• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 13273297057

11 Feb 2025 01:36PM UTC coverage: 91.649% (-0.01%) from 91.659%
13273297057

push

github

web-flow
Merge pull request #4669 from Rohde-Schwarz/fix/tpm2_uses_legacy_ec_point

FIX: tpm2_ecc silently depends on legacy_ec_point

94863 of 103507 relevant lines covered (91.65%)

11216132.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.15
/src/lib/pubkey/ecc_key/ecc_key.cpp
1
/*
2
* ECC Key implemenation
3
* (C) 2007 Manuel Hartl, FlexSecure GmbH
4
*          Falko Strenzke, FlexSecure GmbH
5
*     2008-2010 Jack Lloyd
6
*
7
* Botan is released under the Simplified BSD License (see license.txt)
8
*/
9

10
#include <botan/ecc_key.h>
11

12
#include <botan/ber_dec.h>
13
#include <botan/der_enc.h>
14
#include <botan/secmem.h>
15
#include <botan/internal/ec_key_data.h>
16
#include <botan/internal/fmt.h>
17
#include <botan/internal/workfactor.h>
18

19
#if defined(BOTAN_HAS_LEGACY_EC_POINT)
20
   #include <botan/ec_point.h>
21
#endif
22

23
namespace Botan {
24

25
size_t EC_PublicKey::key_length() const {
918✔
26
   return domain().get_p_bits();
918✔
27
}
28

29
size_t EC_PublicKey::estimated_strength() const {
536✔
30
   return ecp_work_factor(key_length());
536✔
31
}
32

33
namespace {
34

35
EC_Group_Encoding default_encoding_for(const EC_Group& group) {
24,705✔
36
   if(group.get_curve_oid().empty()) {
24,705✔
37
      return EC_Group_Encoding::Explicit;
38
   } else {
39
      return EC_Group_Encoding::NamedCurve;
24,689✔
40
   }
41
}
42

43
}  // namespace
44

45
#if defined(BOTAN_HAS_LEGACY_EC_POINT)
46
EC_PublicKey::EC_PublicKey(EC_Group group, const EC_Point& pub_point) {
×
47
   auto pt = EC_AffinePoint(group, pub_point);
×
48
   m_public_key = std::make_shared<const EC_PublicKey_Data>(std::move(group), std::move(pt));
×
49
   m_domain_encoding = default_encoding_for(domain());
×
50
}
×
51
#endif
52

53
EC_PublicKey::EC_PublicKey(EC_Group group, EC_AffinePoint pub_point) {
12,664✔
54
   m_public_key = std::make_shared<const EC_PublicKey_Data>(std::move(group), std::move(pub_point));
12,664✔
55
   m_domain_encoding = default_encoding_for(domain());
12,664✔
56
}
12,664✔
57

58
EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> key_bits) {
3,772✔
59
   m_public_key = std::make_shared<const EC_PublicKey_Data>(EC_Group(alg_id.parameters()), key_bits);
7,512✔
60
   m_domain_encoding = default_encoding_for(domain());
3,474✔
61
}
3,772✔
62

63
const EC_Group& EC_PublicKey::domain() const {
61,127✔
64
   BOTAN_STATE_CHECK(m_public_key != nullptr);
61,127✔
65
   return m_public_key->group();
61,127✔
66
}
67

68
#if defined(BOTAN_HAS_LEGACY_EC_POINT)
69
const EC_Point& EC_PublicKey::public_point() const {
×
70
   BOTAN_STATE_CHECK(m_public_key != nullptr);
×
71
   return m_public_key->legacy_point();
×
72
}
73
#endif
74

75
const EC_AffinePoint& EC_PublicKey::_public_ec_point() const {
19,141✔
76
   BOTAN_STATE_CHECK(m_public_key != nullptr);
19,141✔
77
   return m_public_key->public_key();
19,141✔
78
}
79

