* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
+{-
+use OpenSSL::paramnames qw(produce_param_decoder);
+-}
/*
* HMAC low level APIs are deprecated for public use, but still ok for internal
static OSSL_FUNC_kdf_derive_fn kdf_hkdf_derive;
static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_hkdf_settable_ctx_params;
static OSSL_FUNC_kdf_set_ctx_params_fn kdf_hkdf_set_ctx_params;
-static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params;
-static OSSL_FUNC_kdf_get_ctx_params_fn kdf_hkdf_get_ctx_params;
+static OSSL_FUNC_kdf_gettable_ctx_params_fn hkdf_gettable_ctx_params;
+static OSSL_FUNC_kdf_get_ctx_params_fn hkdf_common_get_ctx_params;
static OSSL_FUNC_kdf_derive_fn kdf_tls1_3_derive;
static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_tls1_3_settable_ctx_params;
static OSSL_FUNC_kdf_set_ctx_params_fn kdf_tls1_3_set_ctx_params;
const unsigned char *info, size_t info_len,
unsigned char *okm, size_t okm_len);
-/* Settable context parameters that are common across HKDF and the TLS KDF */
-#define HKDF_COMMON_SETTABLES \
- OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0), \
- OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL), \
- OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), \
- OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), \
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0), \
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0)
-
-/*
- * Gettable context parameters that are common across HKDF and the TLS KDF.
- * OSSL_KDF_PARAM_KEY is not gettable because it is a secret value.
- */
-#define HKDF_COMMON_GETTABLES \
- OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), \
- OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0), \
- OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL), \
- OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), \
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0), \
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0)
-
typedef struct {
void *provctx;
int mode;
}
}
-static int hkdf_common_set_ctx_params(KDF_HKDF *ctx, const OSSL_PARAM params[])
+struct hkdf_all_set_ctx_params_st {
+ OSSL_PARAM *mode;
+ OSSL_PARAM *propq;
+ OSSL_PARAM *engine;
+ OSSL_PARAM *digest;
+ OSSL_PARAM *key;
+ OSSL_PARAM *salt;
+ OSSL_PARAM *ind_k;
+ OSSL_PARAM *ind_d;
+ OSSL_PARAM *prefix;
+ OSSL_PARAM *label;
+ OSSL_PARAM *data;
+ OSSL_PARAM *info[5];
+ int num_info;
+};
+
+static int hkdf_common_set_ctx_params
+ (KDF_HKDF *ctx, const struct hkdf_all_set_ctx_params_st *p)
{
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
- const OSSL_PARAM *p;
int n;
- if (ossl_param_is_empty(params))
- return 1;
-
- if ((p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST)) != NULL) {
+ if (p->digest != NULL) {
const EVP_MD *md = NULL;
if (ctx->fixed_digest) {
return 0;
}
- if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))
+ if (!ossl_prov_digest_load(&ctx->digest, p->digest,
+ p->propq, p->engine, libctx))
return 0;
md = ossl_prov_digest_md(&ctx->digest);
}
}
- if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MODE)) != NULL) {
- if (p->data_type == OSSL_PARAM_UTF8_STRING) {
- if (OPENSSL_strcasecmp(p->data, "EXTRACT_AND_EXPAND") == 0) {
+ if (p->mode != NULL) {
+ if (p->mode->data_type == OSSL_PARAM_UTF8_STRING) {
+ if (OPENSSL_strcasecmp(p->mode->data, "EXTRACT_AND_EXPAND") == 0) {
ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND;
- } else if (OPENSSL_strcasecmp(p->data, "EXTRACT_ONLY") == 0) {
+ } else if (OPENSSL_strcasecmp(p->mode->data, "EXTRACT_ONLY") == 0) {
ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY;
- } else if (OPENSSL_strcasecmp(p->data, "EXPAND_ONLY") == 0) {
+ } else if (OPENSSL_strcasecmp(p->mode->data, "EXPAND_ONLY") == 0) {
ctx->mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY;
} else {
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
return 0;
}
- } else if (OSSL_PARAM_get_int(p, &n)) {
+ } else if (OSSL_PARAM_get_int(p->mode, &n)) {
if (n != EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND
&& n != EVP_KDF_HKDF_MODE_EXTRACT_ONLY
&& n != EVP_KDF_HKDF_MODE_EXPAND_ONLY) {
}
}
- if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL) {
+ if (p->key != NULL) {
OPENSSL_clear_free(ctx->key, ctx->key_len);
ctx->key = NULL;
- if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->key, 0,
+ if (!OSSL_PARAM_get_octet_string(p->key, (void **)&ctx->key, 0,
&ctx->key_len))
return 0;
}
- if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) {
+ if (p->salt != NULL) {
OPENSSL_free(ctx->salt);
ctx->salt = NULL;
- if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0,
+ if (!OSSL_PARAM_get_octet_string(p->salt, (void **)&ctx->salt, 0,
&ctx->salt_len))
return 0;
}
return 1;
}
+#define hkdf_set_ctx_params_st hkdf_all_set_ctx_params_st
+
+{- produce_param_decoder('hkdf_set_ctx_params',
+ (['KDF_PARAM_MODE', 'mode', 'utf8_string'],
+ ['KDF_PARAM_MODE', 'mode', 'int'],
+ ['KDF_PARAM_PROPERTIES', 'propq', 'utf8_string'],
+ ['ALG_PARAM_ENGINE', 'engine', 'utf8_string'],
+ ['KDF_PARAM_DIGEST', 'digest', 'utf8_string'],
+ ['KDF_PARAM_KEY', 'key', 'octet_string'],
+ ['KDF_PARAM_SALT', 'salt', 'octet_string'],
+ ['KDF_PARAM_FIPS_KEY_CHECK', 'ind_k', 'int'],
+ ['KDF_PARAM_INFO', 'info', 'octet_string', 5],
+ )); -}
+
static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
+ struct hkdf_all_set_ctx_params_st p;
KDF_HKDF *ctx = vctx;
- if (ossl_param_is_empty(params))
- return 1;
+ if (ctx == NULL || !hkdf_set_ctx_params_decoder(params, &p))
+ return 0;
if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
OSSL_KDF_PARAM_FIPS_KEY_CHECK))
return 0;
- if (!hkdf_common_set_ctx_params(ctx, params))
+ if (!hkdf_common_set_ctx_params(ctx, &p))
return 0;
- if (ossl_param_get1_concat_octet_string(params, OSSL_KDF_PARAM_INFO,
- &ctx->info, &ctx->info_len,
- HKDF_MAXINFO) == 0)
+ if (ossl_param_get1_concat_octet_string(p.num_info, p.info,
+ &ctx->info, &ctx->info_len, 0) == 0)
return 0;
#ifdef FIPS_MODULE
- if (OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY) != NULL)
+ if (p.key != NULL)
if (!fips_hkdf_key_check_passed(ctx))
return 0;
#endif
static const OSSL_PARAM *kdf_hkdf_settable_ctx_params(ossl_unused void *ctx,
ossl_unused void *provctx)
{
- static const OSSL_PARAM known_settable_ctx_params[] = {
- HKDF_COMMON_SETTABLES,
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
- OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)
- OSSL_PARAM_END
- };
- return known_settable_ctx_params;
+ return hkdf_set_ctx_params_list;
+}
+
+{- produce_param_decoder('hkdf_get_ctx_params',
+ (['KDF_PARAM_SIZE', 'size', 'size_t'],
+ ['KDF_PARAM_DIGEST', 'digest', 'utf8_string'],
+ ['KDF_PARAM_MODE', 'mode', 'utf8_string'],
+ ['KDF_PARAM_MODE', 'mode', 'int'],
+ ['KDF_PARAM_SALT', 'salt', 'octet_string'],
+ ['KDF_PARAM_INFO', 'info', 'octet_string'],
+ ['ALG_PARAM_FIPS_APPROVED_INDICATOR', 'ind', 'int'],
+ )); -}
+
+static const OSSL_PARAM *hkdf_gettable_ctx_params(ossl_unused void *ctx,
+ ossl_unused void *provctx)
+{
+ return hkdf_get_ctx_params_list;
}
-static int hkdf_common_get_ctx_params(KDF_HKDF *ctx, OSSL_PARAM params[])
+static int hkdf_common_get_ctx_params(void *vctx, OSSL_PARAM params[])
{
- OSSL_PARAM *p;
+ KDF_HKDF *ctx = (KDF_HKDF *)vctx;
+ struct hkdf_get_ctx_params_st p;
- if (ossl_param_is_empty(params))
- return 1;
+ if (ctx == NULL || !hkdf_get_ctx_params_decoder(params, &p))
+ return 0;
- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) {
+ if (p.size != NULL) {
size_t sz = kdf_hkdf_size(ctx);
if (sz == 0)
return 0;
- if (!OSSL_PARAM_set_size_t(p, sz))
+ if (!OSSL_PARAM_set_size_t(p.size, sz))
return 0;
}
- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_DIGEST)) != NULL) {
+ if (p.digest != NULL) {
const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
if (md == NULL)
return 0;
- else if (!OSSL_PARAM_set_utf8_string(p, EVP_MD_get0_name(md)))
+ else if (!OSSL_PARAM_set_utf8_string(p.digest, EVP_MD_get0_name(md)))
return 0;
}
/* OSSL_KDF_PARAM_MODE has multiple parameter types, so look for all instances */
- p = params;
- while ((p = OSSL_PARAM_locate(p, OSSL_KDF_PARAM_MODE)) != NULL) {
- if (p->data_type == OSSL_PARAM_UTF8_STRING) {
+ if (p.mode != NULL) {
+ if (p.mode->data_type == OSSL_PARAM_UTF8_STRING) {
switch (ctx->mode) {
case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
- if (!OSSL_PARAM_set_utf8_string(p, "EXTRACT_AND_EXPAND"))
+ if (!OSSL_PARAM_set_utf8_string(p.mode, "EXTRACT_AND_EXPAND"))
return 0;
break;
case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
- if (!OSSL_PARAM_set_utf8_string(p, "EXTRACT_ONLY"))
+ if (!OSSL_PARAM_set_utf8_string(p.mode, "EXTRACT_ONLY"))
return 0;
break;
case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
- if (!OSSL_PARAM_set_utf8_string(p, "EXPAND_ONLY"))
+ if (!OSSL_PARAM_set_utf8_string(p.mode, "EXPAND_ONLY"))
return 0;
break;
default:
return 0;
}
- } else if (p->data_type == OSSL_PARAM_INTEGER) {
- if (!OSSL_PARAM_set_int(p, ctx->mode))
+ } else if (p.mode->data_type == OSSL_PARAM_INTEGER) {
+ if (!OSSL_PARAM_set_int(p.mode, ctx->mode))
return 0;
}
- p++;
}
- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SALT)) != NULL) {
+ if (p.salt != NULL) {
if (ctx->salt == NULL || ctx->salt_len == 0)
- p->return_size = 0;
- else if (!OSSL_PARAM_set_octet_string(p, ctx->salt, ctx->salt_len))
+ p.salt->return_size = 0;
+ else if (!OSSL_PARAM_set_octet_string(p.salt, ctx->salt, ctx->salt_len))
return 0;
}
- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_INFO)) != NULL) {
+ if (p.info != NULL) {
if (ctx->info == NULL || ctx->info_len == 0)
- p->return_size = 0;
- else if (!OSSL_PARAM_set_octet_string(p, ctx->info, ctx->info_len))
+ p.info->return_size = 0;
+ else if (!OSSL_PARAM_set_octet_string(p.info, ctx->info, ctx->info_len))
return 0;
}
- return 1;
-}
-
-static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
-{
- KDF_HKDF *ctx = (KDF_HKDF *)vctx;
-
- if (ossl_param_is_empty(params))
- return 1;
-
- if (!hkdf_common_get_ctx_params(ctx, params))
- return 0;
-
- if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
+ if (!OSSL_FIPS_IND_GET_CTX_FROM_PARAM(ctx, p.ind))
return 0;
return 1;
}
-static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx,
- ossl_unused void *provctx)
-{
- static const OSSL_PARAM known_gettable_ctx_params[] = {
- HKDF_COMMON_GETTABLES,
- OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
- OSSL_PARAM_END
- };
- return known_gettable_ctx_params;
-}
-
const OSSL_DISPATCH ossl_kdf_hkdf_functions[] = {
{ OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_hkdf_new },
{ OSSL_FUNC_KDF_DUPCTX, (void(*)(void))kdf_hkdf_dup },
(void(*)(void))kdf_hkdf_settable_ctx_params },
{ OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_hkdf_set_ctx_params },
{ OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
- (void(*)(void))kdf_hkdf_gettable_ctx_params },
- { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_hkdf_get_ctx_params },
+ (void(*)(void))hkdf_gettable_ctx_params },
+ { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))hkdf_common_get_ctx_params },
OSSL_DISPATCH_END
};
}
}
+#define kdf_tls1_3_set_ctx_params_st hkdf_all_set_ctx_params_st
+
+{- produce_param_decoder('kdf_tls1_3_set_ctx_params',
+ (['KDF_PARAM_MODE', 'mode', 'utf8_string'],
+ ['KDF_PARAM_MODE', 'mode', 'int'],
+ ['KDF_PARAM_PROPERTIES', 'propq', 'utf8_string'],
+ ['ALG_PARAM_ENGINE', 'engine', 'utf8_string'],
+ ['KDF_PARAM_DIGEST', 'digest', 'utf8_string'],
+ ['KDF_PARAM_KEY', 'key', 'octet_string'],
+ ['KDF_PARAM_SALT', 'salt', 'octet_string'],
+ ['KDF_PARAM_FIPS_KEY_CHECK', 'ind_k', 'int'],
+ ['KDF_PARAM_FIPS_DIGEST_CHECK', 'ind_d', 'int'],
+ ['KDF_PARAM_PREFIX', 'prefix', 'octet_string'],
+ ['KDF_PARAM_LABEL', 'label', 'octet_string'],
+ ['KDF_PARAM_DATA', 'data', 'octet_string'],
+ )); -}
+
static int kdf_tls1_3_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
- const OSSL_PARAM *p;
+ struct hkdf_all_set_ctx_params_st p;
KDF_HKDF *ctx = vctx;
- if (ossl_param_is_empty(params))
- return 1;
+ if (ctx == NULL || !kdf_tls1_3_set_ctx_params_decoder(params, &p))
+ return 0;
- if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
- OSSL_KDF_PARAM_FIPS_DIGEST_CHECK))
+ if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, p.ind_d))
return 0;
- if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, params,
- OSSL_KDF_PARAM_FIPS_KEY_CHECK))
+ if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, p.ind_k))
return 0;
- if (!hkdf_common_set_ctx_params(ctx, params))
+ if (!hkdf_common_set_ctx_params(ctx, &p))
return 0;
if (ctx->mode == EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND) {
return 0;
}
- if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PREFIX)) != NULL) {
+ if (p.prefix != NULL) {
OPENSSL_free(ctx->prefix);
ctx->prefix = NULL;
- if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->prefix, 0,
+ if (!OSSL_PARAM_get_octet_string(p.prefix, (void **)&ctx->prefix, 0,
&ctx->prefix_len))
return 0;
}
- if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_LABEL)) != NULL) {
+ if (p.label != NULL) {
OPENSSL_free(ctx->label);
ctx->label = NULL;
- if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->label, 0,
+ if (!OSSL_PARAM_get_octet_string(p.label, (void **)&ctx->label, 0,
&ctx->label_len))
return 0;
}
- OPENSSL_clear_free(ctx->data, ctx->data_len);
- ctx->data = NULL;
- if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DATA)) != NULL
- && !OSSL_PARAM_get_octet_string(p, (void **)&ctx->data, 0,
- &ctx->data_len))
- return 0;
+ if (p.data != NULL) {
+ OPENSSL_clear_free(ctx->data, ctx->data_len);
+ ctx->data = NULL;
+ if (!OSSL_PARAM_get_octet_string(p.data, (void **)&ctx->data, 0,
+ &ctx->data_len))
+ return 0;
+ }
#ifdef FIPS_MODULE
- if (OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST) != NULL) {
+ if (p.digest != NULL) {
const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
if (!fips_tls1_3_digest_check_passed(ctx, md))
return 0;
}
- if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL)
+ if (p.key != NULL)
if (!fips_tls1_3_key_check_passed(ctx))
return 0;
#endif
static const OSSL_PARAM *kdf_tls1_3_settable_ctx_params(ossl_unused void *ctx,
ossl_unused void *provctx)
{
- static const OSSL_PARAM known_settable_ctx_params[] = {
- HKDF_COMMON_SETTABLES,
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PREFIX, NULL, 0),
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_LABEL, NULL, 0),
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_DATA, NULL, 0),
- OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_DIGEST_CHECK)
- OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)
- OSSL_PARAM_END
- };
- return known_settable_ctx_params;
-}
-
-static int kdf_tls1_3_get_ctx_params(void *vctx, OSSL_PARAM params[])
-{
- KDF_HKDF *ctx = (KDF_HKDF *)vctx;
-
- if (ossl_param_is_empty(params))
- return 1;
-
- if (!hkdf_common_get_ctx_params(ctx, params))
- return 0;
-
- if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
- return 0;
-
- return 1;
-}
-
-static const OSSL_PARAM *kdf_tls1_3_gettable_ctx_params(ossl_unused void *ctx,
- ossl_unused void *provctx)
-{
- static const OSSL_PARAM known_gettable_ctx_params[] = {
- HKDF_COMMON_GETTABLES,
- OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
- OSSL_PARAM_END
- };
- return known_gettable_ctx_params;
+ return kdf_tls1_3_set_ctx_params_list;
}
const OSSL_DISPATCH ossl_kdf_tls1_3_kdf_functions[] = {
(void(*)(void))kdf_tls1_3_settable_ctx_params },
{ OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_tls1_3_set_ctx_params },
{ OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
- (void(*)(void))kdf_tls1_3_gettable_ctx_params },
- { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_tls1_3_get_ctx_params },
+ (void(*)(void))hkdf_gettable_ctx_params },
+ { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))hkdf_common_get_ctx_params },
OSSL_DISPATCH_END
};