mirror of https://github.com/FOME-Tech/fome-fw.git
1003 lines
30 KiB
C++
Executable File
1003 lines
30 KiB
C++
Executable File
/**
|
|
*
|
|
* \file
|
|
*
|
|
* \brief WINC Crypto module.
|
|
*
|
|
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
|
|
*
|
|
* \asf_license_start
|
|
*
|
|
* \page License
|
|
*
|
|
* Subject to your compliance with these terms, you may use Microchip
|
|
* software and any derivatives exclusively with Microchip products.
|
|
* It is your responsibility to comply with third party license terms applicable
|
|
* to your use of third party software (including open source software) that
|
|
* may accompany Microchip software.
|
|
*
|
|
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
|
|
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
|
|
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
|
|
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
|
|
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
|
|
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
|
|
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
|
|
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
|
|
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
|
|
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
|
|
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
|
|
*
|
|
* \asf_license_stop
|
|
*
|
|
*/
|
|
|
|
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
|
INCLUDES
|
|
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
|
|
|
#include "driver/include/m2m_crypto.h"
|
|
#include "driver/source/nmbus.h"
|
|
#include "driver/source/nmasic.h"
|
|
|
|
#ifdef CONF_CRYPTO_HW
|
|
|
|
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
|
MACROS
|
|
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
|
|
|
/*======*======*======*======*======*=======*
|
|
* WINC SHA256 HW Engine Register Definition *
|
|
*======*======*======*======*======*========*/
|
|
|
|
#define SHA_BLOCK_SIZE (64)
|
|
|
|
#define SHARED_MEM_BASE (0xd0000)
|
|
|
|
|
|
#define SHA256_MEM_BASE (0x180000UL)
|
|
#define SHA256_ENGINE_ADDR (0x180000ul)
|
|
|
|
/* SHA256 Registers */
|
|
#define SHA256_CTRL (SHA256_MEM_BASE+0x00)
|
|
#define SHA256_CTRL_START_CALC_MASK (NBIT0)
|
|
#define SHA256_CTRL_START_CALC_SHIFT (0)
|
|
#define SHA256_CTRL_PREPROCESS_MASK (NBIT1)
|
|
#define SHA256_CTRL_PREPROCESS_SHIFT (1)
|
|
#define SHA256_CTRL_HASH_HASH_MASK (NBIT2)
|
|
#define SHA256_CTRL_HASH_HASH_SHIFT (2)
|
|
#define SHA256_CTRL_INIT_SHA256_STATE_MASK (NBIT3)
|
|
#define SHA256_CTRL_INIT_SHA256_STATE_SHIFT (3)
|
|
#define SHA256_CTRL_WR_BACK_HASH_VALUE_MASK (NBIT4)
|
|
#define SHA256_CTRL_WR_BACK_HASH_VALUE_SHIFT (4)
|
|
#define SHA256_CTRL_FORCE_SHA256_QUIT_MASK (NBIT5)
|
|
#define SHA256_CTRL_FORCE_SHA256_QUIT_SHIFT (5)
|
|
|
|
#define SHA256_REGS_SHA256_CTRL_AHB_BYTE_REV_EN (NBIT6)
|
|
#define SHA256_REGS_SHA256_CTRL_RESERVED (NBIT7)
|
|
#define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO (NBIT8+ NBIT9+ NBIT10)
|
|
#define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_MASK (NBIT2+ NBIT1+ NBIT0)
|
|
#define SHA256_REGS_SHA256_CTRL_CORE_TO_AHB_CLK_RATIO_SHIFT (8)
|
|
#define SHA256_REGS_SHA256_CTRL_RESERVED_11 (NBIT11)
|
|
#define SHA256_REGS_SHA256_CTRL_SHA1_CALC (NBIT12)
|
|
#define SHA256_REGS_SHA256_CTRL_PBKDF2_SHA1_CALC (NBIT13)
|
|
|
|
|
|
#define SHA256_START_RD_ADDR (SHA256_MEM_BASE+0x04UL)
|
|
#define SHA256_DATA_LENGTH (SHA256_MEM_BASE+0x08UL)
|
|
#define SHA256_START_WR_ADDR (SHA256_MEM_BASE+0x0cUL)
|
|
#define SHA256_COND_CHK_CTRL (SHA256_MEM_BASE+0x10)
|
|
#define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_MASK (NBIT1 | NBIT0)
|
|
#define SHA256_COND_CHK_CTRL_HASH_VAL_COND_CHK_SHIFT (0)
|
|
#define SHA256_COND_CHK_CTRL_STEP_VAL_MASK (NBIT6 | NBIT5 | NBIT4 | NBIT3 | NBIT2)
|
|
#define SHA256_COND_CHK_CTRL_STEP_VAL_SHIFT (2)
|
|
#define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_MASK (NBIT7)
|
|
#define SHA256_COND_CHK_CTRL_COND_CHK_RESULT_SHIFT (7)
|
|
|
|
#define SHA256_MOD_DATA_RANGE (SHA256_MEM_BASE+0x14)
|
|
#define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_MASK (NBIT24-1)
|
|
#define SHA256_MOD_DATA_RANGE_ST_BYTE_2_ADD_STP_SHIFT (0)
|
|
#define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_MASK (NBIT24 | NBIT25| NBIT26)
|
|
#define SHA256_MOD_DATA_RANGE_MOD_DATA_LEN_SHIFT (24)
|
|
|
|
|
|
#define SHA256_COND_CHK_STS_1 (SHA256_MEM_BASE+0x18)
|
|
#define SHA256_COND_CHK_STS_2 (SHA256_MEM_BASE+0x1c)
|
|
#define SHA256_DONE_INTR_ENABLE (SHA256_MEM_BASE+0x20)
|
|
#define SHA256_DONE_INTR_STS (SHA256_MEM_BASE+0x24)
|
|
#define SHA256_TARGET_HASH_H1 (SHA256_MEM_BASE+0x28)
|
|
#define SHA256_TARGET_HASH_H2 (SHA256_MEM_BASE+0x2c)
|
|
#define SHA256_TARGET_HASH_H3 (SHA256_MEM_BASE+0x30)
|
|
#define SHA256_TARGET_HASH_H4 (SHA256_MEM_BASE+0x34)
|
|
#define SHA256_TARGET_HASH_H5 (SHA256_MEM_BASE+0x38)
|
|
#define SHA256_TARGET_HASH_H6 (SHA256_MEM_BASE+0x3c)
|
|
#define SHA256_TARGET_HASH_H7 (SHA256_MEM_BASE+0x40)
|
|
#define SHA256_TARGET_HASH_H8 (SHA256_MEM_BASE+0x44)
|
|
|
|
/*======*======*======*======*======*=======*
|
|
* WINC BIGINT HW Engine Register Definition *
|
|
*======*======*======*======*======*========*/
|
|
|
|
|
|
#define BIGINT_ENGINE_ADDR (0x180080ul)
|
|
#define BIGINT_VERSION (BIGINT_ENGINE_ADDR + 0x00)
|
|
|
|
#define BIGINT_MISC_CTRL (BIGINT_ENGINE_ADDR + 0x04)
|
|
#define BIGINT_MISC_CTRL_CTL_START (NBIT0)
|
|
#define BIGINT_MISC_CTRL_CTL_RESET (NBIT1)
|
|
#define BIGINT_MISC_CTRL_CTL_MSW_FIRST (NBIT2)
|
|
#define BIGINT_MISC_CTRL_CTL_SWAP_BYTE_ORDER (NBIT3)
|
|
#define BIGINT_MISC_CTRL_CTL_FORCE_BARRETT (NBIT4)
|
|
#define BIGINT_MISC_CTRL_CTL_M_PRIME_VALID (NBIT5)
|
|
|
|
#define BIGINT_M_PRIME (BIGINT_ENGINE_ADDR + 0x08)
|
|
|
|
#define BIGINT_STATUS (BIGINT_ENGINE_ADDR + 0x0C)
|
|
#define BIGINT_STATUS_STS_DONE (NBIT0)
|
|
|
|
#define BIGINT_CLK_COUNT (BIGINT_ENGINE_ADDR + 0x10)
|
|
#define BIGINT_ADDR_X (BIGINT_ENGINE_ADDR + 0x14)
|
|
#define BIGINT_ADDR_E (BIGINT_ENGINE_ADDR + 0x18)
|
|
#define BIGINT_ADDR_M (BIGINT_ENGINE_ADDR + 0x1C)
|
|
#define BIGINT_ADDR_R (BIGINT_ENGINE_ADDR + 0x20)
|
|
#define BIGINT_LENGTH (BIGINT_ENGINE_ADDR + 0x24)
|
|
|
|
#define BIGINT_IRQ_STS (BIGINT_ENGINE_ADDR + 0x28)
|
|
#define BIGINT_IRQ_STS_DONE (NBIT0)
|
|
#define BIGINT_IRQ_STS_CHOOSE_MONT (NBIT1)
|
|
#define BIGINT_IRQ_STS_M_READ (NBIT2)
|
|
#define BIGINT_IRQ_STS_X_READ (NBIT3)
|
|
#define BIGINT_IRQ_STS_START (NBIT4)
|
|
#define BIGINT_IRQ_STS_PRECOMP_FINISH (NBIT5)
|
|
|
|
#define BIGINT_IRQ_MASK (BIGINT_ENGINE_ADDR + 0x2C)
|
|
#define BIGINT_IRQ_MASK_CTL_IRQ_MASK_START (NBIT4)
|
|
|
|
#define ENABLE_FLIPPING 1
|
|
|
|
|
|
|
|
|
|
#define GET_UINT32(BUF,OFFSET) (((uint32)((BUF)[OFFSET])) | ((uint32)(((BUF)[OFFSET + 1]) << 8)) | \
|
|
((uint32)(((BUF)[OFFSET + 2]) << 16)) | ((uint32)(((BUF)[OFFSET + 3]) << 24)))
|
|
|
|
#define PUTU32(VAL32,BUF,OFFSET) \
|
|
do \
|
|
{ \
|
|
(BUF)[OFFSET ] = BYTE_3((VAL32)); \
|
|
(BUF)[OFFSET +1 ] = BYTE_2((VAL32)); \
|
|
(BUF)[OFFSET +2 ] = BYTE_1((VAL32)); \
|
|
(BUF)[OFFSET +3 ] = BYTE_0((VAL32)); \
|
|
}while(0)
|
|
|
|
|
|
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
|
DATA TYPES
|
|
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
|
|
|
/*!
|
|
@struct \
|
|
tstrHashContext
|
|
|
|
@brief
|
|
*/
|
|
typedef struct{
|
|
uint32 au32HashState[M2M_SHA256_DIGEST_LEN/4];
|
|
uint8 au8CurrentBlock[64];
|
|
uint32 u32TotalLength;
|
|
uint8 u8InitHashFlag;
|
|
}tstrSHA256HashCtxt;
|
|
|
|
|
|
|
|
/*======*======*======*======*======*=======*
|
|
* SHA256 IMPLEMENTATION *
|
|
*======*======*======*======*======*========*/
|
|
|
|
sint8 m2m_crypto_sha256_hash_init(tstrM2mSha256Ctxt *pstrSha256Ctxt)
|
|
{
|
|
tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt;
|
|
if(pstrSHA256 != NULL)
|
|
{
|
|
m2m_memset((uint8*)pstrSha256Ctxt, 0, sizeof(tstrM2mSha256Ctxt));
|
|
pstrSHA256->u8InitHashFlag = 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
sint8 m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Data, uint16 u16DataLength)
|
|
{
|
|
sint8 s8Ret = M2M_ERR_FAIL;
|
|
tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt;
|
|
if(pstrSHA256 != NULL)
|
|
{
|
|
uint32 u32ReadAddr;
|
|
uint32 u32WriteAddr = SHARED_MEM_BASE;
|
|
uint32 u32Addr = u32WriteAddr;
|
|
uint32 u32ResidualBytes;
|
|
uint32 u32NBlocks;
|
|
uint32 u32Offset;
|
|
uint32 u32CurrentBlock = 0;
|
|
uint8 u8IsDone = 0;
|
|
|
|
/* Get the remaining bytes from the previous update (if the length is not block aligned). */
|
|
u32ResidualBytes = pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE;
|
|
|
|
/* Update the total data length. */
|
|
pstrSHA256->u32TotalLength += u16DataLength;
|
|
|
|
if(u32ResidualBytes != 0)
|
|
{
|
|
if((u32ResidualBytes + u16DataLength) >= SHA_BLOCK_SIZE)
|
|
{
|
|
u32Offset = SHA_BLOCK_SIZE - u32ResidualBytes;
|
|
m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u32Offset);
|
|
pu8Data += u32Offset;
|
|
u16DataLength -= u32Offset;
|
|
|
|
nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
|
|
u32Addr += SHA_BLOCK_SIZE;
|
|
u32CurrentBlock = 1;
|
|
}
|
|
else
|
|
{
|
|
m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u16DataLength);
|
|
u16DataLength = 0;
|
|
}
|
|
}
|
|
|
|
/* Get the number of HASH BLOCKs and the residual bytes. */
|
|
u32NBlocks = u16DataLength / SHA_BLOCK_SIZE;
|
|
u32ResidualBytes = u16DataLength % SHA_BLOCK_SIZE;
|
|
|
|
if(u32NBlocks != 0)
|
|
{
|
|
nm_write_block(u32Addr, pu8Data, (uint16)(u32NBlocks * SHA_BLOCK_SIZE));
|
|
pu8Data += (u32NBlocks * SHA_BLOCK_SIZE);
|
|
}
|
|
|
|
u32NBlocks += u32CurrentBlock;
|
|
if(u32NBlocks != 0)
|
|
{
|
|
uint32 u32RegVal = 0;
|
|
|
|
nm_write_reg(SHA256_CTRL, u32RegVal);
|
|
u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK;
|
|
nm_write_reg(SHA256_CTRL, u32RegVal);
|
|
|
|
if(pstrSHA256->u8InitHashFlag)
|
|
{
|
|
pstrSHA256->u8InitHashFlag = 0;
|
|
u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK;
|
|
}
|
|
|
|
u32ReadAddr = u32WriteAddr + (u32NBlocks * SHA_BLOCK_SIZE);
|
|
nm_write_reg(SHA256_DATA_LENGTH, (u32NBlocks * SHA_BLOCK_SIZE));
|
|
nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr);
|
|
nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr);
|
|
|
|
u32RegVal |= SHA256_CTRL_START_CALC_MASK;
|
|
|
|
u32RegVal &= ~(0x7 << 8);
|
|
u32RegVal |= (2 << 8);
|
|
|
|
nm_write_reg(SHA256_CTRL, u32RegVal);
|
|
|
|
/* 5. Wait for done_intr */
|
|
while(!u8IsDone)
|
|
{
|
|
u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS);
|
|
u8IsDone = u32RegVal & NBIT0;
|
|
}
|
|
}
|
|
if(u32ResidualBytes != 0)
|
|
{
|
|
m2m_memcpy(pstrSHA256->au8CurrentBlock, pu8Data, u32ResidualBytes);
|
|
}
|
|
s8Ret = M2M_SUCCESS;
|
|
}
|
|
return s8Ret;
|
|
}
|
|
|
|
|
|
sint8 m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Sha256Digest)
|
|
{
|
|
sint8 s8Ret = M2M_ERR_FAIL;
|
|
tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt;
|
|
if(pstrSHA256 != NULL)
|
|
{
|
|
uint32 u32ReadAddr;
|
|
uint32 u32WriteAddr = SHARED_MEM_BASE;
|
|
uint32 u32Addr = u32WriteAddr;
|
|
uint16 u16Offset;
|
|
uint16 u16PaddingLength;
|
|
uint16 u16NBlocks = 1;
|
|
uint32 u32RegVal = 0;
|
|
uint32 u32Idx,u32ByteIdx;
|
|
uint32 au32Digest[M2M_SHA256_DIGEST_LEN / 4];
|
|
uint8 u8IsDone = 0;
|
|
|
|
nm_write_reg(SHA256_CTRL,u32RegVal);
|
|
u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK;
|
|
nm_write_reg(SHA256_CTRL,u32RegVal);
|
|
|
|
if(pstrSHA256->u8InitHashFlag)
|
|
{
|
|
pstrSHA256->u8InitHashFlag = 0;
|
|
u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK;
|
|
}
|
|
|
|
/* Calculate the offset of the last data byte in the current block. */
|
|
u16Offset = (uint16)(pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE);
|
|
|
|
/* Add the padding byte 0x80. */
|
|
pstrSHA256->au8CurrentBlock[u16Offset ++] = 0x80;
|
|
|
|
/* Calculate the required padding to complete
|
|
one Hash Block Size.
|
|
*/
|
|
u16PaddingLength = SHA_BLOCK_SIZE - u16Offset;
|
|
m2m_memset(&pstrSHA256->au8CurrentBlock[u16Offset], 0, u16PaddingLength);
|
|
|
|
/* If the padding count is not enough to hold 64-bit representation of
|
|
the total input message length, one padding block is required.
|
|
*/
|
|
if(u16PaddingLength < 8)
|
|
{
|
|
nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
|
|
u32Addr += SHA_BLOCK_SIZE;
|
|
m2m_memset(pstrSHA256->au8CurrentBlock, 0, SHA_BLOCK_SIZE);
|
|
u16NBlocks ++;
|
|
}
|
|
|
|
/* pack the length at the end of the padding block */
|
|
PUTU32(pstrSHA256->u32TotalLength << 3, pstrSHA256->au8CurrentBlock, (SHA_BLOCK_SIZE - 4));
|
|
|
|
u32ReadAddr = u32WriteAddr + (u16NBlocks * SHA_BLOCK_SIZE);
|
|
nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE);
|
|
nm_write_reg(SHA256_DATA_LENGTH, (u16NBlocks * SHA_BLOCK_SIZE));
|
|
nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr);
|
|
nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr);
|
|
|
|
u32RegVal |= SHA256_CTRL_START_CALC_MASK;
|
|
u32RegVal |= SHA256_CTRL_WR_BACK_HASH_VALUE_MASK;
|
|
u32RegVal &= ~(0x7UL << 8);
|
|
u32RegVal |= (0x2UL << 8);
|
|
|
|
nm_write_reg(SHA256_CTRL,u32RegVal);
|
|
|
|
|
|
/* 5. Wait for done_intr */
|
|
while(!u8IsDone)
|
|
{
|
|
u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS);
|
|
u8IsDone = u32RegVal & NBIT0;
|
|
}
|
|
nm_read_block(u32ReadAddr, (uint8*)au32Digest, 32);
|
|
|
|
/* Convert the output words to an array of bytes.
|
|
*/
|
|
u32ByteIdx = 0;
|
|
for(u32Idx = 0; u32Idx < (M2M_SHA256_DIGEST_LEN / 4); u32Idx ++)
|
|
{
|
|
pu8Sha256Digest[u32ByteIdx ++] = BYTE_3(au32Digest[u32Idx]);
|
|
pu8Sha256Digest[u32ByteIdx ++] = BYTE_2(au32Digest[u32Idx]);
|
|
pu8Sha256Digest[u32ByteIdx ++] = BYTE_1(au32Digest[u32Idx]);
|
|
pu8Sha256Digest[u32ByteIdx ++] = BYTE_0(au32Digest[u32Idx]);
|
|
}
|
|
s8Ret = M2M_SUCCESS;
|
|
}
|
|
return s8Ret;
|
|
}
|
|
|
|
|
|
/*======*======*======*======*======*=======*
|
|
* RSA IMPLEMENTATION *
|
|
*======*======*======*======*======*========*/
|
|
|
|
static void FlipBuffer(uint8 *pu8InBuffer, uint8 *pu8OutBuffer, uint16 u16BufferSize)
|
|
{
|
|
uint16 u16Idx;
|
|
for(u16Idx = 0; u16Idx < u16BufferSize; u16Idx ++)
|
|
{
|
|
#if ENABLE_FLIPPING == 1
|
|
pu8OutBuffer[u16Idx] = pu8InBuffer[u16BufferSize - u16Idx - 1];
|
|
#else
|
|
pu8OutBuffer[u16Idx] = pu8InBuffer[u16Idx];
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void BigInt_ModExp
|
|
(
|
|
uint8 *pu8X, uint16 u16XSize,
|
|
uint8 *pu8E, uint16 u16ESize,
|
|
uint8 *pu8M, uint16 u16MSize,
|
|
uint8 *pu8R, uint16 u16RSize
|
|
)
|
|
{
|
|
uint32 u32Reg;
|
|
uint8 au8Tmp[780] = {0};
|
|
uint32 u32XAddr = SHARED_MEM_BASE;
|
|
uint32 u32MAddr;
|
|
uint32 u32EAddr;
|
|
uint32 u32RAddr;
|
|
uint8 u8EMswBits = 32;
|
|
uint32 u32Mprime = 0x7F;
|
|
uint16 u16XSizeWords,u16ESizeWords;
|
|
uint32 u32Exponent;
|
|
|
|
u16XSizeWords = (u16XSize + 3) / 4;
|
|
u16ESizeWords = (u16ESize + 3) / 4;
|
|
|
|
u32MAddr = u32XAddr + (u16XSizeWords * 4);
|
|
u32EAddr = u32MAddr + (u16XSizeWords * 4);
|
|
u32RAddr = u32EAddr + (u16ESizeWords * 4);
|
|
|
|
/* Reset the core.
|
|
*/
|
|
u32Reg = 0;
|
|
u32Reg |= BIGINT_MISC_CTRL_CTL_RESET;
|
|
u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
|
|
u32Reg &= ~BIGINT_MISC_CTRL_CTL_RESET;
|
|
u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
|
|
|
|
nm_write_block(u32RAddr,au8Tmp, u16RSize);
|
|
|
|
/* Write Input Operands to Chip Memory.
|
|
*/
|
|
/*------- X -------*/
|
|
FlipBuffer(pu8X,au8Tmp,u16XSize);
|
|
nm_write_block(u32XAddr,au8Tmp,u16XSizeWords * 4);
|
|
|
|
/*------- E -------*/
|
|
m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
|
|
FlipBuffer(pu8E, au8Tmp, u16ESize);
|
|
nm_write_block(u32EAddr, au8Tmp, u16ESizeWords * 4);
|
|
u32Exponent = GET_UINT32(au8Tmp, (u16ESizeWords * 4) - 4);
|
|
while((u32Exponent & NBIT31)== 0)
|
|
{
|
|
u32Exponent <<= 1;
|
|
u8EMswBits --;
|
|
}
|
|
|
|
/*------- M -------*/
|
|
m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
|
|
FlipBuffer(pu8M, au8Tmp, u16XSize);
|
|
nm_write_block(u32MAddr, au8Tmp, u16XSizeWords * 4);
|
|
|
|
/* Program the addresses of the input operands.
|
|
*/
|
|
nm_write_reg(BIGINT_ADDR_X, u32XAddr);
|
|
nm_write_reg(BIGINT_ADDR_E, u32EAddr);
|
|
nm_write_reg(BIGINT_ADDR_M, u32MAddr);
|
|
nm_write_reg(BIGINT_ADDR_R, u32RAddr);
|
|
|
|
/* Mprime.
|
|
*/
|
|
nm_write_reg(BIGINT_M_PRIME,u32Mprime);
|
|
|
|
/* Length.
|
|
*/
|
|
u32Reg = (u16XSizeWords & 0xFF);
|
|
u32Reg += ((u16ESizeWords & 0xFF) << 8);
|
|
u32Reg += (u8EMswBits << 16);
|
|
nm_write_reg(BIGINT_LENGTH,u32Reg);
|
|
|
|
/* CTRL Register.
|
|
*/
|
|
u32Reg = nm_read_reg(BIGINT_MISC_CTRL);
|
|
u32Reg ^= BIGINT_MISC_CTRL_CTL_START;
|
|
u32Reg |= BIGINT_MISC_CTRL_CTL_FORCE_BARRETT;
|
|
//u32Reg |= BIGINT_MISC_CTRL_CTL_M_PRIME_VALID;
|
|
#if ENABLE_FLIPPING == 0
|
|
u32Reg |= BIGINT_MISC_CTRL_CTL_MSW_FIRST;
|
|
#endif
|
|
nm_write_reg(BIGINT_MISC_CTRL,u32Reg);
|
|
|
|
/* Wait for computation to complete. */
|
|
while(1)
|
|
{
|
|
u32Reg = nm_read_reg(BIGINT_IRQ_STS);
|
|
if(u32Reg & BIGINT_IRQ_STS_DONE)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
nm_write_reg(BIGINT_IRQ_STS,0);
|
|
m2m_memset(au8Tmp, 0, sizeof(au8Tmp));
|
|
nm_read_block(u32RAddr, au8Tmp, u16RSize);
|
|
FlipBuffer(au8Tmp, pu8R, u16RSize);
|
|
}
|
|
|
|
|
|
|
|
#define MD5_DIGEST_SIZE (16)
|
|
#define SHA1_DIGEST_SIZE (20)
|
|
|
|
static const uint8 au8TEncodingMD5[] =
|
|
{
|
|
0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86,
|
|
0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00,
|
|
0x04
|
|
};
|
|
/*!< Fixed part of the Encoding T for the MD5 hash algorithm.
|
|
*/
|
|
|
|
|
|
static const uint8 au8TEncodingSHA1[] =
|
|
{
|
|
0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E,
|
|
0x03, 0x02, 0x1A, 0x05, 0x00, 0x04
|
|
};
|
|
/*!< Fixed part of the Encoding T for the SHA-1 hash algorithm.
|
|
*/
|
|
|
|
|
|
static const uint8 au8TEncodingSHA2[] =
|
|
{
|
|
0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86,
|
|
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
|
|
0x00, 0x04
|
|
};
|
|
/*!< Fixed part of the Encoding T for the SHA-2 hash algorithm.
|
|
*/
|
|
|
|
|
|
sint8 m2m_crypto_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash,
|
|
uint16 u16HashLength, uint8 *pu8RsaSignature)
|
|
{
|
|
sint8 s8Ret = M2M_RSA_SIGN_FAIL;
|
|
|
|
if((pu8N != NULL) && (pu8E != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL))
|
|
{
|
|
uint16 u16TLength, u16TEncodingLength;
|
|
uint8 *pu8T;
|
|
uint8 au8EM[512];
|
|
|
|
/* Selection of correct T Encoding based on the hash size.
|
|
*/
|
|
if(u16HashLength == MD5_DIGEST_SIZE)
|
|
{
|
|
pu8T = (uint8*)au8TEncodingMD5;
|
|
u16TEncodingLength = sizeof(au8TEncodingMD5);
|
|
}
|
|
else if(u16HashLength == SHA1_DIGEST_SIZE)
|
|
{
|
|
pu8T = (uint8*)au8TEncodingSHA1;
|
|
u16TEncodingLength = sizeof(au8TEncodingSHA1);
|
|
}
|
|
else
|
|
{
|
|
pu8T = (uint8*)au8TEncodingSHA2;
|
|
u16TEncodingLength = sizeof(au8TEncodingSHA2);
|
|
}
|
|
u16TLength = u16TEncodingLength + 1 + u16HashLength;
|
|
|
|
/* If emLen < tLen + 11.
|
|
*/
|
|
if(u16NSize >= (u16TLength + 11))
|
|
{
|
|
uint32 u32PSLength,u32Idx = 0;
|
|
|
|
/*
|
|
RSA verification
|
|
*/
|
|
BigInt_ModExp(pu8RsaSignature, u16NSize, pu8E, u16ESize, pu8N, u16NSize, au8EM, u16NSize);
|
|
|
|
u32PSLength = u16NSize - u16TLength - 3;
|
|
|
|
/*
|
|
The calculated EM must match the following pattern.
|
|
*======*======*======*======*======*
|
|
* 0x00 || 0x01 || PS || 0x00 || T *
|
|
*======*======*======*======*======*
|
|
Where PS is all 0xFF
|
|
T is defined based on the hash algorithm.
|
|
*/
|
|
if((au8EM[0] == 0x00) && (au8EM[1] == 0x01))
|
|
{
|
|
for(u32Idx = 2; au8EM[u32Idx] == 0xFF; u32Idx ++);
|
|
if(u32Idx == (u32PSLength + 2))
|
|
{
|
|
if(au8EM[u32Idx ++] == 0x00)
|
|
{
|
|
if(!m2m_memcmp(&au8EM[u32Idx], pu8T, u16TEncodingLength))
|
|
{
|
|
u32Idx += u16TEncodingLength;
|
|
if(au8EM[u32Idx ++] == u16HashLength)
|
|
s8Ret = m2m_memcmp(&au8EM[u32Idx], pu8SignedMsgHash, u16HashLength);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return s8Ret;
|
|
}
|
|
|
|
|
|
sint8 m2m_crypto_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash,
|
|
uint16 u16HashLength, uint8 *pu8RsaSignature)
|
|
{
|
|
sint8 s8Ret = M2M_RSA_SIGN_FAIL;
|
|
|
|
if((pu8N != NULL) && (pu8d != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL))
|
|
{
|
|
uint16 u16TLength, u16TEncodingLength;
|
|
uint8 *pu8T;
|
|
uint8 au8EM[512];
|
|
|
|
/* Selection of correct T Encoding based on the hash size.
|
|
*/
|
|
if(u16HashLength == MD5_DIGEST_SIZE)
|
|
{
|
|
pu8T = (uint8*)au8TEncodingMD5;
|
|
u16TEncodingLength = sizeof(au8TEncodingMD5);
|
|
}
|
|
else if(u16HashLength == SHA1_DIGEST_SIZE)
|
|
{
|
|
pu8T = (uint8*)au8TEncodingSHA1;
|
|
u16TEncodingLength = sizeof(au8TEncodingSHA1);
|
|
}
|
|
else
|
|
{
|
|
pu8T = (uint8*)au8TEncodingSHA2;
|
|
u16TEncodingLength = sizeof(au8TEncodingSHA2);
|
|
}
|
|
u16TLength = u16TEncodingLength + 1 + u16HashLength;
|
|
|
|
/* If emLen < tLen + 11.
|
|
*/
|
|
if(u16NSize >= (u16TLength + 11))
|
|
{
|
|
uint16 u16PSLength = 0;
|
|
uint16 u16Offset = 0;
|
|
|
|
/*
|
|
The calculated EM must match the following pattern.
|
|
*======*======*======*======*======*
|
|
* 0x00 || 0x01 || PS || 0x00 || T *
|
|
*======*======*======*======*======*
|
|
Where PS is all 0xFF
|
|
T is defined based on the hash algorithm.
|
|
*/
|
|
au8EM[u16Offset ++] = 0;
|
|
au8EM[u16Offset ++] = 1;
|
|
u16PSLength = u16NSize - u16TLength - 3;
|
|
m2m_memset(&au8EM[u16Offset], 0xFF, u16PSLength);
|
|
u16Offset += u16PSLength;
|
|
au8EM[u16Offset ++] = 0;
|
|
m2m_memcpy(&au8EM[u16Offset], pu8T, u16TEncodingLength);
|
|
u16Offset += u16TEncodingLength;
|
|
au8EM[u16Offset ++] = u16HashLength;
|
|
m2m_memcpy(&au8EM[u16Offset], pu8SignedMsgHash, u16HashLength);
|
|
|
|
/*
|
|
RSA Signature Generation
|
|
*/
|
|
BigInt_ModExp(au8EM, u16NSize, pu8d, u16dSize, pu8N, u16NSize, pu8RsaSignature, u16NSize);
|
|
s8Ret = M2M_RSA_SIGN_OK;
|
|
}
|
|
}
|
|
return s8Ret;
|
|
}
|
|
|
|
#endif /* CONF_CRYPTO */
|
|
|
|
#ifdef CONF_CRYPTO_SOFT
|
|
|
|
typedef struct {
|
|
tpfAppCryproCb pfAppCryptoCb;
|
|
uint8 * pu8Digest;
|
|
uint8 * pu8Rsa;
|
|
uint8 u8CryptoBusy;
|
|
}tstrCryptoCtxt;
|
|
|
|
typedef struct {
|
|
uint8 au8N[M2M_MAX_RSA_LEN];
|
|
uint8 au8E[M2M_MAX_RSA_LEN];
|
|
uint8 au8Hash[M2M_SHA256_DIGEST_LEN];
|
|
uint16 u16Nsz;
|
|
uint16 u16Esz;
|
|
uint16 u16Hsz;
|
|
uint8 _pad16_[2];
|
|
}tstrRsaPayload;
|
|
|
|
static tstrCryptoCtxt gstrCryptoCtxt;
|
|
|
|
|
|
/**
|
|
* @fn m2m_crypto_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
|
|
* @brief WiFi call back function
|
|
* @param [in] u8OpCode
|
|
* HIF Opcode type.
|
|
* @param [in] u16DataSize
|
|
* HIF data length.
|
|
* @param [in] u32Addr
|
|
* HIF address.
|
|
* @author
|
|
* @date
|
|
* @version 1.0
|
|
*/
|
|
static void m2m_crypto_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
|
|
{
|
|
sint8 ret = M2M_SUCCESS;
|
|
gstrCryptoCtxt.u8CryptoBusy = 0;
|
|
if(u8OpCode == M2M_CRYPTO_RESP_SHA256_INIT)
|
|
{
|
|
tstrM2mSha256Ctxt strCtxt;
|
|
if (hif_receive(u32Addr, (uint8*) &strCtxt,sizeof(tstrM2mSha256Ctxt), 0) == M2M_SUCCESS)
|
|
{
|
|
tstrCyptoResp strResp;
|
|
if(hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), (uint8*) &strResp,sizeof(tstrCyptoResp), 1) == M2M_SUCCESS)
|
|
{
|
|
if (gstrCryptoCtxt.pfAppCryptoCb)
|
|
gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,&strCtxt);
|
|
}
|
|
}
|
|
}
|
|
else if(u8OpCode == M2M_CRYPTO_RESP_SHA256_UPDATE)
|
|
{
|
|
tstrM2mSha256Ctxt strCtxt;
|
|
if (hif_receive(u32Addr, (uint8*) &strCtxt,sizeof(tstrM2mSha256Ctxt), 0) == M2M_SUCCESS)
|
|
{
|
|
tstrCyptoResp strResp;
|
|
if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), (uint8*) &strResp,sizeof(tstrCyptoResp), 1) == M2M_SUCCESS)
|
|
{
|
|
if (gstrCryptoCtxt.pfAppCryptoCb)
|
|
gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,&strCtxt);
|
|
}
|
|
}
|
|
|
|
}
|
|
else if(u8OpCode == M2M_CRYPTO_RESP_SHA256_FINISH)
|
|
{
|
|
tstrCyptoResp strResp;
|
|
if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt), (uint8*) &strResp,sizeof(tstrCyptoResp), 0) == M2M_SUCCESS)
|
|
{
|
|
if (hif_receive(u32Addr + sizeof(tstrM2mSha256Ctxt) + sizeof(tstrCyptoResp), (uint8*)gstrCryptoCtxt.pu8Digest,M2M_SHA256_DIGEST_LEN, 1) == M2M_SUCCESS)
|
|
{
|
|
if (gstrCryptoCtxt.pfAppCryptoCb)
|
|
gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,gstrCryptoCtxt.pu8Digest);
|
|
|
|
}
|
|
}
|
|
}
|
|
else if(u8OpCode == M2M_CRYPTO_RESP_RSA_SIGN_GEN)
|
|
{
|
|
tstrCyptoResp strResp;
|
|
if (hif_receive(u32Addr + sizeof(tstrRsaPayload), (uint8*)&strResp,sizeof(tstrCyptoResp), 0) == M2M_SUCCESS)
|
|
{
|
|
if (hif_receive(u32Addr + sizeof(tstrRsaPayload) + sizeof(tstrCyptoResp), (uint8*)gstrCryptoCtxt.pu8Rsa,M2M_MAX_RSA_LEN, 0) == M2M_SUCCESS)
|
|
{
|
|
if (gstrCryptoCtxt.pfAppCryptoCb)
|
|
gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,gstrCryptoCtxt.pu8Rsa);
|
|
}
|
|
}
|
|
}
|
|
else if(u8OpCode == M2M_CRYPTO_RESP_RSA_SIGN_VERIFY)
|
|
{
|
|
tstrCyptoResp strResp;
|
|
if (hif_receive(u32Addr + sizeof(tstrRsaPayload), (uint8*)&strResp,sizeof(tstrCyptoResp), 1) == M2M_SUCCESS)
|
|
{
|
|
if (gstrCryptoCtxt.pfAppCryptoCb)
|
|
gstrCryptoCtxt.pfAppCryptoCb(u8OpCode,&strResp,NULL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
M2M_ERR("u8Code %d ??\n",u8OpCode);
|
|
}
|
|
|
|
}
|
|
/*!
|
|
@fn \
|
|
sint8 m2m_crypto_init();
|
|
|
|
@brief crypto initialization
|
|
|
|
@param[in] pfAppCryproCb
|
|
|
|
*/
|
|
sint8 m2m_crypto_init(tpfAppCryproCb pfAppCryproCb)
|
|
{
|
|
sint8 ret = M2M_ERR_FAIL;
|
|
m2m_memset((uint8*)&gstrCryptoCtxt,0,sizeof(tstrCryptoCtxt));
|
|
if(pfAppCryproCb != NULL)
|
|
{
|
|
gstrCryptoCtxt.pfAppCryptoCb = pfAppCryproCb;
|
|
ret = hif_register_cb(M2M_REQ_GROUP_CRYPTO,m2m_crypto_cb);
|
|
}
|
|
return ret;
|
|
}
|
|
/*!
|
|
@fn \
|
|
sint8 m2m_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt);
|
|
|
|
@brief SHA256 hash initialization
|
|
|
|
@param[in] psha256Ctxt
|
|
Pointer to a sha256 context allocated by the caller.
|
|
*/
|
|
sint8 m2m_crypto_sha256_hash_init(tstrM2mSha256Ctxt *psha256Ctxt)
|
|
{
|
|
sint8 ret = M2M_ERR_FAIL;
|
|
if((psha256Ctxt != NULL)&&(!gstrCryptoCtxt.u8CryptoBusy))
|
|
{
|
|
ret = hif_send(M2M_REQ_GROUP_CRYPTO,M2M_CRYPTO_REQ_SHA256_INIT|M2M_REQ_DATA_PKT,(uint8*)psha256Ctxt,sizeof(tstrM2mSha256Ctxt),NULL,0,0);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*!
|
|
@fn \
|
|
sint8 m2m_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Data, uint16 u16DataLength);
|
|
|
|
@brief SHA256 hash update
|
|
|
|
@param [in] psha256Ctxt
|
|
Pointer to the sha256 context.
|
|
|
|
@param [in] pu8Data
|
|
Buffer holding the data submitted to the hash.
|
|
|
|
@param [in] u16DataLength
|
|
Size of the data buffer in bytes.
|
|
*/
|
|
sint8 m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Data, uint16 u16DataLength)
|
|
{
|
|
sint8 ret = M2M_ERR_FAIL;
|
|
if((!gstrCryptoCtxt.u8CryptoBusy) && (psha256Ctxt != NULL) && (pu8Data != NULL) && (u16DataLength < M2M_SHA256_MAX_DATA))
|
|
{
|
|
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));
|
|
}
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
/*!
|
|
@fn \
|
|
sint8 m2m_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Sha256Digest);
|
|
|
|
@brief SHA256 hash finalization
|
|
|
|
@param[in] psha256Ctxt
|
|
Pointer to a sha256 context allocated by the caller.
|
|
|
|
@param [in] pu8Sha256Digest
|
|
Buffer allocated by the caller which will hold the resultant SHA256 Digest. It must be allocated no less than M2M_SHA256_DIGEST_LEN.
|
|
*/
|
|
sint8 m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *psha256Ctxt, uint8 *pu8Sha256Digest)
|
|
{
|
|
sint8 ret = M2M_ERR_FAIL;
|
|
if((!gstrCryptoCtxt.u8CryptoBusy) && (psha256Ctxt != NULL) && (pu8Sha256Digest != NULL))
|
|
{
|
|
gstrCryptoCtxt.pu8Digest = pu8Sha256Digest;
|
|
ret = hif_send(M2M_REQ_GROUP_CRYPTO,M2M_CRYPTO_REQ_SHA256_FINISH|M2M_REQ_DATA_PKT,(uint8*)psha256Ctxt,sizeof(tstrM2mSha256Ctxt),NULL,0,0);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
@fn \
|
|
sint8 m2m_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash, \
|
|
uint16 u16HashLength, uint8 *pu8RsaSignature);
|
|
|
|
@brief RSA Signature Verification
|
|
|
|
The function shall request the RSA Signature verification from the WINC Firmware for the given message. The signed message shall be
|
|
compressed to the corresponding hash algorithm before calling this function.
|
|
The hash type is identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256.
|
|
|
|
@param[in] pu8N
|
|
RSA Key modulus n.
|
|
|
|
@param[in] u16NSize
|
|
Size of the RSA modulus n in bytes.
|
|
|
|
@param[in] pu8E
|
|
RSA public exponent.
|
|
|
|
@param[in] u16ESize
|
|
Size of the RSA public exponent in bytes.
|
|
|
|
@param[in] pu8SignedMsgHash
|
|
The hash digest of the signed message.
|
|
|
|
@param[in] u16HashLength
|
|
The length of the hash digest.
|
|
|
|
@param[out] pu8RsaSignature
|
|
Signature value to be verified.
|
|
*/
|
|
|
|
|
|
sint8 m2m_crypto_rsa_sign_verify(uint8 *pu8N, uint16 u16NSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8SignedMsgHash,
|
|
uint16 u16HashLength, uint8 *pu8RsaSignature)
|
|
{
|
|
sint8 ret = M2M_ERR_FAIL;
|
|
if((!gstrCryptoCtxt.u8CryptoBusy) && (pu8N != NULL) && (pu8E != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL)
|
|
&& (u16NSize != 0) && (u16ESize != 0) && (u16HashLength != 0) && (pu8RsaSignature != NULL) )
|
|
|
|
{
|
|
tstrRsaPayload strRsa = {0};
|
|
|
|
m2m_memcpy(strRsa.au8N,pu8N,u16NSize);
|
|
m2m_memcpy(strRsa.au8E,pu8E,u16ESize);
|
|
m2m_memcpy(strRsa.au8Hash,pu8SignedMsgHash,u16HashLength);
|
|
|
|
strRsa.u16Esz = u16ESize;
|
|
strRsa.u16Hsz = u16HashLength;
|
|
strRsa.u16Nsz = u16NSize;
|
|
|
|
ret = hif_send(M2M_REQ_GROUP_CRYPTO,M2M_CRYPTO_REQ_RSA_SIGN_VERIFY|M2M_REQ_DATA_PKT,(uint8*)&strRsa,sizeof(tstrRsaPayload),NULL,0,0);
|
|
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*!
|
|
@fn \
|
|
sint8 m2m_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash, \
|
|
uint16 u16HashLength, uint8 *pu8RsaSignature);
|
|
|
|
@brief RSA Signature Generation
|
|
|
|
The function shall request the RSA Signature generation from the WINC Firmware for the given message. The signed message shall be
|
|
compressed to the corresponding hash algorithm before calling this function.
|
|
The hash type is identified by the given hash length. For example, if the hash length is 32 bytes, then it is SHA256.
|
|
|
|
@param[in] pu8N
|
|
RSA Key modulus n.
|
|
|
|
@param[in] u16NSize
|
|
Size of the RSA modulus n in bytes.
|
|
|
|
@param[in] pu8d
|
|
RSA private exponent.
|
|
|
|
@param[in] u16dSize
|
|
Size of the RSA private exponent in bytes.
|
|
|
|
@param[in] pu8SignedMsgHash
|
|
The hash digest of the signed message.
|
|
|
|
@param[in] u16HashLength
|
|
The length of the hash digest.
|
|
|
|
@param[out] pu8RsaSignature
|
|
Pointer to a user buffer allocated by the caller shall hold the generated signature.
|
|
*/
|
|
sint8 m2m_crypto_rsa_sign_gen(uint8 *pu8N, uint16 u16NSize, uint8 *pu8d, uint16 u16dSize, uint8 *pu8SignedMsgHash,
|
|
uint16 u16HashLength, uint8 *pu8RsaSignature)
|
|
{
|
|
sint8 ret = M2M_ERR_FAIL;
|
|
if((!gstrCryptoCtxt.u8CryptoBusy) && (pu8N != NULL) && (pu8d != NULL) && (pu8RsaSignature != NULL) && (pu8SignedMsgHash != NULL)
|
|
&& (u16NSize != 0) && (u16dSize != 0) && (u16HashLength != 0) && (pu8RsaSignature != NULL))
|
|
|
|
{
|
|
tstrRsaPayload strRsa = {0};
|
|
|
|
m2m_memcpy(strRsa.au8N,pu8N,u16NSize);
|
|
m2m_memcpy(strRsa.au8E,pu8d,u16dSize);
|
|
m2m_memcpy(strRsa.au8Hash,pu8SignedMsgHash,u16HashLength);
|
|
|
|
strRsa.u16Esz = u16dSize;
|
|
strRsa.u16Hsz = u16HashLength;
|
|
strRsa.u16Nsz = u16NSize;
|
|
|
|
gstrCryptoCtxt.pu8Rsa = pu8RsaSignature;
|
|
ret = hif_send(M2M_REQ_GROUP_CRYPTO,M2M_CRYPTO_REQ_RSA_SIGN_GEN|M2M_REQ_DATA_PKT,(uint8*)&strRsa,sizeof(tstrRsaPayload),NULL,0,0);
|
|
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#endif |