aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-08-23 17:15:32 -0400
committerJack Lloyd <[email protected]>2018-08-23 17:15:32 -0400
commitafbae250e23c202329792a06783184b7ba08776f (patch)
tree104dd4c9b4bf486cc3041b6f1ce522f18c498a61
parenta34d66282eb191711f2e20c755d83e40b007175d (diff)
Allow SIV for PBES2 private key encryption
-rw-r--r--doc/manual/pubkey.rst19
-rw-r--r--src/lib/pubkey/pbes2/pbes2.cpp9
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;