esp32_aes.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. /* esp32_aes.c
  2. *
  3. * Copyright (C) 2006-2024 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. /*
  22. * WOLFSSL_SUCCESS and WOLFSSL_FAILURE values should only
  23. * be used in the ssl layer, not in wolfCrypt
  24. **/
  25. #ifdef HAVE_CONFIG_H
  26. #include <config.h>
  27. #endif
  28. /* Reminder: user_settings.h is needed and included from settings.h
  29. * Be sure to define WOLFSSL_USER_SETTINGS, typically in CMakeLists.txt */
  30. #include <wolfssl/wolfcrypt/settings.h>
  31. #if defined(WOLFSSL_ESPIDF) /* Entire file is only for Espressif EDP-IDF */
  32. #include "sdkconfig.h" /* programmatically generated from sdkconfig */
  33. #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
  34. #ifndef NO_AES
  35. #if defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
  36. #include <wolfssl/wolfcrypt/aes.h>
  37. #include <wolfssl/wolfcrypt/error-crypt.h>
  38. /* breadcrumb tag text for ESP_LOG() */
  39. static const char* TAG = "wolf_hw_aes";
  40. /* mutex */
  41. static wolfSSL_Mutex aes_mutex;
  42. /* keep track as to whether esp aes is initialized */
  43. static int espaes_CryptHwMutexInit = 0;
  44. #if defined(WOLFSSL_HW_METRICS)
  45. static unsigned long esp_aes_unsupported_length_usage_ct = 0;
  46. #endif
  47. /*
  48. * lock hw engine.
  49. * this should be called before using engine.
  50. *
  51. * returns 0 if the hw lock was initialized and mutex lock
  52. */
  53. static int esp_aes_hw_InUse(void)
  54. {
  55. int ret = ESP_OK;
  56. ESP_LOGV(TAG, "enter esp_aes_hw_InUse");
  57. if (espaes_CryptHwMutexInit == 0) {
  58. ret = esp_CryptHwMutexInit(&aes_mutex);
  59. if (ret == ESP_OK) {
  60. /* flag esp aes as initialized */
  61. espaes_CryptHwMutexInit = 1;
  62. }
  63. else {
  64. ESP_LOGE(TAG, "aes mutex initialization failed.");
  65. }
  66. }
  67. else {
  68. /* esp aes has already been initialized */
  69. }
  70. if (ret == ESP_OK) {
  71. /* lock hardware; there should be exactly one instance
  72. * of esp_CryptHwMutexLock(&aes_mutex ...) in code */
  73. /* TODO - do we really want to wait?
  74. * probably not */
  75. ret = esp_CryptHwMutexLock(&aes_mutex, portMAX_DELAY);
  76. }
  77. else {
  78. ESP_LOGE(TAG, "aes engine lock failed.");
  79. }
  80. if (ret == ESP_OK) {
  81. /* Enable AES hardware */
  82. periph_module_enable(PERIPH_AES_MODULE);
  83. #if defined(CONFIG_IDF_TARGET_ESP32S2) || \
  84. defined(CONFIG_IDF_TARGET_ESP32S3)
  85. {
  86. /* Select working mode. Can be typical or DMA.
  87. * 0 => typical
  88. * 1 => DMA */
  89. DPORT_REG_WRITE(AES_DMA_ENABLE_REG, 0);
  90. }
  91. #elif defined(CONFIG_IDF_TARGET_ESP32C3) || \
  92. defined(CONFIG_IDF_TARGET_ESP32C6)
  93. {
  94. /* Select working mode. Can be typical or DMA.
  95. * 0 => typical
  96. * 1 => DMA */
  97. DPORT_REG_WRITE(AES_DMA_ENABLE_REG, 0);
  98. }
  99. #endif
  100. }
  101. ESP_LOGV(TAG, "leave esp_aes_hw_InUse");
  102. return ret;
  103. } /* esp_aes_hw_InUse */
  104. /*
  105. * release hw engine
  106. */
  107. static void esp_aes_hw_Leave( void )
  108. {
  109. ESP_LOGV(TAG, "enter esp_aes_hw_Leave");
  110. /* Disable AES hardware */
  111. periph_module_disable(PERIPH_AES_MODULE);
  112. /* unlock */
  113. esp_CryptHwMutexUnLock(&aes_mutex);
  114. ESP_LOGV(TAG, "leave esp_aes_hw_Leave");
  115. } /* esp_aes_hw_Leave */
  116. /*
  117. * set key to hardware key registers.
  118. * return ESP_OK = 0 on success; BAD_FUNC_ARG if mode isn't supported.
  119. */
  120. static int esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode)
  121. {
  122. int ret = ESP_OK;
  123. word32 i;
  124. word32 mode_ = 0;
  125. ESP_LOGV(TAG, " enter esp_aes_hw_Set_KeyMode %d", mode);
  126. /* check mode */
  127. if (mode == ESP32_AES_UPDATEKEY_ENCRYPT) {
  128. mode_ = 0;
  129. }
  130. else {
  131. if (mode == ESP32_AES_UPDATEKEY_DECRYPT) {
  132. mode_ = 4;
  133. }
  134. else {
  135. ESP_LOGE(TAG, " >> unexpected error.");
  136. ret = BAD_FUNC_ARG;
  137. }
  138. } /* if mode */
  139. /*
  140. ** ESP32: see table 22-1 in ESP32 Technical Reference
  141. ** ESP32-S3: see table 19-2 in ESP32-S3 Technical Reference
  142. ** ESP32-C3:
  143. ** ESP32-C6: see table 18-2 in ESP32-C6 Technical Reference
  144. **
  145. ** Mode Algorithm ESP32 ESP32S3 ESP32C3 ESP32C6
  146. ** 0 AES-128 Encryption y y y y
  147. ** 1 AES-192 Encryption y n n n
  148. ** 2 AES-256 Encryption y y y y
  149. ** 3 reserved n n n n
  150. ** 4 AES-128 Decryption y y y y
  151. ** 5 AES-192 Decryption y n n n
  152. ** 6 AES-256 Decryption y y y y
  153. ** 7 reserved n n n n
  154. */
  155. switch(ctx->keylen){
  156. case 24: mode_ += 1; break;
  157. case 32: mode_ += 2; break;
  158. default: break;
  159. }
  160. /* Some specific modes are not supported on some targets. */
  161. #if defined(CONFIG_IDF_TARGET_ESP32)
  162. #define TARGET_AES_KEY_BASE AES_KEY_BASE
  163. if (mode_ == 3 || mode_ > 6) {
  164. /* this should have been detected in aes.c and fall back to SW */
  165. ESP_LOGE(TAG, "esp_aes_hw_Set_KeyMode unsupported mode: %i", mode_);
  166. ret = BAD_FUNC_ARG;
  167. }
  168. #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
  169. #define TARGET_AES_KEY_BASE AES_KEY_BASE
  170. if (mode_ == 1 || mode_ == 3 || mode_ == 5 || mode_ > 6) {
  171. /* this should have been detected in aes.c and fall back to SW */
  172. ESP_LOGE(TAG, "esp_aes_hw_Set_KeyMode unsupported mode: %i", mode_);
  173. ret = BAD_FUNC_ARG;
  174. }
  175. #elif defined(CONFIG_IDF_TARGET_ESP32C3)
  176. #define TARGET_AES_KEY_BASE AES_KEY_BASE
  177. if (mode_ == 1 || mode_ == 3|| mode_ == 5 || mode_ > 6) {
  178. /* this should have been detected in aes.c and fall back to SW */
  179. ESP_LOGE(TAG, "esp_aes_hw_Set_KeyMode unsupported mode: %i", mode_);
  180. ret = BAD_FUNC_ARG;
  181. }
  182. #elif defined(CONFIG_IDF_TARGET_ESP32C6)
  183. #define TARGET_AES_KEY_BASE AES_KEY_0_REG
  184. if (mode_ == 1 || mode_ == 3 || mode_ == 5 || mode_ > 6) {
  185. /* this should have been detected in aes.c and fall back to SW */
  186. ESP_LOGE(TAG, "esp_aes_hw_Set_KeyMode unsupported mode: %i", mode_);
  187. ret = BAD_FUNC_ARG;
  188. }
  189. #else
  190. /* assume all modes supported, use AES_KEY_BASE */
  191. #define TARGET_AES_KEY_BASE AES_KEY_BASE
  192. #endif
  193. /* */
  194. if (ret == ESP_OK) {
  195. /* update key */
  196. for (i = 0; i < (ctx->keylen) / sizeof(word32); i++) {
  197. DPORT_REG_WRITE((volatile word32*)(TARGET_AES_KEY_BASE + (i * 4)),
  198. *(((word32*)ctx->key) + i)
  199. );
  200. }
  201. if (ret == ESP_OK) {
  202. DPORT_REG_WRITE(AES_MODE_REG, mode_);
  203. }
  204. ESP_LOGV(TAG, " leave esp_aes_hw_Setkey");
  205. }
  206. return ret;
  207. } /* esp_aes_hw_Set_KeyMode */
  208. /*
  209. * esp_aes_bk
  210. * Process a one block of AES
  211. * in: block of 16 bytes (4 x words32) to process
  212. * out: result of processing input bytes.
  213. */
  214. static void esp_aes_bk(const byte* in, byte* out)
  215. {
  216. const word32* inwords;
  217. uint32_t* outwords;
  218. inwords = (const word32*)in;
  219. outwords = (uint32_t*)out;
  220. ESP_LOGV(TAG, "enter esp_aes_bk");
  221. #if defined(CONFIG_IDF_TARGET_ESP32)
  222. /* copy text for encrypting/decrypting blocks */
  223. DPORT_REG_WRITE(AES_TEXT_BASE, inwords[0]);
  224. DPORT_REG_WRITE(AES_TEXT_BASE + 4, inwords[1]);
  225. DPORT_REG_WRITE(AES_TEXT_BASE + 8, inwords[2]);
  226. DPORT_REG_WRITE(AES_TEXT_BASE + 12, inwords[3]);
  227. /* start engine */
  228. DPORT_REG_WRITE(AES_START_REG, 1);
  229. /* wait until finishing the process */
  230. while (1) {
  231. if (DPORT_REG_READ(AES_IDLE_REG) == 1) {
  232. break;
  233. }
  234. }
  235. /* read-out blocks */
  236. esp_dport_access_read_buffer(outwords, AES_TEXT_BASE, 4);
  237. #elif defined(CONFIG_IDF_TARGET_ESP32C3)
  238. /* See ESP32-C3 technical reference manual:
  239. ** 19.4.3 Operation process using CPU working mode.
  240. ** The ESP32-C3 also supports a DMA mode. (not ywt implemented)
  241. **
  242. ** Copy text for encrypting/decrypting blocks: */
  243. DPORT_REG_WRITE(AES_TEXT_IN_BASE, inwords[0]);
  244. DPORT_REG_WRITE(AES_TEXT_IN_BASE + 4, inwords[1]);
  245. DPORT_REG_WRITE(AES_TEXT_IN_BASE + 8, inwords[2]);
  246. DPORT_REG_WRITE(AES_TEXT_IN_BASE + 12, inwords[3]);
  247. /* start engine */
  248. DPORT_REG_WRITE(AES_TRIGGER_REG, 1);
  249. /* wait until finishing the process */
  250. while (DPORT_REG_READ(AES_STATE_REG) != 0) {
  251. /* waiting for the hardware accelerator to complete operation. */
  252. }
  253. /* read-out blocks */
  254. esp_dport_access_read_buffer((uint32_t*)outwords, AES_TEXT_OUT_BASE, 4);
  255. #elif defined(CONFIG_IDF_TARGET_ESP32C6)
  256. /* See ESP32-C6 technical reference manual:
  257. ** 18.4.3 Operation process using CPU working mode.
  258. ** The ESP32-C6 also supports a DMA mode. (not ywt implemented)
  259. **
  260. ** Copy text for encrypting/decrypting blocks: */
  261. DPORT_REG_WRITE(AES_TEXT_IN_0_REG, inwords[0]);
  262. DPORT_REG_WRITE(AES_TEXT_IN_1_REG, inwords[1]);
  263. DPORT_REG_WRITE(AES_TEXT_IN_2_REG, inwords[2]);
  264. DPORT_REG_WRITE(AES_TEXT_IN_3_REG, inwords[3]);
  265. /* start engine */
  266. DPORT_REG_WRITE(AES_TRIGGER_REG, 1);
  267. /* wait until finishing the process */
  268. while (DPORT_REG_READ(AES_STATE_REG) != 0) {
  269. /* waiting for the hardware accelerator to complete operation. */
  270. }
  271. /* read-out blocks */
  272. esp_dport_access_read_buffer(outwords, AES_TEXT_OUT_0_REG, 4);
  273. #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
  274. /* See esp32 - s3 technical reference manual:
  275. ** 19.4.3 Operation process using CPU working mode.
  276. ** The ESP32-S3 also supports a DMA mode.
  277. **
  278. ** Copy text for encrypting/decrypting blocks: */
  279. DPORT_REG_WRITE(AES_TEXT_IN_BASE, inwords[0]);
  280. DPORT_REG_WRITE(AES_TEXT_IN_BASE + 4, inwords[1]);
  281. DPORT_REG_WRITE(AES_TEXT_IN_BASE + 8, inwords[2]);
  282. DPORT_REG_WRITE(AES_TEXT_IN_BASE + 12, inwords[3]);
  283. /* start engine */
  284. DPORT_REG_WRITE(AES_TRIGGER_REG, 1);
  285. /* wait until finishing the process */
  286. while (DPORT_REG_READ(AES_STATE_REG) != 0) {
  287. /* waiting for the hardware accelerator to complete operation. */
  288. }
  289. /* read-out blocks */
  290. esp_dport_access_read_buffer(outwords, AES_TEXT_OUT_BASE, 4);
  291. #else
  292. ESP_LOGW(TAG, "Warning: esp_aes_bk called for unsupported target: %s",
  293. CONFIG_IDF_TARGET)
  294. #endif
  295. ESP_LOGV(TAG, "leave esp_aes_bk");
  296. } /* esp_aes_bk */
  297. /*
  298. * wc_esp32AesSupportedKeyLen
  299. * @brief: returns 1 if AES key length supported in HW, 0 if not
  300. * @param aes:a value of a ley length */
  301. int wc_esp32AesSupportedKeyLenValue(int keylen)
  302. {
  303. int ret = ESP_OK;
  304. #if defined(CONFIG_IDF_TARGET_ESP32)
  305. if (keylen == 16 || keylen == 24 || keylen == 32) {
  306. ret = 1;
  307. }
  308. else {
  309. ret = ESP_OK; /* keylen 24 (192 bit) not supported */
  310. }
  311. #elif defined(CONFIG_IDF_TARGET_ESP32C3)
  312. if (keylen == 16 || keylen == 32) {
  313. ret = 1;
  314. }
  315. else {
  316. ret = ESP_OK; /* keylen 24 (192 bit) not supported */
  317. }
  318. #elif defined(CONFIG_IDF_TARGET_ESP32C6)
  319. if (keylen == 16 || keylen == 32) {
  320. ret = 1;
  321. }
  322. else {
  323. ret = ESP_OK; /* keylen 24 (192 bit) not supported */
  324. }
  325. #elif defined(CONFIG_IDF_TARGET_ESP32H2)
  326. ret = ESP_OK; /* not yet implemented */
  327. #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
  328. if (keylen == 16 || keylen == 32) {
  329. ret = 1;
  330. }
  331. else {
  332. ret = ESP_OK; /* keylen 24 (192 bit) not supported */
  333. }
  334. #else
  335. ret = ESP_OK; /* if we don't know, then it is not supported */
  336. #endif
  337. return ret;
  338. }
  339. /*
  340. * wc_esp32AesSupportedKeyLen
  341. * @brief: returns 1 if AES key length supported in HW, 0 if not
  342. * @param aes: a pointer of the AES object used to encrypt data */
  343. int wc_esp32AesSupportedKeyLen(struct Aes* aes)
  344. {
  345. int ret;
  346. if (aes == NULL) {
  347. ret = ESP_OK; /* we need a valid aes object to get its keylength */
  348. }
  349. else {
  350. ret = wc_esp32AesSupportedKeyLenValue(aes->keylen);
  351. }
  352. return ret;
  353. }
  354. /*
  355. * wc_esp32AesEncrypt
  356. * @brief: a one block encrypt of the input block, into the output block
  357. * @param aes: a pointer of the AES object used to encrypt data
  358. * @param in : a pointer of the input buffer containing
  359. * plain text to be encrypted
  360. * @param out: a pointer of the output buffer in which to store the
  361. * cipher text of the encrypted message
  362. * @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported.
  363. */
  364. int wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out)
  365. {
  366. int ret = ESP_OK;
  367. ESP_LOGV(TAG, "enter wc_esp32AesEncrypt");
  368. /* lock the hw engine */
  369. ret = esp_aes_hw_InUse();
  370. if (ret == ESP_OK) {
  371. ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT);
  372. if (ret != ESP_OK) {
  373. ESP_LOGE(TAG, "wc_esp32AesEncrypt failed "
  374. "during esp_aes_hw_Set_KeyMode");
  375. }
  376. }
  377. /* load the key into the register */
  378. if (ret == ESP_OK) {
  379. /* process a one block of AES */
  380. esp_aes_bk(in, out);
  381. }
  382. /* release hw */
  383. esp_aes_hw_Leave();
  384. return ret;
  385. } /* wc_esp32AesEncrypt */
  386. /*
  387. * wc_esp32AesDecrypt
  388. * @brief: a one block decrypt of the input block, into the output block
  389. * @param aes: a pointer of the AES object used to decrypt data
  390. * @param in : a pointer of the input buffer containing
  391. * plain text to be decrypted
  392. * @param out: a pointer of the output buffer in which to store the
  393. * cipher text of the decrypted message
  394. * @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported.
  395. */
  396. int wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out)
  397. {
  398. int ret;
  399. ESP_LOGV(TAG, "enter wc_esp32AesDecrypt");
  400. /* lock the hw engine */
  401. esp_aes_hw_InUse();
  402. /* load the key into the register */
  403. ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT);
  404. if (ret != ESP_OK) {
  405. ESP_LOGE(TAG, "wc_esp32AesDecrypt failed "
  406. "during esp_aes_hw_Set_KeyMode");
  407. /* release hw */
  408. esp_aes_hw_Leave();
  409. ret = BAD_FUNC_ARG;
  410. }
  411. if (ret == ESP_OK) {
  412. /* process a one block of AES */
  413. esp_aes_bk(in, out);
  414. /* release hw engine */
  415. esp_aes_hw_Leave();
  416. }
  417. return ret;
  418. } /* wc_esp32AesDecrypt */
  419. /*
  420. * wc_esp32AesCbcEncrypt
  421. * @brief: Encrypts a plain text message from the input buffer, and places the
  422. * resulting cipher text into the output buffer using cipher block
  423. * chaining with AES.
  424. * @param aes: a pointer of the AES object used to encrypt data
  425. * @param out: a pointer of the output buffer in which to store the
  426. cipher text of the encrypted message
  427. * @param in : a pointer of the input buffer containing
  428. * plain text to be encrypted
  429. * @param sz : size of input message
  430. * @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported.
  431. */
  432. int wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
  433. {
  434. int ret;
  435. int i;
  436. int offset = 0;
  437. word32 blocks = (sz / AES_BLOCK_SIZE);
  438. byte *iv;
  439. byte temp_block[AES_BLOCK_SIZE];
  440. ESP_LOGV(TAG, "enter wc_esp32AesCbcEncrypt");
  441. iv = (byte*)aes->reg;
  442. ret = esp_aes_hw_InUse();
  443. if (ret == ESP_OK) {
  444. ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT);
  445. if (ret != ESP_OK) {
  446. ESP_LOGW(TAG, "wc_esp32AesCbcEncrypt failed HW Set KeyMode");
  447. }
  448. } /* if set esp_aes_hw_InUse successful */
  449. if (ret == ESP_OK) {
  450. while (blocks--) {
  451. XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
  452. /* XOR block with IV for CBC */
  453. for (i = 0; i < AES_BLOCK_SIZE; i++) {
  454. temp_block[i] ^= iv[i];
  455. }
  456. esp_aes_bk(temp_block, (out + offset));
  457. offset += AES_BLOCK_SIZE;
  458. /* store IV for next block */
  459. XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
  460. } /* while (blocks--) */
  461. } /* if Set Mode successful (ret == ESP_OK) */
  462. esp_aes_hw_Leave();
  463. ESP_LOGV(TAG, "leave wc_esp32AesCbcEncrypt");
  464. return ret;
  465. } /* wc_esp32AesCbcEncrypt */
  466. /*
  467. * wc_esp32AesCbcDecrypt
  468. * @brief: Encrypts a plain text message from the input buffer, and places the
  469. * resulting cipher text into the output buffer using cipher block
  470. * chaining with AES.
  471. * @param aes: a pointer of the AES object used to decrypt data
  472. * @param out: a pointer of the output buffer in which to store the
  473. * cipher text of the decrypted message
  474. * @param in : a pointer of the input buffer containing
  475. * plain text to be decrypted
  476. * @param sz : size of input message
  477. * @return: 0 on success, BAD_FUNC_ARG if the AES algorithm isn't supported.
  478. */
  479. int wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
  480. {
  481. int ret;
  482. int i;
  483. int offset = 0;
  484. word32 blocks = (sz / AES_BLOCK_SIZE);
  485. byte* iv;
  486. byte temp_block[AES_BLOCK_SIZE];
  487. ESP_LOGV(TAG, "enter wc_esp32AesCbcDecrypt");
  488. iv = (byte*)aes->reg;
  489. ret = esp_aes_hw_InUse();
  490. if (ret == ESP_OK) {
  491. ret = esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT);
  492. if (ret != ESP_OK) {
  493. ESP_LOGW(TAG, "wc_esp32AesCbcDecrypt failed HW Set KeyMode");
  494. }
  495. }
  496. if (ret == ESP_OK) {
  497. while (blocks--) {
  498. XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
  499. esp_aes_bk((in + offset), (out + offset));
  500. /* XOR block with IV for CBC */
  501. for (i = 0; i < AES_BLOCK_SIZE; i++) {
  502. (out + offset)[i] ^= iv[i];
  503. }
  504. /* store IV for next block */
  505. XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
  506. offset += AES_BLOCK_SIZE;
  507. } /* while (blocks--) */
  508. } /* if Set Mode was successful (ret == ESP_OK) */
  509. esp_aes_hw_Leave();
  510. ESP_LOGV(TAG, "leave wc_esp32AesCbcDecrypt");
  511. return ret;
  512. } /* wc_esp32AesCbcDecrypt */
  513. #endif /* WOLFSSL_ESP32_CRYPT */
  514. #endif /* NO_AES */
  515. /* Metrics */
  516. #if defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
  517. #if defined(WOLFSSL_HW_METRICS)
  518. /* increment esp_aes_unsupported_length_usage_ct and return current value */
  519. int wc_esp32AesUnupportedLengthCountAdd(void) {
  520. esp_aes_unsupported_length_usage_ct++;
  521. return esp_aes_unsupported_length_usage_ct;
  522. }
  523. #endif /* WOLFSSL_HW_METRICS */
  524. /* Show AES Metrics when enabled, otherwise callable but no action. */
  525. int esp_hw_show_aes_metrics(void)
  526. {
  527. int ret = ESP_OK;
  528. #if defined(WOLFSSL_HW_METRICS)
  529. ESP_LOGI(TAG, "--------------------------------------------------------");
  530. ESP_LOGI(TAG, "------------- wolfSSL ESP HW AES Metrics----------------");
  531. ESP_LOGI(TAG, "--------------------------------------------------------");
  532. ESP_LOGI(TAG, "esp_aes_unsupported_length_usage_ct = %lu",
  533. esp_aes_unsupported_length_usage_ct);
  534. #else
  535. /* no HW math, no HW math metrics */
  536. #endif /* WOLFSSL_HW_METRICS */
  537. return ret;
  538. }
  539. #endif /* WOLFSSL_ESP32_CRYPT && !NO_WOLFSSL_ESP32_CRYPT_AES */
  540. #endif /* WOLFSSL_ESPIDF */