ck_aes.c 13 KB

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