diff options
Diffstat (limited to '')
-rw-r--r-- | src/regress/lib/libcrypto/ec/Makefile | 9 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/ec/ec_arithmetic.c | 210 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/ec/ec_asn1_test.c | 321 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/ec/ectest.c | 9 |
4 files changed, 417 insertions, 132 deletions
diff --git a/src/regress/lib/libcrypto/ec/Makefile b/src/regress/lib/libcrypto/ec/Makefile index b21eacb4bc..1d976c77d0 100644 --- a/src/regress/lib/libcrypto/ec/Makefile +++ b/src/regress/lib/libcrypto/ec/Makefile | |||
@@ -1,12 +1,13 @@ | |||
1 | # $OpenBSD: Makefile,v 1.11 2025/03/08 20:09:35 tb Exp $ | 1 | # $OpenBSD: Makefile,v 1.13 2025/08/03 08:29:39 jsing Exp $ |
2 | 2 | ||
3 | .ifdef EOPENSSL33 | 3 | .ifdef EOPENSSL35 |
4 | LDADD += -Wl,-rpath,/usr/local/lib/eopenssl33 -L/usr/local/lib/eopenssl33 | 4 | LDADD += -Wl,-rpath,/usr/local/lib/eopenssl35 -L/usr/local/lib/eopenssl35 |
5 | CFLAGS += -I/usr/local/include/eopenssl33/ | 5 | CFLAGS += -I/usr/local/include/eopenssl35/ |
6 | CFLAGS += -DOPENSSL_SUPPRESS_DEPRECATED | 6 | CFLAGS += -DOPENSSL_SUPPRESS_DEPRECATED |
7 | .endif | 7 | .endif |
8 | 8 | ||
9 | PROGS += ectest | 9 | PROGS += ectest |
10 | PROGS += ec_arithmetic | ||
10 | PROGS += ec_asn1_test | 11 | PROGS += ec_asn1_test |
11 | PROGS += ec_point_conversion | 12 | PROGS += ec_point_conversion |
12 | 13 | ||
diff --git a/src/regress/lib/libcrypto/ec/ec_arithmetic.c b/src/regress/lib/libcrypto/ec/ec_arithmetic.c new file mode 100644 index 0000000000..c6f7cd4f8c --- /dev/null +++ b/src/regress/lib/libcrypto/ec/ec_arithmetic.c | |||
@@ -0,0 +1,210 @@ | |||
1 | /* $OpenBSD: ec_arithmetic.c,v 1.1 2025/08/03 08:29:39 jsing Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2022,2025 Joel Sing <jsing@openbsd.org> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #include <sys/time.h> | ||
19 | |||
20 | #include <err.h> | ||
21 | #include <signal.h> | ||
22 | #include <stdio.h> | ||
23 | #include <string.h> | ||
24 | #include <time.h> | ||
25 | #include <unistd.h> | ||
26 | |||
27 | #include <openssl/bn.h> | ||
28 | #include <openssl/ec.h> | ||
29 | #include <openssl/objects.h> | ||
30 | |||
31 | static void | ||
32 | benchmark_ec_point_add(const EC_GROUP *group, EC_POINT *result, | ||
33 | const BIGNUM *scalar, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | ||
34 | { | ||
35 | if (!EC_POINT_add(group, result, a, b, ctx)) | ||
36 | errx(1, "EC_POINT_add"); | ||
37 | } | ||
38 | |||
39 | static void | ||
40 | benchmark_ec_point_dbl(const EC_GROUP *group, EC_POINT *result, | ||
41 | const BIGNUM *scalar, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | ||
42 | { | ||
43 | if (!EC_POINT_dbl(group, result, a, ctx)) | ||
44 | errx(1, "EC_POINT_dbl"); | ||
45 | } | ||
46 | |||
47 | static void | ||
48 | benchmark_ec_point_mul_generator(const EC_GROUP *group, EC_POINT *result, | ||
49 | const BIGNUM *scalar, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | ||
50 | { | ||
51 | if (!EC_POINT_mul(group, result, scalar, NULL, NULL, ctx)) | ||
52 | errx(1, "EC_POINT_mul"); | ||
53 | } | ||
54 | |||
55 | struct benchmark { | ||
56 | int curve; | ||
57 | const char *desc; | ||
58 | void (*func)(const EC_GROUP *, EC_POINT *, const BIGNUM *, | ||
59 | const EC_POINT *, const EC_POINT *, BN_CTX *); | ||
60 | }; | ||
61 | |||
62 | static const struct benchmark benchmarks[] = { | ||
63 | { | ||
64 | .curve = NID_X9_62_prime256v1, | ||
65 | .desc = "EC_POINT_add() p256", | ||
66 | .func = benchmark_ec_point_add, | ||
67 | }, | ||
68 | { | ||
69 | .curve = NID_secp384r1, | ||
70 | .desc = "EC_POINT_add() p384", | ||
71 | .func = benchmark_ec_point_add, | ||
72 | }, | ||
73 | { | ||
74 | .curve = NID_secp521r1, | ||
75 | .desc = "EC_POINT_add() p521", | ||
76 | .func = benchmark_ec_point_add, | ||
77 | }, | ||
78 | { | ||
79 | .curve = NID_X9_62_prime256v1, | ||
80 | .desc = "EC_POINT_dbl() p256", | ||
81 | .func = benchmark_ec_point_dbl, | ||
82 | }, | ||
83 | { | ||
84 | .curve = NID_secp384r1, | ||
85 | .desc = "EC_POINT_dbl() p384", | ||
86 | .func = benchmark_ec_point_dbl, | ||
87 | }, | ||
88 | { | ||
89 | .curve = NID_secp521r1, | ||
90 | .desc = "EC_POINT_dbl() p521", | ||
91 | .func = benchmark_ec_point_dbl, | ||
92 | }, | ||
93 | { | ||
94 | .curve = NID_X9_62_prime256v1, | ||
95 | .desc = "EC_POINT_mul() generator p256", | ||
96 | .func = benchmark_ec_point_mul_generator, | ||
97 | }, | ||
98 | { | ||
99 | .curve = NID_secp384r1, | ||
100 | .desc = "EC_POINT_mul() generator p384", | ||
101 | .func = benchmark_ec_point_mul_generator, | ||
102 | }, | ||
103 | { | ||
104 | .curve = NID_secp521r1, | ||
105 | .desc = "EC_POINT_mul() generator p521", | ||
106 | .func = benchmark_ec_point_mul_generator, | ||
107 | }, | ||
108 | }; | ||
109 | |||
110 | #define N_BENCHMARKS (sizeof(benchmarks) / sizeof(benchmarks[0])) | ||
111 | |||
112 | static volatile sig_atomic_t benchmark_stop; | ||
113 | |||
114 | static void | ||
115 | benchmark_sig_alarm(int sig) | ||
116 | { | ||
117 | benchmark_stop = 1; | ||
118 | } | ||
119 | |||
120 | static void | ||
121 | benchmark_run(const struct benchmark *bm, int seconds) | ||
122 | { | ||
123 | struct timespec start, end, duration; | ||
124 | EC_GROUP *group = NULL; | ||
125 | EC_POINT *a = NULL, *b = NULL, *result = NULL; | ||
126 | BIGNUM *order = NULL, *scalar = NULL; | ||
127 | BN_CTX *ctx = NULL; | ||
128 | int i; | ||
129 | |||
130 | signal(SIGALRM, benchmark_sig_alarm); | ||
131 | |||
132 | if ((ctx = BN_CTX_new()) == NULL) | ||
133 | errx(1, "BN_CTX_new"); | ||
134 | |||
135 | if ((group = EC_GROUP_new_by_curve_name(bm->curve)) == NULL) | ||
136 | errx(1, "EC_GROUP_new_by_curve_name"); | ||
137 | if ((order = BN_new()) == NULL) | ||
138 | errx(1, "BN_new"); | ||
139 | if (!EC_GROUP_get_order(group, order, ctx)) | ||
140 | errx(1, "EC_GROUP_get_order"); | ||
141 | |||
142 | if ((scalar = BN_new()) == NULL) | ||
143 | errx(1, "BN_new"); | ||
144 | if (!BN_rand_range(scalar, order)) | ||
145 | errx(1, "BN_rand_range"); | ||
146 | if (!BN_set_bit(scalar, EC_GROUP_order_bits(group) - 1)) | ||
147 | errx(1, "BN_set_bit"); | ||
148 | |||
149 | if ((result = EC_POINT_new(group)) == NULL) | ||
150 | errx(1, "EC_POINT_new"); | ||
151 | if ((a = EC_POINT_new(group)) == NULL) | ||
152 | errx(1, "EC_POINT_new"); | ||
153 | if ((b = EC_POINT_new(group)) == NULL) | ||
154 | errx(1, "EC_POINT_new"); | ||
155 | |||
156 | if (!EC_POINT_mul(group, a, scalar, NULL, NULL, ctx)) | ||
157 | errx(1, "EC_POINT_mul"); | ||
158 | if (!EC_POINT_mul(group, b, scalar, NULL, NULL, ctx)) | ||
159 | errx(1, "EC_POINT_mul"); | ||
160 | |||
161 | benchmark_stop = 0; | ||
162 | i = 0; | ||
163 | alarm(seconds); | ||
164 | |||
165 | clock_gettime(CLOCK_MONOTONIC, &start); | ||
166 | |||
167 | fprintf(stderr, "Benchmarking %s for %ds: ", bm->desc, seconds); | ||
168 | while (!benchmark_stop) { | ||
169 | bm->func(group, result, scalar, a, b, ctx); | ||
170 | i++; | ||
171 | } | ||
172 | clock_gettime(CLOCK_MONOTONIC, &end); | ||
173 | timespecsub(&end, &start, &duration); | ||
174 | fprintf(stderr, "%d iterations in %f seconds\n", i, | ||
175 | duration.tv_sec + duration.tv_nsec / 1000000000.0); | ||
176 | |||
177 | EC_GROUP_free(group); | ||
178 | EC_POINT_free(result); | ||
179 | EC_POINT_free(a); | ||
180 | EC_POINT_free(b); | ||
181 | BN_free(order); | ||
182 | BN_free(scalar); | ||
183 | BN_CTX_free(ctx); | ||
184 | } | ||
185 | |||
186 | static void | ||
187 | benchmark_ec_mul_single(void) | ||
188 | { | ||
189 | const struct benchmark *bm; | ||
190 | size_t i; | ||
191 | |||
192 | for (i = 0; i < N_BENCHMARKS; i++) { | ||
193 | bm = &benchmarks[i]; | ||
194 | benchmark_run(bm, 5); | ||
195 | } | ||
196 | } | ||
197 | |||
198 | int | ||
199 | main(int argc, char **argv) | ||
200 | { | ||
201 | int benchmark = 0, failed = 0; | ||
202 | |||
203 | if (argc == 2 && strcmp(argv[1], "--benchmark") == 0) | ||
204 | benchmark = 1; | ||
205 | |||
206 | if (benchmark && !failed) | ||
207 | benchmark_ec_mul_single(); | ||
208 | |||
209 | return failed; | ||
210 | } | ||
diff --git a/src/regress/lib/libcrypto/ec/ec_asn1_test.c b/src/regress/lib/libcrypto/ec/ec_asn1_test.c index 03358e69ca..50e6304baf 100644 --- a/src/regress/lib/libcrypto/ec/ec_asn1_test.c +++ b/src/regress/lib/libcrypto/ec/ec_asn1_test.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* $OpenBSD: ec_asn1_test.c,v 1.32 2025/03/08 20:09:35 tb Exp $ */ | 1 | /* $OpenBSD: ec_asn1_test.c,v 1.36 2025/07/23 07:42:33 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2017, 2021 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2017, 2021 Joel Sing <jsing@openbsd.org> |
4 | * Copyright (c) 2024 Theo Buehler <tb@openbsd.org> | 4 | * Copyright (c) 2024, 2025 Theo Buehler <tb@openbsd.org> |
5 | * | 5 | * |
6 | * Permission to use, copy, modify, and distribute this software for any | 6 | * Permission to use, copy, modify, and distribute this software for any |
7 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -17,12 +17,17 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <err.h> | 19 | #include <err.h> |
20 | #include <stdio.h> | ||
21 | #include <stdint.h> | ||
22 | #include <stdlib.h> | ||
20 | #include <string.h> | 23 | #include <string.h> |
21 | 24 | ||
22 | #include <openssl/bio.h> | 25 | #include <openssl/bio.h> |
26 | #include <openssl/bn.h> | ||
23 | #include <openssl/ec.h> | 27 | #include <openssl/ec.h> |
24 | #include <openssl/err.h> | 28 | #include <openssl/err.h> |
25 | #include <openssl/objects.h> | 29 | #include <openssl/objects.h> |
30 | #include <openssl/sha.h> | ||
26 | 31 | ||
27 | #include "ec_local.h" | 32 | #include "ec_local.h" |
28 | 33 | ||
@@ -1281,126 +1286,6 @@ static const struct ec_private_key { | |||
1281 | }, | 1286 | }, |
1282 | }, | 1287 | }, |
1283 | { | 1288 | { |
1284 | .name = "prime239v1", | ||
1285 | .der_len = 115, | ||
1286 | .der = { | ||
1287 | 0x30, 0x71, 0x02, 0x01, 0x01, 0x04, 0x1e, 0x6e, | ||
1288 | 0x26, 0x5e, 0xde, 0x5b, 0x67, 0xd6, 0x38, 0x52, | ||
1289 | 0xe7, 0x1e, 0x8d, 0x44, 0xb1, 0xfb, 0xf8, 0xaf, | ||
1290 | 0xf9, 0x94, 0x2c, 0xe2, 0x0d, 0xa8, 0x5f, 0x03, | ||
1291 | 0x67, 0x53, 0x7b, 0x8b, 0x2e, 0xa0, 0x0a, 0x06, | ||
1292 | 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, | ||
1293 | 0x04, 0xa1, 0x40, 0x03, 0x3e, 0x00, 0x04, 0x33, | ||
1294 | 0xc6, 0xe5, 0x8a, 0xc1, 0x8b, 0x7c, 0x96, 0x19, | ||
1295 | 0xc9, 0xe1, 0x54, 0x7f, 0x81, 0x9e, 0x59, 0x62, | ||
1296 | 0xec, 0xc0, 0x1e, 0xe5, 0x53, 0xd5, 0xae, 0x6b, | ||
1297 | 0xd3, 0xe0, 0x09, 0x07, 0xc5, 0x27, 0x81, 0xa6, | ||
1298 | 0x8d, 0x39, 0x8e, 0xfe, 0x01, 0xc2, 0x1d, 0xda, | ||
1299 | 0xde, 0x7b, 0xdc, 0x76, 0x27, 0x17, 0xf9, 0x6f, | ||
1300 | 0xe3, 0x04, 0xef, 0x5d, 0x65, 0x75, 0x98, 0x7f, | ||
1301 | 0x2d, 0xd0, 0x68, | ||
1302 | }, | ||
1303 | .hex = "0433C6E58AC18B7C" | ||
1304 | "9619C9E1547F819E" | ||
1305 | "5962ECC01EE553D5" | ||
1306 | "AE6BD3E00907C527" | ||
1307 | "81A68D398EFE01C2" | ||
1308 | "1DDADE7BDC762717" | ||
1309 | "F96FE304EF5D6575" | ||
1310 | "987F2DD068", | ||
1311 | .oct_len = 61, | ||
1312 | .oct = { | ||
1313 | 0x04, 0x33, 0xc6, 0xe5, 0x8a, 0xc1, 0x8b, 0x7c, | ||
1314 | 0x96, 0x19, 0xc9, 0xe1, 0x54, 0x7f, 0x81, 0x9e, | ||
1315 | 0x59, 0x62, 0xec, 0xc0, 0x1e, 0xe5, 0x53, 0xd5, | ||
1316 | 0xae, 0x6b, 0xd3, 0xe0, 0x09, 0x07, 0xc5, 0x27, | ||
1317 | 0x81, 0xa6, 0x8d, 0x39, 0x8e, 0xfe, 0x01, 0xc2, | ||
1318 | 0x1d, 0xda, 0xde, 0x7b, 0xdc, 0x76, 0x27, 0x17, | ||
1319 | 0xf9, 0x6f, 0xe3, 0x04, 0xef, 0x5d, 0x65, 0x75, | ||
1320 | 0x98, 0x7f, 0x2d, 0xd0, 0x68, | ||
1321 | }, | ||
1322 | }, | ||
1323 | { | ||
1324 | .name = "prime239v2", | ||
1325 | .der_len = 115, | ||
1326 | .der = { | ||
1327 | 0x30, 0x71, 0x02, 0x01, 0x01, 0x04, 0x1e, 0x30, | ||
1328 | 0x2f, 0x01, 0x10, 0xe9, 0x09, 0x15, 0xdd, 0xe3, | ||
1329 | 0xdd, 0xae, 0xcb, 0x9d, 0x3a, 0x58, 0x92, 0x02, | ||
1330 | 0x1e, 0x6e, 0x02, 0x57, 0xa8, 0x36, 0x0b, 0x20, | ||
1331 | 0x0b, 0x7e, 0xf4, 0xad, 0x0b, 0xa0, 0x0a, 0x06, | ||
1332 | 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, | ||
1333 | 0x05, 0xa1, 0x40, 0x03, 0x3e, 0x00, 0x04, 0x3c, | ||
1334 | 0x10, 0x27, 0x7b, 0xac, 0xdf, 0x86, 0xc9, 0x4f, | ||
1335 | 0xf8, 0x39, 0x87, 0x02, 0x39, 0xaf, 0x41, 0xbc, | ||
1336 | 0x4b, 0x67, 0xd8, 0x5e, 0x04, 0x96, 0x84, 0xb5, | ||
1337 | 0x60, 0x50, 0x48, 0x6a, 0x20, 0x1d, 0x2b, 0x7e, | ||
1338 | 0x9f, 0xaf, 0xf8, 0x8e, 0x7e, 0xa4, 0xcd, 0x00, | ||
1339 | 0xad, 0xb1, 0xad, 0x22, 0x69, 0x32, 0x10, 0x6c, | ||
1340 | 0xe0, 0xcc, 0xdd, 0x45, 0xd8, 0xa6, 0x29, 0x2f, | ||
1341 | 0xad, 0x6b, 0xf9, | ||
1342 | }, | ||
1343 | .hex = "043C10277BACDF86" | ||
1344 | "C94FF839870239AF" | ||
1345 | "41BC4B67D85E0496" | ||
1346 | "84B56050486A201D" | ||
1347 | "2B7E9FAFF88E7EA4" | ||
1348 | "CD00ADB1AD226932" | ||
1349 | "106CE0CCDD45D8A6" | ||
1350 | "292FAD6BF9", | ||
1351 | .oct_len = 61, | ||
1352 | .oct = { | ||
1353 | 0x04, 0x3c, 0x10, 0x27, 0x7b, 0xac, 0xdf, 0x86, | ||
1354 | 0xc9, 0x4f, 0xf8, 0x39, 0x87, 0x02, 0x39, 0xaf, | ||
1355 | 0x41, 0xbc, 0x4b, 0x67, 0xd8, 0x5e, 0x04, 0x96, | ||
1356 | 0x84, 0xb5, 0x60, 0x50, 0x48, 0x6a, 0x20, 0x1d, | ||
1357 | 0x2b, 0x7e, 0x9f, 0xaf, 0xf8, 0x8e, 0x7e, 0xa4, | ||
1358 | 0xcd, 0x00, 0xad, 0xb1, 0xad, 0x22, 0x69, 0x32, | ||
1359 | 0x10, 0x6c, 0xe0, 0xcc, 0xdd, 0x45, 0xd8, 0xa6, | ||
1360 | 0x29, 0x2f, 0xad, 0x6b, 0xf9, | ||
1361 | }, | ||
1362 | }, | ||
1363 | { | ||
1364 | .name = "prime239v3", | ||
1365 | .der_len = 115, | ||
1366 | .der = { | ||
1367 | 0x30, 0x71, 0x02, 0x01, 0x01, 0x04, 0x1e, 0x26, | ||
1368 | 0x3f, 0x23, 0x4c, 0xe7, 0xbd, 0xa8, 0xe4, 0xfe, | ||
1369 | 0x7c, 0xf6, 0x18, 0x6a, 0xb2, 0xa6, 0x39, 0x15, | ||
1370 | 0x6d, 0x72, 0xe8, 0x9e, 0x3f, 0x0f, 0x10, 0x1e, | ||
1371 | 0xe5, 0xdf, 0xac, 0xe8, 0x2f, 0xa0, 0x0a, 0x06, | ||
1372 | 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, | ||
1373 | 0x06, 0xa1, 0x40, 0x03, 0x3e, 0x00, 0x04, 0x37, | ||
1374 | 0xba, 0x07, 0x7f, 0xd9, 0x46, 0x5a, 0x33, 0x03, | ||
1375 | 0x31, 0x77, 0x38, 0xef, 0xee, 0xcc, 0x3d, 0xe1, | ||
1376 | 0xaa, 0x57, 0xe3, 0x8d, 0xb7, 0xcd, 0xe3, 0x01, | ||
1377 | 0xf4, 0xd6, 0x75, 0x49, 0x72, 0x61, 0x4c, 0xbf, | ||
1378 | 0xc0, 0x1f, 0x8b, 0x5f, 0x98, 0x9b, 0xa7, 0xe5, | ||
1379 | 0x6a, 0xb7, 0xfe, 0x63, 0xdb, 0xb0, 0x40, 0xcb, | ||
1380 | 0x26, 0x81, 0x2a, 0x91, 0x14, 0x0f, 0xc7, 0x31, | ||
1381 | 0x13, 0x78, 0x16, | ||
1382 | }, | ||
1383 | .hex = "0437BA077FD9465A" | ||
1384 | "3303317738EFEECC" | ||
1385 | "3DE1AA57E38DB7CD" | ||
1386 | "E301F4D675497261" | ||
1387 | "4CBFC01F8B5F989B" | ||
1388 | "A7E56AB7FE63DBB0" | ||
1389 | "40CB26812A91140F" | ||
1390 | "C731137816", | ||
1391 | .oct_len = 61, | ||
1392 | .oct = { | ||
1393 | 0x04, 0x37, 0xba, 0x07, 0x7f, 0xd9, 0x46, 0x5a, | ||
1394 | 0x33, 0x03, 0x31, 0x77, 0x38, 0xef, 0xee, 0xcc, | ||
1395 | 0x3d, 0xe1, 0xaa, 0x57, 0xe3, 0x8d, 0xb7, 0xcd, | ||
1396 | 0xe3, 0x01, 0xf4, 0xd6, 0x75, 0x49, 0x72, 0x61, | ||
1397 | 0x4c, 0xbf, 0xc0, 0x1f, 0x8b, 0x5f, 0x98, 0x9b, | ||
1398 | 0xa7, 0xe5, 0x6a, 0xb7, 0xfe, 0x63, 0xdb, 0xb0, | ||
1399 | 0x40, 0xcb, 0x26, 0x81, 0x2a, 0x91, 0x14, 0x0f, | ||
1400 | 0xc7, 0x31, 0x13, 0x78, 0x16, | ||
1401 | }, | ||
1402 | }, | ||
1403 | { | ||
1404 | .name = "prime256v1", | 1289 | .name = "prime256v1", |
1405 | .der_len = 121, | 1290 | .der_len = 121, |
1406 | .der = { | 1291 | .der = { |
@@ -2468,6 +2353,197 @@ ec_group_check_private_keys(void) | |||
2468 | return failed; | 2353 | return failed; |
2469 | } | 2354 | } |
2470 | 2355 | ||
2356 | static void | ||
2357 | ec_group_sha1_bignum(BIGNUM *out, const BIGNUM *in) | ||
2358 | { | ||
2359 | char md[SHA_DIGEST_LENGTH]; | ||
2360 | unsigned char *bin; | ||
2361 | size_t bin_len; | ||
2362 | |||
2363 | if (BN_num_bytes(in) <= 0) | ||
2364 | errx(1, "%s: invalid bignum", __func__); | ||
2365 | |||
2366 | bin_len = BN_num_bytes(in); | ||
2367 | if ((bin = calloc(1, bin_len)) == NULL) | ||
2368 | err(1, "calloc"); | ||
2369 | if (BN_bn2bin(in, bin) <= 0) | ||
2370 | errx(1, "BN_bn2bin"); | ||
2371 | |||
2372 | SHA1(bin, bin_len, md); | ||
2373 | free(bin); | ||
2374 | |||
2375 | if (BN_bin2bn(md, sizeof(md), out) == NULL) | ||
2376 | errx(1, "BN_bin2bn"); | ||
2377 | } | ||
2378 | |||
2379 | static int | ||
2380 | ec_group_check_seed(const EC_builtin_curve *curve, BN_CTX *ctx) | ||
2381 | { | ||
2382 | EC_GROUP *group = NULL; | ||
2383 | BIGNUM *p, *a, *b, *pow2, *r, *seed_bn, *w; | ||
2384 | const unsigned char *seed; | ||
2385 | size_t seed_len; | ||
2386 | int i, g, h, s, t; | ||
2387 | int failed = 1; | ||
2388 | |||
2389 | if ((group = EC_GROUP_new_by_curve_name(curve->nid)) == NULL) | ||
2390 | errx(1, "EC_GROUP_new_by_curve_name"); | ||
2391 | |||
2392 | BN_CTX_start(ctx); | ||
2393 | |||
2394 | if ((p = BN_CTX_get(ctx)) == NULL) | ||
2395 | errx(1, "p = BN_CTX_get()"); | ||
2396 | if ((a = BN_CTX_get(ctx)) == NULL) | ||
2397 | errx(1, "a = BN_CTX_get()"); | ||
2398 | if ((b = BN_CTX_get(ctx)) == NULL) | ||
2399 | errx(1, "b = BN_CTX_get()"); | ||
2400 | if ((r = BN_CTX_get(ctx)) == NULL) | ||
2401 | errx(1, "r = BN_CTX_get()"); | ||
2402 | if ((pow2 = BN_CTX_get(ctx)) == NULL) | ||
2403 | errx(1, "pow2 = BN_CTX_get()"); | ||
2404 | if ((seed_bn = BN_CTX_get(ctx)) == NULL) | ||
2405 | errx(1, "seed_bn = BN_CTX_get()"); | ||
2406 | if ((w = BN_CTX_get(ctx)) == NULL) | ||
2407 | errx(1, "w = BN_CTX_get()"); | ||
2408 | |||
2409 | /* | ||
2410 | * If the curve has a seed, verify that its parameters a and b have | ||
2411 | * been selected using that seed, loosely following X9.62, F.3.4.b. | ||
2412 | * Otherwise there's nothing to do. | ||
2413 | */ | ||
2414 | if ((seed = EC_GROUP_get0_seed(group)) == NULL) | ||
2415 | goto done; | ||
2416 | seed_len = EC_GROUP_get_seed_len(group); | ||
2417 | |||
2418 | /* | ||
2419 | * This isn't a requirement but happens to be the case for NIST | ||
2420 | * curves - the only built-in curves that have a seed. | ||
2421 | */ | ||
2422 | if (seed_len != SHA_DIGEST_LENGTH) { | ||
2423 | fprintf(stderr, "%s FAIL: unexpected seed length. " | ||
2424 | "want %d, got %zu\n", __func__, SHA_DIGEST_LENGTH, seed_len); | ||
2425 | goto err; | ||
2426 | } | ||
2427 | |||
2428 | /* Seed length in bits, per F.3.3.b. */ | ||
2429 | g = 8 * seed_len; | ||
2430 | |||
2431 | /* | ||
2432 | * Prepare to build the verifiably random element r of GFp by | ||
2433 | * concatenating the SHA-1 of modifications of the seed as a number. | ||
2434 | */ | ||
2435 | if (BN_bin2bn(seed, seed_len, seed_bn) == NULL) | ||
2436 | errx(1, "BN_bin2bn"); | ||
2437 | |||
2438 | if (!EC_GROUP_get_curve(group, p, a, b, ctx)) | ||
2439 | errx(1, "EC_GROUP_get_curve"); | ||
2440 | |||
2441 | t = BN_num_bits(p); /* bit length needed. */ | ||
2442 | s = (t - 1) / 160; /* number of SHA-1 fitting in bit length. */ | ||
2443 | h = t - 160 * s; /* remaining number of bits in r. */ | ||
2444 | |||
2445 | /* | ||
2446 | * Steps 1 - 3: compute hash of the seed and take h - 1 rightmost bits. | ||
2447 | */ | ||
2448 | |||
2449 | ec_group_sha1_bignum(r, seed_bn); | ||
2450 | BN_zero(pow2); | ||
2451 | if (!BN_set_bit(pow2, h - 1)) | ||
2452 | errx(1, "BN_set_bit"); | ||
2453 | if (!BN_mod(r, r, pow2, ctx)) | ||
2454 | errx(1, "BN_nnmod"); | ||
2455 | |||
2456 | /* | ||
2457 | * Steps 4 - 6: for i from 1 to s do Wi = SHA-1(SEED + i mod 2^g), | ||
2458 | * With W0 = r as already computed, let r = W0 || W1 || ... || Ws. | ||
2459 | */ | ||
2460 | |||
2461 | BN_zero(pow2); | ||
2462 | if (!BN_set_bit(pow2, g)) | ||
2463 | errx(1, "BN_set_bit"); | ||
2464 | |||
2465 | for (i = 0; i < s; i++) { | ||
2466 | /* | ||
2467 | * This is a bit silly since the seed isn't going to have all | ||
2468 | * its bits set, so BN_add_word(seed_bn, 1) would do, but for | ||
2469 | * the sake of correctness... | ||
2470 | */ | ||
2471 | if (!BN_mod_add(seed_bn, seed_bn, BN_value_one(), pow2, ctx)) | ||
2472 | errx(1, "BN_mod_add"); | ||
2473 | |||
2474 | ec_group_sha1_bignum(w, seed_bn); | ||
2475 | |||
2476 | if (!BN_lshift(r, r, 8 * SHA_DIGEST_LENGTH)) | ||
2477 | errx(1, "BN_lshift"); | ||
2478 | if (!BN_add(r, r, w)) | ||
2479 | errx(1, "BN_add"); | ||
2480 | } | ||
2481 | |||
2482 | /* | ||
2483 | * Step 7: check that r * b^2 == a^3 (mod p) | ||
2484 | */ | ||
2485 | |||
2486 | /* Compute r = r * b^2 (mod p). */ | ||
2487 | if (!BN_mod_sqr(b, b, p, ctx)) | ||
2488 | errx(1, "BN_mod_sqr"); | ||
2489 | if (!BN_mod_mul(r, r, b, p, ctx)) | ||
2490 | errx(1, "BN_mod_mul"); | ||
2491 | |||
2492 | /* Compute a = a^3 (mod p). */ | ||
2493 | if (!BN_mod_sqr(b, a, p, ctx)) | ||
2494 | errx(1, "BN_mod_sqr"); | ||
2495 | if (!BN_mod_mul(a, a, b, p, ctx)) | ||
2496 | errx(1, "BN_mod_mul"); | ||
2497 | |||
2498 | /* | ||
2499 | * XXX - this assumes that a, b, p >= 0, so the results are in [0, p). | ||
2500 | * This is currently enforced in the EC code. | ||
2501 | */ | ||
2502 | if (BN_cmp(r, a) != 0) { | ||
2503 | fprintf(stderr, "FAIL: %s verification failed for %s\nr * b^2:\t", | ||
2504 | __func__, curve->comment); | ||
2505 | BN_print_fp(stderr, r); | ||
2506 | fprintf(stderr, "\na^3:\t\t"); | ||
2507 | BN_print_fp(stderr, a); | ||
2508 | fprintf(stderr, "\n"); | ||
2509 | goto err; | ||
2510 | } | ||
2511 | |||
2512 | done: | ||
2513 | failed = 0; | ||
2514 | |||
2515 | err: | ||
2516 | BN_CTX_end(ctx); | ||
2517 | EC_GROUP_free(group); | ||
2518 | |||
2519 | return failed; | ||
2520 | } | ||
2521 | |||
2522 | static int | ||
2523 | ec_group_check_seeds(void) | ||
2524 | { | ||
2525 | BN_CTX *ctx = NULL; | ||
2526 | EC_builtin_curve *all_curves = NULL; | ||
2527 | size_t curve_id, ncurves; | ||
2528 | int failed = 0; | ||
2529 | |||
2530 | if ((ctx = BN_CTX_new()) == NULL) | ||
2531 | errx(1, "BN_CTX_new"); | ||
2532 | |||
2533 | ncurves = EC_get_builtin_curves(NULL, 0); | ||
2534 | if ((all_curves = calloc(ncurves, sizeof(*all_curves))) == NULL) | ||
2535 | err(1, "calloc builtin curves"); | ||
2536 | EC_get_builtin_curves(all_curves, ncurves); | ||
2537 | |||
2538 | for (curve_id = 0; curve_id < ncurves; curve_id++) | ||
2539 | failed |= ec_group_check_seed(&all_curves[curve_id], ctx); | ||
2540 | |||
2541 | free(all_curves); | ||
2542 | BN_CTX_free(ctx); | ||
2543 | |||
2544 | return failed; | ||
2545 | } | ||
2546 | |||
2471 | int | 2547 | int |
2472 | main(int argc, char **argv) | 2548 | main(int argc, char **argv) |
2473 | { | 2549 | { |
@@ -2479,6 +2555,7 @@ main(int argc, char **argv) | |||
2479 | failed |= ec_group_roundtrip_builtin_curves(); | 2555 | failed |= ec_group_roundtrip_builtin_curves(); |
2480 | failed |= ec_group_non_builtin_curves(); | 2556 | failed |= ec_group_non_builtin_curves(); |
2481 | failed |= ec_group_check_private_keys(); | 2557 | failed |= ec_group_check_private_keys(); |
2558 | failed |= ec_group_check_seeds(); | ||
2482 | 2559 | ||
2483 | return failed; | 2560 | return failed; |
2484 | } | 2561 | } |
diff --git a/src/regress/lib/libcrypto/ec/ectest.c b/src/regress/lib/libcrypto/ec/ectest.c index fc44f9c886..3e81954174 100644 --- a/src/regress/lib/libcrypto/ec/ectest.c +++ b/src/regress/lib/libcrypto/ec/ectest.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ectest.c,v 1.35 2025/01/24 11:49:13 tb Exp $ */ | 1 | /* $OpenBSD: ectest.c,v 1.36 2025/07/23 07:40:07 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Originally written by Bodo Moeller for the OpenSSL project. | 3 | * Originally written by Bodo Moeller for the OpenSSL project. |
4 | */ | 4 | */ |
@@ -71,14 +71,11 @@ | |||
71 | 71 | ||
72 | #include <stdio.h> | 72 | #include <stdio.h> |
73 | #include <stdlib.h> | 73 | #include <stdlib.h> |
74 | #include <string.h> | ||
75 | #include <time.h> | ||
76 | 74 | ||
75 | #include <openssl/bn.h> | ||
76 | #include <openssl/crypto.h> | ||
77 | #include <openssl/ec.h> | 77 | #include <openssl/ec.h> |
78 | #include <openssl/err.h> | 78 | #include <openssl/err.h> |
79 | #include <openssl/obj_mac.h> | ||
80 | #include <openssl/objects.h> | ||
81 | #include <openssl/bn.h> | ||
82 | #include <openssl/opensslconf.h> | 79 | #include <openssl/opensslconf.h> |
83 | 80 | ||
84 | #define ABORT do { \ | 81 | #define ABORT do { \ |