]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
ccm: update to use improved parameter handling
authorPauli <ppzgs1@gmail.com>
Wed, 18 Jun 2025 00:22:05 +0000 (10:22 +1000)
committerPauli <ppzgs1@gmail.com>
Thu, 19 Jun 2025 22:39:29 +0000 (08:39 +1000)
Also address a problem where more parameters are claimed to be supported
than actually are.

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/27847)

providers/implementations/ciphers/ciphercommon_ccm.c.in

index 380e4702c508c08d398a133a1574e0c95dd1e2ee..a6d71bd2b086e359705670eb2ea4b2301728f777 100644 (file)
@@ -6,6 +6,9 @@
  * in the file LICENSE in the source distribution or at
  * https://www.openssl.org/source/license.html
  */
+{-
+use OpenSSL::paramnames qw(produce_param_decoder);
+-}
 
 /* Dispatch functions for ccm mode */
 
@@ -13,7 +16,7 @@
 #include "prov/ciphercommon.h"
 #include "prov/ciphercommon_ccm.h"
 #include "prov/providercommon.h"
-#include "internal/param_names.h"
+
 
 static int ccm_cipher_internal(PROV_CCM_CTX *ctx, unsigned char *out,
                                size_t *padlen, const unsigned char *in,
@@ -66,160 +69,176 @@ static size_t ccm_get_ivlen(PROV_CCM_CTX *ctx)
     return 15 - ctx->l;
 }
 
+{- produce_param_decoder('ossl_cipher_ccm_set_ctx_params',
+                         (['CIPHER_PARAM_AEAD_IVLEN',           'ivlen', 'size_t'],
+                          ['CIPHER_PARAM_AEAD_TAG',             'tag',   'octet_string'],
+                          ['CIPHER_PARAM_AEAD_TLS1_AAD',        'aad',   'octet_string'],
+                          ['CIPHER_PARAM_AEAD_TLS1_IV_FIXED',   'fixed', 'octet_string'],
+                         )); -}
+
+const OSSL_PARAM *ossl_ccm_settable_ctx_params(
+        ossl_unused void *cctx, ossl_unused void *provctx
+    )
+{
+    return ossl_cipher_ccm_set_ctx_params_ettable;
+}
+
 int ossl_ccm_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 {
     PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx;
-    const OSSL_PARAM *p;
     size_t sz, ivlen;
+    struct ossl_cipher_ccm_set_ctx_params_st p;
 
     if (ossl_param_is_empty(params))
         return 1;
 
-    for (p = params; p->key != NULL; p++)
-        switch (ossl_cipher_aead_set_ctx_params_find_pidx(p->key)) {
-        default:
-            break;
+    p = ossl_cipher_ccm_set_ctx_params_decoder(params);
 
-        case PIDX_CIPHER_PARAM_AEAD_TAG:
-            if (p->data_type != OSSL_PARAM_OCTET_STRING) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
-                return 0;
-            }
-            if ((p->data_size & 1) || (p->data_size < 4) || p->data_size > 16) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG_LENGTH);
-                return 0;
-            }
-
-            if (p->data != NULL) {
-                if (ctx->enc) {
-                    ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOT_NEEDED);
-                    return 0;
-                }
-                memcpy(ctx->buf, p->data, p->data_size);
-                ctx->tag_set = 1;
-            }
-            ctx->m = p->data_size;
-            break;
+    if (p.tag != NULL) {
+        if (p.tag->data_type != OSSL_PARAM_OCTET_STRING) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
+            return 0;
+        }
+        if ((p.tag->data_size & 1) || (p.tag->data_size < 4) || p.tag->data_size > 16) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG_LENGTH);
+            return 0;
+        }
 
-        case PIDX_CIPHER_PARAM_AEAD_IVLEN:
-            if (!OSSL_PARAM_get_size_t(p, &sz)) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
-                return 0;
-            }
-            ivlen = 15 - sz;
-            if (ivlen < 2 || ivlen > 8) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
+        if (p.tag->data != NULL) {
+            if (ctx->enc) {
+                ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOT_NEEDED);
                 return 0;
             }
-            if (ctx->l != ivlen) {
-                ctx->l = ivlen;
-                ctx->iv_set = 0;
-            }
-            break;
+            memcpy(ctx->buf, p.tag->data, p.tag->data_size);
+            ctx->tag_set = 1;
+        }
+        ctx->m = p.tag->data_size;
+    }
 
-        case PIDX_CIPHER_PARAM_AEAD_TLS1_AAD:
-            if (p->data_type != OSSL_PARAM_OCTET_STRING) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
-                return 0;
-            }
-            sz = ccm_tls_init(ctx, p->data, p->data_size);
-            if (sz == 0) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DATA);
-                return 0;
-            }
-            ctx->tls_aad_pad_sz = sz;
-            break;
+    if (p.ivlen != NULL) {
+        if (!OSSL_PARAM_get_size_t(p.ivlen, &sz)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
+            return 0;
+        }
+        ivlen = 15 - sz;
+        if (ivlen < 2 || ivlen > 8) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
+            return 0;
+        }
+        if (ctx->l != ivlen) {
+            ctx->l = ivlen;
+            ctx->iv_set = 0;
+        }
+    }
 
-        case PIDX_CIPHER_PARAM_AEAD_TLS1_IV_FIXED:
-            if (p->data_type != OSSL_PARAM_OCTET_STRING) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
-                return 0;
-            }
-            if (ccm_tls_iv_set_fixed(ctx, p->data, p->data_size) == 0) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
-                return 0;
-            }
-            break;
+    if (p.aad != NULL) {
+        if (p.aad->data_type != OSSL_PARAM_OCTET_STRING) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
+            return 0;
         }
