summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/lib/prov/pkcs11/p11_ecc_key.cpp
blob: 874621b78026b2b89473a19644c0cb7627a3513e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
* PKCS#11 ECC
* (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_ecc_key.h>
#include <botan/pk_keys.h>

#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)

#include <botan/workfactor.h>
#include <botan/ber_dec.h>

namespace Botan {
namespace PKCS11 {
namespace {
/// Converts a DER-encoded ANSI X9.62 ECPoint to PointGFp
PointGFp decode_public_point(const secure_vector<uint8_t>& ec_point_data, const EC_Group& group)
   {
   secure_vector<uint8_t> ec_point;
   BER_Decoder(ec_point_data).decode(ec_point, OCTET_STRING);
   return group.OS2ECP(ec_point);
   }
}

EC_PublicKeyGenerationProperties::EC_PublicKeyGenerationProperties(const std::vector<uint8_t>& ec_params)
   : PublicKeyProperties(KeyType::Ec), m_ec_params(ec_params)
   {
   add_binary(AttributeType::EcParams, m_ec_params);
   }

EC_PublicKeyImportProperties::EC_PublicKeyImportProperties(const std::vector<uint8_t>& ec_params,
      const std::vector<uint8_t>& ec_point)
   : PublicKeyProperties(KeyType::Ec), m_ec_params(ec_params), m_ec_point(ec_point)
   {
   add_binary(AttributeType::EcParams, m_ec_params);
   add_binary(AttributeType::EcPoint, m_ec_point);
   }

PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, ObjectHandle handle)
   : Object(session, handle)
   {
   secure_vector<uint8_t> ec_parameters = get_attribute_value(AttributeType::EcParams);
   m_domain_params = EC_Group(unlock(ec_parameters));
   m_public_key = decode_public_point(get_attribute_value(AttributeType::EcPoint), m_domain_params);
   m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
   }

PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, const EC_PublicKeyImportProperties& props)
   : Object(session, props)
   {
   m_domain_params = EC_Group(props.ec_params());

   secure_vector<uint8_t> ec_point;
   BER_Decoder(props.ec_point()).decode(ec_point, OCTET_STRING);
   m_public_key = m_domain_params.OS2ECP(ec_point);
   m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
   }

EC_PrivateKeyImportProperties::EC_PrivateKeyImportProperties(const std::vector<uint8_t>& ec_params, const BigInt& value)
   : PrivateKeyProperties(KeyType::Ec), m_ec_params(ec_params), m_value(value)
   {
   add_binary(AttributeType::EcParams, m_ec_params);
   add_binary(AttributeType::Value, BigInt::encode(m_value));
   }

PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, ObjectHandle handle)
   : Object(session, handle), m_domain_params(), m_public_key()
   {
   secure_vector<uint8_t> ec_parameters = get_attribute_value(AttributeType::EcParams);
   m_domain_params = EC_Group(unlock(ec_parameters));
   }

PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props)
   : Object(session, props)
   {
   m_domain_params = EC_Group(props.ec_params());
   }

PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, const std::vector<uint8_t>& ec_params,
      const EC_PrivateKeyGenerationProperties& props)
   : Object(session)
   {
   m_domain_params = EC_Group(ec_params);

   EC_PublicKeyGenerationProperties pub_key_props(ec_params);
   pub_key_props.set_verify(true);
   pub_key_props.set_private(false);
   pub_key_props.set_token(false);    // don't create a persistent public key object

   ObjectHandle pub_key_handle = CK_INVALID_HANDLE;
   ObjectHandle priv_key_handle = CK_INVALID_HANDLE;
   Mechanism mechanism = { CKM_EC_KEY_PAIR_GEN, nullptr, 0 };
   session.module()->C_GenerateKeyPair(session.handle(), &mechanism,
                                       pub_key_props.data(), static_cast<Ulong>(pub_key_props.count()),
                                       props.data(), static_cast<Ulong>(props.count()),
                                       &pub_key_handle, &priv_key_handle);

   this->reset_handle(priv_key_handle);

   Object public_key(session, pub_key_handle);
   m_public_key = decode_public_point(public_key.get_attribute_value(AttributeType::EcPoint), m_domain_params);
   }

size_t PKCS11_EC_PrivateKey::key_length() const
   {
   return m_domain_params.get_order().bits();
   }

std::vector<uint8_t> PKCS11_EC_PrivateKey::public_key_bits() const
   {
   return public_point().encode(PointGFp::COMPRESSED);
   }

size_t PKCS11_EC_PrivateKey::estimated_strength() const
   {
   return ecp_work_factor(key_length());
   }

bool PKCS11_EC_PrivateKey::check_key(RandomNumberGenerator&, bool) const
   {
   return m_public_key.on_the_curve();
   }

AlgorithmIdentifier PKCS11_EC_PrivateKey::algorithm_identifier() const
   {
   return AlgorithmIdentifier(get_oid(), domain().DER_encode(EC_DOMPAR_ENC_EXPLICIT));
   }
}

}

#endif