m2m_crypto.c
Go to the documentation of this file.
1 
35 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
36 INCLUDES
37 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
38 
40 #include "driver/source/nmbus.h"
41 #include "driver/source/nmasic.h"
42 
43 #ifdef CONF_CRYPTO
44 
45 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
46 MACROS
47 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
48 
49 /*======*======*======*======*======*=======*
50 * WINC SHA256 HW Engine Register Definition *
51 *======*======*======*======*======*========*/
52 
53 #define SHA_BLOCK_SIZE (64)
54 
55 #define SHARED_MEM_BASE (0xd0000)
56 
57 
58 #define SHA256_MEM_BASE (0x180000UL)
59 #define SHA256_ENGINE_ADDR (0x180000ul)
60 
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 
76 #define SHA256_REGS_SHA256_CTRL_AHB_BYTE_REV_EN (NBIT6)
77 #define SHA256_REGS_SHA256_CTRL_RESERVED (NBIT7)
78 #define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO (NBIT8+ NBIT9+ NBIT10)
79 #define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_MASK (NBIT2+ NBIT1+ NBIT0)
80 #define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_SHIFT (8)
81 #define SHA256_REGS_SHA256_CTRL_RESERVED_11 (NBIT11)
82 #define SHA256_REGS_SHA256_CTRL_SHA1_CALC (NBIT12)
83 #define SHA256_REGS_SHA256_CTRL_PBKDF2_SHA1_CALC (NBIT13)
84 
85 
86 #define SHA256_START_RD_ADDR (SHA256_MEM_BASE+0x04UL)
87 #define SHA256_DATA_LENGTH (SHA256_MEM_BASE+0x08UL)
88 #define SHA256_START_WR_ADDR (SHA256_MEM_BASE+0x0cUL)
89 #define SHA256_COND_CHK_CTRL (SHA256_MEM_BASE+0x10)
90 #define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_MASK (NBIT1 | NBIT0)
91 #define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_SHIFT (0)
92 #define SHA256_COND_CHK_CTRL_STEP_VAL_MASK (NBIT6 | NBIT5 | NBIT4 | NBIT3 | NBIT2)
93 #define SHA256_COND_CHK_CTRL_STEP_VAL_SHIFT (2)
94 #define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_MASK (NBIT7)
95 #define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_SHIFT (7)
96 
97 #define SHA256_MOD_DATA_RANGE (SHA256_MEM_BASE+0x14)
98 #define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_MASK (NBIT24-1)
99 #define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_SHIFT (0)
100 #define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_MASK (NBIT24 | NBIT25| NBIT26)
101 #define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_SHIFT (24)
102 
103 
104 #define SHA256_COND_CHK_STS_1 (SHA256_MEM_BASE+0x18)
105 #define SHA256_COND_CHK_STS_2 (SHA256_MEM_BASE+0x1c)
106 #define SHA256_DONE_INTR_ENABLE (SHA256_MEM_BASE+0x20)
107 #define SHA256_DONE_INTR_STS (SHA256_MEM_BASE+0x24)
108 #define SHA256_TARGET_HASH_H1 (SHA256_MEM_BASE+0x28)
109 #define SHA256_TARGET_HASH_H2 (SHA256_MEM_BASE+0x2c)
110 #define SHA256_TARGET_HASH_H3 (SHA256_MEM_BASE+0x30)
111 #define SHA256_TARGET_HASH_H4 (SHA256_MEM_BASE+0x34)
112 #define SHA256_TARGET_HASH_H5 (SHA256_MEM_BASE+0x38)
113 #define SHA256_TARGET_HASH_H6 (SHA256_MEM_BASE+0x3c)
114 #define SHA256_TARGET_HASH_H7 (SHA256_MEM_BASE+0x40)
115 #define SHA256_TARGET_HASH_H8 (SHA256_MEM_BASE+0x44)
116 
117 /*======*======*======*======*======*=======*
118 * WINC BIGINT HW Engine Register Definition *
119 *======*======*======*======*======*========*/
120 
121 
122 #define BIGINT_ENGINE_ADDR (0x180080ul)
123 #define BIGINT_VERSION (BIGINT_ENGINE_ADDR + 0x00)
124 
125 #define BIGINT_MISC_CTRL (BIGINT_ENGINE_ADDR + 0x04)
126 #define BIGINT_MISC_CTRL_CTL_START (NBIT0)
127 #define BIGINT_MISC_CTRL_CTL_RESET (NBIT1)
128 #define BIGINT_MISC_CTRL_CTL_MSW_FIRST (NBIT2)
129 #define BIGINT_MISC_CTRL_CTL_SWAP_BYTE_ORDER (NBIT3)
130 #define BIGINT_MISC_CTRL_CTL_FORCE_BARRETT (NBIT4)
131 #define BIGINT_MISC_CTRL_CTL_M_PRIME_VALID (NBIT5)
132 
133 #define BIGINT_M_PRIME (BIGINT_ENGINE_ADDR + 0x08)
134 
135 #define BIGINT_STATUS (BIGINT_ENGINE_ADDR + 0x0C)
136 #define BIGINT_STATUS_STS_DONE (NBIT0)
137 
138 #define BIGINT_CLK_COUNT (BIGINT_ENGINE_ADDR + 0x10)
139 #define BIGINT_ADDR_X (BIGINT_ENGINE_ADDR + 0x14)
140 #define BIGINT_ADDR_E (BIGINT_ENGINE_ADDR + 0x18)
141 #define BIGINT_ADDR_M (BIGINT_ENGINE_ADDR + 0x1C)
142 #define BIGINT_ADDR_R (BIGINT_ENGINE_ADDR + 0x20)
143 #define BIGINT_LENGTH (BIGINT_ENGINE_ADDR + 0x24)
144 
145 #define BIGINT_IRQ_STS (BIGINT_ENGINE_ADDR + 0x28)
146 #define BIGINT_IRQ_STS_DONE (NBIT0)
147 #define BIGINT_IRQ_STS_CHOOSE_MONT (NBIT1)
148 #define BIGINT_IRQ_STS_M_READ (NBIT2)
149 #define BIGINT_IRQ_STS_X_READ (NBIT3)
150 #define BIGINT_IRQ_STS_START (NBIT4)
151 #define BIGINT_IRQ_STS_PRECOMP_FINISH (NBIT5)
152 
153 #define BIGINT_IRQ_MASK (BIGINT_ENGINE_ADDR + 0x2C)
154 #define BIGINT_IRQ_MASK_CTL_IRQ_MASK_START (NBIT4)
155 
156 #define ENABLE_FLIPPING 1
157 
158 
159 
160 
161 #define GET_UINT32(BUF,OFFSET) (((uint32)((BUF)[OFFSET])) | ((uint32)(((BUF)[OFFSET + 1]) << 8)) | \
162 ((uint32)(((BUF)[OFFSET + 2]) << 16)) | ((uint32)(((BUF)[OFFSET + 3]) << 24)))
163 
164 #define PUTU32(VAL32,BUF,OFFSET) \
165 do \
166 { \
167  (BUF)[OFFSET ] = BYTE_3((VAL32)); \
168  (BUF)[OFFSET +1 ] = BYTE_2((VAL32)); \
169  (BUF)[OFFSET +2 ] = BYTE_1((VAL32)); \
170  (BUF)[OFFSET +3 ] = BYTE_0((VAL32)); \
171 }while(0)
172 
173 
174 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
175 DATA TYPES
176 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
177 
184 typedef struct{
185  uint32 au32HashState[M2M_SHA256_DIGEST_LEN/4];
186  uint8 au8CurrentBlock[64];
187  uint32 u32TotalLength;
188  uint8 u8InitHashFlag;
189 }tstrSHA256HashCtxt;
190 
191 
192 
193 /*======*======*======*======*======*=======*
194 * SHA256 IMPLEMENTATION *
195 *======*======*======*======*======*========*/
196 
198 {
199  tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt;
200  if(pstrSHA256 != NULL)
201  {
202  m2m_memset((uint8*)pstrSha256Ctxt, 0, sizeof(tstrM2mSha256Ctxt));
203  pstrSHA256->u8InitHashFlag = 1;
204  }
205  return 0;
206 }
207 
208 sint8 m2m_sha256_hash_update(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Data, uint16 u16DataLength)
209 {
210  sint8 s8Ret = M2M_ERR_FAIL;
211  tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt;
212  if(pstrSHA256 != NULL)
213  {
214  uint32 u32ReadAddr;
215  uint32 u32WriteAddr = SHARED_MEM_BASE;
216  uint32 u32Addr = u32WriteAddr;
217  uint32 u32ResidualBytes;
218  uint32 u32NBlocks;
219  uint32 u32Offset;
220  uint32 u32CurrentBlock = 0;
221  uint8 u8IsDone = 0;
222 
223  /* Get the remaining bytes from the previous update (if the length is not block aligned). */
224  u32ResidualBytes = pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE;
225 
226  /* Update the total data length. */
227  pstrSHA256->u32TotalLength += u16DataLength;
228 
229  if(u32ResidualBytes != 0)
230  {
231  if((u32ResidualBytes + u16DataLength) >= SHA_BLOCK_SIZE)
232  {
233  u32Offset = SHA_BLOCK_SIZE - u32ResidualBytes;
234  m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u32Offset);
235  pu8Data += u32Offset;
236  u16DataLength -= u32Offset;
237 
238  nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
239  u32Addr += SHA_BLOCK_SIZE;
240  u32CurrentBlock = 1;
241  }
242  else
243  {
244  m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u16DataLength);
245  u16DataLength = 0;
246  }
247  }
248 
249  /* Get the number of HASH BLOCKs and the residual bytes. */
250  u32NBlocks = u16DataLength / SHA_BLOCK_SIZE;
251  u32ResidualBytes = u16DataLength % SHA_BLOCK_SIZE;
252 
253  if(u32NBlocks != 0)
254  {
255  nm_write_block(u32Addr, pu8Data, (uint16)(u32NBlocks * SHA_BLOCK_SIZE));
256  pu8Data += (u32NBlocks * SHA_BLOCK_SIZE);
257  }
258 
259  u32NBlocks += u32CurrentBlock;
260  if(u32NBlocks != 0)
261  {
262  uint32 u32RegVal = 0;
263 
264  nm_write_reg(SHA256_CTRL, u32RegVal);
265  u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK;
266  nm_write_reg(SHA256_CTRL, u32RegVal);
267 
268  if(pstrSHA256->u8InitHashFlag)
269  {
270  pstrSHA256->u8InitHashFlag = 0;
271  u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK;
272  }
273 
274  u32ReadAddr = u32WriteAddr + (u32NBlocks * SHA_BLOCK_SIZE);
275  nm_write_reg(SHA256_DATA_LENGTH, (u32NBlocks * SHA_BLOCK_SIZE));
276  nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr);
277  nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr);
278 
279  u32RegVal |= SHA256_CTRL_START_CALC_MASK;
280 
281  u32RegVal &= ~(0x7 << 8);
282  u32RegVal |= (2 << 8);
283 
284  nm_write_reg(SHA256_CTRL, u32RegVal);
285 
286  /* 5. Wait for done_intr */
287  while(!u8IsDone)
288  {
289  u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS);
290  u8IsDone = u32RegVal & NBIT0;
291  }
292  }
293  if(u32ResidualBytes != 0)
294  {
295  m2m_memcpy(pstrSHA256->au8CurrentBlock, pu8Data, u32ResidualBytes);
296  }
297  s8Ret = M2M_SUCCESS;
298  }
299  return s8Ret;
300 }
301 
302 
303 sint8 m2m_sha256_hash_finish(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Sha256Digest)
304 {
305  sint8 s8Ret = M2M_ERR_FAIL;
306  tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt;
307  if(pstrSHA256 != NULL)
308  {
309  uint32 u32ReadAddr;
310  uint32 u32WriteAddr = SHARED_MEM_BASE;
311  uint32 u32Addr = u32WriteAddr;
312  uint16 u16Offset;
313  uint16 u16PaddingLength;
314  uint16 u16NBlocks = 1;
315  uint32 u32RegVal = 0;
316  uint32 u32Idx,u32ByteIdx;
317  uint32 au32Digest[M2M_SHA256_DIGEST_LEN / 4];
318  uint8 u8IsDone = 0;
319 
320  nm_write_reg(SHA256_CTRL,u32RegVal);
321  u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK;
322  nm_write_reg(SHA256_CTRL,u32RegVal);
323 
324  if(pstrSHA256->u8InitHashFlag)
325  {
326  pstrSHA256->u8InitHashFlag = 0;
327  u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK;
328  }
329 
330  /* Calculate the offset of the last data byte in the current block. */
331  u16Offset = (uint16)(pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE);
332 
333  /* Add the padding byte 0x80. */
334  pstrSHA256->au8CurrentBlock[u16Offset ++] = 0x80;
335 
336  /* Calculate the required padding to complete
337  one Hash Block Size.
338  */
339  u16PaddingLength = SHA_BLOCK_SIZE - u16Offset;
340  m2m_memset(&pstrSHA256->au8CurrentBlock[u16Offset], 0, u16PaddingLength);
341 
342  /* If the padding count is not enough to hold 64-bit representation of
343  the total input message length, one padding block is required.
344  */
345  if(u16PaddingLength < 8)
346  {
347  nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
348  u32Addr += SHA_BLOCK_SIZE;
349  m2m_memset(pstrSHA256->au8CurrentBlock, 0, SHA_BLOCK_SIZE);
350  u16NBlocks ++;
351  }
352 
353  /* pack the length at the end of the padding block */
354  PUTU32(pstrSHA256->u32TotalLength << 3, pstrSHA256->au8CurrentBlock, (SHA_BLOCK_SIZE - 4));
355 
356  u32ReadAddr = u32WriteAddr + (u16NBlocks * SHA_BLOCK_SIZE);
357  nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
358  nm_write_reg(SHA256_DATA_LENGTH, (u16NBlocks * SHA_BLOCK_SIZE));
359  nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr);
360  nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr);
361 
362  u32RegVal |= SHA256_CTRL_START_CALC_MASK;
363  u32RegVal |= SHA256_CTRL_WR_BACK_HASH_VALUE_MASK;
364  u32RegVal &= ~(0x7UL << 8);
365  u32RegVal |= (0x2UL << 8);
366 
367  nm_write_reg(SHA256_CTRL,u32RegVal);
368 
369 
370  /* 5. Wait for done_intr */
371  while(!u8IsDone)
372  {
373  u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS);
374  u8IsDone = u32RegVal & NBIT0;
375  }
376  nm_read_block(u32ReadAddr, (uint8*)au32Digest, 32);
377 
378  /* Convert the output words to an array of bytes.
379  */
380  u32ByteIdx = 0;
381  for(u32Idx = 0; u32Idx < (M2M_SHA256_DIGEST_LEN / 4); u32Idx ++)
382  {
383  pu8Sha256Digest[u32ByteIdx ++] = BYTE_3(au32Digest[u32Idx]);
384  pu8Sha256Digest[u32ByteIdx ++] = BYTE_2(au32Digest[u32Idx]);
385  pu8Sha256Digest[u32ByteIdx ++] = BYTE_1(au32Digest[u32Idx]);
386  pu8Sha256Digest[u32ByteIdx ++] = BYTE_0(au32Digest[u32Idx]);
387  }
388  s8Ret = M2M_SUCCESS;
389  }
390  return s8Ret;
391 }
392 
393 
394 /*======*======*======*======*======*=======*
395 * RSA IMPLEMENTATION *
396 *======*======*======*======*======*========*/
397 
398 static void FlipBuffer(uint8 *pu8InBuffer, uint8 *pu8OutBuffer, uint16 u16BufferSize)
399 {
400  uint16 u16Idx;
401  for(u16Idx = 0; u16Idx < u16BufferSize; u16Idx ++)
402  {
403 #if ENABLE_FLIPPING == 1
404  pu8OutBuffer[u16Idx] = pu8InBuffer[u16BufferSize - u16Idx - 1];
405 #else
406  pu8OutBuffer[u16Idx] = pu8InBuffer[u16Idx];
407 #endif
408  }
409 }
410 
411 void BigInt_ModExp
412 (
413  uint8 *pu8X, uint16 u16XSize,
414  uint8 *pu8E, uint16 u16ESize,
415  uint8 *pu8M, uint16 u16MSize,
416  uint8 *pu8R, uint16 u16RSize
417  )
418 {
419  uint32 u32Reg;
420  uint8 au8Tmp[780] = {0};
421  uint32 u32XAddr = SHARED_MEM_BASE;
422  uint32 u32MAddr;
423  uint32 u32EAddr;
424  uint32 u32RAddr;
425  uint8 u8EMswBits = 32;
426  uint32 u32Mprime = 0x7F;
427  uint16 u16XSizeWords,u16ESizeWords;
428  uint32 u32Exponent;
429 
430  u16XSizeWords = (u16XSize + 3) / 4;
431  u16ESizeWords = (u16ESize + 3) / 4;
432 
433  u32MAddr = u32XAddr + (u16XSizeWords * 4);
434  u32EAddr = u32MAddr + (u16XSizeWords * 4);
435  u32RAddr = u32EAddr + (u16ESizeWords * 4);
436 
437  /* Reset the core.
438  */
439  u32Reg = 0;
440  u32Reg |= BIGINT_MISC_CTRL_CTL_RESET;
441  u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
442  u32Reg &= ~BIGINT_MISC_CTRL_CTL_RESET;
443  u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
444 
445  nm_write_block(u32RAddr,au8Tmp, u16RSize);
446 
447  /* Write Input Operands to Chip Memory.
448  */
449  /*------- X -------*/
450  FlipBuffer(pu8X,au8Tmp,u16XSize);
451  nm_write_block(u32XAddr,au8Tmp,u16XSizeWords * 4);
452 
453  /*------- E -------*/
454  m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
455  FlipBuffer(pu8E, au8Tmp, u16ESize);
456  nm_write_block(u32EAddr, au8Tmp, u16ESizeWords * 4);
457  u32Exponent = GET_UINT32(au8Tmp, (u16ESizeWords * 4) - 4);
458  while((u32Exponent & NBIT31)== 0)
459  {
460  u32Exponent <<= 1;
461  u8EMswBits --;
462  }
463 
464  /*------- M -------*/
465  m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
466  FlipBuffer(pu8M, au8Tmp, u16XSize);
467  nm_write_block(u32MAddr, au8Tmp, u16XSizeWords * 4);
468 
469  /* Program the addresses of the input operands.
470  */
471  nm_write_reg(BIGINT_ADDR_X, u32XAddr);
472  nm_write_reg(BIGINT_ADDR_E, u32EAddr);
473  nm_write_reg(BIGINT_ADDR_M, u32MAddr);
474  nm_write_reg(BIGINT_ADDR_R, u32RAddr);
475 
476  /* Mprime.
477  */
478  nm_write_reg(BIGINT_M_PRIME,u32Mprime);
479 
480  /* Length.
481  */
482  u32Reg = (u16XSizeWords & 0xFF);
483  u32Reg += ((u16ESizeWords & 0xFF) << 8);
484  u32Reg += (u8EMswBits << 16);
485  nm_write_reg(BIGINT_LENGTH,u32Reg);
486 
487  /* CTRL Register.
488  */
489  u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
490  u32Reg ^= BIGINT_MISC_CTRL_CTL_START;
491  u32Reg |= BIGINT_MISC_CTRL_CTL_FORCE_BARRETT;
492  //u32Reg |= BIGINT_MISC_CTRL_CTL_M_PRIME_VALID;
493 #if ENABLE_FLIPPING == 0
494  u32Reg |= BIGINT_MISC_CTRL_CTL_MSW_FIRST;
495 #endif
496  nm_write_reg(BIGINT_MISC_CTRL,u32Reg);
497 
498  /* Wait for computation to complete. */
499  while(1)
500  {
501  u32Reg = nm_read_reg(BIGINT_IRQ_STS);
502  if(u32Reg & BIGINT_IRQ_STS_DONE)
503  {
504  break;
505  }
506  }
507  nm_write_reg(BIGINT_IRQ_STS,0);
508  m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
509  nm_read_block(u32RAddr, au8Tmp, u16RSize);
510  FlipBuffer(au8Tmp, pu8R, u16RSize);
511 }
512 
513 
514 
515 #define MD5_DIGEST_SIZE (16)
516 #define SHA1_DIGEST_SIZE (20)
517 
518 static const uint8 au8TEncodingMD5[] =
519 {
520  0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86,
521  0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00,
522  0x04
523 };
528 static const uint8 au8TEncodingSHA1[] =
529 {
530  0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E,
531  0x03, 0x02, 0x1A, 0x05, 0x00, 0x04
532 };
537 static const uint8 au8TEncodingSHA2[] =
538 {
539  0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86,
540  0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
541  0x00, 0x04
542 };
547 sint8 m2m_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash,
548  uint16 u16HashLength, uint8 *pu8RsaSignature)
549 {
550  sint8 s8Ret = M2M_RSA_SIGN_FAIL;
551 
552  if((pu8N != NULL) && (pu8E != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL))
553  {
554  uint16 u16TLength, u16TEncodingLength;
555  uint8 *pu8T;
556  uint8 au8EM[512];
557 
558  /* Selection of correct T Encoding based on the hash size.
559  */
560  if(u16HashLength == MD5_DIGEST_SIZE)
561  {
562  pu8T = (uint8*)au8TEncodingMD5;
563  u16TEncodingLength = sizeof(au8TEncodingMD5);
564  }
565  else if(u16HashLength == SHA1_DIGEST_SIZE)
566  {
567  pu8T = (uint8*)au8TEncodingSHA1;
568  u16TEncodingLength = sizeof(au8TEncodingSHA1);
569  }
570  else
571  {
572  pu8T = (uint8*)au8TEncodingSHA2;
573  u16TEncodingLength = sizeof(au8TEncodingSHA2);
574  }
575  u16TLength = u16TEncodingLength + 1 + u16HashLength;
576 
577  /* If emLen < tLen + 11.
578  */
579  if(u16NSize >= (u16TLength + 11))
580  {
581  uint32 u32PSLength,u32Idx = 0;
582 
583  /*
584  RSA verification
585  */
586  BigInt_ModExp(pu8RsaSignature, u16NSize, pu8E, u16ESize, pu8N, u16NSize, au8EM, u16NSize);
587 
588  u32PSLength = u16NSize - u16TLength - 3;
589 
590  /*
591  The calculated EM must match the following pattern.
592  *======*======*======*======*======*
593  * 0x00 || 0x01 || PS || 0x00 || T *
594  *======*======*======*======*======*
595  Where PS is all 0xFF
596  T is defined based on the hash algorithm.
597  */
598  if((au8EM[0] == 0x00) && (au8EM[1] == 0x01))
599  {
600  for(u32Idx = 2; au8EM[u32Idx] == 0xFF; u32Idx ++);
601  if(u32Idx == (u32PSLength + 2))
602  {
603  if(au8EM[u32Idx ++] == 0x00)
604  {
605  if(!m2m_memcmp(&au8EM[u32Idx], pu8T, u16TEncodingLength))
606  {
607  u32Idx += u16TEncodingLength;
608  if(au8EM[u32Idx ++] == u16HashLength)
609  s8Ret = m2m_memcmp(&au8EM[u32Idx], pu8SignedMsgHash, u16HashLength);
610  }
611  }
612  }
613  }
614  }
615  }
616  return s8Ret;
617 }
618 
619 
620 sint8 m2m_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash,
621  uint16 u16HashLength, uint8 *pu8RsaSignature)
622 {
623  sint8 s8Ret = M2M_RSA_SIGN_FAIL;
624 
625  if((pu8N != NULL) && (pu8d != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL))
626  {
627  uint16 u16TLength, u16TEncodingLength;
628  uint8 *pu8T;
629  uint8 au8EM[512];
630 
631  /* Selection of correct T Encoding based on the hash size.
632  */
633  if(u16HashLength == MD5_DIGEST_SIZE)
634  {
635  pu8T = (uint8*)au8TEncodingMD5;
636  u16TEncodingLength = sizeof(au8TEncodingMD5);
637  }
638  else if(u16HashLength == SHA1_DIGEST_SIZE)
639  {
640  pu8T = (uint8*)au8TEncodingSHA1;
641  u16TEncodingLength = sizeof(au8TEncodingSHA1);
642  }
643  else
644  {
645  pu8T = (uint8*)au8TEncodingSHA2;
646  u16TEncodingLength = sizeof(au8TEncodingSHA2);
647  }
648  u16TLength = u16TEncodingLength + 1 + u16HashLength;
649 
650  /* If emLen < tLen + 11.
651  */
652  if(u16NSize >= (u16TLength + 11))
653  {
654  uint16 u16PSLength = 0;
655  uint16 u16Offset = 0;
656 
657  /*
658  The calculated EM must match the following pattern.
659  *======*======*======*======*======*
660  * 0x00 || 0x01 || PS || 0x00 || T *
661  *======*======*======*======*======*
662  Where PS is all 0xFF
663  T is defined based on the hash algorithm.
664  */
665  au8EM[u16Offset ++] = 0;
666  au8EM[u16Offset ++] = 1;
667  u16PSLength = u16NSize - u16TLength - 3;
668  m2m_memset(&au8EM[u16Offset], 0xFF, u16PSLength);
669  u16Offset += u16PSLength;
670  au8EM[u16Offset ++] = 0;
671  m2m_memcpy(&au8EM[u16Offset], pu8T, u16TEncodingLength);
672  u16Offset += u16TEncodingLength;
673  au8EM[u16Offset ++] = u16HashLength;
674  m2m_memcpy(&au8EM[u16Offset], pu8SignedMsgHash, u16HashLength);
675 
676  /*
677  RSA Signature Generation
678  */
679  BigInt_ModExp(au8EM, u16NSize, pu8d, u16dSize, pu8N, u16NSize, pu8RsaSignature, u16NSize);
680  s8Ret = M2M_RSA_SIGN_OK;
681  }
682  }
683  return s8Ret;
684 }
685 
686 #endif /* CONF_CRYPTO */
NMI_API void m2m_memcpy(uint8 *pDst, uint8 *pSrc, uint32 sz)
Copy specified number of bytes from source buffer to destination buffer.
Definition: nm_common.c:36
#define M2M_ERR_FAIL
Definition: nm_common.h:63
sint8 nm_read_block(uint32 u32Addr, uint8 *puBuf, uint32 u32Sz)
Definition: nmbus.c:195
signed char sint8
Range of values between -128 to 127.
Definition: nm_bsp.h:111
NMI_API sint8 m2m_memcmp(uint8 *pu8Buff1, uint8 *pu8Buff2, uint32 u32Size)
Compare specified number of data bytes in pu8Buff1 and pu8Buff2 and decide if they all match...
Definition: nm_common.c:116
sint8 nm_write_block(uint32 u32Addr, uint8 *puBuf, uint32 u32Sz)
Definition: nmbus.c:248
#define BYTE_0(word)
Definition: nm_common.h:129
#define BYTE_3(word)
Definition: nm_common.h:135
#define M2M_SUCCESS
Definition: nm_common.h:51
#define GET_UINT32(X, Y)
Definition: nmasic.c:44
#define NULL
Definition: nm_bsp.h:52
SHA256 context data.
unsigned short uint16
Range of values between 0 to 65535.
Definition: nm_bsp.h:96
#define BYTE_1(word)
Definition: nm_common.h:131
sint8 m2m_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt)
SHA256 hash initialization.
This module contains WINC3400 ASIC specific internal APIs.
WINC3400 Crypto API.
#define NBIT0
Definition: nm_common.h:114
#define M2M_SHA256_DIGEST_LEN
Definition: m2m_crypto.h:51
NMI_API void m2m_memset(uint8 *pBuf, uint8 val, uint32 sz)
Set specified number of data bytes in specified data buffer to specified value.
Definition: nm_common.c:58
#define BYTE_2(word)
Definition: nm_common.h:133
sint8 nm_write_reg(uint32 u32Addr, uint32 u32Val)
Definition: nmbus.c:155
#define NBIT31
Definition: nm_common.h:83
This module contains WINC3400 bus APIs implementation.
sint8 m2m_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Data, uint16 u16DataLength)
SHA256 hash update.
sint8 m2m_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash, uint16 u16HashLength, uint8 *pu8RsaSignature)
RSA Signature Verification.
unsigned long uint32
Range of values between 0 to 4294967295.
Definition: nm_bsp.h:103
unsigned char uint8
Range of values between 0 to 255.
Definition: nm_bsp.h:89
sint8 m2m_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Sha256Digest)
SHA256 hash finalization.
sint8 m2m_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash, uint16 u16HashLength, uint8 *pu8RsaSignature)
RSA Signature Generation.
uint32 nm_read_reg(uint32 u32Addr)
Definition: nmbus.c:104


inertial_sense_ros
Author(s):
autogenerated on Sun Feb 28 2021 03:17:57