CyaSSL master, 2.8.6

This commit is contained in:
Takashi Kojo
2014-01-31 08:44:42 +09:00
parent 9a67901081
commit e28d256197
83 changed files with 7807 additions and 859 deletions

View File

@@ -62,8 +62,8 @@
* document (See note in README).
*/
#include "stm32f2xx.h"
#include "stm32f2xx_cryp.h"
#include "stm32f2xx_cryp.h"
int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
int dir)
{
@@ -553,6 +553,96 @@ int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
return 0;
}
#elif defined FREESCALE_MMCAU
/*
* Freescale mmCAU hardware AES support through the CAU/mmCAU library.
* Documentation located in ColdFire/ColdFire+ CAU and Kinetis mmCAU
* Software Library User Guide (See note in README).
*/
#include "cau_api.h"
int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
int dir)
{
byte *rk = (byte*)aes->key;
if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
return BAD_FUNC_ARG;
if (rk == NULL)
return BAD_FUNC_ARG;
aes->rounds = keylen/4 + 6;
cau_aes_set_key(userKey, keylen*8, rk);
return AesSetIV(aes, iv);
}
int AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
int i;
int offset = 0;
int len = sz;
byte *iv, *enc_key;
byte temp_block[AES_BLOCK_SIZE];
iv = (byte*)aes->reg;
enc_key = (byte*)aes->key;
while (len > 0)
{
XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
/* XOR block with IV for CBC */
for (i = 0; i < AES_BLOCK_SIZE; i++)
temp_block[i] ^= iv[i];
cau_aes_encrypt(temp_block, enc_key, aes->rounds, out + offset);
len -= AES_BLOCK_SIZE;
offset += AES_BLOCK_SIZE;
/* store IV for next block */
XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
}
return 0;
}
int AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
int i;
int offset = 0;
int len = sz;
byte* iv, *dec_key;
byte temp_block[AES_BLOCK_SIZE];
iv = (byte*)aes->reg;
dec_key = (byte*)aes->key;
while (len > 0)
{
XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
cau_aes_decrypt(in + offset, dec_key, aes->rounds, out + offset);
/* XOR block with IV for CBC */
for (i = 0; i < AES_BLOCK_SIZE; i++)
(out + offset)[i] ^= iv[i];
/* store IV for next block */
XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
len -= AES_BLOCK_SIZE;
offset += AES_BLOCK_SIZE;
}
return 0;
}
#else /* CTaoCrypt software implementation */
static const word32 rcon[] = {
@@ -1386,6 +1476,10 @@ static int AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
#ifdef CYASSL_AESNI
aes->use_aesni = 0;
#endif /* CYASSL_AESNI */
#ifdef CYASSL_AES_COUNTER
aes->left = 0;
#endif /* CYASSL_AES_COUNTER */
aes->rounds = keylen/4 + 6;
XMEMCPY(rk, userKey, keylen);
@@ -2039,15 +2133,39 @@ static INLINE void IncrementAesCounter(byte* inOutCtr)
void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
word32 blocks = sz / AES_BLOCK_SIZE;
byte* tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
while (blocks--) {
/* consume any unused bytes left in aes->tmp */
while (aes->left && sz) {
*(out++) = *(in++) ^ *(tmp++);
aes->left--;
sz--;
}
/* do as many block size ops as possible */
while (sz >= AES_BLOCK_SIZE) {
AesEncrypt(aes, (byte*)aes->reg, out);
IncrementAesCounter((byte*)aes->reg);
xorbuf(out, in, AES_BLOCK_SIZE);
out += AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
sz -= AES_BLOCK_SIZE;
aes->left = 0;
}
/* handle non block size remaining and sotre unused byte count in left */
if (sz) {
AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp);
IncrementAesCounter((byte*)aes->reg);
aes->left = AES_BLOCK_SIZE;
tmp = (byte*)aes->tmp;
while (sz--) {
*(out++) = *(in++) ^ *(tmp++);
aes->left--;
}
}
}

View File

