Move cipher ctx 'original iv' parameter into the provider
authorShane Lontis <shane.lontis@oracle.com>
Mon, 7 Oct 2019 23:19:10 +0000 (09:19 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Mon, 7 Oct 2019 23:19:10 +0000 (09:19 +1000)
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10026)

18 files changed:
crypto/evp/evp_enc.c
crypto/evp/evp_lib.c
providers/common/ciphers/cipher_aes_ccm.c
providers/common/ciphers/cipher_aes_gcm.c
providers/common/ciphers/cipher_aes_wrp.c
providers/common/ciphers/cipher_aes_xts.c
providers/common/ciphers/cipher_aes_xts.h
providers/common/ciphers/cipher_ccm.c
providers/common/ciphers/cipher_common.c
providers/common/ciphers/cipher_gcm.c
providers/common/ciphers/cipher_tdes.c
providers/common/include/internal/ciphers/cipher_ccm.h
providers/common/include/internal/ciphers/cipher_gcm.h
providers/common/include/internal/ciphers/ciphercommon.h
providers/default/ciphers/cipher_aes_ocb.c
providers/default/ciphers/cipher_aria_ccm.c
providers/default/ciphers/cipher_aria_gcm.c
providers/default/ciphers/cipher_des.c

index 046a9f6..2a22336 100644 (file)
@@ -341,19 +341,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
             return 0;
     }
 
-    switch (EVP_CIPHER_mode(ctx->cipher)) {
-    case EVP_CIPH_CFB_MODE:
-    case EVP_CIPH_OFB_MODE:
-    case EVP_CIPH_CBC_MODE:
-        /* For these modes we remember the original IV for later use */
-        if (!ossl_assert(EVP_CIPHER_CTX_iv_length(ctx) <= (int)sizeof(ctx->oiv))) {
-            EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
-            return 0;
-        }
-        if (iv != NULL)
-            memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
-    }
-
     if (enc) {
         if (ctx->cipher->einit == NULL) {
             EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
index 3abea33..3a3eec6 100644 (file)
@@ -194,11 +194,13 @@ int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
 {
     int i = 0;
     unsigned int j;
+    unsigned char *oiv = NULL;
 
     if (type != NULL) {
+        oiv = (unsigned char *)EVP_CIPHER_CTX_original_iv(c);
         j = EVP_CIPHER_CTX_iv_length(c);
         OPENSSL_assert(j <= sizeof(c->iv));
-        i = ASN1_TYPE_set_octetstring(type, c->oiv, j);
+        i = ASN1_TYPE_set_octetstring(type, oiv, j);
     }
     return i;
 }
@@ -403,7 +405,16 @@ int EVP_CIPHER_CTX_tag_length(const EVP_CIPHER_CTX *ctx)
 
 const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx)
 {
-    return ctx->oiv;
+    int ok;
+    const unsigned char *v = ctx->oiv;
+    OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+
+    params[0] =
+        OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_IV,
+                                       (void **)&v, sizeof(ctx->oiv));
+    ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
+
+    return ok != 0 ? v : NULL;
 }
 
 /*
index c801589..cffca06 100644 (file)
@@ -27,7 +27,6 @@ static void aes_ccm_freectx(void *vctx)
 {
     PROV_AES_CCM_CTX *ctx = (PROV_AES_CCM_CTX *)vctx;
 
-    ccm_finalctx((PROV_CCM_CTX *)ctx);
     OPENSSL_clear_free(ctx,  sizeof(*ctx));
 }
 
index ba03bed..ef015bf 100644 (file)
@@ -27,7 +27,6 @@ static void aes_gcm_freectx(void *vctx)
 {
     PROV_AES_GCM_CTX *ctx = (PROV_AES_GCM_CTX *)vctx;
 
-    gcm_deinitctx((PROV_GCM_CTX *)ctx);
     OPENSSL_clear_free(ctx,  sizeof(*ctx));
 }
 
index 70f387f..1bf4c17 100644 (file)
@@ -36,7 +36,6 @@ typedef struct prov_aes_wrap_ctx_st {
         OSSL_UNION_ALIGN;
         AES_KEY ks;
     } ks;
-    unsigned int iv_set : 1;
     aeswrap_fn wrapfn;
 
 } PROV_AES_WRAP_CTX;
@@ -59,9 +58,7 @@ static void *aes_wrap_newctx(size_t kbits, size_t blkbits,
 static void aes_wrap_freectx(void *vctx)
 {
     PROV_AES_WRAP_CTX *wctx = (PROV_AES_WRAP_CTX *)vctx;
-    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
 
-    OPENSSL_cleanse(ctx->iv, sizeof(ctx->iv));
     OPENSSL_clear_free(wctx,  sizeof(*wctx));
 }
 
@@ -80,9 +77,8 @@ static int aes_wrap_init(void *vctx, const unsigned char *key,
         wctx->wrapfn = enc ? CRYPTO_128_wrap : CRYPTO_128_unwrap;
 
     if (iv != NULL) {
-        ctx->ivlen = ivlen;
-        memcpy(ctx->iv, iv, ivlen);
-        wctx->iv_set = 1;
+        if (!cipher_generic_initiv(ctx, iv, ivlen))
+            return 0;
     }
     if (key != NULL) {
         if (keylen != ctx->keylen) {
@@ -150,7 +146,7 @@ static int aes_wrap_cipher_internal(void *vctx, unsigned char *out,
         }
     }
 
-    rv = wctx->wrapfn(&wctx->ks.ks, wctx->iv_set ? ctx->iv : NULL, out, in,
+    rv = wctx->wrapfn(&wctx->ks.ks, ctx->iv_set ? ctx->iv : NULL, out, in,
                       inlen, ctx->block);
     return rv ? (int)rv : -1;
 }
index f114793..fdda733 100644 (file)
@@ -76,12 +76,8 @@ static int aes_xts_init(void *vctx, const unsigned char *key, size_t keylen,
     ctx->enc = enc;
 
     if (iv != NULL) {
-        if (ivlen != ctx->ivlen) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
+        if (!cipher_generic_initiv(vctx, iv, ivlen))
             return 0;
-        }
-        memcpy(ctx->iv, iv, ivlen);
-        xctx->iv_set = 1;
     }
     if (key != NULL) {
         if (keylen != ctx->keylen) {
@@ -155,7 +151,7 @@ static int aes_xts_cipher(void *vctx, unsigned char *out, size_t *outl,
 
     if (ctx->xts.key1 == NULL
             || ctx->xts.key2 == NULL
-            || !ctx->iv_set
+            || !ctx->base.iv_set
             || out == NULL
             || in == NULL
             || inl < AES_BLOCK_SIZE)
index daad274..4f8a8f8 100644 (file)
@@ -23,7 +23,6 @@ typedef struct prov_aes_xts_ctx_st {
     } ks1, ks2;                /* AES key schedules to use */
     XTS128_CONTEXT xts;
     OSSL_xts_stream_fn stream;