80
bool EC_PublicKey::check_key(RandomNumberGenerator& rng, bool /*strong*/) const {
106✔
81
   // We already checked when deserializing that the point was on the curve
82
   return domain().verify_group(rng) && !_public_ec_point().is_identity();
106✔
83
}
84

85
AlgorithmIdentifier EC_PublicKey::algorithm_identifier() const {
1,220✔
86
   return AlgorithmIdentifier(object_identifier(), DER_domain());
3,660✔
87
}
88

89
std::vector<uint8_t> EC_PublicKey::raw_public_key_bits() const {
889✔
90
   return _public_ec_point().serialize(point_encoding());
889✔
91
}
92

93
std::vector<uint8_t> EC_PublicKey::public_key_bits() const {
699✔
94
   return raw_public_key_bits();
699✔
95
}
96

97
std::vector<uint8_t> EC_PublicKey::DER_domain() const {
1,228✔
98
   return domain().DER_encode(domain_format());
1,228✔
99
}
100

101
void EC_PublicKey::set_point_encoding(EC_Point_Format enc) {
84✔
102
   if(enc != EC_Point_Format::Compressed && enc != EC_Point_Format::Uncompressed && enc != EC_Point_Format::Hybrid) {
84✔
103
      throw Invalid_Argument("Invalid point encoding for EC_PublicKey");
28✔
104
   }
105

106
   m_point_encoding = enc;
56✔
107
}
56✔
108

109
void EC_PublicKey::set_parameter_encoding(EC_Group_Encoding form) {
×
110
   if(form == EC_Group_Encoding::NamedCurve && domain().get_curve_oid().empty()) {
×
111
      throw Invalid_Argument("Cannot used NamedCurve encoding for a curve without an OID");
×
112
   }
113

114
   m_domain_encoding = form;
×
115
}
×
116

117
const BigInt& EC_PrivateKey::private_value() const {
17✔
118
   BOTAN_STATE_CHECK(m_private_key != nullptr);
17✔
119
   return m_private_key->legacy_bigint();
17✔
120
}
121

122
const EC_Scalar& EC_PrivateKey::_private_key() const {
7,402✔
123
   BOTAN_STATE_CHECK(m_private_key != nullptr);
7,402✔
124
   return m_private_key->private_key();
7,402✔
125
}
126

127
/**
128
* EC_PrivateKey constructor
129
*/
130
EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng,
594✔
131
                             EC_Group ec_group,
132
                             const BigInt& x,
133
                             bool with_modular_inverse) {
594✔
134
   auto scalar = (x.is_zero()) ? EC_Scalar::random(ec_group, rng) : EC_Scalar::from_bigint(ec_group, x);
1,188✔
135
   m_private_key = std::make_shared<EC_PrivateKey_Data>(std::move(ec_group), std::move(scalar));
594✔
136
   m_public_key = m_private_key->public_key(rng, with_modular_inverse);
594✔
137
   m_domain_encoding = default_encoding_for(domain());
594✔
138
}
594✔
139

140
EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng, EC_Group ec_group, bool with_modular_inverse) {
6,077✔
141
   auto scalar = EC_Scalar::random(ec_group, rng);
6,077✔
142
   m_private_key = std::make_shared<EC_PrivateKey_Data>(std::move(ec_group), std::move(scalar));
6,077✔
143
   m_public_key = m_private_key->public_key(rng, with_modular_inverse);
6,077✔
144
   m_domain_encoding = default_encoding_for(domain());
6,077✔
145
}
6,077✔
146

147
EC_PrivateKey::EC_PrivateKey(EC_Group ec_group, EC_Scalar x, bool with_modular_inverse) {
×
148
   m_private_key = std::make_shared<EC_PrivateKey_Data>(std::move(ec_group), std::move(x));
×
149
   m_public_key = m_private_key->public_key(with_modular_inverse);
×
150
   m_domain_encoding = default_encoding_for(domain());
×
151
}
×
152

153
secure_vector<uint8_t> EC_PrivateKey::raw_private_key_bits() const {
761✔
154
   BOTAN_STATE_CHECK(m_private_key != nullptr);
761✔
155
   return m_private_key->serialize<secure_vector<uint8_t>>();
761✔
156
}
157

