drv_crypto.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /*
  2. * Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-07-01 lik first version
  9. */
  10. #include "drv_crypto.h"
  11. #include <string.h>
  12. #ifdef RT_USING_HWCRYPTO
  13. //#define DRV_DEBUG
  14. #define LOG_TAG "drv.crypto"
  15. #include <drv_log.h>
  16. struct swm_hwcrypto_device
  17. {
  18. struct rt_hwcrypto_device dev;
  19. struct rt_mutex mutex;
  20. };
  21. static struct swm_hwcrypto_device hwcrypto_obj;
  22. #ifdef BSP_USING_CRC
  23. struct swm_crc_cfg
  24. {
  25. CRC_TypeDef *CRCx;
  26. CRC_InitStructure CRC_initstruct;
  27. };
  28. static struct hwcrypto_crc_cfg swm_crc_cfg;
  29. static rt_uint32_t swm_crc_update(struct hwcrypto_crc *ctx, const rt_uint8_t *in, rt_size_t length)
  30. {
  31. rt_uint32_t result = 0;
  32. struct swm_hwcrypto_device *hwcrypto_dev = (struct swm_hwcrypto_device *)ctx->parent.device->user_data;
  33. struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->parent.contex);
  34. rt_mutex_take(&hwcrypto_dev->mutex, RT_WAITING_FOREVER);
  35. if (memcmp(&swm_crc_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg)) != 0)
  36. {
  37. crc_cfg->CRCx = CRC;
  38. crc_cfg->CRC_initstruct.init_crc = ctx->crc_cfg.last_val;
  39. switch (ctx->crc_cfg.poly)
  40. {
  41. case 0x07:
  42. crc_cfg->CRC_initstruct.Poly = CRC_POLY_107;
  43. break;
  44. case 0x1021:
  45. crc_cfg->CRC_initstruct.Poly = CRC_POLY_11021;
  46. break;
  47. case 0x8005:
  48. crc_cfg->CRC_initstruct.Poly = CRC_POLY_18005;
  49. break;
  50. case 0x04C11DB7:
  51. crc_cfg->CRC_initstruct.Poly = CRC_POLY_104C11DB7;
  52. break;
  53. default:
  54. goto _exit;
  55. }
  56. switch (ctx->crc_cfg.width)
  57. {
  58. case 8:
  59. crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_8;
  60. break;
  61. case 16:
  62. crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_16;
  63. break;
  64. case 32:
  65. crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_32;
  66. break;
  67. default:
  68. goto _exit;
  69. }
  70. switch (ctx->crc_cfg.flags)
  71. {
  72. case 0:
  73. crc_cfg->CRC_initstruct.in_not = false;
  74. crc_cfg->CRC_initstruct.out_not = false;
  75. break;
  76. case CRC_FLAG_REFIN:
  77. crc_cfg->CRC_initstruct.in_not = true;
  78. crc_cfg->CRC_initstruct.out_not = false;
  79. break;
  80. case CRC_FLAG_REFOUT:
  81. crc_cfg->CRC_initstruct.in_not = false;
  82. crc_cfg->CRC_initstruct.out_not = true;
  83. break;
  84. case CRC_FLAG_REFIN | CRC_FLAG_REFOUT:
  85. crc_cfg->CRC_initstruct.in_not = true;
  86. crc_cfg->CRC_initstruct.out_not = true;
  87. break;
  88. default:
  89. goto _exit;
  90. }
  91. crc_cfg->CRC_initstruct.in_rev = CRC_REV_NOT;
  92. crc_cfg->CRC_initstruct.out_rev = CRC_REV_NOT;
  93. CRC_Init(crc_cfg->CRCx, &(crc_cfg->CRC_initstruct));
  94. memcpy(&swm_crc_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg));
  95. }
  96. for (uint32_t i = 0; i < length; i++)
  97. CRC_Write((uint32_t)in[i]);
  98. result = CRC_Result();
  99. ctx->crc_cfg.last_val = result;
  100. swm_crc_cfg.last_val = ctx->crc_cfg.last_val;
  101. result = (result ? result ^ (ctx->crc_cfg.xorout) : result);
  102. _exit:
  103. rt_mutex_release(&hwcrypto_dev->mutex);
  104. return result;
  105. }
  106. static const struct hwcrypto_crc_ops swm_crc_ops =
  107. {
  108. .update = swm_crc_update,
  109. };
  110. #endif /* BSP_USING_CRC */
  111. #if defined(BSP_USING_RNG)
  112. struct swm_rng_cfg
  113. {
  114. SYS_TypeDef *SYSx;
  115. };
  116. static rt_uint32_t swm_rng_update(struct hwcrypto_rng *ctx)
  117. {
  118. rt_uint32_t gen_randoml = 0, gen_randomh = 0;
  119. struct swm_rng_cfg *rng_cfg = (struct swm_rng_cfg *)(ctx->parent.contex);
  120. while ((rng_cfg->SYSx->PRNGCR & SYS_PRNGCR_RDY_Msk) == 0)
  121. __NOP();
  122. gen_randoml = rng_cfg->SYSx->PRNGDL;
  123. gen_randomh = rng_cfg->SYSx->PRNGDH;
  124. return gen_randoml;
  125. }
  126. static const struct hwcrypto_rng_ops swm_rng_ops =
  127. {
  128. .update = swm_rng_update,
  129. };
  130. #endif /* BSP_USING_RNG */
  131. static rt_err_t swm_crypto_create(struct rt_hwcrypto_ctx *ctx)
  132. {
  133. rt_err_t res = RT_EOK;
  134. switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
  135. {
  136. #if defined(BSP_USING_CRC)
  137. case HWCRYPTO_TYPE_CRC:
  138. {
  139. struct swm_crc_cfg *crc_cfg = rt_calloc(1, sizeof(struct swm_crc_cfg));
  140. if (RT_NULL == crc_cfg)
  141. {
  142. res = -RT_ERROR;
  143. break;
  144. }
  145. ctx->contex = crc_cfg;
  146. ((struct hwcrypto_crc *)ctx)->ops = &swm_crc_ops;
  147. break;
  148. }
  149. #endif /* BSP_USING_CRC */
  150. #if defined(BSP_USING_RNG)
  151. case HWCRYPTO_TYPE_RNG:
  152. {
  153. struct swm_rng_cfg *rng_cfg = rt_calloc(1, sizeof(struct swm_rng_cfg));
  154. if (RT_NULL == rng_cfg)
  155. {
  156. res = -RT_ERROR;
  157. break;
  158. }
  159. rng_cfg->SYSx = SYS;
  160. rng_cfg->SYSx->HRCCR |= (1 << SYS_HRCCR_ON_Pos);
  161. rng_cfg->SYSx->LRCCR |= (1 << SYS_LRCCR_ON_Pos);
  162. rng_cfg->SYSx->PRNGCR = (0 << SYS_PRNGCR_CLR_Pos) |
  163. (3 << SYS_PRNGCR_MODE_Pos);
  164. ctx->contex = rng_cfg;
  165. ((struct hwcrypto_rng *)ctx)->ops = &swm_rng_ops;
  166. break;
  167. }
  168. #endif /* BSP_USING_RNG */
  169. default:
  170. res = -RT_ERROR;
  171. break;
  172. }
  173. return res;
  174. }
  175. static void swm_crypto_destroy(struct rt_hwcrypto_ctx *ctx)
  176. {
  177. struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
  178. switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
  179. {
  180. #if defined(BSP_USING_CRC)
  181. case HWCRYPTO_TYPE_CRC:
  182. crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
  183. break;
  184. #endif /* BSP_USING_CRC */
  185. #if defined(BSP_USING_RNG)
  186. case HWCRYPTO_TYPE_RNG:
  187. break;
  188. #endif /* BSP_USING_RNG */
  189. default:
  190. break;
  191. }
  192. rt_free(ctx->contex);
  193. }
  194. static rt_err_t swm_crypto_clone(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
  195. {
  196. rt_err_t res = RT_EOK;
  197. switch (src->type & HWCRYPTO_MAIN_TYPE_MASK)
  198. {
  199. #if defined(BSP_USING_CRC)
  200. case HWCRYPTO_TYPE_CRC:
  201. if (des->contex && src->contex)
  202. {
  203. rt_memcpy(des->contex, src->contex, sizeof(struct swm_crc_cfg));
  204. }
  205. break;
  206. #endif /* BSP_USING_CRC */
  207. #if defined(BSP_USING_RNG)
  208. case HWCRYPTO_TYPE_RNG:
  209. if (des->contex && src->contex)
  210. {
  211. rt_memcpy(des->contex, src->contex, sizeof(struct swm_rng_cfg));
  212. }
  213. break;
  214. #endif /* BSP_USING_RNG */
  215. default:
  216. res = -RT_ERROR;
  217. break;
  218. }
  219. return res;
  220. }
  221. static void swm_crypto_reset(struct rt_hwcrypto_ctx *ctx)
  222. {
  223. struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
  224. switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
  225. {
  226. #if defined(BSP_USING_CRC)
  227. case HWCRYPTO_TYPE_CRC:
  228. crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
  229. break;
  230. #endif /* BSP_USING_CRC */
  231. #if defined(BSP_USING_RNG)
  232. case HWCRYPTO_TYPE_RNG:
  233. break;
  234. #endif /* BSP_USING_RNG */
  235. default:
  236. break;
  237. }
  238. }
  239. static const struct rt_hwcrypto_ops swm_hwcrypto_ops =
  240. {
  241. .create = swm_crypto_create,
  242. .destroy = swm_crypto_destroy,
  243. .copy = swm_crypto_clone,
  244. .reset = swm_crypto_reset,
  245. };
  246. int swm_crypto_init(void)
  247. {
  248. rt_uint32_t cpuid[2] = {0};
  249. hwcrypto_obj.dev.ops = &swm_hwcrypto_ops;
  250. cpuid[0] = SCB->CPUID;
  251. hwcrypto_obj.dev.id = 0;
  252. rt_memcpy(&hwcrypto_obj.dev.id, cpuid, 8);
  253. hwcrypto_obj.dev.user_data = &hwcrypto_obj;
  254. if (rt_hwcrypto_register(&hwcrypto_obj.dev, RT_HWCRYPTO_DEFAULT_NAME) != RT_EOK)
  255. {
  256. return -1;
  257. }
  258. rt_mutex_init(&hwcrypto_obj.mutex, RT_HWCRYPTO_DEFAULT_NAME, RT_IPC_FLAG_FIFO);
  259. return 0;
  260. }
  261. INIT_BOARD_EXPORT(swm_crypto_init);
  262. #endif /* RT_USING_HWCRYPTO */