[openssl] master update

Richard Levitte levitte at openssl.org
Thu Jul 11 05:27:12 UTC 2019


The branch master has been updated
       via  06c8331c51797f43881e5262b4c114aacc6d0ca0 (commit)
       via  13273237a65d46186b6bea0b51aec90670d4598a (commit)
       via  80942379c9fc66076b784cba6318ed6ca85ca3ea (commit)
       via  48ebde226d4bd66556f25d0c4b3679478890974d (commit)
      from  7a228c391e0a35e1dc1223e3af3371968376857b (commit)


- Log -----------------------------------------------------------------
commit 06c8331c51797f43881e5262b4c114aacc6d0ca0
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Jul 9 12:03:00 2019 +0200

    Adapt the provider AES for more use of OSSL_PARAM
    
    The cipher context IV was a bit interesting.  EVP_CIPHER_CTX_iv()
    returns a pointer to the live IV, while EVP_CIPHER_CTX_ctrl() with the
    type EVP_CTRL_GET_IV gets a copy of the live IV.  To support both, we
    support getting it with both the OSSL_PARAM_OCTET_STRING and
    OSSL_PARAM_OCTET_PTR datatypes.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9328)

commit 13273237a65d46186b6bea0b51aec90670d4598a
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Jul 9 07:32:16 2019 +0200

    Adapt diverse EVP_CIPHER functions to use get_params and set_params interfaces
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9328)

commit 80942379c9fc66076b784cba6318ed6ca85ca3ea
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue Jul 9 07:27:27 2019 +0200

    Make more use of OSSL_PARAM for ciphers
    
    A lot of the different numbers associated with ciphers are really
    algorithm parameters.  Key length, block size, IV length, that sort of
    thing.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9328)

commit 48ebde226d4bd66556f25d0c4b3679478890974d
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Jul 8 20:36:29 2019 +0200

    test/evp_test.c: [ciphers] Test that we get back the same IV we gave
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9328)

-----------------------------------------------------------------------

Summary of changes:
 crypto/evp/build.info             |   2 +-
 crypto/evp/evp_enc.c              |  77 ++++++------
 crypto/evp/evp_lib.c              | 112 +++++++++--------
 crypto/evp/evp_locl.h             |  37 ++++++
 crypto/evp/evp_utils.c            |  78 ++++++++++++
 crypto/include/internal/evp_int.h |   3 -
 include/openssl/core_names.h      |   6 +
 include/openssl/core_numbers.h    |  12 +-
 include/openssl/evp.h             |   2 +-
 providers/common/ciphers/aes.c    | 246 ++++++++++++++++++++------------------
 test/evp_test.c                   |   8 ++
 11 files changed, 360 insertions(+), 223 deletions(-)
 create mode 100644 crypto/evp/evp_utils.c

diff --git a/crypto/evp/build.info b/crypto/evp/build.info
index 26be4d9..fa49f2e 100644
--- a/crypto/evp/build.info
+++ b/crypto/evp/build.info
@@ -1,5 +1,5 @@
 LIBS=../../libcrypto
