mirror of https://github.com/wolfSSL/wolfssl
Fixes for building ARMv8. Adds missing SHA224 and AES KeyWrap. Fixes for FE/GE warning with Aarch32. Fix possible build error with `ed25519_test` with `ret` not defined.
This commit is contained in:
parent
b6854d620f
commit
205da48416
|
@ -4645,6 +4645,177 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
|
|||
#endif /* HAVE_AES_DECRYPT */
|
||||
#endif /* WOLFSSL_AES_DIRECT */
|
||||
|
||||
#ifdef HAVE_AES_KEYWRAP
|
||||
|
||||
/* Initialize key wrap counter with value */
|
||||
static INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
|
||||
{
|
||||
int i;
|
||||
word32 bytes;
|
||||
|
||||
bytes = sizeof(word32);
|
||||
for (i = 0; i < (int)sizeof(word32); i++) {
|
||||
inOutCtr[i+sizeof(word32)] = (value >> ((bytes - 1) * 8)) & 0xFF;
|
||||
bytes--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Increment key wrap counter */
|
||||
static INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* in network byte order so start at end and work back */
|
||||
for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
|
||||
if (++inOutCtr[i]) /* we're done unless we overflow */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Decrement key wrap counter */
|
||||
static INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
|
||||
if (--inOutCtr[i] != 0xFF) /* we're done unless we underflow */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
|
||||
int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
|
||||
byte* out, word32 outSz, const byte* iv)
|
||||
{
|
||||
Aes aes;
|
||||
byte* r;
|
||||
word32 i;
|
||||
int ret, j;
|
||||
|
||||
byte t[KEYWRAP_BLOCK_SIZE];
|
||||
byte tmp[AES_BLOCK_SIZE];
|
||||
|
||||
/* n must be at least 2, output size is n + 8 bytes */
|
||||
if (key == NULL || in == NULL || inSz < 2 ||
|
||||
out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* input must be multiple of 64-bits */
|
||||
if (inSz % KEYWRAP_BLOCK_SIZE != 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* user IV is optional */
|
||||
if (iv == NULL) {
|
||||
XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);
|
||||
} else {
|
||||
XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
r = out + 8;
|
||||
XMEMCPY(r, in, inSz);
|
||||
XMEMSET(t, 0, sizeof(t));
|
||||
|
||||
ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_ENCRYPTION);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
for (j = 0; j <= 5; j++) {
|
||||
for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
|
||||
|
||||
/* load R[i] */
|
||||
XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
|
||||
|
||||
wc_AesEncryptDirect(&aes, tmp, tmp);
|
||||
|
||||
/* calculate new A */
|
||||
IncrementKeyWrapCounter(t);
|
||||
xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
|
||||
|
||||
/* save R[i] */
|
||||
XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
|
||||
r += KEYWRAP_BLOCK_SIZE;
|
||||
}
|
||||
r = out + KEYWRAP_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/* C[0] = A */
|
||||
XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
|
||||
|
||||
return inSz + KEYWRAP_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
|
||||
byte* out, word32 outSz, const byte* iv)
|
||||
{
|
||||
Aes aes;
|
||||
byte* r;
|
||||
word32 i, n;
|
||||
int ret, j;
|
||||
|
||||
byte t[KEYWRAP_BLOCK_SIZE];
|
||||
byte tmp[AES_BLOCK_SIZE];
|
||||
|
||||
const byte* expIv;
|
||||
const byte defaultIV[] = {
|
||||
0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
|
||||
};
|
||||
|
||||
(void)iv;
|
||||
|
||||
if (key == NULL || in == NULL || inSz < 3 ||
|
||||
out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* input must be multiple of 64-bits */
|
||||
if (inSz % KEYWRAP_BLOCK_SIZE != 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* user IV optional */
|
||||
if (iv != NULL) {
|
||||
expIv = iv;
|
||||
} else {
|
||||
expIv = defaultIV;
|
||||
}
|
||||
|
||||
/* A = C[0], R[i] = C[i] */
|
||||
XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
|
||||
XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
|
||||
XMEMSET(t, 0, sizeof(t));
|
||||
|
||||
ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_DECRYPTION);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* initialize counter to 6n */
|
||||
n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
|
||||
InitKeyWrapCounter(t, 6 * n);
|
||||
|
||||
for (j = 5; j >= 0; j--) {
|
||||
for (i = n; i >= 1; i--) {
|
||||
|
||||
/* calculate A */
|
||||
xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
|
||||
DecrementKeyWrapCounter(t);
|
||||
|
||||
/* load R[i], starting at end of R */
|
||||
r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
|
||||
XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
|
||||
wc_AesDecryptDirect(&aes, tmp, tmp);
|
||||
|
||||
/* save R[i] */
|
||||
XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/* verify IV */
|
||||
if (XMEMCMP(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)
|
||||
return BAD_KEYWRAP_IV_E;
|
||||
|
||||
return inSz - KEYWRAP_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
#endif /* HAVE_AES_KEYWRAP */
|
||||
|
||||
int wc_AesGetKeySize(Aes* aes, word32* keySize)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
|
@ -26,7 +26,9 @@
|
|||
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
|
||||
#if !defined(NO_SHA256) && defined(WOLFSSL_ARMASM)
|
||||
#ifdef WOLFSSL_ARMASM
|
||||
#if !defined(NO_SHA256) || defined(WOLFSSL_SHA224)
|
||||
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
@ -56,7 +58,7 @@ static const ALIGN32 word32 K[64] = {
|
|||
};
|
||||
|
||||
|
||||
int wc_InitSha256_ex(Sha256* sha256, void* heap, int devId)
|
||||
static int InitSha256(Sha256* sha256)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -77,41 +79,25 @@ int wc_InitSha256_ex(Sha256* sha256, void* heap, int devId)
|
|||
sha256->loLen = 0;
|
||||
sha256->hiLen = 0;
|
||||
|
||||
(void)heap;
|
||||
(void)devId;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wc_InitSha256(Sha256* sha256)
|
||||
{
|
||||
return wc_InitSha256_ex(sha256, NULL, INVALID_DEVID);
|
||||
}
|
||||
|
||||
void wc_Sha256Free(Sha256* sha256)
|
||||
{
|
||||
(void)sha256;
|
||||
}
|
||||
|
||||
static INLINE void AddLength(Sha256* sha256, word32 len)
|
||||
{
|
||||
word32 tmp = sha256->loLen;
|
||||
if ( (sha256->loLen += len) < tmp)
|
||||
if ((sha256->loLen += len) < tmp)
|
||||
sha256->hiLen++; /* carry low to high */
|
||||
}
|
||||
|
||||
|
||||
#ifdef __aarch64__
|
||||
|
||||
/* ARMv8 hardware accleration */
|
||||
int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len)
|
||||
static INLINE int Sha256Update(Sha256* sha256, const byte* data, word32 len)
|
||||
{
|
||||
word32 add;
|
||||
word32 numBlocks;
|
||||
|
||||
if (sha256 == NULL || (data == NULL && len != 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* only perform actions if a buffer is passed in */
|
||||
if (len > 0) {
|
||||
/* fill leftover buffer with data */
|
||||
|
@ -320,14 +306,10 @@ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len)
|
|||
}
|
||||
|
||||
|
||||
int wc_Sha256Final(Sha256* sha256, byte* hash)
|
||||
static INLINE int Sha256Final(Sha256* sha256, byte* hash)
|
||||
{
|
||||
byte* local;
|
||||
|
||||
if (sha256 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
local = (byte*)sha256->buffer;
|
||||
AddLength(sha256, sha256->buffLen); /* before adding pads */
|
||||
|
||||
|
@ -667,20 +649,17 @@ int wc_Sha256Final(Sha256* sha256, byte* hash)
|
|||
"v22", "v23", "v24", "v25"
|
||||
);
|
||||
|
||||
return wc_InitSha256(sha256); /* reset state */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* not using 64 bit */
|
||||
|
||||
/* ARMv8 hardware accleration Aarch32 */
|
||||
int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len)
|
||||
static INLINE int Sha256Update(Sha256* sha256, const byte* data, word32 len)
|
||||
{
|
||||
word32 add;
|
||||
word32 numBlocks;
|
||||
|
||||
if (sha256 == NULL || (data == NULL && len != 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* only perform actions if a buffer is passed in */
|
||||
if (len > 0) {
|
||||
/* fill leftover buffer with data */
|
||||
|
@ -903,7 +882,7 @@ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len)
|
|||
}
|
||||
|
||||
|
||||
int wc_Sha256Final(Sha256* sha256, byte* hash)
|
||||
static INLINE int Sha256Final(Sha256* sha256, byte* hash)
|
||||
{
|
||||
byte* local;
|
||||
|
||||
|
@ -1298,12 +1277,66 @@ int wc_Sha256Final(Sha256* sha256, byte* hash)
|
|||
"q15"
|
||||
);
|
||||
|
||||
return wc_InitSha256(sha256); /* reset state */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __aarch64__ */
|
||||
|
||||
|
||||
#ifndef NO_SHA256
|
||||
|
||||
int wc_InitSha256_ex(Sha256* sha256, void* heap, int devId)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (sha256 == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
sha256->heap = heap;
|
||||
|
||||
ret = InitSha256(sha256);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
(void)devId;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wc_InitSha256(Sha256* sha256)
|
||||
{
|
||||
return wc_InitSha256_ex(sha256, NULL, INVALID_DEVID);
|
||||
}
|
||||
|
||||
void wc_Sha256Free(Sha256* sha256)
|
||||
{
|
||||
(void)sha256;
|
||||
}
|
||||
|
||||
int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len)
|
||||
{
|
||||
if (sha256 == NULL || (data == NULL && len != 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
return Sha256Update(sha256, data, len);
|
||||
}
|
||||
|
||||
int wc_Sha256Final(Sha256* sha256, byte* hash)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sha256 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
ret = Sha256Final(sha256, hash);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return InitSha256(sha256); /* reset state */
|
||||
}
|
||||
|
||||
int wc_Sha256GetHash(Sha256* sha256, byte* hash)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1331,4 +1364,122 @@ int wc_Sha256Copy(Sha256* src, Sha256* dst)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#endif /* NO_SHA256 and WOLFSSL_ARMASM */
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
|
||||
#ifdef WOLFSSL_SHA224
|
||||
static int InitSha224(Sha224* sha224)
|
||||
{
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (sha224 == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
sha224->digest[0] = 0xc1059ed8;
|
||||
sha224->digest[1] = 0x367cd507;
|
||||
sha224->digest[2] = 0x3070dd17;
|
||||
sha224->digest[3] = 0xf70e5939;
|
||||
sha224->digest[4] = 0xffc00b31;
|
||||
sha224->digest[5] = 0x68581511;
|
||||
sha224->digest[6] = 0x64f98fa7;
|
||||
sha224->digest[7] = 0xbefa4fa4;
|
||||
|
||||
sha224->buffLen = 0;
|
||||
sha224->loLen = 0;
|
||||
sha224->hiLen = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wc_InitSha224_ex(Sha224* sha224, void* heap, int devId)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (sha224 == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
sha224->heap = heap;
|
||||
|
||||
ret = InitSha224(sha224);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
(void)devId;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wc_InitSha224(Sha224* sha224)
|
||||
{
|
||||
return wc_InitSha224_ex(sha224, NULL, INVALID_DEVID);
|
||||
}
|
||||
|
||||
int wc_Sha224Update(Sha224* sha224, const byte* data, word32 len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sha224 == NULL || (data == NULL && len > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
ret = Sha256Update((Sha256 *)sha224, data, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wc_Sha224Final(Sha224* sha224, byte* hash)
|
||||
{
|
||||
int ret;
|
||||
word32 hashTmp[SHA256_DIGEST_SIZE/sizeof(word32)];
|
||||
|
||||
if (sha224 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
ret = Sha256Final((Sha256*)sha224, (byte*)hashTmp);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
XMEMCPY(hash, hashTmp, SHA224_DIGEST_SIZE);
|
||||
|
||||
return InitSha224(sha224); /* reset state */
|
||||
}
|
||||
|
||||
void wc_Sha224Free(Sha224* sha224)
|
||||
{
|
||||
if (sha224 == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
int wc_Sha224GetHash(Sha224* sha224, byte* hash)
|
||||
{
|
||||
int ret;
|
||||
Sha224 tmpSha224;
|
||||
|
||||
if (sha224 == NULL || hash == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
ret = wc_Sha224Copy(sha224, &tmpSha224);
|
||||
if (ret == 0) {
|
||||
ret = wc_Sha224Final(&tmpSha224, hash);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int wc_Sha224Copy(Sha224* src, Sha224* dst)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (src == NULL || dst == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
XMEMCPY(dst, src, sizeof(Sha224));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_SHA224 */
|
||||
|
||||
#endif /* !NO_SHA256 || WOLFSSL_SHA224 */
|
||||
#endif /* WOLFSSL_ARMASM */
|
||||
|
|
|
@ -11693,6 +11693,7 @@ done:
|
|||
|
||||
int ed25519_test(void)
|
||||
{
|
||||
int ret;
|
||||
WC_RNG rng;
|
||||
#if defined(HAVE_ED25519_SIGN) && defined(HAVE_ED25519_KEY_EXPORT) &&\
|
||||
defined(HAVE_ED25519_KEY_IMPORT)
|
||||
|
@ -11701,7 +11702,7 @@ int ed25519_test(void)
|
|||
byte exportSKey[ED25519_KEY_SIZE];
|
||||
word32 exportPSz;
|
||||
word32 exportSSz;
|
||||
int i, ret;
|
||||
int i;
|
||||
word32 outlen;
|
||||
#ifdef HAVE_ED25519_VERIFY
|
||||
int verify;
|
||||
|
|
|
@ -90,7 +90,7 @@ WOLFSSL_LOCAL void fe_mul121666(fe,fe);
|
|||
WOLFSSL_LOCAL void fe_cmov(fe,const fe, int);
|
||||
WOLFSSL_LOCAL void fe_pow22523(fe,const fe);
|
||||
|
||||
#if defined(HAVE___UINT128_T)
|
||||
#if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL)
|
||||
/* 64 type needed for SHA512 */
|
||||
WOLFSSL_LOCAL uint64_t load_3(const unsigned char *in);
|
||||
WOLFSSL_LOCAL uint64_t load_4(const unsigned char *in);
|
||||
|
|
Loading…
Reference in New Issue