mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Add WINC1500 FW upload code.
This commit is contained in:
parent
dae73f6250
commit
330b41aab6
61
src/winc1500/include/programmer/programmer.h
Normal file
61
src/winc1500/include/programmer/programmer.h
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief Programmer APIs.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef IMAGE_DOWNLOADER_H_INCLUDED
|
||||
#define IMAGE_DOWNLOADER_H_INCLUDED
|
||||
|
||||
#include "spi_flash/include/spi_flash_map.h"
|
||||
#include "spi_flash/include/spi_flash.h"
|
||||
#include "programmer/programmer_apis.h"
|
||||
|
||||
#define ROOT_CERT_SIZE M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE
|
||||
|
||||
#define programmer_get_flash_size() (((spi_flash_get_size() * 1024) / 8) * 1024)
|
||||
#define programmer_write(pu8Buf, u32Offset, u32Sz) spi_flash_write(pu8Buf, u32Offset, u32Sz)
|
||||
#define programmer_erase(u32Offset, u32Sz) spi_flash_erase(u32Offset, u32Sz)
|
||||
#define programmer_eraseall() programmer_erase(0, programmer_get_flash_size())
|
||||
#define programmer_read(pu8Buf, u32Offset, u32Sz) spi_flash_read(pu8Buf, u32Offset, u32Sz)
|
||||
|
||||
int burn_firmware(void);
|
||||
int verify_firmware(void);
|
||||
int burn_certificates(void);
|
||||
int verify_certificates(void);
|
||||
#endif /* IMAGE_DOWNLOADER_H_INCLUDED */
|
||||
56
src/winc1500/include/programmer/programmer_apis.h
Normal file
56
src/winc1500/include/programmer/programmer_apis.h
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief Programmer APIs.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FIRMWARE_PROGRAMMER_APIS_H_INCLUDED
|
||||
#define FIRMWARE_PROGRAMMER_APIS_H_INCLUDED
|
||||
|
||||
#include "common/include/nm_common.h"
|
||||
#include "spi_flash/include/spi_flash_map.h"
|
||||
|
||||
#define programmer_write_cert_image(buff) programmer_write((uint8*)buff, M2M_TLS_FLASH_ROOTCERT_CACHE_OFFSET, M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE)
|
||||
#define programmer_read_cert_image(buff) programmer_read((uint8*)buff, M2M_TLS_FLASH_ROOTCERT_CACHE_OFFSET, M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE)
|
||||
#define programmer_erase_cert_image() programmer_erase(M2M_TLS_FLASH_ROOTCERT_CACHE_OFFSET, M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE)
|
||||
|
||||
#define programmer_write_firmware_image(buff,offSet,sz) programmer_write((uint8*)buff, offSet, sz)
|
||||
#define programmer_read_firmware_image(buff,offSet,sz) programmer_read((uint8*)buff, offSet, sz)
|
||||
|
||||
#define programmer_erase_all() programmer_erase(0, programmer_get_flash_size())
|
||||
#endif /* FIRMWARE_PROGRAMMER_APIS_H_INCLUDED */
|
||||
49
src/winc1500/include/root_cert/root_setup.h
Normal file
49
src/winc1500/include/root_cert/root_setup.h
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief Root Certificate Setup.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ROOT_CERT_SETUP_H_INCLUDED
|
||||
#define ROOT_CERT_SETUP_H_INCLUDED
|
||||
|
||||
#include "programmer/programmer.h"
|
||||
|
||||
int WriteRootCertificate(const char *filename, char *pcRootCertFileData, uint32 u32FileSize);
|
||||
|
||||
#endif /* ROOT_CERT_SETUP_H_INCLUDED */
|
||||
84
src/winc1500/include/root_cert/x509/asn1.h
Normal file
84
src/winc1500/include/root_cert/x509/asn1.h
Normal file
@ -0,0 +1,84 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief ASN1.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ASN1_H_INCLUDED
|
||||
#define ASN1_H_INCLUDED
|
||||
|
||||
#include "common/include/nm_common.h"
|
||||
|
||||
/* ASN.1 TAG DEFINITIONS. */
|
||||
#define ASN1_INVALID 0x00
|
||||
#define ASN1_BOOLEAN 0x01
|
||||
#define ASN1_INTEGER 0x02
|
||||
#define ASN1_BIT_STRING 0x03
|
||||
#define ASN1_OCTET_STRING 0x04
|
||||
#define ASN1_NULL 0x05
|
||||
#define ASN1_OBJECT_IDENTIFIER 0x06
|
||||
#define ASN1_UTF8_DTRING 0x0C
|
||||
#define ASN1_PRINTABLE_STRING 0x13
|
||||
#define ASN1_TELETEX_STRING 0x14
|
||||
#define ASN1_UTC_TIME 0x17
|
||||
#define ASN1_GENERALIZED_TIME 0x18
|
||||
#define ASN1_SEQUENCE 0x30
|
||||
#define ASN1_SET 0x31
|
||||
|
||||
#define ASN1_SUCCESS 0
|
||||
|
||||
#define ASN1_FAIL -1
|
||||
|
||||
typedef struct {
|
||||
uint8 *pu8Buff;
|
||||
uint8 *pu8Data;
|
||||
uint16 u16BuffLen;
|
||||
} tstrAsn1Context;
|
||||
|
||||
typedef struct {
|
||||
uint32 u32Length;
|
||||
uint8 u8Tag;
|
||||
} tstrAsn1Element;
|
||||
|
||||
uint16 ASN1_GetNextElement(tstrAsn1Context *pstrAsn1Ctxt, tstrAsn1Element *pstrElement);
|
||||
|
||||
uint16 ASN1_Read(tstrAsn1Context *pstrAsn1Cxt, uint32 u32ReadLength, uint8 *pu8ReadBuffer);
|
||||
|
||||
uint16 ASN1_ReadReference(tstrAsn1Context *pstrAsn1Cxt, uint32 u32ReadLength, uint8 **ppu8ReadBuffer);
|
||||
|
||||
#endif /* ASN1_H_INCLUDED */
|
||||
101
src/winc1500/include/root_cert/x509/common.h
Normal file
101
src/winc1500/include/root_cert/x509/common.h
Normal file
@ -0,0 +1,101 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief Common Functions.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H_INCLUDED
|
||||
#define COMMON_H_INCLUDED
|
||||
|
||||
#include "common/include/nm_common.h"
|
||||
#include <string.h>
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint16 u16BufferSize;
|
||||
uint8 *pu8Data;
|
||||
} tstrBuffer;
|
||||
|
||||
/* Used for time storage. */
|
||||
typedef struct {
|
||||
uint16 u16Year;
|
||||
uint8 u8Month;
|
||||
uint8 u8Day;
|
||||
uint8 u8Hour;
|
||||
uint8 u8Minute;
|
||||
uint8 u8Second;
|
||||
} tstrSystemTime;
|
||||
|
||||
#define SIZE_128_BITS (16)
|
||||
#define SIZE_256_BITS (32)
|
||||
#define SIZE_512_BITS (64)
|
||||
#define SIZE_1024_BITS (128)
|
||||
#define SIZE_1536_BITS (192)
|
||||
#define SIZE_2048_BITS (256)
|
||||
|
||||
#define GETU16(BUF, OFFSET) ((((uint16)((BUF)[OFFSET]) << 8)) | (((uint16)(BUF)[OFFSET + 1])))
|
||||
|
||||
/*!< Retrieve 2 bytes from the given buffer at the given
|
||||
* offset as 16-bit unsigned integer in the Network byte order.
|
||||
*/
|
||||
|
||||
#define GETU32(BUF,OFFSET) ((((uint32)((BUF)[OFFSET]) << 24)) | (((uint32)((BUF)[OFFSET + 1]) << 16)) | \
|
||||
(((uint32)((BUF)[OFFSET + 2]) << 8)) | ((uint32)((BUF)[OFFSET + 3])))
|
||||
/*!< Retrieve 4 bytes from the given buffer at the given
|
||||
offset as 32-bit unsigned integer in the Network byte order.
|
||||
*/
|
||||
|
||||
#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)
|
||||
|
||||
#define PUTU16(VAL16, BUF, OFFSET) \
|
||||
do \
|
||||
{ \
|
||||
(BUF)[OFFSET ] = BYTE_1((VAL16)); \
|
||||
(BUF)[OFFSET + 1 ] = BYTE_0((VAL16)); \
|
||||
} while (0)
|
||||
|
||||
#endif /* COMMON_H_INCLUDED */
|
||||
112
src/winc1500/include/root_cert/x509/hash.h
Normal file
112
src/winc1500/include/root_cert/x509/hash.h
Normal file
@ -0,0 +1,112 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief Hash Functions.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HASH_H_INCLUDED
|
||||
#define HASH_H_INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define SHA_BLOCK_SIZE 64
|
||||
|
||||
#define MD5_DIGEST_SIZE (16)
|
||||
#define SHA1_DIGEST_SIZE (20)
|
||||
#define SHA256_DIGEST_SIZE 32
|
||||
|
||||
#define SHA_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
|
||||
|
||||
#define SHA_FLAGS_INIT 0x01
|
||||
|
||||
/*!< A flag to tell the hash function to
|
||||
* start hash from the initial state.
|
||||
*/
|
||||
|
||||
#define SHA_FLAGS_UPDATE 0x02
|
||||
|
||||
/*!< Update the current hash with the
|
||||
* given data.
|
||||
*/
|
||||
|
||||
#define SHA_FLAGS_FINISH 0x04
|
||||
|
||||
/*!< Finalize the hashing and calculate
|
||||
* the final result.
|
||||
*/
|
||||
|
||||
#define SHA_FLAGS_FULL_HASH (SHA_FLAGS_INIT | SHA_FLAGS_UPDATE | SHA_FLAGS_FINISH)
|
||||
|
||||
#define SHA1_INIT(ctxt) SHA1_Hash((ctxt), SHA_FLAGS_INIT, NULL, 0, NULL)
|
||||
#define SHA1_UPDATE(ctxt, data, dataLen) SHA1_Hash((ctxt), SHA_FLAGS_UPDATE, (data), (dataLen), NULL)
|
||||
#define SHA1_FINISH(ctxt, digest) SHA1_Hash((ctxt), SHA_FLAGS_FINISH, NULL, 0, digest)
|
||||
|
||||
#define MD5_INIT(ctxt) MD5_Hash((ctxt), SHA_FLAGS_INIT, NULL, 0, NULL)
|
||||
#define MD5_UPDATE(ctxt, data, dataLen) MD5_Hash((ctxt), SHA_FLAGS_UPDATE, (data), (dataLen), NULL)
|
||||
#define MD5_FINISH(ctxt, digest) MD5_Hash((ctxt), SHA_FLAGS_FINISH, NULL, 0, digest)
|
||||
|
||||
typedef void (*tpfHashProcessBlock)(uint32 *pu32HashState, const uint8 *pu8MessageBlock);
|
||||
|
||||
typedef struct {
|
||||
uint32 au32HashState[SHA_MAX_DIGEST_SIZE / 4];
|
||||
uint8 au8CurrentBlock[SHA_BLOCK_SIZE];
|
||||
uint32 u32TotalLength;
|
||||
tpfHashProcessBlock fpHash;
|
||||
uint8 u8BlockSize;
|
||||
uint8 u8DigestSize;
|
||||
} tstrHashContext;
|
||||
|
||||
typedef tstrHashContext tstrMd5Context;
|
||||
typedef tstrHashContext tstrSha1Context;
|
||||
typedef tstrHashContext tstrSha256Context;
|
||||
|
||||
typedef void (*tpfHash)
|
||||
(
|
||||
tstrHashContext *pstrHashContext,
|
||||
uint8 u8Flags,
|
||||
uint8 *pu8Data,
|
||||
uint32 u32DataLength,
|
||||
uint8 *pu8Digest
|
||||
);
|
||||
|
||||
void MD5_Hash(tstrHashContext *pstrMD5Context, uint8 u8Flags, uint8 *pu8Data, uint32 u32DataLength, uint8 *pu8Digest);
|
||||
void HMAC_Vector(tpfHash fpHash, uint8 *pu8Key, uint32 u32KeyLength, tstrBuffer *pstrInData, uint8 u8NumInputs, uint8 *pu8Out);
|
||||
void SHA1_Hash(tstrHashContext *pstrSha1Context, uint8 u8Flags, uint8 *pu8Data, uint32 u32DataLength, uint8 *pu8Digest);
|
||||
void SHA256_Hash(tstrHashContext *pstrSha256Context, uint8 u8Flags, uint8 *pu8Data, uint32 u32DataLength, uint8 *pu8Digest);
|
||||
|
||||
#endif /* HASH_H_INCLUDED */
|
||||
177
src/winc1500/include/root_cert/x509/x509_cert.h
Normal file
177
src/winc1500/include/root_cert/x509/x509_cert.h
Normal file
@ -0,0 +1,177 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief X509 Certificate Functions.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef X509_CERT_H_INCLUDED
|
||||
#define X509_CERT_H_INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
#include "hash.h"
|
||||
|
||||
#define X509_SUCCESS 0
|
||||
#define X509_FAIL -1
|
||||
|
||||
#define X509_SERIAL_NO_MAX_LENGTH 20
|
||||
|
||||
/* X509 ALGORITHMS. */
|
||||
#define X509_ALG_NULL 0
|
||||
#define X509_PUB_RSA 1
|
||||
#define X509_SIGN_MD5RSA 2
|
||||
#define X509_SIGN_SHA1RSA 3
|
||||
#define X509_SIGN_SHA256RSA 4
|
||||
#define X509_SIGN_SHA384RSA 5
|
||||
#define X509_SIGN_SHA512RSA 6
|
||||
|
||||
#define X509_STATUS_VALID 0
|
||||
/*!<
|
||||
* The X.509 certificate is valid.
|
||||
*/
|
||||
|
||||
#define X509_STATUS_EXPIRED 1
|
||||
/*!<
|
||||
* The X.509 certificate is expired.
|
||||
*/
|
||||
|
||||
#define X509_STATUS_REVOKED 2
|
||||
/*!<
|
||||
* The X.509 certificate is marked as revoked and should not
|
||||
* be trusted.
|
||||
*/
|
||||
|
||||
#define X509_STATUS_DECODE_ERR 4
|
||||
/*!<
|
||||
* Error decoding the certificate time.
|
||||
*/
|
||||
|
||||
#define X509_CERT_DUMP X509Cert_Dump
|
||||
#define X509_CERT_IS_VALID X509Cert_IsValid
|
||||
|
||||
typedef enum {
|
||||
PUBKEY_ALG_RSA,
|
||||
PUBKEY_ALG_DH,
|
||||
PUBKEY_ALG_ECDH
|
||||
} tenuPubKeyAlg;
|
||||
|
||||
typedef enum {
|
||||
SIGN_VERIFY,
|
||||
SIGN_GEN
|
||||
} tenuSignMode;
|
||||
|
||||
/*!
|
||||
* @struct tstrDHPublicKey
|
||||
*
|
||||
* @brief Diffie-Hellman Public Key Definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint8 *pu8P;
|
||||
uint8 *pu8G;
|
||||
uint8 *pu8Key;
|
||||
uint16 u16PSize;
|
||||
uint16 u16GSize;
|
||||
uint16 u16KeySize;
|
||||
} tstrDHPublicKey;
|
||||
|
||||
/*!
|
||||
* @struct tstrRSAPublicKey
|
||||
*
|
||||
* @brief RSA Public Key Definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint16 u16NSize;
|
||||
uint16 u16ESize;
|
||||
uint8 *pu8N;
|
||||
uint8 *pu8E;
|
||||
} tstrRSAPublicKey;
|
||||
|
||||
typedef struct {
|
||||
tenuPubKeyAlg enuType;
|
||||
union {
|
||||
tstrRSAPublicKey strRSAKey;
|
||||
tstrDHPublicKey strDHKey;
|
||||
};
|
||||
} tstrPublicKey;
|
||||
|
||||
typedef struct {
|
||||
char acCmnName[65];
|
||||
char acOrg[65];
|
||||
char acOrgUnit[65];
|
||||
uint8 au8NameSHA1[SHA1_DIGEST_SIZE];
|
||||
} tstrX520Name;
|
||||
|
||||
typedef struct {
|
||||
uint8 au8Time[20];
|
||||
} tstrX509Time;
|
||||
|
||||
typedef struct {
|
||||
uint8 u8Version;
|
||||
/*!<
|
||||
* X509 version.
|
||||
*/
|
||||
|
||||
uint8 u8SerialNumberLength;
|
||||
/*!<
|
||||
* X509 certificate serial number Length in bytes.
|
||||
*/
|
||||
|
||||
uint8 au8SerialNo[X509_SERIAL_NO_MAX_LENGTH];
|
||||
/*!<
|
||||
* X509 certificate serial number.
|
||||
*/
|
||||
|
||||
uint8 u8SignAlg;
|
||||
/*!<
|
||||
* X509 certificate serial number Length in bytes.
|
||||
*/
|
||||
|
||||
uint8 u8ValidityStatus;
|
||||
tstrX520Name strIssuer;
|
||||
tstrX509Time strStartDate;
|
||||
tstrX509Time strExpiryDate;
|
||||
tstrX520Name strSubject;
|
||||
tstrPublicKey strPubKey;
|
||||
tstrBuffer strSignature;
|
||||
uint8 *pu8TBSCert;
|
||||
uint16 u16TBSCertSize;
|
||||
} tstrX509Cert;
|
||||
|
||||
sint8 X509Cert_Decode(uint8 *pu8X509Buffer, uint32 u32CertSize, tstrX509Cert *pstrCert, uint8 bDumpX509);
|
||||
void X509Cert_Dump(void *pvCert);
|
||||
|
||||
#endif /* X509_CERT_H_INCLUDED */
|
||||
223
src/winc1500/include/spi_flash/include/spi_flash.h
Normal file
223
src/winc1500/include/spi_flash/include/spi_flash.h
Normal file
@ -0,0 +1,223 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief WINC1500 SPI Flash.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
/** \defgroup SPIFLASH Spi Flash
|
||||
* @file spi_flash.h
|
||||
* @brief This file describe SPI flash APIs, how to use it and limitations with each one.
|
||||
* @section Example
|
||||
* This example illustrates a complete guide of how to use these APIs.
|
||||
* @code{.c}
|
||||
#include "spi_flash.h"
|
||||
|
||||
#define DATA_TO_REPLACE "THIS IS A NEW SECTOR IN FLASH"
|
||||
|
||||
int main()
|
||||
{
|
||||
uint8 au8FlashContent[FLASH_SECTOR_SZ] = {0};
|
||||
uint32 u32FlashTotalSize = 0;
|
||||
uint32 u32FlashOffset = 0;
|
||||
|
||||
ret = m2m_wifi_download_mode();
|
||||
if(M2M_SUCCESS != ret)
|
||||
{
|
||||
printf("Unable to enter download mode\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
u32FlashTotalSize = spi_flash_get_size();
|
||||
}
|
||||
|
||||
while((u32FlashTotalSize > u32FlashOffset) && (M2M_SUCCESS == ret))
|
||||
{
|
||||
ret = spi_flash_read(au8FlashContent, u32FlashOffset, FLASH_SECTOR_SZ);
|
||||
if(M2M_SUCCESS != ret)
|
||||
{
|
||||
printf("Unable to read SPI sector\r\n");
|
||||
break;
|
||||
}
|
||||
memcpy(au8FlashContent, DATA_TO_REPLACE, strlen(DATA_TO_REPLACE));
|
||||
|
||||
ret = spi_flash_erase(u32FlashOffset, FLASH_SECTOR_SZ);
|
||||
if(M2M_SUCCESS != ret)
|
||||
{
|
||||
printf("Unable to erase SPI sector\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ret = spi_flash_write(au8FlashContent, u32FlashOffset, FLASH_SECTOR_SZ);
|
||||
if(M2M_SUCCESS != ret)
|
||||
{
|
||||
printf("Unable to write SPI sector\r\n");
|
||||
break;
|
||||
}
|
||||
u32FlashOffset += FLASH_SECTOR_SZ;
|
||||
}
|
||||
|
||||
if(M2M_SUCCESS == ret)
|
||||
{
|
||||
printf("Successful operations\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Failed operations\r\n");
|
||||
}
|
||||
|
||||
while(1);
|
||||
return M2M_SUCCESS;
|
||||
}
|
||||
* @endcode
|
||||
*/
|
||||
|
||||
#ifndef __SPI_FLASH_H__
|
||||
#define __SPI_FLASH_H__
|
||||
#include "common/include/nm_common.h"
|
||||
#include "bus_wrapper/include/nm_bus_wrapper.h"
|
||||
#include "driver/include/nmbus.h"
|
||||
#include "driver/include/nmasic.h"
|
||||
#include "spi_flash/include/spi_flash_map.h"
|
||||
|
||||
/**
|
||||
* @fn spi_flash_enable
|
||||
* @brief Enable spi flash operations
|
||||
* @version 1.0
|
||||
*/
|
||||
sint8 spi_flash_enable(uint8 enable);
|
||||
/** \defgroup SPIFLASHAPI Function
|
||||
* @ingroup SPIFLASH
|
||||
*/
|
||||
|
||||
/** @defgroup SPiFlashGetFn spi_flash_get_size
|
||||
* @ingroup SPIFLASHAPI
|
||||
*/
|
||||
/**@{*/
|
||||
/*!
|
||||
* @fn uint32 spi_flash_get_size(void);
|
||||
* @brief Returns with \ref uint32 value which is total flash size\n
|
||||
* @note Returned value in Mb (Mega Bit).
|
||||
* @return SPI flash size in case of success and a ZERO value in case of failure.
|
||||
*/
|
||||
uint32 spi_flash_get_size(void);
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup SPiFlashRead spi_flash_read
|
||||
* @ingroup SPIFLASHAPI
|
||||
*/
|
||||
/**@{*/
|
||||
/*!
|
||||
* @fn sint8 spi_flash_read(uint8 *, uint32, uint32);
|
||||
* @brief Read a specified portion of data from SPI Flash.\n
|
||||
* @param [out] pu8Buf
|
||||
* Pointer to data buffer which will fill in with data in case of successful operation.
|
||||
* @param [in] u32Addr
|
||||
* Address (Offset) to read from at the SPI flash.
|
||||
* @param [in] u32Sz
|
||||
* Total size of data to be read in bytes
|
||||
* @warning
|
||||
* - Address (offset) plus size of data must not exceed flash size.\n
|
||||
* - No firmware is required for reading from SPI flash.\n
|
||||
* - In case of there is a running firmware, it is required to pause your firmware first
|
||||
* before any trial to access SPI flash to avoid any racing between host and running firmware on bus using
|
||||
* @ref m2m_wifi_download_mode
|
||||
* @note
|
||||
* - It is blocking function\n
|
||||
* @sa m2m_wifi_download_mode, spi_flash_get_size
|
||||
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
|
||||
*/
|
||||
sint8 spi_flash_read(uint8 *pu8Buf, uint32 u32Addr, uint32 u32Sz);
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup SPiFlashWrite spi_flash_write
|
||||
* @ingroup SPIFLASHAPI
|
||||
*/
|
||||
/**@{*/
|
||||
/*!
|
||||
* @fn sint8 spi_flash_write(uint8 *, uint32, uint32);
|
||||
* @brief Write a specified portion of data to SPI Flash.\n
|
||||
* @param [in] pu8Buf
|
||||
* Pointer to data buffer which contains the required to be written.
|
||||
* @param [in] u32Offset
|
||||
* Address (Offset) to write at the SPI flash.
|
||||
* @param [in] u32Sz
|
||||
* Total number of size of data bytes
|
||||
* @note
|
||||
* - It is blocking function\n
|
||||
* - It is user's responsibility to verify that data has been written successfully
|
||||
* by reading data again and compare it with the original.
|
||||
* @warning
|
||||
* - Address (offset) plus size of data must not exceed flash size.\n
|
||||
* - No firmware is required for writing to SPI flash.\n
|
||||
* - In case of there is a running firmware, it is required to pause your firmware first
|
||||
* before any trial to access SPI flash to avoid any racing between host and running firmware on bus using
|
||||
* @ref m2m_wifi_download_mode.
|
||||
* - Before writing to any section, it is required to erase it first.
|
||||
* @sa m2m_wifi_download_mode, spi_flash_get_size, spi_flash_erase
|
||||
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
|
||||
|
||||
*/
|
||||
sint8 spi_flash_write(uint8* pu8Buf, uint32 u32Offset, uint32 u32Sz);
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup SPiFlashErase spi_flash_erase
|
||||
* @ingroup SPIFLASHAPI
|
||||
*/
|
||||
/**@{*/
|
||||
/*!
|
||||
* @fn sint8 spi_flash_erase(uint32, uint32);
|
||||
* @brief Erase a specified portion of SPI Flash.\n
|
||||
* @param [in] u32Offset
|
||||
* Address (Offset) to erase from the SPI flash.
|
||||
* @param [in] u32Sz
|
||||
* Size of SPI flash required to be erased.
|
||||
* @note It is blocking function \n
|
||||
* @warning
|
||||
* - Address (offset) plus size of data must not exceed flash size.\n
|
||||
* - No firmware is required for writing to SPI flash.\n
|
||||
* - In case of there is a running firmware, it is required to pause your firmware first
|
||||
* before any trial to access SPI flash to avoid any racing between host and running firmware on bus using
|
||||
* @ref m2m_wifi_download_mode
|
||||
* - It is blocking function\n
|
||||
* @sa m2m_wifi_download_mode, spi_flash_get_size
|
||||
* @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
|
||||
|
||||
*/
|
||||
sint8 spi_flash_erase(uint32 u32Offset, uint32 u32Sz);
|
||||
/**@}*/
|
||||
#endif //__SPI_FLASH_H__
|
||||
230
src/winc1500/include/spi_flash/include/spi_flash_map.h
Normal file
230
src/winc1500/include/spi_flash/include/spi_flash_map.h
Normal file
@ -0,0 +1,230 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief SPI Flash Memory Mapping.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SPI_FLASH_MAP_H_INCLUDED
|
||||
#define SPI_FLASH_MAP_H_INCLUDED
|
||||
|
||||
#define FLASH_MAP_VER_0 (0)
|
||||
#define FLAAH_MAP_VER_1 (1)
|
||||
|
||||
#define FLASH_MAP_VERSION FLAAH_MAP_VER_1
|
||||
|
||||
//#define DOWNLOAD_ROLLBACK
|
||||
//#define OTA_GEN
|
||||
#define _PROGRAM_POWER_SAVE_
|
||||
|
||||
/* =======*=======*=======*=======*=======
|
||||
* General Sizes for Flash Memory
|
||||
* =======*=======*=======*=======*=======
|
||||
*/
|
||||
|
||||
#define FLASH_START_ADDR (0UL)
|
||||
/*!<Starting Address of Flash Memory
|
||||
*
|
||||
*/
|
||||
#define FLASH_BLOCK_SIZE (32 * 1024UL)
|
||||
/*!<Block Size in Flash Memory
|
||||
*/
|
||||
#define FLASH_SECTOR_SZ (4 * 1024UL)
|
||||
/*!<Sector Size in Flash Memory
|
||||
*/
|
||||
#define FLASH_PAGE_SZ (256)
|
||||
/*!<Page Size in Flash Memory
|
||||
*/
|
||||
#define FLASH_2M_TOTAL_SZ (256 * 1024UL)
|
||||
/*!<Total Size of 2M Flash Memory
|
||||
*/
|
||||
#define FLASH_4M_TOTAL_SZ (512 * 1024UL)
|
||||
/*!<Total Size of 4M Flash Memory
|
||||
*/
|
||||
#define FLASH_8M_TOTAL_SZ (1024 * 1024UL)
|
||||
/*!<Total Size of 8M Flash Memory
|
||||
*/
|
||||
|
||||
/*
|
||||
* Detailed Sizes and locations for Flash Memory:
|
||||
* ____________________ ___________ ___________________________ _______________________________________________
|
||||
* | Starting Address | Size | Location's Name | Description |
|
||||
* |____________________|___________|___________________________|_______________________________________________|
|
||||
* | 0 K | 4 K | Boot Firmware | Firmware to select which version to run |
|
||||
* | 4 K | 8 K | Control Section | Structured data used by Boot firmware |
|
||||
* | 12 K | 4 K | PLL+GAIN : | LookUp Table for PLL and Gain calculations |
|
||||
* | | | PLL Size = 1K | PLL |
|
||||
* | | | GAIN Size = 3K | Gain configuration |
|
||||
* | 16 K | 4 K | CERTIFICATE | X.509 Certificate storage |
|
||||
* | 20 K | 4 K | Scratch Section | Empty Section |
|
||||
* | 24 K | 4 K | Reserved TLS Server | Reserved |
|
||||
* | 28 K | 8 K | HTTP Files | Files used with Provisioning Mode |
|
||||
* | 36 K | 4 K | Connection Parameters | Parameters for success connection to AP |
|
||||
* | 40 K | 236 K | Main Firmware/program | Main Firmware to run WiFi Chip |
|
||||
* | 276 K | 236 K | OTA Firmware | OTA firmware |
|
||||
* | 512 K Total flash size |
|
||||
* |____________________|___________|___________________________|_______________________________________________|
|
||||
*
|
||||
*
|
||||
* *Keys for Comments with each MACRO:
|
||||
* "L:xxxK" -means-> location :xxxK
|
||||
* "S:xxxK" -means-> Size is :xxxK
|
||||
*/
|
||||
|
||||
/*
|
||||
* Boot Firmware: which used to select which firmware to run
|
||||
*
|
||||
*/
|
||||
#define M2M_BOOT_FIRMWARE_STARTING_ADDR (FLASH_START_ADDR)
|
||||
#define M2M_BOOT_FIRMWARE_FLASH_SZ (FLASH_SECTOR_SZ)
|
||||
|
||||
/*
|
||||
* Control Section: which used by Boot firmware
|
||||
*
|
||||
*/
|
||||
#define M2M_CONTROL_FLASH_OFFSET (M2M_BOOT_FIRMWARE_STARTING_ADDR + M2M_BOOT_FIRMWARE_FLASH_SZ)
|
||||
#define M2M_CONTROL_FLASH_BKP_OFFSET (M2M_CONTROL_FLASH_OFFSET + FLASH_SECTOR_SZ)
|
||||
#define M2M_CONTROL_FLASH_SEC_SZ (FLASH_SECTOR_SZ)
|
||||
#define M2M_CONTROL_FLASH_TOTAL_SZ (FLASH_SECTOR_SZ * 2)
|
||||
|
||||
/*
|
||||
* LUT for PLL and TX Gain settings:
|
||||
*
|
||||
*/
|
||||
#define M2M_PLL_FLASH_OFFSET (M2M_CONTROL_FLASH_OFFSET + M2M_CONTROL_FLASH_TOTAL_SZ)
|
||||
#define M2M_PLL_FLASH_SZ (1024 * 1)
|
||||
#define M2M_GAIN_FLASH_OFFSET (M2M_PLL_FLASH_OFFSET + M2M_PLL_FLASH_SZ)
|
||||
#define M2M_GAIN_FLASH_SZ (M2M_CONFIG_SECT_TOTAL_SZ - M2M_PLL_FLASH_SZ)
|
||||
#define M2M_CONFIG_SECT_TOTAL_SZ (FLASH_SECTOR_SZ)
|
||||
|
||||
/*
|
||||
* Certificate:
|
||||
*
|
||||
*/
|
||||
#define M2M_TLS_FLASH_ROOTCERT_CACHE_OFFSET (M2M_PLL_FLASH_OFFSET + M2M_CONFIG_SECT_TOTAL_SZ)
|
||||
#define M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE (FLASH_SECTOR_SZ * 1)
|
||||
|
||||
/*
|
||||
* Scratch:
|
||||
*
|
||||
*/
|
||||
#define M2M_TLS_FLASH_SESSION_CACHE_OFFSET (M2M_TLS_FLASH_ROOTCERT_CACHE_OFFSET + M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE)
|
||||
#define M2M_TLS_FLASH_SESSION_CACHE_SIZE (FLASH_SECTOR_SZ * 1)
|
||||
|
||||
/*
|
||||
* reserved section
|
||||
*
|
||||
*/
|
||||
#define M2M_RESERVED_FLASH_OFFSET (M2M_TLS_FLASH_SESSION_CACHE_OFFSET + M2M_TLS_FLASH_SESSION_CACHE_SIZE)
|
||||
#define M2M_RESERVED_FLASH_SZ (FLASH_SECTOR_SZ * 1)
|
||||
/*
|
||||
* HTTP Files
|
||||
*
|
||||
*/
|
||||
#define M2M_HTTP_MEM_FLASH_OFFSET (M2M_RESERVED_FLASH_OFFSET + M2M_RESERVED_FLASH_SZ)
|
||||
#define M2M_HTTP_MEM_FLASH_SZ (FLASH_SECTOR_SZ * 2)
|
||||
/*
|
||||
* Saved Connection Parameters:
|
||||
*
|
||||
*/
|
||||
#define M2M_CACHED_CONNS_FLASH_OFFSET (M2M_HTTP_MEM_FLASH_OFFSET + M2M_HTTP_MEM_FLASH_SZ)
|
||||
#define M2M_CACHED_CONNS_FLASH_SZ (FLASH_SECTOR_SZ * 1)
|
||||
|
||||
/*
|
||||
*
|
||||
* Common section size
|
||||
*/
|
||||
|
||||
#define M2M_COMMON_DATA_SEC (M2M_BOOT_FIRMWARE_FLASH_SZ + M2M_CONTROL_FLASH_TOTAL_SZ + M2M_CONFIG_SECT_TOTAL_SZ + \
|
||||
M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE + M2M_TLS_FLASH_SESSION_CACHE_SIZE + \
|
||||
M2M_HTTP_MEM_FLASH_SZ + M2M_CACHED_CONNS_FLASH_SZ + M2M_RESERVED_FLASH_SZ)
|
||||
/*
|
||||
*
|
||||
* OTA image1 Offset
|
||||
*/
|
||||
|
||||
#define M2M_OTA_IMAGE1_OFFSET (M2M_CACHED_CONNS_FLASH_OFFSET + M2M_CACHED_CONNS_FLASH_SZ)
|
||||
/*
|
||||
* Firmware Offset
|
||||
*
|
||||
*/
|
||||
#if (defined _FIRMWARE_)||(defined OTA_GEN)
|
||||
#define M2M_FIRMWARE_FLASH_OFFSET (0UL)
|
||||
#else
|
||||
#if (defined DOWNLOAD_ROLLBACK)
|
||||
#define M2M_FIRMWARE_FLASH_OFFSET (M2M_OTA_IMAGE2_OFFSET)
|
||||
#else
|
||||
#define M2M_FIRMWARE_FLASH_OFFSET (M2M_OTA_IMAGE1_OFFSET)
|
||||
#endif
|
||||
#endif
|
||||
/*
|
||||
*
|
||||
* Firmware
|
||||
*/
|
||||
#define M2M_FIRMWARE_FLASH_SZ (236*1024UL)
|
||||
/**
|
||||
*
|
||||
* OTA image Size
|
||||
*/
|
||||
#define OTA_IMAGE_SIZE (M2M_FIRMWARE_FLASH_SZ)
|
||||
/**
|
||||
*
|
||||
* Flash Total size
|
||||
*/
|
||||
#define FLASH_IMAGE1_CONTENT_SZ (M2M_COMMON_DATA_SEC + OTA_IMAGE_SIZE)
|
||||
|
||||
/**
|
||||
*
|
||||
* OTA image 2 offset
|
||||
*/
|
||||
#define M2M_OTA_IMAGE2_OFFSET (FLASH_IMAGE1_CONTENT_SZ)
|
||||
|
||||
/*
|
||||
* App(Cortus App 4M): App. which runs over firmware
|
||||
*
|
||||
*/
|
||||
#define M2M_APP_4M_MEM_FLASH_SZ (FLASH_SECTOR_SZ * 10)
|
||||
#define M2M_APP_4M_MEM_FLASH_OFFSET (FLASH_4M_TOTAL_SZ - M2M_APP_4M_MEM_FLASH_SZ)
|
||||
|
||||
/* Check if total size of content
|
||||
* don't exceed total size of memory allowed
|
||||
**/
|
||||
#if (M2M_COMMON_DATA_SEC + (OTA_IMAGE_SIZE *2)> FLASH_4M_TOTAL_SZ)
|
||||
#error "Excced 4M Flash Size"
|
||||
#endif /* (FLASH_CONTENT_SZ > FLASH_TOTAL_SZ) */
|
||||
|
||||
#endif /* SPI_FLASH_MAP_H_INCLUDED */
|
||||
120
src/winc1500/src/asn1.c
Normal file
120
src/winc1500/src/asn1.c
Normal file
@ -0,0 +1,120 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief ASN1.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#include "root_cert/x509/asn1.h"
|
||||
|
||||
uint16 ASN1_GetNextElement(tstrAsn1Context *pstrAsn1Ctxt, tstrAsn1Element *pstrElement)
|
||||
{
|
||||
uint16 u16ElemLength = 0;
|
||||
|
||||
if ((pstrElement != NULL) && (pstrAsn1Ctxt != NULL)) {
|
||||
uint8 u8NLenBytes;
|
||||
|
||||
do {
|
||||
u8NLenBytes = 0;
|
||||
|
||||
/* Get the ASN.1 Element Tag. */
|
||||
pstrElement->u8Tag = *pstrAsn1Ctxt->pu8Data++;
|
||||
|
||||
/* Get the ASN.1 element length. */
|
||||
pstrElement->u32Length = *pstrAsn1Ctxt->pu8Data++;
|
||||
pstrElement->u32Length &= 0xFF;
|
||||
if (pstrElement->u32Length & NBIT7) {
|
||||
uint8 u8Idx;
|
||||
uint8 au8Tmp[4];
|
||||
|
||||
/* Multiple Length octets. */
|
||||
u8NLenBytes = (uint8)(pstrElement->u32Length & 0x03);
|
||||
pstrElement->u32Length = 0;
|
||||
|
||||
m2m_memcpy(au8Tmp, pstrAsn1Ctxt->pu8Data, u8NLenBytes);
|
||||
pstrAsn1Ctxt->pu8Data += u8NLenBytes;
|
||||
|
||||
for (u8Idx = 0; u8Idx < u8NLenBytes; u8Idx++) {
|
||||
pstrElement->u32Length +=
|
||||
(uint32)(au8Tmp[u8Idx] << ((u8NLenBytes - u8Idx - 1) * 8));
|
||||
}
|
||||
}
|
||||
|
||||
u16ElemLength += u8NLenBytes + 2 + (uint16)pstrElement->u32Length;
|
||||
} while (pstrElement->u8Tag == ASN1_NULL);
|
||||
}
|
||||
|
||||
return u16ElemLength;
|
||||
}
|
||||
|
||||
uint16 ASN1_Read(tstrAsn1Context *pstrAsn1Cxt, uint32 u32ReadLength, uint8 *pu8ReadBuffer)
|
||||
{
|
||||
uint16 u16Read = 0;
|
||||
|
||||
if (pstrAsn1Cxt != NULL) {
|
||||
uint16 u16RemLen = pstrAsn1Cxt->u16BuffLen - (uint16)(pstrAsn1Cxt->pu8Data - pstrAsn1Cxt->pu8Buff);
|
||||
|
||||
u16Read = (uint16)((u32ReadLength <= u16RemLen) ? u32ReadLength : u16RemLen);
|
||||
|
||||
if (pu8ReadBuffer != NULL) {
|
||||
m2m_memcpy(pu8ReadBuffer, pstrAsn1Cxt->pu8Data, u16Read);
|
||||
}
|
||||
|
||||
pstrAsn1Cxt->pu8Data += u16Read;
|
||||
}
|
||||
|
||||
return u16Read;
|
||||
}
|
||||
|
||||
uint16 ASN1_ReadReference(tstrAsn1Context *pstrAsn1Cxt, uint32 u32ReadLength, uint8 **ppu8ReadBuffer)
|
||||
{
|
||||
uint16 u16Read = 0;
|
||||
|
||||
if (pstrAsn1Cxt != NULL) {
|
||||
uint16 u16RemLen = pstrAsn1Cxt->u16BuffLen - (uint16)(pstrAsn1Cxt->pu8Data - pstrAsn1Cxt->pu8Buff);
|
||||
|
||||
u16Read = (uint16)((u32ReadLength <= u16RemLen) ? u32ReadLength : u16RemLen);
|
||||
|
||||
if (ppu8ReadBuffer != NULL) {
|
||||
*ppu8ReadBuffer = pstrAsn1Cxt->pu8Data;
|
||||
}
|
||||
|
||||
pstrAsn1Cxt->pu8Data += u16Read;
|
||||
}
|
||||
|
||||
return u16Read;
|
||||
}
|
||||
527
src/winc1500/src/hash.c
Normal file
527
src/winc1500/src/hash.c
Normal file
@ -0,0 +1,527 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief Hash Functions.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#include "root_cert/x509/hash.h"
|
||||
|
||||
#define SHA_SHR(x, n) ((x & 0xFFFFFFFF) >> n)
|
||||
#define SHA_SHL(x, n) ((x & 0xFFFFFFFF) << n)
|
||||
#define SHA_ROTR(x, n) (SHA_SHR(x, n) | SHA_SHL(x, (32 - n)))
|
||||
#define SHA_ROTL(x, n) (SHA_SHL(x, n) | SHA_SHR(x, (32 - n)))
|
||||
|
||||
/* MD5 specific defines. */
|
||||
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||
|
||||
#define MD5_INERMEDIATE(A, B, C, D, W, K, S) \
|
||||
{ \
|
||||
W += A + K; \
|
||||
W = B + SHA_ROTL(W, S); \
|
||||
A = D; \
|
||||
D = C; \
|
||||
C = B; \
|
||||
B = W; \
|
||||
}
|
||||
|
||||
/* SHA1 specific defines. */
|
||||
#define SHA1_CH(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
|
||||
#define SHA1_MAJ(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
|
||||
#define SHA_PARITY(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define SHA1_INERMEDIATE(A, B, C, D, E, W, K) \
|
||||
{ \
|
||||
W += SHA_ROTL(A, 5) + E + K; \
|
||||
E = D; \
|
||||
D = C; \
|
||||
C = SHA_ROTL(B, 30); \
|
||||
B = A; \
|
||||
A = W; \
|
||||
}
|
||||
|
||||
#define SHA_PAD_BYTE 0x80
|
||||
|
||||
/* SHA256 specific defines. */
|
||||
#define SHA256_SMALL_SIGMA0(x) (SHA_ROTR(x, 7) ^ SHA_ROTR(x, 18) ^ SHA_SHR(x, 3))
|
||||
#define SHA256_SMALL_SIGMA1(x) (SHA_ROTR(x, 17) ^ SHA_ROTR(x, 19) ^ SHA_SHR(x, 10))
|
||||
#define SHA256_CAP_SIGMA0(x) (SHA_ROTR(x, 2) ^ SHA_ROTR(x, 13) ^ SHA_ROTR(x, 22))
|
||||
#define SHA256_CAP_SIGMA1(x) (SHA_ROTR(x, 6) ^ SHA_ROTR(x, 11) ^ SHA_ROTR(x, 25))
|
||||
#define SHA256_MAJ(x, y, z) ((x & y) | (z & (x | y)))
|
||||
#define SHA256_CH(x, y, z) (z ^ (x & (y ^ z)))
|
||||
|
||||
static void MD5ProcessBlock(uint32 *pu32Md5State, const uint8 *pu8MessageBlock)
|
||||
{
|
||||
const uint32 T[] = {
|
||||
0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501,
|
||||
0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821,
|
||||
0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA, 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8,
|
||||
0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED, 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A,
|
||||
0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C, 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70,
|
||||
0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665,
|
||||
0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039, 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1,
|
||||
0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1, 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391
|
||||
};
|
||||
uint8 S[] = {
|
||||
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
||||
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
|
||||
};
|
||||
uint32 A, B, C, D;
|
||||
uint32 W = 0;
|
||||
uint32 X[16];
|
||||
uint8 u8Idx, u8Count;
|
||||
|
||||
A = pu32Md5State[0];
|
||||
B = pu32Md5State[1];
|
||||
C = pu32Md5State[2];
|
||||
D = pu32Md5State[3];
|
||||
|
||||
memcpy(X, pu8MessageBlock, 64);
|
||||
|
||||
for (u8Idx = 0; u8Idx < 16; u8Idx++) {
|
||||
W = F(B, C, D) + X[u8Idx];
|
||||
MD5_INERMEDIATE(A, B, C, D, W, T[u8Idx], S[u8Idx]);
|
||||
}
|
||||
|
||||
for (u8Idx = 16, u8Count = 1; u8Idx < 32; u8Idx++, u8Count += 5) {
|
||||
W = G(B, C, D) + X[u8Count & 0x0F];
|
||||
MD5_INERMEDIATE(A, B, C, D, W, T[u8Idx], S[u8Idx]);
|
||||
}
|
||||
|
||||
for (u8Idx = 32, u8Count = 5; u8Idx < 48; u8Idx++, u8Count += 3) {
|
||||
W = H(B, C, D) + X[u8Count & 0x0F];
|
||||
MD5_INERMEDIATE(A, B, C, D, W, T[u8Idx], S[u8Idx]);
|
||||
}
|
||||
|
||||
for (u8Idx = 48, u8Count = 0; u8Idx < 64; u8Idx++, u8Count += 7) {
|
||||
W = I(B, C, D) + X[u8Count & 0x0F];
|
||||
MD5_INERMEDIATE(A, B, C, D, W, T[u8Idx], S[u8Idx]);
|
||||
}
|
||||
|
||||
pu32Md5State[0] += A;
|
||||
pu32Md5State[1] += B;
|
||||
pu32Md5State[2] += C;
|
||||
pu32Md5State[3] += D;
|
||||
}
|
||||
|
||||
static void SHA1ProcessBlock(uint32 *pu32Sha1State, const uint8 *pu8MessageBlock)
|
||||
{
|
||||
/* Constants defined in FIPS-180-2, section 4.2.1 */
|
||||
const uint32 K[4] = {
|
||||
0x5A827999,
|
||||
0x6ED9EBA1,
|
||||
0x8F1BBCDC,
|
||||
0xCA62C1D6
|
||||
};
|
||||
int t; /* Loop counter */
|
||||
uint32 W[80]; /* Word sequence */
|
||||
uint32 A, B, C, D, E; /* Word buffers */
|
||||
|
||||
/* Initialize the first 16 words in the array W. */
|
||||
for (t = 0; t < 16; t++) {
|
||||
W[t] = GETU32(pu8MessageBlock, (t * 4));
|
||||
}
|
||||
|
||||
for (t = 16; t < 80; t++) {
|
||||
W[t] = SHA_ROTL((W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]), 1);
|
||||
}
|
||||
|
||||
A = pu32Sha1State[0];
|
||||
B = pu32Sha1State[1];
|
||||
C = pu32Sha1State[2];
|
||||
D = pu32Sha1State[3];
|
||||
E = pu32Sha1State[4];
|
||||
|
||||
for (t = 0; t < 20; t++) {
|
||||
W[t] += SHA1_CH(B, C, D);
|
||||
SHA1_INERMEDIATE(A, B, C, D, E, W[t], K[0])
|
||||
}
|
||||
|
||||
for (t = 20; t < 40; t++) {
|
||||
W[t] += SHA_PARITY(B, C, D);
|
||||
SHA1_INERMEDIATE(A, B, C, D, E, W[t], K[1])
|
||||
}
|
||||
|
||||
for (t = 40; t < 60; t++) {
|
||||
W[t] += SHA1_MAJ(B, C, D);
|
||||
SHA1_INERMEDIATE(A, B, C, D, E, W[t], K[2])
|
||||
}
|
||||
|
||||
for (t = 60; t < 80; t++) {
|
||||
W[t] += SHA_PARITY(B, C, D);
|
||||
SHA1_INERMEDIATE(A, B, C, D, E, W[t], K[3])
|
||||
}
|
||||
|
||||
pu32Sha1State[0] += A;
|
||||
pu32Sha1State[1] += B;
|
||||
pu32Sha1State[2] += C;
|
||||
pu32Sha1State[3] += D;
|
||||
pu32Sha1State[4] += E;
|
||||
}
|
||||
|
||||
static void SHA256ProcessBlock(uint32 *pu32Sha256State, const uint8 *pu8Data)
|
||||
{
|
||||
/* Hardcoded when using for loop unrolling. */
|
||||
/* Constants defined in SHA-256. */
|
||||
const uint32 K[] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
};
|
||||
|
||||
uint32 t; /* Loop counter */
|
||||
uint32 temp1, temp2; /* Temporary word value */
|
||||
uint32 W[64]; /* Word sequence */
|
||||
uint32 A, B, C, D, E, F, G, H; /* Word buffers */
|
||||
|
||||
A = pu32Sha256State[0];
|
||||
B = pu32Sha256State[1];
|
||||
C = pu32Sha256State[2];
|
||||
D = pu32Sha256State[3];
|
||||
E = pu32Sha256State[4];
|
||||
F = pu32Sha256State[5];
|
||||
G = pu32Sha256State[6];
|
||||
H = pu32Sha256State[7];
|
||||
|
||||
/* Initialize the first 16 words in the array W */
|
||||
for (t = 16; (t--) != 0;) {
|
||||
W[t] = pu8Data[t * 4] << 24;
|
||||
W[t] |= pu8Data[t * 4 + 1] << 16;
|
||||
W[t] |= pu8Data[t * 4 + 2] << 8;
|
||||
W[t] |= pu8Data[t * 4 + 3];
|
||||
}
|
||||
|
||||
for (t = 16; t < 64; t++) {
|
||||
W[t] = SHA256_SMALL_SIGMA1(W[t - 2]) + W[t - 7] +
|
||||
SHA256_SMALL_SIGMA0(W[t - 15]) + W[t - 16];
|
||||
}
|
||||
|
||||
for (t = 0; t < 64; t++) {
|
||||
temp1 = H + SHA256_CAP_SIGMA1(E) + SHA256_CH(E, F, G) + K[t] + W[t];
|
||||
temp2 = SHA256_CAP_SIGMA0(A) + SHA256_MAJ(A, B, C);
|
||||
|
||||
H = G;
|
||||
G = F;
|
||||
F = E;
|
||||
E = D + temp1;
|
||||
D = C;
|
||||
C = B;
|
||||
B = A;
|
||||
A = temp1 + temp2;
|
||||
}
|
||||
|
||||
pu32Sha256State[0] += A;
|
||||
pu32Sha256State[1] += B;
|
||||
pu32Sha256State[2] += C;
|
||||
pu32Sha256State[3] += D;
|
||||
pu32Sha256State[4] += E;
|
||||
pu32Sha256State[5] += F;
|
||||
pu32Sha256State[6] += G;
|
||||
pu32Sha256State[7] += H;
|
||||
}
|
||||
|
||||
static void Sha_HashUpdate(tstrHashContext *pstrHashCxt, uint8 *pu8Data, uint32 u32DataLength)
|
||||
{
|
||||
if ((pstrHashCxt != NULL) && (pu8Data != NULL) && (u32DataLength != 0)) {
|
||||
if (pstrHashCxt->fpHash != NULL) {
|
||||
uint32 u32ResidualBytes;
|
||||
uint32 u32NBlocks;
|
||||
uint32 u32Offset;
|
||||
uint32 u32BlockCount;
|
||||
|
||||
/* Get the remaining bytes from the previous update (if the length is not block alligned). */
|
||||
u32ResidualBytes = pstrHashCxt->u32TotalLength % pstrHashCxt->u8BlockSize;
|
||||
|
||||
/* Update the total data length. */
|
||||
pstrHashCxt->u32TotalLength += u32DataLength;
|
||||
|
||||
if (u32ResidualBytes != 0) {
|
||||
if ((u32ResidualBytes + u32DataLength) >= pstrHashCxt->u8BlockSize) {
|
||||
u32Offset = pstrHashCxt->u8BlockSize - u32ResidualBytes;
|
||||
memcpy(&pstrHashCxt->au8CurrentBlock[u32ResidualBytes], pu8Data, u32Offset);
|
||||
pu8Data += u32Offset;
|
||||
u32DataLength -= u32Offset;
|
||||
pstrHashCxt->fpHash(pstrHashCxt->au32HashState, pstrHashCxt->au8CurrentBlock);
|
||||
} else {
|
||||
memcpy(&pstrHashCxt->au8CurrentBlock[u32ResidualBytes], pu8Data, u32DataLength);
|
||||
u32DataLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the number of HASH BLOCKs and the residual bytes. */
|
||||
u32NBlocks = u32DataLength / pstrHashCxt->u8BlockSize;
|
||||
u32ResidualBytes = u32DataLength % pstrHashCxt->u8BlockSize;
|
||||
for (u32BlockCount = 0; u32BlockCount < u32NBlocks; u32BlockCount++) {
|
||||
pstrHashCxt->fpHash(pstrHashCxt->au32HashState, pu8Data);
|
||||
pu8Data += pstrHashCxt->u8BlockSize;
|
||||
}
|
||||
|
||||
if (u32ResidualBytes != 0) {
|
||||
memcpy(pstrHashCxt->au8CurrentBlock, pu8Data, u32ResidualBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Sha_HashFinish(tstrHashContext *pstrHashCxt, uint8 *pu8LengthPadding)
|
||||
{
|
||||
if (pstrHashCxt != NULL) {
|
||||
if (pstrHashCxt->fpHash != NULL) {
|
||||
uint32 u32Offset;
|
||||
uint32 u32PaddingLength;
|
||||
|
||||
/* Calculate the offset of the last data byte in the current block. */
|
||||
u32Offset = pstrHashCxt->u32TotalLength % pstrHashCxt->u8BlockSize;
|
||||
|
||||
/* Add the padding byte 0x80. */
|
||||
pstrHashCxt->au8CurrentBlock[u32Offset++] = SHA_PAD_BYTE;
|
||||
|
||||
/* Calculate the required padding to complete one Hash Block Size. */
|
||||
u32PaddingLength = pstrHashCxt->u8BlockSize - u32Offset;
|
||||
memset(&pstrHashCxt->au8CurrentBlock[u32Offset], 0, u32PaddingLength);
|
||||
|
||||
/* If the padding count is not enough to hold 64-bit representation */
|
||||
/* of the total input message length, one padding block is required. */
|
||||
if (u32PaddingLength < 8) {
|
||||
pstrHashCxt->fpHash(pstrHashCxt->au32HashState, pstrHashCxt->au8CurrentBlock);
|
||||
memset(pstrHashCxt->au8CurrentBlock, 0, pstrHashCxt->u8BlockSize);
|
||||
}
|
||||
|
||||
memcpy(&pstrHashCxt->au8CurrentBlock[pstrHashCxt->u8BlockSize - 8], pu8LengthPadding, 8);
|
||||
pstrHashCxt->fpHash(pstrHashCxt->au32HashState, pstrHashCxt->au8CurrentBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SHA1_Hash(tstrHashContext *pstrSha1Context, uint8 u8Flags, uint8 *pu8Data, uint32 u32DataLength, uint8 *pu8Digest) {
|
||||
if (pstrSha1Context != NULL) {
|
||||
/* SHA1 HASH INITIALIZATION. */
|
||||
if (u8Flags & SHA_FLAGS_INIT) {
|
||||
/* Initialize the Hash Context. */
|
||||
memset(pstrSha1Context, 0, sizeof(tstrHashContext));
|
||||
|
||||
/* Define SHA1 Specific parameters. */
|
||||
pstrSha1Context->fpHash = SHA1ProcessBlock;
|
||||
pstrSha1Context->u8BlockSize = SHA_BLOCK_SIZE;
|
||||
pstrSha1Context->u8DigestSize = SHA1_DIGEST_SIZE;
|
||||
|
||||
/* Set the Hash state to the initial value (specified by the standard). */
|
||||
pstrSha1Context->au32HashState[0] = 0x67452301;
|
||||
pstrSha1Context->au32HashState[1] = 0xEFCDAB89;
|
||||
pstrSha1Context->au32HashState[2] = 0x98BADCFE;
|
||||
pstrSha1Context->au32HashState[3] = 0x10325476;
|
||||
pstrSha1Context->au32HashState[4] = 0xC3D2E1F0;
|
||||
}
|
||||
|
||||
/* SHA1 HASH UPDATE. */
|
||||
if ((u8Flags & SHA_FLAGS_UPDATE) && (pu8Data != NULL)) {
|
||||
Sha_HashUpdate(pstrSha1Context, pu8Data, u32DataLength);
|
||||
}
|
||||
|
||||
/* SHA1 HASH FINISH. */
|
||||
if (u8Flags & SHA_FLAGS_FINISH) {
|
||||
uint8 au8Tmp[8];
|
||||
|
||||
/* Pack the length at the end of the padding block. */
|
||||
PUTU32(pstrSha1Context->u32TotalLength >> 29, au8Tmp, 0);
|
||||
PUTU32(pstrSha1Context->u32TotalLength << 3, au8Tmp, 4);
|
||||
Sha_HashFinish(pstrSha1Context, au8Tmp);
|
||||
|
||||
/* Compute digest. */
|
||||
PUTU32(pstrSha1Context->au32HashState[0], pu8Digest, 0);
|
||||
PUTU32(pstrSha1Context->au32HashState[1], pu8Digest, 4);
|
||||
PUTU32(pstrSha1Context->au32HashState[2], pu8Digest, 8);
|
||||
PUTU32(pstrSha1Context->au32HashState[3], pu8Digest, 12);
|
||||
PUTU32(pstrSha1Context->au32HashState[4], pu8Digest, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SHA256_Hash(tstrHashContext *pstrSha256Context, uint8 u8Flags, uint8 *pu8Data, uint32 u32DataLength, uint8 *pu8Digest)
|
||||
{
|
||||
if (pstrSha256Context != NULL) {
|
||||
/* SHA256 HASH INITIALIZATION. */
|
||||
if (u8Flags & SHA_FLAGS_INIT) {
|
||||
/* Initialize the Hash Context. */
|
||||
memset(pstrSha256Context, 0, sizeof(tstrHashContext));
|
||||
|
||||
/* Define SHA256 specific parameters. */
|
||||
pstrSha256Context->fpHash = SHA256ProcessBlock;
|
||||
pstrSha256Context->u8BlockSize = SHA_BLOCK_SIZE;
|
||||
pstrSha256Context->u8DigestSize = SHA256_DIGEST_SIZE;
|
||||
|
||||
/* Set the Hash state to the initial value (specified by the standard). */
|
||||
pstrSha256Context->au32HashState[0] = 0x6A09E667;
|
||||
pstrSha256Context->au32HashState[1] = 0xBB67AE85;
|
||||
pstrSha256Context->au32HashState[2] = 0x3C6EF372;
|
||||
pstrSha256Context->au32HashState[3] = 0xA54FF53A;
|
||||
pstrSha256Context->au32HashState[4] = 0x510E527F;
|
||||
pstrSha256Context->au32HashState[5] = 0x9B05688C;
|
||||
pstrSha256Context->au32HashState[6] = 0x1F83D9AB;
|
||||
pstrSha256Context->au32HashState[7] = 0x5BE0CD19;
|
||||
}
|
||||
|
||||
/* SHA256 HASH UPDATE. */
|
||||
if ((u8Flags & SHA_FLAGS_UPDATE) && (pu8Data != NULL)) {
|
||||
Sha_HashUpdate(pstrSha256Context, pu8Data, u32DataLength);
|
||||
}
|
||||
|
||||
/* SHA256 HASH FINISH. */
|
||||
if ((u8Flags & SHA_FLAGS_FINISH) && (pu8Digest != NULL)) {
|
||||
uint8 au8Tmp[8];
|
||||
|
||||
/* Pack the length at the end of the padding block. */
|
||||
PUTU32(pstrSha256Context->u32TotalLength >> 29, au8Tmp, 0);
|
||||
PUTU32(pstrSha256Context->u32TotalLength << 3, au8Tmp, 4);
|
||||
Sha_HashFinish(pstrSha256Context, au8Tmp);
|
||||
|
||||
/* Compute digest. */
|
||||
PUTU32(pstrSha256Context->au32HashState[0], pu8Digest, 0);
|
||||
PUTU32(pstrSha256Context->au32HashState[1], pu8Digest, 4);
|
||||
PUTU32(pstrSha256Context->au32HashState[2], pu8Digest, 8);
|
||||
PUTU32(pstrSha256Context->au32HashState[3], pu8Digest, 12);
|
||||
PUTU32(pstrSha256Context->au32HashState[4], pu8Digest, 16);
|
||||
PUTU32(pstrSha256Context->au32HashState[5], pu8Digest, 20);
|
||||
PUTU32(pstrSha256Context->au32HashState[6], pu8Digest, 24);
|
||||
PUTU32(pstrSha256Context->au32HashState[7], pu8Digest, 28);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MD5_Hash( tstrHashContext *pstrMD5Context, uint8 u8Flags, uint8 *pu8Data, uint32 u32DataLength, uint8 *pu8Digest)
|
||||
{
|
||||
if (pstrMD5Context != NULL) {
|
||||
/* SHA256 HASH INITIALIZATION. */
|
||||
if (u8Flags & 1) {
|
||||
/* Initialize the Hash Context. */
|
||||
memset(pstrMD5Context, 0, sizeof(tstrHashContext));
|
||||
|
||||
/* Define SHA256 specific parameters. */
|
||||
pstrMD5Context->fpHash = MD5ProcessBlock;
|
||||
pstrMD5Context->u8BlockSize = 64;
|
||||
pstrMD5Context->u8DigestSize = 16;
|
||||
|
||||
pstrMD5Context->au32HashState[0] = 0x67452301;
|
||||
pstrMD5Context->au32HashState[1] = 0xEFCDAB89;
|
||||
pstrMD5Context->au32HashState[2] = 0x98BADCFE;
|
||||
pstrMD5Context->au32HashState[3] = 0x10325476;
|
||||
}
|
||||
|
||||
/* SHA256 HASH UPDATE. */
|
||||
if ((u8Flags & 2) && (pu8Data != NULL)) {
|
||||
Sha_HashUpdate(pstrMD5Context, pu8Data, u32DataLength);
|
||||
}
|
||||
|
||||
/* SHA256 HASH FINISH. */
|
||||
if ((u8Flags & 4) && (pu8Digest != NULL)) {
|
||||
uint8 au8Tmp[8] = {0};
|
||||
uint8 u8Idx, u8ByteIdx = 0;
|
||||
uint32 u32LengthBits = pstrMD5Context->u32TotalLength << 3;
|
||||
|
||||
/* Pack the length at the end of the padding block. */
|
||||
au8Tmp[0] = BYTE_0(u32LengthBits);
|
||||
au8Tmp[1] = BYTE_1(u32LengthBits);
|
||||
au8Tmp[2] = BYTE_2(u32LengthBits);
|
||||
au8Tmp[3] = BYTE_3(u32LengthBits);
|
||||
|
||||
Sha_HashFinish(pstrMD5Context, au8Tmp);
|
||||
|
||||
/* Compute digest. */
|
||||
for (u8Idx = 0; u8Idx < (MD5_DIGEST_SIZE / 4); u8Idx++) {
|
||||
pu8Digest[u8ByteIdx++] = BYTE_0(pstrMD5Context->au32HashState[u8Idx]);
|
||||
pu8Digest[u8ByteIdx++] = BYTE_1(pstrMD5Context->au32HashState[u8Idx]);
|
||||
pu8Digest[u8ByteIdx++] = BYTE_2(pstrMD5Context->au32HashState[u8Idx]);
|
||||
pu8Digest[u8ByteIdx++] = BYTE_3(pstrMD5Context->au32HashState[u8Idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Perform the HMAC operation on a given vector of data streams.
|
||||
*/
|
||||
void HMAC_Vector(tpfHash fpHash, uint8 *pu8Key, uint32 u32KeyLength, tstrBuffer *pstrInData, uint8 u8NumInputs, uint8 *pu8Out)
|
||||
{
|
||||
if ((pu8Key != NULL) && (pstrInData != NULL) && (pu8Out != NULL) && (fpHash != NULL)) {
|
||||
tstrHashContext strHashContext;
|
||||
uint32 i;
|
||||
uint8 au8TmpBuffer[SHA_BLOCK_SIZE];
|
||||
uint8 au8TmpHash[SHA_MAX_DIGEST_SIZE];
|
||||
uint8 au8TmpKey[SHA_MAX_DIGEST_SIZE];
|
||||
|
||||
/* HMAC INIT. */
|
||||
/* Adjust the key size. */
|
||||
if (u32KeyLength > SHA_BLOCK_SIZE) {
|
||||
fpHash(&strHashContext, SHA_FLAGS_FULL_HASH, pu8Key, u32KeyLength, pu8Key);
|
||||
u32KeyLength = strHashContext.u8DigestSize;
|
||||
pu8Key = au8TmpKey;
|
||||
}
|
||||
|
||||
memset(au8TmpBuffer, 0x36, SHA_BLOCK_SIZE);
|
||||
for (i = 0; i < u32KeyLength; i++) {
|
||||
au8TmpBuffer[i] ^= pu8Key[i];
|
||||
}
|
||||
|
||||
/* Start hashing. */
|
||||
fpHash(&strHashContext, SHA_FLAGS_INIT | SHA_FLAGS_UPDATE, au8TmpBuffer, SHA_BLOCK_SIZE, NULL);
|
||||
|
||||
/* HMAC UPDATE. */
|
||||
for (i = 0; i < u8NumInputs; i++) {
|
||||
fpHash(&strHashContext, SHA_FLAGS_UPDATE, pstrInData[i].pu8Data, pstrInData[i].u16BufferSize, NULL);
|
||||
}
|
||||
|
||||
fpHash(&strHashContext, SHA_FLAGS_FINISH, NULL, 0, au8TmpHash);
|
||||
|
||||
/* HMAC Finalize. */
|
||||
memset(au8TmpBuffer, 0x5C, SHA_BLOCK_SIZE);
|
||||
for (i = 0; i < u32KeyLength; i++) {
|
||||
au8TmpBuffer[i] ^= pu8Key[i];
|
||||
}
|
||||
|
||||
fpHash(&strHashContext, SHA_FLAGS_INIT | SHA_FLAGS_UPDATE, au8TmpBuffer, SHA_BLOCK_SIZE, NULL);
|
||||
fpHash(&strHashContext, SHA_FLAGS_UPDATE | SHA_FLAGS_FINISH, au8TmpHash, strHashContext.u8DigestSize, pu8Out);
|
||||
}
|
||||
}
|
||||
194
src/winc1500/src/programmer.c
Normal file
194
src/winc1500/src/programmer.c
Normal file
@ -0,0 +1,194 @@
|
||||
#include <ff.h>
|
||||
#include <stdio.h>
|
||||
#include "fb_alloc.h"
|
||||
|
||||
#include "programmer/programmer.h"
|
||||
#include "root_cert/root_setup.h"
|
||||
#include "spi_flash/include/spi_flash_map.h"
|
||||
|
||||
#define FW_PATH "/firmware/bin/m2m_aio_3a0.bin"
|
||||
#define CERT_DIGI_PATH "/firmware/cert/DigiCert_Root.cer"
|
||||
#define CERT_DIGISHA2_PATH "/firmware/cert/DigiCertSHA2_Root.cer"
|
||||
#define CERT_GEOTRUST_PATH "/firmware/cert/GeoTrustGlobalCA_Root.cer"
|
||||
#define CERT_RADIUS_PATH "/firmware/cert/Radius_Root.cer"
|
||||
#define CERT_VERISIGN_PATH "/firmware/cert/VeriSign_Root.cer"
|
||||
|
||||
#define MIN(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a < _b ? _a : _b; })
|
||||
|
||||
/**
|
||||
* Program firmware to WINC1500 memory.
|
||||
*
|
||||
* return M2M_SUCCESS on success, error code otherwise.
|
||||
*/
|
||||
int burn_firmware()
|
||||
{
|
||||
FIL fp;
|
||||
uint32_t offset = 0;
|
||||
UINT bytes = 0, bytes_out=0;
|
||||
|
||||
int ret = M2M_ERR_FAIL;
|
||||
uint8_t *buf = fb_alloc(FLASH_SECTOR_SZ);
|
||||
|
||||
if (f_open(&fp, FW_PATH, FA_READ|FA_OPEN_EXISTING) != FR_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Firmware image size
|
||||
uint32_t size = f_size(&fp);
|
||||
|
||||
while (size) {
|
||||
// Read a chuck (max FLASH_SECTOR_SZ bytes).
|
||||
bytes = MIN(size, FLASH_SECTOR_SZ);
|
||||
if (f_read(&fp, buf, bytes, &bytes_out) != FR_OK || bytes != bytes_out) {
|
||||
printf("burn_firmware: file read error!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Write firmware sector to the WINC1500 memory.
|
||||
if (programmer_write_firmware_image(buf, offset, bytes) != M2M_SUCCESS) {
|
||||
printf("burn_firmware: write error!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
size -= bytes;
|
||||
offset += bytes;
|
||||
}
|
||||
|
||||
ret = M2M_SUCCESS;
|
||||
|
||||
error:
|
||||
fb_free();
|
||||
f_close(&fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify WINC1500 firmware
|
||||
* return M2M_SUCCESS on success, error code otherwise.
|
||||
*/
|
||||
int verify_firmware()
|
||||
{
|
||||
FIL fp;
|
||||
uint32_t offset = 0;
|
||||
UINT bytes = 0, bytes_out=0;
|
||||
|
||||
int ret = M2M_ERR_FAIL;
|
||||
uint8_t *file_buf = fb_alloc(FLASH_SECTOR_SZ);
|
||||
uint8_t *flash_buf = fb_alloc(FLASH_SECTOR_SZ);
|
||||
|
||||
if (f_open(&fp, FW_PATH, FA_READ|FA_OPEN_EXISTING) != FR_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Firmware image size
|
||||
uint32_t size = f_size(&fp);
|
||||
|
||||
while (size) {
|
||||
// Firmware chuck size (max FLASH_SECTOR_SZ bytes).
|
||||
bytes = MIN(size, FLASH_SECTOR_SZ);
|
||||
|
||||
if (f_read(&fp, file_buf, bytes, &bytes_out) != FR_OK || bytes_out != bytes) {
|
||||
printf("burn_firmware: file read error!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (programmer_read_firmware_image(flash_buf, offset, bytes) != M2M_SUCCESS) {
|
||||
printf("verify_firmware: read access failed on firmware section!\r\n");
|
||||
return M2M_ERR_FAIL;
|
||||
}
|
||||
|
||||
for (int i=0; i<bytes; i++) {
|
||||
if (flash_buf[i] != file_buf[i]) {
|
||||
printf("verify_firmware: verification failed! offset:%d flash:%x file:%x\n", i, flash_buf[i], file_buf[i]);
|
||||
return M2M_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
size -= bytes;
|
||||
offset += bytes;
|
||||
}
|
||||
|
||||
ret = M2M_SUCCESS;
|
||||
|
||||
error:
|
||||
fb_free();
|
||||
fb_free();
|
||||
f_close(&fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int burn_certificate(const char *cert, const char *path)
|
||||
{
|
||||
FIL fp;
|
||||
int ret = M2M_ERR_FAIL;
|
||||
// This is big enough for the max certificate
|
||||
char *buf = fb_alloc(2048);
|
||||
|
||||
if (f_open(&fp, path, FA_READ|FA_OPEN_EXISTING) != FR_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
UINT bytes_out=0;
|
||||
UINT bytes = f_size(&fp);
|
||||
|
||||
// Read root certificate
|
||||
if (f_read(&fp, buf, bytes, &bytes_out) != FR_OK || bytes_out != bytes) {
|
||||
printf("burn_certificate: file read error!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Write root certificate to the WINC1500 memory.
|
||||
ret = WriteRootCertificate(cert, buf, bytes);
|
||||
|
||||
error:
|
||||
fb_free();
|
||||
f_close(&fp);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Program root certificates to WINC1500 memory.
|
||||
*
|
||||
* return: M2M_SUCCESS on success, error code otherwise.
|
||||
*/
|
||||
int burn_certificates()
|
||||
{
|
||||
const char *root_certs[][2] = {
|
||||
{"DigiCert_Root", CERT_DIGI_PATH },
|
||||
{"DigiCertSHA2_Root", CERT_DIGISHA2_PATH},
|
||||
{"GeoTrustGlobalCA_Root", CERT_GEOTRUST_PATH},
|
||||
{"Radius_Root", CERT_RADIUS_PATH },
|
||||
{"VeriSign_Root", CERT_VERISIGN_PATH},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
int ret=M2M_SUCCESS;
|
||||
for (int i=0; ret==M2M_SUCCESS && root_certs[i][0]; i++) {
|
||||
ret = burn_certificate(root_certs[i][0], root_certs[i][1]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Verify WINC1500 certificates
|
||||
* return M2M_SUCCESS on success, error code otherwise.
|
||||
*/
|
||||
int verify_certificate(void)
|
||||
{
|
||||
uint8_t flash_content[FLASH_SECTOR_SZ] = {0};
|
||||
|
||||
/* Dump entire root certificate memory region. */
|
||||
if (programmer_read_cert_image(flash_content) != M2M_SUCCESS) {
|
||||
printf("verify_certificate: read access failed on certificate section!\r\n");
|
||||
return M2M_ERR_FAIL;
|
||||
}
|
||||
|
||||
return M2M_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
253
src/winc1500/src/root_setup.c
Normal file
253
src/winc1500/src/root_setup.c
Normal file
@ -0,0 +1,253 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief Root Certificate Setup.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fb_alloc.h"
|
||||
#include "root_cert/x509/x509_cert.h"
|
||||
#include "root_cert/root_setup.h"
|
||||
#include "programmer/programmer_apis.h"
|
||||
|
||||
//#define ENABLE_VERIFICATION
|
||||
|
||||
#define WORD_ALIGN(val) (((val) & 0x03) ? ((val) + 4 - ((val) & 0x03)) : (val))
|
||||
|
||||
#define ROOT_CERT_FLASH_START_PATTERN_LENGTH 16
|
||||
|
||||
#define ROOT_CERT_FLASH_START_PATTERN \
|
||||
{ \
|
||||
0x01, 0xF1, 0x02, 0xF2, 0x03, 0xF3, 0x04, 0xF4, \
|
||||
0x05, 0xF5, 0x06, 0xF6, 0x07, 0xF7, 0x08, 0xF8 \
|
||||
}
|
||||
|
||||
/*!< A Pattern is stored at the start of the root certificate flash area
|
||||
* in order to identify if the flash is written before or not.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint8 au8StartPattern[ROOT_CERT_FLASH_START_PATTERN_LENGTH];
|
||||
uint32 u32nCerts;
|
||||
} tstrRootCertFlashHeader;
|
||||
|
||||
typedef struct {
|
||||
uint8 au8SHA1NameHash[SHA1_DIGEST_SIZE];
|
||||
uint16 u16NSize;
|
||||
uint16 u16ESize;
|
||||
uint8 au8ValidityStartDate[20];
|
||||
uint8 au8ValidityExpDate[20];
|
||||
} tstrRootCertEntryHeader;
|
||||
|
||||
#ifdef ENABLE_VERIFICATION
|
||||
static uint8 gau8Verify[M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Parse and validate certificate.
|
||||
*
|
||||
* \return M2M_SUCCESS on success, error code otherwise.
|
||||
*/
|
||||
static int GetRootCertificate(uint8 *pcRootCertFileData, uint32 u32FileSize, tstrX509Cert *pstrX509, uint8 **ppu8CertificateBuffer)
|
||||
{
|
||||
sint8 ret = -1;
|
||||
|
||||
/* Decode the certificate. */
|
||||
if (X509Cert_Decode(pcRootCertFileData, u32FileSize, pstrX509, 1) == X509_SUCCESS) {
|
||||
printf(">Root certificate verified OK.\n");
|
||||
*ppu8CertificateBuffer = pcRootCertFileData;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Update the root certificate list.
|
||||
*
|
||||
* \return M2M_SUCCESS on success, error code otherwise.
|
||||
*/
|
||||
static sint8 UpdateRootList(tstrX509Cert *pstrRootCert, uint8 *gau8RootCertMem)
|
||||
{
|
||||
uint32 u32Idx;
|
||||
uint8 bIncrement = 0;
|
||||
uint32 u32nStoredCerts = 0;
|
||||
uint8 au8StartPattern[] = ROOT_CERT_FLASH_START_PATTERN;
|
||||
tstrRootCertFlashHeader *pstrRootFlashHdr;
|
||||
tstrRootCertEntryHeader *pstrEntryHDR;
|
||||
uint16 u16BufferOffset;
|
||||
uint16 u16WriteSize;
|
||||
tstrRSAPublicKey *pstrKey;
|
||||
|
||||
pstrKey = &pstrRootCert->strPubKey.strRSAKey;
|
||||
pstrRootFlashHdr = (tstrRootCertFlashHeader *)((void *)gau8RootCertMem);
|
||||
u16BufferOffset = sizeof(tstrRootCertFlashHeader);
|
||||
u16WriteSize = pstrKey->u16ESize + pstrKey->u16NSize + sizeof(tstrRootCertEntryHeader);
|
||||
|
||||
/* Check if the flash has been written before. */
|
||||
if (!memcmp(au8StartPattern, pstrRootFlashHdr->au8StartPattern, ROOT_CERT_FLASH_START_PATTERN_LENGTH)) {
|
||||
u32nStoredCerts = pstrRootFlashHdr->u32nCerts;
|
||||
bIncrement = 1;
|
||||
|
||||
for (u32Idx = 0; u32Idx < u32nStoredCerts; u32Idx++) {
|
||||
pstrEntryHDR = (tstrRootCertEntryHeader *)((void *)&gau8RootCertMem[u16BufferOffset]);
|
||||
|
||||
/* Check for match (equivalent NameSHA1). */
|
||||
if (!memcmp(pstrRootCert->strSubject.au8NameSHA1, pstrEntryHDR->au8SHA1NameHash, SHA1_DIGEST_SIZE)) {
|
||||
/* The current entry will be overwritten. */
|
||||
bIncrement = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
u16BufferOffset += sizeof(tstrRootCertEntryHeader) + WORD_ALIGN(pstrEntryHDR->u16NSize + pstrEntryHDR->u16ESize);
|
||||
}
|
||||
} else {
|
||||
pstrRootFlashHdr->u32nCerts = 0;
|
||||
memcpy(pstrRootFlashHdr->au8StartPattern, au8StartPattern, ROOT_CERT_FLASH_START_PATTERN_LENGTH);
|
||||
bIncrement = 1;
|
||||
}
|
||||
|
||||
if (bIncrement) {
|
||||
/* A new certificate is to be inserted into the flash. */
|
||||
/* Increment the number of stored Certificates. */
|
||||
if (u16BufferOffset + u16WriteSize > M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE) {
|
||||
printf("(ERROR) Root Certificate Flash is Full\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pstrRootFlashHdr->u32nCerts++;
|
||||
}
|
||||
|
||||
/* Write Root Certificate to flash. The entry is ordered as follows:
|
||||
- SHA1_DIGEST_SIZE --> NameSHA1 of the Root certificate.
|
||||
- uint16 --> N_SIZE (Byte count for the RSA modulus N).
|
||||
- uint16 --> E_SIZE (Byte count for the RSA public exponent E).
|
||||
- START_DATE --> Start date of the root certificate(20 bytes).
|
||||
- EXPIRATION_DATE --> Expiration date of the root certificate(20 bytes).
|
||||
- N_SIZE --> RSA Modulus N.
|
||||
- E_SIZE --> RSA Public exponent.
|
||||
*/
|
||||
|
||||
pstrEntryHDR = (tstrRootCertEntryHeader *)((void *)&gau8RootCertMem[u16BufferOffset]);
|
||||
|
||||
/* NameSHA1 */
|
||||
memcpy(pstrEntryHDR->au8SHA1NameHash, pstrRootCert->strSubject.au8NameSHA1, SHA1_DIGEST_SIZE);
|
||||
|
||||
/* N_SIZE */
|
||||
pstrEntryHDR->u16NSize = pstrKey->u16NSize;
|
||||
|
||||
/* E_SIZE */
|
||||
pstrEntryHDR->u16ESize = pstrKey->u16ESize;
|
||||
|
||||
/* Start Date */
|
||||
memcpy(pstrEntryHDR->au8ValidityStartDate, pstrRootCert->strStartDate.au8Time, 20);
|
||||
|
||||
/* Expiration Date */
|
||||
memcpy(pstrEntryHDR->au8ValidityExpDate, pstrRootCert->strExpiryDate.au8Time, 20);
|
||||
u16BufferOffset += sizeof(tstrRootCertEntryHeader);
|
||||
|
||||
/* N */
|
||||
memcpy(&gau8RootCertMem[u16BufferOffset], pstrKey->pu8N, pstrKey->u16NSize);
|
||||
|
||||
/* E */
|
||||
memcpy(&gau8RootCertMem[u16BufferOffset + pstrKey->u16NSize], pstrKey->pu8E, pstrKey->u16ESize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write root certificate to flash.
|
||||
*
|
||||
* \return M2M_SUCCESS on success, error code otherwise.
|
||||
*/
|
||||
int WriteRootCertificate(const char *filename, char *pcRootCertFileData, uint32 u32FileSize)
|
||||
{
|
||||
uint8 *pu8CertBuffer;
|
||||
tstrX509Cert strX509Root;
|
||||
#ifdef ENABLE_VERIFICATION
|
||||
uint32 u32Idx;
|
||||
#endif
|
||||
int ret = -1;
|
||||
|
||||
uint8 *gau8RootCertMem = fb_alloc(M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE);
|
||||
|
||||
/* Read Certificate File. */
|
||||
if (GetRootCertificate((uint8 *)pcRootCertFileData, u32FileSize, &strX509Root, &pu8CertBuffer) == 0) {
|
||||
programmer_read_cert_image(gau8RootCertMem);
|
||||
|
||||
if (UpdateRootList(&strX509Root, gau8RootCertMem) == 0) {
|
||||
/* Erase memory. */
|
||||
ret = programmer_erase_cert_image();
|
||||
if (M2M_SUCCESS != ret) {
|
||||
goto END;
|
||||
}
|
||||
|
||||
nm_bsp_sleep(50);
|
||||
|
||||
/* Write. */
|
||||
printf(">Writing the certificate to SPI flash...\r\n");
|
||||
ret = programmer_write_cert_image(gau8RootCertMem);
|
||||
if (M2M_SUCCESS != ret) {
|
||||
goto END;
|
||||
}
|
||||
|
||||
printf("Done\r\n");
|
||||
|
||||
#ifdef ENABLE_VERIFICATION
|
||||
/* Verification. */
|
||||
memset(gau8Verify, 0, M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE);
|
||||
programmer_read_cert_image(gau8Verify);
|
||||
|
||||
for (u32Idx = 0; u32Idx < M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE; u32Idx++) {
|
||||
if (gau8RootCertMem[u32Idx] != gau8Verify[u32Idx]) {
|
||||
printf("ERROR verification failed at %u\n", u32Idx);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
printf("\r\n>>>Invalid root certificate %s\n", filename);
|
||||
}
|
||||
|
||||
END:
|
||||
fb_free();
|
||||
return ret;
|
||||
}
|
||||
690
src/winc1500/src/spi_flash.c
Normal file
690
src/winc1500/src/spi_flash.c
Normal file
@ -0,0 +1,690 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief WINC1500 SPI Flash.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#include "spi_flash/include/spi_flash.h"
|
||||
#define DUMMY_REGISTER (0x1084)
|
||||
#define HOST_SHARE_MEM_BASE (0xd0000UL)
|
||||
#define CORTUS_SHARE_MEM_BASE (0x60000000UL)
|
||||
#define NMI_SPI_FLASH_ADDR (0x111c)
|
||||
/***********************************************************
|
||||
SPI Flash DMA
|
||||
***********************************************************/
|
||||
#define GET_UINT32(X,Y) (X[0+Y] + ((uint32)X[1+Y]<<8) + ((uint32)X[2+Y]<<16) +((uint32)X[3+Y]<<24))
|
||||
#define SPI_FLASH_BASE (0x10200)
|
||||
#define SPI_FLASH_MODE (SPI_FLASH_BASE + 0x00)
|
||||
#define SPI_FLASH_CMD_CNT (SPI_FLASH_BASE + 0x04)
|
||||
#define SPI_FLASH_DATA_CNT (SPI_FLASH_BASE + 0x08)
|
||||
#define SPI_FLASH_BUF1 (SPI_FLASH_BASE + 0x0c)
|
||||
#define SPI_FLASH_BUF2 (SPI_FLASH_BASE + 0x10)
|
||||
#define SPI_FLASH_BUF_DIR (SPI_FLASH_BASE + 0x14)
|
||||
#define SPI_FLASH_TR_DONE (SPI_FLASH_BASE + 0x18)
|
||||
#define SPI_FLASH_DMA_ADDR (SPI_FLASH_BASE + 0x1c)
|
||||
#define SPI_FLASH_MSB_CTL (SPI_FLASH_BASE + 0x20)
|
||||
#define SPI_FLASH_TX_CTL (SPI_FLASH_BASE + 0x24)
|
||||
|
||||
/*********************************************/
|
||||
/* STATIC FUNCTIONS */
|
||||
/*********************************************/
|
||||
|
||||
/**
|
||||
* @fn spi_flash_read_status_reg
|
||||
* @brief Read status register
|
||||
* @param[OUT] val
|
||||
value of status reg
|
||||
* @return Status of execution
|
||||
*/
|
||||
static sint8 spi_flash_read_status_reg(uint8 * val)
|
||||
{
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
uint8 cmd[1];
|
||||
uint32 reg;
|
||||
|
||||
cmd[0] = 0x05;
|
||||
|
||||
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 4);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
|
||||
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER);
|
||||
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
|
||||
do
|
||||
{
|
||||
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)®);
|
||||
if(M2M_SUCCESS != ret) break;
|
||||
}
|
||||
while(reg != 1);
|
||||
|
||||
reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0);
|
||||
*val = (uint8)(reg & 0xff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef DISABLE_UNSED_FLASH_FUNCTIONS
|
||||
/**
|
||||
* @fn spi_flash_read_security_reg
|
||||
* @brief Read security register
|
||||
* @return Security register value
|
||||
*/
|
||||
static uint8 spi_flash_read_security_reg(void)
|
||||
{
|
||||
uint8 cmd[1];
|
||||
uint32 reg;
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
|
||||
cmd[0] = 0x2b;
|
||||
|
||||
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 1);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
|
||||
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER);
|
||||
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
|
||||
do
|
||||
{
|
||||
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)®);
|
||||
if(M2M_SUCCESS != ret) break;
|
||||
}
|
||||
while(reg != 1);
|
||||
reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0);
|
||||
|
||||
return (sint8)reg & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn spi_flash_gang_unblock
|
||||
* @brief Unblock all flash area
|
||||
*/
|
||||
static sint8 spi_flash_gang_unblock(void)
|
||||
{
|
||||
uint8 cmd[1];
|
||||
uint32 val = 0;
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
|
||||
cmd[0] = 0x98;
|
||||
|
||||
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
|
||||
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
|
||||
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
|
||||
do
|
||||
{
|
||||
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
|
||||
if(M2M_SUCCESS != ret) break;
|
||||
}
|
||||
while(val != 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn spi_flash_clear_security_flags
|
||||
* @brief Clear all security flags
|
||||
*/
|
||||
static sint8 spi_flash_clear_security_flags(void)
|
||||
{
|
||||
uint8 cmd[1];
|
||||
uint32 val = 0;
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
|
||||
cmd[0] = 0x30;
|
||||
|
||||
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
|
||||
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
|
||||
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
|
||||
do
|
||||
{
|
||||
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
|
||||
if(M2M_SUCCESS != ret) break;
|
||||
}
|
||||
while(val != 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @fn spi_flash_load_to_cortus_mem
|
||||
* @brief Load data from SPI flash into cortus memory
|
||||
* @param[IN] u32MemAdr
|
||||
* Cortus load address. It must be set to its AHB access address
|
||||
* @param[IN] u32FlashAdr
|
||||
* Address to read from at the SPI flash
|
||||
* @param[IN] u32Sz
|
||||
* Data size
|
||||
* @return Status of execution
|
||||
*/
|
||||
static sint8 spi_flash_load_to_cortus_mem(uint32 u32MemAdr, uint32 u32FlashAdr, uint32 u32Sz)
|
||||
{
|
||||
uint8 cmd[5];
|
||||
uint32 val = 0;
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
|
||||
cmd[0] = 0x0b;
|
||||
cmd[1] = (uint8)(u32FlashAdr >> 16);
|
||||
cmd[2] = (uint8)(u32FlashAdr >> 8);
|
||||
cmd[3] = (uint8)(u32FlashAdr);
|
||||
cmd[4] = 0xA5;
|
||||
|
||||
ret += nm_write_reg(SPI_FLASH_DATA_CNT, u32Sz);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(cmd[1]<<8)|(cmd[2]<<16)|(cmd[3]<<24));
|
||||
ret += nm_write_reg(SPI_FLASH_BUF2, cmd[4]);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x1f);
|
||||
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, u32MemAdr);
|
||||
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 5 | (1<<7));
|
||||
do
|
||||
{
|
||||
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
|
||||
if(M2M_SUCCESS != ret) break;
|
||||
}
|
||||
while(val != 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn spi_flash_sector_erase
|
||||
* @brief Erase sector (4KB)
|
||||
* @param[IN] u32FlashAdr
|
||||
* Any memory address within the sector
|
||||
* @return Status of execution
|
||||
*/
|
||||
static sint8 spi_flash_sector_erase(uint32 u32FlashAdr)
|
||||
{
|
||||
uint8 cmd[4];
|
||||
uint32 val = 0;
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
|
||||
cmd[0] = 0x20;
|
||||
cmd[1] = (uint8)(u32FlashAdr >> 16);
|
||||
cmd[2] = (uint8)(u32FlashAdr >> 8);
|
||||
cmd[3] = (uint8)(u32FlashAdr);
|
||||
|
||||
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(cmd[1]<<8)|(cmd[2]<<16)|(cmd[3]<<24));
|
||||
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x0f);
|
||||
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
|
||||
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 4 | (1<<7));
|
||||
do
|
||||
{
|
||||
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
|
||||
if(M2M_SUCCESS != ret) break;
|
||||
}
|
||||
while(val != 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn spi_flash_write_enable
|
||||
* @brief Send write enable command to SPI flash
|
||||
* @return Status of execution
|
||||
*/
|
||||
static sint8 spi_flash_write_enable(void)
|
||||
{
|
||||
uint8 cmd[1];
|
||||
uint32 val = 0;
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
|
||||
cmd[0] = 0x06;
|
||||
|
||||
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
|
||||
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
|
||||
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
|
||||
do
|
||||
{
|
||||
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
|
||||
if(M2M_SUCCESS != ret) break;
|
||||
}
|
||||
while(val != 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn spi_flash_write_disable
|
||||
* @brief Send write disable command to SPI flash
|
||||
*/
|
||||
static sint8 spi_flash_write_disable(void)
|
||||
{
|
||||
uint8 cmd[1];
|
||||
uint32 val = 0;
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
cmd[0] = 0x04;
|
||||
|
||||
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
|
||||
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
|
||||
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
|
||||
do
|
||||
{
|
||||
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
|
||||
if(M2M_SUCCESS != ret) break;
|
||||
}
|
||||
while(val != 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn spi_flash_page_program
|
||||
* @brief Write data (less than page size) from cortus memory to SPI flash
|
||||
* @param[IN] u32MemAdr
|
||||
* Cortus data address. It must be set to its AHB access address
|
||||
* @param[IN] u32FlashAdr
|
||||
* Address to write to at the SPI flash
|
||||
* @param[IN] u32Sz
|
||||
* Data size
|
||||
*/
|
||||
static sint8 spi_flash_page_program(uint32 u32MemAdr, uint32 u32FlashAdr, uint32 u32Sz)
|
||||
{
|
||||
uint8 cmd[4];
|
||||
uint32 val = 0;
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
|
||||
cmd[0] = 0x02;
|
||||
cmd[1] = (uint8)(u32FlashAdr >> 16);
|
||||
cmd[2] = (uint8)(u32FlashAdr >> 8);
|
||||
cmd[3] = (uint8)(u32FlashAdr);
|
||||
|
||||
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(cmd[1]<<8)|(cmd[2]<<16)|(cmd[3]<<24));
|
||||
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x0f);
|
||||
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, u32MemAdr);
|
||||
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 4 | (1<<7) | ((u32Sz & 0xfffff) << 8));
|
||||
do
|
||||
{
|
||||
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)&val);
|
||||
if(M2M_SUCCESS != ret) break;
|
||||
}
|
||||
while(val != 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn spi_flash_read_internal
|
||||
* @brief Read from data from SPI flash
|
||||
* @param[OUT] pu8Buf
|
||||
* Pointer to data buffer
|
||||
* @param[IN] u32Addr
|
||||
* Address to read from at the SPI flash
|
||||
* @param[IN] u32Sz
|
||||
* Data size
|
||||
*/
|
||||
static sint8 spi_flash_read_internal(uint8 *pu8Buf, uint32 u32Addr, uint32 u32Sz)
|
||||
{
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
/* read size must be < 64KB */
|
||||
ret = spi_flash_load_to_cortus_mem(HOST_SHARE_MEM_BASE, u32Addr, u32Sz);
|
||||
if(M2M_SUCCESS != ret) goto ERR;
|
||||
ret = nm_read_block(HOST_SHARE_MEM_BASE, pu8Buf, u32Sz);
|
||||
ERR:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn spi_flash_pp
|
||||
* @brief Program data of size less than a page (256 bytes) at the SPI flash
|
||||
* @param[IN] u32Offset
|
||||
* Address to write to at the SPI flash
|
||||
* @param[IN] pu8Buf
|
||||
* Pointer to data buffer
|
||||
* @param[IN] u32Sz
|
||||
* Data size
|
||||
* @return Status of execution
|
||||
*/
|
||||
static sint8 spi_flash_pp(uint32 u32Offset, uint8 *pu8Buf, uint16 u16Sz)
|
||||
{
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
uint8 tmp;
|
||||
spi_flash_write_enable();
|
||||
/* use shared packet memory as temp mem */
|
||||
ret += nm_write_block(HOST_SHARE_MEM_BASE, pu8Buf, u16Sz);
|
||||
ret += spi_flash_page_program(HOST_SHARE_MEM_BASE, u32Offset, u16Sz);
|
||||
ret += spi_flash_read_status_reg(&tmp);
|
||||
do
|
||||
{
|
||||
if(ret != M2M_SUCCESS) goto ERR;
|
||||
ret += spi_flash_read_status_reg(&tmp);
|
||||
}while(tmp & 0x01);
|
||||
ret += spi_flash_write_disable();
|
||||
ERR:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn spi_flash_rdid
|
||||
* @brief Read SPI Flash ID
|
||||
* @return SPI FLash ID
|
||||
*/
|
||||
static uint32 spi_flash_rdid(void)
|
||||
{
|
||||
unsigned char cmd[1];
|
||||
uint32 reg = 0;
|
||||
uint32 cnt = 0;
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
|
||||
cmd[0] = 0x9f;
|
||||
|
||||
ret += nm_write_reg(SPI_FLASH_DATA_CNT, 4);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
|
||||
ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x1);
|
||||
ret += nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER);
|
||||
ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
|
||||
do
|
||||
{
|
||||
ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)®);
|
||||
if(M2M_SUCCESS != ret) break;
|
||||
if(++cnt > 500)
|
||||
{
|
||||
ret = M2M_ERR_INIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(reg != 1);
|
||||
reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0);
|
||||
M2M_PRINT("Flash ID %x \n",(unsigned int)reg);
|
||||
return reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn spi_flash_unlock
|
||||
* @brief Unlock SPI Flash
|
||||
*/
|
||||
#if 0
|
||||
static void spi_flash_unlock(void)
|
||||
{
|
||||
uint8 tmp;
|
||||
tmp = spi_flash_read_security_reg();
|
||||
spi_flash_clear_security_flags();
|
||||
if(tmp & 0x80)
|
||||
{
|
||||
spi_flash_write_enable();
|
||||
spi_flash_gang_unblock();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
static void spi_flash_enter_low_power_mode(void) {
|
||||
volatile unsigned long tmp;
|
||||
unsigned char* cmd = (unsigned char*) &tmp;
|
||||
|
||||
cmd[0] = 0xb9;
|
||||
|
||||
nm_write_reg(SPI_FLASH_DATA_CNT, 0);
|
||||
nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
|
||||
nm_write_reg(SPI_FLASH_BUF_DIR, 0x1);
|
||||
nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
|
||||
nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1 << 7));
|
||||
while(nm_read_reg(SPI_FLASH_TR_DONE) != 1);
|
||||
}
|
||||
|
||||
|
||||
static void spi_flash_leave_low_power_mode(void) {
|
||||
volatile unsigned long tmp;
|
||||
unsigned char* cmd = (unsigned char*) &tmp;
|
||||
|
||||
cmd[0] = 0xab;
|
||||
|
||||
nm_write_reg(SPI_FLASH_DATA_CNT, 0);
|
||||
nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
|
||||
nm_write_reg(SPI_FLASH_BUF_DIR, 0x1);
|
||||
nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
|
||||
nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1 << 7));
|
||||
while(nm_read_reg(SPI_FLASH_TR_DONE) != 1);
|
||||
}
|
||||
/*********************************************/
|
||||
/* GLOBAL FUNCTIONS */
|
||||
/*********************************************/
|
||||
/**
|
||||
* @fn spi_flash_enable
|
||||
* @brief Enable spi flash operations
|
||||
*/
|
||||
sint8 spi_flash_enable(uint8 enable)
|
||||
{
|
||||
sint8 s8Ret = M2M_SUCCESS;
|
||||
if(REV(nmi_get_chipid()) >= REV_3A0) {
|
||||
uint32 u32Val;
|
||||
|
||||
/* Enable pinmux to SPI flash. */
|
||||
s8Ret = nm_read_reg_with_ret(0x1410, &u32Val);
|
||||
if(s8Ret != M2M_SUCCESS) {
|
||||
goto ERR1;
|
||||
}
|
||||
/* GPIO15/16/17/18 */
|
||||
u32Val &= ~((0x7777ul) << 12);
|
||||
u32Val |= ((0x1111ul) << 12);
|
||||
nm_write_reg(0x1410, u32Val);
|
||||
if(enable) {
|
||||
spi_flash_leave_low_power_mode();
|
||||
} else {
|
||||
spi_flash_enter_low_power_mode();
|
||||
}
|
||||
/* Disable pinmux to SPI flash to minimize leakage. */
|
||||
u32Val &= ~((0x7777ul) << 12);
|
||||
u32Val |= ((0x0010ul) << 12);
|
||||
nm_write_reg(0x1410, u32Val);
|
||||
}
|
||||
ERR1:
|
||||
return s8Ret;
|
||||
}
|
||||
/**
|
||||
* @fn spi_flash_read
|
||||
* @brief Read from data from SPI flash
|
||||
* @param[OUT] pu8Buf
|
||||
* Pointer to data buffer
|
||||
* @param[IN] u32offset
|
||||
* Address to read from at the SPI flash
|
||||
* @param[IN] u32Sz
|
||||
* Data size
|
||||
* @return Status of execution
|
||||
* @note Data size is limited by the SPI flash size only
|
||||
*/
|
||||
sint8 spi_flash_read(uint8 *pu8Buf, uint32 u32offset, uint32 u32Sz)
|
||||
{
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
if(u32Sz > FLASH_BLOCK_SIZE)
|
||||
{
|
||||
do
|
||||
{
|
||||
ret = spi_flash_read_internal(pu8Buf, u32offset, FLASH_BLOCK_SIZE);
|
||||
if(M2M_SUCCESS != ret) goto ERR;
|
||||
u32Sz -= FLASH_BLOCK_SIZE;
|
||||
u32offset += FLASH_BLOCK_SIZE;
|
||||
pu8Buf += FLASH_BLOCK_SIZE;
|
||||
} while(u32Sz > FLASH_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
ret = spi_flash_read_internal(pu8Buf, u32offset, u32Sz);
|
||||
|
||||
ERR:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn spi_flash_write
|
||||
* @brief Proram SPI flash
|
||||
* @param[IN] pu8Buf
|
||||
* Pointer to data buffer
|
||||
* @param[IN] u32Offset
|
||||
* Address to write to at the SPI flash
|
||||
* @param[IN] u32Sz
|
||||
* Data size
|
||||
* @return Status of execution
|
||||
*/
|
||||
sint8 spi_flash_write(uint8* pu8Buf, uint32 u32Offset, uint32 u32Sz)
|
||||
{
|
||||
#ifdef PROFILING
|
||||
uint32 t1 = 0;
|
||||
uint32 percent =0;
|
||||
uint32 tpercent =0;
|
||||
#endif
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
uint32 u32wsz;
|
||||
uint32 u32off;
|
||||
uint32 u32Blksz;
|
||||
u32Blksz = FLASH_PAGE_SZ;
|
||||
u32off = u32Offset % u32Blksz;
|
||||
#ifdef PROFILING
|
||||
tpercent = (u32Sz/u32Blksz)+((u32Sz%u32Blksz)>0);
|
||||
t1 = GetTickCount();
|
||||
M2M_PRINT(">Start programming...\r\n");
|
||||
#endif
|
||||
if(u32Sz<=0)
|
||||
{
|
||||
M2M_ERR("Data size = %d",(int)u32Sz);
|
||||
ret = M2M_ERR_FAIL;
|
||||
goto ERR;
|
||||
}
|
||||
|
||||
if (u32off)/*first part of data in the address page*/
|
||||
{
|
||||
u32wsz = u32Blksz - u32off;
|
||||
if(spi_flash_pp(u32Offset, pu8Buf, (uint16)BSP_MIN(u32Sz, u32wsz))!=M2M_SUCCESS)
|
||||
{
|
||||
ret = M2M_ERR_FAIL;
|
||||
goto ERR;
|
||||
}
|
||||
if (u32Sz < u32wsz) goto EXIT;
|
||||
pu8Buf += u32wsz;
|
||||
u32Offset += u32wsz;
|
||||
u32Sz -= u32wsz;
|
||||
}
|
||||
while (u32Sz > 0)
|
||||
{
|
||||
u32wsz = BSP_MIN(u32Sz, u32Blksz);
|
||||
|
||||
/*write complete page or the remaining data*/
|
||||
if(spi_flash_pp(u32Offset, pu8Buf, (uint16)u32wsz)!=M2M_SUCCESS)
|
||||
{
|
||||
ret = M2M_ERR_FAIL;
|
||||
goto ERR;
|
||||
}
|
||||
pu8Buf += u32wsz;
|
||||
u32Offset += u32wsz;
|
||||
u32Sz -= u32wsz;
|
||||
#ifdef PROFILING
|
||||
percent++;
|
||||
printf("\r>Complete Percentage = %d%%.\r",((percent*100)/tpercent));
|
||||
#endif
|
||||
}
|
||||
EXIT:
|
||||
#ifdef PROFILING
|
||||
M2M_PRINT("\rDone\t\t\t\t\t\t");
|
||||
M2M_PRINT("\n#Programming time = %f sec\n\r",(GetTickCount() - t1)/1000.0);
|
||||
#endif
|
||||
ERR:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn spi_flash_erase
|
||||
* @brief Erase from data from SPI flash
|
||||
* @param[IN] u32Offset
|
||||
* Address to write to at the SPI flash
|
||||
* @param[IN] u32Sz
|
||||
* Data size
|
||||
* @return Status of execution
|
||||
* @note Data size is limited by the SPI flash size only
|
||||
*/
|
||||
sint8 spi_flash_erase(uint32 u32Offset, uint32 u32Sz)
|
||||
{
|
||||
uint32 i = 0;
|
||||
sint8 ret = M2M_SUCCESS;
|
||||
uint8 tmp = 0;
|
||||
#ifdef PROFILING
|
||||
uint32 t;
|
||||
t = GetTickCount();
|
||||
#endif
|
||||
M2M_PRINT("\r\n>Start erasing...\r\n");
|
||||
for(i = u32Offset; i < (u32Sz +u32Offset); i += (16*FLASH_PAGE_SZ))
|
||||
{
|
||||
ret += spi_flash_write_enable();
|
||||
ret += spi_flash_read_status_reg(&tmp);
|
||||
ret += spi_flash_sector_erase(i + 10);
|
||||
ret += spi_flash_read_status_reg(&tmp);
|
||||
do
|
||||
{
|
||||
if(ret != M2M_SUCCESS) goto ERR;
|
||||
ret += spi_flash_read_status_reg(&tmp);
|
||||
}while(tmp & 0x01);
|
||||
|
||||
}
|
||||
M2M_PRINT("Done\r\n");
|
||||
#ifdef PROFILING
|
||||
M2M_PRINT("#Erase time = %f sec\n", (GetTickCount()-t)/1000.0);
|
||||
#endif
|
||||
ERR:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn spi_flash_get_size
|
||||
* @brief Get size of SPI Flash
|
||||
* @return Size of Flash
|
||||
*/
|
||||
uint32 spi_flash_get_size(void)
|
||||
{
|
||||
uint32 u32FlashId = 0, u32FlashPwr = 0;
|
||||
static uint32 gu32InernalFlashSize= 0;
|
||||
|
||||
if(!gu32InernalFlashSize)
|
||||
{
|
||||
u32FlashId = spi_flash_rdid();//spi_flash_probe();
|
||||
if(u32FlashId != 0xffffffff)
|
||||
{
|
||||
/*flash size is the third byte from the FLASH RDID*/
|
||||
u32FlashPwr = ((u32FlashId>>16)&0xff) - 0x11; /*2MBIT is the min*/
|
||||
/*That number power 2 to get the flash size*/
|
||||
gu32InernalFlashSize = 1<<u32FlashPwr;
|
||||
M2M_INFO("Flash Size %lu Mb\n",gu32InernalFlashSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
M2M_ERR("Cann't Detect Flash size\n");
|
||||
}
|
||||
}
|
||||
|
||||
return gu32InernalFlashSize;
|
||||
}
|
||||
895
src/winc1500/src/x509_cert.c
Normal file
895
src/winc1500/src/x509_cert.c
Normal file
@ -0,0 +1,895 @@
|
||||
/**
|
||||
*
|
||||
* \file
|
||||
*
|
||||
* \brief X509 Certificate Functions.
|
||||
*
|
||||
* Copyright (c) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#include "root_cert/x509/x509_cert.h"
|
||||
#include "root_cert/x509/asn1.h"
|
||||
|
||||
/* X509 SUPPORTED VERSIONS. */
|
||||
#define X509_VER_1 0
|
||||
#define X509_VER_2 1
|
||||
#define X509_VER_3 2
|
||||
|
||||
/* X509 CERTIFICATE PARSING STATES. */
|
||||
|
||||
#define CERT_VERSION_PENDING 0
|
||||
#define CERT_SERIAL_PENDING 1
|
||||
#define CERT_SIGNATURE_PENDING 2
|
||||
#define CERT_ISSUER_PENDING 3
|
||||
#define CERT_VALIDITY_PENDING 4
|
||||
#define CERT_SUBJECT_PENDING 5
|
||||
#define CERT_SUBECTKEYINFO_PENDING 6
|
||||
#define CERT_EXTENSIONS_PENDING 7
|
||||
#define CERT_PARSING_DONE 8
|
||||
|
||||
/* X509 ENCODED FIELD IDs. */
|
||||
|
||||
#define X509_VERSION 0xA0
|
||||
|
||||
/*!<
|
||||
* Identifier of the version field in the X.509 certificate
|
||||
* encoding. It is given in the ASN.1 syntax as
|
||||
* [0] EXPLICIT
|
||||
* Context-Specific class (10) | constructed (1) | 00000
|
||||
*/
|
||||
|
||||
#define X509_SERIAL_NO ASN1_INTEGER
|
||||
|
||||
/*!<
|
||||
* Identifier for the certificate serial num ber element.
|
||||
*/
|
||||
|
||||
#define X509_SIGNATURE ASN1_SEQUENCE
|
||||
|
||||
/*!<
|
||||
* Identifier for the Signature algorithm ID element.
|
||||
*/
|
||||
|
||||
#define X509_ISSUER ASN1_SEQUENCE
|
||||
|
||||
/*!<
|
||||
* Identifier for the certificate ISSUER element.
|
||||
*/
|
||||
|
||||
#define X509_VALIDITY ASN1_SEQUENCE
|
||||
|
||||
/*!<
|
||||
* Identifier for the certificate validity interval element.
|
||||
*/
|
||||
|
||||
#define X509_SUBJECT ASN1_SEQUENCE
|
||||
|
||||
/*!<
|
||||
* Identifier for the certificate SUBJECT information element.
|
||||
*/
|
||||
|
||||
#define X509_SUBJECT_KEY_INFO ASN1_SEQUENCE
|
||||
|
||||
/*!<
|
||||
* Identifier for the publick key information element.
|
||||
*/
|
||||
|
||||
#define X509_ISSUER_UNIQUE_ID 0x81
|
||||
|
||||
/*!<
|
||||
* Encoded value for the issuerUniqueID tag. It is defined as
|
||||
* [1] IMPLICIT BIT STRING
|
||||
* Context-Specific class (10) | primitive (0) | 00001
|
||||
*/
|
||||
|
||||
#define X509_SUBJECT_UNIQUE_ID 0x82
|
||||
|
||||
/*!<
|
||||
* Encoded value for the subjectUniqueID tag. It is defined as
|
||||
* [2] IMPLICIT BIT STRING
|
||||
* Context-Specific class (10) | primitive (0) | 00010
|
||||
*/
|
||||
|
||||
#define X509_EXTENSIONS_ID 0xA3
|
||||
|
||||
/*!<
|
||||
* Encoded value for the issuerUniqueID tag. It is defined as
|
||||
* [3] EXPLICIT
|
||||
* Context-Specific class (10) | constructed (1) | 00011
|
||||
*/
|
||||
|
||||
/* NAME ATTRIBUTE IDs. */
|
||||
|
||||
#define ID_AT 85, 0x04,
|
||||
#define ID_AT_COMMONNAME {ID_AT 3 }
|
||||
#define ID_AT_SERIALNUMBER {ID_AT 5 }
|
||||
#define ID_AT_COUNTRYNAME {ID_AT 6 }
|
||||
#define ID_AT_ORGANIZATIONNAME {ID_AT 10}
|
||||
#define ID_AT_ORGANIZATIONALUNITNAME {ID_AT 11}
|
||||
|
||||
#define X520_COMMON_NAME 1
|
||||
#define X520_ORG_UNIT 2
|
||||
#define X520_ORG 3
|
||||
|
||||
/* CERTIFICATE EXTENSION IDs. */
|
||||
|
||||
#define ID_CE 85, 29,
|
||||
#define ID_CE_AUTHORITY_KEY_ID {ID_CE 35}
|
||||
#define ID_CE_SUBJECT_KEY_ID {ID_CE 14}
|
||||
|
||||
/* SIGNATURE ALGORITHM IDs. */
|
||||
|
||||
#define PKCS_1 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01, 0x01,
|
||||
/* 1.2.840.113549.1.1 */
|
||||
|
||||
#define RSA_ENCRYPTION {PKCS_1 1} /* 1.2.840.113549.1.1 */
|
||||
#define MD5_WITH_RSA_ENCRYPTION {PKCS_1 4} /* 1.2.840.113549.1.1.4 */
|
||||
#define SHA1_WITH_RSA_ENCRYPTION {PKCS_1 5} /* 1.2.840.113549.1.1.5 */
|
||||
#define SHA256_WITH_RSA_ENCRYPTION {PKCS_1 11} /* 1.2.840.113549.1.1.11 */
|
||||
#define SHA384_WITH_RSA_ENCRYPTION {PKCS_1 12} /* 1.2.840.113549.1.1.12 */
|
||||
#define SHA512_WITH_RSA_ENCRYPTION {PKCS_1 13} /* 1.2.840.113549.1.1.13 */
|
||||
|
||||
typedef struct {
|
||||
uint8 u8Type;
|
||||
uint8 *pu8Name;
|
||||
uint8 u8Length;
|
||||
} tstrX520DistinguishedName;
|
||||
|
||||
sint8 M2M_GetTimeOfDay(tstrSystemTime *pstrSysTime);
|
||||
uint8 Cert_DecodeAlgID(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size);
|
||||
sint8 Cert_DecodeDistinguishedName(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrX520DistinguishedName *pstrDN);
|
||||
sint8 Cert_DecodeX520Name(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrX520Name *pstrName);
|
||||
sint8 Cert_DecodeRSAPubKey(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32KeySize, tstrRSAPublicKey *pstrRsaPublicKey);
|
||||
sint8 Cert_DecodeSubjectPubKey(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrPublicKey *pstrPubKey);
|
||||
sint8 Cert_DecodeValidity(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrX509Time *pstrNotBefore, tstrX509Time *pstrNotAfter);
|
||||
sint8 Cert_DecodeTBSCertificate(tstrAsn1Context *pstrX509Asn1Cxt, uint16 u16CertSize, tstrX509Cert *pstrCert);
|
||||
sint8 Cert_DecodeTime(uint8 *pu8Time, tstrSystemTime *pstrTime);
|
||||
sint8 Cert_CompareTime(tstrSystemTime *pstrT1, tstrSystemTime *pstrT2);
|
||||
uint8 X509Cert_IsValid(void *pvX509);
|
||||
|
||||
sint8 M2M_GetTimeOfDay(tstrSystemTime *pstrSysTime)
|
||||
{
|
||||
#ifdef WIN32
|
||||
SYSTEMTIME winTime;
|
||||
GetSystemTime(&winTime);
|
||||
pstrSysTime->u16Year = (uint16)winTime.wYear;
|
||||
pstrSysTime->u8Month = (uint8)winTime.wMonth;
|
||||
pstrSysTime->u8Day = (uint8)winTime.wDay;
|
||||
pstrSysTime->u8Hour = (uint8)winTime.wHour;
|
||||
pstrSysTime->u8Minute = (uint8)winTime.wMinute;
|
||||
pstrSysTime->u8Second = (uint8)winTime.wSecond;
|
||||
#else
|
||||
pstrSysTime->u16Year = (uint16)(2015);
|
||||
pstrSysTime->u8Month = (uint8)8;
|
||||
pstrSysTime->u8Day = (uint8)6;
|
||||
pstrSysTime->u8Hour = (uint8)9;
|
||||
pstrSysTime->u8Minute = (uint8)39;
|
||||
pstrSysTime->u8Second = (uint8)10;
|
||||
#endif
|
||||
|
||||
return M2M_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Perform decoding to the data type "AlgorithmIdentifier".
|
||||
*/
|
||||
uint8 Cert_DecodeAlgID(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size)
|
||||
{
|
||||
/*
|
||||
* AlgorithmIdentifier ::= SEQUENCE {
|
||||
* algorithm OBJECT IDENTIFIER,
|
||||
* parameters NULL
|
||||
* }
|
||||
*/
|
||||
|
||||
const uint8 gau8SecAlgorithms[][16] = {
|
||||
RSA_ENCRYPTION,
|
||||
MD5_WITH_RSA_ENCRYPTION,
|
||||
SHA1_WITH_RSA_ENCRYPTION,
|
||||
SHA256_WITH_RSA_ENCRYPTION,
|
||||
SHA384_WITH_RSA_ENCRYPTION,
|
||||
SHA512_WITH_RSA_ENCRYPTION
|
||||
};
|
||||
#define X509_NUM_SUPPORTED_SEC_ALGORITHMS (sizeof(gau8SecAlgorithms) / sizeof(gau8SecAlgorithms[0]))
|
||||
|
||||
uint8 u8Alg = X509_ALG_NULL;
|
||||
|
||||
if (pstrX509Asn1Cxt != NULL) {
|
||||
tstrAsn1Element strElem;
|
||||
|
||||
/* Initialize a decoding object for this SEQUENCE. */
|
||||
ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem);
|
||||
if (strElem.u8Tag == ASN1_OBJECT_IDENTIFIER) {
|
||||
if (strElem.u32Length <= 16) {
|
||||
uint8 u8Idx;
|
||||
uint8 au8AlgID[16];
|
||||
ASN1_Read(pstrX509Asn1Cxt, strElem.u32Length, au8AlgID);
|
||||
for (u8Idx = 0; u8Idx < X509_NUM_SUPPORTED_SEC_ALGORITHMS; u8Idx++) {
|
||||
if (!m2m_memcmp(au8AlgID, (uint8 *)gau8SecAlgorithms[u8Idx], strElem.u32Length)) {
|
||||
u8Alg = u8Idx + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return u8Alg;
|
||||
}
|
||||
|
||||
sint8 Cert_DecodeDistinguishedName(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrX520DistinguishedName *pstrDN)
|
||||
{
|
||||
sint8 s8Ret = X509_FAIL;
|
||||
|
||||
if ((pstrX509Asn1Cxt != NULL) && (pstrDN != NULL)) {
|
||||
tstrAsn1Element strElem;
|
||||
|
||||
ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem);
|
||||
if (strElem.u8Tag == ASN1_OBJECT_IDENTIFIER) {
|
||||
uint8 au8CmnNameID[4] = ID_AT_COMMONNAME;
|
||||
uint8 au8TempID[16];
|
||||
|
||||
pstrDN->u8Type = 0;
|
||||
ASN1_Read(pstrX509Asn1Cxt, strElem.u32Length, au8TempID);
|
||||
if (!m2m_memcmp(au8CmnNameID, au8TempID, strElem.u32Length)) {
|
||||
pstrDN->u8Type = X520_COMMON_NAME;
|
||||
}
|
||||
|
||||
if (ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem) != ASN1_FAIL) {
|
||||
pstrDN->u8Length = (uint8)strElem.u32Length;
|
||||
ASN1_ReadReference(pstrX509Asn1Cxt, strElem.u32Length, &pstrDN->pu8Name);
|
||||
s8Ret = X509_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s8Ret;
|
||||
}
|
||||
|
||||
sint8 Cert_DecodeX520Name(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrX520Name *pstrName)
|
||||
{
|
||||
/*
|
||||
* Name ::= CHOICE { -- only one possibility for now --
|
||||
* rdnSequence RDNSequence
|
||||
* }
|
||||
*
|
||||
* RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
|
||||
*
|
||||
* RelativeDistinguishedName ::=
|
||||
* SET SIZE (1..MAX) OF AttributeTypeAndValue
|
||||
*
|
||||
* AttributeTypeAndValue ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
* value AttributeValue
|
||||
* }
|
||||
*
|
||||
* AttributeType ::= OBJECT IDENTIFIER
|
||||
* AttributeValue ::= ANY -- DEFINED BY AttributeType
|
||||
*
|
||||
* DirectoryString ::= CHOICE {
|
||||
* teletexString TeletexString (SIZE (1..MAX)),
|
||||
* printableString PrintableString (SIZE (1..MAX)),
|
||||
* universalString UniversalString (SIZE (1..MAX)),
|
||||
* utf8String UTF8String (SIZE (1..MAX)),
|
||||
* bmpString BMPString (SIZE (1..MAX))
|
||||
* }
|
||||
*/
|
||||
sint8 s8Ret = X509_SUCCESS;
|
||||
|
||||
if ((pstrX509Asn1Cxt != NULL) && (pstrName != NULL)) {
|
||||
tstrAsn1Element strSetElem, strSeqElem;
|
||||
tstrX520DistinguishedName strDN;
|
||||
tstrSha1Context strSha1Cxt;
|
||||
uint16 u16Offset = 0;
|
||||
|
||||
SHA1_INIT(&strSha1Cxt);
|
||||
|
||||
/* RelativeDistinguishedName. */
|
||||
while (u16Offset < u32Size) {
|
||||
u16Offset += ASN1_GetNextElement(pstrX509Asn1Cxt, &strSetElem);
|
||||
if (strSetElem.u8Tag == ASN1_SET) {
|
||||
ASN1_GetNextElement(pstrX509Asn1Cxt, &strSeqElem);
|
||||
if (strSeqElem.u8Tag != ASN1_SEQUENCE) {
|
||||
s8Ret = X509_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Cert_DecodeDistinguishedName(pstrX509Asn1Cxt, strSeqElem.u32Length, &strDN) != X509_SUCCESS) {
|
||||
s8Ret = X509_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (strDN.u8Type == X520_COMMON_NAME) {
|
||||
m2m_memcpy((uint8 *)pstrName->acCmnName, strDN.pu8Name, strDN.u8Length);
|
||||
pstrName->acCmnName[strDN.u8Length] = '\0';
|
||||
} else if (strDN.u8Type == X520_ORG_UNIT) {
|
||||
if (pstrName->acOrgUnit[0] == 0) {
|
||||
m2m_memcpy((uint8 *)pstrName->acOrgUnit, strDN.pu8Name, strDN.u8Length);
|
||||
pstrName->acOrgUnit[strDN.u8Length] = '\0';
|
||||
}
|
||||
} else if (strDN.u8Type == X520_ORG) {
|
||||
m2m_memcpy((uint8 *)pstrName->acOrg, strDN.pu8Name, strDN.u8Length);
|
||||
pstrName->acOrg[strDN.u8Length] = '\0';
|
||||
}
|
||||
|
||||
SHA1_UPDATE(&strSha1Cxt, strDN.pu8Name, strDN.u8Length);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
SHA1_FINISH(&strSha1Cxt, pstrName->au8NameSHA1);
|
||||
}
|
||||
|
||||
return s8Ret;
|
||||
}
|
||||
|
||||
sint8 Cert_DecodeRSAPubKey(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32KeySize, tstrRSAPublicKey *pstrRsaPublicKey)
|
||||
{
|
||||
/*
|
||||
* RSAPublicKey ::= SEQUENCE {
|
||||
* modulus INTEGER, -- n
|
||||
* publicExponent INTEGER -- e
|
||||
* }
|
||||
*/
|
||||
sint8 s8Ret = X509_FAIL;
|
||||
if ((pstrX509Asn1Cxt != NULL) && (pstrRsaPublicKey != NULL)) {
|
||||
tstrAsn1Element strElem;
|
||||
|
||||
ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem);
|
||||
if (strElem.u8Tag == ASN1_SEQUENCE) {
|
||||
ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem);
|
||||
if (strElem.u8Tag == ASN1_INTEGER) {
|
||||
ASN1_ReadReference(pstrX509Asn1Cxt, strElem.u32Length, &pstrRsaPublicKey->pu8N);
|
||||
while (*pstrRsaPublicKey->pu8N == 0) {
|
||||
pstrRsaPublicKey->pu8N++;
|
||||
strElem.u32Length--;
|
||||
}
|
||||
pstrRsaPublicKey->u16NSize = (uint16)strElem.u32Length;
|
||||
|
||||
ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem);
|
||||
if (strElem.u8Tag == ASN1_INTEGER) {
|
||||
ASN1_ReadReference(pstrX509Asn1Cxt, strElem.u32Length, &pstrRsaPublicKey->pu8E);
|
||||
while (*pstrRsaPublicKey->pu8E == 0) {
|
||||
pstrRsaPublicKey->pu8E++;
|
||||
strElem.u32Length--;
|
||||
}
|
||||
pstrRsaPublicKey->u16ESize = (uint16)strElem.u32Length;
|
||||
s8Ret = X509_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s8Ret;
|
||||
}
|
||||
|
||||
sint8 Cert_DecodeSubjectPubKey(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrPublicKey *pstrPubKey)
|
||||
{
|
||||
/*
|
||||
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
* algorithm AlgorithmIdentifier,
|
||||
* subjectPublicKey BIT STRING
|
||||
* }
|
||||
*/
|
||||
sint8 s8Ret = X509_SUCCESS;
|
||||
|
||||
if ((pstrX509Asn1Cxt != NULL) && (pstrPubKey != NULL)) {
|
||||
tstrAsn1Element strElem;
|
||||
uint8 u8PubKeyAlg = 0;
|
||||
uint16 u16Offset = 0;
|
||||
|
||||
while (u16Offset < u32Size) {
|
||||
u16Offset += ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem);
|
||||
if (strElem.u8Tag == ASN1_SEQUENCE) {
|
||||
u8PubKeyAlg = Cert_DecodeAlgID(pstrX509Asn1Cxt, strElem.u32Length);
|
||||
} else if (strElem.u8Tag == ASN1_BIT_STRING) {
|
||||
if (u8PubKeyAlg != X509_PUB_RSA) {
|
||||
s8Ret = X509_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
pstrPubKey->enuType = PUBKEY_ALG_RSA;
|
||||
ASN1_Read(pstrX509Asn1Cxt, 1, NULL);
|
||||
s8Ret = Cert_DecodeRSAPubKey(pstrX509Asn1Cxt, strElem.u32Length - 1, &pstrPubKey->strRSAKey);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s8Ret;
|
||||
}
|
||||
|
||||
sint8 Cert_DecodeValidity(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrX509Time *pstrNotBefore, tstrX509Time *pstrNotAfter)
|
||||
{
|
||||
/*
|
||||
* Validity ::= SEQUENCE {
|
||||
* notBefore Time,
|
||||
* notAfter Time
|
||||
* }
|
||||
*/
|
||||
sint8 s8Ret = X509_FAIL;
|
||||
|
||||
if ((pstrX509Asn1Cxt != 0) && (pstrNotAfter != NULL) && (pstrNotBefore != NULL)) {
|
||||
tstrAsn1Element strElem;
|
||||
|
||||
if (ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem) != ASN1_INVALID) {
|
||||
/* Start time. */
|
||||
ASN1_Read(pstrX509Asn1Cxt, strElem.u32Length, pstrNotBefore->au8Time);
|
||||
pstrNotBefore->au8Time[strElem.u32Length] = '\0';
|
||||
|
||||
if (ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem) != ASN1_INVALID) {
|
||||
/* End time. */
|
||||
ASN1_Read(pstrX509Asn1Cxt, strElem.u32Length, pstrNotAfter->au8Time);
|
||||
pstrNotAfter->au8Time[strElem.u32Length] = '\0';
|
||||
s8Ret = X509_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s8Ret;
|
||||
}
|
||||
|
||||
sint8 Cert_DecodeTBSCertificate(tstrAsn1Context *pstrX509Asn1Cxt, uint16 u16CertSize, tstrX509Cert *pstrCert)
|
||||
{
|
||||
/*
|
||||
* TBSCertificate ::= SEQUENCE {
|
||||
* version [0]
|
||||
* Version DEFAULT v1,
|
||||
* serialNumber CertificateSerialNumber,
|
||||
* signature AlgorithmIdentifier,
|
||||
* issuer Name,
|
||||
* validity Validity,
|
||||
* subject Name,
|
||||
* subjectPublicKeyInfo SubjectPublicKeyInfo,
|
||||
* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, If present, version MUST be v2 or v3
|
||||
* subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, If present, version MUST be v2 or v3
|
||||
* extensions [3] Extensions OPTIONAL If present, version MUST be v3
|
||||
* }
|
||||
*
|
||||
*/
|
||||
sint8 s8Ret = X509_SUCCESS;
|
||||
|
||||
if ((pstrX509Asn1Cxt != NULL) && (pstrCert != NULL)) {
|
||||
uint16 u16ReadOffset = 0;
|
||||
tstrAsn1Element strElement;
|
||||
uint8 u8CertState = CERT_VERSION_PENDING;
|
||||
|
||||
/* Loop on the elements of the certificate until finishing. */
|
||||
while (u16ReadOffset < u16CertSize) {
|
||||
u16ReadOffset += ASN1_GetNextElement(pstrX509Asn1Cxt, &strElement);
|
||||
switch (u8CertState) {
|
||||
case CERT_VERSION_PENDING:
|
||||
|
||||
/* Version. */
|
||||
if (strElement.u8Tag == X509_VERSION) {
|
||||
/* The encoding of version is on the form A0 03 02 01 ver. */
|
||||
if (strElement.u32Length < 3) {
|
||||
s8Ret = X509_FAIL;
|
||||
}
|
||||
|
||||
ASN1_Read(pstrX509Asn1Cxt, 2, NULL);
|
||||
ASN1_Read(pstrX509Asn1Cxt, 1, &pstrCert->u8Version);
|
||||
u8CertState = CERT_SERIAL_PENDING;
|
||||
} else if (strElement.u8Tag == X509_SERIAL_NO) {
|
||||
/* The certificate version number is absent from the certificate. */
|
||||
/* It will be set to the default value Version 1.0. */
|
||||
pstrCert->u8Version = X509_VER_1;
|
||||
|
||||
/* The first field is the serial number. */
|
||||
if (strElement.u32Length > X509_SERIAL_NO_MAX_LENGTH) {
|
||||
strElement.u32Length = X509_SERIAL_NO_MAX_LENGTH;
|
||||
}
|
||||
|
||||
pstrCert->u8SerialNumberLength = (uint8)strElement.u32Length;
|
||||
ASN1_Read(pstrX509Asn1Cxt, strElement.u32Length, pstrCert->au8SerialNo);
|
||||
u8CertState = CERT_SIGNATURE_PENDING;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CERT_SERIAL_PENDING:
|
||||
|
||||
/* SerialNumber. */
|
||||
if (strElement.u8Tag == X509_SERIAL_NO) {
|
||||
/* The first field is the serial number. */
|
||||
if (strElement.u32Length > X509_SERIAL_NO_MAX_LENGTH) {
|
||||
strElement.u32Length = X509_SERIAL_NO_MAX_LENGTH;
|
||||
}
|
||||
|
||||
pstrCert->u8SerialNumberLength = (uint8)strElement.u32Length;
|
||||
ASN1_Read(pstrX509Asn1Cxt, strElement.u32Length, pstrCert->au8SerialNo);
|
||||
u8CertState = CERT_SIGNATURE_PENDING;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CERT_SIGNATURE_PENDING:
|
||||
|
||||
/* Signature. */
|
||||
if (strElement.u8Tag == X509_SIGNATURE) {
|
||||
pstrCert->u8SignAlg = Cert_DecodeAlgID(pstrX509Asn1Cxt, strElement.u32Length);
|
||||
u8CertState = CERT_ISSUER_PENDING;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CERT_ISSUER_PENDING:
|
||||
|
||||
/* Issuer. */
|
||||
if (strElement.u8Tag == X509_ISSUER) {
|
||||
Cert_DecodeX520Name(pstrX509Asn1Cxt, strElement.u32Length, &pstrCert->strIssuer);
|
||||
u8CertState = CERT_VALIDITY_PENDING;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CERT_VALIDITY_PENDING:
|
||||
|
||||
/* Validity. */
|
||||
if (strElement.u8Tag == X509_VALIDITY) {
|
||||
Cert_DecodeValidity(pstrX509Asn1Cxt, strElement.u32Length,
|
||||
&pstrCert->strStartDate, &pstrCert->strExpiryDate);
|
||||
u8CertState = CERT_SUBJECT_PENDING;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CERT_SUBJECT_PENDING:
|
||||
|
||||
/* Subject. */
|
||||
if (strElement.u8Tag == X509_SUBJECT) {
|
||||
Cert_DecodeX520Name(pstrX509Asn1Cxt, strElement.u32Length, &pstrCert->strSubject);
|
||||
u8CertState = CERT_SUBECTKEYINFO_PENDING;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CERT_SUBECTKEYINFO_PENDING:
|
||||
|
||||
/* SubjectPublicKeyInfo. */
|
||||
if (strElement.u8Tag == X509_SUBJECT_KEY_INFO) {
|
||||
Cert_DecodeSubjectPubKey(pstrX509Asn1Cxt, strElement.u32Length, &pstrCert->strPubKey);
|
||||
u8CertState = CERT_EXTENSIONS_PENDING;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CERT_EXTENSIONS_PENDING:
|
||||
ASN1_Read(pstrX509Asn1Cxt, strElement.u32Length, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s8Ret;
|
||||
}
|
||||
|
||||
sint8 X509Cert_Decode(uint8 *pu8X509Buffer, uint32 u32CertSize, tstrX509Cert *pstrCert, uint8 bDumpX509)
|
||||
{
|
||||
/*
|
||||
*
|
||||
* Certificate ::= SEQUENCE {
|
||||
* tbsCertificate TBSCertificate,
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
* signature BIT STRING }
|
||||
*
|
||||
*/
|
||||
sint8 s8Ret = X509_FAIL;
|
||||
|
||||
if ((pu8X509Buffer != NULL) && (pstrCert != NULL)) {
|
||||
tstrAsn1Context strX509ASN1Cxt;
|
||||
tstrAsn1Element strElement;
|
||||
uint8 u8SignAlgorithm = X509_ALG_NULL;
|
||||
|
||||
/* Initialize the certificate structure. */
|
||||
m2m_memset((uint8 *)pstrCert, 0, sizeof(tstrX509Cert));
|
||||
|
||||
/* Initialize the ASN1 Decoding operation. */
|
||||
strX509ASN1Cxt.pu8Buff = pu8X509Buffer;
|
||||
strX509ASN1Cxt.pu8Data = pu8X509Buffer;
|
||||
|
||||
ASN1_GetNextElement(&strX509ASN1Cxt, &strElement);
|
||||
if ((strElement.u8Tag == ASN1_SEQUENCE) && (strElement.u32Length < u32CertSize)) {
|
||||
/* Copy the TBS certificate. It shall be used later to calculate the certificate HASH. */
|
||||
pstrCert->pu8TBSCert = strX509ASN1Cxt.pu8Data;
|
||||
|
||||
/* tbsCertificate. */
|
||||
pstrCert->u16TBSCertSize = ASN1_GetNextElement(&strX509ASN1Cxt, &strElement);
|
||||
if (strElement.u8Tag == ASN1_SEQUENCE) {
|
||||
if (Cert_DecodeTBSCertificate(&strX509ASN1Cxt, (uint16)strElement.u32Length, pstrCert) == 0) {
|
||||
/* signatureAlgorithm. */
|
||||
ASN1_GetNextElement(&strX509ASN1Cxt, &strElement);
|
||||
if (strElement.u8Tag == ASN1_SEQUENCE) {
|
||||
/* Check if the signatureAlgorithm ID obtained in this element matches */
|
||||
/* the signature field of the TBS Certificate. */
|
||||
u8SignAlgorithm = Cert_DecodeAlgID(&strX509ASN1Cxt, strElement.u32Length);
|
||||
if (u8SignAlgorithm == pstrCert->u8SignAlg) {
|
||||
/* signature. */
|
||||
ASN1_GetNextElement(&strX509ASN1Cxt, &strElement);
|
||||
if (strElement.u8Tag == ASN1_BIT_STRING) {
|
||||
/* Store the obtained signature. */
|
||||
pstrCert->strSignature.u16BufferSize = (uint16)strElement.u32Length - 1;
|
||||
|
||||
/* Jump one byte. */
|
||||
ASN1_Read(&strX509ASN1Cxt, 1, NULL);
|
||||
|
||||
/* Get the signature value. */
|
||||
ASN1_ReadReference(&strX509ASN1Cxt, pstrCert->strSignature.u16BufferSize,
|
||||
&pstrCert->strSignature.pu8Data);
|
||||
|
||||
/* Dump the certificate contents. */
|
||||
if (bDumpX509) {
|
||||
X509_CERT_DUMP(pstrCert);
|
||||
}
|
||||
|
||||
s8Ret = X509_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s8Ret;
|
||||
}
|
||||
|
||||
#define X509_UTC_TIME_LENGTH 0x0D
|
||||
|
||||
/*!<
|
||||
* The UTC time for the X.509 encoding takes the format
|
||||
* YYMMDDHHMMSSZ. Each digit is BCD encoded as ASCII digit.
|
||||
*/
|
||||
|
||||
#define X509_GENERALIZED_TIME_LENGTH 0x0F
|
||||
|
||||
/*!<
|
||||
* The UTC time for the X.509 encoding takes the format
|
||||
* YYYYMMDDHHMMSSZ. Each digit is BCD encoded as ASCII digit.
|
||||
*/
|
||||
|
||||
#define GET_VAL(BUF, OFFSET) (((BUF)[OFFSET] * 10) + ((BUF)[OFFSET + 1]))
|
||||
|
||||
sint8 Cert_DecodeTime(uint8 *pu8Time, tstrSystemTime *pstrTime)
|
||||
{
|
||||
sint8 s8Ret = X509_FAIL;
|
||||
|
||||
if (pu8Time != NULL) {
|
||||
uint8 u8TimeLength = (uint8)strlen((char *)pu8Time);
|
||||
uint8 au8Time[20];
|
||||
uint8 u8Idx;
|
||||
|
||||
memcpy(au8Time, pu8Time, 20);
|
||||
|
||||
if ((u8TimeLength >= X509_UTC_TIME_LENGTH) && (u8TimeLength <= X509_GENERALIZED_TIME_LENGTH)) {
|
||||
if (au8Time[u8TimeLength - 1] == 'Z') {
|
||||
for (u8Idx = 0; u8Idx < (u8TimeLength - 1); u8Idx++) {
|
||||
au8Time[u8Idx] -= '0';
|
||||
}
|
||||
|
||||
if (u8TimeLength == X509_UTC_TIME_LENGTH) {
|
||||
pstrTime->u16Year = (au8Time[0] * 10) + au8Time[1];
|
||||
pstrTime->u16Year += (pstrTime->u16Year < 50 ? 2000 : 1900);
|
||||
u8Idx = 2;
|
||||
} else {
|
||||
pstrTime->u16Year = (au8Time[0] * 1000) + (au8Time[1] * 100) + (au8Time[2] * 10) + au8Time[3];
|
||||
u8Idx = 4;
|
||||
}
|
||||
|
||||
pstrTime->u8Month = GET_VAL(au8Time, u8Idx);
|
||||
u8Idx += 2;
|
||||
|
||||
pstrTime->u8Day = GET_VAL(au8Time, u8Idx);
|
||||
u8Idx += 2;
|
||||
|
||||
pstrTime->u8Hour = GET_VAL(au8Time, u8Idx);
|
||||
u8Idx += 2;
|
||||
|
||||
pstrTime->u8Minute = GET_VAL(au8Time, u8Idx);
|
||||
u8Idx += 2;
|
||||
|
||||
pstrTime->u8Second = GET_VAL(au8Time, u8Idx);
|
||||
|
||||
s8Ret = X509_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s8Ret;
|
||||
}
|
||||
|
||||
sint8 Cert_CompareTime(tstrSystemTime *pstrT1, tstrSystemTime *pstrT2)
|
||||
{
|
||||
sint8 s8Cmp = 1;
|
||||
|
||||
if ((pstrT1 != NULL) && (pstrT2 != NULL)) {
|
||||
/* YEAR. */
|
||||
if (pstrT1->u16Year == pstrT2->u16Year) {
|
||||
/* MONTH. */
|
||||
if (pstrT1->u8Month == pstrT2->u8Month) {
|
||||
/* DAY */
|
||||
if (pstrT1->u8Day == pstrT2->u8Day) {
|
||||
s8Cmp = pstrT1->u8Hour - pstrT2->u8Hour;
|
||||
} else {
|
||||
s8Cmp = pstrT1->u8Day - pstrT2->u8Day;
|
||||
}
|
||||
} else {
|
||||
s8Cmp = pstrT1->u8Month - pstrT2->u8Month;
|
||||
}
|
||||
} else {
|
||||
s8Cmp = pstrT1->u16Year - pstrT2->u16Year;
|
||||
}
|
||||
}
|
||||
|
||||
return s8Cmp;
|
||||
}
|
||||
|
||||
uint8 X509Cert_IsValid(void *pvX509)
|
||||
{
|
||||
tstrX509Cert *pstrX509 = (tstrX509Cert *)pvX509;
|
||||
uint8 u8Status = X509_STATUS_VALID;
|
||||
|
||||
if (pstrX509 != NULL) {
|
||||
tstrSystemTime strExpirationDate = {0};
|
||||
|
||||
if (Cert_DecodeTime(pstrX509->strExpiryDate.au8Time, &strExpirationDate) == X509_SUCCESS) {
|
||||
M2M_DBG("Expiration Date\n\t%d-%02d-%02d %02d:%02d:%02d\n",
|
||||
strExpirationDate.u16Year, strExpirationDate.u8Month, strExpirationDate.u8Day,
|
||||
strExpirationDate.u8Hour, strExpirationDate.u8Minute, strExpirationDate.u8Second);
|
||||
|
||||
if (strExpirationDate.u16Year != 9999) {
|
||||
#ifdef WIN32
|
||||
if (M2M_GetTimeOfDay(&strSystemTime) == M2M_SUCCESS) {
|
||||
if (Cert_CompareTime(&strExpirationDate, &strSystemTime) <= 0) {
|
||||
u8Status = X509_STATUS_EXPIRED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
u8Status = X509_STATUS_DECODE_ERR;
|
||||
}
|
||||
} else {
|
||||
u8Status = X509_STATUS_DECODE_ERR;
|
||||
}
|
||||
|
||||
return u8Status;
|
||||
}
|
||||
|
||||
void X509Cert_Dump(void *pvCert)
|
||||
{
|
||||
tstrX509Cert *pstrCert = (tstrX509Cert *)pvCert;
|
||||
if (pstrCert != NULL) {
|
||||
#define X509_DUMP_ENABLE
|
||||
#ifdef X509_DUMP_ENABLE
|
||||
uint32 i;
|
||||
tstrSystemTime strTime = {0};
|
||||
|
||||
printf("\r\n");
|
||||
printf("*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=\r\n");
|
||||
printf(" ROOT CERTIFICATE \r\n");
|
||||
printf("*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=\r\n");
|
||||
|
||||
printf("VERSION %u\r\n", pstrCert->u8Version + 1);
|
||||
printf("SERIAL NO ");
|
||||
for (i = 0; i < pstrCert->u8SerialNumberLength; i++) {
|
||||
printf("%02X ", pstrCert->au8SerialNo[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
|
||||
printf("SIGNATURE ALGORITHM ");
|
||||
if (pstrCert->u8SignAlg == X509_SIGN_MD5RSA) {
|
||||
printf("md5WithRsaEncryption");
|
||||
} else if (pstrCert->u8SignAlg == X509_SIGN_SHA1RSA) {
|
||||
printf("shaWithRsaEncryption");
|
||||
} else if (pstrCert->u8SignAlg == X509_SIGN_SHA256RSA) {
|
||||
printf("sha256WithRsaEncryption");
|
||||
} else if (pstrCert->u8SignAlg == X509_SIGN_SHA384RSA) {
|
||||
printf("sha384WithRsaEncryption");
|
||||
} else if (pstrCert->u8SignAlg == X509_SIGN_SHA512RSA) {
|
||||
printf("sha512WithRsaEncryption");
|
||||
}
|
||||
|
||||
printf("\r\n");
|
||||
|
||||
printf("ISSUER ");
|
||||
if (strlen(pstrCert->strIssuer.acCmnName) != 0) {
|
||||
printf("%s", pstrCert->strIssuer.acCmnName);
|
||||
}
|
||||
|
||||
printf("\r\n");
|
||||
|
||||
printf("SUBJECT ");
|
||||
if (strlen(pstrCert->strSubject.acCmnName) != 0) {
|
||||
printf("%s", pstrCert->strSubject.acCmnName);
|
||||
}
|
||||
|
||||
printf("\r\n");
|
||||
|
||||
printf("VALIDITY\n");
|
||||
printf(" Not Before : ");
|
||||
Cert_DecodeTime(pstrCert->strStartDate.au8Time, &strTime);
|
||||
printf("%d-%02d-%02d %02d:%02d:%02d\r\n",
|
||||
strTime.u16Year, strTime.u8Month, strTime.u8Day,
|
||||
strTime.u8Hour, strTime.u8Minute, strTime.u8Second);
|
||||
|
||||
printf(" Not After : ");
|
||||
Cert_DecodeTime(pstrCert->strExpiryDate.au8Time, &strTime);
|
||||
printf("%d-%02d-%02d %02d:%02d:%02d\r\n",
|
||||
strTime.u16Year, strTime.u8Month, strTime.u8Day,
|
||||
strTime.u8Hour, strTime.u8Minute, strTime.u8Second);
|
||||
|
||||
if (pstrCert->strPubKey.enuType == PUBKEY_ALG_RSA) {
|
||||
printf("PUBLIC KEY ");
|
||||
printf("RSA\n\n");
|
||||
printf("\tModulus");
|
||||
for (i = 0; i < pstrCert->strPubKey.strRSAKey.u16NSize; i++) {
|
||||
if (!(i % 16)) {
|
||||
printf("\r\n\t\t");
|
||||
}
|
||||
|
||||
printf("%02X ", pstrCert->strPubKey.strRSAKey.pu8N[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
|
||||
printf("\tExponent");
|
||||
for (i = 0; i < pstrCert->strPubKey.strRSAKey.u16ESize; i++) {
|
||||
if (!(i % 16)) {
|
||||
printf("\r\n\t\t");
|
||||
}
|
||||
|
||||
printf("%02X ", pstrCert->strPubKey.strRSAKey.pu8E[i]);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\r\n");
|
||||
|
||||
printf("SIGNATURE");
|
||||
for (i = 0; i < pstrCert->strSignature.u16BufferSize; i++) {
|
||||
if (!(i % 16)) {
|
||||
printf("\r\n\t");
|
||||
}
|
||||
|
||||
printf("%02X ", pstrCert->strSignature.pu8Data[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
printf("*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=\n");
|
||||
#else
|
||||
M2M_INFO("*=*=* X509 *=*=*\n");
|
||||
M2M_INFO("\tSubject <%s>\n", ((strlen(pstrCert->strSubject.acCmnName) != 0) ? pstrCert->strSubject.acCmnName : " "));
|
||||
M2M_INFO("\tIssuer <%s>\n", ((strlen(pstrCert->strIssuer.acCmnName) != 0) ? pstrCert->strIssuer.acCmnName : " "));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user