forked from wolfSSL/wolfssl
CyaSSL master, 2.8.6
This commit is contained in:
@@ -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--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
1348
ctaocrypt/src/pkcs7.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user