-    unsigned int iv_set : 1;   /* Set if an iv is set */
 } PROV_AES_XTS_CTX;
 
 const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_xts(size_t keybits);
index cc37b49..3fbaef9 100644 (file)
@@ -213,7 +213,6 @@ static int ccm_init(void *vctx, const unsigned char *key, size_t keylen,
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
             return 0;
         }
-
         memcpy(ctx->iv, iv, ivlen);
         ctx->iv_set = 1;
     }
@@ -420,7 +419,3 @@ void ccm_initctx(PROV_CCM_CTX *ctx, size_t keybits, const PROV_CCM_HW *hw)
     ctx->hw = hw;
 }
 
-void ccm_finalctx(PROV_CCM_CTX *ctx)
-{
-    OPENSSL_cleanse(ctx->iv, sizeof(ctx->iv));
-}
index bc8776d..2577d94 100644 (file)
@@ -109,11 +109,8 @@ static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx,
     ctx->enc = enc ? 1 : 0;
 
     if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) {
-        if (ivlen != ctx->ivlen) {
-            ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
+        if (!cipher_generic_initiv(ctx, iv, ivlen))
             return 0;
-        }
-        memcpy(ctx->iv, iv, ctx->ivlen);
     }
     if (key != NULL) {
         if ((ctx->flags & EVP_CIPH_VARIABLE_LENGTH) == 0) {
@@ -322,8 +319,8 @@ int cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[])
     }
     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
     if (p != NULL
-        && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)
-        && !OSSL_PARAM_set_octet_string(p, &ctx->iv, ctx->ivlen)) {
+        && !OSSL_PARAM_set_octet_ptr(p, &ctx->oiv, ctx->ivlen)
+        && !OSSL_PARAM_set_octet_string(p, &ctx->oiv, ctx->ivlen)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
@@ -337,7 +334,6 @@ int cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[])
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
-
     return 1;
 }
 
