You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

950 lines
31 KiB

  1. /**
  2. *
  3. * \file m2m_crypto.c
  4. *
  5. * \brief WINC Crypto module.
  6. *
  7. * Copyright (c) 2014 Atmel Corporation. All rights reserved.
  8. *
  9. * \asf_license_start
  10. *
  11. * \page License
  12. *
  13. * Redistribution and use in source and binary forms, with or without
  14. * modification, are permitted provided that the following conditions are met:
  15. *
  16. * 1. Redistributions of source code must retain the above copyright notice,
  17. * this list of conditions and the following disclaimer.
  18. *
  19. * 2. Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. *
  23. * 3. The name of Atmel may not be used to endorse or promote products derived
  24. * from this software without specific prior written permission.
  25. *
  26. * 4. This software may only be redistributed and used in connection with an
  27. * Atmel microcontroller product.
  28. *
  29. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  30. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  31. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  32. * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
  33. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  34. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  35. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  36. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  37. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  38. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  39. * POSSIBILITY OF SUCH DAMAGE.
  40. *
  41. * \asf_license_stop
  42. *
  43. */
  44. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  45. INCLUDES
  46. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  47. #include "driver/include/m2m_crypto.h"
  48. #include "driver/source/nmbus.h"
  49. #include "driver/source/nmasic.h"
  50. #ifdef CONF_CRYPTO_HW
  51. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  52. MACROS
  53. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  54. /*======*======*======*======*======*=======*
  55. * WINC SHA256 HW Engine Register Definition *
  56. *======*======*======*======*======*========*/
  57. #define SHA_BLOCK_SIZE (64)
  58. #define SHARED_MEM_BASE (0xd0000)
  59. #define SHA256_MEM_BASE (0x180000UL)
  60. #define SHA256_ENGINE_ADDR (0x180000ul)
  61. /* SHA256 Registers */
  62. #define SHA256_CTRL (SHA256_MEM_BASE + 0x00)
  63. #define SHA256_CTRL_START_CALC_MASK (NBIT0)
  64. #define SHA256_CTRL_START_CALC_SHIFT (0)
  65. #define SHA256_CTRL_PREPROCESS_MASK (NBIT1)
  66. #define SHA256_CTRL_PREPROCESS_SHIFT (1)
  67. #define SHA256_CTRL_HASH_HASH_MASK (NBIT2)
  68. #define SHA256_CTRL_HASH_HASH_SHIFT (2)
  69. #define SHA256_CTRL_INIT_SHA256_STATE_MASK (NBIT3)
  70. #define SHA256_CTRL_INIT_SHA256_STATE_SHIFT (3)
  71. #define SHA256_CTRL_WR_BACK_HASH_VALUE_MASK (NBIT4)
  72. #define SHA256_CTRL_WR_BACK_HASH_VALUE_SHIFT (4)
  73. #define SHA256_CTRL_FORCE_SHA256_QUIT_MASK (NBIT5)
  74. #define SHA256_CTRL_FORCE_SHA256_QUIT_SHIFT (5)
  75. #define SHA256_REGS_SHA256_CTRL_AHB_BYTE_REV_EN (NBIT6)
  76. #define SHA256_REGS_SHA256_CTRL_RESERVED (NBIT7)
  77. #define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO (NBIT8 + NBIT9 + NBIT10)
  78. #define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_MASK (NBIT2 + NBIT1 + NBIT0)
  79. #define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_SHIFT (8)
  80. #define SHA256_REGS_SHA256_CTRL_RESERVED_11 (NBIT11)
  81. #define SHA256_REGS_SHA256_CTRL_SHA1_CALC (NBIT12)
  82. #define SHA256_REGS_SHA256_CTRL_PBKDF2_SHA1_CALC (NBIT13)
  83. #define SHA256_START_RD_ADDR (SHA256_MEM_BASE + 0x04UL)
  84. #define SHA256_DATA_LENGTH (SHA256_MEM_BASE + 0x08UL)
  85. #define SHA256_START_WR_ADDR (SHA256_MEM_BASE + 0x0cUL)
  86. #define SHA256_COND_CHK_CTRL (SHA256_MEM_BASE + 0x10)
  87. #define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_MASK (NBIT1 | NBIT0)
  88. #define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_SHIFT (0)
  89. #define SHA256_COND_CHK_CTRL_STEP_VAL_MASK (NBIT6 | NBIT5 | NBIT4 | NBIT3 | NBIT2)
  90. #define SHA256_COND_CHK_CTRL_STEP_VAL_SHIFT (2)
  91. #define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_MASK (NBIT7)
  92. #define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_SHIFT (7)
  93. #define SHA256_MOD_DATA_RANGE (SHA256_MEM_BASE + 0x14)
  94. #define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_MASK (NBIT24 - 1)
  95. #define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_SHIFT (0)
  96. #define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_MASK (NBIT24 | NBIT25 | NBIT26)
  97. #define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_SHIFT (24)
  98. #define SHA256_COND_CHK_STS_1 (SHA256_MEM_BASE + 0x18)
  99. #define SHA256_COND_CHK_STS_2 (SHA256_MEM_BASE + 0x1c)
  100. #define SHA256_DONE_INTR_ENABLE (SHA256_MEM_BASE + 0x20)
  101. #define SHA256_DONE_INTR_STS (SHA256_MEM_BASE + 0x24)
  102. #define SHA256_TARGET_HASH_H1 (SHA256_MEM_BASE + 0x28)
  103. #define SHA256_TARGET_HASH_H2 (SHA256_MEM_BASE + 0x2c)
  104. #define SHA256_TARGET_HASH_H3 (SHA256_MEM_BASE + 0x30)
  105. #define SHA256_TARGET_HASH_H4 (SHA256_MEM_BASE + 0x34)
  106. #define SHA256_TARGET_HASH_H5 (SHA256_MEM_BASE + 0x38)
  107. #define SHA256_TARGET_HASH_H6 (SHA256_MEM_BASE + 0x3c)
  108. #define SHA256_TARGET_HASH_H7 (SHA256_MEM_BASE + 0x40)
  109. #define SHA256_TARGET_HASH_H8 (SHA256_MEM_BASE + 0x44)
  110. /*======*======*======*======*======*=======*
  111. * WINC BIGINT HW Engine Register Definition *
  112. *======*======*======*======*======*========*/
  113. #define BIGINT_ENGINE_ADDR (0x180080ul)
  114. #define BIGINT_VERSION (BIGINT_ENGINE_ADDR + 0x00)
  115. #define BIGINT_MISC_CTRL (BIGINT_ENGINE_ADDR + 0x04)
  116. #define BIGINT_MISC_CTRL_CTL_START (NBIT0)
  117. #define BIGINT_MISC_CTRL_CTL_RESET (NBIT1)
  118. #define BIGINT_MISC_CTRL_CTL_MSW_FIRST (NBIT2)
  119. #define BIGINT_MISC_CTRL_CTL_SWAP_BYTE_ORDER (NBIT3)
  120. #define BIGINT_MISC_CTRL_CTL_FORCE_BARRETT (NBIT4)
  121. #define BIGINT_MISC_CTRL_CTL_M_PRIME_VALID (NBIT5)
  122. #define BIGINT_M_PRIME (BIGINT_ENGINE_ADDR + 0x08)
  123. #define BIGINT_STATUS (BIGINT_ENGINE_ADDR + 0x0C)
  124. #define BIGINT_STATUS_STS_DONE (NBIT0)
  125. #define BIGINT_CLK_COUNT (BIGINT_ENGINE_ADDR + 0x10)
  126. #define BIGINT_ADDR_X (BIGINT_ENGINE_ADDR + 0x14)
  127. #define BIGINT_ADDR_E (BIGINT_ENGINE_ADDR + 0x18)
  128. #define BIGINT_ADDR_M (BIGINT_ENGINE_ADDR + 0x1C)
  129. #define BIGINT_ADDR_R (BIGINT_ENGINE_ADDR + 0x20)
  130. #define BIGINT_LENGTH (BIGINT_ENGINE_ADDR + 0x24)
  131. #define BIGINT_IRQ_STS (BIGINT_ENGINE_ADDR + 0x28)
  132. #define BIGINT_IRQ_STS_DONE (NBIT0)
  133. #define BIGINT_IRQ_STS_CHOOSE_MONT (NBIT1)
  134. #define BIGINT_IRQ_STS_M_READ (NBIT2)
  135. #define BIGINT_IRQ_STS_X_READ (NBIT3)
  136. #define BIGINT_IRQ_STS_START (NBIT4)
  137. #define BIGINT_IRQ_STS_PRECOMP_FINISH (NBIT5)
  138. #define BIGINT_IRQ_MASK (BIGINT_ENGINE_ADDR + 0x2C)
  139. #define BIGINT_IRQ_MASK_CTL_IRQ_MASK_START (NBIT4)
  140. #define ENABLE_FLIPPING 1
  141. #define GET_UINT32(BUF, OFFSET) \
  142. (((uint32)((BUF)[OFFSET])) | ((uint32)(((BUF)[OFFSET + 1]) << 8)) | ((uint32)(((BUF)[OFFSET + 2]) << 16)) \
  143. | ((uint32)(((BUF)[OFFSET + 3]) << 24)))
  144. #define PUTU32(VAL32, BUF, OFFSET) \
  145. do { \
  146. (BUF)[OFFSET] = BYTE_3((VAL32)); \
  147. (BUF)[OFFSET + 1] = BYTE_2((VAL32)); \
  148. (BUF)[OFFSET + 2] = BYTE_1((VAL32)); \
  149. (BUF)[OFFSET + 3] = BYTE_0((VAL32)); \
  150. } while (0)
  151. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  152. DATA TYPES
  153. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  154. /*!
  155. @struct \
  156. tstrHashContext
  157. @brief
  158. */
  159. typedef struct {
  160. uint32 au32HashState[M2M_SHA256_DIGEST_LEN / 4];
  161. uint8 au8CurrentBlock[64];
  162. uint32 u32TotalLength;
  163. uint8 u8InitHashFlag;
  164. } tstrSHA256HashCtxt;
  165. /*======*======*======*======*======*=======*
  166. * SHA256 IMPLEMENTATION *
  167. *======*======*======*======*======*========*/
  168. sint8 m2m_crypto_sha256_hash_init(tstrM2mSha256Ctxt *pstrSha256Ctxt)
  169. {
  170. tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt *)pstrSha256Ctxt;
  171. if (pstrSHA256 != NULL) {
  172. m2m_memset((uint8 *)pstrSha256Ctxt, 0, sizeof(tstrM2mSha256Ctxt));
  173. pstrSHA256->u8InitHashFlag = 1;
  174. }
  175. return 0;
  176. }
  177. sint8 m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Data, uint16 u16DataLength)
  178. {
  179. sint8 s8Ret = M2M_ERR_FAIL;
  180. tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt *)pstrSha256Ctxt;
  181. if (pstrSHA256 != NULL) {
  182. uint32 u32ReadAddr;
  183. uint32 u32WriteAddr = SHARED_MEM_BASE;
  184. uint32 u32Addr = u32WriteAddr;
  185. uint32 u32ResidualBytes;
  186. uint32 u32NBlocks;
  187. uint32 u32Offset;
  188. uint32 u32CurrentBlock = 0;
  189. uint8 u8IsDone = 0;
  190. /* Get the remaining bytes from the previous update (if the length is not block aligned). */
  191. u32ResidualBytes = pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE;
  192. /* Update the total data length. */
  193. pstrSHA256->u32TotalLength += u16DataLength;
  194. if (u32ResidualBytes != 0) {
  195. if ((u32ResidualBytes + u16DataLength) >= SHA_BLOCK_SIZE) {
  196. u32Offset = SHA_BLOCK_SIZE - u32ResidualBytes;
  197. m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u32Offset);
  198. pu8Data += u32Offset;
  199. u16DataLength -= u32Offset;
  200. nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
  201. u32Addr += SHA_BLOCK_SIZE;
  202. u32CurrentBlock = 1;
  203. } else {
  204. m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u16DataLength);
  205. u16DataLength = 0;
  206. }
  207. }
  208. /* Get the number of HASH BLOCKs and the residual bytes. */
  209. u32NBlocks = u16DataLength / SHA_BLOCK_SIZE;
  210. u32ResidualBytes = u16DataLength % SHA_BLOCK_SIZE;
  211. if (u32NBlocks != 0) {
  212. nm_write_block(u32Addr, pu8Data, (uint16)(u32NBlocks * SHA_BLOCK_SIZE));
  213. pu8Data += (u32NBlocks * SHA_BLOCK_SIZE);
  214. }
  215. u32NBlocks += u32CurrentBlock;
  216. if (u32NBlocks != 0) {
  217. uint32 u32RegVal = 0;
  218. nm_write_reg(SHA256_CTRL, u32RegVal);
  219. u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK;
  220. nm_write_reg(SHA256_CTRL, u32RegVal);
  221. if (pstrSHA256->u8InitHashFlag) {
  222. pstrSHA256->u8InitHashFlag = 0;
  223. u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK;
  224. }
  225. u32ReadAddr = u32WriteAddr + (u32NBlocks * SHA_BLOCK_SIZE);
  226. nm_write_reg(SHA256_DATA_LENGTH, (u32NBlocks * SHA_BLOCK_SIZE));
  227. nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr);
  228. nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr);
  229. u32RegVal |= SHA256_CTRL_START_CALC_MASK;
  230. u32RegVal &= ~(0x7 << 8);
  231. u32RegVal |= (2 << 8);
  232. nm_write_reg(SHA256_CTRL, u32RegVal);
  233. /* 5. Wait for done_intr */
  234. while (!u8IsDone) {
  235. u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS);
  236. u8IsDone = u32RegVal & NBIT0;
  237. }
  238. }
  239. if (u32ResidualBytes != 0) {
  240. m2m_memcpy(pstrSHA256->au8CurrentBlock, pu8Data, u32ResidualBytes);
  241. }
  242. s8Ret = M2M_SUCCESS;
  243. }
  244. return s8Ret;
  245. }
  246. sint8 m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Sha256Digest)
  247. {
  248. sint8 s8Ret = M2M_ERR_FAIL;
  249. tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt *)pstrSha256Ctxt;
  250. if (pstrSHA256 != NULL) {
  251. uint32 u32ReadAddr;
  252. uint32 u32WriteAddr = SHARED_MEM_BASE;
  253. uint32 u32Addr = u32WriteAddr;
  254. uint16 u16Offset;
  255. uint16 u16PaddingLength;
  256. uint16 u16NBlocks = 1;
  257. uint32 u32RegVal = 0;
  258. uint32 u32Idx, u32ByteIdx;
  259. uint32 au32Digest[M2M_SHA256_DIGEST_LEN / 4];
  260. uint8 u8IsDone = 0;
  261. nm_write_reg(SHA256_CTRL, u32RegVal);
  262. u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK;
  263. nm_write_reg(SHA256_CTRL, u32RegVal);
  264. if (pstrSHA256->u8InitHashFlag) {
  265. pstrSHA256->u8InitHashFlag = 0;
  266. u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK;
  267. }
  268. /* Calculate the offset of the last data byte in the current block. */
  269. u16Offset = (uint16)(pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE);
  270. /* Add the padding byte 0x80. */
  271. pstrSHA256->au8CurrentBlock[u16Offset++] = 0x80;
  272. /* Calculate the required padding to complete
  273. one Hash Block Size.
  274. */
  275. u16PaddingLength = SHA_BLOCK_SIZE - u16Offset;
  276. m2m_memset(&pstrSHA256->au8CurrentBlock[u16Offset], 0, u16PaddingLength);
  277. /* If the padding count is not enough to hold 64-bit representation of
  278. the total input message length, one padding block is required.
  279. */
  280. if (u16PaddingLength < 8) {
  281. nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
  282. u32Addr += SHA_BLOCK_SIZE;
  283. m2m_memset(pstrSHA256->au8CurrentBlock, 0, SHA_BLOCK_SIZE);
  284. u16NBlocks++;
  285. }
  286. /* pack the length at the end of the padding block */
  287. PUTU32(pstrSHA256->u32TotalLength << 3, pstrSHA256->au8CurrentBlock, (SHA_BLOCK_SIZE - 4));
  288. u32ReadAddr = u32WriteAddr + (u16NBlocks * SHA_BLOCK_SIZE);
  289. nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
  290. nm_write_reg(SHA256_DATA_LENGTH, (u16NBlocks * SHA_BLOCK_SIZE));
  291. nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr);
  292. nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr);
  293. u32RegVal |= SHA256_CTRL_START_CALC_MASK;
  294. u32RegVal |= SHA256_CTRL_WR_BACK_HASH_VALUE_MASK;
  295. u32RegVal &= ~(0x7UL << 8);
  296. u32RegVal |= (0x2UL << 8);
  297. nm_write_reg(SHA256_CTRL, u32RegVal);
  298. /* 5. Wait for done_intr */
  299. while (!u8IsDone) {
  300. u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS);
  301. u8IsDone = u32RegVal & NBIT0;
  302. }
  303. nm_read_block(u32ReadAddr, (uint8 *)au32Digest, 32);
  304. /* Convert the output words to an array of bytes.
  305. */
  306. u32ByteIdx = 0;
  307. for (u32Idx = 0; u32Idx < (M2M_SHA256_DIGEST_LEN / 4); u32Idx++) {
  308. pu8Sha256Digest[u32ByteIdx++] = BYTE_3(au32Digest[u32Idx]);
  309. pu8Sha256Digest[u32ByteIdx++] = BYTE_2(au32Digest[u32Idx]);
  310. pu8Sha256Digest[u32ByteIdx++] = BYTE_1(au32Digest[u32Idx]);
  311. pu8Sha256Digest[u32ByteIdx++] = BYTE_0(au32Digest[u32Idx]);
  312. }
  313. s8Ret = M2M_SUCCESS;
  314. }
  315. return s8Ret;
  316. }
  317. /*======*======*======*======*======*=======*
  318. * RSA IMPLEMENTATION *
  319. *======*======*======*======*======*========*/
  320. static void FlipBuffer(uint8 *pu8InBuffer, uint8 *pu8OutBuffer, uint16 u16BufferSize)
  321. {
  322. uint16 u16Idx;
  323. for (u16Idx = 0; u16Idx < u16BufferSize; u16Idx++) {
  324. #if ENABLE_FLIPPING == 1
  325. pu8OutBuffer[u16Idx] = pu8InBuffer[u16BufferSize - u16Idx - 1];
  326. #else
  327. pu8OutBuffer[u16Idx] = pu8InBuffer[u16Idx];
  328. #endif
  329. }
  330. }
  331. void BigInt_ModExp(uint8 *pu8X, uint16 u16XSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8M, uint16 u16MSize,
  332. uint8 *pu8R, uint16 u16RSize)
  333. {
  334. uint32 u32Reg;
  335. uint8 au8Tmp[780] = {0};
  336. uint32 u32XAddr = SHARED_MEM_BASE;
  337. uint32 u32MAddr;
  338. uint32 u32EAddr;
  339. uint32 u32RAddr;
  340. uint8 u8EMswBits = 32;
  341. uint32 u32Mprime = 0x7F;
  342. uint16 u16XSizeWords, u16ESizeWords;
  343. uint32 u32Exponent;
  344. u16XSizeWords = (u16XSize + 3) / 4;
  345. u16ESizeWords = (u16ESize + 3) / 4;
  346. u32MAddr = u32XAddr + (u16XSizeWords * 4);
  347. u32EAddr = u32MAddr + (u16XSizeWords * 4);
  348. u32RAddr = u32EAddr + (u16ESizeWords * 4);
  349. /* Reset the core.
  350. */
  351. u32Reg = 0;
  352. u32Reg |= BIGINT_MISC_CTRL_CTL_RESET;
  353. u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
  354. u32Reg &= ~BIGINT_MISC_CTRL_CTL_RESET;
  355. u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
  356. nm_write_block(u32RAddr, au8Tmp, u16RSize);
  357. /* Write Input Operands to Chip Memory.
  358. */
  359. /*------- X -------*/
  360. FlipBuffer(pu8X, au8Tmp, u16XSize);
  361. nm_write_block(u32XAddr, au8Tmp, u16XSizeWords * 4);
  362. /*------- E -------*/
  363. m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
  364. FlipBuffer(pu8E, au8Tmp, u16ESize);
  365. nm_write_block(u32EAddr, au8Tmp, u16ESizeWords * 4);
  366. u32Exponent = GET_UINT32(au8Tmp, (u16ESizeWords * 4) - 4);
  367. while ((u32Exponent & NBIT31) == 0) {
  368. u32Exponent <<= 1;
  369. u8EMswBits--;
  370. }
  371. /*------- M -------*/
  372. m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
  373. FlipBuffer(pu8M, au8Tmp, u16XSize);
  374. nm_write_block(u32MAddr, au8Tmp, u16XSizeWords * 4);
  375. /* Program the addresses of the input operands.
  376. */
  377. nm_write_reg(BIGINT_ADDR_X, u32XAddr);
  378. nm_write_reg(BIGINT_ADDR_E, u32EAddr);
  379. nm_write_reg(BIGINT_ADDR_M, u32MAddr);
  380. nm_write_reg(BIGINT_ADDR_R, u32RAddr);
  381. /* Mprime.
  382. */
  383. nm_write_reg(BIGINT_M_PRIME, u32Mprime);
  384. /* Length.
  385. */
  386. u32Reg = (u16XSizeWords & 0xFF);
  387. u32Reg += ((u16ESizeWords & 0xFF) << 8);
  388. u32Reg += (u8EMswBits << 16);
  389. nm_write_reg(BIGINT_LENGTH, u32Reg);
  390. /* CTRL Register.
  391. */
  392. u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
  393. u32Reg ^= BIGINT_MISC_CTRL_CTL_START;
  394. u32Reg |= BIGINT_MISC_CTRL_CTL_FORCE_BARRETT;
  395. // u32Reg |= BIGINT_MISC_CTRL_CTL_M_PRIME_VALID;
  396. #if ENABLE_FLIPPING == 0
  397. u32Reg |= BIGINT_MISC_CTRL_CTL_MSW_FIRST;
  398. #endif
  399. nm_write_reg(BIGINT_MISC_CTRL, u32Reg);
  400. /* Wait for computation to complete. */
  401. while (1) {
  402. u32Reg = nm_read_reg(BIGINT_IRQ_STS);
  403. if (u32Reg & BIGINT_IRQ_STS_DONE) {
  404. break;
  405. }
  406. }
  407. nm_write_reg(BIGINT_IRQ_STS, 0);
  408. m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
  409. nm_read_block(u32RAddr, au8Tmp, u16RSize);
  410. FlipBuffer(au8Tmp, pu8R, u16RSize);
  411. }
  412. #define MD5_DIGEST_SIZE (16)
  413. #define SHA1_DIGEST_SIZE (20)
  414. static const uint8 au8TEncodingMD5[]
  415. = {0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04};
  416. /*!< Fixed part of the Encoding T for the MD5 hash algorithm.
  417. */
  418. static const uint8 au8TEncodingSHA1[]
  419. = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04};
  420. /*!< Fixed part of the Encoding T for the SHA-1 hash algorithm.
  421. */
  422. static const uint8 au8TEncodingSHA2[]
  423. = {0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04};
  424. /*!< Fixed part of the Encoding T for the SHA-2 hash algorithm.
  425. */
  426. sint8 m2m_crypto_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash,
  427. uint16 u16HashLength, uint8 *pu8RsaSignature)
  428. {
  429. sint8 s8Ret = M2M_RSA_SIGN_FAIL;
  430. if ((pu8N != NULL) && (pu8E != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL)) {
  431. uint16 u16TLength, u16TEncodingLength;
  432. uint8 *pu8T;
  433. uint8 au8EM[512];
  434. /* Selection of correct T Encoding based on the hash size.
  435. */
  436. if (u16HashLength == MD5_DIGEST_SIZE) {
  437. pu8T = (uint8 *)au8TEncodingMD5;
  438. u16TEncodingLength = sizeof(au8TEncodingMD5);
  439. } else if (u16HashLength == SHA1_DIGEST_SIZE) {
  440. pu8T = (uint8 *)au8TEncodingSHA1;
  441. u16TEncodingLength = sizeof(au8TEncodingSHA1);
  442. } else {
  443. pu8T = (uint8 *)au8TEncodingSHA2;
  444. u16TEncodingLength = sizeof(au8TEncodingSHA2);
  445. }
  446. u16TLength = u16TEncodingLength + 1 + u16HashLength;
  447. /* If emLen < tLen + 11.
  448. */
  449. if (u16NSize >= (u16TLength + 11)) {
  450. uint32 u32PSLength, u32Idx = 0;
  451. /*
  452. RSA verification
  453. */
  454. BigInt_ModExp(pu8RsaSignature, u16NSize, pu8E, u16ESize, pu8N, u16NSize, au8EM, u16NSize);
  455. u32PSLength = u16NSize - u16TLength - 3;
  456. /*
  457. The calculated EM must match the following pattern.
  458. *======*======*======*======*======*
  459. * 0x00 || 0x01 || PS || 0x00 || T *
  460. *======*======*======*======*======*
  461. Where PS is all 0xFF
  462. T is defined based on the hash algorithm.
  463. */
  464. if ((au8EM[0] == 0x00) && (au8EM[1] == 0x01)) {
  465. for (u32Idx = 2; au8EM[u32Idx] == 0xFF; u32Idx++)
  466. ;
  467. if (u32Idx == (u32PSLength + 2)) {
  468. if (au8EM[u32Idx++] == 0x00) {
  469. if (!m2m_memcmp(&au8EM[u32Idx], pu8T, u16TEncodingLength)) {
  470. u32Idx += u16TEncodingLength;
  471. if (au8EM[u32Idx++] == u16HashLength)
  472. s8Ret = m2m_memcmp(&au8EM[u32Idx], pu8SignedMsgHash, u16HashLength);
  473. }
  474. }
  475. }
  476. }
  477. }
  478. }
  479. return s8Ret;
  480. }
  481. sint8 m2m_crypto_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash,
  482. uint16 u16HashLength, uint8 *pu8RsaSignature)
  483. {
  484. sint8 s8Ret = M2M_RSA_SIGN_FAIL;
  485. if ((pu8N != NULL) && (pu8d != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL)) {
  486. uint16 u16TLength, u16TEncodingLength;
  487. uint8 *pu8T;
  488. uint8 au8EM[512];
  489. /* Selection of correct T Encoding based on the hash size.
  490. */
  491. if (u16HashLength == MD5_DIGEST_SIZE) {
  492. pu8T = (uint8 *)au8TEncodingMD5;
  493. u16TEncodingLength = sizeof(au8TEncodingMD5);
  494. } else if (u16HashLength == SHA1_DIGEST_SIZE) {
  495. pu8T = (uint8 *)au8TEncodingSHA1;
  496. u16TEncodingLength = sizeof(au8TEncodingSHA1);
  497. } else {
  498. pu8T = (uint8 *)au8TEncodingSHA2;
  499. u16TEncodingLength = sizeof(au8TEncodingSHA2);
  500. }
  501. u16TLength = u16TEncodingLength + 1 + u16HashLength;
  502. /* If emLen < tLen + 11.
  503. */
  504. if (u16NSize >= (u16TLength + 11)) {
  505. uint16 u16PSLength = 0;
  506. uint16 u16Offset = 0;
  507. /*
  508. The calculated EM must match the following pattern.
  509. *======*======*======*======*======*
  510. * 0x00 || 0x01 || PS || 0x00 || T *
  511. *======*======*======*======*======*
  512. Where PS is all 0xFF
  513. T is defined based on the hash algorithm.
  514. */
  515. au8EM[u16Offset++] = 0;
  516. au8EM[u16Offset++] = 1;
  517. u16PSLength = u16NSize - u16TLength - 3;
  518. m2m_memset(&au8EM[u16Offset], 0xFF, u16PSLength);
  519. u16Offset += u16PSLength;
  520. au8EM[u16Offset++] = 0;
  521. m2m_memcpy(&au8EM[u16Offset], pu8T, u16TEncodingLength);
  522. u16Offset += u16TEncodingLength;
  523. au8EM[u16Offset++] = u16HashLength;
  524. m2m_memcpy(&au8EM[u16Offset], pu8SignedMsgHash, u16HashLength);
  525. /*
  526. RSA Signature Generation
  527. */
  528. BigInt_ModExp(au8EM, u16NSize, pu8d, u16dSize, pu8N, u16NSize, pu8RsaSignature, u16NSize);
  529. s8Ret = M2M_RSA_SIGN_OK;
  530. }
  531. }
  532. return s8Ret;
  533. }
  534. #endif /* CONF_CRYPTO */
  535. #ifdef CONF_CRYPTO_SOFT
  536. typedef struct {
  537. tpfAppCryproCb pfAppCryptoCb;
  538. uint8 * pu8Digest;
  539. uint8 * pu8Rsa;
  540. uint8 u8CryptoBusy;
  541. } tstrCryptoCtxt;
  542. typedef struct {
  543. uint8 au8N[M2M_MAX_RSA_LEN];
  544. uint8 au8E[M2M_MAX_RSA_LEN];
  545. uint8 au8Hash[M2M_SHA256_DIGEST_LEN];
  546. uint16 u16Nsz;
  547. uint16 u16Esz;
  548. uint16 u16Hsz;
  549. uint8 _pad16_[2];
  550. } tstrRsaPayload;
  551. static tstrCryptoCtxt gstrCryptoCtxt;
  552. /**
  553. * @fn m2m_crypto_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
  554. * @brief WiFi call back function
  555. * @param [in] u8OpCode
  556. * HIF Opcode type.
  557. * @param [in] u16DataSize
  558. * HIF data length.
  559. * @param [in] u32Addr
  560. * HIF address.
  561. * @author
  562. * @date
  563. * @version 1.0
  564. */
  565. static void m2m_crypto_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
  566. {
  567. sint8 ret = M2M_SUCCESS;
  568. gstrCryptoCtxt.u8CryptoBusy = 0;
  569. if (u8OpCode == M2M_CRYPTO_RESP_SHA256_INIT) {
  570. tstrM2mSha256Ctxt strCtxt;
  571. if (hif_receive(u32Addr, (uint8 *)&strCtxt, sizeof(tstrM2mSha256Ctxt), 0) == M2M_SUCCESS) {
  572. tstrCyptoResp strResp;
  573. if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), (uint8 *)&strResp, sizeof(tstrCyptoResp), 1)
  574. == M2M_SUCCESS) {
  575. if (gstrCryptoCtxt.pfAppCryptoCb)
  576. gstrCryptoCtxt.pfAppCryptoCb(u8OpCode, &strResp, &strCtxt);
  577. }
  578. }
  579. } else if (u8OpCode == M2M_CRYPTO_RESP_SHA256_UPDATE) {
  580. tstrM2mSha256Ctxt strCtxt;
  581. if (hif_receive(u32Addr, (uint8 *)&strCtxt, sizeof(tstrM2mSha256Ctxt), 0) == M2M_SUCCESS) {
  582. tstrCyptoResp strResp;
  583. if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), (uint8 *)&strResp, sizeof(tstrCyptoResp), 1)
  584. == M2M_SUCCESS) {
  585. if (gstrCryptoCtxt.pfAppCryptoCb)
  586. gstrCryptoCtxt.pfAppCryptoCb(u8OpCode, &strResp, &strCtxt);
  587. }
  588. }
  589. } else if (u8OpCode == M2M_CRYPTO_RESP_SHA256_FINSIH) {
  590. tstrCyptoResp strResp;
  591. if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), (uint8 *)&strResp, sizeof(tstrCyptoResp), 0)
  592. == M2M_SUCCESS) {
  593. if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt) + sizeof(tstrCyptoResp),
  594. (uint8 *)gstrCryptoCtxt.pu8Digest,
  595. M2M_SHA256_DIGEST_LEN,
  596. 1)
  597. == M2M_SUCCESS) {
  598. if (gstrCryptoCtxt.pfAppCryptoCb)
  599. gstrCryptoCtxt.pfAppCryptoCb(u8OpCode, &strResp, gstrCryptoCtxt.pu8Digest);
  600. }
  601. }
  602. } else if (u8OpCode == M2M_CRYPTO_RESP_RSA_SIGN_GEN) {
  603. tstrCyptoResp strResp;
  604. if (hif_receive(u32Addr + sizeof(tstrRsaPayload), (uint8 *)&strResp, sizeof(tstrCyptoResp), 0) == M2M_SUCCESS) {
  605. if (hif_receive(u32Addr + sizeof(tstrRsaPayload) + sizeof(tstrCyptoResp),
  606. (uint8 *)gstrCryptoCtxt.pu8Rsa,
  607. M2M_MAX_RSA_LEN,
  608. 0)
  609. == M2M_SUCCESS) {
  610. if (gstrCryptoCtxt.pfAppCryptoCb)
  611. gstrCryptoCtxt.pfAppCryptoCb(u8OpCode, &strResp, gstrCryptoCtxt.pu8Rsa);
  612. }
  613. }
  614. } else if (u8OpCode == M2M_CRYPTO_RESP_RSA_SIGN_VERIFY) {
  615. tstrCyptoResp strResp;
  616. if (hif_receive(u32Addr + sizeof(tstrRsaPayload), (uint8 *)&strResp, sizeof(tstrCyptoResp), 1) == M2M_SUCCESS) {
  617. if (gstrCryptoCtxt.pfAppCryptoCb)
  618. gstrCryptoCtxt.pfAppCryptoCb(u8OpCode, &strResp, NULL);
  619. }
  620. } else {
  621. M2M_ERR("u8Code %d ??\n", u8OpCode);
  622. }
  623. }
  624. /*!
  625. @fn \
  626. sint8 m2m_crypto_init();
  627. @brief crypto initialization
  628. @param[in] pfAppCryproCb
  629. */
  630. sint8 m2m_crypto_init(tpfAppCryproCb pfAppCryproCb)
  631. {
  632. sint8 ret = M2M_ERR_FAIL;
  633. m2m_memset((uint8 *)&gstrCryptoCtxt, 0, sizeof(tstrCryptoCtxt));
  634. if (pfAppCryproCb != NULL) {
  635. gstrCryptoCtxt.pfAppCryptoCb = pfAppCryproCb;
  636. ret = hif_register_cb(M2M_REQ_GROUP_CRYPTO, m2m_crypto_cb);
  637. }
  638. return ret;
  639. }
  640. /*!
  641. @fn \
  642. sint8 m2m_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt);
  643. @brief SHA256 hash initialization
  644. @param[in] psha256Ctxt
  645. Pointer to a sha256 context allocated by the caller.
  646. */
  647. sint8 m2m_crypto_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt)
  648. {
  649. sint8 ret = M2M_ERR_FAIL;
  650. if ((psha256Ctxt != NULL) && (!gstrCryptoCtxt.u8CryptoBusy)) {
  651. ret = hif_send(M2M_REQ_GROUP_CRYPTO,
  652. M2M_CRYPTO_REQ_SHA256_INIT | M2M_REQ_DATA_PKT,
  653. (uint8 *)psha256Ctxt,
  654. sizeof(tstrM2mSha256Ctxt),
  655. NULL,
  656. 0,
  657. 0);
  658. }
  659. return ret;
  660. }
  661. /*!
  662. @fn \
  663. sint8 m2m_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Data, uint16 u16DataLength);
  664. @brief SHA256 hash update
  665. @param [in] psha256Ctxt
  666. Pointer to the sha256 context.
  667. @param [in] pu8Data
  668. Buffer holding the data submitted to the hash.
  669. @param [in] u16DataLength
  670. Size of the data bufefr in bytes.
  671. */
  672. sint8 m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Data, uint16 u16DataLength)
  673. {
  674. sint8 ret = M2M_ERR_FAIL;
  675. if ((!gstrCryptoCtxt.u8CryptoBusy) && (psha256Ctxt != NULL) && (pu8Data != NULL)
  676. && (u16DataLength < M2M_SHA256_MAX_DATA)) {
  677. ret = hif_send(M2M_REQ_GROUP_CRYPTO,
  678. M2M_CRYPTO_REQ_SHA256_UPDATE | M2M_REQ_DATA_PKT,
  679. (uint8 *)psha256Ctxt,
  680. sizeof(tstrM2mSha256Ctxt),
  681. pu8Data,
  682. u16DataLength,
  683. sizeof(tstrM2mSha256Ctxt) + sizeof(tstrCyptoResp));
  684. }
  685. return ret;
  686. }
  687. /*!
  688. @fn \
  689. sint8 m2m_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Sha256Digest);
  690. @brief SHA256 hash finalization
  691. @param[in] psha256Ctxt
  692. Pointer to a sha256 context allocated by the caller.
  693. @param [in] pu8Sha256Digest
  694. Buffer allocated by the caller which will hold the resultant SHA256 Digest. It must be allocated no less
  695. than M2M_SHA256_DIGEST_LEN.
  696. */
  697. sint8 m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Sha256Digest)
  698. {
  699. sint8 ret = M2M_ERR_FAIL;
  700. if ((!gstrCryptoCtxt.u8CryptoBusy) && (psha256Ctxt != NULL) && (pu8Sha256Digest != NULL)) {
  701. gstrCryptoCtxt.pu8Digest = pu8Sha256Digest;
  702. ret = hif_send(M2M_REQ_GROUP_CRYPTO,
  703. M2M_CRYPTO_REQ_SHA256_FINSIH | M2M_REQ_DATA_PKT,
  704. (uint8 *)psha256Ctxt,
  705. sizeof(tstrM2mSha256Ctxt),
  706. NULL,
  707. 0,
  708. 0);
  709. }
  710. return ret;
  711. }
  712. /*!
  713. @fn \
  714. sint8 m2m_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash, \
  715. uint16 u16HashLength, uint8 *pu8RsaSignature);
  716. @brief RSA Signature Verification
  717. The function shall request the RSA Signature verification from the WINC Firmware for the given message. The signed
  718. message shall be compressed to the corresponding hash algorithm before calling this function. The hash type is
  719. identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256.
  720. @param[in] pu8N
  721. RSA Key modulus n.
  722. @param[in] u16NSize
  723. Size of the RSA modulus n in bytes.
  724. @param[in] pu8E
  725. RSA public exponent.
  726. @param[in] u16ESize
  727. Size of the RSA public exponent in bytes.
  728. @param[in] pu8SignedMsgHash
  729. The hash digest of the signed message.
  730. @param[in] u16HashLength
  731. The length of the hash digest.
  732. @param[out] pu8RsaSignature
  733. Signature value to be verified.
  734. */
  735. sint8 m2m_crypto_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash,
  736. uint16 u16HashLength, uint8 *pu8RsaSignature)
  737. {
  738. sint8 ret = M2M_ERR_FAIL;
  739. if ((!gstrCryptoCtxt.u8CryptoBusy) && (pu8N != NULL) && (pu8E != NULL) && (pu8RsaSignature != NULL)
  740. && (pu8SignedMsgHash != NULL) && (u16NSize != 0) && (u16ESize != 0) && (u16HashLength != 0)
  741. && (pu8RsaSignature != NULL))
  742. {
  743. tstrRsaPayload strRsa = {0};
  744. m2m_memcpy(strRsa.au8N, pu8N, u16NSize);
  745. m2m_memcpy(strRsa.au8E, pu8E, u16ESize);
  746. m2m_memcpy(strRsa.au8Hash, pu8SignedMsgHash, u16HashLength);
  747. strRsa.u16Esz = u16ESize;
  748. strRsa.u16Hsz = u16HashLength;
  749. strRsa.u16Nsz = u16NSize;
  750. ret = hif_send(M2M_REQ_GROUP_CRYPTO,
  751. M2M_CRYPTO_REQ_RSA_SIGN_VERIFY | M2M_REQ_DATA_PKT,
  752. (uint8 *)&strRsa,
  753. sizeof(tstrRsaPayload),
  754. NULL,
  755. 0,
  756. 0);
  757. }
  758. return ret;
  759. }
  760. /*!
  761. @fn \
  762. sint8 m2m_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash, \
  763. uint16 u16HashLength, uint8 *pu8RsaSignature);
  764. @brief RSA Signature Generation
  765. The function shall request the RSA Signature generation from the WINC Firmware for the given message. The signed
  766. message shall be compressed to the corresponding hash algorithm before calling this function. The hash type is
  767. identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256.
  768. @param[in] pu8N
  769. RSA Key modulus n.
  770. @param[in] u16NSize
  771. Size of the RSA modulus n in bytes.
  772. @param[in] pu8d
  773. RSA private exponent.
  774. @param[in] u16dSize
  775. Size of the RSA private exponent in bytes.
  776. @param[in] pu8SignedMsgHash
  777. The hash digest of the signed message.
  778. @param[in] u16HashLength
  779. The length of the hash digest.
  780. @param[out] pu8RsaSignature
  781. Pointer to a user buffer allocated by teh caller shall hold the generated signature.
  782. */
  783. sint8 m2m_crypto_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash,
  784. uint16 u16HashLength, uint8 *pu8RsaSignature)
  785. {
  786. sint8 ret = M2M_ERR_FAIL;
  787. if ((!gstrCryptoCtxt.u8CryptoBusy) && (pu8N != NULL) && (pu8d != NULL) && (pu8RsaSignature != NULL)
  788. && (pu8SignedMsgHash != NULL) && (u16NSize != 0) && (u16dSize != 0) && (u16HashLength != 0)
  789. && (pu8RsaSignature != NULL))
  790. {
  791. tstrRsaPayload strRsa = {0};
  792. m2m_memcpy(strRsa.au8N, pu8N, u16NSize);
  793. m2m_memcpy(strRsa.au8E, pu8d, u16dSize);
  794. m2m_memcpy(strRsa.au8Hash, pu8SignedMsgHash, u16HashLength);
  795. strRsa.u16Esz = u16dSize;
  796. strRsa.u16Hsz = u16HashLength;
  797. strRsa.u16Nsz = u16NSize;
  798. gstrCryptoCtxt.pu8Rsa = pu8RsaSignature;
  799. ret = hif_send(M2M_REQ_GROUP_CRYPTO,
  800. M2M_CRYPTO_REQ_RSA_SIGN_GEN | M2M_REQ_DATA_PKT,
  801. (uint8 *)&strRsa,
  802. sizeof(tstrRsaPayload),
  803. NULL,
  804. 0,
  805. 0);
  806. }
  807. return ret;
  808. }
  809. #endif