158
secure_vector<uint8_t> EC_PrivateKey::private_key_bits() const {
758✔
159
   BOTAN_STATE_CHECK(m_private_key != nullptr && m_public_key != nullptr);
758✔
160

161
   return DER_Encoder()
758✔
162
      .start_sequence()
758✔
163
      .encode(static_cast<size_t>(1))
758✔
164
      .encode(raw_private_key_bits(), ASN1_Type::OctetString)
2,274✔
165
      .start_explicit_context_specific(1)
758✔
166
      .encode(m_public_key->public_key().serialize_uncompressed(), ASN1_Type::BitString)
1,516✔
167
      .end_cons()
758✔
168
      .end_cons()
758✔
169
      .get_contents();
1,516✔
170
}
171

172
EC_PrivateKey::EC_PrivateKey(const AlgorithmIdentifier& alg_id,
2,528✔
173
                             std::span<const uint8_t> key_bits,
174
                             bool with_modular_inverse) {
2,528✔
175
   EC_Group group(alg_id.parameters());
2,528✔
176

177
   OID key_parameters;
2,180✔
178
   secure_vector<uint8_t> private_key_bits;
2,180✔
179
   secure_vector<uint8_t> public_key_bits;
2,180✔
180

181
   BER_Decoder(key_bits)
4,345✔
182
      .start_sequence()
2,165✔
183
      .decode_and_check<size_t>(1, "Unknown version code for ECC key")
2,165✔
184
      .decode(private_key_bits, ASN1_Type::OctetString)
2,161✔
185
      .decode_optional(key_parameters, ASN1_Type(0), ASN1_Class::ExplicitContextSpecific)
4,326✔
186
      .decode_optional_string(public_key_bits, ASN1_Type::BitString, 1, ASN1_Class::ExplicitContextSpecific)
2,156✔
187
      .end_cons();
2,151✔
188

189
   m_private_key = std::make_shared<EC_PrivateKey_Data>(group, private_key_bits);
2,150✔
190

191
   if(public_key_bits.empty()) {
2,086✔
192
      m_public_key = m_private_key->public_key(with_modular_inverse);
300✔
193
   } else {
194
      m_public_key = std::make_shared<EC_PublicKey_Data>(group, public_key_bits);
1,880✔
195
   }
196

197
   m_domain_encoding = default_encoding_for(domain());
3,792✔
198
}
5,276✔
199

200
bool EC_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const {
52✔
201
   if(!m_private_key) {
52✔
202
      return false;
203
   }
204

205
   return EC_PublicKey::check_key(rng, strong);
52✔
206
}
207

208
const BigInt& EC_PublicKey::get_int_field(std::string_view field) const {
2✔
209
   if(field == "public_x" || field == "public_y") {
2✔
210
      throw Not_Implemented(fmt("EC_PublicKey::get_int_field no longer implements getter for {}", field));
×
211
   } else if(field == "base_x") {
2✔
212
      return this->domain().get_g_x();
×
213
   } else if(field == "base_y") {
2✔
214
      return this->domain().get_g_y();
×
215
   } else if(field == "p") {
2✔
216
      return this->domain().get_p();
×
217
   } else if(field == "a") {
2✔
218
      return this->domain().get_a();
×
219
   } else if(field == "b") {
2✔
220
      return this->domain().get_b();
×
221
   } else if(field == "cofactor") {
2✔
222
      return this->domain().get_cofactor();
×
223
   } else if(field == "order") {
2✔
224
      return this->domain().get_order();
×
225
   } else {
226
      return Public_Key::get_int_field(field);
2✔
227
   }
228
}
229

230
const BigInt& EC_PrivateKey::get_int_field(std::string_view field) const {
10✔
231
   if(field == "x") {
10✔
232
      return this->private_value();
9✔
233
   } else {
234
      return EC_PublicKey::get_int_field(field);
1✔
235
   }
236
}
237

238
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc