PageRenderTime 28ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/aes/ck_aes.c

https://gitlab.com/21mece13/FreeRTOS
C | 525 lines | 350 code | 82 blank | 93 comment | 82 complexity | 5cabbf6000808fd65ae01ec8c630e429 MD5 | raw file
  1. /*
  2. * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
  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. /******************************************************************************
  17. * @file ck_aes.c
  18. * @brief CSI Source File for aes driver
  19. * @version V1.0
  20. * @date 02. June 2017
  21. ******************************************************************************/
  22. #include <string.h>
  23. #include "csi_core.h"
  24. #include "drv_aes.h"
  25. #include "ck_aes.h"
  26. #define ERR_AES(errno) (CSI_DRV_ERRNO_AES_BASE | errno)
  27. #define AES_NULL_PARA_CHK(para) \
  28. do { \
  29. if (para == NULL) { \
  30. return ERR_AES(EDRV_PARAMETER); \
  31. } \
  32. } while (0)
  33. static ck_aes_reg_t *aes_reg = NULL;
  34. volatile static uint8_t block_cal_done = 0;
  35. typedef struct {
  36. uint32_t base;
  37. uint32_t irq;
  38. void *iv;
  39. uint8_t *result_out;
  40. uint32_t len;
  41. aes_event_cb_t cb;
  42. aes_mode_e mode;
  43. aes_key_len_bits_e keylen;
  44. aes_endian_mode_e endian;
  45. aes_crypto_mode_e enc;
  46. aes_status_t status;
  47. } ck_aes_priv_t;
  48. extern int32_t target_get_aes_count(void);
  49. extern int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq);
  50. static ck_aes_priv_t aes_handle[CONFIG_AES_NUM];
  51. /* Driver Capabilities */
  52. static const aes_capabilities_t driver_capabilities = {
  53. .ecb_mode = 1, /* ECB mode */
  54. .cbc_mode = 1, /* CBC mode */
  55. .cfb_mode = 0, /* CFB mode */
  56. .ofb_mode = 0, /* OFB mode */
  57. .ctr_mode = 0, /* CTR mode */
  58. .bits_128 = 1, /* 128bits key length mode */
  59. .bits_192 = 1, /* 192bits key lenght mode */
  60. .bits_256 = 1 /* 256bits key length mode */
  61. };
  62. extern int32_t target_get_aes(int32_t idx, uint32_t *base, uint32_t *irq);
  63. extern int32_t target_get_aes_count(void);
  64. //
  65. // Functions
  66. //
  67. static inline void aes_set_opcode(aes_crypto_mode_e opcode)
  68. {
  69. aes_reg->ctrl &= ~(3 << AES_OPCODE_OFFSET); //clear bit[7:6]
  70. aes_reg->ctrl |= (opcode << AES_OPCODE_OFFSET); //set opcode
  71. }
  72. static inline void aes_set_endian(aes_endian_mode_e endian)
  73. {
  74. if (endian == AES_ENDIAN_LITTLE) {
  75. aes_reg->ctrl &= ~AES_LITTLE_ENDIAN;
  76. } else {
  77. aes_reg->ctrl |= AES_LITTLE_ENDIAN;
  78. }
  79. }
  80. static inline uint32_t aes_set_keylen(aes_key_len_bits_e keylength)
  81. {
  82. aes_reg->ctrl &= ~(3 << AES_KEY_LEN_OFFSET); //clear bit[5:4]
  83. aes_reg->ctrl |= (keylength << AES_KEY_LEN_OFFSET);// Set key length
  84. return 0;
  85. }
  86. static inline void aes_set_mode(aes_mode_e mode)
  87. {
  88. aes_reg->ctrl &= ~(1 << AES_MODE_OFFSET); //clear bit 3
  89. aes_reg->ctrl |= (mode << AES_MODE_OFFSET); //set mode
  90. }
  91. static inline void aes_enable(void)
  92. {
  93. aes_reg->ctrl |= (1 << AES_WORK_ENABLE_OFFSET);
  94. }
  95. static inline void aes_disable(void)
  96. {
  97. aes_reg->ctrl &= ~(1 << AES_WORK_ENABLE_OFFSET);
  98. }
  99. static inline void aes_enable_interrupt(void)
  100. {
  101. aes_reg->ctrl |= (1 << AES_INT_ENABLE_OFFSET);
  102. }
  103. static inline void aes_disable_interrupt(void)
  104. {
  105. aes_reg->ctrl &= ~(1 << AES_INT_ENABLE_OFFSET);
  106. }
  107. static inline void aes_clear_interrupt(void)
  108. {
  109. aes_reg->state = 0x0;
  110. }
  111. static inline uint32_t aes_get_intstatus(uint32_t AES_IT)
  112. {
  113. return (aes_reg->state & AES_IT) ? 1 : 0;
  114. }
  115. static void aes_set_key(void *context, uint8_t *key, aes_key_len_bits_e keylen, uint32_t enc, uint32_t endian)
  116. {
  117. uint8_t keynum = 0;
  118. if (keylen == AES_KEY_LEN_BITS_128) {
  119. keynum = 4;
  120. } else if (keylen == AES_KEY_LEN_BITS_192) {
  121. keynum = 6;
  122. } else if (keylen == AES_KEY_LEN_BITS_256) {
  123. keynum = 8;
  124. }
  125. uint32_t i;
  126. uint32_t temp = 0;
  127. /* set key according to the endian mode */
  128. if (endian == AES_ENDIAN_LITTLE) {
  129. for (i = 0; i < keynum; i++) {
  130. temp = key[3] << 24 | key[2] << 16 | key[1] << 8 | key[0];
  131. aes_reg->key[keynum - 1 - i] = temp;
  132. key += 4;
  133. }
  134. } else if (endian == AES_ENDIAN_BIG) {
  135. for (i = 0; i < keynum; i++) {
  136. temp = key[3] << 24 | key[2] << 16 | key[1] << 8 | key[0];
  137. aes_reg->key[i] = temp;
  138. key += 4;
  139. }
  140. }
  141. if (enc == AES_CRYPTO_MODE_DECRYPT) {
  142. aes_set_opcode(AES_CRYPTO_KEYEXP); /* if the mode is decrypt before decrypt you have to keyexpand */
  143. aes_enable();
  144. // while(block_cal_done == 0);
  145. // block_cal_done = 0;
  146. while (aes_get_intstatus(AES_IT_KEYINT));
  147. aes_set_opcode(AES_CRYPTO_MODE_DECRYPT);
  148. } else if (enc == AES_CRYPTO_MODE_ENCRYPT) {
  149. aes_set_opcode(AES_CRYPTO_MODE_ENCRYPT);
  150. }
  151. aes_disable();
  152. }
  153. static void aes_set_iv(uint32_t mode, uint32_t endian, uint8_t *iv)
  154. {
  155. uint32_t temp;
  156. uint32_t i;
  157. /* set iv if the mode is CBC */
  158. if (mode == AES_MODE_CBC) {
  159. if (endian == AES_ENDIAN_BIG) {
  160. for (i = 0; i < 4; i++) {
  161. temp = iv[3] << 24 | iv[2] << 16 | iv[1] << 8 | iv[0];
  162. aes_reg->iv[i] = temp;
  163. iv += 4;
  164. }
  165. } else if (endian == AES_ENDIAN_LITTLE) {
  166. for (i = 0; i < 4; i++) {
  167. temp = iv[3] << 24 | iv[2] << 16 | iv[1] << 8 | iv[0];
  168. aes_reg->iv[3 - i] = temp;
  169. iv += 4;
  170. }
  171. }
  172. }
  173. }
  174. static int aes_crypto(void *context, uint8_t *in, uint8_t *out,
  175. uint32_t len, uint8_t *iv, uint32_t mode, uint32_t endian, uint32_t enc)
  176. {
  177. uint32_t temp[4];
  178. aes_set_iv(mode, endian, iv);
  179. uint32_t i = 0;
  180. uint32_t j = 0;
  181. /* set the text before aes calculating */
  182. for (i = 0; i < len; i = i + 16) {
  183. for (j = 0; j < 4; j++) {
  184. temp[j] = in[3] << 24 | in[2] << 16 | in[1] << 8 | in[0];
  185. if (endian == AES_ENDIAN_BIG) {
  186. aes_reg->datain[j] = temp[j];
  187. } else if (endian == AES_ENDIAN_LITTLE) {
  188. aes_reg->datain[3 - j] = temp[j];
  189. }
  190. in += 4;
  191. }
  192. aes_enable();
  193. while(block_cal_done == 0);
  194. block_cal_done = 0;
  195. if (enc == AES_CRYPTO_MODE_ENCRYPT && mode == AES_MODE_CBC) {
  196. aes_set_iv(mode, endian, out);
  197. memcpy(iv, out, 16);
  198. out += 16;
  199. } else if (enc == AES_CRYPTO_MODE_DECRYPT && mode == AES_MODE_CBC) {
  200. aes_set_iv(mode, endian, (uint8_t *)&temp);
  201. memcpy(iv, temp, 16);
  202. }
  203. }
  204. return 0;
  205. }
  206. void ck_aes_irqhandler(int32_t idx)
  207. {
  208. ck_aes_priv_t *aes_priv = &aes_handle[idx];
  209. volatile uint32_t j;
  210. uint32_t tmp = 0;
  211. /* get the result after aes calculating*/
  212. if (aes_priv->result_out != NULL) {
  213. for (j = 0; j < 4; j++) {
  214. if (aes_priv->endian == AES_ENDIAN_BIG) {
  215. tmp = aes_reg->dataout[j];
  216. } else if (aes_priv->endian == AES_ENDIAN_LITTLE) {
  217. tmp = aes_reg->dataout[3 - j];
  218. }
  219. memcpy(aes_priv->result_out, &tmp, 4);
  220. aes_priv->result_out += 4;
  221. aes_priv->len -= 4;
  222. }
  223. }
  224. block_cal_done = 1;
  225. /* disable aes and clear the aes interrupt */
  226. aes_disable();
  227. aes_clear_interrupt();
  228. /* execute the callback function */
  229. if (aes_priv->len == 0) {
  230. if (aes_priv->cb) {
  231. aes_priv->cb(AES_EVENT_CRYPTO_COMPLETE);
  232. }
  233. }
  234. }
  235. /**
  236. \brief get aes instance count.
  237. \return aes handle count
  238. */
  239. int32_t csi_aes_get_instance_count(void)
  240. {
  241. return target_get_aes_count();
  242. }
  243. /**
  244. \brief Initialize AES Interface. 1. Initializes the resources needed for the AES interface 2.registers event callback function
  245. \param[in] idx must not exceed return value of csi_aes_get_instance_count().
  246. \param[in] cb_event Pointer to \ref aes_event_cb_t
  247. \return return aes handle if success
  248. */
  249. aes_handle_t csi_aes_initialize(int32_t idx, aes_event_cb_t cb_event)
  250. {
  251. if (idx < 0 || idx >= CONFIG_AES_NUM) {
  252. return NULL;
  253. }
  254. uint32_t irq = 0u;
  255. uint32_t base = 0u;
  256. /* obtain the aes information */
  257. int32_t real_idx = target_get_aes(idx, &base, &irq);
  258. if (real_idx != idx) {
  259. return NULL;
  260. }
  261. ck_aes_priv_t *aes_priv = &aes_handle[idx];
  262. aes_priv->base = base;
  263. aes_priv->irq = irq;
  264. /* initialize the aes context */
  265. aes_reg = (ck_aes_reg_t *)(aes_priv->base);
  266. aes_priv->cb = cb_event;
  267. aes_priv->iv = NULL;
  268. aes_priv->len = 16;
  269. aes_priv->result_out = NULL;
  270. aes_priv->mode = AES_MODE_CBC;
  271. aes_priv->keylen = AES_KEY_LEN_BITS_128;
  272. aes_priv->endian = AES_ENDIAN_LITTLE;
  273. aes_priv->status.busy = 0;
  274. aes_enable_interrupt(); /* enable the aes interrupt */
  275. drv_nvic_enable_irq(aes_priv->irq); /* enable the aes bit in nvic */
  276. return (aes_handle_t)aes_priv;
  277. }
  278. /**
  279. \brief De-initialize AES Interface. stops operation and releases the software resources used by the interface
  280. \param[in] handle aes handle to operate.
  281. \return error code
  282. */
  283. int32_t csi_aes_uninitialize(aes_handle_t handle)
  284. {
  285. AES_NULL_PARA_CHK(handle);
  286. ck_aes_priv_t *aes_priv = handle;
  287. aes_priv->cb = NULL;
  288. aes_disable_interrupt(); /* disable the aes interrupt */
  289. drv_nvic_disable_irq(aes_priv->irq);
  290. return 0;
  291. }
  292. /**
  293. \brief Get driver capabilities.
  294. \param[in] handle aes handle to operate.
  295. \return \ref aes_capabilities_t
  296. */
  297. aes_capabilities_t csi_aes_get_capabilities(aes_handle_t handle)
  298. {
  299. return driver_capabilities;
  300. }
  301. /**
  302. \brief config aes mode.
  303. \param[in] handle aes handle to operate.
  304. \param[in] mode \ref aes_mode_e
  305. \param[in] keylen_bits \ref aes_key_len_bits_e
  306. \param[in] endian \ref aes_endian_mode_e
  307. \param[in] arg Pointer to the iv address when mode is cbc_mode
  308. \return error code
  309. */
  310. int32_t csi_aes_config(aes_handle_t handle, aes_mode_e mode, aes_key_len_bits_e keylen_bits, aes_endian_mode_e endian, uint32_t arg)
  311. {
  312. AES_NULL_PARA_CHK(handle);
  313. ck_aes_priv_t *aes_priv = handle;
  314. aes_reg = (ck_aes_reg_t *)(aes_priv->base);
  315. /* config the aes mode */
  316. switch (mode) {
  317. case AES_MODE_CBC:
  318. aes_priv->iv = (void *)arg;
  319. aes_priv->mode = mode;
  320. aes_set_mode(mode);
  321. break;
  322. case AES_MODE_ECB:
  323. aes_priv->mode = mode;
  324. aes_set_mode(mode);
  325. break;
  326. case AES_MODE_CFB:
  327. case AES_MODE_OFB:
  328. case AES_MODE_CTR:
  329. return ERR_AES(EDRV_UNSUPPORTED);
  330. default:
  331. return ERR_AES(EDRV_PARAMETER);
  332. }
  333. /* config the key length */
  334. switch (keylen_bits) {
  335. case AES_KEY_LEN_BITS_128:
  336. case AES_KEY_LEN_BITS_192:
  337. case AES_KEY_LEN_BITS_256:
  338. aes_priv->keylen = keylen_bits;
  339. aes_set_keylen(keylen_bits);
  340. break;
  341. default:
  342. return ERR_AES(EDRV_PARAMETER);
  343. }
  344. /* config the endian mode */
  345. switch (endian) {
  346. case AES_ENDIAN_LITTLE:
  347. aes_priv->endian = endian;
  348. aes_set_endian(endian);
  349. break;
  350. case AES_ENDIAN_BIG:
  351. aes_priv->endian = endian;
  352. aes_set_endian(endian);
  353. break;
  354. default:
  355. return ERR_AES(EDRV_PARAMETER);
  356. }
  357. return 0;
  358. }
  359. /**
  360. \brief set crypto key.
  361. \param[in] handle aes handle to operate.
  362. \param[in] context aes information context(NULL when hardware implementation)
  363. \param[in] key Pointer to the key buf
  364. \param[in] key_len Pointer to the aes_key_len_bits_e
  365. \param[in] enc \ref aes_crypto_mode_e
  366. \return error code
  367. */
  368. int32_t csi_aes_set_key(aes_handle_t handle, void *context, void *key, aes_key_len_bits_e key_len, aes_crypto_mode_e enc)
  369. {
  370. AES_NULL_PARA_CHK(handle);
  371. AES_NULL_PARA_CHK(key);
  372. if ((key_len != AES_KEY_LEN_BITS_128 &&
  373. key_len != AES_KEY_LEN_BITS_192 &&
  374. key_len != AES_KEY_LEN_BITS_256) ||
  375. (enc != AES_CRYPTO_MODE_ENCRYPT &&
  376. enc != AES_CRYPTO_MODE_DECRYPT)) {
  377. return ERR_AES(EDRV_PARAMETER);
  378. }
  379. ck_aes_priv_t *aes_priv = handle;
  380. aes_priv->enc = enc;
  381. aes_set_key(context, key, key_len, enc, aes_priv->endian);
  382. return 0;
  383. }
  384. /**
  385. \brief encrypt or decrypt
  386. \param[in] handle aes handle to operate.
  387. \param[in] context aes information context(NULL when hardware implementation)
  388. \param[in] in Pointer to the Source data
  389. \param[out] out Pointer to the Result data.
  390. \param[in] len the Source data len.
  391. \param[in] padding \ref aes_padding_mode_e.
  392. \return error code
  393. */
  394. int32_t csi_aes_crypto(aes_handle_t handle, void *context, void *in, void *out, uint32_t len, aes_padding_mode_e padding)
  395. {
  396. AES_NULL_PARA_CHK(handle);
  397. AES_NULL_PARA_CHK(in);
  398. AES_NULL_PARA_CHK(out);
  399. AES_NULL_PARA_CHK(len);
  400. ck_aes_priv_t *aes_priv = handle;
  401. aes_priv->status.busy = 1;
  402. uint8_t left_len = len & 0xf;
  403. switch (padding) {
  404. case AES_PADDING_MODE_NO:
  405. if (left_len) {
  406. return ERR_AES(EDRV_PARAMETER);
  407. }
  408. /* crypto in padding no mode */
  409. aes_priv->result_out = out;
  410. aes_priv->len = len;
  411. aes_crypto(context, in, out, len, aes_priv->iv, aes_priv->mode, aes_priv->endian, aes_priv->enc);
  412. break;
  413. case AES_PADDING_MODE_ZERO:
  414. if (left_len == 0) {
  415. return ERR_AES(EDRV_PARAMETER);
  416. }
  417. uint8_t i = 0;
  418. for (i = 0; i < (16 - left_len); i++) {
  419. *((uint8_t *)in + len + i) = 0x0;
  420. }
  421. /* crypto in padding zero mode */
  422. aes_priv->result_out = out;
  423. aes_priv->len = len + 16 -left_len;
  424. aes_crypto(context, in, out, len + 16 - left_len, aes_priv->iv, aes_priv->mode, aes_priv->endian, aes_priv->enc);
  425. break;
  426. case AES_PADDING_MODE_PKCS5:
  427. return ERR_AES(EDRV_UNSUPPORTED);
  428. default:
  429. return ERR_AES(EDRV_PARAMETER);
  430. }
  431. aes_priv->status.busy = 0;
  432. return 0;
  433. }
  434. /**
  435. \brief Get AES status.
  436. \param[in] handle aes handle to operate.
  437. \return AES status \ref aes_status_t
  438. */
  439. aes_status_t csi_aes_get_status(aes_handle_t handle)
  440. {
  441. ck_aes_priv_t *aes_priv = handle;
  442. return aes_priv->status;
  443. }