@@ -379,6 +375,20 @@ int cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[])
     return 1;
 }
 
+int cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,
+                          size_t ivlen)
+{
+    if (ivlen != ctx->ivlen
+        || ivlen > sizeof(ctx->iv)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
+        return 0;
+    }
+    ctx->iv_set = 1;
+    memcpy(ctx->iv, iv, ivlen);
+    memcpy(ctx->oiv, iv, ivlen);
+    return 1;
+}
+
 void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
                             size_t ivbits, unsigned int mode, uint64_t flags,
                             const PROV_CIPHER_HW *hw, void *provctx)
index 137ad50..59368dc 100644 (file)
@@ -38,11 +38,6 @@ void gcm_initctx(void *provctx, PROV_GCM_CTX *ctx, size_t keybits,
     ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
 }
 
-void gcm_deinitctx(PROV_GCM_CTX *ctx)
-{
-    OPENSSL_cleanse(ctx->iv, sizeof(ctx->iv));
-}
-
 static int gcm_init(void *vctx, const unsigned char *key, size_t keylen,
                     const unsigned char *iv, size_t ivlen, int enc)
 {
@@ -56,7 +51,7 @@ static int gcm_init(void *vctx, const unsigned char *key, size_t keylen,
             return 0;
         }
         ctx->ivlen = ivlen;
-        memcpy(ctx->iv, iv, ctx->ivlen);
+        memcpy(ctx->iv, iv, ivlen);
         ctx->iv_state = IV_STATE_BUFFERED;
     }
 
index 004ebc7..e5fa163 100644 (file)
@@ -26,7 +26,7 @@ void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
 
 void tdes_freectx(void *vctx)
 {
-    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
+    PROV_TDES_CTX *ctx = (PROV_TDES_CTX *)vctx;
 
     OPENSSL_clear_free(ctx,  sizeof(*ctx));
 }
@@ -39,11 +39,8 @@ static int tdes_init(void *vctx, const unsigned char *key, size_t keylen,
     ctx->enc = enc;
 
     if (iv != NULL) {
-        if (ivlen != TDES_IVLEN) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
+        if (!cipher_generic_initiv(ctx, iv, ivlen))
             return 0;
-        }
-        memcpy(ctx->iv, iv, TDES_IVLEN);
     }
 
     if (key != NULL) {
index 757c22e..2214b5f 100644 (file)
@@ -121,7 +121,6 @@ OSSL_OP_cipher_update_fn ccm_stream_update;
 OSSL_OP_cipher_final_fn ccm_stream_final;
 OSSL_OP_cipher_cipher_fn ccm_cipher;
 void ccm_initctx(PROV_CCM_CTX *ctx, size_t keybits, const PROV_CCM_HW *hw);
-void ccm_finalctx(PROV_CCM_CTX *ctx);
 
 int ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce,
                       size_t nlen, size_t mlen);
index f4e2894..711b40c 100644 (file)
@@ -139,7 +139,6 @@ OSSL_OP_cipher_set_ctx_params_fn gcm_set_ctx_params;
 OSSL_OP_cipher_cipher_fn gcm_cipher;
 OSSL_OP_cipher_update_fn gcm_stream_update;
 OSSL_OP_cipher_final_fn gcm_stream_final;
-void gcm_deinitctx(PROV_GCM_CTX *ctx);
 void gcm_initctx(void *provctx, PROV_GCM_CTX *ctx, size_t keybits,
                  const PROV_GCM_HW *hw, size_t ivlen_min);
 
index e30af4d..21511a1 100644 (file)
@@ -40,12 +40,13 @@ struct prov_cipher_ctx_st {
     } stream;
 
     unsigned int mode;
-    size_t keylen;        /* key size (in bytes) */
+    size_t keylen;           /* key size (in bytes) */
     size_t ivlen;
     size_t blocksize;
