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 046a9f60af86d6f26b531cf305ea7eb99840a8d7..2a22336a364d64d76fe0050efae0589f3f03d08b 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 3abea33d1969f327d7f70b496117a74c778a984e..3a3eec615fc4527ecf56971f48271a9c70026a7a 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 c8015898dd1d23c7c4efba0f3a46868a3173cb5c..cffca06c80c6f5bdf5aeb754c28d7a39366e5532 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 ba03bed59078b7813ace5adb322ef134b4db5314..ef015bff21544ea5b6cef44ff2a869e945fd0d06 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 70f387f515e6670a2fe4a3f2064195258bc784a4..1bf4c1793a0898f77717cd5574bc423581a19eab 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 f114793ba8aa405470010b944c0fa4bde2710c63..fdda733d24124906ed59002c2ad9ba943d0dafb5 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 daad274328ab244fc5b4549f3bc1d39df85563f2..4f8a8f874f27795980440e3739fb0ba7c1c886a5 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 cc37b49c608e985573eec7164c73e0d1dc801ded..3fbaef9a466fcc5306a7fa57ac5016645a1a2a67 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 bc8776d87473f1dd8d2389cb1360d143c258c81e..2577d94d7a86a37d40a37d4f2006544b3691b40f 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 137ad5029c53daf402598172651744351615ac0e..59368dc81e513fbd3fe3dfc7bacb2eba7d11ddf3 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 004ebc72690f3ce377f7c495f506912eaf74c16d..e5fa16358ce11955f77c5d8ff65a1d062510d77d 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 757c22eb53629aa8a806e77621428fe64380e11a..2214b5fc647f5f3c90a5fb2ca682f1c0ea21d157 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 f4e2894fe2a0e6532965497485aeeeb403a1181c..711b40cdd4bcd0c874f11f543b3a7734ac8e69a0 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 e30af4dfbf86720ebbdd5b81acc627c6a651e7fd..21511a163c42ad7044bdca5b51495b23d4434e2e 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 93df4a5dbc75542b9b5d5df47316a07e476c4e76..95c0658fee88fe6f6b97b87637ff2f4d9fa466ac 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 53b3defa9d670aead4e51c4c21ca4d9376890fc8..97e8137db8423b6d4dfc988606fb72691adab0e7 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 213fc147c8c0207f4404b82e05edcc4853f06852..7c9fa3d211fc56336bd2d8576dc5fab210505e52 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 c4eb10be153fca2a1c4aec4acccf9992a85eef22..4530114187a6979be86409f2e5b1f40b9c80d95d 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) {