1 /**
2  * @file cryptopp.h
3  * @brief Crypto layer using Crypto++
4  *
5  * (c) 2013-2014 by Mega Limited, Auckland, New Zealand
6  *
7  * This file is part of the MEGA SDK - Client Access Engine.
8  *
9  * Applications using the MEGA API must present a valid application key
10  * and comply with the the rules set forth in the Terms of Service.
11  *
12  * The MEGA SDK is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  *
16  * @copyright Simplified (2-clause) BSD License.
17  *
18  * You should have received a copy of the license along with this
19  * program.
20  */
21 
22 #ifdef USE_CRYPTOPP
23 #ifndef CRYPTOCRYPTOPP_H
24 #define CRYPTOCRYPTOPP_H 1
25 
26 #include <cryptopp/cryptlib.h>
27 #include <cryptopp/modes.h>
28 #include <cryptopp/ccm.h>
29 #include <cryptopp/gcm.h>
30 #include <cryptopp/integer.h>
31 #include <cryptopp/aes.h>
32 #include <cryptopp/osrng.h>
33 #include <cryptopp/sha.h>
34 #include <cryptopp/rsa.h>
35 #include <cryptopp/crc.h>
36 #include <cryptopp/nbtheory.h>
37 #include <cryptopp/algparam.h>
38 #include <cryptopp/hmac.h>
39 #include <cryptopp/pwdbased.h>
40 
41 namespace mega {
42 
43 /**
44  * @brief A generic pseudo-random number generator.
45  */
46 class MEGA_API PrnGen : public CryptoPP::AutoSeededRandomPool
47 {
48 public:
49     /**
50      * @brief Generates a block of random bytes of length `len` into a buffer
51      *        `buf`.
52      *
53      * @param buf The buffer that takes the generated random bytes. Ensure that
54      *     the buffer is of sufficient size to take `len` bytes.
55      * @param len The number of random bytes to generate.
56      * @return Void.
57      */
58     void genblock(byte* buf, size_t len);
59 
60     /**
61      * @brief Generates a random integer between 0 ... max - 1.
62      *
63      * @param max The maximum of which the number is to generate under.
64      * @return The random number generated.
65      */
66     uint32_t genuint32(uint64_t max);
67 };
68 
69 // symmetric cryptography: AES-128
70 class MEGA_API SymmCipher
71 {
72 public:
73 
74 private:
75     CryptoPP::ECB_Mode<CryptoPP::AES>::Encryption aesecb_e;
76     CryptoPP::ECB_Mode<CryptoPP::AES>::Decryption aesecb_d;
77 
78     CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption aescbc_e;
79     CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption aescbc_d;
80 
81     CryptoPP::CCM<CryptoPP::AES, 16>::Encryption aesccm16_e;
82     CryptoPP::CCM<CryptoPP::AES, 16>::Decryption aesccm16_d;
83 
84     CryptoPP::CCM<CryptoPP::AES, 8>::Encryption aesccm8_e;
85     CryptoPP::CCM<CryptoPP::AES, 8>::Decryption aesccm8_d;
86 
87     CryptoPP::GCM<CryptoPP::AES>::Encryption aesgcm_e;
88     CryptoPP::GCM<CryptoPP::AES>::Decryption aesgcm_d;
89 
90 public:
91     static byte zeroiv[CryptoPP::AES::BLOCKSIZE];
92 
93     static const int BLOCKSIZE = CryptoPP::AES::BLOCKSIZE;
94     static const int KEYLENGTH = CryptoPP::AES::BLOCKSIZE;
95 
96     byte key[KEYLENGTH];
97 
98     typedef uint64_t ctr_iv;
99 
100     void setkey(const byte*, int = 1);
101     bool setkey(const std::string*);
102 
103     /**
104      * @brief Encrypt symmetrically using AES in ECB mode.
105      *
106      * @param data Data to be encrypted.
107      * @param dst Target buffer to encrypt to. If NULL, encrypt in-place (to `data`).
108      * @param len Length of data to be encrypted in bytes. Defaults to
109      *     SymCipher::BLOCKSIZE.
110      * @return Void.
111      */
112     void ecb_encrypt(byte*, byte* = NULL, size_t = BLOCKSIZE);
113 
114     /**
115      * @brief Decrypt symmetrically using AES in ECB mode.
116      *
117      * @param data Data to be decrypted (in-place).
118      * @param len Length of data to be decrypted in bytes. Defaults to
119      *     SymCipher::BLOCKSIZE.
120      * @return Void.
121      */
122     void ecb_decrypt(byte*, size_t = BLOCKSIZE);
123 
124     /**
125      * @brief Encrypt symmetrically using AES in CBC mode.
126      *
127      * The size of the IV is one block in AES-128 (16 bytes).
128      *
129      * @param data Data to be encrypted (encryption in-place).
130      * @param len Length of data to be encrypted in bytes.
131      * @param iv Initialisation vector to use. Choose randomly and never re-use.
132      * @return Void.
133      */
134     void cbc_encrypt(byte* data, size_t len, const byte* iv = NULL);
135 
136     /**
137      * @brief Decrypt symmetrically using AES in CBC mode.
138      *
139      * The size of the IV is one block in AES-128 (16 bytes).
140      *
141      * @param data Data to be decrypted (encryption in-place).
142      * @param len Length of cipher text to be decrypted in bytes.
143      * @param iv Initialisation vector.
144      * @return Void.
145      */
146     void cbc_decrypt(byte* data, size_t len, const byte* iv = NULL);
147 
148     /**
149      * @brief Encrypt symmetrically using AES in CBC mode and pkcs padding
150      *
151      * The size of the IV is one block in AES-128 (16 bytes).
152      *
153      * @param data Data to be encrypted
154      * @param iv Initialisation vector.
155      * @param result Encrypted message
156      * @return Void.
157      */
158     void cbc_encrypt_pkcs_padding(const std::string *data, const byte* iv, std::string *result);
159 
160     /**
161      * @brief Decrypt symmetrically using AES in CBC mode and pkcs padding
162      *
163      * The size of the IV is one block in AES-128 (16 bytes).
164      *
165      * @param data Data to be decrypted
166      * @param iv Initialisation vector.
167      * @param result Decrypted message
168      * @return Void.
169      */
170     void cbc_decrypt_pkcs_padding(const std::string *data, const byte* iv, std::string *result);
171 
172     /**
173      * Authenticated symmetric encryption using AES in CCM mode (counter with CBC-MAC).
174      *
175      * The size of the IV limits the maximum length of data. A length of 12 bytes
176      * allows for up to 16.7 MB data size. Smaller IVs lead to larger maximum data
177      * sizes.
178      *
179      * @param data Data to be encrypted.
180      * @param iv Initialisation vector or nonce to use for encryption. Choose randomly
181      * and never re-use. See note on size above.
182      * @param ivlen Length of IV. Allowed sizes are 7, 8, 9, 10, 11, 12, and 13 bytes.
183      * @param taglen Length of expected authentication tag. Allowed sizes are 8 and 16 bytes.
184      * @param result Encrypted data, including the authentication tag.
185      */
186     void ccm_encrypt(const std::string *data, const byte *iv, unsigned ivlen, unsigned taglen, std::string *result);
187 
188     /**
189      * @brief Authenticated symmetric decryption using AES in CCM mode (counter with CBC-MAC).
190      *
191      * The size of the IV limits the maximum length of data. A length of 12 bytes
192      * allows for up to 16.7 MB data size. Smaller IVs lead to larger maximum data
193      * sizes.
194      *
195      * @param data Data to be decrypted.
196      * @param iv Initialisation vector or nonce.
197      * @param ivlen Length of IV. Allowed sizes are 7, 8, 9, 10, 11, 12, and 13 bytes.
198      * @param taglen Length of expected authentication tag. Allowed sizes are 8 and 16 bytes.
199      * @param result Decrypted data, not including the authentication tag.
200      */
201     bool ccm_decrypt(const std::string *data, const byte *iv, unsigned ivlen, unsigned taglen, std::string *result);
202 
203     /**
204      * @brief Authenticated symmetric encryption using AES in GCM mode.
205      *
206      * The size of the IV limits the maximum length of data. A length of 12 bytes
207      * allows for up to 16.7 MB data size. Smaller IVs lead to larger maximum data
208      * sizes.
209      *
210      * @param data Data to be encrypted.
211      * @param iv Initialisation vector or nonce to use for encryption. Choose randomly
212      * and never re-use. See note on size above.
213      * @param ivlen Length of IV. Allowed sizes are 7, 8, 9, 10, 11, 12, and 13 bytes.
214      * @param taglen Length of expected authentication tag.
215      * @param result Encrypted data, including the authentication tag.
216      */
217     void gcm_encrypt(const std::string *data, const byte *iv, unsigned ivlen, unsigned taglen, std::string *result);
218 
219     /**
220      * @brief Authenticated symmetric decryption using AES in GCM mode.
221      *
222      * The size of the IV limits the maximum length of data. A length of 12 bytes
223      * allows for up to 16.7 MB data size. Smaller IVs lead to larger maximum data
224      * sizes.
225      *
226      * @param data Data to be decrypted.
227      * @param iv Initialisation vector or nonce.
228      * @param ivlen Length of IV. Allowed sizes are 7, 8, 9, 10, 11, 12, and 13 bytes.
229      * @param taglen Length of expected authentication tag. Allowed sizes are 8 and 16 bytes.
230      * @param result Decrypted data, not including the authentication tag.
231      */
232     bool gcm_decrypt(const std::string *data, const byte *iv, unsigned ivlen, unsigned taglen, std::string *result);
233 
234     /**
235      * @brief Serialize key for compatibility with the webclient
236      *
237      * The key is serialized to a JSON array like this one:
238      * "[669070598,-250738112,2059051645,-1942187558]"
239      *
240      * @param d string that receives the serialized key
241      */
242     void serializekeyforjs(std::string *);
243 
244     void ctr_crypt(byte *, unsigned, m_off_t, ctr_iv, byte *, bool, bool initmac = true);
245 
246     static void setint64(int64_t, byte*);
247 
248     static void xorblock(const byte*, byte*);
249     static void xorblock(const byte*, byte*, int);
250 
251     static void incblock(byte*, unsigned = BLOCKSIZE);
252 
SymmCipher()253     SymmCipher() { }
254     SymmCipher(const SymmCipher& ref);
255     SymmCipher& operator=(const SymmCipher& ref);
256     SymmCipher(const byte*);
257 };
258 
259 /**
260  * @brief Asymmetric cryptography using RSA.
261  */
262 class MEGA_API AsymmCipher
263 {
264     int decodeintarray(CryptoPP::Integer*, int, const byte*, int);
265 
266 public:
267     enum { PRIV_P, PRIV_Q, PRIV_D, PRIV_U };
268     enum { PUB_PQ, PUB_E };
269 
270     static const int PRIVKEY = 4;
271     static const int PUBKEY = 2;
272 
273     CryptoPP::Integer key[PRIVKEY];
274     unsigned int padding;
275 
276     static const int MAXKEYLENGTH = 1026;   // in bytes, allows for RSA keys up
277                                             // to 8192 bits
278 
279     /**
280      * @brief Sets a key from a buffer.
281      *
282      * @param numints Number of integers for key type (AsymmCipher::PRIVKEY
283      *     or AsymmCipher::PUBKEY).
284      * @param data Buffer containing the serialised key.
285      * @param len Length of data in buffer.
286      * @return Number of bytes encrypted, 0 on failure.
287      */
288     int setkey(int numints, const byte* data, int len);
289 
290     /**
291      * @brief Reset the existing key
292      */
293     void resetkey();
294 
295     /**
296      * @brief Simple check for validity of key pair.
297      *
298      * @param keytype Key type indication by number of integers for key type
299      *     (AsymmCipher::PRIVKEY or AsymmCipher::PUBKEY).
300      * @return 0 on an invalid key pair.
301      */
302     int isvalid(int keytype = PUBKEY);
303 
304     /**
305      * @brief Encrypts a randomly padded plain text into a buffer.
306      *
307      * @param rng Reference to the random block generator
308      * @param plain The plain text to encrypt.
309      * @param plainlen Length of the plain text.
310      * @param buf Buffer to take the cipher text..
311      * @param buflen Length of the cipher text.
312      * @return Number of bytes encrypted, 0 on failure.
313      */
314     int encrypt(PrnGen &rng, const byte* plain, size_t plainlen, byte* buf, size_t buflen);
315 
316     /**
317      * @brief Decrypts a cipher text into a buffer and strips random padding.
318      *
319      * @param cipher The cipher text to encrypt.
320      * @param cipherlen Length of the cipher text.
321      * @param buf Buffer to take the plain text..
322      * @param buflen Length of the plain text.
323      * @return Always returns 1.
324      */
325     int decrypt(const byte* cipher, size_t cipherlen, byte* buf, size_t buflen);
326 
327     /**
328      * @brief Encrypts a plain text into a buffer.
329      *
330      * @param plain The plain text to encrypt.
331      * @param plainlen Length of the plain text.
332      * @param buf Buffer to take the cipher text..
333      * @param buflen Length of the cipher text.
334      * @return Number of bytes encrypted, 0 on failure.
335      */
336     unsigned rawencrypt(const byte* plain, size_t plainlen, byte* buf, size_t buflen);
337 
338     /**
339      * @brief Decrypts a cipher text into a buffer.
340      *
341      * @param cipher The cipher text to encrypt.
342      * @param cipherlen Length of the cipher text.
343      * @param buf Buffer to take the plain text..
344      * @param buflen Length of the plain text.
345      * @return Always returns 1.
346      */
347     unsigned rawdecrypt(const byte* cipher, size_t cipherlen, byte* buf, size_t buflen);
348 
349     static void serializeintarray(CryptoPP::Integer*, int, std::string*, bool headers = true);
350 
351     /**
352      * @brief Serialises a key to a string.
353      *
354      * @param d String to take the key.
355      * @param keytype Key type indication by number of integers for key type
356      *     (AsymmCipher::PRIVKEY or AsymmCipher::PUBKEY).
357      * @return Void.
358      */
359     void serializekey(std::string* d, int keytype);
360 
361     /**
362      * @brief Serialize public key for compatibility with the webclient.
363      *
364      * It also add padding (PUB_E size is forced to 4 bytes) in case the
365      * of the key, at reception from server, indicates it has zero-padding.
366      *
367      * @param d String to take the serialized key without size-headers
368      * @return Void.
369      */
370     void serializekeyforjs(std::string& d);
371 
372     /**
373      * @brief Generates an RSA key pair of a given key size.
374      *
375      * @param rng Reference to the random block generator
376      * @param privk Private key.
377      * @param pubk Public key.
378      * @param size Size of key to generate in bits (key strength).
379      * @return Always returns 1.
380      */
381     void genkeypair(PrnGen &rng, CryptoPP::Integer* privk, CryptoPP::Integer* pubk, int size);
382 };
383 
384 class MEGA_API Hash
385 {
386     CryptoPP::SHA512 hash;
387 
388 public:
389     void add(const byte*, unsigned);
390     void get(std::string*);
391 };
392 
393 class MEGA_API HashSHA256
394 {
395     CryptoPP::SHA256 hash;
396 
397 public:
398     void add(const byte*, unsigned int);
399     void get(std::string*);
400 };
401 
402 class MEGA_API HashCRC32
403 {
404     CryptoPP::CRC32 hash;
405 
406 public:
407     void add(const byte*, unsigned);
408     void get(byte*);
409 };
410 
411 /**
412  * @brief HMAC-SHA256 generator
413  */
414 class MEGA_API HMACSHA256
415 {
416     CryptoPP::HMAC< CryptoPP::SHA256 > hmac;
417 
418 public:
419     /**
420      * @brief Constructor
421      * @param key HMAC key
422      * @param length Key length
423      */
424     HMACSHA256(const byte *key, size_t length);
425 
426     /**
427      * @brief Add data to the HMAC
428      * @param data Data to add
429      * @param len Data length
430      */
431     void add(const byte* data, size_t len);
432 
433     /**
434      * @brief Compute the HMAC for the current message
435      * @param out The HMAC-SHA256 will be returned in the first 32 bytes of this buffer
436      */
437     void get(byte *out);
438 };
439 
440 /**
441  * @brief HMAC-SHA512 generator
442  */
443 class MEGA_API PBKDF2_HMAC_SHA512
444 {
445     CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA512> pbkdf2;
446 
447 public:
448     PBKDF2_HMAC_SHA512();
449     void deriveKey(byte* derivedkey, size_t derivedkeyLen,
450                    byte* pwd, size_t pwdLen,
451                    byte* salt, size_t saltLen, unsigned int iterations);
452 };
453 
454 } // namespace
455 
456 #endif
457 #endif
458