summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/ec/ec.h3
-rw-r--r--src/lib/libcrypto/ec/ec_err.c3
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c118
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 */
270static int
271ec_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
256int 331int
257EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, 332EC_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}