+        sz = ccm_tls_init(ctx, p.aad->data, p.aad->data_size);
+        if (sz == 0) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DATA);
+            return 0;
+        }
+        ctx->tls_aad_pad_sz = sz;
+    }
+
+    if (p.fixed != NULL) {
+        if (p.fixed->data_type != OSSL_PARAM_OCTET_STRING) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
+            return 0;
+        }
+        if (ccm_tls_iv_set_fixed(ctx, p.fixed->data, p.fixed->data_size) == 0) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
+            return 0;
+        }
+    }
     return 1;
 }
 
+{- produce_param_decoder('ossl_cipher_ccm_get_ctx_params',
+                         (['CIPHER_PARAM_KEYLEN',               'keylen', 'size_t'],
+                          ['CIPHER_PARAM_IVLEN',                'ivlen',  'size_t'],
+                          ['CIPHER_PARAM_AEAD_TAGLEN',          'taglen', 'size_t'],
+                          ['CIPHER_PARAM_IV',                   'iv',     'octet_string'],
+                          ['CIPHER_PARAM_UPDATED_IV',           'updiv',  'octet_string'],
+                          ['CIPHER_PARAM_AEAD_TAG',             'tag',    'octet_string'],
+                          ['CIPHER_PARAM_AEAD_TLS1_AAD_PAD',    'pad',    'size_t'],
+                         )); -}
+
+const OSSL_PARAM *ossl_ccm_gettable_ctx_params(
+        ossl_unused void *cctx, ossl_unused void *provctx
+    )
+{
+    return ossl_cipher_ccm_get_ctx_params_ettable;
+}
+
 int ossl_ccm_get_ctx_params(void *vctx, OSSL_PARAM params[])
 {
     PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx;
-    OSSL_PARAM *p;
+    struct ossl_cipher_ccm_get_ctx_params_st p;
 
-    for (p = params; p->key != NULL; p++)
-        switch (ossl_cipher_aead_get_ctx_params_find_pidx(p->key)) {
-        default:
-            break;
+    p = ossl_cipher_ccm_get_ctx_params_decoder(params);
 
-        case PIDX_CIPHER_PARAM_IVLEN:
-            if (!OSSL_PARAM_set_size_t(p, ccm_get_ivlen(ctx))) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-                return 0;
-            }
-            break;
+    if (p.ivlen != NULL && !OSSL_PARAM_set_size_t(p.ivlen, ccm_get_ivlen(ctx))) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+        return 0;
+    }
 
-        case PIDX_CIPHER_PARAM_AEAD_TAGLEN:
-            if (!OSSL_PARAM_set_size_t(p, ctx->m)) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-                return 0;
-            }
-            break;
+    if (p.taglen != NULL && !OSSL_PARAM_set_size_t(p.taglen, ctx->m)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+        return 0;
+    }
 
-        case PIDX_CIPHER_PARAM_IV:
-            if (ccm_get_ivlen(ctx) > p->data_size) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
-                return 0;
-            }
-            if (!OSSL_PARAM_set_octet_string_or_ptr(p, ctx->iv, p->data_size)) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-                return 0;
-            }
-            break;
+    if (p.iv != NULL) {
+        if (ccm_get_ivlen(ctx) > p.iv->data_size) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
+            return 0;
+        }
+        if (!OSSL_PARAM_set_octet_string_or_ptr(p.iv, ctx->iv, p.iv->data_size)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+            return 0;
+        }
+    }
 
-        case PIDX_CIPHER_PARAM_UPDATED_IV:
-            if (ccm_get_ivlen(ctx) > p->data_size) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
-                return 0;
-            }
-            if (!OSSL_PARAM_set_octet_string_or_ptr(p, ctx->iv, p->data_size)) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-                return 0;
-            }
-            break;
+    if (p.updiv != NULL) {
+        if (ccm_get_ivlen(ctx) > p.updiv->data_size) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
+            return 0;
+        }
+        if (!OSSL_PARAM_set_octet_string_or_ptr(p.updiv, ctx->iv, p.updiv->data_size)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+            return 0;
+        }
+    }
 
-        case PIDX_CIPHER_PARAM_KEYLEN:
-            if (!OSSL_PARAM_set_size_t(p, ctx->keylen)) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-                return 0;
-            }
-            break;
+    if (p.keylen != NULL && !OSSL_PARAM_set_size_t(p.keylen, ctx->keylen)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+        return 0;
+    }
 
-        case PIDX_CIPHER_PARAM_AEAD_TLS1_AAD_PAD:
-            if (!OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-                return 0;
-            }
-            break;
+    if (p.pad != NULL && !OSSL_PARAM_set_size_t(p.pad, ctx->tls_aad_pad_sz)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+        return 0;
+    }
 
-        case PIDX_CIPHER_PARAM_AEAD_TAG:
-            if (!ctx->enc || !ctx->tag_set) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOT_SET);
-                return 0;
-            }
-            if (p->data_type != OSSL_PARAM_OCTET_STRING) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-                return 0;
-            }
-            if (!ctx->hw->gettag(ctx, p->data, p->data_size))
-                return 0;
-            ctx->tag_set = 0;
-            ctx->iv_set = 0;
-            ctx->len_set = 0;
-            break;
+    if (p.tag != NULL) {
+        if (!ctx->enc || !ctx->tag_set) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOT_SET);
+            return 0;
+        }
+        if (p.tag->data_type != OSSL_PARAM_OCTET_STRING) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+            return 0;
         }
+        if (!ctx->hw->gettag(ctx, p.tag->data, p.tag->data_size))
+            return 0;
+        ctx->tag_set = 0;
+        ctx->iv_set = 0;
+        ctx->len_set = 0;
+    }
+
     return 1;
 }