Use constant curve-specific groups whenever possible

Also remove unnecessary EC_GROUP_free calls. EC_GROUP_free is only
necessary in codepaths where arbitrary groups are possible.

Bug: 20
Change-Id: I3dfb7f07b890ab002ba8a302724d8bc671590cfe
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60932
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
chromium-stable
David Benjamin 2 years ago committed by Boringssl LUCI CQ
parent ac6793a425
commit 70be01270b
  1. 13
      crypto/ec_extra/ec_asn1.c
  2. 29
      crypto/ecdh_extra/ecdh_test.cc
  3. 1
      crypto/err/ssl.errordata
  4. 6
      crypto/evp/p_ec.c
  5. 8
      crypto/evp/p_ec_asn1.c
  6. 161
      crypto/fipsmodule/ec/ec_test.cc
  7. 13
      crypto/fipsmodule/ec/p256-nistz_test.cc
  8. 9
      crypto/fipsmodule/ecdsa/ecdsa_test.cc
  9. 11
      crypto/fipsmodule/self_check/self_check.c
  10. 18
      crypto/fipsmodule/service_indicator/service_indicator_test.cc
  11. 28
      crypto/test/wycheproof_util.cc
  12. 4
      crypto/test/wycheproof_util.h
  13. 14
      crypto/trust_token/pmbtoken.c
  14. 8
      crypto/trust_token/trust_token_test.cc
  15. 183
      crypto/trust_token/voprf.c
  16. 1
      include/openssl/ssl.h
  17. 15
      ssl/extensions.cc
  18. 26
      ssl/ssl_key_share.cc
  19. 55
      tool/speed.cc

