/src/botan/src/lib/pubkey/pubkey.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * (C) 1999-2010,2015,2018 Jack Lloyd |
3 | | * |
4 | | * Botan is released under the Simplified BSD License (see license.txt) |
5 | | */ |
6 | | |
7 | | #include <botan/pubkey.h> |
8 | | #include <botan/der_enc.h> |
9 | | #include <botan/ber_dec.h> |
10 | | #include <botan/bigint.h> |
11 | | #include <botan/pk_ops.h> |
12 | | #include <botan/internal/ct_utils.h> |
13 | | #include <botan/rng.h> |
14 | | |
15 | | namespace Botan { |
16 | | |
17 | | secure_vector<uint8_t> PK_Decryptor::decrypt(const uint8_t in[], size_t length) const |
18 | 0 | { |
19 | 0 | uint8_t valid_mask = 0; |
20 | 0 |
|
21 | 0 | secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length); |
22 | 0 |
|
23 | 0 | if(valid_mask == 0) |
24 | 0 | throw Decoding_Error("Invalid public key ciphertext, cannot decrypt"); |
25 | 0 | |
26 | 0 | return decoded; |
27 | 0 | } |
28 | | |
29 | | secure_vector<uint8_t> |
30 | | PK_Decryptor::decrypt_or_random(const uint8_t in[], |
31 | | size_t length, |
32 | | size_t expected_pt_len, |
33 | | RandomNumberGenerator& rng, |
34 | | const uint8_t required_content_bytes[], |
35 | | const uint8_t required_content_offsets[], |
36 | | size_t required_contents_length) const |
37 | 0 | { |
38 | 0 | const secure_vector<uint8_t> fake_pms = rng.random_vec(expected_pt_len); |
39 | 0 |
|
40 | 0 | uint8_t decrypt_valid = 0; |
41 | 0 | secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length); |
42 | 0 |
|
43 | 0 | auto valid_mask = CT::Mask<uint8_t>::is_equal(decrypt_valid, 0xFF); |
44 | 0 | valid_mask &= CT::Mask<uint8_t>(CT::Mask<size_t>::is_zero(decoded.size() ^ expected_pt_len)); |
45 | 0 |
|
46 | 0 | decoded.resize(expected_pt_len); |
47 | 0 |
|
48 | 0 | for(size_t i = 0; i != required_contents_length; ++i) |
49 | 0 | { |
50 | 0 | /* |
51 | 0 | These values are chosen by the application and for TLS are constants, |
52 | 0 | so this early failure via assert is fine since we know 0,1 < 48 |
53 | 0 |
|
54 | 0 | If there is a protocol that has content checks on the key where |
55 | 0 | the expected offsets are controllable by the attacker this could |
56 | 0 | still leak. |
57 | 0 |
|
58 | 0 | Alternately could always reduce the offset modulo the length? |
59 | 0 | */ |
60 | 0 |
|
61 | 0 | const uint8_t exp = required_content_bytes[i]; |
62 | 0 | const uint8_t off = required_content_offsets[i]; |
63 | 0 |
|
64 | 0 | BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext"); |
65 | 0 |
|
66 | 0 | auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp); |
67 | 0 |
|
68 | 0 | valid_mask &= eq; |
69 | 0 | } |
70 | 0 |
|
71 | 0 | // If valid_mask is false, assign fake pre master instead |
72 | 0 | valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len); |
73 | 0 |
|
74 | 0 | return decoded; |
75 | 0 | } |
76 | | |
77 | | secure_vector<uint8_t> |
78 | | PK_Decryptor::decrypt_or_random(const uint8_t in[], |
79 | | size_t length, |
80 | | size_t expected_pt_len, |
81 | | RandomNumberGenerator& rng) const |
82 | 0 | { |
83 | 0 | return decrypt_or_random(in, length, expected_pt_len, rng, |
84 | 0 | nullptr, nullptr, 0); |
85 | 0 | } |
86 | | |
87 | | PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, |
88 | | RandomNumberGenerator& rng, |
89 | | const std::string& padding, |
90 | | const std::string& provider) |
91 | 63 | { |
92 | 63 | m_op = key.create_encryption_op(rng, padding, provider); |
93 | 63 | if(!m_op) |
94 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support encryption"); |
95 | 63 | } |
96 | | |
97 | 63 | PK_Encryptor_EME::~PK_Encryptor_EME() { /* for unique_ptr */ } |
98 | | |
99 | | size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const |
100 | 0 | { |
101 | 0 | return m_op->ciphertext_length(ptext_len); |
102 | 0 | } |
103 | | |
104 | | std::vector<uint8_t> |
105 | | PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const |
106 | 63 | { |
107 | 63 | return unlock(m_op->encrypt(in, length, rng)); |
108 | 63 | } |
109 | | |
110 | | size_t PK_Encryptor_EME::maximum_input_size() const |
111 | 0 | { |
112 | 0 | return m_op->max_input_bits() / 8; |
113 | 0 | } |
114 | | |
115 | | PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, |
116 | | RandomNumberGenerator& rng, |
117 | | const std::string& padding, |
118 | | const std::string& provider) |
119 | 0 | { |
120 | 0 | m_op = key.create_decryption_op(rng, padding, provider); |
121 | 0 | if(!m_op) |
122 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support decryption"); |
123 | 0 | } |
124 | | |
125 | 0 | PK_Decryptor_EME::~PK_Decryptor_EME() { /* for unique_ptr */ } |
126 | | |
127 | | size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const |
128 | 0 | { |
129 | 0 | return m_op->plaintext_length(ctext_len); |
130 | 0 | } |
131 | | |
132 | | secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, |
133 | | const uint8_t in[], size_t in_len) const |
134 | 0 | { |
135 | 0 | return m_op->decrypt(valid_mask, in, in_len); |
136 | 0 | } |
137 | | |
138 | | PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, |
139 | | RandomNumberGenerator& rng, |
140 | | const std::string& param, |
141 | | const std::string& provider) |
142 | 0 | { |
143 | 0 | m_op = key.create_kem_encryption_op(rng, param, provider); |
144 | 0 | if(!m_op) |
145 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM encryption"); |
146 | 0 | } |
147 | | |
148 | 0 | PK_KEM_Encryptor::~PK_KEM_Encryptor() { /* for unique_ptr */ } |
149 | | |
150 | | void PK_KEM_Encryptor::encrypt(secure_vector<uint8_t>& out_encapsulated_key, |
151 | | secure_vector<uint8_t>& out_shared_key, |
152 | | size_t desired_shared_key_len, |
153 | | Botan::RandomNumberGenerator& rng, |
154 | | const uint8_t salt[], |
155 | | size_t salt_len) |
156 | 0 | { |
157 | 0 | m_op->kem_encrypt(out_encapsulated_key, |
158 | 0 | out_shared_key, |
159 | 0 | desired_shared_key_len, |
160 | 0 | rng, |
161 | 0 | salt, |
162 | 0 | salt_len); |
163 | 0 | } |
164 | | |
165 | | PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key, |
166 | | RandomNumberGenerator& rng, |
167 | | const std::string& param, |
168 | | const std::string& provider) |
169 | 0 | { |
170 | 0 | m_op = key.create_kem_decryption_op(rng, param, provider); |
171 | 0 | if(!m_op) |
172 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM decryption"); |
173 | 0 | } |
174 | | |
175 | 0 | PK_KEM_Decryptor::~PK_KEM_Decryptor() { /* for unique_ptr */ } |
176 | | |
177 | | secure_vector<uint8_t> PK_KEM_Decryptor::decrypt(const uint8_t encap_key[], |
178 | | size_t encap_key_len, |
179 | | size_t desired_shared_key_len, |
180 | | const uint8_t salt[], |
181 | | size_t salt_len) |
182 | 0 | { |
183 | 0 | return m_op->kem_decrypt(encap_key, encap_key_len, |
184 | 0 | desired_shared_key_len, |
185 | 0 | salt, salt_len); |
186 | 0 | } |
187 | | |
188 | | PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key, |
189 | | RandomNumberGenerator& rng, |
190 | | const std::string& kdf, |
191 | | const std::string& provider) |
192 | 14.2k | { |
193 | 14.2k | m_op = key.create_key_agreement_op(rng, kdf, provider); |
194 | 14.2k | if(!m_op) |
195 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support key agreement"); |
196 | 14.2k | } |
197 | | |
198 | 14.2k | PK_Key_Agreement::~PK_Key_Agreement() { /* for unique_ptr */ } |
199 | | |
200 | | PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&& other) |
201 | 0 | { |
202 | 0 | if(this != &other) |
203 | 0 | { |
204 | 0 | m_op = std::move(other.m_op); |
205 | 0 | } |
206 | 0 | return (*this); |
207 | 0 | } |
208 | | |
209 | | PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&& other) : |
210 | | m_op(std::move(other.m_op)) |
211 | 0 | {} |
212 | | |
213 | | size_t PK_Key_Agreement::agreed_value_size() const |
214 | 0 | { |
215 | 0 | return m_op->agreed_value_size(); |
216 | 0 | } |
217 | | |
218 | | SymmetricKey PK_Key_Agreement::derive_key(size_t key_len, |
219 | | const uint8_t in[], size_t in_len, |
220 | | const uint8_t salt[], |
221 | | size_t salt_len) const |
222 | 14.2k | { |
223 | 14.2k | return m_op->agree(key_len, in, in_len, salt, salt_len); |
224 | 14.2k | } |
225 | | |
226 | | PK_Signer::PK_Signer(const Private_Key& key, |
227 | | RandomNumberGenerator& rng, |
228 | | const std::string& emsa, |
229 | | Signature_Format format, |
230 | | const std::string& provider) |
231 | 0 | { |
232 | 0 | m_op = key.create_signature_op(rng, emsa, provider); |
233 | 0 | if(!m_op) |
234 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature generation"); |
235 | 0 | m_sig_format = format; |
236 | 0 | m_parts = key.message_parts(); |
237 | 0 | m_part_size = key.message_part_size(); |
238 | 0 | } |
239 | | |
240 | 0 | PK_Signer::~PK_Signer() { /* for unique_ptr */ } |
241 | | |
242 | | void PK_Signer::update(const uint8_t in[], size_t length) |
243 | 0 | { |
244 | 0 | m_op->update(in, length); |
245 | 0 | } |
246 | | |
247 | | namespace { |
248 | | |
249 | | std::vector<uint8_t> der_encode_signature(const std::vector<uint8_t>& sig, |
250 | | size_t parts, |
251 | | size_t part_size) |
252 | 722 | { |
253 | 722 | if(sig.size() % parts != 0 || sig.size() != parts * part_size) |
254 | 0 | throw Encoding_Error("Unexpected size for DER signature"); |
255 | 722 | |
256 | 722 | std::vector<BigInt> sig_parts(parts); |
257 | 2.16k | for(size_t i = 0; i != sig_parts.size(); ++i) |
258 | 1.44k | sig_parts[i].binary_decode(&sig[part_size*i], part_size); |
259 | 722 | |
260 | 722 | std::vector<uint8_t> output; |
261 | 722 | DER_Encoder(output) |
262 | 722 | .start_cons(SEQUENCE) |
263 | 722 | .encode_list(sig_parts) |
264 | 722 | .end_cons(); |
265 | 722 | return output; |
266 | 722 | } |
267 | | |
268 | | } |
269 | | |
270 | | size_t PK_Signer::signature_length() const |
271 | 0 | { |
272 | 0 | if(m_sig_format == IEEE_1363) |
273 | 0 | { |
274 | 0 | return m_op->signature_length(); |
275 | 0 | } |
276 | 0 | else if(m_sig_format == DER_SEQUENCE) |
277 | 0 | { |
278 | 0 | // This is a large over-estimate but its easier than computing |
279 | 0 | // the exact value |
280 | 0 | return m_op->signature_length() + (8 + 4*m_parts); |
281 | 0 | } |
282 | 0 | else |
283 | 0 | throw Internal_Error("PK_Signer: Invalid signature format enum"); |
284 | 0 | } |
285 | | |
286 | | std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) |
287 | 0 | { |
288 | 0 | const std::vector<uint8_t> sig = unlock(m_op->sign(rng)); |
289 | 0 |
|
290 | 0 | if(m_sig_format == IEEE_1363) |
291 | 0 | { |
292 | 0 | return sig; |
293 | 0 | } |
294 | 0 | else if(m_sig_format == DER_SEQUENCE) |
295 | 0 | { |
296 | 0 | return der_encode_signature(sig, m_parts, m_part_size); |
297 | 0 | } |
298 | 0 | else |
299 | 0 | throw Internal_Error("PK_Signer: Invalid signature format enum"); |
300 | 0 | } |
301 | | |
302 | | PK_Verifier::PK_Verifier(const Public_Key& key, |
303 | | const std::string& emsa, |
304 | | Signature_Format format, |
305 | | const std::string& provider) |
306 | 8.06k | { |
307 | 8.06k | m_op = key.create_verification_op(emsa, provider); |
308 | 8.06k | if(!m_op) |
309 | 0 | throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature verification"); |
310 | 8.06k | m_sig_format = format; |
311 | 8.06k | m_parts = key.message_parts(); |
312 | 8.06k | m_part_size = key.message_part_size(); |
313 | 8.06k | } |
314 | | |
315 | 8.06k | PK_Verifier::~PK_Verifier() { /* for unique_ptr */ } |
316 | | |
317 | | void PK_Verifier::set_input_format(Signature_Format format) |
318 | 0 | { |
319 | 0 | if(format != IEEE_1363 && m_parts == 1) |
320 | 0 | throw Invalid_Argument("PK_Verifier: This algorithm does not support DER encoding"); |
321 | 0 | m_sig_format = format; |
322 | 0 | } |
323 | | |
324 | | bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, |
325 | | const uint8_t sig[], size_t sig_length) |
326 | 8.06k | { |
327 | 8.06k | update(msg, msg_length); |
328 | 8.06k | return check_signature(sig, sig_length); |
329 | 8.06k | } |
330 | | |
331 | | void PK_Verifier::update(const uint8_t in[], size_t length) |
332 | 8.06k | { |
333 | 8.06k | m_op->update(in, length); |
334 | 8.06k | } |
335 | | |
336 | | bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) |
337 | 8.06k | { |
338 | 8.06k | try { |
339 | 8.06k | if(m_sig_format == IEEE_1363) |
340 | 6.40k | { |
341 | 6.40k | return m_op->is_valid_signature(sig, length); |
342 | 6.40k | } |
343 | 1.65k | else if(m_sig_format == DER_SEQUENCE) |
344 | 1.65k | { |
345 | 1.65k | std::vector<uint8_t> real_sig; |
346 | 1.65k | BER_Decoder decoder(sig, length); |
347 | 1.65k | BER_Decoder ber_sig = decoder.start_cons(SEQUENCE); |
348 | 1.65k | |
349 | 1.65k | BOTAN_ASSERT_NOMSG(m_parts != 0 && m_part_size != 0); |
350 | 1.65k | |
351 | 1.65k | size_t count = 0; |
352 | 1.65k | |
353 | 4.08k | while(ber_sig.more_items()) |
354 | 2.43k | { |
355 | 2.43k | BigInt sig_part; |
356 | 2.43k | ber_sig.decode(sig_part); |
357 | 2.43k | real_sig += BigInt::encode_1363(sig_part, m_part_size); |
358 | 2.43k | ++count; |
359 | 2.43k | } |
360 | 1.65k | |
361 | 1.65k | if(count != m_parts) |
362 | 32 | throw Decoding_Error("PK_Verifier: signature size invalid"); |
363 | 1.62k | |
364 | 1.62k | const std::vector<uint8_t> reencoded = |
365 | 1.62k | der_encode_signature(real_sig, m_parts, m_part_size); |
366 | 1.62k | |
367 | 1.62k | if(reencoded.size() != length || |
368 | 1.62k | same_mem(reencoded.data(), sig, reencoded.size()) == false) |
369 | 81 | { |
370 | 81 | throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding"); |
371 | 81 | } |
372 | 1.54k | |
373 | 1.54k | return m_op->is_valid_signature(real_sig.data(), real_sig.size()); |
374 | 1.54k | } |
375 | 0 | else |
376 | 0 | throw Internal_Error("PK_Verifier: Invalid signature format enum"); |
377 | 1.10k | } |
378 | 1.10k | catch(Invalid_Argument&) { return false; } |
379 | 8.06k | } |
380 | | |
381 | | } |