Implement AES CBC ciphers in the default provider
authorMatt Caswell <matt@openssl.org>
Wed, 3 Apr 2019 17:01:21 +0000 (18:01 +0100)
committerMatt Caswell <matt@openssl.org>
Fri, 19 Apr 2019 08:31:54 +0000 (09:31 +0100)
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/8700)

13 files changed:
crypto/err/openssl.txt
crypto/evp/evp_enc.c
crypto/evp/evp_err.c
crypto/evp/evp_lib.c
crypto/include/internal/evp_int.h
include/openssl/core_names.h
include/openssl/core_numbers.h
include/openssl/evp.h
include/openssl/evperr.h
providers/common/ciphers/aes.c
providers/common/include/internal/provider_algs.h
providers/default/defltprov.c
util/libcrypto.num

index 6a904d8e65719d557ea06ee242c5cbe009e8ba21..d914c5b4cb4da6afad62ab182bc64c439591797c 100644 (file)
@@ -787,6 +787,7 @@ EVP_F_EVP_CIPHER_CTX_CTRL:124:EVP_CIPHER_CTX_ctrl
 EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH:122:EVP_CIPHER_CTX_set_key_length
 EVP_F_EVP_CIPHER_CTX_SET_PADDING:237:EVP_CIPHER_CTX_set_padding
 EVP_F_EVP_CIPHER_FROM_DISPATCH:238:evp_cipher_from_dispatch
+EVP_F_EVP_CIPHER_MODE:239:EVP_CIPHER_mode
 EVP_F_EVP_CIPHER_PARAM_TO_ASN1:205:EVP_CIPHER_param_to_asn1
 EVP_F_EVP_DECRYPTFINAL_EX:101:EVP_DecryptFinal_ex
 EVP_F_EVP_DECRYPTUPDATE:166:EVP_DecryptUpdate
index 6dbc7147e41c9011750b716ee86af785b8c75542..7b22e21ee6363974ee8af77eacfd9d5c8e4d8984 100644 (file)
@@ -142,6 +142,9 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
         case NID_aes_256_ecb:
         case NID_aes_192_ecb:
         case NID_aes_128_ecb:
+        case NID_aes_256_cbc:
+        case NID_aes_192_cbc:
+        case NID_aes_128_cbc:
             break;
         default:
             goto legacy;
@@ -204,6 +207,19 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
             return 0;
     }
 