@@ -1004,15 +1004,17 @@ __asm__( \
#define SQRADDAC(i, j) \
do { fp_word t; \
t = sc0 + ((fp_word)i) * ((fp_word)j); sc0 = t; \
t = sc1 + (t >> DIGIT_BIT); sc1 = t; sc2 += t >> DIGIT_BIT; \
t = sc0 + ((fp_word)i) * ((fp_word)j); sc0 = (fp_digit)t; \
t = sc1 + (t >> DIGIT_BIT); sc1 = (fp_digit)t; \
sc2 += (fp_digit)(t >> DIGIT_BIT); \
} while (0);
#define SQRADDDB \
do { fp_word t; \
t = ((fp_word)sc0) + ((fp_word)sc0) + c0; c0 = t; \
t = ((fp_word)sc1) + ((fp_word)sc1) + c1 + (t >> DIGIT_BIT); c1 = t; \
c2 = c2 + ((fp_word)sc2) + ((fp_word)sc2) + (t >> DIGIT_BIT); \
t = ((fp_word)sc0) + ((fp_word)sc0) + c0; c0 = (fp_digit)t; \
t = ((fp_word)sc1) + ((fp_word)sc1) + c1 + (t >> DIGIT_BIT); \
c1 = (fp_digit)t; \
c2 = c2 + (fp_digit)(((fp_word)sc2) + ((fp_word)sc2) + (t >> DIGIT_BIT)); \
} while (0);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -147,16 +147,101 @@ const byte base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
};
/* porting assistance from yaSSL by Raphael HUCK */
int Base64_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)
/* make sure *i (idx) won't exceed max, store and possibly escape to out,
* raw means use e w/o decode, 0 on success */
static int CEscape(int escaped, byte e, byte* out, word32* i, word32 max,
int raw)
{
int doEscape = 0;
word32 needed = 1;
word32 idx = *i;
byte basic;
byte plus = 0;
byte equals = 0;
byte newline = 0;
if (raw)
basic = e;
else
basic = base64Encode[e];
/* check whether to escape */
if (escaped) {
switch ((char)basic) {
case '+' :
plus = 1;
doEscape = 1;
needed += 2;
break;
case '=' :
equals = 1;
doEscape = 1;
needed += 2;
break;
case '\n' :
newline = 1;
doEscape = 1;
needed += 2;
break;
default:
/* do nothing */
break;
}
}
/* check size */
if ( (idx+needed) > max) {
CYASSL_MSG("Escape buffer max too small");
return BUFFER_E;
}
/* store it */
if (doEscape == 0) {
out[idx++] = basic;
}
else {
out[idx++] = '%'; /* start escape */
if (plus) {
out[idx++] = '2';
out[idx++] = 'B';
}
else if (equals) {
out[idx++] = '3';
out[idx++] = 'D';
}
else if (newline) {
out[idx++] = '0';
out[idx++] = 'A';
}
}
*i = idx;
return 0;
}
/* internal worker, handles both escaped and normal line endings */
static int DoBase64_Encode(const byte* in, word32 inLen, byte* out,
word32* outLen, int escaped)
{
int ret = 0;
word32 i = 0,
j = 0,
n = 0; /* new line counter */
word32 outSz = (inLen + 3 - 1) / 3 * 4;
outSz += (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ; /* new lines */
word32 addSz = (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ; /* new lines */
if (escaped)
addSz *= 3; /* instead of just \n, we're doing %0A triplet */
outSz += addSz;
/* if escaped we can't predetermine size for one pass encoding, but
* make sure we have enough if no escapes are in input */
if (outSz > *outLen) return BAD_FUNC_ARG;
while (inLen > 2) {
@@ -171,19 +256,25 @@ int Base64_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)
byte e4 = b3 & 0x3F;
/* store */
out[i++] = base64Encode[e1];
out[i++] = base64Encode[e2];
out[i++] = base64Encode[e3];
out[i++] = base64Encode[e4];
ret = CEscape(escaped, e1, out, &i, *outLen, 0);
if (ret != 0) break;
ret = CEscape(escaped, e2, out, &i, *outLen, 0);
if (ret != 0) break;
ret = CEscape(escaped, e3, out, &i, *outLen, 0);
if (ret != 0) break;
ret = CEscape(escaped, e4, out, &i, *outLen, 0);
if (ret != 0) break;
inLen -= 3;
if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen)
out[i++] = '\n';
if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen) {
ret = CEscape(escaped, '\n', out, &i, *outLen, 1);
if (ret != 0) break;
}
}
/* last integral */
if (inLen) {
if (inLen && ret == 0) {
int twoBytes = (inLen == 2);
byte b1 = in[j++];
@@ -193,18 +284,43 @@ int Base64_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)
byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4);
byte e3 = (b2 & 0xF) << 2;
out[i++] = base64Encode[e1];
out[i++] = base64Encode[e2];
out[i++] = (twoBytes) ? base64Encode[e3] : PAD;
out[i++] = PAD;
ret = CEscape(escaped, e1, out, &i, *outLen, 0);
if (ret == 0)
ret = CEscape(escaped, e2, out, &i, *outLen, 0);
if (ret == 0) {
/* third */
if (twoBytes)
ret = CEscape(escaped, e3, out, &i, *outLen, 0);
else
ret = CEscape(escaped, '=', out, &i, *outLen, 1);
}
/* fourth always pad */
if (ret == 0)
ret = CEscape(escaped, '=', out, &i, *outLen, 1);
}
out[i++] = '\n';
if (i != outSz)
return ASN_INPUT_E;
*outLen = outSz;
if (ret == 0)
ret = CEscape(escaped, '\n', out, &i, *outLen, 1);
return 0;
if (i != outSz && escaped == 0 && ret == 0)
return ASN_INPUT_E;
*outLen = i;
return ret;
}
/* Base64 Encode, PEM style, with \n line endings */
int Base64_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)
{
return DoBase64_Encode(in, inLen, out, outLen, 0);
}
/* Base64 Encode, with %0A esacped line endings instead of \n */
int Base64_EncodeEsc(const byte* in, word32 inLen, byte* out, word32* outLen)
{
return DoBase64_Encode(in, inLen, out, outLen, 1);
}

View File

