1 /*
2 * Public Key Interface
3 * (C) 1999-2010 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #ifndef BOTAN_PUBKEY_H__
9 #define BOTAN_PUBKEY_H__
10 
11 #include <botan/pk_keys.h>
12 #include <botan/pk_ops.h>
13 #include <botan/symkey.h>
14 #include <botan/rng.h>
15 #include <botan/eme.h>
16 #include <botan/emsa.h>
17 #include <botan/kdf.h>
18 
19 namespace Botan {
20 
21 /**
22 * The two types of signature format supported by Botan.
23 */
24 enum Signature_Format { IEEE_1363, DER_SEQUENCE };
25 
26 /**
27 * Enum marking if protection against fault attacks should be used
28 */
29 enum Fault_Protection {
30    ENABLE_FAULT_PROTECTION,
31    DISABLE_FAULT_PROTECTION
32 };
33 
34 /**
35 * Public Key Encryptor
36 */
37 class BOTAN_DLL PK_Encryptor
38    {
39    public:
40 
41       /**
42       * Encrypt a message.
43       * @param in the message as a byte array
44       * @param length the length of the above byte array
45       * @param rng the random number source to use
46       * @return encrypted message
47       */
encrypt(const byte in[],size_t length,RandomNumberGenerator & rng)48       SecureVector<byte> encrypt(const byte in[], size_t length,
49                                  RandomNumberGenerator& rng) const
50          {
51          return enc(in, length, rng);
52          }
53 
54       /**
55       * Encrypt a message.
56       * @param in the message
57       * @param rng the random number source to use
58       * @return encrypted message
59       */
encrypt(const MemoryRegion<byte> & in,RandomNumberGenerator & rng)60       SecureVector<byte> encrypt(const MemoryRegion<byte>& in,
61                                  RandomNumberGenerator& rng) const
62          {
63          return enc(&in[0], in.size(), rng);
64          }
65 
66       /**
67       * Return the maximum allowed message size in bytes.
68       * @return maximum message size in bytes
69       */
70       virtual size_t maximum_input_size() const = 0;
71 
PK_Encryptor()72       PK_Encryptor() {}
~PK_Encryptor()73       virtual ~PK_Encryptor() {}
74    private:
PK_Encryptor(const PK_Encryptor &)75       PK_Encryptor(const PK_Encryptor&) {}
76       PK_Encryptor& operator=(const PK_Encryptor&) { return *this; }
77 
78       virtual SecureVector<byte> enc(const byte[], size_t,
79                                      RandomNumberGenerator&) const = 0;
80    };
81 
82 /**
83 * Public Key Decryptor
84 */
85 class BOTAN_DLL PK_Decryptor
86    {
87    public:
88       /**
89       * Decrypt a ciphertext.
90       * @param in the ciphertext as a byte array
91       * @param length the length of the above byte array
92       * @return decrypted message
93       */
decrypt(const byte in[],size_t length)94       SecureVector<byte> decrypt(const byte in[], size_t length) const
95          {
96          return dec(in, length);
97          }
98 
99       /**
100       * Decrypt a ciphertext.
101       * @param in the ciphertext
102       * @return decrypted message
103       */
decrypt(const MemoryRegion<byte> & in)104       SecureVector<byte> decrypt(const MemoryRegion<byte>& in) const
105          {
106          return dec(&in[0], in.size());
107          }
108 
PK_Decryptor()109       PK_Decryptor() {}
~PK_Decryptor()110       virtual ~PK_Decryptor() {}
111    private:
PK_Decryptor(const PK_Decryptor &)112       PK_Decryptor(const PK_Decryptor&) {}
113       PK_Decryptor& operator=(const PK_Decryptor&) { return *this; }
114 
115       virtual SecureVector<byte> dec(const byte[], size_t) const = 0;
116    };
117 
118 /**
119 * Public Key Signer. Use the sign_message() functions for small
120 * messages. Use multiple calls update() to process large messages and
121 * generate the signature by finally calling signature().
122 */
123 class BOTAN_DLL PK_Signer
124    {
125    public:
126       /**
127       * Sign a message.
128       * @param in the message to sign as a byte array
129       * @param length the length of the above byte array
130       * @param rng the rng to use
131       * @return signature
132       */
133       SecureVector<byte> sign_message(const byte in[], size_t length,
134                                       RandomNumberGenerator& rng);
135 
136       /**
137       * Sign a message.
138       * @param in the message to sign
139       * @param rng the rng to use
140       * @return signature
141       */
sign_message(const MemoryRegion<byte> & in,RandomNumberGenerator & rng)142       SecureVector<byte> sign_message(const MemoryRegion<byte>& in,
143                                       RandomNumberGenerator& rng)
144          { return sign_message(&in[0], in.size(), rng); }
145 
146       /**
147       * Add a message part (single byte).
148       * @param in the byte to add
149       */
update(byte in)150       void update(byte in) { update(&in, 1); }
151 
152       /**
153       * Add a message part.
154       * @param in the message part to add as a byte array
155       * @param length the length of the above byte array
156       */
157       void update(const byte in[], size_t length);
158 
159       /**
160       * Add a message part.
161       * @param in the message part to add
162       */
update(const MemoryRegion<byte> & in)163       void update(const MemoryRegion<byte>& in) { update(&in[0], in.size()); }
164 
165       /**
166       * Get the signature of the so far processed message (provided by the
167       * calls to update()).
168       * @param rng the rng to use
169       * @return signature of the total message
170       */
171       SecureVector<byte> signature(RandomNumberGenerator& rng);
172 
173       /**
174       * Set the output format of the signature.
175       * @param format the signature format to use
176       */
set_output_format(Signature_Format format)177       void set_output_format(Signature_Format format) { sig_format = format; }
178 
179       /**
180       * Construct a PK Signer.
181       * @param key the key to use inside this signer
182       * @param emsa the EMSA to use
183       * An example would be "EMSA1(SHA-224)".
184       * @param format the signature format to use
185       * @param prot says if fault protection should be enabled
186       */
187       PK_Signer(const Private_Key& key,
188                 const std::string& emsa,
189                 Signature_Format format = IEEE_1363,
190                 Fault_Protection prot = ENABLE_FAULT_PROTECTION);
191 
~PK_Signer()192       ~PK_Signer() { delete op; delete verify_op; delete emsa; }
193    private:
194       bool self_test_signature(const MemoryRegion<byte>& msg,
195                                const MemoryRegion<byte>& sig) const;
196 
PK_Signer(const PK_Signer &)197       PK_Signer(const PK_Signer&) {}
198       PK_Signer& operator=(const PK_Signer&) { return *this; }
199 
200       PK_Ops::Signature* op;
201       PK_Ops::Verification* verify_op;
202       EMSA* emsa;
203       Signature_Format sig_format;
204    };
205 
206 /**
207 * Public Key Verifier. Use the verify_message() functions for small
208 * messages. Use multiple calls update() to process large messages and
209 * verify the signature by finally calling check_signature().
210 */
211 class BOTAN_DLL PK_Verifier
212    {
213    public:
214       /**
215       * Verify a signature.
216       * @param msg the message that the signature belongs to, as a byte array
217       * @param msg_length the length of the above byte array msg
218       * @param sig the signature as a byte array
219       * @param sig_length the length of the above byte array sig
220       * @return true if the signature is valid
221       */
222       bool verify_message(const byte msg[], size_t msg_length,
223                           const byte sig[], size_t sig_length);
224       /**
225       * Verify a signature.
226       * @param msg the message that the signature belongs to
227       * @param sig the signature
228       * @return true if the signature is valid
229       */
verify_message(const MemoryRegion<byte> & msg,const MemoryRegion<byte> & sig)230       bool verify_message(const MemoryRegion<byte>& msg,
231                           const MemoryRegion<byte>& sig)
232          {
233          return verify_message(&msg[0], msg.size(),
234                                &sig[0], sig.size());
235          }
236 
237       /**
238       * Add a message part (single byte) of the message corresponding to the
239       * signature to be verified.
240       * @param in the byte to add
241       */
update(byte in)242       void update(byte in) { update(&in, 1); }
243 
244       /**
245       * Add a message part of the message corresponding to the
246       * signature to be verified.
247       * @param msg_part the new message part as a byte array
248       * @param length the length of the above byte array
249       */
250       void update(const byte msg_part[], size_t length);
251 
252       /**
253       * Add a message part of the message corresponding to the
254       * signature to be verified.
255       * @param in the new message part
256       */
update(const MemoryRegion<byte> & in)257       void update(const MemoryRegion<byte>& in)
258          { update(&in[0], in.size()); }
259 
260       /**
261       * Check the signature of the buffered message, i.e. the one build
262       * by successive calls to update.
263       * @param sig the signature to be verified as a byte array
264       * @param length the length of the above byte array
265       * @return true if the signature is valid, false otherwise
266       */
267       bool check_signature(const byte sig[], size_t length);
268 
269       /**
270       * Check the signature of the buffered message, i.e. the one build
271       * by successive calls to update.
272       * @param sig the signature to be verified
273       * @return true if the signature is valid, false otherwise
274       */
check_signature(const MemoryRegion<byte> & sig)275       bool check_signature(const MemoryRegion<byte>& sig)
276          {
277          return check_signature(&sig[0], sig.size());
278          }
279 
280       /**
281       * Set the format of the signatures fed to this verifier.
282       * @param format the signature format to use
283       */
284       void set_input_format(Signature_Format format);
285 
286       /**
287       * Construct a PK Verifier.
288       * @param pub_key the public key to verify against
289       * @param emsa the EMSA to use (eg "EMSA3(SHA-1)")
290       * @param format the signature format to use
291       */
292       PK_Verifier(const Public_Key& pub_key,
293                   const std::string& emsa,
294                   Signature_Format format = IEEE_1363);
295 
~PK_Verifier()296       ~PK_Verifier() { delete op; delete emsa; }
297    private:
PK_Verifier(const PK_Verifier &)298       PK_Verifier(const PK_Verifier&) {}
299       PK_Verifier& operator=(const PK_Verifier&) { return *this; }
300 
301       bool validate_signature(const MemoryRegion<byte>& msg,
302                               const byte sig[], size_t sig_len);
303 
304       PK_Ops::Verification* op;
305       EMSA* emsa;
306       Signature_Format sig_format;
307    };
308 
309 /**
310 * Key used for key agreement
311 */
312 class BOTAN_DLL PK_Key_Agreement
313    {
314    public:
315 
316       /*
317       * Perform Key Agreement Operation
318       * @param key_len the desired key output size
319       * @param in the other parties key
320       * @param in_len the length of in in bytes
321       * @param params extra derivation params
322       * @param params_len the length of params in bytes
323       */
324       SymmetricKey derive_key(size_t key_len,
325                               const byte in[],
326                               size_t in_len,
327                               const byte params[],
328                               size_t params_len) const;
329 
330       /*
331       * Perform Key Agreement Operation
332       * @param key_len the desired key output size
333       * @param in the other parties key
334       * @param in_len the length of in in bytes
335       * @param params extra derivation params
336       * @param params_len the length of params in bytes
337       */
derive_key(size_t key_len,const MemoryRegion<byte> & in,const byte params[],size_t params_len)338       SymmetricKey derive_key(size_t key_len,
339                               const MemoryRegion<byte>& in,
340                               const byte params[],
341                               size_t params_len) const
342          {
343          return derive_key(key_len, &in[0], in.size(),
344                            params, params_len);
345          }
346 
347       /*
348       * Perform Key Agreement Operation
349       * @param key_len the desired key output size
350       * @param in the other parties key
351       * @param in_len the length of in in bytes
352       * @param params extra derivation params
353       */
354       SymmetricKey derive_key(size_t key_len,
355                               const byte in[], size_t in_len,
356                               const std::string& params = "") const
357          {
358          return derive_key(key_len, in, in_len,
359                            reinterpret_cast<const byte*>(params.data()),
360                            params.length());
361          }
362 
363       /*
364       * Perform Key Agreement Operation
365       * @param key_len the desired key output size
366       * @param in the other parties key
367       * @param params extra derivation params
368       */
369       SymmetricKey derive_key(size_t key_len,
370                               const MemoryRegion<byte>& in,
371                               const std::string& params = "") const
372          {
373          return derive_key(key_len, &in[0], in.size(),
374                            reinterpret_cast<const byte*>(params.data()),
375                            params.length());
376          }
377 
378       /**
379       * Construct a PK Key Agreement.
380       * @param key the key to use
381       * @param kdf name of the KDF to use (or 'Raw' for no KDF)
382       */
383       PK_Key_Agreement(const PK_Key_Agreement_Key& key,
384                        const std::string& kdf);
385 
~PK_Key_Agreement()386       ~PK_Key_Agreement() { delete op; delete kdf; }
387    private:
PK_Key_Agreement(const PK_Key_Agreement_Key &)388       PK_Key_Agreement(const PK_Key_Agreement_Key&) {}
389       PK_Key_Agreement& operator=(const PK_Key_Agreement&) { return *this; }
390 
391       PK_Ops::Key_Agreement* op;
392       KDF* kdf;
393    };
394 
395 /**
396 * Encryption with an MR algorithm and an EME.
397 */
398 class BOTAN_DLL PK_Encryptor_EME : public PK_Encryptor
399    {
400    public:
401       size_t maximum_input_size() const;
402 
403       /**
404       * Construct an instance.
405       * @param key the key to use inside the decryptor
406       * @param eme the EME to use
407       */
408       PK_Encryptor_EME(const Public_Key& key,
409                        const std::string& eme);
410 
~PK_Encryptor_EME()411       ~PK_Encryptor_EME() { delete op; delete eme; }
412    private:
413       SecureVector<byte> enc(const byte[], size_t,
414                              RandomNumberGenerator& rng) const;
415 
416       PK_Ops::Encryption* op;
417       const EME* eme;
418    };
419 
420 /**
421 * Decryption with an MR algorithm and an EME.
422 */
423 class BOTAN_DLL PK_Decryptor_EME : public PK_Decryptor
424    {
425    public:
426      /**
427       * Construct an instance.
428       * @param key the key to use inside the encryptor
429       * @param eme the EME to use
430       */
431       PK_Decryptor_EME(const Private_Key& key,
432                        const std::string& eme);
433 
~PK_Decryptor_EME()434       ~PK_Decryptor_EME() { delete op; delete eme; }
435    private:
436       SecureVector<byte> dec(const byte[], size_t) const;
437 
438       PK_Ops::Decryption* op;
439       const EME* eme;
440    };
441 
442 /*
443 * Typedefs for compatability with 1.8
444 */
445 typedef PK_Encryptor_EME PK_Encryptor_MR_with_EME;
446 typedef PK_Decryptor_EME PK_Decryptor_MR_with_EME;
447 
448 }
449 
450 #endif
451