VoodooPad Cryptography Overview
This document provides a high-level overview of the encryption implementation released in VoodooPad 5.1.4 (Mac) and VoodooPad 5.1.4 (iOS).
Additional technical details are available via the VoodooPad Crypto Specification.
VoodooPad prior to Plausible Labs
After Plausible Labs' acquisition of VoodooPad, a cryptography audit was performed, and VoodooPad's legacy encryption implementation was found to be fundamentally insecure. This standard was developed as a replacement, using only well-documented and well-understood primitives and protocols. The standard is published publicly to allow
for external review, verification, and comment.
As of 5.1.4 (Mac OS X) and 2.1.4 (iOS), all VoodooPad releases ship with a secure encryption implementation conforming to this standard. In addition, VoodooPad will display a warning -- and allow the user to perform an immediate upgrade -- upon opening a document encrypted with the insecure legacy cryptography implementation.
VoodooPad supports two modes of document encryption:
- Full document encryption: All resources within a document are fully encrypted and unreadable without the document password.
- Single page encryption: User-specified pages are encrypted and unreadable without a per-page password; multiple passwords may be used for different pages, and the document may contain both encrypted and unencrypted data.
Both per-page and full-document encryption are based on the composition of well-understood standards and recommendations:
- AES-256-CBC - NIST SP-800-38a
- PKCS#7 padding - RFC 5652
- HMAC-SHA-256 - FIPS-198-1
- PBKDF2 - NIST SP-800-132
- HKDF - RFC 5869 and NIST SP-800-56C
To prevent padding oracle attacks, as well as to decrease the potential attack surface of the application, VoodooPad leverages encrypt-then-MAC for all authenticated encrypted data.
PBKDF2-HMAC-SHA512 is used for all password-based key derivation, and HKDF is used to generate subkeys from the PBKDF2 output, where required. Keys are only ever used for a single purpose.
VoodooPad also makes use of SQLite to generate indices of document data for faster querying and searching, stored seperately in ~/Library/Caches. Refer to Appendix A for additional details regarding the use of encryption with SQLite.
Full Document Encryption
When performing full document encryption, multiple keys are used to perform encryption and authentication of the VooodooPad document:
- A Document Master Key (DMK) is derived from the user-supplied password via PBKDF2. This key is only used as input to HKDF to generate additional subkeys.
- Two sub-keys are generated from the DMK via HKDF:
- DMK-SUBKEY - Used to encrypt and authenticate randomly generated data protection keys.
- DMK-SQLITE - Used with SQLite SEE (refer to Appendix A) to encrypt and authenticate the AES-128-CCM-protected document data cache.
- Data Protection Keys (DPK) are used to perform encryption and authentication of document data (other than SQLite). These keys are randomly generated, never re-used, and encrypted and authenticated using the DMK-SUBKEY key.
If the document password is changed:
- A new DMK is derived from the user-supplied password via PBKDF2.
- New DMK-SUBKEY and DMK-SQLITE keys are derived from the DMK via HKDF.
- All existing DPKs are re-encrypted with the new DMK-SUBKEY key.
- The SQLite SEE cache is re-keyed with the new DMK-SQLITE key.
Per-page encryption builds on the same cryptographic foundation as full-document encryption, but uses a slightly simplified keying model based on per-pagepassword-based key derivation:
- A Page Master Key (PMK) is derived from the user-supplied password via PBKDF2. This key is only used as input to HKDF to generate additional subkeys.
- A single sub-key is generated from the PMK via HKDF:
- PMK-DATA - Used to encrypt and authenticate the page data directly.
If the page's password is changed, new PMK and PMK-DATA keys are generated as above, and the page data is re-encrypted with the newly derived keys.
Unlike full-document encryption, per-page encryption exposes page meta-data – including the page name – as unauthenticated plaintext in the document's SQLite cache (stored seperately from the document in ~/Library/Caches);
Refer to the VoodooPad Crypto Specification for a complete accounting of meta-data exposed via per-page encryption.
Appendix A: SQLite Encryption Extension (SEE)
When encrypting SQLite indexes, VoodooPad makes use of SEE, a proprietary encryption extension authored by the SQLite developers. SEE supports a fixed set of ciphers and encryption modes; VoodooPad uses SEE's AES-128-CCM implementation to ensure both confidentially and authentication of the per-document index data.