summaryrefslogtreecommitdiffstats
path: root/crypto/modes
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2020-07-22 10:40:55 +1000
committerShane Lontis <shane.lontis@oracle.com>2020-07-22 10:40:55 +1000
commit90409da6a520812b0266fcb1303175406dea81fe (patch)
treea9d4fcbae513c3daaa7dabb9dce681e30465bd90 /crypto/modes
parent77174598920a05826a28d8a0bd87a3af43d3f4d8 (diff)
Fix provider cipher reinit issue
Fixes #12405 Fixes #12377 Calling Init()/Update() and then Init()/Update() again gave a different result when using the same key and iv. Cipher modes that were using ctx->num were not resetting this value, this includes OFB, CFB & CTR. The fix is to reset this value during the ciphers einit() and dinit() methods. Most ciphers go thru a generic method so one line fixes most cases. Add test for calling EVP_EncryptInit()/EVP_EncryptUpdate() multiple times for all ciphers. Ciphers should return the same value for both updates. DES3-WRAP does not since it uses a random in the update. CCM modes currently also fail on the second update (This also happens in 1_1_1). Fix memory leak in AES_OCB cipher if EVP_EncryptInit is called multiple times. Fix AES_SIV cipher dup_ctx and init. Calling EVP_CIPHER_init multiple times resulted in a memory leak in the siv. Fixing this leak also showed that the dup ctx was not working for siv mode. Note: aes_siv_cleanup() can not be used by aes_siv_dupctx() as it clears data that is required for the decrypt (e.g the tag). Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/12413)
Diffstat (limited to 'crypto/modes')
-rw-r--r--crypto/modes/siv128.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/crypto/modes/siv128.c b/crypto/modes/siv128.c
index d3655674b4..27e29c3cc6 100644
--- a/crypto/modes/siv128.c
+++ b/crypto/modes/siv128.c
@@ -140,13 +140,15 @@ __owur static ossl_inline int siv128_do_encrypt(EVP_CIPHER_CTX *ctx, unsigned ch
/*
* Create a new SIV128_CONTEXT
*/
-SIV128_CONTEXT *CRYPTO_siv128_new(const unsigned char *key, int klen, EVP_CIPHER* cbc, EVP_CIPHER* ctr)
+SIV128_CONTEXT *CRYPTO_siv128_new(const unsigned char *key, int klen,
+ EVP_CIPHER *cbc, EVP_CIPHER *ctr,
+ OPENSSL_CTX *libctx, const char *propq)
{
SIV128_CONTEXT *ctx;
int ret;
if ((ctx = OPENSSL_malloc(sizeof(*ctx))) != NULL) {
- ret = CRYPTO_siv128_init(ctx, key, klen, cbc, ctr);
+ ret = CRYPTO_siv128_init(ctx, key, klen, cbc, ctr, libctx, propq);
if (ret)
return ctx;
OPENSSL_free(ctx);
@@ -159,7 +161,8 @@ SIV128_CONTEXT *CRYPTO_siv128_new(const unsigned char *key, int klen, EVP_CIPHER
* Initialise an existing SIV128_CONTEXT
*/
int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen,
- const EVP_CIPHER* cbc, const EVP_CIPHER* ctr)
+ const EVP_CIPHER *cbc, const EVP_CIPHER *ctr,
+ OPENSSL_CTX *libctx, const char *propq)
{
static const unsigned char zero[SIV_LEN] = { 0 };
size_t out_len = SIV_LEN;
@@ -174,14 +177,17 @@ int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen,
params[2] = OSSL_PARAM_construct_end();
memset(&ctx->d, 0, sizeof(ctx->d));
+ EVP_CIPHER_CTX_free(ctx->cipher_ctx);
+ EVP_MAC_CTX_free(ctx->mac_ctx_init);
+ EVP_MAC_free(ctx->mac);
+ ctx->mac = NULL;
ctx->cipher_ctx = NULL;
ctx->mac_ctx_init = NULL;
if (key == NULL || cbc == NULL || ctr == NULL
|| (ctx->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL
- /* TODO(3.0) library context */
|| (ctx->mac =
- EVP_MAC_fetch(NULL, OSSL_MAC_NAME_CMAC, NULL)) == NULL
+ EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, propq)) == NULL
|| (ctx->mac_ctx_init = EVP_MAC_CTX_new(ctx->mac)) == NULL
|| !EVP_MAC_CTX_set_params(ctx->mac_ctx_init, params)
|| !EVP_EncryptInit_ex(ctx->cipher_ctx, ctr, NULL, key + klen, NULL)
@@ -209,12 +215,20 @@ int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen,
int CRYPTO_siv128_copy_ctx(SIV128_CONTEXT *dest, SIV128_CONTEXT *src)
{
memcpy(&dest->d, &src->d, sizeof(src->d));
+ if (dest->cipher_ctx == NULL) {
+ dest->cipher_ctx = EVP_CIPHER_CTX_new();
+ if (dest->cipher_ctx == NULL)
+ return 0;
+ }
if (!EVP_CIPHER_CTX_copy(dest->cipher_ctx, src->cipher_ctx))
return 0;
EVP_MAC_CTX_free(dest->mac_ctx_init);
dest->mac_ctx_init = EVP_MAC_CTX_dup(src->mac_ctx_init);
if (dest->mac_ctx_init == NULL)
return 0;
+ dest->mac = src->mac;
+ if (dest->mac != NULL)
+ EVP_MAC_up_ref(dest->mac);
return 1;
}