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