8 #include <botan/internal/openssl.h>
10 #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
11 #include <botan/der_enc.h>
12 #include <botan/pkcs8.h>
13 #include <botan/oids.h>
14 #include <botan/internal/pk_ops_impl.h>
17 #if defined(BOTAN_HAS_ECDSA)
18 #include <botan/ecdsa.h>
21 #if defined(BOTAN_HAS_ECDH)
22 #include <botan/ecdh.h>
25 #include <openssl/x509.h>
26 #include <openssl/objects.h>
28 #if !defined(OPENSSL_NO_EC)
29 #include <openssl/ec.h>
32 #if !defined(OPENSSL_NO_ECDSA)
33 #include <openssl/ecdsa.h>
36 #if !defined(OPENSSL_NO_ECDH)
37 #include <openssl/ecdh.h>
42 #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
46 secure_vector<uint8_t> PKCS8_for_openssl(
const EC_PrivateKey& ec)
48 const PointGFp& pub_key = ec.public_point();
49 const BigInt& priv_key = ec.private_value();
53 .encode(static_cast<size_t>(1))
65 int OpenSSL_EC_nid_for(
const OID& oid)
72 if(name ==
"secp192r1")
73 return NID_X9_62_prime192v1;
74 if(name ==
"secp224r1")
76 if(name ==
"secp256r1")
77 return NID_X9_62_prime256v1;
78 if(name ==
"secp384r1")
80 if(name ==
"secp521r1")
84 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL
85 if(name ==
"brainpool160r1")
86 return NID_brainpoolP160r1;
87 if(name ==
"brainpool192r1")
88 return NID_brainpoolP192r1;
89 if(name ==
"brainpool224r1")
90 return NID_brainpoolP224r1;
91 if(name ==
"brainpool256r1")
92 return NID_brainpoolP256r1;
93 if(name ==
"brainpool320r1")
94 return NID_brainpoolP320r1;
95 if(name ==
"brainpool384r1")
96 return NID_brainpoolP384r1;
97 if(name ==
"brainpool512r1")
98 return NID_brainpoolP512r1;
108 #if defined(BOTAN_HAS_ECDSA) && !defined(OPENSSL_NO_ECDSA)
112 class OpenSSL_ECDSA_Verification_Operation :
public PK_Ops::Verification_with_EMSA
115 OpenSSL_ECDSA_Verification_Operation(
const ECDSA_PublicKey& ecdsa,
const std::string& emsa,
int nid) :
116 PK_Ops::Verification_with_EMSA(emsa), m_ossl_ec(::EC_KEY_new(), ::EC_KEY_free)
118 std::unique_ptr<::EC_GROUP, std::function<void (::EC_GROUP*)>> grp(::EC_GROUP_new_by_curve_name(nid),
122 throw OpenSSL_Error(
"EC_GROUP_new_by_curve_name");
124 ::EC_KEY_set_group(m_ossl_ec.get(), grp.get());
127 const uint8_t* enc_ptr = enc.data();
128 EC_KEY* key_ptr = m_ossl_ec.get();
129 if(!::o2i_ECPublicKey(&key_ptr, &enc_ptr, enc.size()))
130 throw OpenSSL_Error(
"o2i_ECPublicKey");
132 const EC_GROUP* group = ::EC_KEY_get0_group(m_ossl_ec.get());
133 m_order_bits = ::EC_GROUP_get_degree(group);
136 size_t max_input_bits()
const override {
return m_order_bits; }
138 bool with_recovery()
const override {
return false; }
140 bool verify(
const uint8_t msg[],
size_t msg_len,
141 const uint8_t sig_bytes[],
size_t sig_len)
override
143 const size_t order_bytes = (m_order_bits + 7) / 8;
144 if(sig_len != 2 * order_bytes)
147 std::unique_ptr<ECDSA_SIG, std::function<void (ECDSA_SIG*)>> sig(
nullptr, ECDSA_SIG_free);
148 sig.reset(::ECDSA_SIG_new());
150 sig->r = BN_bin2bn(sig_bytes , sig_len / 2,
nullptr);
151 sig->s = BN_bin2bn(sig_bytes + sig_len / 2, sig_len / 2,
nullptr);
153 const int res = ECDSA_do_verify(msg, msg_len, sig.get(), m_ossl_ec.get());
155 throw OpenSSL_Error(
"ECDSA_do_verify");
160 std::unique_ptr<EC_KEY, std::function<void (EC_KEY*)>> m_ossl_ec;
161 size_t m_order_bits = 0;
164 class OpenSSL_ECDSA_Signing_Operation :
public PK_Ops::Signature_with_EMSA
167 OpenSSL_ECDSA_Signing_Operation(
const ECDSA_PrivateKey& ecdsa,
const std::string& emsa) :
168 PK_Ops::Signature_with_EMSA(emsa),
169 m_ossl_ec(nullptr, ::EC_KEY_free)
171 const secure_vector<uint8_t> der = PKCS8_for_openssl(ecdsa);
172 const uint8_t* der_ptr = der.data();
173 m_ossl_ec.reset(d2i_ECPrivateKey(
nullptr, &der_ptr, der.size()));
175 throw OpenSSL_Error(
"d2i_ECPrivateKey");
177 const EC_GROUP* group = ::EC_KEY_get0_group(m_ossl_ec.get());
178 m_order_bits = ::EC_GROUP_get_degree(group);
181 secure_vector<uint8_t> raw_sign(
const uint8_t msg[],
size_t msg_len,
182 RandomNumberGenerator&)
override
184 std::unique_ptr<ECDSA_SIG, std::function<void (ECDSA_SIG*)>> sig(
nullptr, ECDSA_SIG_free);
185 sig.reset(::ECDSA_do_sign(msg, msg_len, m_ossl_ec.get()));
188 throw OpenSSL_Error(
"ECDSA_do_sign");
190 const size_t order_bytes = (m_order_bits + 7) / 8;
191 const size_t r_bytes = BN_num_bytes(sig->r);
192 const size_t s_bytes = BN_num_bytes(sig->s);
193 secure_vector<uint8_t> sigval(2*order_bytes);
194 BN_bn2bin(sig->r, &sigval[order_bytes - r_bytes]);
195 BN_bn2bin(sig->s, &sigval[2*order_bytes - s_bytes]);
199 size_t max_input_bits()
const override {
return m_order_bits; }
202 std::unique_ptr<EC_KEY, std::function<void (EC_KEY*)>> m_ossl_ec;
203 size_t m_order_bits = 0;
208 std::unique_ptr<PK_Ops::Verification>
209 make_openssl_ecdsa_ver_op(
const ECDSA_PublicKey& key,
const std::string& params)
211 const int nid = OpenSSL_EC_nid_for(key.domain().get_oid());
214 throw Lookup_Error(
"OpenSSL ECDSA does not support this curve");
216 return std::unique_ptr<PK_Ops::Verification>(
new OpenSSL_ECDSA_Verification_Operation(key, params, nid));
219 std::unique_ptr<PK_Ops::Signature>
220 make_openssl_ecdsa_sig_op(
const ECDSA_PrivateKey& key,
const std::string& params)
222 const int nid = OpenSSL_EC_nid_for(key.domain().get_oid());
225 throw Lookup_Error(
"OpenSSL ECDSA does not support this curve");
227 return std::unique_ptr<PK_Ops::Signature>(
new OpenSSL_ECDSA_Signing_Operation(key, params));
232 #if defined(BOTAN_HAS_ECDH) && !defined(OPENSSL_NO_ECDH)
236 class OpenSSL_ECDH_KA_Operation :
public PK_Ops::Key_Agreement_with_KDF
240 OpenSSL_ECDH_KA_Operation(
const ECDH_PrivateKey& ecdh,
const std::string& kdf) :
241 PK_Ops::Key_Agreement_with_KDF(kdf), m_ossl_ec(::EC_KEY_new(), ::EC_KEY_free)
243 const secure_vector<uint8_t> der = PKCS8_for_openssl(ecdh);
244 const uint8_t* der_ptr = der.data();
245 m_ossl_ec.reset(d2i_ECPrivateKey(
nullptr, &der_ptr, der.size()));
247 throw OpenSSL_Error(
"d2i_ECPrivateKey");
250 secure_vector<uint8_t> raw_agree(
const uint8_t w[],
size_t w_len)
override
252 const EC_GROUP* group = ::EC_KEY_get0_group(m_ossl_ec.get());
253 const size_t out_len = (::EC_GROUP_get_degree(group) + 7) / 8;
254 secure_vector<uint8_t> out(out_len);
255 EC_POINT* pub_key = ::EC_POINT_new(group);
258 throw OpenSSL_Error(
"EC_POINT_new");
260 const int os2ecp_rc =
261 ::EC_POINT_oct2point(group, pub_key, w, w_len,
nullptr);
264 throw OpenSSL_Error(
"EC_POINT_oct2point");
266 const int ecdh_rc = ::ECDH_compute_key(out.data(),
273 throw OpenSSL_Error(
"ECDH_compute_key");
275 const size_t ecdh_sz =
static_cast<size_t>(ecdh_rc);
277 if(ecdh_sz > out.size())
278 throw Internal_Error(
"OpenSSL ECDH returned more than requested");
285 std::unique_ptr<EC_KEY, std::function<void (EC_KEY*)>> m_ossl_ec;
290 std::unique_ptr<PK_Ops::Key_Agreement>
291 make_openssl_ecdh_ka_op(
const ECDH_PrivateKey& key,
const std::string& params)
293 const int nid = OpenSSL_EC_nid_for(key.domain().get_oid());
296 throw Lookup_Error(
"OpenSSL ECDH does not support this curve");
299 return std::unique_ptr<PK_Ops::Key_Agreement>(
new OpenSSL_ECDH_KA_Operation(key, params));
secure_vector< uint8_t > EC2OSP(const PointGFp &point, uint8_t format)
std::string lookup(const OID &oid)
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)