diff options
Diffstat (limited to 'providers/implementations/ciphers/ciphercommon_gcm.c')
-rw-r--r-- | providers/implementations/ciphers/ciphercommon_gcm.c | 311 |
1 files changed, 167 insertions, 144 deletions
diff --git a/providers/implementations/ciphers/ciphercommon_gcm.c b/providers/implementations/ciphers/ciphercommon_gcm.c index 4ec73d5a6dba..475693f336a4 100644 --- a/providers/implementations/ciphers/ciphercommon_gcm.c +++ b/providers/implementations/ciphers/ciphercommon_gcm.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2024 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 @@ -15,6 +15,7 @@ #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, @@ -145,85 +146,101 @@ 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; - - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); - if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->ivlen)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); - if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN); - if (p != NULL) { - 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; - } - } - - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); - if (p != NULL) { - 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(p, ctx->iv, ctx->ivlen) - && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - } - - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); - if (p != NULL) { - 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(p, ctx->iv, ctx->ivlen) - && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - } - - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD); - if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); - if (p != NULL) { - 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; + int type; + + for (p = params; p->key != NULL; p++) { + type = ossl_param_find_pidx(p->key); + switch (type) { + default: + break; + + 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; + + 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(p, ctx->iv, ctx->ivlen) + && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + break; + + 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(p, ctx->iv, ctx->ivlen) + && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + break; + + 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; + + 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; } } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN); - if (p != NULL) { - if (p->data == NULL - || p->data_type != OSSL_PARAM_OCTET_STRING - || !getivgen(ctx, p->data, p->data_size)) - return 0; - } return 1; } @@ -233,76 +250,80 @@ int ossl_gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) const OSSL_PARAM *p; size_t sz; void *vp; + int type; - if (params == NULL) + if (ossl_param_is_empty(params)) return 1; - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG); - if (p != NULL) { - 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; - } - - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_IVLEN); - if (p != NULL) { - 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; - } - } - - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD); - if (p != NULL) { - 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; + for (p = params; p->key != NULL; p++) { + type = ossl_param_find_pidx(p->key); + switch (type) { + default: + break; + + 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; + + 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; + + 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; + + 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; } - ctx->tls_aad_pad_sz = sz; } - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED); - if (p != NULL) { - 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; - } - } - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV); - if (p != NULL) { - if (p->data == NULL - || p->data_type != OSSL_PARAM_OCTET_STRING - || !setivinv(ctx, p->data, p->data_size)) - return 0; - } - - return 1; } @@ -495,9 +516,11 @@ static int gcm_tls_iv_set_fixed(PROV_GCM_CTX *ctx, unsigned char *iv, return 0; if (len > 0) memcpy(ctx->iv, iv, len); - if (ctx->enc - && RAND_bytes_ex(ctx->libctx, ctx->iv + len, ctx->ivlen - len, 0) <= 0) + if (ctx->enc) { + if (RAND_bytes_ex(ctx->libctx, ctx->iv + len, ctx->ivlen - len, 0) <= 0) return 0; + ctx->iv_gen_rand = 1; + } ctx->iv_gen = 1; ctx->iv_state = IV_STATE_BUFFERED; return 1; |