Latest update.

This commit is contained in:
2020-03-03 19:16:19 +09:00
parent f85de4da03
commit b412d79e8b
310 changed files with 32765 additions and 19720 deletions
+182 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -20,6 +20,11 @@
#include "internal/refcount.h"
#include <openssl/err.h>
#include <openssl/engine.h>
#include <openssl/self_test.h>
#include "crypto/bn.h"
static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
void *cbarg);
#ifndef FIPS_MODE
EC_KEY *EC_KEY_new(void)
@@ -169,6 +174,8 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
if (src->meth->copy != NULL && src->meth->copy(dest, src) == 0)
return NULL;
dest->dirty_cnt++;
return dest;
}
@@ -209,15 +216,28 @@ int EC_KEY_generate_key(EC_KEY *eckey)
ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (eckey->meth->keygen != NULL)
return eckey->meth->keygen(eckey);
if (eckey->meth->keygen != NULL) {
int ret;
ret = eckey->meth->keygen(eckey);
if (ret == 1)
eckey->dirty_cnt++;
return ret;
}
ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
return 0;
}
int ossl_ec_key_gen(EC_KEY *eckey)
{
return eckey->group->meth->keygen(eckey);
int ret;
ret = eckey->group->meth->keygen(eckey);
if (ret == 1)
eckey->dirty_cnt++;
return ret;
}
/*
@@ -225,11 +245,14 @@ int ossl_ec_key_gen(EC_KEY *eckey)
* See SP800-56AR3 5.6.1.2.2 "Key Pair Generation by Testing Candidates"
*
* Params:
* libctx A context containing an optional self test callback.
* eckey An EC key object that contains domain params. The generated keypair
* is stored in this object.
* pairwise_test Set to non zero to perform a pairwise test. If the test
* fails then the keypair is not generated,
* Returns 1 if the keypair was generated or 0 otherwise.
*/
int ec_key_simple_generate_key(EC_KEY *eckey)
int ec_generate_key(OPENSSL_CTX *libctx, EC_KEY *eckey, int pairwise_test)
{
int ok = 0;
BIGNUM *priv_key = NULL;
@@ -287,8 +310,20 @@ int ec_key_simple_generate_key(EC_KEY *eckey)
priv_key = NULL;
pub_key = NULL;
ok = 1;
eckey->dirty_cnt++;
#ifdef FIPS_MODE
pairwise_test = 1;
#endif /* FIPS_MODE */
ok = 1;
if (pairwise_test) {
OSSL_CALLBACK *cb = NULL;
void *cbarg = NULL;
OSSL_SELF_TEST_get_callback(libctx, &cb, &cbarg);
ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg);
}
err:
/* Step (9): If there is an error return an invalid keypair. */
if (!ok) {
@@ -303,14 +338,26 @@ err:
return ok;
}
int ec_key_simple_generate_key(EC_KEY *eckey)
{
return ec_generate_key(NULL, eckey, 0);
}
int ec_key_simple_generate_public_key(EC_KEY *eckey)
{
int ret;
/*
* See SP800-56AR3 5.6.1.2.2: Step (8)
* pub_key = priv_key * G (where G is a point on the curve)
*/
return EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
NULL, NULL);
ret = EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
NULL, NULL);
if (ret == 1)
eckey->dirty_cnt++;
return ret;
}
int EC_KEY_check_key(const EC_KEY *eckey)
@@ -505,6 +552,7 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
goto err;
}
/* EC_KEY_set_public_key updates dirty_cnt */
if (!EC_KEY_set_public_key(key, point))
goto err;
@@ -532,6 +580,7 @@ int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
return 0;
EC_GROUP_free(key->group);
key->group = EC_GROUP_dup(group);
key->dirty_cnt++;
return (key->group == NULL) ? 0 : 1;
}
@@ -542,17 +591,87 @@ const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
{
int fixed_top;
const BIGNUM *order = NULL;
BIGNUM *tmp_key = NULL;
if (key->group == NULL || key->group->meth == NULL)
return 0;
/*
* Not only should key->group be set, but it should also be in a valid
* fully initialized state.
*
* Specifically, to operate in constant time, we need that the group order
* is set, as we use its length as the fixed public size of any scalar used
* as an EC private key.
*/
order = EC_GROUP_get0_order(key->group);
if (order == NULL || BN_is_zero(order))
return 0; /* This should never happen */
if (key->group->meth->set_private != NULL
&& key->group->meth->set_private(key, priv_key) == 0)
return 0;
if (key->meth->set_private != NULL
&& key->meth->set_private(key, priv_key) == 0)
return 0;
/*
* We should never leak the bit length of the secret scalar in the key,
* so we always set the `BN_FLG_CONSTTIME` flag on the internal `BIGNUM`
* holding the secret scalar.
*
* This is important also because `BN_dup()` (and `BN_copy()`) do not
* propagate the `BN_FLG_CONSTTIME` flag from the source `BIGNUM`, and
* this brings an extra risk of inadvertently losing the flag, even when
* the called specifically set it.
*
* The propagation has been turned on and off a few times in the past
* years because in some conditions has shown unintended consequences in
* some code paths, so at the moment we can't fix this in the BN layer.
*
* In `EC_KEY_set_private_key()` we can work around the propagation by
* manually setting the flag after `BN_dup()` as we know for sure that
* inside the EC module the `BN_FLG_CONSTTIME` is always treated
* correctly and should not generate unintended consequences.
*
* Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
* to preallocate the BIGNUM internal buffer to a fixed public size big
* enough that operations performed during the processing never trigger
* a realloc which would leak the size of the scalar through memory
* accesses.
*
* Fixed Length
* ------------
*
* The order of the large prime subgroup of the curve is our choice for
* a fixed public size, as that is generally the upper bound for
* generating a private key in EC cryptosystems and should fit all valid
* secret scalars.
*
* For preallocating the BIGNUM storage we look at the number of "words"
* required for the internal representation of the order, and we
* preallocate 2 extra "words" in case any of the subsequent processing
* might temporarily overflow the order length.
*/
tmp_key = BN_dup(priv_key);
if (tmp_key == NULL)
return 0;
BN_set_flags(tmp_key, BN_FLG_CONSTTIME);
fixed_top = bn_get_top(order) + 2;
if (bn_wexpand(tmp_key, fixed_top) == NULL) {
BN_clear_free(tmp_key);
return 0;
}
BN_clear_free(key->priv_key);
key->priv_key = BN_dup(priv_key);
return (key->priv_key == NULL) ? 0 : 1;
key->priv_key = tmp_key;
key->dirty_cnt++;
return 1;
}
const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
@@ -567,6 +686,7 @@ int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
return 0;
EC_POINT_free(key->pub_key);
key->pub_key = EC_POINT_dup(pub_key, key->group);
key->dirty_cnt++;
return (key->pub_key == NULL) ? 0 : 1;
}
@@ -613,11 +733,13 @@ int EC_KEY_get_flags(const EC_KEY *key)
void EC_KEY_set_flags(EC_KEY *key, int flags)
{
key->flags |= flags;
key->dirty_cnt++;
}
void EC_KEY_clear_flags(EC_KEY *key, int flags)
{
key->flags &= ~flags;
key->dirty_cnt++;
}
size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
@@ -639,6 +761,7 @@ int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
return 0;
if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0)
return 0;
key->dirty_cnt++;
/*
* Save the point conversion form.
* For non-custom curves the first octet of the buffer (excluding
@@ -689,13 +812,18 @@ size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
int EC_KEY_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
{
int ret;
if (eckey->group == NULL || eckey->group->meth == NULL)
return 0;
if (eckey->group->meth->oct2priv == NULL) {
ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return eckey->group->meth->oct2priv(eckey, buf, len);
ret = eckey->group->meth->oct2priv(eckey, buf, len);
if (ret == 1)
eckey->dirty_cnt++;
return ret;
}
int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
@@ -711,6 +839,7 @@ int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB);
return 0;
}
eckey->dirty_cnt++;
return 1;
}
@@ -742,3 +871,45 @@ int EC_KEY_can_sign(const EC_KEY *eckey)
return 0;
return 1;
}
/*
* FIPS 140-2 IG 9.9 AS09.33
* Perform a sign/verify operation.
*
* NOTE: When generating keys for key-agreement schemes - FIPS 140-2 IG 9.9
* states that no additional pairwise tests are required (apart from the tests
* specified in SP800-56A) when generating keys. Hence pairwise ECDH tests are
* omitted here.
*/
static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
void *cbarg)
{
int ret = 0;
unsigned char dgst[16] = {0};
int dgst_len = (int)sizeof(dgst);
ECDSA_SIG *sig = NULL;
OSSL_SELF_TEST *st = NULL;
st = OSSL_SELF_TEST_new(cb, cbarg);
if (st == NULL)
return 0;
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
OSSL_SELF_TEST_DESC_PCT_ECDSA);
sig = ECDSA_do_sign(dgst, dgst_len, eckey);
if (sig == NULL)
goto err;
OSSL_SELF_TEST_oncorrupt_byte(st, dgst);
if (ECDSA_do_verify(dgst, dgst_len, sig, eckey) != 1)
goto err;
ret = 1;
err:
OSSL_SELF_TEST_onend(st, ret);
OSSL_SELF_TEST_free(st);
ECDSA_SIG_free(sig);
return ret;
}