diff options
Diffstat (limited to 'src/lib/libcrypto/mlkem/mlkem768.c')
-rw-r--r-- | src/lib/libcrypto/mlkem/mlkem768.c | 89 |
1 files changed, 57 insertions, 32 deletions
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; |