at_aes_crypt.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /*
  2. * Copyright (C) 2014-2016 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "at_aes_crypt.h"
  17. #include "at_log.h"
  18. /*
  19. * The OpenSSL 1.1.0 API requires we allocate these dynamically. Cache them
  20. * globally to avoid alocator thrash and the potential for another dynamic
  21. * failure.
  22. */
  23. static EVP_CIPHER_CTX *cipher_ctx;
  24. static HMAC_CTX *hmac_ctx;
  25. static void crypt_init(void) {
  26. cipher_ctx = EVP_CIPHER_CTX_new();
  27. assert(cipher_ctx);
  28. }
  29. static void hmac_init(void) {
  30. hmac_ctx = HMAC_CTX_new();
  31. assert(hmac_ctx);
  32. }
  33. static void crypt_shutdown(void) {
  34. EVP_CIPHER_CTX_free(cipher_ctx);
  35. cipher_ctx = NULL;
  36. }
  37. static void hmac_shutdown(void) {
  38. HMAC_CTX_free(hmac_ctx);
  39. hmac_ctx = NULL;
  40. }
  41. /**
  42. * crypt - Helper function for encrypt and decrypt.
  43. * @key: Key object.
  44. * @data_in_out: Data to encrypt or decrypt.
  45. * @data_size: Number of bytes in @data_in_out.
  46. * @iv: Initialization vector to use for Cipher Block Chaining.
  47. * @padding: Have padding or not.
  48. * @encrypt: %true to select encrypt, %false to select decrypt.
  49. *
  50. * Return: 0 on success, -1 if an error was detected.
  51. */
  52. static int crypt(const struct key *key, at_crypt_data *in, at_crypt_data *out,
  53. const struct iv *iv, bool padding, bool encrypt) {
  54. int evp_ret;
  55. const EVP_CIPHER *cipher;
  56. int out_data_size;
  57. size_t key_len;
  58. /*
  59. * Make sure iv is large enough. Current implementation allows static
  60. * check.
  61. * TODO: Switch to runtime check for selcted cipher if EVP_MAX_IV_LENGTH
  62. * changes to cover larger ivs used by other cipers.
  63. */
  64. STATIC_ASSERT(sizeof(*iv) >= EVP_MAX_IV_LENGTH);
  65. cipher = EVP_aes_128_cbc();
  66. key_len = EVP_CIPHER_key_length(cipher);
  67. if (key_len > sizeof(*key)) {
  68. ATLOGE("key too small for selected cipher, %zd < %zd\n", sizeof(*key),
  69. key_len);
  70. evp_ret = 0;
  71. goto err;
  72. }
  73. assert(cipher_ctx);
  74. EVP_CIPHER_CTX_reset(cipher_ctx);
  75. evp_ret =
  76. EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key->byte, iv->byte, encrypt);
  77. if (!evp_ret) {
  78. ATLOGE("EVP_CipherInit_ex failed\n");
  79. goto err;
  80. }
  81. evp_ret = EVP_CIPHER_CTX_set_padding(cipher_ctx, padding);
  82. if (!evp_ret) {
  83. ATLOGE("EVP_CIPHER_CTX_set_padding failed\n");
  84. goto err;
  85. }
  86. evp_ret =
  87. EVP_CipherUpdate(cipher_ctx, out->data, &out->size, in->data, in->size);
  88. if (!evp_ret) {
  89. ATLOGE("EVP_CipherUpdate failed\n");
  90. goto err;
  91. }
  92. out_data_size = out->size;
  93. evp_ret =
  94. EVP_CipherFinal_ex(cipher_ctx, out->data + out_data_size, &out_data_size);
  95. if (!evp_ret) {
  96. ATLOGE("EVP_CipherFinal_ex failed\n");
  97. goto err;
  98. }
  99. out->size += out_data_size;
  100. err:
  101. return evp_ret ? 0 : -1;
  102. }
  103. /**
  104. * calculate_mac - Calulate keyed-hash message authentication code (HMAC SHA256)
  105. * @key: Key object.
  106. * @mac: Mac object to return calulated mac in.
  107. * @data: Data to calculate mac for.
  108. * @data_size: Number of bytes in @data.
  109. *
  110. * Return: 0 on success, -1 if an error was detected.
  111. */
  112. static int calculate_mac(const struct key *key, struct mac *mac,
  113. const void *data, size_t data_size) {
  114. int hmac_ret;
  115. unsigned int md_len;
  116. unsigned char mac_buf[EVP_MAX_MD_SIZE];
  117. assert(hmac_ctx);
  118. HMAC_CTX_reset(hmac_ctx);
  119. hmac_ret = HMAC_Init_ex(hmac_ctx, key, sizeof(*key), EVP_sha256(), NULL);
  120. if (!hmac_ret) {
  121. fprintf(stderr, "HMAC_Init_ex failed\n");
  122. goto err;
  123. }
  124. hmac_ret = HMAC_Update(hmac_ctx, data, data_size);
  125. if (!hmac_ret) {
  126. fprintf(stderr, "HMAC_Update failed\n");
  127. goto err;
  128. }
  129. hmac_ret = HMAC_Final(hmac_ctx, mac_buf, &md_len);
  130. if (!hmac_ret) {
  131. fprintf(stderr, "HMAC_Final failed\n");
  132. goto err;
  133. }
  134. if (md_len < sizeof(*mac)) {
  135. fprintf(stderr, "bad md_len %d < %zd\n", md_len, sizeof(*mac));
  136. hmac_ret = 0;
  137. goto err;
  138. }
  139. memcpy(mac, mac_buf, sizeof(*mac));
  140. err:
  141. return hmac_ret ? 0 : -1;
  142. }
  143. /**
  144. * at_aes_hmac_encrypt - Encrypt data using AES-128-CBC and HMAC.
  145. * @key: Key object.
  146. * @data_in: Data to encrypt.
  147. * @data_out: Data to encrypt for.
  148. * @iv_in: Initialization vector to use for Cipher Block Chaining.
  149. *
  150. * Return: 0 on success, -1 if an error was detected.
  151. */
  152. int at_aes_hmac_encrypt(const struct key *key, at_crypt_data *data_in,
  153. at_crypt_data *data_out, const struct iv *iv_in) {
  154. if (key == NULL || data_in == NULL || data_out == NULL || iv_in == NULL) {
  155. ATLOGE("encrypt param error.\n");
  156. goto param_err;
  157. }
  158. at_crypt_data crypt_out;
  159. crypt_out.size = data_in->size / 16 * 16 +
  160. (1 + (data_in->size % 16 & INT_MAX) ? 1 : 0) * 16;
  161. crypt_out.data = (uint8_t *)malloc(sizeof(uint8_t) * crypt_out.size + 1);
  162. if (crypt_out.data == NULL) {
  163. ATLOGE("malloc error.\n");
  164. goto malloc_err;
  165. }
  166. memset(crypt_out.data, 0, crypt_out.size + 1);
  167. data_out->size = crypt_out.size + AT_HMAC_SIZE;
  168. data_out->data = (uint8_t *)malloc(sizeof(uint8_t) * data_out->size + 1);
  169. if (data_out->data == NULL) {
  170. ATLOGE("malloc error.\n");
  171. goto malloc_err;
  172. }
  173. memset(data_out->data, 0, data_out->size + 1);
  174. crypt_init();
  175. int rc = crypt(key, data_in, &crypt_out, iv_in, true, true);
  176. if (rc < 0) {
  177. ATLOGE("crypt faild.\n");
  178. goto crypt_err;
  179. }
  180. hmac_init();
  181. struct mac mac;
  182. rc = calculate_mac(key, &mac, crypt_out.data, crypt_out.size);
  183. if (rc < 0) {
  184. ATLOGE("calculate_mac faild.\n");
  185. goto hash_err;
  186. }
  187. memcpy(data_out->data, mac.byte, AT_HMAC_SIZE);
  188. memcpy(data_out->data + AT_HMAC_SIZE, crypt_out.data, crypt_out.size);
  189. data_out->size = crypt_out.size + AT_HMAC_SIZE;
  190. hmac_shutdown();
  191. crypt_shutdown();
  192. if (crypt_out.data != NULL) {
  193. free(crypt_out.data);
  194. }
  195. return 0;
  196. hash_err:
  197. hmac_shutdown();
  198. crypt_err:
  199. crypt_shutdown();
  200. if (data_out->data != NULL) {
  201. free(data_out->data);
  202. }
  203. malloc_err:
  204. if (crypt_out.data != NULL) {
  205. free(crypt_out.data);
  206. }
  207. param_err:
  208. return -1;
  209. }
  210. /**
  211. * at_aes_hmac_decrypt - Decrypt data using AES-128-CBC and verify HMAC.
  212. * @key: Key object.
  213. * @data_in: Data to decrypt.
  214. * @data_out: Data to decrypt for.
  215. * @iv_in: Initialization vector to use for Cipher Block Chaining.
  216. *
  217. * Return: 0 on success, -1 if an error was detected.
  218. */
  219. int at_aes_hmac_decrypt(const struct key *key, at_crypt_data *data_in,
  220. at_crypt_data *data_out, const struct iv *iv_in) {
  221. if (key == NULL || data_in == NULL || data_out == NULL || iv_in == NULL) {
  222. ATLOGE("encrypt param error.\n");
  223. goto param_err;
  224. }
  225. if((data_in->size/16 < 2) || (data_in->size%16 != 0) || (data_in->size == 0)) {
  226. ATLOGE("data_in size error.\n");
  227. goto param_err;
  228. }
  229. hmac_init();
  230. struct mac mac;
  231. int rc = calculate_mac(key, &mac, data_in->data + AT_HMAC_SIZE,
  232. data_in->size - AT_HMAC_SIZE);
  233. if (rc < 0) {
  234. ATLOGE("calculate_mac faild.\n");
  235. goto hash_err;
  236. }
  237. rc = memcmp(data_in->data, mac.byte, AT_HMAC_SIZE);
  238. if (rc != 0) {
  239. ATLOGE("hash error.\n");
  240. goto hash_err;
  241. }
  242. int decrypt_osize = data_in->size - AT_HMAC_SIZE;
  243. uint8_t *decrypt_odata = (uint8_t *)malloc(sizeof(uint8_t) * decrypt_osize);
  244. if (decrypt_odata == NULL) {
  245. ATLOGE("malloc error.\n");
  246. goto malloc_err;
  247. }
  248. memset(decrypt_odata, 0, decrypt_osize);
  249. data_out->size = data_in->size - AT_HMAC_SIZE;
  250. data_out->data = (uint8_t *)malloc(sizeof(uint8_t) * data_out->size);
  251. if (data_out->data == NULL) {
  252. ATLOGE("malloc error.\n");
  253. goto malloc_err;
  254. }
  255. at_crypt_data decrypt_in;
  256. at_crypt_data decrypt_out;
  257. decrypt_in.data = data_in->data + AT_HMAC_SIZE;
  258. decrypt_in.size = data_in->size - AT_HMAC_SIZE;
  259. decrypt_out.data = decrypt_odata;
  260. decrypt_out.size = decrypt_osize;
  261. crypt_init();
  262. rc = crypt(key, &decrypt_in, &decrypt_out, iv_in, true, false);
  263. if (rc < 0) {
  264. ATLOGE("crypt faild.\n");
  265. goto decrypt_err;
  266. }
  267. memset(data_out->data, 0, data_out->size);
  268. memcpy(data_out->data, decrypt_out.data, decrypt_out.size);
  269. data_out->size = decrypt_out.size;
  270. hmac_shutdown();
  271. crypt_shutdown();
  272. if (decrypt_odata != NULL) {
  273. free(decrypt_odata);
  274. }
  275. return 0;
  276. decrypt_err:
  277. crypt_shutdown();
  278. if (data_out->data != NULL) {
  279. free(data_out->data);
  280. }
  281. malloc_err:
  282. if (decrypt_odata != NULL) {
  283. free(decrypt_odata);
  284. }
  285. hash_err:
  286. hmac_shutdown();
  287. param_err:
  288. return -1;
  289. }
  290. /**
  291. * at_aes_encrypt - Encrypt data using AES-128-CBC.
  292. * @key: Key object.
  293. * @data_in: Data to encrypt.
  294. * @data_out: Data to encrypt for.
  295. * @iv_in: Initialization vector to use for Cipher Block Chaining.
  296. *
  297. * Return: 0 on success, -1 if an error was detected.
  298. */
  299. int at_aes_encrypt(const struct key *key, at_crypt_data *data_in,
  300. at_crypt_data *data_out, const struct iv *iv_in) {
  301. if (key == NULL || data_in == NULL || data_out == NULL || iv_in == NULL) {
  302. ATLOGE("encrypt param error.\n");
  303. goto param_err;
  304. }
  305. if((data_in->size%16 != 0) || (data_in->size == 0)) {
  306. ATLOGE("data_in size error.\n");
  307. goto param_err;
  308. }
  309. data_out->size = data_in->size;
  310. data_out->data = (uint8_t *)malloc(sizeof(uint8_t) * data_out->size);
  311. if (data_out->data == NULL) {
  312. ATLOGE("malloc error.\n");
  313. goto malloc_err;
  314. }
  315. memset(data_out->data, 0, data_out->size);
  316. crypt_init();
  317. int rc = crypt(key, data_in, data_out, iv_in, false, true);
  318. if (rc < 0) {
  319. ATLOGE("crypt faild.\n");
  320. goto crypt_err;
  321. }
  322. crypt_shutdown();
  323. return 0;
  324. crypt_err:
  325. crypt_shutdown();
  326. if (data_out->data != NULL) {
  327. free(data_out->data);
  328. }
  329. malloc_err:
  330. param_err:
  331. return -1;
  332. }
  333. /**
  334. * at_aes_decrypt - Decrypt data using AES-128-CBC.
  335. * @key: Key object.
  336. * @data_in: Data to decrypt.
  337. * @data_out: Data to decrypt for.
  338. * @iv_in: Initialization vector to use for Cipher Block Chaining.
  339. *
  340. * Return: 0 on success, -1 if an error was detected.
  341. */
  342. int at_aes_decrypt(const struct key *key, at_crypt_data *data_in,
  343. at_crypt_data *data_out, const struct iv *iv_in) {
  344. if (key == NULL || data_in == NULL || data_out == NULL || iv_in == NULL) {
  345. ATLOGE("encrypt param error.\n");
  346. goto param_err;
  347. }
  348. if((data_in->size%16 != 0) || (data_in->size == 0)) {
  349. ATLOGE("data_in size error.\n");
  350. goto param_err;
  351. }
  352. data_out->size = data_in->size;
  353. data_out->data = (uint8_t *)malloc(sizeof(uint8_t) * data_out->size);
  354. if (data_out->data == NULL) {
  355. ATLOGE("malloc error.\n");
  356. goto malloc_err;
  357. }
  358. memset(data_out->data, 0, data_out->size);
  359. crypt_init();
  360. int rc = crypt(key, data_in, data_out, iv_in, false, false);
  361. if (rc < 0) {
  362. ATLOGE("crypt faild.\n");
  363. goto decrypt_err;
  364. }
  365. crypt_shutdown();
  366. return 0;
  367. decrypt_err:
  368. crypt_shutdown();
  369. if (data_out->data != NULL) {
  370. free(data_out->data);
  371. }
  372. malloc_err:
  373. param_err:
  374. return -1;
  375. }