drv_crypto.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. * Copyright (c) 2006-2018, Synwit Technology Co.,Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-07-10 lik first version
  9. */
  10. #include "drv_crypto.h"
  11. #include <string.h>
  12. #ifdef RT_USING_HWCRYPTO
  13. struct swm_hwcrypto_device
  14. {
  15. struct rt_hwcrypto_device dev;
  16. struct rt_mutex mutex;
  17. };
  18. #ifdef BSP_USING_CRC
  19. static struct hwcrypto_crc_cfg crc_backup_cfg;
  20. static rt_uint32_t _crc_update(struct hwcrypto_crc *ctx, const rt_uint8_t *in, rt_size_t length)
  21. {
  22. rt_uint32_t result = 0;
  23. struct swm_hwcrypto_device *swm_hw_dev = (struct swm_hwcrypto_device *)ctx->parent.device->user_data;
  24. struct swm_crc_cfg *hw_crc_cfg = (struct swm_crc_cfg *)(ctx->parent.contex);
  25. rt_mutex_take(&swm_hw_dev->mutex, RT_WAITING_FOREVER);
  26. if (memcmp(&crc_backup_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg)) != 0)
  27. {
  28. hw_crc_cfg->CRCx = CRC;
  29. hw_crc_cfg->inival = ctx->crc_cfg.last_val;
  30. switch (ctx->crc_cfg.width)
  31. {
  32. case 8:
  33. hw_crc_cfg->crc_inbits = 2;
  34. break;
  35. case 16:
  36. hw_crc_cfg->crc_inbits = 1;
  37. break;
  38. case 32:
  39. hw_crc_cfg->crc_inbits = 0;
  40. break;
  41. default:
  42. goto _exit;
  43. }
  44. switch (ctx->crc_cfg.poly)
  45. {
  46. case 0x1021:
  47. hw_crc_cfg->crc_1632 = 1;
  48. break;
  49. case 0x04C11DB7:
  50. hw_crc_cfg->crc_1632 = 0;
  51. break;
  52. default:
  53. goto _exit;
  54. }
  55. hw_crc_cfg->crc_out_not = 0;
  56. switch (ctx->crc_cfg.flags)
  57. {
  58. case 0:
  59. case CRC_FLAG_REFIN:
  60. hw_crc_cfg->crc_out_rev = 0;
  61. break;
  62. case CRC_FLAG_REFOUT:
  63. case CRC_FLAG_REFIN | CRC_FLAG_REFOUT:
  64. hw_crc_cfg->crc_out_rev = 1;
  65. break;
  66. default:
  67. goto _exit;
  68. }
  69. CRC_Init(hw_crc_cfg->CRCx, (hw_crc_cfg->crc_inbits << 1) | hw_crc_cfg->crc_1632, hw_crc_cfg->crc_out_not, hw_crc_cfg->crc_out_rev, hw_crc_cfg->inival);
  70. memcpy(&crc_backup_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg));
  71. }
  72. for (uint32_t i = 0; i < length; i++)
  73. CRC_Write((uint32_t)in[i]);
  74. result = CRC_Result();
  75. ctx->crc_cfg.last_val = result;
  76. crc_backup_cfg.last_val = ctx->crc_cfg.last_val;
  77. result = (result ? result ^ (ctx->crc_cfg.xorout) : result);
  78. _exit:
  79. rt_mutex_release(&swm_hw_dev->mutex);
  80. return result;
  81. }
  82. static const struct hwcrypto_crc_ops crc_ops =
  83. {
  84. .update = _crc_update,
  85. };
  86. #endif /* BSP_USING_CRC */
  87. static rt_err_t _crypto_create(struct rt_hwcrypto_ctx *ctx)
  88. {
  89. rt_err_t res = RT_EOK;
  90. switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
  91. {
  92. #if defined(BSP_USING_CRC)
  93. case HWCRYPTO_TYPE_CRC:
  94. {
  95. struct swm_crc_cfg *contex = rt_calloc(1, sizeof(struct swm_crc_cfg));
  96. if (RT_NULL == contex)
  97. {
  98. res = -RT_ERROR;
  99. break;
  100. }
  101. contex->CRCx = DEFAULT_CRC;
  102. contex->inival = DEFAULT_INIVAL;
  103. contex->crc_inbits = DEFAULT_INBITS;
  104. contex->crc_1632 = DEFAULT_CRC1632;
  105. contex->crc_out_not = DEFAULT_OUT_NOT;
  106. contex->crc_out_rev = DEFAULT_OUT_REV;
  107. ctx->contex = contex;
  108. ((struct hwcrypto_crc *)ctx)->ops = &crc_ops;
  109. break;
  110. }
  111. #endif /* BSP_USING_CRC */
  112. default:
  113. res = -RT_ERROR;
  114. break;
  115. }
  116. return res;
  117. }
  118. static void _crypto_destroy(struct rt_hwcrypto_ctx *ctx)
  119. {
  120. struct swm_crc_cfg *hw_crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
  121. switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
  122. {
  123. #if defined(BSP_USING_CRC)
  124. case HWCRYPTO_TYPE_CRC:
  125. hw_crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
  126. break;
  127. #endif /* BSP_USING_CRC */
  128. default:
  129. break;
  130. }
  131. rt_free(ctx->contex);
  132. }
  133. static rt_err_t _crypto_clone(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
  134. {
  135. rt_err_t res = RT_EOK;
  136. switch (src->type & HWCRYPTO_MAIN_TYPE_MASK)
  137. {
  138. #if defined(BSP_USING_CRC)
  139. case HWCRYPTO_TYPE_CRC:
  140. if (des->contex && src->contex)
  141. {
  142. rt_memcpy(des->contex, src->contex, sizeof(struct swm_crc_cfg));
  143. }
  144. break;
  145. #endif /* BSP_USING_CRC */
  146. default:
  147. res = -RT_ERROR;
  148. break;
  149. }
  150. return res;
  151. }
  152. static void _crypto_reset(struct rt_hwcrypto_ctx *ctx)
  153. {
  154. struct swm_crc_cfg *hw_crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
  155. switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
  156. {
  157. #if defined(BSP_USING_CRC)
  158. case HWCRYPTO_TYPE_CRC:
  159. hw_crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
  160. break;
  161. #endif /* BSP_USING_CRC */
  162. default:
  163. break;
  164. }
  165. }
  166. static const struct rt_hwcrypto_ops _ops =
  167. {
  168. .create = _crypto_create,
  169. .destroy = _crypto_destroy,
  170. .copy = _crypto_clone,
  171. .reset = _crypto_reset,
  172. };
  173. int rt_hw_crypto_init(void)
  174. {
  175. static struct swm_hwcrypto_device _crypto_dev;
  176. rt_uint32_t cpuid[2] = {0};
  177. _crypto_dev.dev.ops = &_ops;
  178. cpuid[0] = SCB->CPUID;
  179. _crypto_dev.dev.id = 0;
  180. rt_memcpy(&_crypto_dev.dev.id, cpuid, 8);
  181. _crypto_dev.dev.user_data = &_crypto_dev;
  182. if (rt_hwcrypto_register(&_crypto_dev.dev, RT_HWCRYPTO_DEFAULT_NAME) != RT_EOK)
  183. {
  184. return -1;
  185. }
  186. rt_mutex_init(&_crypto_dev.mutex, RT_HWCRYPTO_DEFAULT_NAME, RT_IPC_FLAG_PRIO);
  187. return 0;
  188. }
  189. INIT_BOARD_EXPORT(rt_hw_crypto_init);
  190. #endif /* RT_USING_HWCRYPTO */