@@ -413,6 +413,187 @@ void Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
}
}
#elif defined FREESCALE_MMCAU
/*
* Freescale mmCAU hardware DES/3DES support through the CAU/mmCAU library.
* Documentation located in ColdFire/ColdFire+ CAU and Kinetis mmCAU
* Software Library User Guide (See note in README).
*/
#include "cau_api.h"
const unsigned char parityLookup[128] =
{
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
};
void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
{
int i = 0;
byte* dkey = (byte*)des->key;
XMEMCPY(dkey, key, 8);
Des_SetIV(des, iv);
/* fix key parity, if needed */
for (i = 0; i < 8; i++) {
dkey[i] = ((dkey[i] & 0xFE) | parityLookup[dkey[i] >> 1]);
}
}
void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
{
int i = 0;
byte* dkey1 = (byte*)des->key[0];
byte* dkey2 = (byte*)des->key[1];
byte* dkey3 = (byte*)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 */
Des3_SetIV(des, iv);
/* fix key parity if needed */
for (i = 0; i < 8; i++)
dkey1[i] = ((dkey1[i] & 0xFE) | parityLookup[dkey1[i] >> 1]);
for (i = 0; i < 8; i++)
dkey2[i] = ((dkey2[i] & 0xFE) | parityLookup[dkey2[i] >> 1]);
for (i = 0; i < 8; i++)
dkey3[i] = ((dkey3[i] & 0xFE) | parityLookup[dkey3[i] >> 1]);
}
void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
{
int i;
int offset = 0;
int len = sz;
byte *iv;
byte temp_block[DES_BLOCK_SIZE];
iv = (byte*)des->reg;
while (len > 0)
{
XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
/* XOR block with IV for CBC */
for (i = 0; i < DES_BLOCK_SIZE; i++)
temp_block[i] ^= iv[i];
cau_des_encrypt(temp_block, (byte*)des->key, out + offset);
len -= DES_BLOCK_SIZE;
offset += DES_BLOCK_SIZE;
/* store IV for next block */
XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
}
return;
}
void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
{
int i;
int offset = 0;
int len = sz;
byte* iv;
byte temp_block[DES_BLOCK_SIZE];
iv = (byte*)des->reg;
while (len > 0)
{
XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
cau_des_decrypt(in + offset, (byte*)des->key, out + offset);
/* XOR block with IV for CBC */
for (i = 0; i < DES_BLOCK_SIZE; i++)
(out + offset)[i] ^= iv[i];
/* store IV for next block */
XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);
len -= DES_BLOCK_SIZE;
offset += DES_BLOCK_SIZE;
}
return;
}
void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
{
int i;
int offset = 0;
int len = sz;
byte *iv;
byte temp_block[DES_BLOCK_SIZE];
iv = (byte*)des->reg;
while (len > 0)
{
XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
/* XOR block with IV for CBC */
for (i = 0; i < DES_BLOCK_SIZE; i++)
temp_block[i] ^= iv[i];
cau_des_encrypt(temp_block , (byte*)des->key[0], out + offset);
cau_des_decrypt(out + offset, (byte*)des->key[1], out + offset);
cau_des_encrypt(out + offset, (byte*)des->key[2], out + offset);
len -= DES_BLOCK_SIZE;
offset += DES_BLOCK_SIZE;
/* store IV for next block */
XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
}
return;
}
void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
{
int i;
int offset = 0;
int len = sz;
byte* iv;
byte temp_block[DES_BLOCK_SIZE];
iv = (byte*)des->reg;
while (len > 0)
{
XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
cau_des_decrypt(in + offset , (byte*)des->key[2], out + offset);
cau_des_encrypt(out + offset, (byte*)des->key[1], out + offset);
cau_des_decrypt(out + offset, (byte*)des->key[0], out + offset);
/* XOR block with IV for CBC */
for (i = 0; i < DES_BLOCK_SIZE; i++)
(out + offset)[i] ^= iv[i];
/* store IV for next block */
XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);
len -= DES_BLOCK_SIZE;
offset += DES_BLOCK_SIZE;
}
return;
}
#else /* CTaoCrypt software implementation */
/* permuted choice table (key) */

View File

