diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/third_party/botan/src/lib/prov/pkcs11/p11_ecdh.cpp | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/third_party/botan/src/lib/prov/pkcs11/p11_ecdh.cpp')
-rw-r--r-- | comm/third_party/botan/src/lib/prov/pkcs11/p11_ecdh.cpp | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/prov/pkcs11/p11_ecdh.cpp b/comm/third_party/botan/src/lib/prov/pkcs11/p11_ecdh.cpp new file mode 100644 index 0000000000..4110fd486e --- /dev/null +++ b/comm/third_party/botan/src/lib/prov/pkcs11/p11_ecdh.cpp @@ -0,0 +1,125 @@ +/* +* PKCS#11 ECDH +* (C) 2016 Daniel Neus, Sirrix AG +* (C) 2016 Philipp Weber, Sirrix AG +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/p11_ecdh.h> + +#if defined(BOTAN_HAS_ECDH) + +#include <botan/internal/p11_mechanism.h> +#include <botan/der_enc.h> +#include <botan/pk_ops.h> +#include <botan/rng.h> + +namespace Botan { + +namespace PKCS11 { + +ECDH_PublicKey PKCS11_ECDH_PublicKey::export_key() const + { + return ECDH_PublicKey(domain(), public_point()); + } + +ECDH_PrivateKey PKCS11_ECDH_PrivateKey::export_key() const + { + auto priv_key = get_attribute_value(AttributeType::Value); + + Null_RNG rng; + return ECDH_PrivateKey(rng, domain(), BigInt::decode(priv_key)); + } + +secure_vector<uint8_t> PKCS11_ECDH_PrivateKey::private_key_bits() const + { + return export_key().private_key_bits(); + } + +namespace { +class PKCS11_ECDH_KA_Operation final : public PK_Ops::Key_Agreement + { + public: + PKCS11_ECDH_KA_Operation(const PKCS11_EC_PrivateKey& key, const std::string& params) + : PK_Ops::Key_Agreement(), m_key(key), m_mechanism(MechanismWrapper::create_ecdh_mechanism(params)) + {} + + size_t agreed_value_size() const override { return m_key.domain().get_p_bytes(); } + + /// The encoding in V2.20 was not specified and resulted in different implementations choosing different encodings. + /// Applications relying only on a V2.20 encoding (e.g. the DER variant) other than the one specified now (raw) may not work with all V2.30 compliant tokens. + secure_vector<uint8_t> agree(size_t key_len, const uint8_t other_key[], size_t other_key_len, const uint8_t salt[], + size_t salt_len) override + { + std::vector<uint8_t> der_encoded_other_key; + if(m_key.point_encoding() == PublicPointEncoding::Der) + { + DER_Encoder(der_encoded_other_key).encode(other_key, other_key_len, OCTET_STRING); + m_mechanism.set_ecdh_other_key(der_encoded_other_key.data(), der_encoded_other_key.size()); + } + else + { + m_mechanism.set_ecdh_other_key(other_key, other_key_len); + } + + if(salt != nullptr && salt_len > 0) + { + m_mechanism.set_ecdh_salt(salt, salt_len); + } + + ObjectHandle secret_handle = 0; + AttributeContainer attributes; + attributes.add_bool(AttributeType::Sensitive, false); + attributes.add_bool(AttributeType::Extractable, true); + attributes.add_numeric(AttributeType::Class, static_cast< CK_OBJECT_CLASS >(ObjectClass::SecretKey)); + attributes.add_numeric(AttributeType::KeyType, static_cast< CK_KEY_TYPE >(KeyType::GenericSecret)); + attributes.add_numeric(AttributeType::ValueLen, static_cast< CK_ULONG >(key_len)); + m_key.module()->C_DeriveKey(m_key.session().handle(), m_mechanism.data(), m_key.handle(), attributes.data(), + static_cast<Ulong>(attributes.count()), &secret_handle); + + Object secret_object(m_key.session(), secret_handle); + secure_vector<uint8_t> secret = secret_object.get_attribute_value(AttributeType::Value); + if(secret.size() < key_len) + { + throw PKCS11_Error("ECDH key derivation secret length is too short"); + } + secret.resize(key_len); + return secret; + } + + private: + const PKCS11_EC_PrivateKey& m_key; + MechanismWrapper m_mechanism; + }; + +} + +std::unique_ptr<PK_Ops::Key_Agreement> +PKCS11_ECDH_PrivateKey::create_key_agreement_op(RandomNumberGenerator&, + const std::string& params, + const std::string& /*provider*/) const + { + return std::unique_ptr<PK_Ops::Key_Agreement>(new PKCS11_ECDH_KA_Operation(*this, params)); + } + +PKCS11_ECDH_KeyPair generate_ecdh_keypair(Session& session, const EC_PublicKeyGenerationProperties& pub_props, + const EC_PrivateKeyGenerationProperties& priv_props) + { + ObjectHandle pub_key_handle = 0; + ObjectHandle priv_key_handle = 0; + + Mechanism mechanism = { static_cast< CK_MECHANISM_TYPE >(MechanismType::EcKeyPairGen), nullptr, 0 }; + + session.module()->C_GenerateKeyPair(session.handle(), &mechanism, + pub_props.data(), static_cast<Ulong>(pub_props.count()), + priv_props.data(), static_cast<Ulong>(priv_props.count()), + &pub_key_handle, &priv_key_handle); + + return std::make_pair(PKCS11_ECDH_PublicKey(session, pub_key_handle), PKCS11_ECDH_PrivateKey(session, priv_key_handle)); + } + +} +} + +#endif |