diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/ec/ec.h | 3 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_err.c | 3 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_lib.c | 118 |
3 files changed, 113 insertions, 11 deletions
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h index d0e3673675..a95d99f6a9 100644 --- a/src/lib/libcrypto/ec/ec.h +++ b/src/lib/libcrypto/ec/ec.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec.h,v 1.17 2019/09/06 17:59:25 jsing Exp $ */ | 1 | /* $OpenBSD: ec.h,v 1.18 2019/09/29 10:09:09 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 | */ |
@@ -1286,6 +1286,7 @@ void ERR_load_EC_strings(void); | |||
1286 | #define EC_R_SLOT_FULL 108 | 1286 | #define EC_R_SLOT_FULL 108 |
1287 | #define EC_R_UNDEFINED_GENERATOR 113 | 1287 | #define EC_R_UNDEFINED_GENERATOR 113 |
1288 | #define EC_R_UNDEFINED_ORDER 128 | 1288 | #define EC_R_UNDEFINED_ORDER 128 |
1289 | #define EC_R_UNKNOWN_COFACTOR 164 | ||
1289 | #define EC_R_UNKNOWN_GROUP 129 | 1290 | #define EC_R_UNKNOWN_GROUP 129 |
1290 | #define EC_R_UNKNOWN_ORDER 114 | 1291 | #define EC_R_UNKNOWN_ORDER 114 |
1291 | #define EC_R_UNSUPPORTED_FIELD 131 | 1292 | #define EC_R_UNSUPPORTED_FIELD 131 |
diff --git a/src/lib/libcrypto/ec/ec_err.c b/src/lib/libcrypto/ec/ec_err.c index 7c42618881..95c15a1110 100644 --- a/src/lib/libcrypto/ec/ec_err.c +++ b/src/lib/libcrypto/ec/ec_err.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec_err.c,v 1.11 2019/09/06 17:59:25 jsing Exp $ */ | 1 | /* $OpenBSD: ec_err.c,v 1.12 2019/09/29 10:09:09 tb Exp $ */ |
2 | /* ==================================================================== | 2 | /* ==================================================================== |
3 | * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. |
4 | * | 4 | * |
@@ -124,6 +124,7 @@ static ERR_STRING_DATA EC_str_reasons[] = | |||
124 | {ERR_REASON(EC_R_SLOT_FULL), "slot full"}, | 124 | {ERR_REASON(EC_R_SLOT_FULL), "slot full"}, |
125 | {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"}, | 125 | {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"}, |
126 | {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"}, | 126 | {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"}, |
127 | {ERR_REASON(EC_R_UNKNOWN_COFACTOR), "unknown cofactor"}, | ||
127 | {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"}, | 128 | {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"}, |
128 | {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"}, | 129 | {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"}, |
129 | {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"}, | 130 | {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"}, |
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c index e5d9620a00..df9061627e 100644 --- a/src/lib/libcrypto/ec/ec_lib.c +++ b/src/lib/libcrypto/ec/ec_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec_lib.c,v 1.31 2018/11/06 07:02:33 tb Exp $ */ | 1 | /* $OpenBSD: ec_lib.c,v 1.32 2019/09/29 10:09:09 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 | */ |
@@ -68,6 +68,7 @@ | |||
68 | #include <openssl/err.h> | 68 | #include <openssl/err.h> |
69 | #include <openssl/opensslv.h> | 69 | #include <openssl/opensslv.h> |
70 | 70 | ||
71 | #include "bn_lcl.h" | ||
71 | #include "ec_lcl.h" | 72 | #include "ec_lcl.h" |
72 | 73 | ||
73 | /* functions for EC_GROUP objects */ | 74 | /* functions for EC_GROUP objects */ |
@@ -252,6 +253,80 @@ EC_METHOD_get_field_type(const EC_METHOD *meth) | |||
252 | return meth->field_type; | 253 | return meth->field_type; |
253 | } | 254 | } |
254 | 255 | ||
256 | /* | ||
257 | * Try computing the cofactor from generator order n and field cardinality q. | ||
258 | * This works for all curves of cryptographic interest. | ||
259 | * | ||
260 | * Hasse's theorem: | h * n - (q + 1) | <= 2 * sqrt(q) | ||
261 | * | ||
262 | * So: h_min = (q + 1 - 2*sqrt(q)) / n and h_max = (q + 1 + 2*sqrt(q)) / n and | ||
263 | * therefore h_max - h_min = 4*sqrt(q) / n. So if n > 4*sqrt(q) holds, there is | ||
264 | * only one possible value for h: | ||
265 | * | ||
266 | * h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil | ||
267 | * | ||
268 | * Otherwise, zero cofactor and return success. | ||
269 | */ | ||
270 | static int | ||
271 | ec_guess_cofactor(EC_GROUP *group) | ||
272 | { | ||
273 | BN_CTX *ctx = NULL; | ||
274 | BIGNUM *q = NULL; | ||
275 | int ret = 0; | ||
276 | |||
277 | /* | ||
278 | * If the cofactor is too large, we cannot guess it and default to zero. | ||
279 | * The RHS of below is a strict overestimate of log(4 * sqrt(q)). | ||
280 | */ | ||
281 | if (BN_num_bits(&group->order) <= | ||
282 | (BN_num_bits(&group->field) + 1) / 2 + 3) { | ||
283 | BN_zero(&group->cofactor); | ||
284 | return 1; | ||
285 | } | ||
286 | |||
287 | if ((ctx = BN_CTX_new()) == NULL) | ||
288 | goto err; | ||
289 | |||
290 | BN_CTX_start(ctx); | ||
291 | if ((q = BN_CTX_get(ctx)) == NULL) | ||
292 | goto err; | ||
293 | |||
294 | /* Set q = 2**m for binary fields; q = p otherwise. */ | ||
295 | if (group->meth->field_type == NID_X9_62_characteristic_two_field) { | ||
296 | BN_zero(q); | ||
297 | if (!BN_set_bit(q, BN_num_bits(&group->field) - 1)) | ||
298 | goto err; | ||
299 | } else { | ||
300 | if (!BN_copy(q, &group->field)) | ||
301 | goto err; | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * Compute | ||
306 | * h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2) / n \rfloor. | ||
307 | */ | ||
308 | |||
309 | /* h = n/2 */ | ||
310 | if (!BN_rshift1(&group->cofactor, &group->order)) | ||
311 | goto err; | ||
312 | /* h = 1 + n/2 */ | ||
313 | if (!BN_add(&group->cofactor, &group->cofactor, BN_value_one())) | ||
314 | goto err; | ||
315 | /* h = q + 1 + n/2 */ | ||
316 | if (!BN_add(&group->cofactor, &group->cofactor, q)) | ||
317 | goto err; | ||
318 | /* h = (q + 1 + n/2) / n */ | ||
319 | if (!BN_div_ct(&group->cofactor, NULL, &group->cofactor, &group->order, | ||
320 | ctx)) | ||
321 | goto err; | ||
322 | |||
323 | ret = 1; | ||
324 | err: | ||
325 | BN_CTX_end(ctx); | ||
326 | BN_CTX_free(ctx); | ||
327 | BN_zero(&group->cofactor); | ||
328 | return ret; | ||
329 | } | ||
255 | 330 | ||
256 | int | 331 | int |
257 | EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, | 332 | EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, |
@@ -261,6 +336,33 @@ EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, | |||
261 | ECerror(ERR_R_PASSED_NULL_PARAMETER); | 336 | ECerror(ERR_R_PASSED_NULL_PARAMETER); |
262 | return 0; | 337 | return 0; |
263 | } | 338 | } |
339 | |||
340 | /* Require group->field >= 1. */ | ||
341 | if (BN_is_zero(&group->field) || BN_is_negative(&group->field)) { | ||
342 | ECerror(EC_R_INVALID_FIELD); | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | /* | ||
347 | * Require order >= 1 and enforce an upper bound of at most one bit more | ||
348 | * than the field cardinality due to Hasse's theorem. | ||
349 | */ | ||
350 | if (order == NULL || BN_is_zero(order) || BN_is_negative(order) || | ||
351 | BN_num_bits(order) > BN_num_bits(&group->field) + 1) { | ||
352 | ECerror(EC_R_INVALID_GROUP_ORDER); | ||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | /* | ||
357 | * Unfortunately, the cofactor is an optional field in many standards. | ||
358 | * Internally, the library uses a 0 cofactor as a marker for "unknown | ||
359 | * cofactor". So accept cofactor == NULL or cofactor >= 0. | ||
360 | */ | ||
361 | if (cofactor != NULL && BN_is_negative(cofactor)) { | ||
362 | ECerror(EC_R_UNKNOWN_COFACTOR); | ||
363 | return 0; | ||
364 | } | ||
365 | |||
264 | if (group->generator == NULL) { | 366 | if (group->generator == NULL) { |
265 | group->generator = EC_POINT_new(group); | 367 | group->generator = EC_POINT_new(group); |
266 | if (group->generator == NULL) | 368 | if (group->generator == NULL) |
@@ -269,17 +371,15 @@ EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, | |||
269 | if (!EC_POINT_copy(group->generator, generator)) | 371 | if (!EC_POINT_copy(group->generator, generator)) |
270 | return 0; | 372 | return 0; |
271 | 373 | ||
272 | if (order != NULL) { | 374 | if (!BN_copy(&group->order, order)) |
273 | if (!BN_copy(&group->order, order)) | 375 | return 0; |
274 | return 0; | ||
275 | } else | ||
276 | BN_zero(&group->order); | ||
277 | 376 | ||
278 | if (cofactor != NULL) { | 377 | /* Either take the provided positive cofactor, or try to compute it. */ |
378 | if (cofactor != NULL && !BN_is_zero(cofactor)) { | ||
279 | if (!BN_copy(&group->cofactor, cofactor)) | 379 | if (!BN_copy(&group->cofactor, cofactor)) |
280 | return 0; | 380 | return 0; |
281 | } else | 381 | } else if (!ec_guess_cofactor(group)) |
282 | BN_zero(&group->cofactor); | 382 | return 0; |
283 | 383 | ||
284 | return 1; | 384 | return 1; |
285 | } | 385 | } |