@ -94,7 +94,6 @@ EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) {
}
// Parse the optional parameters field.
EC_GROUP *inner_group = NULL;
EC_KEY *ret = NULL;
BIGNUM *priv_key = NULL;
if (CBS_peek_asn1_tag(&ec_private_key, kParametersTag)) {
@ -107,7 +106,7 @@ EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) {
OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
goto err;
}
inner_group = EC_KEY_parse_parameters(&child);
const EC_GROUP *inner_group = EC_KEY_parse_parameters(&child);
if (inner_group == NULL) {
goto err;
}
@ -189,13 +188,11 @@ EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) {
}
BN_free(priv_key);
EC_GROUP_free(inner_group);
return ret;
err:
EC_KEY_free(ret);
BN_free(priv_key);
EC_GROUP_free(inner_group);
return NULL;
}
@ -353,8 +350,6 @@ EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs) {
for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kAllGroups); i++) {
const EC_GROUP *group = kAllGroups[i]();
if (CBS_mem_equal(&named_curve, group->oid, group->oid_len)) {
// TODO(davidben): Remove unnecessary calls to |EC_GROUP_free| within the
// library.
return (EC_GROUP *)group;
}
}
@ -433,8 +428,6 @@ err:
BN_free(b);
BN_free(x);
BN_free(y);
// TODO(davidben): Remove unnecessary calls to |EC_GROUP_free| within the
// library.
return (EC_GROUP *)ret;
}
@ -492,18 +485,16 @@ EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, long len) {
CBS cbs;
CBS_init(&cbs, *inp, (size_t)len);
EC_GROUP *group = EC_KEY_parse_parameters(&cbs);
const EC_GROUP *group = EC_KEY_parse_parameters(&cbs);
if (group == NULL) {
return NULL;
}
EC_KEY *ret = EC_KEY_new();
if (ret == NULL || !EC_KEY_set_group(ret, group)) {
EC_GROUP_free(group);
EC_KEY_free(ret);
return NULL;
}
EC_GROUP_free(group);
if (out_key != NULL) {
EC_KEY_free(*out_key);

@ -35,24 +35,23 @@
#include "../test/wycheproof_util.h"
static bssl::UniquePtr<EC_GROUP> GetCurve(FileTest *t, const char *key) {
static const EC_GROUP *GetCurve(FileTest *t, const char *key) {
std::string curve_name;
if (!t->GetAttribute(&curve_name, key)) {
return nullptr;
}
if (curve_name == "P-224") {
return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp224r1));
return EC_group_p224();
}
if (curve_name == "P-256") {
return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(
NID_X9_62_prime256v1));
return EC_group_p256();
}
if (curve_name == "P-384") {
return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp384r1));
return EC_group_p384();
}
if (curve_name == "P-521") {
return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp521r1));
return EC_group_p521();
}
t->PrintLine("Unknown curve '%s'", curve_name.c_str());
@ -70,7 +69,7 @@ static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *key) {
TEST(ECDHTest, TestVectors) {
FileTestGTest("crypto/ecdh_extra/ecdh_tests.txt", [](FileTest *t) {
bssl::UniquePtr<EC_GROUP> group = GetCurve(t, "Curve");
const EC_GROUP *group = GetCurve(t, "Curve");
ASSERT_TRUE(group);
bssl::UniquePtr<BIGNUM> priv_key = GetBIGNUM(t, "Private");
ASSERT_TRUE(priv_key);
@ -87,16 +86,16 @@ TEST(ECDHTest, TestVectors) {
bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
ASSERT_TRUE(key);
bssl::UniquePtr<EC_POINT> pub_key(EC_POINT_new(group.get()));
bssl::UniquePtr<EC_POINT> pub_key(EC_POINT_new(group));
ASSERT_TRUE(pub_key);
bssl::UniquePtr<EC_POINT> peer_pub_key(EC_POINT_new(group.get()));
bssl::UniquePtr<EC_POINT> peer_pub_key(EC_POINT_new(group));
ASSERT_TRUE(peer_pub_key);
ASSERT_TRUE(EC_KEY_set_group(key.get(), group.get()));
ASSERT_TRUE(EC_KEY_set_group(key.get(), group));
ASSERT_TRUE(EC_KEY_set_private_key(key.get(), priv_key.get()));
ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(group.get(), pub_key.get(),
ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(group, pub_key.get(),
x.get(), y.get(), nullptr));
ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(
group.get(), peer_pub_key.get(), peer_x.get(), peer_y.get(), nullptr));
group, peer_pub_key.get(), peer_x.get(), peer_y.get(), nullptr));
ASSERT_TRUE(EC_KEY_set_public_key(key.get(), pub_key.get()));
ASSERT_TRUE(EC_KEY_check_key(key.get()));
@ -130,7 +129,7 @@ TEST(ECDHTest, TestVectors) {
static void RunWycheproofTest(FileTest *t) {
t->IgnoreInstruction("encoding");
bssl::UniquePtr<EC_GROUP> group = GetWycheproofCurve(t, "curve", true);
const EC_GROUP *group = GetWycheproofCurve(t, "curve", true);
ASSERT_TRUE(group);
bssl::UniquePtr<BIGNUM> priv_key = GetWycheproofBIGNUM(t, "private", false);
ASSERT_TRUE(priv_key);
@ -157,10 +156,10 @@ static void RunWycheproofTest(FileTest *t) {
bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
ASSERT_TRUE(key);
ASSERT_TRUE(EC_KEY_set_group(key.get(), group.get()));
ASSERT_TRUE(EC_KEY_set_group(key.get(), group));
ASSERT_TRUE(EC_KEY_set_private_key(key.get(), priv_key.get()));
std::vector<uint8_t> actual((EC_GROUP_get_degree(group.get()) + 7) / 8);
std::vector<uint8_t> actual((EC_GROUP_get_degree(group) + 7) / 8);
int ret =
ECDH_compute_key(actual.data(), actual.size(),
EC_KEY_get0_public_key(peer_ec), key.get(), nullptr);

@ -121,7 +121,6 @@ SSL,253,NO_COMMON_SIGNATURE_ALGORITHMS
SSL,178,NO_COMPRESSION_SPECIFIED
SSL,265,NO_GROUPS_SPECIFIED
SSL,179,NO_METHOD_SPECIFIED
SSL,180,NO_P256_SUPPORT
SSL,181,NO_PRIVATE_KEY_ASSIGNED
SSL,182,NO_RENEGOTIATION
SSL,183,NO_REQUIRED_DIGEST

@ -75,7 +75,7 @@
typedef struct {
// message digest
const EVP_MD *md;
EC_GROUP *gen_group;
const EC_GROUP *gen_group;
} EC_PKEY_CTX;
@ -111,7 +111,6 @@ static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) {
return;
}
EC_GROUP_free(dctx->gen_group);
OPENSSL_free(dctx);
}
@ -195,11 +194,10 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
return 1;
case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: {
EC_GROUP *group = EC_GROUP_new_by_curve_name(p1);
const EC_GROUP *group = EC_GROUP_new_by_curve_name(p1);
if (group == NULL) {
return 0;
}
EC_GROUP_free(dctx->gen_group);
dctx->gen_group = group;
return 1;
}

@ -94,7 +94,7 @@ static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
// The parameters are a named curve.
EC_KEY *eckey = NULL;
EC_GROUP *group = EC_KEY_parse_curve_name(params);
const EC_GROUP *group = EC_KEY_parse_curve_name(params);
if (group == NULL || CBS_len(params) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto err;
@ -107,12 +107,10 @@ static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
goto err;
}
EC_GROUP_free(group);
EVP_PKEY_assign_EC_KEY(out, eckey);
return 1;
err:
EC_GROUP_free(group);
EC_KEY_free(eckey);
return 0;
}
@ -135,15 +133,13 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
static int eckey_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
// See RFC 5915.
EC_GROUP *group = EC_KEY_parse_parameters(params);
const EC_GROUP *group = EC_KEY_parse_parameters(params);
if (group == NULL || CBS_len(params) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
EC_GROUP_free(group);
return 0;
}
EC_KEY *ec_key = EC_KEY_parse_private_key(key, group);
EC_GROUP_free(group);
if (ec_key == NULL || CBS_len(key) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
EC_KEY_free(ec_key);

@ -430,11 +430,8 @@ TEST(ECTest, SetKeyWithoutGroup) {
EXPECT_FALSE(EC_KEY_set_private_key(key.get(), BN_value_one()));
// Public keys may not be configured without a group.
bssl::UniquePtr<EC_GROUP> group(
EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
ASSERT_TRUE(group);
EXPECT_FALSE(
EC_KEY_set_public_key(key.get(), EC_GROUP_get0_generator(group.get())));
EXPECT_FALSE(EC_KEY_set_public_key(key.get(),
EC_GROUP_get0_generator(EC_group_p256())));
}
TEST(ECTest, SetNULLKey) {
@ -454,16 +451,13 @@ TEST(ECTest, SetNULLKey) {
TEST(ECTest, GroupMismatch) {
bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_secp384r1));
ASSERT_TRUE(key);
bssl::UniquePtr<EC_GROUP> p256(
EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
ASSERT_TRUE(p256);
// Changing a key's group is invalid.
EXPECT_FALSE(EC_KEY_set_group(key.get(), p256.get()));
EXPECT_FALSE(EC_KEY_set_group(key.get(), EC_group_p256()));
// Configuring a public key with the wrong group is invalid.
EXPECT_FALSE(
EC_KEY_set_public_key(key.get(), EC_GROUP_get0_generator(p256.get())));
EXPECT_FALSE(EC_KEY_set_public_key(key.get(),
EC_GROUP_get0_generator(EC_group_p256())));
}
TEST(ECTest, EmptyKey) {
@ -531,15 +525,15 @@ TEST(ECTest, BrainpoolP256r1) {
class ECCurveTest : public testing::TestWithParam<int> {
public:
const EC_GROUP *group() const { return group_.get(); }
const EC_GROUP *group() const { return group_; }
void SetUp() override {
group_.reset(EC_GROUP_new_by_curve_name(GetParam()));
group_ = EC_GROUP_new_by_curve_name(GetParam());
ASSERT_TRUE(group_);
}
private:
bssl::UniquePtr<EC_GROUP> group_;
const EC_GROUP *group_;
};
TEST_P(ECCurveTest, SetAffine) {
@ -995,24 +989,23 @@ static std::string CurveToString(const testing::TestParamInfo<int> &params) {
INSTANTIATE_TEST_SUITE_P(All, ECCurveTest, testing::ValuesIn(AllCurves()),
CurveToString);
static bssl::UniquePtr<EC_GROUP> GetCurve(FileTest *t, const char *key) {
static const EC_GROUP *GetCurve(FileTest *t, const char *key) {
std::string curve_name;
if (!t->GetAttribute(&curve_name, key)) {
return nullptr;
}
if (curve_name == "P-224") {
return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp224r1));
return EC_group_p224();
}
if (curve_name == "P-256") {
return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(
NID_X9_62_prime256v1));
return EC_group_p256();
}
if (curve_name == "P-384") {
return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp384r1));
return EC_group_p384();
}
if (curve_name == "P-521") {
return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp521r1));
return EC_group_p521();
}
t->PrintLine("Unknown curve '%s'", curve_name.c_str());
@ -1035,7 +1028,7 @@ TEST(ECTest, ScalarBaseMultVectors) {
FileTestGTest("crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt",
[&](FileTest *t) {
bssl::UniquePtr<EC_GROUP> group = GetCurve(t, "Curve");
const EC_GROUP *group = GetCurve(t, "Curve");
ASSERT_TRUE(group);
bssl::UniquePtr<BIGNUM> n = GetBIGNUM(t, "N");
ASSERT_TRUE(n);
@ -1051,25 +1044,24 @@ TEST(ECTest, ScalarBaseMultVectors) {
ASSERT_TRUE(py);
auto check_point = [&](const EC_POINT *p) {
if (is_infinity) {
EXPECT_TRUE(EC_POINT_is_at_infinity(group.get(), p));
EXPECT_TRUE(EC_POINT_is_at_infinity(group, p));
} else {
ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
group.get(), p, px.get(), py.get(), ctx.get()));
group, p, px.get(), py.get(), ctx.get()));
EXPECT_EQ(0, BN_cmp(x.get(), px.get()));
EXPECT_EQ(0, BN_cmp(y.get(), py.get()));
}
};
const EC_POINT *g = EC_GROUP_get0_generator(group.get());
bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group.get()));
const EC_POINT *g = EC_GROUP_get0_generator(group);
bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group));
ASSERT_TRUE(p);
// Test single-point multiplication.
ASSERT_TRUE(EC_POINT_mul(group.get(), p.get(), n.get(), nullptr, nullptr,
ASSERT_TRUE(EC_POINT_mul(group, p.get(), n.get(), nullptr, nullptr,
ctx.get()));
check_point(p.get());
ASSERT_TRUE(
EC_POINT_mul(group.get(), p.get(), nullptr, g, n.get(), ctx.get()));
ASSERT_TRUE(EC_POINT_mul(group, p.get(), nullptr, g, n.get(), ctx.get()));
check_point(p.get());
});
}
@ -1082,7 +1074,7 @@ TEST(ECTest, DISABLED_ScalarBaseMultVectorsTwoPoint) {
FileTestGTest("crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt",
[&](FileTest *t) {
bssl::UniquePtr<EC_GROUP> group = GetCurve(t, "Curve");
const EC_GROUP *group = GetCurve(t, "Curve");
ASSERT_TRUE(group);
bssl::UniquePtr<BIGNUM> n = GetBIGNUM(t, "N");
ASSERT_TRUE(n);
@ -1098,41 +1090,40 @@ TEST(ECTest, DISABLED_ScalarBaseMultVectorsTwoPoint) {
ASSERT_TRUE(py);
auto check_point = [&](const EC_POINT *p) {
if (is_infinity) {
EXPECT_TRUE(EC_POINT_is_at_infinity(group.get(), p));
EXPECT_TRUE(EC_POINT_is_at_infinity(group, p));
} else {
ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
group.get(), p, px.get(), py.get(), ctx.get()));
group, p, px.get(), py.get(), ctx.get()));
EXPECT_EQ(0, BN_cmp(x.get(), px.get()));
EXPECT_EQ(0, BN_cmp(y.get(), py.get()));
}
};
const EC_POINT *g = EC_GROUP_get0_generator(group.get());
bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group.get()));
const EC_POINT *g = EC_GROUP_get0_generator(group);
bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group));
ASSERT_TRUE(p);
bssl::UniquePtr<BIGNUM> a(BN_new()), b(BN_new());
for (int i = -64; i < 64; i++) {
SCOPED_TRACE(i);
ASSERT_TRUE(BN_set_word(a.get(), abs(i)));
if (i < 0) {
ASSERT_TRUE(BN_sub(a.get(), EC_GROUP_get0_order(group.get()), a.get()));
ASSERT_TRUE(BN_sub(a.get(), EC_GROUP_get0_order(group), a.get()));
}
ASSERT_TRUE(BN_copy(b.get(), n.get()));
ASSERT_TRUE(BN_sub(b.get(), b.get(), a.get()));
if (BN_is_negative(b.get())) {
ASSERT_TRUE(BN_add(b.get(), b.get(), EC_GROUP_get0_order(group.get())));
ASSERT_TRUE(BN_add(b.get(), b.get(), EC_GROUP_get0_order(group)));
}
ASSERT_TRUE(
EC_POINT_mul(group.get(), p.get(), a.get(), g, b.get(), ctx.get()));
ASSERT_TRUE(EC_POINT_mul(group, p.get(), a.get(), g, b.get(), ctx.get()));
check_point(p.get());
EC_SCALAR a_scalar, b_scalar;
ASSERT_TRUE(ec_bignum_to_scalar(group.get(), &a_scalar, a.get()));
ASSERT_TRUE(ec_bignum_to_scalar(group.get(), &b_scalar, b.get()));
ASSERT_TRUE(ec_point_mul_scalar_public(group.get(), &p->raw, &a_scalar,
&g->raw, &b_scalar));
ASSERT_TRUE(ec_bignum_to_scalar(group, &a_scalar, a.get()));
ASSERT_TRUE(ec_bignum_to_scalar(group, &b_scalar, b.get()));
ASSERT_TRUE(ec_point_mul_scalar_public(group, &p->raw, &a_scalar, &g->raw,
&b_scalar));
check_point(p.get());
}
});
@ -1148,31 +1139,31 @@ static std::vector<uint8_t> HexToBytes(const char *str) {
TEST(ECTest, DeriveFromSecret) {
struct DeriveTest {
int curve;
const EC_GROUP *group;
std::vector<uint8_t> secret;
std::vector<uint8_t> expected_priv;
std::vector<uint8_t> expected_pub;
};
const DeriveTest kDeriveTests[] = {
{NID_X9_62_prime256v1, HexToBytes(""),
{EC_group_p256(), HexToBytes(""),
HexToBytes(
"b98a86a71efb51ebdac4759937b977e9b0c05224675bb2b6a58ba306e237f4b8"),
HexToBytes(
"04fbe6cab439918e00231a2ff073cdc25823998864a9eb36f809095a1a919ece875"
"a145803fbe89a6cde53936e3c6d9c253ed3d38f5f58cae455c27e95645ceda9")},
{NID_X9_62_prime256v1, HexToBytes("123456"),
{EC_group_p256(), HexToBytes("123456"),
HexToBytes(
"44a72bc62087b88e5ab7126766177ed0d8f1ed09ad066cd746527fc201105a7e"),
HexToBytes(
"04ec0555cd76e991fef7f5504343937d0f38696db3360a4854052cb0d84a377a5a0"
"ff64c352755c28692b4ae085c2b817db9a1eddbd22e9cf39c12751e0870791b")},
{NID_X9_62_prime256v1, HexToBytes("00000000000000000000000000000000"),
{EC_group_p256(), HexToBytes("00000000000000000000000000000000"),
HexToBytes(
"7ca1e2c83e6a5f2c1b3e7d58180226f269930c4b9fbe2a275096079630b7c57d"),
HexToBytes(
"0442ef70c8fc0fbe383ed0a0da36f39f9a590f3feebc07863cc858c9a8ef0465731"
"0408c249bd4d61929c54b71ffe056e6b4fa1eb537039b43d1c175f0ceab0f89")},
{NID_X9_62_prime256v1,
{EC_group_p256(),
HexToBytes(
"de9c9b35543aaa0fba039e34e8ca9695da3225c7161c9e3a8c70356cac28c780"),
HexToBytes(
@ -1180,7 +1171,7 @@ TEST(ECTest, DeriveFromSecret) {
HexToBytes(
"046741f806b593bf3a3d4a9d76bdcb9b0d7874633cbea8f42c05e78561f7e8ec362"
"b9b6f1913ded796fbdafe7f210cea897ac22a4e580c06a60f2659fd09f1830f")},
{NID_secp384r1, HexToBytes("123456"),
{EC_group_p384(), HexToBytes("123456"),
HexToBytes("95cd90d548997de090c7622708eccb7edc1b1bd78d2422235ad97406dada"
"076555309da200096f6e4b36c46002beee89"),
HexToBytes(
@ -1191,13 +1182,12 @@ TEST(ECTest, DeriveFromSecret) {
for (const auto &test : kDeriveTests) {
SCOPED_TRACE(Bytes(test.secret));
bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(test.curve));
ASSERT_TRUE(group);
bssl::UniquePtr<EC_KEY> key(EC_KEY_derive_from_secret(
group.get(), test.secret.data(), test.secret.size()));
test.group, test.secret.data(), test.secret.size()));
ASSERT_TRUE(key);
std::vector<uint8_t> priv(BN_num_bytes(EC_GROUP_get0_order(group.get())));
std::vector<uint8_t> priv(BN_num_bytes(EC_GROUP_get0_order(test.group)));
ASSERT_TRUE(BN_bn2bin_padded(priv.data(), priv.size(),
EC_KEY_get0_private_key(key.get())));
EXPECT_EQ(Bytes(priv), Bytes(test.expected_priv));
@ -1226,33 +1216,33 @@ TEST(ECTest, HashToCurve) {
int (*hash_to_curve)(const EC_GROUP *group, EC_POINT *out,
const uint8_t *dst, size_t dst_len, const uint8_t *msg,
size_t msg_len);
int curve_nid;
const EC_GROUP *group;
const char *dst;
const char *msg;
const char *x_hex;
const char *y_hex;
};
static const HashToCurveTest kTests[] = {
const HashToCurveTest kTests[] = {
// See draft-irtf-cfrg-hash-to-curve-16, appendix J.1.1.
{&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1,
{&EC_hash_to_curve_p256_xmd_sha256_sswu, EC_group_p256(),
"QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", "",
"2c15230b26dbc6fc9a37051158c95b79656e17a1a920b11394ca91"
"c44247d3e4",
"8a7a74985cc5c776cdfe4b1f19884970453912e9d31528c060be9a"
"b5c43e8415"},
{&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1,
{&EC_hash_to_curve_p256_xmd_sha256_sswu, EC_group_p256(),
"QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", "abc",
"0bb8b87485551aa43ed54f009230450b492fead5f1cc91658775da"
"c4a3388a0f",
"5c41b3d0731a27a7b14bc0bf0ccded2d8751f83493404c84a88e71"
"ffd424212e"},
{&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1,
{&EC_hash_to_curve_p256_xmd_sha256_sswu, EC_group_p256(),
"QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", "abcdef0123456789",
"65038ac8f2b1def042a5df0b33b1f4eca6bff7cb0f9c6c15268118"
"64e544ed80",
"cad44d40a656e7aff4002a8de287abc8ae0482b5ae825822bb870d"
"6df9b56ca3"},
{&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1,
{&EC_hash_to_curve_p256_xmd_sha256_sswu, EC_group_p256(),
"QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_",
"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
"qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
@ -1261,7 +1251,7 @@ TEST(ECTest, HashToCurve) {
"3dc65a0b5d",
"98f8df449a072c4721d241a3b1236d3caccba603f916ca680f4539"
"d2bfb3c29e"},
{&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1,
{&EC_hash_to_curve_p256_xmd_sha256_sswu, EC_group_p256(),
"QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_",
"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@ -1279,25 +1269,25 @@ TEST(ECTest, HashToCurve) {
"2b0f4757dc"},
// See draft-irtf-cfrg-hash-to-curve-07, appendix G.2.1.
{hash_to_curve_p384_sha512_draft07, NID_secp384r1,
{hash_to_curve_p384_sha512_draft07, EC_group_p384(),
"P384_XMD:SHA-512_SSWU_RO_TESTGEN", "",
"2fc0b9efdd63a8e43b4db88dc12f03c798f6fd91bccac0c9096185"
"4386e58fdc54fc2a01f0f358759054ce1f9b762025",
"949b936fabb72cdb02cd7980b86cb6a3adf286658e81301648851d"
"b8a49d9bec00ccb57698d559fc5960fa5030a8e54b"},
{hash_to_curve_p384_sha512_draft07, NID_secp384r1,
{hash_to_curve_p384_sha512_draft07, EC_group_p384(),
"P384_XMD:SHA-512_SSWU_RO_TESTGEN", "abc",
"4f3338035391e8ce8ce40c974136f0edc97f392ffd44a643338741"
"8ed1b8c2603487e1688ec151f048fbc6b2c138c92f",
"152b90aef6558be328a3168855fb1906452e7167b0f7c8a56ff9d4"
"fa87d6fb522cdf8e409db54418b2c764fd26260757"},
{hash_to_curve_p384_sha512_draft07, NID_secp384r1,
{hash_to_curve_p384_sha512_draft07, EC_group_p384(),
"P384_XMD:SHA-512_SSWU_RO_TESTGEN", "abcdef0123456789",
"e9e5d7ac397e123d060ad44301cbc8eb972f6e64ebcff29dcc9b9a"
"10357902aace2240c580fec85e5b427d98b4e80703",
"916cb8963521ad75105be43cc4148e5a5bbb4fcf107f1577e4f7fa"
"3ca58cd786aa76890c8e687d2353393bc16c78ec4d"},
{hash_to_curve_p384_sha512_draft07, NID_secp384r1,
{hash_to_curve_p384_sha512_draft07, EC_group_p384(),
"P384_XMD:SHA-512_SSWU_RO_TESTGEN",
"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@ -1319,17 +1309,15 @@ TEST(ECTest, HashToCurve) {
SCOPED_TRACE(test.dst);
SCOPED_TRACE(test.msg);
bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(test.curve_nid));
ASSERT_TRUE(group);
bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group.get()));
bssl::UniquePtr<EC_POINT> p(EC_POINT_new(test.group));
ASSERT_TRUE(p);
ASSERT_TRUE(test.hash_to_curve(
group.get(), p.get(), reinterpret_cast<const uint8_t *>(test.dst),
test.group, p.get(), reinterpret_cast<const uint8_t *>(test.dst),
strlen(test.dst), reinterpret_cast<const uint8_t *>(test.msg),
strlen(test.msg)));
std::vector<uint8_t> buf;
ASSERT_TRUE(EncodeECPoint(&buf, group.get(), p.get(),
ASSERT_TRUE(EncodeECPoint(&buf, test.group, p.get(),
POINT_CONVERSION_UNCOMPRESSED));
size_t field_len = (buf.size() - 1) / 2;
EXPECT_EQ(test.x_hex,
@ -1339,32 +1327,28 @@ TEST(ECTest, HashToCurve) {
}
// hash-to-curve functions should check for the wrong group.
bssl::UniquePtr<EC_GROUP> p224(EC_GROUP_new_by_curve_name(NID_secp224r1));
ASSERT_TRUE(p224);
bssl::UniquePtr<EC_GROUP> p384(EC_GROUP_new_by_curve_name(NID_secp384r1));
ASSERT_TRUE(p384);
EC_JACOBIAN raw;
bssl::UniquePtr<EC_POINT> p_p384(EC_POINT_new(p384.get()));
bssl::UniquePtr<EC_POINT> p_p384(EC_POINT_new(EC_group_p384()));
ASSERT_TRUE(p_p384);
bssl::UniquePtr<EC_POINT> p_p224(EC_POINT_new(p224.get()));
bssl::UniquePtr<EC_POINT> p_p224(EC_POINT_new(EC_group_p224()));
ASSERT_TRUE(p_p224);
static const uint8_t kDST[] = {0, 1, 2, 3};
static const uint8_t kMessage[] = {4, 5, 6, 7};
EXPECT_FALSE(ec_hash_to_curve_p384_xmd_sha384_sswu(
p224.get(), &raw, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
EC_group_p224(), &raw, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
EXPECT_FALSE(EC_hash_to_curve_p384_xmd_sha384_sswu(
p224.get(), p_p224.get(), kDST, sizeof(kDST), kMessage,
EC_group_p224(), p_p224.get(), kDST, sizeof(kDST), kMessage,
sizeof(kMessage)));
EXPECT_FALSE(EC_hash_to_curve_p384_xmd_sha384_sswu(
p224.get(), p_p384.get(), kDST, sizeof(kDST), kMessage,
EC_group_p224(), p_p384.get(), kDST, sizeof(kDST), kMessage,
sizeof(kMessage)));
EXPECT_FALSE(EC_hash_to_curve_p384_xmd_sha384_sswu(
p384.get(), p_p224.get(), kDST, sizeof(kDST), kMessage,
EC_group_p384(), p_p224.get(), kDST, sizeof(kDST), kMessage,
sizeof(kMessage)));
// Zero-length DSTs are not allowed.
EXPECT_FALSE(ec_hash_to_curve_p384_xmd_sha384_sswu(
p384.get(), &raw, nullptr, 0, kMessage, sizeof(kMessage)));
EC_group_p384(), &raw, nullptr, 0, kMessage, sizeof(kMessage)));
}
TEST(ECTest, HashToScalar) {
@ -1372,21 +1356,21 @@ TEST(ECTest, HashToScalar) {
int (*hash_to_scalar)(const EC_GROUP *group, EC_SCALAR *out,
const uint8_t *dst, size_t dst_len,
const uint8_t *msg, size_t msg_len);
int curve_nid;
const EC_GROUP *group;
const char *dst;
const char *msg;
const char *result_hex;
};
static const HashToScalarTest kTests[] = {
{&ec_hash_to_scalar_p384_xmd_sha512_draft07, NID_secp384r1,
const HashToScalarTest kTests[] = {
{&ec_hash_to_scalar_p384_xmd_sha512_draft07, EC_group_p384(),
"P384_XMD:SHA-512_SCALAR_TEST", "",
"9687acc2de56c3cf94c0e05b6811a21aa480092254ec0532bdce63"
"140ecd340f09dc2d45d77e21fb0aa76f7707b8a676"},
{&ec_hash_to_scalar_p384_xmd_sha512_draft07, NID_secp384r1,
{&ec_hash_to_scalar_p384_xmd_sha512_draft07, EC_group_p384(),
"P384_XMD:SHA-512_SCALAR_TEST", "abcdef0123456789",
"8f8076022a68233cbcecaceae68c2068f132724f001caa78619eff"
"1ffc58fa871db73fe9034fc9cf853c384ed34b5666"},
{&ec_hash_to_scalar_p384_xmd_sha512_draft07, NID_secp384r1,
{&ec_hash_to_scalar_p384_xmd_sha512_draft07, EC_group_p384(),
"P384_XMD:SHA-512_SCALAR_TEST",
"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@ -1406,25 +1390,22 @@ TEST(ECTest, HashToScalar) {
SCOPED_TRACE(test.dst);
SCOPED_TRACE(test.msg);
bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(test.curve_nid));
ASSERT_TRUE(group);
EC_SCALAR scalar;
ASSERT_TRUE(test.hash_to_scalar(
group.get(), &scalar, reinterpret_cast<const uint8_t *>(test.dst),
test.group, &scalar, reinterpret_cast<const uint8_t *>(test.dst),
strlen(test.dst), reinterpret_cast<const uint8_t *>(test.msg),
strlen(test.msg)));
uint8_t buf[EC_MAX_BYTES];
size_t len;
ec_scalar_to_bytes(group.get(), buf, &len, &scalar);
ec_scalar_to_bytes(test.group, buf, &len, &scalar);
EXPECT_EQ(test.result_hex, EncodeHex(bssl::MakeConstSpan(buf, len)));
}
// hash-to-scalar functions should check for the wrong group.
bssl::UniquePtr<EC_GROUP> p224(EC_GROUP_new_by_curve_name(NID_secp224r1));
ASSERT_TRUE(p224);
EC_SCALAR scalar;
static const uint8_t kDST[] = {0, 1, 2, 3};
static const uint8_t kMessage[] = {4, 5, 6, 7};
EXPECT_FALSE(ec_hash_to_scalar_p384_xmd_sha512_draft07(
p224.get(), &scalar, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
EC_group_p224(), &scalar, kDST, sizeof(kDST), kMessage,
sizeof(kMessage)));
}

@ -109,13 +109,10 @@ TEST(P256_NistzTest, BEEU) {
}
#endif
bssl::UniquePtr<EC_GROUP> group(
EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
ASSERT_TRUE(group);
const EC_GROUP *group = EC_group_p256();
BN_ULONG order_words[P256_LIMBS];
ASSERT_TRUE(
bn_copy_words(order_words, P256_LIMBS, EC_GROUP_get0_order(group.get())));
bn_copy_words(order_words, P256_LIMBS, EC_GROUP_get0_order(group)));
BN_ULONG in[P256_LIMBS], out[P256_LIMBS];
EC_SCALAR in_scalar, out_scalar, result;
@ -154,9 +151,9 @@ TEST(P256_NistzTest, BEEU) {
// Calculate out*in and confirm that it equals one, modulo the order.
OPENSSL_memcpy(in_scalar.words, in, sizeof(in));
OPENSSL_memcpy(out_scalar.words, out, sizeof(out));
ec_scalar_to_montgomery(group.get(), &in_scalar, &in_scalar);
ec_scalar_to_montgomery(group.get(), &out_scalar, &out_scalar);
ec_scalar_mul_montgomery(group.get(), &result, &in_scalar, &out_scalar);
ec_scalar_to_montgomery(group, &in_scalar, &in_scalar);
ec_scalar_to_montgomery(group, &out_scalar, &out_scalar);
ec_scalar_mul_montgomery(group, &result, &in_scalar, &out_scalar);
EXPECT_EQ(0, OPENSSL_memcmp(kOneMont, &result, sizeof(kOneMont)));

@ -319,17 +319,16 @@ static bssl::UniquePtr<EC_GROUP> GetCurve(FileTest *t, const char *key) {
}
if (curve_name == "P-224") {
return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp224r1));
return bssl::UniquePtr<EC_GROUP>(const_cast<EC_GROUP *>(EC_group_p224()));
}
if (curve_name == "P-256") {
return bssl::UniquePtr<EC_GROUP>(
EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
return bssl::UniquePtr<EC_GROUP>(const_cast<EC_GROUP *>(EC_group_p256()));
}
if (curve_name == "P-384") {
return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp384r1));
return bssl::UniquePtr<EC_GROUP>(const_cast<EC_GROUP *>(EC_group_p384()));
}
if (curve_name == "P-521") {
return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp521r1));
return bssl::UniquePtr<EC_GROUP>(const_cast<EC_GROUP *>(EC_group_p521()));
}
if (curve_name == "secp160r1") {
return NewSecp160r1Group();

@ -249,11 +249,12 @@ static EC_KEY *self_test_ecdsa_key(void) {
0x93, 0x8b, 0x74, 0xf2, 0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77,
};
EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
EC_KEY *ec_key = EC_KEY_new();
BIGNUM *qx = BN_bin2bn(kQx, sizeof(kQx), NULL);
BIGNUM *qy = BN_bin2bn(kQy, sizeof(kQy), NULL);
BIGNUM *d = BN_bin2bn(kD, sizeof(kD), NULL);
if (ec_key == NULL || qx == NULL || qy == NULL || d == NULL ||
!EC_KEY_set_group(ec_key, EC_group_p256()) ||
!EC_KEY_set_public_key_affine_coordinates(ec_key, qx, qy) ||
!EC_KEY_set_private_key(ec_key, d)) {
EC_KEY_free(ec_key);
@ -411,7 +412,6 @@ err:
static int boringssl_self_test_ecc(void) {
int ret = 0;
EC_KEY *ec_key = NULL;
EC_GROUP *ec_group = NULL;
EC_POINT *ec_point_in = NULL;
EC_POINT *ec_point_out = NULL;
BIGNUM *ec_scalar = NULL;
@ -506,11 +506,7 @@ static int boringssl_self_test_ecc(void) {
0x7c, 0x41, 0x8f, 0xaf, 0x9c, 0x40, 0xaf, 0x2e, 0x4a, 0x0c,
};
ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
if (ec_group == NULL) {
fprintf(stderr, "Failed to create P-256 group.\n");
goto err;
}
const EC_GROUP *ec_group = EC_group_p256();
ec_point_in = EC_POINT_new(ec_group);
ec_point_out = EC_POINT_new(ec_group);
ec_scalar = BN_new();
@ -535,7 +531,6 @@ err:
EC_KEY_free(ec_key);
EC_POINT_free(ec_point_in);
EC_POINT_free(ec_point_out);
EC_GROUP_free(ec_group);
BN_free(ec_scalar);
ECDSA_SIG_free(sig);

@ -1497,12 +1497,12 @@ TEST_P(ECDSAServiceIndicatorTest, ECDSASigGen) {
FIPSStatus approved = FIPSStatus::NOT_APPROVED;
bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(test.nid));
const EC_GROUP *group = EC_GROUP_new_by_curve_name(test.nid);
bssl::UniquePtr<EC_KEY> eckey(EC_KEY_new());
bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
bssl::ScopedEVP_MD_CTX md_ctx;
ASSERT_TRUE(eckey);
ASSERT_TRUE(EC_KEY_set_group(eckey.get(), group.get()));
ASSERT_TRUE(EC_KEY_set_group(eckey.get(), group));
// Generate a generic EC key.
ASSERT_TRUE(EC_KEY_generate_key(eckey.get()));
@ -1557,12 +1557,12 @@ TEST_P(ECDSAServiceIndicatorTest, ECDSASigVer) {
FIPSStatus approved = FIPSStatus::NOT_APPROVED;
bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(test.nid));
const EC_GROUP *group = EC_GROUP_new_by_curve_name(test.nid);
bssl::UniquePtr<EC_KEY> eckey(EC_KEY_new());
bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
bssl::ScopedEVP_MD_CTX md_ctx;
ASSERT_TRUE(eckey);
ASSERT_TRUE(EC_KEY_set_group(eckey.get(), group.get()));
ASSERT_TRUE(EC_KEY_set_group(eckey.get(), group));
// Generate ECDSA signatures for ECDSA verification.
ASSERT_TRUE(EC_KEY_generate_key(eckey.get()));
@ -1623,12 +1623,12 @@ TEST_P(ECDSAServiceIndicatorTest, ManualECDSASignVerify) {
ASSERT_TRUE(EVP_DigestInit(ctx.get(), test.func()));
ASSERT_TRUE(EVP_DigestUpdate(ctx.get(), kPlaintext, sizeof(kPlaintext)));
bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(test.nid));
const EC_GROUP *group = EC_GROUP_new_by_curve_name(test.nid);
bssl::UniquePtr<EC_KEY> eckey(EC_KEY_new());
bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
bssl::ScopedEVP_MD_CTX md_ctx;
ASSERT_TRUE(eckey);
ASSERT_TRUE(EC_KEY_set_group(eckey.get(), group.get()));
ASSERT_TRUE(EC_KEY_set_group(eckey.get(), group));
// Generate a generic ec key.
EC_KEY_generate_key(eckey.get());
@ -1719,7 +1719,7 @@ TEST_P(ECDH_ServiceIndicatorTest, ECDH) {
FIPSStatus approved = FIPSStatus::NOT_APPROVED;
bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(test.nid));
const EC_GROUP *group = EC_GROUP_new_by_curve_name(test.nid);
bssl::UniquePtr<EC_KEY> our_key(EC_KEY_new());
bssl::UniquePtr<EC_KEY> peer_key(EC_KEY_new());
bssl::ScopedEVP_MD_CTX md_ctx;
@ -1727,11 +1727,11 @@ TEST_P(ECDH_ServiceIndicatorTest, ECDH) {
ASSERT_TRUE(peer_key);
// Generate two generic ec key pairs.
ASSERT_TRUE(EC_KEY_set_group(our_key.get(), group.get()));
ASSERT_TRUE(EC_KEY_set_group(our_key.get(), group));
ASSERT_TRUE(EC_KEY_generate_key(our_key.get()));
ASSERT_TRUE(EC_KEY_check_key(our_key.get()));
ASSERT_TRUE(EC_KEY_set_group(peer_key.get(), group.get()));
ASSERT_TRUE(EC_KEY_set_group(peer_key.get(), group));
ASSERT_TRUE(EC_KEY_generate_key(peer_key.get()));
ASSERT_TRUE(EC_KEY_check_key(peer_key.get()));

@ -106,28 +106,28 @@ const EVP_MD *GetWycheproofDigest(FileTest *t, const char *key,
return nullptr;
}
bssl::UniquePtr<EC_GROUP> GetWycheproofCurve(FileTest *t, const char *key,
bool instruction) {
const EC_GROUP *GetWycheproofCurve(FileTest *t, const char *key,
bool instruction) {
std::string name;
bool ok =
instruction ? t->GetInstruction(&name, key) : t->GetAttribute(&name, key);
if (!ok) {
return nullptr;
}
int nid;
if (name == "secp224r1") {
nid = NID_secp224r1;
} else if (name == "secp256r1") {
nid = NID_X9_62_prime256v1;
} else if (name == "secp384r1") {
nid = NID_secp384r1;
} else if (name == "secp521r1") {
nid = NID_secp521r1;
} else {
t->PrintLine("Unknown curve '%s'", name.c_str());
return nullptr;
return EC_group_p224();
}
if (name == "secp256r1") {
return EC_group_p256();
}
return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(nid));
if (name == "secp384r1") {
return EC_group_p384();
}
if (name == "secp521r1") {
return EC_group_p521();
}
t->PrintLine("Unknown curve '%s'", name.c_str());
return nullptr;
}
bssl::UniquePtr<BIGNUM> GetWycheproofBIGNUM(FileTest *t, const char *key,

@ -51,8 +51,8 @@ const EVP_MD *GetWycheproofDigest(FileTest *t, const char *key,
// GetWycheproofCurve returns a curve using the Wycheproof name, or nullptr on
// error.
bssl::UniquePtr<EC_GROUP> GetWycheproofCurve(FileTest *t, const char *key,
bool instruction);
const EC_GROUP *GetWycheproofCurve(FileTest *t, const char *key,
bool instruction);
// GetWycheproofBIGNUM returns a BIGNUM in the Wycheproof format, or nullptr on
// error.

@ -62,17 +62,13 @@ typedef struct {
static const uint8_t kDefaultAdditionalData[32] = {0};
static int pmbtoken_init_method(PMBTOKEN_METHOD *method, int curve_nid,
static int pmbtoken_init_method(PMBTOKEN_METHOD *method, const EC_GROUP *group,
const uint8_t *h_bytes, size_t h_len,
hash_t_func_t hash_t, hash_s_func_t hash_s,
hash_c_func_t hash_c,
hash_to_scalar_func_t hash_to_scalar,
int prefix_point) {
method->group = EC_GROUP_new_by_curve_name(curve_nid);
if (method->group == NULL) {
return 0;
}
method->group = group;
method->hash_t = hash_t;
method->hash_s = hash_s;
method->hash_c = hash_c;
@ -1230,7 +1226,7 @@ static void pmbtoken_exp1_init_method_impl(void) {
};
pmbtoken_exp1_ok = pmbtoken_init_method(
&pmbtoken_exp1_method, NID_secp384r1, kH, sizeof(kH),
&pmbtoken_exp1_method, EC_group_p384(), kH, sizeof(kH),
pmbtoken_exp1_hash_t, pmbtoken_exp1_hash_s, pmbtoken_exp1_hash_c,
pmbtoken_exp1_hash_to_scalar, 1);
}
@ -1403,7 +1399,7 @@ static void pmbtoken_exp2_init_method_impl(void) {
};
pmbtoken_exp2_ok = pmbtoken_init_method(
&pmbtoken_exp2_method, NID_secp384r1, kH, sizeof(kH),
&pmbtoken_exp2_method, EC_group_p384(), kH, sizeof(kH),
pmbtoken_exp2_hash_t, pmbtoken_exp2_hash_s, pmbtoken_exp2_hash_c,
pmbtoken_exp2_hash_to_scalar, 0);
}
@ -1577,7 +1573,7 @@ static void pmbtoken_pst1_init_method_impl(void) {
};
pmbtoken_pst1_ok = pmbtoken_init_method(
&pmbtoken_pst1_method, NID_secp384r1, kH, sizeof(kH),
&pmbtoken_pst1_method, EC_group_p384(), kH, sizeof(kH),
pmbtoken_pst1_hash_t, pmbtoken_pst1_hash_s, pmbtoken_pst1_hash_c,
pmbtoken_pst1_hash_to_scalar, 0);
}

@ -250,9 +250,7 @@ TEST(TrustTokenTest, KeyGenExp2PMB) {
// Test that H in |TRUST_TOKEN_experiment_v1| was computed correctly.
TEST(TrustTokenTest, HExp1) {
const EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp384r1);
ASSERT_TRUE(group);
const EC_GROUP *group = EC_group_p384();
const uint8_t kHGen[] = "generator";
const uint8_t kHLabel[] = "PMBTokens Experiment V1 HashH";
@ -272,9 +270,7 @@ TEST(TrustTokenTest, HExp1) {
// Test that H in |TRUST_TOKEN_experiment_v2_pmb| was computed correctly.
TEST(TrustTokenTest, HExp2) {
const EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp384r1);
ASSERT_TRUE(group);
const EC_GROUP *group = EC_group_p384();
const uint8_t kHGen[] = "generator";
const uint8_t kHLabel[] = "PMBTokens Experiment V2 HashH";

@ -35,7 +35,7 @@ typedef int (*hash_to_scalar_func_t)(const EC_GROUP *group, EC_SCALAR *out,
uint8_t *buf, size_t len);
typedef struct {
const EC_GROUP *group;
const EC_GROUP *(*group_func)(void);
// hash_to_group implements the HashToGroup operation for VOPRFs. It returns
// one on success and zero on error.
@ -47,20 +47,6 @@ typedef struct {
static const uint8_t kDefaultAdditionalData[32] = {0};
static int voprf_init_method(VOPRF_METHOD *method, int curve_nid,
hash_to_group_func_t hash_to_group,
hash_to_scalar_func_t hash_to_scalar) {
method->group = EC_GROUP_new_by_curve_name(curve_nid);
if (method->group == NULL) {
return 0;
}
method->hash_to_group = hash_to_group;
method->hash_to_scalar = hash_to_scalar;
return 1;
}
static int cbb_add_point(CBB *out, const EC_GROUP *group,
const EC_AFFINE *point) {
uint8_t *p;
@ -117,7 +103,7 @@ static int scalar_from_cbs(CBS *cbs, const EC_GROUP *group, EC_SCALAR *out) {
static int voprf_calculate_key(const VOPRF_METHOD *method, CBB *out_private,
CBB *out_public, const EC_SCALAR *priv) {
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
EC_JACOBIAN pub;
EC_AFFINE pub_affine;
if (!ec_point_mul_scalar_base(group, &pub, priv) ||
@ -139,7 +125,8 @@ static int voprf_calculate_key(const VOPRF_METHOD *method, CBB *out_private,
static int voprf_generate_key(const VOPRF_METHOD *method, CBB *out_private,
CBB *out_public) {
EC_SCALAR priv;
if (!ec_random_nonzero_scalar(method->group, &priv, kDefaultAdditionalData)) {
if (!ec_random_nonzero_scalar(method->group_func(), &priv,
kDefaultAdditionalData)) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE);
return 0;
}
@ -162,7 +149,7 @@ static int voprf_derive_key_from_secret(const VOPRF_METHOD *method,
!CBB_add_bytes(&cbb, kKeygenLabel, sizeof(kKeygenLabel)) ||
!CBB_add_bytes(&cbb, secret, secret_len) ||
!CBB_finish(&cbb, &buf, &len) ||
!method->hash_to_scalar(method->group, &priv, buf, len)) {
!method->hash_to_scalar(method->group_func(), &priv, buf, len)) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE);
goto err;
}
@ -178,7 +165,7 @@ err:
static int voprf_client_key_from_bytes(const VOPRF_METHOD *method,
TRUST_TOKEN_CLIENT_KEY *key,
const uint8_t *in, size_t len) {
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
if (!ec_point_from_uncompressed(group, &key->pubs, in, len)) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
return 0;
@ -190,7 +177,7 @@ static int voprf_client_key_from_bytes(const VOPRF_METHOD *method,
static int voprf_issuer_key_from_bytes(const VOPRF_METHOD *method,
TRUST_TOKEN_ISSUER_KEY *key,
const uint8_t *in, size_t len) {
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
if (!ec_scalar_from_bytes(group, &key->xs, in, len)) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
return 0;
@ -213,7 +200,7 @@ static STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_blind(const VOPRF_METHOD *method,
size_t msg_len) {
SHA512_CTX hash_ctx;
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens =
sk_TRUST_TOKEN_PRETOKEN_new_null();
if (pretokens == NULL) {
@ -280,6 +267,7 @@ static int hash_to_scalar_dleq(const VOPRF_METHOD *method, EC_SCALAR *out,
const EC_AFFINE *K1) {
static const uint8_t kDLEQLabel[] = "DLEQ";
const EC_GROUP *group = method->group_func();
int ok = 0;
CBB cbb;
CBB_zero(&cbb);
@ -287,13 +275,13 @@ static int hash_to_scalar_dleq(const VOPRF_METHOD *method, EC_SCALAR *out,
size_t len;
if (!CBB_init(&cbb, 0) ||
!CBB_add_bytes(&cbb, kDLEQLabel, sizeof(kDLEQLabel)) ||
!cbb_add_point(&cbb, method->group, X) ||
!cbb_add_point(&cbb, method->group, T) ||
!cbb_add_point(&cbb, method->group, W) ||
!cbb_add_point(&cbb, method->group, K0) ||
!cbb_add_point(&cbb, method->group, K1) ||
!cbb_add_point(&cbb, group, X) ||
!cbb_add_point(&cbb, group, T) ||
!cbb_add_point(&cbb, group, W) ||
!cbb_add_point(&cbb, group, K0) ||
!cbb_add_point(&cbb, group, K1) ||
!CBB_finish(&cbb, &buf, &len) ||
!method->hash_to_scalar(method->group, out, buf, len)) {
!method->hash_to_scalar(group, out, buf, len)) {
goto err;
}
@ -311,18 +299,19 @@ static int hash_to_scalar_challenge(const VOPRF_METHOD *method, EC_SCALAR *out,
const EC_AFFINE *a3) {
static const uint8_t kChallengeLabel[] = "Challenge";
const EC_GROUP *group = method->group_func();
CBB cbb;
uint8_t transcript[5 * EC_MAX_COMPRESSED + 2 + sizeof(kChallengeLabel) - 1];
size_t len;
if (!CBB_init_fixed(&cbb, transcript, sizeof(transcript)) ||
!cbb_serialize_point(&cbb, method->group, Bm) ||
!cbb_serialize_point(&cbb, method->group, a0) ||
!cbb_serialize_point(&cbb, method->group, a1) ||
!cbb_serialize_point(&cbb, method->group, a2) ||
!cbb_serialize_point(&cbb, method->group, a3) ||
!cbb_serialize_point(&cbb, group, Bm) ||
!cbb_serialize_point(&cbb, group, a0) ||
!cbb_serialize_point(&cbb, group, a1) ||
!cbb_serialize_point(&cbb, group, a2) ||
!cbb_serialize_point(&cbb, group, a3) ||
!CBB_add_bytes(&cbb, kChallengeLabel, sizeof(kChallengeLabel) - 1) ||
!CBB_finish(&cbb, NULL, &len) ||
!method->hash_to_scalar(method->group, out, transcript, len)) {
!method->hash_to_scalar(group, out, transcript, len)) {
return 0;
}
@ -348,7 +337,7 @@ static int hash_to_scalar_batch(const VOPRF_METHOD *method, EC_SCALAR *out,
!CBB_add_bytes(&cbb, CBB_data(points), CBB_len(points)) ||
!CBB_add_u16(&cbb, (uint16_t)index) ||
!CBB_finish(&cbb, &buf, &len) ||
!method->hash_to_scalar(method->group, out, buf, len)) {
!method->hash_to_scalar(method->group_func(), out, buf, len)) {
goto err;
}
@ -363,7 +352,7 @@ err:
static int dleq_generate(const VOPRF_METHOD *method, CBB *cbb,
const TRUST_TOKEN_ISSUER_KEY *priv,
const EC_JACOBIAN *T, const EC_JACOBIAN *W) {
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
enum {
idx_T,
@ -429,7 +418,7 @@ static int mul_public_2(const EC_GROUP *group, EC_JACOBIAN *out,
static int dleq_verify(const VOPRF_METHOD *method, CBS *cbs,
const TRUST_TOKEN_CLIENT_KEY *pub, const EC_JACOBIAN *T,
const EC_JACOBIAN *W) {
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
enum {
@ -488,7 +477,7 @@ static int dleq_verify(const VOPRF_METHOD *method, CBS *cbs,
static int voprf_sign_tt(const VOPRF_METHOD *method,
const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
size_t num_requested, size_t num_to_issue) {
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
if (num_requested < num_to_issue) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
return 0;
@ -510,7 +499,7 @@ static int voprf_sign_tt(const VOPRF_METHOD *method,
!Zs ||
!es ||
!CBB_init(&batch_cbb, 0) ||
!cbb_add_point(&batch_cbb, method->group, &key->pubs)) {
!cbb_add_point(&batch_cbb, group, &key->pubs)) {
goto err;
}
@ -587,7 +576,7 @@ static STACK_OF(TRUST_TOKEN) *voprf_unblind_tt(
const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key,
const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
uint32_t key_id) {
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
return NULL;
@ -611,7 +600,7 @@ static STACK_OF(TRUST_TOKEN) *voprf_unblind_tt(
Zs == NULL ||
es == NULL ||
!CBB_init(&batch_cbb, 0) ||
!cbb_add_point(&batch_cbb, method->group, &key->pubs)) {
!cbb_add_point(&batch_cbb, group, &key->pubs)) {
goto err;
}
@ -721,7 +710,7 @@ static void sha384_update_point_with_length(
static int compute_composite_seed(const VOPRF_METHOD *method,
uint8_t out[SHA384_DIGEST_LENGTH],
const EC_AFFINE *pub) {
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
static const uint8_t kSeedDST[] = "Seed-OPRFV1-\x01-P384-SHA384";
SHA512_CTX hash_ctx;
@ -739,7 +728,7 @@ static int compute_composite_element(const VOPRF_METHOD *method,
EC_SCALAR *di, size_t index,
const EC_AFFINE *C, const EC_AFFINE *D) {
static const uint8_t kCompositeLabel[] = "Composite";
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
if (index > UINT16_MAX) {
return 0;
@ -758,7 +747,7 @@ static int compute_composite_element(const VOPRF_METHOD *method,
!CBB_add_bytes(&cbb, kCompositeLabel,
sizeof(kCompositeLabel) - 1) ||
!CBB_finish(&cbb, NULL, &len) ||
!method->hash_to_scalar(method->group, di, transcript, len)) {
!method->hash_to_scalar(group, di, transcript, len)) {
return 0;
}
@ -769,7 +758,7 @@ static int generate_proof(const VOPRF_METHOD *method, CBB *cbb,
const TRUST_TOKEN_ISSUER_KEY *priv,
const EC_SCALAR *r, const EC_JACOBIAN *M,
const EC_JACOBIAN *Z) {
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
enum {
idx_M,
@ -820,7 +809,7 @@ static int generate_proof(const VOPRF_METHOD *method, CBB *cbb,
static int verify_proof(const VOPRF_METHOD *method, CBS *cbs,
const TRUST_TOKEN_CLIENT_KEY *pub,
const EC_JACOBIAN *M, const EC_JACOBIAN *Z) {
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
enum {
idx_M,
@ -873,7 +862,7 @@ static int voprf_sign_impl(const VOPRF_METHOD *method,
const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb,
CBS *cbs, size_t num_requested, size_t num_to_issue,
const EC_SCALAR *proof_scalar) {
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
if (num_requested < num_to_issue) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
return 0;
@ -963,7 +952,7 @@ static int voprf_sign(const VOPRF_METHOD *method,
const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
size_t num_requested, size_t num_to_issue) {
EC_SCALAR proof_scalar;
if (!ec_random_nonzero_scalar(method->group, &proof_scalar,
if (!ec_random_nonzero_scalar(method->group_func(), &proof_scalar,
kDefaultAdditionalData)) {
return 0;
}
@ -977,8 +966,8 @@ static int voprf_sign_with_proof_scalar_for_testing(
CBS *cbs, size_t num_requested, size_t num_to_issue,
const uint8_t *proof_scalar_buf, size_t proof_scalar_len) {
EC_SCALAR proof_scalar;
if (!ec_scalar_from_bytes(method->group, &proof_scalar, proof_scalar_buf,
proof_scalar_len)) {
if (!ec_scalar_from_bytes(method->group_func(), &proof_scalar,
proof_scalar_buf, proof_scalar_len)) {
return 0;
}
return voprf_sign_impl(method, key, cbb, cbs, num_requested, num_to_issue,
@ -989,7 +978,7 @@ static STACK_OF(TRUST_TOKEN) *voprf_unblind(
const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key,
const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
uint32_t key_id) {
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
return NULL;
@ -1099,7 +1088,7 @@ static int voprf_read(const VOPRF_METHOD *method,
uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE],
const uint8_t *token, size_t token_len,
int include_message, const uint8_t *msg, size_t msg_len) {
const EC_GROUP *group = method->group;
const EC_GROUP *group = method->group_func();
CBS cbs, salt;
CBS_init(&cbs, token, token_len);
EC_AFFINE Ws;
@ -1154,57 +1143,27 @@ static int voprf_exp2_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
group, out, kHashCLabel, sizeof(kHashCLabel), buf, len);
}
static int voprf_exp2_ok = 0;
static VOPRF_METHOD voprf_exp2_method;
static CRYPTO_once_t voprf_exp2_method_once = CRYPTO_ONCE_INIT;
static void voprf_exp2_init_method_impl(void) {
voprf_exp2_ok =
voprf_init_method(&voprf_exp2_method, NID_secp384r1,
voprf_exp2_hash_to_group, voprf_exp2_hash_to_scalar);
}
static int voprf_exp2_init_method(void) {
CRYPTO_once(&voprf_exp2_method_once, voprf_exp2_init_method_impl);
if (!voprf_exp2_ok) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
static VOPRF_METHOD voprf_exp2_method = {
EC_group_p384, voprf_exp2_hash_to_group, voprf_exp2_hash_to_scalar};
int voprf_exp2_generate_key(CBB *out_private, CBB *out_public) {
if (!voprf_exp2_init_method()) {
return 0;
}
return voprf_generate_key(&voprf_exp2_method, out_private, out_public);
}
int voprf_exp2_derive_key_from_secret(CBB *out_private, CBB *out_public,
const uint8_t *secret,
size_t secret_len) {
if (!voprf_exp2_init_method()) {
return 0;
}
return voprf_derive_key_from_secret(&voprf_exp2_method, out_private,
out_public, secret, secret_len);
}
int voprf_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key,
const uint8_t *in, size_t len) {
if (!voprf_exp2_init_method()) {
return 0;
}
return voprf_client_key_from_bytes(&voprf_exp2_method, key, in, len);
}
int voprf_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key,
const uint8_t *in, size_t len) {
if (!voprf_exp2_init_method()) {
return 0;
}
return voprf_issuer_key_from_bytes(&voprf_exp2_method, key, in, len);
}
@ -1212,9 +1171,6 @@ STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_exp2_blind(CBB *cbb, size_t count,
int include_message,
const uint8_t *msg,
size_t msg_len) {
if (!voprf_exp2_init_method()) {
return NULL;
}
return voprf_blind(&voprf_exp2_method, cbb, count, include_message, msg,
msg_len);
}
@ -1222,7 +1178,7 @@ STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_exp2_blind(CBB *cbb, size_t count,
int voprf_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
size_t num_requested, size_t num_to_issue,
uint8_t private_metadata) {
if (!voprf_exp2_init_method() || private_metadata != 0) {
if (private_metadata != 0) {
return 0;
}
return voprf_sign_tt(&voprf_exp2_method, key, cbb, cbs, num_requested,
@ -1233,9 +1189,6 @@ STACK_OF(TRUST_TOKEN) *voprf_exp2_unblind(
const TRUST_TOKEN_CLIENT_KEY *key,
const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
uint32_t key_id) {
if (!voprf_exp2_init_method()) {
return NULL;
}
return voprf_unblind_tt(&voprf_exp2_method, key, pretokens, cbs, count,
key_id);
}
@ -1245,9 +1198,6 @@ int voprf_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key,
uint8_t *out_private_metadata, const uint8_t *token,
size_t token_len, int include_message, const uint8_t *msg,
size_t msg_len) {
if (!voprf_exp2_init_method()) {
return 0;
}
return voprf_read(&voprf_exp2_method, key, out_nonce, token, token_len,
include_message, msg, msg_len);
}
@ -1269,57 +1219,27 @@ static int voprf_pst1_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
sizeof(kHashCLabel) - 1, buf, len);
}
static int voprf_pst1_ok = 0;
static VOPRF_METHOD voprf_pst1_method;
static CRYPTO_once_t voprf_pst1_method_once = CRYPTO_ONCE_INIT;
static void voprf_pst1_init_method_impl(void) {
voprf_pst1_ok =
voprf_init_method(&voprf_pst1_method, NID_secp384r1,
voprf_pst1_hash_to_group, voprf_pst1_hash_to_scalar);
}
static int voprf_pst1_init_method(void) {
CRYPTO_once(&voprf_pst1_method_once, voprf_pst1_init_method_impl);
if (!voprf_pst1_ok) {
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
static VOPRF_METHOD voprf_pst1_method = {
EC_group_p384, voprf_pst1_hash_to_group, voprf_pst1_hash_to_scalar};
int voprf_pst1_generate_key(CBB *out_private, CBB *out_public) {
if (!voprf_pst1_init_method()) {
return 0;
}
return voprf_generate_key(&voprf_pst1_method, out_private, out_public);
}
int voprf_pst1_derive_key_from_secret(CBB *out_private, CBB *out_public,
const uint8_t *secret,
size_t secret_len) {
if (!voprf_pst1_init_method()) {
return 0;
}
return voprf_derive_key_from_secret(&voprf_pst1_method, out_private,
out_public, secret, secret_len);
}
int voprf_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key,
const uint8_t *in, size_t len) {
if (!voprf_pst1_init_method()) {
return 0;
}
return voprf_client_key_from_bytes(&voprf_pst1_method, key, in, len);
}
int voprf_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key,
const uint8_t *in, size_t len) {
if (!voprf_pst1_init_method()) {
return 0;
}
return voprf_issuer_key_from_bytes(&voprf_pst1_method, key, in, len);
}
@ -1327,9 +1247,6 @@ STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_pst1_blind(CBB *cbb, size_t count,
int include_message,
const uint8_t *msg,
size_t msg_len) {
if (!voprf_pst1_init_method()) {
return NULL;
}
return voprf_blind(&voprf_pst1_method, cbb, count, include_message, msg,
msg_len);
}
@ -1337,7 +1254,7 @@ STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_pst1_blind(CBB *cbb, size_t count,
int voprf_pst1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
size_t num_requested, size_t num_to_issue,
uint8_t private_metadata) {
if (!voprf_pst1_init_method() || private_metadata != 0) {
if (private_metadata != 0) {
return 0;
}
return voprf_sign(&voprf_pst1_method, key, cbb, cbs, num_requested,
@ -1349,7 +1266,7 @@ int voprf_pst1_sign_with_proof_scalar_for_testing(
const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, size_t num_requested,
size_t num_to_issue, uint8_t private_metadata,
const uint8_t *proof_scalar_buf, size_t proof_scalar_len) {
if (!voprf_pst1_init_method() || private_metadata != 0) {
if (private_metadata != 0) {
return 0;
}
return voprf_sign_with_proof_scalar_for_testing(
@ -1361,9 +1278,6 @@ STACK_OF(TRUST_TOKEN) *voprf_pst1_unblind(
const TRUST_TOKEN_CLIENT_KEY *key,
const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
uint32_t key_id) {
if (!voprf_pst1_init_method()) {
return NULL;
}
return voprf_unblind(&voprf_pst1_method, key, pretokens, cbs, count, key_id);
}
@ -1372,9 +1286,6 @@ int voprf_pst1_read(const TRUST_TOKEN_ISSUER_KEY *key,
uint8_t *out_private_metadata, const uint8_t *token,
size_t token_len, int include_message, const uint8_t *msg,
size_t msg_len) {
if (!voprf_pst1_init_method()) {
return 0;
}
return voprf_read(&voprf_pst1_method, key, out_nonce, token, token_len,
include_message, msg, msg_len);
}

@ -5684,7 +5684,6 @@ BSSL_NAMESPACE_END
#define SSL_R_NO_CIPHER_MATCH 177
#define SSL_R_NO_COMPRESSION_SPECIFIED 178
#define SSL_R_NO_METHOD_SPECIFIED 179
#define SSL_R_NO_P256_SUPPORT 180
#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 181
#define SSL_R_NO_RENEGOTIATION 182
#define SSL_R_NO_REQUIRED_DIGEST 183

@ -4102,12 +4102,7 @@ bool tls1_verify_channel_id(SSL_HANDSHAKE *hs, const SSLMessage &msg) {
return false;
}
UniquePtr<EC_GROUP> p256(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
if (!p256) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT);
return false;
}
const EC_GROUP *p256 = EC_group_p256();
UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
UniquePtr<BIGNUM> x(BN_new()), y(BN_new());
if (!sig || !x || !y) {
@ -4123,11 +4118,11 @@ bool tls1_verify_channel_id(SSL_HANDSHAKE *hs, const SSLMessage &msg) {
}
UniquePtr<EC_KEY> key(EC_KEY_new());
UniquePtr<EC_POINT> point(EC_POINT_new(p256.get()));
UniquePtr<EC_POINT> point(EC_POINT_new(p256));
if (!key || !point ||
!EC_POINT_set_affine_coordinates_GFp(p256.get(), point.get(), x.get(),
y.get(), nullptr) ||
!EC_KEY_set_group(key.get(), p256.get()) ||
!EC_POINT_set_affine_coordinates_GFp(p256, point.get(), x.get(), y.get(),
nullptr) ||
!EC_KEY_set_group(key.get(), p256) ||
!EC_KEY_set_public_key(key.get(), point.get())) {
return false;
}

@ -40,8 +40,8 @@ namespace {
class ECKeyShare : public SSLKeyShare {
public:
ECKeyShare(int nid, uint16_t group_id)
: group_(EC_GROUP_new_by_curve_name(nid)), group_id_(group_id) {}
ECKeyShare(const EC_GROUP *group, uint16_t group_id)
: group_(group), group_id_(group_id) {}
uint16_t GroupID() const override { return group_id_; }
@ -49,17 +49,16 @@ class ECKeyShare : public SSLKeyShare {
assert(!private_key_);
// Generate a private key.
private_key_.reset(BN_new());
if (!group_ || !private_key_ ||
!BN_rand_range_ex(private_key_.get(), 1,
EC_GROUP_get0_order(group_))) {
if (!private_key_ ||
!BN_rand_range_ex(private_key_.get(), 1, EC_GROUP_get0_order(group_))) {
return false;
}
// Compute the corresponding public key and serialize it.
UniquePtr<EC_POINT> public_key(EC_POINT_new(group_));
if (!public_key ||
!EC_POINT_mul(group_, public_key.get(), private_key_.get(),
nullptr, nullptr, /*ctx=*/nullptr) ||
!EC_POINT_mul(group_, public_key.get(), private_key_.get(), nullptr,
nullptr, /*ctx=*/nullptr) ||
!EC_POINT_point2cbb(out, group_, public_key.get(),
POINT_CONVERSION_UNCOMPRESSED, /*ctx=*/nullptr)) {
return false;
@ -98,11 +97,10 @@ class ECKeyShare : public SSLKeyShare {
}
// Compute the x-coordinate of |peer_key| * |private_key_|.
if (!EC_POINT_mul(group_, result.get(), NULL, peer_point.get(),
if (!EC_POINT_mul(group_, result.get(), nullptr, peer_point.get(),
private_key_.get(), /*ctx=*/nullptr) ||
!EC_POINT_get_affine_coordinates_GFp(group_, result.get(), x.get(),
NULL,
/*ctx=*/nullptr)) {
nullptr, /*ctx=*/nullptr)) {
return false;
}
@ -303,13 +301,13 @@ Span<const NamedGroup> NamedGroups() {
UniquePtr<SSLKeyShare> SSLKeyShare::Create(uint16_t group_id) {
switch (group_id) {
case SSL_GROUP_SECP224R1:
return MakeUnique<ECKeyShare>(NID_secp224r1, SSL_GROUP_SECP224R1);
return MakeUnique<ECKeyShare>(EC_group_p224(), SSL_GROUP_SECP224R1);
case SSL_GROUP_SECP256R1:
return MakeUnique<ECKeyShare>(NID_X9_62_prime256v1, SSL_GROUP_SECP256R1);
return MakeUnique<ECKeyShare>(EC_group_p256(), SSL_GROUP_SECP256R1);
case SSL_GROUP_SECP384R1:
return MakeUnique<ECKeyShare>(NID_secp384r1, SSL_GROUP_SECP384R1);
return MakeUnique<ECKeyShare>(EC_group_p384(), SSL_GROUP_SECP384R1);
case SSL_GROUP_SECP521R1:
return MakeUnique<ECKeyShare>(NID_secp521r1, SSL_GROUP_SECP521R1);
return MakeUnique<ECKeyShare>(EC_group_p521(), SSL_GROUP_SECP521R1);
case SSL_GROUP_X25519:
return MakeUnique<X25519KeyShare>();
case SSL_GROUP_X25519_KYBER768_DRAFT00:

@ -741,14 +741,15 @@ static bool SpeedRandom(const std::string &selected) {
return true;
}
static bool SpeedECDHCurve(const std::string &name, int nid,
static bool SpeedECDHCurve(const std::string &name, const EC_GROUP *group,
const std::string &selected) {
if (!selected.empty() && name.find(selected) == std::string::npos) {
return true;
}
bssl::UniquePtr<EC_KEY> peer_key(EC_KEY_new_by_curve_name(nid));
bssl::UniquePtr<EC_KEY> peer_key(EC_KEY_new());
if (!peer_key ||
!EC_KEY_set_group(peer_key.get(), group) ||
!EC_KEY_generate_key(peer_key.get())) {
return false;
}
@ -769,12 +770,12 @@ static bool SpeedECDHCurve(const std::string &name, int nid,
TimeResults results;
if (!TimeFunctionParallel(
&results, [nid, peer_value_len, &peer_value]() -> bool {
bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid));
if (!key || !EC_KEY_generate_key(key.get())) {
&results, [group, peer_value_len, &peer_value]() -> bool {
bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
if (!key || !EC_KEY_set_group(key.get(), group) ||
!EC_KEY_generate_key(key.get())) {
return false;
}
const EC_GROUP *const group = EC_KEY_get0_group(key.get());
bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group));
bssl::UniquePtr<EC_POINT> peer_point(EC_POINT_new(group));
bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
@ -798,14 +799,15 @@ static bool SpeedECDHCurve(const std::string &name, int nid,
return true;
}
static bool SpeedECDSACurve(const std::string &name, int nid,
static bool SpeedECDSACurve(const std::string &name, const EC_GROUP *group,
const std::string &selected) {
if (!selected.empty() && name.find(selected) == std::string::npos) {
return true;
}
bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid));
bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
if (!key ||
!EC_KEY_set_group(key.get(), group) ||
!EC_KEY_generate_key(key.get())) {
return false;
}
@ -849,17 +851,17 @@ static bool SpeedECDSACurve(const std::string &name, int nid,
}
static bool SpeedECDH(const std::string &selected) {
return SpeedECDHCurve("ECDH P-224", NID_secp224r1, selected) &&
SpeedECDHCurve("ECDH P-256", NID_X9_62_prime256v1, selected) &&
SpeedECDHCurve("ECDH P-384", NID_secp384r1, selected) &&
SpeedECDHCurve("ECDH P-521", NID_secp521r1, selected);
return SpeedECDHCurve("ECDH P-224", EC_group_p224(), selected) &&
SpeedECDHCurve("ECDH P-256", EC_group_p256(), selected) &&
SpeedECDHCurve("ECDH P-384", EC_group_p384(), selected) &&
SpeedECDHCurve("ECDH P-521", EC_group_p521(), selected);
}
static bool SpeedECDSA(const std::string &selected) {
return SpeedECDSACurve("ECDSA P-224", NID_secp224r1, selected) &&
SpeedECDSACurve("ECDSA P-256", NID_X9_62_prime256v1, selected) &&
SpeedECDSACurve("ECDSA P-384", NID_secp384r1, selected) &&
SpeedECDSACurve("ECDSA P-521", NID_secp521r1, selected);
return SpeedECDSACurve("ECDSA P-224", EC_group_p224(), selected) &&
SpeedECDSACurve("ECDSA P-256", EC_group_p256(), selected) &&
SpeedECDSACurve("ECDSA P-384", EC_group_p384(), selected) &&
SpeedECDSACurve("ECDSA P-521", EC_group_p521(), selected);
}
static bool Speed25519(const std::string &selected) {
@ -1139,28 +1141,22 @@ static bool SpeedHashToCurve(const std::string &selected) {
TimeResults results;
{
const EC_GROUP *p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
if (p256 == NULL) {
return false;
}
if (!TimeFunctionParallel(&results, [&]() -> bool {
EC_JACOBIAN out;
return ec_hash_to_curve_p256_xmd_sha256_sswu(
p256, &out, kLabel, sizeof(kLabel), input, sizeof(input));
return ec_hash_to_curve_p256_xmd_sha256_sswu(EC_group_p256(), &out,
kLabel, sizeof(kLabel),
input, sizeof(input));
})) {
fprintf(stderr, "hash-to-curve failed.\n");
return false;
}
results.Print("hash-to-curve P256_XMD:SHA-256_SSWU_RO_");
const EC_GROUP *p384 = EC_GROUP_new_by_curve_name(NID_secp384r1);
if (p384 == NULL) {
return false;
}
if (!TimeFunctionParallel(&results, [&]() -> bool {
EC_JACOBIAN out;
return ec_hash_to_curve_p384_xmd_sha384_sswu(
p384, &out, kLabel, sizeof(kLabel), input, sizeof(input));
return ec_hash_to_curve_p384_xmd_sha384_sswu(EC_group_p384(), &out,
kLabel, sizeof(kLabel),
input, sizeof(input));
})) {
fprintf(stderr, "hash-to-curve failed.\n");
return false;
@ -1170,7 +1166,8 @@ static bool SpeedHashToCurve(const std::string &selected) {
if (!TimeFunctionParallel(&results, [&]() -> bool {
EC_SCALAR out;
return ec_hash_to_scalar_p384_xmd_sha512_draft07(
p384, &out, kLabel, sizeof(kLabel), input, sizeof(input));
EC_group_p384(), &out, kLabel, sizeof(kLabel), input,
sizeof(input));
})) {
fprintf(stderr, "hash-to-scalar failed.\n");
return false;

Loading…
Cancel
Save