mbedtls_backend_aes_aead.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /**
  2. * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #include "sdk_common.h"
  41. #include <drivers/nrfx_common.h>
  42. #if NRF_MODULE_ENABLED(NRF_CRYPTO)
  43. #include "nrf_crypto_error.h"
  44. #include "mbedtls_backend_aes_aead.h"
  45. #if NRF_MODULE_ENABLED(NRF_CRYPTO_MBEDTLS_AES_AEAD)
  46. /**@internal @brief Type declaration of a template suiting all possible context sizes
  47. * for this backend.
  48. */
  49. typedef union
  50. {
  51. nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
  52. #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
  53. nrf_crypto_backend_aes_ccm_context_t ccm;
  54. #endif
  55. #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
  56. nrf_crypto_backend_aes_gcm_context_t gcm;
  57. #endif
  58. } nrf_crypto_backend_mbedtls_aes_aead_context_t;
  59. static ret_code_t result_get(int error)
  60. {
  61. ret_code_t ret_val;
  62. switch (error)
  63. {
  64. case 0:
  65. ret_val = NRF_SUCCESS;
  66. break;
  67. case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
  68. ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
  69. break;
  70. case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
  71. ret_val = NRF_ERROR_CRYPTO_ALLOC_FAILED;
  72. break;
  73. case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
  74. ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
  75. break;
  76. #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
  77. case MBEDTLS_ERR_CCM_BAD_INPUT:
  78. ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
  79. break;
  80. case MBEDTLS_ERR_CCM_AUTH_FAILED:
  81. ret_val = NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
  82. break;
  83. #endif
  84. #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
  85. case MBEDTLS_ERR_GCM_BAD_INPUT:
  86. ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
  87. break;
  88. case MBEDTLS_ERR_GCM_AUTH_FAILED:
  89. ret_val = NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
  90. break;
  91. #endif
  92. default:
  93. ret_val = NRF_ERROR_CRYPTO_INTERNAL;
  94. break;
  95. }
  96. return ret_val;
  97. }
  98. static ret_code_t backend_mbedtls_init(void * const p_context, uint8_t * p_key)
  99. {
  100. int result;
  101. ret_code_t ret_val;
  102. nrf_crypto_backend_mbedtls_aes_aead_context_t * p_ctx =
  103. (nrf_crypto_backend_mbedtls_aes_aead_context_t *)p_context;
  104. if ((p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_128) &&
  105. (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_192) &&
  106. (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_256))
  107. {
  108. return NRF_ERROR_CRYPTO_KEY_SIZE;
  109. }
  110. switch (p_ctx->header.p_info->mode)
  111. {
  112. #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
  113. case NRF_CRYPTO_AEAD_MODE_AES_CCM:
  114. mbedtls_ccm_init(&p_ctx->ccm.context);
  115. result = mbedtls_ccm_setkey(&p_ctx->ccm.context,
  116. MBEDTLS_CIPHER_ID_AES,
  117. p_key,
  118. p_ctx->header.p_info->key_size);
  119. break;
  120. #endif
  121. #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
  122. case NRF_CRYPTO_AEAD_MODE_AES_GCM:
  123. mbedtls_gcm_init(&p_ctx->gcm.context);
  124. result = mbedtls_gcm_setkey(&p_ctx->gcm.context,
  125. MBEDTLS_CIPHER_ID_AES,
  126. p_key,
  127. p_ctx->header.p_info->key_size);
  128. break;
  129. #endif
  130. default:
  131. return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
  132. }
  133. if (result != 0)
  134. {
  135. ret_val = result_get(result);
  136. return ret_val;
  137. }
  138. return NRF_SUCCESS;
  139. }
  140. static ret_code_t backend_mbedtls_uninit(void * const p_context)
  141. {
  142. nrf_crypto_backend_mbedtls_aes_aead_context_t * p_ctx =
  143. (nrf_crypto_backend_mbedtls_aes_aead_context_t *)p_context;
  144. if (p_ctx->header.p_info->mode == NRF_CRYPTO_AEAD_MODE_AES_CCM)
  145. {
  146. #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
  147. mbedtls_ccm_free(&p_ctx->ccm.context);
  148. #endif
  149. }
  150. else
  151. {
  152. #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
  153. mbedtls_gcm_free(&p_ctx->gcm.context);
  154. #endif
  155. }
  156. return NRF_SUCCESS;
  157. }
  158. #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
  159. static ret_code_t backend_mbedtls_ccm_crypt(void * const p_context,
  160. nrf_crypto_operation_t operation,
  161. uint8_t * p_nonce,
  162. uint8_t nonce_size,
  163. uint8_t * p_adata,
  164. size_t adata_size,
  165. uint8_t * p_data_in,
  166. size_t data_in_size,
  167. uint8_t * p_data_out,
  168. uint8_t * p_mac,
  169. uint8_t mac_size)
  170. {
  171. int result;
  172. ret_code_t ret_val;
  173. nrf_crypto_backend_mbedtls_aes_aead_context_t * p_ctx =
  174. (nrf_crypto_backend_mbedtls_aes_aead_context_t *)p_context;
  175. /* CCM mode allows following MAC sizes: [4, 6, 8, 10, 12, 14, 16] */
  176. if ((mac_size < NRF_CRYPTO_AES_CCM_MAC_MIN) || (mac_size > NRF_CRYPTO_AES_CCM_MAC_MAX) ||
  177. ((mac_size & 0x01) != 0))
  178. {
  179. return NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
  180. }
  181. if ((nonce_size < NRF_CRYPTO_AES_CCM_NONCE_SIZE_MIN) ||
  182. (nonce_size > NRF_CRYPTO_AES_CCM_NONCE_SIZE_MAX))
  183. {
  184. return NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE;
  185. }
  186. if (operation == NRF_CRYPTO_ENCRYPT)
  187. {
  188. result = mbedtls_ccm_encrypt_and_tag(&p_ctx->ccm.context,
  189. data_in_size,
  190. p_nonce,
  191. nonce_size,
  192. p_adata,
  193. adata_size,
  194. p_data_in,
  195. p_data_out,
  196. p_mac,
  197. (size_t)mac_size);
  198. }
  199. else if (operation == NRF_CRYPTO_DECRYPT)
  200. {
  201. result = mbedtls_ccm_auth_decrypt(&p_ctx->ccm.context,
  202. data_in_size,
  203. p_nonce,
  204. nonce_size,
  205. p_adata,
  206. adata_size,
  207. p_data_in,
  208. p_data_out,
  209. p_mac,
  210. (size_t)mac_size);
  211. }
  212. else
  213. {
  214. return NRF_ERROR_CRYPTO_INVALID_PARAM;
  215. }
  216. ret_val = result_get(result);
  217. return ret_val;
  218. }
  219. #endif
  220. #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
  221. static ret_code_t backend_mbedtls_gcm_crypt(void * const p_context,
  222. nrf_crypto_operation_t operation,
  223. uint8_t * p_nonce,
  224. uint8_t nonce_size,
  225. uint8_t * p_adata,
  226. size_t adata_size,
  227. uint8_t * p_data_in,
  228. size_t data_in_size,
  229. uint8_t * p_data_out,
  230. uint8_t * p_mac,
  231. uint8_t mac_size)
  232. {
  233. int result;
  234. ret_code_t ret_val;
  235. nrf_crypto_backend_mbedtls_aes_aead_context_t * p_ctx =
  236. (nrf_crypto_backend_mbedtls_aes_aead_context_t *)p_context;
  237. /* GCM allows following MAC size: [4 ... 16] */
  238. if ((mac_size < NRF_CRYPTO_AES_GCM_MAC_MIN) || (mac_size > NRF_CRYPTO_AES_GCM_MAC_MAX))
  239. {
  240. return NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
  241. }
  242. if (operation == NRF_CRYPTO_ENCRYPT)
  243. {
  244. result = mbedtls_gcm_crypt_and_tag(&p_ctx->gcm.context,
  245. MBEDTLS_GCM_ENCRYPT,
  246. data_in_size,
  247. p_nonce,
  248. nonce_size,
  249. p_adata,
  250. adata_size,
  251. p_data_in,
  252. p_data_out,
  253. (size_t)mac_size,
  254. p_mac);
  255. ret_val = result_get(result);
  256. }
  257. else if (operation == NRF_CRYPTO_DECRYPT)
  258. {
  259. result = mbedtls_gcm_auth_decrypt(&p_ctx->gcm.context,
  260. data_in_size,
  261. p_nonce,
  262. nonce_size,
  263. p_adata,
  264. adata_size,
  265. p_mac,
  266. (size_t)mac_size,
  267. p_data_in,
  268. p_data_out);
  269. ret_val = result_get(result);
  270. }
  271. else
  272. {
  273. return NRF_ERROR_CRYPTO_INVALID_PARAM;
  274. }
  275. return ret_val;
  276. }
  277. #endif
  278. #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
  279. nrf_crypto_aead_info_t const g_nrf_crypto_aes_ccm_128_info =
  280. {
  281. .key_size = NRF_CRYPTO_KEY_SIZE_128,
  282. .mode = NRF_CRYPTO_AEAD_MODE_AES_CCM,
  283. .init_fn = backend_mbedtls_init,
  284. .uninit_fn = backend_mbedtls_uninit,
  285. .crypt_fn = backend_mbedtls_ccm_crypt
  286. };
  287. nrf_crypto_aead_info_t const g_nrf_crypto_aes_ccm_192_info =
  288. {
  289. .key_size = NRF_CRYPTO_KEY_SIZE_192,
  290. .mode = NRF_CRYPTO_AEAD_MODE_AES_CCM,
  291. .init_fn = backend_mbedtls_init,
  292. .uninit_fn = backend_mbedtls_uninit,
  293. .crypt_fn = backend_mbedtls_ccm_crypt
  294. };
  295. nrf_crypto_aead_info_t const g_nrf_crypto_aes_ccm_256_info =
  296. {
  297. .key_size = NRF_CRYPTO_KEY_SIZE_256,
  298. .mode = NRF_CRYPTO_AEAD_MODE_AES_CCM,
  299. .init_fn = backend_mbedtls_init,
  300. .uninit_fn = backend_mbedtls_uninit,
  301. .crypt_fn = backend_mbedtls_ccm_crypt
  302. };
  303. #endif
  304. #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
  305. nrf_crypto_aead_info_t const g_nrf_crypto_aes_gcm_128_info =
  306. {
  307. .key_size = NRF_CRYPTO_KEY_SIZE_128,
  308. .mode = NRF_CRYPTO_AEAD_MODE_AES_GCM,
  309. .init_fn = backend_mbedtls_init,
  310. .uninit_fn = backend_mbedtls_uninit,
  311. .crypt_fn = backend_mbedtls_gcm_crypt
  312. };
  313. nrf_crypto_aead_info_t const g_nrf_crypto_aes_gcm_192_info =
  314. {
  315. .key_size = NRF_CRYPTO_KEY_SIZE_192,
  316. .mode = NRF_CRYPTO_AEAD_MODE_AES_GCM,
  317. .init_fn = backend_mbedtls_init,
  318. .uninit_fn = backend_mbedtls_uninit,
  319. .crypt_fn = backend_mbedtls_gcm_crypt
  320. };
  321. nrf_crypto_aead_info_t const g_nrf_crypto_aes_gcm_256_info =
  322. {
  323. .key_size = NRF_CRYPTO_KEY_SIZE_256,
  324. .mode = NRF_CRYPTO_AEAD_MODE_AES_GCM,
  325. .init_fn = backend_mbedtls_init,
  326. .uninit_fn = backend_mbedtls_uninit,
  327. .crypt_fn = backend_mbedtls_gcm_crypt
  328. };
  329. #endif
  330. #endif // MODULE_ENABLED(NRF_CRYPTO_MBEDTLS_AES_AEAD)
  331. #endif // MODULE_ENABLED(NRF_CRYPTO)