]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
gcm: update to use improved parameter handling
authorPauli <ppzgs1@gmail.com>
Wed, 18 Jun 2025 00:23:01 +0000 (10:23 +1000)
committerPauli <ppzgs1@gmail.com>
Thu, 19 Jun 2025 22:39:29 +0000 (08:39 +1000)
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_gcm.c.in

index 84a8e7d628296aaf47bce973adfa60c6ac811b64..afa3ac7237855b492261951bbf1d28328adb1cd9 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 gcm mode */
 
@@ -15,7 +18,6 @@
 #include "prov/ciphercommon_gcm.h"
 #include "prov/providercommon.h"
 #include "prov/provider_ctx.h"
-#include "internal/param_names.h"
 
 static int gcm_tls_init(PROV_GCM_CTX *dat, unsigned char *aad, size_t aad_len);
 static int gcm_tls_iv_set_fixed(PROV_GCM_CTX *ctx, unsigned char *iv,
@@ -141,180 +143,199 @@ static int setivinv(PROV_GCM_CTX *ctx, unsigned char *in, size_t inl)
     return 1;
 }
 
+{- produce_param_decoder('ossl_cipher_gcm_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'],
+                          ['CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN', 'ivgen',  'octet_string'],
+                          ['CIPHER_PARAM_AEAD_IV_GENERATED',    'gen',    'uint'],
+                         )); -}
+
+const OSSL_PARAM *ossl_gcm_gettable_ctx_params(
+        ossl_unused void *cctx, ossl_unused void *provctx
+    )
+{
+    return ossl_cipher_gcm_get_ctx_params_ettable;
+}
+
 int ossl_gcm_get_ctx_params(void *vctx, OSSL_PARAM params[])
 {
     PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx;
-    OSSL_PARAM *p;
     size_t sz;
+    struct ossl_cipher_gcm_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_gcm_get_ctx_params_decoder(params);
 
-        case PIDX_CIPHER_PARAM_IVLEN:
-            if (!OSSL_PARAM_set_size_t(p, ctx->ivlen)) {
-                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, ctx->ivlen)) {
+        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;
-
-        case PIDX_CIPHER_PARAM_AEAD_TAGLEN:
-            {
-                size_t taglen = (ctx->taglen != UNINITIALISED_SIZET) ? ctx->taglen :
-                                 GCM_TAG_MAX_SIZE;
-
-                if (!OSSL_PARAM_set_size_t(p, taglen)) {
-                    ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-                    return 0;
-                }
-            }
-            break;
-
-        case PIDX_CIPHER_PARAM_IV:
-            if (ctx->iv_state == IV_STATE_UNINITIALISED)
-                return 0;
-            if (ctx->ivlen > 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, ctx->ivlen)) {
-                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_UPDATED_IV:
-            if (ctx->iv_state == IV_STATE_UNINITIALISED)
-                return 0;
-            if (ctx->ivlen > 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, ctx->ivlen)) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-                return 0;
-            }
-            break;
+    if (p.taglen != NULL) {
+        size_t taglen = (ctx->taglen != UNINITIALISED_SIZET) ? ctx->taglen :
+                         GCM_TAG_MAX_SIZE;
 
-        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;
-
-        case PIDX_CIPHER_PARAM_AEAD_TAG:
-            sz = p->data_size;
-            if (sz == 0
-                || sz > EVP_GCM_TLS_TAG_LEN
-                || !ctx->enc
-                || ctx->taglen == UNINITIALISED_SIZET) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG);
-                return 0;
-            }
-            if (!OSSL_PARAM_set_octet_string(p, ctx->buf, sz)) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
-                return 0;
-            }
-            break;
+        if (!OSSL_PARAM_set_size_t(p.taglen, taglen)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+            return 0;
+        }
+    }
 
-        case PIDX_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN:
-            if (p->data == NULL
-                || p->data_type != OSSL_PARAM_OCTET_STRING
-                || !getivgen(ctx, p->data, p->data_size))
-                return 0;
-            break;
-        case PIDX_CIPHER_PARAM_AEAD_IV_GENERATED:
-            if (!OSSL_PARAM_set_uint(p, ctx->iv_gen_rand))
-                return 0;
+    if (p.iv != NULL) {
+        if (ctx->iv_state == IV_STATE_UNINITIALISED)
+            return 0;
+        if (ctx->ivlen > 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, ctx->ivlen)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+            return 0;
+        }
+    }
+
+    if (p.updiv != NULL) {
+        if (ctx->iv_state == IV_STATE_UNINITIALISED)
+            return 0;
+        if (ctx->ivlen > 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, ctx->ivlen)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+            return 0;
         }
