Merge branch 'master' of github.com:cyassl/cyassl

This commit is contained in:
John Safranek 2012-12-26 21:53:20 -08:00
commit d993ee1969
9 changed files with 883 additions and 26 deletions

View File

@ -41,6 +41,367 @@
#endif
#ifdef STM32F2_CRYPTO
/*
* STM32F2 hardware AES support through the STM32F2 standard peripheral
* library. Documentation located in STM32F2xx Standard Peripheral Library
* document (See note in README).
*/
#include "stm32f2xx.h"
int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
int dir)
{
word32 *rk = aes->key;
if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
return BAD_FUNC_ARG;
aes->rounds = keylen/4 + 6;
XMEMCPY(rk, userKey, keylen);
ByteReverseWords(rk, rk, keylen);
return AesSetIV(aes, iv);
}
void AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
word32 *enc_key, *iv;
CRYP_InitTypeDef AES_CRYP_InitStructure;
CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
enc_key = aes->key;
iv = aes->reg;
/* crypto structure initialization */
CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
CRYP_StructInit(&AES_CRYP_InitStructure);
CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
/* reset registers to their default values */
CRYP_DeInit();
/* load key into correct registers */
switch(aes->rounds)
{
case 10: /* 128-bit key */
AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[0];
AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1];
AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[2];
AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3];
break;
case 12: /* 192-bit key */
AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[0];
AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1];
AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[2];
AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3];
AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[4];
AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5];
break;
case 14: /* 256-bit key */
AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
AES_CRYP_KeyInitStructure.CRYP_Key0Left = enc_key[0];
AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1];
AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[2];
AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3];
AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[4];
AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5];
AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[6];
AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7];
break;
default:
break;
}
CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
/* set iv */
ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
AES_CRYP_IVInitStructure.CRYP_IV0Left = iv[0];
AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
AES_CRYP_IVInitStructure.CRYP_IV1Left = iv[2];
AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
CRYP_IVInit(&AES_CRYP_IVInitStructure);
/* set direction, mode, and datatype */
AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
CRYP_Init(&AES_CRYP_InitStructure);
/* enable crypto processor */
CRYP_Cmd(ENABLE);
while (sz > 0)
{
/* flush IN/OUT FIFOs */
CRYP_FIFOFlush();
CRYP_DataIn(*(uint32_t*)&in[0]);
CRYP_DataIn(*(uint32_t*)&in[4]);
CRYP_DataIn(*(uint32_t*)&in[8]);
CRYP_DataIn(*(uint32_t*)&in[12]);
/* wait until the complete message has been processed */
while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
*(uint32_t*)&out[0] = CRYP_DataOut();
*(uint32_t*)&out[4] = CRYP_DataOut();
*(uint32_t*)&out[8] = CRYP_DataOut();
*(uint32_t*)&out[12] = CRYP_DataOut();
/* store iv for next call */
XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
sz -= 16;
in += 16;
out += 16;
}
/* disable crypto processor */
CRYP_Cmd(DISABLE);
}
void AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
word32 *dec_key, *iv;
CRYP_InitTypeDef AES_CRYP_InitStructure;
CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
dec_key = aes->key;
iv = aes->reg;
/* crypto structure initialization */
CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
CRYP_StructInit(&AES_CRYP_InitStructure);
CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
/* if input and output same will overwrite input iv */
XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
/* reset registers to their default values */
CRYP_DeInit();
/* load key into correct registers */
switch(aes->rounds)
{
case 10: /* 128-bit key */
AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
AES_CRYP_KeyInitStructure.CRYP_Key2Left = dec_key[0];
AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[1];
AES_CRYP_KeyInitStructure.CRYP_Key3Left = dec_key[2];
AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[3];
break;
case 12: /* 192-bit key */
AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
AES_CRYP_KeyInitStructure.CRYP_Key1Left = dec_key[0];
AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[1];
AES_CRYP_KeyInitStructure.CRYP_Key2Left = dec_key[2];
AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[3];
AES_CRYP_KeyInitStructure.CRYP_Key3Left = dec_key[4];
AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[5];
break;
case 14: /* 256-bit key */
AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
AES_CRYP_KeyInitStructure.CRYP_Key0Left = dec_key[0];
AES_CRYP_KeyInitStructure.CRYP_Key0Right = dec_key[1];
AES_CRYP_KeyInitStructure.CRYP_Key1Left = dec_key[2];
AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[3];
AES_CRYP_KeyInitStructure.CRYP_Key2Left = dec_key[4];
AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[5];
AES_CRYP_KeyInitStructure.CRYP_Key3Left = dec_key[6];
AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[7];
break;
default:
break;
}
/* set direction, mode, and datatype for key preparation */
AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b;
CRYP_Init(&AES_CRYP_InitStructure);
CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
/* enable crypto processor */
CRYP_Cmd(ENABLE);
/* wait until key has been prepared */
while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
/* set direction, mode, and datatype for decryption */
AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
CRYP_Init(&AES_CRYP_InitStructure);
/* set iv */
ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
AES_CRYP_IVInitStructure.CRYP_IV0Left = iv[0];
AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
AES_CRYP_IVInitStructure.CRYP_IV1Left = iv[2];
AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
CRYP_IVInit(&AES_CRYP_IVInitStructure);
/* enable crypto processor */
CRYP_Cmd(ENABLE);
while (sz > 0)
{
/* flush IN/OUT FIFOs */
CRYP_FIFOFlush();
CRYP_DataIn(*(uint32_t*)&in[0]);
CRYP_DataIn(*(uint32_t*)&in[4]);
CRYP_DataIn(*(uint32_t*)&in[8]);
CRYP_DataIn(*(uint32_t*)&in[12]);
/* wait until the complete message has been processed */
while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
*(uint32_t*)&out[0] = CRYP_DataOut();
*(uint32_t*)&out[4] = CRYP_DataOut();
*(uint32_t*)&out[8] = CRYP_DataOut();
*(uint32_t*)&out[12] = CRYP_DataOut();
/* store iv for next call */
XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
sz -= 16;
in += 16;
out += 16;
}
/* disable crypto processor */
CRYP_Cmd(DISABLE);
}
#ifdef CYASSL_AES_COUNTER
/* AES-CTR calls this for key setup */
int AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
const byte* iv, int dir)
{
return AesSetKey(aes, userKey, keylen, iv, dir);
}
void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
word32 *enc_key, *iv;
CRYP_InitTypeDef AES_CRYP_InitStructure;
CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
enc_key = aes->key;
iv = aes->reg;
/* crypto structure initialization */
CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
CRYP_StructInit(&AES_CRYP_InitStructure);
CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
/* reset registers to their default values */
CRYP_DeInit();
/* load key into correct registers */
switch(aes->rounds)
{
case 10: /* 128-bit key */
AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[0];
AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1];
AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[2];
AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3];
break;
case 12: /* 192-bit key */
AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[0];
AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1];
AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[2];
AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3];
AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[4];
AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5];
break;
case 14: /* 256-bit key */
AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
AES_CRYP_KeyInitStructure.CRYP_Key0Left = enc_key[0];
AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1];
AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[2];
AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3];
AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[4];
AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5];
AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[6];
AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7];
break;
default:
break;
}
CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
/* set iv */
ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
AES_CRYP_IVInitStructure.CRYP_IV0Left = iv[0];
AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
AES_CRYP_IVInitStructure.CRYP_IV1Left = iv[2];
AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
CRYP_IVInit(&AES_CRYP_IVInitStructure);
/* set direction, mode, and datatype */
AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
CRYP_Init(&AES_CRYP_InitStructure);
/* enable crypto processor */
CRYP_Cmd(ENABLE);
while (sz > 0)
{
/* flush IN/OUT FIFOs */
CRYP_FIFOFlush();
CRYP_DataIn(*(uint32_t*)&in[0]);
CRYP_DataIn(*(uint32_t*)&in[4]);
CRYP_DataIn(*(uint32_t*)&in[8]);
CRYP_DataIn(*(uint32_t*)&in[12]);
/* wait until the complete message has been processed */
while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
*(uint32_t*)&out[0] = CRYP_DataOut();
*(uint32_t*)&out[4] = CRYP_DataOut();
*(uint32_t*)&out[8] = CRYP_DataOut();
*(uint32_t*)&out[12] = CRYP_DataOut();
/* store iv for next call */
XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
sz -= 16;
in += 16;
out += 16;
}
/* disable crypto processor */
CRYP_Cmd(DISABLE);
}
#endif /* CYASSL_AES_COUNTER */
#else /* CTaoCrypt software implementation */
static const word32 rcon[] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000,
@ -847,18 +1208,6 @@ static int AES_set_decrypt_key(const unsigned char* userKey, const int bits,
#endif /* CYASSL_AESNI */
int AesSetIV(Aes* aes, const byte* iv)
{
if (aes == NULL)
return BAD_FUNC_ARG;
if (iv)
XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
return 0;
}
static int AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
const byte* iv, int dir)
{
@ -2192,6 +2541,19 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
#endif /* HAVE_AESGCM */
#endif /* STM32F2_CRYPTO */
int AesSetIV(Aes* aes, const byte* iv)
{
if (aes == NULL)
return BAD_FUNC_ARG;
if (iv)
XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
return 0;
}
#endif /* NO_AES */

View File

@ -34,6 +34,223 @@
#endif
#ifdef STM32F2_CRYPTO
/*
* STM32F2 hardware DES/3DES support through the STM32F2 standard
* peripheral library. Documentation located in STM32F2xx Standard
* Peripheral Library document (See note in README).
*/
#include "stm32f2xx.h"
void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
{
word32 *dkey = des->key;
XMEMCPY(dkey, key, 8);
ByteReverseWords(dkey, dkey, 8);
Des_SetIV(des, iv);
}
void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
{
word32 *dkey1 = des->key[0];
word32 *dkey2 = des->key[1];
word32 *dkey3 = des->key[2];
XMEMCPY(dkey1, key, 8); /* set key 1 */
XMEMCPY(dkey2, key + 8, 8); /* set key 2 */
XMEMCPY(dkey3, key + 16, 8); /* set key 3 */
ByteReverseWords(dkey1, dkey1, 8);
ByteReverseWords(dkey2, dkey2, 8);
ByteReverseWords(dkey3, dkey3, 8);
Des3_SetIV(des, iv);
}
void DesCrypt(Des* des, byte* out, const byte* in, word32 sz,
int dir, int mode)
{
word32 *dkey, *iv;
CRYP_InitTypeDef DES_CRYP_InitStructure;
CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure;
CRYP_IVInitTypeDef DES_CRYP_IVInitStructure;
dkey = des->key;
iv = des->reg;
/* crypto structure initialization */
CRYP_KeyStructInit(&DES_CRYP_KeyInitStructure);
CRYP_StructInit(&DES_CRYP_InitStructure);
CRYP_IVStructInit(&DES_CRYP_IVInitStructure);
/* reset registers to their default values */
CRYP_DeInit();
/* set direction, mode, and datatype */
if (dir == DES_ENCRYPTION) {
DES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
} else { /* DES_DECRYPTION */
DES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
}
if (mode == DES_CBC) {
DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_CBC;
} else { /* DES_ECB */
DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_ECB;
}
DES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
CRYP_Init(&DES_CRYP_InitStructure);
/* load key into correct registers */
DES_CRYP_KeyInitStructure.CRYP_Key1Left = dkey[0];
DES_CRYP_KeyInitStructure.CRYP_Key1Right = dkey[1];
CRYP_KeyInit(&DES_CRYP_KeyInitStructure);
/* set iv */
ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
DES_CRYP_IVInitStructure.CRYP_IV0Left = iv[0];
DES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
CRYP_IVInit(&DES_CRYP_IVInitStructure);
/* enable crypto processor */
CRYP_Cmd(ENABLE);
while (sz > 0)
{
/* flush IN/OUT FIFOs */
CRYP_FIFOFlush();
/* if input and output same will overwrite input iv */
XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
CRYP_DataIn(*(uint32_t*)&in[0]);
CRYP_DataIn(*(uint32_t*)&in[4]);
/* wait until the complete message has been processed */
while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
*(uint32_t*)&out[0] = CRYP_DataOut();
*(uint32_t*)&out[4] = CRYP_DataOut();
/* store iv for next call */
XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
sz -= DES_BLOCK_SIZE;
in += DES_BLOCK_SIZE;
out += DES_BLOCK_SIZE;
}
/* disable crypto processor */
CRYP_Cmd(DISABLE);
}
void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
{
DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_CBC);
}
void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
{
DesCrypt(des, out, in, sz, DES_DECRYPTION, DES_CBC);
}
void Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
{
DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_ECB);
}
void Des3Crypt(Des3* des, byte* out, const byte* in, word32 sz,
int dir)
{
word32 *dkey1, *dkey2, *dkey3, *iv;
CRYP_InitTypeDef DES3_CRYP_InitStructure;
CRYP_KeyInitTypeDef DES3_CRYP_KeyInitStructure;
CRYP_IVInitTypeDef DES3_CRYP_IVInitStructure;
dkey1 = des->key[0];
dkey2 = des->key[1];
dkey3 = des->key[2];
iv = des->reg;
/* crypto structure initialization */
CRYP_KeyStructInit(&DES3_CRYP_KeyInitStructure);
CRYP_StructInit(&DES3_CRYP_InitStructure);
CRYP_IVStructInit(&DES3_CRYP_IVInitStructure);
/* reset registers to their default values */
CRYP_DeInit();
/* set direction, mode, and datatype */
if (dir == DES_ENCRYPTION) {
DES3_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
} else {
DES3_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
}
DES3_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_TDES_CBC;
DES3_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
CRYP_Init(&DES3_CRYP_InitStructure);
/* load key into correct registers */
DES3_CRYP_KeyInitStructure.CRYP_Key1Left = dkey1[0];
DES3_CRYP_KeyInitStructure.CRYP_Key1Right = dkey1[1];
DES3_CRYP_KeyInitStructure.CRYP_Key2Left = dkey2[0];
DES3_CRYP_KeyInitStructure.CRYP_Key2Right = dkey2[1];
DES3_CRYP_KeyInitStructure.CRYP_Key3Left = dkey3[0];
DES3_CRYP_KeyInitStructure.CRYP_Key3Right = dkey3[1];
CRYP_KeyInit(&DES3_CRYP_KeyInitStructure);
/* set iv */
ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
DES3_CRYP_IVInitStructure.CRYP_IV0Left = iv[0];
DES3_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
CRYP_IVInit(&DES3_CRYP_IVInitStructure);
/* enable crypto processor */
CRYP_Cmd(ENABLE);
while (sz > 0)
{
/* flush IN/OUT FIFOs */
CRYP_FIFOFlush();
CRYP_DataIn(*(uint32_t*)&in[0]);
CRYP_DataIn(*(uint32_t*)&in[4]);
/* wait until the complete message has been processed */
while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
*(uint32_t*)&out[0] = CRYP_DataOut();
*(uint32_t*)&out[4] = CRYP_DataOut();
/* store iv for next call */
XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
sz -= DES_BLOCK_SIZE;
in += DES_BLOCK_SIZE;
out += DES_BLOCK_SIZE;
}
/* disable crypto processor */
CRYP_Cmd(DISABLE);
}
void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
{
Des3Crypt(des, out, in, sz, DES_ENCRYPTION);
}
void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
{
Des3Crypt(des, out, in, sz, DES_DECRYPTION);
}
#else /* CTaoCrypt software implementation */
/* permuted choice table (key) */
static const byte pc1[] = {
57, 49, 41, 33, 25, 17, 9,
@ -327,20 +544,6 @@ static INLINE int Reverse(int dir)
}
void Des_SetIV(Des* des, const byte* iv)
{
if (des && iv)
XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
}
void Des3_SetIV(Des3* des, const byte* iv)
{
if (des && iv)
XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
}
void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
{
DesSetKey(key, dir, des->key);
@ -524,5 +727,20 @@ void Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
#endif /* CYASSL_DES_ECB */
#endif /* STM32F2_CRYPTO */
void Des_SetIV(Des* des, const byte* iv)
{
if (des && iv)
XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
}
void Des3_SetIV(Des3* des, const byte* iv)
{
if (des && iv)
XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
}
#endif /* NO_DES3 */

View File

@ -33,6 +33,120 @@
#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
static INLINE word32 min(word32 a, word32 b)
@ -224,3 +338,5 @@ void Md5Final(Md5* md5, byte* hash)
InitMd5(md5); /* reset state */
}
#endif /* STM32F2_CRYPTO */