-$COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c
+$COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c
 SOURCE[../../libcrypto]=$COMMON\
         encode.c evp_key.c evp_cnf.c \
         e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index ebe7fa8..3b83d11 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -920,6 +920,14 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 
 int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
 {
+    int ok = evp_do_param(c->cipher, &keylen, sizeof(keylen),
+                          OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER,
+                          evp_do_ciph_ctx_setparams, c->provctx);
+
+    if (ok != -2)
+        return ok;
+
+    /* TODO(3.0) legacy code follows */
     if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
         return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
     if (EVP_CIPHER_CTX_key_length(c) == keylen)
@@ -934,40 +942,51 @@ int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
 
 int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
 {
+    int ok;
+
     if (pad)
         ctx->flags &= ~EVP_CIPH_NO_PADDING;
     else
         ctx->flags |= EVP_CIPH_NO_PADDING;
 
-    if (ctx->cipher != NULL && ctx->cipher->prov != NULL) {
-        OSSL_PARAM params[] = {
-            OSSL_PARAM_int(OSSL_CIPHER_PARAM_PADDING, NULL),
-            OSSL_PARAM_END
-        };
-
-        params[0].data = &pad;
-
-        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->ctx_set_params(ctx->provctx, params))
-            return 0;
-    }
-
-    return 1;
+    ok = evp_do_param(ctx->cipher, &pad, sizeof(pad),
+                      OSSL_CIPHER_PARAM_PADDING, OSSL_PARAM_INTEGER,
+                      evp_do_ciph_ctx_setparams, ctx->provctx);
+    return ok != 0;
 }
 
 int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
 {
-    int ret;
+    int ret = -2;                /* Unsupported */
 
     if (!ctx->cipher) {
         EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
         return 0;
     }
 
+    if (ctx->cipher->prov == NULL)
+        goto legacy;
+
+    switch (type) {
+    case EVP_CTRL_SET_KEY_LENGTH:
+        ret = evp_do_param(ctx->cipher, &arg, sizeof(arg),
+                           OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER,
+                           evp_do_ciph_ctx_setparams, ctx->provctx);
+        break;
+    case EVP_CTRL_GET_IV:
+        ret = evp_do_param(ctx->cipher, ptr, arg,
+                           OSSL_CIPHER_PARAM_IV, OSSL_PARAM_OCTET_STRING,
+                           evp_do_ciph_ctx_getparams, ctx->provctx);
+        break;
+    case EVP_CTRL_RAND_KEY:      /* Used by DES */
+    case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS: /* Used by DASYNC */
+    case EVP_CTRL_INIT: /* TODO(3.0) Purely legacy, no provider counterpart */
+        ret = -2;                /* Unsupported */
+        break;
+    }
+    return ret;
+
+ legacy:
     if (!ctx->cipher->ctrl) {
         EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
         return 0;
@@ -1123,21 +1142,6 @@ static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns,
                 break;
             cipher->dupctx = OSSL_get_OP_cipher_dupctx(fns);
             break;
-        case OSSL_FUNC_CIPHER_KEY_LENGTH:
-            if (cipher->key_length != NULL)
-                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;
@@ -1157,10 +1161,7 @@ static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns,
     }
     if ((fnciphcnt != 0 && fnciphcnt != 3 && fnciphcnt != 4)
             || (fnciphcnt == 0 && cipher->ccipher == NULL)
-            || fnctxcnt != 2
-            || cipher->blocksize == NULL
-            || cipher->iv_length == NULL
-            || cipher->key_length == 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"
diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c
index 8ed39cb..9d1d197 100644
--- a/crypto/evp/evp_lib.c
+++ b/crypto/evp/evp_lib.c
@@ -217,13 +217,12 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx)
 
 int EVP_CIPHER_block_size(const EVP_CIPHER *cipher)
 {
-    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 v = cipher->block_size;
+    int ok = evp_do_param(cipher, &v, sizeof(v),
+                          OSSL_CIPHER_PARAM_BLOCK_SIZE, OSSL_PARAM_INTEGER,
+                          evp_do_ciph_getparams, NULL);
+
+    return ok != 0 ? v : -1;
 }
 
 int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
@@ -266,7 +265,12 @@ int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx)
 
 unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
 {
-    return cipher->flags;
+    unsigned long v = cipher->flags;
+    int ok = evp_do_param(cipher, &v, sizeof(v),
+                          OSSL_CIPHER_PARAM_FLAGS, OSSL_PARAM_UNSIGNED_INTEGER,
+                          evp_do_ciph_getparams, NULL);
+
+    return ok != 0 ? v : 0;
 }
 
 void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
@@ -296,13 +300,12 @@ 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;
-    }
+    int v = cipher->iv_len;
+    int ok = evp_do_param(cipher, &v, sizeof(v),
+                          OSSL_CIPHER_PARAM_IVLEN, OSSL_PARAM_UNSIGNED_INTEGER,
+                          evp_do_ciph_getparams, NULL);
 
-    return cipher->iv_len;
+    return ok != 0 ? v: -1;
 }
 
 int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
@@ -315,14 +318,27 @@ const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx)
     return ctx->oiv;
 }
 