+    switch (EVP_CIPHER_mode(ctx->cipher)) {
+    case EVP_CIPH_CFB_MODE:
+    case EVP_CIPH_OFB_MODE:
+    case EVP_CIPH_CBC_MODE:
+        /* For these modes we remember the original IV for later use */
+        if (!ossl_assert(EVP_CIPHER_CTX_iv_length(ctx) <= (int)sizeof(ctx->oiv))) {
+            EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
+            return 0;
+        }
+        if (iv != NULL)
+            memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+    }
+
     if (enc) {
         if (ctx->cipher->einit == NULL) {
             EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
@@ -851,12 +867,12 @@ int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
 
         params[0].data = &pad;
 
-        if (ctx->cipher->set_params == NULL) {
+        if (ctx->cipher->ctx_set_params == NULL) {
             EVPerr(EVP_F_EVP_CIPHER_CTX_SET_PADDING, EVP_R_CTRL_NOT_IMPLEMENTED);
             return 0;
         }
 
-        if (!ctx->cipher->set_params(ctx->provctx, params))
+        if (!ctx->cipher->ctx_set_params(ctx->provctx, params))
             return 0;
     }
 
@@ -915,7 +931,7 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
     *out = *in;
     out->provctx = NULL;
 
-    if (in->fetched_cipher != NULL || !EVP_CIPHER_upref(in->fetched_cipher)) {
+    if (in->fetched_cipher != NULL && !EVP_CIPHER_upref(in->fetched_cipher)) {
         out->fetched_cipher = NULL;
         return 0;
     }
@@ -1002,6 +1018,11 @@ static void *evp_cipher_from_dispatch(int nid, const OSSL_DISPATCH *fns,
             cipher->cfinal = OSSL_get_OP_cipher_final(fns);
             fnciphcnt++;
             break;
+        case OSSL_FUNC_CIPHER_CIPHER:
+            if (cipher->ccipher != NULL)
+                break;
+            cipher->ccipher = OSSL_get_OP_cipher_cipher(fns);
+            break;
         case OSSL_FUNC_CIPHER_FREECTX:
             if (cipher->freectx != NULL)
                 break;
@@ -1018,25 +1039,41 @@ static void *evp_cipher_from_dispatch(int nid, const OSSL_DISPATCH *fns,
                 break;
             cipher->key_length = OSSL_get_OP_cipher_key_length(fns);
             break;
+        case OSSL_FUNC_CIPHER_IV_LENGTH:
+            if (cipher->iv_length != NULL)
+                break;
+            cipher->iv_length = OSSL_get_OP_cipher_iv_length(fns);
+            break;
+        case OSSL_FUNC_CIPHER_BLOCK_SIZE:
+            if (cipher->blocksize != NULL)
+                break;
+            cipher->blocksize = OSSL_get_OP_cipher_block_size(fns);
+            break;
         case OSSL_FUNC_CIPHER_GET_PARAMS:
             if (cipher->get_params != NULL)
                 break;
             cipher->get_params = OSSL_get_OP_cipher_get_params(fns);
             break;
-        case OSSL_FUNC_CIPHER_SET_PARAMS:
-            if (cipher->set_params != NULL)
+        case OSSL_FUNC_CIPHER_CTX_GET_PARAMS:
+            if (cipher->ctx_get_params != NULL)
+                break;
+            cipher->ctx_get_params = OSSL_get_OP_cipher_ctx_get_params(fns);
+            break;
+        case OSSL_FUNC_CIPHER_CTX_SET_PARAMS:
+            if (cipher->ctx_set_params != NULL)
                 break;
-            cipher->set_params = OSSL_get_OP_cipher_set_params(fns);
+            cipher->ctx_set_params = OSSL_get_OP_cipher_ctx_set_params(fns);
             break;
         }
     }
-    if ((fnciphcnt != 3 && fnciphcnt != 4)
+    if ((fnciphcnt != 0 && fnciphcnt != 3 && fnciphcnt != 4)
+            || (fnciphcnt == 0 && cipher->ccipher == NULL)
             || fnctxcnt != 2) {
         /*
          * In order to be a consistent set of functions we must have at least
          * a complete set of "encrypt" functions, or a complete set of "decrypt"
-         * functions. In both cases we need a complete set of context management
-         * functions
+         * functions, or a single "cipher" function. In all cases we need a
+         * complete set of context management functions
          */
         EVP_CIPHER_meth_free(cipher);
         EVPerr(EVP_F_EVP_CIPHER_FROM_DISPATCH, EVP_R_INVALID_PROVIDER_FUNCTIONS);
index 9c79f8655e62ccf95ea0f7aca6de23d35c3c22c8..3555c0e5f8954c42216b51ca12e04ef1aea60f9b 100644 (file)
@@ -57,6 +57,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
      "EVP_CIPHER_CTX_set_padding"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_FROM_DISPATCH, 0),
      "evp_cipher_from_dispatch"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_MODE, 0), "EVP_CIPHER_mode"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_PARAM_TO_ASN1, 0),
      "EVP_CIPHER_param_to_asn1"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, 0),
index c99dd9e898cebe46d8e3711e117c33a0498d62ef..189c953266d9eb522dba95a040128462bbbf44be 100644 (file)
@@ -11,6 +11,8 @@
 #include "internal/cryptlib.h"
 #include <openssl/evp.h>
 #include <openssl/objects.h>
+#include <openssl/params.h>
+#include <openssl/core_names.h>
 #include "internal/evp_int.h"
 #include "internal/provider.h"
 #include "evp_locl.h"
 int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
 {
     int ret;
+    const EVP_CIPHER *cipher = c->cipher;
 
-    if (c->cipher->set_asn1_parameters != NULL)
-        ret = c->cipher->set_asn1_parameters(c, type);
-    else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
-        switch (EVP_CIPHER_CTX_mode(c)) {
+    if (cipher->prov != NULL) {
+        /*
+         * The cipher has come from a provider and won't have the default flags.
+         * Find the implicit form so we can check the flags.
+         * TODO(3.0): This won't work for 3rd party ciphers we know nothing about
+         * We'll need to think of something else for those.
+         */
+        cipher = EVP_get_cipherbynid(cipher->nid);
+        if (cipher == NULL) {
+            EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, ASN1_R_UNSUPPORTED_CIPHER);
+            return -1;
+        }
+    }
+
+    if (cipher->set_asn1_parameters != NULL)
+        ret = cipher->set_asn1_parameters(c, type);
+    else if (cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
+        switch (EVP_CIPHER_mode(cipher)) {
         case EVP_CIPH_WRAP_MODE:
-            if (EVP_CIPHER_CTX_nid(c) == NID_id_smime_alg_CMS3DESwrap)
+            if (EVP_CIPHER_nid(cipher) == NID_id_smime_alg_CMS3DESwrap)
                 ASN1_TYPE_set(type, V_ASN1_NULL, NULL);
             ret = 1;
             break;
@@ -53,11 +70,22 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
 int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
 {
     int ret;
+    const EVP_CIPHER *cipher = c->cipher;
+
+    if (cipher->prov != NULL) {
+        /*
+         * The cipher has come from a provider and won't have the default flags.
+         * Find the implicit form so we can check the flags.
+         */
+        cipher = EVP_get_cipherbynid(cipher->nid);
+        if (cipher == NULL)
+            return -1;
+    }
 
-    if (c->cipher->get_asn1_parameters != NULL)
-        ret = c->cipher->get_asn1_parameters(c, type);
-    else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
-        switch (EVP_CIPHER_CTX_mode(c)) {
+    if (cipher->get_asn1_parameters != NULL)
+        ret = cipher->get_asn1_parameters(c, type);
+    else if (cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
+        switch (EVP_CIPHER_mode(cipher)) {
 
         case EVP_CIPH_WRAP_MODE:
             ret = 1;
@@ -85,19 +113,23 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
     return ret;
 }
 
-int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *ctx, ASN1_TYPE *type)
 {
     int i = 0;
     unsigned int l;
 
     if (type != NULL) {
-        l = EVP_CIPHER_CTX_iv_length(c);
-        OPENSSL_assert(l <= sizeof(c->iv));
-        i = ASN1_TYPE_get_octetstring(type, c->oiv, l);
+        unsigned char iv[EVP_MAX_IV_LENGTH];
+
+        l = EVP_CIPHER_CTX_iv_length(ctx);
+        if (!ossl_assert(l <= sizeof(iv)))
+            return -1;
+        i = ASN1_TYPE_get_octetstring(type, iv, l);
         if (i != (int)l)
             return -1;
-        else if (i > 0)
-            memcpy(c->iv, c->oiv, l);
+
+        if (!EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1))
+            return -1;
     }
     return i;
 }
@@ -175,14 +207,20 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx)
     }
 }
 
-int EVP_CIPHER_block_size(const EVP_CIPHER *e)
+int EVP_CIPHER_block_size(const EVP_CIPHER *cipher)
 {
-    return e->block_size;
+    if (cipher->prov != NULL) {
+        if (cipher->blocksize != NULL)
+            return cipher->blocksize();
+        /* We default to a block size of 1 */
+        return 1;
+    }
+    return cipher->block_size;
 }
 
 int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
 {
-    return ctx->cipher->block_size;
+    return EVP_CIPHER_block_size(ctx->cipher);
 }
 
 int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *e)
@@ -193,6 +231,12 @@ int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *e)
 int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                const unsigned char *in, unsigned int inl)
 {
+    if (ctx->cipher->prov != NULL) {
+        if (ctx->cipher->ccipher != NULL)
+            return ctx->cipher->ccipher(ctx->provctx, out, in, (size_t)inl);
+        return 0;
+    }
+
     return ctx->cipher->do_cipher(ctx, out, in, inl);
 }
 
