NNN50 WIFI_API library

Dependents:   NNN50_CE_Test_UDP NNN50_linux_firmware NNN50_SoftAP_HelloWorld NNN50_BLEWIFISensor ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m2m_crypto.c Source File

m2m_crypto.c

Go to the documentation of this file.
00001 /**
00002  *
00003  * \file
00004  *
00005  * \brief WINC Crypto module.
00006  *
00007  * Copyright (c) 2016 Atmel Corporation. All rights reserved.
00008  *
00009  * \asf_license_start
00010  *
00011  * \page License
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. The name of Atmel may not be used to endorse or promote products derived
00024  *    from this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
00027  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00028  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00029  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
00030  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00034  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00035  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * \asf_license_stop
00039  *
00040  */
00041 
00042 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
00043 INCLUDES
00044 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
00045 
00046 #include "driver/include/m2m_crypto.h"
00047 #include "driver/source/nmbus.h"
00048 #include "driver/source/nmasic.h"
00049 
00050 #ifdef CONF_CRYPTO_HW
00051 
00052 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
00053 MACROS
00054 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
00055 
00056 /*======*======*======*======*======*=======*
00057 * WINC SHA256 HW Engine Register Definition * 
00058 *======*======*======*======*======*========*/
00059 
00060 #define SHA_BLOCK_SIZE                                          (64)
00061 
00062 #define SHARED_MEM_BASE                                         (0xd0000)
00063 
00064 
00065 #define SHA256_MEM_BASE                                         (0x180000UL)
00066 #define SHA256_ENGINE_ADDR                                      (0x180000ul)
00067 
00068 /* SHA256 Registers */
00069 #define SHA256_CTRL                                             (SHA256_MEM_BASE+0x00)
00070 #define SHA256_CTRL_START_CALC_MASK                             (NBIT0)
00071 #define SHA256_CTRL_START_CALC_SHIFT                            (0)
00072 #define SHA256_CTRL_PREPROCESS_MASK                             (NBIT1)
00073 #define SHA256_CTRL_PREPROCESS_SHIFT                            (1)
00074 #define SHA256_CTRL_HASH_HASH_MASK                              (NBIT2)
00075 #define SHA256_CTRL_HASH_HASH_SHIFT                             (2)
00076 #define SHA256_CTRL_INIT_SHA256_STATE_MASK                      (NBIT3)
00077 #define SHA256_CTRL_INIT_SHA256_STATE_SHIFT                     (3)
00078 #define SHA256_CTRL_WR_BACK_HASH_VALUE_MASK                     (NBIT4)
00079 #define SHA256_CTRL_WR_BACK_HASH_VALUE_SHIFT                    (4)
00080 #define SHA256_CTRL_FORCE_SHA256_QUIT_MASK                      (NBIT5)
00081 #define SHA256_CTRL_FORCE_SHA256_QUIT_SHIFT                     (5)
00082 
00083 #define SHA256_REGS_SHA256_CTRL_AHB_BYTE_REV_EN                 (NBIT6)
00084 #define SHA256_REGS_SHA256_CTRL_RESERVED                        (NBIT7)
00085 #define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO           (NBIT8+ NBIT9+ NBIT10)
00086 #define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_MASK      (NBIT2+ NBIT1+ NBIT0)
00087 #define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_SHIFT     (8)
00088 #define SHA256_REGS_SHA256_CTRL_RESERVED_11                     (NBIT11)
00089 #define SHA256_REGS_SHA256_CTRL_SHA1_CALC                       (NBIT12)
00090 #define SHA256_REGS_SHA256_CTRL_PBKDF2_SHA1_CALC                (NBIT13)
00091 
00092 
00093 #define SHA256_START_RD_ADDR                                    (SHA256_MEM_BASE+0x04UL)
00094 #define SHA256_DATA_LENGTH                                      (SHA256_MEM_BASE+0x08UL)
00095 #define SHA256_START_WR_ADDR                                    (SHA256_MEM_BASE+0x0cUL)
00096 #define SHA256_COND_CHK_CTRL                                    (SHA256_MEM_BASE+0x10)
00097 #define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_MASK             (NBIT1 | NBIT0)
00098 #define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_SHIFT            (0)
00099 #define SHA256_COND_CHK_CTRL_STEP_VAL_MASK                      (NBIT6 | NBIT5 | NBIT4 | NBIT3 | NBIT2)
00100 #define SHA256_COND_CHK_CTRL_STEP_VAL_SHIFT                     (2)
00101 #define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_MASK               (NBIT7)
00102 #define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_SHIFT              (7)
00103 
00104 #define SHA256_MOD_DATA_RANGE                                   (SHA256_MEM_BASE+0x14)
00105 #define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_MASK            (NBIT24-1)
00106 #define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_SHIFT           (0)
00107 #define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_MASK                 (NBIT24 | NBIT25| NBIT26)
00108 #define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_SHIFT                (24)
00109 
00110 
00111 #define SHA256_COND_CHK_STS_1                                   (SHA256_MEM_BASE+0x18)
00112 #define SHA256_COND_CHK_STS_2                                   (SHA256_MEM_BASE+0x1c)
00113 #define SHA256_DONE_INTR_ENABLE                                 (SHA256_MEM_BASE+0x20)
00114 #define SHA256_DONE_INTR_STS                                    (SHA256_MEM_BASE+0x24)
00115 #define SHA256_TARGET_HASH_H1                                   (SHA256_MEM_BASE+0x28)
00116 #define SHA256_TARGET_HASH_H2                                   (SHA256_MEM_BASE+0x2c)
00117 #define SHA256_TARGET_HASH_H3                                   (SHA256_MEM_BASE+0x30)
00118 #define SHA256_TARGET_HASH_H4                                   (SHA256_MEM_BASE+0x34)
00119 #define SHA256_TARGET_HASH_H5                                   (SHA256_MEM_BASE+0x38)
00120 #define SHA256_TARGET_HASH_H6                                   (SHA256_MEM_BASE+0x3c)
00121 #define SHA256_TARGET_HASH_H7                                   (SHA256_MEM_BASE+0x40)
00122 #define SHA256_TARGET_HASH_H8                                   (SHA256_MEM_BASE+0x44)
00123 
00124 /*======*======*======*======*======*=======*
00125 * WINC BIGINT HW Engine Register Definition *
00126 *======*======*======*======*======*========*/
00127 
00128 
00129 #define BIGINT_ENGINE_ADDR                          (0x180080ul)
00130 #define BIGINT_VERSION                              (BIGINT_ENGINE_ADDR + 0x00)
00131 
00132 #define BIGINT_MISC_CTRL                            (BIGINT_ENGINE_ADDR + 0x04)
00133 #define BIGINT_MISC_CTRL_CTL_START                  (NBIT0)
00134 #define BIGINT_MISC_CTRL_CTL_RESET                  (NBIT1)
00135 #define BIGINT_MISC_CTRL_CTL_MSW_FIRST              (NBIT2)
00136 #define BIGINT_MISC_CTRL_CTL_SWAP_BYTE_ORDER        (NBIT3)
00137 #define BIGINT_MISC_CTRL_CTL_FORCE_BARRETT          (NBIT4)
00138 #define BIGINT_MISC_CTRL_CTL_M_PRIME_VALID          (NBIT5)
00139 
00140 #define BIGINT_M_PRIME                              (BIGINT_ENGINE_ADDR + 0x08)
00141 
00142 #define BIGINT_STATUS                               (BIGINT_ENGINE_ADDR + 0x0C)
00143 #define BIGINT_STATUS_STS_DONE                      (NBIT0)
00144 
00145 #define BIGINT_CLK_COUNT                            (BIGINT_ENGINE_ADDR + 0x10)
00146 #define BIGINT_ADDR_X                               (BIGINT_ENGINE_ADDR + 0x14)
00147 #define BIGINT_ADDR_E                               (BIGINT_ENGINE_ADDR + 0x18)
00148 #define BIGINT_ADDR_M                               (BIGINT_ENGINE_ADDR + 0x1C)
00149 #define BIGINT_ADDR_R                               (BIGINT_ENGINE_ADDR + 0x20)
00150 #define BIGINT_LENGTH                               (BIGINT_ENGINE_ADDR + 0x24)
00151 
00152 #define BIGINT_IRQ_STS                              (BIGINT_ENGINE_ADDR + 0x28)
00153 #define BIGINT_IRQ_STS_DONE                         (NBIT0)
00154 #define BIGINT_IRQ_STS_CHOOSE_MONT                  (NBIT1)
00155 #define BIGINT_IRQ_STS_M_READ                       (NBIT2)
00156 #define BIGINT_IRQ_STS_X_READ                       (NBIT3)
00157 #define BIGINT_IRQ_STS_START                        (NBIT4)
00158 #define BIGINT_IRQ_STS_PRECOMP_FINISH               (NBIT5)
00159 
00160 #define BIGINT_IRQ_MASK                             (BIGINT_ENGINE_ADDR + 0x2C)
00161 #define BIGINT_IRQ_MASK_CTL_IRQ_MASK_START          (NBIT4)
00162 
00163 #define ENABLE_FLIPPING         1
00164 
00165 
00166 
00167 
00168 #define GET_UINT32(BUF,OFFSET)          (((uint32)((BUF)[OFFSET])) | ((uint32)(((BUF)[OFFSET + 1]) << 8))  | \
00169 ((uint32)(((BUF)[OFFSET + 2]) << 16)) | ((uint32)(((BUF)[OFFSET + 3]) << 24)))
00170 
00171 #define PUTU32(VAL32,BUF,OFFSET)    \
00172 do  \
00173 {   \
00174     (BUF)[OFFSET    ] = BYTE_3((VAL32));    \
00175     (BUF)[OFFSET +1 ] = BYTE_2((VAL32));    \
00176     (BUF)[OFFSET +2 ] = BYTE_1((VAL32));    \
00177     (BUF)[OFFSET +3 ] = BYTE_0((VAL32));    \
00178 }while(0)
00179 
00180 
00181 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
00182 DATA TYPES
00183 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
00184 
00185 /*!
00186 @struct \
00187     tstrHashContext
00188     
00189 @brief
00190 */
00191 typedef struct{
00192     uint32      au32HashState[M2M_SHA256_DIGEST_LEN/4];
00193     uint8       au8CurrentBlock[64];
00194     uint32      u32TotalLength;
00195     uint8       u8InitHashFlag;
00196 }tstrSHA256HashCtxt;
00197 
00198 
00199 
00200 /*======*======*======*======*======*=======*
00201 *           SHA256 IMPLEMENTATION           *
00202 *======*======*======*======*======*========*/
00203 
00204 sint8 m2m_crypto_sha256_hash_init(tstrM2mSha256Ctxt *pstrSha256Ctxt)
00205 {
00206     tstrSHA256HashCtxt  *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt;
00207     if(pstrSHA256 != NULL)
00208     {
00209         m2m_memset((uint8*)pstrSha256Ctxt, 0, sizeof(tstrM2mSha256Ctxt));
00210         pstrSHA256->u8InitHashFlag = 1;
00211     }
00212     return 0;
00213 }
00214 
00215 sint8 m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Data, uint16 u16DataLength)
00216 {
00217     sint8   s8Ret = M2M_ERR_FAIL;
00218     tstrSHA256HashCtxt  *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt;
00219     if(pstrSHA256 != NULL)
00220     {
00221         uint32  u32ReadAddr;
00222         uint32  u32WriteAddr    = SHARED_MEM_BASE;
00223         uint32  u32Addr         = u32WriteAddr;
00224         uint32  u32ResidualBytes;
00225         uint32  u32NBlocks;
00226         uint32  u32Offset;
00227         uint32  u32CurrentBlock = 0;
00228         uint8   u8IsDone        = 0;
00229 
00230         /* Get the remaining bytes from the previous update (if the length is not block aligned). */
00231         u32ResidualBytes = pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE;
00232 
00233         /* Update the total data length. */
00234         pstrSHA256->u32TotalLength += u16DataLength;
00235 
00236         if(u32ResidualBytes != 0)
00237         {
00238             if((u32ResidualBytes + u16DataLength) >= SHA_BLOCK_SIZE)
00239             {
00240                 u32Offset = SHA_BLOCK_SIZE - u32ResidualBytes;
00241                 m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u32Offset);
00242                 pu8Data         += u32Offset;
00243                 u16DataLength   -= u32Offset;
00244 
00245                 nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
00246                 u32Addr += SHA_BLOCK_SIZE;
00247                 u32CurrentBlock  = 1;
00248             }
00249             else
00250             {
00251                 m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u16DataLength);
00252                 u16DataLength = 0;
00253             }
00254         }
00255 
00256         /* Get the number of HASH BLOCKs and the residual bytes. */
00257         u32NBlocks          = u16DataLength / SHA_BLOCK_SIZE;
00258         u32ResidualBytes    = u16DataLength % SHA_BLOCK_SIZE;
00259 
00260         if(u32NBlocks != 0)
00261         {
00262             nm_write_block(u32Addr, pu8Data, (uint16)(u32NBlocks * SHA_BLOCK_SIZE));
00263             pu8Data += (u32NBlocks * SHA_BLOCK_SIZE);
00264         }
00265 
00266         u32NBlocks += u32CurrentBlock;
00267         if(u32NBlocks != 0)
00268         {
00269             uint32  u32RegVal = 0;
00270 
00271             nm_write_reg(SHA256_CTRL, u32RegVal);
00272             u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK;
00273             nm_write_reg(SHA256_CTRL, u32RegVal);
00274 
00275             if(pstrSHA256->u8InitHashFlag)
00276             {
00277                 pstrSHA256->u8InitHashFlag = 0;
00278                 u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK;
00279             }
00280 
00281             u32ReadAddr = u32WriteAddr + (u32NBlocks * SHA_BLOCK_SIZE);
00282             nm_write_reg(SHA256_DATA_LENGTH, (u32NBlocks * SHA_BLOCK_SIZE));
00283             nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr);
00284             nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr);
00285 
00286             u32RegVal |= SHA256_CTRL_START_CALC_MASK;
00287 
00288             u32RegVal &= ~(0x7 << 8);
00289             u32RegVal |= (2 << 8);
00290 
00291             nm_write_reg(SHA256_CTRL, u32RegVal);
00292 
00293             /* 5.   Wait for done_intr */
00294             while(!u8IsDone)
00295             {
00296                 u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS);
00297                 u8IsDone = u32RegVal & NBIT0;
00298             }
00299         }
00300         if(u32ResidualBytes != 0)
00301         {
00302             m2m_memcpy(pstrSHA256->au8CurrentBlock, pu8Data, u32ResidualBytes);
00303         }
00304         s8Ret = M2M_SUCCESS;
00305     }
00306     return s8Ret;
00307 }
00308 
00309 
00310 sint8 m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Sha256Digest)
00311 {
00312     sint8   s8Ret = M2M_ERR_FAIL;
00313     tstrSHA256HashCtxt  *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt;
00314     if(pstrSHA256 != NULL)
00315     {
00316         uint32  u32ReadAddr;
00317         uint32  u32WriteAddr    = SHARED_MEM_BASE;
00318         uint32  u32Addr         = u32WriteAddr;
00319         uint16  u16Offset;
00320         uint16  u16PaddingLength;
00321         uint16  u16NBlocks      = 1;
00322         uint32  u32RegVal       = 0;
00323         uint32  u32Idx,u32ByteIdx;
00324         uint32  au32Digest[M2M_SHA256_DIGEST_LEN / 4];
00325         uint8   u8IsDone        = 0;
00326 
00327         nm_write_reg(SHA256_CTRL,u32RegVal);
00328         u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK;
00329         nm_write_reg(SHA256_CTRL,u32RegVal);
00330 
00331         if(pstrSHA256->u8InitHashFlag)
00332         {
00333             pstrSHA256->u8InitHashFlag = 0;
00334             u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK;
00335         }
00336 
00337         /* Calculate the offset of the last data byte in the current block. */
00338         u16Offset = (uint16)(pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE);
00339 
00340         /* Add the padding byte 0x80. */
00341         pstrSHA256->au8CurrentBlock[u16Offset ++] = 0x80;
00342 
00343         /* Calculate the required padding to complete
00344         one Hash Block Size.
00345         */
00346         u16PaddingLength = SHA_BLOCK_SIZE - u16Offset;
00347         m2m_memset(&pstrSHA256->au8CurrentBlock[u16Offset], 0, u16PaddingLength);
00348 
00349         /* If the padding count is not enough to hold 64-bit representation of
00350         the total input message length, one padding block is required.
00351         */
00352         if(u16PaddingLength < 8)
00353         {
00354             nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
00355             u32Addr += SHA_BLOCK_SIZE;
00356             m2m_memset(pstrSHA256->au8CurrentBlock, 0, SHA_BLOCK_SIZE);
00357             u16NBlocks ++;
00358         }
00359 
00360         /* pack the length at the end of the padding block */
00361         PUTU32(pstrSHA256->u32TotalLength << 3, pstrSHA256->au8CurrentBlock, (SHA_BLOCK_SIZE - 4));
00362 
00363         u32ReadAddr = u32WriteAddr + (u16NBlocks * SHA_BLOCK_SIZE);
00364         nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
00365         nm_write_reg(SHA256_DATA_LENGTH, (u16NBlocks * SHA_BLOCK_SIZE));
00366         nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr);
00367         nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr);
00368 
00369         u32RegVal |= SHA256_CTRL_START_CALC_MASK;
00370         u32RegVal |= SHA256_CTRL_WR_BACK_HASH_VALUE_MASK;
00371         u32RegVal &= ~(0x7UL << 8);
00372         u32RegVal |= (0x2UL << 8);
00373 
00374         nm_write_reg(SHA256_CTRL,u32RegVal);
00375 
00376 
00377         /* 5.   Wait for done_intr */
00378         while(!u8IsDone)
00379         {
00380             u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS);
00381             u8IsDone = u32RegVal & NBIT0;
00382         }
00383         nm_read_block(u32ReadAddr, (uint8*)au32Digest, 32);
00384         
00385         /* Convert the output words to an array of bytes.
00386         */
00387         u32ByteIdx = 0;
00388         for(u32Idx = 0; u32Idx < (M2M_SHA256_DIGEST_LEN / 4); u32Idx ++)
00389         {
00390             pu8Sha256Digest[u32ByteIdx ++] = BYTE_3(au32Digest[u32Idx]);
00391             pu8Sha256Digest[u32ByteIdx ++] = BYTE_2(au32Digest[u32Idx]);
00392             pu8Sha256Digest[u32ByteIdx ++] = BYTE_1(au32Digest[u32Idx]);
00393             pu8Sha256Digest[u32ByteIdx ++] = BYTE_0(au32Digest[u32Idx]);
00394         }
00395         s8Ret = M2M_SUCCESS;
00396     }
00397     return s8Ret;
00398 }
00399 
00400 
00401 /*======*======*======*======*======*=======*
00402 *             RSA IMPLEMENTATION            *
00403 *======*======*======*======*======*========*/
00404 
00405 static void FlipBuffer(uint8 *pu8InBuffer, uint8 *pu8OutBuffer, uint16 u16BufferSize)
00406 {
00407     uint16  u16Idx;
00408     for(u16Idx = 0; u16Idx < u16BufferSize; u16Idx ++)
00409     {
00410 #if ENABLE_FLIPPING == 1
00411         pu8OutBuffer[u16Idx] = pu8InBuffer[u16BufferSize - u16Idx - 1];
00412 #else
00413         pu8OutBuffer[u16Idx] = pu8InBuffer[u16Idx];
00414 #endif
00415     }
00416 }
00417 
00418 void BigInt_ModExp
00419 (   
00420  uint8  *pu8X,  uint16  u16XSize,
00421  uint8  *pu8E,  uint16  u16ESize,
00422  uint8  *pu8M,  uint16  u16MSize,
00423  uint8  *pu8R,  uint16  u16RSize
00424  )
00425 {
00426     uint32  u32Reg;
00427     uint8   au8Tmp[780] = {0};
00428     uint32  u32XAddr    = SHARED_MEM_BASE;
00429     uint32  u32MAddr;
00430     uint32  u32EAddr;
00431     uint32  u32RAddr;
00432     uint8   u8EMswBits  = 32;
00433     uint32  u32Mprime   = 0x7F;
00434     uint16  u16XSizeWords,u16ESizeWords;
00435     uint32  u32Exponent;
00436 
00437     u16XSizeWords = (u16XSize + 3) / 4;
00438     u16ESizeWords = (u16ESize + 3) / 4;
00439     
00440     u32MAddr    = u32XAddr + (u16XSizeWords * 4);
00441     u32EAddr    = u32MAddr + (u16XSizeWords * 4);
00442     u32RAddr    = u32EAddr + (u16ESizeWords * 4);
00443 
00444     /* Reset the core.
00445     */
00446     u32Reg  = 0;
00447     u32Reg  |= BIGINT_MISC_CTRL_CTL_RESET;
00448     u32Reg  = nm_read_reg(BIGINT_MISC_CTRL);
00449     u32Reg  &= ~BIGINT_MISC_CTRL_CTL_RESET;
00450     u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
00451 
00452     nm_write_block(u32RAddr,au8Tmp, u16RSize);
00453 
00454     /* Write Input Operands to Chip Memory. 
00455     */
00456     /*------- X -------*/
00457     FlipBuffer(pu8X,au8Tmp,u16XSize);
00458     nm_write_block(u32XAddr,au8Tmp,u16XSizeWords * 4);
00459 
00460     /*------- E -------*/
00461     m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
00462     FlipBuffer(pu8E, au8Tmp, u16ESize);
00463     nm_write_block(u32EAddr, au8Tmp, u16ESizeWords * 4);
00464     u32Exponent = GET_UINT32(au8Tmp, (u16ESizeWords * 4) - 4);
00465     while((u32Exponent & NBIT31)== 0)
00466     {
00467         u32Exponent <<= 1;
00468         u8EMswBits --;
00469     }
00470 
00471     /*------- M -------*/
00472     m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
00473     FlipBuffer(pu8M, au8Tmp, u16XSize);
00474     nm_write_block(u32MAddr, au8Tmp, u16XSizeWords * 4);
00475 
00476     /* Program the addresses of the input operands. 
00477     */
00478     nm_write_reg(BIGINT_ADDR_X, u32XAddr);
00479     nm_write_reg(BIGINT_ADDR_E, u32EAddr);
00480     nm_write_reg(BIGINT_ADDR_M, u32MAddr);
00481     nm_write_reg(BIGINT_ADDR_R, u32RAddr);
00482 
00483     /* Mprime. 
00484     */
00485     nm_write_reg(BIGINT_M_PRIME,u32Mprime);
00486 
00487     /* Length. 
00488     */
00489     u32Reg  = (u16XSizeWords & 0xFF);
00490     u32Reg += ((u16ESizeWords & 0xFF) << 8);
00491     u32Reg += (u8EMswBits << 16);
00492     nm_write_reg(BIGINT_LENGTH,u32Reg);
00493 
00494     /* CTRL Register. 
00495     */
00496     u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
00497     u32Reg ^= BIGINT_MISC_CTRL_CTL_START;
00498     u32Reg |= BIGINT_MISC_CTRL_CTL_FORCE_BARRETT;
00499     //u32Reg |= BIGINT_MISC_CTRL_CTL_M_PRIME_VALID;
00500 #if ENABLE_FLIPPING == 0
00501     u32Reg |= BIGINT_MISC_CTRL_CTL_MSW_FIRST;
00502 #endif
00503     nm_write_reg(BIGINT_MISC_CTRL,u32Reg);
00504 
00505     /* Wait for computation to complete. */
00506     while(1)
00507     {
00508         u32Reg = nm_read_reg(BIGINT_IRQ_STS);
00509         if(u32Reg & BIGINT_IRQ_STS_DONE)
00510         {
00511             break;
00512         }
00513     }
00514     nm_write_reg(BIGINT_IRQ_STS,0);
00515     m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
00516     nm_read_block(u32RAddr, au8Tmp, u16RSize);
00517     FlipBuffer(au8Tmp, pu8R, u16RSize);
00518 }
00519 
00520 
00521 
00522 #define MD5_DIGEST_SIZE         (16)
00523 #define SHA1_DIGEST_SIZE        (20)
00524 
00525 static const uint8 au8TEncodingMD5 [] = 
00526 {
00527     0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86,
00528     0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00,
00529     0x04
00530 };
00531 /*!< Fixed part of the Encoding T for the MD5 hash algorithm.
00532 */
00533 
00534 
00535 static const uint8 au8TEncodingSHA1 [] = 
00536 {
00537     0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E,
00538     0x03, 0x02, 0x1A, 0x05, 0x00, 0x04 
00539 };
00540 /*!< Fixed part of the Encoding T for the SHA-1 hash algorithm.
00541 */
00542 
00543 
00544 static const uint8 au8TEncodingSHA2 [] = 
00545 {
00546     0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86,
00547     0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
00548     0x00, 0x04
00549 };
00550 /*!< Fixed part of the Encoding T for the SHA-2 hash algorithm.
00551 */
00552 
00553 
00554 sint8 m2m_crypto_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash, 
00555                           uint16 u16HashLength, uint8 *pu8RsaSignature)
00556 {
00557     sint8       s8Ret = M2M_RSA_SIGN_FAIL;
00558 
00559     if((pu8N != NULL) && (pu8E != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL))
00560     {
00561         uint16  u16TLength, u16TEncodingLength;
00562         uint8   *pu8T;
00563         uint8   au8EM[512];
00564 
00565         /* Selection of correct T Encoding based on the hash size.
00566         */
00567         if(u16HashLength == MD5_DIGEST_SIZE)
00568         {
00569             pu8T                = (uint8*)au8TEncodingMD5;
00570             u16TEncodingLength  = sizeof(au8TEncodingMD5 );
00571         }
00572         else if(u16HashLength == SHA1_DIGEST_SIZE)
00573         {
00574             pu8T                = (uint8*)au8TEncodingSHA1;
00575             u16TEncodingLength  = sizeof(au8TEncodingSHA1 );
00576         }
00577         else 
00578         {
00579             pu8T                = (uint8*)au8TEncodingSHA2;
00580             u16TEncodingLength  = sizeof(au8TEncodingSHA2 );
00581         }
00582         u16TLength = u16TEncodingLength + 1 + u16HashLength;
00583                     
00584         /* If emLen < tLen + 11.
00585         */
00586         if(u16NSize >= (u16TLength + 11))
00587         {
00588             uint32  u32PSLength,u32Idx = 0;
00589     
00590             /*
00591             RSA verification
00592             */
00593             BigInt_ModExp(pu8RsaSignature, u16NSize, pu8E, u16ESize, pu8N, u16NSize, au8EM, u16NSize);
00594 
00595             u32PSLength = u16NSize - u16TLength - 3;
00596 
00597             /* 
00598             The calculated EM must match the following pattern.
00599             *======*======*======*======*======*
00600             * 0x00 || 0x01 || PS || 0x00 || T  *    
00601             *======*======*======*======*======*
00602             Where PS is all 0xFF 
00603             T is defined based on the hash algorithm.
00604             */
00605             if((au8EM[0] == 0x00) && (au8EM[1] == 0x01))
00606             {
00607                 for(u32Idx = 2; au8EM[u32Idx] == 0xFF; u32Idx ++);
00608                 if(u32Idx == (u32PSLength + 2))
00609                 {
00610                     if(au8EM[u32Idx ++] == 0x00)
00611                     {
00612                         if(!m2m_memcmp(&au8EM[u32Idx], pu8T, u16TEncodingLength))
00613                         {
00614                             u32Idx += u16TEncodingLength;
00615                             if(au8EM[u32Idx ++] == u16HashLength)
00616                                 s8Ret = m2m_memcmp(&au8EM[u32Idx], pu8SignedMsgHash, u16HashLength);
00617                         }
00618                     }
00619                 }
00620             }
00621         }
00622     }
00623     return s8Ret;
00624 }
00625 
00626 
00627 sint8 m2m_crypto_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash, 
00628                        uint16 u16HashLength, uint8 *pu8RsaSignature)
00629 {
00630     sint8       s8Ret = M2M_RSA_SIGN_FAIL;
00631 
00632     if((pu8N != NULL) && (pu8d != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL))
00633     {
00634         uint16  u16TLength, u16TEncodingLength;
00635         uint8   *pu8T;
00636         uint8   au8EM[512];
00637 
00638         /* Selection of correct T Encoding based on the hash size.
00639         */
00640         if(u16HashLength == MD5_DIGEST_SIZE)
00641         {
00642             pu8T                = (uint8*)au8TEncodingMD5;
00643             u16TEncodingLength  = sizeof(au8TEncodingMD5 );
00644         }
00645         else if(u16HashLength == SHA1_DIGEST_SIZE)
00646         {
00647             pu8T                = (uint8*)au8TEncodingSHA1;
00648             u16TEncodingLength  = sizeof(au8TEncodingSHA1 );
00649         }
00650         else 
00651         {
00652             pu8T                = (uint8*)au8TEncodingSHA2;
00653             u16TEncodingLength  = sizeof(au8TEncodingSHA2 );
00654         }
00655         u16TLength = u16TEncodingLength + 1 + u16HashLength;
00656                     
00657         /* If emLen < tLen + 11.
00658         */
00659         if(u16NSize >= (u16TLength + 11))
00660         {
00661             uint16  u16PSLength = 0;
00662             uint16  u16Offset   = 0;    
00663 
00664             /* 
00665             The calculated EM must match the following pattern.
00666             *======*======*======*======*======*
00667             * 0x00 || 0x01 || PS || 0x00 || T  *    
00668             *======*======*======*======*======*
00669             Where PS is all 0xFF 
00670             T is defined based on the hash algorithm.
00671             */
00672             au8EM[u16Offset ++] = 0;
00673             au8EM[u16Offset ++] = 1;
00674             u16PSLength = u16NSize - u16TLength - 3;
00675             m2m_memset(&au8EM[u16Offset], 0xFF, u16PSLength);
00676             u16Offset += u16PSLength;
00677             au8EM[u16Offset ++] = 0;
00678             m2m_memcpy(&au8EM[u16Offset], pu8T, u16TEncodingLength);
00679             u16Offset += u16TEncodingLength;
00680             au8EM[u16Offset ++] = u16HashLength;
00681             m2m_memcpy(&au8EM[u16Offset], pu8SignedMsgHash, u16HashLength);
00682             
00683             /*
00684             RSA Signature Generation
00685             */
00686             BigInt_ModExp(au8EM, u16NSize, pu8d, u16dSize, pu8N, u16NSize, pu8RsaSignature, u16NSize);
00687             s8Ret = M2M_RSA_SIGN_OK;
00688         }
00689     }
00690     return s8Ret;
00691 }
00692 
00693 #endif /* CONF_CRYPTO */
00694 
00695 #ifdef CONF_CRYPTO_SOFT
00696 
00697 typedef struct {
00698     tpfAppCryproCb pfAppCryptoCb;
00699     uint8 * pu8Digest;
00700     uint8 * pu8Rsa;
00701     uint8 u8CryptoBusy;
00702 }tstrCryptoCtxt;
00703 
00704 typedef struct {
00705     uint8 au8N[M2M_MAX_RSA_LEN];
00706     uint8 au8E[M2M_MAX_RSA_LEN];
00707     uint8 au8Hash[M2M_SHA256_DIGEST_LEN];
00708     uint16 u16Nsz;
00709     uint16 u16Esz;
00710     uint16 u16Hsz;
00711     uint8 _pad16_[2];
00712 }tstrRsaPayload;
00713 
00714 static tstrCryptoCtxt gstrCryptoCtxt;
00715 
00716 
00717 /**
00718 *   @fn         m2m_crypto_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
00719 *   @brief      WiFi call back function
00720 *   @param [in] u8OpCode
00721 *                   HIF Opcode type.
00722 *   @param [in] u16DataSize
00723 *                   HIF data length.
00724 *   @param [in] u32Addr
00725 *                   HIF address.
00726 *   @author
00727 *   @date
00728 *   @version    1.0
00729 */
00730 static void m2m_crypto_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
00731 {
00732     sint8 ret = M2M_SUCCESS;
00733     gstrCryptoCtxt.u8CryptoBusy = 0;
00734     if(u8OpCode == M2M_CRYPTO_RESP_SHA256_INIT)
00735     {
00736         tstrM2mSha256Ctxt strCtxt;  
00737         if (hif_receive(u32Addr, (uint8*) &strCtxt,sizeof(tstrM2mSha256Ctxt), 0) == M2M_SUCCESS)
00738         {   
00739             tstrCyptoResp strResp;  
00740             if(hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), (uint8*) &strResp,sizeof(tstrCyptoResp), 1) == M2M_SUCCESS)
00741             {
00742                 if (gstrCryptoCtxt.pfAppCryptoCb)
00743                     gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,&strCtxt);
00744             }
00745         }
00746     }
00747     else if(u8OpCode == M2M_CRYPTO_RESP_SHA256_UPDATE)
00748     {
00749         tstrM2mSha256Ctxt strCtxt;
00750         if (hif_receive(u32Addr, (uint8*) &strCtxt,sizeof(tstrM2mSha256Ctxt), 0) == M2M_SUCCESS)
00751         {
00752             tstrCyptoResp strResp;
00753             if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), (uint8*) &strResp,sizeof(tstrCyptoResp), 1) == M2M_SUCCESS)
00754             {
00755                 if (gstrCryptoCtxt.pfAppCryptoCb)
00756                     gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,&strCtxt);
00757             }
00758         }
00759 
00760     }
00761     else if(u8OpCode == M2M_CRYPTO_RESP_SHA256_FINSIH)
00762     {
00763         tstrCyptoResp strResp;
00764         if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), (uint8*) &strResp,sizeof(tstrCyptoResp), 0) == M2M_SUCCESS)
00765         {
00766             if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt) + sizeof(tstrCyptoResp), (uint8*)gstrCryptoCtxt.pu8Digest,M2M_SHA256_DIGEST_LEN, 1) == M2M_SUCCESS)
00767             {
00768                 if (gstrCryptoCtxt.pfAppCryptoCb)
00769                     gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,gstrCryptoCtxt.pu8Digest);
00770                 
00771             }
00772         }
00773     }
00774     else if(u8OpCode == M2M_CRYPTO_RESP_RSA_SIGN_GEN)
00775     {
00776         tstrCyptoResp strResp;
00777         if (hif_receive(u32Addr + sizeof(tstrRsaPayload), (uint8*)&strResp,sizeof(tstrCyptoResp), 0) == M2M_SUCCESS)
00778         {
00779             if (hif_receive(u32Addr + sizeof(tstrRsaPayload) + sizeof(tstrCyptoResp), (uint8*)gstrCryptoCtxt.pu8Rsa,M2M_MAX_RSA_LEN, 0) == M2M_SUCCESS)
00780             {
00781                 if (gstrCryptoCtxt.pfAppCryptoCb)
00782                     gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,gstrCryptoCtxt.pu8Rsa);
00783             }
00784         }
00785     }
00786     else if(u8OpCode == M2M_CRYPTO_RESP_RSA_SIGN_VERIFY)
00787     {
00788         tstrCyptoResp strResp;
00789         if (hif_receive(u32Addr + sizeof(tstrRsaPayload), (uint8*)&strResp,sizeof(tstrCyptoResp), 1) == M2M_SUCCESS)
00790         {
00791             if (gstrCryptoCtxt.pfAppCryptoCb)
00792                 gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,NULL);
00793         }
00794     }
00795     else 
00796     {
00797         M2M_ERR("u8Code %d ??\n",u8OpCode);
00798     }
00799 
00800 }
00801 /*!
00802 @fn \
00803     sint8 m2m_crypto_init();
00804     
00805 @brief  crypto initialization
00806 
00807 @param[in]  pfAppCryproCb
00808 
00809 */
00810 sint8 m2m_crypto_init(tpfAppCryproCb pfAppCryproCb)
00811 {
00812     sint8 ret = M2M_ERR_FAIL;
00813     m2m_memset((uint8*)&gstrCryptoCtxt,0,sizeof(tstrCryptoCtxt));
00814     if(pfAppCryproCb != NULL)
00815     {
00816         gstrCryptoCtxt.pfAppCryptoCb = pfAppCryproCb;
00817         ret = hif_register_cb(M2M_REQ_GROUP_CRYPTO,m2m_crypto_cb);
00818     }
00819     return ret;
00820 }
00821 /*!
00822 @fn \
00823     sint8 m2m_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt);
00824     
00825 @brief  SHA256 hash initialization
00826 
00827 @param[in]  psha256Ctxt
00828                 Pointer to a sha256 context allocated by the caller.
00829 */
00830 sint8 m2m_crypto_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt)
00831 {
00832     sint8  ret = M2M_ERR_FAIL;
00833     if((psha256Ctxt != NULL)&&(!gstrCryptoCtxt.u8CryptoBusy))
00834     {
00835         ret = hif_send(M2M_REQ_GROUP_CRYPTO,M2M_CRYPTO_REQ_SHA256_INIT|M2M_REQ_DATA_PKT,(uint8*)psha256Ctxt,sizeof(tstrM2mSha256Ctxt),NULL,0,0);
00836     }
00837     return ret;
00838 }
00839 
00840 
00841 /*!
00842 @fn \
00843     sint8 m2m_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Data, uint16 u16DataLength);
00844     
00845 @brief  SHA256 hash update
00846 
00847 @param [in] psha256Ctxt
00848                 Pointer to the sha256 context.
00849                 
00850 @param [in] pu8Data
00851                 Buffer holding the data submitted to the hash.
00852                 
00853 @param [in] u16DataLength
00854                 Size of the data bufefr in bytes.
00855 */
00856 sint8 m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Data, uint16 u16DataLength)
00857 {
00858     sint8  ret = M2M_ERR_FAIL;
00859     if((!gstrCryptoCtxt.u8CryptoBusy) && (psha256Ctxt != NULL) && (pu8Data != NULL) && (u16DataLength < M2M_SHA256_MAX_DATA))
00860     {
00861         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));
00862     }
00863     return ret;
00864     
00865 }
00866 
00867 
00868 /*!
00869 @fn \
00870     sint8 m2m_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Sha256Digest);
00871     
00872 @brief  SHA256 hash finalization
00873 
00874 @param[in]  psha256Ctxt
00875                 Pointer to a sha256 context allocated by the caller.
00876                 
00877 @param [in] pu8Sha256Digest
00878                 Buffer allocated by the caller which will hold the resultant SHA256 Digest. It must be allocated no less than M2M_SHA256_DIGEST_LEN.
00879 */
00880 sint8 m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Sha256Digest)
00881 {
00882     sint8  ret = M2M_ERR_FAIL;
00883     if((!gstrCryptoCtxt.u8CryptoBusy) && (psha256Ctxt != NULL) && (pu8Sha256Digest != NULL))
00884     {
00885         gstrCryptoCtxt.pu8Digest = pu8Sha256Digest;
00886         ret = hif_send(M2M_REQ_GROUP_CRYPTO,M2M_CRYPTO_REQ_SHA256_FINSIH|M2M_REQ_DATA_PKT,(uint8*)psha256Ctxt,sizeof(tstrM2mSha256Ctxt),NULL,0,0);
00887     }
00888     return ret;
00889 }
00890 
00891 
00892 
00893 
00894 /*!
00895 @fn \
00896     sint8 m2m_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash, \
00897         uint16 u16HashLength, uint8 *pu8RsaSignature);
00898     
00899 @brief  RSA Signature Verification
00900 
00901     The function shall request the RSA Signature verification from the WINC Firmware for the given message. The signed message shall be 
00902     compressed to the corresponding hash algorithm before calling this function.
00903     The hash type is identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256.
00904 
00905 @param[in]  pu8N
00906                 RSA Key modulus n.
00907                 
00908 @param[in]  u16NSize
00909                 Size of the RSA modulus n in bytes.
00910                 
00911 @param[in]  pu8E
00912                 RSA public exponent.
00913                 
00914 @param[in]  u16ESize
00915                 Size of the RSA public exponent in bytes.
00916 
00917 @param[in]  pu8SignedMsgHash
00918                 The hash digest of the signed message.
00919                 
00920 @param[in]  u16HashLength
00921                 The length of the hash digest.
00922                 
00923 @param[out] pu8RsaSignature
00924                 Signature value to be verified.
00925 */
00926 
00927 
00928 sint8 m2m_crypto_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash, 
00929                           uint16 u16HashLength, uint8 *pu8RsaSignature)
00930 {
00931     sint8 ret = M2M_ERR_FAIL;
00932     if((!gstrCryptoCtxt.u8CryptoBusy) && (pu8N != NULL) && (pu8E != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL) 
00933     && (u16NSize != 0) && (u16ESize != 0) && (u16HashLength != 0) && (pu8RsaSignature != NULL) )
00934     
00935     {
00936         tstrRsaPayload strRsa = {0};
00937         
00938         m2m_memcpy(strRsa.au8N,pu8N,u16NSize);
00939         m2m_memcpy(strRsa.au8E,pu8E,u16ESize);
00940         m2m_memcpy(strRsa.au8Hash,pu8SignedMsgHash,u16HashLength);
00941         
00942         strRsa.u16Esz = u16ESize;
00943         strRsa.u16Hsz = u16HashLength;
00944         strRsa.u16Nsz = u16NSize;
00945         
00946         ret = hif_send(M2M_REQ_GROUP_CRYPTO,M2M_CRYPTO_REQ_RSA_SIGN_VERIFY|M2M_REQ_DATA_PKT,(uint8*)&strRsa,sizeof(tstrRsaPayload),NULL,0,0);
00947         
00948     }
00949     return ret;
00950 }
00951 
00952 
00953 /*!
00954 @fn \
00955     sint8 m2m_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash, \
00956         uint16 u16HashLength, uint8 *pu8RsaSignature);
00957     
00958 @brief  RSA Signature Generation
00959 
00960     The function shall request the RSA Signature generation from the WINC Firmware for the given message. The signed message shall be 
00961     compressed to the corresponding hash algorithm before calling this function.
00962     The hash type is identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256.
00963 
00964 @param[in]  pu8N
00965                 RSA Key modulus n.
00966                 
00967 @param[in]  u16NSize
00968                 Size of the RSA modulus n in bytes.
00969                 
00970 @param[in]  pu8d
00971                 RSA private exponent.
00972                 
00973 @param[in]  u16dSize
00974                 Size of the RSA private exponent in bytes.
00975 
00976 @param[in]  pu8SignedMsgHash
00977                 The hash digest of the signed message.
00978                 
00979 @param[in]  u16HashLength
00980                 The length of the hash digest.
00981                 
00982 @param[out] pu8RsaSignature
00983                 Pointer to a user buffer allocated by teh caller shall hold the generated signature.
00984 */
00985 sint8 m2m_crypto_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash, 
00986                        uint16 u16HashLength, uint8 *pu8RsaSignature)
00987 {
00988     sint8 ret = M2M_ERR_FAIL;
00989     if((!gstrCryptoCtxt.u8CryptoBusy) && (pu8N != NULL) && (pu8d != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL)
00990     && (u16NSize != 0) && (u16dSize != 0) && (u16HashLength != 0) && (pu8RsaSignature != NULL))
00991     
00992     {
00993         tstrRsaPayload strRsa = {0};
00994         
00995         m2m_memcpy(strRsa.au8N,pu8N,u16NSize);
00996         m2m_memcpy(strRsa.au8E,pu8d,u16dSize);
00997         m2m_memcpy(strRsa.au8Hash,pu8SignedMsgHash,u16HashLength);
00998         
00999         strRsa.u16Esz = u16dSize;
01000         strRsa.u16Hsz = u16HashLength;
01001         strRsa.u16Nsz = u16NSize;
01002         
01003         gstrCryptoCtxt.pu8Rsa = pu8RsaSignature;
01004         ret = hif_send(M2M_REQ_GROUP_CRYPTO,M2M_CRYPTO_REQ_RSA_SIGN_GEN|M2M_REQ_DATA_PKT,(uint8*)&strRsa,sizeof(tstrRsaPayload),NULL,0,0);
01005         
01006     }
01007     return ret;            
01008 }
01009 
01010 #endif
01011