+/*
+ * OSSL_PARAM_OCTET_PTR gets us the pointer to the running IV in the provider
+ */
 const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx)
 {
-    return ctx->iv;
+    const unsigned char *v = ctx->iv;
+    int ok = evp_do_param(ctx->cipher, &v, sizeof(ctx->iv),
+                          OSSL_CIPHER_PARAM_IV, OSSL_PARAM_OCTET_PTR,
+                          evp_do_ciph_ctx_getparams, ctx->provctx);
+
+    return ok != 0 ? v: NULL;
 }
 
 unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx)
 {
-    return ctx->iv;
+    unsigned char *v = ctx->iv;
+    int ok = evp_do_param(ctx->cipher, &v, sizeof(ctx->iv),
+                          OSSL_CIPHER_PARAM_IV, OSSL_PARAM_OCTET_PTR,
+                          evp_do_ciph_ctx_getparams, ctx->provctx);
+
+    return ok != 0 ? v: NULL;
 }
 
 unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx)
@@ -332,34 +348,42 @@ unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx)
 
 int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx)
 {
-    return ctx->num;
+    int v = ctx->num;
+    int ok = evp_do_param(ctx->cipher, &v, sizeof(v),
+                          OSSL_CIPHER_PARAM_NUM, OSSL_PARAM_INTEGER,
+                          evp_do_ciph_ctx_getparams, ctx->provctx);
+
+    return ok != 0 ? v: -1;
 }
 
-void EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num)
+int EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num)
 {
+    int ok = evp_do_param(ctx->cipher, &num, sizeof(num),
+                          OSSL_CIPHER_PARAM_NUM, OSSL_PARAM_INTEGER,
+                          evp_do_ciph_ctx_setparams, ctx->provctx);
+
     ctx->num = num;
+    return ok != 0;
 }
 
 int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
 {
-    if (cipher->prov != NULL) {
-        if (cipher->key_length != NULL)
-            return (int)cipher->key_length();
-        return -1;
-    }
+    int v = cipher->key_len;
+    int ok = evp_do_param(cipher, &v, sizeof(v),
+                          OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER,
+                          evp_do_ciph_getparams, NULL);
 
-    return cipher->key_len;
+    return ok != 0 ? v: -1;
 }
 
 int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
 {
-    /*
-     * TODO(3.0): This may need to change if/when we introduce variable length
-     * key ciphers into the providers.
-     */
-    if (ctx->cipher != NULL && ctx->cipher->prov != NULL)
-        return EVP_CIPHER_key_length(ctx->cipher);
-    return ctx->key_len;
+    int v = ctx->key_len;
+    int ok = evp_do_param(ctx->cipher, &v, sizeof(v),
+                          OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER,
+                          evp_do_ciph_ctx_getparams, ctx->provctx);
+
+    return ok != 0 ? v: -1;
 }
 
 int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
