• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

TLS/SSL and crypto library


コミットメタ情報

リビジョン21c856b75d81eff61aa63b4f036bb64a85bf6d46 (tree)
日時2019-09-09 16:34:44
作者Billy Brumley <bbrumley@gmai...>
コミッターMatt Caswell

ログメッセージ

[crypto/ec] for ECC parameters with NULL or zero cofactor, compute it

The cofactor argument to EC_GROUP_set_generator is optional, and SCA
mitigations for ECC currently use it. So the library currently falls
back to very old SCA-vulnerable code if the cofactor is not present.

This PR allows EC_GROUP_set_generator to compute the cofactor for all
curves of cryptographic interest. Steering scalar multiplication to more
SCA-robust code.

This issue affects persisted private keys in explicit parameter form,
where the (optional) cofactor field is zero or absent.

It also affects curves not built-in to the library, but constructed
programatically with explicit parameters, then calling
EC_GROUP_set_generator with a nonsensical value (NULL, zero).

The very old scalar multiplication code is known to be vulnerable to
local uarch attacks, outside of the OpenSSL threat model. New results
suggest the code path is also vulnerable to traditional wall clock
timing attacks.

CVE-2019-1547

Reviewed-by: Nicola Tuveri <nic.tuv@gmail.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9799)

変更サマリ

差分

