Fix provider cipher reinit issue
[openssl.git] / crypto / modes / siv128.c
index d3655674b4474a29b112dfc23cdc12b0f01898bd..27e29c3cc614c4ca89d6907570123f178fb8f4fd 100644 (file)
@@ -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;
 }