diff options
author | Jack Lloyd <[email protected]> | 2018-08-23 17:15:32 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-08-23 17:15:32 -0400 |
commit | afbae250e23c202329792a06783184b7ba08776f (patch) | |
tree | 104dd4c9b4bf486cc3041b6f1ce522f18c498a61 | |
parent | a34d66282eb191711f2e20c755d83e40b007175d (diff) |
Allow SIV for PBES2 private key encryption
-rw-r--r-- | doc/manual/pubkey.rst | 19 | ||||
-rw-r--r-- | src/lib/pubkey/pbes2/pbes2.cpp | 9 |
2 files changed, 18 insertions, 10 deletions
diff --git a/doc/manual/pubkey.rst b/doc/manual/pubkey.rst index 767cb1552..5647170db 100644 --- a/doc/manual/pubkey.rst +++ b/doc/manual/pubkey.rst @@ -106,20 +106,23 @@ encrypted storage. PBE, a sensible default will be used. The currently supported PBE is PBES2 from PKCS5. Format is as follows: - `PBE-PKCS5v20(CIPHER,PBKDF)`. Cipher can be any block cipher with /CBC or /GCM - appended, for example "AES-128/CBC" or "Camellia-256/GCM". For best interop - with other systems, use AES in CBC mode. The PBKDF can be either the name of a - hash function (in which case PBKDF2 is used with that hash) or "Scrypt", which - causes the scrypt memory hard password hashing function to be used. Scrypt is - supported since version 2.7.0. + ``PBE-PKCS5v20(CIPHER,PBKDF)``. Since 2.8.0, ``PBES2(CIPHER,PBKDF)`` also works. + Cipher can be any block cipher with /CBC or /GCM appended, for example + "AES-128/CBC" or "Camellia-256/GCM". For best interop with other systems, use + AES in CBC mode. The PBKDF can be either the name of a hash function (in which + case PBKDF2 is used with that hash) or "Scrypt", which causes the scrypt + memory hard password hashing function to be used. Scrypt is supported since + version 2.7.0. Use `PBE-PKCS5v20(AES-256/CBC,SHA-256)` if you want to ensure the keys can be imported by different software packages. Use `PBE-PKCS5v20(AES-256/GCM,Scrypt)` for best security assuming you do not care about interop. - For ciphers you can use anything which has an OID defined for CBC or GCM mode. - Currently this includes 3DES, AES, Camellia, SM4, Serpent, and Twofish. + For ciphers you can use anything which has an OID defined for CBC, GCM or SIV + modes. Currently this includes AES, Camellia, Serpent, Twofish, and SM4. Most + other libraries only support CBC mode for private key encryption. GCM has + been supported in PBES2 since 1.11.10. SIV has been supported since 2.8. .. cpp:function:: std::string PKCS8::PEM_encode(const Private_Key& key, \ RandomNumberGenerator& rng, const std::string& pass, const std::string& pbe_algo = "") diff --git a/src/lib/pubkey/pbes2/pbes2.cpp b/src/lib/pubkey/pbes2/pbes2.cpp index cfac722d7..fce225e99 100644 --- a/src/lib/pubkey/pbes2/pbes2.cpp +++ b/src/lib/pubkey/pbes2/pbes2.cpp @@ -23,6 +23,11 @@ namespace Botan { namespace { +bool known_pbes_cipher_mode(const std::string& mode) + { + return (mode == "CBC" || mode == "GCM" || mode == "SIV"); + } + SymmetricKey derive_key(const std::string& passphrase, const AlgorithmIdentifier& kdf_algo, size_t default_key_size) @@ -181,7 +186,7 @@ pbes2_encrypt_shared(const secure_vector<uint8_t>& key_bits, if(cipher_spec.size() != 2) throw Encoding_Error("PBE-PKCS5 v2.0: Invalid cipher spec " + cipher); - if(cipher_spec[1] != "CBC" && cipher_spec[1] != "GCM") + if(!known_pbes_cipher_mode(cipher_spec[1])) throw Encoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher); const OID cipher_oid = OIDS::lookup(cipher); @@ -289,7 +294,7 @@ pbes2_decrypt(const secure_vector<uint8_t>& key_bits, const std::vector<std::string> cipher_spec = split_on(cipher, '/'); if(cipher_spec.size() != 2) throw Decoding_Error("PBE-PKCS5 v2.0: Invalid cipher spec " + cipher); - if(cipher_spec[1] != "CBC" && cipher_spec[1] != "GCM") + if(!known_pbes_cipher_mode(cipher_spec[1])) throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher); secure_vector<uint8_t> iv; |