diff options
Diffstat (limited to 'src/lib/libcrypto/mlkem')
| -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 |
4 files changed, 126 insertions, 78 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]); |
