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