Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

686 linhas
20 KiB

  1. /**
  2. *
  3. * \file m2m_crypto.c
  4. *
  5. * \brief WINC Crypto module.
  6. *
  7. * Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
  8. *
  9. * \asf_license_start
  10. *
  11. * \page License
  12. *
  13. * Subject to your compliance with these terms, you may use Microchip
  14. * software and any derivatives exclusively with Microchip products.
  15. * It is your responsibility to comply with third party license terms applicable
  16. * to your use of third party software (including open source software) that
  17. * may accompany Microchip software.
  18. *
  19. * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
  20. * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
  21. * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
  22. * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
  23. * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
  24. * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
  25. * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
  26. * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
  27. * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
  28. * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
  29. * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
  30. *
  31. * \asf_license_stop
  32. *
  33. */
  34. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  35. INCLUDES
  36. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  37. #include "driver/include/m2m_crypto.h"
  38. #include "driver/source/nmbus.h"
  39. #include "driver/source/nmasic.h"
  40. #ifdef CONF_CRYPTO
  41. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  42. MACROS
  43. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  44. /*======*======*======*======*======*=======*
  45. * WINC SHA256 HW Engine Register Definition *
  46. *======*======*======*======*======*========*/
  47. #define SHA_BLOCK_SIZE (64)
  48. #define SHARED_MEM_BASE (0xd0000)
  49. #define SHA256_MEM_BASE (0x180000UL)
  50. #define SHA256_ENGINE_ADDR (0x180000ul)
  51. /* SHA256 Registers */
  52. #define SHA256_CTRL (SHA256_MEM_BASE+0x00)
  53. #define SHA256_CTRL_START_CALC_MASK (NBIT0)
  54. #define SHA256_CTRL_START_CALC_SHIFT (0)
  55. #define SHA256_CTRL_PREPROCESS_MASK (NBIT1)
  56. #define SHA256_CTRL_PREPROCESS_SHIFT (1)
  57. #define SHA256_CTRL_HASH_HASH_MASK (NBIT2)
  58. #define SHA256_CTRL_HASH_HASH_SHIFT (2)
  59. #define SHA256_CTRL_INIT_SHA256_STATE_MASK (NBIT3)
  60. #define SHA256_CTRL_INIT_SHA256_STATE_SHIFT (3)
  61. #define SHA256_CTRL_WR_BACK_HASH_VALUE_MASK (NBIT4)
  62. #define SHA256_CTRL_WR_BACK_HASH_VALUE_SHIFT (4)
  63. #define SHA256_CTRL_FORCE_SHA256_QUIT_MASK (NBIT5)
  64. #define SHA256_CTRL_FORCE_SHA256_QUIT_SHIFT (5)
  65. #define SHA256_REGS_SHA256_CTRL_AHB_BYTE_REV_EN (NBIT6)
  66. #define SHA256_REGS_SHA256_CTRL_RESERVED (NBIT7)
  67. #define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO (NBIT8+ NBIT9+ NBIT10)
  68. #define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_MASK (NBIT2+ NBIT1+ NBIT0)
  69. #define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_SHIFT (8)
  70. #define SHA256_REGS_SHA256_CTRL_RESERVED_11 (NBIT11)
  71. #define SHA256_REGS_SHA256_CTRL_SHA1_CALC (NBIT12)
  72. #define SHA256_REGS_SHA256_CTRL_PBKDF2_SHA1_CALC (NBIT13)
  73. #define SHA256_START_RD_ADDR (SHA256_MEM_BASE+0x04UL)
  74. #define SHA256_DATA_LENGTH (SHA256_MEM_BASE+0x08UL)
  75. #define SHA256_START_WR_ADDR (SHA256_MEM_BASE+0x0cUL)
  76. #define SHA256_COND_CHK_CTRL (SHA256_MEM_BASE+0x10)
  77. #define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_MASK (NBIT1 | NBIT0)
  78. #define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_SHIFT (0)
  79. #define SHA256_COND_CHK_CTRL_STEP_VAL_MASK (NBIT6 | NBIT5 | NBIT4 | NBIT3 | NBIT2)
  80. #define SHA256_COND_CHK_CTRL_STEP_VAL_SHIFT (2)
  81. #define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_MASK (NBIT7)
  82. #define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_SHIFT (7)
  83. #define SHA256_MOD_DATA_RANGE (SHA256_MEM_BASE+0x14)
  84. #define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_MASK (NBIT24-1)
  85. #define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_SHIFT (0)
  86. #define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_MASK (NBIT24 | NBIT25| NBIT26)
  87. #define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_SHIFT (24)
  88. #define SHA256_COND_CHK_STS_1 (SHA256_MEM_BASE+0x18)
  89. #define SHA256_COND_CHK_STS_2 (SHA256_MEM_BASE+0x1c)
  90. #define SHA256_DONE_INTR_ENABLE (SHA256_MEM_BASE+0x20)
  91. #define SHA256_DONE_INTR_STS (SHA256_MEM_BASE+0x24)
  92. #define SHA256_TARGET_HASH_H1 (SHA256_MEM_BASE+0x28)
  93. #define SHA256_TARGET_HASH_H2 (SHA256_MEM_BASE+0x2c)
  94. #define SHA256_TARGET_HASH_H3 (SHA256_MEM_BASE+0x30)
  95. #define SHA256_TARGET_HASH_H4 (SHA256_MEM_BASE+0x34)
  96. #define SHA256_TARGET_HASH_H5 (SHA256_MEM_BASE+0x38)
  97. #define SHA256_TARGET_HASH_H6 (SHA256_MEM_BASE+0x3c)
  98. #define SHA256_TARGET_HASH_H7 (SHA256_MEM_BASE+0x40)
  99. #define SHA256_TARGET_HASH_H8 (SHA256_MEM_BASE+0x44)
  100. /*======*======*======*======*======*=======*
  101. * WINC BIGINT HW Engine Register Definition *
  102. *======*======*======*======*======*========*/
  103. #define BIGINT_ENGINE_ADDR (0x180080ul)
  104. #define BIGINT_VERSION (BIGINT_ENGINE_ADDR + 0x00)
  105. #define BIGINT_MISC_CTRL (BIGINT_ENGINE_ADDR + 0x04)
  106. #define BIGINT_MISC_CTRL_CTL_START (NBIT0)
  107. #define BIGINT_MISC_CTRL_CTL_RESET (NBIT1)
  108. #define BIGINT_MISC_CTRL_CTL_MSW_FIRST (NBIT2)
  109. #define BIGINT_MISC_CTRL_CTL_SWAP_BYTE_ORDER (NBIT3)
  110. #define BIGINT_MISC_CTRL_CTL_FORCE_BARRETT (NBIT4)
  111. #define BIGINT_MISC_CTRL_CTL_M_PRIME_VALID (NBIT5)
  112. #define BIGINT_M_PRIME (BIGINT_ENGINE_ADDR + 0x08)
  113. #define BIGINT_STATUS (BIGINT_ENGINE_ADDR + 0x0C)
  114. #define BIGINT_STATUS_STS_DONE (NBIT0)
  115. #define BIGINT_CLK_COUNT (BIGINT_ENGINE_ADDR + 0x10)
  116. #define BIGINT_ADDR_X (BIGINT_ENGINE_ADDR + 0x14)
  117. #define BIGINT_ADDR_E (BIGINT_ENGINE_ADDR + 0x18)
  118. #define BIGINT_ADDR_M (BIGINT_ENGINE_ADDR + 0x1C)
  119. #define BIGINT_ADDR_R (BIGINT_ENGINE_ADDR + 0x20)
  120. #define BIGINT_LENGTH (BIGINT_ENGINE_ADDR + 0x24)
  121. #define BIGINT_IRQ_STS (BIGINT_ENGINE_ADDR + 0x28)
  122. #define BIGINT_IRQ_STS_DONE (NBIT0)
  123. #define BIGINT_IRQ_STS_CHOOSE_MONT (NBIT1)
  124. #define BIGINT_IRQ_STS_M_READ (NBIT2)
  125. #define BIGINT_IRQ_STS_X_READ (NBIT3)
  126. #define BIGINT_IRQ_STS_START (NBIT4)
  127. #define BIGINT_IRQ_STS_PRECOMP_FINISH (NBIT5)
  128. #define BIGINT_IRQ_MASK (BIGINT_ENGINE_ADDR + 0x2C)
  129. #define BIGINT_IRQ_MASK_CTL_IRQ_MASK_START (NBIT4)
  130. #define ENABLE_FLIPPING 1
  131. #define GET_UINT32(BUF,OFFSET) (((uint32)((BUF)[OFFSET])) | ((uint32)(((BUF)[OFFSET + 1]) << 8)) | \
  132. ((uint32)(((BUF)[OFFSET + 2]) << 16)) | ((uint32)(((BUF)[OFFSET + 3]) << 24)))
  133. #define PUTU32(VAL32,BUF,OFFSET) \
  134. do \
  135. { \
  136. (BUF)[OFFSET ] = BYTE_3((VAL32)); \
  137. (BUF)[OFFSET +1 ] = BYTE_2((VAL32)); \
  138. (BUF)[OFFSET +2 ] = BYTE_1((VAL32)); \
  139. (BUF)[OFFSET +3 ] = BYTE_0((VAL32)); \
  140. }while(0)
  141. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  142. DATA TYPES
  143. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  144. /*!
  145. @struct \
  146. tstrHashContext
  147. @brief
  148. */
  149. typedef struct{
  150. uint32 au32HashState[M2M_SHA256_DIGEST_LEN/4];
  151. uint8 au8CurrentBlock[64];
  152. uint32 u32TotalLength;
  153. uint8 u8InitHashFlag;
  154. }tstrSHA256HashCtxt;
  155. /*======*======*======*======*======*=======*
  156. * SHA256 IMPLEMENTATION *
  157. *======*======*======*======*======*========*/
  158. sint8 m2m_sha256_hash_init(tstrM2mSha256Ctxt *pstrSha256Ctxt)
  159. {
  160. tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt;
  161. if(pstrSHA256 != NULL)
  162. {
  163. m2m_memset((uint8*)pstrSha256Ctxt, 0, sizeof(tstrM2mSha256Ctxt));
  164. pstrSHA256->u8InitHashFlag = 1;
  165. }
  166. return 0;
  167. }
  168. sint8 m2m_sha256_hash_update(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Data, uint16 u16DataLength)
  169. {
  170. sint8 s8Ret = M2M_ERR_FAIL;
  171. tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt;
  172. if(pstrSHA256 != NULL)
  173. {
  174. uint32 u32ReadAddr;
  175. uint32 u32WriteAddr = SHARED_MEM_BASE;
  176. uint32 u32Addr = u32WriteAddr;
  177. uint32 u32ResidualBytes;
  178. uint32 u32NBlocks;
  179. uint32 u32Offset;
  180. uint32 u32CurrentBlock = 0;
  181. uint8 u8IsDone = 0;
  182. /* Get the remaining bytes from the previous update (if the length is not block aligned). */
  183. u32ResidualBytes = pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE;
  184. /* Update the total data length. */
  185. pstrSHA256->u32TotalLength += u16DataLength;
  186. if(u32ResidualBytes != 0)
  187. {
  188. if((u32ResidualBytes + u16DataLength) >= SHA_BLOCK_SIZE)
  189. {
  190. u32Offset = SHA_BLOCK_SIZE - u32ResidualBytes;
  191. m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u32Offset);
  192. pu8Data += u32Offset;
  193. u16DataLength -= u32Offset;
  194. nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
  195. u32Addr += SHA_BLOCK_SIZE;
  196. u32CurrentBlock = 1;
  197. }
  198. else
  199. {
  200. m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u16DataLength);
  201. u16DataLength = 0;
  202. }
  203. }
  204. /* Get the number of HASH BLOCKs and the residual bytes. */
  205. u32NBlocks = u16DataLength / SHA_BLOCK_SIZE;
  206. u32ResidualBytes = u16DataLength % SHA_BLOCK_SIZE;
  207. if(u32NBlocks != 0)
  208. {
  209. nm_write_block(u32Addr, pu8Data, (uint16)(u32NBlocks * SHA_BLOCK_SIZE));
  210. pu8Data += (u32NBlocks * SHA_BLOCK_SIZE);
  211. }
  212. u32NBlocks += u32CurrentBlock;
  213. if(u32NBlocks != 0)
  214. {
  215. uint32 u32RegVal = 0;
  216. nm_write_reg(SHA256_CTRL, u32RegVal);
  217. u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK;
  218. nm_write_reg(SHA256_CTRL, u32RegVal);
  219. if(pstrSHA256->u8InitHashFlag)
  220. {
  221. pstrSHA256->u8InitHashFlag = 0;
  222. u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK;
  223. }
  224. u32ReadAddr = u32WriteAddr + (u32NBlocks * SHA_BLOCK_SIZE);
  225. nm_write_reg(SHA256_DATA_LENGTH, (u32NBlocks * SHA_BLOCK_SIZE));
  226. nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr);
  227. nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr);
  228. u32RegVal |= SHA256_CTRL_START_CALC_MASK;
  229. u32RegVal &= ~(0x7 << 8);
  230. u32RegVal |= (2 << 8);
  231. nm_write_reg(SHA256_CTRL, u32RegVal);
  232. /* 5. Wait for done_intr */
  233. while(!u8IsDone)
  234. {
  235. u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS);
  236. u8IsDone = u32RegVal & NBIT0;
  237. }
  238. }
  239. if(u32ResidualBytes != 0)
  240. {
  241. m2m_memcpy(pstrSHA256->au8CurrentBlock, pu8Data, u32ResidualBytes);
  242. }
  243. s8Ret = M2M_SUCCESS;
  244. }
  245. return s8Ret;
  246. }
  247. sint8 m2m_sha256_hash_finish(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Sha256Digest)
  248. {
  249. sint8 s8Ret = M2M_ERR_FAIL;
  250. tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt;
  251. if(pstrSHA256 != NULL)
  252. {
  253. uint32 u32ReadAddr;
  254. uint32 u32WriteAddr = SHARED_MEM_BASE;
  255. uint32 u32Addr = u32WriteAddr;
  256. uint16 u16Offset;
  257. uint16 u16PaddingLength;
  258. uint16 u16NBlocks = 1;
  259. uint32 u32RegVal = 0;
  260. uint32 u32Idx,u32ByteIdx;
  261. uint32 au32Digest[M2M_SHA256_DIGEST_LEN / 4];
  262. uint8 u8IsDone = 0;
  263. nm_write_reg(SHA256_CTRL,u32RegVal);
  264. u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK;
  265. nm_write_reg(SHA256_CTRL,u32RegVal);
  266. if(pstrSHA256->u8InitHashFlag)
  267. {
  268. pstrSHA256->u8InitHashFlag = 0;
  269. u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK;
  270. }
  271. /* Calculate the offset of the last data byte in the current block. */
  272. u16Offset = (uint16)(pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE);
  273. /* Add the padding byte 0x80. */
  274. pstrSHA256->au8CurrentBlock[u16Offset ++] = 0x80;
  275. /* Calculate the required padding to complete
  276. one Hash Block Size.
  277. */
  278. u16PaddingLength = SHA_BLOCK_SIZE - u16Offset;
  279. m2m_memset(&pstrSHA256->au8CurrentBlock[u16Offset], 0, u16PaddingLength);
  280. /* If the padding count is not enough to hold 64-bit representation of
  281. the total input message length, one padding block is required.
  282. */
  283. if(u16PaddingLength < 8)
  284. {
  285. nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
  286. u32Addr += SHA_BLOCK_SIZE;
  287. m2m_memset(pstrSHA256->au8CurrentBlock, 0, SHA_BLOCK_SIZE);
  288. u16NBlocks ++;
  289. }
  290. /* pack the length at the end of the padding block */
  291. PUTU32(pstrSHA256->u32TotalLength << 3, pstrSHA256->au8CurrentBlock, (SHA_BLOCK_SIZE - 4));
  292. u32ReadAddr = u32WriteAddr + (u16NBlocks * SHA_BLOCK_SIZE);
  293. nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
  294. nm_write_reg(SHA256_DATA_LENGTH, (u16NBlocks * SHA_BLOCK_SIZE));
  295. nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr);
  296. nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr);
  297. u32RegVal |= SHA256_CTRL_START_CALC_MASK;
  298. u32RegVal |= SHA256_CTRL_WR_BACK_HASH_VALUE_MASK;
  299. u32RegVal &= ~(0x7UL << 8);
  300. u32RegVal |= (0x2UL << 8);
  301. nm_write_reg(SHA256_CTRL,u32RegVal);
  302. /* 5. Wait for done_intr */
  303. while(!u8IsDone)
  304. {
  305. u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS);
  306. u8IsDone = u32RegVal & NBIT0;
  307. }
  308. nm_read_block(u32ReadAddr, (uint8*)au32Digest, 32);
  309. /* Convert the output words to an array of bytes.
  310. */
  311. u32ByteIdx = 0;
  312. for(u32Idx = 0; u32Idx < (M2M_SHA256_DIGEST_LEN / 4); u32Idx ++)
  313. {
  314. pu8Sha256Digest[u32ByteIdx ++] = BYTE_3(au32Digest[u32Idx]);
  315. pu8Sha256Digest[u32ByteIdx ++] = BYTE_2(au32Digest[u32Idx]);
  316. pu8Sha256Digest[u32ByteIdx ++] = BYTE_1(au32Digest[u32Idx]);
  317. pu8Sha256Digest[u32ByteIdx ++] = BYTE_0(au32Digest[u32Idx]);
  318. }
  319. s8Ret = M2M_SUCCESS;
  320. }
  321. return s8Ret;
  322. }
  323. /*======*======*======*======*======*=======*
  324. * RSA IMPLEMENTATION *
  325. *======*======*======*======*======*========*/
  326. static void FlipBuffer(uint8 *pu8InBuffer, uint8 *pu8OutBuffer, uint16 u16BufferSize)
  327. {
  328. uint16 u16Idx;
  329. for(u16Idx = 0; u16Idx < u16BufferSize; u16Idx ++)
  330. {
  331. #if ENABLE_FLIPPING == 1
  332. pu8OutBuffer[u16Idx] = pu8InBuffer[u16BufferSize - u16Idx - 1];
  333. #else
  334. pu8OutBuffer[u16Idx] = pu8InBuffer[u16Idx];
  335. #endif
  336. }
  337. }
  338. void BigInt_ModExp
  339. (
  340. uint8 *pu8X, uint16 u16XSize,
  341. uint8 *pu8E, uint16 u16ESize,
  342. uint8 *pu8M, uint16 u16MSize,
  343. uint8 *pu8R, uint16 u16RSize
  344. )
  345. {
  346. uint32 u32Reg;
  347. uint8 au8Tmp[780] = {0};
  348. uint32 u32XAddr = SHARED_MEM_BASE;
  349. uint32 u32MAddr;
  350. uint32 u32EAddr;
  351. uint32 u32RAddr;
  352. uint8 u8EMswBits = 32;
  353. uint32 u32Mprime = 0x7F;
  354. uint16 u16XSizeWords,u16ESizeWords;
  355. uint32 u32Exponent;
  356. u16XSizeWords = (u16XSize + 3) / 4;
  357. u16ESizeWords = (u16ESize + 3) / 4;
  358. u32MAddr = u32XAddr + (u16XSizeWords * 4);
  359. u32EAddr = u32MAddr + (u16XSizeWords * 4);
  360. u32RAddr = u32EAddr + (u16ESizeWords * 4);
  361. /* Reset the core.
  362. */
  363. u32Reg = 0;
  364. u32Reg |= BIGINT_MISC_CTRL_CTL_RESET;
  365. u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
  366. u32Reg &= ~BIGINT_MISC_CTRL_CTL_RESET;
  367. u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
  368. nm_write_block(u32RAddr,au8Tmp, u16RSize);
  369. /* Write Input Operands to Chip Memory.
  370. */
  371. /*------- X -------*/
  372. FlipBuffer(pu8X,au8Tmp,u16XSize);
  373. nm_write_block(u32XAddr,au8Tmp,u16XSizeWords * 4);
  374. /*------- E -------*/
  375. m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
  376. FlipBuffer(pu8E, au8Tmp, u16ESize);
  377. nm_write_block(u32EAddr, au8Tmp, u16ESizeWords * 4);
  378. u32Exponent = GET_UINT32(au8Tmp, (u16ESizeWords * 4) - 4);
  379. while((u32Exponent & NBIT31)== 0)
  380. {
  381. u32Exponent <<= 1;
  382. u8EMswBits --;
  383. }
  384. /*------- M -------*/
  385. m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
  386. FlipBuffer(pu8M, au8Tmp, u16XSize);
  387. nm_write_block(u32MAddr, au8Tmp, u16XSizeWords * 4);
  388. /* Program the addresses of the input operands.
  389. */
  390. nm_write_reg(BIGINT_ADDR_X, u32XAddr);
  391. nm_write_reg(BIGINT_ADDR_E, u32EAddr);
  392. nm_write_reg(BIGINT_ADDR_M, u32MAddr);
  393. nm_write_reg(BIGINT_ADDR_R, u32RAddr);
  394. /* Mprime.
  395. */
  396. nm_write_reg(BIGINT_M_PRIME,u32Mprime);
  397. /* Length.
  398. */
  399. u32Reg = (u16XSizeWords & 0xFF);
  400. u32Reg += ((u16ESizeWords & 0xFF) << 8);
  401. u32Reg += (u8EMswBits << 16);
  402. nm_write_reg(BIGINT_LENGTH,u32Reg);
  403. /* CTRL Register.
  404. */
  405. u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
  406. u32Reg ^= BIGINT_MISC_CTRL_CTL_START;
  407. u32Reg |= BIGINT_MISC_CTRL_CTL_FORCE_BARRETT;
  408. //u32Reg |= BIGINT_MISC_CTRL_CTL_M_PRIME_VALID;
  409. #if ENABLE_FLIPPING == 0
  410. u32Reg |= BIGINT_MISC_CTRL_CTL_MSW_FIRST;
  411. #endif
  412. nm_write_reg(BIGINT_MISC_CTRL,u32Reg);
  413. /* Wait for computation to complete. */
  414. while(1)
  415. {
  416. u32Reg = nm_read_reg(BIGINT_IRQ_STS);
  417. if(u32Reg & BIGINT_IRQ_STS_DONE)
  418. {
  419. break;
  420. }
  421. }
  422. nm_write_reg(BIGINT_IRQ_STS,0);
  423. m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
  424. nm_read_block(u32RAddr, au8Tmp, u16RSize);
  425. FlipBuffer(au8Tmp, pu8R, u16RSize);
  426. }
  427. #define MD5_DIGEST_SIZE (16)
  428. #define SHA1_DIGEST_SIZE (20)
  429. static const uint8 au8TEncodingMD5[] =
  430. {
  431. 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86,
  432. 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00,
  433. 0x04
  434. };
  435. /*!< Fixed part of the Encoding T for the MD5 hash algorithm.
  436. */
  437. static const uint8 au8TEncodingSHA1[] =
  438. {
  439. 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E,
  440. 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04
  441. };
  442. /*!< Fixed part of the Encoding T for the SHA-1 hash algorithm.
  443. */
  444. static const uint8 au8TEncodingSHA2[] =
  445. {
  446. 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86,
  447. 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
  448. 0x00, 0x04
  449. };
  450. /*!< Fixed part of the Encoding T for the SHA-2 hash algorithm.
  451. */
  452. sint8 m2m_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash,
  453. uint16 u16HashLength, uint8 *pu8RsaSignature)
  454. {
  455. sint8 s8Ret = M2M_RSA_SIGN_FAIL;
  456. if((pu8N != NULL) && (pu8E != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL))
  457. {
  458. uint16 u16TLength, u16TEncodingLength;
  459. uint8 *pu8T;
  460. uint8 au8EM[512];
  461. /* Selection of correct T Encoding based on the hash size.
  462. */
  463. if(u16HashLength == MD5_DIGEST_SIZE)
  464. {
  465. pu8T = (uint8*)au8TEncodingMD5;
  466. u16TEncodingLength = sizeof(au8TEncodingMD5);
  467. }
  468. else if(u16HashLength == SHA1_DIGEST_SIZE)
  469. {
  470. pu8T = (uint8*)au8TEncodingSHA1;
  471. u16TEncodingLength = sizeof(au8TEncodingSHA1);
  472. }
  473. else
  474. {
  475. pu8T = (uint8*)au8TEncodingSHA2;
  476. u16TEncodingLength = sizeof(au8TEncodingSHA2);
  477. }
  478. u16TLength = u16TEncodingLength + 1 + u16HashLength;
  479. /* If emLen < tLen + 11.
  480. */
  481. if(u16NSize >= (u16TLength + 11))
  482. {
  483. uint32 u32PSLength,u32Idx = 0;
  484. /*
  485. RSA verification
  486. */
  487. BigInt_ModExp(pu8RsaSignature, u16NSize, pu8E, u16ESize, pu8N, u16NSize, au8EM, u16NSize);
  488. u32PSLength = u16NSize - u16TLength - 3;
  489. /*
  490. The calculated EM must match the following pattern.
  491. *======*======*======*======*======*
  492. * 0x00 || 0x01 || PS || 0x00 || T *
  493. *======*======*======*======*======*
  494. Where PS is all 0xFF
  495. T is defined based on the hash algorithm.
  496. */
  497. if((au8EM[0] == 0x00) && (au8EM[1] == 0x01))
  498. {
  499. for(u32Idx = 2; au8EM[u32Idx] == 0xFF; u32Idx ++);
  500. if(u32Idx == (u32PSLength + 2))
  501. {
  502. if(au8EM[u32Idx ++] == 0x00)
  503. {
  504. if(!m2m_memcmp(&au8EM[u32Idx], pu8T, u16TEncodingLength))
  505. {
  506. u32Idx += u16TEncodingLength;
  507. if(au8EM[u32Idx ++] == u16HashLength)
  508. s8Ret = m2m_memcmp(&au8EM[u32Idx], pu8SignedMsgHash, u16HashLength);
  509. }
  510. }
  511. }
  512. }
  513. }
  514. }
  515. return s8Ret;
  516. }
  517. sint8 m2m_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash,
  518. uint16 u16HashLength, uint8 *pu8RsaSignature)
  519. {
  520. sint8 s8Ret = M2M_RSA_SIGN_FAIL;
  521. if((pu8N != NULL) && (pu8d != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL))
  522. {
  523. uint16 u16TLength, u16TEncodingLength;
  524. uint8 *pu8T;
  525. uint8 au8EM[512];
  526. /* Selection of correct T Encoding based on the hash size.
  527. */
  528. if(u16HashLength == MD5_DIGEST_SIZE)
  529. {
  530. pu8T = (uint8*)au8TEncodingMD5;
  531. u16TEncodingLength = sizeof(au8TEncodingMD5);
  532. }
  533. else if(u16HashLength == SHA1_DIGEST_SIZE)
  534. {
  535. pu8T = (uint8*)au8TEncodingSHA1;
  536. u16TEncodingLength = sizeof(au8TEncodingSHA1);
  537. }
  538. else
  539. {
  540. pu8T = (uint8*)au8TEncodingSHA2;
  541. u16TEncodingLength = sizeof(au8TEncodingSHA2);
  542. }
  543. u16TLength = u16TEncodingLength + 1 + u16HashLength;
  544. /* If emLen < tLen + 11.
  545. */
  546. if(u16NSize >= (u16TLength + 11))
  547. {
  548. uint16 u16PSLength = 0;
  549. uint16 u16Offset = 0;
  550. /*
  551. The calculated EM must match the following pattern.
  552. *======*======*======*======*======*
  553. * 0x00 || 0x01 || PS || 0x00 || T *
  554. *======*======*======*======*======*
  555. Where PS is all 0xFF
  556. T is defined based on the hash algorithm.
  557. */
  558. au8EM[u16Offset ++] = 0;
  559. au8EM[u16Offset ++] = 1;
  560. u16PSLength = u16NSize - u16TLength - 3;
  561. m2m_memset(&au8EM[u16Offset], 0xFF, u16PSLength);
  562. u16Offset += u16PSLength;
  563. au8EM[u16Offset ++] = 0;
  564. m2m_memcpy(&au8EM[u16Offset], pu8T, u16TEncodingLength);
  565. u16Offset += u16TEncodingLength;
  566. au8EM[u16Offset ++] = u16HashLength;
  567. m2m_memcpy(&au8EM[u16Offset], pu8SignedMsgHash, u16HashLength);
  568. /*
  569. RSA Signature Generation
  570. */
  571. BigInt_ModExp(au8EM, u16NSize, pu8d, u16dSize, pu8N, u16NSize, pu8RsaSignature, u16NSize);
  572. s8Ret = M2M_RSA_SIGN_OK;
  573. }
  574. }
  575. return s8Ret;
  576. }
  577. #endif /* CONF_CRYPTO */