@@ -238,12 +282,18 @@ void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data)
 
 int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
 {
+    if (cipher->prov != NULL) {
+        if (cipher->iv_length != NULL)
+            return (int)cipher->iv_length();
+        return 0;
+    }
+
     return cipher->iv_len;
 }
 
 int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
 {
-    return ctx->cipher->iv_len;
+    return EVP_CIPHER_iv_length(ctx->cipher);
 }
 
 const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx)
@@ -308,6 +358,33 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
     return ctx->cipher->nid;
 }
 
+int EVP_CIPHER_mode(const EVP_CIPHER *cipher)
+{
+    if (cipher->prov != NULL) {
+        int mode;
+
+        /* Cipher comes from a provider - so ask the provider for the mode */
+        OSSL_PARAM params[] = {
+            OSSL_PARAM_int(OSSL_CIPHER_PARAM_MODE, NULL),
+            OSSL_PARAM_END
+        };
+
+        params[0].data = &mode;
+
+        if (cipher->get_params == NULL) {
+            EVPerr(EVP_F_EVP_CIPHER_MODE, EVP_R_CTRL_NOT_IMPLEMENTED);
+            return 0;
+        }
+
+        if (!cipher->get_params(params))
+            return 0;
+
+        return mode;
+    }
+    return EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE;
+}
+
+
 int EVP_MD_block_size(const EVP_MD *md)
 {
     if (md == NULL) {
index e428a63d105b295e417e49276d0b9043ffb917cb..b3d9694618f9ddc68e029adfeb8ca12f7f65ca2e 100644 (file)
@@ -249,11 +249,15 @@ struct evp_cipher_st {
     OSSL_OP_cipher_decrypt_init_fn *dinit;
     OSSL_OP_cipher_update_fn *cupdate;
     OSSL_OP_cipher_final_fn *cfinal;
+    OSSL_OP_cipher_cipher_fn *ccipher;
     OSSL_OP_cipher_freectx_fn *freectx;
     OSSL_OP_cipher_dupctx_fn *dupctx;
     OSSL_OP_cipher_key_length_fn *key_length;
+    OSSL_OP_cipher_iv_length_fn *iv_length;
+    OSSL_OP_cipher_block_size_fn *blocksize;
     OSSL_OP_cipher_get_params_fn *get_params;
-    OSSL_OP_cipher_get_params_fn *set_params;
+    OSSL_OP_cipher_ctx_get_params_fn *ctx_get_params;
+    OSSL_OP_cipher_ctx_set_params_fn *ctx_set_params;
 } /* EVP_CIPHER */ ;
 
 /* Macros to code block cipher wrappers */
index 7a41778c2fc449214ae23dd3b9bc7fd25c07a420..35a23d74218ba4d88571473eb11d0e2ff3a4a449 100644 (file)
@@ -38,6 +38,7 @@ extern "C" {
 /* Well known cipher parameters */
 
 #define OSSL_CIPHER_PARAM_PADDING   "padding"
+#define OSSL_CIPHER_PARAM_MODE      "mode"
 
 # ifdef __cplusplus
 }
index 7b17d2cbb8d7f5e4d1d676d8d31c03685c325b07..8994374567277c792628385d1542b6f06b0b2991 100644 (file)
@@ -113,12 +113,15 @@ OSSL_CORE_MAKE_FUNC(size_t, OP_digest_block_size, (void))
 # define OSSL_FUNC_CIPHER_DECRYPT_INIT               3
 # define OSSL_FUNC_CIPHER_UPDATE                     4
 # define OSSL_FUNC_CIPHER_FINAL                      5
-# define OSSL_FUNC_CIPHER_FREECTX                    6
-# define OSSL_FUNC_CIPHER_DUPCTX                     7
-# define OSSL_FUNC_CIPHER_KEY_LENGTH                 8
-# define OSSL_FUNC_CIPHER_GET_PARAMS                 9
-# define OSSL_FUNC_CIPHER_SET_PARAMS                10
-
+# define OSSL_FUNC_CIPHER_CIPHER                     6
+# define OSSL_FUNC_CIPHER_FREECTX                    7
+# define OSSL_FUNC_CIPHER_DUPCTX                     8
+# define OSSL_FUNC_CIPHER_KEY_LENGTH                 9
+# define OSSL_FUNC_CIPHER_IV_LENGTH                 10
+# define OSSL_FUNC_CIPHER_BLOCK_SIZE                11
+# define OSSL_FUNC_CIPHER_GET_PARAMS                12
+# define OSSL_FUNC_CIPHER_CTX_GET_PARAMS            13
+# define OSSL_FUNC_CIPHER_CTX_SET_PARAMS            14
 
 OSSL_CORE_MAKE_FUNC(void *, OP_cipher_newctx, (void))
 OSSL_CORE_MAKE_FUNC(int, OP_cipher_encrypt_init, (void *vctx,
@@ -138,10 +141,13 @@ OSSL_CORE_MAKE_FUNC(int, OP_cipher_cipher,
 OSSL_CORE_MAKE_FUNC(void, OP_cipher_freectx, (void *vctx))
 OSSL_CORE_MAKE_FUNC(void *, OP_cipher_dupctx, (void *vctx))
 OSSL_CORE_MAKE_FUNC(size_t, OP_cipher_key_length, (void))
-OSSL_CORE_MAKE_FUNC(int, OP_cipher_get_params, (void *vctx,
-                                                const OSSL_PARAM params[]))
-OSSL_CORE_MAKE_FUNC(int, OP_cipher_set_params, (void *vctx,
-                                                const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(size_t, OP_cipher_iv_length, (void))
+OSSL_CORE_MAKE_FUNC(size_t, OP_cipher_block_size, (void))
+OSSL_CORE_MAKE_FUNC(int, OP_cipher_get_params, (const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(int, OP_cipher_ctx_get_params, (void *vctx,
+                                                    const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(int, OP_cipher_ctx_set_params, (void *vctx,
+                                                    const OSSL_PARAM params[]))
 
 
 # ifdef __cplusplus
index 0db98573046e67e5245038b93da5da9edc7ce5e1..6fc0f351148cfc3c4b6e8df3002c6a1a78758517 100644 (file)
@@ -474,7 +474,7 @@ int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *cipher);
 int EVP_CIPHER_key_length(const EVP_CIPHER *cipher);
 int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher);
 unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher);
-# define EVP_CIPHER_mode(e)              (EVP_CIPHER_flags(e) & EVP_CIPH_MODE)
+int EVP_CIPHER_mode(const EVP_CIPHER *cipher);
 EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
                              const char *properties);
 
index 417d6ae57124412bec7742ecd135cd83f0ac4362..d88d4a8403e414fb1c46ec0d09bcbed114ed159c 100644 (file)
@@ -57,6 +57,7 @@ int ERR_load_EVP_strings(void);
 # define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH              122
 # define EVP_F_EVP_CIPHER_CTX_SET_PADDING                 237
 # define EVP_F_EVP_CIPHER_FROM_DISPATCH                   238
+# define EVP_F_EVP_CIPHER_MODE                            239
 # define EVP_F_EVP_CIPHER_PARAM_TO_ASN1                   205
 # define EVP_F_EVP_DECRYPTFINAL_EX                        101
 # define EVP_F_EVP_DECRYPTUPDATE                          166
index 6a46e869100179c8d0e491f162da9a5ad6b86cbf..3a278db6db0ab5cef8323c7779b60955d262277d 100644 (file)
@@ -135,38 +135,52 @@ static int aes_final(void *vctx, unsigned char *out, size_t *outl)
     return 1;
 }
 
-static void *aes_256_ecb_newctx(void)
+static int aes_cipher(void *vctx, unsigned char *out, const unsigned char *in,
+                      size_t inl)
 {
-    PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx));
+    PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
+
+    if (!ctx->ciph->cipher(ctx, out, in, inl))
+        return 0;
 
-    ctx->pad = 1;
-    ctx->keylen = 256 / 8;
-    ctx->ciph = PROV_AES_CIPHER_ecb();
-    ctx->mode = EVP_CIPH_ECB_MODE;
-    return ctx;
+    return 1;
 }
 
-static void *aes_192_ecb_newctx(void)
-{
-    PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx));
+#define IMPLEMENT_new_params(lcmode, UCMODE) \
+    static int aes_##lcmode##_get_params(const OSSL_PARAM params[]) \
+    { \
+        const OSSL_PARAM *p; \
+    \
+        p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); \
+        if (p != NULL && !OSSL_PARAM_set_int(p, EVP_CIPH_##UCMODE##_MODE)) \
+            return 0; \
+    \
+        return 1; \
+    }
 
-    ctx->pad = 1;
-    ctx->keylen = 192 / 8;
-    ctx->ciph = PROV_AES_CIPHER_ecb();
-    ctx->mode = EVP_CIPH_ECB_MODE;
-    return ctx;
-}
+#define IMPLEMENT_new_ctx(lcmode, UCMODE, len) \
+    static void *aes_##len##_##lcmode##_newctx(void) \
+    { \
+        PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx)); \
+    \
+        ctx->pad = 1; \
+        ctx->keylen = (len / 8); \
+        ctx->ciph = PROV_AES_CIPHER_##lcmode(); \
+        ctx->mode = EVP_CIPH_##UCMODE##_MODE; \
+        return ctx; \
+    }
 
-static void *aes_128_ecb_newctx(void)
-{
-    PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx));
+/* ECB */
+IMPLEMENT_new_params(ecb, ECB)
+IMPLEMENT_new_ctx(ecb, ECB, 256)
+IMPLEMENT_new_ctx(ecb, ECB, 192)
+IMPLEMENT_new_ctx(ecb, ECB, 128)
 
