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