Audit
The Open Crypto Audit Project has generously taken on an extensive audit of TrueCrypt. The audit makes these high level recommendations:
- Rebuild with current build tools.
- Release instructions for producing reproducible builds.
- Improve code quality.
Did we actually have to pay someone to make these recommendations?
This audit found 8 vulnerabilities, and 3 informational issues, all prioritized by severity.
Audit Issue List
- Weak Volume Header key derivation - Insecure use of PKCS5
- - Severity: MEDIUM
- - Where: Common/Pkcs5.c line 619
- - Remediation (short term): Increase # of iterations
- - Remediation (long term): Replace PBKDF2 with scrypt
- Sensitive information being paged out - Poor memory handling
- - Severity: MEDIUM
- Where: <unknown>
- Remediation (short term): Consolidate & secure sensitive data
- - Remediation (long term): Educate users in best practice config
- Bootloader decompressor - Evil Maid attack
- - Severity: MEDIUM
- - Where: Boot/Windows/Decompressor.c
- - Remediation (short term): Employ input validation
- - Remediation (long term): Standardize int types throughout code
- Win driver uses memset() to clear sensitive data - Data leak
- - Severity: MEDIUM
- Where: Common/Pkcs5.c, DIgcode.c, Fat.c, GfMul.c, & others
- - Remediation (short term): Replace memset() with burn()
- - Remediation (long term): Remove all instances of memset()
- TC_IOCTL_GET_SYSTEM_DRIVE_DUMP_CONFIG kernel pointer - ALSR bypass
- - Severity: LOW
- - Where: Driver/NTdriver.c line 1504
- - Remediation (short term): Remove userland permissions
- Remediation (long term): <as above>
- IOCTL_DISK_VERIFY integer overflow - Buffer Overflow
- - Severity: LOW
- - Where: Driver/NTdriver.c line 580
- - Remediation (short term): Insert sum validation
- - Remediation (long term): Deploy sum validation throughout code
- TC_IOCTL_OPEN_TEST multiple issues - Data leak
- - Severity: LOW
- - Where: Driver/NTdriver.c line 493
- Remediation (short term): Replace ZwCreateFile() with NtCreateFile()
- - Remediation (long term): Replace all Zw calls with NT functions
MainThreadProc() integer overflow - Buffer Overflow
- - Severity: LOW
- - Where: Driver/EncryptedIoQueue.c line 528
- - Remediation (short term): Sanitize inputs
- Remediation (long term): <as above>
MountVolume() device check bypass - Input Sanitation
- - Severity: INFORMATIONAL
- - Where: Driver/NTdriver.c line 1748
- - Remediation (short term): Sanitize inputs
- Remediation (long term): <as above>
GetWipePassCount() / WipeBuffer() crashing - System crash
- - Severity: INFORMATIONAL
- - Where: Common/Wipe.c line 159
- - Remediation (short term): Insert error checking
- Remediation (long term): <as above>
EncryptDataUnits() lacks error handling - Data leak
- - Severity: INFORMATIONAL
- - Where: Common/Crypto.c line 1370
- - Remediation (short term): Insert validation
- Remediation (long term): <as above>
Most of the MEDIUM severity ones are relatively easy to implement (at least the short term fixes at any rate)
Bill Cox's Responses
1. Weak Volume Header key derivation algorithm
The audit team got the most severe vulnerability right! The password hashing is so weak that one coder forked TrueCrypt to create VeraCrypt. A top priority for Phase 2 needs to be fixing this vulnerability. Scrypt should probably be included in the short term, while a memory-hard password hashing scheme winning the Password Hashing Competition should be employed long term.
Unfortunately, the audit team can only do so much. As they stated, they did not review the volume header format, or the rationale behind it, and it shows in their recommendations. They recommend that in the short term iteration count be increased to much more than 2,000, just as VeraCrypt does. However, they then recommend encoding this parameter in the volume header, showing that most likely they made one of the following errors:
- They do not understand that volume headers in TC attempt to appear random
- They do not understand that encoding the iteration count in the clear would not appear random
Errors like this are human. It's just fun to find them TrueCrypt does encode the salt in the clear, but salt appears random anyway. Nothing else is encoded in the clear. Because of this, TrueCrypt tries each possible password hashing function in sequence, until one is found that succeeds in decrypting the volume header. Because of this, there is a stronger motivation for TrueCrypt to use fast password hashing algorithms. If several were available that each take 1 second each, decrypting a volume would become unacceptably slow. Also, vastly different computing power and memory exists on the various machines running TrueCrypt, and while hashing 1GiB with Scrypt would be appropriate for a modern high-end laptop, this would simply not work on a 10-year-old machine. A solution is to use "garlic", as suggested in the Catena password hashing scheme. Increasing levels of difficulty are tried until the correct level is found. This slows down password hashing by about 2X, but is still far better than the situation with TrueCrypt today. Any delay could be eliminated by saving the result along with the path to the volume that TrueCrypt saves today, for users who do not require the ability to deny that a specific file is in fact a TrueCrypt volume. Users using FDE already give up this option, so the hashing parameters can be stored in the clear.
2. Sensitive information might be paged out from kernel stacks
The second vulnerability found was sensitive data in the Windows driver that was not stored in non-swappable memory. It is possible in low memory situations for key information to be swapped to disk, and later recovered by an attacker. This is a common failure in crypto code (I've done it before). This should be a simple fix which can be addressed in Phase 1.
3. Multiple issues in the bootloader decompressor
The third vulnerability relates to several bugs in the Windows boot loader which can give an attacker with physical access to the machine while powered off a way to compromise the machine. However, Evil Maid Attacks are possible in any event. Users should be warned that FDE does not secure their data if an attacker gains physical access to their machine, modifies the boot loader, and later the user boots it. Is it possible to make such attacks more difficult by supporting TPM modules? Would this be a good thing? In Phase 1, we should fix the bugs identified in the Windows boot loader. In Phase 2, most or all usages of the "int" type should be converted to the appropriate stdint.h type.
4. Windows kernel driver uses memset() to clear sensitive data
The simple "fix" is to call a function similar to Blake2's "secure_zero_memory" function. What is the "burn" function the audit refers to for this function? We should replace all calls to memset in Phase I. However, just calling "burn" or "secure_zero_memory" does not insure that key information does not leak! For example, if an interrupt happens, and the password length is stored in a register, that length can be leaked to the interrupt code, and even swapped to disk in some cases. However, every attempt to scrub sensitive data ASAP from memory should be made. To avoid leaking the password length, it may be best to use a fixed length password buffer of sufficient length (1024 bytes should do), with an error if this length is exceeded. This is something that could be addressed in Phase 2.
Remaining Issues
The remaining issues are less severe, but still important enough to at least do the "short term fix" in Phase 1. They are issues like integer overflows and errors in the kernel driver checking file permissions and names. They are real security holes, but assuming there is only one user on the machine and no malware to exploit the holes (big IF), then they should not cause problems.
After reading this audit, we would recommend that TrueCrypt 7.1a remains safe for use.