--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,13 @@
99
1010 Changes between 1.0.2s and 1.0.2t [xx XXX xxxx]
1111
12+ *) Compute ECC cofactors if not provided during EC_GROUP construction. Before
13+ this change, EC_GROUP_set_generator would accept order and/or cofactor as
14+ NULL. After this change, only the cofactor parameter can be NULL. It also
15+ does some minimal sanity checks on the passed order.
16+ (CVE-2019-1547)
17+ [Billy Bob Brumley]
18+
1219 *) Document issue with installation paths in diverse Windows builds
1320
1421 '/usr/local/ssl' is an unsafe prefix for location to install OpenSSL
--- a/crypto/ec/ec.h
+++ b/crypto/ec/ec.h
@@ -1073,6 +1073,7 @@ int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
10731073 * The following lines are auto generated by the script mkerr.pl. Any changes
10741074 * made after this point may be overwritten when the script is next run.
10751075 */
1076+
10761077 void ERR_load_EC_strings(void);
10771078
10781079 /* Error codes for the EC functions. */
@@ -1270,13 +1271,14 @@ void ERR_load_EC_strings(void);
12701271 # define EC_R_SLOT_FULL 108
12711272 # define EC_R_UNDEFINED_GENERATOR 113
12721273 # define EC_R_UNDEFINED_ORDER 128
1274+# define EC_R_UNKNOWN_COFACTOR 152
12731275 # define EC_R_UNKNOWN_GROUP 129
12741276 # define EC_R_UNKNOWN_ORDER 114
12751277 # define EC_R_UNSUPPORTED_FIELD 131
12761278 # define EC_R_WRONG_CURVE_PARAMETERS 145
12771279 # define EC_R_WRONG_ORDER 130
12781280
1279-#ifdef __cplusplus
1281+# ifdef __cplusplus
12801282 }
1281-#endif
1283+# endif
12821284 #endif
--- a/crypto/ec/ec_err.c
+++ b/crypto/ec/ec_err.c
@@ -1,6 +1,6 @@
11 /* crypto/ec/ec_err.c */
22 /* ====================================================================
3- * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved.
3+ * Copyright (c) 1999-2019 The OpenSSL Project. All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
66 * modification, are permitted provided that the following conditions
@@ -310,6 +310,7 @@ static ERR_STRING_DATA EC_str_reasons[] = {
310310 {ERR_REASON(EC_R_SLOT_FULL), "slot full"},
311311 {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"},
312312 {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"},
313+ {ERR_REASON(EC_R_UNKNOWN_COFACTOR), "unknown cofactor"},
313314 {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"},
314315 {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"},
315316 {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"},
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -294,6 +294,67 @@ int EC_METHOD_get_field_type(const EC_METHOD *meth)
294294 return meth->field_type;
295295 }
296296
297+/*-
298+ * Try computing cofactor from the generator order (n) and field cardinality (q).
299+ * This works for all curves of cryptographic interest.
300+ *
301+ * Hasse thm: q + 1 - 2*sqrt(q) <= n*h <= q + 1 + 2*sqrt(q)
302+ * h_min = (q + 1 - 2*sqrt(q))/n
303+ * h_max = (q + 1 + 2*sqrt(q))/n
304+ * h_max - h_min = 4*sqrt(q)/n
305+ * So if n > 4*sqrt(q) holds, there is only one possible value for h:
306+ * h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil
307+ *
308+ * Otherwise, zero cofactor and return success.
309+ */
310+static int ec_guess_cofactor(EC_GROUP *group) {
311+ int ret = 0;
312+ BN_CTX *ctx = NULL;
313+ BIGNUM *q = NULL;
314+
315+ /*-
316+ * If the cofactor is too large, we cannot guess it.
317+ * The RHS of below is a strict overestimate of lg(4 * sqrt(q))
318+ */
319+ if (BN_num_bits(&group->order) <= (BN_num_bits(&group->field) + 1) / 2 + 3) {
320+ /* default to 0 */
321+ BN_zero(&group->cofactor);
322+ /* return success */
323+ return 1;
324+ }
325+
326+ if ((ctx = BN_CTX_new()) == NULL)
327+ return 0;
328+
329+ BN_CTX_start(ctx);
330+ if ((q = BN_CTX_get(ctx)) == NULL)
331+ goto err;
332+
333+ /* set q = 2**m for binary fields; q = p otherwise */
334+ if (group->meth->field_type == NID_X9_62_characteristic_two_field) {
335+ BN_zero(q);
336+ if (!BN_set_bit(q, BN_num_bits(&group->field) - 1))
337+ goto err;
338+ } else {
339+ if (!BN_copy(q, &group->field))
340+ goto err;
341+ }
342+
343+ /* compute h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2)/n \rfloor */
344+ if (!BN_rshift1(&group->cofactor, &group->order) /* n/2 */
345+ || !BN_add(&group->cofactor, &group->cofactor, q) /* q + n/2 */
346+ /* q + 1 + n/2 */
347+ || !BN_add(&group->cofactor, &group->cofactor, BN_value_one())
348+ /* (q + 1 + n/2)/n */
349+ || !BN_div(&group->cofactor, NULL, &group->cofactor, &group->order, ctx))
350+ goto err;
351+ ret = 1;
352+ err:
353+ BN_CTX_end(ctx);
354+ BN_CTX_free(ctx);
355+ return ret;
356+}
357+
297358 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
298359 const BIGNUM *order, const BIGNUM *cofactor)
299360 {
@@ -302,6 +363,33 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
302363 return 0;
303364 }
304365
366+ /* require group->field >= 1 */
367+ if (BN_is_zero(&group->field) || BN_is_negative(&group->field)) {
368+ ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_FIELD);
369+ return 0;
370+ }
371+
372+ /*-
373+ * - require order >= 1
374+ * - enforce upper bound due to Hasse thm: order can be no more than one bit
375+ * longer than field cardinality
376+ */
377+ if (order == NULL || BN_is_zero(order) || BN_is_negative(order)
378+ || BN_num_bits(order) > BN_num_bits(&group->field) + 1) {
379+ ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_GROUP_ORDER);
380+ return 0;
381+ }
382+
383+ /*-
384+ * Unfortunately the cofactor is an optional field in many standards.
385+ * Internally, the lib uses 0 cofactor as a marker for "unknown cofactor".
386+ * So accept cofactor == NULL or cofactor >= 0.
387+ */
388+ if (cofactor != NULL && BN_is_negative(cofactor)) {
389+ ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_UNKNOWN_COFACTOR);
390+ return 0;
391+ }
392+
305393 if (group->generator == NULL) {
306394 group->generator = EC_POINT_new(group);
307395 if (group->generator == NULL)
@@ -310,17 +398,17 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
310398 if (!EC_POINT_copy(group->generator, generator))
311399 return 0;
312400
313- if (order != NULL) {
314- if (!BN_copy(&group->order, order))
315- return 0;
316- } else
317- BN_zero(&group->order);
401+ if (!BN_copy(&group->order, order))
402+ return 0;
318403
319- if (cofactor != NULL) {
404+ /* Either take the provided positive cofactor, or try to compute it */
405+ if (cofactor != NULL && !BN_is_zero(cofactor)) {
320406 if (!BN_copy(&group->cofactor, cofactor))
321407 return 0;
322- } else
408+ } else if (!ec_guess_cofactor(group)) {
323409 BN_zero(&group->cofactor);
410+ return 0;
411+ }
324412
325413 /*-
326414 * Access to the `mont_data` field of an EC_GROUP struct should always be