@@ -374,28 +398,12 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
 
 int EVP_CIPHER_mode(const EVP_CIPHER *cipher)
 {
-    if (cipher->prov != NULL) {
-        int mode;
+    int v = EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE;
+    int ok = evp_do_param(cipher, &v, sizeof(v),
+                          OSSL_CIPHER_PARAM_MODE, OSSL_PARAM_INTEGER,
+                          evp_do_ciph_getparams, NULL);
 
-        /* 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;
+    return ok != 0 ? v: 0;
 }
 
 
diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h
index fdafe4f..54f9e08 100644
--- a/crypto/evp/evp_locl.h
+++ b/crypto/evp/evp_locl.h
@@ -95,3 +95,40 @@ void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id,
                                             OSSL_PROVIDER *prov),
                         int (*up_ref_method)(void *),
                         void (*free_method)(void *));
+
+/* Helper functions to avoid duplicating code */
+
+/*
+ * The callbacks implement different ways to pass a params array to the
+ * provider.  They will return one of these values:
+ *
+ * -2 if the method doesn't come from a provider
+ *    (evp_do_param will return this to the called)
+ * -1 if the provider doesn't offer the desired function
+ *    (evp_do_param will raise an error and return 0)
+ * or the return value from the desired function
+ *    (evp_do_param will return it to the caller)
+ */
+int evp_do_ciph_getparams(const void *vciph, void *ignored,
+                          OSSL_PARAM params[]);
+int evp_do_ciph_ctx_getparams(const void *vciph, void *provctx,
+                              OSSL_PARAM params[]);
+int evp_do_ciph_ctx_setparams(const void *vciph, void *provctx,
+                              OSSL_PARAM params[]);
+
+/*-
+ * prepares a singular parameter, then calls the callback to execute.
+ *
+ * |method|   points to the method used by the callback.
+ *            EVP_CIPHER, EVP_MD, ...
+ * |ptr|      points at the data to transfer.
+ * |sz|       is the size of the data to transfer.
+ * |key|      is the name of the parameter to pass.
+ * |datatype| is the data type of the parameter to pass.
+ * |cb|       is the callback that actually performs the parameter passing
+ * |cb_ctx|   is the cipher context
+ */
+int evp_do_param(const void *method, void *ptr, size_t sz, const char *key,
+                 int datatype,
+                 int (*cb)(const void *method, void *ctx, OSSL_PARAM params[]),
+                 void *cb_ctx);
diff --git a/crypto/evp/evp_utils.c b/crypto/evp/evp_utils.c
new file mode 100644
index 0000000..48f548c
--- /dev/null
+++ b/crypto/evp/evp_utils.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
+ */
+
+/* Internal EVP utility functions */
+
+#include <openssl/core.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/asn1.h>        /* evp_locl.h needs it */
+#include <openssl/safestack.h>   /* evp_locl.h needs it */
+#include "internal/evp_int.h"    /* evp_locl.h needs it */
+#include "evp_locl.h"
+
+int evp_do_ciph_getparams(const void *vciph, void *ignored,
+                          OSSL_PARAM params[])
+{
+    const EVP_CIPHER *ciph = vciph;
+
+    if (ciph->prov == NULL)
+        return -2;
+    if (ciph->get_params == NULL)
+        return -1;
+    return ciph->get_params(params);
+}
+
+int evp_do_ciph_ctx_getparams(const void *vciph, void *provctx,
+                              OSSL_PARAM params[])
+{
+    const EVP_CIPHER *ciph = vciph;
+
+    if (ciph->prov == NULL)
+        return -2;
+    if (ciph->ctx_get_params == NULL)
+        return -1;
+    return ciph->ctx_get_params(provctx, params);
+}
+
+int evp_do_ciph_ctx_setparams(const void *vciph, void *provctx,
+                              OSSL_PARAM params[])
+{
+    const EVP_CIPHER *ciph = vciph;
+
+    if (ciph->prov == NULL)
+        return -2;
+    if (ciph->ctx_set_params == NULL)
+        return -1;
+    return ciph->ctx_set_params(provctx, params);
+}
+
+int evp_do_param(const void *method, void *ptr, size_t sz, const char *key,
+                 int datatype,
+                 int (*cb)(const void *method, void *ctx, OSSL_PARAM params[]),
+                 void *cb_ctx)
+{
+    OSSL_PARAM params[2] = {
+        OSSL_PARAM_END,
+        OSSL_PARAM_END
+    };
+    int ret;
+
+    params[0].key = key;
+    params[0].data_type = datatype;
+    params[0].data = ptr;
+    params[0].data_size = sz;
+
+    ret = cb(method, cb_ctx, params);
+    if (ret == -1) {
+        EVPerr(0, EVP_R_CTRL_NOT_IMPLEMENTED);
+        ret = 0;
+    }
+    return ret;
+}
diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h
index 732fad8..da4ae0f 100644
--- a/crypto/include/internal/evp_int.h
+++ b/crypto/include/internal/evp_int.h
@@ -257,9 +257,6 @@ struct evp_cipher_st {
     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_ctx_get_params_fn *ctx_get_params;
     OSSL_OP_cipher_ctx_set_params_fn *ctx_set_params;
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index a9a3b44..e4dd733 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -39,6 +39,12 @@ extern "C" {
 
 #define OSSL_CIPHER_PARAM_PADDING   "padding"
 #define OSSL_CIPHER_PARAM_MODE      "mode"
+#define OSSL_CIPHER_PARAM_BLOCK_SIZE "blocksize" /* OSSL_PARAM_INTEGER */
+#define OSSL_CIPHER_PARAM_FLAGS     "flags" /* OSSL_PARAM_UNSIGNED_INTEGER */
+#define OSSL_CIPHER_PARAM_KEYLEN    "keylen" /* OSSL_PARAM_INTEGER */
+#define OSSL_CIPHER_PARAM_IVLEN     "ivlen"  /* OSSL_PARAM_INTEGER */
+#define OSSL_CIPHER_PARAM_IV        "iv"  /* OSSL_PARAM_OCTET_PTR */
+#define OSSL_CIPHER_PARAM_NUM       "num" /* OSSL_PARAM_INTEGER */
 
 /* digest parameters */
 #define OSSL_DIGEST_PARAM_XOFLEN    "xoflen"
diff --git a/include/openssl/core_numbers.h b/include/openssl/core_numbers.h
index ff50636..0901ed3 100644
--- a/include/openssl/core_numbers.h
+++ b/include/openssl/core_numbers.h
@@ -139,12 +139,9 @@ OSSL_CORE_MAKE_FUNC(int, OP_digest_get_params,
 # 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
+# define OSSL_FUNC_CIPHER_GET_PARAMS                 9
+# define OSSL_FUNC_CIPHER_CTX_GET_PARAMS            10
+# define OSSL_FUNC_CIPHER_CTX_SET_PARAMS            11
 
 OSSL_CORE_MAKE_FUNC(void *, OP_cipher_newctx, (void *provctx))
 OSSL_CORE_MAKE_FUNC(int, OP_cipher_encrypt_init, (void *cctx,
@@ -170,9 +167,6 @@ OSSL_CORE_MAKE_FUNC(int, OP_cipher_cipher,
                      const unsigned char *in, size_t inl))
 OSSL_CORE_MAKE_FUNC(void, OP_cipher_freectx, (void *cctx))
 OSSL_CORE_MAKE_FUNC(void *, OP_cipher_dupctx, (void *cctx))
-OSSL_CORE_MAKE_FUNC(size_t, OP_cipher_key_length, (void))
-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, (OSSL_PARAM params[]))
 OSSL_CORE_MAKE_FUNC(int, OP_cipher_ctx_get_params, (void *cctx,
                                                     OSSL_PARAM params[]))
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 2fb5fe2..e781ebe 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -490,7 +490,7 @@ const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx);
 unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx);
 unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx);
 int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx);
-void EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num);
+int EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num);
 int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
 void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
 void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