@@ -1997,7 +1997,6 @@ int ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
int ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
{
int x, err;
if (in == NULL || key == NULL)
return ECC_BAD_ARG_E;
@@ -2144,17 +2143,22 @@ int ecc_sig_size(ecc_key* key)
/** Our FP cache */
static struct {
typedef struct {
ecc_point* g; /* cached COPY of base point */
ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
mp_int mu; /* copy of the montgomery constant */
int lru_count; /* amount of times this entry has been used */
int lock; /* flag to indicate cache eviction */
/* permitted (0) or not (1) */
} fp_cache[FP_ENTRIES];
} fp_cache_t;
static volatile int initMutex = 0; /* prevent multiple mutex inits */
static CyaSSL_Mutex ecc_fp_lock;
/* if HAVE_THREAD_LS this cache is per thread, no locking needed */
static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
#ifndef HAVE_THREAD_LS
static volatile int initMutex = 0; /* prevent multiple mutex inits */
static CyaSSL_Mutex ecc_fp_lock;
#endif /* HAVE_THREAD_LS */
/* simple table to help direct the generation of the LUT */
static const struct {
@@ -3263,21 +3267,22 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
ecc_point* B, mp_int* kB,
ecc_point* C, mp_int* modulus)
{
int idx1, idx2, err = MP_OKAY, mpInit = 0;
int idx1 = -1, idx2 = -1, err = MP_OKAY, mpInit = 0;
mp_digit mp;
mp_int mu;
if (initMutex == 0) {
InitMutex(&ecc_fp_lock);
initMutex = 1;
}
err = mp_init(&mu);
if (err != MP_OKAY)
return err;
#ifndef HAVE_THREAD_LS
if (initMutex == 0) {
InitMutex(&ecc_fp_lock);
initMutex = 1;
}
if (LockMutex(&ecc_fp_lock) != 0)
return BAD_MUTEX_E;
#endif /* HAVE_THREAD_LS */
/* find point */
idx1 = find_base(A);
@@ -3362,7 +3367,9 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
}
}
#ifndef HAVE_THREAD_LS
UnLockMutex(&ecc_fp_lock);
#endif /* HAVE_THREAD_LS */
mp_clear(&mu);
return err;
@@ -3389,6 +3396,7 @@ int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus,
if (mp_init(&mu) != MP_OKAY)
return MP_INIT_E;
#ifndef HAVE_THREAD_LS
if (initMutex == 0) {
InitMutex(&ecc_fp_lock);
initMutex = 1;
@@ -3396,6 +3404,7 @@ int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus,
if (LockMutex(&ecc_fp_lock) != 0)
return BAD_MUTEX_E;
#endif /* HAVE_THREAD_LS */
/* find point */
idx = find_base(G);
@@ -3445,7 +3454,9 @@ int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus,
}
}
#ifndef HAVE_THREAD_LS
UnLockMutex(&ecc_fp_lock);
#endif /* HAVE_THREAD_LS */
mp_clear(&mu);
return err;
@@ -3474,18 +3485,23 @@ static void ecc_fp_free_cache(void)
/** Free the Fixed Point cache */
void ecc_fp_free(void)
{
#ifndef HAVE_THREAD_LS
if (initMutex == 0) {
InitMutex(&ecc_fp_lock);
initMutex = 1;
}
if (LockMutex(&ecc_fp_lock) == 0) {
ecc_fp_free_cache();
UnLockMutex(&ecc_fp_lock);
#endif /* HAVE_THREAD_LS */
ecc_fp_free_cache();
#ifndef HAVE_THREAD_LS
UnLockMutex(&ecc_fp_lock);
FreeMutex(&ecc_fp_lock);
initMutex = 0;
}
#endif /* HAVE_THREAD_LS */
}
@@ -3493,33 +3509,189 @@ void ecc_fp_free(void)
#ifdef HAVE_ECC_ENCRYPT
/* init and set defaults, just holders */
void ecc_encrypt_init_options(ecEncOptions* options)
{
if (options) {
XMEMSET(options, 0, sizeof(ecEncOptions));
options->encAlgo = ecAES_128_CBC;
options->kdfAlgo = ecHKDF_SHA256;
options->macAlgo = ecHMAC_SHA256;
enum ecCliState {
ecCLI_INIT = 1,
ecCLI_SALT_GET = 2,
ecCLI_SALT_SET = 3,
ecCLI_SENT_REQ = 4,
ecCLI_RECV_RESP = 5,
ecCLI_BAD_STATE = 99
};
enum ecSrvState {
ecSRV_INIT = 1,
ecSRV_SALT_GET = 2,
ecSRV_SALT_SET = 3,
ecSRV_RECV_REQ = 4,
ecSRV_SENT_RESP = 5,
ecSRV_BAD_STATE = 99
};
struct ecEncCtx {
byte* kdfSalt; /* optional salt for kdf */
byte* kdfInfo; /* optional info for kdf */
byte* macSalt; /* optional salt for mac */
word32 kdfSaltSz; /* size of kdfSalt */
word32 kdfInfoSz; /* size of kdfInfo */
word32 macSaltSz; /* size of macSalt */
byte clientSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */
byte serverSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */
byte encAlgo; /* which encryption type */
byte kdfAlgo; /* which key derivation function type */
byte macAlgo; /* which mac function type */
byte protocol; /* are we REQ_RESP client or server ? */
byte cliSt; /* protocol state, for sanity checks */
byte srvSt; /* protocol state, for sanity checks */
};
const byte* ecc_ctx_get_own_salt(ecEncCtx* ctx)
{
if (ctx == NULL || ctx->protocol == 0)
return NULL;
if (ctx->protocol == REQ_RESP_CLIENT) {
if (ctx->cliSt == ecCLI_INIT) {
ctx->cliSt = ecCLI_SALT_GET;
return ctx->clientSalt;
}
else {
ctx->cliSt = ecCLI_BAD_STATE;
return NULL;
}
}
else if (ctx->protocol == REQ_RESP_SERVER) {
if (ctx->srvSt == ecSRV_INIT) {
ctx->srvSt = ecSRV_SALT_GET;
return ctx->serverSalt;
}
else {
ctx->srvSt = ecSRV_BAD_STATE;
return NULL;
}
}
return NULL;
}
static const char* exchange_info = "Secure Message Exchange";
int ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
{
byte tmp[EXCHANGE_SALT_SZ/2];
int halfSz = EXCHANGE_SALT_SZ/2;
if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
return BAD_FUNC_ARG;
if (ctx->protocol == REQ_RESP_CLIENT) {
XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
if (ctx->cliSt == ecCLI_SALT_GET)
ctx->cliSt = ecCLI_SALT_SET;
else {
ctx->cliSt = ecCLI_BAD_STATE;
return BAD_ENC_STATE_E;
}
}
else {
XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
if (ctx->srvSt == ecSRV_SALT_GET)
ctx->srvSt = ecSRV_SALT_SET;
else {
ctx->srvSt = ecSRV_BAD_STATE;
return BAD_ENC_STATE_E;
}
}
/* mix half and half */
/* tmp stores 2nd half of client before overwrite */
XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz);
XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz);
XMEMCPY(ctx->serverSalt, tmp, halfSz);
ctx->kdfSalt = ctx->clientSalt;
ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
ctx->macSalt = ctx->serverSalt;
ctx->macSaltSz = EXCHANGE_SALT_SZ;
ctx->kdfInfo = (byte*)exchange_info;
ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
return 0;
}
static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, RNG* rng)
{
byte* saltBuffer = NULL;
if (ctx == NULL || rng == NULL || flags == 0)
return BAD_FUNC_ARG;
saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ);
return 0;
}
static void ecc_ctx_init(ecEncCtx* ctx, int flags)
{
if (ctx) {
XMEMSET(ctx, 0, sizeof(ecEncCtx));
ctx->encAlgo = ecAES_128_CBC;
ctx->kdfAlgo = ecHKDF_SHA256;
ctx->macAlgo = ecHMAC_SHA256;
ctx->protocol = (byte)flags;
if (flags == REQ_RESP_CLIENT)
ctx->cliSt = ecCLI_INIT;
if (flags == REQ_RESP_SERVER)
ctx->srvSt = ecSRV_INIT;
}
}
/* alloc/init and set defaults, return new Context */
ecEncCtx* ecc_ctx_new(int flags, RNG* rng)
{
int ret = 0;
ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), 0, DYNAMIC_TYPE_ECC);
ecc_ctx_init(ctx, flags);
if (ctx && flags)
ret = ecc_ctx_set_salt(ctx, flags, rng);
if (ret != 0) {
ecc_ctx_free(ctx);
ctx = NULL;
}
return ctx;
}
/* free any resources, clear any keys */
void ecc_encrypt_free_options(ecEncOptions* options)
void ecc_ctx_free(ecEncCtx* ctx)
{
if (options) {
XMEMSET(options, 0, sizeof(ecEncOptions));
if (ctx) {
XMEMSET(ctx, 0, sizeof(ecEncCtx));
XFREE(ctx, 0, DYNAMIC_TYPE_ECC);
}
}
static int ecc_get_key_sizes(ecEncOptions* options, int* encKeySz, int* ivSz,
static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
int* keysLen, word32* digestSz, word32* blockSz)
{
if (options) {
switch (options->encAlgo) {
if (ctx) {
switch (ctx->encAlgo) {
case ecAES_128_CBC:
*encKeySz = KEY_SIZE_128;
*ivSz = IV_SIZE_64;
@@ -3529,7 +3701,7 @@ static int ecc_get_key_sizes(ecEncOptions* options, int* encKeySz, int* ivSz,
return BAD_FUNC_ARG;
}
switch (options->macAlgo) {
switch (ctx->macAlgo) {
case ecHMAC_SHA256:
*digestSz = SHA256_DIGEST_SIZE;
break;
@@ -3546,22 +3718,23 @@ static int ecc_get_key_sizes(ecEncOptions* options, int* encKeySz, int* ivSz,
/* ecc encrypt with shared secret run through kdf
options holds non default algos and inputs
ctx holds non default algos and inputs
msgSz should be the right size for encAlgo, i.e., already padded
return 0 on success */
int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
word32 msgSz, byte* out, word32* outSz, ecEncOptions* opts)
word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
{
int ret;
word32 blockSz;
word32 digestSz;
ecEncOptions options;
ecEncCtx localCtx;
byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */
byte keys[ECC_BUFSIZE]; /* max size */
word32 sharedSz = sizeof(sharedSecret);
int keysLen;
int encKeySz;
int ivSz;
int offset = 0; /* keys offset if doing msg exchange */
byte* encKey;
byte* encIv;
byte* macKey;
@@ -3570,19 +3743,37 @@ int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
outSz == NULL)
return BAD_FUNC_ARG;
if (opts)
options = *opts;
else {
ecc_encrypt_init_options(&options); /* defaults */
if (ctx == NULL) { /* use defaults */
ecc_ctx_init(&localCtx, 0);
ctx = &localCtx;
}
ret = ecc_get_key_sizes(&options, &encKeySz, &ivSz, &keysLen, &digestSz,
ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
&blockSz);
if (ret != 0)
return ret;
if (ctx->protocol == REQ_RESP_SERVER) {
offset = keysLen;
keysLen *= 2;
if (ctx->srvSt != ecSRV_RECV_REQ)
return BAD_ENC_STATE_E;
ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
}
else if (ctx->protocol == REQ_RESP_CLIENT) {
if (ctx->cliSt != ecCLI_SALT_SET)
return BAD_ENC_STATE_E;
ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
}
if (keysLen > (int)sizeof(keys))
return BUFFER_E;
if ( (msgSz%blockSz) != 0)
return BAD_FUNC_ARG;
return BAD_PADDING_E;
if (*outSz < (msgSz + digestSz))
return BUFFER_E;
@@ -3591,11 +3782,11 @@ int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
if (ret != 0)
return ret;
switch (options.kdfAlgo) {
switch (ctx->kdfAlgo) {
case ecHKDF_SHA256 :
ret = HKDF(SHA256, sharedSecret, sharedSz, options.kdfSalt,
options.kdfSaltSz, options.kdfInfo,
options.kdfInfoSz, keys, keysLen);
ret = HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
ctx->kdfSaltSz, ctx->kdfInfo,
ctx->kdfInfoSz, keys, keysLen);
if (ret != 0)
return ret;
break;
@@ -3604,11 +3795,11 @@ int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
return BAD_FUNC_ARG;
}
encKey = keys;
encKey = keys + offset;
encIv = encKey + encKeySz;
macKey = encKey + encKeySz + ivSz;
switch (options.encAlgo) {
switch (ctx->encAlgo) {
case ecAES_128_CBC:
{
Aes aes;
@@ -3625,7 +3816,7 @@ int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
return BAD_FUNC_ARG;
}
switch (options.macAlgo) {
switch (ctx->macAlgo) {
case ecHMAC_SHA256:
{
Hmac hmac;
@@ -3633,7 +3824,7 @@ int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
if (ret != 0)
return ret;
HmacUpdate(&hmac, out, msgSz);
HmacUpdate(&hmac, options.macSalt, options.macSaltSz);
HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
HmacFinal(&hmac, out+msgSz);
}
break;
@@ -3648,19 +3839,23 @@ int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
}
/* ecc decrypt with shared secret run through kdf
ctx holds non default algos and inputs
return 0 on success */
int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
word32 msgSz, byte* out, word32* outSz, ecEncOptions* opts)
word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
{
int ret;
word32 blockSz;
word32 digestSz;
ecEncOptions options;
ecEncCtx localCtx;
byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */
byte keys[ECC_BUFSIZE]; /* max size */
word32 sharedSz = sizeof(sharedSecret);
int keysLen;
int encKeySz;
int ivSz;
int offset = 0; /* in case using msg exchange */
byte* encKey;
byte* encIv;
byte* macKey;
@@ -3669,19 +3864,37 @@ int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
outSz == NULL)
return BAD_FUNC_ARG;
if (opts)
options = *opts;
else {
ecc_encrypt_init_options(&options); /* defaults */
if (ctx == NULL) { /* use defaults */
ecc_ctx_init(&localCtx, 0);
ctx = &localCtx;
}
ret = ecc_get_key_sizes(&options, &encKeySz, &ivSz, &keysLen, &digestSz,
ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
&blockSz);
if (ret != 0)
return ret;
if (ctx->protocol == REQ_RESP_CLIENT) {
offset = keysLen;
keysLen *= 2;
if (ctx->cliSt != ecCLI_SENT_REQ)
return BAD_ENC_STATE_E;
ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
}
else if (ctx->protocol == REQ_RESP_SERVER) {
if (ctx->srvSt != ecSRV_SALT_SET)
return BAD_ENC_STATE_E;
ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
}
if (keysLen > (int)sizeof(keys))
return BUFFER_E;
if ( ((msgSz-digestSz) % blockSz) != 0)
return BAD_FUNC_ARG;
return BAD_PADDING_E;
if (*outSz < (msgSz - digestSz))
return BUFFER_E;
@@ -3690,11 +3903,11 @@ int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
if (ret != 0)
return ret;
switch (options.kdfAlgo) {
switch (ctx->kdfAlgo) {
case ecHKDF_SHA256 :
ret = HKDF(SHA256, sharedSecret, sharedSz, options.kdfSalt,
options.kdfSaltSz, options.kdfInfo,
options.kdfInfoSz, keys, keysLen);
ret = HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
ctx->kdfSaltSz, ctx->kdfInfo,
ctx->kdfInfoSz, keys, keysLen);
if (ret != 0)
return ret;
break;
@@ -3703,11 +3916,11 @@ int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
return BAD_FUNC_ARG;
}
encKey = keys;
encKey = keys + offset;
encIv = encKey + encKeySz;
macKey = encKey + encKeySz + ivSz;
switch (options.macAlgo) {
switch (ctx->macAlgo) {
case ecHMAC_SHA256:
{
byte verify[SHA256_DIGEST_SIZE];
@@ -3716,7 +3929,7 @@ int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
if (ret != 0)
return ret;
HmacUpdate(&hmac, msg, msgSz-digestSz);
HmacUpdate(&hmac, options.macSalt, options.macSaltSz);
HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
HmacFinal(&hmac, verify);
if (memcmp(verify, msg + msgSz - digestSz, digestSz) != 0) {
@@ -3729,7 +3942,7 @@ int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
return BAD_FUNC_ARG;
}
switch (options.encAlgo) {
switch (ctx->encAlgo) {
case ecAES_128_CBC:
{
Aes aes;

View File

@@ -323,6 +323,26 @@ void CTaoCryptErrorString(int error, char* buffer)
XSTRNCPY(buffer, "ASN OCSP sig error, confirm failure", max);
break;
case BAD_ENC_STATE_E:
XSTRNCPY(buffer, "Bad ecc encrypt state operation", max);
break;
case BAD_PADDING_E:
XSTRNCPY(buffer, "Bad padding, message wrong length", max);
break;
case REQ_ATTRIBUTE_E:
XSTRNCPY(buffer, "Setting cert request attributes error", max);
break;
case PKCS7_OID_E:
XSTRNCPY(buffer, "PKCS#7 error: mismatched OID value", max);
break;
case PKCS7_RECIP_E:
XSTRNCPY(buffer, "PKCS#7 error: no matching recipient found", max);
break;
default:
XSTRNCPY(buffer, "unknown error number", max);

View File

@@ -24,7 +24,9 @@
void fp_sqr_comba12(fp_int *A, fp_int *B)
{
fp_digit *a, b[24], c0, c1, c2, sc0, sc1, sc2;
#ifdef TFM_ISO
fp_word tt;
#endif
a = A->dp;
COMBA_START;

View File

@@ -24,6 +24,9 @@
void fp_sqr_comba17(fp_int *A, fp_int *B)
{
fp_digit *a, b[34], c0, c1, c2, sc0, sc1, sc2;
#ifdef TFM_ISO
fp_word tt;
#endif
a = A->dp;
COMBA_START;

View File

@@ -24,6 +24,9 @@
void fp_sqr_comba3(fp_int *A, fp_int *B)
{
fp_digit *a, b[6], c0, c1, c2;
#ifdef TFM_ISO
fp_word tt;
#endif
a = A->dp;
COMBA_START;

View File

@@ -24,6 +24,9 @@
void fp_sqr_comba4(fp_int *A, fp_int *B)
{
fp_digit *a, b[8], c0, c1, c2;
#ifdef TFM_ISO
fp_word tt;
#endif
a = A->dp;
COMBA_START;

View File

@@ -24,6 +24,9 @@
void fp_sqr_comba6(fp_int *A, fp_int *B)
{
fp_digit *a, b[12], c0, c1, c2, sc0, sc1, sc2;
#ifdef TFM_ISO
fp_word tt;
#endif
a = A->dp;
COMBA_START;

View File

@@ -24,6 +24,9 @@
void fp_sqr_comba7(fp_int *A, fp_int *B)
{
fp_digit *a, b[14], c0, c1, c2, sc0, sc1, sc2;
#ifdef TFM_ISO
fp_word tt;
#endif
a = A->dp;
COMBA_START;

View File

@@ -24,6 +24,9 @@
void fp_sqr_comba8(fp_int *A, fp_int *B)
{
fp_digit *a, b[16], c0, c1, c2, sc0, sc1, sc2;
#ifdef TFM_ISO
fp_word tt;
#endif
a = A->dp;
COMBA_START;

View File

@@ -24,6 +24,9 @@
void fp_sqr_comba9(fp_int *A, fp_int *B)
{
fp_digit *a, b[18], c0, c1, c2, sc0, sc1, sc2;
#ifdef TFM_ISO
fp_word tt;
#endif
a = A->dp;
COMBA_START;

View File

@@ -3765,7 +3765,7 @@ int mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
#endif
#if defined(HAVE_ECC) || !defined(NO_PWDBASED) || defined(CYASSL_SNIFFER)
#if defined(HAVE_ECC) || !defined(NO_PWDBASED) || defined(CYASSL_SNIFFER) || defined(CYASSL_HAVE_WOLFSCEP)
/* single digit addition */
int mp_add_d (mp_int* a, mp_digit b, mp_int* c)

View File

@@ -36,6 +36,13 @@
#include <ctaocrypt/src/misc.c>
#endif
#ifdef FREESCALE_MMCAU
#include "cau_api.h"
#define XTRANSFORM(S,B) cau_md5_hash_n((B), 1, (unsigned char*)(S)->digest)
#else
#define XTRANSFORM(S,B) Transform((S))
#endif
#ifdef STM32F2_HASH
/*
@@ -174,6 +181,7 @@ void InitMd5(Md5* md5)
md5->hiLen = 0;
}
#ifndef FREESCALE_MMCAU
static void Transform(Md5* md5)
{
@@ -266,6 +274,8 @@ static void Transform(Md5* md5)
md5->digest[3] += d;
}
#endif /* FREESCALE_MMCAU */
static INLINE void AddLength(Md5* md5, word32 len)
{
@@ -289,10 +299,10 @@ void Md5Update(Md5* md5, const byte* data, word32 len)
len -= add;
if (md5->buffLen == MD5_BLOCK_SIZE) {
#ifdef BIG_ENDIAN_ORDER
#if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
ByteReverseBytes(local, local, MD5_BLOCK_SIZE);
#endif
Transform(md5);
XTRANSFORM(md5, local);
AddLength(md5, MD5_BLOCK_SIZE);
md5->buffLen = 0;
}
@@ -304,7 +314,7 @@ void Md5Final(Md5* md5, byte* hash)
{
byte* local = (byte*)md5->buffer;
AddLength(md5, md5->buffLen); /* before adding pads */
AddLength(md5, md5->buffLen); /* before adding pads */
local[md5->buffLen++] = 0x80; /* add 1 */
@@ -313,10 +323,10 @@ void Md5Final(Md5* md5, byte* hash)
XMEMSET(&local[md5->buffLen], 0, MD5_BLOCK_SIZE - md5->buffLen);
md5->buffLen += MD5_BLOCK_SIZE - md5->buffLen;
#ifdef BIG_ENDIAN_ORDER
#if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
ByteReverseBytes(local, local, MD5_BLOCK_SIZE);
#endif
Transform(md5);
XTRANSFORM(md5, local);
md5->buffLen = 0;
}
XMEMSET(&local[md5->buffLen], 0, MD5_PAD_SIZE - md5->buffLen);
@@ -327,14 +337,14 @@ void Md5Final(Md5* md5, byte* hash)
md5->loLen = md5->loLen << 3;
/* store lengths */
#ifdef BIG_ENDIAN_ORDER
#if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
ByteReverseBytes(local, local, MD5_BLOCK_SIZE);
#endif
/* ! length ordering dependent on digest endian type ! */
XMEMCPY(&local[MD5_PAD_SIZE], &md5->loLen, sizeof(word32));
XMEMCPY(&local[MD5_PAD_SIZE + sizeof(word32)], &md5->hiLen, sizeof(word32));
Transform(md5);
XTRANSFORM(md5, local);
#ifdef BIG_ENDIAN_ORDER
ByteReverseWords(md5->digest, md5->digest, MD5_DIGEST_SIZE);
#endif

1348
ctaocrypt/src/pkcs7.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -35,6 +35,13 @@
#include <ctaocrypt/src/misc.c>
#endif
#ifdef FREESCALE_MMCAU
#include "cau_api.h"
#define XTRANSFORM(S,B) cau_sha1_hash_n((B), 1, ((S))->digest)
#else
#define XTRANSFORM(S,B) Transform((S))
#endif
#ifdef STM32F2_HASH
/*
@@ -164,17 +171,23 @@
void InitSha(Sha* sha)
{
sha->digest[0] = 0x67452301L;
sha->digest[1] = 0xEFCDAB89L;
sha->digest[2] = 0x98BADCFEL;
sha->digest[3] = 0x10325476L;
sha->digest[4] = 0xC3D2E1F0L;
#ifdef FREESCALE_MMCAU
cau_sha1_initialize_output(sha->digest);
#else
sha->digest[0] = 0x67452301L;
sha->digest[1] = 0xEFCDAB89L;
sha->digest[2] = 0x98BADCFEL;
sha->digest[3] = 0x10325476L;
sha->digest[4] = 0xC3D2E1F0L;
#endif
sha->buffLen = 0;
sha->loLen = 0;
sha->hiLen = 0;
}
#ifndef FREESCALE_MMCAU
#define blk0(i) (W[i] = sha->buffer[i])
#define blk1(i) (W[i&15] = \
rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
@@ -272,6 +285,8 @@ static void Transform(Sha* sha)
sha->digest[4] += e;
}
#endif /* FREESCALE_MMCAU */
static INLINE void AddLength(Sha* sha, word32 len)
{
@@ -295,10 +310,10 @@ void ShaUpdate(Sha* sha, const byte* data, word32 len)
len -= add;
if (sha->buffLen == SHA_BLOCK_SIZE) {
#ifdef LITTLE_ENDIAN_ORDER
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
#endif
Transform(sha);
XTRANSFORM(sha, local);
AddLength(sha, SHA_BLOCK_SIZE);
sha->buffLen = 0;
}
@@ -310,7 +325,7 @@ void ShaFinal(Sha* sha, byte* hash)
{
byte* local = (byte*)sha->buffer;
AddLength(sha, sha->buffLen); /* before adding pads */
AddLength(sha, sha->buffLen); /* before adding pads */
local[sha->buffLen++] = 0x80; /* add 1 */
@@ -319,10 +334,10 @@ void ShaFinal(Sha* sha, byte* hash)
XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen);
sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen;
#ifdef LITTLE_ENDIAN_ORDER
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
#endif
Transform(sha);
XTRANSFORM(sha, local);
sha->buffLen = 0;
}
XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen);
@@ -333,14 +348,20 @@ void ShaFinal(Sha* sha, byte* hash)
sha->loLen = sha->loLen << 3;
/* store lengths */
#ifdef LITTLE_ENDIAN_ORDER
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
#endif
/* ! length ordering dependent on digest endian type ! */
XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32));
XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32));
Transform(sha);
#ifdef FREESCALE_MMCAU
/* Kinetis requires only these bytes reversed */
ByteReverseBytes(&local[SHA_PAD_SIZE], &local[SHA_PAD_SIZE],
2 * sizeof(word32));
#endif
XTRANSFORM(sha, local);
#ifdef LITTLE_ENDIAN_ORDER
ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
#endif

View File

@@ -37,6 +37,13 @@
#include <ctaocrypt/src/misc.c>
#endif
#ifdef FREESCALE_MMCAU
#include "cau_api.h"
#define XTRANSFORM(S,B) cau_sha256_hash_n((B), 1, ((S))->digest)
#else
#define XTRANSFORM(S,B) Transform((S))
#endif
#ifndef min
@@ -50,20 +57,26 @@
void InitSha256(Sha256* sha256)
{
sha256->digest[0] = 0x6A09E667L;
sha256->digest[1] = 0xBB67AE85L;
sha256->digest[2] = 0x3C6EF372L;
sha256->digest[3] = 0xA54FF53AL;
sha256->digest[4] = 0x510E527FL;
sha256->digest[5] = 0x9B05688CL;
sha256->digest[6] = 0x1F83D9ABL;
sha256->digest[7] = 0x5BE0CD19L;
#ifdef FREESCALE_MMCAU
cau_sha256_initialize_output(sha256->digest);
#else
sha256->digest[0] = 0x6A09E667L;
sha256->digest[1] = 0xBB67AE85L;
sha256->digest[2] = 0x3C6EF372L;
sha256->digest[3] = 0xA54FF53AL;
sha256->digest[4] = 0x510E527FL;
sha256->digest[5] = 0x9B05688CL;
sha256->digest[6] = 0x1F83D9ABL;
sha256->digest[7] = 0x5BE0CD19L;
#endif
sha256->buffLen = 0;
sha256->loLen = 0;
sha256->hiLen = 0;
}
#ifndef FREESCALE_MMCAU
static const word32 K[64] = {
0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL,
0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L,
@@ -128,6 +141,8 @@ static void Transform(Sha256* sha256)
}
}
#endif /* FREESCALE_MMCAU */
static INLINE void AddLength(Sha256* sha256, word32 len)
{
@@ -151,10 +166,10 @@ void Sha256Update(Sha256* sha256, const byte* data, word32 len)
len -= add;
if (sha256->buffLen == SHA256_BLOCK_SIZE) {
#ifdef LITTLE_ENDIAN_ORDER
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
ByteReverseBytes(local, local, SHA256_BLOCK_SIZE);
#endif
Transform(sha256);
XTRANSFORM(sha256, local);
AddLength(sha256, SHA256_BLOCK_SIZE);
sha256->buffLen = 0;
}
@@ -168,17 +183,17 @@ void Sha256Final(Sha256* sha256, byte* hash)
AddLength(sha256, sha256->buffLen); /* before adding pads */
local[sha256->buffLen++] = 0x80; /* add 1 */
local[sha256->buffLen++] = 0x80; /* add 1 */
/* pad with zeros */
if (sha256->buffLen > SHA256_PAD_SIZE) {
XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen);
sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen;
#ifdef LITTLE_ENDIAN_ORDER
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
ByteReverseBytes(local, local, SHA256_BLOCK_SIZE);
#endif
Transform(sha256);
XTRANSFORM(sha256, local);
sha256->buffLen = 0;
}
XMEMSET(&local[sha256->buffLen], 0, SHA256_PAD_SIZE - sha256->buffLen);
@@ -189,7 +204,7 @@ void Sha256Final(Sha256* sha256, byte* hash)
sha256->loLen = sha256->loLen << 3;
/* store lengths */
#ifdef LITTLE_ENDIAN_ORDER
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
ByteReverseBytes(local, local, SHA256_BLOCK_SIZE);
#endif
/* ! length ordering dependent on digest endian type ! */
@@ -197,7 +212,13 @@ void Sha256Final(Sha256* sha256, byte* hash)
XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen,
sizeof(word32));
Transform(sha256);
#ifdef FREESCALE_MMCAU
/* Kinetis requires only these bytes reversed */
ByteReverseBytes(&local[SHA256_PAD_SIZE], &local[SHA256_PAD_SIZE],
2 * sizeof(word32));
#endif
XTRANSFORM(sha256, local);
#ifdef LITTLE_ENDIAN_ORDER
ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE);
#endif

View File

@@ -146,13 +146,24 @@ static void Transform(Sha512* sha512)
/* Copy digest to working vars */
XMEMCPY(T, sha512->digest, sizeof(T));
/* 64 operations, partially loop unrolled */
#ifdef USE_SLOW_SHA2
/* over twice as small, but 50% slower */
/* 80 operations, not unrolled */
for (j = 0; j < 80; j += 16) {
int m;
for (m = 0; m < 16; m++) { /* braces needed here for macros {} */
R(m);
}
}
#else
/* 80 operations, partially loop unrolled */
for (j = 0; j < 80; j += 16) {
R( 0); R( 1); R( 2); R( 3);
R( 4); R( 5); R( 6); R( 7);
R( 8); R( 9); R(10); R(11);
R(12); R(13); R(14); R(15);
}
#endif /* USE_SLOW_SHA2 */
/* Add the working vars back into digest */
@@ -280,13 +291,24 @@ static void Transform384(Sha384* sha384)
/* Copy digest to working vars */
XMEMCPY(T, sha384->digest, sizeof(T));
/* 64 operations, partially loop unrolled */
#ifdef USE_SLOW_SHA2
/* over twice as small, but 50% slower */
/* 80 operations, not unrolled */
for (j = 0; j < 80; j += 16) {
int m;
for (m = 0; m < 16; m++) { /* braces needed for macros {} */
R2(m);
}
}
#else
/* 80 operations, partially loop unrolled */
for (j = 0; j < 80; j += 16) {
R2( 0); R2( 1); R2( 2); R2( 3);
R2( 4); R2( 5); R2( 6); R2( 7);
R2( 8); R2( 9); R2(10); R2(11);
R2(12); R2(13); R2(14); R2(15);
}
#endif /* USE_SLOW_SHA2 */
/* Add the working vars back into digest */