From bdc32a98b97c97145054edfa217569351ff41baa Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sat, 29 Sep 2018 06:39:03 -0400 Subject: Refactor mode tests, and correct bugs found Several problems in CBC found by adding tests - If you set a key, then set a nonce, then set a new key, you could encrypt without setting a new nonce. - It was possible to call CBC finish without setting a nonce, which would crash. - If you had an CBC decryption object, set a key, set a nonce, then reset message state, it should throw because no nonce is set. Instead it would carry on using an all-zero nonce. Disable CommonCrypto with PKCS7 padding as it seems to have some problem that I cannot figure out from the build logs. This work sponsored by Ribose Inc --- src/lib/prov/openssl/openssl_mode.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/lib/prov/openssl') diff --git a/src/lib/prov/openssl/openssl_mode.cpp b/src/lib/prov/openssl/openssl_mode.cpp index ce98e0c62..5636d008f 100644 --- a/src/lib/prov/openssl/openssl_mode.cpp +++ b/src/lib/prov/openssl/openssl_mode.cpp @@ -86,11 +86,20 @@ void OpenSSL_Cipher_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) if(!valid_nonce_length(nonce_len)) throw Invalid_IV_Length(name(), nonce_len); + if(nonce_len) { if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, nullptr, nonce, -1)) throw OpenSSL_Error("EVP_CipherInit_ex nonce"); } + else if(m_nonce_set == false) + { + const std::vector zeros(m_block_size); + if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, nullptr, zeros.data(), -1)) + throw OpenSSL_Error("EVP_CipherInit_ex nonce"); + } + // otherwise existing CBC state left unchanged + m_nonce_set = true; } @@ -116,6 +125,7 @@ void OpenSSL_Cipher_Mode::finish(secure_vector& buffer, size_t offset) { verify_key_set(m_key_set); + BOTAN_STATE_CHECK(m_nonce_set); BOTAN_ASSERT(buffer.size() >= offset, "Offset ok"); uint8_t* buf = buffer.data() + offset; @@ -163,6 +173,7 @@ size_t OpenSSL_Cipher_Mode::output_length(size_t input_length) const void OpenSSL_Cipher_Mode::clear() { m_key_set = false; + m_nonce_set = false; const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(m_cipher); @@ -180,6 +191,7 @@ void OpenSSL_Cipher_Mode::reset() { if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, nullptr, nullptr, -1)) throw OpenSSL_Error("EVP_CipherInit_ex clear"); + m_nonce_set = false; } Key_Length_Specification OpenSSL_Cipher_Mode::key_spec() const @@ -194,6 +206,7 @@ void OpenSSL_Cipher_Mode::key_schedule(const uint8_t key[], size_t length) if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, key, nullptr, -1)) throw OpenSSL_Error("EVP_CipherInit_ex key"); m_key_set = true; + m_nonce_set = false; } } -- cgit v1.2.3