diff --git a/providers/common/ciphers/aes.c b/providers/common/ciphers/aes.c
index be769e8..a151a8b 100644
--- a/providers/common/ciphers/aes.c
+++ b/providers/common/ciphers/aes.c
@@ -27,13 +27,6 @@ static OSSL_OP_cipher_final_fn aes_stream_final;
 static OSSL_OP_cipher_cipher_fn aes_cipher;
 static OSSL_OP_cipher_freectx_fn aes_freectx;
 static OSSL_OP_cipher_dupctx_fn aes_dupctx;
-static OSSL_OP_cipher_key_length_fn key_length_256;
-static OSSL_OP_cipher_key_length_fn key_length_192;
-static OSSL_OP_cipher_key_length_fn key_length_128;
-static OSSL_OP_cipher_iv_length_fn iv_length_16;
-static OSSL_OP_cipher_iv_length_fn iv_length_0;
-static OSSL_OP_cipher_block_size_fn block_size_16;
-static OSSL_OP_cipher_block_size_fn block_size_1;
 static OSSL_OP_cipher_ctx_get_params_fn aes_ctx_get_params;
 static OSSL_OP_cipher_ctx_set_params_fn aes_ctx_set_params;
 
@@ -255,69 +248,82 @@ static int aes_cipher(void *vctx,
     return 1;
 }
 
-#define IMPLEMENT_new_params(lcmode, UCMODE) \
-    static OSSL_OP_cipher_get_params_fn aes_##lcmode##_get_params; \
-    static int aes_##lcmode##_get_params(OSSL_PARAM params[]) \
+#define IMPLEMENT_cipher(lcmode, UCMODE, flags, kbits, blkbits, ivbits) \
+    static OSSL_OP_cipher_get_params_fn aes_##kbits##_##lcmode##_get_params; \
+    static int aes_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \
     { \
         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; \
+                                                                \
+        p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE);          \
+        if (p != NULL) {                                                \
+            if (!OSSL_PARAM_set_int(p, EVP_CIPH_##UCMODE##_MODE))           \
+                return 0;                                               \
+        }                                                           \
+        p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_FLAGS); \
+        if (p != NULL) {                                                \
+            if (!OSSL_PARAM_set_ulong(p, (flags)))                          \
+                return 0;                                               \
+        }                                                           \
+        p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);        \
+        if (p != NULL) {                                                \
+            if (!OSSL_PARAM_set_int(p, (kbits) / 8))                         \
+                return 0;                                               \
+        }                                                           \
+        p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE);    \
+        if (p != NULL) {                                                \
+            if (!OSSL_PARAM_set_int(p, (blkbits) / 8))                   \
+                return 0;                                               \
+        }                                                               \
+        p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);         \
+        if (p != NULL) {                                                \
+            if (!OSSL_PARAM_set_int(p, (ivbits) / 8))                    \
+                return 0;                                               \
+        }                                                               \
     \
         return 1; \