-    size_t bufsz;         /* Number of bytes in buf */
-    unsigned int pad : 1; /* Whether padding should be used or not */
-    unsigned int enc : 1; /* Set to 1 for encrypt, or 0 otherwise */
+    size_t bufsz;            /* Number of bytes in buf */
+    unsigned int pad : 1;    /* Whether padding should be used or not */
+    unsigned int enc : 1;    /* Set to 1 for encrypt, or 0 otherwise */
+    unsigned int iv_set : 1; /* Set when the iv is copied to the iv/oiv buffers */
 
     /*
      * num contains the number of bytes of |iv| which are valid for modes that
@@ -54,6 +55,8 @@ struct prov_cipher_ctx_st {
     unsigned int num;
     uint64_t flags;
 
+    /* The original value of the iv */
+    unsigned char oiv[GENERIC_BLOCK_SIZE];
     /* Buffer of partial blocks processed via update calls */
     unsigned char buf[GENERIC_BLOCK_SIZE];
     unsigned char iv[GENERIC_BLOCK_SIZE];
@@ -254,6 +257,9 @@ const OSSL_PARAM * name##_settable_ctx_params(void)                            \
     return name##_known_settable_ctx_params;                                   \
 }
 
+int cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,
+                          size_t ivlen);
+
 size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
                  const unsigned char **in, size_t *inlen);
 int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
index 93df4a5..95c0658 100644 (file)
@@ -107,7 +107,8 @@ static int aes_ocb_init(void *vctx, const unsigned char *key, size_t keylen,
            }
            ctx->base.ivlen = ivlen;
        }
-       memcpy(ctx->base.iv, iv, ivlen);
+       if (!cipher_generic_initiv(&ctx->base, iv, ivlen))
+           return 0;
        ctx->iv_state = IV_STATE_BUFFERED;
    }
    if (key != NULL) {
@@ -287,7 +288,6 @@ static void aes_ocb_freectx(void *vctx)
 
     if (ctx != NULL) {
         aes_generic_ocb_cleanup(ctx);
-        OPENSSL_cleanse(ctx->base.iv, sizeof(ctx->base.iv));
         OPENSSL_clear_free(ctx,  sizeof(*ctx));
     }
 }
@@ -388,7 +388,7 @@ static int aes_ocb_get_ctx_params(void *vctx, OSSL_PARAM params[])
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
             return 0;
         }
-        if (!OSSL_PARAM_set_octet_string(p, ctx->base.iv, ctx->base.ivlen)) {
+        if (!OSSL_PARAM_set_octet_string(p, ctx->base.oiv, ctx->base.ivlen)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
             return 0;
         }
index 53b3def..97e8137 100644 (file)
@@ -27,7 +27,6 @@ static void aria_ccm_freectx(void *vctx)
 {
     PROV_ARIA_CCM_CTX *ctx = (PROV_ARIA_CCM_CTX *)vctx;
 
-    ccm_finalctx((PROV_CCM_CTX *)ctx);
     OPENSSL_clear_free(ctx,  sizeof(*ctx));
 }
 
index 213fc14..7c9fa3d 100644 (file)
@@ -26,7 +26,6 @@ static void aria_gcm_freectx(void *vctx)
 {
     PROV_ARIA_GCM_CTX *ctx = (PROV_ARIA_GCM_CTX *)vctx;
 
-    gcm_deinitctx((PROV_GCM_CTX *)ctx);
     OPENSSL_clear_free(ctx,  sizeof(*ctx));
 }
 
index c4eb10b..4530114 100644 (file)
@@ -36,7 +36,7 @@ static void *des_newctx(void *provctx, size_t kbits, size_t blkbits,
 
 static void des_freectx(void *vctx)
 {
-    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
+    PROV_DES_CTX *ctx = (PROV_DES_CTX *)vctx;
 
     OPENSSL_clear_free(ctx,  sizeof(*ctx));
 }
@@ -49,11 +49,8 @@ static int des_init(void *vctx, const unsigned char *key, size_t keylen,
     ctx->enc = enc;
 
     if (iv != NULL) {
-        if (ivlen != ctx->ivlen) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
+        if (!cipher_generic_initiv(ctx, iv, ivlen))
             return 0;
-        }
-        memcpy(ctx->iv, iv, ivlen);
     }
 
     if (key != NULL) {