diff options
author | beck <> | 2025-05-19 06:47:40 +0000 |
---|---|---|
committer | beck <> | 2025-05-19 06:47:40 +0000 |
commit | 5a25995ae14e36a5cea71734d202bac849f02727 (patch) | |
tree | c0473c2a6778acc8c1c57a2e73ed27b1d35552a6 /src | |
parent | c2782d1f52bceb30584b71c11631e00eacebcc4e (diff) | |
download | openbsd-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.h | 22 | ||||
-rw-r--r-- | src/lib/libcrypto/mlkem/mlkem1024.c | 87 | ||||
-rw-r--r-- | src/lib/libcrypto/mlkem/mlkem768.c | 89 | ||||
-rw-r--r-- | src/lib/libcrypto/mlkem/mlkem_internal.h | 6 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/mlkem/mlkem_iteration_tests.c | 8 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/mlkem/mlkem_tests.c | 11 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/mlkem/mlkem_tests_util.c | 80 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/mlkem/mlkem_tests_util.h | 32 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/mlkem/mlkem_unittest.c | 44 |
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 @@ | |||
25 | extern "C" { | 25 | extern "C" { |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | /* Hack for now */ | ||
29 | struct cbs_st; | ||
30 | struct 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 | */ |
84 | void MLKEM768_generate_key( | 80 | int 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 | */ |
140 | int MLKEM768_marshal_public_key(struct cbb_st *out, | 136 | int 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 | */ |
149 | int MLKEM768_parse_public_key(struct MLKEM768_public_key *out_public_key, | 145 | int 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 | */ |
159 | int MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key, | 155 | int 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 | */ |
203 | void MLKEM1024_generate_key( | 199 | int 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 | */ |
259 | int MLKEM1024_marshal_public_key(struct cbb_st *out, | 255 | int 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 | */ |
268 | int MLKEM1024_parse_public_key(struct MLKEM1024_public_key *out_public_key, | 264 | int 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 | */ |
278 | int MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key, | 274 | int 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 | */ |
822 | void | 822 | int |
823 | MLKEM1024_generate_key(uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], | 823 | MLKEM1024_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 | } |
835 | LCRYPTO_ALIAS(MLKEM1024_generate_key); | 835 | LCRYPTO_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 | } |
851 | LCRYPTO_ALIAS(MLKEM1024_private_key_from_seed); | 849 | LCRYPTO_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 | ||
868 | void | 866 | int |
869 | MLKEM1024_generate_key_external_entropy( | 867 | MLKEM1024_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 | ||
909 | void | 916 | void |
@@ -1049,11 +1056,26 @@ MLKEM1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | |||
1049 | LCRYPTO_ALIAS(MLKEM1024_decap); | 1056 | LCRYPTO_ALIAS(MLKEM1024_decap); |
1050 | 1057 | ||
1051 | int | 1058 | int |
1052 | MLKEM1024_marshal_public_key(CBB *out, | 1059 | MLKEM1024_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 | } |
1058 | LCRYPTO_ALIAS(MLKEM1024_marshal_public_key); | 1080 | LCRYPTO_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 | ||
1080 | int | 1102 | int |
1081 | MLKEM1024_parse_public_key(struct MLKEM1024_public_key *public_key, CBS *in) | 1103 | MLKEM1024_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 | } |
1093 | LCRYPTO_ALIAS(MLKEM1024_parse_public_key); | 1118 | LCRYPTO_ALIAS(MLKEM1024_parse_public_key); |
@@ -1116,26 +1141,28 @@ MLKEM1024_marshal_private_key(CBB *out, | |||
1116 | 1141 | ||
1117 | int | 1142 | int |
1118 | MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key, | 1143 | MLKEM1024_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 | */ |
821 | void | 821 | int |
822 | MLKEM768_generate_key(uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], | 822 | MLKEM768_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 | } |
834 | LCRYPTO_ALIAS(MLKEM768_generate_key); | 834 | LCRYPTO_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 | } |
850 | LCRYPTO_ALIAS(MLKEM768_private_key_from_seed); | 848 | LCRYPTO_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 | ||
867 | void | 865 | int |
868 | MLKEM768_generate_key_external_entropy( | 866 | MLKEM768_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 | ||
908 | void | 914 | void |
@@ -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 | } |
971 | LCRYPTO_ALIAS(MLKEM768_encap); | 977 | LCRYPTO_ALIAS(MLKEM768_encap); |
972 | 978 | ||
@@ -1048,11 +1054,25 @@ MLKEM768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | |||
1048 | LCRYPTO_ALIAS(MLKEM768_decap); | 1054 | LCRYPTO_ALIAS(MLKEM768_decap); |
1049 | 1055 | ||
1050 | int | 1056 | int |
1051 | MLKEM768_marshal_public_key(CBB *out, | 1057 | MLKEM768_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 | } |
1057 | LCRYPTO_ALIAS(MLKEM768_marshal_public_key); | 1077 | LCRYPTO_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 | ||
1079 | int | 1099 | int |
1080 | MLKEM768_parse_public_key(struct MLKEM768_public_key *public_key, CBS *in) | 1100 | MLKEM768_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 | } |
1092 | LCRYPTO_ALIAS(MLKEM768_parse_public_key); | 1115 | LCRYPTO_ALIAS(MLKEM768_parse_public_key); |
@@ -1115,26 +1138,28 @@ MLKEM768_marshal_private_key(CBB *out, | |||
1115 | 1138 | ||
1116 | int | 1139 | int |
1117 | MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key, | 1140 | MLKEM768_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 | */ |
44 | void MLKEM768_generate_key_external_entropy( | 44 | int 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 | */ |
83 | void MLKEM1024_generate_key_external_entropy( | 83 | int 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 | ||
85 | int | 85 | int |
86 | mlkem768_encode_public_key(const void *public_key, uint8_t **out_buf, | 86 | mlkem768_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 | ||
107 | int | 92 | int |
@@ -127,25 +112,10 @@ mlkem1024_encode_private_key(const void *private_key, uint8_t **out_buf, | |||
127 | } | 112 | } |
128 | 113 | ||
129 | int | 114 | int |
130 | mlkem1024_encode_public_key(const void *public_key, uint8_t **out_buf, | 115 | mlkem1024_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 | ||
151 | int | 121 | int |
@@ -173,32 +143,36 @@ mlkem768_encap_external_entropy(uint8_t *out_ciphertext, | |||
173 | public_key, entropy); | 143 | public_key, entropy); |
174 | } | 144 | } |
175 | 145 | ||
176 | void | 146 | int |
177 | mlkem768_generate_key(uint8_t *out_encoded_public_key, | 147 | mlkem768_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 | ||
184 | void | 154 | int |
185 | mlkem768_generate_key_external_entropy(uint8_t *out_encoded_public_key, | 155 | mlkem768_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 | ||
192 | int | 162 | int |
193 | mlkem768_parse_private_key(void *out_private_key, CBS *private_key_cbs) | 163 | mlkem768_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 | ||
198 | int | 170 | int |
199 | mlkem768_parse_public_key(void *out_public_key, CBS *public_key_cbs) | 171 | mlkem768_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 | ||
204 | void | 178 | void |
@@ -232,26 +206,28 @@ mlkem1024_encap_external_entropy(uint8_t *out_ciphertext, | |||
232 | public_key, entropy); | 206 | public_key, entropy); |
233 | } | 207 | } |
234 | 208 | ||
235 | void | 209 | int |
236 | mlkem1024_generate_key(uint8_t *out_encoded_public_key, | 210 | mlkem1024_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 | ||
243 | void | 217 | int |
244 | mlkem1024_generate_key_external_entropy(uint8_t *out_encoded_public_key, | 218 | mlkem1024_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 | ||
251 | int | 225 | int |
252 | mlkem1024_parse_private_key(void *out_private_key, CBS *private_key_cbs) | 226 | mlkem1024_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 | ||
257 | void | 233 | void |
@@ -261,7 +237,9 @@ mlkem1024_public_from_private(void *out_public_key, const void *private_key) | |||
261 | } | 237 | } |
262 | 238 | ||
263 | int | 239 | int |
264 | mlkem1024_parse_public_key(void *out_public_key, CBS *public_key_cbs) | 240 | mlkem1024_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 | ||
33 | int mlkem768_encode_private_key(const void *priv, uint8_t **out_buf, | 33 | int mlkem768_encode_private_key(const void *priv, uint8_t **out_buf, |
34 | size_t *out_len); | 34 | size_t *out_len); |
35 | int mlkem768_encode_public_key(const void *pub, uint8_t **out_buf, | 35 | int mlkem768_marshal_public_key(const void *pub, uint8_t **out_buf, |
36 | size_t *out_len); | 36 | size_t *out_len); |
37 | int mlkem1024_encode_private_key(const void *priv, uint8_t **out_buf, | 37 | int mlkem1024_encode_private_key(const void *priv, uint8_t **out_buf, |
38 | size_t *out_len); | 38 | size_t *out_len); |
39 | int mlkem1024_encode_public_key(const void *pub, uint8_t **out_buf, | 39 | int mlkem1024_marshal_public_key(const void *pub, uint8_t **out_buf, |
40 | size_t *out_len); | 40 | size_t *out_len); |
41 | 41 | ||
42 | int mlkem768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | 42 | int mlkem768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], |
@@ -46,12 +46,12 @@ void mlkem768_encap(uint8_t *out_ciphertext, | |||
46 | void mlkem768_encap_external_entropy(uint8_t *out_ciphertext, | 46 | void 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]); |
49 | void mlkem768_generate_key(uint8_t *out_encoded_public_key, | 49 | int 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); |
51 | void mlkem768_generate_key_external_entropy(uint8_t *out_encoded_public_key, | 51 | int 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]); |
53 | int mlkem768_parse_private_key(void *priv, CBS *private_key_cbs); | 53 | int mlkem768_parse_private_key(void *priv, const uint8_t *in, size_t in_len); |
54 | int mlkem768_parse_public_key(void *pub, CBS *in); | 54 | int mlkem768_parse_public_key(void *pub, const uint8_t *in, size_t in_len); |
55 | void mlkem768_public_from_private(void *out_public_key, const void *private_key); | 55 | void mlkem768_public_from_private(void *out_public_key, const void *private_key); |
56 | 56 | ||
57 | int mlkem1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | 57 | int mlkem1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], |
@@ -61,16 +61,16 @@ void mlkem1024_encap(uint8_t *out_ciphertext, | |||
61 | void mlkem1024_encap_external_entropy(uint8_t *out_ciphertext, | 61 | void 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]); |
64 | void mlkem1024_generate_key(uint8_t *out_encoded_public_key, | 64 | int 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); |
66 | void mlkem1024_generate_key_external_entropy(uint8_t *out_encoded_public_key, | 66 | int 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]); |
68 | int mlkem1024_parse_private_key(void *priv, CBS *private_key_cbs); | 68 | int mlkem1024_parse_private_key(void *priv, const uint8_t *in, size_t in_len); |
69 | int mlkem1024_parse_public_key(void *pub, CBS *in); | 69 | int mlkem1024_parse_public_key(void *pub, const uint8_t *in, size_t in_len); |
70 | void mlkem1024_public_from_private(void *out_public_key, const void *private_key); | 70 | void mlkem1024_public_from_private(void *out_public_key, const void *private_key); |
71 | 71 | ||
72 | typedef int (*mlkem_encode_private_key_fn)(const void *, uint8_t **, size_t *); | 72 | typedef int (*mlkem_encode_private_key_fn)(const void *, uint8_t **, size_t *); |
73 | typedef int (*mlkem_encode_public_key_fn)(const void *, uint8_t **, size_t *); | 73 | typedef int (*mlkem_marshal_public_key_fn)(const void *, uint8_t **, size_t *); |
74 | typedef int (*mlkem_decap_fn)(uint8_t [MLKEM_SHARED_SECRET_BYTES], | 74 | typedef 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 *); |
76 | typedef void (*mlkem_encap_fn)(uint8_t *, uint8_t [MLKEM_SHARED_SECRET_BYTES], | 76 | typedef 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], | |||
78 | typedef void (*mlkem_encap_external_entropy_fn)(uint8_t *, | 78 | typedef 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]); |
81 | typedef void (*mlkem_generate_key_fn)(uint8_t *, uint8_t *, void *); | 81 | typedef int (*mlkem_generate_key_fn)(uint8_t *, uint8_t *, void *); |
82 | typedef void (*mlkem_generate_key_external_entropy_fn)(uint8_t *, void *, | 82 | typedef int (*mlkem_generate_key_external_entropy_fn)(uint8_t *, void *, |
83 | const uint8_t [MLKEM_SEED_BYTES]); | 83 | const uint8_t [MLKEM_SEED_BYTES]); |
84 | typedef int (*mlkem_parse_private_key_fn)(void *, CBS *); | 84 | typedef int (*mlkem_parse_private_key_fn)(void *, const uint8_t *, size_t); |
85 | typedef int (*mlkem_parse_public_key_fn)(void *, CBS *); | 85 | typedef int (*mlkem_parse_public_key_fn)(void *, const uint8_t *, size_t); |
86 | typedef void (*mlkem_public_from_private_fn)(void *out_public_key, | 86 | typedef 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 | ||