aes_util.cc 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /* aes_util.c
  2. *
  3. */
  4. #include "src/libcrypto.h"
  5. #include "src/compat/compat.h"
  6. #include <bdlib/src/String.h>
  7. #define CRYPT_BLOCKSIZE AES_BLOCK_SIZE
  8. #define CRYPT_KEYBITS 256
  9. #define CRYPT_KEYSIZE (CRYPT_KEYBITS >> 3)
  10. AES_KEY e_key, d_key;
  11. /**
  12. * @brief Encrypt a string with AES 256 ECB
  13. * @param key The key to encrypt with
  14. * @param data The string to encrypt
  15. * @return A new, encrypted string
  16. */
  17. bd::String encrypt_string(const bd::String& key, const bd::String& data) {
  18. if (!key) return data;
  19. size_t len = data.length();
  20. char *bdata = (char*) aes_encrypt_ecb_binary(key.c_str(), (unsigned char*) data.c_str(), &len);
  21. bd::String encrypted(bdata, len);
  22. free(bdata);
  23. return encrypted;
  24. }
  25. /**
  26. * @brief Encrypt a string with AES 256 CBC
  27. * @param key The key to encrypt with
  28. * @param data The string to encrypt
  29. * @param IV The IV to use (WARNING: This is modified inplace)
  30. * @return A new, encrypted string
  31. */
  32. bd::String encrypt_string_cbc(const bd::String& key, bd::String data, bd::String IV) {
  33. if (!key) return data;
  34. // Add padding
  35. size_t padding = CRYPT_BLOCKSIZE;
  36. if (data.length() % CRYPT_BLOCKSIZE)
  37. padding = (CRYPT_BLOCKSIZE - (data.length() % CRYPT_BLOCKSIZE));
  38. // Pad with padding bytes of padding
  39. data.resize(data.length() + padding, padding);
  40. AES_set_encrypt_key((const unsigned char *) key.c_str(), CRYPT_KEYBITS, &e_key);
  41. AES_cbc_encrypt((const unsigned char*)data.data(), (unsigned char*)data.mdata(), data.length(), &e_key, (unsigned char*)IV.mdata(), AES_ENCRYPT);
  42. OPENSSL_cleanse(&e_key, sizeof(e_key));
  43. return data;
  44. }
  45. /**
  46. * @brief Decrypt an AES 256 ECB ciphered string
  47. * @param key The key to decrypt with
  48. * @param data The string to decrypt
  49. * @return A new, decrypted string
  50. */
  51. bd::String decrypt_string(const bd::String& key, const bd::String& data) {
  52. if (!key) return data;
  53. size_t len = data.length();
  54. char *bdata = (char*) aes_decrypt_ecb_binary(key.c_str(), (unsigned char*) data.c_str(), &len);
  55. bd::String decrypted(bdata, len);
  56. OPENSSL_cleanse(bdata, len);
  57. free(bdata);
  58. return decrypted;
  59. }
  60. /**
  61. * @brief Decrypt anAES 256 CBC ciphered string
  62. * @param key The key to decrypt with
  63. * @param data The string to decrypt
  64. * @param IV The IV to use (WARNING: This is modified inplace)
  65. * @return A new, decrypted string
  66. */
  67. bd::String decrypt_string_cbc(const bd::String& key, bd::String data, bd::String IV) {
  68. if (!key) return data;
  69. data.resize(data.length() - (data.length() % CRYPT_BLOCKSIZE));
  70. AES_set_decrypt_key((const unsigned char *) key.c_str(), CRYPT_KEYBITS, &d_key);
  71. AES_cbc_encrypt((const unsigned char*)data.data(), (unsigned char*)data.mdata(), data.length(), &d_key, (unsigned char*)IV.mdata(), AES_DECRYPT);
  72. OPENSSL_cleanse(&d_key, sizeof(d_key));
  73. // How much padding?
  74. size_t padding = data[data.length() - 1];
  75. if (!padding || padding > 16)
  76. data.resize(strlen((char*) data.c_str()));
  77. else
  78. data.resize(data.length() - padding);
  79. return data;
  80. }
  81. unsigned char *
  82. aes_encrypt_ecb_binary(const char *keydata, unsigned char *in, size_t *inlen)
  83. {
  84. size_t len = *inlen;
  85. int blocks = 0, block = 0;
  86. unsigned char *out = NULL;
  87. /* First pad indata to CRYPT_BLOCKSIZE multiple */
  88. if (len % CRYPT_BLOCKSIZE) /* more than 1 block? */
  89. len += (CRYPT_BLOCKSIZE - (len % CRYPT_BLOCKSIZE));
  90. out = (unsigned char *) calloc(1, len + 1);
  91. memcpy(out, in, *inlen);
  92. *inlen = len;
  93. if (!keydata || !*keydata) {
  94. /* No key, no encryption */
  95. memcpy(out, in, len);
  96. } else {
  97. char key[CRYPT_KEYSIZE + 1] = "";
  98. strlcpy(key, keydata, sizeof(key));
  99. AES_set_encrypt_key((const unsigned char *) key, CRYPT_KEYBITS, &e_key);
  100. /* Now loop through the blocks and crypt them */
  101. blocks = len / CRYPT_BLOCKSIZE;
  102. for (block = blocks - 1; block >= 0; --block)
  103. AES_encrypt(&out[block * CRYPT_BLOCKSIZE], &out[block * CRYPT_BLOCKSIZE], &e_key);
  104. OPENSSL_cleanse(key, sizeof(key));
  105. OPENSSL_cleanse(&e_key, sizeof(e_key));
  106. }
  107. out[len] = 0;
  108. return out;
  109. }
  110. unsigned char *
  111. aes_decrypt_ecb_binary(const char *keydata, unsigned char *in, size_t *len)
  112. {
  113. int blocks = 0, block = 0;
  114. unsigned char *out = NULL;
  115. *len -= *len % CRYPT_BLOCKSIZE;
  116. out = (unsigned char *) calloc(1, *len + 1);
  117. memcpy(out, in, *len);
  118. if (!keydata || !*keydata) {
  119. /* No key, no decryption */
  120. } else {
  121. /* Init/fetch key */
  122. char key[CRYPT_KEYSIZE + 1] = "";
  123. strlcpy(key, keydata, sizeof(key));
  124. AES_set_decrypt_key((const unsigned char *) key, CRYPT_KEYBITS, &d_key);
  125. /* Now loop through the blocks and decrypt them */
  126. blocks = *len / CRYPT_BLOCKSIZE;
  127. for (block = blocks - 1; block >= 0; --block)
  128. AES_decrypt(&out[block * CRYPT_BLOCKSIZE], &out[block * CRYPT_BLOCKSIZE], &d_key);
  129. OPENSSL_cleanse(key, sizeof(key));
  130. OPENSSL_cleanse(&d_key, sizeof(d_key));
  131. }
  132. *len = strlen((char*) out);
  133. out[*len] = 0;
  134. return out;
  135. }
  136. unsigned char *
  137. aes_encrypt_cbc_binary(const char *keydata, unsigned char *in, size_t *inlen, unsigned char *ivec)
  138. {
  139. size_t len = *inlen;
  140. unsigned char *out = NULL;
  141. /* First pad indata to CRYPT_BLOCKSIZE multiple */
  142. size_t padding = 16;
  143. if (len % CRYPT_BLOCKSIZE) /* more than 1 block? */
  144. padding = (CRYPT_BLOCKSIZE - (len % CRYPT_BLOCKSIZE));
  145. len += padding;
  146. out = (unsigned char *) calloc(1, len);
  147. memset(out + *inlen, padding, padding);
  148. memcpy(out, in, *inlen);
  149. *inlen = len;
  150. if (!keydata || !*keydata) {
  151. /* No key, no encryption */
  152. memcpy(out, in, len);
  153. } else {
  154. char key[CRYPT_KEYSIZE + 1] = "";
  155. strlcpy(key, keydata, sizeof(key));
  156. AES_set_encrypt_key((const unsigned char *) key, CRYPT_KEYBITS, &e_key);
  157. AES_cbc_encrypt(out, out, len, &e_key, ivec, AES_ENCRYPT);
  158. OPENSSL_cleanse(key, sizeof(key));
  159. OPENSSL_cleanse(&e_key, sizeof(e_key));
  160. }
  161. return out;
  162. }
  163. unsigned char *
  164. aes_decrypt_cbc_binary(const char *keydata, unsigned char *in, size_t *len, unsigned char* ivec)
  165. {
  166. unsigned char *out = NULL;
  167. *len -= *len % CRYPT_BLOCKSIZE;
  168. out = (unsigned char *) calloc(1, *len + 1);
  169. memcpy(out, in, *len);
  170. if (!keydata || !*keydata) {
  171. /* No key, no decryption */
  172. } else {
  173. /* Init/fetch key */
  174. char key[CRYPT_KEYSIZE + 1] = "";
  175. strlcpy(key, keydata, sizeof(key));
  176. AES_set_decrypt_key((const unsigned char *) key, CRYPT_KEYBITS, &d_key);
  177. AES_cbc_encrypt(out, out, *len, &d_key, ivec, AES_DECRYPT);
  178. OPENSSL_cleanse(key, sizeof(key));
  179. OPENSSL_cleanse(&d_key, sizeof(d_key));
  180. }
  181. // How much padding?
  182. size_t padding = out[*len - 1];
  183. if (!padding)
  184. *len = strlen((char*) out);
  185. else
  186. *len -= padding;
  187. return out;
  188. }
  189. /* vim: set sts=2 sw=2 ts=8 et: */