CryptoMBedTLS.cpp 6.6 KB

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