* https://www.openssl.org/source/license.html
*/
{-
-use OpenSSL::paramnames qw(produce_param_list);
+use OpenSSL::paramnames qw(produce_param_decoder);
-}
#include <openssl/core_dispatch.h>
#include "crypto/ml_kem.h"
#include "internal/fips.h"
#include "internal/param_build_set.h"
-#include "internal/param_names.h"
#include "prov/implementations.h"
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
return ret;
}
-/* Machine generated by util/perl/OpenSSL/paramnames.pm */
-{- produce_param_list('static', 'ml_kem_key_types',
- 'static', 'ml_kem_key_types_find_pidx',
- (['PKEY_PARAM_ML_KEM_SEED', 'octet_string'],
- ['PKEY_PARAM_PRIV_KEY', 'octet_string'],
- ['PKEY_PARAM_PUB_KEY', 'octet_string'],
- )); -}
-/* End of machine generated */
+{- produce_param_decoder('ml_kem_key_type_params',
+ (['PKEY_PARAM_ML_KEM_SEED', 'seed', 'octet_string'],
+ ['PKEY_PARAM_PRIV_KEY', 'privkey', 'octet_string'],
+ ['PKEY_PARAM_PUB_KEY', 'pubkey', 'octet_string'],
+ )); -}
static const OSSL_PARAM *ml_kem_imexport_types(int selection)
{
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
- return ml_kem_key_types;
+ return ml_kem_key_type_params_ettable;
return NULL;
}
const OSSL_PARAM params[],
int include_private)
{
- const OSSL_PARAM *p = NULL;
const void *pubenc = NULL, *prvenc = NULL, *seedenc = NULL;
size_t publen = 0, prvlen = 0, seedlen = 0, puboff;
const ML_KEM_VINFO *v;
+ struct ml_kem_key_type_params_st p;
/* Invalid attempt to mutate a key, what is the right error to report? */
if (key == NULL || ossl_ml_kem_have_pubkey(key))
return 0;
v = ossl_ml_kem_key_vinfo(key);
+ p = ml_kem_key_type_params_decoder(params);
/*
* When a private key is provided, without a seed, any public key also
* provided will be ignored (apart from length), just as with the seed.
*/
- for (p = params; p->key != NULL; p++)
- switch (ml_kem_key_types_find_pidx(p->key)) {
- default:
- break;
-
- case PIDX_PKEY_PARAM_ML_KEM_SEED:
- if (include_private) {
- /*
- * When a seed is provided, the private and public keys may be ignored,
- * after validating just their lengths. Comparing encodings or hashes
- * when applicable is possible, but not currently implemented.
- */
- if (OSSL_PARAM_get_octet_string_ptr(p, &seedenc, &seedlen) != 1)
- return 0;
- if (seedlen != 0 && seedlen != ML_KEM_SEED_BYTES) {
- ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH);
- return 0;
- }
- }
- break;
-
- case PIDX_PKEY_PARAM_PRIV_KEY:
- if (include_private) {
- if (OSSL_PARAM_get_octet_string_ptr(p, &prvenc, &prvlen) != 1)
- return 0;
- if (prvlen != 0 && prvlen != v->prvkey_bytes) {
- ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
- return 0;
- }
- }
- break;
-
- /* Used only when no seed or private key is provided. */
- case PIDX_PKEY_PARAM_PUB_KEY:
- if (OSSL_PARAM_get_octet_string_ptr(p, &pubenc, &publen) != 1)
- return 0;
- if (publen != 0 && publen != v->pubkey_bytes) {
- ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
- return 0;
- }
- break;
+ if (p.seed != NULL && include_private) {
+ /*
+ * When a seed is provided, the private and public keys may be ignored,
+ * after validating just their lengths. Comparing encodings or hashes
+ * when applicable is possible, but not currently implemented.
+ */
+ if (OSSL_PARAM_get_octet_string_ptr(p.seed, &seedenc, &seedlen) != 1)
+ return 0;
+ if (seedlen != 0 && seedlen != ML_KEM_SEED_BYTES) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH);
+ return 0;
}
+ }
+
+ if (p.privkey != NULL && include_private) {
+ if (OSSL_PARAM_get_octet_string_ptr(p.privkey, &prvenc, &prvlen) != 1)
+ return 0;
+ if (prvlen != 0 && prvlen != v->prvkey_bytes) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+ }
+
+ /* Used only when no seed or private key is provided. */
+ if (p.pubkey != NULL) {
+ if (OSSL_PARAM_get_octet_string_ptr(p.pubkey, &pubenc, &publen) != 1)
+ return 0;
+ if (publen != 0 && publen != v->pubkey_bytes) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+ }
/* The caller MUST specify at least one of seed, private or public keys. */
if (seedlen == 0 && publen == 0 && prvlen == 0) {
return res;
}
-/* Machine generated by util/perl/OpenSSL/paramnames.pm */
-{- produce_param_list('static', 'ml_kem_known_gettable_params',
- 'static', 'ml_kem_get_params_find_pidx',
- (['PKEY_PARAM_BITS', 'int'],
- ['PKEY_PARAM_SECURITY_BITS', 'int'],
- ['PKEY_PARAM_MAX_SIZE', 'int'],
- ['PKEY_PARAM_SECURITY_CATEGORY', 'int'],
- ['PKEY_PARAM_ML_KEM_SEED', 'octet_string'],
- ['PKEY_PARAM_PRIV_KEY', 'octet_string'],
- ['PKEY_PARAM_PUB_KEY', 'octet_string'],
- ['PKEY_PARAM_ENCODED_PUBLIC_KEY', 'octet_string'],
- )); -}
-/* End of machine generated */
+{- produce_param_decoder('ml_kem_get_params',
+ (['PKEY_PARAM_BITS', 'bits', 'int'],
+ ['PKEY_PARAM_SECURITY_BITS', 'secbits', 'int'],
+ ['PKEY_PARAM_MAX_SIZE', 'maxsize', 'int'],
+ ['PKEY_PARAM_SECURITY_CATEGORY', 'seccat', 'int'],
+ ['PKEY_PARAM_ML_KEM_SEED', 'seed', 'octet_string'],
+ ['PKEY_PARAM_PRIV_KEY', 'privkey', 'octet_string'],
+ ['PKEY_PARAM_PUB_KEY', 'pubkey', 'octet_string'],
+ ['PKEY_PARAM_ENCODED_PUBLIC_KEY', 'encpubkey', 'octet_string'],
+ )); -}
static const OSSL_PARAM *ml_kem_gettable_params(void *provctx)
{
- return ml_kem_known_gettable_params;
+ return ml_kem_get_params_ettable;
}
#ifndef FIPS_MODULE
}
#endif
+static int ml_kem_get_key_param(const ML_KEM_KEY *key, OSSL_PARAM *p,
+ size_t bytes,
+ int (*get_f)(uint8_t *out, size_t len,
+ const ML_KEM_KEY *key))
+{
+ if (p->data_type != OSSL_PARAM_OCTET_STRING)
+ return 0;
+ p->return_size = bytes;
+ if (p->data != NULL)
+ if (p->data_size < p->return_size
+ || !(*get_f)(p->data, p->return_size, key))
+ return 0;
+ return 1;
+}
+
/*
* It is assumed the key is guaranteed non-NULL here, and is from this provider
*/
{
ML_KEM_KEY *key = vkey;
const ML_KEM_VINFO *v = ossl_ml_kem_key_vinfo(key);
- OSSL_PARAM *p;
- uint8_t *pubenc = NULL;
-
- for (p = params; p->key != NULL; p++)
- switch (ml_kem_get_params_find_pidx(p->key)) {
- default:
- break;
-
- case PIDX_PKEY_PARAM_BITS:
- if (!OSSL_PARAM_set_int(p, v->bits))
- return 0;
- break;
-
- case PIDX_PKEY_PARAM_SECURITY_BITS:
- if (!OSSL_PARAM_set_int(p, v->secbits))
- return 0;
- break;
-
- case PIDX_PKEY_PARAM_MAX_SIZE:
- if (!OSSL_PARAM_set_int(p, v->ctext_bytes))
- return 0;
- break;
-
- case PIDX_PKEY_PARAM_SECURITY_CATEGORY:
- if (!OSSL_PARAM_set_int(p, v->security_category))
- return 0;
- break;
+ struct ml_kem_get_params_st p = ml_kem_get_params_decoder(params);
+
+ if (p.bits != NULL && !OSSL_PARAM_set_int(p.bits, v->bits))
+ return 0;
+
+ if (p.secbits != NULL && !OSSL_PARAM_set_int(p.secbits, v->secbits))
+ return 0;
+
+ if (p.maxsize != NULL && !OSSL_PARAM_set_int(p.maxsize, v->ctext_bytes))
+ return 0;
+
+ if (p.seccat != NULL && !OSSL_PARAM_set_int(p.seccat, v->security_category))
+ return 0;
+ if (p.pubkey != NULL && ossl_ml_kem_have_pubkey(key)) {
/* Exported to EVP_PKEY_get_raw_public_key() */
- case PIDX_PKEY_PARAM_PUB_KEY:
+ if (!ml_kem_get_key_param(key, p.pubkey, v->pubkey_bytes,
+ &ossl_ml_kem_encode_public_key))
+ return 0;
+ }
+
+ if (p.encpubkey != NULL && ossl_ml_kem_have_pubkey(key)) {
/* Needed by EVP_PKEY_get1_encoded_public_key() */
- case PIDX_PKEY_PARAM_ENCODED_PUBLIC_KEY:
- if (ossl_ml_kem_have_pubkey(key)) {
- if (p->data_type != OSSL_PARAM_OCTET_STRING)
- return 0;
- p->return_size = v->pubkey_bytes;
- if (p->data == NULL)
- break;
- if (p->data_size < p->return_size)
- return 0;
- if (pubenc != NULL) {
- memcpy(p->data, pubenc, p->return_size);
- break;
- }
- if (!ossl_ml_kem_encode_public_key(p->data, p->return_size, key))
- return 0;
- pubenc = p->data;
- }
- break;
+ if (!ml_kem_get_key_param(key, p.encpubkey, v->pubkey_bytes,
+ &ossl_ml_kem_encode_public_key))
+ return 0;
+ }
+ if (p.privkey != NULL && ossl_ml_kem_have_prvkey(key)) {
/* Exported to EVP_PKEY_get_raw_private_key() */
- case PIDX_PKEY_PARAM_PRIV_KEY:
- if (ossl_ml_kem_have_prvkey(key)) {
- if (p->data_type != OSSL_PARAM_OCTET_STRING)
- return 0;
- p->return_size = v->prvkey_bytes;
- if (p->data != NULL) {
- if (p->data_size < p->return_size)
- return 0;
- if (!ossl_ml_kem_encode_private_key(p->data, p->return_size, key))
- return 0;
- }
- }
- break;
+ if (!ml_kem_get_key_param(key, p.privkey, v->prvkey_bytes,
+ &ossl_ml_kem_encode_private_key))
+ return 0;
+ }
+ if (p.seed != NULL && ossl_ml_kem_have_seed(key)) {
/* Exported for import */
- case PIDX_PKEY_PARAM_ML_KEM_SEED:
- if (ossl_ml_kem_have_seed(key)) {
- if (p->data_type != OSSL_PARAM_OCTET_STRING)
- return 0;
- p->return_size = ML_KEM_SEED_BYTES;
- if (p->data != NULL) {
- if (p->data_size < p->return_size)
- return 0;
- if (!ossl_ml_kem_encode_seed(p->data, p->return_size, key))
- return 0;
- }
- }
- break;
- }
+ if (!ml_kem_get_key_param(key, p.seed, ML_KEM_SEED_BYTES,
+ &ossl_ml_kem_encode_seed))
+ return 0;
+ }
return 1;
}
+{- produce_param_decoder('ml_kem_set_params',
+ (['PKEY_PARAM_ENCODED_PUBLIC_KEY', 'pub', 'octet_string'],
+ )); -}
+
static const OSSL_PARAM *ml_kem_settable_params(void *provctx)
{
- static const OSSL_PARAM arr[] = {
- /* Used in TLS via EVP_PKEY_set1_encoded_public_key(). */
- OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
- OSSL_PARAM_END
- };
-
- return arr;
+ return ml_kem_set_params_ettable;
}
static int ml_kem_set_params(void *vkey, const OSSL_PARAM params[])
{
ML_KEM_KEY *key = vkey;
- const OSSL_PARAM *p;
const void *pubenc = NULL;
size_t publen = 0;
+ struct ml_kem_set_params_st p;
if (ossl_param_is_empty(params))
return 1;
- p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
- if (p != NULL
- && (OSSL_PARAM_get_octet_string_ptr(p, &pubenc, &publen) != 1
+ p = ml_kem_set_params_decoder(params);
+
+ /* Used in TLS via EVP_PKEY_set1_encoded_public_key(). */
+ if (p.pub != NULL
+ && (OSSL_PARAM_get_octet_string_ptr(p.pub, &pubenc, &publen) != 1
|| publen != key->vinfo->pubkey_bytes)) {
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
return 0;
return ossl_ml_kem_parse_public_key(pubenc, publen, key);
}
+{- produce_param_decoder('ml_kem_gen_set_params',
+ (['PKEY_PARAM_ML_DSA_SEED', 'seed', 'octet_string'],
+ ['PKEY_PARAM_PROPERTIES', 'propq', 'utf8_string'],
+ )); -}
+
static int ml_kem_gen_set_params(void *vgctx, const OSSL_PARAM params[])
{
PROV_ML_KEM_GEN_CTX *gctx = vgctx;
- const OSSL_PARAM *p;
+ struct ml_kem_gen_set_params_st p;
if (gctx == NULL)
return 0;
if (ossl_param_is_empty(params))
return 1;
- p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES);
- if (p != NULL) {
- if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ p = ml_kem_gen_set_params_decoder(params);
+
+ if (p.propq != NULL) {
+ if (p.propq->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
OPENSSL_free(gctx->propq);
- if ((gctx->propq = OPENSSL_strdup(p->data)) == NULL)
+ if ((gctx->propq = OPENSSL_strdup(p.propq->data)) == NULL)
return 0;
}
- p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ML_KEM_SEED);
- if (p != NULL) {
+ if (p.seed != NULL) {
size_t len = ML_KEM_SEED_BYTES;
gctx->seed = gctx->seedbuf;
- if (OSSL_PARAM_get_octet_string(p, (void **)&gctx->seed, len, &len)
+ if (OSSL_PARAM_get_octet_string(p.seed, (void **)&gctx->seed, len, &len)
&& len == ML_KEM_SEED_BYTES)
return 1;
static const OSSL_PARAM *ml_kem_gen_settable_params(ossl_unused void *vgctx,
ossl_unused void *provctx)
{
- static OSSL_PARAM settable[] = {
- OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ML_KEM_SEED, NULL, 0),
- OSSL_PARAM_END
- };
- return settable;
+ return ml_kem_gen_set_params_ettable;
}
static void *ml_kem_gen(void *vgctx, OSSL_CALLBACK *osslcb, void *cbarg)