summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2026-01-01 13:36:09 +0000
committertb <>2026-01-01 13:36:09 +0000
commit2f3ff374dcb9558a8165a6b1cf17cc024522a212 (patch)
tree2e89d7bda538c32322ff1fabe1804b21093d0439 /src
parent10bebbca92ef87af97bc15c6337afbbe050bb96e (diff)
downloadopenbsd-2f3ff374dcb9558a8165a6b1cf17cc024522a212.tar.gz
openbsd-2f3ff374dcb9558a8165a6b1cf17cc024522a212.tar.bz2
openbsd-2f3ff374dcb9558a8165a6b1cf17cc024522a212.zip
mlkem: clear a few (pointers to) secrets
The ML-KEM code is doing a pretty poor job at cleaning up secrets it no longer needs. This commit clears a few stack-based arrays containing secrets or not obviously public information and stack-based structs containing pointers to secrets. ok jsing kenjiro
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/mlkem/mlkem.c14
-rw-r--r--src/lib/libcrypto/mlkem/mlkem_internal.c46
2 files changed, 47 insertions, 13 deletions
diff --git a/src/lib/libcrypto/mlkem/mlkem.c b/src/lib/libcrypto/mlkem/mlkem.c
index 006937c39d..2f3f3c23e4 100644
--- a/src/lib/libcrypto/mlkem/mlkem.c
+++ b/src/lib/libcrypto/mlkem/mlkem.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem.c,v 1.5 2026/01/01 12:47:52 tb Exp $ */ 1/* $OpenBSD: mlkem.c,v 1.6 2026/01/01 13:36:09 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2025, Bob Beck <beck@obtuse.com> 3 * Copyright (c) 2025, Bob Beck <beck@obtuse.com>
4 * 4 *
@@ -14,9 +14,12 @@
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */ 16 */
17
17#include <stdlib.h> 18#include <stdlib.h>
19#include <string.h>
18 20
19#include <openssl/mlkem.h> 21#include <openssl/mlkem.h>
22
20#include "mlkem_internal.h" 23#include "mlkem_internal.h"
21 24
22static inline int 25static inline int
@@ -229,11 +232,14 @@ MLKEM_encap(const MLKEM_public_key *public_key,
229 uint8_t **out_shared_secret, size_t *out_shared_secret_len) 232 uint8_t **out_shared_secret, size_t *out_shared_secret_len)
230{ 233{
231 uint8_t entropy[MLKEM_ENCAP_ENTROPY]; 234 uint8_t entropy[MLKEM_ENCAP_ENTROPY];
235 int ret;
232 236
233 arc4random_buf(entropy, MLKEM_ENCAP_ENTROPY); 237 arc4random_buf(entropy, sizeof(entropy));
234 238 ret = MLKEM_encap_external_entropy(public_key, entropy, out_ciphertext,
235 return MLKEM_encap_external_entropy(public_key, entropy, out_ciphertext,
236 out_ciphertext_len, out_shared_secret, out_shared_secret_len); 239 out_ciphertext_len, out_shared_secret, out_shared_secret_len);
240 explicit_bzero(entropy, sizeof(entropy));
241
242 return ret;
237} 243}
238LCRYPTO_ALIAS(MLKEM_encap); 244LCRYPTO_ALIAS(MLKEM_encap);
239 245
diff --git a/src/lib/libcrypto/mlkem/mlkem_internal.c b/src/lib/libcrypto/mlkem/mlkem_internal.c
index 903b1ea2a3..c8305bb0d9 100644
--- a/src/lib/libcrypto/mlkem/mlkem_internal.c
+++ b/src/lib/libcrypto/mlkem/mlkem_internal.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem_internal.c,v 1.4 2026/01/01 12:47:52 tb Exp $ */ 1/* $OpenBSD: mlkem_internal.c,v 1.5 2026/01/01 13:36:09 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2024, Google Inc. 3 * Copyright (c) 2024, Google Inc.
4 * Copyright (c) 2024, 2025 Bob Beck <beck@obtuse.com> 4 * Copyright (c) 2024, 2025 Bob Beck <beck@obtuse.com>
@@ -887,10 +887,14 @@ mlkem_generate_key(uint8_t *out_encoded_public_key,
887 uint8_t entropy_buf[MLKEM_SEED_LENGTH]; 887 uint8_t entropy_buf[MLKEM_SEED_LENGTH];
888 uint8_t *entropy = optional_out_seed != NULL ? optional_out_seed : 888 uint8_t *entropy = optional_out_seed != NULL ? optional_out_seed :
889 entropy_buf; 889 entropy_buf;
890 int ret;
890 891
891 arc4random_buf(entropy, MLKEM_SEED_LENGTH); 892 arc4random_buf(entropy, MLKEM_SEED_LENGTH);
892 return mlkem_generate_key_external_entropy(out_encoded_public_key, 893 ret = mlkem_generate_key_external_entropy(out_encoded_public_key,
893 out_private_key, entropy); 894 out_private_key, entropy);
895 explicit_bzero(entropy_buf, sizeof(entropy_buf));
896
897 return ret;
894} 898}
895 899
896int 900int
@@ -978,6 +982,10 @@ mlkem_generate_key_external_entropy(uint8_t *out_encoded_public_key,
978 982
979 err: 983 err:
980 CBB_cleanup(&cbb); 984 CBB_cleanup(&cbb);
985 explicit_bzero(&priv, sizeof(priv));
986 explicit_bzero(augmented_seed, sizeof(augmented_seed));
987 explicit_bzero(error, sizeof(error));
988 explicit_bzero(hashed, sizeof(hashed));
981 989
982 return ret; 990 return ret;
983} 991}
@@ -1042,6 +1050,11 @@ encrypt_cpa(uint8_t *out, const struct public_key *pub,
1042 vector_encode(out, &u[0], u_bits, rank); 1050 vector_encode(out, &u[0], u_bits, rank);
1043 scalar_compress(&v, v_bits); 1051 scalar_compress(&v, v_bits);
1044 scalar_encode(out + compressed_vector_size(rank), &v, v_bits); 1052 scalar_encode(out + compressed_vector_size(rank), &v, v_bits);
1053
1054 explicit_bzero(secret, sizeof(secret));
1055 explicit_bzero(error, sizeof(error));
1056 explicit_bzero(u, sizeof(u));
1057 explicit_bzero(input, sizeof(input));
1045} 1058}
1046 1059
1047/* Calls mlkem_encap_external_entropy| with random bytes */ 1060/* Calls mlkem_encap_external_entropy| with random bytes */
@@ -1055,6 +1068,7 @@ mlkem_encap(const MLKEM_public_key *public_key,
1055 arc4random_buf(entropy, MLKEM_ENCAP_ENTROPY); 1068 arc4random_buf(entropy, MLKEM_ENCAP_ENTROPY);
1056 mlkem_encap_external_entropy(out_ciphertext, 1069 mlkem_encap_external_entropy(out_ciphertext,
1057 out_shared_secret, public_key, entropy); 1070 out_shared_secret, public_key, entropy);
1071 explicit_bzero(entropy, sizeof(entropy));
1058} 1072}
1059 1073
1060/* See section 6.2 of the spec. */ 1074/* See section 6.2 of the spec. */
@@ -1076,6 +1090,9 @@ mlkem_encap_external_entropy(uint8_t *out_ciphertext,
1076 encrypt_cpa(out_ciphertext, &pub, entropy, key_and_randomness + 32, 1090 encrypt_cpa(out_ciphertext, &pub, entropy, key_and_randomness + 32,
1077 public_key->rank); 1091 public_key->rank);
1078 memcpy(out_shared_secret, key_and_randomness, 32); 1092 memcpy(out_shared_secret, key_and_randomness, 32);
1093
1094 explicit_bzero(key_and_randomness, sizeof(key_and_randomness));
1095 explicit_bzero(input, sizeof(input));
1079} 1096}
1080 1097
1081static void 1098static void
@@ -1101,6 +1118,8 @@ decrypt_cpa(uint8_t out[32], const struct private_key *priv,
1101 scalar_sub(&v, &mask); 1118 scalar_sub(&v, &mask);
1102 scalar_compress(&v, 1); 1119 scalar_compress(&v, 1);
1103 scalar_encode_1(out, &v); 1120 scalar_encode_1(out, &v);
1121
1122 explicit_bzero(u, sizeof(u));
1104} 1123}
1105 1124
1106/* See section 6.3 */ 1125/* See section 6.3 */
@@ -1149,6 +1168,8 @@ mlkem_decap(const MLKEM_private_key *private_key, const uint8_t *ciphertext,
1149 1168
1150 err: 1169 err:
1151 freezero(expected_ciphertext, expected_ciphertext_length); 1170 freezero(expected_ciphertext, expected_ciphertext_length);
1171 explicit_bzero(key_and_randomness, sizeof(key_and_randomness));
1172 explicit_bzero(decrypted, sizeof(decrypted));
1152 1173
1153 return ret; 1174 return ret;
1154} 1175}
@@ -1249,6 +1270,7 @@ mlkem_marshal_private_key(const MLKEM_private_key *private_key,
1249 1270
1250 err: 1271 err:
1251 CBB_cleanup(&cbb); 1272 CBB_cleanup(&cbb);
1273 explicit_bzero(&priv, sizeof(priv));
1252 1274
1253 return ret; 1275 return ret;
1254} 1276}
@@ -1259,28 +1281,34 @@ mlkem_parse_private_key(const uint8_t *input, size_t input_len,
1259{ 1281{
1260 struct private_key priv; 1282 struct private_key priv;
1261 CBS cbs, s_bytes; 1283 CBS cbs, s_bytes;
1284 int ret = 0;
1262 1285
1263 private_key_from_external(out_private_key, &priv); 1286 private_key_from_external(out_private_key, &priv);
1264 CBS_init(&cbs, input, input_len); 1287 CBS_init(&cbs, input, input_len);
1265 1288
1266 if (!CBS_get_bytes(&cbs, &s_bytes, 1289 if (!CBS_get_bytes(&cbs, &s_bytes,
1267 encoded_vector_size(out_private_key->rank))) 1290 encoded_vector_size(out_private_key->rank)))
1268 return 0; 1291 goto err;
1269 if (!vector_decode(priv.s, CBS_data(&s_bytes), kLog2Prime, 1292 if (!vector_decode(priv.s, CBS_data(&s_bytes), kLog2Prime,
1270 out_private_key->rank)) 1293 out_private_key->rank))
1271 return 0; 1294 goto err;
1272 if (!mlkem_parse_public_key_no_hash(&priv.pub, &cbs, 1295 if (!mlkem_parse_public_key_no_hash(&priv.pub, &cbs,
1273 out_private_key->rank)) 1296 out_private_key->rank))
1274 return 0; 1297 goto err;
1275 1298
1276 memcpy(priv.pub.public_key_hash, CBS_data(&cbs), 32); 1299 memcpy(priv.pub.public_key_hash, CBS_data(&cbs), 32);
1277 if (!CBS_skip(&cbs, 32)) 1300 if (!CBS_skip(&cbs, 32))
1278 return 0; 1301 goto err;
1279 memcpy(priv.fo_failure_secret, CBS_data(&cbs), 32); 1302 memcpy(priv.fo_failure_secret, CBS_data(&cbs), 32);
1280 if (!CBS_skip(&cbs, 32)) 1303 if (!CBS_skip(&cbs, 32))
1281 return 0; 1304 goto err;
1282 if (CBS_len(&cbs) != 0) 1305 if (CBS_len(&cbs) != 0)
1283 return 0; 1306 goto err;
1284 1307
1285 return 1; 1308 ret = 1;
1309
1310 err:
1311 explicit_bzero(&priv, sizeof(priv));
1312
1313 return ret;
1286} 1314}