Fix EVP_DigestSign interface when used with DES CMAC
authorPatrick Steuer <patrick.steuer@de.ibm.com>
Thu, 9 Apr 2020 17:58:02 +0000 (19:58 +0200)
committerPatrick Steuer <patrick.steuer@de.ibm.com>
Fri, 10 Apr 2020 22:31:57 +0000 (00:31 +0200)
DES implementations were missing the dup/copy ctx routines
required by CMAC implementation. A regression test is added.

Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11498)

providers/implementations/ciphers/cipher_des.c
providers/implementations/ciphers/cipher_des_hw.c
providers/implementations/ciphers/cipher_desx_hw.c
providers/implementations/ciphers/cipher_tdes.h
providers/implementations/ciphers/cipher_tdes_common.c
providers/implementations/ciphers/cipher_tdes_hw.c
test/recipes/30-test_evp_data/evpmac.txt

index d0547b7..c1454fb 100644 (file)
@@ -40,6 +40,20 @@ static void *des_newctx(void *provctx, size_t kbits, size_t blkbits,
     return ctx;
 }
 
+static void *des_dupctx(void *ctx)
+{
+    PROV_DES_CTX *in = (PROV_DES_CTX *)ctx;
+    PROV_DES_CTX *ret = OPENSSL_malloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    in->base.hw->copyctx(&ret->base, &in->base);
+
+    return ret;
+}
+
 static void des_freectx(void *vctx)
 {
     PROV_DES_CTX *ctx = (PROV_DES_CTX *)vctx;
@@ -137,6 +151,7 @@ const OSSL_DISPATCH des_##lcmode##_functions[] = {                             \
     { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher },        \
     { OSSL_FUNC_CIPHER_NEWCTX,                                                 \
       (void (*)(void))des_##lcmode##_newctx },                                 \
+    { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))des_dupctx },                   \
     { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))des_freectx },                 \
     { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
       (void (*)(void))des_##lcmode##_get_params },                             \
index c465c42..a1572af 100644 (file)
@@ -38,6 +38,16 @@ static int cipher_hw_des_initkey(PROV_CIPHER_CTX *ctx,
     return 1;
 }
 
+static void cipher_hw_des_copyctx(PROV_CIPHER_CTX *dst,
+                                  const PROV_CIPHER_CTX *src)
+{
+    PROV_DES_CTX *sctx = (PROV_DES_CTX *)src;
+    PROV_DES_CTX *dctx = (PROV_DES_CTX *)dst;
+
+    *dctx = *sctx;
+    dst->ks = &dctx->dks.ks;
+}
+
 static int cipher_hw_des_ecb_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
                                     const unsigned char *in, size_t len)
 {
@@ -164,7 +174,8 @@ static int cipher_hw_des_cfb8_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out,
 #define PROV_CIPHER_HW_des_mode(mode)                                          \
 static const PROV_CIPHER_HW des_##mode = {                                     \
     cipher_hw_des_initkey,                                                     \
-    cipher_hw_des_##mode##_cipher                                              \
+    cipher_hw_des_##mode##_cipher,                                             \
+    cipher_hw_des_copyctx                                                      \
 };                                                                             \
 const PROV_CIPHER_HW *PROV_CIPHER_HW_des_##mode(void)                          \
 {                                                                              \
index afc01b8..b2c3e17 100644 (file)
@@ -37,6 +37,16 @@ static int cipher_hw_desx_cbc_initkey(PROV_CIPHER_CTX *ctx,
     return 1;
 }
 
+static void cipher_hw_desx_copyctx(PROV_CIPHER_CTX *dst,
+                                   const PROV_CIPHER_CTX *src)
+{
+    PROV_TDES_CTX *sctx = (PROV_TDES_CTX *)src;
+    PROV_TDES_CTX *dctx = (PROV_TDES_CTX *)dst;
+
+    *dctx = *sctx;
+    dst->ks = &dctx->tks.ks;
+}
+
 static int cipher_hw_desx_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
                               const unsigned char *in, size_t inl)
 {
@@ -60,7 +70,8 @@ static int cipher_hw_desx_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
 static const PROV_CIPHER_HW desx_cbc =
 {
     cipher_hw_desx_cbc_initkey,
-    cipher_hw_desx_cbc
+    cipher_hw_desx_cbc,
+    cipher_hw_desx_copyctx
 };
 const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_desx_cbc(void)
 {
index e1fb760..fb4217d 100644 (file)
@@ -30,7 +30,7 @@ typedef struct prov_tdes_ctx_st {
 
 } PROV_TDES_CTX;
 
-#define IMPLEMENT_tdes_cipher(type, UCTYPE, lcmode, UCMODE, flags,             \
+#define IMPLEMENT_tdes_cipher(type, UCTYPE, lcmode, UCMODE, flags,            \
                               kbits, blkbits, ivbits, block)                   \
 static OSSL_OP_cipher_newctx_fn tdes_##type##_##lcmode##_newctx;               \
 static void *tdes_##type##_##lcmode##_newctx(void *provctx)                    \
@@ -53,6 +53,7 @@ const OSSL_DISPATCH tdes_##type##_##lcmode##_functions[] = {                   \
     { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher },        \
     { OSSL_FUNC_CIPHER_NEWCTX,                                                 \
       (void (*)(void))tdes_##type##_##lcmode##_newctx },                       \
+    { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))tdes_dupctx },                  \
     { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))tdes_freectx },                \
     { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
       (void (*)(void))tdes_##type##_##lcmode##_get_params },                   \
@@ -70,16 +71,18 @@ const OSSL_DISPATCH tdes_##type##_##lcmode##_functions[] = {                   \
 
 void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
                   size_t ivbits, uint64_t flags, const PROV_CIPHER_HW *hw);
