aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/prov
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-10-26 20:31:30 -0400
committerJack Lloyd <[email protected]>2017-10-26 22:26:15 -0400
commite6d45052efedfe49e99adb6318aaf56e0a9e8d7b (patch)
treec6c3ccd3cff3d04285940bf1d518c809e0653947 /src/lib/prov
parent315b002ecf00f6b6bb0f0d5200d1f39a83527e8f (diff)
Add checks that keyed algorithms are actually keyed before use
Previously calling update or encrypt without calling set_key first would result in invalid outputs or else crashing.
Diffstat (limited to 'src/lib/prov')
-rw-r--r--src/lib/prov/openssl/openssl_block.cpp15
-rw-r--r--src/lib/prov/openssl/openssl_rc4.cpp5
2 files changed, 17 insertions, 3 deletions
diff --git a/src/lib/prov/openssl/openssl_block.cpp b/src/lib/prov/openssl/openssl_block.cpp
index 33cd9b8cc..3cf203961 100644
--- a/src/lib/prov/openssl/openssl_block.cpp
+++ b/src/lib/prov/openssl/openssl_block.cpp
@@ -36,6 +36,7 @@ class OpenSSL_BlockCipher final : public BlockCipher
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
{
+ verify_key_set(m_key_set);
int out_len = 0;
if(!EVP_EncryptUpdate(m_encrypt, out, &out_len, in, blocks * m_block_sz))
throw OpenSSL_Error("EVP_EncryptUpdate");
@@ -43,6 +44,7 @@ class OpenSSL_BlockCipher final : public BlockCipher
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
{
+ verify_key_set(m_key_set);
int out_len = 0;
if(!EVP_DecryptUpdate(m_decrypt, out, &out_len, in, blocks * m_block_sz))
throw OpenSSL_Error("EVP_DecryptUpdate");
@@ -55,13 +57,15 @@ class OpenSSL_BlockCipher final : public BlockCipher
std::string m_cipher_name;
EVP_CIPHER_CTX *m_encrypt;
EVP_CIPHER_CTX *m_decrypt;
+ bool m_key_set;
};
OpenSSL_BlockCipher::OpenSSL_BlockCipher(const std::string& algo_name,
const EVP_CIPHER* algo) :
m_block_sz(EVP_CIPHER_block_size(algo)),
m_cipher_key_spec(EVP_CIPHER_key_length(algo)),
- m_cipher_name(algo_name)
+ m_cipher_name(algo_name),
+ m_key_set(false)
{
if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE)
throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in");
@@ -92,7 +96,8 @@ OpenSSL_BlockCipher::OpenSSL_BlockCipher(const std::string& algo_name,
size_t key_mod) :
m_block_sz(EVP_CIPHER_block_size(algo)),
m_cipher_key_spec(key_min, key_max, key_mod),
- m_cipher_name(algo_name)
+ m_cipher_name(algo_name),
+ m_key_set(false)
{
if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE)
throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in");
@@ -134,15 +139,19 @@ void OpenSSL_BlockCipher::key_schedule(const uint8_t key[], size_t length)
full_key += std::make_pair(key, 8);
}
else
+ {
if(EVP_CIPHER_CTX_set_key_length(m_encrypt, length) == 0 ||
EVP_CIPHER_CTX_set_key_length(m_decrypt, length) == 0)
throw Invalid_Argument("OpenSSL_BlockCipher: Bad key length for " +
m_cipher_name);
+ }
if(!EVP_EncryptInit_ex(m_encrypt, nullptr, nullptr, full_key.data(), nullptr))
throw OpenSSL_Error("EVP_EncryptInit_ex");
if(!EVP_DecryptInit_ex(m_decrypt, nullptr, nullptr, full_key.data(), nullptr))
throw OpenSSL_Error("EVP_DecryptInit_ex");
+
+ m_key_set = true;
}
/*
@@ -164,6 +173,8 @@ void OpenSSL_BlockCipher::clear()
{
const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(m_encrypt);
+ m_key_set = false;
+
if(!EVP_CIPHER_CTX_cleanup(m_encrypt))
throw OpenSSL_Error("EVP_CIPHER_CTX_cleanup encrypt");
if(!EVP_CIPHER_CTX_cleanup(m_decrypt))
diff --git a/src/lib/prov/openssl/openssl_rc4.cpp b/src/lib/prov/openssl/openssl_rc4.cpp
index 5fb2a68f5..b24760f45 100644
--- a/src/lib/prov/openssl/openssl_rc4.cpp
+++ b/src/lib/prov/openssl/openssl_rc4.cpp
@@ -21,7 +21,7 @@ namespace {
class OpenSSL_RC4 final : public StreamCipher
{
public:
- void clear() override { clear_mem(&m_rc4, 1); }
+ void clear() override { clear_mem(&m_rc4, 1); m_key_set = false; }
std::string provider() const override { return "openssl"; }
@@ -61,6 +61,7 @@ class OpenSSL_RC4 final : public StreamCipher
private:
void cipher(const uint8_t in[], uint8_t out[], size_t length) override
{
+ verify_key_set(m_key_set);
::RC4(&m_rc4, length, in, out);
}
@@ -70,10 +71,12 @@ class OpenSSL_RC4 final : public StreamCipher
uint8_t d = 0;
for(size_t i = 0; i != m_skip; ++i)
::RC4(&m_rc4, 1, &d, &d);
+ m_key_set = true;
}
size_t m_skip;
RC4_KEY m_rc4;
+ bool m_key_set;
};
}