Packages
hackney
3.0.3
4.7.2
4.7.1
4.7.0
4.6.1
4.6.0
4.5.2
4.5.1
4.5.0
4.4.5
4.4.3
4.4.2
4.4.1
4.4.0
4.3.0
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.3
4.0.2
4.0.1
4.0.0
3.2.1
3.2.0
3.1.2
3.1.1
3.1.0
3.0.3
3.0.2
3.0.1
3.0.0
retired
2.0.1
2.0.0
2.0.0-beta.1
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.1
1.20.0
1.19.1
1.19.0
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.0
1.15.2
1.15.1
1.15.0
1.14.3
1.14.2
1.14.0
1.13.0
1.12.1
1.12.0
1.11.0
1.10.1
1.10.0
1.9.0
1.8.6
1.8.5
1.8.4
1.8.3
1.8.2
1.8.0
1.7.1
1.7.0
1.6.6
retired
1.6.5
1.6.4
retired
1.6.3
1.6.2
1.6.1
1.6.0
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.6
1.0.5
1.0.2
1.0.1
0.15.2
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
Simple HTTP client with HTTP/1.1, HTTP/2, and HTTP/3 support
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
c_src/boringssl/crypto/ec/ec_derive.cc
// Copyright 2019 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <openssl/ec_key.h>
#include <string.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/digest.h>
#include <openssl/hkdf.h>
#include <openssl/mem.h>
#include "../fipsmodule/ec/internal.h"
EC_KEY *EC_KEY_derive_from_secret(const EC_GROUP *group, const uint8_t *secret,
size_t secret_len) {
#define EC_KEY_DERIVE_MAX_NAME_LEN 16
const char *name = EC_curve_nid2nist(EC_GROUP_get_curve_name(group));
if (name == nullptr || strlen(name) > EC_KEY_DERIVE_MAX_NAME_LEN) {
OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
return nullptr;
}
// Assemble a label string to provide some key separation in case |secret| is
// misused, but ultimately it's on the caller to ensure |secret| is suitably
// separated.
static const char kLabel[] = "derive EC key ";
char info[sizeof(kLabel) + EC_KEY_DERIVE_MAX_NAME_LEN];
OPENSSL_strlcpy(info, kLabel, sizeof(info));
OPENSSL_strlcat(info, name, sizeof(info));
// Generate 128 bits beyond the group order so the bias is at most 2^-128.
#define EC_KEY_DERIVE_EXTRA_BITS 128
#define EC_KEY_DERIVE_EXTRA_BYTES (EC_KEY_DERIVE_EXTRA_BITS / 8)
if (EC_GROUP_order_bits(group) <= EC_KEY_DERIVE_EXTRA_BITS + 8) {
// The reduction strategy below requires the group order be large enough.
// (The actual bound is a bit tighter, but our curves are much larger than
// 128-bit.)
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
return nullptr;
}
uint8_t derived[EC_KEY_DERIVE_EXTRA_BYTES + EC_MAX_BYTES];
size_t derived_len =
BN_num_bytes(EC_GROUP_get0_order(group)) + EC_KEY_DERIVE_EXTRA_BYTES;
assert(derived_len <= sizeof(derived));
if (!HKDF(derived, derived_len, EVP_sha256(), secret, secret_len,
/*salt=*/nullptr, /*salt_len=*/0, (const uint8_t *)info,
strlen(info))) {
return nullptr;
}
bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
bssl::UniquePtr<BIGNUM> priv(BN_bin2bn(derived, derived_len, nullptr));
bssl::UniquePtr<EC_POINT> pub(EC_POINT_new(group));
if (key == nullptr || ctx == nullptr || priv == nullptr || pub == nullptr ||
// Reduce |priv| with Montgomery reduction. First, convert "from"
// Montgomery form to compute |priv| * R^-1 mod |order|. This requires
// |priv| be under order * R, which is true if the group order is large
// enough. 2^(num_bytes(order)) < 2^8 * order, so:
//
// priv < 2^8 * order * 2^128 < order * order < order * R
!BN_from_montgomery(priv.get(), priv.get(), &group->order, ctx.get()) ||
// Multiply by R^2 and do another Montgomery reduction to compute
// priv * R^-1 * R^2 * R^-1 = priv mod order.
!BN_to_montgomery(priv.get(), priv.get(), &group->order, ctx.get()) ||
!EC_POINT_mul(group, pub.get(), priv.get(), nullptr, nullptr,
ctx.get()) ||
!EC_KEY_set_group(key.get(), group) ||
!EC_KEY_set_public_key(key.get(), pub.get()) ||
!EC_KEY_set_private_key(key.get(), priv.get())) {
OPENSSL_cleanse(derived, sizeof(derived));
return nullptr;
}
OPENSSL_cleanse(derived, sizeof(derived));
return key.release();
}