mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 20:24:39 +02:00
add STM32F2 SHA1, MD5 support
This commit is contained in:
@@ -33,6 +33,120 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef STM32F2_CRYPTO
|
||||||
|
/*
|
||||||
|
* STM32F2 hardware MD5 support through the STM32F2 standard peripheral
|
||||||
|
* library. Documentation located in STM32F2xx Standard Peripheral Library
|
||||||
|
* document (See note in README).
|
||||||
|
*/
|
||||||
|
#include "stm32f2xx.h"
|
||||||
|
|
||||||
|
void InitMd5(Md5* md5)
|
||||||
|
{
|
||||||
|
/* STM32F2 struct notes:
|
||||||
|
* md5->buffer = first 4 bytes used to hold partial block if needed
|
||||||
|
* md5->buffLen = num bytes currently stored in md5->buffer
|
||||||
|
* md5->loLen = num bytes that have been written to STM32 FIFO
|
||||||
|
*/
|
||||||
|
XMEMSET(md5->buffer, 0, MD5_REG_SIZE);
|
||||||
|
md5->buffLen = 0;
|
||||||
|
md5->loLen = 0;
|
||||||
|
|
||||||
|
/* initialize HASH peripheral */
|
||||||
|
HASH_DeInit();
|
||||||
|
|
||||||
|
/* configure algo used, algo mode, datatype */
|
||||||
|
HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
|
||||||
|
HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HASH
|
||||||
|
| HASH_DataType_8b);
|
||||||
|
|
||||||
|
/* reset HASH processor */
|
||||||
|
HASH->CR |= HASH_CR_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Md5Update(Md5* md5, const byte* data, word32 len)
|
||||||
|
{
|
||||||
|
word32 i = 0;
|
||||||
|
word32 fill = 0;
|
||||||
|
word32 diff = 0;
|
||||||
|
|
||||||
|
/* if saved partial block is available */
|
||||||
|
if (md5->buffLen > 0) {
|
||||||
|
fill = 4 - md5->buffLen;
|
||||||
|
|
||||||
|
/* if enough data to fill, fill and push to FIFO */
|
||||||
|
if (fill <= len) {
|
||||||
|
XMEMCPY((byte*)md5->buffer + md5->buffLen, data, fill);
|
||||||
|
HASH_DataIn(*(uint32_t*)md5->buffer);
|
||||||
|
|
||||||
|
data += fill;
|
||||||
|
len -= fill;
|
||||||
|
md5->loLen += 4;
|
||||||
|
md5->buffLen = 0;
|
||||||
|
} else {
|
||||||
|
/* append partial to existing stored block */
|
||||||
|
XMEMCPY((byte*)md5->buffer + md5->buffLen, data, len);
|
||||||
|
md5->buffLen += len;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write input block in the IN FIFO */
|
||||||
|
for (i = 0; i < len; i += 4)
|
||||||
|
{
|
||||||
|
diff = len - i;
|
||||||
|
if (diff < 4) {
|
||||||
|
/* store incomplete last block, not yet in FIFO */
|
||||||
|
XMEMSET(md5->buffer, 0, MD5_REG_SIZE);
|
||||||
|
XMEMCPY((byte*)md5->buffer, data, diff);
|
||||||
|
md5->buffLen = diff;
|
||||||
|
} else {
|
||||||
|
HASH_DataIn(*(uint32_t*)data);
|
||||||
|
data+=4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* keep track of total data length thus far */
|
||||||
|
md5->loLen += (len - md5->buffLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Md5Final(Md5* md5, byte* hash)
|
||||||
|
{
|
||||||
|
__IO uint16_t nbvalidbitsdata = 0;
|
||||||
|
|
||||||
|
/* finish reading any trailing bytes into FIFO */
|
||||||
|
if (md5->buffLen > 0) {
|
||||||
|
HASH_DataIn(*(uint32_t*)md5->buffer);
|
||||||
|
md5->loLen += md5->buffLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate number of valid bits in last word of input data */
|
||||||
|
nbvalidbitsdata = 8 * (md5->loLen % MD5_REG_SIZE);
|
||||||
|
|
||||||
|
/* configure number of valid bits in last word of the data */
|
||||||
|
HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
|
||||||
|
|
||||||
|
/* start HASH processor */
|
||||||
|
HASH_StartDigest();
|
||||||
|
|
||||||
|
/* wait until Busy flag == RESET */
|
||||||
|
while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {}
|
||||||
|
|
||||||
|
/* read message digest */
|
||||||
|
md5->digest[0] = HASH->HR[0];
|
||||||
|
md5->digest[1] = HASH->HR[1];
|
||||||
|
md5->digest[2] = HASH->HR[2];
|
||||||
|
md5->digest[3] = HASH->HR[3];
|
||||||
|
|
||||||
|
ByteReverseWords(md5->digest, md5->digest, MD5_DIGEST_SIZE);
|
||||||
|
|
||||||
|
XMEMCPY(hash, md5->digest, MD5_DIGEST_SIZE);
|
||||||
|
|
||||||
|
InitMd5(md5); /* reset state */
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* CTaoCrypt software implementation */
|
||||||
|
|
||||||
#ifndef min
|
#ifndef min
|
||||||
|
|
||||||
static INLINE word32 min(word32 a, word32 b)
|
static INLINE word32 min(word32 a, word32 b)
|
||||||
@@ -224,3 +338,5 @@ void Md5Final(Md5* md5, byte* hash)
|
|||||||
InitMd5(md5); /* reset state */
|
InitMd5(md5); /* reset state */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* STM32F2_CRYPTO */
|
||||||
|
|
||||||
|
@@ -76,6 +76,8 @@ STATIC INLINE word32 ByteReverseWord32(word32 value)
|
|||||||
#ifdef PPC_INTRINSICS
|
#ifdef PPC_INTRINSICS
|
||||||
/* PPC: load reverse indexed instruction */
|
/* PPC: load reverse indexed instruction */
|
||||||
return (word32)__lwbrx(&value,0);
|
return (word32)__lwbrx(&value,0);
|
||||||
|
#elif defined(KEIL_INTRINSICS)
|
||||||
|
return (word32)__rev(value);
|
||||||
#elif defined(FAST_ROTATE)
|
#elif defined(FAST_ROTATE)
|
||||||
/* 5 instructions with rotate instruction, 9 without */
|
/* 5 instructions with rotate instruction, 9 without */
|
||||||
return (rotrFixed(value, 8U) & 0xff00ff00) |
|
return (rotrFixed(value, 8U) & 0xff00ff00) |
|
||||||
|
@@ -31,6 +31,121 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef STM32F2_CRYPTO
|
||||||
|
/*
|
||||||
|
* STM32F2 hardware SHA1 support through the STM32F2 standard peripheral
|
||||||
|
* library. Documentation located in STM32F2xx Standard Peripheral Library
|
||||||
|
* document (See note in README).
|
||||||
|
*/
|
||||||
|
#include "stm32f2xx.h"
|
||||||
|
|
||||||
|
void InitSha(Sha* sha)
|
||||||
|
{
|
||||||
|
/* STM32F2 struct notes:
|
||||||
|
* sha->buffer = first 4 bytes used to hold partial block if needed
|
||||||
|
* sha->buffLen = num bytes currently stored in sha->buffer
|
||||||
|
* sha->loLen = num bytes that have been written to STM32 FIFO
|
||||||
|
*/
|
||||||
|
XMEMSET(sha->buffer, 0, SHA_REG_SIZE);
|
||||||
|
sha->buffLen = 0;
|
||||||
|
sha->loLen = 0;
|
||||||
|
|
||||||
|
/* initialize HASH peripheral */
|
||||||
|
HASH_DeInit();
|
||||||
|
|
||||||
|
/* configure algo used, algo mode, datatype */
|
||||||
|
HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
|
||||||
|
HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HASH
|
||||||
|
| HASH_DataType_8b);
|
||||||
|
|
||||||
|
/* reset HASH processor */
|
||||||
|
HASH->CR |= HASH_CR_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaUpdate(Sha* sha, const byte* data, word32 len)
|
||||||
|
{
|
||||||
|
word32 i = 0;
|
||||||
|
word32 fill = 0;
|
||||||
|
word32 diff = 0;
|
||||||
|
|
||||||
|
/* if saved partial block is available */
|
||||||
|
if (sha->buffLen) {
|
||||||
|
fill = 4 - sha->buffLen;
|
||||||
|
|
||||||
|
/* if enough data to fill, fill and push to FIFO */
|
||||||
|
if (fill <= len) {
|
||||||
|
XMEMCPY((byte*)sha->buffer + sha->buffLen, data, fill);
|
||||||
|
HASH_DataIn(*(uint32_t*)sha->buffer);
|
||||||
|
|
||||||
|
data += fill;
|
||||||
|
len -= fill;
|
||||||
|
sha->loLen += 4;
|
||||||
|
sha->buffLen = 0;
|
||||||
|
} else {
|
||||||
|
/* append partial to existing stored block */
|
||||||
|
XMEMCPY((byte*)sha->buffer + sha->buffLen, data, len);
|
||||||
|
sha->buffLen += len;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write input block in the IN FIFO */
|
||||||
|
for(i = 0; i < len; i += 4)
|
||||||
|
{
|
||||||
|
diff = len - i;
|
||||||
|
if ( diff < 4) {
|
||||||
|
/* store incomplete last block, not yet in FIFO */
|
||||||
|
XMEMSET(sha->buffer, 0, SHA_REG_SIZE);
|
||||||
|
XMEMCPY((byte*)sha->buffer, data, diff);
|
||||||
|
sha->buffLen = diff;
|
||||||
|
} else {
|
||||||
|
HASH_DataIn(*(uint32_t*)data);
|
||||||
|
data+=4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* keep track of total data length thus far */
|
||||||
|
sha->loLen += (len - sha->buffLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaFinal(Sha* sha, byte* hash)
|
||||||
|
{
|
||||||
|
__IO uint16_t nbvalidbitsdata = 0;
|
||||||
|
|
||||||
|
/* finish reading any trailing bytes into FIFO */
|
||||||
|
if (sha->buffLen) {
|
||||||
|
HASH_DataIn(*(uint32_t*)sha->buffer);
|
||||||
|
sha->loLen += sha->buffLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate number of valid bits in last word of input data */
|
||||||
|
nbvalidbitsdata = 8 * (sha->loLen % SHA_REG_SIZE);
|
||||||
|
|
||||||
|
/* configure number of valid bits in last word of the data */
|
||||||
|
HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
|
||||||
|
|
||||||
|
/* start HASH processor */
|
||||||
|
HASH_StartDigest();
|
||||||
|
|
||||||
|
/* wait until Busy flag == RESET */
|
||||||
|
while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {}
|
||||||
|
|
||||||
|
/* read message digest */
|
||||||
|
sha->digest[0] = HASH->HR[0];
|
||||||
|
sha->digest[1] = HASH->HR[1];
|
||||||
|
sha->digest[2] = HASH->HR[2];
|
||||||
|
sha->digest[3] = HASH->HR[3];
|
||||||
|
sha->digest[4] = HASH->HR[4];
|
||||||
|
|
||||||
|
ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
|
||||||
|
|
||||||
|
XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE);
|
||||||
|
|
||||||
|
InitSha(sha); /* reset state */
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* CTaoCrypt software implementation */
|
||||||
|
|
||||||
#ifndef min
|
#ifndef min
|
||||||
|
|
||||||
static INLINE word32 min(word32 a, word32 b)
|
static INLINE word32 min(word32 a, word32 b)
|
||||||
@@ -228,3 +343,5 @@ void ShaFinal(Sha* sha, byte* hash)
|
|||||||
InitSha(sha); /* reset state */
|
InitSha(sha); /* reset state */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* STM32F2_CRYPTO */
|
||||||
|
|
||||||
|
@@ -33,6 +33,9 @@
|
|||||||
|
|
||||||
/* in bytes */
|
/* in bytes */
|
||||||
enum {
|
enum {
|
||||||
|
#ifdef STM32F2_CRYPTO
|
||||||
|
MD5_REG_SIZE = 4, /* STM32 register size, bytes */
|
||||||
|
#endif
|
||||||
MD5 = 0, /* hash type unique */
|
MD5 = 0, /* hash type unique */
|
||||||
MD5_BLOCK_SIZE = 64,
|
MD5_BLOCK_SIZE = 64,
|
||||||
MD5_DIGEST_SIZE = 16,
|
MD5_DIGEST_SIZE = 16,
|
||||||
|
@@ -32,6 +32,9 @@
|
|||||||
|
|
||||||
/* in bytes */
|
/* in bytes */
|
||||||
enum {
|
enum {
|
||||||
|
#ifdef STM32F2_CRYPTO
|
||||||
|
SHA_REG_SIZE = 4, /* STM32 register size, bytes */
|
||||||
|
#endif
|
||||||
SHA = 1, /* hash type unique */
|
SHA = 1, /* hash type unique */
|
||||||
SHA_BLOCK_SIZE = 64,
|
SHA_BLOCK_SIZE = 64,
|
||||||
SHA_DIGEST_SIZE = 20,
|
SHA_DIGEST_SIZE = 20,
|
||||||
|
Reference in New Issue
Block a user