diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2021-05-27 18:08:53 +1000 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2021-06-01 15:22:30 +1000 |
commit | e2311445bbfc9e2a6ff05e467cf13475b058d0a2 (patch) | |
tree | fcb1072a80cc78fdaa5dc6685a7d4d0968c21106 | |
parent | d11dd381c561db5c5144e575ac6db63e07d5507b (diff) |
Fix aes cfb1 so that it can operate in bit mode.
The code to handle the cipher operation was already in the provider.
It just needed a OSSL_PARAM in order to set this into the algorithm.
EVP_CIPHER_CTX_set_flags() has been modified to pass the OSSL_PARAM.
Issue reported by Mark Powers from Acumen.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15496)
-rw-r--r-- | crypto/evp/evp_lib.c | 17 | ||||
-rw-r--r-- | include/openssl/core_names.h | 1 | ||||
-rw-r--r-- | providers/implementations/ciphers/ciphercommon.c | 11 | ||||
-rw-r--r-- | test/acvp_test.c | 49 |
4 files changed, 78 insertions, 0 deletions
diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index adae97b8f5..bc872c0e79 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -1058,14 +1058,31 @@ int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags) return (ctx->flags & flags); } +static int evp_cipher_ctx_enable_use_bits(EVP_CIPHER_CTX *ctx, + unsigned int enable) +{ + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_USE_BITS, &enable); + return EVP_CIPHER_CTX_set_params(ctx, params); +} + void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags) { + int oldflags = ctx->flags; + ctx->flags |= flags; + if (((oldflags ^ ctx->flags) & EVP_CIPH_FLAG_LENGTH_BITS) != 0) + evp_cipher_ctx_enable_use_bits(ctx, 1); } void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags) { + int oldflags = ctx->flags; + ctx->flags &= ~flags; + if (((oldflags ^ ctx->flags) & EVP_CIPH_FLAG_LENGTH_BITS) != 0) + evp_cipher_ctx_enable_use_bits(ctx, 0); } int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags) diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h index e4601a51ab..5ecde3c994 100644 --- a/include/openssl/core_names.h +++ b/include/openssl/core_names.h @@ -65,6 +65,7 @@ extern "C" { /* cipher parameters */ #define OSSL_CIPHER_PARAM_PADDING "padding" /* uint */ +#define OSSL_CIPHER_PARAM_USE_BITS "use-bits" /* uint */ #define OSSL_CIPHER_PARAM_TLS_VERSION "tls-version" /* uint */ #define OSSL_CIPHER_PARAM_TLS_MAC "tls-mac" /* octet_ptr */ #define OSSL_CIPHER_PARAM_TLS_MAC_SIZE "tls-mac-size" /* size_t */ diff --git a/providers/implementations/ciphers/ciphercommon.c b/providers/implementations/ciphers/ciphercommon.c index f84f7a36c2..3c8ea8c03c 100644 --- a/providers/implementations/ciphers/ciphercommon.c +++ b/providers/implementations/ciphers/ciphercommon.c @@ -95,6 +95,7 @@ CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(ossl_cipher_generic) CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(ossl_cipher_generic) CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(ossl_cipher_generic) +OSSL_PARAM_uint(OSSL_CIPHER_PARAM_USE_BITS, NULL), OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS_VERSION, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS_MAC_SIZE, NULL), CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(ossl_cipher_generic) @@ -598,6 +599,16 @@ int ossl_cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[]) } ctx->pad = pad ? 1 : 0; } + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_USE_BITS); + if (p != NULL) { + unsigned int bits; + + if (!OSSL_PARAM_get_uint(p, &bits)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + ctx->use_bits = bits ? 1 : 0; + } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_VERSION); if (p != NULL) { if (!OSSL_PARAM_get_uint(p, &ctx->tlsversion)) { diff --git a/test/acvp_test.c b/test/acvp_test.c index 339c2fb965..84009193c2 100644 --- a/test/acvp_test.c +++ b/test/acvp_test.c @@ -1387,6 +1387,54 @@ err: return res; } +static int aes_cfb1_bits_test(void) +{ + int ret = 0; + EVP_CIPHER *cipher = NULL; + EVP_CIPHER_CTX *ctx = NULL; + unsigned char out[16] = { 0 }; + int outlen; + const OSSL_PARAM *params, *p; + + static const unsigned char key[] = { + 0x12, 0x22, 0x58, 0x2F, 0x1C, 0x1A, 0x8A, 0x88, + 0x30, 0xFC, 0x18, 0xB7, 0x24, 0x89, 0x7F, 0xC0 + }; + static const unsigned char iv[] = { + 0x05, 0x28, 0xB5, 0x2B, 0x58, 0x27, 0x63, 0x5C, + 0x81, 0x86, 0xD3, 0x63, 0x60, 0xB0, 0xAA, 0x2B + }; + static const unsigned char pt[] = { + 0xB4 + }; + static const unsigned char expected[] = { + 0x6C + }; + + if (!TEST_ptr(cipher = EVP_CIPHER_fetch(libctx, "AES-128-CFB1", "fips=yes"))) + goto err; + if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())) + goto err; + if (!TEST_int_gt(EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1), 0)) + goto err; + if (!TEST_ptr(params = EVP_CIPHER_CTX_settable_params(ctx)) + || !TEST_ptr(p = OSSL_PARAM_locate_const(params, + OSSL_CIPHER_PARAM_USE_BITS))) + goto err; + EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS); + if (!TEST_int_gt(EVP_CipherUpdate(ctx, out, &outlen, pt, 7), 0)) + goto err; + if (!TEST_int_eq(outlen, 7)) + goto err; + if (!TEST_mem_eq(out, (outlen + 7) / 8, expected, sizeof(expected))) + goto err; + ret = 1; +err: + EVP_CIPHER_free(cipher); + EVP_CIPHER_CTX_free(ctx); + return ret; +} + int setup_tests(void) { char *config_file = NULL; @@ -1411,6 +1459,7 @@ int setup_tests(void) OSSL_SELF_TEST_set_callback(libctx, self_test_events, &self_test_args); + ADD_TEST(aes_cfb1_bits_test); ADD_ALL_TESTS(cipher_enc_dec_test, OSSL_NELEM(cipher_enc_data)); ADD_ALL_TESTS(aes_ccm_enc_dec_test, OSSL_NELEM(aes_ccm_enc_data)); ADD_ALL_TESTS(aes_gcm_enc_dec_test, OSSL_NELEM(aes_gcm_enc_data)); |