Botan 1.10.17
pubkey.cpp
Go to the documentation of this file.
1/*
2* Public Key Base
3* (C) 1999-2010 Jack Lloyd
4*
5* Distributed under the terms of the Botan license
6*/
7
8#include <botan/pubkey.h>
9#include <botan/der_enc.h>
10#include <botan/ber_dec.h>
11#include <botan/bigint.h>
12#include <botan/parsing.h>
13#include <botan/libstate.h>
14#include <botan/engine.h>
15#include <botan/lookup.h>
16#include <botan/internal/bit_ops.h>
17#include <botan/internal/assert.h>
18#include <memory>
19
20namespace Botan {
21
22/*
23* PK_Encryptor_EME Constructor
24*/
26 const std::string& eme_name)
27 {
28 Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
29
30 op = 0;
31
32 while(const Engine* engine = i.next())
33 {
34 op = engine->get_encryption_op(key);
35 if(op)
36 break;
37 }
38
39 if(!op)
40 throw Lookup_Error("Encryption with " + key.algo_name() + " not supported");
41
42 eme = (eme_name == "Raw") ? 0 : get_eme(eme_name);
43 }
44
45/*
46* Encrypt a message
47*/
49PK_Encryptor_EME::enc(const byte in[],
50 size_t length,
51 RandomNumberGenerator& rng) const
52 {
53 if(eme)
54 {
55 SecureVector<byte> encoded =
56 eme->encode(in, length, op->max_input_bits(), rng);
57
58 if(8*(encoded.size() - 1) + high_bit(encoded[0]) > op->max_input_bits())
59 throw Invalid_Argument("PK_Encryptor_EME: Input is too large");
60
61 return op->encrypt(&encoded[0], encoded.size(), rng);
62 }
63 else
64 {
65 if(8*(length - 1) + high_bit(in[0]) > op->max_input_bits())
66 throw Invalid_Argument("PK_Encryptor_EME: Input is too large");
67
68 return op->encrypt(&in[0], length, rng);
69 }
70 }
71
72/*
73* Return the max size, in bytes, of a message
74*/
76 {
77 if(!eme)
78 return (op->max_input_bits() / 8);
79 else
80 return eme->maximum_input_size(op->max_input_bits());
81 }
82
83/*
84* PK_Decryptor_EME Constructor
85*/
87 const std::string& eme_name)
88 {
89 Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
90
91 op = 0;
92
93 while(const Engine* engine = i.next())
94 {
95 op = engine->get_decryption_op(key);
96 if(op)
97 break;
98 }
99
100 if(!op)
101 throw Lookup_Error("Decryption with " + key.algo_name() + " not supported");
102
103 eme = (eme_name == "Raw") ? 0 : get_eme(eme_name);
104 }
105
106/*
107* Decrypt a message
108*/
109SecureVector<byte> PK_Decryptor_EME::dec(const byte msg[],
110 size_t length) const
111 {
112 try {
113 SecureVector<byte> decrypted = op->decrypt(msg, length);
114 if(eme)
115 return eme->decode(decrypted, op->max_input_bits());
116 else
117 return decrypted;
118 }
119 catch(Invalid_Argument)
120 {
121 throw Decoding_Error("PK_Decryptor_EME: Input is invalid");
122 }
123 }
124
125/*
126* PK_Signer Constructor
127*/
129 const std::string& emsa_name,
130 Signature_Format format,
131 Fault_Protection prot)
132 {
133 Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
134
135 op = 0;
136 verify_op = 0;
137
138 while(const Engine* engine = i.next())
139 {
140 if(!op)
141 op = engine->get_signature_op(key);
142
143 if(!verify_op && prot == ENABLE_FAULT_PROTECTION)
144 verify_op = engine->get_verify_op(key);
145
146 if(op && (verify_op || prot == DISABLE_FAULT_PROTECTION))
147 break;
148 }
149
150 if(!op || (!verify_op && prot == ENABLE_FAULT_PROTECTION))
151 throw Lookup_Error("Signing with " + key.algo_name() + " not supported");
152
153 emsa = get_emsa(emsa_name);
154 sig_format = format;
155 }
156
157/*
158* Sign a message
159*/
160SecureVector<byte> PK_Signer::sign_message(const byte msg[], size_t length,
162 {
163 update(msg, length);
164 return signature(rng);
165 }
166
167/*
168* Add more to the message to be signed
169*/
170void PK_Signer::update(const byte in[], size_t length)
171 {
172 emsa->update(in, length);
173 }
174
175/*
176* Check the signature we just created, to help prevent fault attacks
177*/
178bool PK_Signer::self_test_signature(const MemoryRegion<byte>& msg,
179 const MemoryRegion<byte>& sig) const
180 {
181 if(!verify_op)
182 return true; // checking disabled, assume ok
183
184 if(verify_op->with_recovery())
185 {
186 SecureVector<byte> recovered =
187 verify_op->verify_mr(&sig[0], sig.size());
188
189 if(msg.size() > recovered.size())
190 {
191 size_t extra_0s = msg.size() - recovered.size();
192
193 for(size_t i = 0; i != extra_0s; ++i)
194 if(msg[i] != 0)
195 return false;
196
197 return same_mem(&msg[extra_0s], &recovered[0], recovered.size());
198 }
199
200 return (recovered == msg);
201 }
202 else
203 return verify_op->verify(&msg[0], msg.size(),
204 &sig[0], sig.size());
205 }
206
207/*
208* Create a signature
209*/
211 {
212 SecureVector<byte> encoded = emsa->encoding_of(emsa->raw_data(),
213 op->max_input_bits(),
214 rng);
215
216 SecureVector<byte> plain_sig = op->sign(&encoded[0], encoded.size(), rng);
217
218 BOTAN_ASSERT(self_test_signature(encoded, plain_sig),
219 "PK_Signer consistency check failed");
220
221 if(op->message_parts() == 1 || sig_format == IEEE_1363)
222 return plain_sig;
223
224 if(sig_format == DER_SEQUENCE)
225 {
226 if(plain_sig.size() % op->message_parts())
227 throw Encoding_Error("PK_Signer: strange signature size found");
228 const size_t SIZE_OF_PART = plain_sig.size() / op->message_parts();
229
230 std::vector<BigInt> sig_parts(op->message_parts());
231 for(size_t j = 0; j != sig_parts.size(); ++j)
232 sig_parts[j].binary_decode(&plain_sig[SIZE_OF_PART*j], SIZE_OF_PART);
233
234 return DER_Encoder()
236 .encode_list(sig_parts)
237 .end_cons()
238 .get_contents();
239 }
240 else
241 throw Encoding_Error("PK_Signer: Unknown signature format " +
242 to_string(sig_format));
243 }
244
245/*
246* PK_Verifier Constructor
247*/
249 const std::string& emsa_name,
250 Signature_Format format)
251 {
252 Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
253
254 op = 0;
255
256 while(const Engine* engine = i.next())
257 {
258 op = engine->get_verify_op(key);
259 if(op)
260 break;
261 }
262
263 if(!op)
264 throw Lookup_Error("Verification with " + key.algo_name() + " not supported");
265
266 emsa = get_emsa(emsa_name);
267 sig_format = format;
268 }
269
270/*
271* Set the signature format
272*/
274 {
275 if(op->message_parts() == 1 && format != IEEE_1363)
276 throw Invalid_State("PK_Verifier: This algorithm always uses IEEE 1363");
277 sig_format = format;
278 }
279
280/*
281* Verify a message
282*/
283bool PK_Verifier::verify_message(const byte msg[], size_t msg_length,
284 const byte sig[], size_t sig_length)
285 {
286 update(msg, msg_length);
287 return check_signature(sig, sig_length);
288 }
289
290/*
291* Append to the message
292*/
293void PK_Verifier::update(const byte in[], size_t length)
294 {
295 emsa->update(in, length);
296 }
297
298/*
299* Check a signature
300*/
301bool PK_Verifier::check_signature(const byte sig[], size_t length)
302 {
303 try {
304 if(sig_format == IEEE_1363)
305 return validate_signature(emsa->raw_data(), sig, length);
306 else if(sig_format == DER_SEQUENCE)
307 {
308 BER_Decoder decoder(sig, length);
309 BER_Decoder ber_sig = decoder.start_cons(SEQUENCE);
310
311 size_t count = 0;
312 SecureVector<byte> real_sig;
313 while(ber_sig.more_items())
314 {
315 BigInt sig_part;
316 ber_sig.decode(sig_part);
317 real_sig += BigInt::encode_1363(sig_part, op->message_part_size());
318 ++count;
319 }
320
321 if(count != op->message_parts())
322 throw Decoding_Error("PK_Verifier: signature size invalid");
323
324 return validate_signature(emsa->raw_data(),
325 &real_sig[0], real_sig.size());
326 }
327 else
328 throw Decoding_Error("PK_Verifier: Unknown signature format " +
329 to_string(sig_format));
330 }
331 catch(Invalid_Argument) { return false; }
332 }
333
334/*
335* Verify a signature
336*/
337bool PK_Verifier::validate_signature(const MemoryRegion<byte>& msg,
338 const byte sig[], size_t sig_len)
339 {
340 if(op->with_recovery())
341 {
342 SecureVector<byte> output_of_key = op->verify_mr(sig, sig_len);
343 return emsa->verify(output_of_key, msg, op->max_input_bits());
344 }
345 else
346 {
347 Null_RNG rng;
348
349 SecureVector<byte> encoded =
350 emsa->encoding_of(msg, op->max_input_bits(), rng);
351
352 return op->verify(&encoded[0], encoded.size(), sig, sig_len);
353 }
354 }
355
356/*
357* PK_Key_Agreement Constructor
358*/
360 const std::string& kdf_name)
361 {
362 Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
363
364 op = 0;
365
366 while(const Engine* engine = i.next())
367 {
368 op = engine->get_key_agreement_op(key);
369 if(op)
370 break;
371 }
372
373 if(!op)
374 throw Lookup_Error("Key agreement with " + key.algo_name() + " not supported");
375
376 kdf = (kdf_name == "Raw") ? 0 : get_kdf(kdf_name);
377 }
378
379SymmetricKey PK_Key_Agreement::derive_key(size_t key_len, const byte in[],
380 size_t in_len, const byte params[],
381 size_t params_len) const
382 {
383 SecureVector<byte> z = op->agree(in, in_len);
384
385 if(!kdf)
386 return z;
387
388 return kdf->derive_key(key_len, z, params, params_len);
389 }
390
391}
#define BOTAN_ASSERT(expr, msg)
Definition assert.h:19
BER_Decoder start_cons(ASN1_Tag, ASN1_Tag=UNIVERSAL)
Definition ber_dec.cpp:238
bool more_items() const
Definition ber_dec.cpp:153
BER_Decoder & decode(bool &)
Definition ber_dec.cpp:344
static SecureVector< byte > encode_1363(const BigInt &n, size_t bytes)
Definition big_code.cpp:78
DER_Encoder & encode_list(const std::vector< T > &values)
Definition der_enc.h:75
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition der_enc.cpp:135
SecureVector< byte > get_contents()
Definition der_enc.cpp:122
DER_Encoder & end_cons()
Definition der_enc.cpp:145
SecureVector< byte > decode(const byte in[], size_t in_length, size_t key_length) const
Definition eme.cpp:35
SecureVector< byte > encode(const byte in[], size_t in_length, size_t key_length, RandomNumberGenerator &rng) const
Definition eme.cpp:15
virtual SecureVector< byte > encoding_of(const MemoryRegion< byte > &msg, size_t output_bits, RandomNumberGenerator &rng)=0
virtual bool verify(const MemoryRegion< byte > &coded, const MemoryRegion< byte > &raw, size_t key_bits)=0
size_t size() const
Definition secmem.h:29
PK_Decryptor_EME(const Private_Key &key, const std::string &eme)
Definition pubkey.cpp:86
PK_Encryptor_EME(const Public_Key &key, const std::string &eme)
Definition pubkey.cpp:25
size_t maximum_input_size() const
Definition pubkey.cpp:75
SymmetricKey derive_key(size_t key_len, const byte in[], size_t in_len, const byte params[], size_t params_len) const
Definition pubkey.cpp:379
PK_Key_Agreement(const PK_Key_Agreement_Key &key, const std::string &kdf)
Definition pubkey.cpp:359
virtual SecureVector< byte > decrypt(const byte msg[], size_t msg_len)=0
virtual size_t max_input_bits() const =0
virtual size_t max_input_bits() const =0
virtual SecureVector< byte > encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator &rng)=0
virtual bool verify(const byte[], size_t, const byte[], size_t)
Definition pk_ops.h:120
virtual size_t max_input_bits() const =0
virtual SecureVector< byte > verify_mr(const byte[], size_t)
Definition pk_ops.h:133
virtual bool with_recovery() const =0
void update(byte in)
Definition pubkey.h:150
SecureVector< byte > sign_message(const byte in[], size_t length, RandomNumberGenerator &rng)
Definition pubkey.cpp:160
PK_Signer(const Private_Key &key, const std::string &emsa, Signature_Format format=IEEE_1363, Fault_Protection prot=ENABLE_FAULT_PROTECTION)
Definition pubkey.cpp:128
SecureVector< byte > signature(RandomNumberGenerator &rng)
Definition pubkey.cpp:210
void update(byte in)
Definition pubkey.h:242
void set_input_format(Signature_Format format)
Definition pubkey.cpp:273
bool verify_message(const byte msg[], size_t msg_length, const byte sig[], size_t sig_length)
Definition pubkey.cpp:283
bool check_signature(const byte sig[], size_t length)
Definition pubkey.cpp:301
PK_Verifier(const Public_Key &pub_key, const std::string &emsa, Signature_Format format=IEEE_1363)
Definition pubkey.cpp:248
virtual std::string algo_name() const =0
OctetString SymmetricKey
Definition symkey.h:147
KDF * get_kdf(const std::string &algo_spec)
Definition get_enc.cpp:174
EMSA * get_emsa(const std::string &algo_spec)
Definition get_enc.cpp:86
std::string to_string(u64bit n, size_t min_len)
Definition parsing.cpp:42
std::invalid_argument Invalid_Argument
Definition exceptn.h:20
@ SEQUENCE
Definition asn1_int.h:35
Fault_Protection
Definition pubkey.h:29
@ ENABLE_FAULT_PROTECTION
Definition pubkey.h:30
@ DISABLE_FAULT_PROTECTION
Definition pubkey.h:31
Library_State & global_state()
bool same_mem(const T *p1, const T *p2, size_t n)
Definition mem_ops.h:57
size_t high_bit(T n)
Definition bit_ops.h:33
Signature_Format
Definition pubkey.h:24
@ DER_SEQUENCE
Definition pubkey.h:24
@ IEEE_1363
Definition pubkey.h:24
EME * get_eme(const std::string &algo_spec)
Definition get_enc.cpp:143
Decoding_Error(const std::string &name)
Definition exceptn.h:140
Encoding_Error(const std::string &name)
Definition exceptn.h:131
Invalid_State(const std::string &err)
Definition exceptn.h:27
Lookup_Error(const std::string &err)
Definition exceptn.h:37