diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib/libcrypto/mlkem/mlkem.h | 26 | ||||
-rw-r--r-- | src/lib/libcrypto/mlkem/mlkem1024.c | 173 | ||||
-rw-r--r-- | src/lib/libcrypto/mlkem/mlkem768.c | 178 | ||||
-rw-r--r-- | src/lib/libcrypto/mlkem/mlkem_internal.h | 15 |
4 files changed, 248 insertions, 144 deletions
diff --git a/src/lib/libcrypto/mlkem/mlkem.h b/src/lib/libcrypto/mlkem/mlkem.h index a5645facc6..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.4 2024/12/19 23:52:26 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 | * |
@@ -78,10 +74,10 @@ struct MLKEM768_private_key { | |||
78 | /* | 74 | /* |
79 | * MLKEM_generate_key generates a random public/private key pair, writes the | 75 | * MLKEM_generate_key generates a random public/private key pair, writes the |
80 | * encoded public key to |out_encoded_public_key| and sets |out_private_key| to | 76 | * encoded public key to |out_encoded_public_key| and sets |out_private_key| to |
81 | * the private key. If |optional_out_seed| us not NULL then te seed used to | 77 | * the private key. If |optional_out_seed| is not NULL then the seed used to |
82 | * generate te 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 f6fccdf6a8..26c4716539 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.6 2025/01/03 08:19:24 tb Exp $ */ | 1 | /* $OpenBSD: mlkem1024.c,v 1.11 2025/05/21 02:18:11 kenjiro 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> |
@@ -612,6 +612,19 @@ vector_encode(uint8_t *out, const vector *a, int bits) | |||
612 | } | 612 | } |
613 | } | 613 | } |
614 | 614 | ||
615 | /* Encodes an entire vector as above, but adding it to a CBB */ | ||
616 | static int | ||
617 | vector_encode_cbb(CBB *cbb, const vector *a, int bits) | ||
618 | { | ||
619 | uint8_t *encoded_vector; | ||
620 | |||
621 | if (!CBB_add_space(cbb, &encoded_vector, kEncodedVectorSize)) | ||
622 | return 0; | ||
623 | vector_encode(encoded_vector, a, bits); | ||
624 | |||
625 | return 1; | ||
626 | } | ||
627 | |||
615 | /* | 628 | /* |
616 | * scalar_decode parses |DEGREE * bits| bits from |in| into |DEGREE| values in | 629 | * scalar_decode parses |DEGREE * bits| bits from |in| into |DEGREE| values in |
617 | * |out|. It returns one on success and zero if any parsed value is >= | 630 | * |out|. It returns one on success and zero if any parsed value is >= |
@@ -793,6 +806,8 @@ struct public_key { | |||
793 | matrix m; | 806 | matrix m; |
794 | }; | 807 | }; |
795 | 808 | ||
809 | CTASSERT(sizeof(struct MLKEM1024_public_key) == sizeof(struct public_key)); | ||
810 | |||
796 | static struct public_key * | 811 | static struct public_key * |
797 | public_key_1024_from_external(const struct MLKEM1024_public_key *external) | 812 | public_key_1024_from_external(const struct MLKEM1024_public_key *external) |
798 | { | 813 | { |
@@ -805,6 +820,8 @@ struct private_key { | |||
805 | uint8_t fo_failure_secret[32]; | 820 | uint8_t fo_failure_secret[32]; |
806 | }; | 821 | }; |
807 | 822 | ||
823 | CTASSERT(sizeof(struct MLKEM1024_private_key) == sizeof(struct private_key)); | ||
824 | |||
808 | static struct private_key * | 825 | static struct private_key * |
809 | private_key_1024_from_external(const struct MLKEM1024_private_key *external) | 826 | private_key_1024_from_external(const struct MLKEM1024_private_key *external) |
810 | { | 827 | { |
@@ -815,7 +832,7 @@ private_key_1024_from_external(const struct MLKEM1024_private_key *external) | |||
815 | * Calls |MLKEM1024_generate_key_external_entropy| with random bytes from | 832 | * Calls |MLKEM1024_generate_key_external_entropy| with random bytes from |
816 | * |RAND_bytes|. | 833 | * |RAND_bytes|. |
817 | */ | 834 | */ |
818 | void | 835 | int |
819 | MLKEM1024_generate_key(uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], | 836 | MLKEM1024_generate_key(uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], |
820 | uint8_t optional_out_seed[MLKEM_SEED_BYTES], | 837 | uint8_t optional_out_seed[MLKEM_SEED_BYTES], |
821 | struct MLKEM1024_private_key *out_private_key) | 838 | struct MLKEM1024_private_key *out_private_key) |
@@ -825,7 +842,7 @@ MLKEM1024_generate_key(uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES | |||
825 | entropy_buf; | 842 | entropy_buf; |
826 | 843 | ||
827 | arc4random_buf(entropy, MLKEM_SEED_BYTES); | 844 | arc4random_buf(entropy, MLKEM_SEED_BYTES); |
828 | MLKEM1024_generate_key_external_entropy(out_encoded_public_key, | 845 | return MLKEM1024_generate_key_external_entropy(out_encoded_public_key, |
829 | out_private_key, entropy); | 846 | out_private_key, entropy); |
830 | } | 847 | } |
831 | LCRYPTO_ALIAS(MLKEM1024_generate_key); | 848 | LCRYPTO_ALIAS(MLKEM1024_generate_key); |
@@ -839,29 +856,20 @@ MLKEM1024_private_key_from_seed(struct MLKEM1024_private_key *out_private_key, | |||
839 | if (seed_len != MLKEM_SEED_BYTES) { | 856 | if (seed_len != MLKEM_SEED_BYTES) { |
840 | return 0; | 857 | return 0; |
841 | } | 858 | } |
842 | MLKEM1024_generate_key_external_entropy(public_key_bytes, | 859 | return MLKEM1024_generate_key_external_entropy(public_key_bytes, |
843 | out_private_key, seed); | 860 | out_private_key, seed); |
844 | |||
845 | return 1; | ||
846 | } | 861 | } |
847 | LCRYPTO_ALIAS(MLKEM1024_private_key_from_seed); | 862 | LCRYPTO_ALIAS(MLKEM1024_private_key_from_seed); |
848 | 863 | ||
849 | static int | 864 | static int |
850 | mlkem_marshal_public_key(CBB *out, const struct public_key *pub) | 865 | mlkem_marshal_public_key(CBB *out, const struct public_key *pub) |
851 | { | 866 | { |
852 | uint8_t *vector_output; | 867 | if (!vector_encode_cbb(out, &pub->t, kLog2Prime)) |
853 | |||
854 | if (!CBB_add_space(out, &vector_output, kEncodedVectorSize)) { | ||
855 | return 0; | 868 | return 0; |
856 | } | 869 | return CBB_add_bytes(out, pub->rho, sizeof(pub->rho)); |
857 | vector_encode(vector_output, &pub->t, kLog2Prime); | ||
858 | if (!CBB_add_bytes(out, pub->rho, sizeof(pub->rho))) { | ||
859 | return 0; | ||
860 | } | ||
861 | return 1; | ||
862 | } | 870 | } |
863 | 871 | ||
864 | void | 872 | int |
865 | MLKEM1024_generate_key_external_entropy( | 873 | MLKEM1024_generate_key_external_entropy( |
866 | uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], | 874 | uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], |
867 | struct MLKEM1024_private_key *out_private_key, | 875 | struct MLKEM1024_private_key *out_private_key, |
@@ -875,7 +883,9 @@ MLKEM1024_generate_key_external_entropy( | |||
875 | uint8_t hashed[64]; | 883 | uint8_t hashed[64]; |
876 | vector error; | 884 | vector error; |
877 | CBB cbb; | 885 | CBB cbb; |
886 | int ret = 0; | ||
878 | 887 | ||
888 | memset(&cbb, 0, sizeof(CBB)); | ||
879 | memcpy(augmented_seed, entropy, 32); | 889 | memcpy(augmented_seed, entropy, 32); |
880 | augmented_seed[32] = RANK1024; | 890 | augmented_seed[32] = RANK1024; |
881 | hash_g(hashed, augmented_seed, 33); | 891 | hash_g(hashed, augmented_seed, 33); |
@@ -890,16 +900,23 @@ MLKEM1024_generate_key_external_entropy( | |||
890 | matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s); | 900 | matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s); |
891 | vector_add(&priv->pub.t, &error); | 901 | vector_add(&priv->pub.t, &error); |
892 | 902 | ||
893 | /* XXX - error checking. */ | 903 | if (!CBB_init_fixed(&cbb, out_encoded_public_key, |
894 | CBB_init_fixed(&cbb, out_encoded_public_key, MLKEM1024_PUBLIC_KEY_BYTES); | 904 | MLKEM1024_PUBLIC_KEY_BYTES)) |
895 | if (!mlkem_marshal_public_key(&cbb, &priv->pub)) { | 905 | goto err; |
896 | abort(); | 906 | |
897 | } | 907 | if (!mlkem_marshal_public_key(&cbb, &priv->pub)) |
898 | CBB_cleanup(&cbb); | 908 | goto err; |
899 | 909 | ||
900 | hash_h(priv->pub.public_key_hash, out_encoded_public_key, | 910 | hash_h(priv->pub.public_key_hash, out_encoded_public_key, |
901 | MLKEM1024_PUBLIC_KEY_BYTES); | 911 | MLKEM1024_PUBLIC_KEY_BYTES); |
902 | memcpy(priv->fo_failure_secret, entropy + 32, 32); | 912 | memcpy(priv->fo_failure_secret, entropy + 32, 32); |
913 | |||
914 | ret = 1; | ||
915 | |||
916 | err: | ||
917 | CBB_cleanup(&cbb); | ||
918 | |||
919 | return ret; | ||
903 | } | 920 | } |
904 | 921 | ||
905 | void | 922 | void |
@@ -1045,11 +1062,26 @@ MLKEM1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | |||
1045 | LCRYPTO_ALIAS(MLKEM1024_decap); | 1062 | LCRYPTO_ALIAS(MLKEM1024_decap); |
1046 | 1063 | ||
1047 | int | 1064 | int |
1048 | MLKEM1024_marshal_public_key(CBB *out, | 1065 | MLKEM1024_marshal_public_key(uint8_t **output, size_t *output_len, |
1049 | const struct MLKEM1024_public_key *public_key) | 1066 | const struct MLKEM1024_public_key *public_key) |
1050 | { | 1067 | { |
1051 | return mlkem_marshal_public_key(out, | 1068 | int ret = 0; |
1052 | public_key_1024_from_external(public_key)); | 1069 | CBB cbb; |
1070 | |||
1071 | if (!CBB_init(&cbb, MLKEM1024_PUBLIC_KEY_BYTES)) | ||
1072 | goto err; | ||
1073 | if (!mlkem_marshal_public_key(&cbb, | ||
1074 | public_key_1024_from_external(public_key))) | ||
1075 | goto err; | ||
1076 | if (!CBB_finish(&cbb, output, output_len)) | ||
1077 | goto err; | ||
1078 | |||
1079 | ret = 1; | ||
1080 | |||
1081 | err: | ||
1082 | CBB_cleanup(&cbb); | ||
1083 | |||
1084 | return ret; | ||
1053 | } | 1085 | } |
1054 | LCRYPTO_ALIAS(MLKEM1024_marshal_public_key); | 1086 | LCRYPTO_ALIAS(MLKEM1024_marshal_public_key); |
1055 | 1087 | ||
@@ -1062,10 +1094,11 @@ mlkem_parse_public_key_no_hash(struct public_key *pub, CBS *in) | |||
1062 | { | 1094 | { |
1063 | CBS t_bytes; | 1095 | CBS t_bytes; |
1064 | 1096 | ||
1065 | if (!CBS_get_bytes(in, &t_bytes, kEncodedVectorSize) || | 1097 | if (!CBS_get_bytes(in, &t_bytes, kEncodedVectorSize)) |
1066 | !vector_decode(&pub->t, CBS_data(&t_bytes), kLog2Prime)) { | ||
1067 | return 0; | 1098 | return 0; |
1068 | } | 1099 | if (!vector_decode(&pub->t, CBS_data(&t_bytes), kLog2Prime)) |
1100 | return 0; | ||
1101 | |||
1069 | memcpy(pub->rho, CBS_data(in), sizeof(pub->rho)); | 1102 | memcpy(pub->rho, CBS_data(in), sizeof(pub->rho)); |
1070 | if (!CBS_skip(in, sizeof(pub->rho))) | 1103 | if (!CBS_skip(in, sizeof(pub->rho))) |
1071 | return 0; | 1104 | return 0; |
@@ -1074,64 +1107,84 @@ mlkem_parse_public_key_no_hash(struct public_key *pub, CBS *in) | |||
1074 | } | 1107 | } |
1075 | 1108 | ||
1076 | int | 1109 | int |
1077 | MLKEM1024_parse_public_key(struct MLKEM1024_public_key *public_key, CBS *in) | 1110 | MLKEM1024_parse_public_key(struct MLKEM1024_public_key *public_key, |
1111 | const uint8_t *input, size_t input_len) | ||
1078 | { | 1112 | { |
1079 | struct public_key *pub = public_key_1024_from_external(public_key); | 1113 | struct public_key *pub = public_key_1024_from_external(public_key); |
1080 | CBS orig_in = *in; | 1114 | CBS cbs; |
1081 | 1115 | ||
1082 | if (!mlkem_parse_public_key_no_hash(pub, in) || | 1116 | CBS_init(&cbs, input, input_len); |
1083 | CBS_len(in) != 0) { | 1117 | if (!mlkem_parse_public_key_no_hash(pub, &cbs)) |
1084 | return 0; | 1118 | return 0; |
1085 | } | 1119 | if (CBS_len(&cbs) != 0) |
1086 | hash_h(pub->public_key_hash, CBS_data(&orig_in), CBS_len(&orig_in)); | 1120 | return 0; |
1121 | |||
1122 | hash_h(pub->public_key_hash, input, input_len); | ||
1123 | |||
1087 | return 1; | 1124 | return 1; |
1088 | } | 1125 | } |
1089 | LCRYPTO_ALIAS(MLKEM1024_parse_public_key); | 1126 | LCRYPTO_ALIAS(MLKEM1024_parse_public_key); |
1090 | 1127 | ||
1091 | int | 1128 | int |
1092 | MLKEM1024_marshal_private_key(CBB *out, | 1129 | MLKEM1024_marshal_private_key(const struct MLKEM1024_private_key *private_key, |
1093 | const struct MLKEM1024_private_key *private_key) | 1130 | uint8_t **out_private_key, size_t *out_private_key_len) |
1094 | { | 1131 | { |
1095 | const struct private_key *const priv = private_key_1024_from_external( | 1132 | const struct private_key *const priv = private_key_1024_from_external( |
1096 | private_key); | 1133 | private_key); |
1097 | uint8_t *s_output; | 1134 | CBB cbb; |
1135 | int ret = 0; | ||
1098 | 1136 | ||
1099 | if (!CBB_add_space(out, &s_output, kEncodedVectorSize)) { | 1137 | if (!CBB_init(&cbb, MLKEM1024_PRIVATE_KEY_BYTES)) |
1100 | return 0; | 1138 | goto err; |
1101 | } | 1139 | |
1102 | vector_encode(s_output, &priv->s, kLog2Prime); | 1140 | if (!vector_encode_cbb(&cbb, &priv->s, kLog2Prime)) |
1103 | if (!mlkem_marshal_public_key(out, &priv->pub) || | 1141 | goto err; |
1104 | !CBB_add_bytes(out, priv->pub.public_key_hash, | 1142 | if (!mlkem_marshal_public_key(&cbb, &priv->pub)) |
1105 | sizeof(priv->pub.public_key_hash)) || | 1143 | goto err; |
1106 | !CBB_add_bytes(out, priv->fo_failure_secret, | 1144 | if (!CBB_add_bytes(&cbb, priv->pub.public_key_hash, |
1107 | sizeof(priv->fo_failure_secret))) { | 1145 | sizeof(priv->pub.public_key_hash))) |
1108 | return 0; | 1146 | goto err; |
1109 | } | 1147 | if (!CBB_add_bytes(&cbb, priv->fo_failure_secret, |
1110 | return 1; | 1148 | sizeof(priv->fo_failure_secret))) |
1149 | goto err; | ||
1150 | |||
1151 | if (!CBB_finish(&cbb, out_private_key, out_private_key_len)) | ||
1152 | goto err; | ||
1153 | |||
1154 | ret = 1; | ||
1155 | |||
1156 | err: | ||
1157 | CBB_cleanup(&cbb); | ||
1158 | |||
1159 | return ret; | ||
1111 | } | 1160 | } |
1112 | 1161 | ||
1113 | int | 1162 | int |
1114 | MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key, | 1163 | MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key, |
1115 | CBS *in) | 1164 | const uint8_t *input, size_t input_len) |
1116 | { | 1165 | { |
1117 | struct private_key *const priv = private_key_1024_from_external( | 1166 | struct private_key *const priv = private_key_1024_from_external( |
1118 | out_private_key); | 1167 | out_private_key); |
1119 | CBS s_bytes; | 1168 | CBS cbs, s_bytes; |
1120 | 1169 | ||
1121 | if (!CBS_get_bytes(in, &s_bytes, kEncodedVectorSize) || | 1170 | CBS_init(&cbs, input, input_len); |
1122 | !vector_decode(&priv->s, CBS_data(&s_bytes), kLog2Prime) || | 1171 | |
1123 | !mlkem_parse_public_key_no_hash(&priv->pub, in)) { | 1172 | if (!CBS_get_bytes(&cbs, &s_bytes, kEncodedVectorSize)) |
1124 | return 0; | 1173 | return 0; |
1125 | } | 1174 | if (!vector_decode(&priv->s, CBS_data(&s_bytes), kLog2Prime)) |
1126 | memcpy(priv->pub.public_key_hash, CBS_data(in), | 1175 | return 0; |
1176 | if (!mlkem_parse_public_key_no_hash(&priv->pub, &cbs)) | ||
1177 | return 0; | ||
1178 | |||
1179 | memcpy(priv->pub.public_key_hash, CBS_data(&cbs), | ||
1127 | sizeof(priv->pub.public_key_hash)); | 1180 | sizeof(priv->pub.public_key_hash)); |
1128 | if (!CBS_skip(in, sizeof(priv->pub.public_key_hash))) | 1181 | if (!CBS_skip(&cbs, sizeof(priv->pub.public_key_hash))) |
1129 | return 0; | 1182 | return 0; |
1130 | memcpy(priv->fo_failure_secret, CBS_data(in), | 1183 | memcpy(priv->fo_failure_secret, CBS_data(&cbs), |
1131 | sizeof(priv->fo_failure_secret)); | 1184 | sizeof(priv->fo_failure_secret)); |
1132 | if (!CBS_skip(in, sizeof(priv->fo_failure_secret))) | 1185 | if (!CBS_skip(&cbs, sizeof(priv->fo_failure_secret))) |
1133 | return 0; | 1186 | return 0; |
1134 | if (CBS_len(in) != 0) | 1187 | if (CBS_len(&cbs) != 0) |
1135 | return 0; | 1188 | return 0; |
1136 | 1189 | ||
1137 | return 1; | 1190 | return 1; |
diff --git a/src/lib/libcrypto/mlkem/mlkem768.c b/src/lib/libcrypto/mlkem/mlkem768.c index bacde0c0b7..653b92d8d8 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.7 2025/01/03 08:19:24 tb Exp $ */ | 1 | /* $OpenBSD: mlkem768.c,v 1.12 2025/05/20 00:30:38 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> |
@@ -89,6 +89,7 @@ static const int kLog2Prime = 12; | |||
89 | static const uint16_t kHalfPrime = (/*kPrime=*/3329 - 1) / 2; | 89 | static const uint16_t kHalfPrime = (/*kPrime=*/3329 - 1) / 2; |
90 | static const int kDU768 = 10; | 90 | static const int kDU768 = 10; |
91 | static const int kDV768 = 4; | 91 | static const int kDV768 = 4; |
92 | |||
92 | /* | 93 | /* |
93 | * kInverseDegree is 128^-1 mod 3329; 128 because kPrime does not have a 512th | 94 | * kInverseDegree is 128^-1 mod 3329; 128 because kPrime does not have a 512th |
94 | * root of unity. | 95 | * root of unity. |
@@ -611,6 +612,19 @@ vector_encode(uint8_t *out, const vector *a, int bits) | |||
611 | } | 612 | } |
612 | } | 613 | } |
613 | 614 | ||
615 | /* Encodes an entire vector as above, but adding it to a CBB */ | ||
616 | static int | ||
617 | vector_encode_cbb(CBB *cbb, const vector *a, int bits) | ||
618 | { | ||
619 | uint8_t *encoded_vector; | ||
620 | |||
621 | if (!CBB_add_space(cbb, &encoded_vector, kEncodedVectorSize)) | ||
622 | return 0; | ||
623 | vector_encode(encoded_vector, a, bits); | ||
624 | |||
625 | return 1; | ||
626 | } | ||
627 | |||
614 | /* | 628 | /* |
615 | * scalar_decode parses |DEGREE * bits| bits from |in| into |DEGREE| values in | 629 | * scalar_decode parses |DEGREE * bits| bits from |in| into |DEGREE| values in |
616 | * |out|. It returns one on success and zero if any parsed value is >= | 630 | * |out|. It returns one on success and zero if any parsed value is >= |
@@ -792,6 +806,8 @@ struct public_key { | |||
792 | matrix m; | 806 | matrix m; |
793 | }; | 807 | }; |
794 | 808 | ||
809 | CTASSERT(sizeof(struct MLKEM768_public_key) == sizeof(struct public_key)); | ||
810 | |||
795 | static struct public_key * | 811 | static struct public_key * |
796 | public_key_768_from_external(const struct MLKEM768_public_key *external) | 812 | public_key_768_from_external(const struct MLKEM768_public_key *external) |
797 | { | 813 | { |
@@ -804,6 +820,8 @@ struct private_key { | |||
804 | uint8_t fo_failure_secret[32]; | 820 | uint8_t fo_failure_secret[32]; |
805 | }; | 821 | }; |
806 | 822 | ||
823 | CTASSERT(sizeof(struct MLKEM768_private_key) == sizeof(struct private_key)); | ||
824 | |||
807 | static struct private_key * | 825 | static struct private_key * |
808 | private_key_768_from_external(const struct MLKEM768_private_key *external) | 826 | private_key_768_from_external(const struct MLKEM768_private_key *external) |
809 | { | 827 | { |
@@ -814,7 +832,7 @@ private_key_768_from_external(const struct MLKEM768_private_key *external) | |||
814 | * Calls |MLKEM768_generate_key_external_entropy| with random bytes from | 832 | * Calls |MLKEM768_generate_key_external_entropy| with random bytes from |
815 | * |RAND_bytes|. | 833 | * |RAND_bytes|. |
816 | */ | 834 | */ |
817 | void | 835 | int |
818 | MLKEM768_generate_key(uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], | 836 | MLKEM768_generate_key(uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], |
819 | uint8_t optional_out_seed[MLKEM_SEED_BYTES], | 837 | uint8_t optional_out_seed[MLKEM_SEED_BYTES], |
820 | struct MLKEM768_private_key *out_private_key) | 838 | struct MLKEM768_private_key *out_private_key) |
@@ -824,7 +842,7 @@ MLKEM768_generate_key(uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], | |||
824 | entropy_buf; | 842 | entropy_buf; |
825 | 843 | ||
826 | arc4random_buf(entropy, MLKEM_SEED_BYTES); | 844 | arc4random_buf(entropy, MLKEM_SEED_BYTES); |
827 | MLKEM768_generate_key_external_entropy(out_encoded_public_key, | 845 | return MLKEM768_generate_key_external_entropy(out_encoded_public_key, |
828 | out_private_key, entropy); | 846 | out_private_key, entropy); |
829 | } | 847 | } |
830 | LCRYPTO_ALIAS(MLKEM768_generate_key); | 848 | LCRYPTO_ALIAS(MLKEM768_generate_key); |
@@ -838,29 +856,20 @@ MLKEM768_private_key_from_seed(struct MLKEM768_private_key *out_private_key, | |||
838 | if (seed_len != MLKEM_SEED_BYTES) { | 856 | if (seed_len != MLKEM_SEED_BYTES) { |
839 | return 0; | 857 | return 0; |
840 | } | 858 | } |
841 | MLKEM768_generate_key_external_entropy(public_key_bytes, | 859 | return MLKEM768_generate_key_external_entropy(public_key_bytes, |
842 | out_private_key, seed); | 860 | out_private_key, seed); |
843 | |||
844 | return 1; | ||
845 | } | 861 | } |
846 | LCRYPTO_ALIAS(MLKEM768_private_key_from_seed); | 862 | LCRYPTO_ALIAS(MLKEM768_private_key_from_seed); |
847 | 863 | ||
848 | static int | 864 | static int |
849 | mlkem_marshal_public_key(CBB *out, const struct public_key *pub) | 865 | mlkem_marshal_public_key(CBB *out, const struct public_key *pub) |
850 | { | 866 | { |
851 | uint8_t *vector_output; | 867 | if (!vector_encode_cbb(out, &pub->t, kLog2Prime)) |
852 | |||
853 | if (!CBB_add_space(out, &vector_output, kEncodedVectorSize)) { | ||
854 | return 0; | ||
855 | } | ||
856 | vector_encode(vector_output, &pub->t, kLog2Prime); | ||
857 | if (!CBB_add_bytes(out, pub->rho, sizeof(pub->rho))) { | ||
858 | return 0; | 868 | return 0; |
859 | } | 869 | return CBB_add_bytes(out, pub->rho, sizeof(pub->rho)); |
860 | return 1; | ||
861 | } | 870 | } |
862 | 871 | ||
863 | void | 872 | int |
864 | MLKEM768_generate_key_external_entropy( | 873 | MLKEM768_generate_key_external_entropy( |
865 | uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], | 874 | uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], |
866 | struct MLKEM768_private_key *out_private_key, | 875 | struct MLKEM768_private_key *out_private_key, |
@@ -874,7 +883,9 @@ MLKEM768_generate_key_external_entropy( | |||
874 | uint8_t hashed[64]; | 883 | uint8_t hashed[64]; |
875 | vector error; | 884 | vector error; |
876 | CBB cbb; | 885 | CBB cbb; |
886 | int ret = 0; | ||
877 | 887 | ||
888 | memset(&cbb, 0, sizeof(CBB)); | ||
878 | memcpy(augmented_seed, entropy, 32); | 889 | memcpy(augmented_seed, entropy, 32); |
879 | augmented_seed[32] = RANK768; | 890 | augmented_seed[32] = RANK768; |
880 | hash_g(hashed, augmented_seed, 33); | 891 | hash_g(hashed, augmented_seed, 33); |
@@ -889,16 +900,23 @@ MLKEM768_generate_key_external_entropy( | |||
889 | matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s); | 900 | matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s); |
890 | vector_add(&priv->pub.t, &error); | 901 | vector_add(&priv->pub.t, &error); |
891 | 902 | ||
892 | /* XXX - error checking */ | 903 | if (!CBB_init_fixed(&cbb, out_encoded_public_key, |
893 | CBB_init_fixed(&cbb, out_encoded_public_key, MLKEM768_PUBLIC_KEY_BYTES); | 904 | MLKEM768_PUBLIC_KEY_BYTES)) |
894 | if (!mlkem_marshal_public_key(&cbb, &priv->pub)) { | 905 | goto err; |
895 | abort(); | 906 | |
896 | } | 907 | if (!mlkem_marshal_public_key(&cbb, &priv->pub)) |
897 | CBB_cleanup(&cbb); | 908 | goto err; |
898 | 909 | ||
899 | hash_h(priv->pub.public_key_hash, out_encoded_public_key, | 910 | hash_h(priv->pub.public_key_hash, out_encoded_public_key, |
900 | MLKEM768_PUBLIC_KEY_BYTES); | 911 | MLKEM768_PUBLIC_KEY_BYTES); |
901 | memcpy(priv->fo_failure_secret, entropy + 32, 32); | 912 | memcpy(priv->fo_failure_secret, entropy + 32, 32); |
913 | |||
914 | ret = 1; | ||
915 | |||
916 | err: | ||
917 | CBB_cleanup(&cbb); | ||
918 | |||
919 | return ret; | ||
902 | } | 920 | } |
903 | 921 | ||
904 | void | 922 | void |
@@ -961,8 +979,8 @@ MLKEM768_encap(uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES], | |||
961 | uint8_t entropy[MLKEM_ENCAP_ENTROPY]; | 979 | uint8_t entropy[MLKEM_ENCAP_ENTROPY]; |
962 | 980 | ||
963 | arc4random_buf(entropy, MLKEM_ENCAP_ENTROPY); | 981 | arc4random_buf(entropy, MLKEM_ENCAP_ENTROPY); |
964 | MLKEM768_encap_external_entropy(out_ciphertext, out_shared_secret, | 982 | MLKEM768_encap_external_entropy(out_ciphertext, |
965 | public_key, entropy); | 983 | out_shared_secret, public_key, entropy); |
966 | } | 984 | } |
967 | LCRYPTO_ALIAS(MLKEM768_encap); | 985 | LCRYPTO_ALIAS(MLKEM768_encap); |
968 | 986 | ||
@@ -1044,11 +1062,26 @@ MLKEM768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | |||
1044 | LCRYPTO_ALIAS(MLKEM768_decap); | 1062 | LCRYPTO_ALIAS(MLKEM768_decap); |
1045 | 1063 | ||
1046 | int | 1064 | int |
1047 | MLKEM768_marshal_public_key(CBB *out, | 1065 | MLKEM768_marshal_public_key(uint8_t **output, size_t *output_len, |
1048 | const struct MLKEM768_public_key *public_key) | 1066 | const struct MLKEM768_public_key *public_key) |
1049 | { | 1067 | { |
1050 | return mlkem_marshal_public_key(out, | 1068 | int ret = 0; |
1051 | public_key_768_from_external(public_key)); | 1069 | CBB cbb; |
1070 | |||
1071 | if (!CBB_init(&cbb, MLKEM768_PUBLIC_KEY_BYTES)) | ||
1072 | goto err; | ||
1073 | if (!mlkem_marshal_public_key(&cbb, | ||
1074 | public_key_768_from_external(public_key))) | ||
1075 | goto err; | ||
1076 | if (!CBB_finish(&cbb, output, output_len)) | ||
1077 | goto err; | ||
1078 | |||
1079 | ret = 1; | ||
1080 | |||
1081 | err: | ||
1082 | CBB_cleanup(&cbb); | ||
1083 | |||
1084 | return ret; | ||
1052 | } | 1085 | } |
1053 | LCRYPTO_ALIAS(MLKEM768_marshal_public_key); | 1086 | LCRYPTO_ALIAS(MLKEM768_marshal_public_key); |
1054 | 1087 | ||
@@ -1061,10 +1094,11 @@ mlkem_parse_public_key_no_hash(struct public_key *pub, CBS *in) | |||
1061 | { | 1094 | { |
1062 | CBS t_bytes; | 1095 | CBS t_bytes; |
1063 | 1096 | ||
1064 | if (!CBS_get_bytes(in, &t_bytes, kEncodedVectorSize) || | 1097 | if (!CBS_get_bytes(in, &t_bytes, kEncodedVectorSize)) |
1065 | !vector_decode(&pub->t, CBS_data(&t_bytes), kLog2Prime)) { | ||
1066 | return 0; | 1098 | return 0; |
1067 | } | 1099 | if (!vector_decode(&pub->t, CBS_data(&t_bytes), kLog2Prime)) |
1100 | return 0; | ||
1101 | |||
1068 | memcpy(pub->rho, CBS_data(in), sizeof(pub->rho)); | 1102 | memcpy(pub->rho, CBS_data(in), sizeof(pub->rho)); |
1069 | if (!CBS_skip(in, sizeof(pub->rho))) | 1103 | if (!CBS_skip(in, sizeof(pub->rho))) |
1070 | return 0; | 1104 | return 0; |
@@ -1073,64 +1107,84 @@ mlkem_parse_public_key_no_hash(struct public_key *pub, CBS *in) | |||
1073 | } | 1107 | } |
1074 | 1108 | ||
1075 | int | 1109 | int |
1076 | MLKEM768_parse_public_key(struct MLKEM768_public_key *public_key, CBS *in) | 1110 | MLKEM768_parse_public_key(struct MLKEM768_public_key *public_key, |
1111 | const uint8_t *input, size_t input_len) | ||
1077 | { | 1112 | { |
1078 | struct public_key *pub = public_key_768_from_external(public_key); | 1113 | struct public_key *pub = public_key_768_from_external(public_key); |
1079 | CBS orig_in = *in; | 1114 | CBS cbs; |
1080 | 1115 | ||
1081 | if (!mlkem_parse_public_key_no_hash(pub, in) || | 1116 | CBS_init(&cbs, input, input_len); |
1082 | CBS_len(in) != 0) { | 1117 | if (!mlkem_parse_public_key_no_hash(pub, &cbs)) |
1083 | return 0; | 1118 | return 0; |
1084 | } | 1119 | if (CBS_len(&cbs) != 0) |
1085 | hash_h(pub->public_key_hash, CBS_data(&orig_in), CBS_len(&orig_in)); | 1120 | return 0; |
1121 | |||
1122 | hash_h(pub->public_key_hash, input, input_len); | ||
1123 | |||
1086 | return 1; | 1124 | return 1; |
1087 | } | 1125 | } |
1088 | LCRYPTO_ALIAS(MLKEM768_parse_public_key); | 1126 | LCRYPTO_ALIAS(MLKEM768_parse_public_key); |
1089 | 1127 | ||
1090 | int | 1128 | int |
1091 | MLKEM768_marshal_private_key(CBB *out, | 1129 | MLKEM768_marshal_private_key(const struct MLKEM768_private_key *private_key, |
1092 | const struct MLKEM768_private_key *private_key) | 1130 | uint8_t **out_private_key, size_t *out_private_key_len) |
1093 | { | 1131 | { |
1094 | const struct private_key *const priv = private_key_768_from_external( | 1132 | const struct private_key *const priv = private_key_768_from_external( |
1095 | private_key); | 1133 | private_key); |
1096 | uint8_t *s_output; | 1134 | CBB cbb; |
1135 | int ret = 0; | ||
1097 | 1136 | ||
1098 | if (!CBB_add_space(out, &s_output, kEncodedVectorSize)) { | 1137 | if (!CBB_init(&cbb, MLKEM768_PRIVATE_KEY_BYTES)) |
1099 | return 0; | 1138 | goto err; |
1100 | } | 1139 | |
1101 | vector_encode(s_output, &priv->s, kLog2Prime); | 1140 | if (!vector_encode_cbb(&cbb, &priv->s, kLog2Prime)) |
1102 | if (!mlkem_marshal_public_key(out, &priv->pub) || | 1141 | goto err; |
1103 | !CBB_add_bytes(out, priv->pub.public_key_hash, | 1142 | if (!mlkem_marshal_public_key(&cbb, &priv->pub)) |
1104 | sizeof(priv->pub.public_key_hash)) || | 1143 | goto err; |
1105 | !CBB_add_bytes(out, priv->fo_failure_secret, | 1144 | if (!CBB_add_bytes(&cbb, priv->pub.public_key_hash, |
1106 | sizeof(priv->fo_failure_secret))) { | 1145 | sizeof(priv->pub.public_key_hash))) |
1107 | return 0; | 1146 | goto err; |
1108 | } | 1147 | if (!CBB_add_bytes(&cbb, priv->fo_failure_secret, |
1109 | return 1; | 1148 | sizeof(priv->fo_failure_secret))) |
1149 | goto err; | ||
1150 | |||
1151 | if (!CBB_finish(&cbb, out_private_key, out_private_key_len)) | ||
1152 | goto err; | ||
1153 | |||
1154 | ret = 1; | ||
1155 | |||
1156 | err: | ||
1157 | CBB_cleanup(&cbb); | ||
1158 | |||
1159 | return ret; | ||
1110 | } | 1160 | } |
1111 | 1161 | ||
1112 | int | 1162 | int |
1113 | MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key, | 1163 | MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key, |
1114 | CBS *in) | 1164 | const uint8_t *input, size_t input_len) |
1115 | { | 1165 | { |
1116 | struct private_key *const priv = private_key_768_from_external( | 1166 | struct private_key *const priv = private_key_768_from_external( |
1117 | out_private_key); | 1167 | out_private_key); |
1118 | CBS s_bytes; | 1168 | CBS cbs, s_bytes; |
1119 | 1169 | ||
1120 | if (!CBS_get_bytes(in, &s_bytes, kEncodedVectorSize) || | 1170 | CBS_init(&cbs, input, input_len); |
1121 | !vector_decode(&priv->s, CBS_data(&s_bytes), kLog2Prime) || | 1171 | |
1122 | !mlkem_parse_public_key_no_hash(&priv->pub, in)) { | 1172 | if (!CBS_get_bytes(&cbs, &s_bytes, kEncodedVectorSize)) |
1123 | return 0; | 1173 | return 0; |
1124 | } | 1174 | if (!vector_decode(&priv->s, CBS_data(&s_bytes), kLog2Prime)) |
1125 | memcpy(priv->pub.public_key_hash, CBS_data(in), | 1175 | return 0; |
1176 | if (!mlkem_parse_public_key_no_hash(&priv->pub, &cbs)) | ||
1177 | return 0; | ||
1178 | |||
1179 | memcpy(priv->pub.public_key_hash, CBS_data(&cbs), | ||
1126 | sizeof(priv->pub.public_key_hash)); | 1180 | sizeof(priv->pub.public_key_hash)); |
1127 | if (!CBS_skip(in, sizeof(priv->pub.public_key_hash))) | 1181 | if (!CBS_skip(&cbs, sizeof(priv->pub.public_key_hash))) |
1128 | return 0; | 1182 | return 0; |
1129 | memcpy(priv->fo_failure_secret, CBS_data(in), | 1183 | memcpy(priv->fo_failure_secret, CBS_data(&cbs), |
1130 | sizeof(priv->fo_failure_secret)); | 1184 | sizeof(priv->fo_failure_secret)); |
1131 | if (!CBS_skip(in, sizeof(priv->fo_failure_secret))) | 1185 | if (!CBS_skip(&cbs, sizeof(priv->fo_failure_secret))) |
1132 | return 0; | 1186 | return 0; |
1133 | if (CBS_len(in) != 0) | 1187 | if (CBS_len(&cbs) != 0) |
1134 | return 0; | 1188 | return 0; |
1135 | 1189 | ||
1136 | return 1; | 1190 | return 1; |
diff --git a/src/lib/libcrypto/mlkem/mlkem_internal.h b/src/lib/libcrypto/mlkem/mlkem_internal.h index d3f325932f..1e051970a8 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.7 2025/05/20 00:33: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]); |
@@ -57,8 +57,8 @@ void MLKEM768_generate_key_external_entropy( | |||
57 | * format for ML-KEM private keys. It returns one on success or zero on | 57 | * format for ML-KEM private keys. It returns one on success or zero on |
58 | * allocation error. | 58 | * allocation error. |
59 | */ | 59 | */ |
60 | int MLKEM768_marshal_private_key(CBB *out, | 60 | int MLKEM768_marshal_private_key(const struct MLKEM768_private_key *private_key, |
61 | const struct MLKEM768_private_key *private_key); | 61 | uint8_t **out_private_key, size_t *out_private_key_len); |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * MLKEM_encap_external_entropy behaves like |MLKEM_encap|, but uses | 64 | * MLKEM_encap_external_entropy behaves like |MLKEM_encap|, but uses |
@@ -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]); |
@@ -96,8 +96,9 @@ void MLKEM1024_generate_key_external_entropy( | |||
96 | * standard format for ML-KEM private keys. It returns one on success or zero on | 96 | * standard format for ML-KEM private keys. It returns one on success or zero on |
97 | * allocation error. | 97 | * allocation error. |
98 | */ | 98 | */ |
99 | int MLKEM1024_marshal_private_key(CBB *out, | 99 | int MLKEM1024_marshal_private_key( |
100 | const struct MLKEM1024_private_key *private_key); | 100 | const struct MLKEM1024_private_key *private_key, uint8_t **out_private_key, |
101 | size_t *out_private_key_len); | ||
101 | 102 | ||
102 | /* | 103 | /* |
103 | * MLKEM_encap_external_entropy behaves like |MLKEM_encap|, but uses | 104 | * MLKEM_encap_external_entropy behaves like |MLKEM_encap|, but uses |