+    }
+
+    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;
+    }
+
+    if (p.tag != NULL) {
+        sz = p.tag->data_size;
+        if (sz == 0
+            || sz > EVP_GCM_TLS_TAG_LEN
+            || !ctx->enc
+            || ctx->taglen == UNINITIALISED_SIZET) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG);
+            return 0;
+        }
+        if (!OSSL_PARAM_set_octet_string(p.tag, ctx->buf, sz)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+            return 0;
+        }
+    }
+
+    if (p.ivgen != NULL)
+        if (p.ivgen->data == NULL
+            || p.ivgen->data_type != OSSL_PARAM_OCTET_STRING
+            || !getivgen(ctx, p.ivgen->data, p.ivgen->data_size))
+            return 0;
+
+    if (p.gen != NULL && !OSSL_PARAM_set_uint(p.gen, ctx->iv_gen_rand))
+        return 0;
+
     return 1;
 }
 
+{- produce_param_decoder
+        ('ossl_cipher_gcm_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'],
+          ['CIPHER_PARAM_AEAD_TLS1_SET_IV_INV', 'inviv', 'octet_string'],
+         )); -}
+
+const OSSL_PARAM *ossl_gcm_settable_ctx_params(
+        ossl_unused void *cctx, ossl_unused void *provctx
+    )
+{
+    return ossl_cipher_gcm_set_ctx_params_ettable;
+}
+
 int ossl_gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 {
     PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx;
-    const OSSL_PARAM *p;
     size_t sz;
     void *vp;
+    struct ossl_cipher_gcm_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_gcm_set_ctx_params_decoder(params);
 
-        case PIDX_CIPHER_PARAM_AEAD_TAG:
-            vp = ctx->buf;
-            if (!OSSL_PARAM_get_octet_string(p, &vp, EVP_GCM_TLS_TAG_LEN, &sz)) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
-                return 0;
-            }
-            if (sz == 0 || ctx->enc) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG);
-                return 0;
-            }
-            ctx->taglen = sz;
-            break;
+    if (p.tag != NULL) {
+        vp = ctx->buf;
+        if (!OSSL_PARAM_get_octet_string(p.tag, &vp, EVP_GCM_TLS_TAG_LEN, &sz)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
+            return 0;
+        }
+        if (sz == 0 || ctx->enc) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG);
+            return 0;
+        }
+        ctx->taglen = sz;
+    }
 
-        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;
-            }
-            if (sz == 0 || sz > sizeof(ctx->iv)) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
-                return 0;
-            }
-            if (ctx->ivlen != sz) {
-                /* If the iv was already set or autogenerated, it is invalid. */
-                if (ctx->iv_state != IV_STATE_UNINITIALISED)
-                    ctx->iv_state = IV_STATE_FINISHED;
-                ctx->ivlen = sz;
-            }
-            break;
-
-        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 = gcm_tls_init(ctx, p->data, p->data_size);
-            if (sz == 0) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_AAD);
-                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;
+        }
+        if (sz == 0 || sz > sizeof(ctx->iv)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
+            return 0;
+        }
+        if (ctx->ivlen != sz) {
+            /* If the iv was already set or autogenerated, it is invalid. */
+            if (ctx->iv_state != IV_STATE_UNINITIALISED)
+                ctx->iv_state = IV_STATE_FINISHED;
+            ctx->ivlen = sz;
+        }
+    }
 
-        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 (gcm_tls_iv_set_fixed(ctx, p->data, p->data_size) == 0) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
-                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 = gcm_tls_init(ctx, p.aad->data, p.aad->data_size);
+        if (sz == 0) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_AAD);
+            return 0;
+        }
+        ctx->tls_aad_pad_sz = sz;
+    }
 
-        case PIDX_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV:
-            if (p->data == NULL
-                || p->data_type != OSSL_PARAM_OCTET_STRING
-                || !setivinv(ctx, p->data, p->data_size))
-                return 0;
-            break;
+    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 (gcm_tls_iv_set_fixed(ctx, p.fixed->data, p.fixed->data_size) == 0) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
+            return 0;
         }
+    }
+
+    if (p.inviv != NULL)
+            if (p.inviv->data == NULL
+                || p.inviv->data_type != OSSL_PARAM_OCTET_STRING
+                || !setivinv(ctx, p.inviv->data, p.inviv->data_size))
+                return 0;
+
     return 1;
 }