+OSSL_OP_cipher_dupctx_fn tdes_dupctx;
 OSSL_OP_cipher_freectx_fn tdes_freectx;
 OSSL_OP_cipher_encrypt_init_fn tdes_einit;
 OSSL_OP_cipher_decrypt_init_fn tdes_dinit;
 OSSL_OP_cipher_get_ctx_params_fn tdes_get_ctx_params;
 OSSL_OP_cipher_gettable_ctx_params_fn tdes_gettable_ctx_params;
 
-#define PROV_CIPHER_HW_tdes_mode(type, mode)                                   \
+#define PROV_CIPHER_HW_tdes_mode(type, mode)                                  \
 static const PROV_CIPHER_HW type##_##mode = {                                  \
     cipher_hw_tdes_##type##_initkey,                                           \
-    cipher_hw_tdes_##mode                                                      \
+    cipher_hw_tdes_##mode,                                                     \
+    cipher_hw_tdes_copyctx                                                     \
 };                                                                             \
 const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_##type##_##mode(void)                \
 {                                                                              \
@@ -88,6 +91,7 @@ const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_##type##_##mode(void)                \
 
 int cipher_hw_tdes_ede3_initkey(PROV_CIPHER_CTX *ctx, const unsigned char *key,
                                 size_t keylen);
+void cipher_hw_tdes_copyctx(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src);
 int cipher_hw_tdes_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
                        const unsigned char *in, size_t inl);
 int cipher_hw_tdes_ecb(PROV_CIPHER_CTX *ctx, unsigned char *out,
index 36a8962..4e50450 100644 (file)
@@ -30,6 +30,20 @@ void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
     return tctx;
 }
 
+void *tdes_dupctx(void *ctx)
+{
+    PROV_TDES_CTX *in = (PROV_TDES_CTX *)ctx;
+    PROV_TDES_CTX *ret = OPENSSL_malloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    in->base.hw->copyctx(&ret->base, &in->base);
+
+    return ret;
+}
+
 void tdes_freectx(void *vctx)
 {
     PROV_TDES_CTX *ctx = (PROV_TDES_CTX *)vctx;
index c7fe393..2391b60 100644 (file)
@@ -45,6 +45,15 @@ int cipher_hw_tdes_ede3_initkey(PROV_CIPHER_CTX *ctx, const unsigned char *key,
     return 1;
 }
 
+void cipher_hw_tdes_copyctx(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src)
+{
+    PROV_TDES_CTX *sctx = (PROV_TDES_CTX *)src;
+    PROV_TDES_CTX *dctx = (PROV_TDES_CTX *)dst;
+
+    *dctx = *sctx;
+    dst->ks = &dctx->tks.ks;
+}
+
 int cipher_hw_tdes_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
                        const unsigned char *in, size_t inl)
 {
index 0b83cff..17c3220 100644 (file)
@@ -624,6 +624,11 @@ Key = 89BCD952A8C8AB371AF48AC7D07085D5EFF702E6D62CDC23
 Input = FA620C1BBE97319E9A0CF0492121F7A20EB08A6A709DCBD00AAF38E4F99E754E
 Output = 8F49A1B7D6AA2258
 
+MAC = CMAC by EVP_PKEY
+Algorithm = DES-EDE3-CBC
+Key = 89BCD952A8C8AB371AF48AC7D07085D5EFF702E6D62CDC23
+Input = FA620C1BBE97319E9A0CF0492121F7A20EB08A6A709DCBD00AAF38E4F99E754E
+Output = 8F49A1B7D6AA2258
 
 Title = GMAC Tests (from NIST)