-    ctx->pad = 1;
-    ctx->keylen = 128 / 8;
-    ctx->ciph = PROV_AES_CIPHER_ecb();
-    ctx->mode = EVP_CIPH_ECB_MODE;
-    return ctx;
-}
+/* CBC */
+IMPLEMENT_new_params(cbc, CBC)
+IMPLEMENT_new_ctx(cbc, CBC, 256)
+IMPLEMENT_new_ctx(cbc, CBC, 192)
+IMPLEMENT_new_ctx(cbc, CBC, 128)
 
 static void aes_freectx(void *vctx)
 {
@@ -200,7 +214,22 @@ static size_t key_length_128(void)
     return 128 / 8;
 }
 
-static int aes_get_params(void *vctx, const OSSL_PARAM params[])
+static size_t iv_length_16(void)
+{
+    return 16;
+}
+
+static size_t iv_length_0(void)
+{
+    return 0;
+}
+
+static size_t block_size_16(void)
+{
+    return 16;
+}
+
+static int aes_ctx_get_params(void *vctx, const OSSL_PARAM params[])
 {
     PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
     const OSSL_PARAM *p;
@@ -212,7 +241,7 @@ static int aes_get_params(void *vctx, const OSSL_PARAM params[])
     return 1;
 }
 
-static int aes_set_params(void *vctx, const OSSL_PARAM params[])
+static int aes_ctx_set_params(void *vctx, const OSSL_PARAM params[])
 {
     PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
     const OSSL_PARAM *p;
@@ -228,48 +257,33 @@ static int aes_set_params(void *vctx, const OSSL_PARAM params[])
     return 1;
 }
 
