Skip to content

Latest commit

 

History

History
116 lines (91 loc) · 8.71 KB

File metadata and controls

116 lines (91 loc) · 8.71 KB

Mitigation Strategies Analysis for jedisct1/libsodium

Mitigation Strategy: Correct Libsodium API Usage

  1. Documentation Adherence: Before using any libsodium function, developers must consult the official libsodium documentation (https://libsodium.gitbook.io/doc/). This includes understanding:
    • Function purpose.
    • Precise parameter types, sizes, and expected ranges.
    • Return values and error handling mechanisms.
    • All security considerations and warnings.
  2. High-Level API Preference: Prioritize the use of high-level "easy" APIs (e.g., crypto_secretbox_easy, crypto_box_easy, crypto_generichash_easy) over lower-level primitives whenever possible. These are designed for safer and simpler use.
  3. Function-Specific Unit Tests: Create unit tests that specifically target each libsodium function used. Tests should cover:
    • Valid inputs within expected ranges.
    • Invalid inputs (e.g., incorrect sizes, null pointers) to test error handling.
    • Boundary conditions (e.g., maximum input sizes).
    • Verification of expected outputs and return codes.
  4. Fuzzing (Optional but Recommended): Implement fuzzing tests that feed random or malformed inputs to libsodium wrappers or functions that directly call libsodium APIs.
  • Threats Mitigated:

    • Cryptographic Weakness (Severity: High to Critical): Incorrect API usage can lead to vulnerabilities that completely undermine the security guarantees of libsodium.
    • Implementation Errors (Severity: High): Reduces the risk of subtle bugs in how libsodium is used, which could lead to security flaws.
    • Unexpected Behavior (Severity: Medium to High): Helps ensure that libsodium functions behave as expected, even with unexpected inputs.
  • Impact:

    • Cryptographic Weakness: Risk reduced significantly (ensures correct usage of cryptographic primitives).
    • Implementation Errors: Risk reduced significantly (early detection of bugs).
    • Unexpected Behavior: Risk reduced (more robust and predictable behavior).
  • Currently Implemented:

    • Unit tests exist for most cryptographic functions, but coverage could be improved.
  • Missing Implementation:

    • Fuzzing is not currently implemented.
    • Unit test coverage for boundary conditions and invalid inputs needs improvement.
    • A formal checklist for libsodium API usage during code reviews should be created, specifically referencing the official documentation.
  1. Understand Nonce Requirements: For each libsodium function, carefully read the documentation to determine the exact nonce requirements (size, uniqueness guarantees).
  2. randombytes_buf() for Nonces (Generally Preferred): In most cases, generate nonces using randombytes_buf(nonce, REQUIRED_NONCE_SIZE). Ensure REQUIRED_NONCE_SIZE matches the specific function's requirement (e.g., crypto_secretbox_NONCEBYTES, crypto_box_NONCEBYTES).
  3. Counter-Based Nonces (Avoid if Possible): Only use counter-based nonces if absolutely required by a specific protocol and you can guarantee no reuse with the same key. If used:
    • Use a sufficiently large counter (at least 64 bits).
    • Increment before each use.
    • Persist the counter state securely and ensure it's recoverable. This is outside the scope of libsodium itself.
  4. Avoid Predictable Values: Never use timestamps, easily guessable values, or sequential IDs (without robust, secure, and persistent state management) as nonces.
  5. Testing: Include unit tests that specifically verify:
    • Correct nonce generation (size, randomness when using randombytes_buf()).
    • Correct nonce usage with each libsodium function.
  • Threats Mitigated:

    • Replay Attacks (Severity: Critical): Nonce reuse can completely break the security of many authenticated encryption schemes, allowing attackers to replay messages.
    • Cryptographic Weakness (Severity: Critical): Incorrect nonce usage can lead to weaknesses that make decryption or forgery easier.
  • Impact:

    • Replay Attacks: Risk reduced significantly (from high to negligible with correct implementation).
    • Cryptographic Weakness: Risk reduced significantly (ensures the intended security properties).
  • Currently Implemented:

    • randombytes_buf() is used for nonce generation in most cryptographic functions.
    • Unit tests verify nonce size.
  • Missing Implementation:

    • No specific tests for replay attacks (although correct nonce usage inherently mitigates this). More focused integration tests could be added.
    • Counter-based nonces are not used, and documentation should explicitly discourage their use unless absolutely necessary and with extreme caution.
  1. sodium_memzero(): After using sensitive data (keys, intermediate values) that have been stored in memory, immediately use sodium_memzero(sensitive_data, size_of_data) to securely erase the data. This prevents data remnants from being recovered from memory.
  2. sodium_mlock() and sodium_munlock() (Use with Caution):
    • Consider using sodium_mlock(data, size) to lock sensitive data in memory, preventing it from being swapped to disk.
    • Always use sodium_munlock(data, size) to unlock the memory when it's no longer needed.
    • Important: Thoroughly test sodium_mlock()/sodium_munlock() on your target platforms. Be aware of potential issues:
      • Resource exhaustion (limited locked memory).
      • Platform-specific behavior and limitations.
      • Potential for deadlocks if not used carefully.
    • This is a defense-in-depth measure, not a primary security control. Proper key management is far more important.
  • Threats Mitigated:

    • Data Remnants in Memory (Severity: Medium to High): Reduces the risk of sensitive data being recovered from memory after it's no longer needed.
    • Swap File Exposure (Severity: Medium): sodium_mlock() (if used correctly) can prevent sensitive data from being written to the swap file.
  • Impact:

    • Data Remnants: Risk reduced (especially if sodium_memzero() is used consistently).
    • Swap File Exposure: Risk reduced (if sodium_mlock() is used correctly and effectively).
  • Currently Implemented:

    • sodium_memzero() is used after key usage in several places.
  • Missing Implementation:

    • sodium_memzero() is not used consistently throughout the codebase. A thorough audit is needed to identify all locations where it should be added.
    • sodium_mlock()/sodium_munlock() are not currently used. Extensive research, testing, and careful consideration are required before implementing these.

Mitigation Strategy: Secure Compilation of Libsodium

  1. Follow Official Instructions: Strictly adhere to the compilation instructions and recommended compiler flags provided in the official libsodium documentation.
  2. Verification: After building libsodium, verify the integrity of the compiled library using the checksums (e.g., SHA-256) provided by the libsodium project. This ensures that the library hasn't been tampered with during the build process.
  3. Compiler Flags: Use appropriate compiler flags to enable security features and optimizations. This may include flags related to:
    • Stack canaries
    • Address Space Layout Randomization (ASLR)
    • Data Execution Prevention (DEP/NX)
    • Optimization levels (ensure they don't introduce vulnerabilities)
  • Threats Mitigated:

    • Compilation Errors (Severity: Medium to High): Incorrect compilation can lead to weakened or incorrect implementations of the cryptographic algorithms.
    • Tampering (Severity: High): Checksum verification helps detect if the compiled library has been maliciously modified.
  • Impact:

    • Compilation Errors: Risk reduced significantly (ensures correct and secure compilation).
    • Tampering: Risk reduced (allows detection of tampering).
  • Currently Implemented:

    • Basic compilation instructions are followed.
  • Missing Implementation:

    • Checksum verification is not automated.
    • Compiler flags for enhanced security features are not consistently applied and verified.