-    }
-
-#define IMPLEMENT_new_ctx(lcmode, UCMODE, len) \
-    static OSSL_OP_cipher_newctx_fn aes_##len##_##lcmode##_newctx; \
-    static void *aes_##len##_##lcmode##_newctx(void *provctx) \
+    } \
+    static OSSL_OP_cipher_newctx_fn aes_##kbits##_##lcmode##_newctx; \
+    static void *aes_##kbits##_##lcmode##_newctx(void *provctx) \
     { \
         PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx)); \
     \
         ctx->pad = 1; \
-        ctx->keylen = (len / 8); \
+        ctx->keylen = ((kbits) / 8);                        \
         ctx->ciph = PROV_AES_CIPHER_##lcmode(ctx->keylen); \
         ctx->mode = EVP_CIPH_##UCMODE##_MODE; \
         return 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)
+IMPLEMENT_cipher(ecb, ECB, 0, 256, 128, 0)
+IMPLEMENT_cipher(ecb, ECB, 0, 192, 128, 0)
+IMPLEMENT_cipher(ecb, ECB, 0, 128, 128, 0)
 
 /* CBC */
-IMPLEMENT_new_params(cbc, CBC)
-IMPLEMENT_new_ctx(cbc, CBC, 256)
-IMPLEMENT_new_ctx(cbc, CBC, 192)
-IMPLEMENT_new_ctx(cbc, CBC, 128)
+IMPLEMENT_cipher(cbc, CBC, 0, 256, 128, 128)
+IMPLEMENT_cipher(cbc, CBC, 0, 192, 128, 128)
+IMPLEMENT_cipher(cbc, CBC, 0, 128, 128, 128)
 
 /* OFB */
-IMPLEMENT_new_params(ofb, OFB)
-IMPLEMENT_new_ctx(ofb, OFB, 256)
-IMPLEMENT_new_ctx(ofb, OFB, 192)
-IMPLEMENT_new_ctx(ofb, OFB, 128)
+IMPLEMENT_cipher(ofb, OFB, 0, 256, 8, 128)
+IMPLEMENT_cipher(ofb, OFB, 0, 192, 8, 128)
+IMPLEMENT_cipher(ofb, OFB, 0, 128, 8, 128)
 
 /* CFB */
-IMPLEMENT_new_params(cfb, CFB)
-IMPLEMENT_new_params(cfb1, CFB)
-IMPLEMENT_new_params(cfb8, CFB)
-IMPLEMENT_new_ctx(cfb, CFB, 256)
-IMPLEMENT_new_ctx(cfb, CFB, 192)
-IMPLEMENT_new_ctx(cfb, CFB, 128)
-IMPLEMENT_new_ctx(cfb1, CFB, 256)
-IMPLEMENT_new_ctx(cfb1, CFB, 192)
-IMPLEMENT_new_ctx(cfb1, CFB, 128)
-IMPLEMENT_new_ctx(cfb8, CFB, 256)
-IMPLEMENT_new_ctx(cfb8, CFB, 192)
-IMPLEMENT_new_ctx(cfb8, CFB, 128)
+IMPLEMENT_cipher(cfb, CFB, 0, 256, 8, 128)
+IMPLEMENT_cipher(cfb, CFB, 0, 192, 8, 128)
+IMPLEMENT_cipher(cfb, CFB, 0, 128, 8, 128)
+IMPLEMENT_cipher(cfb1, CFB, 0, 256, 8, 128)
+IMPLEMENT_cipher(cfb1, CFB, 0, 192, 8, 128)
+IMPLEMENT_cipher(cfb1, CFB, 0, 128, 8, 128)
+IMPLEMENT_cipher(cfb8, CFB, 0, 256, 8, 128)
+IMPLEMENT_cipher(cfb8, CFB, 0, 192, 8, 128)
+IMPLEMENT_cipher(cfb8, CFB, 0, 128, 8, 128)
 
 /* CTR */