-const OSSL_DISPATCH aes256ecb_functions[] = {
-    { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_256_ecb_newctx },
-    { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit },
-    { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit },
-    { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_update },
-    { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_final },
-    { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx },
-    { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx },
-    { OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_256 },
-    { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_get_params },
-    { OSSL_FUNC_CIPHER_SET_PARAMS, (void (*)(void))aes_set_params },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH aes192ecb_functions[] = {
-    { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_192_ecb_newctx },
-    { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit },
-    { OSSL_FUNC_CIPHER_ENCRYPT_UPDATE, (void (*)(void))aes_update },
-    { OSSL_FUNC_CIPHER_ENCRYPT_FINAL, (void (*)(void))aes_efinal },
-    { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit },
-    { OSSL_FUNC_CIPHER_DECRYPT_UPDATE, (void (*)(void))aes_update },
-    { OSSL_FUNC_CIPHER_DECRYPT_FINAL, (void (*)(void))aes_dfinal },
-    { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx },
-    { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx },
-    { OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_192 },
-    { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_get_params },
-    { OSSL_FUNC_CIPHER_SET_PARAMS, (void (*)(void))aes_set_params },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH aes128ecb_functions[] = {
-    { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_128_ecb_newctx },
-    { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit },
-    { OSSL_FUNC_CIPHER_ENCRYPT_UPDATE, (void (*)(void))aes_update },
-    { OSSL_FUNC_CIPHER_ENCRYPT_FINAL, (void (*)(void))aes_efinal },
-    { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit },
-    { OSSL_FUNC_CIPHER_DECRYPT_UPDATE, (void (*)(void))aes_update },
-    { OSSL_FUNC_CIPHER_DECRYPT_FINAL, (void (*)(void))aes_dfinal },
-    { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx },
-    { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx },
-    { OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_128 },
-    { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_get_params },
-    { OSSL_FUNC_CIPHER_SET_PARAMS, (void (*)(void))aes_set_params },
-    { 0, NULL }
-};
+#define IMPLEMENT_funcs(mode, keylen, ivlen, blksz) \
+    const OSSL_DISPATCH aes##keylen##mode##_functions[] = { \
+        { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##keylen##_##mode##_newctx }, \
+        { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, \
+        { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, \
+        { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_update }, \
+        { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_final }, \
+        { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_cipher }, \
+        { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, \
+        { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, \
+        { OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_##keylen }, \
+        { OSSL_FUNC_CIPHER_IV_LENGTH, (void (*)(void))iv_length_##ivlen }, \
+        { OSSL_FUNC_CIPHER_BLOCK_SIZE, (void (*)(void))block_size_##blksz }, \
+        { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##mode##_get_params }, \
+        { OSSL_FUNC_CIPHER_CTX_GET_PARAMS, (void (*)(void))aes_ctx_get_params }, \
+        { OSSL_FUNC_CIPHER_CTX_SET_PARAMS, (void (*)(void))aes_ctx_set_params }, \
+        { 0, NULL } \
+    };
+
+/* ECB */
+
+IMPLEMENT_funcs(ecb, 256, 0, 16)
+IMPLEMENT_funcs(ecb, 192, 0, 16)
+IMPLEMENT_funcs(ecb, 128, 0, 16)
+
+/* CBC */
+
+IMPLEMENT_funcs(cbc, 256, 16, 16)
+IMPLEMENT_funcs(cbc, 192, 16, 16)
+IMPLEMENT_funcs(cbc, 128, 16, 16)
index b03d4f43fcfa14be036f8c064d1c24b2df0ae2c0..bf5576e767c9e60fda05f85557eb795f618b3fb5 100644 (file)
@@ -14,3 +14,6 @@ extern const OSSL_DISPATCH sha256_functions[];
 extern const OSSL_DISPATCH aes256ecb_functions[];
 extern const OSSL_DISPATCH aes192ecb_functions[];
 extern const OSSL_DISPATCH aes128ecb_functions[];
+extern const OSSL_DISPATCH aes256cbc_functions[];
+extern const OSSL_DISPATCH aes192cbc_functions[];
+extern const OSSL_DISPATCH aes128cbc_functions[];
index 1d98485253e068e97563a051fe5c2f9d2a964efd..298725aa97c62b4165b616f872fdc000fa1c6da0 100644 (file)
@@ -59,6 +59,9 @@ static const OSSL_ALGORITHM deflt_ciphers[] = {
     { "AES-256-ECB", "default=yes", aes256ecb_functions },
     { "AES-192-ECB", "default=yes", aes192ecb_functions },
     { "AES-128-ECB", "default=yes", aes128ecb_functions },
+    { "AES-256-CBC", "default=yes", aes256cbc_functions },
+    { "AES-192-CBC", "default=yes", aes192cbc_functions },
+    { "AES-128-CBC", "default=yes", aes128cbc_functions },
     { NULL, NULL, NULL }
 };
 
index af5ad52475b7c9c04614bf3594b6c4b45eae9263..b9be3490ec83dba5f80c25bafb6363e0fc17b2e6 100644 (file)
@@ -4798,3 +4798,4 @@ OSSL_PARAM_construct_end                4745      3_0_0   EXIST::FUNCTION:
 EC_GROUP_check_named_curve              4746   3_0_0   EXIST::FUNCTION:EC
 EVP_CIPHER_upref                        4747   3_0_0   EXIST::FUNCTION:
 EVP_CIPHER_fetch                        4748   3_0_0   EXIST::FUNCTION:
+EVP_CIPHER_mode                         4749   3_0_0   EXIST::FUNCTION: