summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbeck <>2025-05-19 06:47:40 +0000
committerbeck <>2025-05-19 06:47:40 +0000
commit5a25995ae14e36a5cea71734d202bac849f02727 (patch)
treec0473c2a6778acc8c1c57a2e73ed27b1d35552a6 /src
parentc2782d1f52bceb30584b71c11631e00eacebcc4e (diff)
downloadopenbsd-5a25995ae14e36a5cea71734d202bac849f02727.tar.gz
openbsd-5a25995ae14e36a5cea71734d202bac849f02727.tar.bz2
openbsd-5a25995ae14e36a5cea71734d202bac849f02727.zip
API changes for ML-KEM
- Get rid of CBB/CBS usage in public api - Make void functions return int that can fail if malloc fails. Along with some fallout and resulting bikeshedding in the regress tests. ok jsing@, tb@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/mlkem/mlkem.h22
-rw-r--r--src/lib/libcrypto/mlkem/mlkem1024.c87
-rw-r--r--src/lib/libcrypto/mlkem/mlkem768.c89
-rw-r--r--src/lib/libcrypto/mlkem/mlkem_internal.h6
-rw-r--r--src/regress/lib/libcrypto/mlkem/mlkem_iteration_tests.c8
-rw-r--r--src/regress/lib/libcrypto/mlkem/mlkem_tests.c11
-rw-r--r--src/regress/lib/libcrypto/mlkem/mlkem_tests_util.c80
-rw-r--r--src/regress/lib/libcrypto/mlkem/mlkem_tests_util.h32
-rw-r--r--src/regress/lib/libcrypto/mlkem/mlkem_unittest.c44
9 files changed, 203 insertions, 176 deletions
diff --git a/src/lib/libcrypto/mlkem/mlkem.h b/src/lib/libcrypto/mlkem/mlkem.h
index 055d92290e..a2c5d7fed0 100644
--- a/src/lib/libcrypto/mlkem/mlkem.h
+++ b/src/lib/libcrypto/mlkem/mlkem.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem.h,v 1.5 2025/03/28 12:17:16 tb Exp $ */ 1/* $OpenBSD: mlkem.h,v 1.6 2025/05/19 06:47:40 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2024, Google Inc. 3 * Copyright (c) 2024, Google Inc.
4 * 4 *
@@ -25,10 +25,6 @@
25extern "C" { 25extern "C" {
26#endif 26#endif
27 27
28/* Hack for now */
29struct cbs_st;
30struct cbb_st;
31
32/* 28/*
33 * ML-KEM-768 29 * ML-KEM-768
34 * 30 *
@@ -81,7 +77,7 @@ struct MLKEM768_private_key {
81 * the private key. If |optional_out_seed| is not NULL then the seed used to 77 * the private key. If |optional_out_seed| is not NULL then the seed used to
82 * generate the private key is written to it. 78 * generate the private key is written to it.
83 */ 79 */
84void MLKEM768_generate_key( 80int MLKEM768_generate_key(
85 uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], 81 uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES],
86 uint8_t optional_out_seed[MLKEM_SEED_BYTES], 82 uint8_t optional_out_seed[MLKEM_SEED_BYTES],
87 struct MLKEM768_private_key *out_private_key); 83 struct MLKEM768_private_key *out_private_key);
@@ -137,7 +133,7 @@ int MLKEM768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
137 * format for ML-KEM public keys. It returns one on success or zero on allocation 133 * format for ML-KEM public keys. It returns one on success or zero on allocation
138 * error. 134 * error.
139 */ 135 */
140int MLKEM768_marshal_public_key(struct cbb_st *out, 136int MLKEM768_marshal_public_key(uint8_t **output, size_t *output_len,
141 const struct MLKEM768_public_key *public_key); 137 const struct MLKEM768_public_key *public_key);
142 138
143/* 139/*
@@ -147,7 +143,7 @@ int MLKEM768_marshal_public_key(struct cbb_st *out,
147 * there are trailing bytes in |in|. 143 * there are trailing bytes in |in|.
148 */ 144 */
149int MLKEM768_parse_public_key(struct MLKEM768_public_key *out_public_key, 145int MLKEM768_parse_public_key(struct MLKEM768_public_key *out_public_key,
150 struct cbs_st *in); 146 const uint8_t *input, size_t input_len);
151 147
152/* 148/*
153 * MLKEM_parse_private_key parses a private key, in the format generated by 149 * MLKEM_parse_private_key parses a private key, in the format generated by
@@ -157,7 +153,7 @@ int MLKEM768_parse_public_key(struct MLKEM768_public_key *out_public_key,
157 * Private keys should be stored as seeds and parsed using |MLKEM768_private_key_from_seed|. 153 * Private keys should be stored as seeds and parsed using |MLKEM768_private_key_from_seed|.
158 */ 154 */
159int MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key, 155int MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key,
160 struct cbs_st *in); 156 const uint8_t *input, size_t input_len);
161 157
162/* 158/*
163 * ML-KEM-1024 159 * ML-KEM-1024
@@ -200,7 +196,7 @@ struct MLKEM1024_private_key {
200 * the private key. If |optional_out_seed| is not NULL then the seed used to 196 * the private key. If |optional_out_seed| is not NULL then the seed used to
201 * generate the private key is written to it. 197 * generate the private key is written to it.
202 */ 198 */
203void MLKEM1024_generate_key( 199int MLKEM1024_generate_key(
204 uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], 200 uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES],
205 uint8_t optional_out_seed[MLKEM_SEED_BYTES], 201 uint8_t optional_out_seed[MLKEM_SEED_BYTES],
206 struct MLKEM1024_private_key *out_private_key); 202 struct MLKEM1024_private_key *out_private_key);
@@ -256,7 +252,7 @@ int MLKEM1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
256 * format for ML-KEM-1024 public keys. It returns one on success or zero on 252 * format for ML-KEM-1024 public keys. It returns one on success or zero on
257 * allocation error. 253 * allocation error.
258 */ 254 */
259int MLKEM1024_marshal_public_key(struct cbb_st *out, 255int MLKEM1024_marshal_public_key(uint8_t **output, size_t *output_len,
260 const struct MLKEM1024_public_key *public_key); 256 const struct MLKEM1024_public_key *public_key);
261 257
262/* 258/*
@@ -266,7 +262,7 @@ int MLKEM1024_marshal_public_key(struct cbb_st *out,
266 * there are trailing bytes in |in|. 262 * there are trailing bytes in |in|.
267 */ 263 */
268int MLKEM1024_parse_public_key(struct MLKEM1024_public_key *out_public_key, 264int MLKEM1024_parse_public_key(struct MLKEM1024_public_key *out_public_key,
269 struct cbs_st *in); 265 const uint8_t *input, size_t input_len);
270 266
271/* 267/*
272 * MLKEM1024_parse_private_key parses a private key, in NIST's format for 268 * MLKEM1024_parse_private_key parses a private key, in NIST's format for
@@ -276,7 +272,7 @@ int MLKEM1024_parse_public_key(struct MLKEM1024_public_key *out_public_key,
276 * stored as seeds and parsed using |MLKEM1024_private_key_from_seed|. 272 * stored as seeds and parsed using |MLKEM1024_private_key_from_seed|.
277 */ 273 */
278int MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key, 274int MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key,
279 struct cbs_st *in); 275 const uint8_t *input, size_t input_len);
280 276
281#if defined(__cplusplus) 277#if defined(__cplusplus)
282} 278}
diff --git a/src/lib/libcrypto/mlkem/mlkem1024.c b/src/lib/libcrypto/mlkem/mlkem1024.c
index ce6f26e66c..04e106299a 100644
--- a/src/lib/libcrypto/mlkem/mlkem1024.c
+++ b/src/lib/libcrypto/mlkem/mlkem1024.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem1024.c,v 1.7 2025/05/03 08:39:33 tb Exp $ */ 1/* $OpenBSD: mlkem1024.c,v 1.8 2025/05/19 06:47:40 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2024, Google Inc. 3 * Copyright (c) 2024, Google Inc.
4 * Copyright (c) 2024, Bob Beck <beck@obtuse.com> 4 * Copyright (c) 2024, Bob Beck <beck@obtuse.com>
@@ -819,7 +819,7 @@ private_key_1024_from_external(const struct MLKEM1024_private_key *external)
819 * Calls |MLKEM1024_generate_key_external_entropy| with random bytes from 819 * Calls |MLKEM1024_generate_key_external_entropy| with random bytes from
820 * |RAND_bytes|. 820 * |RAND_bytes|.
821 */ 821 */
822void 822int
823MLKEM1024_generate_key(uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], 823MLKEM1024_generate_key(uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES],
824 uint8_t optional_out_seed[MLKEM_SEED_BYTES], 824 uint8_t optional_out_seed[MLKEM_SEED_BYTES],
825 struct MLKEM1024_private_key *out_private_key) 825 struct MLKEM1024_private_key *out_private_key)
@@ -829,7 +829,7 @@ MLKEM1024_generate_key(uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES
829 entropy_buf; 829 entropy_buf;
830 830
831 arc4random_buf(entropy, MLKEM_SEED_BYTES); 831 arc4random_buf(entropy, MLKEM_SEED_BYTES);
832 MLKEM1024_generate_key_external_entropy(out_encoded_public_key, 832 return MLKEM1024_generate_key_external_entropy(out_encoded_public_key,
833 out_private_key, entropy); 833 out_private_key, entropy);
834} 834}
835LCRYPTO_ALIAS(MLKEM1024_generate_key); 835LCRYPTO_ALIAS(MLKEM1024_generate_key);
@@ -843,10 +843,8 @@ MLKEM1024_private_key_from_seed(struct MLKEM1024_private_key *out_private_key,
843 if (seed_len != MLKEM_SEED_BYTES) { 843 if (seed_len != MLKEM_SEED_BYTES) {
844 return 0; 844 return 0;
845 } 845 }
846 MLKEM1024_generate_key_external_entropy(public_key_bytes, 846 return MLKEM1024_generate_key_external_entropy(public_key_bytes,
847 out_private_key, seed); 847 out_private_key, seed);
848
849 return 1;
850} 848}
851LCRYPTO_ALIAS(MLKEM1024_private_key_from_seed); 849LCRYPTO_ALIAS(MLKEM1024_private_key_from_seed);
852 850
@@ -865,7 +863,7 @@ mlkem_marshal_public_key(CBB *out, const struct public_key *pub)
865 return 1; 863 return 1;
866} 864}
867 865
868void 866int
869MLKEM1024_generate_key_external_entropy( 867MLKEM1024_generate_key_external_entropy(
870 uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], 868 uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES],
871 struct MLKEM1024_private_key *out_private_key, 869 struct MLKEM1024_private_key *out_private_key,
@@ -879,7 +877,9 @@ MLKEM1024_generate_key_external_entropy(
879 uint8_t hashed[64]; 877 uint8_t hashed[64];
880 vector error; 878 vector error;
881 CBB cbb; 879 CBB cbb;
880 int ret = 0;
882 881
882 memset(&cbb, 0, sizeof(CBB));
883 memcpy(augmented_seed, entropy, 32); 883 memcpy(augmented_seed, entropy, 32);
884 augmented_seed[32] = RANK1024; 884 augmented_seed[32] = RANK1024;
885 hash_g(hashed, augmented_seed, 33); 885 hash_g(hashed, augmented_seed, 33);
@@ -894,16 +894,23 @@ MLKEM1024_generate_key_external_entropy(
894 matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s); 894 matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s);
895 vector_add(&priv->pub.t, &error); 895 vector_add(&priv->pub.t, &error);
896 896
897 /* XXX - error checking. */ 897 if (!CBB_init_fixed(&cbb, out_encoded_public_key,
898 CBB_init_fixed(&cbb, out_encoded_public_key, MLKEM1024_PUBLIC_KEY_BYTES); 898 MLKEM1024_PUBLIC_KEY_BYTES))
899 if (!mlkem_marshal_public_key(&cbb, &priv->pub)) { 899 goto err;
900 abort(); 900
901 } 901 if (!mlkem_marshal_public_key(&cbb, &priv->pub))
902 CBB_cleanup(&cbb); 902 goto err;
903 903
904 hash_h(priv->pub.public_key_hash, out_encoded_public_key, 904 hash_h(priv->pub.public_key_hash, out_encoded_public_key,
905 MLKEM1024_PUBLIC_KEY_BYTES); 905 MLKEM1024_PUBLIC_KEY_BYTES);
906 memcpy(priv->fo_failure_secret, entropy + 32, 32); 906 memcpy(priv->fo_failure_secret, entropy + 32, 32);
907
908 ret = 1;
909
910 err:
911 CBB_cleanup(&cbb);
912
913 return ret;
907} 914}
908 915
909void 916void
@@ -1049,11 +1056,26 @@ MLKEM1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
1049LCRYPTO_ALIAS(MLKEM1024_decap); 1056LCRYPTO_ALIAS(MLKEM1024_decap);
1050 1057
1051int 1058int
1052MLKEM1024_marshal_public_key(CBB *out, 1059MLKEM1024_marshal_public_key(uint8_t **output, size_t *output_len,
1053 const struct MLKEM1024_public_key *public_key) 1060 const struct MLKEM1024_public_key *public_key)
1054{ 1061{
1055 return mlkem_marshal_public_key(out, 1062 int ret = 0;
1056 public_key_1024_from_external(public_key)); 1063 CBB cbb;
1064
1065 if (!CBB_init(&cbb, MLKEM768_PUBLIC_KEY_BYTES))
1066 goto err;
1067 if (!mlkem_marshal_public_key(&cbb,
1068 public_key_1024_from_external(public_key)))
1069 goto err;
1070 if (!CBB_finish(&cbb, output, output_len))
1071 goto err;
1072
1073 ret = 1;
1074
1075 err:
1076 CBB_cleanup(&cbb);
1077
1078 return ret;
1057} 1079}
1058LCRYPTO_ALIAS(MLKEM1024_marshal_public_key); 1080LCRYPTO_ALIAS(MLKEM1024_marshal_public_key);
1059 1081
@@ -1078,16 +1100,19 @@ mlkem_parse_public_key_no_hash(struct public_key *pub, CBS *in)
1078} 1100}
1079 1101
1080int 1102int
1081MLKEM1024_parse_public_key(struct MLKEM1024_public_key *public_key, CBS *in) 1103MLKEM1024_parse_public_key(struct MLKEM1024_public_key *public_key,
1104 const uint8_t *input, size_t input_len)
1082{ 1105{
1083 struct public_key *pub = public_key_1024_from_external(public_key); 1106 struct public_key *pub = public_key_1024_from_external(public_key);
1084 CBS orig_in = *in; 1107 CBS cbs;
1085 1108
1086 if (!mlkem_parse_public_key_no_hash(pub, in) || 1109 CBS_init(&cbs, input, input_len);
1087 CBS_len(in) != 0) { 1110 if (!mlkem_parse_public_key_no_hash(pub, &cbs) ||
1111 CBS_len(&cbs) != 0) {
1088 return 0; 1112 return 0;
1089 } 1113 }
1090 hash_h(pub->public_key_hash, CBS_data(&orig_in), CBS_len(&orig_in)); 1114 hash_h(pub->public_key_hash, input, input_len);
1115
1091 return 1; 1116 return 1;
1092} 1117}
1093LCRYPTO_ALIAS(MLKEM1024_parse_public_key); 1118LCRYPTO_ALIAS(MLKEM1024_parse_public_key);
@@ -1116,26 +1141,28 @@ MLKEM1024_marshal_private_key(CBB *out,
1116 1141
1117int 1142int
1118MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key, 1143MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key,
1119 CBS *in) 1144 const uint8_t *input, size_t input_len)
1120{ 1145{
1121 struct private_key *const priv = private_key_1024_from_external( 1146 struct private_key *const priv = private_key_1024_from_external(
1122 out_private_key); 1147 out_private_key);
1123 CBS s_bytes; 1148 CBS cbs, s_bytes;
1149
1150 CBS_init(&cbs, input, input_len);
1124 1151
1125 if (!CBS_get_bytes(in, &s_bytes, kEncodedVectorSize) || 1152 if (!CBS_get_bytes(&cbs, &s_bytes, kEncodedVectorSize) ||
1126 !vector_decode(&priv->s, CBS_data(&s_bytes), kLog2Prime) || 1153 !vector_decode(&priv->s, CBS_data(&s_bytes), kLog2Prime) ||
1127 !mlkem_parse_public_key_no_hash(&priv->pub, in)) { 1154 !mlkem_parse_public_key_no_hash(&priv->pub, &cbs)) {
1128 return 0; 1155 return 0;
1129 } 1156 }
1130 memcpy(priv->pub.public_key_hash, CBS_data(in), 1157 memcpy(priv->pub.public_key_hash, CBS_data(&cbs),
1131 sizeof(priv->pub.public_key_hash)); 1158 sizeof(priv->pub.public_key_hash));
1132 if (!CBS_skip(in, sizeof(priv->pub.public_key_hash))) 1159 if (!CBS_skip(&cbs, sizeof(priv->pub.public_key_hash)))
1133 return 0; 1160 return 0;
1134 memcpy(priv->fo_failure_secret, CBS_data(in), 1161 memcpy(priv->fo_failure_secret, CBS_data(&cbs),
1135 sizeof(priv->fo_failure_secret)); 1162 sizeof(priv->fo_failure_secret));
1136 if (!CBS_skip(in, sizeof(priv->fo_failure_secret))) 1163 if (!CBS_skip(&cbs, sizeof(priv->fo_failure_secret)))
1137 return 0; 1164 return 0;
1138 if (CBS_len(in) != 0) 1165 if (CBS_len(&cbs) != 0)
1139 return 0; 1166 return 0;
1140 1167
1141 return 1; 1168 return 1;
diff --git a/src/lib/libcrypto/mlkem/mlkem768.c b/src/lib/libcrypto/mlkem/mlkem768.c
index 73e293d542..a76971778c 100644
--- a/src/lib/libcrypto/mlkem/mlkem768.c
+++ b/src/lib/libcrypto/mlkem/mlkem768.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem768.c,v 1.8 2025/05/03 08:39:33 tb Exp $ */ 1/* $OpenBSD: mlkem768.c,v 1.9 2025/05/19 06:47:40 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2024, Google Inc. 3 * Copyright (c) 2024, Google Inc.
4 * Copyright (c) 2024, Bob Beck <beck@obtuse.com> 4 * Copyright (c) 2024, Bob Beck <beck@obtuse.com>
@@ -818,7 +818,7 @@ private_key_768_from_external(const struct MLKEM768_private_key *external)
818 * Calls |MLKEM768_generate_key_external_entropy| with random bytes from 818 * Calls |MLKEM768_generate_key_external_entropy| with random bytes from
819 * |RAND_bytes|. 819 * |RAND_bytes|.
820 */ 820 */
821void 821int
822MLKEM768_generate_key(uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], 822MLKEM768_generate_key(uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES],
823 uint8_t optional_out_seed[MLKEM_SEED_BYTES], 823 uint8_t optional_out_seed[MLKEM_SEED_BYTES],
824 struct MLKEM768_private_key *out_private_key) 824 struct MLKEM768_private_key *out_private_key)
@@ -828,7 +828,7 @@ MLKEM768_generate_key(uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES],
828 entropy_buf; 828 entropy_buf;
829 829
830 arc4random_buf(entropy, MLKEM_SEED_BYTES); 830 arc4random_buf(entropy, MLKEM_SEED_BYTES);
831 MLKEM768_generate_key_external_entropy(out_encoded_public_key, 831 return MLKEM768_generate_key_external_entropy(out_encoded_public_key,
832 out_private_key, entropy); 832 out_private_key, entropy);
833} 833}
834LCRYPTO_ALIAS(MLKEM768_generate_key); 834LCRYPTO_ALIAS(MLKEM768_generate_key);
@@ -842,10 +842,8 @@ MLKEM768_private_key_from_seed(struct MLKEM768_private_key *out_private_key,
842 if (seed_len != MLKEM_SEED_BYTES) { 842 if (seed_len != MLKEM_SEED_BYTES) {
843 return 0; 843 return 0;
844 } 844 }
845 MLKEM768_generate_key_external_entropy(public_key_bytes, 845 return MLKEM768_generate_key_external_entropy(public_key_bytes,
846 out_private_key, seed); 846 out_private_key, seed);
847
848 return 1;
849} 847}
850LCRYPTO_ALIAS(MLKEM768_private_key_from_seed); 848LCRYPTO_ALIAS(MLKEM768_private_key_from_seed);
851 849
@@ -864,7 +862,7 @@ mlkem_marshal_public_key(CBB *out, const struct public_key *pub)
864 return 1; 862 return 1;
865} 863}
866 864
867void 865int
868MLKEM768_generate_key_external_entropy( 866MLKEM768_generate_key_external_entropy(
869 uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], 867 uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES],
870 struct MLKEM768_private_key *out_private_key, 868 struct MLKEM768_private_key *out_private_key,
@@ -878,7 +876,9 @@ MLKEM768_generate_key_external_entropy(
878 uint8_t hashed[64]; 876 uint8_t hashed[64];
879 vector error; 877 vector error;
880 CBB cbb; 878 CBB cbb;
879 int ret = 0;
881 880
881 memset(&cbb, 0, sizeof(CBB));
882 memcpy(augmented_seed, entropy, 32); 882 memcpy(augmented_seed, entropy, 32);
883 augmented_seed[32] = RANK768; 883 augmented_seed[32] = RANK768;
884 hash_g(hashed, augmented_seed, 33); 884 hash_g(hashed, augmented_seed, 33);
@@ -893,16 +893,22 @@ MLKEM768_generate_key_external_entropy(
893 matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s); 893 matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s);
894 vector_add(&priv->pub.t, &error); 894 vector_add(&priv->pub.t, &error);
895 895
896 /* XXX - error checking */ 896 if (!CBB_init_fixed(&cbb, out_encoded_public_key,
897 CBB_init_fixed(&cbb, out_encoded_public_key, MLKEM768_PUBLIC_KEY_BYTES); 897 MLKEM768_PUBLIC_KEY_BYTES))
898 if (!mlkem_marshal_public_key(&cbb, &priv->pub)) { 898 goto err;
899 abort(); 899
900 } 900 if (!mlkem_marshal_public_key(&cbb, &priv->pub))
901 CBB_cleanup(&cbb); 901 goto err;
902 902
903 hash_h(priv->pub.public_key_hash, out_encoded_public_key, 903 hash_h(priv->pub.public_key_hash, out_encoded_public_key,
904 MLKEM768_PUBLIC_KEY_BYTES); 904 MLKEM768_PUBLIC_KEY_BYTES);
905 memcpy(priv->fo_failure_secret, entropy + 32, 32); 905 memcpy(priv->fo_failure_secret, entropy + 32, 32);
906
907 ret = 1;
908 err:
909 CBB_cleanup(&cbb);
910
911 return ret;
906} 912}
907 913
908void 914void
@@ -965,8 +971,8 @@ MLKEM768_encap(uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES],
965 uint8_t entropy[MLKEM_ENCAP_ENTROPY]; 971 uint8_t entropy[MLKEM_ENCAP_ENTROPY];
966 972
967 arc4random_buf(entropy, MLKEM_ENCAP_ENTROPY); 973 arc4random_buf(entropy, MLKEM_ENCAP_ENTROPY);
968 MLKEM768_encap_external_entropy(out_ciphertext, out_shared_secret, 974 MLKEM768_encap_external_entropy(out_ciphertext,
969 public_key, entropy); 975 out_shared_secret, public_key, entropy);
970} 976}
971LCRYPTO_ALIAS(MLKEM768_encap); 977LCRYPTO_ALIAS(MLKEM768_encap);
972 978
@@ -1048,11 +1054,25 @@ MLKEM768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
1048LCRYPTO_ALIAS(MLKEM768_decap); 1054LCRYPTO_ALIAS(MLKEM768_decap);
1049 1055
1050int 1056int
1051MLKEM768_marshal_public_key(CBB *out, 1057MLKEM768_marshal_public_key(uint8_t **output, size_t *output_len,
1052 const struct MLKEM768_public_key *public_key) 1058 const struct MLKEM768_public_key *public_key)
1053{ 1059{
1054 return mlkem_marshal_public_key(out, 1060 int ret = 0;
1055 public_key_768_from_external(public_key)); 1061 CBB cbb;
1062
1063 if (!CBB_init(&cbb, MLKEM768_PUBLIC_KEY_BYTES))
1064 goto err;
1065 if (!mlkem_marshal_public_key(&cbb,
1066 public_key_768_from_external(public_key)))
1067 goto err;
1068 if (!CBB_finish(&cbb, output, output_len))
1069 goto err;
1070
1071 ret = 1;
1072 err:
1073 CBB_cleanup(&cbb);
1074
1075 return ret;
1056} 1076}
1057LCRYPTO_ALIAS(MLKEM768_marshal_public_key); 1077LCRYPTO_ALIAS(MLKEM768_marshal_public_key);
1058 1078
@@ -1077,16 +1097,19 @@ mlkem_parse_public_key_no_hash(struct public_key *pub, CBS *in)
1077} 1097}
1078 1098
1079int 1099int
1080MLKEM768_parse_public_key(struct MLKEM768_public_key *public_key, CBS *in) 1100MLKEM768_parse_public_key(struct MLKEM768_public_key *public_key,
1101 const uint8_t *input, size_t input_len)
1081{ 1102{
1082 struct public_key *pub = public_key_768_from_external(public_key); 1103 struct public_key *pub = public_key_768_from_external(public_key);
1083 CBS orig_in = *in; 1104 CBS cbs;
1084 1105
1085 if (!mlkem_parse_public_key_no_hash(pub, in) || 1106 CBS_init(&cbs, input, input_len);
1086 CBS_len(in) != 0) { 1107 if (!mlkem_parse_public_key_no_hash(pub, &cbs) ||
1108 CBS_len(&cbs) != 0) {
1087 return 0; 1109 return 0;
1088 } 1110 }
1089 hash_h(pub->public_key_hash, CBS_data(&orig_in), CBS_len(&orig_in)); 1111 hash_h(pub->public_key_hash, input, input_len);
1112
1090 return 1; 1113 return 1;
1091} 1114}
1092LCRYPTO_ALIAS(MLKEM768_parse_public_key); 1115LCRYPTO_ALIAS(MLKEM768_parse_public_key);
@@ -1115,26 +1138,28 @@ MLKEM768_marshal_private_key(CBB *out,
1115 1138
1116int 1139int
1117MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key, 1140MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key,
1118 CBS *in) 1141 const uint8_t *input, size_t input_len)
1119{ 1142{
1120 struct private_key *const priv = private_key_768_from_external( 1143 struct private_key *const priv = private_key_768_from_external(
1121 out_private_key); 1144 out_private_key);
1122 CBS s_bytes; 1145 CBS cbs, s_bytes;
1146
1147 CBS_init(&cbs, input, input_len);
1123 1148
1124 if (!CBS_get_bytes(in, &s_bytes, kEncodedVectorSize) || 1149 if (!CBS_get_bytes(&cbs, &s_bytes, kEncodedVectorSize) ||
1125 !vector_decode(&priv->s, CBS_data(&s_bytes), kLog2Prime) || 1150 !vector_decode(&priv->s, CBS_data(&s_bytes), kLog2Prime) ||
1126 !mlkem_parse_public_key_no_hash(&priv->pub, in)) { 1151 !mlkem_parse_public_key_no_hash(&priv->pub, &cbs)) {
1127 return 0; 1152 return 0;
1128 } 1153 }
1129 memcpy(priv->pub.public_key_hash, CBS_data(in), 1154 memcpy(priv->pub.public_key_hash, CBS_data(&cbs),
1130 sizeof(priv->pub.public_key_hash)); 1155 sizeof(priv->pub.public_key_hash));
1131 if (!CBS_skip(in, sizeof(priv->pub.public_key_hash))) 1156 if (!CBS_skip(&cbs, sizeof(priv->pub.public_key_hash)))
1132 return 0; 1157 return 0;
1133 memcpy(priv->fo_failure_secret, CBS_data(in), 1158 memcpy(priv->fo_failure_secret, CBS_data(&cbs),
1134 sizeof(priv->fo_failure_secret)); 1159 sizeof(priv->fo_failure_secret));
1135 if (!CBS_skip(in, sizeof(priv->fo_failure_secret))) 1160 if (!CBS_skip(&cbs, sizeof(priv->fo_failure_secret)))
1136 return 0; 1161 return 0;
1137 if (CBS_len(in) != 0) 1162 if (CBS_len(&cbs) != 0)
1138 return 0; 1163 return 0;
1139 1164
1140 return 1; 1165 return 1;
diff --git a/src/lib/libcrypto/mlkem/mlkem_internal.h b/src/lib/libcrypto/mlkem/mlkem_internal.h
index d3f325932f..7a51197c36 100644
--- a/src/lib/libcrypto/mlkem/mlkem_internal.h
+++ b/src/lib/libcrypto/mlkem/mlkem_internal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem_internal.h,v 1.4 2024/12/19 23:52:26 tb Exp $ */ 1/* $OpenBSD: mlkem_internal.h,v 1.5 2025/05/19 06:47:40 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2023, Google Inc. 3 * Copyright (c) 2023, Google Inc.
4 * 4 *
@@ -41,7 +41,7 @@ __BEGIN_HIDDEN_DECLS
41 * regular callers should use the non-deterministic |MLKEM_generate_key| 41 * regular callers should use the non-deterministic |MLKEM_generate_key|
42 * directly. 42 * directly.
43 */ 43 */
44void MLKEM768_generate_key_external_entropy( 44int MLKEM768_generate_key_external_entropy(
45 uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], 45 uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES],
46 struct MLKEM768_private_key *out_private_key, 46 struct MLKEM768_private_key *out_private_key,
47 const uint8_t entropy[MLKEM_SEED_BYTES]); 47 const uint8_t entropy[MLKEM_SEED_BYTES]);
@@ -80,7 +80,7 @@ void MLKEM768_encap_external_entropy(
80 * regular callers should use the non-deterministic |MLKEM_generate_key| 80 * regular callers should use the non-deterministic |MLKEM_generate_key|
81 * directly. 81 * directly.
82 */ 82 */
83void MLKEM1024_generate_key_external_entropy( 83int MLKEM1024_generate_key_external_entropy(
84 uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], 84 uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES],
85 struct MLKEM1024_private_key *out_private_key, 85 struct MLKEM1024_private_key *out_private_key,
86 const uint8_t entropy[MLKEM_SEED_BYTES]); 86 const uint8_t entropy[MLKEM_SEED_BYTES]);
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem_iteration_tests.c b/src/regress/lib/libcrypto/mlkem/mlkem_iteration_tests.c
index 5a61248090..a8495f55e3 100644
--- a/src/regress/lib/libcrypto/mlkem/mlkem_iteration_tests.c
+++ b/src/regress/lib/libcrypto/mlkem/mlkem_iteration_tests.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem_iteration_tests.c,v 1.2 2024/12/26 07:26:45 tb Exp $ */ 1/* $OpenBSD: mlkem_iteration_tests.c,v 1.3 2025/05/19 06:47:40 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2024 Google Inc. 3 * Copyright (c) 2024 Google Inc.
4 * Copyright (c) 2024 Bob Beck <beck@obtuse.com> 4 * Copyright (c) 2024 Bob Beck <beck@obtuse.com>
@@ -116,8 +116,10 @@ MlkemIterativeTest(struct iteration_ctx *ctx)
116 } 116 }
117 117
118 /* generate ek as encoded_public_key */ 118 /* generate ek as encoded_public_key */
119 ctx->generate_key_external_entropy(ctx->encoded_public_key, 119 if (!ctx->generate_key_external_entropy(ctx->encoded_public_key,
120 ctx->priv, seed); 120 ctx->priv, seed)) {
121 errx(1, "generate_key_external_entropy");
122 }
121 ctx->public_from_private(ctx->pub, ctx->priv); 123 ctx->public_from_private(ctx->pub, ctx->priv);
122 124
123 /* hash in ek */ 125 /* hash in ek */
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem_tests.c b/src/regress/lib/libcrypto/mlkem/mlkem_tests.c
index e9ae417887..a4e7208c76 100644
--- a/src/regress/lib/libcrypto/mlkem/mlkem_tests.c
+++ b/src/regress/lib/libcrypto/mlkem/mlkem_tests.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem_tests.c,v 1.3 2025/05/03 08:34:07 tb Exp $ */ 1/* $OpenBSD: mlkem_tests.c,v 1.4 2025/05/19 06:47:40 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2024 Google Inc. 3 * Copyright (c) 2024 Google Inc.
4 * Copyright (c) 2024 Theo Buehler <tb@openbsd.org> 4 * Copyright (c) 2024 Theo Buehler <tb@openbsd.org>
@@ -112,7 +112,8 @@ MlkemDecapFileTest(struct decap_ctx *decap)
112 parse_get_cbs(p, DECAP_PRIVATE_KEY, &private_key); 112 parse_get_cbs(p, DECAP_PRIVATE_KEY, &private_key);
113 parse_get_int(p, DECAP_RESULT, &should_fail); 113 parse_get_int(p, DECAP_RESULT, &should_fail);
114 114
115 if (!decap->parse_private_key(decap->private_key, &private_key)) { 115 if (!decap->parse_private_key(decap->private_key,
116 CBS_data(&private_key), CBS_len(&private_key))) {
116 if ((failed = !should_fail)) 117 if ((failed = !should_fail))
117 parse_info(p, "parse private key"); 118 parse_info(p, "parse private key");
118 goto err; 119 goto err;
@@ -207,7 +208,8 @@ MlkemNistDecapFileTest(struct decap_ctx *decap)
207 MLKEM_SHARED_SECRET_BYTES, CBS_len(&k))) 208 MLKEM_SHARED_SECRET_BYTES, CBS_len(&k)))
208 goto err; 209 goto err;
209 210
210 if (!decap->parse_private_key(decap->private_key, &dk)) { 211 if (!decap->parse_private_key(decap->private_key, CBS_data(&dk),
212 CBS_len(&dk))) {
211 parse_info(p, "parse private key"); 213 parse_info(p, "parse private key");
212 goto err; 214 goto err;
213 } 215 }
@@ -360,7 +362,8 @@ MlkemEncapFileTest(struct encap_ctx *encap)
360 parse_get_cbs(p, ENCAP_SHARED_SECRET, &shared_secret); 362 parse_get_cbs(p, ENCAP_SHARED_SECRET, &shared_secret);
361 parse_get_int(p, ENCAP_RESULT, &should_fail); 363 parse_get_int(p, ENCAP_RESULT, &should_fail);
362 364
363 if (!encap->parse_public_key(encap->public_key, &public_key)) { 365 if (!encap->parse_public_key(encap->public_key, CBS_data(&public_key),
366 CBS_len(&public_key))) {
364 if ((failed = !should_fail)) 367 if ((failed = !should_fail))
365 parse_info(p, "parse public key"); 368 parse_info(p, "parse public key");
366 goto err; 369 goto err;
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem_tests_util.c b/src/regress/lib/libcrypto/mlkem/mlkem_tests_util.c
index 1bb2ed3a8b..8677713c8e 100644
--- a/src/regress/lib/libcrypto/mlkem/mlkem_tests_util.c
+++ b/src/regress/lib/libcrypto/mlkem/mlkem_tests_util.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem_tests_util.c,v 1.5 2024/12/26 00:04:24 tb Exp $ */ 1/* $OpenBSD: mlkem_tests_util.c,v 1.6 2025/05/19 06:47:40 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2024 Google Inc. 3 * Copyright (c) 2024 Google Inc.
4 * Copyright (c) 2024 Bob Beck <beck@obtuse.com> 4 * Copyright (c) 2024 Bob Beck <beck@obtuse.com>
@@ -83,25 +83,10 @@ mlkem768_encode_private_key(const void *private_key, uint8_t **out_buf,
83} 83}
84 84
85int 85int
86mlkem768_encode_public_key(const void *public_key, uint8_t **out_buf, 86mlkem768_marshal_public_key(const void *public_key, uint8_t **out_buf,
87 size_t *out_len) 87 size_t *out_len)
88{ 88{
89 CBB cbb; 89 return MLKEM768_marshal_public_key(out_buf, out_len, public_key);
90 int ret = 0;
91
92 if (!CBB_init(&cbb, MLKEM768_PUBLIC_KEY_BYTES))
93 goto err;
94 if (!MLKEM768_marshal_public_key(&cbb, public_key))
95 goto err;
96 if (!CBB_finish(&cbb, out_buf, out_len))
97 goto err;
98
99 ret = 1;
100
101 err:
102 CBB_cleanup(&cbb);
103
104 return ret;
105} 90}
106 91
107int 92int
@@ -127,25 +112,10 @@ mlkem1024_encode_private_key(const void *private_key, uint8_t **out_buf,
127} 112}
128 113
129int 114int
130mlkem1024_encode_public_key(const void *public_key, uint8_t **out_buf, 115mlkem1024_marshal_public_key(const void *public_key, uint8_t **out_buf,
131 size_t *out_len) 116 size_t *out_len)
132{ 117{
133 CBB cbb; 118 return MLKEM1024_marshal_public_key(out_buf, out_len, public_key);
134 int ret = 0;
135
136 if (!CBB_init(&cbb, MLKEM1024_PUBLIC_KEY_BYTES))
137 goto err;
138 if (!MLKEM1024_marshal_public_key(&cbb, public_key))
139 goto err;
140 if (!CBB_finish(&cbb, out_buf, out_len))
141 goto err;
142
143 ret = 1;
144
145 err:
146 CBB_cleanup(&cbb);
147
148 return ret;
149} 119}
150 120
151int 121int
@@ -173,32 +143,36 @@ mlkem768_encap_external_entropy(uint8_t *out_ciphertext,
173 public_key, entropy); 143 public_key, entropy);
174} 144}
175 145
176void 146int
177mlkem768_generate_key(uint8_t *out_encoded_public_key, 147mlkem768_generate_key(uint8_t *out_encoded_public_key,
178 uint8_t optional_out_seed[MLKEM_SEED_BYTES], void *out_private_key) 148 uint8_t optional_out_seed[MLKEM_SEED_BYTES], void *out_private_key)
179{ 149{
180 MLKEM768_generate_key(out_encoded_public_key, optional_out_seed, 150 return MLKEM768_generate_key(out_encoded_public_key, optional_out_seed,
181 out_private_key); 151 out_private_key);
182} 152}
183 153
184void 154int
185mlkem768_generate_key_external_entropy(uint8_t *out_encoded_public_key, 155mlkem768_generate_key_external_entropy(uint8_t *out_encoded_public_key,
186 void *out_private_key, const uint8_t entropy[MLKEM_SEED_BYTES]) 156 void *out_private_key, const uint8_t entropy[MLKEM_SEED_BYTES])
187{ 157{
188 MLKEM768_generate_key_external_entropy(out_encoded_public_key, 158 return MLKEM768_generate_key_external_entropy(out_encoded_public_key,
189 out_private_key, entropy); 159 out_private_key, entropy);
190} 160}
191 161
192int 162int
193mlkem768_parse_private_key(void *out_private_key, CBS *private_key_cbs) 163mlkem768_parse_private_key(void *out_private_key, const uint8_t *private_key,
164 size_t private_key_len)
194{ 165{
195 return MLKEM768_parse_private_key(out_private_key, private_key_cbs); 166 return MLKEM768_parse_private_key(out_private_key, private_key,
167 private_key_len);
196} 168}
197 169
198int 170int
199mlkem768_parse_public_key(void *out_public_key, CBS *public_key_cbs) 171mlkem768_parse_public_key(void *out_public_key, const uint8_t *public_key,
172 size_t public_key_len)
200{ 173{
201 return MLKEM768_parse_public_key(out_public_key, public_key_cbs); 174 return MLKEM768_parse_public_key(out_public_key, public_key,
175 public_key_len);
202} 176}
203 177
204void 178void
@@ -232,26 +206,28 @@ mlkem1024_encap_external_entropy(uint8_t *out_ciphertext,
232 public_key, entropy); 206 public_key, entropy);
233} 207}
234 208
235void 209int
236mlkem1024_generate_key(uint8_t *out_encoded_public_key, 210mlkem1024_generate_key(uint8_t *out_encoded_public_key,
237 uint8_t optional_out_seed[MLKEM_SEED_BYTES], void *out_private_key) 211 uint8_t optional_out_seed[MLKEM_SEED_BYTES], void *out_private_key)
238{ 212{
239 MLKEM1024_generate_key(out_encoded_public_key, optional_out_seed, 213 return MLKEM1024_generate_key(out_encoded_public_key, optional_out_seed,
240 out_private_key); 214 out_private_key);
241} 215}
242 216
243void 217int
244mlkem1024_generate_key_external_entropy(uint8_t *out_encoded_public_key, 218mlkem1024_generate_key_external_entropy(uint8_t *out_encoded_public_key,
245 void *out_private_key, const uint8_t entropy[MLKEM_SEED_BYTES]) 219 void *out_private_key, const uint8_t entropy[MLKEM_SEED_BYTES])
246{ 220{
247 MLKEM1024_generate_key_external_entropy(out_encoded_public_key, 221 return MLKEM1024_generate_key_external_entropy(out_encoded_public_key,
248 out_private_key, entropy); 222 out_private_key, entropy);
249} 223}
250 224
251int 225int
252mlkem1024_parse_private_key(void *out_private_key, CBS *private_key_cbs) 226mlkem1024_parse_private_key(void *out_private_key, const uint8_t *private_key,
227 size_t private_key_len)
253{ 228{
254 return MLKEM1024_parse_private_key(out_private_key, private_key_cbs); 229 return MLKEM1024_parse_private_key(out_private_key, private_key,
230 private_key_len);
255} 231}
256 232
257void 233void
@@ -261,7 +237,9 @@ mlkem1024_public_from_private(void *out_public_key, const void *private_key)
261} 237}
262 238
263int 239int
264mlkem1024_parse_public_key(void *out_public_key, CBS *public_key_cbs) 240mlkem1024_parse_public_key(void *out_public_key, const uint8_t *public_key,
241 size_t public_key_len)
265{ 242{
266 return MLKEM1024_parse_public_key(out_public_key, public_key_cbs); 243 return MLKEM1024_parse_public_key(out_public_key, public_key,
244 public_key_len);
267} 245}
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem_tests_util.h b/src/regress/lib/libcrypto/mlkem/mlkem_tests_util.h
index 7fbe6f76a9..a3b255082f 100644
--- a/src/regress/lib/libcrypto/mlkem/mlkem_tests_util.h
+++ b/src/regress/lib/libcrypto/mlkem/mlkem_tests_util.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem_tests_util.h,v 1.4 2024/12/26 00:04:24 tb Exp $ */ 1/* $OpenBSD: mlkem_tests_util.h,v 1.5 2025/05/19 06:47:40 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2024 Bob Beck <beck@obtuse.com> 3 * Copyright (c) 2024 Bob Beck <beck@obtuse.com>
4 * Copyright (c) 2024 Theo Buehler <tb@openbsd.org> 4 * Copyright (c) 2024 Theo Buehler <tb@openbsd.org>
@@ -32,11 +32,11 @@ int compare_data(const uint8_t *want, const uint8_t *got, size_t len,
32 32
33int mlkem768_encode_private_key(const void *priv, uint8_t **out_buf, 33int mlkem768_encode_private_key(const void *priv, uint8_t **out_buf,
34 size_t *out_len); 34 size_t *out_len);
35int mlkem768_encode_public_key(const void *pub, uint8_t **out_buf, 35int mlkem768_marshal_public_key(const void *pub, uint8_t **out_buf,
36 size_t *out_len); 36 size_t *out_len);
37int mlkem1024_encode_private_key(const void *priv, uint8_t **out_buf, 37int mlkem1024_encode_private_key(const void *priv, uint8_t **out_buf,
38 size_t *out_len); 38 size_t *out_len);
39int mlkem1024_encode_public_key(const void *pub, uint8_t **out_buf, 39int mlkem1024_marshal_public_key(const void *pub, uint8_t **out_buf,
40 size_t *out_len); 40 size_t *out_len);
41 41
42int mlkem768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], 42int mlkem768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
@@ -46,12 +46,12 @@ void mlkem768_encap(uint8_t *out_ciphertext,
46void mlkem768_encap_external_entropy(uint8_t *out_ciphertext, 46void mlkem768_encap_external_entropy(uint8_t *out_ciphertext,
47 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], const void *pub, 47 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], const void *pub,
48 const uint8_t entropy[MLKEM_ENCAP_ENTROPY]); 48 const uint8_t entropy[MLKEM_ENCAP_ENTROPY]);
49void mlkem768_generate_key(uint8_t *out_encoded_public_key, 49int mlkem768_generate_key(uint8_t *out_encoded_public_key,
50 uint8_t optional_out_seed[MLKEM_SEED_BYTES], void *out_private_key); 50 uint8_t optional_out_seed[MLKEM_SEED_BYTES], void *out_private_key);
51void mlkem768_generate_key_external_entropy(uint8_t *out_encoded_public_key, 51int mlkem768_generate_key_external_entropy(uint8_t *out_encoded_public_key,
52 void *out_private_key, const uint8_t entropy[MLKEM_SEED_BYTES]); 52 void *out_private_key, const uint8_t entropy[MLKEM_SEED_BYTES]);
53int mlkem768_parse_private_key(void *priv, CBS *private_key_cbs); 53int mlkem768_parse_private_key(void *priv, const uint8_t *in, size_t in_len);
54int mlkem768_parse_public_key(void *pub, CBS *in); 54int mlkem768_parse_public_key(void *pub, const uint8_t *in, size_t in_len);
55void mlkem768_public_from_private(void *out_public_key, const void *private_key); 55void mlkem768_public_from_private(void *out_public_key, const void *private_key);
56 56
57int mlkem1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], 57int mlkem1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
@@ -61,16 +61,16 @@ void mlkem1024_encap(uint8_t *out_ciphertext,
61void mlkem1024_encap_external_entropy(uint8_t *out_ciphertext, 61void mlkem1024_encap_external_entropy(uint8_t *out_ciphertext,
62 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], const void *pub, 62 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], const void *pub,
63 const uint8_t entropy[MLKEM_ENCAP_ENTROPY]); 63 const uint8_t entropy[MLKEM_ENCAP_ENTROPY]);
64void mlkem1024_generate_key(uint8_t *out_encoded_public_key, 64int mlkem1024_generate_key(uint8_t *out_encoded_public_key,
65 uint8_t optional_out_seed[MLKEM_SEED_BYTES], void *out_private_key); 65 uint8_t optional_out_seed[MLKEM_SEED_BYTES], void *out_private_key);
66void mlkem1024_generate_key_external_entropy(uint8_t *out_encoded_public_key, 66int mlkem1024_generate_key_external_entropy(uint8_t *out_encoded_public_key,
67 void *out_private_key, const uint8_t entropy[MLKEM_SEED_BYTES]); 67 void *out_private_key, const uint8_t entropy[MLKEM_SEED_BYTES]);
68int mlkem1024_parse_private_key(void *priv, CBS *private_key_cbs); 68int mlkem1024_parse_private_key(void *priv, const uint8_t *in, size_t in_len);
69int mlkem1024_parse_public_key(void *pub, CBS *in); 69int mlkem1024_parse_public_key(void *pub, const uint8_t *in, size_t in_len);
70void mlkem1024_public_from_private(void *out_public_key, const void *private_key); 70void mlkem1024_public_from_private(void *out_public_key, const void *private_key);
71 71
72typedef int (*mlkem_encode_private_key_fn)(const void *, uint8_t **, size_t *); 72typedef int (*mlkem_encode_private_key_fn)(const void *, uint8_t **, size_t *);
73typedef int (*mlkem_encode_public_key_fn)(const void *, uint8_t **, size_t *); 73typedef int (*mlkem_marshal_public_key_fn)(const void *, uint8_t **, size_t *);
74typedef int (*mlkem_decap_fn)(uint8_t [MLKEM_SHARED_SECRET_BYTES], 74typedef int (*mlkem_decap_fn)(uint8_t [MLKEM_SHARED_SECRET_BYTES],
75 const uint8_t *, size_t, const void *); 75 const uint8_t *, size_t, const void *);
76typedef void (*mlkem_encap_fn)(uint8_t *, uint8_t [MLKEM_SHARED_SECRET_BYTES], 76typedef void (*mlkem_encap_fn)(uint8_t *, uint8_t [MLKEM_SHARED_SECRET_BYTES],
@@ -78,11 +78,11 @@ typedef void (*mlkem_encap_fn)(uint8_t *, uint8_t [MLKEM_SHARED_SECRET_BYTES],
78typedef void (*mlkem_encap_external_entropy_fn)(uint8_t *, 78typedef void (*mlkem_encap_external_entropy_fn)(uint8_t *,
79 uint8_t [MLKEM_SHARED_SECRET_BYTES], const void *, 79 uint8_t [MLKEM_SHARED_SECRET_BYTES], const void *,
80 const uint8_t [MLKEM_ENCAP_ENTROPY]); 80 const uint8_t [MLKEM_ENCAP_ENTROPY]);
81typedef void (*mlkem_generate_key_fn)(uint8_t *, uint8_t *, void *); 81typedef int (*mlkem_generate_key_fn)(uint8_t *, uint8_t *, void *);
82typedef void (*mlkem_generate_key_external_entropy_fn)(uint8_t *, void *, 82typedef int (*mlkem_generate_key_external_entropy_fn)(uint8_t *, void *,
83 const uint8_t [MLKEM_SEED_BYTES]); 83 const uint8_t [MLKEM_SEED_BYTES]);
84typedef int (*mlkem_parse_private_key_fn)(void *, CBS *); 84typedef int (*mlkem_parse_private_key_fn)(void *, const uint8_t *, size_t);
85typedef int (*mlkem_parse_public_key_fn)(void *, CBS *); 85typedef int (*mlkem_parse_public_key_fn)(void *, const uint8_t *, size_t);
86typedef void (*mlkem_public_from_private_fn)(void *out_public_key, 86typedef void (*mlkem_public_from_private_fn)(void *out_public_key,
87 const void *private_key); 87 const void *private_key);
88 88
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c b/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c
index 597297b8cc..a1adc88569 100644
--- a/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c
+++ b/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem_unittest.c,v 1.7 2025/05/03 08:34:55 tb Exp $ */ 1/* $OpenBSD: mlkem_unittest.c,v 1.8 2025/05/19 06:47:40 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2024 Google Inc. 3 * Copyright (c) 2024 Google Inc.
4 * Copyright (c) 2024 Bob Beck <beck@obtuse.com> 4 * Copyright (c) 2024 Bob Beck <beck@obtuse.com>
@@ -42,7 +42,7 @@ struct unittest_ctx {
42 mlkem_parse_private_key_fn parse_private_key; 42 mlkem_parse_private_key_fn parse_private_key;
43 mlkem_parse_public_key_fn parse_public_key; 43 mlkem_parse_public_key_fn parse_public_key;
44 mlkem_encode_private_key_fn encode_private_key; 44 mlkem_encode_private_key_fn encode_private_key;
45 mlkem_encode_public_key_fn encode_public_key; 45 mlkem_marshal_public_key_fn marshal_public_key;
46 mlkem_public_from_private_fn public_from_private; 46 mlkem_public_from_private_fn public_from_private;
47}; 47};
48 48
@@ -54,36 +54,32 @@ MlKemUnitTest(struct unittest_ctx *ctx)
54 uint8_t first_two_bytes[2]; 54 uint8_t first_two_bytes[2];
55 uint8_t *encoded_private_key = NULL, *tmp_buf = NULL; 55 uint8_t *encoded_private_key = NULL, *tmp_buf = NULL;
56 size_t encoded_private_key_len, tmp_buf_len; 56 size_t encoded_private_key_len, tmp_buf_len;
57 CBS cbs;
58 int failed = 0; 57 int failed = 0;
59 58
60 ctx->generate_key(ctx->encoded_public_key, NULL, ctx->priv); 59 if (!ctx->generate_key(ctx->encoded_public_key, NULL, ctx->priv)) {
60 warnx("generate_key failed");
61 failed |= 1;
62 }
61 63
62 memcpy(first_two_bytes, ctx->encoded_public_key, sizeof(first_two_bytes)); 64 memcpy(first_two_bytes, ctx->encoded_public_key, sizeof(first_two_bytes));
63 memset(ctx->encoded_public_key, 0xff, sizeof(first_two_bytes)); 65 memset(ctx->encoded_public_key, 0xff, sizeof(first_two_bytes));
64 66
65 CBS_init(&cbs, ctx->encoded_public_key, ctx->encoded_public_key_len);
66
67 /* Parsing should fail because the first coefficient is >= kPrime. */ 67 /* Parsing should fail because the first coefficient is >= kPrime. */
68 if (ctx->parse_public_key(ctx->pub, &cbs)) { 68 if (ctx->parse_public_key(ctx->pub, ctx->encoded_public_key,
69 ctx->encoded_public_key_len)) {
69 warnx("parse_public_key should have failed"); 70 warnx("parse_public_key should have failed");
70 failed |= 1; 71 failed |= 1;
71 } 72 }
72 73
73 memcpy(ctx->encoded_public_key, first_two_bytes, sizeof(first_two_bytes)); 74 memcpy(ctx->encoded_public_key, first_two_bytes, sizeof(first_two_bytes));
74 CBS_init(&cbs, ctx->encoded_public_key, ctx->encoded_public_key_len); 75 if (!ctx->parse_public_key(ctx->pub, ctx->encoded_public_key,
75 if (!ctx->parse_public_key(ctx->pub, &cbs)) { 76 ctx->encoded_public_key_len)) {
76 warnx("MLKEM768_parse_public_key"); 77 warnx("MLKEM768_parse_public_key");
77 failed |= 1; 78 failed |= 1;
78 } 79 }
79 80
80 if (CBS_len(&cbs) != 0u) { 81 if (!ctx->marshal_public_key(ctx->pub, &tmp_buf, &tmp_buf_len)) {
81 warnx("CBS_len must be 0"); 82 warnx("marshal_public_key");
82 failed |= 1;
83 }
84
85 if (!ctx->encode_public_key(ctx->pub, &tmp_buf, &tmp_buf_len)) {
86 warnx("encode_public_key");
87 failed |= 1; 83 failed |= 1;
88 } 84 }
89 if (ctx->encoded_public_key_len != tmp_buf_len) { 85 if (ctx->encoded_public_key_len != tmp_buf_len) {
@@ -100,8 +96,8 @@ MlKemUnitTest(struct unittest_ctx *ctx)
100 tmp_buf = NULL; 96 tmp_buf = NULL;
101 97
102 ctx->public_from_private(ctx->pub2, ctx->priv); 98 ctx->public_from_private(ctx->pub2, ctx->priv);
103 if (!ctx->encode_public_key(ctx->pub2, &tmp_buf, &tmp_buf_len)) { 99 if (!ctx->marshal_public_key(ctx->pub2, &tmp_buf, &tmp_buf_len)) {
104 warnx("encode_public_key"); 100 warnx("marshal_public_key");
105 failed |= 1; 101 failed |= 1;
106 } 102 }
107 if (ctx->encoded_public_key_len != tmp_buf_len) { 103 if (ctx->encoded_public_key_len != tmp_buf_len) {
@@ -125,18 +121,18 @@ MlKemUnitTest(struct unittest_ctx *ctx)
125 121
126 memcpy(first_two_bytes, encoded_private_key, sizeof(first_two_bytes)); 122 memcpy(first_two_bytes, encoded_private_key, sizeof(first_two_bytes));
127 memset(encoded_private_key, 0xff, sizeof(first_two_bytes)); 123 memset(encoded_private_key, 0xff, sizeof(first_two_bytes));
128 CBS_init(&cbs, encoded_private_key, encoded_private_key_len);
129 124
130 /* Parsing should fail because the first coefficient is >= kPrime. */ 125 /* Parsing should fail because the first coefficient is >= kPrime. */
131 if (ctx->parse_private_key(ctx->priv2, &cbs)) { 126 if (ctx->parse_private_key(ctx->priv2, encoded_private_key,
127 encoded_private_key_len)) {
132 warnx("MLKEM768_parse_private_key should have failed"); 128 warnx("MLKEM768_parse_private_key should have failed");
133 failed |= 1; 129 failed |= 1;
134 } 130 }
135 131
136 memcpy(encoded_private_key, first_two_bytes, sizeof(first_two_bytes)); 132 memcpy(encoded_private_key, first_two_bytes, sizeof(first_two_bytes));
137 CBS_init(&cbs, encoded_private_key, encoded_private_key_len);
138 133
139 if (!ctx->parse_private_key(ctx->priv2, &cbs)) { 134 if (!ctx->parse_private_key(ctx->priv2, encoded_private_key,
135 encoded_private_key_len)) {
140 warnx("MLKEM768_parse_private_key"); 136 warnx("MLKEM768_parse_private_key");
141 failed |= 1; 137 failed |= 1;
142 } 138 }
@@ -210,7 +206,7 @@ mlkem768_unittest(void)
210 .parse_private_key = mlkem768_parse_private_key, 206 .parse_private_key = mlkem768_parse_private_key,
211 .parse_public_key = mlkem768_parse_public_key, 207 .parse_public_key = mlkem768_parse_public_key,
212 .encode_private_key = mlkem768_encode_private_key, 208 .encode_private_key = mlkem768_encode_private_key,
213 .encode_public_key = mlkem768_encode_public_key, 209 .marshal_public_key = mlkem768_marshal_public_key,
214 .public_from_private = mlkem768_public_from_private, 210 .public_from_private = mlkem768_public_from_private,
215 }; 211 };
216 212
@@ -239,7 +235,7 @@ mlkem1024_unittest(void)
239 .parse_private_key = mlkem1024_parse_private_key, 235 .parse_private_key = mlkem1024_parse_private_key,
240 .parse_public_key = mlkem1024_parse_public_key, 236 .parse_public_key = mlkem1024_parse_public_key,
241 .encode_private_key = mlkem1024_encode_private_key, 237 .encode_private_key = mlkem1024_encode_private_key,
242 .encode_public_key = mlkem1024_encode_public_key, 238 .marshal_public_key = mlkem1024_marshal_public_key,
243 .public_from_private = mlkem1024_public_from_private, 239 .public_from_private = mlkem1024_public_from_private,
244 }; 240 };
245 241