-IMPLEMENT_new_params(ctr, CTR)
-IMPLEMENT_new_ctx(ctr, CTR, 256)
-IMPLEMENT_new_ctx(ctr, CTR, 192)
-IMPLEMENT_new_ctx(ctr, CTR, 128)
+IMPLEMENT_cipher(ctr, CTR, 0, 256, 8, 128)
+IMPLEMENT_cipher(ctr, CTR, 0, 192, 8, 128)
+IMPLEMENT_cipher(ctr, CTR, 0, 128, 8, 128)
 
 static void aes_freectx(void *vctx)
 {
@@ -340,41 +346,6 @@ static void *aes_dupctx(void *ctx)
     return ret;
 }
 
-static size_t key_length_256(void)
-{
-    return 256 / 8;
-}
-
-static size_t key_length_192(void)
-{
-    return 192 / 8;
-}
-
-static size_t key_length_128(void)
-{
-    return 128 / 8;
-}
-
-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 size_t block_size_1(void)
-{
-    return 1;
-}
-
 static int aes_ctx_get_params(void *vctx, OSSL_PARAM params[])
 {
     PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
@@ -385,6 +356,26 @@ static int aes_ctx_get_params(void *vctx, OSSL_PARAM params[])
         PROVerr(PROV_F_AES_CTX_GET_PARAMS, PROV_R_FAILED_TO_SET_PARAMETER);
         return 0;
     }
+    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
+    if (p != NULL
+        && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, AES_BLOCK_SIZE)
+        && !OSSL_PARAM_set_octet_string(p, &ctx->iv, AES_BLOCK_SIZE)) {
+        PROVerr(PROV_F_AES_CTX_GET_PARAMS,
+                PROV_R_FAILED_TO_SET_PARAMETER);
+        return 0;
+    }
+    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_NUM);
+    if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->num)) {
+        PROVerr(PROV_F_AES_CTX_GET_PARAMS,
+                PROV_R_FAILED_TO_SET_PARAMETER);
+        return 0;
+    }
+    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
+    if (p != NULL && !OSSL_PARAM_set_int(p, ctx->keylen)) {
+        PROVerr(PROV_F_AES_CTX_GET_PARAMS,
+                PROV_R_FAILED_TO_SET_PARAMETER);
+        return 0;
+    }
 
     return 1;
 }
@@ -399,17 +390,40 @@ static int aes_ctx_set_params(void *vctx, const OSSL_PARAM params[])
         int pad;
 
         if (!OSSL_PARAM_get_int(p, &pad)) {
-        PROVerr(PROV_F_AES_CTX_SET_PARAMS, PROV_R_FAILED_TO_GET_PARAMETER);
+            PROVerr(PROV_F_AES_CTX_SET_PARAMS,
+                    PROV_R_FAILED_TO_GET_PARAMETER);
             return 0;
         }
         ctx->pad = pad ? 1 : 0;
     }
+    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_NUM);
+    if (p != NULL) {
+        int num;
+
+        if (!OSSL_PARAM_get_int(p, &num)) {
+            PROVerr(PROV_F_AES_CTX_SET_PARAMS,
+                    PROV_R_FAILED_TO_GET_PARAMETER);
+            return 0;
+        }
+        ctx->num = num;
+    }
+    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
+    if (p != NULL) {
+        int keylen;
+
+        if (!OSSL_PARAM_get_int(p, &keylen)) {
+            PROVerr(PROV_F_AES_CTX_SET_PARAMS,
+                    PROV_R_FAILED_TO_GET_PARAMETER);
+            return 0;
+        }
+        ctx->keylen = keylen;
+    }
     return 1;
 }
 
