From abfc73f374c2b80e15f6c9d0b3a7437b3e94afa8 Mon Sep 17 00:00:00 2001 From: Patrick Steuer Date: Thu, 9 Apr 2020 19:58:02 +0200 Subject: [PATCH] Fix EVP_DigestSign interface when used with DES CMAC DES implementations were missing the dup/copy ctx routines required by CMAC implementation. A regression test is added. Signed-off-by: Patrick Steuer Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/11498) --- providers/implementations/ciphers/cipher_des.c | 15 +++++++++++++++ providers/implementations/ciphers/cipher_des_hw.c | 13 ++++++++++++- .../implementations/ciphers/cipher_desx_hw.c | 13 ++++++++++++- providers/implementations/ciphers/cipher_tdes.h | 10 +++++++--- .../implementations/ciphers/cipher_tdes_common.c | 14 ++++++++++++++ .../implementations/ciphers/cipher_tdes_hw.c | 9 +++++++++ test/recipes/30-test_evp_data/evpmac.txt | 5 +++++ 7 files changed, 74 insertions(+), 5 deletions(-) diff --git a/providers/implementations/ciphers/cipher_des.c b/providers/implementations/ciphers/cipher_des.c index d0547b7060..c1454fb46e 100644 --- a/providers/implementations/ciphers/cipher_des.c +++ b/providers/implementations/ciphers/cipher_des.c @@ -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 }, \ diff --git a/providers/implementations/ciphers/cipher_des_hw.c b/providers/implementations/ciphers/cipher_des_hw.c index c465c42391..a1572af1c1 100644 --- a/providers/implementations/ciphers/cipher_des_hw.c +++ b/providers/implementations/ciphers/cipher_des_hw.c @@ -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) \ { \ diff --git a/providers/implementations/ciphers/cipher_desx_hw.c b/providers/implementations/ciphers/cipher_desx_hw.c index afc01b8659..b2c3e1732c 100644 --- a/providers/implementations/ciphers/cipher_desx_hw.c +++ b/providers/implementations/ciphers/cipher_desx_hw.c @@ -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) { diff --git a/providers/implementations/ciphers/cipher_tdes.h b/providers/implementations/ciphers/cipher_tdes.h index e1fb760e23..fb4217d5b6 100644 --- a/providers/implementations/ciphers/cipher_tdes.h +++ b/providers/implementations/ciphers/cipher_tdes.h @@ -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, diff --git a/providers/implementations/ciphers/cipher_tdes_common.c b/providers/implementations/ciphers/cipher_tdes_common.c index 36a8962e03..4e50450e4d 100644 --- a/providers/implementations/ciphers/cipher_tdes_common.c +++ b/providers/implementations/ciphers/cipher_tdes_common.c @@ -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; diff --git a/providers/implementations/ciphers/cipher_tdes_hw.c b/providers/implementations/ciphers/cipher_tdes_hw.c index c7fe393653..2391b60e57 100644 --- a/providers/implementations/ciphers/cipher_tdes_hw.c +++ b/providers/implementations/ciphers/cipher_tdes_hw.c @@ -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) { diff --git a/test/recipes/30-test_evp_data/evpmac.txt b/test/recipes/30-test_evp_data/evpmac.txt index 0b83cff36c..17c3220d6c 100644 --- a/test/recipes/30-test_evp_data/evpmac.txt +++ b/test/recipes/30-test_evp_data/evpmac.txt @@ -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)