View File

@ -76,6 +76,8 @@ STATIC INLINE word32 ByteReverseWord32(word32 value)
#ifdef PPC_INTRINSICS
/* PPC: load reverse indexed instruction */
return (word32)__lwbrx(&value,0);
#elif defined(KEIL_INTRINSICS)
return (word32)__rev(value);
#elif defined(FAST_ROTATE)
/* 5 instructions with rotate instruction, 9 without */
return (rotrFixed(value, 8U) & 0xff00ff00) |

View File

@ -462,6 +462,35 @@ int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
}
#endif /* FREESCALE_K70_RNGA */
#elif defined(STM32F2_RNG)
#include "stm32f2xx_rng.h"
/*
* Generate a RNG seed using the hardware random number generator
* on the STM32F2. Documentation located in STM32F2xx Standard Peripheral
* Library document (See note in README).
*/
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
{
int i;
/* enable RNG clock source */
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
/* enable RNG peripheral */
RNG_Cmd(ENABLE);
for (i = 0; i < sz; i++) {
/* wait until RNG number is ready */
while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET) { }
/* get value */
output[i] = RNG_GetRandomNumber();
}
return 0;
}
#elif defined(NO_DEV_RANDOM)
#error "you need to write an os specific GenerateSeed() here"

View File

@ -31,6 +31,121 @@
#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
static INLINE word32 min(word32 a, word32 b)
@ -228,3 +343,5 @@ void ShaFinal(Sha* sha, byte* hash)
InitSha(sha); /* reset state */
}
#endif /* STM32F2_CRYPTO */

View File

@ -43,6 +43,13 @@ enum {
DES_DECRYPTION = 1
};
#ifdef STM32F2_CRYPTO
enum {
DES_CBC = 0,
DES_ECB = 1
};
#endif
/* DES encryption and decryption */
typedef struct Des {

View File

@ -33,6 +33,9 @@
/* in bytes */
enum {
#ifdef STM32F2_CRYPTO
MD5_REG_SIZE = 4, /* STM32 register size, bytes */
#endif
MD5 = 0, /* hash type unique */
MD5_BLOCK_SIZE = 64,
MD5_DIGEST_SIZE = 16,

View File

@ -32,6 +32,9 @@
/* in bytes */
enum {
#ifdef STM32F2_CRYPTO
SHA_REG_SIZE = 4, /* STM32 register size, bytes */
#endif
SHA = 1, /* hash type unique */
SHA_BLOCK_SIZE = 64,
SHA_DIGEST_SIZE = 20,