-#define IMPLEMENT_block_funcs(mode, keylen, ivlen) \
-    const OSSL_DISPATCH aes##keylen##mode##_functions[] = { \
-        { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##keylen##_##mode##_newctx }, \
+#define IMPLEMENT_block_funcs(mode, kbits) \
+    const OSSL_DISPATCH aes##kbits##mode##_functions[] = { \
+        { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##kbits##_##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_block_update }, \
@@ -417,18 +431,15 @@ static int aes_ctx_set_params(void *vctx, const OSSL_PARAM params[])
         { 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_16 }, \
-        { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##mode##_get_params }, \
+        { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##kbits##_##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 } \
     };
 
-#define IMPLEMENT_stream_funcs(mode, keylen, ivlen) \
-    const OSSL_DISPATCH aes##keylen##mode##_functions[] = { \
-        { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##keylen##_##mode##_newctx }, \
+#define IMPLEMENT_stream_funcs(mode, kbits) \
+    const OSSL_DISPATCH aes##kbits##mode##_functions[] = { \
+        { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##kbits##_##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_stream_update }, \
@@ -436,42 +447,39 @@ static int aes_ctx_set_params(void *vctx, const OSSL_PARAM params[])
         { 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_1 }, \
-        { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##mode##_get_params }, \
+        { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##kbits##_##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_block_funcs(ecb, 256, 0)
-IMPLEMENT_block_funcs(ecb, 192, 0)
-IMPLEMENT_block_funcs(ecb, 128, 0)
+IMPLEMENT_block_funcs(ecb, 256)
+IMPLEMENT_block_funcs(ecb, 192)
+IMPLEMENT_block_funcs(ecb, 128)
 
 /* CBC */
-IMPLEMENT_block_funcs(cbc, 256, 16)
-IMPLEMENT_block_funcs(cbc, 192, 16)
-IMPLEMENT_block_funcs(cbc, 128, 16)
+IMPLEMENT_block_funcs(cbc, 256)
+IMPLEMENT_block_funcs(cbc, 192)
+IMPLEMENT_block_funcs(cbc, 128)
 
 /* OFB */
-IMPLEMENT_stream_funcs(ofb, 256, 16)
-IMPLEMENT_stream_funcs(ofb, 192, 16)
-IMPLEMENT_stream_funcs(ofb, 128, 16)
+IMPLEMENT_stream_funcs(ofb, 256)
+IMPLEMENT_stream_funcs(ofb, 192)
+IMPLEMENT_stream_funcs(ofb, 128)
 
 /* CFB */
-IMPLEMENT_stream_funcs(cfb, 256, 16)
-IMPLEMENT_stream_funcs(cfb, 192, 16)
-IMPLEMENT_stream_funcs(cfb, 128, 16)
-IMPLEMENT_stream_funcs(cfb1, 256, 16)
-IMPLEMENT_stream_funcs(cfb1, 192, 16)
-IMPLEMENT_stream_funcs(cfb1, 128, 16)
-IMPLEMENT_stream_funcs(cfb8, 256, 16)
-IMPLEMENT_stream_funcs(cfb8, 192, 16)
-IMPLEMENT_stream_funcs(cfb8, 128, 16)
+IMPLEMENT_stream_funcs(cfb, 256)
+IMPLEMENT_stream_funcs(cfb, 192)
+IMPLEMENT_stream_funcs(cfb, 128)
+IMPLEMENT_stream_funcs(cfb1, 256)
+IMPLEMENT_stream_funcs(cfb1, 192)
+IMPLEMENT_stream_funcs(cfb1, 128)
+IMPLEMENT_stream_funcs(cfb8, 256)
+IMPLEMENT_stream_funcs(cfb8, 192)
+IMPLEMENT_stream_funcs(cfb8, 128)
 
 /* CTR */
-IMPLEMENT_stream_funcs(ctr, 256, 16)
-IMPLEMENT_stream_funcs(ctr, 192, 16)
-IMPLEMENT_stream_funcs(ctr, 128, 16)
+IMPLEMENT_stream_funcs(ctr, 256)
+IMPLEMENT_stream_funcs(ctr, 192)
+IMPLEMENT_stream_funcs(ctr, 128)
diff --git a/test/evp_test.c b/test/evp_test.c
index 0489bbe..f76929d 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -661,6 +661,14 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
         t->err = "KEY_SET_ERROR";
         goto err;
     }
+    /* Check that we get the same IV back */
+    if (expected->iv != NULL
+        && (EVP_CIPHER_flags(expected->cipher) & EVP_CIPH_CUSTOM_IV) == 0
+        && !TEST_mem_eq(expected->iv, expected->iv_len,
+                        EVP_CIPHER_CTX_iv(ctx), expected->iv_len)) {
+        t->err = "INVALID_IV";
+        goto err;
+    }
 
     if (expected->aead == EVP_CIPH_CCM_MODE) {
         if (!EVP_CipherUpdate(ctx, NULL, &tmplen, NULL, out_len)) {


More information about the openssl-commits mailing list