]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix aes cfb1 so that it can operate in bit mode.
authorShane Lontis <shane.lontis@oracle.com>
Thu, 27 May 2021 08:08:53 +0000 (18:08 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Tue, 1 Jun 2021 05:22:30 +0000 (15:22 +1000)
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)

crypto/evp/evp_lib.c
include/openssl/core_names.h
providers/implementations/ciphers/ciphercommon.c
test/acvp_test.c

index adae97b8f5c342e932977f73e690f0107f17b72c..bc872c0e79c14dfe9d7e778f18a067badbce4dc5 100644 (file)
@@ -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)
index e4601a51abfdbf83176c6897e2958438c07ee8a8..5ecde3c994c40311135c745058f5a8c421a50ccb 100644 (file)
@@ -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 */
index f84f7a36c222e9504bc1a4375d7c27934c3518b6..3c8ea8c03ca5b6da78bc1f85c1af5e81342d0eae 100644 (file)
@@ -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)) {
index 339c2fb9652ce7647a89f9fae63e8935d1700f99..84009193c2b05039a9f0cb37d68702d7c8f8eeda 100644 (file)
@@ -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));