EVP_PKEY-ML-KEM(7SSL)
β¨ NAME β¨
okay bestie, buckle up π this whole page β the OpenSSL one, EVP_PKEY-ML-KEM(7SSL) β is basically the β¨group chatβ¨ for ML-KEM. Like, every single name that follows is the same vibe, the same little family, all here to tell you about ML-KEM keytype and algorithm support.
The whole squad, no cap, every last one of them:
EVP_PKEY-ML-KEMEVP_KEYMGMT-ML-KEMEVP_PKEY-ML-KEM-512EVP_PKEY-ML-KEM-768EVP_PKEY-ML-KEM-1024EVP_KEYMGMT-ML-KEM-512EVP_KEYMGMT-ML-KEM-768EVP_KEYMGMT-ML-KEM-1024
and that's the whole invite list π β all of them exist for ML-KEM keytype and algorithm support, fr fr. π
β¨ DESCRIPTION β¨
ok bestie so here's the tea: the ML-KEM-512, ML-KEM-768, and ML-KEM-1024 keytypes are implemented in OpenSSL's default and FIPS providers. that's the whole vibe. π
π Keygen Parameters
ngl there are no mandatory parameters required for generating a key pair. if you want to set explicit parameters though, call EVP_PKEY_CTX_set_params() after you've called EVP_PKEY_keygen_init(). order matters, bestie.
"seed"(OSSL_PKEY_PARAM_ML_KEM_SEED) <octet string> β so internally, ML-KEM generates keys using a 64-byte random value (the seed π), and that seed is literally the concatenation of the 32-bytedandzparameters described in FIPS 203. this optional parameter is your β¨ moment β¨ to set a pre-determined seed before keypair generation happens.
Generated keys default to retaining the seed used. the seed is also by default retained when keys are loaded from PKCS#8 files in the seed format. and when it's available, the seed parameter is also used during key export and import β with keys (by default) regenerated from the seed even when the seed is also provided on import. (iykyk.) see "Provider configuration parameters" below for the related controls.
When the seed is retained it's also available as a gettable parameter, and private key output to PKCS#8 files will by default include the seed. when the seed was not initially known, or just wasn't retained, PKCS#8 private key files will contain only the private key in FIPS 203 dk format. no seed, just vibes.
"properties"(OSSL_PKEY_PARAM_PROPERTIES) <UTF8 string> β sets properties to be used when fetching algorithm implementations used for ML-KEM hashing operations. useEVP_PKEY_CTX_set_params(3)after callingEVP_PKEY_keygen_init(3). π
The following key generation parameter can be retrieved with EVP_PKEY_CTX_get_params(3) from the OpenSSL FIPS provider:
"fips-indicator"(OSSL_PKEY_PARAM_FIPS_APPROVED_INDICATOR) <integer> β returns1if the operation is FIPS approved, or0otherwise. see "FIPS indicators" infips_module(7)for more info.
π Encoder Parameters
"output_formats"(OSSL_PKEY_PARAM_OUTPUT_FORMATS) <UTF8 string> β this parameter can be used withOSSL_ENCODER_CTX_new_for_pkey(3)andOSSL_ENCODER_CTX_set_params(3)to select the preferred PKCS#8 output formats of a private key. when this parameter is either not specified or empty, the behaviour is determined by the provider configuration parameters described below. otherwise, it has the same syntax and behaviour as the provider configurationml-kem.output_formatsparameter β except that theml-kem.retain-seedparameter is then ignored, i.e. the"seed-only"and"seed-priv"formats remain available so long as the seed was initially known, regardless of any setting ofml-kem.retain-seed. slay.
π Common parameters
In addition to the common parameters that all keytypes should support (see "Common Information Parameters" in provider-keymgmt(7)), ML-KEM keys support the parameters listed below. these are gettable using EVP_PKEY_get_octet_string_param(3) or EVP_PKEY_get_params(3). they can be initialised via EVP_PKEY_fromdata(3), and are returned by EVP_PKEY_todata(3) given a suitable selection.
β οΈ once a public or private key is configured, it can no longer be modified, nor can another key component be added. it's locked in. no take-backs. π
"pub"(OSSL_PKEY_PARAM_PUB_KEY) <octet string> β the public key value.
this parameter is used when importing or exporting the public key value with the EVP_PKEY_fromdata() and EVP_PKEY_todata() functions. the key length and content is that of the FIPS 203 (Algorithm 16: ML-KEM.KeyGen_internal) ek public key for the given ML-KEM variant. initial import aside, this parameter is otherwise only gettable.
"priv"(OSSL_PKEY_PARAM_PRIV_KEY) <octet string> β the private key value.
this parameter is used when importing or exporting the private key value with the EVP_PKEY_fromdata() and EVP_PKEY_todata() functions. the key length and content is that of the FIPS 203 (Algorithm 16: ML-KEM.KeyGen_internal) dk private key for the given ML-KEM variant. initial import aside, this parameter is otherwise only gettable.
"encoded-pub-key"(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY) <octet string> β used for getting and setting the encoding of a public key. the key format is that ofekin FIPS 203, Algorithm 16:ML-KEM.KeyGen_internal. updates of the public and private key components are only allowed on keys that are empty. once a public or private key component is set, no further changes are allowed. this parameter is gettable and settable (once only). one shot, bestie. π«Ά
π¦ Provider configuration parameters
see the description of the -provparam option in openssl(1) to learn how to set provider configuration parameters in the command line tools. see OSSL_PROVIDER_add_conf_parameter(3) to learn how to set provider configuration options programmatically.
"ml-kem.import_pct_type"(OSSL_PKEY_PARAM_ML_KEM_IMPORT_PCT_TYPE) <UTF8 string> β when an ML-KEM key is imported as an explicit FIPS 203dkdecapsulation key, rather than a seed, a pairwise consistency test (PCT) is optionally performed. by default, or when this parameter is set explicitly to"random", the PCT is performed with a random entropy value for the encapsulation step. setting the parameter to"fixed"still runs the test, but the encapsulation entropy is a fixed 32 byte value. specifying any other value of the parameter, e.g."none", skips the test. π"ml-kem.retain_seed"(OSSL_PKEY_PARAM_ML_KEM_RETAIN_SEED) <UTF8 string> β when set to a string representing a false boolean value (seeOSSL_PROVIDER_conf_get_bool(3)), the seed will not be included when keys are encoded to PKCS#8 form β unless the"output_formats"encoder parameter is set to a nonempty value, as described above. the output PKCS#8 object will contain only the FIPS 203"dk"key. periodt."ml-kem.prefer_seed"(OSSL_PKEY_PARAM_ML_KEM_PREFER_SEED) <UTF8 string> β when decoding PKCS#8 objects that contain both a seed and the FIPS 203"dk"private key, the seed is by default used to regenerate the key, and the companion key is ignored. when this configuration parameter is set to a string representing a false boolean value (seeOSSL_PROVIDER_conf_get_bool(3)), the seed is ignored (neither used to regenerate the key, nor retained), and the companion key is used instead. choose your fighter. π₯"ml-kem.input_formats"(OSSL_PKEY_PARAM_ML_KEM_INPUT_FORMATS) <UTF8 string> β list of enabled private key input formats when parsing PKCS#8 objects. list elements are separated by commas and/or spaces or tabs. the list of enabled formats can be specified in the configuration file, as seen in the "EXAMPLES" section below, or via the-provparamcommand-line option (see alsoOSSL_PROVIDER_add_conf_parameter(3)).
Values specified on the command-line override any configuration file settings. by default all the supported formats are enabled. the supported formats are:
"seed-priv": this format represents PKCS#8 objects in which both the FIPS 203 64-byte (d,z) seed and the decapsulation keydkare present in the private key as part of the DER encoding of the ASN.1 sequence:
ML-KEM-PrivateKey ::= CHOICE {
seed [0] IMPLICIT OCTET STRING (SIZE (64)),
expandedKey OCTET STRING (SIZE (1632 | 2400 | 3168)),
both SEQUENCE {
seed OCTET STRING (SIZE (64)),
expandedKey OCTET STRING (SIZE (1632 | 2400 | 3168)) } }
If the "seed-priv" format is not included in the list, this format will not be recognised on input.
"seed-only": this format represents PKCS#8 objects in which only the 64-byte (d,z) seed is present in the above sequence. if the"seed-only"format is not included in the list, this format will not be recognised on input."priv-only": this format represents PKCS#8 objects in which only the FIPS 203 decapsulation keydkis present in the above sequence. if the"priv-only"format is not included in the list, this format will not be recognised on input."oqskeypair": this format represents PKCS#8 objects in which the private key is a DER encoding of an octet string containing the concatenaton of the FIPS 203 decapsulation keydkand the encapsulation keyek. this encoding is used in some builds of the"oqsprovider". if the"oqskeypair"format is not included in the list, this format will not be recognised on input."bare-seed": this format represents PKCS#8 objects in which the private key contains the 64-byte FIPS 203 seed (d,z) without any ASN.1 encapsulation. if the"bare-seed"format is not included in the list, this format will not be recognised on input."bare-priv": this format represents PKCS#8 objects in which the private key contains the FIPS 203 decapsulation keydkwithout any ASN.1 encapsulation. if the"bare-priv"format is not included in the list, this format will not be recognised on input.
"ml-kem.output_formats"(OSSL_PKEY_PARAM_ML_KEM_OUTPUT_FORMATS) <UTF8 string> β ordered list of enabled private key output formats when writing PKCS#8 files. list elements are separated by commas, spaces or tabs. the list of enabled formats can be specified in the configuration file, as seen in the "EXAMPLES" section below, or via the-provparamcommand-line option.
This supports the same set of formats as described under "ml-kem.input_formats" above. the order in which elements are listed is important β the selected format will be the first one that is possible to output. if the key seed is known, the first listed format will be selected. if the key seed is not known, the first format that omits the seed will be selected. the default order is equivalent to "seed-priv" first and "priv-only" second, with both seed and key output when the seed is available, and just the key otherwise. if "seed-only" is listed first, then the seed will be output without the key when available, otherwise the output will have just the key. if "priv-only" is listed first, then just the key is output regardless of whether the seed is present. the legacy "oqskeypair", "bare-seed" and "bare-priv" formats can also be output, by listing those first. π
π CONFORMING TO π
FIPS 203
β¨ EXAMPLES β¨
okay bestie this is the part where we actually do the thing π here's every single way you can get your hands on an ML-KEM moment.
Wanna get yourself an EVP_PKEY context? just call:
EVP_PKEY_CTX *pctx =
EVP_PKEY_CTX_new_from_name(NULL, "ML-KEM-768", NULL);
And if you want to β¨manifestβ¨ an ML-KEM-768 key out of thin air, it's literally just:
pkey = EVP_PKEY_Q_keygen(NULL, NULL, "ML-KEM-768");
Now. Say you've got an ML-KEM private key in seed format and you want to glow it up into the FIPS 203 dk format? run this:
$ openssl pkey -provparam ml-kem.retain_seed=no \
-in seed-only.pem -out priv-only.pem
And if you'd rather generate a key β like, say, an ML-KEM-768 key β already in FIPS 203 dk format from the jump, you do:
$ openssl genpkey -provparam ml-kem.retain_seed=no \
-algorithm ml-kem-768 -out priv-only.pem
Now here's a lil scenario for you π what if you have a PKCS#8 file holding both a seed and a key, and you lowkey wanna import the companion key instead of the seed? easy:
$ openssl pkey -provparam ml-kem.prefer_seed=no \
-in seed-priv.pem -out priv-only.pem
And in the openssl.cnf file, all of this looks like this:
openssl_conf = openssl_init
[openssl_init]
providers = providers_sect
# Can be referenced in one or more provider sections
[ml_kem_sect]
prefer_seed = yes
retain_seed = yes
# OQS legacy formats disabled
input_formats = seed-priv, seed-only, priv-only
# Output either the seed alone, or else the key alone
output_formats = seed-only, priv-only
[providers_sect]
default = default_sect
# Or perhaps just: base = default_sect
base = base_sect
[default_sect]
ml-kem = ml_kem_sect
[base_sect]
ml-kem = ml_kem_sect
periodt, that's the whole config vibe π
π SEE ALSO π
go read these next, bestie, they're all in the family:
openssl(1)openssl-pkey(1)openssl-genpkey(1)EVP_KEYMGMT(3)EVP_PKEY(3)EVP_PKEY_get_raw_private_key(3)EVP_PKEY_get_raw_public_key(3)EVP_PKEY_get1_encoded_public_key(3)OSSL_ENCODER_CTX_new_for_pkey(3)OSSL_ENCODER_CTX_set_params(3)OSSL_PROVIDER_add_conf_parameter(3)provider-keymgmt(7)EVP_KEM-ML-KEM(7)
π HISTORY π
This functionality was added in OpenSSL 3.5. And the "output_formats" OSSL_ENCODER_CTX parameter? that one only showed up in OpenSSL 4.0 β so don't come at me if it's missing on your older install π
π COPYRIGHT π
Copyright 2024-2026 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 in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.
and that's a wrap on the whole page, bestie π«Ά this was page 3 of EVP_PKEY-ML-KEM(7SSL), brought to you by OpenSSL 4.0.3, dated 2026-09-29. go forth and quantum-resist, you absolute icon πβ¨
π¦ where this page comes from
- ubuntu stonking: openssl 4.0.3-1ubuntu1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms