Skip to content

Commit d845eda

Browse files
committed
add 0012-FIPS-ML-KEM-IKME-indicator.patch and 0013-FIPS-ML-KEM-SEED-indicator.patch
1 parent 6ad1eba commit d845eda

File tree

3 files changed

+214
-0
lines changed

3 files changed

+214
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
commit 03f69738add6f3f3885b70b963f4e9dab393b773
2+
Author: nkraetzschmar <9020053+nkraetzschmar@users.noreply.github.com>
3+
Date: Tue Mar 10 15:40:02 2026 +0100
4+
5+
ml-kem: add FIPS indicator for caller-provided encapsulation randomness
6+
7+
Mark encapsulation using OSSL_KEM_PARAM_IKME as unapproved in FIPS mode unless tolerated via indicator, as randomness must originate from an approved RBG.
8+
9+
diff --git a/providers/fips/include/fips_indicator_params.inc b/providers/fips/include/fips_indicator_params.inc
10+
index 2f97ffde4a..68dfce36c1 100644
11+
--- a/providers/fips/include/fips_indicator_params.inc
12+
+++ b/providers/fips/include/fips_indicator_params.inc
13+
@@ -26,3 +26,4 @@ OSSL_FIPS_PARAM(x963kdf_key_check, X963KDF_KEY_CHECK, 1)
14+
OSSL_FIPS_PARAM(x942kdf_key_check, X942KDF_KEY_CHECK, 1)
15+
OSSL_FIPS_PARAM(pbkdf2_lower_bound_check, PBKDF2_LOWER_BOUND_CHECK, 1)
16+
OSSL_FIPS_PARAM(ecdh_cofactor_check, ECDH_COFACTOR_CHECK, 1)
17+
+OSSL_FIPS_PARAM(ml_kem_ikme_check, ML_KEM_IKME_CHECK, 1)
18+
diff --git a/providers/implementations/kem/ml_kem_kem.c b/providers/implementations/kem/ml_kem_kem.c
19+
index 722eadf228..66c219d794 100644
20+
--- a/providers/implementations/kem/ml_kem_kem.c
21+
+++ b/providers/implementations/kem/ml_kem_kem.c
22+
@@ -35,6 +35,8 @@ typedef struct {
23+
uint8_t entropy_buf[ML_KEM_RANDOM_BYTES];
24+
uint8_t *entropy;
25+
int op;
26+
+ void *provctx;
27+
+ OSSL_FIPS_IND_DECLARE
28+
} PROV_ML_KEM_CTX;
29+
30+
static void *ml_kem_newctx(void *provctx)
31+
@@ -47,6 +49,8 @@ static void *ml_kem_newctx(void *provctx)
32+
ctx->key = NULL;
33+
ctx->entropy = NULL;
34+
ctx->op = 0;
35+
+ ctx->provctx = provctx;
36+
+ OSSL_FIPS_IND_INIT(ctx)
37+
return ctx;
38+
}
39+
40+
@@ -112,6 +116,16 @@ static int ml_kem_set_ctx_params(void *vctx, const OSSL_PARAM params[])
41+
if (ossl_param_is_empty(params))
42+
return 1;
43+
44+
+#ifdef FIPS_MODULE
45+
+ if (!OSSL_FIPS_IND_SET_CTX_PARAM(
46+
+ ctx,
47+
+ OSSL_FIPS_IND_SETTABLE0,
48+
+ params,
49+
+ OSSL_KEM_PARAM_FIPS_IKME_CHECK
50+
+ ))
51+
+ return 0;
52+
+#endif
53+
+
54+
/* Encapsulation ephemeral input key material "ikmE" */
55+
if (ctx->op == EVP_PKEY_OP_ENCAPSULATE
56+
&& (p = OSSL_PARAM_locate_const(params, OSSL_KEM_PARAM_IKME)) != NULL) {
57+
@@ -120,8 +134,24 @@ static int ml_kem_set_ctx_params(void *vctx, const OSSL_PARAM params[])
58+
ctx->entropy = ctx->entropy_buf;
59+
if (OSSL_PARAM_get_octet_string(p, (void **)&ctx->entropy,
60+
len, &len)
61+
- && len == ML_KEM_RANDOM_BYTES)
62+
+ && len == ML_KEM_RANDOM_BYTES) {
63+
+#ifdef FIPS_MODULE
64+
+ if (!OSSL_FIPS_IND_ON_UNAPPROVED(
65+
+ ctx,
66+
+ OSSL_FIPS_IND_SETTABLE0,
67+
+ PROV_LIBCTX_OF(ctx->provctx),
68+
+ "ML-KEM",
69+
+ "Explicit encapsulation seed",
70+
+ ossl_fips_config_ml_kem_ikme_check
71+
+ )) {
72+
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH);
73+
+ OPENSSL_cleanse(ctx->entropy, ML_KEM_RANDOM_BYTES);
74+
+ ctx->entropy = NULL;
75+
+ return 0;
76+
+ }
77+
+#endif
78+
return 1;
79+
+ }
80+
81+
/* Possibly, but much less likely wrong type */
82+
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH);
83+
diff --git a/util/perl/OpenSSL/paramnames.pm b/util/perl/OpenSSL/paramnames.pm
84+
index 262c184ca2..e681747e83 100644
85+
--- a/util/perl/OpenSSL/paramnames.pm
86+
+++ b/util/perl/OpenSSL/paramnames.pm
87+
@@ -58,6 +58,7 @@ my %params = (
88+
'PROV_PARAM_PBKDF2_LOWER_BOUND_CHECK' => "pbkdf2-lower-bound-check", # uint
89+
'PROV_PARAM_ECDH_COFACTOR_CHECK' => "ecdh-cofactor-check", # uint
90+
'PROV_PARAM_SIGNATURE_DIGEST_CHECK' => "signature-digest-check", # uint
91+
+ 'PROV_PARAM_ML_KEM_IKME_CHECK' => "ml-kem-ikme-check", # uint
92+
93+
# Self test callback parameters
94+
'PROV_PARAM_SELF_TEST_PHASE' => "st-phase",# utf8_string
95+
@@ -543,6 +544,7 @@ my %params = (
96+
'KEM_PARAM_OPERATION' => "operation",
97+
'KEM_PARAM_IKME' => "ikme",
98+
'KEM_PARAM_FIPS_KEY_CHECK' => '*PKEY_PARAM_FIPS_KEY_CHECK',
99+
+ 'KEM_PARAM_FIPS_IKME_CHECK' => '*PROV_PARAM_ML_KEM_IKME_CHECK',
100+
'KEM_PARAM_FIPS_APPROVED_INDICATOR' => '*ALG_PARAM_FIPS_APPROVED_INDICATOR',
101+
102+
# Capabilities
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
commit c44f6f626b49643fef3a901552192634b71c3912
2+
Author: nkraetzschmar <9020053+nkraetzschmar@users.noreply.github.com>
3+
Date: Tue Mar 10 22:14:09 2026 +0100
4+
5+
ml-kem: add FIPS indicator for caller-provided key generation seed
6+
7+
Mark key generation using OSSL_PKEY_PARAM_ML_KEM_SEED as unapproved in FIPS mode unless tolerated via indicator, as key generation randomness must originate from an approved RBG.
8+
9+
diff --git a/providers/fips/include/fips_indicator_params.inc b/providers/fips/include/fips_indicator_params.inc
10+
index 68dfce36c1..667fb46852 100644
11+
--- a/providers/fips/include/fips_indicator_params.inc
12+
+++ b/providers/fips/include/fips_indicator_params.inc
13+
@@ -27,3 +27,4 @@ OSSL_FIPS_PARAM(x942kdf_key_check, X942KDF_KEY_CHECK, 1)
14+
OSSL_FIPS_PARAM(pbkdf2_lower_bound_check, PBKDF2_LOWER_BOUND_CHECK, 1)
15+
OSSL_FIPS_PARAM(ecdh_cofactor_check, ECDH_COFACTOR_CHECK, 1)
16+
OSSL_FIPS_PARAM(ml_kem_ikme_check, ML_KEM_IKME_CHECK, 1)
17+
+OSSL_FIPS_PARAM(ml_kem_seed_check, ML_KEM_SEED_CHECK, 1)
18+
diff --git a/providers/implementations/keymgmt/ml_kem_kmgmt.c b/providers/implementations/keymgmt/ml_kem_kmgmt.c
19+
index 0be2a1e298..5ca5c488ba 100644
20+
--- a/providers/implementations/keymgmt/ml_kem_kmgmt.c
21+
+++ b/providers/implementations/keymgmt/ml_kem_kmgmt.c
22+
@@ -61,6 +61,7 @@ typedef struct ml_kem_gen_ctx_st {
23+
int evp_type;
24+
uint8_t seedbuf[ML_KEM_SEED_BYTES];
25+
uint8_t *seed;
26+
+ OSSL_FIPS_IND_DECLARE
27+
} PROV_ML_KEM_GEN_CTX;
28+
29+
static int ml_kem_pairwise_test(const ML_KEM_KEY *key, int key_flags)
30+
@@ -687,6 +688,16 @@ static int ml_kem_gen_set_params(void *vgctx, const OSSL_PARAM params[])
31+
if (ossl_param_is_empty(params))
32+
return 1;
33+
34+
+#ifdef FIPS_MODULE
35+
+ if (!OSSL_FIPS_IND_SET_CTX_PARAM(
36+
+ gctx,
37+
+ OSSL_FIPS_IND_SETTABLE0,
38+
+ params,
39+
+ OSSL_KEM_PARAM_FIPS_SEED_CHECK
40+
+ ))
41+
+ return 0;
42+
+#endif
43+
+
44+
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES);
45+
if (p != NULL) {
46+
if (p->data_type != OSSL_PARAM_UTF8_STRING)
47+
@@ -702,8 +713,24 @@ static int ml_kem_gen_set_params(void *vgctx, const OSSL_PARAM params[])
48+
49+
gctx->seed = gctx->seedbuf;
50+
if (OSSL_PARAM_get_octet_string(p, (void **)&gctx->seed, len, &len)
51+
- && len == ML_KEM_SEED_BYTES)
52+
+ && len == ML_KEM_SEED_BYTES) {
53+
+#ifdef FIPS_MODULE
54+
+ if (!OSSL_FIPS_IND_ON_UNAPPROVED(
55+
+ gctx,
56+
+ OSSL_FIPS_IND_SETTABLE0,
57+
+ PROV_LIBCTX_OF(gctx->provctx),
58+
+ "ML-KEM",
59+
+ "Explicit key generation seed",
60+
+ ossl_fips_config_ml_kem_seed_check
61+
+ )) {
62+
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH);
63+
+ OPENSSL_cleanse(gctx->seed, ML_KEM_SEED_BYTES);
64+
+ gctx->seed = NULL;
65+
+ return 0;
66+
+ }
67+
+#endif
68+
return 1;
69+
+ }
70+
71+
/* Possibly, but less likely wrong data type */
72+
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH);
73+
@@ -731,6 +758,8 @@ static void *ml_kem_gen_init(void *provctx, int selection,
74+
gctx->selection = selection;
75+
gctx->evp_type = evp_type;
76+
gctx->provctx = provctx;
77+
+ OSSL_FIPS_IND_INIT(gctx)
78+
+
79+
if (ml_kem_gen_set_params(gctx, params))
80+
return gctx;
81+
82+
@@ -799,7 +828,7 @@ static void ml_kem_gen_cleanup(void *vgctx)
83+
return;
84+
85+
if (gctx->seed != NULL)
86+
- OPENSSL_cleanse(gctx->seed, ML_KEM_RANDOM_BYTES);
87+
+ OPENSSL_cleanse(gctx->seed, ML_KEM_SEED_BYTES);
88+
OPENSSL_free(gctx->propq);
89+
OPENSSL_free(gctx);
90+
}
91+
diff --git a/util/perl/OpenSSL/paramnames.pm b/util/perl/OpenSSL/paramnames.pm
92+
index e681747e83..74858a45bb 100644
93+
--- a/util/perl/OpenSSL/paramnames.pm
94+
+++ b/util/perl/OpenSSL/paramnames.pm
95+
@@ -59,6 +59,7 @@ my %params = (
96+
'PROV_PARAM_ECDH_COFACTOR_CHECK' => "ecdh-cofactor-check", # uint
97+
'PROV_PARAM_SIGNATURE_DIGEST_CHECK' => "signature-digest-check", # uint
98+
'PROV_PARAM_ML_KEM_IKME_CHECK' => "ml-kem-ikme-check", # uint
99+
+ 'PROV_PARAM_ML_KEM_SEED_CHECK' => "ml-kem-seed-check", # uint
100+
101+
# Self test callback parameters
102+
'PROV_PARAM_SELF_TEST_PHASE' => "st-phase",# utf8_string
103+
@@ -545,6 +546,7 @@ my %params = (
104+
'KEM_PARAM_IKME' => "ikme",
105+
'KEM_PARAM_FIPS_KEY_CHECK' => '*PKEY_PARAM_FIPS_KEY_CHECK',
106+
'KEM_PARAM_FIPS_IKME_CHECK' => '*PROV_PARAM_ML_KEM_IKME_CHECK',
107+
+ 'KEM_PARAM_FIPS_SEED_CHECK' => '*PROV_PARAM_ML_KEM_SEED_CHECK',
108+
'KEM_PARAM_FIPS_APPROVED_INDICATOR' => '*ALG_PARAM_FIPS_APPROVED_INDICATOR',
109+
110+
# Capabilities

upstream_patches/series

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@
88
0009-FIPS-DH-PCT.patch
99
0010-FIPS-Add-extra-public-private-key-checks.patch
1010
0011-FIPS-Check-RSA-SP800-56b.patch
11+
0012-FIPS-ML-KEM-IKME-indicator.patch
12+
0013-FIPS-ML-KEM-SEED-indicator.patch

0 commit comments

Comments
 (0)