ald_crypt.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999
  1. /**
  2. *********************************************************************************
  3. *
  4. * @file ald_crypt.c
  5. * @brief CRYPT module driver.
  6. * This is the common part of the CRYPT initialization
  7. *
  8. * @version V1.0
  9. * @date 7 Dec 2017
  10. * @author AE Team
  11. * @note
  12. *
  13. * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
  14. *
  15. *********************************************************************************
  16. */
  17. #include "ald_crypt.h"
  18. /** @addtogroup ES32FXXX_ALD
  19. * @{
  20. */
  21. /** @defgroup CRYPT CRYPT
  22. * @brief CRYPT module driver
  23. * @{
  24. */
  25. #ifdef ALD_CRYPT
  26. /** @addtogroup CRYPT_Private_Functions CRYPT Private Functions
  27. * @{
  28. */
  29. void crypt_reset(crypt_handle_t *hperh);
  30. #ifdef ALD_DMA
  31. static void crypt_dma_crypt_cplt(void *arg);
  32. static void crypt_dma_error(void *arg);
  33. #endif
  34. /**
  35. * @}
  36. */
  37. /** @defgroup CRYPT_Public_Functions CRYPT Public Functions
  38. * @{
  39. */
  40. /** @defgroup CRYPT_Public_Functions_Group1 Initialization functions
  41. * @brief Initialization and Configuration functions
  42. * @{
  43. */
  44. /**
  45. * @brief Initializes the CRYPT mode according to the specified parameters in
  46. * the crypt_init_t and create the associated handle.
  47. * @param hperh: Pointer to a crypt_handle_t structure that contains
  48. * the configuration information for the specified CRYPT module.
  49. * @retval Status, see @ref ald_status_t.
  50. */
  51. ald_status_t crypt_init(crypt_handle_t *hperh)
  52. {
  53. uint32_t tmp = 0;
  54. if (hperh == NULL)
  55. return ERROR;
  56. assert_param(IS_CRYPT(hperh->perh));
  57. assert_param(IS_CRYPT_MODE(hperh->init.mode));
  58. __LOCK(hperh);
  59. crypt_reset(hperh);
  60. if (hperh->state == CRYPT_STATE_RESET)
  61. __UNLOCK(hperh);
  62. tmp = hperh->perh->CON;
  63. hperh->step = 4;
  64. tmp |= ((1 << CRYPT_CON_FIFOODR_POS) | (hperh->init.mode << CRYPT_CON_MODE_POSS) | \
  65. (hperh->init.type << CRYPT_CON_TYPE_POSS) | (1 << CRYPT_CON_FIFOEN_POS));
  66. WRITE_REG(hperh->perh->CON, tmp);
  67. hperh->state = CRYPT_STATE_READY;
  68. __UNLOCK(hperh);
  69. return OK;
  70. }
  71. /**
  72. * @brief Write the Content of KEY.
  73. * @param hperh: Pointer to a crypt_handle_t structure that contains
  74. * the configuration information for the specified CRYPT module.
  75. * @param key: Pointer to key data buffer
  76. * @retval Status, see @ref ald_status_t.
  77. */
  78. ald_status_t crypt_write_key(crypt_handle_t *hperh, uint32_t *key)
  79. {
  80. uint32_t *temp = key;
  81. uint32_t i;
  82. if (hperh->state == CRYPT_STATE_BUSY)
  83. return BUSY;
  84. if ((hperh == NULL) || (key == NULL))
  85. return ERROR;
  86. assert_param(IS_CRYPT(hperh->perh));
  87. hperh->perh->KEY[3] = *temp++;
  88. hperh->perh->KEY[2] = *temp++;
  89. hperh->perh->KEY[1] = *temp++;
  90. hperh->perh->KEY[0] = *temp;
  91. for (i = 0; i < 4; i++)
  92. hperh->key[i] = *key++;
  93. return OK;
  94. }
  95. /**
  96. * @brief Read the Content of KEY.
  97. * @param hperh: Pointer to a crypt_handle_t structure that contains
  98. * the configuration information for the specified CRYPT module.
  99. * @param key: The pointer to the key
  100. * @retval Status, see @ref ald_status_t.
  101. */
  102. ald_status_t crypt_read_key(crypt_handle_t *hperh, uint32_t *key)
  103. {
  104. uint32_t *temp = key;
  105. if (hperh->state == CRYPT_STATE_BUSY)
  106. return BUSY;
  107. if ((hperh == NULL) || (key == NULL))
  108. return ERROR;
  109. assert_param(IS_CRYPT(hperh->perh));
  110. *temp++ = hperh->perh->KEY[3];
  111. *temp++ = hperh->perh->KEY[2];
  112. *temp++ = hperh->perh->KEY[1];
  113. *temp = hperh->perh->KEY[0];
  114. return OK;
  115. }
  116. /**
  117. * @brief Write the Content of IV if you use CBC mode
  118. * @param hperh: Pointer to a crypt_handle_t structure that contains
  119. * the configuration information for the specified CRYPT module.
  120. * @param iv: Pointer to iv data buffer
  121. * @retval Status, see @ref ald_status_t.
  122. */
  123. ald_status_t crypt_write_ivr(crypt_handle_t *hperh, uint32_t *iv)
  124. {
  125. uint32_t *temp = iv;
  126. uint32_t i;
  127. if (hperh->state == CRYPT_STATE_BUSY)
  128. return BUSY;
  129. if ((hperh == NULL) || (iv == NULL))
  130. return ERROR;
  131. assert_param(IS_CRYPT(hperh->perh));
  132. hperh->perh->IV[3] = *temp++;
  133. hperh->perh->IV[2] = *temp++;
  134. hperh->perh->IV[1] = *temp++;
  135. hperh->perh->IV[0] = *temp;
  136. for (i = 0; i < 4; i++)
  137. hperh->iv[i] = *iv++;
  138. CRYPT_IVEN_ENABLE(hperh);
  139. return OK;
  140. }
  141. /**
  142. * @brief Read the Content of IV.
  143. * @param hperh: Pointer to a crypt_handle_t structure that contains
  144. * the configuration information for the specified CRYPT module.
  145. * @param iv: Pointer to iv data buffer
  146. * @retval Status, see @ref ald_status_t.
  147. */
  148. ald_status_t crypt_read_ivr(crypt_handle_t *hperh, uint32_t *iv)
  149. {
  150. uint32_t *temp = iv;
  151. if (hperh->state == CRYPT_STATE_BUSY)
  152. return BUSY;
  153. if ((hperh == NULL) || (iv == NULL))
  154. return ERROR;
  155. assert_param(IS_CRYPT(hperh->perh));
  156. *temp++ = hperh->perh->IV[3];
  157. *temp++ = hperh->perh->IV[2];
  158. *temp++ = hperh->perh->IV[1];
  159. *temp = hperh->perh->IV[0];
  160. return OK;
  161. }
  162. /**
  163. * @}
  164. */
  165. /** @defgroup CRYPT_Public_Functions_Group2 Encrypt or Decrypt functions
  166. * @brief Encrypt or Decrypt functions
  167. * @{
  168. */
  169. /**
  170. * @brief Encrypt an amount of data in blocking mode.
  171. * @param hperh: Pointer to a crypt_handle_t structure that contains
  172. * the configuration information for the specified CRYPT module.
  173. * @param plain_text: Pointer to plain data buffer
  174. * @param cipher_text: Pointer to cipher data buffer
  175. * @param size: Amount of plain data
  176. * @retval Status, see @ref ald_status_t.
  177. * @note the size is multiple of 16(ase)
  178. */
  179. ald_status_t crypt_encrypt(crypt_handle_t *hperh, uint8_t *plain_text, uint8_t *cipher_text, uint32_t size)
  180. {
  181. uint32_t count = 0;
  182. uint32_t i;
  183. uint32_t *plain_buf = (uint32_t *)plain_text;
  184. uint32_t *cipher_buf = (uint32_t *)cipher_text;
  185. if (hperh->state != CRYPT_STATE_READY)
  186. return ERROR;
  187. if ((plain_buf == NULL) || (cipher_buf == NULL) || (size == 0))
  188. return ERROR;
  189. assert_param(IS_CRYPT(hperh->perh));
  190. __LOCK(hperh);
  191. hperh->state = CRYPT_STATE_BUSY;
  192. CRYPT_SETDIR(hperh, CRYPT_ENCRYPT);
  193. count = size / (4 * hperh->step);
  194. while (count--) {
  195. for (i = 0; i < hperh->step; i++) {
  196. CRYPT_WRITE_FIFO(hperh, *plain_buf);
  197. plain_buf++;
  198. }
  199. while (crypt_get_flag_status(hperh, CRYPT_FLAG_DONE) == SET);
  200. for (i = 0; i < hperh->step; i++) {
  201. *cipher_buf = CRYPT_READ_FIFO(hperh);
  202. cipher_buf++;
  203. }
  204. }
  205. hperh->state = CRYPT_STATE_READY;
  206. __UNLOCK(hperh);
  207. return OK;
  208. }
  209. /**
  210. * @brief Decrypt an amount of data in blocking mode.
  211. * @param hperh: Pointer to a crypt_handle_t structure that contains
  212. * the configuration information for the specified CRYPT module.
  213. * @param cipher_text: Pointer to cipher data buffer
  214. * @param plain_text: Pointer to plain data buffer
  215. * @param size: Amount of cipher data
  216. * @retval Status, see @ref ald_status_t.
  217. * @note the size is multiple of 16(ase)
  218. */
  219. ald_status_t crypt_decrypt(crypt_handle_t *hperh, uint8_t *cipher_text, uint8_t *plain_text, uint32_t size)
  220. {
  221. uint32_t count = 0;
  222. uint32_t i;
  223. uint32_t *plain_buf = (uint32_t*)plain_text;
  224. uint32_t *cipher_buf = (uint32_t*)cipher_text;
  225. if (hperh->init.mode == CRYPT_MODE_CTR) {
  226. return crypt_encrypt(hperh, cipher_text, plain_text, size);
  227. }
  228. if (hperh->state != CRYPT_STATE_READY)
  229. return ERROR;
  230. if ((plain_buf == NULL) || (cipher_buf == NULL) || (size == 0))
  231. return ERROR;
  232. assert_param(IS_CRYPT(hperh->perh));
  233. __LOCK(hperh);
  234. hperh->state = CRYPT_STATE_BUSY;
  235. CRYPT_SETDIR(hperh, CRYPT_DECRYPT);
  236. count = size / (4 * hperh->step);
  237. while (count--) {
  238. for (i = 0; i < hperh->step; i++) {
  239. CRYPT_WRITE_FIFO(hperh, *cipher_buf);
  240. cipher_buf++;
  241. }
  242. while (crypt_get_flag_status(hperh, CRYPT_FLAG_DONE) == SET);
  243. for (i = 0; i < hperh->step; i++) {
  244. *plain_buf = CRYPT_READ_FIFO(hperh);
  245. plain_buf++;
  246. }
  247. }
  248. hperh->state = CRYPT_STATE_READY;
  249. __UNLOCK(hperh);
  250. return OK;
  251. }
  252. void gcm_mul(uint32_t *res, uint32_t *data, uint32_t *iv)
  253. {
  254. CRYPT->CON = 0;
  255. CRYPT->DATA[0] = data[3];
  256. CRYPT->DATA[1] = data[2];
  257. CRYPT->DATA[2] = data[1];
  258. CRYPT->DATA[3] = data[0];
  259. CRYPT->IV[0] = iv[3];
  260. CRYPT->IV[1] = iv[2];
  261. CRYPT->IV[2] = iv[1];
  262. CRYPT->IV[3] = iv[0];
  263. CRYPT->CON |= ((1 << CRYPT_CON_RESCLR_POS) | (3 << CRYPT_CON_MODE_POSS) | \
  264. (1 << CRYPT_CON_GO_POS));
  265. while (READ_BIT(CRYPT->IF, CRYPT_IF_MULTHIF_MSK) == 0);
  266. res[3] = CRYPT->RES[0];
  267. res[2] = CRYPT->RES[1];
  268. res[1] = CRYPT->RES[2];
  269. res[0] = CRYPT->RES[3];
  270. WRITE_REG(CRYPT->IFC, CRYPT_IFC_MULTHIFC_MSK);
  271. return;
  272. }
  273. /**
  274. * @brief verify an amount of data in gcm mode.
  275. * @param hperh: Pointer to a crypt_handle_t structure that contains
  276. * the configuration information for the specified CRYPT module.
  277. * @param cipher_text: Pointer to cipher data buffer
  278. * @param size: Amount of cipher data
  279. * @param aadata: Pointer to additional authenticated data buffer
  280. * @param alen: Amount of additional authenticated data
  281. * @param tag: Pointer to authentication tag buffer
  282. * @retval Status, see @ref ald_status_t.
  283. */
  284. ald_status_t crypt_gcm_verify(crypt_handle_t *hperh, uint8_t *cipher_text, uint32_t size, uint8_t *aadata, uint32_t alen, uint8_t *tag)
  285. {
  286. uint8_t GCM_HASH_in[0x60] = {0};
  287. uint8_t ecb[16] = {0};
  288. uint32_t x_temp[4];
  289. uint64_t u, v;
  290. uint32_t len = 0;
  291. uint32_t j, i, k;
  292. uint32_t *tag_temp, *cipher_text_temp;
  293. /* calculate u and v */
  294. u = 128 * ((size % 16) ? (size / 16 + 1) : size / 16) - size * 8;
  295. v = 128 * ((alen % 16) ? (alen / 16 + 1): alen / 16) - alen * 8;
  296. /* get the input of GHASH algorithm,the input:A||0^v||C||0^u||[len(A)]_64||[len(C)]_64 */
  297. for (i = 0; i < alen; i++) {
  298. GCM_HASH_in [i] = * (aadata + i);
  299. }
  300. len += alen;
  301. for (i = 0; i < v / 8; i++) {
  302. GCM_HASH_in[i + len] = 0;
  303. }
  304. len += v / 8;
  305. for (i = 0; i < size; i++) {
  306. GCM_HASH_in[i + len] = * (cipher_text + i);
  307. }
  308. len += size;
  309. for (i = 0; i < u / 8; i++) {
  310. GCM_HASH_in[i + len] = 0;
  311. }
  312. len += u / 8;
  313. for (i = 0; i < 4; i++) {
  314. GCM_HASH_in[i + len] = 0;
  315. }
  316. len += 4;
  317. for (i = 0; i < 4; i++) {
  318. GCM_HASH_in[i + len] = ((alen * 8) >> (8 * i)) & 0xFF;
  319. }
  320. len += 4;
  321. for (i = 0; i < 4; i++) {
  322. GCM_HASH_in[i + len] = 0;
  323. }
  324. len += 4;
  325. for (i = 0; i < 4; i++) {
  326. GCM_HASH_in[i + len] = ((size * 8) >> (8 * i)) & 0xFF;
  327. }
  328. len += 4;
  329. CRYPT->CON &= ~(3 << CRYPT_CON_MODE_POSS);
  330. CRYPT->CON |= (CRYPT_MODE_ECB << CRYPT_CON_MODE_POSS);
  331. crypt_encrypt(hperh, ecb, ecb, 16);
  332. k = len / 16;
  333. for (i = 0; i < 16; i++) {
  334. tag[i] = 0;
  335. }
  336. cipher_text_temp = (uint32_t *)GCM_HASH_in;
  337. tag_temp = (uint32_t *)tag;
  338. for (i = 0; i < k; i++) {
  339. for (j = 0; j < 4; j++) {
  340. x_temp[j] = (*cipher_text_temp) ^ tag_temp[j];
  341. ++cipher_text_temp;
  342. }
  343. gcm_mul((uint32_t *)tag_temp, x_temp, (uint32_t *)ecb);
  344. }
  345. /* calculate the authentication tag T,
  346. * T = CIPH_K(J0)^S,J0=IV||0^31||1,CIPH_K is the algorithm of AES in ECB mode
  347. */
  348. tag_temp = (uint32_t *)tag;
  349. crypt_init(hperh);
  350. CRYPT->CON &= ~(3 << CRYPT_CON_MODE_POSS);
  351. CRYPT->CON |= (CRYPT_MODE_CTR << CRYPT_CON_MODE_POSS);
  352. crypt_write_key(hperh, hperh->key);
  353. hperh->iv[3] = 1;
  354. crypt_write_ivr(hperh, hperh->iv);
  355. crypt_encrypt(hperh, tag, tag, 16);
  356. return OK;
  357. }
  358. /**
  359. * @brief Encrypt an amount of data in non-blocking mode.
  360. * @param hperh: Pointer to a crypt_handle_t structure that contains
  361. * the configuration information for the specified CRYPT module.
  362. * @param plain_text: Pointer to plain data buffer
  363. * @param cipher_text: Pointer to cipher data buffer
  364. * @param size: Amount of plain data
  365. * @retval Status, see @ref ald_status_t.
  366. * @note the size is multiple of 16(ase)
  367. */
  368. ald_status_t crypt_encrypt_by_it(crypt_handle_t *hperh, uint8_t * plain_text, uint8_t *cipher_text, uint32_t size)
  369. {
  370. uint32_t i;
  371. uint32_t *plain_buf = (uint32_t *)plain_text;
  372. if (hperh->state != CRYPT_STATE_READY)
  373. return ERROR;
  374. if ((plain_text == NULL) || (cipher_text == NULL) || (size == 0))
  375. return ERROR;
  376. assert_param(IS_CRYPT(hperh->perh));
  377. __LOCK(hperh);
  378. hperh->state = CRYPT_STATE_BUSY;
  379. CRYPT_SETDIR(hperh, CRYPT_ENCRYPT);
  380. hperh->count = hperh->step;
  381. hperh->plain_text = plain_text;
  382. hperh->cipher_text = cipher_text;
  383. hperh->size = size;
  384. crypt_interrupt_config(hperh, CRYPT_IT_IT, ENABLE);
  385. for (i = 0; i < hperh->step; i++) {
  386. CRYPT_WRITE_FIFO(hperh, *plain_buf);
  387. ++plain_buf;
  388. }
  389. __UNLOCK(hperh);
  390. return OK;
  391. }
  392. /**
  393. * @brief Decrypt an amount of data in non-blocking mode.
  394. * @param hperh: Pointer to a crypt_handle_t structure that contains
  395. * the configuration information for the specified CRYPT module.
  396. * @param plain_text: Pointer to plain data buffer
  397. * @param cipher_text: Pointer to cipher data buffer
  398. * @param size: Amount of cipher data
  399. * @retval Status, see @ref ald_status_t.
  400. * @note the size is multiple of 16(ase)
  401. */
  402. ald_status_t crypt_decrypt_by_it(crypt_handle_t *hperh, uint8_t *cipher_text, uint8_t *plain_text, uint32_t size)
  403. {
  404. uint32_t i;
  405. uint32_t *cipher_buf = (uint32_t*)cipher_text;
  406. if (hperh->init.mode == CRYPT_MODE_CTR) {
  407. return crypt_decrypt_by_it(hperh, cipher_text, plain_text, size);
  408. }
  409. if (hperh->state != CRYPT_STATE_READY)
  410. return ERROR;
  411. if ((plain_text == NULL) || (cipher_text == NULL) || (size == 0))
  412. return ERROR;
  413. assert_param(IS_CRYPT(hperh->perh));
  414. __LOCK(hperh);
  415. hperh->state = CRYPT_STATE_BUSY;
  416. CRYPT_SETDIR(hperh, CRYPT_DECRYPT);
  417. hperh->count = hperh->step;
  418. hperh->plain_text = plain_text;
  419. hperh->cipher_text = cipher_text;
  420. hperh->size = size;
  421. crypt_interrupt_config(hperh, CRYPT_IT_IT, ENABLE);
  422. for (i = 0; i < hperh->step; i++) {
  423. CRYPT_WRITE_FIFO(hperh, *cipher_buf);
  424. cipher_buf++;
  425. }
  426. __UNLOCK(hperh);
  427. return OK;
  428. }
  429. #ifdef ALD_DMA
  430. /**
  431. * @brief Encrypt an amount of data in non-blocking mode.
  432. * @param hperh: Pointer to a crypt_handle_t structure that contains
  433. * the configuration information for the specified CRYPT module.
  434. * @param plain_text: Pointer to plain data buffer
  435. * @param cipher_text: Pointer to cipher data buffer
  436. * @param size: Amount of plain data
  437. * @param channel_m2p: Memory to Crypt module DMA channel
  438. * @param channel_p2m: Crypt module to Memory DMA channel
  439. * @retval Status, see @ref ald_status_t.
  440. * @note the size is multiple of 16(ase)
  441. */
  442. ald_status_t crypt_encrypt_by_dma(crypt_handle_t *hperh, uint8_t * plain_text,
  443. uint8_t *cipher_text, uint32_t size, uint8_t channel_m2p, uint8_t channel_p2m)
  444. {
  445. if (hperh->state != CRYPT_STATE_READY)
  446. return ERROR;
  447. if (plain_text == NULL || cipher_text == NULL || size == 0)
  448. return ERROR;
  449. assert_param(IS_CRYPT(hperh->perh));
  450. __LOCK(hperh);
  451. hperh->state = CRYPT_STATE_BUSY;
  452. hperh->plain_text = plain_text;
  453. hperh->cipher_text = cipher_text;
  454. hperh->size = size;
  455. hperh->count = size;
  456. if (hperh->hdma_m2p.perh == NULL)
  457. hperh->hdma_m2p.perh = DMA0;
  458. if (hperh->hdma_p2m.perh == NULL)
  459. hperh->hdma_p2m.perh = DMA0;
  460. hperh->hdma_m2p.cplt_arg = NULL;
  461. hperh->hdma_m2p.cplt_cbk = NULL;
  462. hperh->hdma_m2p.err_arg = NULL;
  463. hperh->hdma_m2p.err_cbk = NULL;
  464. hperh->hdma_p2m.cplt_arg = (void *)hperh;
  465. hperh->hdma_p2m.cplt_cbk = &crypt_dma_crypt_cplt;
  466. hperh->hdma_p2m.err_arg = (void *)hperh;
  467. hperh->hdma_p2m.err_cbk = &crypt_dma_error;
  468. CRYPT_SETDIR(hperh, CRYPT_ENCRYPT);
  469. dma_config_struct(&hperh->hdma_m2p.config);
  470. hperh->hdma_m2p.config.data_width = DMA_DATA_SIZE_WORD;
  471. hperh->hdma_m2p.config.src = (void *)hperh->plain_text;
  472. hperh->hdma_m2p.config.dst = (void *)&hperh->perh->FIFO;
  473. hperh->hdma_m2p.config.size = size / 4;
  474. hperh->hdma_m2p.config.src_inc = DMA_DATA_INC_WORD;
  475. hperh->hdma_m2p.config.dst_inc = DMA_DATA_INC_NONE;
  476. hperh->hdma_m2p.config.msel = DMA_MSEL_CRYPT;
  477. hperh->hdma_m2p.config.msigsel = DMA_MSIGSEL_CRYPT_WRITE;
  478. hperh->hdma_m2p.config.channel = channel_m2p;
  479. dma_config_basic(&(hperh->hdma_m2p));
  480. dma_config_struct(&hperh->hdma_p2m.config);
  481. hperh->hdma_p2m.config.data_width = DMA_DATA_SIZE_WORD;
  482. hperh->hdma_p2m.config.src = (void *)&hperh->perh->FIFO;
  483. hperh->hdma_p2m.config.dst = (void *)hperh->cipher_text;
  484. hperh->hdma_p2m.config.size = size / 4;
  485. hperh->hdma_p2m.config.src_inc = DMA_DATA_INC_NONE;
  486. hperh->hdma_p2m.config.dst_inc = DMA_DATA_INC_WORD;
  487. hperh->hdma_p2m.config.msel = DMA_MSEL_CRYPT;
  488. hperh->hdma_p2m.config.msigsel = DMA_MSIGSEL_CRYPT_READ;
  489. hperh->hdma_p2m.config.channel = channel_p2m;
  490. dma_config_basic(&(hperh->hdma_p2m));
  491. CRYPT_DMA_ENABLE(hperh);
  492. __UNLOCK(hperh);
  493. return OK;
  494. }
  495. /**
  496. * @brief Decrypt an amount of data in non-blocking mode.
  497. * @param hperh: Pointer to a crypt_handle_t structure that contains
  498. * the configuration information for the specified CRYPT module.
  499. * @param plain_text: Pointer to plain data buffer
  500. * @param cipher_text: Pointer to cipher data buffer
  501. * @param size: Amount of cipher data
  502. * @param channel_m2p: Memory to Crypt module DMA channel
  503. * @param channel_p2m: Crypt module to Memory DMA channel
  504. * @retval Status, see @ref ald_status_t.
  505. * @note the size is multiple of 16(ase)
  506. */
  507. ald_status_t crypt_decrypt_by_dma(crypt_handle_t *hperh, uint8_t * cipher_text,
  508. uint8_t *plain_text, uint32_t size, uint8_t channel_m2p, uint8_t channel_p2m)
  509. {
  510. if (hperh->init.mode == CRYPT_MODE_CTR)
  511. return crypt_decrypt_by_dma(hperh, cipher_text, plain_text, size, channel_m2p, channel_p2m);
  512. if (hperh->state != CRYPT_STATE_READY)
  513. return ERROR;
  514. if (plain_text == NULL || cipher_text == NULL || size == 0)
  515. return ERROR;
  516. __LOCK(hperh);
  517. hperh->state = CRYPT_STATE_BUSY;
  518. hperh->plain_text = plain_text;
  519. hperh->cipher_text = cipher_text;
  520. hperh->size = size;
  521. hperh->count = size;
  522. if (hperh->hdma_m2p.perh == NULL)
  523. hperh->hdma_m2p.perh = DMA0;
  524. if (hperh->hdma_p2m.perh == NULL)
  525. hperh->hdma_p2m.perh = DMA0;
  526. hperh->hdma_m2p.cplt_arg = NULL;
  527. hperh->hdma_m2p.cplt_cbk = NULL;
  528. hperh->hdma_m2p.err_arg = NULL;
  529. hperh->hdma_m2p.err_cbk = NULL;
  530. hperh->hdma_p2m.cplt_arg = (void *)hperh;
  531. hperh->hdma_p2m.cplt_cbk = &crypt_dma_crypt_cplt;
  532. hperh->hdma_p2m.err_arg = (void *)hperh;
  533. hperh->hdma_p2m.err_cbk = &crypt_dma_error;
  534. CRYPT_SETDIR(hperh, CRYPT_DECRYPT);
  535. dma_config_struct(&hperh->hdma_m2p.config);
  536. hperh->hdma_m2p.config.data_width = DMA_DATA_SIZE_WORD;
  537. hperh->hdma_m2p.config.src = (void *)hperh->cipher_text;
  538. hperh->hdma_m2p.config.dst = (void *)&hperh->perh->FIFO;
  539. hperh->hdma_m2p.config.size = size / 4;
  540. hperh->hdma_m2p.config.src_inc = DMA_DATA_INC_WORD;
  541. hperh->hdma_m2p.config.dst_inc = DMA_DATA_INC_NONE;
  542. hperh->hdma_m2p.config.msel = DMA_MSEL_CRYPT;
  543. hperh->hdma_m2p.config.msigsel = DMA_MSIGSEL_CRYPT_WRITE;
  544. hperh->hdma_m2p.config.channel = channel_m2p;
  545. dma_config_basic(&(hperh->hdma_m2p));
  546. dma_config_struct(&hperh->hdma_p2m.config);
  547. hperh->hdma_p2m.config.data_width = DMA_DATA_SIZE_WORD;
  548. hperh->hdma_p2m.config.src = (void *)&hperh->perh->FIFO;
  549. hperh->hdma_p2m.config.dst = (void *)hperh->plain_text;
  550. hperh->hdma_p2m.config.size = size / 4;
  551. hperh->hdma_p2m.config.src_inc = DMA_DATA_INC_NONE;
  552. hperh->hdma_p2m.config.dst_inc = DMA_DATA_INC_WORD;
  553. hperh->hdma_p2m.config.msel = DMA_MSEL_CRYPT;
  554. hperh->hdma_p2m.config.msigsel = DMA_MSIGSEL_CRYPT_READ;
  555. hperh->hdma_p2m.config.channel = channel_p2m;
  556. dma_config_basic(&(hperh->hdma_p2m));
  557. CRYPT_DMA_ENABLE(hperh);
  558. __UNLOCK(hperh);
  559. return OK;
  560. }
  561. /**
  562. * @}
  563. */
  564. /** @defgroup CRYPT_Public_Functions_Group3 DMA operation functions
  565. * @brief DMA operation functions
  566. * @{
  567. */
  568. /**
  569. * @brief Pauses the DMA Transfer.
  570. * @param hperh: Pointer to a crypt_handle_t structure that contains
  571. * the configuration information for the specified CRYPT module.
  572. * @retval Status, see @ref ald_status_t.
  573. */
  574. ald_status_t crypt_dma_pause(crypt_handle_t *hperh)
  575. {
  576. __LOCK(hperh);
  577. CRYPT_DMA_DISABLE(hperh);
  578. __UNLOCK(hperh);
  579. return OK;
  580. }
  581. /**
  582. * @brief Resumes the DMA Transfer.
  583. * @param hperh: Pointer to a crypt_handle_t structure that contains
  584. * the configuration information for the specified CRYPT module.
  585. * @retval Status, see @ref ald_status_t.
  586. */
  587. ald_status_t crypt_dma_resume(crypt_handle_t *hperh)
  588. {
  589. __LOCK(hperh);
  590. CRYPT_DMA_ENABLE(hperh);
  591. __UNLOCK(hperh);
  592. return OK;
  593. }
  594. /**
  595. * @brief Stops the DMA Transfer.
  596. * @param hperh: Pointer to a crypt_handle_t structure that contains
  597. * the configuration information for the specified CRYPT module.
  598. * @retval Status, see @ref ald_status_t.
  599. */
  600. ald_status_t crypt_dma_stop(crypt_handle_t *hperh)
  601. {
  602. __LOCK(hperh);
  603. CRYPT_DMA_DISABLE(hperh);
  604. __UNLOCK(hperh);
  605. hperh->state = CRYPT_STATE_READY;
  606. return OK;
  607. }
  608. #endif
  609. /**
  610. * @brief This function handles CRYPT interrupt request.
  611. * @param hperh: Pointer to a crypt_handle_t structure that contains
  612. * the configuration information for the specified CRYPT module.
  613. * @retval None
  614. */
  615. void crypt_irq_handle(crypt_handle_t *hperh)
  616. {
  617. uint32_t i;
  618. uint32_t *in_buf;
  619. uint32_t *out_buf;
  620. if (READ_BIT(hperh->perh->CON, CRYPT_CON_ENCS_MSK)) {
  621. in_buf = (uint32_t *)hperh->plain_text + hperh->count;
  622. out_buf = (uint32_t *)hperh->cipher_text + hperh->count - hperh->step;
  623. }
  624. else {
  625. in_buf = (uint32_t *)hperh->cipher_text + hperh->count;
  626. out_buf = (uint32_t *)hperh->plain_text + hperh->count - hperh->step;
  627. }
  628. if (crypt_get_flag_status(hperh, CRYPT_FLAG_AESIF) == SET) {
  629. crypt_clear_flag_status(hperh, CRYPT_FLAG_AESIF);
  630. }
  631. for (i = 0; i < hperh->step; i++)
  632. *out_buf++ = CRYPT_READ_FIFO(hperh);
  633. hperh->count += hperh->step;
  634. if (hperh->count > (hperh->size / 4)) {
  635. hperh->count = 0;
  636. hperh->state = CRYPT_STATE_READY;
  637. if (hperh->crypt_cplt_cbk)
  638. hperh->crypt_cplt_cbk(hperh);
  639. }
  640. else {
  641. for (i = 0; i < hperh->step; i++) {
  642. CRYPT_WRITE_FIFO(hperh, *in_buf++);
  643. }
  644. }
  645. }
  646. /**
  647. * @}
  648. */
  649. /** @defgroup CRYPT_Public_Functions_Group4 Peripheral Control functions
  650. * @brief CRYPT control functions
  651. * @{
  652. */
  653. /**
  654. * @brief Enables or disables the specified CRYPT interrupts.
  655. * @param hperh: Pointer to a crypt_handle_t structure that contains
  656. * the configuration information for the specified CRYPT module.
  657. * @param it: Specifies the CRYPT interrupt sources to be enabled or disabled.
  658. * This parameter can be one of the following values:
  659. * @arg crypt_it_t: CRYPT interrupt
  660. * @param state: New status
  661. * - ENABLE
  662. * - DISABLE
  663. * @retval None
  664. */
  665. void crypt_interrupt_config(crypt_handle_t *hperh, crypt_it_t it, type_func_t state)
  666. {
  667. assert_param(IS_CRYPT(hperh->perh));
  668. if (it == CRYPT_IT_IT) {
  669. CLEAR_BIT(CRYPT->CON, CRYPT_CON_IE_MSK);
  670. CRYPT->CON |= (state << CRYPT_CON_IE_POS);
  671. }
  672. return;
  673. }
  674. /** @brief Check whether the specified CRYPT flag is set or not.
  675. * @param hperh: Pointer to a crypt_handle_t structure that contains
  676. * the configuration information for the specified CRYPT module.
  677. * @param flag: specifies the flag to check.
  678. * This parameter can be one of the @ref crypt_flag_t.
  679. * @retval Status
  680. * - SET
  681. * - RESET
  682. */
  683. flag_status_t crypt_get_flag_status(crypt_handle_t *hperh, crypt_flag_t flag)
  684. {
  685. assert_param(IS_CRYPT(hperh->perh));
  686. assert_param(IS_CRYPT_FLAG(flag));
  687. if (CRYPT->IF & flag)
  688. return SET;
  689. return RESET;
  690. }
  691. /** @brief Clear the specified CRYPT pending flags.
  692. * @param hperh: Pointer to a crypt_handle_t structure that contains
  693. * the configuration information for the specified CRYPT module.
  694. * @param flag: specifies the flag to check.
  695. * This parameter can be any combination of the following values:
  696. * @arg CRYPT_FLAG_AESIF: AES encrypt or decrypt Complete flag.
  697. * @arg CRYPT_FLAG_DONE: encrypt or decrypt Complete flag.
  698. * @retval None
  699. */
  700. void crypt_clear_flag_status(crypt_handle_t *hperh, crypt_flag_t flag)
  701. {
  702. assert_param(IS_CRYPT(hperh->perh));
  703. assert_param(IS_CRYPT_FLAG(flag));
  704. WRITE_REG(CRYPT->IFC, flag);
  705. return;
  706. }
  707. /**
  708. * @brief Checks whether the specified CRYPT interrupt has occurred or not.
  709. * @param hperh: Pointer to a crypt_handle_t structure that contains
  710. * the configuration information for the specified CRYPT module.
  711. * @param it: Specifies the CRYPT interrupt source to check.
  712. * This parameter can be one of the following values:
  713. * @arg crypt_it_t: CRYPT interrupt
  714. * @retval Status
  715. * - SET
  716. * - RESET
  717. */
  718. it_status_t crypt_get_it_status(crypt_handle_t *hperh, crypt_it_t it)
  719. {
  720. assert_param(IS_CRYPT_IT(it));
  721. if (READ_BIT(CRYPT->CON, CRYPT_CON_IE_MSK))
  722. return SET;
  723. return RESET;
  724. }
  725. /**
  726. * @}
  727. */
  728. /** @defgroup CRYPT_Public_Functions_Group5 Peripheral State and Errors functions
  729. * @brief State and Errors functions
  730. * @{
  731. */
  732. /**
  733. * @brief Returns the CRYPT state.
  734. * @param hperh: Pointer to a crypt_handle_t structure that contains
  735. * the configuration information for the specified CRYPT module.
  736. * @retval CRYPT state
  737. */
  738. crypt_state_t crypt_get_state(crypt_handle_t *hperh)
  739. {
  740. assert_param(IS_CRYPT(hperh->perh));
  741. return hperh->state;
  742. }
  743. /**
  744. * @}
  745. */
  746. /**
  747. * @}
  748. */
  749. /** @defgroup CRYPT_Private_Functions CRYPT Private Functions
  750. * @brief CRYPT Private functions
  751. * @{
  752. */
  753. /**
  754. * @brief Reset the CRYPT peripheral.
  755. * @param hperh: Pointer to a crypt_handle_t structure that contains
  756. * the configuration information for the specified CRYPT module.
  757. * @retval None
  758. */
  759. void crypt_reset(crypt_handle_t *hperh)
  760. {
  761. hperh->perh->DATA[0] = 0x0;
  762. hperh->perh->DATA[1] = 0x0;
  763. hperh->perh->DATA[2] = 0x0;
  764. hperh->perh->DATA[3] = 0x0;
  765. hperh->perh->KEY[0] = 0x0;
  766. hperh->perh->KEY[1] = 0x0;
  767. hperh->perh->KEY[2] = 0x0;
  768. hperh->perh->KEY[3] = 0x0;
  769. hperh->perh->KEY[4] = 0x0;
  770. hperh->perh->KEY[5] = 0x0;
  771. hperh->perh->KEY[6] = 0x0;
  772. hperh->perh->KEY[7] = 0x0;
  773. hperh->perh->IV[0] = 0x0;
  774. hperh->perh->IV[1] = 0x0;
  775. hperh->perh->IV[2] = 0x0;
  776. hperh->perh->IV[3] = 0x0;
  777. hperh->perh->CON = 0x0;
  778. hperh->state = CRYPT_STATE_READY;
  779. __UNLOCK(hperh);
  780. }
  781. #ifdef ALD_DMA
  782. /**
  783. * @brief DMA CRYPT encrypt or decrypt process complete callback.
  784. * @param arg: Pointer to a crypt_handle_t structure that contains
  785. * the configuration information for the specified CRYPT module.
  786. * @retval None
  787. */
  788. static void crypt_dma_crypt_cplt(void *arg)
  789. {
  790. crypt_handle_t *hperh = (crypt_handle_t *)arg;
  791. CRYPT_DMA_DISABLE(hperh);
  792. hperh->count = 0;
  793. hperh->plain_text = NULL;
  794. hperh->cipher_text = NULL;
  795. hperh->size = 0;
  796. hperh->state = CRYPT_STATE_READY;
  797. if (hperh->crypt_cplt_cbk)
  798. hperh->crypt_cplt_cbk(hperh);
  799. }
  800. /**
  801. * @brief DMA CRYPT communication error callback.
  802. * @param arg: Pointer to a crypt_handle_t structure that contains
  803. * the configuration information for the specified CRYPT module.
  804. * @retval None
  805. */
  806. static void crypt_dma_error(void *arg)
  807. {
  808. crypt_handle_t *hperh = (crypt_handle_t *)arg;
  809. CRYPT_DMA_DISABLE(hperh);
  810. hperh->count = 0;
  811. hperh->plain_text = NULL;
  812. hperh->cipher_text = NULL;
  813. hperh->size = 0;
  814. hperh->state = CRYPT_STATE_READY;
  815. if (hperh->err_cplt_cbk)
  816. hperh->err_cplt_cbk(hperh);
  817. }
  818. #endif
  819. /**
  820. * @}
  821. */
  822. /**
  823. * @}
  824. */
  825. #endif /* ALD_CRYPT */
  826. /**
  827. * @}
  828. */