From 4a42e2640499ce46d2733c4316c5fe4594a37c54 Mon Sep 17 00:00:00 2001 From: Shane Lontis Date: Mon, 26 Aug 2019 17:05:08 +1000 Subject: [PATCH] Cleanup ciphers and Add 3des ciphers. Moved the relevant ciphers into default and restructed headers to allow the move. This removed most of the cases of #ifdef NO_XXX (which are now specified in build.info) Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/9482) --- crypto/des/build.info | 9 +- crypto/err/openssl.txt | 1 + crypto/evp/evp_enc.c | 39 +++- crypto/include/internal/ciphermode_platform.h | 7 + doc/man7/provider-cipher.pod | 6 + include/openssl/core_names.h | 1 + providers/common/ciphers/block.c | 1 + providers/common/ciphers/build.info | 23 +- providers/common/ciphers/cipher_aes.c | 3 +- providers/common/ciphers/cipher_aes.h | 1 + providers/common/ciphers/cipher_aes_ccm.c | 2 + providers/common/ciphers/cipher_aes_ccm_hw.c | 64 ++++++ .../ciphers/cipher_aes_ccm_hw_aesni.inc | 5 +- .../common/ciphers/cipher_aes_ccm_hw_t4.inc | 2 +- providers/common/ciphers/cipher_aes_gcm.c | 2 + providers/common/ciphers/cipher_aes_gcm_hw.c | 78 +++++++ .../ciphers/cipher_aes_gcm_hw_aesni.inc | 5 +- .../common/ciphers/cipher_aes_gcm_hw_t4.inc | 2 +- providers/common/ciphers/cipher_aes_hw.c | 3 +- providers/common/ciphers/cipher_ccm.c | 2 + providers/common/ciphers/cipher_ccm_hw.c | 76 ++----- providers/common/ciphers/cipher_common.c | 84 ++++---- providers/common/ciphers/cipher_common_hw.c | 3 - providers/common/ciphers/cipher_gcm.c | 2 + providers/common/ciphers/cipher_gcm_hw.c | 101 +-------- providers/common/ciphers/cipher_locl.h | 190 ++--------------- providers/common/ciphers/cipher_tdes.c | 116 ++++++++++ providers/common/ciphers/cipher_tdes_hw.c | 82 ++++++++ .../include/internal/ciphers/cipher_aead.h | 49 +++++ .../internal}/ciphers/cipher_ccm.h | 27 ++- .../internal}/ciphers/cipher_gcm.h | 38 ++-- .../include/internal/ciphers/cipher_tdes.h | 96 +++++++++ .../include/internal/ciphers/ciphercommon.h | 149 +++++++++++++ .../common/include/internal/provider_algs.h | 18 ++ .../include/internal/providercommonerr.h | 3 +- providers/common/provider_err.c | 2 + providers/default/build.info | 2 +- providers/default/ciphers/build.info | 22 ++ .../{common => default}/ciphers/cipher_aria.c | 3 +- .../{common => default}/ciphers/cipher_aria.h | 7 +- .../ciphers/cipher_aria_ccm.c | 6 +- providers/default/ciphers/cipher_aria_ccm.h | 22 ++ .../ciphers/cipher_aria_ccm_hw.c} | 4 +- .../ciphers/cipher_aria_gcm.c | 3 +- providers/default/ciphers/cipher_aria_gcm.h | 22 ++ .../ciphers/cipher_aria_gcm_hw.c} | 7 +- .../ciphers/cipher_aria_hw.c | 2 +- .../ciphers/cipher_camellia.c | 5 +- .../ciphers/cipher_camellia.h | 11 +- .../ciphers/cipher_camellia_hw.c | 5 +- .../ciphers/cipher_camellia_hw_t4.inc | 0 providers/default/ciphers/cipher_desx.c | 15 ++ providers/default/ciphers/cipher_desx_hw.c | 62 ++++++ .../default/ciphers/cipher_tdes_default.c | 29 +++ .../default/ciphers/cipher_tdes_default.h | 25 +++ .../default/ciphers/cipher_tdes_default_hw.c | 140 ++++++++++++ providers/default/ciphers/cipher_tdes_wrap.c | 199 ++++++++++++++++++ .../default/ciphers/cipher_tdes_wrap_hw.c | 14 ++ providers/default/defltprov.c | 12 ++ providers/fips/fipsprov.c | 2 + test/recipes/30-test_evp_data/evpciph.txt | 10 + 61 files changed, 1441 insertions(+), 480 deletions(-) create mode 100644 providers/common/ciphers/cipher_aes_ccm_hw.c create mode 100644 providers/common/ciphers/cipher_aes_gcm_hw.c create mode 100644 providers/common/ciphers/cipher_tdes.c create mode 100644 providers/common/ciphers/cipher_tdes_hw.c create mode 100644 providers/common/include/internal/ciphers/cipher_aead.h rename providers/common/{ => include/internal}/ciphers/cipher_ccm.h (87%) rename providers/common/{ => include/internal}/ciphers/cipher_gcm.h (83%) create mode 100644 providers/common/include/internal/ciphers/cipher_tdes.h create mode 100644 providers/common/include/internal/ciphers/ciphercommon.h create mode 100644 providers/default/ciphers/build.info rename providers/{common => default}/ciphers/cipher_aria.c (97%) rename providers/{common => default}/ciphers/cipher_aria.h (92%) rename providers/{common => default}/ciphers/cipher_aria_ccm.c (94%) create mode 100644 providers/default/ciphers/cipher_aria_ccm.h rename providers/{common/ciphers/cipher_aria_ccm_hw.inc => default/ciphers/cipher_aria_ccm_hw.c} (89%) rename providers/{common => default}/ciphers/cipher_aria_gcm.c (94%) create mode 100644 providers/default/ciphers/cipher_aria_gcm.h rename providers/{common/ciphers/cipher_aria_gcm_hw.inc => default/ciphers/cipher_aria_gcm_hw.c} (84%) rename providers/{common => default}/ciphers/cipher_aria_hw.c (98%) rename providers/{common => default}/ciphers/cipher_camellia.c (97%) rename providers/{common => default}/ciphers/cipher_camellia.h (81%) rename providers/{common => default}/ciphers/cipher_camellia_hw.c (96%) rename providers/{common => default}/ciphers/cipher_camellia_hw_t4.inc (100%) create mode 100644 providers/default/ciphers/cipher_desx.c create mode 100644 providers/default/ciphers/cipher_desx_hw.c create mode 100644 providers/default/ciphers/cipher_tdes_default.c create mode 100644 providers/default/ciphers/cipher_tdes_default.h create mode 100644 providers/default/ciphers/cipher_tdes_default_hw.c create mode 100644 providers/default/ciphers/cipher_tdes_wrap.c create mode 100644 providers/default/ciphers/cipher_tdes_wrap_hw.c diff --git a/crypto/des/build.info b/crypto/des/build.info index 474d14e229..33dd90c89a 100644 --- a/crypto/des/build.info +++ b/crypto/des/build.info @@ -13,13 +13,14 @@ IF[{- !$disabled{asm} -}] ENDIF LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - set_key.c ecb_enc.c cbc_enc.c \ - ecb3_enc.c cfb64enc.c cfb64ede.c cfb_enc.c \ +$COMMON=set_key.c ecb3_enc.c $DESASM +SOURCE[../../libcrypto]=$COMMON\ + ecb_enc.c cbc_enc.c \ + cfb64enc.c cfb64ede.c cfb_enc.c \ ofb64ede.c ofb64enc.c ofb_enc.c \ str2key.c pcbc_enc.c qud_cksm.c rand_key.c \ - $DESASM \ fcrypt.c xcbc_enc.c cbc_cksm.c +SOURCE[../../providers/fips]=$COMMON GENERATE[des_enc-sparc.S]=asm/des_enc.m4 GENERATE[dest4-sparcv9.S]=asm/dest4-sparcv9.pl $(PERLASM_SCHEME) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index a545636447..58f6c4894f 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2708,6 +2708,7 @@ PROP_R_TRAILING_CHARACTERS:110:trailing characters PROV_R_AES_KEY_SETUP_FAILED:101:aes key setup failed PROV_R_BAD_DECRYPT:100:bad decrypt PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed +PROV_R_FAILED_TO_GENERATE_KEY:121:failed to generate key PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter PROV_R_INVALID_AAD:108:invalid aad diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index e67e20c7ba..5723fe888e 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -217,6 +217,18 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, case NID_camellia_256_ctr: case NID_camellia_192_ctr: case NID_camellia_128_ctr: + case NID_des_ede3_cbc: + case NID_des_ede3_ecb: + case NID_des_ede3_ofb64: + case NID_des_ede3_cfb64: + case NID_des_ede3_cfb8: + case NID_des_ede3_cfb1: + case NID_des_ede_cbc: + case NID_des_ede_ecb: + case NID_des_ede_ofb64: + case NID_des_ede_cfb64: + case NID_desx_cbc: + case NID_id_smime_alg_CMS3DESwrap: break; default: goto legacy; @@ -1030,6 +1042,12 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) params[0] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_KEYLEN, &arg); break; case EVP_CTRL_RAND_KEY: /* Used by DES */ + set_params = 0; + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, + ptr, (size_t)arg); + break; + case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS: /* Used by DASYNC */ case EVP_CTRL_INIT: /* TODO(3.0) Purely legacy, no provider counterpart */ default: @@ -1141,19 +1159,24 @@ const OSSL_PARAM *EVP_CIPHER_CTX_gettable_params(const EVP_CIPHER *cipher) return NULL; } -#if !defined(FIPS_MODE) -/* TODO(3.0): No support for RAND yet in the FIPS module */ int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) { - int kl; if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); - kl = EVP_CIPHER_CTX_key_length(ctx); - if (kl <= 0 || RAND_priv_bytes(key, kl) <= 0) - return 0; - return 1; + +#ifdef FIPS_MODE + return 0; +#else + { + int kl; + + kl = EVP_CIPHER_CTX_key_length(ctx); + if (kl <= 0 || RAND_priv_bytes(key, kl) <= 0) + return 0; + return 1; + } +#endif /* FIPS_MODE */ } -#endif int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { diff --git a/crypto/include/internal/ciphermode_platform.h b/crypto/include/internal/ciphermode_platform.h index 934d8136d3..5db2e23eb9 100644 --- a/crypto/include/internal/ciphermode_platform.h +++ b/crypto/include/internal/ciphermode_platform.h @@ -223,6 +223,7 @@ void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, # define SPARC_AES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_AES) +# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES) # define HWAES_CAPABLE (OPENSSL_sparcv9cap_P[0] & SPARCV9_FJAESX) # define HWAES_set_encrypt_key aes_fx_set_encrypt_key # define HWAES_set_decrypt_key aes_fx_set_decrypt_key @@ -237,6 +238,12 @@ void aes_t4_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); void aes_t4_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); +void des_t4_key_expand(const void *key, DES_key_schedule *ks); +void des_t4_ede3_cbc_encrypt(const void *inp, void *out, size_t len, + const DES_key_schedule ks[3], unsigned char iv[8]); +void des_t4_ede3_cbc_decrypt(const void *inp, void *out, size_t len, + const DES_key_schedule ks[3], unsigned char iv[8]); + /* * Key-length specific subroutines were chosen for following reason. * Each SPARC T4 core can execute up to 8 threads which share core's diff --git a/doc/man7/provider-cipher.pod b/doc/man7/provider-cipher.pod index 2e2e73b68b..040a34c126 100644 --- a/doc/man7/provider-cipher.pod +++ b/doc/man7/provider-cipher.pod @@ -302,6 +302,12 @@ IV length and the tag length. Sets the IV length to be used for an AEAD cipher for the associated cipher ctx. +=item B (octet_string) + +Gets a implementation specific randomly generated key for the associated +cipher ctx. This is currently only supported by 3DES (which sets the key to +odd parity). + =back =head1 RETURN VALUES diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h index 11232cb177..448bc50e8a 100644 --- a/include/openssl/core_names.h +++ b/include/openssl/core_names.h @@ -54,6 +54,7 @@ extern "C" { #define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD "tlsaadpad" /* size_t */ #define OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED "tlsivfixed" /* octet_string */ #define OSSL_CIPHER_PARAM_AEAD_IVLEN "aeadivlen" /* size_t */ +#define OSSL_CIPHER_PARAM_RANDOM_KEY "randkey" /* octet_string */ /* digest parameters */ #define OSSL_DIGEST_PARAM_XOFLEN "xoflen" diff --git a/providers/common/ciphers/block.c b/providers/common/ciphers/block.c index 73e17e1a11..a53e9255c9 100644 --- a/providers/common/ciphers/block.c +++ b/providers/common/ciphers/block.c @@ -9,6 +9,7 @@ #include #include "cipher_locl.h" +#include "internal/providercommonerr.h" /* * Fills a single block of buffered data from the input, and returns the amount diff --git a/providers/common/ciphers/build.info b/providers/common/ciphers/build.info index 4a816d0f4d..0302cf151e 100644 --- a/providers/common/ciphers/build.info +++ b/providers/common/ciphers/build.info @@ -1,21 +1,18 @@ LIBS=../../../libcrypto +IF[{- !$disabled{des} -}] + $COMMON_DES=cipher_tdes.c cipher_tdes_hw.c +ENDIF + $COMMON=cipher_common.c cipher_common_hw.c block.c \ cipher_aes.c cipher_aes_hw.c \ - cipher_gcm.c cipher_aes_gcm.c cipher_gcm_hw.c \ - cipher_ccm.c cipher_aes_ccm.c cipher_ccm_hw.c - + cipher_gcm.c cipher_gcm_hw.c \ + cipher_aes_gcm.c cipher_aes_gcm_hw.c \ + cipher_ccm.c cipher_ccm_hw.c \ + cipher_aes_ccm.c cipher_aes_ccm_hw.c \ + $COMMON_DES + SOURCE[../../../libcrypto]=$COMMON -IF[{- !$disabled{aria} -}] - SOURCE[../../../libcrypto]=\ - cipher_aria.c cipher_aria_hw.c \ - cipher_aria_gcm.c cipher_aria_ccm.c -ENDIF - -IF[{- !$disabled{camellia} -}] - SOURCE[../../../libcrypto]=\ - cipher_camellia.c cipher_camellia_hw.c -ENDIF INCLUDE[../../../libcrypto]=. ../../../crypto SOURCE[../../fips]=$COMMON diff --git a/providers/common/ciphers/cipher_aes.c b/providers/common/ciphers/cipher_aes.c index 15433bf326..46880e0bf7 100644 --- a/providers/common/ciphers/cipher_aes.c +++ b/providers/common/ciphers/cipher_aes.c @@ -9,7 +9,8 @@ /* Dispatch functions for AES cipher modes ecb, cbc, ofb, cfb, ctr */ -#include "cipher_locl.h" +#include "cipher_aes.h" +#include "internal/provider_algs.h" static OSSL_OP_cipher_freectx_fn aes_freectx; static OSSL_OP_cipher_dupctx_fn aes_dupctx; diff --git a/providers/common/ciphers/cipher_aes.h b/providers/common/ciphers/cipher_aes.h index 6c4a6237c0..741b20f6e3 100644 --- a/providers/common/ciphers/cipher_aes.h +++ b/providers/common/ciphers/cipher_aes.h @@ -8,6 +8,7 @@ */ #include +#include "internal/ciphers/ciphercommon.h" typedef struct prov_aes_ctx_st { PROV_CIPHER_CTX base; /* Must be first */ diff --git a/providers/common/ciphers/cipher_aes_ccm.c b/providers/common/ciphers/cipher_aes_ccm.c index 26b508df29..75f6e3fc9d 100644 --- a/providers/common/ciphers/cipher_aes_ccm.c +++ b/providers/common/ciphers/cipher_aes_ccm.c @@ -10,6 +10,8 @@ /* Dispatch functions for AES CCM mode */ #include "cipher_locl.h" +#include "internal/ciphers/cipher_ccm.h" +#include "internal/provider_algs.h" static void *aes_ccm_newctx(void *provctx, size_t keybits) { diff --git a/providers/common/ciphers/cipher_aes_ccm_hw.c b/providers/common/ciphers/cipher_aes_ccm_hw.c new file mode 100644 index 0000000000..f445cb73b7 --- /dev/null +++ b/providers/common/ciphers/cipher_aes_ccm_hw.c @@ -0,0 +1,64 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* AES CCM mode */ + +#include "cipher_locl.h" +#include "internal/ciphers/cipher_ccm.h" + +#define AES_HW_CCM_SET_KEY_FN(fn_set_enc_key, fn_blk, fn_ccm_enc, fn_ccm_dec) \ + fn_set_enc_key(key, keylen * 8, &actx->ccm.ks.ks); \ + CRYPTO_ccm128_init(&ctx->ccm_ctx, ctx->m, ctx->l, &actx->ccm.ks.ks, \ + (block128_f)fn_blk); \ + ctx->str = ctx->enc ? (ccm128_f)fn_ccm_enc : (ccm128_f)fn_ccm_dec; \ + ctx->key_set = 1; + +static int ccm_generic_aes_initkey(PROV_CCM_CTX *ctx, const unsigned char *key, + size_t keylen) +{ + PROV_AES_CCM_CTX *actx = (PROV_AES_CCM_CTX *)ctx; + +#ifdef HWAES_CAPABLE + if (HWAES_CAPABLE) { + AES_HW_CCM_SET_KEY_FN(HWAES_set_encrypt_key, HWAES_encrypt, NULL, NULL); + } else +#endif /* HWAES_CAPABLE */ + +#ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + AES_HW_CCM_SET_KEY_FN(vpaes_set_encrypt_key, vpaes_encrypt, NULL, NULL); + } else +#endif + { + AES_HW_CCM_SET_KEY_FN(AES_set_encrypt_key, AES_encrypt, NULL, NULL) + } + return 1; +} + +static const PROV_CCM_HW aes_ccm = { + ccm_generic_aes_initkey, + ccm_generic_setiv, + ccm_generic_setaad, + ccm_generic_auth_encrypt, + ccm_generic_auth_decrypt, + ccm_generic_gettag +}; + +#if defined(S390X_aes_128_CAPABLE) +# include "cipher_aes_ccm_hw_s390x.inc" +#elif defined(AESNI_CAPABLE) +# include "cipher_aes_ccm_hw_aesni.inc" +#elif defined(SPARC_AES_CAPABLE) +# include "cipher_aes_ccm_hw_t4.inc" +#else +const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keybits) +{ + return &aes_ccm; +} +#endif diff --git a/providers/common/ciphers/cipher_aes_ccm_hw_aesni.inc b/providers/common/ciphers/cipher_aes_ccm_hw_aesni.inc index 0ace026a89..3a5e4a740d 100644 --- a/providers/common/ciphers/cipher_aes_ccm_hw_aesni.inc +++ b/providers/common/ciphers/cipher_aes_ccm_hw_aesni.inc @@ -17,8 +17,9 @@ static int ccm_aesni_initkey(PROV_CCM_CTX *ctx, const unsigned char *key, { PROV_AES_CCM_CTX *actx = (PROV_AES_CCM_CTX *)ctx; - AES_CCM_SET_KEY_FN(aesni_set_encrypt_key, aesni_encrypt, - aesni_ccm64_encrypt_blocks, aesni_ccm64_decrypt_blocks); + AES_HW_CCM_SET_KEY_FN(aesni_set_encrypt_key, aesni_encrypt, + aesni_ccm64_encrypt_blocks, + aesni_ccm64_decrypt_blocks); return 1; } diff --git a/providers/common/ciphers/cipher_aes_ccm_hw_t4.inc b/providers/common/ciphers/cipher_aes_ccm_hw_t4.inc index 0dc6efcef4..21bf6861e0 100644 --- a/providers/common/ciphers/cipher_aes_ccm_hw_t4.inc +++ b/providers/common/ciphers/cipher_aes_ccm_hw_t4.inc @@ -17,7 +17,7 @@ static int ccm_t4_aes_initkey(PROV_CCM_CTX *ctx, const unsigned char *key, { PROV_AES_CCM_CTX *actx = (PROV_AES_CCM_CTX *)ctx; - AES_CCM_SET_KEY_FN(aes_t4_set_encrypt_key, aes_t4_encrypt, NULL, NULL); + AES_HW_CCM_SET_KEY_FN(aes_t4_set_encrypt_key, aes_t4_encrypt, NULL, NULL); return 1; } diff --git a/providers/common/ciphers/cipher_aes_gcm.c b/providers/common/ciphers/cipher_aes_gcm.c index 60df02588f..69c98f4e13 100644 --- a/providers/common/ciphers/cipher_aes_gcm.c +++ b/providers/common/ciphers/cipher_aes_gcm.c @@ -10,6 +10,8 @@ /* Dispatch functions for AES GCM mode */ #include "cipher_locl.h" +#include "internal/ciphers/cipher_gcm.h" +#include "internal/provider_algs.h" static void *aes_gcm_newctx(void *provctx, size_t keybits) { diff --git a/providers/common/ciphers/cipher_aes_gcm_hw.c b/providers/common/ciphers/cipher_aes_gcm_hw.c new file mode 100644 index 0000000000..3f56e6861d --- /dev/null +++ b/providers/common/ciphers/cipher_aes_gcm_hw.c @@ -0,0 +1,78 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* Dispatch functions for AES GCM mode */ + +#include "cipher_locl.h" +#include "internal/ciphers/cipher_gcm.h" + +static int generic_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, + size_t keylen) +{ + PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx; + AES_KEY *ks = &actx->ks.ks; + +# ifdef HWAES_CAPABLE + if (HWAES_CAPABLE) { +# ifdef HWAES_ctr32_encrypt_blocks + GCM_HW_SET_KEY_CTR_FN(ks, HWAES_set_encrypt_key, HWAES_encrypt, + HWAES_ctr32_encrypt_blocks); +# else + GCM_HW_SET_KEY_CTR_FN(ks, HWAES_set_encrypt_key, HWAES_encrypt, NULL); +# endif /* HWAES_ctr32_encrypt_blocks */ + } else +# endif /* HWAES_CAPABLE */ + +# ifdef BSAES_CAPABLE + if (BSAES_CAPABLE) { + GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt, + bsaes_ctr32_encrypt_blocks); + } else +# endif /* BSAES_CAPABLE */ + +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + GCM_HW_SET_KEY_CTR_FN(ks, vpaes_set_encrypt_key, vpaes_encrypt, NULL); + } else +# endif /* VPAES_CAPABLE */ + + { +# ifdef AES_CTR_ASM + GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt, + AES_ctr32_encrypt); +# else + GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt, NULL); +# endif /* AES_CTR_ASM */ + } + ctx->key_set = 1; + return 1; +} + +static const PROV_GCM_HW aes_gcm = { + generic_aes_gcm_initkey, + gcm_setiv, + gcm_aad_update, + gcm_cipher_update, + gcm_cipher_final, + gcm_one_shot +}; + +#if defined(S390X_aes_128_CAPABLE) +# include "cipher_aes_gcm_hw_s390x.inc" +#elif defined(AESNI_CAPABLE) +# include "cipher_aes_gcm_hw_aesni.inc" +#elif defined(SPARC_AES_CAPABLE) +# include "cipher_aes_gcm_hw_t4.inc" +#else +const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits) +{ + return &aes_gcm; +} +#endif + diff --git a/providers/common/ciphers/cipher_aes_gcm_hw_aesni.inc b/providers/common/ciphers/cipher_aes_gcm_hw_aesni.inc index c0cb231ff4..eb2a3f343a 100644 --- a/providers/common/ciphers/cipher_aes_gcm_hw_aesni.inc +++ b/providers/common/ciphers/cipher_aes_gcm_hw_aesni.inc @@ -17,9 +17,8 @@ static int aesni_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, { PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx; AES_KEY *ks = &actx->ks.ks; - - SET_KEY_CTR_FN(ks, aesni_set_encrypt_key, aesni_encrypt, - aesni_ctr32_encrypt_blocks); + GCM_HW_SET_KEY_CTR_FN(ks, aesni_set_encrypt_key, aesni_encrypt, + aesni_ctr32_encrypt_blocks); return 1; } diff --git a/providers/common/ciphers/cipher_aes_gcm_hw_t4.inc b/providers/common/ciphers/cipher_aes_gcm_hw_t4.inc index 0cb3f811e1..19e9ccb760 100644 --- a/providers/common/ciphers/cipher_aes_gcm_hw_t4.inc +++ b/providers/common/ciphers/cipher_aes_gcm_hw_t4.inc @@ -34,7 +34,7 @@ static int t4_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, return 0; } - SET_KEY_CTR_FN(ks, aes_t4_set_encrypt_key, aes_t4_encrypt, ctr); + GCM_HW_SET_KEY_CTR_FN(ks, aes_t4_set_encrypt_key, aes_t4_encrypt, ctr); return 1; } diff --git a/providers/common/ciphers/cipher_aes_hw.c b/providers/common/ciphers/cipher_aes_hw.c index d80c63ecf9..e9b6388300 100644 --- a/providers/common/ciphers/cipher_aes_hw.c +++ b/providers/common/ciphers/cipher_aes_hw.c @@ -7,7 +7,8 @@ * https://www.openssl.org/source/license.html */ -#include "cipher_locl.h" +#include "cipher_aes.h" +#include "internal/providercommonerr.h" static int cipher_hw_aes_initkey(PROV_CIPHER_CTX *dat, const unsigned char *key, size_t keylen) diff --git a/providers/common/ciphers/cipher_ccm.c b/providers/common/ciphers/cipher_ccm.c index fcfef73197..211b64f768 100644 --- a/providers/common/ciphers/cipher_ccm.c +++ b/providers/common/ciphers/cipher_ccm.c @@ -10,6 +10,8 @@ /* Dispatch functions for ccm mode */ #include "cipher_locl.h" +#include "internal/ciphers/cipher_ccm.h" +#include "internal/providercommonerr.h" static int ccm_cipher_internal(PROV_CCM_CTX *ctx, unsigned char *out, size_t *padlen, const unsigned char *in, diff --git a/providers/common/ciphers/cipher_ccm_hw.c b/providers/common/ciphers/cipher_ccm_hw.c index 3036bfaa2e..b093b768e7 100644 --- a/providers/common/ciphers/cipher_ccm_hw.c +++ b/providers/common/ciphers/cipher_ccm_hw.c @@ -7,58 +7,29 @@ * https://www.openssl.org/source/license.html */ -#include "cipher_locl.h" +#include "internal/ciphers/ciphercommon.h" +#include "internal/ciphers/cipher_ccm.h" -#define AES_CCM_SET_KEY_FN(fn_set_enc_key, fn_blk, fn_ccm_enc, fn_ccm_dec) \ - fn_set_enc_key(key, keylen * 8, &actx->ccm.ks.ks); \ - CRYPTO_ccm128_init(&ctx->ccm_ctx, ctx->m, ctx->l, &actx->ccm.ks.ks, \ - (block128_f)fn_blk); \ - ctx->str = ctx->enc ? (ccm128_f)fn_ccm_enc : (ccm128_f)fn_ccm_dec; \ - ctx->key_set = 1; - -static int ccm_generic_aes_initkey(PROV_CCM_CTX *ctx, const unsigned char *key, - size_t keylen) -{ - PROV_AES_CCM_CTX *actx = (PROV_AES_CCM_CTX *)ctx; - -#ifdef HWAES_CAPABLE - if (HWAES_CAPABLE) { - AES_CCM_SET_KEY_FN(HWAES_set_encrypt_key, HWAES_encrypt, NULL, NULL); - } else -#endif /* HWAES_CAPABLE */ -#ifdef VPAES_CAPABLE - if (VPAES_CAPABLE) { - AES_CCM_SET_KEY_FN(vpaes_set_encrypt_key, vpaes_encrypt, NULL, NULL); - } else -#endif - { - AES_CCM_SET_KEY_FN(AES_set_encrypt_key, AES_encrypt, NULL, NULL) - } - return 1; -} - -static int ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce, - size_t nlen, size_t mlen) +int ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce, + size_t nlen, size_t mlen) { return CRYPTO_ccm128_setiv(&ctx->ccm_ctx, nonce, nlen, mlen) == 0; } -static int ccm_generic_setaad(PROV_CCM_CTX *ctx, const unsigned char *aad, - size_t alen) +int ccm_generic_setaad(PROV_CCM_CTX *ctx, const unsigned char *aad, size_t alen) { CRYPTO_ccm128_aad(&ctx->ccm_ctx, aad, alen); return 1; } -static int ccm_generic_gettag(PROV_CCM_CTX *ctx, unsigned char *tag, - size_t tlen) +int ccm_generic_gettag(PROV_CCM_CTX *ctx, unsigned char *tag, size_t tlen) { return CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, tlen) > 0; } -static int ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in, - unsigned char *out, size_t len, - unsigned char *tag, size_t taglen) +int ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in, + unsigned char *out, size_t len, + unsigned char *tag, size_t taglen) { int rv; @@ -73,10 +44,9 @@ static int ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in, return rv; } -static int ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in, - unsigned char *out, size_t len, - unsigned char *expected_tag, - size_t taglen) +int ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in, + unsigned char *out, size_t len, + unsigned char *expected_tag, size_t taglen) { int rv = 0; @@ -97,25 +67,3 @@ static int ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in, return rv; } -static const PROV_CCM_HW aes_ccm = { - ccm_generic_aes_initkey, - ccm_generic_setiv, - ccm_generic_setaad, - ccm_generic_auth_encrypt, - ccm_generic_auth_decrypt, - ccm_generic_gettag -}; -#if defined(S390X_aes_128_CAPABLE) -# include "cipher_aes_ccm_hw_s390x.inc" -#elif defined(AESNI_CAPABLE) -# include "cipher_aes_ccm_hw_aesni.inc" -#elif defined(SPARC_AES_CAPABLE) -# include "cipher_aes_ccm_hw_t4.inc" -#else -const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keybits) -{ - return &aes_ccm; -} -#endif - -#include "cipher_aria_ccm_hw.inc" diff --git a/providers/common/ciphers/cipher_common.c b/providers/common/ciphers/cipher_common.c index 9c9047ca52..5abd2c0010 100644 --- a/providers/common/ciphers/cipher_common.c +++ b/providers/common/ciphers/cipher_common.c @@ -12,12 +12,11 @@ */ #include "cipher_locl.h" - -#define MAXCHUNK ((size_t)1 << (sizeof(long) * 8 - 2)) -#define MAXBITCHUNK ((size_t)1 << (sizeof(size_t) * 8 - 4)) +#include "internal/provider_ctx.h" +#include "internal/providercommonerr.h" /*- - * Default cipher functions for OSSL_PARAM gettables and settables + * Generic cipher functions for OSSL_PARAM gettables and settables */ static const OSSL_PARAM cipher_known_gettable_params[] = { OSSL_PARAM_int(OSSL_CIPHER_PARAM_MODE, NULL), @@ -26,12 +25,12 @@ static const OSSL_PARAM cipher_known_gettable_params[] = { OSSL_PARAM_int(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL), OSSL_PARAM_END }; -const OSSL_PARAM *cipher_default_gettable_params(void) +const OSSL_PARAM *cipher_generic_gettable_params(void) { return cipher_known_gettable_params; } -int cipher_default_get_params(OSSL_PARAM params[], int md, unsigned long flags, +int cipher_generic_get_params(OSSL_PARAM params[], int md, unsigned long flags, int kbits, int blkbits, int ivbits) { OSSL_PARAM *p; @@ -64,18 +63,8 @@ int cipher_default_get_params(OSSL_PARAM params[], int md, unsigned long flags, return 1; } -static const OSSL_PARAM cipher_known_gettable_ctx_params[] = { - OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL), - OSSL_PARAM_int(OSSL_CIPHER_PARAM_IVLEN, NULL), - OSSL_PARAM_int(OSSL_CIPHER_PARAM_PADDING, NULL), - OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_NUM, NULL), - OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), - OSSL_PARAM_END -}; -const OSSL_PARAM *cipher_default_gettable_ctx_params(void) -{ - return cipher_known_gettable_ctx_params; -} +CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(cipher_generic) +CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(cipher_generic) static const OSSL_PARAM cipher_known_settable_ctx_params[] = { OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL), @@ -83,7 +72,7 @@ static const OSSL_PARAM cipher_known_settable_ctx_params[] = { OSSL_PARAM_int(OSSL_CIPHER_PARAM_NUM, NULL), OSSL_PARAM_END }; -const OSSL_PARAM *cipher_default_settable_ctx_params(void) +const OSSL_PARAM *cipher_generic_settable_ctx_params(void) { return cipher_known_settable_ctx_params; } @@ -125,11 +114,11 @@ static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx, ctx->enc = enc; if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) { - if (ivlen != GENERIC_BLOCK_SIZE) { + if (ivlen != ctx->ivlen) { ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); return 0; } - memcpy(ctx->iv, iv, GENERIC_BLOCK_SIZE); + memcpy(ctx->iv, iv, ctx->ivlen); } if (key != NULL) { if (keylen != ctx->keylen) { @@ -161,34 +150,34 @@ int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl, { size_t outlint = 0; PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; - size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, GENERIC_BLOCK_SIZE, &in, - &inl); + size_t blksz = ctx->blocksize; + size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, blksz, &in, &inl); /* * If we're decrypting and we end an update on a block boundary we hold * the last block back in case this is the last update call and the last * block is padded. */ - if (ctx->bufsz == GENERIC_BLOCK_SIZE && (ctx->enc || inl > 0 || !ctx->pad)) { - if (outsize < GENERIC_BLOCK_SIZE) { + if (ctx->bufsz == blksz && (ctx->enc || inl > 0 || !ctx->pad)) { + if (outsize < blksz) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } - if (!ctx->hw->cipher(ctx, out, ctx->buf, GENERIC_BLOCK_SIZE)) { + if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) { ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); return 0; } ctx->bufsz = 0; - outlint = GENERIC_BLOCK_SIZE; - out += GENERIC_BLOCK_SIZE; + outlint = blksz; + out += blksz; } if (nextblocks > 0) { if (!ctx->enc && ctx->pad && nextblocks == inl) { - if (!ossl_assert(inl >= GENERIC_BLOCK_SIZE)) { + if (!ossl_assert(inl >= blksz)) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } - nextblocks -= GENERIC_BLOCK_SIZE; + nextblocks -= blksz; } outlint += nextblocks; if (outsize < outlint) { @@ -202,7 +191,7 @@ int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl, in += nextblocks; inl -= nextblocks; } - if (!trailingdata(ctx->buf, &ctx->bufsz, GENERIC_BLOCK_SIZE, &in, &inl)) { + if (!trailingdata(ctx->buf, &ctx->bufsz, blksz, &in, &inl)) { /* ERR_raise already called */ return 0; } @@ -215,33 +204,34 @@ int cipher_generic_block_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; + size_t blksz = ctx->blocksize; if (ctx->enc) { if (ctx->pad) { - padblock(ctx->buf, &ctx->bufsz, GENERIC_BLOCK_SIZE); + padblock(ctx->buf, &ctx->bufsz, blksz); } else if (ctx->bufsz == 0) { *outl = 0; return 1; - } else if (ctx->bufsz != GENERIC_BLOCK_SIZE) { + } else if (ctx->bufsz != blksz) { ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH); return 0; } - if (outsize < GENERIC_BLOCK_SIZE) { + if (outsize < blksz) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } - if (!ctx->hw->cipher(ctx, out, ctx->buf, GENERIC_BLOCK_SIZE)) { + if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) { ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); return 0; } ctx->bufsz = 0; - *outl = GENERIC_BLOCK_SIZE; + *outl = blksz; return 1; } /* Decrypting */ - if (ctx->bufsz != GENERIC_BLOCK_SIZE) { + if (ctx->bufsz != blksz) { if (ctx->bufsz == 0 && !ctx->pad) { *outl = 0; return 1; @@ -250,12 +240,12 @@ int cipher_generic_block_final(void *vctx, unsigned char *out, size_t *outl, return 0; } - if (!ctx->hw->cipher(ctx, ctx->buf, ctx->buf, GENERIC_BLOCK_SIZE)) { + if (!ctx->hw->cipher(ctx, ctx->buf, ctx->buf, blksz)) { ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); return 0; } - if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, GENERIC_BLOCK_SIZE)) { + if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, blksz)) { /* ERR_raise already called */ return 0; } @@ -322,7 +312,7 @@ int cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[]) OSSL_PARAM *p; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); - if (p != NULL && !OSSL_PARAM_set_int(p, GENERIC_BLOCK_SIZE)) { + if (p != NULL && !OSSL_PARAM_set_int(p, ctx->ivlen)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } @@ -333,8 +323,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, GENERIC_BLOCK_SIZE) - && !OSSL_PARAM_set_octet_string(p, &ctx->iv, GENERIC_BLOCK_SIZE)) { + && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen) + && !OSSL_PARAM_set_octet_string(p, &ctx->iv, ctx->ivlen)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } @@ -390,14 +380,18 @@ int cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -void cipher_generic_initkey(void *vctx, int kbits, int blkbits, int mode, - const PROV_CIPHER_HW *hw) +void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits, + size_t ivbits, int mode, + const PROV_CIPHER_HW *hw, void *provctx) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; ctx->pad = 1; ctx->keylen = ((kbits) / 8); + ctx->ivlen = ((ivbits) / 8); ctx->hw = hw; ctx->mode = mode; - ctx->blocksize = blkbits/8; + ctx->blocksize = blkbits / 8; + if (provctx != NULL) + ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); /* used for rand */ } diff --git a/providers/common/ciphers/cipher_common_hw.c b/providers/common/ciphers/cipher_common_hw.c index 47e14afbbb..5a3fb3060b 100644 --- a/providers/common/ciphers/cipher_common_hw.c +++ b/providers/common/ciphers/cipher_common_hw.c @@ -9,9 +9,6 @@ #include "cipher_locl.h" -#define MAXCHUNK ((size_t)1 << (sizeof(long) * 8 - 2)) -#define MAXBITCHUNK ((size_t)1 << (sizeof(size_t) * 8 - 4)) - /*- * The generic cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr. * Used if there is no special hardware implementations. diff --git a/providers/common/ciphers/cipher_gcm.c b/providers/common/ciphers/cipher_gcm.c index 40c8845eca..7d0e47b823 100644 --- a/providers/common/ciphers/cipher_gcm.c +++ b/providers/common/ciphers/cipher_gcm.c @@ -10,6 +10,8 @@ /* Dispatch functions for gcm mode */ #include "cipher_locl.h" +#include "internal/ciphers/cipher_gcm.h" +#include "internal/providercommonerr.h" #include "internal/rand_int.h" #include "internal/provider_ctx.h" diff --git a/providers/common/ciphers/cipher_gcm_hw.c b/providers/common/ciphers/cipher_gcm_hw.c index f9ddc4d8a6..4ef5190b5f 100644 --- a/providers/common/ciphers/cipher_gcm_hw.c +++ b/providers/common/ciphers/cipher_gcm_hw.c @@ -8,94 +8,22 @@ */ #include "cipher_locl.h" +#include "internal/ciphers/cipher_gcm.h" -static const PROV_GCM_HW aes_gcm; -static int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen); -static int gcm_aad_update(PROV_GCM_CTX *ctx, const unsigned char *aad, - size_t aad_len); -static int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag); -static int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len, - const unsigned char *in, size_t in_len, - unsigned char *out, unsigned char *tag, size_t tag_len); -static int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in, - size_t len, unsigned char *out); - -#define SET_KEY_CTR_FN(ks, fn_set_enc_key, fn_block, fn_ctr) \ - ctx->ks = ks; \ - fn_set_enc_key(key, keylen * 8, ks); \ - CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f)fn_block); \ - ctx->ctr = (ctr128_f)fn_ctr; \ - ctx->key_set = 1; - -#if defined(AESNI_CAPABLE) -# include "cipher_aes_gcm_hw_aesni.inc" -#elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) -# include "cipher_aes_gcm_hw_t4.inc" -#elif defined(OPENSSL_CPUID_OBJ) && defined(__s390__) -# include "cipher_aes_gcm_hw_s390x.inc" -#else -const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits) -{ - return &aes_gcm; -} -#endif - -static int generic_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, - size_t keylen) -{ - PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx; - AES_KEY *ks = &actx->ks.ks; - -# ifdef HWAES_CAPABLE - if (HWAES_CAPABLE) { -# ifdef HWAES_ctr32_encrypt_blocks - SET_KEY_CTR_FN(ks, HWAES_set_encrypt_key, HWAES_encrypt, - HWAES_ctr32_encrypt_blocks); -# else - SET_KEY_CTR_FN(ks, HWAES_set_encrypt_key, HWAES_encrypt, NULL); -# endif /* HWAES_ctr32_encrypt_blocks */ - } else -# endif /* HWAES_CAPABLE */ - -# ifdef BSAES_CAPABLE - if (BSAES_CAPABLE) { - SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt, - bsaes_ctr32_encrypt_blocks); - } else -# endif /* BSAES_CAPABLE */ - -# ifdef VPAES_CAPABLE - if (VPAES_CAPABLE) { - SET_KEY_CTR_FN(ks, vpaes_set_encrypt_key, vpaes_encrypt, NULL); - } else -# endif /* VPAES_CAPABLE */ - - { -# ifdef AES_CTR_ASM - SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt, AES_ctr32_encrypt); -# else - SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt, NULL); -# endif /* AES_CTR_ASM */ - } - ctx->key_set = 1; - return 1; -} - -static int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen) +int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen) { CRYPTO_gcm128_setiv(&ctx->gcm, iv, ivlen); return 1; } -static int gcm_aad_update(PROV_GCM_CTX *ctx, - const unsigned char *aad, size_t aad_len) +int gcm_aad_update(PROV_GCM_CTX *ctx, const unsigned char *aad, size_t aad_len) { return CRYPTO_gcm128_aad(&ctx->gcm, aad, aad_len) == 0; } -static int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in, - size_t len, unsigned char *out) +int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in, + size_t len, unsigned char *out) { if (ctx->enc) { if (ctx->ctr != NULL) { @@ -156,7 +84,7 @@ static int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in, return 1; } -static int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag) +int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag) { if (ctx->enc) { CRYPTO_gcm128_tag(&ctx->gcm, tag, GCM_TAG_MAX_SIZE); @@ -169,9 +97,9 @@ static int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag) return 1; } -static int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len, - const unsigned char *in, size_t in_len, - unsigned char *out, unsigned char *tag, size_t tag_len) +int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len, + const unsigned char *in, size_t in_len, + unsigned char *out, unsigned char *tag, size_t tag_len) { int ret = 0; @@ -188,14 +116,3 @@ static int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len, err: return ret; } - -static const PROV_GCM_HW aes_gcm = { - generic_aes_gcm_initkey, - gcm_setiv, - gcm_aad_update, - gcm_cipher_update, - gcm_cipher_final, - gcm_one_shot -}; - -#include "cipher_aria_gcm_hw.inc" diff --git a/providers/common/ciphers/cipher_locl.h b/providers/common/ciphers/cipher_locl.h index 9d95a7c482..8313498e5e 100644 --- a/providers/common/ciphers/cipher_locl.h +++ b/providers/common/ciphers/cipher_locl.h @@ -7,84 +7,23 @@ * https://www.openssl.org/source/license.html */ -#include -#include -#include -#include -#include -#include -#include -#include "internal/cryptlib.h" -#include "internal/modes_int.h" -#include "internal/provider_algs.h" -#include "internal/providercommonerr.h" -#include "internal/ciphermode_platform.h" +#include "internal/ciphers/ciphercommon.h" -#define GENERIC_BLOCK_SIZE 16 -#define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */ -#define IV_STATE_BUFFERED 1 /* iv has been copied to the iv buffer */ -#define IV_STATE_COPIED 2 /* iv has been copied from the iv buffer */ -#define IV_STATE_FINISHED 3 /* the iv has been used - so don't reuse it */ +#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name) \ +static const OSSL_PARAM name##_known_gettable_ctx_params[] = { \ + OSSL_PARAM_int(OSSL_CIPHER_PARAM_KEYLEN, NULL), \ + OSSL_PARAM_int(OSSL_CIPHER_PARAM_IVLEN, NULL), \ + OSSL_PARAM_int(OSSL_CIPHER_PARAM_PADDING, NULL), \ + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_NUM, NULL), \ + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), -#define PROV_CIPHER_FUNC(type, name, args) typedef type (* OSSL_##name##_fn)args - -typedef struct prov_cipher_hw_st PROV_CIPHER_HW; -typedef struct prov_cipher_ctx_st PROV_CIPHER_CTX; - -typedef int (PROV_CIPHER_HW_FN)(PROV_CIPHER_CTX *dat, unsigned char *out, - const unsigned char *in, size_t len); - -struct prov_cipher_ctx_st { - block128_f block; - union { - cbc128_f cbc; - ctr128_f ctr; - } stream; - - /* - * num contains the number of bytes of |iv| which are valid for modes that - * manage partial blocks themselves. - */ - size_t num; - - int mode; - int enc; /* Set to 1 for encrypt, or 0 otherwise */ - size_t bufsz; /* Number of bytes in buf */ - size_t keylen; /* key size (in bytes) */ - size_t blocksize; - uint64_t flags; - unsigned int pad : 1; /* Whether padding should be used or not */ - - /* Buffer of partial blocks processed via update calls */ - unsigned char buf[GENERIC_BLOCK_SIZE]; - unsigned char iv[GENERIC_BLOCK_SIZE]; - const PROV_CIPHER_HW *hw; /* hardware specific functions */ - const void *ks; /* Pointer to algorithm specific key data */ -}; - -struct prov_cipher_hw_st { - int (*init)(PROV_CIPHER_CTX *dat, const uint8_t *key, size_t keylen); - PROV_CIPHER_HW_FN *cipher; -}; - -OSSL_OP_cipher_encrypt_init_fn cipher_generic_einit; -OSSL_OP_cipher_decrypt_init_fn cipher_generic_dinit; -OSSL_OP_cipher_update_fn cipher_generic_block_update; -OSSL_OP_cipher_final_fn cipher_generic_block_final; -OSSL_OP_cipher_update_fn cipher_generic_stream_update; -OSSL_OP_cipher_final_fn cipher_generic_stream_final; -OSSL_OP_cipher_cipher_fn cipher_generic_cipher; -OSSL_OP_cipher_get_ctx_params_fn cipher_generic_get_ctx_params; -OSSL_OP_cipher_set_ctx_params_fn cipher_generic_set_ctx_params; -OSSL_OP_cipher_gettable_params_fn cipher_default_gettable_params; -OSSL_OP_cipher_gettable_ctx_params_fn cipher_default_gettable_ctx_params; -OSSL_OP_cipher_settable_ctx_params_fn cipher_default_settable_ctx_params; -OSSL_OP_cipher_gettable_ctx_params_fn cipher_aead_gettable_ctx_params; -OSSL_OP_cipher_settable_ctx_params_fn cipher_aead_settable_ctx_params; -int cipher_default_get_params(OSSL_PARAM params[], int md, unsigned long flags, - int kbits, int blkbits, int ivbits); -void cipher_generic_initkey(void *vctx, int kbits, int blkbits, int mode, - const PROV_CIPHER_HW *ciph); +#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name) \ + OSSL_PARAM_END \ +}; \ +const OSSL_PARAM * name##_gettable_ctx_params(void) \ +{ \ + return name##_known_gettable_ctx_params; \ +} size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize, const unsigned char **in, size_t *inlen); @@ -92,102 +31,3 @@ int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize, const unsigned char **in, size_t *inlen); void padblock(unsigned char *buf, size_t *buflen, size_t blocksize); int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize); - -#include "cipher_aes.h" -#include "cipher_aria.h" -#include "cipher_camellia.h" -#include "cipher_gcm.h" -#include "cipher_ccm.h" - -#define IMPLEMENT_generic_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \ - blkbits, ivbits, typ) \ -static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \ -static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ -{ \ - return cipher_default_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, \ - kbits, blkbits, ivbits); \ -} \ -static OSSL_OP_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \ -static void * alg##_##kbits##_##lcmode##_newctx(void *provctx) \ -{ \ - PROV_##UCALG##_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ - if (ctx != NULL) { \ - cipher_generic_initkey(ctx, kbits, blkbits, EVP_CIPH_##UCMODE##_MODE, \ - PROV_CIPHER_HW_##alg##_##lcmode(kbits)); \ - } \ - return ctx; \ -} \ -const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = { \ - { OSSL_FUNC_CIPHER_NEWCTX, \ - (void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \ - { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \ - { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \ - { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))cipher_generic_einit }, \ - { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))cipher_generic_dinit }, \ - { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))cipher_generic_##typ##_update },\ - { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##typ##_final }, \ - { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \ - { OSSL_FUNC_CIPHER_GET_PARAMS, \ - (void (*)(void)) alg##_##kbits##_##lcmode##_get_params }, \ - { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ - (void (*)(void))cipher_generic_get_ctx_params }, \ - { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ - (void (*)(void))cipher_generic_set_ctx_params }, \ - { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_default_gettable_params }, \ - { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_default_gettable_ctx_params }, \ - { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_default_settable_ctx_params }, \ - { 0, NULL } \ -}; - -#define IMPLEMENT_aead_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits) \ -static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lc##_get_params; \ -static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \ -{ \ - return cipher_default_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ - flags, kbits, blkbits, ivbits); \ -} \ -static OSSL_OP_cipher_newctx_fn alg##kbits##lc##_newctx; \ -static void * alg##kbits##lc##_newctx(void *provctx) \ -{ \ - return alg##_##lc##_newctx(provctx, kbits); \ -} \ -const OSSL_DISPATCH alg##kbits##lc##_functions[] = { \ - { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx }, \ - { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx }, \ - { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void)) lc##_einit }, \ - { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void)) lc##_dinit }, \ - { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void)) lc##_stream_update }, \ - { OSSL_FUNC_CIPHER_FINAL, (void (*)(void)) lc##_stream_final }, \ - { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void)) lc##_cipher }, \ - { OSSL_FUNC_CIPHER_GET_PARAMS, \ - (void (*)(void)) alg##_##kbits##_##lc##_get_params }, \ - { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ - (void (*)(void)) lc##_get_ctx_params }, \ - { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ - (void (*)(void)) lc##_set_ctx_params }, \ - { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_default_gettable_params }, \ - { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_aead_gettable_ctx_params }, \ - { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_aead_settable_ctx_params }, \ - { 0, NULL } \ -} - -PROV_CIPHER_HW_FN cipher_hw_generic_cbc; -PROV_CIPHER_HW_FN cipher_hw_generic_ecb; -PROV_CIPHER_HW_FN cipher_hw_generic_ofb128; -PROV_CIPHER_HW_FN cipher_hw_generic_cfb128; -PROV_CIPHER_HW_FN cipher_hw_generic_cfb8; -PROV_CIPHER_HW_FN cipher_hw_generic_cfb1; -PROV_CIPHER_HW_FN cipher_hw_generic_ctr; -PROV_CIPHER_HW_FN cipher_hw_chunked_cbc; -PROV_CIPHER_HW_FN cipher_hw_chunked_cfb8; -PROV_CIPHER_HW_FN cipher_hw_chunked_cfb128; -PROV_CIPHER_HW_FN cipher_hw_chunked_ofb128; -#define cipher_hw_chunked_ecb cipher_hw_generic_ecb -#define cipher_hw_chunked_ctr cipher_hw_generic_ctr -#define cipher_hw_chunked_cfb1 cipher_hw_generic_cfb1 diff --git a/providers/common/ciphers/cipher_tdes.c b/providers/common/ciphers/cipher_tdes.c new file mode 100644 index 0000000000..91df2ce194 --- /dev/null +++ b/providers/common/ciphers/cipher_tdes.c @@ -0,0 +1,116 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "cipher_locl.h" +#include "internal/ciphers/cipher_tdes.h" +#include "internal/rand_int.h" +#include "internal/provider_algs.h" +#include "internal/providercommonerr.h" + +void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits, + size_t ivbits, const PROV_CIPHER_HW *hw) +{ + PROV_TDES_CTX *tctx = OPENSSL_zalloc(sizeof(*tctx)); + + if (tctx != NULL) + cipher_generic_initkey(tctx, kbits, blkbits, ivbits, mode, hw, provctx); + return tctx; +} + +void tdes_freectx(void *vctx) +{ + PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; + + OPENSSL_clear_free(ctx, sizeof(*ctx)); +} + +static int tdes_init(void *vctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen, int enc) +{ + PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; + + ctx->enc = enc; + + if (iv != NULL) { + if (ivlen != TDES_IVLEN) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN); + return 0; + } + memcpy(ctx->iv, iv, TDES_IVLEN); + } + + if (key != NULL) { + if (keylen != ctx->keylen) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEYLEN); + return 0; + } + return ctx->hw->init(ctx, key, ctx->keylen); + } + return 1; +} + +int tdes_einit(void *vctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen) +{ + return tdes_init(vctx, key, keylen, iv, ivlen, 1); +} + +int tdes_dinit(void *vctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen) +{ + return tdes_init(vctx, key, keylen, iv, ivlen, 0); +} + +static int tdes_generatekey(PROV_CIPHER_CTX *ctx, void *ptr) +{ + + DES_cblock *deskey = ptr; + size_t kl = ctx->keylen; + + if (kl == 0 || rand_priv_bytes_ex(ctx->libctx, ptr, kl) <= 0) + return 0; + DES_set_odd_parity(deskey); + if (kl >= 16) + DES_set_odd_parity(deskey + 1); + if (kl >= 24) { + DES_set_odd_parity(deskey + 2); + return 1; + } + return 0; +} + +CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(tdes) + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0), +CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(tdes) + +int tdes_get_ctx_params(void *vctx, OSSL_PARAM params[]) +{ + PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; + OSSL_PARAM *p; + + if (!cipher_generic_get_ctx_params(vctx, params)) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RANDOM_KEY); + if (p != NULL && !tdes_generatekey(ctx, p->data)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY); + return 0; + } + return 1; +} + +/* + * TODO(3.0) - ECB mode does not use an IV - but existing test code is setting + * an IV. Fixing this could potentially make applications break. + */ + +/* tdes_ede3_ecb_functions */ +IMPLEMENT_tdes_cipher(ede3, EDE3, ecb, ECB, TDES_FLAGS, 64*3, 64, 64, block); +/* tdes_ede3_cbc_functions */ +IMPLEMENT_tdes_cipher(ede3, EDE3, cbc, CBC, TDES_FLAGS, 64*3, 64, 64, block); diff --git a/providers/common/ciphers/cipher_tdes_hw.c b/providers/common/ciphers/cipher_tdes_hw.c new file mode 100644 index 0000000000..980201267b --- /dev/null +++ b/providers/common/ciphers/cipher_tdes_hw.c @@ -0,0 +1,82 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "cipher_locl.h" +#include "internal/ciphers/cipher_tdes.h" + +#define ks1 tks.ks[0] +#define ks2 tks.ks[1] +#define ks3 tks.ks[2] + +int cipher_hw_tdes_ede3_initkey(PROV_CIPHER_CTX *ctx, const unsigned char *key, + size_t keylen) +{ + PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; + DES_cblock *deskey = (DES_cblock *)key; + + tctx->tstream.cbc = NULL; +# if defined(SPARC_DES_CAPABLE) + if (SPARC_DES_CAPABLE) { + if (ctx->mode == EVP_CIPH_CBC_MODE) { + des_t4_key_expand(&deskey[0], &tctx->ks1); + des_t4_key_expand(&deskey[1], &tctx->ks2); + des_t4_key_expand(&deskey[2], &tctx->ks3); + dat->tstream.cbc = enc ? des_t4_ede3_cbc_encrypt : + des_t4_ede3_cbc_decrypt; + return 1; + } + } +# endif + DES_set_key_unchecked(&deskey[0], &tctx->ks1); + DES_set_key_unchecked(&deskey[1], &tctx->ks2); + DES_set_key_unchecked(&deskey[2], &tctx->ks3); + return 1; +} + +int cipher_hw_tdes_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; + + if (tctx->tstream.cbc != NULL) { + (*tctx->tstream.cbc) (in, out, inl, tctx->tks.ks, ctx->iv); + return 1; + } + + while (inl >= MAXCHUNK) { + DES_ede3_cbc_encrypt(in, out, (long)MAXCHUNK, &tctx->ks1, &tctx->ks2, + &tctx->ks3, (DES_cblock *)ctx->iv, ctx->enc); + inl -= MAXCHUNK; + in += MAXCHUNK; + out += MAXCHUNK; + } + if (inl > 0) + DES_ede3_cbc_encrypt(in, out, (long)inl, &tctx->ks1, &tctx->ks2, + &tctx->ks3, (DES_cblock *)ctx->iv, ctx->enc); + return 1; +} + +int cipher_hw_tdes_ecb(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + size_t i; + PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; + + if (len < DES_BLOCK_SIZE) + return 1; + + for (i = 0, len -= DES_BLOCK_SIZE; i <= len; i += DES_BLOCK_SIZE) { + DES_ecb3_encrypt((const_DES_cblock *)(in + i), (DES_cblock *)(out + i), + &tctx->ks1, &tctx->ks2, &tctx->ks3, ctx->enc); + } + return 1; +} + +PROV_CIPHER_HW_tdes_mode(ede3, ecb) +PROV_CIPHER_HW_tdes_mode(ede3, cbc) diff --git a/providers/common/include/internal/ciphers/cipher_aead.h b/providers/common/include/internal/ciphers/cipher_aead.h new file mode 100644 index 0000000000..a2fe87e967 --- /dev/null +++ b/providers/common/include/internal/ciphers/cipher_aead.h @@ -0,0 +1,49 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* TODO(3.0) Figure out what flags are really needed */ +#define AEAD_FLAGS (EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_DEFAULT_ASN1 \ + | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ + | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ + | EVP_CIPH_CUSTOM_COPY) + +#define IMPLEMENT_aead_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits) \ +static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lc##_get_params; \ +static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \ +{ \ + return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + flags, kbits, blkbits, ivbits); \ +} \ +static OSSL_OP_cipher_newctx_fn alg##kbits##lc##_newctx; \ +static void * alg##kbits##lc##_newctx(void *provctx) \ +{ \ + return alg##_##lc##_newctx(provctx, kbits); \ +} \ +const OSSL_DISPATCH alg##kbits##lc##_functions[] = { \ + { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx }, \ + { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx }, \ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void)) lc##_einit }, \ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void)) lc##_dinit }, \ + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void)) lc##_stream_update }, \ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void)) lc##_stream_final }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void)) lc##_cipher }, \ + { OSSL_FUNC_CIPHER_GET_PARAMS, \ + (void (*)(void)) alg##_##kbits##_##lc##_get_params }, \ + { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ + (void (*)(void)) lc##_get_ctx_params }, \ + { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ + (void (*)(void)) lc##_set_ctx_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ + (void (*)(void))cipher_generic_gettable_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ + (void (*)(void))cipher_aead_gettable_ctx_params }, \ + { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ + (void (*)(void))cipher_aead_settable_ctx_params }, \ + { 0, NULL } \ +} diff --git a/providers/common/ciphers/cipher_ccm.h b/providers/common/include/internal/ciphers/cipher_ccm.h similarity index 87% rename from providers/common/ciphers/cipher_ccm.h rename to providers/common/include/internal/ciphers/cipher_ccm.h index d91ad0013e..503d077def 100644 --- a/providers/common/ciphers/cipher_ccm.h +++ b/providers/common/include/internal/ciphers/cipher_ccm.h @@ -7,6 +7,8 @@ * https://www.openssl.org/source/license.html */ +#include "cipher_aead.h" + typedef struct prov_ccm_hw_st PROV_CCM_HW; #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) @@ -111,20 +113,6 @@ struct prov_ccm_hw_st { const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keylen); -#if !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE) -# include "internal/aria.h" -typedef struct prov_aria_ccm_ctx_st { - PROV_CCM_CTX base; /* Must be first */ - union { - OSSL_UNION_ALIGN; - ARIA_KEY ks; - } ks; /* ARIA key schedule to use */ -} PROV_ARIA_CCM_CTX; - -const PROV_CCM_HW *PROV_ARIA_HW_ccm(size_t keylen); - -#endif /* !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE) */ - OSSL_OP_cipher_encrypt_init_fn ccm_einit; OSSL_OP_cipher_decrypt_init_fn ccm_dinit; OSSL_OP_cipher_get_ctx_params_fn ccm_get_ctx_params; @@ -134,3 +122,14 @@ 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); +int ccm_generic_setaad(PROV_CCM_CTX *ctx, const unsigned char *aad, size_t alen); +int ccm_generic_gettag(PROV_CCM_CTX *ctx, unsigned char *tag, size_t tlen); +int ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in, + unsigned char *out, size_t len, + unsigned char *tag, size_t taglen); +int ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in, + unsigned char *out, size_t len, + unsigned char *expected_tag, size_t taglen); diff --git a/providers/common/ciphers/cipher_gcm.h b/providers/common/include/internal/ciphers/cipher_gcm.h similarity index 83% rename from providers/common/ciphers/cipher_gcm.h rename to providers/common/include/internal/ciphers/cipher_gcm.h index 59bbeee04a..63600c38e7 100644 --- a/providers/common/ciphers/cipher_gcm.h +++ b/providers/common/include/internal/ciphers/cipher_gcm.h @@ -9,6 +9,7 @@ */ #include +#include "cipher_aead.h" typedef struct prov_gcm_hw_st PROV_GCM_HW; @@ -16,12 +17,6 @@ typedef struct prov_gcm_hw_st PROV_GCM_HW; #define GCM_IV_MAX_SIZE 64 #define GCM_TAG_MAX_SIZE 16 -/* TODO(3.0) Figure out what flags are really needed */ -#define AEAD_FLAGS (EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_DEFAULT_ASN1 \ - | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ - | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ - | EVP_CIPH_CUSTOM_COPY) - #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) /*- * KMA-GCM-AES parameter block - begin @@ -137,21 +132,6 @@ struct prov_gcm_hw_st { }; const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits); -#if !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE) - -#include "internal/aria.h" - -typedef struct prov_aria_gcm_ctx_st { - PROV_GCM_CTX base; /* must be first entry in struct */ - union { - OSSL_UNION_ALIGN; - ARIA_KEY ks; - } ks; -} PROV_ARIA_GCM_CTX; -const PROV_GCM_HW *PROV_ARIA_HW_gcm(size_t keybits); - -#endif /* !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE) */ - OSSL_OP_cipher_encrypt_init_fn gcm_einit; OSSL_OP_cipher_decrypt_init_fn gcm_dinit; OSSL_OP_cipher_get_ctx_params_fn gcm_get_ctx_params; @@ -163,3 +143,19 @@ 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); +int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen); +int gcm_aad_update(PROV_GCM_CTX *ctx, const unsigned char *aad, + size_t aad_len); +int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag); +int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len, + const unsigned char *in, size_t in_len, + unsigned char *out, unsigned char *tag, size_t tag_len); +int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in, + size_t len, unsigned char *out); + +#define GCM_HW_SET_KEY_CTR_FN(ks, fn_set_enc_key, fn_block, fn_ctr) \ + ctx->ks = ks; \ + fn_set_enc_key(key, keylen * 8, ks); \ + CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f)fn_block); \ + ctx->ctr = (ctr128_f)fn_ctr; \ + ctx->key_set = 1; diff --git a/providers/common/include/internal/ciphers/cipher_tdes.h b/providers/common/include/internal/ciphers/cipher_tdes.h new file mode 100644 index 0000000000..0d3c90c0af --- /dev/null +++ b/providers/common/include/internal/ciphers/cipher_tdes.h @@ -0,0 +1,96 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +#define DES_BLOCK_SIZE 8 +#define TDES_IVLEN 8 + +/* TODO(3.0) Figure out what flags need to be here */ +#define TDES_FLAGS (EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1) + +typedef struct prov_tdes_ctx_st { + PROV_CIPHER_CTX base; /* Must be first */ + union { + OSSL_UNION_ALIGN; + DES_key_schedule ks[3]; + } tks; + union { + void (*cbc) (const void *, void *, size_t, + const DES_key_schedule *, unsigned char *); + } tstream; + +} PROV_TDES_CTX; + +#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) \ +{ \ + return tdes_newctx(provctx, EVP_CIPH_##UCMODE##_MODE, kbits, blkbits, \ + ivbits, PROV_CIPHER_HW_tdes_##type##_##lcmode()); \ +} \ +static OSSL_OP_cipher_get_params_fn tdes_##type##_##lcmode##_get_params; \ +static int tdes_##type##_##lcmode##_get_params(OSSL_PARAM params[]) \ +{ \ + return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, \ + kbits, blkbits, ivbits); \ +} \ +const OSSL_DISPATCH tdes_##type##_##lcmode##_functions[] = { \ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))tdes_einit }, \ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))tdes_dinit }, \ + { OSSL_FUNC_CIPHER_UPDATE, \ + (void (*)(void))cipher_generic_##block##_update }, \ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##block##_final },\ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \ + { OSSL_FUNC_CIPHER_NEWCTX, \ + (void (*)(void))tdes_##type##_##lcmode##_newctx }, \ + { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))tdes_freectx }, \ + { OSSL_FUNC_CIPHER_GET_PARAMS, \ + (void (*)(void))tdes_##type##_##lcmode##_get_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ + (void (*)(void))cipher_generic_gettable_params }, \ + { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))tdes_get_ctx_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ + (void (*)(void))tdes_gettable_ctx_params }, \ + { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ + (void (*)(void))cipher_generic_set_ctx_params }, \ + { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ + (void (*)(void))cipher_generic_settable_ctx_params }, \ + { 0, NULL } \ +} + +void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits, + size_t ivbits, const PROV_CIPHER_HW *hw); +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) \ +static const PROV_CIPHER_HW type##_##mode = { \ + cipher_hw_tdes_##type##_initkey, \ + cipher_hw_tdes_##mode \ +}; \ +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_##type##_##mode(void) \ +{ \ + return &type##_##mode; \ +} + +int cipher_hw_tdes_ede3_initkey(PROV_CIPHER_CTX *ctx, const unsigned char *key, + size_t keylen); +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, + const unsigned char *in, size_t len); + +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_cbc(void); +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_ecb(void); diff --git a/providers/common/include/internal/ciphers/ciphercommon.h b/providers/common/include/internal/ciphers/ciphercommon.h new file mode 100644 index 0000000000..38d0396902 --- /dev/null +++ b/providers/common/include/internal/ciphers/ciphercommon.h @@ -0,0 +1,149 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/modes_int.h" +#include "internal/ciphermode_platform.h" + +#define MAXCHUNK ((size_t)1 << (sizeof(long) * 8 - 2)) +#define MAXBITCHUNK ((size_t)1 << (sizeof(size_t) * 8 - 4)) + +#define GENERIC_BLOCK_SIZE 16 +#define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */ +#define IV_STATE_BUFFERED 1 /* iv has been copied to the iv buffer */ +#define IV_STATE_COPIED 2 /* iv has been copied from the iv buffer */ +#define IV_STATE_FINISHED 3 /* the iv has been used - so don't reuse it */ + +#define PROV_CIPHER_FUNC(type, name, args) typedef type (* OSSL_##name##_fn)args + +typedef struct prov_cipher_hw_st PROV_CIPHER_HW; +typedef struct prov_cipher_ctx_st PROV_CIPHER_CTX; + +typedef int (PROV_CIPHER_HW_FN)(PROV_CIPHER_CTX *dat, unsigned char *out, + const unsigned char *in, size_t len); + +struct prov_cipher_ctx_st { + block128_f block; + union { + cbc128_f cbc; + ctr128_f ctr; + } stream; + + /* + * num contains the number of bytes of |iv| which are valid for modes that + * manage partial blocks themselves. + */ + size_t num; + + int mode; + int enc; /* Set to 1 for encrypt, or 0 otherwise */ + size_t bufsz; /* Number of bytes in buf */ + size_t keylen; /* key size (in bytes) */ + size_t ivlen; + size_t blocksize; + uint64_t flags; + unsigned int pad : 1; /* Whether padding should be used or not */ + + /* Buffer of partial blocks processed via update calls */ + unsigned char buf[GENERIC_BLOCK_SIZE]; + unsigned char iv[GENERIC_BLOCK_SIZE]; + const PROV_CIPHER_HW *hw; /* hardware specific functions */ + const void *ks; /* Pointer to algorithm specific key data */ + OPENSSL_CTX *libctx; +}; + +struct prov_cipher_hw_st { + int (*init)(PROV_CIPHER_CTX *dat, const uint8_t *key, size_t keylen); + PROV_CIPHER_HW_FN *cipher; +}; + +OSSL_OP_cipher_encrypt_init_fn cipher_generic_einit; +OSSL_OP_cipher_decrypt_init_fn cipher_generic_dinit; +OSSL_OP_cipher_update_fn cipher_generic_block_update; +OSSL_OP_cipher_final_fn cipher_generic_block_final; +OSSL_OP_cipher_update_fn cipher_generic_stream_update; +OSSL_OP_cipher_final_fn cipher_generic_stream_final; +OSSL_OP_cipher_cipher_fn cipher_generic_cipher; +OSSL_OP_cipher_get_ctx_params_fn cipher_generic_get_ctx_params; +OSSL_OP_cipher_set_ctx_params_fn cipher_generic_set_ctx_params; +OSSL_OP_cipher_gettable_params_fn cipher_generic_gettable_params; +OSSL_OP_cipher_gettable_ctx_params_fn cipher_generic_gettable_ctx_params; +OSSL_OP_cipher_settable_ctx_params_fn cipher_generic_settable_ctx_params; +OSSL_OP_cipher_gettable_ctx_params_fn cipher_aead_gettable_ctx_params; +OSSL_OP_cipher_settable_ctx_params_fn cipher_aead_settable_ctx_params; +int cipher_generic_get_params(OSSL_PARAM params[], int md, unsigned long flags, + int kbits, int blkbits, int ivbits); +void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits, + size_t ivbits, int mode, + const PROV_CIPHER_HW *hw, void *provctx); + +#define IMPLEMENT_generic_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \ + blkbits, ivbits, typ) \ +static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \ +static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ +{ \ + return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, \ + kbits, blkbits, ivbits); \ +} \ +static OSSL_OP_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \ +static void * alg##_##kbits##_##lcmode##_newctx(void *provctx) \ +{ \ + PROV_##UCALG##_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ + if (ctx != NULL) { \ + cipher_generic_initkey(ctx, kbits, blkbits, ivbits, \ + EVP_CIPH_##UCMODE##_MODE, \ + PROV_CIPHER_HW_##alg##_##lcmode(kbits), NULL); \ + } \ + return ctx; \ +} \ +const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = { \ + { OSSL_FUNC_CIPHER_NEWCTX, \ + (void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \ + { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \ + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))cipher_generic_einit }, \ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))cipher_generic_dinit }, \ + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))cipher_generic_##typ##_update },\ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##typ##_final }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \ + { OSSL_FUNC_CIPHER_GET_PARAMS, \ + (void (*)(void)) alg##_##kbits##_##lcmode##_get_params }, \ + { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ + (void (*)(void))cipher_generic_get_ctx_params }, \ + { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ + (void (*)(void))cipher_generic_set_ctx_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ + (void (*)(void))cipher_generic_gettable_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ + (void (*)(void))cipher_generic_gettable_ctx_params }, \ + { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ + (void (*)(void))cipher_generic_settable_ctx_params }, \ + { 0, NULL } \ +}; + +PROV_CIPHER_HW_FN cipher_hw_generic_cbc; +PROV_CIPHER_HW_FN cipher_hw_generic_ecb; +PROV_CIPHER_HW_FN cipher_hw_generic_ofb128; +PROV_CIPHER_HW_FN cipher_hw_generic_cfb128; +PROV_CIPHER_HW_FN cipher_hw_generic_cfb8; +PROV_CIPHER_HW_FN cipher_hw_generic_cfb1; +PROV_CIPHER_HW_FN cipher_hw_generic_ctr; +PROV_CIPHER_HW_FN cipher_hw_chunked_cbc; +PROV_CIPHER_HW_FN cipher_hw_chunked_cfb8; +PROV_CIPHER_HW_FN cipher_hw_chunked_cfb128; +PROV_CIPHER_HW_FN cipher_hw_chunked_ofb128; +#define cipher_hw_chunked_ecb cipher_hw_generic_ecb +#define cipher_hw_chunked_ctr cipher_hw_generic_ctr +#define cipher_hw_chunked_cfb1 cipher_hw_generic_cfb1 + + diff --git a/providers/common/include/internal/provider_algs.h b/providers/common/include/internal/provider_algs.h index cfa88dff42..e66c0523e7 100644 --- a/providers/common/include/internal/provider_algs.h +++ b/providers/common/include/internal/provider_algs.h @@ -126,6 +126,24 @@ extern const OSSL_DISPATCH kmac256_functions[]; extern const OSSL_DISPATCH siphash_functions[]; extern const OSSL_DISPATCH poly1305_functions[]; +extern const OSSL_DISPATCH tdes_ede3_ecb_functions[]; +extern const OSSL_DISPATCH tdes_ede3_cbc_functions[]; + +#ifndef FIPS_MODE +extern const OSSL_DISPATCH tdes_ede3_ofb_functions[]; +extern const OSSL_DISPATCH tdes_ede3_cfb_functions[]; +extern const OSSL_DISPATCH tdes_ede3_cfb8_functions[]; +extern const OSSL_DISPATCH tdes_ede3_cfb1_functions[]; + +extern const OSSL_DISPATCH tdes_ede2_ecb_functions[]; +extern const OSSL_DISPATCH tdes_ede2_cbc_functions[]; +extern const OSSL_DISPATCH tdes_ede2_ofb_functions[]; +extern const OSSL_DISPATCH tdes_ede2_cfb_functions[]; + +extern const OSSL_DISPATCH tdes_desx_cbc_functions[]; +extern const OSSL_DISPATCH tdes_wrap_cbc_functions[]; +#endif /* FIPS_MODE */ + /* Key management */ extern const OSSL_DISPATCH dh_keymgmt_functions[]; diff --git a/providers/common/include/internal/providercommonerr.h b/providers/common/include/internal/providercommonerr.h index da5644b50d..c436495a5b 100644 --- a/providers/common/include/internal/providercommonerr.h +++ b/providers/common/include/internal/providercommonerr.h @@ -41,7 +41,7 @@ int ERR_load_PROV_strings(void); # define PROV_F_GMAC_SET_PARAMS 0 # define PROV_F_KMAC_SET_PARAMS 0 # define PROV_F_POLY1305_SET_PARAMS 0 -# define PROV_F_PROV_AES_CTX_GENERIC_INIT 0 +# define PROV_F_PROV_AES_KEY_GENERIC_INIT 0 # define PROV_F_TRAILINGDATA 0 # define PROV_F_UNPADBLOCK 0 # endif @@ -52,6 +52,7 @@ int ERR_load_PROV_strings(void); # define PROV_R_AES_KEY_SETUP_FAILED 101 # define PROV_R_BAD_DECRYPT 100 # define PROV_R_CIPHER_OPERATION_FAILED 102 +# define PROV_R_FAILED_TO_GENERATE_KEY 121 # define PROV_R_FAILED_TO_GET_PARAMETER 103 # define PROV_R_FAILED_TO_SET_PARAMETER 104 # define PROV_R_INVALID_AAD 108 diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index 9d9f484e42..ed1d930712 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -19,6 +19,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_DECRYPT), "bad decrypt"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_CIPHER_OPERATION_FAILED), "cipher operation failed"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_GENERATE_KEY), + "failed to generate key"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_GET_PARAMETER), "failed to get parameter"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SET_PARAMETER), diff --git a/providers/default/build.info b/providers/default/build.info index dd133388fc..f0a6c5c742 100644 --- a/providers/default/build.info +++ b/providers/default/build.info @@ -1,4 +1,4 @@ -SUBDIRS=digests macs +SUBDIRS=digests macs ciphers LIBS=../../libcrypto SOURCE[../../libcrypto]=\ defltprov.c diff --git a/providers/default/ciphers/build.info b/providers/default/ciphers/build.info new file mode 100644 index 0000000000..92f87e0301 --- /dev/null +++ b/providers/default/ciphers/build.info @@ -0,0 +1,22 @@ +LIBS=../../../libcrypto + +IF[{- !$disabled{des} -}] + SOURCE[../../../libcrypto]=\ + cipher_tdes_default.c cipher_tdes_default_hw.c \ + cipher_tdes_wrap.c cipher_tdes_wrap_hw.c \ + cipher_desx.c cipher_desx_hw.c +ENDIF + +IF[{- !$disabled{aria} -}] + SOURCE[../../../libcrypto]=\ + cipher_aria.c cipher_aria_hw.c \ + cipher_aria_gcm.c cipher_aria_gcm_hw.c \ + cipher_aria_ccm.c cipher_aria_ccm_hw.c +ENDIF + +IF[{- !$disabled{camellia} -}] + SOURCE[../../../libcrypto]=\ + cipher_camellia.c cipher_camellia_hw.c +ENDIF + +INCLUDE[../../../libcrypto]=. ../../../crypto diff --git a/providers/common/ciphers/cipher_aria.c b/providers/default/ciphers/cipher_aria.c similarity index 97% rename from providers/common/ciphers/cipher_aria.c rename to providers/default/ciphers/cipher_aria.c index 5b7e8398bc..861b28268b 100644 --- a/providers/common/ciphers/cipher_aria.c +++ b/providers/default/ciphers/cipher_aria.c @@ -9,7 +9,8 @@ /* Dispatch functions for ARIA cipher modes ecb, cbc, ofb, cfb, ctr */ -#include "cipher_locl.h" +#include "cipher_aria.h" +#include "internal/provider_algs.h" static OSSL_OP_cipher_freectx_fn aria_freectx; static OSSL_OP_cipher_dupctx_fn aria_dupctx; diff --git a/providers/common/ciphers/cipher_aria.h b/providers/default/ciphers/cipher_aria.h similarity index 92% rename from providers/common/ciphers/cipher_aria.h rename to providers/default/ciphers/cipher_aria.h index 2b8015f6d7..984be8f4aa 100644 --- a/providers/common/ciphers/cipher_aria.h +++ b/providers/default/ciphers/cipher_aria.h @@ -7,8 +7,8 @@ * https://www.openssl.org/source/license.html */ -#if !defined(OPENSSL_NO_ARIA) -# include "internal/aria.h" +#include "internal/aria.h" +#include "internal/ciphers/ciphercommon.h" typedef struct prov_aria_ctx_st { PROV_CIPHER_CTX base; /* Must be first */ @@ -18,6 +18,7 @@ typedef struct prov_aria_ctx_st { } ks; } PROV_ARIA_CTX; + # define PROV_CIPHER_HW_aria_ofb PROV_CIPHER_HW_aria_ofb128 # define PROV_CIPHER_HW_aria_cfb PROV_CIPHER_HW_aria_cfb128 const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_ecb(size_t keybits); @@ -27,5 +28,3 @@ const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_cfb128(size_t keybits); const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_cfb1(size_t keybits); const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_cfb8(size_t keybits); const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_ctr(size_t keybits); - -#endif /* OPENSSL_NO_ARIA */ diff --git a/providers/common/ciphers/cipher_aria_ccm.c b/providers/default/ciphers/cipher_aria_ccm.c similarity index 94% rename from providers/common/ciphers/cipher_aria_ccm.c rename to providers/default/ciphers/cipher_aria_ccm.c index 061ce53176..53b3defa9d 100644 --- a/providers/common/ciphers/cipher_aria_ccm.c +++ b/providers/default/ciphers/cipher_aria_ccm.c @@ -9,7 +9,10 @@ /* Dispatch functions for ARIA CCM mode */ -#include "cipher_locl.h" +#include "cipher_aria_ccm.h" +#include "internal/provider_algs.h" + +static OSSL_OP_cipher_freectx_fn aria_ccm_freectx; static void *aria_ccm_newctx(void *provctx, size_t keybits) { @@ -20,7 +23,6 @@ static void *aria_ccm_newctx(void *provctx, size_t keybits) return ctx; } -static OSSL_OP_cipher_freectx_fn aria_ccm_freectx; static void aria_ccm_freectx(void *vctx) { PROV_ARIA_CCM_CTX *ctx = (PROV_ARIA_CCM_CTX *)vctx; diff --git a/providers/default/ciphers/cipher_aria_ccm.h b/providers/default/ciphers/cipher_aria_ccm.h new file mode 100644 index 0000000000..b3e990766d --- /dev/null +++ b/providers/default/ciphers/cipher_aria_ccm.h @@ -0,0 +1,22 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/aria.h" +#include "internal/ciphers/ciphercommon.h" +#include "internal/ciphers/cipher_ccm.h" + +typedef struct prov_aria_ccm_ctx_st { + PROV_CCM_CTX base; /* Must be first */ + union { + OSSL_UNION_ALIGN; + ARIA_KEY ks; + } ks; /* ARIA key schedule to use */ +} PROV_ARIA_CCM_CTX; + +const PROV_CCM_HW *PROV_ARIA_HW_ccm(size_t keylen); diff --git a/providers/common/ciphers/cipher_aria_ccm_hw.inc b/providers/default/ciphers/cipher_aria_ccm_hw.c similarity index 89% rename from providers/common/ciphers/cipher_aria_ccm_hw.inc rename to providers/default/ciphers/cipher_aria_ccm_hw.c index d980fa9b97..db3a9c8ea8 100644 --- a/providers/common/ciphers/cipher_aria_ccm_hw.inc +++ b/providers/default/ciphers/cipher_aria_ccm_hw.c @@ -9,10 +9,9 @@ /*- * Generic support for ARIA CCM. - * This file is included by cipher_ccm_hw.c */ -#if !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE) +#include "cipher_aria_ccm.h" static int ccm_aria_initkey(PROV_CCM_CTX *ctx, const unsigned char *key, size_t keylen) @@ -39,4 +38,3 @@ const PROV_CCM_HW *PROV_ARIA_HW_ccm(size_t keybits) { return &ccm_aria; } -#endif /* OPENSSL_NO_ARIA */ diff --git a/providers/common/ciphers/cipher_aria_gcm.c b/providers/default/ciphers/cipher_aria_gcm.c similarity index 94% rename from providers/common/ciphers/cipher_aria_gcm.c rename to providers/default/ciphers/cipher_aria_gcm.c index c68ad2c3ae..213fc147c8 100644 --- a/providers/common/ciphers/cipher_aria_gcm.c +++ b/providers/default/ciphers/cipher_aria_gcm.c @@ -9,7 +9,8 @@ /* Dispatch functions for ARIA GCM mode */ -#include "cipher_locl.h" +#include "cipher_aria_gcm.h" +#include "internal/provider_algs.h" static void *aria_gcm_newctx(void *provctx, size_t keybits) { diff --git a/providers/default/ciphers/cipher_aria_gcm.h b/providers/default/ciphers/cipher_aria_gcm.h new file mode 100644 index 0000000000..3499ceaaf7 --- /dev/null +++ b/providers/default/ciphers/cipher_aria_gcm.h @@ -0,0 +1,22 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/aria.h" +#include "internal/ciphers/ciphercommon.h" +#include "internal/ciphers/cipher_gcm.h" + +typedef struct prov_aria_gcm_ctx_st { + PROV_GCM_CTX base; /* must be first entry in struct */ + union { + OSSL_UNION_ALIGN; + ARIA_KEY ks; + } ks; +} PROV_ARIA_GCM_CTX; + +const PROV_GCM_HW *PROV_ARIA_HW_gcm(size_t keybits); diff --git a/providers/common/ciphers/cipher_aria_gcm_hw.inc b/providers/default/ciphers/cipher_aria_gcm_hw.c similarity index 84% rename from providers/common/ciphers/cipher_aria_gcm_hw.inc rename to providers/default/ciphers/cipher_aria_gcm_hw.c index fcb9bfce2b..ed1e1851dc 100644 --- a/providers/common/ciphers/cipher_aria_gcm_hw.inc +++ b/providers/default/ciphers/cipher_aria_gcm_hw.c @@ -9,10 +9,9 @@ /*- * Generic support for ARIA GCM. - * This file is included by cipher_gcm_hw.c */ -#if !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE) +#include "cipher_aria_gcm.h" static int aria_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, size_t keylen) @@ -20,7 +19,7 @@ static int aria_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, PROV_ARIA_GCM_CTX *actx = (PROV_ARIA_GCM_CTX *)ctx; ARIA_KEY *ks = &actx->ks.ks; - SET_KEY_CTR_FN(ks, aria_set_encrypt_key, aria_encrypt, NULL); + GCM_HW_SET_KEY_CTR_FN(ks, aria_set_encrypt_key, aria_encrypt, NULL); return 1; } @@ -49,5 +48,3 @@ const PROV_GCM_HW *PROV_ARIA_HW_gcm(size_t keybits) { return &aria_gcm; } - -#endif /* !defined(OPENSSL_NO_ARIA) && !defined(FIPS_MODE) */ diff --git a/providers/common/ciphers/cipher_aria_hw.c b/providers/default/ciphers/cipher_aria_hw.c similarity index 98% rename from providers/common/ciphers/cipher_aria_hw.c rename to providers/default/ciphers/cipher_aria_hw.c index 2a89573521..b644be8dda 100644 --- a/providers/common/ciphers/cipher_aria_hw.c +++ b/providers/default/ciphers/cipher_aria_hw.c @@ -7,7 +7,7 @@ * https://www.openssl.org/source/license.html */ -#include "cipher_locl.h" +#include "cipher_aria.h" static int cipher_hw_aria_initkey(PROV_CIPHER_CTX *dat, const unsigned char *key, size_t keylen) diff --git a/providers/common/ciphers/cipher_camellia.c b/providers/default/ciphers/cipher_camellia.c similarity index 97% rename from providers/common/ciphers/cipher_camellia.c rename to providers/default/ciphers/cipher_camellia.c index 9215346924..68c0e91355 100644 --- a/providers/common/ciphers/cipher_camellia.c +++ b/providers/default/ciphers/cipher_camellia.c @@ -9,9 +9,9 @@ /* Dispatch functions for CAMELLIA cipher modes ecb, cbc, ofb, cfb, ctr */ -#include "cipher_locl.h" +#include "cipher_camellia.h" +#include "internal/provider_algs.h" -#if !defined(OPENSSL_NO_CAMELLIA) static OSSL_OP_cipher_freectx_fn camellia_freectx; static OSSL_OP_cipher_dupctx_fn camellia_dupctx; @@ -79,4 +79,3 @@ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ctr, CTR, 0, 192, 8, 128, stream) /* camellia128ctr_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ctr, CTR, 0, 128, 8, 128, stream) -#endif /* OPENSSL_NO_CAMELLIA */ diff --git a/providers/common/ciphers/cipher_camellia.h b/providers/default/ciphers/cipher_camellia.h similarity index 81% rename from providers/common/ciphers/cipher_camellia.h rename to providers/default/ciphers/cipher_camellia.h index e8e96bad81..521c03e261 100644 --- a/providers/common/ciphers/cipher_camellia.h +++ b/providers/default/ciphers/cipher_camellia.h @@ -7,9 +7,8 @@ * https://www.openssl.org/source/license.html */ -#ifndef OPENSSL_NO_CAMELLIA - -# include +#include "openssl/camellia.h" +#include "internal/ciphers/ciphercommon.h" typedef struct prov_camellia_ctx_st { PROV_CIPHER_CTX base; /* Must be first */ @@ -19,8 +18,8 @@ typedef struct prov_camellia_ctx_st { } ks; } PROV_CAMELLIA_CTX; -# define PROV_CIPHER_HW_camellia_ofb PROV_CIPHER_HW_camellia_ofb128 -# define PROV_CIPHER_HW_camellia_cfb PROV_CIPHER_HW_camellia_cfb128 +#define PROV_CIPHER_HW_camellia_ofb PROV_CIPHER_HW_camellia_ofb128 +#define PROV_CIPHER_HW_camellia_cfb PROV_CIPHER_HW_camellia_cfb128 const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_ecb(size_t keybits); const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_cbc(size_t keybits); const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_ofb128(size_t keybits); @@ -28,5 +27,3 @@ const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_cfb128(size_t keybits); const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_cfb1(size_t keybits); const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_cfb8(size_t keybits); const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_ctr(size_t keybits); - -#endif /* OPENSSL_NO_CAMELLIA */ diff --git a/providers/common/ciphers/cipher_camellia_hw.c b/providers/default/ciphers/cipher_camellia_hw.c similarity index 96% rename from providers/common/ciphers/cipher_camellia_hw.c rename to providers/default/ciphers/cipher_camellia_hw.c index dd65b31aef..39ba4bd0ac 100644 --- a/providers/common/ciphers/cipher_camellia_hw.c +++ b/providers/default/ciphers/cipher_camellia_hw.c @@ -7,9 +7,9 @@ * https://www.openssl.org/source/license.html */ -#include "cipher_locl.h" +#include "cipher_camellia.h" +#include -#if !defined(OPENSSL_NO_CAMELLIA) static int cipher_hw_camellia_initkey(PROV_CIPHER_CTX *dat, const unsigned char *key, size_t keylen) { @@ -62,4 +62,3 @@ PROV_CIPHER_HW_camellia_mode(cfb128) PROV_CIPHER_HW_camellia_mode(cfb1) PROV_CIPHER_HW_camellia_mode(cfb8) PROV_CIPHER_HW_camellia_mode(ctr) -#endif /* OPENSSL_NO_CAMELLIA */ diff --git a/providers/common/ciphers/cipher_camellia_hw_t4.inc b/providers/default/ciphers/cipher_camellia_hw_t4.inc similarity index 100% rename from providers/common/ciphers/cipher_camellia_hw_t4.inc rename to providers/default/ciphers/cipher_camellia_hw_t4.inc diff --git a/providers/default/ciphers/cipher_desx.c b/providers/default/ciphers/cipher_desx.c new file mode 100644 index 0000000000..4a232cd080 --- /dev/null +++ b/providers/default/ciphers/cipher_desx.c @@ -0,0 +1,15 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "cipher_tdes_default.h" +#include "internal/provider_algs.h" + +/* desx_cbc_functions */ +IMPLEMENT_tdes_cipher(desx, DESX, cbc, CBC, TDES_FLAGS, 64*3, 64, 64, block); + diff --git a/providers/default/ciphers/cipher_desx_hw.c b/providers/default/ciphers/cipher_desx_hw.c new file mode 100644 index 0000000000..ef1b3b0694 --- /dev/null +++ b/providers/default/ciphers/cipher_desx_hw.c @@ -0,0 +1,62 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "cipher_tdes_default.h" + +/* + * Note the PROV_TDES_CTX has been used for the DESX cipher, just to reduce + * code size. + */ +#define ks1 tks.ks[0] +#define ks2 tks.ks[1].ks[0].cblock +#define ks3 tks.ks[2].ks[0].cblock + +static int cipher_hw_desx_cbc_initkey(PROV_CIPHER_CTX *ctx, + const unsigned char *key, size_t keylen) +{ + PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; + DES_cblock *deskey = (DES_cblock *)key; + + DES_set_key_unchecked(deskey, &tctx->ks1); + memcpy(&tctx->ks2, &key[8], 8); + memcpy(&tctx->ks3, &key[16], 8); + + return 1; +} + +static int cipher_hw_desx_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; + + while (inl >= MAXCHUNK) { + DES_xcbc_encrypt(in, out, (long)MAXCHUNK, &tctx->ks1, + (DES_cblock *)ctx->iv, &tctx->ks2, &tctx->ks3, + ctx->enc); + inl -= MAXCHUNK; + in += MAXCHUNK; + out += MAXCHUNK; + } + if (inl > 0) + DES_xcbc_encrypt(in, out, (long)inl, &tctx->ks1, + (DES_cblock *)ctx->iv, &tctx->ks2, &tctx->ks3, + ctx->enc); + return 1; +} + +static const PROV_CIPHER_HW desx_cbc = +{ + cipher_hw_desx_cbc_initkey, + cipher_hw_desx_cbc +}; +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_desx_cbc(void) +{ + return &desx_cbc; +} diff --git a/providers/default/ciphers/cipher_tdes_default.c b/providers/default/ciphers/cipher_tdes_default.c new file mode 100644 index 0000000000..73a78e8089 --- /dev/null +++ b/providers/default/ciphers/cipher_tdes_default.c @@ -0,0 +1,29 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "cipher_tdes_default.h" +#include "internal/provider_algs.h" + +/* tdes_ede3_ofb_functions */ +IMPLEMENT_tdes_cipher(ede3, EDE3, ofb, OFB, TDES_FLAGS, 64*3, 8, 64, stream); +/* tdes_ede3_cfb_functions */ +IMPLEMENT_tdes_cipher(ede3, EDE3, cfb, CFB, TDES_FLAGS, 64*3, 8, 64, stream); +/* tdes_ede3_cfb1_functions */ +IMPLEMENT_tdes_cipher(ede3, EDE3, cfb1, CFB, TDES_FLAGS, 64*3, 8, 64, stream); +/* tdes_ede3_cfb8_functions */ +IMPLEMENT_tdes_cipher(ede3, EDE3, cfb8, CFB, TDES_FLAGS, 64*3, 8, 64, stream); + +/* tdes_ede2_ecb_functions */ +IMPLEMENT_tdes_cipher(ede2, EDE2, ecb, ECB, TDES_FLAGS, 64*2, 64, 64, block); +/* tdes_ede2_cbc_functions */ +IMPLEMENT_tdes_cipher(ede2, EDE2, cbc, CBC, TDES_FLAGS, 64*2, 64, 64, block); +/* tdes_ede2_ofb_functions */ +IMPLEMENT_tdes_cipher(ede2, EDE2, ofb, OFB, TDES_FLAGS, 64*2, 8, 64, stream); +/* tdes_ede2_cfb_functions */ +IMPLEMENT_tdes_cipher(ede2, EDE2, cfb, CFB, TDES_FLAGS, 64*2, 8, 64, stream); diff --git a/providers/default/ciphers/cipher_tdes_default.h b/providers/default/ciphers/cipher_tdes_default.h new file mode 100644 index 0000000000..c809993795 --- /dev/null +++ b/providers/default/ciphers/cipher_tdes_default.h @@ -0,0 +1,25 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/ciphers/ciphercommon.h" +#include "internal/ciphers/cipher_tdes.h" + +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_ofb(void); +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_cfb(void); +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_cfb1(void); +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_cfb8(void); + +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede2_cbc(void); +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede2_ecb(void); +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede2_ofb(void); +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede2_cfb(void); + +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_desx_cbc(void); + +const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_wrap_cbc(void); diff --git a/providers/default/ciphers/cipher_tdes_default_hw.c b/providers/default/ciphers/cipher_tdes_default_hw.c new file mode 100644 index 0000000000..73169a0e56 --- /dev/null +++ b/providers/default/ciphers/cipher_tdes_default_hw.c @@ -0,0 +1,140 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "cipher_tdes_default.h" + +#define ks1 tks.ks[0] +#define ks2 tks.ks[1] +#define ks3 tks.ks[2] + +static int cipher_hw_tdes_ede2_initkey(PROV_CIPHER_CTX *ctx, + const unsigned char *key, size_t keylen) +{ + PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; + DES_cblock *deskey = (DES_cblock *)key; + + tctx->tstream.cbc = NULL; +# if defined(SPARC_DES_CAPABLE) + if (SPARC_DES_CAPABLE) { + if (ctx->mode == EVP_CIPH_CBC_MODE) { + des_t4_key_expand(&deskey[0], &tctx->ks1); + des_t4_key_expand(&deskey[1], &tctx->ks2); + memcpy(&tctx->ks3, &tctx->ks1, sizeof(tctx->ks1)); + tctx->tstream.cbc = ctx->enc ? des_t4_ede3_cbc_encrypt : + des_t4_ede3_cbc_decrypt; + return 1; + } + } +# endif + DES_set_key_unchecked(&deskey[0], &tctx->ks1); + DES_set_key_unchecked(&deskey[1], &tctx->ks2); + memcpy(&tctx->ks3, &tctx->ks1, sizeof(tctx->ks1)); + return 1; +} + +static int cipher_hw_tdes_ofb(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; + int num = ctx->num; + + while (inl >= MAXCHUNK) { + DES_ede3_ofb64_encrypt(in, out, (long)MAXCHUNK, &tctx->ks1, &tctx->ks2, + &tctx->ks3, (DES_cblock *)ctx->iv, &num); + inl -= MAXCHUNK; + in += MAXCHUNK; + out += MAXCHUNK; + } + if (inl > 0) { + DES_ede3_ofb64_encrypt(in, out, (long)inl, &tctx->ks1, &tctx->ks2, + &tctx->ks3, (DES_cblock *)ctx->iv, &num); + } + ctx->num = num; + return 1; +} + +static int cipher_hw_tdes_cfb(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; + int num = ctx->num; + + while (inl >= MAXCHUNK) { + + DES_ede3_cfb64_encrypt(in, out, (long)MAXCHUNK, + &tctx->ks1, &tctx->ks2, &tctx->ks3, + (DES_cblock *)ctx->iv, &num, ctx->enc); + inl -= MAXCHUNK; + in += MAXCHUNK; + out += MAXCHUNK; + } + if (inl > 0) { + DES_ede3_cfb64_encrypt(in, out, (long)inl, + &tctx->ks1, &tctx->ks2, &tctx->ks3, + (DES_cblock *)ctx->iv, &num, ctx->enc); + } + ctx->num = num; + return 1; +} + +/* + * Although we have a CFB-r implementation for 3-DES, it doesn't pack the + * right way, so wrap it here + */ +static int cipher_hw_tdes_cfb1(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; + size_t n; + unsigned char c[1], d[1]; + + if ((ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) == 0) + inl *= 8; + for (n = 0; n < inl; ++n) { + c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; + DES_ede3_cfb_encrypt(c, d, 1, 1, + &tctx->ks1, &tctx->ks2, &tctx->ks3, + (DES_cblock *)ctx->iv, ctx->enc); + out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) + | ((d[0] & 0x80) >> (unsigned int)(n % 8)); + } + + return 1; +} + +static int cipher_hw_tdes_cfb8(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; + + while (inl >= MAXCHUNK) { + DES_ede3_cfb_encrypt(in, out, 8, (long)MAXCHUNK, + &tctx->ks1, &tctx->ks2, &tctx->ks3, + (DES_cblock *)ctx->iv, ctx->enc); + inl -= MAXCHUNK; + in += MAXCHUNK; + out += MAXCHUNK; + } + if (inl > 0) + DES_ede3_cfb_encrypt(in, out, 8, (long)inl, + &tctx->ks1, &tctx->ks2, &tctx->ks3, + (DES_cblock *)ctx->iv, ctx->enc); + return 1; +} + +PROV_CIPHER_HW_tdes_mode(ede3, ofb) +PROV_CIPHER_HW_tdes_mode(ede3, cfb) +PROV_CIPHER_HW_tdes_mode(ede3, cfb1) +PROV_CIPHER_HW_tdes_mode(ede3, cfb8) + +PROV_CIPHER_HW_tdes_mode(ede2, ecb) +PROV_CIPHER_HW_tdes_mode(ede2, cbc) +PROV_CIPHER_HW_tdes_mode(ede2, ofb) +PROV_CIPHER_HW_tdes_mode(ede2, cfb) + diff --git a/providers/default/ciphers/cipher_tdes_wrap.c b/providers/default/ciphers/cipher_tdes_wrap.c new file mode 100644 index 0000000000..833e18190a --- /dev/null +++ b/providers/default/ciphers/cipher_tdes_wrap.c @@ -0,0 +1,199 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "cipher_tdes_default.h" +#include "internal/evp_int.h" +#include "internal/rand_int.h" +#include "internal/provider_algs.h" +#include "internal/providercommonerr.h" + +/* TODO (3.0) Figure out what flags are requred */ +#define TDES_WRAP_FLAGS (EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV \ + | EVP_CIPH_FLAG_CUSTOM_CIPHER \ + | EVP_CIPH_FLAG_DEFAULT_ASN1) + + +static OSSL_OP_cipher_update_fn tdes_wrap_update; +static OSSL_OP_cipher_cipher_fn tdes_wrap_cipher; + +static const unsigned char wrap_iv[8] = +{ + 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 +}; + +static int des_ede3_unwrap(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + unsigned char icv[8], iv[TDES_IVLEN], sha1tmp[SHA_DIGEST_LENGTH]; + int rv = -1; + + if (inl < 24) + return -1; + if (out == NULL) + return inl - 16; + + memcpy(ctx->iv, wrap_iv, 8); + /* Decrypt first block which will end up as icv */ + ctx->hw->cipher(ctx, icv, in, 8); + /* Decrypt central blocks */ + /* + * If decrypting in place move whole output along a block so the next + * des_ede_cbc_cipher is in place. + */ + if (out == in) { + memmove(out, out + 8, inl - 8); + in -= 8; + } + ctx->hw->cipher(ctx, out, in + 8, inl - 16); + /* Decrypt final block which will be IV */ + ctx->hw->cipher(ctx, iv, in + inl - 8, 8); + /* Reverse order of everything */ + BUF_reverse(icv, NULL, 8); + BUF_reverse(out, NULL, inl - 16); + BUF_reverse(ctx->iv, iv, 8); + /* Decrypt again using new IV */ + ctx->hw->cipher(ctx, out, out, inl - 16); + ctx->hw->cipher(ctx, icv, icv, 8); + /* Work out SHA1 hash of first portion */ + SHA1(out, inl - 16, sha1tmp); + + if (!CRYPTO_memcmp(sha1tmp, icv, 8)) + rv = inl - 16; + OPENSSL_cleanse(icv, 8); + OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); + OPENSSL_cleanse(iv, 8); + OPENSSL_cleanse(ctx->iv, sizeof(ctx->iv)); + if (rv == -1) + OPENSSL_cleanse(out, inl - 16); + + return rv; +} + +static int des_ede3_wrap(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + unsigned char sha1tmp[SHA_DIGEST_LENGTH]; + size_t ivlen = TDES_IVLEN; + size_t icvlen = TDES_IVLEN; + size_t len = inl + ivlen + icvlen; + + if (out == NULL) + return len; + + /* Copy input to output buffer + 8 so we have space for IV */ + memmove(out + ivlen, in, inl); + /* Work out ICV */ + SHA1(in, inl, sha1tmp); + memcpy(out + inl + ivlen, sha1tmp, icvlen); + OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); + /* Generate random IV */ + if (rand_bytes_ex(ctx->libctx, ctx->iv, ivlen) <= 0) + return 0; + memcpy(out, ctx->iv, ivlen); + /* Encrypt everything after IV in place */ + ctx->hw->cipher(ctx, out + ivlen, out + ivlen, inl + ivlen); + BUF_reverse(out, NULL, len); + memcpy(ctx->iv, wrap_iv, ivlen); + ctx->hw->cipher(ctx, out, out, len); + return len; +} + +static int tdes_wrap_cipher_internal(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + /* + * Sanity check input length: we typically only wrap keys so EVP_MAXCHUNK + * is more than will ever be needed. Also input length must be a multiple + * of 8 bits. + */ + if (inl >= EVP_MAXCHUNK || inl % 8) + return -1; + if (ctx->enc) + return des_ede3_wrap(ctx, out, in, inl); + else + return des_ede3_unwrap(ctx, out, in, inl); +} + +static int tdes_wrap_cipher(void *vctx, + unsigned char *out, size_t *outl, size_t outsize, + const unsigned char *in, size_t inl) +{ + PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; + int ret; + + *outl = 0; + if (outsize < inl) { + PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return -1; + } + + ret = tdes_wrap_cipher_internal(ctx, out, in, inl); + if (ret <= 0) + return 0; + + *outl = ret; + return 1; +} + +static int tdes_wrap_update(void *vctx, unsigned char *out, size_t *outl, + size_t outsize, const unsigned char *in, + size_t inl) +{ + *outl = 0; + if (outsize < inl) { + PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (!tdes_wrap_cipher(vctx, out, outl, outsize, in, inl)) { + PROVerr(0, PROV_R_CIPHER_OPERATION_FAILED); + return 0; + } + return 1; +} + + +# define IMPLEMENT_WRAP_CIPHER(flags, kbits, blkbits, ivbits) \ +static OSSL_OP_cipher_newctx_fn tdes_wrap_newctx; \ +static void *tdes_wrap_newctx(void *provctx) \ +{ \ + return tdes_newctx(provctx, EVP_CIPH_WRAP_MODE, kbits, blkbits, ivbits, \ + PROV_CIPHER_HW_tdes_wrap_cbc()); \ +} \ +static OSSL_OP_cipher_get_params_fn tdes_wrap_get_params; \ +static int tdes_wrap_get_params(OSSL_PARAM params[]) \ +{ \ + return cipher_generic_get_params(params, EVP_CIPH_WRAP_MODE, flags, \ + kbits, blkbits, ivbits); \ +} \ +const OSSL_DISPATCH tdes_wrap_cbc_functions[] = \ +{ \ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void)) tdes_einit }, \ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void)) tdes_dinit }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))tdes_wrap_cipher }, \ + { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))tdes_wrap_newctx }, \ + { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))tdes_freectx }, \ + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))tdes_wrap_update }, \ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_stream_final }, \ + { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))tdes_wrap_get_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ + (void (*)(void))cipher_generic_gettable_params }, \ + { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))tdes_get_ctx_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ + (void (*)(void))tdes_gettable_ctx_params }, \ + { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ + (void (*)(void))cipher_generic_set_ctx_params }, \ + { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ + (void (*)(void))cipher_generic_settable_ctx_params }, \ + { 0, NULL } \ +} + +/* tdes_wrap_cbc_functions */ +IMPLEMENT_WRAP_CIPHER(TDES_WRAP_FLAGS, 64*3, 64, 0); diff --git a/providers/default/ciphers/cipher_tdes_wrap_hw.c b/providers/default/ciphers/cipher_tdes_wrap_hw.c new file mode 100644 index 0000000000..09155b6f48 --- /dev/null +++ b/providers/default/ciphers/cipher_tdes_wrap_hw.c @@ -0,0 +1,14 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "cipher_tdes_default.h" + +#define cipher_hw_tdes_wrap_initkey cipher_hw_tdes_ede3_initkey + +PROV_CIPHER_HW_tdes_mode(wrap, cbc) diff --git a/providers/default/defltprov.c b/providers/default/defltprov.c index 5664fbe3b2..2498d068df 100644 --- a/providers/default/defltprov.c +++ b/providers/default/defltprov.c @@ -173,6 +173,18 @@ static const OSSL_ALGORITHM deflt_ciphers[] = { { "CAMELLIA-192-CTR", "default=yes", camellia192ctr_functions }, { "CAMELLIA-128-CTR", "default=yes", camellia128ctr_functions }, #endif /* OPENSSL_NO_CAMELLIA */ + { "DES-EDE3", "default=yes", tdes_ede3_ecb_functions }, + { "DES-EDE3-CBC", "default=yes", tdes_ede3_cbc_functions }, + { "DES-EDE3-OFB", "default=yes", tdes_ede3_ofb_functions }, + { "DES-EDE3-CFB", "default=yes", tdes_ede3_cfb_functions }, + { "DES-EDE3-CFB8", "default=yes", tdes_ede3_cfb8_functions }, + { "DES-EDE3-CFB1", "default=yes", tdes_ede3_cfb1_functions }, + { "DES-EDE", "default=yes", tdes_ede2_ecb_functions }, + { "DES-EDE-CBC", "default=yes", tdes_ede2_cbc_functions }, + { "DES-EDE-OFB", "default=yes", tdes_ede2_ofb_functions }, + { "DES-EDE-CFB", "default=yes", tdes_ede2_cfb_functions }, + { "DESX-CBC", "default=yes", tdes_desx_cbc_functions }, + { "id-smime-alg-CMS3DESwrap", "default=yes", tdes_wrap_cbc_functions }, { NULL, NULL, NULL } }; diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 839581bbe9..8e68a6c843 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -324,6 +324,8 @@ static const OSSL_ALGORITHM fips_ciphers[] = { { "id-aes256-CCM", "fips=yes", aes256ccm_functions }, { "id-aes192-CCM", "fips=yes", aes192ccm_functions }, { "id-aes128-CCM", "fips=yes", aes128ccm_functions }, + { "DES-EDE3", "fips=yes", tdes_ede3_ecb_functions }, + { "DES-EDE3-CBC", "fips=yes", tdes_ede3_cbc_functions }, { NULL, NULL, NULL } }; diff --git a/test/recipes/30-test_evp_data/evpciph.txt b/test/recipes/30-test_evp_data/evpciph.txt index bd2778e398..28820ecf52 100644 --- a/test/recipes/30-test_evp_data/evpciph.txt +++ b/test/recipes/30-test_evp_data/evpciph.txt @@ -22,12 +22,14 @@ Title = DES Tests (various sources) Cipher = DES-EDE3-CFB1 +Availablein = default Key = 000102030405060708090A0B0C0D0E0F1011121314151617 IV = 0001020304050607 Plaintext = "Hello World" Ciphertext = 3CF55D656E9C0664513358 Cipher = DES-EDE3-CFB1 +Availablein = default Key = 000102030405060708090A0B0C0D0E0F1011121314151617 IV = 0001020304050607 Operation = DECRYPT @@ -35,6 +37,7 @@ Plaintext = "Hello World" Ciphertext = 3CF55D656E9C0664513358 Cipher = DESX-CBC +Availablein = default Key = 0123456789abcdeff1e0d3c2b5a49786fedcba9876543210 IV = fedcba9876543210 Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000 @@ -50,36 +53,43 @@ Ciphertext = 3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675 # DES ECB tests (from destest) Cipher = DES-ECB +Availablein = default Key = 0000000000000000 Plaintext = 0000000000000000 Ciphertext = 8CA64DE9C1B123A7 Cipher = DES-ECB +Availablein = default Key = FFFFFFFFFFFFFFFF Plaintext = FFFFFFFFFFFFFFFF Ciphertext = 7359B2163E4EDC58 Cipher = DES-ECB +Availablein = default Key = 3000000000000000 Plaintext = 1000000000000001 Ciphertext = 958E6E627A05557B Cipher = DES-ECB +Availablein = default Key = 1111111111111111 Plaintext = 1111111111111111 Ciphertext = F40379AB9E0EC533 Cipher = DES-ECB +Availablein = default Key = 0123456789ABCDEF Plaintext = 1111111111111111 Ciphertext = 17668DFC7292532D Cipher = DES-ECB +Availablein = default Key = 1111111111111111 Plaintext = 0123456789ABCDEF Ciphertext = 8A5AE1F81AB8F2DD Cipher = DES-ECB +Availablein = default Key = FEDCBA9876543210 Plaintext = 0123456789ABCDEF Ciphertext = ED39D950FA74BCC4