Crypto.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #include "Crypto.h"
  2. CryptoMbedTLS::CryptoMbedTLS()
  3. {
  4. mbedtls_aes_init(&aesCtx);
  5. }
  6. CryptoMbedTLS::~CryptoMbedTLS()
  7. {
  8. mbedtls_aes_free(&aesCtx);
  9. }
  10. std::vector<uint8_t> CryptoMbedTLS::base64Decode(const std::string &data)
  11. {
  12. // Calculate max decode length
  13. size_t requiredSize;
  14. mbedtls_base64_encode(nullptr, 0, &requiredSize, (unsigned char *)data.c_str(), data.size());
  15. std::vector<uint8_t> output(requiredSize);
  16. size_t outputLen = 0;
  17. mbedtls_base64_decode(output.data(), requiredSize, &outputLen, (unsigned char *)data.c_str(), data.size());
  18. return std::vector<uint8_t>(output.begin(), output.begin() + outputLen);
  19. }
  20. std::string CryptoMbedTLS::base64Encode(const std::vector<uint8_t> &data)
  21. {
  22. // Calculate max output length
  23. size_t requiredSize;
  24. mbedtls_base64_encode(nullptr, 0, &requiredSize, data.data(), data.size());
  25. std::vector<uint8_t> output(requiredSize);
  26. size_t outputLen = 0;
  27. mbedtls_base64_encode(output.data(), requiredSize, &outputLen, data.data(), data.size());
  28. return std::string(output.begin(), output.begin() + outputLen);
  29. }
  30. // Sha1
  31. void CryptoMbedTLS::sha1Init()
  32. {
  33. // Init mbedtls md context, pick sha1
  34. mbedtls_md_init(&sha1Context);
  35. mbedtls_md_setup(&sha1Context, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1);
  36. mbedtls_md_starts(&sha1Context);
  37. }
  38. void CryptoMbedTLS::sha1Update(const std::string &s)
  39. {
  40. sha1Update(std::vector<uint8_t>(s.begin(), s.end()));
  41. }
  42. void CryptoMbedTLS::sha1Update(const std::vector<uint8_t> &vec)
  43. {
  44. mbedtls_md_update(&sha1Context, vec.data(), vec.size());
  45. }
  46. std::vector<uint8_t> CryptoMbedTLS::sha1FinalBytes()
  47. {
  48. std::vector<uint8_t> digest(20); // SHA1 digest size
  49. mbedtls_md_finish(&sha1Context, digest.data());
  50. mbedtls_md_free(&sha1Context);
  51. return digest;
  52. }
  53. std::string CryptoMbedTLS::sha1Final()
  54. {
  55. auto digest = sha1FinalBytes();
  56. return std::string(digest.begin(), digest.end());
  57. }
  58. // HMAC SHA1
  59. std::vector<uint8_t> CryptoMbedTLS::sha1HMAC(const std::vector<uint8_t> &inputKey, const std::vector<uint8_t> &message)
  60. {
  61. std::vector<uint8_t> digest(20); // SHA1 digest size
  62. sha1Init();
  63. mbedtls_md_hmac_starts(&sha1Context, inputKey.data(), inputKey.size());
  64. mbedtls_md_hmac_update(&sha1Context, message.data(), message.size());
  65. mbedtls_md_hmac_finish(&sha1Context, digest.data());
  66. mbedtls_md_free(&sha1Context);
  67. return digest;
  68. }
  69. // AES CTR
  70. void CryptoMbedTLS::aesCTRXcrypt(const std::vector<uint8_t> &key, std::vector<uint8_t> &iv, uint8_t* buffer, size_t nbytes)
  71. {
  72. // needed for internal cache
  73. size_t off = 0;
  74. unsigned char streamBlock[16] = {0};
  75. // set IV
  76. mbedtls_aes_setkey_enc(&aesCtx, key.data(), key.size() * 8);
  77. // Perform decrypt
  78. mbedtls_aes_crypt_ctr(&aesCtx,
  79. nbytes,
  80. &off,
  81. iv.data(),
  82. streamBlock,
  83. buffer,
  84. buffer);
  85. }
  86. void CryptoMbedTLS::aesECBdecrypt(const std::vector<uint8_t> &key, std::vector<uint8_t> &data)
  87. {
  88. // Set 192bit key
  89. mbedtls_aes_setkey_dec(&aesCtx, key.data(), key.size() * 8);
  90. // Mbedtls's decrypt only works on 16 byte blocks
  91. for (unsigned int x = 0; x < data.size() / 16; x++)
  92. {
  93. // Perform finalize
  94. mbedtls_aes_crypt_ecb(&aesCtx,
  95. MBEDTLS_AES_DECRYPT,
  96. data.data() + (x * 16),
  97. data.data() + (x * 16));
  98. }
  99. }
  100. // PBKDF2
  101. std::vector<uint8_t> CryptoMbedTLS::pbkdf2HmacSha1(const std::vector<uint8_t> &password, const std::vector<uint8_t> &salt, int iterations, int digestSize)
  102. {
  103. auto digest = std::vector<uint8_t>(digestSize);
  104. // Init sha context
  105. sha1Init();
  106. mbedtls_pkcs5_pbkdf2_hmac(&sha1Context, password.data(), password.size(), salt.data(), salt.size(), iterations, digestSize, digest.data());
  107. // Free sha context
  108. mbedtls_md_free(&sha1Context);
  109. return digest;
  110. }
  111. void CryptoMbedTLS::dhInit()
  112. {
  113. privateKey = generateVectorWithRandomData(DH_KEY_SIZE);
  114. // initialize big num
  115. mbedtls_mpi prime, generator, res, privKey;
  116. mbedtls_mpi_init(&prime);
  117. mbedtls_mpi_init(&generator);
  118. mbedtls_mpi_init(&privKey);
  119. mbedtls_mpi_init(&res);
  120. // Read bin into big num mpi
  121. mbedtls_mpi_read_binary(&prime, DHPrime, sizeof(DHPrime));
  122. mbedtls_mpi_read_binary(&generator, DHGenerator, sizeof(DHGenerator));
  123. mbedtls_mpi_read_binary(&privKey, privateKey.data(), DH_KEY_SIZE);
  124. // perform diffie hellman G^X mod P
  125. mbedtls_mpi_exp_mod(&res, &generator, &privKey, &prime, NULL);
  126. // Write generated public key to vector
  127. this->publicKey = std::vector<uint8_t>(DH_KEY_SIZE);
  128. mbedtls_mpi_write_binary(&res, publicKey.data(), DH_KEY_SIZE);
  129. // Release memory
  130. mbedtls_mpi_free(&prime);
  131. mbedtls_mpi_free(&generator);
  132. mbedtls_mpi_free(&privKey);
  133. mbedtls_mpi_free(&res);
  134. }
  135. std::vector<uint8_t> CryptoMbedTLS::dhCalculateShared(const std::vector<uint8_t> &remoteKey)
  136. {
  137. // initialize big num
  138. mbedtls_mpi prime, remKey, res, privKey;
  139. mbedtls_mpi_init(&prime);
  140. mbedtls_mpi_init(&remKey);
  141. mbedtls_mpi_init(&privKey);
  142. mbedtls_mpi_init(&res);
  143. // Read bin into big num mpi
  144. mbedtls_mpi_read_binary(&prime, DHPrime, sizeof(DHPrime));
  145. mbedtls_mpi_read_binary(&remKey, remoteKey.data(), remoteKey.size());
  146. mbedtls_mpi_read_binary(&privKey, privateKey.data(), DH_KEY_SIZE);
  147. // perform diffie hellman (G^Y)^X mod P (for shared secret)
  148. mbedtls_mpi_exp_mod(&res, &remKey, &privKey, &prime, NULL);
  149. auto sharedKey = std::vector<uint8_t>(DH_KEY_SIZE);
  150. mbedtls_mpi_write_binary(&res, sharedKey.data(), DH_KEY_SIZE);
  151. // Release memory
  152. mbedtls_mpi_free(&prime);
  153. mbedtls_mpi_free(&remKey);
  154. mbedtls_mpi_free(&privKey);
  155. mbedtls_mpi_free(&res);
  156. return sharedKey;
  157. }
  158. // Random stuff
  159. std::vector<uint8_t> CryptoMbedTLS::generateVectorWithRandomData(size_t length)
  160. {
  161. std::vector<uint8_t> randomVector(length);
  162. mbedtls_entropy_context entropy;
  163. mbedtls_ctr_drbg_context ctrDrbg;
  164. // Personification string
  165. const char *pers = "cspotGen";
  166. // init entropy and random num generator
  167. mbedtls_entropy_init(&entropy);
  168. mbedtls_ctr_drbg_init(&ctrDrbg);
  169. // Seed the generator
  170. mbedtls_ctr_drbg_seed(&ctrDrbg, mbedtls_entropy_func, &entropy,
  171. (const unsigned char *)pers,
  172. 7);
  173. // Generate random bytes
  174. mbedtls_ctr_drbg_random(&ctrDrbg, randomVector.data(), length);
  175. // Release memory
  176. mbedtls_entropy_free(&entropy);
  177. mbedtls_ctr_drbg_free(&ctrDrbg);
  178. return randomVector;
  179. }