aboutsummaryrefslogtreecommitdiff
path: root/providers/implementations/ciphers/ciphercommon_gcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'providers/implementations/ciphers/ciphercommon_gcm.c')
-rw-r--r--providers/implementations/ciphers/ciphercommon_gcm.c311
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;