Merge branch 'master' of https://github.com/kaleb-himes/cyassl
This commit is contained in:
commit
11a563aa91
3749
ctaocrypt/src/aes.c
3749
ctaocrypt/src/aes.c
File diff suppressed because it is too large
Load Diff
1577
ctaocrypt/src/des3.c
1577
ctaocrypt/src/des3.c
File diff suppressed because it is too large
Load Diff
@ -1,825 +1 @@
|
||||
/* hmac.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#ifndef NO_HMAC
|
||||
|
||||
#ifdef CYASSL_PIC32MZ_HASH
|
||||
|
||||
#define InitMd5 InitMd5_sw
|
||||
#define Md5Update Md5Update_sw
|
||||
#define Md5Final Md5Final_sw
|
||||
|
||||
#define InitSha InitSha_sw
|
||||
#define ShaUpdate ShaUpdate_sw
|
||||
#define ShaFinal ShaFinal_sw
|
||||
|
||||
#define InitSha256 InitSha256_sw
|
||||
#define Sha256Update Sha256Update_sw
|
||||
#define Sha256Final Sha256Final_sw
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FIPS
|
||||
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
|
||||
#define FIPS_NO_WRAPPERS
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/hmac.h>
|
||||
#include <cyassl/ctaocrypt/error-crypt.h>
|
||||
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
static void HmacCaviumFinal(Hmac* hmac, byte* hash);
|
||||
static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length);
|
||||
static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key,
|
||||
word32 length);
|
||||
#endif
|
||||
|
||||
static int InitHmac(Hmac* hmac, int type)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
hmac->innerHashKeyed = 0;
|
||||
hmac->macType = (byte)type;
|
||||
|
||||
if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384
|
||||
|| type == SHA512 || type == BLAKE2B_ID))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
switch (type) {
|
||||
#ifndef NO_MD5
|
||||
case MD5:
|
||||
InitMd5(&hmac->hash.md5);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA
|
||||
case SHA:
|
||||
ret = InitSha(&hmac->hash.sha);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case SHA256:
|
||||
ret = InitSha256(&hmac->hash.sha256);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SHA384
|
||||
case SHA384:
|
||||
ret = InitSha384(&hmac->hash.sha384);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SHA512
|
||||
case SHA512:
|
||||
ret = InitSha512(&hmac->hash.sha512);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BLAKE2
|
||||
case BLAKE2B_ID:
|
||||
ret = InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
|
||||
{
|
||||
byte* ip = (byte*) hmac->ipad;
|
||||
byte* op = (byte*) hmac->opad;
|
||||
word32 i, hmac_block_size = 0;
|
||||
int ret;
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC)
|
||||
return HmacCaviumSetKey(hmac, type, key, length);
|
||||
#endif
|
||||
|
||||
ret = InitHmac(hmac, type);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
#ifdef HAVE_FIPS
|
||||
if (length < HMAC_FIPS_MIN_KEY)
|
||||
return HMAC_MIN_KEYLEN_E;
|
||||
#endif
|
||||
|
||||
switch (hmac->macType) {
|
||||
#ifndef NO_MD5
|
||||
case MD5:
|
||||
{
|
||||
hmac_block_size = MD5_BLOCK_SIZE;
|
||||
if (length <= MD5_BLOCK_SIZE) {
|
||||
XMEMCPY(ip, key, length);
|
||||
}
|
||||
else {
|
||||
Md5Update(&hmac->hash.md5, key, length);
|
||||
Md5Final(&hmac->hash.md5, ip);
|
||||
length = MD5_DIGEST_SIZE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA
|
||||
case SHA:
|
||||
{
|
||||
hmac_block_size = SHA_BLOCK_SIZE;
|
||||
if (length <= SHA_BLOCK_SIZE) {
|
||||
XMEMCPY(ip, key, length);
|
||||
}
|
||||
else {
|
||||
ShaUpdate(&hmac->hash.sha, key, length);
|
||||
ShaFinal(&hmac->hash.sha, ip);
|
||||
length = SHA_DIGEST_SIZE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case SHA256:
|
||||
{
|
||||
hmac_block_size = SHA256_BLOCK_SIZE;
|
||||
if (length <= SHA256_BLOCK_SIZE) {
|
||||
XMEMCPY(ip, key, length);
|
||||
}
|
||||
else {
|
||||
ret = Sha256Update(&hmac->hash.sha256, key, length);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Sha256Final(&hmac->hash.sha256, ip);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
length = SHA256_DIGEST_SIZE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SHA384
|
||||
case SHA384:
|
||||
{
|
||||
hmac_block_size = SHA384_BLOCK_SIZE;
|
||||
if (length <= SHA384_BLOCK_SIZE) {
|
||||
XMEMCPY(ip, key, length);
|
||||
}
|
||||
else {
|
||||
ret = Sha384Update(&hmac->hash.sha384, key, length);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Sha384Final(&hmac->hash.sha384, ip);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
length = SHA384_DIGEST_SIZE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SHA512
|
||||
case SHA512:
|
||||
{
|
||||
hmac_block_size = SHA512_BLOCK_SIZE;
|
||||
if (length <= SHA512_BLOCK_SIZE) {
|
||||
XMEMCPY(ip, key, length);
|
||||
}
|
||||
else {
|
||||
ret = Sha512Update(&hmac->hash.sha512, key, length);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Sha512Final(&hmac->hash.sha512, ip);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
length = SHA512_DIGEST_SIZE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BLAKE2
|
||||
case BLAKE2B_ID:
|
||||
{
|
||||
hmac_block_size = BLAKE2B_BLOCKBYTES;
|
||||
if (length <= BLAKE2B_BLOCKBYTES) {
|
||||
XMEMCPY(ip, key, length);
|
||||
}
|
||||
else {
|
||||
ret = Blake2bUpdate(&hmac->hash.blake2b, key, length);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
length = BLAKE2B_256;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
if (length < hmac_block_size)
|
||||
XMEMSET(ip + length, 0, hmac_block_size - length);
|
||||
|
||||
for(i = 0; i < hmac_block_size; i++) {
|
||||
op[i] = ip[i] ^ OPAD;
|
||||
ip[i] ^= IPAD;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int HmacKeyInnerHash(Hmac* hmac)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (hmac->macType) {
|
||||
#ifndef NO_MD5
|
||||
case MD5:
|
||||
Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA
|
||||
case SHA:
|
||||
ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, SHA_BLOCK_SIZE);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case SHA256:
|
||||
ret = Sha256Update(&hmac->hash.sha256,
|
||||
(byte*) hmac->ipad, SHA256_BLOCK_SIZE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SHA384
|
||||
case SHA384:
|
||||
ret = Sha384Update(&hmac->hash.sha384,
|
||||
(byte*) hmac->ipad, SHA384_BLOCK_SIZE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SHA512
|
||||
case SHA512:
|
||||
ret = Sha512Update(&hmac->hash.sha512,
|
||||
(byte*) hmac->ipad, SHA512_BLOCK_SIZE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BLAKE2
|
||||
case BLAKE2B_ID:
|
||||
ret = Blake2bUpdate(&hmac->hash.blake2b,
|
||||
(byte*) hmac->ipad,BLAKE2B_BLOCKBYTES);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
hmac->innerHashKeyed = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int HmacUpdate(Hmac* hmac, const byte* msg, word32 length)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC)
|
||||
return HmacCaviumUpdate(hmac, msg, length);
|
||||
#endif
|
||||
|
||||
if (!hmac->innerHashKeyed) {
|
||||
ret = HmacKeyInnerHash(hmac);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (hmac->macType) {
|
||||
#ifndef NO_MD5
|
||||
case MD5:
|
||||
Md5Update(&hmac->hash.md5, msg, length);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA
|
||||
case SHA:
|
||||
ShaUpdate(&hmac->hash.sha, msg, length);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case SHA256:
|
||||
ret = Sha256Update(&hmac->hash.sha256, msg, length);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SHA384
|
||||
case SHA384:
|
||||
ret = Sha384Update(&hmac->hash.sha384, msg, length);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SHA512
|
||||
case SHA512:
|
||||
ret = Sha512Update(&hmac->hash.sha512, msg, length);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BLAKE2
|
||||
case BLAKE2B_ID:
|
||||
ret = Blake2bUpdate(&hmac->hash.blake2b, msg, length);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int HmacFinal(Hmac* hmac, byte* hash)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC)
|
||||
return HmacCaviumFinal(hmac, hash);
|
||||
#endif
|
||||
|
||||
if (!hmac->innerHashKeyed) {
|
||||
ret = HmacKeyInnerHash(hmac);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (hmac->macType) {
|
||||
#ifndef NO_MD5
|
||||
case MD5:
|
||||
{
|
||||
Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash);
|
||||
|
||||
Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE);
|
||||
Md5Update(&hmac->hash.md5,
|
||||
(byte*) hmac->innerHash, MD5_DIGEST_SIZE);
|
||||
|
||||
Md5Final(&hmac->hash.md5, hash);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA
|
||||
case SHA:
|
||||
{
|
||||
ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash);
|
||||
|
||||
ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, SHA_BLOCK_SIZE);
|
||||
ShaUpdate(&hmac->hash.sha,
|
||||
(byte*) hmac->innerHash, SHA_DIGEST_SIZE);
|
||||
|
||||
ShaFinal(&hmac->hash.sha, hash);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case SHA256:
|
||||
{
|
||||
ret = Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Sha256Update(&hmac->hash.sha256,
|
||||
(byte*) hmac->opad, SHA256_BLOCK_SIZE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Sha256Update(&hmac->hash.sha256,
|
||||
(byte*) hmac->innerHash, SHA256_DIGEST_SIZE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Sha256Final(&hmac->hash.sha256, hash);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SHA384
|
||||
case SHA384:
|
||||
{
|
||||
ret = Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Sha384Update(&hmac->hash.sha384,
|
||||
(byte*) hmac->opad, SHA384_BLOCK_SIZE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Sha384Update(&hmac->hash.sha384,
|
||||
(byte*) hmac->innerHash, SHA384_DIGEST_SIZE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Sha384Final(&hmac->hash.sha384, hash);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SHA512
|
||||
case SHA512:
|
||||
{
|
||||
ret = Sha512Final(&hmac->hash.sha512, (byte*) hmac->innerHash);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Sha512Update(&hmac->hash.sha512,
|
||||
(byte*) hmac->opad, SHA512_BLOCK_SIZE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Sha512Update(&hmac->hash.sha512,
|
||||
(byte*) hmac->innerHash, SHA512_DIGEST_SIZE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Sha512Final(&hmac->hash.sha512, hash);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BLAKE2
|
||||
case BLAKE2B_ID:
|
||||
{
|
||||
ret = Blake2bFinal(&hmac->hash.blake2b, (byte*) hmac->innerHash,
|
||||
BLAKE2B_256);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Blake2bUpdate(&hmac->hash.blake2b,
|
||||
(byte*) hmac->opad, BLAKE2B_BLOCKBYTES);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Blake2bUpdate(&hmac->hash.blake2b,
|
||||
(byte*) hmac->innerHash, BLAKE2B_256);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
hmac->innerHashKeyed = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
|
||||
/* Initiliaze Hmac for use with Nitrox device */
|
||||
int HmacInitCavium(Hmac* hmac, int devId)
|
||||
{
|
||||
if (hmac == NULL)
|
||||
return -1;
|
||||
|
||||
if (CspAllocContext(CONTEXT_SSL, &hmac->contextHandle, devId) != 0)
|
||||
return -1;
|
||||
|
||||
hmac->keyLen = 0;
|
||||
hmac->dataLen = 0;
|
||||
hmac->type = 0;
|
||||
hmac->devId = devId;
|
||||
hmac->magic = CYASSL_HMAC_CAVIUM_MAGIC;
|
||||
hmac->data = NULL; /* buffered input data */
|
||||
|
||||
hmac->innerHashKeyed = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Free Hmac from use with Nitrox device */
|
||||
void HmacFreeCavium(Hmac* hmac)
|
||||
{
|
||||
if (hmac == NULL)
|
||||
return;
|
||||
|
||||
CspFreeContext(CONTEXT_SSL, hmac->contextHandle, hmac->devId);
|
||||
hmac->magic = 0;
|
||||
XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP);
|
||||
hmac->data = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void HmacCaviumFinal(Hmac* hmac, byte* hash)
|
||||
{
|
||||
word32 requestId;
|
||||
|
||||
if (CspHmac(CAVIUM_BLOCKING, hmac->type, NULL, hmac->keyLen,
|
||||
(byte*)hmac->ipad, hmac->dataLen, hmac->data, hash, &requestId,
|
||||
hmac->devId) != 0) {
|
||||
CYASSL_MSG("Cavium Hmac failed");
|
||||
}
|
||||
hmac->innerHashKeyed = 0; /* tell update to start over if used again */
|
||||
}
|
||||
|
||||
|
||||
static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length)
|
||||
{
|
||||
word16 add = (word16)length;
|
||||
word32 total;
|
||||
byte* tmp;
|
||||
|
||||
if (length > CYASSL_MAX_16BIT) {
|
||||
CYASSL_MSG("Too big msg for cavium hmac");
|
||||
return;
|
||||
}
|
||||
|
||||
if (hmac->innerHashKeyed == 0) { /* starting new */
|
||||
hmac->dataLen = 0;
|
||||
hmac->innerHashKeyed = 1;
|
||||
}
|
||||
|
||||
total = add + hmac->dataLen;
|
||||
if (total > CYASSL_MAX_16BIT) {
|
||||
CYASSL_MSG("Too big msg for cavium hmac");
|
||||
return;
|
||||
}
|
||||
|
||||
tmp = XMALLOC(hmac->dataLen + add, NULL,DYNAMIC_TYPE_CAVIUM_TMP);
|
||||
if (tmp == NULL) {
|
||||
CYASSL_MSG("Out of memory for cavium update");
|
||||
return;
|
||||
}
|
||||
if (hmac->dataLen)
|
||||
XMEMCPY(tmp, hmac->data, hmac->dataLen);
|
||||
XMEMCPY(tmp + hmac->dataLen, msg, add);
|
||||
|
||||
hmac->dataLen += add;
|
||||
XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP);
|
||||
hmac->data = tmp;
|
||||
}
|
||||
|
||||
|
||||
static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key,
|
||||
word32 length)
|
||||
{
|
||||
hmac->macType = (byte)type;
|
||||
if (type == MD5)
|
||||
hmac->type = MD5_TYPE;
|
||||
else if (type == SHA)
|
||||
hmac->type = SHA1_TYPE;
|
||||
else if (type == SHA256)
|
||||
hmac->type = SHA256_TYPE;
|
||||
else {
|
||||
CYASSL_MSG("unsupported cavium hmac type");
|
||||
}
|
||||
|
||||
hmac->innerHashKeyed = 0; /* should we key Startup flag */
|
||||
|
||||
hmac->keyLen = (word16)length;
|
||||
/* store key in ipad */
|
||||
XMEMCPY(hmac->ipad, key, length);
|
||||
}
|
||||
|
||||
#endif /* HAVE_CAVIUM */
|
||||
|
||||
int CyaSSL_GetHmacMaxSize(void)
|
||||
{
|
||||
return MAX_DIGEST_SIZE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_HKDF
|
||||
|
||||
#ifndef min
|
||||
|
||||
static INLINE word32 min(word32 a, word32 b)
|
||||
{
|
||||
return a > b ? b : a;
|
||||
}
|
||||
|
||||
#endif /* min */
|
||||
|
||||
|
||||
static INLINE int GetHashSizeByType(int type)
|
||||
{
|
||||
if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384
|
||||
|| type == SHA512 || type == BLAKE2B_ID))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
switch (type) {
|
||||
#ifndef NO_MD5
|
||||
case MD5:
|
||||
return MD5_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA
|
||||
case SHA:
|
||||
return SHA_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case SHA256:
|
||||
return SHA256_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SHA384
|
||||
case SHA384:
|
||||
return SHA384_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SHA512
|
||||
case SHA512:
|
||||
return SHA512_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BLAKE2
|
||||
case BLAKE2B_ID:
|
||||
return BLAKE2B_OUTBYTES;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* HMAC-KDF with hash type, optional salt and info, return 0 on success */
|
||||
int HKDF(int type, const byte* inKey, word32 inKeySz,
|
||||
const byte* salt, word32 saltSz,
|
||||
const byte* info, word32 infoSz,
|
||||
byte* out, word32 outSz)
|
||||
{
|
||||
Hmac myHmac;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
byte* tmp;
|
||||
byte* prk;
|
||||
#else
|
||||
byte tmp[MAX_DIGEST_SIZE]; /* localSalt helper and T */
|
||||
byte prk[MAX_DIGEST_SIZE];
|
||||
#endif
|
||||
const byte* localSalt; /* either points to user input or tmp */
|
||||
int hashSz = GetHashSizeByType(type);
|
||||
word32 outIdx = 0;
|
||||
byte n = 0x1;
|
||||
int ret;
|
||||
|
||||
if (hashSz < 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
tmp = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (tmp == NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
prk = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (prk == NULL) {
|
||||
XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
localSalt = salt;
|
||||
if (localSalt == NULL) {
|
||||
XMEMSET(tmp, 0, hashSz);
|
||||
localSalt = tmp;
|
||||
saltSz = hashSz;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = HmacSetKey(&myHmac, type, localSalt, saltSz);
|
||||
if (ret != 0)
|
||||
break;
|
||||
ret = HmacUpdate(&myHmac, inKey, inKeySz);
|
||||
if (ret != 0)
|
||||
break;
|
||||
ret = HmacFinal(&myHmac, prk);
|
||||
} while (0);
|
||||
|
||||
if (ret == 0) {
|
||||
while (outIdx < outSz) {
|
||||
int tmpSz = (n == 1) ? 0 : hashSz;
|
||||
word32 left = outSz - outIdx;
|
||||
|
||||
ret = HmacSetKey(&myHmac, type, prk, hashSz);
|
||||
if (ret != 0)
|
||||
break;
|
||||
ret = HmacUpdate(&myHmac, tmp, tmpSz);
|
||||
if (ret != 0)
|
||||
break;
|
||||
ret = HmacUpdate(&myHmac, info, infoSz);
|
||||
if (ret != 0)
|
||||
break;
|
||||
ret = HmacUpdate(&myHmac, &n, 1);
|
||||
if (ret != 0)
|
||||
break;
|
||||
ret = HmacFinal(&myHmac, tmp);
|
||||
if (ret != 0)
|
||||
break;
|
||||
|
||||
left = min(left, (word32)hashSz);
|
||||
XMEMCPY(out+outIdx, tmp, left);
|
||||
|
||||
outIdx += hashSz;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(prk, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* HAVE_HKDF */
|
||||
|
||||
#endif /* NO_HMAC */
|
||||
|
||||
/* dummy file for autoconf */
|
||||
|
@ -1,996 +1 @@
|
||||
/* random.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
/* on HPUX 11 you may need to install /dev/random see
|
||||
http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_FIPS
|
||||
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
|
||||
#define FIPS_NO_WRAPPERS
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/random.h>
|
||||
#include <cyassl/ctaocrypt/error-crypt.h>
|
||||
|
||||
#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
|
||||
|
||||
#include <cyassl/ctaocrypt/sha256.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <cyassl/ctaocrypt/misc.h>
|
||||
#else
|
||||
#include <ctaocrypt/src/misc.c>
|
||||
#endif
|
||||
#endif /* HAVE_HASHDRBG || NO_RC4 */
|
||||
|
||||
#if defined(USE_WINDOWS_API)
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#else
|
||||
#if !defined(NO_DEV_RANDOM) && !defined(CYASSL_MDK_ARM) \
|
||||
&& !defined(CYASSL_IAR_ARM)
|
||||
#include <fcntl.h>
|
||||
#ifndef EBSNET
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#else
|
||||
/* include headers that may be needed to get good seed */
|
||||
#endif
|
||||
#endif /* USE_WINDOWS_API */
|
||||
|
||||
|
||||
#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
|
||||
|
||||
/* Start NIST DRBG code */
|
||||
|
||||
#define OUTPUT_BLOCK_LEN (SHA256_DIGEST_SIZE)
|
||||
#define MAX_REQUEST_LEN (0x10000)
|
||||
#define RESEED_INTERVAL (1000000)
|
||||
#define SECURITY_STRENGTH (256)
|
||||
#define ENTROPY_SZ (SECURITY_STRENGTH/8)
|
||||
#define NONCE_SZ (ENTROPY_SZ/2)
|
||||
#define ENTROPY_NONCE_SZ (ENTROPY_SZ+NONCE_SZ)
|
||||
|
||||
/* Internal return codes */
|
||||
#define DRBG_SUCCESS 0
|
||||
#define DRBG_ERROR 1
|
||||
#define DRBG_FAILURE 2
|
||||
#define DRBG_NEED_RESEED 3
|
||||
#define DRBG_CONT_FAILURE 4
|
||||
|
||||
/* RNG health states */
|
||||
#define DRBG_NOT_INIT 0
|
||||
#define DRBG_OK 1
|
||||
#define DRBG_FAILED 2
|
||||
#define DRBG_CONT_FAILED 3
|
||||
|
||||
|
||||
enum {
|
||||
drbgInitC = 0,
|
||||
drbgReseed = 1,
|
||||
drbgGenerateW = 2,
|
||||
drbgGenerateH = 3,
|
||||
drbgInitV
|
||||
};
|
||||
|
||||
|
||||
typedef struct DRBG {
|
||||
Sha256 sha;
|
||||
byte digest[SHA256_DIGEST_SIZE];
|
||||
byte V[DRBG_SEED_LEN];
|
||||
byte C[DRBG_SEED_LEN];
|
||||
word32 reseedCtr;
|
||||
word32 lastBlock;
|
||||
byte matchCount;
|
||||
} DRBG;
|
||||
|
||||
|
||||
/* Hash Derivation Function */
|
||||
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
|
||||
static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type,
|
||||
const byte* inA, word32 inASz,
|
||||
const byte* inB, word32 inBSz)
|
||||
{
|
||||
byte ctr;
|
||||
int i;
|
||||
int len;
|
||||
word32 bits = (outSz * 8); /* reverse byte order */
|
||||
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
bits = ByteReverseWord32(bits);
|
||||
#endif
|
||||
len = (outSz / OUTPUT_BLOCK_LEN)
|
||||
+ ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
|
||||
|
||||
for (i = 0, ctr = 1; i < len; i++, ctr++)
|
||||
{
|
||||
if (InitSha256(&drbg->sha) != 0)
|
||||
return DRBG_FAILURE;
|
||||
|
||||
if (Sha256Update(&drbg->sha, &ctr, sizeof(ctr)) != 0)
|
||||
return DRBG_FAILURE;
|
||||
|
||||
if (Sha256Update(&drbg->sha, (byte*)&bits, sizeof(bits)) != 0)
|
||||
return DRBG_FAILURE;
|
||||
|
||||
/* churning V is the only string that doesn't have
|
||||
* the type added */
|
||||
if (type != drbgInitV)
|
||||
if (Sha256Update(&drbg->sha, &type, sizeof(type)) != 0)
|
||||
return DRBG_FAILURE;
|
||||
|
||||
if (Sha256Update(&drbg->sha, inA, inASz) != 0)
|
||||
return DRBG_FAILURE;
|
||||
|
||||
if (inB != NULL && inBSz > 0)
|
||||
if (Sha256Update(&drbg->sha, inB, inBSz) != 0)
|
||||
return DRBG_FAILURE;
|
||||
|
||||
if (Sha256Final(&drbg->sha, drbg->digest) != 0)
|
||||
return DRBG_FAILURE;
|
||||
|
||||
if (outSz > OUTPUT_BLOCK_LEN) {
|
||||
XMEMCPY(out, drbg->digest, OUTPUT_BLOCK_LEN);
|
||||
outSz -= OUTPUT_BLOCK_LEN;
|
||||
out += OUTPUT_BLOCK_LEN;
|
||||
}
|
||||
else {
|
||||
XMEMCPY(out, drbg->digest, outSz);
|
||||
}
|
||||
}
|
||||
|
||||
return DRBG_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
|
||||
static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz)
|
||||
{
|
||||
byte seed[DRBG_SEED_LEN];
|
||||
|
||||
if (Hash_df(drbg, seed, sizeof(seed), drbgReseed, drbg->V, sizeof(drbg->V),
|
||||
entropy, entropySz) != DRBG_SUCCESS) {
|
||||
return DRBG_FAILURE;
|
||||
}
|
||||
|
||||
XMEMCPY(drbg->V, seed, sizeof(drbg->V));
|
||||
XMEMSET(seed, 0, sizeof(seed));
|
||||
|
||||
if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
|
||||
sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) {
|
||||
return DRBG_FAILURE;
|
||||
}
|
||||
|
||||
drbg->reseedCtr = 1;
|
||||
drbg->lastBlock = 0;
|
||||
drbg->matchCount = 0;
|
||||
return DRBG_SUCCESS;
|
||||
}
|
||||
|
||||
static INLINE void array_add_one(byte* data, word32 dataSz)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = dataSz - 1; i >= 0; i--)
|
||||
{
|
||||
data[i]++;
|
||||
if (data[i] != 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
|
||||
static int Hash_gen(DRBG* drbg, byte* out, word32 outSz, const byte* V)
|
||||
{
|
||||
byte data[DRBG_SEED_LEN];
|
||||
int i;
|
||||
int len;
|
||||
word32 checkBlock;
|
||||
|
||||
/* Special case: outSz is 0 and out is NULL. Generate a block to save for
|
||||
* the continuous test. */
|
||||
|
||||
if (outSz == 0) outSz = 1;
|
||||
|
||||
len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
|
||||
|
||||
XMEMCPY(data, V, sizeof(data));
|
||||
for (i = 0; i < len; i++) {
|
||||
if (InitSha256(&drbg->sha) != 0 ||
|
||||
Sha256Update(&drbg->sha, data, sizeof(data)) != 0 ||
|
||||
Sha256Final(&drbg->sha, drbg->digest) != 0) {
|
||||
|
||||
return DRBG_FAILURE;
|
||||
}
|
||||
|
||||
checkBlock = *(word32*)drbg->digest;
|
||||
if (drbg->reseedCtr > 1 && checkBlock == drbg->lastBlock) {
|
||||
if (drbg->matchCount == 1) {
|
||||
return DRBG_CONT_FAILURE;
|
||||
}
|
||||
else {
|
||||
if (i == len) {
|
||||
len++;
|
||||
}
|
||||
drbg->matchCount = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
drbg->matchCount = 0;
|
||||
drbg->lastBlock = checkBlock;
|
||||
}
|
||||
|
||||
if (outSz >= OUTPUT_BLOCK_LEN) {
|
||||
XMEMCPY(out, drbg->digest, OUTPUT_BLOCK_LEN);
|
||||
outSz -= OUTPUT_BLOCK_LEN;
|
||||
out += OUTPUT_BLOCK_LEN;
|
||||
array_add_one(data, DRBG_SEED_LEN);
|
||||
}
|
||||
else if (out != NULL && outSz != 0) {
|
||||
XMEMCPY(out, drbg->digest, outSz);
|
||||
outSz = 0;
|
||||
}
|
||||
}
|
||||
XMEMSET(data, 0, sizeof(data));
|
||||
|
||||
return DRBG_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
|
||||
{
|
||||
word16 carry = 0;
|
||||
|
||||
if (dLen > 0 && sLen > 0 && dLen >= sLen) {
|
||||
int sIdx, dIdx;
|
||||
|
||||
for (sIdx = sLen - 1, dIdx = dLen - 1; sIdx >= 0; dIdx--, sIdx--)
|
||||
{
|
||||
carry += d[dIdx] + s[sIdx];
|
||||
d[dIdx] = carry;
|
||||
carry >>= 8;
|
||||
}
|
||||
|
||||
for (; carry != 0 && dIdx >= 0; dIdx--) {
|
||||
carry += d[dIdx];
|
||||
d[dIdx] = carry;
|
||||
carry >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Returns: DRBG_SUCCESS, DRBG_NEED_RESEED, or DRBG_FAILURE */
|
||||
static int Hash_DRBG_Generate(DRBG* drbg, byte* out, word32 outSz)
|
||||
{
|
||||
int ret = DRBG_NEED_RESEED;
|
||||
|
||||
if (drbg->reseedCtr != RESEED_INTERVAL) {
|
||||
byte type = drbgGenerateH;
|
||||
word32 reseedCtr = drbg->reseedCtr;
|
||||
|
||||
ret = Hash_gen(drbg, out, outSz, drbg->V);
|
||||
if (ret == DRBG_SUCCESS) {
|
||||
if (InitSha256(&drbg->sha) != 0 ||
|
||||
Sha256Update(&drbg->sha, &type, sizeof(type)) != 0 ||
|
||||
Sha256Update(&drbg->sha, drbg->V, sizeof(drbg->V)) != 0 ||
|
||||
Sha256Final(&drbg->sha, drbg->digest) != 0) {
|
||||
|
||||
ret = DRBG_FAILURE;
|
||||
}
|
||||
else {
|
||||
array_add(drbg->V, sizeof(drbg->V),
|
||||
drbg->digest, sizeof(drbg->digest));
|
||||
array_add(drbg->V, sizeof(drbg->V), drbg->C, sizeof(drbg->C));
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
reseedCtr = ByteReverseWord32(reseedCtr);
|
||||
#endif
|
||||
array_add(drbg->V, sizeof(drbg->V),
|
||||
(byte*)&reseedCtr, sizeof(reseedCtr));
|
||||
ret = DRBG_SUCCESS;
|
||||
}
|
||||
drbg->reseedCtr++;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
|
||||
static int Hash_DRBG_Instantiate(DRBG* drbg, const byte* seed, word32 seedSz,
|
||||
const byte* nonce, word32 nonceSz)
|
||||
{
|
||||
int ret = DRBG_FAILURE;
|
||||
|
||||
XMEMSET(drbg, 0, sizeof(DRBG));
|
||||
|
||||
if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz,
|
||||
nonce, nonceSz) == DRBG_SUCCESS &&
|
||||
Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
|
||||
sizeof(drbg->V), NULL, 0) == DRBG_SUCCESS) {
|
||||
|
||||
drbg->reseedCtr = 1;
|
||||
drbg->lastBlock = 0;
|
||||
drbg->matchCount = 0;
|
||||
ret = DRBG_SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Returns: DRBG_SUCCESS */
|
||||
static int Hash_DRBG_Uninstantiate(DRBG* drbg)
|
||||
{
|
||||
XMEMSET(drbg, 0, sizeof(DRBG));
|
||||
|
||||
return DRBG_SUCCESS;
|
||||
}
|
||||
|
||||
/* End NIST DRBG Code */
|
||||
|
||||
|
||||
/* Get seed and key cipher */
|
||||
int InitRng(RNG* rng)
|
||||
{
|
||||
int ret = BAD_FUNC_ARG;
|
||||
|
||||
if (rng != NULL) {
|
||||
byte entropy[ENTROPY_NONCE_SZ];
|
||||
|
||||
rng->drbg = (struct DRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);
|
||||
if (rng->drbg == NULL) {
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
/* This doesn't use a separate nonce. The entropy input will be
|
||||
* the default size plus the size of the nonce making the seed
|
||||
* size. */
|
||||
else if (GenerateSeed(&rng->seed, entropy, ENTROPY_NONCE_SZ) == 0 &&
|
||||
Hash_DRBG_Instantiate(rng->drbg, entropy, ENTROPY_NONCE_SZ,
|
||||
NULL, 0) == DRBG_SUCCESS) {
|
||||
|
||||
ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
|
||||
}
|
||||
else
|
||||
ret = DRBG_FAILURE;
|
||||
|
||||
XMEMSET(entropy, 0, ENTROPY_NONCE_SZ);
|
||||
|
||||
if (ret == DRBG_SUCCESS) {
|
||||
rng->status = DRBG_OK;
|
||||
ret = 0;
|
||||
}
|
||||
else if (ret == DRBG_CONT_FAILURE) {
|
||||
rng->status = DRBG_CONT_FAILED;
|
||||
ret = DRBG_CONT_FIPS_E;
|
||||
}
|
||||
else if (ret == DRBG_FAILURE) {
|
||||
rng->status = DRBG_FAILED;
|
||||
ret = RNG_FAILURE_E;
|
||||
}
|
||||
else {
|
||||
rng->status = DRBG_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* place a generated block in output */
|
||||
int RNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (rng == NULL || output == NULL || sz > MAX_REQUEST_LEN)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (rng->status != DRBG_OK)
|
||||
return RNG_FAILURE_E;
|
||||
|
||||
ret = Hash_DRBG_Generate(rng->drbg, output, sz);
|
||||
|
||||
if (ret == DRBG_NEED_RESEED) {
|
||||
byte entropy[ENTROPY_SZ];
|
||||
|
||||
if (GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 &&
|
||||
Hash_DRBG_Reseed(rng->drbg, entropy, ENTROPY_SZ) == DRBG_SUCCESS) {
|
||||
|
||||
ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
|
||||
if (ret == DRBG_SUCCESS)
|
||||
ret = Hash_DRBG_Generate(rng->drbg, output, sz);
|
||||
}
|
||||
else
|
||||
ret = DRBG_FAILURE;
|
||||
|
||||
XMEMSET(entropy, 0, ENTROPY_SZ);
|
||||
}
|
||||
|
||||
if (ret == DRBG_SUCCESS) {
|
||||
ret = 0;
|
||||
}
|
||||
else if (ret == DRBG_CONT_FAILURE) {
|
||||
ret = DRBG_CONT_FIPS_E;
|
||||
rng->status = DRBG_CONT_FAILED;
|
||||
}
|
||||
else {
|
||||
ret = RNG_FAILURE_E;
|
||||
rng->status = DRBG_FAILED;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int RNG_GenerateByte(RNG* rng, byte* b)
|
||||
{
|
||||
return RNG_GenerateBlock(rng, b, 1);
|
||||
}
|
||||
|
||||
|
||||
int FreeRng(RNG* rng)
|
||||
{
|
||||
int ret = BAD_FUNC_ARG;
|
||||
|
||||
if (rng != NULL) {
|
||||
if (Hash_DRBG_Uninstantiate(rng->drbg) == DRBG_SUCCESS)
|
||||
ret = 0;
|
||||
else
|
||||
ret = RNG_FAILURE_E;
|
||||
|
||||
XFREE(rng->drbg, NULL, DYNAMIC_TYPE_RNG);
|
||||
rng->drbg = NULL;
|
||||
rng->status = DRBG_NOT_INIT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
|
||||
const byte* entropyB, word32 entropyBSz,
|
||||
byte* output, word32 outputSz)
|
||||
{
|
||||
DRBG drbg;
|
||||
|
||||
if (entropyA == NULL || output == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (reseed != 0 && entropyB == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (outputSz != (SHA256_DIGEST_SIZE * 4))
|
||||
return -1;
|
||||
|
||||
if (Hash_DRBG_Instantiate(&drbg, entropyA, entropyASz, NULL, 0) != 0)
|
||||
return -1;
|
||||
|
||||
if (reseed) {
|
||||
if (Hash_DRBG_Reseed(&drbg, entropyB, entropyBSz) != 0) {
|
||||
Hash_DRBG_Uninstantiate(&drbg);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Hash_DRBG_Generate(&drbg, output, outputSz) != 0) {
|
||||
Hash_DRBG_Uninstantiate(&drbg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (Hash_DRBG_Generate(&drbg, output, outputSz) != 0) {
|
||||
Hash_DRBG_Uninstantiate(&drbg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Hash_DRBG_Uninstantiate(&drbg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#else /* HAVE_HASHDRBG || NO_RC4 */
|
||||
|
||||
/* Get seed and key cipher */
|
||||
int InitRng(RNG* rng)
|
||||
{
|
||||
int ret;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
byte* key;
|
||||
byte* junk;
|
||||
#else
|
||||
byte key[32];
|
||||
byte junk[256];
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (rng->magic == CYASSL_RNG_CAVIUM_MAGIC)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
key = (byte*)XMALLOC(32, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (key == NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
junk = (byte*)XMALLOC(256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (junk == NULL) {
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = GenerateSeed(&rng->seed, key, 32);
|
||||
|
||||
if (ret == 0) {
|
||||
Arc4SetKey(&rng->cipher, key, sizeof(key));
|
||||
|
||||
ret = RNG_GenerateBlock(rng, junk, 256); /*rid initial state*/
|
||||
}
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(junk, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz);
|
||||
#endif
|
||||
|
||||
/* place a generated block in output */
|
||||
int RNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
|
||||
{
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (rng->magic == CYASSL_RNG_CAVIUM_MAGIC)
|
||||
return CaviumRNG_GenerateBlock(rng, output, sz);
|
||||
#endif
|
||||
XMEMSET(output, 0, sz);
|
||||
Arc4Process(&rng->cipher, output, output, sz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int RNG_GenerateByte(RNG* rng, byte* b)
|
||||
{
|
||||
return RNG_GenerateBlock(rng, b, 1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
|
||||
#include <cyassl/ctaocrypt/logging.h>
|
||||
#include "cavium_common.h"
|
||||
|
||||
/* Initiliaze RNG for use with Nitrox device */
|
||||
int InitRngCavium(RNG* rng, int devId)
|
||||
{
|
||||
if (rng == NULL)
|
||||
return -1;
|
||||
|
||||
rng->devId = devId;
|
||||
rng->magic = CYASSL_RNG_CAVIUM_MAGIC;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void CaviumRNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
|
||||
{
|
||||
cyassl_word offset = 0;
|
||||
word32 requestId;
|
||||
|
||||
while (sz > CYASSL_MAX_16BIT) {
|
||||
word16 slen = (word16)CYASSL_MAX_16BIT;
|
||||
if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId,
|
||||
rng->devId) != 0) {
|
||||
CYASSL_MSG("Cavium RNG failed");
|
||||
}
|
||||
sz -= CYASSL_MAX_16BIT;
|
||||
offset += CYASSL_MAX_16BIT;
|
||||
}
|
||||
if (sz) {
|
||||
word16 slen = (word16)sz;
|
||||
if (CspRandom(CAVIUM_BLOCKING, slen, output + offset, &requestId,
|
||||
rng->devId) != 0) {
|
||||
CYASSL_MSG("Cavium RNG failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_CAVIUM */
|
||||
|
||||
#endif /* HAVE_HASHDRBG || NO_RC4 */
|
||||
|
||||
|
||||
#if defined(USE_WINDOWS_API)
|
||||
|
||||
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT))
|
||||
return WINCRYPT_E;
|
||||
|
||||
if (!CryptGenRandom(os->handle, sz, output))
|
||||
return CRYPTGEN_E;
|
||||
|
||||
CryptReleaseContext(os->handle, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#elif defined(HAVE_RTP_SYS) || defined(EBSNET)
|
||||
|
||||
#include "rtprand.h" /* rtp_rand () */
|
||||
#include "rtptime.h" /* rtp_get_system_msec() */
|
||||
|
||||
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
int i;
|
||||
rtp_srand(rtp_get_system_msec());
|
||||
|
||||
for (i = 0; i < sz; i++ ) {
|
||||
output[i] = rtp_rand() % 256;
|
||||
if ( (i % 8) == 7)
|
||||
rtp_srand(rtp_get_system_msec());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#elif defined(MICRIUM)
|
||||
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
#if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
|
||||
NetSecure_InitSeed(output, sz);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(MBED)
|
||||
|
||||
/* write a real one !!!, just for testing board */
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sz; i++ )
|
||||
output[i] = i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(MICROCHIP_PIC32)
|
||||
|
||||
#ifdef MICROCHIP_MPLAB_HARMONY
|
||||
#define PIC32_SEED_COUNT _CP0_GET_COUNT
|
||||
#else
|
||||
#if !defined(CYASSL_MICROCHIP_PIC32MZ)
|
||||
#include <peripheral/timer.h>
|
||||
#endif
|
||||
#define PIC32_SEED_COUNT ReadCoreTimer
|
||||
#endif
|
||||
#ifdef CYASSL_MIC32MZ_RNG
|
||||
#include "xc.h"
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
int i ;
|
||||
byte rnd[8] ;
|
||||
word32 *rnd32 = (word32 *)rnd ;
|
||||
word32 size = sz ;
|
||||
byte* op = output ;
|
||||
|
||||
/* This part has to be replaced with better random seed */
|
||||
RNGNUMGEN1 = ReadCoreTimer();
|
||||
RNGPOLY1 = ReadCoreTimer();
|
||||
RNGPOLY2 = ReadCoreTimer();
|
||||
RNGNUMGEN2 = ReadCoreTimer();
|
||||
#ifdef DEBUG_CYASSL
|
||||
printf("GenerateSeed::Seed=%08x, %08x\n", RNGNUMGEN1, RNGNUMGEN2) ;
|
||||
#endif
|
||||
RNGCONbits.PLEN = 0x40;
|
||||
RNGCONbits.PRNGEN = 1;
|
||||
for(i=0; i<5; i++) { /* wait for RNGNUMGEN ready */
|
||||
volatile int x ;
|
||||
x = RNGNUMGEN1 ;
|
||||
x = RNGNUMGEN2 ;
|
||||
}
|
||||
do {
|
||||
rnd32[0] = RNGNUMGEN1;
|
||||
rnd32[1] = RNGNUMGEN2;
|
||||
|
||||
for(i=0; i<8; i++, op++) {
|
||||
*op = rnd[i] ;
|
||||
size -- ;
|
||||
if(size==0)break ;
|
||||
}
|
||||
} while(size) ;
|
||||
return 0;
|
||||
}
|
||||
#else /* CYASSL_MIC32MZ_RNG */
|
||||
/* uses the core timer, in nanoseconds to seed srand */
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
int i;
|
||||
srand(PIC32_SEED_COUNT() * 25);
|
||||
|
||||
for (i = 0; i < sz; i++ ) {
|
||||
output[i] = rand() % 256;
|
||||
if ( (i % 8) == 7)
|
||||
srand(PIC32_SEED_COUNT() * 25);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* CYASSL_MIC32MZ_RNG */
|
||||
|
||||
#elif defined(FREESCALE_MQX)
|
||||
|
||||
#ifdef FREESCALE_K70_RNGA
|
||||
/*
|
||||
* Generates a RNG seed using the Random Number Generator Accelerator
|
||||
* on the Kinetis K70. Documentation located in Chapter 37 of
|
||||
* K70 Sub-Family Reference Manual (see Note 3 in the README for link).
|
||||
*/
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* turn on RNGA module */
|
||||
SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK;
|
||||
|
||||
/* set SLP bit to 0 - "RNGA is not in sleep mode" */
|
||||
RNG_CR &= ~RNG_CR_SLP_MASK;
|
||||
|
||||
/* set HA bit to 1 - "security violations masked" */
|
||||
RNG_CR |= RNG_CR_HA_MASK;
|
||||
|
||||
/* set GO bit to 1 - "output register loaded with data" */
|
||||
RNG_CR |= RNG_CR_GO_MASK;
|
||||
|
||||
for (i = 0; i < sz; i++) {
|
||||
|
||||
/* wait for RNG FIFO to be full */
|
||||
while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {}
|
||||
|
||||
/* get value */
|
||||
output[i] = RNG_OR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(FREESCALE_K53_RNGB)
|
||||
/*
|
||||
* Generates a RNG seed using the Random Number Generator (RNGB)
|
||||
* on the Kinetis K53. Documentation located in Chapter 33 of
|
||||
* K53 Sub-Family Reference Manual (see note in the README for link).
|
||||
*/
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* turn on RNGB module */
|
||||
SIM_SCGC3 |= SIM_SCGC3_RNGB_MASK;
|
||||
|
||||
/* reset RNGB */
|
||||
RNG_CMD |= RNG_CMD_SR_MASK;
|
||||
|
||||
/* FIFO generate interrupt, return all zeros on underflow,
|
||||
* set auto reseed */
|
||||
RNG_CR |= (RNG_CR_FUFMOD_MASK | RNG_CR_AR_MASK);
|
||||
|
||||
/* gen seed, clear interrupts, clear errors */
|
||||
RNG_CMD |= (RNG_CMD_GS_MASK | RNG_CMD_CI_MASK | RNG_CMD_CE_MASK);
|
||||
|
||||
/* wait for seeding to complete */
|
||||
while ((RNG_SR & RNG_SR_SDN_MASK) == 0) {}
|
||||
|
||||
for (i = 0; i < sz; i++) {
|
||||
|
||||
/* wait for a word to be available from FIFO */
|
||||
while((RNG_SR & RNG_SR_FIFO_LVL_MASK) == 0) {}
|
||||
|
||||
/* get value */
|
||||
output[i] = RNG_OUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#warning "write a real random seed!!!!, just for testing now"
|
||||
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sz; i++ )
|
||||
output[i] = i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* FREESCALE_K70_RNGA */
|
||||
|
||||
#elif defined(CYASSL_SAFERTOS) || defined(CYASSL_LEANPSK) \
|
||||
|| defined(CYASSL_IAR_ARM) || defined(CYASSL_MDK_ARM)
|
||||
|
||||
#warning "write a real random seed!!!!, just for testing now"
|
||||
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
word32 i;
|
||||
for (i = 0; i < sz; i++ )
|
||||
output[i] = i;
|
||||
|
||||
(void)os;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(STM32F2_RNG)
|
||||
#undef RNG
|
||||
#include "stm32f2xx_rng.h"
|
||||
#include "stm32f2xx_rcc.h"
|
||||
/*
|
||||
* Generate a RNG seed using the hardware random number generator
|
||||
* on the STM32F2. Documentation located in STM32F2xx Standard Peripheral
|
||||
* Library document (See note in README).
|
||||
*/
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* enable RNG clock source */
|
||||
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
|
||||
|
||||
/* enable RNG peripheral */
|
||||
RNG_Cmd(ENABLE);
|
||||
|
||||
for (i = 0; i < sz; i++) {
|
||||
/* wait until RNG number is ready */
|
||||
while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET) { }
|
||||
|
||||
/* get value */
|
||||
output[i] = RNG_GetRandomNumber();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#elif defined(CYASSL_LPC43xx) || defined(CYASSL_STM32F2xx)
|
||||
|
||||
#warning "write a real random seed!!!!, just for testing now"
|
||||
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sz; i++ )
|
||||
output[i] = i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(CYASSL_TIRTOS)
|
||||
|
||||
#include <xdc/runtime/Timestamp.h>
|
||||
#include <stdlib.h>
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
int i;
|
||||
srand(xdc_runtime_Timestamp_get32());
|
||||
|
||||
for (i = 0; i < sz; i++ ) {
|
||||
output[i] = rand() % 256;
|
||||
if ((i % 8) == 7) {
|
||||
srand(xdc_runtime_Timestamp_get32());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(CUSTOM_RAND_GENERATE)
|
||||
|
||||
/* Implement your own random generation function
|
||||
* word32 rand_gen(void);
|
||||
* #define CUSTOM_RAND_GENERATE rand_gen */
|
||||
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sz; i++ )
|
||||
output[i] = CUSTOM_RAND_GENERATE();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(NO_DEV_RANDOM)
|
||||
|
||||
#error "you need to write an os specific GenerateSeed() here"
|
||||
|
||||
/*
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
#else /* !USE_WINDOWS_API && !HAVE_RPT_SYS && !MICRIUM && !NO_DEV_RANDOM */
|
||||
|
||||
|
||||
/* may block */
|
||||
int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
os->fd = open("/dev/urandom",O_RDONLY);
|
||||
if (os->fd == -1) {
|
||||
/* may still have /dev/random */
|
||||
os->fd = open("/dev/random",O_RDONLY);
|
||||
if (os->fd == -1)
|
||||
return OPEN_RAN_E;
|
||||
}
|
||||
|
||||
while (sz) {
|
||||
int len = (int)read(os->fd, output, sz);
|
||||
if (len == -1) {
|
||||
ret = READ_RAN_E;
|
||||
break;
|
||||
}
|
||||
|
||||
sz -= len;
|
||||
output += len;
|
||||
|
||||
if (sz) {
|
||||
#ifdef BLOCKING
|
||||
sleep(0); /* context switch */
|
||||
#else
|
||||
ret = RAN_BLOCK_E;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
close(os->fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* USE_WINDOWS_API */
|
||||
|
||||
/* dummy file for autoconf */
|
||||
|
@ -1,862 +1 @@
|
||||
/* rsa.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#ifndef NO_RSA
|
||||
|
||||
#ifdef HAVE_FIPS
|
||||
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
|
||||
#define FIPS_NO_WRAPPERS
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/rsa.h>
|
||||
#include <cyassl/ctaocrypt/random.h>
|
||||
#include <cyassl/ctaocrypt/error-crypt.h>
|
||||
#include <cyassl/ctaocrypt/logging.h>
|
||||
|
||||
#ifdef SHOW_GEN
|
||||
#ifdef FREESCALE_MQX
|
||||
#include <fio.h>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
static int InitCaviumRsaKey(RsaKey* key, void* heap);
|
||||
static int FreeCaviumRsaKey(RsaKey* key);
|
||||
static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
|
||||
word32 outLen, RsaKey* key);
|
||||
static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
|
||||
word32 outLen, RsaKey* key);
|
||||
static int CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out,
|
||||
word32 outLen, RsaKey* key);
|
||||
static int CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out,
|
||||
word32 outLen, RsaKey* key);
|
||||
#endif
|
||||
|
||||
enum {
|
||||
RSA_PUBLIC_ENCRYPT = 0,
|
||||
RSA_PUBLIC_DECRYPT = 1,
|
||||
RSA_PRIVATE_ENCRYPT = 2,
|
||||
RSA_PRIVATE_DECRYPT = 3,
|
||||
|
||||
RSA_BLOCK_TYPE_1 = 1,
|
||||
RSA_BLOCK_TYPE_2 = 2,
|
||||
|
||||
RSA_MIN_SIZE = 512,
|
||||
RSA_MAX_SIZE = 4096,
|
||||
|
||||
RSA_MIN_PAD_SZ = 11 /* seperator + 0 + pad value + 8 pads */
|
||||
};
|
||||
|
||||
|
||||
int InitRsaKey(RsaKey* key, void* heap)
|
||||
{
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
|
||||
return InitCaviumRsaKey(key, heap);
|
||||
#endif
|
||||
|
||||
key->type = -1; /* haven't decided yet */
|
||||
key->heap = heap;
|
||||
|
||||
/* TomsFastMath doesn't use memory allocation */
|
||||
#ifndef USE_FAST_MATH
|
||||
key->n.dp = key->e.dp = 0; /* public alloc parts */
|
||||
|
||||
key->d.dp = key->p.dp = 0; /* private alloc parts */
|
||||
key->q.dp = key->dP.dp = 0;
|
||||
key->u.dp = key->dQ.dp = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int FreeRsaKey(RsaKey* key)
|
||||
{
|
||||
(void)key;
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
|
||||
return FreeCaviumRsaKey(key);
|
||||
#endif
|
||||
|
||||
/* TomsFastMath doesn't use memory allocation */
|
||||
#ifndef USE_FAST_MATH
|
||||
if (key->type == RSA_PRIVATE) {
|
||||
mp_clear(&key->u);
|
||||
mp_clear(&key->dQ);
|
||||
mp_clear(&key->dP);
|
||||
mp_clear(&key->q);
|
||||
mp_clear(&key->p);
|
||||
mp_clear(&key->d);
|
||||
}
|
||||
mp_clear(&key->e);
|
||||
mp_clear(&key->n);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
|
||||
word32 pkcsBlockLen, byte padValue, RNG* rng)
|
||||
{
|
||||
if (inputLen == 0)
|
||||
return 0;
|
||||
|
||||
pkcsBlock[0] = 0x0; /* set first byte to zero and advance */
|
||||
pkcsBlock++; pkcsBlockLen--;
|
||||
pkcsBlock[0] = padValue; /* insert padValue */
|
||||
|
||||
if (padValue == RSA_BLOCK_TYPE_1)
|
||||
/* pad with 0xff bytes */
|
||||
XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2);
|
||||
else {
|
||||
/* pad with non-zero random bytes */
|
||||
word32 padLen = pkcsBlockLen - inputLen - 1, i;
|
||||
int ret = RNG_GenerateBlock(rng, &pkcsBlock[1], padLen);
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* remove zeros */
|
||||
for (i = 1; i < padLen; i++)
|
||||
if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;
|
||||
}
|
||||
|
||||
pkcsBlock[pkcsBlockLen-inputLen-1] = 0; /* separator */
|
||||
XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* UnPad plaintext, set start to *output, return length of plaintext,
|
||||
* < 0 on error */
|
||||
static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
|
||||
byte **output, byte padValue)
|
||||
{
|
||||
word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0,
|
||||
invalid = 0,
|
||||
i = 1,
|
||||
outputLen;
|
||||
|
||||
if (pkcsBlock[0] != 0x0) /* skip past zero */
|
||||
invalid = 1;
|
||||
pkcsBlock++; pkcsBlockLen--;
|
||||
|
||||
/* Require block type padValue */
|
||||
invalid = (pkcsBlock[0] != padValue) || invalid;
|
||||
|
||||
/* verify the padding until we find the separator */
|
||||
if (padValue == RSA_BLOCK_TYPE_1) {
|
||||
while (i<pkcsBlockLen && pkcsBlock[i++] == 0xFF) {/* Null body */}
|
||||
}
|
||||
else {
|
||||
while (i<pkcsBlockLen && pkcsBlock[i++]) {/* Null body */}
|
||||
}
|
||||
|
||||
if(!(i==pkcsBlockLen || pkcsBlock[i-1]==0)) {
|
||||
CYASSL_MSG("RsaUnPad error, bad formatting");
|
||||
return RSA_PAD_E;
|
||||
}
|
||||
|
||||
outputLen = pkcsBlockLen - i;
|
||||
invalid = (outputLen > maxOutputLen) || invalid;
|
||||
|
||||
if (invalid) {
|
||||
CYASSL_MSG("RsaUnPad error, bad formatting");
|
||||
return RSA_PAD_E;
|
||||
}
|
||||
|
||||
*output = (byte *)(pkcsBlock + i);
|
||||
return outputLen;
|
||||
}
|
||||
|
||||
|
||||
static int RsaFunction(const byte* in, word32 inLen, byte* out, word32* outLen,
|
||||
int type, RsaKey* key)
|
||||
{
|
||||
#define ERROR_OUT(x) { ret = (x); goto done;}
|
||||
|
||||
mp_int tmp;
|
||||
int ret = 0;
|
||||
word32 keyLen, len;
|
||||
|
||||
if (mp_init(&tmp) != MP_OKAY)
|
||||
return MP_INIT_E;
|
||||
|
||||
if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY)
|
||||
ERROR_OUT(MP_READ_E);
|
||||
|
||||
if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
|
||||
#ifdef RSA_LOW_MEM /* half as much memory but twice as slow */
|
||||
if (mp_exptmod(&tmp, &key->d, &key->n, &tmp) != MP_OKAY)
|
||||
ERROR_OUT(MP_EXPTMOD_E);
|
||||
#else
|
||||
#define INNER_ERROR_OUT(x) { ret = (x); goto inner_done; }
|
||||
|
||||
mp_int tmpa, tmpb;
|
||||
|
||||
if (mp_init(&tmpa) != MP_OKAY)
|
||||
ERROR_OUT(MP_INIT_E);
|
||||
|
||||
if (mp_init(&tmpb) != MP_OKAY) {
|
||||
mp_clear(&tmpa);
|
||||
ERROR_OUT(MP_INIT_E);
|
||||
}
|
||||
|
||||
/* tmpa = tmp^dP mod p */
|
||||
if (mp_exptmod(&tmp, &key->dP, &key->p, &tmpa) != MP_OKAY)
|
||||
INNER_ERROR_OUT(MP_EXPTMOD_E);
|
||||
|
||||
/* tmpb = tmp^dQ mod q */
|
||||
if (mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb) != MP_OKAY)
|
||||
INNER_ERROR_OUT(MP_EXPTMOD_E);
|
||||
|
||||
/* tmp = (tmpa - tmpb) * qInv (mod p) */
|
||||
if (mp_sub(&tmpa, &tmpb, &tmp) != MP_OKAY)
|
||||
INNER_ERROR_OUT(MP_SUB_E);
|
||||
|
||||
if (mp_mulmod(&tmp, &key->u, &key->p, &tmp) != MP_OKAY)
|
||||
INNER_ERROR_OUT(MP_MULMOD_E);
|
||||
|
||||
/* tmp = tmpb + q * tmp */
|
||||
if (mp_mul(&tmp, &key->q, &tmp) != MP_OKAY)
|
||||
INNER_ERROR_OUT(MP_MUL_E);
|
||||
|
||||
if (mp_add(&tmp, &tmpb, &tmp) != MP_OKAY)
|
||||
INNER_ERROR_OUT(MP_ADD_E);
|
||||
|
||||
inner_done:
|
||||
mp_clear(&tmpa);
|
||||
mp_clear(&tmpb);
|
||||
|
||||
if (ret != 0) return ret;
|
||||
|
||||
#endif /* RSA_LOW_MEM */
|
||||
}
|
||||
else if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PUBLIC_DECRYPT) {
|
||||
if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY)
|
||||
ERROR_OUT(MP_EXPTMOD_E);
|
||||
}
|
||||
else
|
||||
ERROR_OUT(RSA_WRONG_TYPE_E);
|
||||
|
||||
keyLen = mp_unsigned_bin_size(&key->n);
|
||||
if (keyLen > *outLen)
|
||||
ERROR_OUT(RSA_BUFFER_E);
|
||||
|
||||
len = mp_unsigned_bin_size(&tmp);
|
||||
|
||||
/* pad front w/ zeros to match key length */
|
||||
while (len < keyLen) {
|
||||
*out++ = 0x00;
|
||||
len++;
|
||||
}
|
||||
|
||||
*outLen = keyLen;
|
||||
|
||||
/* convert */
|
||||
if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY)
|
||||
ERROR_OUT(MP_TO_E);
|
||||
|
||||
done:
|
||||
mp_clear(&tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
|
||||
RsaKey* key, RNG* rng)
|
||||
{
|
||||
int sz, ret;
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
|
||||
return CaviumRsaPublicEncrypt(in, inLen, out, outLen, key);
|
||||
#endif
|
||||
|
||||
sz = mp_unsigned_bin_size(&key->n);
|
||||
if (sz > (int)outLen)
|
||||
return RSA_BUFFER_E;
|
||||
|
||||
if (inLen > (word32)(sz - RSA_MIN_PAD_SZ))
|
||||
return RSA_BUFFER_E;
|
||||
|
||||
ret = RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_2, rng);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = RsaFunction(out, sz, out, &outLen, RSA_PUBLIC_ENCRYPT, key)) < 0)
|
||||
sz = ret;
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
int RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) {
|
||||
ret = CaviumRsaPrivateDecrypt(in, inLen, in, inLen, key);
|
||||
if (ret > 0)
|
||||
*out = in;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((ret = RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key))
|
||||
< 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_2);
|
||||
}
|
||||
|
||||
|
||||
int RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
|
||||
RsaKey* key)
|
||||
{
|
||||
int plainLen;
|
||||
byte* tmp;
|
||||
byte* pad = 0;
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
|
||||
return CaviumRsaPrivateDecrypt(in, inLen, out, outLen, key);
|
||||
#endif
|
||||
|
||||
tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA);
|
||||
if (tmp == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
XMEMCPY(tmp, in, inLen);
|
||||
|
||||
if ( (plainLen = RsaPrivateDecryptInline(tmp, inLen, &pad, key) ) < 0) {
|
||||
XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
|
||||
return plainLen;
|
||||
}
|
||||
if (plainLen > (int)outLen)
|
||||
plainLen = BAD_FUNC_ARG;
|
||||
else
|
||||
XMEMCPY(out, pad, plainLen);
|
||||
XMEMSET(tmp, 0x00, inLen);
|
||||
|
||||
XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
|
||||
return plainLen;
|
||||
}
|
||||
|
||||
|
||||
/* for Rsa Verify */
|
||||
int RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) {
|
||||
ret = CaviumRsaSSL_Verify(in, inLen, in, inLen, key);
|
||||
if (ret > 0)
|
||||
*out = in;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((ret = RsaFunction(in, inLen, in, &inLen, RSA_PUBLIC_DECRYPT, key))
|
||||
< 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_1);
|
||||
}
|
||||
|
||||
|
||||
int RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
|
||||
RsaKey* key)
|
||||
{
|
||||
int plainLen;
|
||||
byte* tmp;
|
||||
byte* pad = 0;
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
|
||||
return CaviumRsaSSL_Verify(in, inLen, out, outLen, key);
|
||||
#endif
|
||||
|
||||
tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA);
|
||||
if (tmp == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
XMEMCPY(tmp, in, inLen);
|
||||
|
||||
if ( (plainLen = RsaSSL_VerifyInline(tmp, inLen, &pad, key) ) < 0) {
|
||||
XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
|
||||
return plainLen;
|
||||
}
|
||||
|
||||
if (plainLen > (int)outLen)
|
||||
plainLen = BAD_FUNC_ARG;
|
||||
else
|
||||
XMEMCPY(out, pad, plainLen);
|
||||
XMEMSET(tmp, 0x00, inLen);
|
||||
|
||||
XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
|
||||
return plainLen;
|
||||
}
|
||||
|
||||
|
||||
/* for Rsa Sign */
|
||||
int RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
|
||||
RsaKey* key, RNG* rng)
|
||||
{
|
||||
int sz, ret;
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
|
||||
return CaviumRsaSSL_Sign(in, inLen, out, outLen, key);
|
||||
#endif
|
||||
|
||||
sz = mp_unsigned_bin_size(&key->n);
|
||||
if (sz > (int)outLen)
|
||||
return RSA_BUFFER_E;
|
||||
|
||||
if (inLen > (word32)(sz - RSA_MIN_PAD_SZ))
|
||||
return RSA_BUFFER_E;
|
||||
|
||||
ret = RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = RsaFunction(out, sz, out, &outLen, RSA_PRIVATE_ENCRYPT,key)) < 0)
|
||||
sz = ret;
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
int RsaEncryptSize(RsaKey* key)
|
||||
{
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
|
||||
return key->c_nSz;
|
||||
#endif
|
||||
return mp_unsigned_bin_size(&key->n);
|
||||
}
|
||||
|
||||
|
||||
int RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n, word32* nSz)
|
||||
{
|
||||
int sz, ret;
|
||||
|
||||
if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
sz = mp_unsigned_bin_size(&key->e);
|
||||
if ((word32)sz > *nSz)
|
||||
return RSA_BUFFER_E;
|
||||
ret = mp_to_unsigned_bin(&key->e, e);
|
||||
if (ret != MP_OKAY)
|
||||
return ret;
|
||||
*eSz = (word32)sz;
|
||||
|
||||
sz = mp_unsigned_bin_size(&key->n);
|
||||
if ((word32)sz > *nSz)
|
||||
return RSA_BUFFER_E;
|
||||
ret = mp_to_unsigned_bin(&key->n, n);
|
||||
if (ret != MP_OKAY)
|
||||
return ret;
|
||||
*nSz = (word32)sz;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CYASSL_KEY_GEN
|
||||
|
||||
static const int USE_BBS = 1;
|
||||
|
||||
static int rand_prime(mp_int* N, int len, RNG* rng, void* heap)
|
||||
{
|
||||
int err, res, type;
|
||||
byte* buf;
|
||||
|
||||
(void)heap;
|
||||
if (N == NULL || rng == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* get type */
|
||||
if (len < 0) {
|
||||
type = USE_BBS;
|
||||
len = -len;
|
||||
} else {
|
||||
type = 0;
|
||||
}
|
||||
|
||||
/* allow sizes between 2 and 512 bytes for a prime size */
|
||||
if (len < 2 || len > 512) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* allocate buffer to work with */
|
||||
buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_RSA);
|
||||
if (buf == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(buf, 0, len);
|
||||
|
||||
do {
|
||||
#ifdef SHOW_GEN
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
/* generate value */
|
||||
err = RNG_GenerateBlock(rng, buf, len);
|
||||
if (err != 0) {
|
||||
XFREE(buf, heap, DYNAMIC_TYPE_RSA);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* munge bits */
|
||||
buf[0] |= 0x80 | 0x40;
|
||||
buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);
|
||||
|
||||
/* load value */
|
||||
if ((err = mp_read_unsigned_bin(N, buf, len)) != MP_OKAY) {
|
||||
XFREE(buf, heap, DYNAMIC_TYPE_RSA);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* test */
|
||||
if ((err = mp_prime_is_prime(N, 8, &res)) != MP_OKAY) {
|
||||
XFREE(buf, heap, DYNAMIC_TYPE_RSA);
|
||||
return err;
|
||||
}
|
||||
} while (res == MP_NO);
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
XMEMSET(buf, 0, len);
|
||||
#endif
|
||||
|
||||
XFREE(buf, heap, DYNAMIC_TYPE_RSA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Make an RSA key for size bits, with e specified, 65537 is a good e */
|
||||
int MakeRsaKey(RsaKey* key, int size, long e, RNG* rng)
|
||||
{
|
||||
mp_int p, q, tmp1, tmp2, tmp3;
|
||||
int err;
|
||||
|
||||
if (key == NULL || rng == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (e < 3 || (e & 1) == 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY)
|
||||
return err;
|
||||
|
||||
err = mp_set_int(&tmp3, e);
|
||||
|
||||
/* make p */
|
||||
if (err == MP_OKAY) {
|
||||
do {
|
||||
err = rand_prime(&p, size/16, rng, key->heap); /* size in bytes/2 */
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_sub_d(&p, 1, &tmp1); /* tmp1 = p-1 */
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(p-1, e) */
|
||||
} while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divdes p-1 */
|
||||
}
|
||||
|
||||
/* make q */
|
||||
if (err == MP_OKAY) {
|
||||
do {
|
||||
err = rand_prime(&q, size/16, rng, key->heap); /* size in bytes/2 */
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_sub_d(&q, 1, &tmp1); /* tmp1 = q-1 */
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(q-1, e) */
|
||||
} while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divdes q-1 */
|
||||
}
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL);
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_init_multi(&key->dP, &key->dQ, &key->u, NULL, NULL, NULL);
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_sub_d(&p, 1, &tmp2); /* tmp2 = p-1 */
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_lcm(&tmp1, &tmp2, &tmp1); /* tmp1 = lcm(p-1, q-1),last loop */
|
||||
|
||||
/* make key */
|
||||
if (err == MP_OKAY)
|
||||
err = mp_set_int(&key->e, e); /* key->e = e */
|
||||
|
||||
if (err == MP_OKAY) /* key->d = 1/e mod lcm(p-1, q-1) */
|
||||
err = mp_invmod(&key->e, &tmp1, &key->d);
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_mul(&p, &q, &key->n); /* key->n = pq */
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_sub_d(&p, 1, &tmp1);
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_sub_d(&q, 1, &tmp2);
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_mod(&key->d, &tmp1, &key->dP);
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_mod(&key->d, &tmp2, &key->dQ);
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_invmod(&q, &p, &key->u);
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_copy(&p, &key->p);
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_copy(&q, &key->q);
|
||||
|
||||
if (err == MP_OKAY)
|
||||
key->type = RSA_PRIVATE;
|
||||
|
||||
mp_clear(&tmp3);
|
||||
mp_clear(&tmp2);
|
||||
mp_clear(&tmp1);
|
||||
mp_clear(&q);
|
||||
mp_clear(&p);
|
||||
|
||||
if (err != MP_OKAY) {
|
||||
FreeRsaKey(key);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* CYASSL_KEY_GEN */
|
||||
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
|
||||
#include <cyassl/ctaocrypt/logging.h>
|
||||
#include "cavium_common.h"
|
||||
|
||||
/* Initiliaze RSA for use with Nitrox device */
|
||||
int RsaInitCavium(RsaKey* rsa, int devId)
|
||||
{
|
||||
if (rsa == NULL)
|
||||
return -1;
|
||||
|
||||
if (CspAllocContext(CONTEXT_SSL, &rsa->contextHandle, devId) != 0)
|
||||
return -1;
|
||||
|
||||
rsa->devId = devId;
|
||||
rsa->magic = CYASSL_RSA_CAVIUM_MAGIC;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Free RSA from use with Nitrox device */
|
||||
void RsaFreeCavium(RsaKey* rsa)
|
||||
{
|
||||
if (rsa == NULL)
|
||||
return;
|
||||
|
||||
CspFreeContext(CONTEXT_SSL, rsa->contextHandle, rsa->devId);
|
||||
rsa->magic = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize cavium RSA key */
|
||||
static int InitCaviumRsaKey(RsaKey* key, void* heap)
|
||||
{
|
||||
if (key == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
key->heap = heap;
|
||||
key->type = -1; /* don't know yet */
|
||||
|
||||
key->c_n = NULL;
|
||||
key->c_e = NULL;
|
||||
key->c_d = NULL;
|
||||
key->c_p = NULL;
|
||||
key->c_q = NULL;
|
||||
key->c_dP = NULL;
|
||||
key->c_dQ = NULL;
|
||||
key->c_u = NULL;
|
||||
|
||||
key->c_nSz = 0;
|
||||
key->c_eSz = 0;
|
||||
key->c_dSz = 0;
|
||||
key->c_pSz = 0;
|
||||
key->c_qSz = 0;
|
||||
key->c_dP_Sz = 0;
|
||||
key->c_dQ_Sz = 0;
|
||||
key->c_uSz = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Free cavium RSA key */
|
||||
static int FreeCaviumRsaKey(RsaKey* key)
|
||||
{
|
||||
if (key == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
XFREE(key->c_n, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
|
||||
XFREE(key->c_e, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
|
||||
XFREE(key->c_d, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
|
||||
XFREE(key->c_p, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
|
||||
XFREE(key->c_q, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
|
||||
XFREE(key->c_dP, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
|
||||
XFREE(key->c_dQ, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
|
||||
XFREE(key->c_u, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
|
||||
|
||||
return InitCaviumRsaKey(key, key->heap); /* reset pointers */
|
||||
}
|
||||
|
||||
|
||||
static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
|
||||
word32 outLen, RsaKey* key)
|
||||
{
|
||||
word32 requestId;
|
||||
word32 ret;
|
||||
|
||||
if (key == NULL || in == NULL || out == NULL || outLen < (word32)key->c_nSz)
|
||||
return -1;
|
||||
|
||||
ret = CspPkcs1v15Enc(CAVIUM_BLOCKING, BT2, key->c_nSz, key->c_eSz,
|
||||
(word16)inLen, key->c_n, key->c_e, (byte*)in, out,
|
||||
&requestId, key->devId);
|
||||
if (ret != 0) {
|
||||
CYASSL_MSG("Cavium Enc BT2 failed");
|
||||
return -1;
|
||||
}
|
||||
return key->c_nSz;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void ato16(const byte* c, word16* u16)
|
||||
{
|
||||
*u16 = (c[0] << 8) | (c[1]);
|
||||
}
|
||||
|
||||
|
||||
static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
|
||||
word32 outLen, RsaKey* key)
|
||||
{
|
||||
word32 requestId;
|
||||
word32 ret;
|
||||
word16 outSz = (word16)outLen;
|
||||
|
||||
if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->c_nSz)
|
||||
return -1;
|
||||
|
||||
ret = CspPkcs1v15CrtDec(CAVIUM_BLOCKING, BT2, key->c_nSz, key->c_q,
|
||||
key->c_dQ, key->c_p, key->c_dP, key->c_u,
|
||||
(byte*)in, &outSz, out, &requestId, key->devId);
|
||||
if (ret != 0) {
|
||||
CYASSL_MSG("Cavium CRT Dec BT2 failed");
|
||||
return -1;
|
||||
}
|
||||
ato16((const byte*)&outSz, &outSz);
|
||||
|
||||
return outSz;
|
||||
}
|
||||
|
||||
|
||||
static int CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out,
|
||||
word32 outLen, RsaKey* key)
|
||||
{
|
||||
word32 requestId;
|
||||
word32 ret;
|
||||
|
||||
if (key == NULL || in == NULL || out == NULL || inLen == 0 || outLen <
|
||||
(word32)key->c_nSz)
|
||||
return -1;
|
||||
|
||||
ret = CspPkcs1v15CrtEnc(CAVIUM_BLOCKING, BT1, key->c_nSz, (word16)inLen,
|
||||
key->c_q, key->c_dQ, key->c_p, key->c_dP, key->c_u,
|
||||
(byte*)in, out, &requestId, key->devId);
|
||||
if (ret != 0) {
|
||||
CYASSL_MSG("Cavium CRT Enc BT1 failed");
|
||||
return -1;
|
||||
}
|
||||
return key->c_nSz;
|
||||
}
|
||||
|
||||
|
||||
static int CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out,
|
||||
word32 outLen, RsaKey* key)
|
||||
{
|
||||
word32 requestId;
|
||||
word32 ret;
|
||||
word16 outSz = (word16)outLen;
|
||||
|
||||
if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->c_nSz)
|
||||
return -1;
|
||||
|
||||
ret = CspPkcs1v15Dec(CAVIUM_BLOCKING, BT1, key->c_nSz, key->c_eSz,
|
||||
key->c_n, key->c_e, (byte*)in, &outSz, out,
|
||||
&requestId, key->devId);
|
||||
if (ret != 0) {
|
||||
CYASSL_MSG("Cavium Dec BT1 failed");
|
||||
return -1;
|
||||
}
|
||||
outSz = ntohs(outSz);
|
||||
|
||||
return outSz;
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_CAVIUM */
|
||||
|
||||
#endif /* NO_RSA */
|
||||
/* dummy file for autoconf */
|
||||
|
@ -1,428 +1 @@
|
||||
/* sha.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#if !defined(NO_SHA)
|
||||
|
||||
#ifdef CYASSL_PIC32MZ_HASH
|
||||
#define InitSha InitSha_sw
|
||||
#define ShaUpdate ShaUpdate_sw
|
||||
#define ShaFinal ShaFinal_sw
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FIPS
|
||||
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
|
||||
#define FIPS_NO_WRAPPERS
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/sha.h>
|
||||
#include <cyassl/ctaocrypt/logging.h>
|
||||
#include <cyassl/ctaocrypt/error-crypt.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <cyassl/ctaocrypt/misc.h>
|
||||
#else
|
||||
#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
|
||||
/*
|
||||
* STM32F2 hardware SHA1 support through the STM32F2 standard peripheral
|
||||
* library. Documentation located in STM32F2xx Standard Peripheral Library
|
||||
* document (See note in README).
|
||||
*/
|
||||
#include "stm32f2xx.h"
|
||||
#include "stm32f2xx_hash.h"
|
||||
|
||||
int InitSha(Sha* sha)
|
||||
{
|
||||
/* STM32F2 struct notes:
|
||||
* sha->buffer = first 4 bytes used to hold partial block if needed
|
||||
* sha->buffLen = num bytes currently stored in sha->buffer
|
||||
* sha->loLen = num bytes that have been written to STM32 FIFO
|
||||
*/
|
||||
XMEMSET(sha->buffer, 0, SHA_REG_SIZE);
|
||||
sha->buffLen = 0;
|
||||
sha->loLen = 0;
|
||||
|
||||
/* initialize HASH peripheral */
|
||||
HASH_DeInit();
|
||||
|
||||
/* configure algo used, algo mode, datatype */
|
||||
HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
|
||||
HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HASH
|
||||
| HASH_DataType_8b);
|
||||
|
||||
/* reset HASH processor */
|
||||
HASH->CR |= HASH_CR_INIT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ShaUpdate(Sha* sha, const byte* data, word32 len)
|
||||
{
|
||||
word32 i = 0;
|
||||
word32 fill = 0;
|
||||
word32 diff = 0;
|
||||
|
||||
/* if saved partial block is available */
|
||||
if (sha->buffLen) {
|
||||
fill = 4 - sha->buffLen;
|
||||
|
||||
/* if enough data to fill, fill and push to FIFO */
|
||||
if (fill <= len) {
|
||||
XMEMCPY((byte*)sha->buffer + sha->buffLen, data, fill);
|
||||
HASH_DataIn(*(uint32_t*)sha->buffer);
|
||||
|
||||
data += fill;
|
||||
len -= fill;
|
||||
sha->loLen += 4;
|
||||
sha->buffLen = 0;
|
||||
} else {
|
||||
/* append partial to existing stored block */
|
||||
XMEMCPY((byte*)sha->buffer + sha->buffLen, data, len);
|
||||
sha->buffLen += len;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* write input block in the IN FIFO */
|
||||
for(i = 0; i < len; i += 4)
|
||||
{
|
||||
diff = len - i;
|
||||
if ( diff < 4) {
|
||||
/* store incomplete last block, not yet in FIFO */
|
||||
XMEMSET(sha->buffer, 0, SHA_REG_SIZE);
|
||||
XMEMCPY((byte*)sha->buffer, data, diff);
|
||||
sha->buffLen = diff;
|
||||
} else {
|
||||
HASH_DataIn(*(uint32_t*)data);
|
||||
data+=4;
|
||||
}
|
||||
}
|
||||
|
||||
/* keep track of total data length thus far */
|
||||
sha->loLen += (len - sha->buffLen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ShaFinal(Sha* sha, byte* hash)
|
||||
{
|
||||
__IO uint16_t nbvalidbitsdata = 0;
|
||||
|
||||
/* finish reading any trailing bytes into FIFO */
|
||||
if (sha->buffLen) {
|
||||
HASH_DataIn(*(uint32_t*)sha->buffer);
|
||||
sha->loLen += sha->buffLen;
|
||||
}
|
||||
|
||||
/* calculate number of valid bits in last word of input data */
|
||||
nbvalidbitsdata = 8 * (sha->loLen % SHA_REG_SIZE);
|
||||
|
||||
/* configure number of valid bits in last word of the data */
|
||||
HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
|
||||
|
||||
/* start HASH processor */
|
||||
HASH_StartDigest();
|
||||
|
||||
/* wait until Busy flag == RESET */
|
||||
while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {}
|
||||
|
||||
/* read message digest */
|
||||
sha->digest[0] = HASH->HR[0];
|
||||
sha->digest[1] = HASH->HR[1];
|
||||
sha->digest[2] = HASH->HR[2];
|
||||
sha->digest[3] = HASH->HR[3];
|
||||
sha->digest[4] = HASH->HR[4];
|
||||
|
||||
ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
|
||||
|
||||
XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE);
|
||||
|
||||
return InitSha(sha); /* reset state */
|
||||
}
|
||||
|
||||
#else /* CTaoCrypt software implementation */
|
||||
|
||||
#ifndef min
|
||||
|
||||
static INLINE word32 min(word32 a, word32 b)
|
||||
{
|
||||
return a > b ? b : a;
|
||||
}
|
||||
|
||||
#endif /* min */
|
||||
|
||||
|
||||
int InitSha(Sha* sha)
|
||||
{
|
||||
#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;
|
||||
|
||||
return 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))
|
||||
|
||||
#define f1(x,y,z) ((z)^((x) &((y)^(z))))
|
||||
#define f2(x,y,z) ((x)^(y)^(z))
|
||||
#define f3(x,y,z) (((x)&(y))|((z)&((x)|(y))))
|
||||
#define f4(x,y,z) ((x)^(y)^(z))
|
||||
|
||||
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
||||
#define R0(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk0((i)) + 0x5A827999+ \
|
||||
rotlFixed((v),5); (w) = rotlFixed((w),30);
|
||||
#define R1(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk1((i)) + 0x5A827999+ \
|
||||
rotlFixed((v),5); (w) = rotlFixed((w),30);
|
||||
#define R2(v,w,x,y,z,i) (z)+= f2((w),(x),(y)) + blk1((i)) + 0x6ED9EBA1+ \
|
||||
rotlFixed((v),5); (w) = rotlFixed((w),30);
|
||||
#define R3(v,w,x,y,z,i) (z)+= f3((w),(x),(y)) + blk1((i)) + 0x8F1BBCDC+ \
|
||||
rotlFixed((v),5); (w) = rotlFixed((w),30);
|
||||
#define R4(v,w,x,y,z,i) (z)+= f4((w),(x),(y)) + blk1((i)) + 0xCA62C1D6+ \
|
||||
rotlFixed((v),5); (w) = rotlFixed((w),30);
|
||||
|
||||
static void Transform(Sha* sha)
|
||||
{
|
||||
word32 W[SHA_BLOCK_SIZE / sizeof(word32)];
|
||||
|
||||
/* Copy context->state[] to working vars */
|
||||
word32 a = sha->digest[0];
|
||||
word32 b = sha->digest[1];
|
||||
word32 c = sha->digest[2];
|
||||
word32 d = sha->digest[3];
|
||||
word32 e = sha->digest[4];
|
||||
|
||||
#ifdef USE_SLOW_SHA
|
||||
word32 t, i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
R0(a, b, c, d, e, i);
|
||||
t = e; e = d; d = c; c = b; b = a; a = t;
|
||||
}
|
||||
|
||||
for (; i < 20; i++) {
|
||||
R1(a, b, c, d, e, i);
|
||||
t = e; e = d; d = c; c = b; b = a; a = t;
|
||||
}
|
||||
|
||||
for (; i < 40; i++) {
|
||||
R2(a, b, c, d, e, i);
|
||||
t = e; e = d; d = c; c = b; b = a; a = t;
|
||||
}
|
||||
|
||||
for (; i < 60; i++) {
|
||||
R3(a, b, c, d, e, i);
|
||||
t = e; e = d; d = c; c = b; b = a; a = t;
|
||||
}
|
||||
|
||||
for (; i < 80; i++) {
|
||||
R4(a, b, c, d, e, i);
|
||||
t = e; e = d; d = c; c = b; b = a; a = t;
|
||||
}
|
||||
#else
|
||||
/* nearly 1 K bigger in code size but 25% faster */
|
||||
/* 4 rounds of 20 operations each. Loop unrolled. */
|
||||
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
||||
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
||||
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
||||
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
|
||||
|
||||
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
|
||||
|
||||
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
|
||||
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
|
||||
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
|
||||
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
|
||||
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
|
||||
|
||||
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
|
||||
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
|
||||
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
|
||||
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
|
||||
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
|
||||
|
||||
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
|
||||
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
|
||||
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
||||
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
||||
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
||||
#endif
|
||||
|
||||
/* Add the working vars back into digest state[] */
|
||||
sha->digest[0] += a;
|
||||
sha->digest[1] += b;
|
||||
sha->digest[2] += c;
|
||||
sha->digest[3] += d;
|
||||
sha->digest[4] += e;
|
||||
}
|
||||
|
||||
#endif /* FREESCALE_MMCAU */
|
||||
|
||||
|
||||
static INLINE void AddLength(Sha* sha, word32 len)
|
||||
{
|
||||
word32 tmp = sha->loLen;
|
||||
if ( (sha->loLen += len) < tmp)
|
||||
sha->hiLen++; /* carry low to high */
|
||||
}
|
||||
|
||||
|
||||
int ShaUpdate(Sha* sha, const byte* data, word32 len)
|
||||
{
|
||||
/* do block size increments */
|
||||
byte* local = (byte*)sha->buffer;
|
||||
|
||||
while (len) {
|
||||
word32 add = min(len, SHA_BLOCK_SIZE - sha->buffLen);
|
||||
XMEMCPY(&local[sha->buffLen], data, add);
|
||||
|
||||
sha->buffLen += add;
|
||||
data += add;
|
||||
len -= add;
|
||||
|
||||
if (sha->buffLen == SHA_BLOCK_SIZE) {
|
||||
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||
ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE);
|
||||
#endif
|
||||
XTRANSFORM(sha, local);
|
||||
AddLength(sha, SHA_BLOCK_SIZE);
|
||||
sha->buffLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ShaFinal(Sha* sha, byte* hash)
|
||||
{
|
||||
byte* local = (byte*)sha->buffer;
|
||||
|
||||
AddLength(sha, sha->buffLen); /* before adding pads */
|
||||
|
||||
local[sha->buffLen++] = 0x80; /* add 1 */
|
||||
|
||||
/* pad with zeros */
|
||||
if (sha->buffLen > SHA_PAD_SIZE) {
|
||||
XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen);
|
||||
sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen;
|
||||
|
||||
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||
ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE);
|
||||
#endif
|
||||
XTRANSFORM(sha, local);
|
||||
sha->buffLen = 0;
|
||||
}
|
||||
XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen);
|
||||
|
||||
/* put lengths in bits */
|
||||
sha->hiLen = (sha->loLen >> (8*sizeof(sha->loLen) - 3)) +
|
||||
(sha->hiLen << 3);
|
||||
sha->loLen = sha->loLen << 3;
|
||||
|
||||
/* store lengths */
|
||||
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||
ByteReverseWords(sha->buffer, sha->buffer, 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));
|
||||
|
||||
#ifdef FREESCALE_MMCAU
|
||||
/* Kinetis requires only these bytes reversed */
|
||||
ByteReverseWords(&sha->buffer[SHA_PAD_SIZE/sizeof(word32)],
|
||||
&sha->buffer[SHA_PAD_SIZE/sizeof(word32)],
|
||||
2 * sizeof(word32));
|
||||
#endif
|
||||
|
||||
XTRANSFORM(sha, local);
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
|
||||
#endif
|
||||
XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE);
|
||||
|
||||
return InitSha(sha); /* reset state */
|
||||
}
|
||||
|
||||
#endif /* STM32F2_HASH */
|
||||
|
||||
|
||||
int ShaHash(const byte* data, word32 len, byte* hash)
|
||||
{
|
||||
int ret = 0;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
Sha* sha;
|
||||
#else
|
||||
Sha sha[1];
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (sha == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
if ((ret = InitSha(sha)) != 0) {
|
||||
CYASSL_MSG("InitSha failed");
|
||||
}
|
||||
else {
|
||||
ShaUpdate(sha, data, len);
|
||||
ShaFinal(sha, hash);
|
||||
}
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* NO_SHA */
|
||||
/* dummy file for autoconf */
|
||||
|
@ -1,322 +1 @@
|
||||
/* sha256.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
/* code submitted by raphael.huck@efixo.com */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#if !defined(NO_SHA256)
|
||||
|
||||
#ifdef CYASSL_PIC32MZ_HASH
|
||||
#define InitSha256 InitSha256_sw
|
||||
#define Sha256Update Sha256Update_sw
|
||||
#define Sha256Final Sha256Final_sw
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FIPS
|
||||
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
|
||||
#define FIPS_NO_WRAPPERS
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/sha256.h>
|
||||
#include <cyassl/ctaocrypt/logging.h>
|
||||
#include <cyassl/ctaocrypt/error-crypt.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <cyassl/ctaocrypt/misc.h>
|
||||
#else
|
||||
#include <ctaocrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
#ifdef FREESCALE_MMCAU
|
||||
#include "cau_api.h"
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
|
||||
static INLINE word32 min(word32 a, word32 b)
|
||||
{
|
||||
return a > b ? b : a;
|
||||
}
|
||||
|
||||
#endif /* min */
|
||||
|
||||
|
||||
int InitSha256(Sha256* sha256)
|
||||
{
|
||||
#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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef FREESCALE_MMCAU
|
||||
#define XTRANSFORM(S,B) Transform((S), (B))
|
||||
|
||||
static int Transform(Sha256* sha256, byte* buf)
|
||||
{
|
||||
cau_sha256_hash_n(buf, 1, sha256->digest);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define XTRANSFORM(S,B) Transform((S))
|
||||
|
||||
static const word32 K[64] = {
|
||||
0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL,
|
||||
0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L,
|
||||
0x243185BEL, 0x550C7DC3L, 0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L,
|
||||
0xC19BF174L, 0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL,
|
||||
0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL, 0x983E5152L,
|
||||
0xA831C66DL, 0xB00327C8L, 0xBF597FC7L, 0xC6E00BF3L, 0xD5A79147L,
|
||||
0x06CA6351L, 0x14292967L, 0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL,
|
||||
0x53380D13L, 0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L,
|
||||
0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L, 0xD192E819L,
|
||||
0xD6990624L, 0xF40E3585L, 0x106AA070L, 0x19A4C116L, 0x1E376C08L,
|
||||
0x2748774CL, 0x34B0BCB5L, 0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL,
|
||||
0x682E6FF3L, 0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L,
|
||||
0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L
|
||||
};
|
||||
|
||||
#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define Maj(x,y,z) ((((x) | (y)) & (z)) | ((x) & (y)))
|
||||
#define S(x, n) rotrFixed(x, n)
|
||||
#define R(x, n) (((x)&0xFFFFFFFFU)>>(n))
|
||||
#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
|
||||
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
|
||||
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
|
||||
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
|
||||
|
||||
#define RND(a,b,c,d,e,f,g,h,i) \
|
||||
t0 = (h) + Sigma1((e)) + Ch((e), (f), (g)) + K[(i)] + W[(i)]; \
|
||||
t1 = Sigma0((a)) + Maj((a), (b), (c)); \
|
||||
(d) += t0; \
|
||||
(h) = t0 + t1;
|
||||
|
||||
|
||||
static int Transform(Sha256* sha256)
|
||||
{
|
||||
word32 S[8], t0, t1;
|
||||
int i;
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
word32* W;
|
||||
|
||||
W = (word32*) XMALLOC(sizeof(word32) * 64, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (W == NULL)
|
||||
return MEMORY_E;
|
||||
#else
|
||||
word32 W[64];
|
||||
#endif
|
||||
|
||||
/* Copy context->state[] to working vars */
|
||||
for (i = 0; i < 8; i++)
|
||||
S[i] = sha256->digest[i];
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
W[i] = sha256->buffer[i];
|
||||
|
||||
for (i = 16; i < 64; i++)
|
||||
W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16];
|
||||
|
||||
for (i = 0; i < 64; i += 8) {
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
|
||||
}
|
||||
|
||||
/* Add the working vars back into digest state[] */
|
||||
for (i = 0; i < 8; i++) {
|
||||
sha256->digest[i] += S[i];
|
||||
}
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* FREESCALE_MMCAU */
|
||||
|
||||
|
||||
static INLINE void AddLength(Sha256* sha256, word32 len)
|
||||
{
|
||||
word32 tmp = sha256->loLen;
|
||||
if ( (sha256->loLen += len) < tmp)
|
||||
sha256->hiLen++; /* carry low to high */
|
||||
}
|
||||
|
||||
|
||||
int Sha256Update(Sha256* sha256, const byte* data, word32 len)
|
||||
{
|
||||
/* do block size increments */
|
||||
byte* local = (byte*)sha256->buffer;
|
||||
|
||||
while (len) {
|
||||
word32 add = min(len, SHA256_BLOCK_SIZE - sha256->buffLen);
|
||||
XMEMCPY(&local[sha256->buffLen], data, add);
|
||||
|
||||
sha256->buffLen += add;
|
||||
data += add;
|
||||
len -= add;
|
||||
|
||||
if (sha256->buffLen == SHA256_BLOCK_SIZE) {
|
||||
int ret;
|
||||
|
||||
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||
ByteReverseWords(sha256->buffer, sha256->buffer,
|
||||
SHA256_BLOCK_SIZE);
|
||||
#endif
|
||||
|
||||
ret = XTRANSFORM(sha256, local);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
AddLength(sha256, SHA256_BLOCK_SIZE);
|
||||
sha256->buffLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Sha256Final(Sha256* sha256, byte* hash)
|
||||
{
|
||||
byte* local = (byte*)sha256->buffer;
|
||||
int ret;
|
||||
|
||||
AddLength(sha256, sha256->buffLen); /* before adding pads */
|
||||
|
||||
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;
|
||||
|
||||
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||
ByteReverseWords(sha256->buffer, sha256->buffer, SHA256_BLOCK_SIZE);
|
||||
#endif
|
||||
|
||||
ret = XTRANSFORM(sha256, local);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
sha256->buffLen = 0;
|
||||
}
|
||||
XMEMSET(&local[sha256->buffLen], 0, SHA256_PAD_SIZE - sha256->buffLen);
|
||||
|
||||
/* put lengths in bits */
|
||||
sha256->hiLen = (sha256->loLen >> (8*sizeof(sha256->loLen) - 3)) +
|
||||
(sha256->hiLen << 3);
|
||||
sha256->loLen = sha256->loLen << 3;
|
||||
|
||||
/* store lengths */
|
||||
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
|
||||
ByteReverseWords(sha256->buffer, sha256->buffer, SHA256_BLOCK_SIZE);
|
||||
#endif
|
||||
/* ! length ordering dependent on digest endian type ! */
|
||||
XMEMCPY(&local[SHA256_PAD_SIZE], &sha256->hiLen, sizeof(word32));
|
||||
XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen,
|
||||
sizeof(word32));
|
||||
|
||||
#ifdef FREESCALE_MMCAU
|
||||
/* Kinetis requires only these bytes reversed */
|
||||
ByteReverseWords(&sha256->buffer[SHA256_PAD_SIZE/sizeof(word32)],
|
||||
&sha256->buffer[SHA256_PAD_SIZE/sizeof(word32)],
|
||||
2 * sizeof(word32));
|
||||
#endif
|
||||
|
||||
ret = XTRANSFORM(sha256, local);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE);
|
||||
#endif
|
||||
XMEMCPY(hash, sha256->digest, SHA256_DIGEST_SIZE);
|
||||
|
||||
return InitSha256(sha256); /* reset state */
|
||||
}
|
||||
|
||||
|
||||
int Sha256Hash(const byte* data, word32 len, byte* hash)
|
||||
{
|
||||
int ret = 0;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
Sha256* sha256;
|
||||
#else
|
||||
Sha256 sha256[1];
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (sha256 == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
if ((ret = InitSha256(sha256)) != 0) {
|
||||
CYASSL_MSG("InitSha256 failed");
|
||||
}
|
||||
else if ((ret = Sha256Update(sha256, data, len)) != 0) {
|
||||
CYASSL_MSG("Sha256Update failed");
|
||||
}
|
||||
else if ((ret = Sha256Final(sha256, hash)) != 0) {
|
||||
CYASSL_MSG("Sha256Final failed");
|
||||
}
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif /* NO_SHA256 */
|
||||
|
||||
/* dummy file for autoconf */
|
||||
|
@ -1,542 +1 @@
|
||||
/* sha512.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#ifdef CYASSL_SHA512
|
||||
|
||||
#ifdef HAVE_FIPS
|
||||
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
|
||||
#define FIPS_NO_WRAPPERS
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/sha512.h>
|
||||
#include <cyassl/ctaocrypt/logging.h>
|
||||
#include <cyassl/ctaocrypt/error-crypt.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <cyassl/ctaocrypt/misc.h>
|
||||
#else
|
||||
#include <ctaocrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef min
|
||||
|
||||
static INLINE word32 min(word32 a, word32 b)
|
||||
{
|
||||
return a > b ? b : a;
|
||||
}
|
||||
|
||||
#endif /* min */
|
||||
|
||||
|
||||
int InitSha512(Sha512* sha512)
|
||||
{
|
||||
sha512->digest[0] = W64LIT(0x6a09e667f3bcc908);
|
||||
sha512->digest[1] = W64LIT(0xbb67ae8584caa73b);
|
||||
sha512->digest[2] = W64LIT(0x3c6ef372fe94f82b);
|
||||
sha512->digest[3] = W64LIT(0xa54ff53a5f1d36f1);
|
||||
sha512->digest[4] = W64LIT(0x510e527fade682d1);
|
||||
sha512->digest[5] = W64LIT(0x9b05688c2b3e6c1f);
|
||||
sha512->digest[6] = W64LIT(0x1f83d9abfb41bd6b);
|
||||
sha512->digest[7] = W64LIT(0x5be0cd19137e2179);
|
||||
|
||||
sha512->buffLen = 0;
|
||||
sha512->loLen = 0;
|
||||
sha512->hiLen = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const word64 K512[80] = {
|
||||
W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
|
||||
W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
|
||||
W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
|
||||
W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
|
||||
W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
|
||||
W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
|
||||
W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
|
||||
W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
|
||||
W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
|
||||
W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
|
||||
W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
|
||||
W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
|
||||
W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
|
||||
W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
|
||||
W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
|
||||
W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
|
||||
W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
|
||||
W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
|
||||
W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
|
||||
W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
|
||||
W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
|
||||
W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
|
||||
W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
|
||||
W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
|
||||
W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
|
||||
W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
|
||||
W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
|
||||
W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
|
||||
W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
|
||||
W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
|
||||
W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
|
||||
W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
|
||||
W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
|
||||
W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
|
||||
W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
|
||||
W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
|
||||
W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
|
||||
W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
|
||||
W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
|
||||
W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
|
||||
};
|
||||
|
||||
|
||||
#define blk0(i) (W[i] = sha512->buffer[i])
|
||||
#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
|
||||
|
||||
#define Ch(x,y,z) (z^(x&(y^z)))
|
||||
#define Maj(x,y,z) ((x&y)|(z&(x|y)))
|
||||
|
||||
#define a(i) T[(0-i)&7]
|
||||
#define b(i) T[(1-i)&7]
|
||||
#define c(i) T[(2-i)&7]
|
||||
#define d(i) T[(3-i)&7]
|
||||
#define e(i) T[(4-i)&7]
|
||||
#define f(i) T[(5-i)&7]
|
||||
#define g(i) T[(6-i)&7]
|
||||
#define h(i) T[(7-i)&7]
|
||||
|
||||
#define S0(x) (rotrFixed64(x,28)^rotrFixed64(x,34)^rotrFixed64(x,39))
|
||||
#define S1(x) (rotrFixed64(x,14)^rotrFixed64(x,18)^rotrFixed64(x,41))
|
||||
#define s0(x) (rotrFixed64(x,1)^rotrFixed64(x,8)^(x>>7))
|
||||
#define s1(x) (rotrFixed64(x,19)^rotrFixed64(x,61)^(x>>6))
|
||||
|
||||
#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j]+(j?blk2(i):blk0(i));\
|
||||
d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
|
||||
|
||||
#define blk384(i) (W[i] = sha384->buffer[i])
|
||||
|
||||
#define R2(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j]+(j?blk2(i):blk384(i));\
|
||||
d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
|
||||
|
||||
|
||||
static int Transform(Sha512* sha512)
|
||||
{
|
||||
const word64* K = K512;
|
||||
|
||||
word32 j;
|
||||
word64 T[8];
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
word64* W;
|
||||
|
||||
W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (W == NULL)
|
||||
return MEMORY_E;
|
||||
#else
|
||||
word64 W[16];
|
||||
#endif
|
||||
|
||||
/* Copy digest to working vars */
|
||||
XMEMCPY(T, sha512->digest, sizeof(T));
|
||||
|
||||
#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 */
|
||||
|
||||
sha512->digest[0] += a(0);
|
||||
sha512->digest[1] += b(0);
|
||||
sha512->digest[2] += c(0);
|
||||
sha512->digest[3] += d(0);
|
||||
sha512->digest[4] += e(0);
|
||||
sha512->digest[5] += f(0);
|
||||
sha512->digest[6] += g(0);
|
||||
sha512->digest[7] += h(0);
|
||||
|
||||
/* Wipe variables */
|
||||
XMEMSET(W, 0, sizeof(word64) * 16);
|
||||
XMEMSET(T, 0, sizeof(T));
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void AddLength(Sha512* sha512, word32 len)
|
||||
{
|
||||
word32 tmp = sha512->loLen;
|
||||
if ( (sha512->loLen += len) < tmp)
|
||||
sha512->hiLen++; /* carry low to high */
|
||||
}
|
||||
|
||||
|
||||
int Sha512Update(Sha512* sha512, const byte* data, word32 len)
|
||||
{
|
||||
/* do block size increments */
|
||||
byte* local = (byte*)sha512->buffer;
|
||||
|
||||
while (len) {
|
||||
word32 add = min(len, SHA512_BLOCK_SIZE - sha512->buffLen);
|
||||
XMEMCPY(&local[sha512->buffLen], data, add);
|
||||
|
||||
sha512->buffLen += add;
|
||||
data += add;
|
||||
len -= add;
|
||||
|
||||
if (sha512->buffLen == SHA512_BLOCK_SIZE) {
|
||||
int ret;
|
||||
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(sha512->buffer, sha512->buffer,
|
||||
SHA512_BLOCK_SIZE);
|
||||
#endif
|
||||
ret = Transform(sha512);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
AddLength(sha512, SHA512_BLOCK_SIZE);
|
||||
sha512->buffLen = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Sha512Final(Sha512* sha512, byte* hash)
|
||||
{
|
||||
byte* local = (byte*)sha512->buffer;
|
||||
int ret;
|
||||
|
||||
AddLength(sha512, sha512->buffLen); /* before adding pads */
|
||||
|
||||
local[sha512->buffLen++] = 0x80; /* add 1 */
|
||||
|
||||
/* pad with zeros */
|
||||
if (sha512->buffLen > SHA512_PAD_SIZE) {
|
||||
XMEMSET(&local[sha512->buffLen], 0, SHA512_BLOCK_SIZE -sha512->buffLen);
|
||||
sha512->buffLen += SHA512_BLOCK_SIZE - sha512->buffLen;
|
||||
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(sha512->buffer,sha512->buffer,SHA512_BLOCK_SIZE);
|
||||
#endif
|
||||
ret = Transform(sha512);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
sha512->buffLen = 0;
|
||||
}
|
||||
XMEMSET(&local[sha512->buffLen], 0, SHA512_PAD_SIZE - sha512->buffLen);
|
||||
|
||||
/* put lengths in bits */
|
||||
sha512->hiLen = (sha512->loLen >> (8*sizeof(sha512->loLen) - 3)) +
|
||||
(sha512->hiLen << 3);
|
||||
sha512->loLen = sha512->loLen << 3;
|
||||
|
||||
/* store lengths */
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(sha512->buffer, sha512->buffer, SHA512_PAD_SIZE);
|
||||
#endif
|
||||
/* ! length ordering dependent on digest endian type ! */
|
||||
sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen;
|
||||
sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen;
|
||||
|
||||
ret = Transform(sha512);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(sha512->digest, sha512->digest, SHA512_DIGEST_SIZE);
|
||||
#endif
|
||||
XMEMCPY(hash, sha512->digest, SHA512_DIGEST_SIZE);
|
||||
|
||||
return InitSha512(sha512); /* reset state */
|
||||
}
|
||||
|
||||
|
||||
int Sha512Hash(const byte* data, word32 len, byte* hash)
|
||||
{
|
||||
int ret = 0;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
Sha512* sha512;
|
||||
#else
|
||||
Sha512 sha512[1];
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (sha512 == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
if ((ret = InitSha512(sha512)) != 0) {
|
||||
CYASSL_MSG("InitSha512 failed");
|
||||
}
|
||||
else if ((ret = Sha512Update(sha512, data, len)) != 0) {
|
||||
CYASSL_MSG("Sha512Update failed");
|
||||
}
|
||||
else if ((ret = Sha512Final(sha512, hash)) != 0) {
|
||||
CYASSL_MSG("Sha512Final failed");
|
||||
}
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(sha512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CYASSL_SHA384
|
||||
|
||||
int InitSha384(Sha384* sha384)
|
||||
{
|
||||
sha384->digest[0] = W64LIT(0xcbbb9d5dc1059ed8);
|
||||
sha384->digest[1] = W64LIT(0x629a292a367cd507);
|
||||
sha384->digest[2] = W64LIT(0x9159015a3070dd17);
|
||||
sha384->digest[3] = W64LIT(0x152fecd8f70e5939);
|
||||
sha384->digest[4] = W64LIT(0x67332667ffc00b31);
|
||||
sha384->digest[5] = W64LIT(0x8eb44a8768581511);
|
||||
sha384->digest[6] = W64LIT(0xdb0c2e0d64f98fa7);
|
||||
sha384->digest[7] = W64LIT(0x47b5481dbefa4fa4);
|
||||
|
||||
sha384->buffLen = 0;
|
||||
sha384->loLen = 0;
|
||||
sha384->hiLen = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int Transform384(Sha384* sha384)
|
||||
{
|
||||
const word64* K = K512;
|
||||
|
||||
word32 j;
|
||||
word64 T[8];
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
word64* W;
|
||||
|
||||
W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (W == NULL)
|
||||
return MEMORY_E;
|
||||
#else
|
||||
word64 W[16];
|
||||
#endif
|
||||
|
||||
/* Copy digest to working vars */
|
||||
XMEMCPY(T, sha384->digest, sizeof(T));
|
||||
|
||||
#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 */
|
||||
|
||||
sha384->digest[0] += a(0);
|
||||
sha384->digest[1] += b(0);
|
||||
sha384->digest[2] += c(0);
|
||||
sha384->digest[3] += d(0);
|
||||
sha384->digest[4] += e(0);
|
||||
sha384->digest[5] += f(0);
|
||||
sha384->digest[6] += g(0);
|
||||
sha384->digest[7] += h(0);
|
||||
|
||||
/* Wipe variables */
|
||||
XMEMSET(W, 0, sizeof(word64) * 16);
|
||||
XMEMSET(T, 0, sizeof(T));
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void AddLength384(Sha384* sha384, word32 len)
|
||||
{
|
||||
word32 tmp = sha384->loLen;
|
||||
if ( (sha384->loLen += len) < tmp)
|
||||
sha384->hiLen++; /* carry low to high */
|
||||
}
|
||||
|
||||
|
||||
int Sha384Update(Sha384* sha384, const byte* data, word32 len)
|
||||
{
|
||||
/* do block size increments */
|
||||
byte* local = (byte*)sha384->buffer;
|
||||
|
||||
while (len) {
|
||||
word32 add = min(len, SHA384_BLOCK_SIZE - sha384->buffLen);
|
||||
XMEMCPY(&local[sha384->buffLen], data, add);
|
||||
|
||||
sha384->buffLen += add;
|
||||
data += add;
|
||||
len -= add;
|
||||
|
||||
if (sha384->buffLen == SHA384_BLOCK_SIZE) {
|
||||
int ret;
|
||||
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(sha384->buffer, sha384->buffer,
|
||||
SHA384_BLOCK_SIZE);
|
||||
#endif
|
||||
ret = Transform384(sha384);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
AddLength384(sha384, SHA384_BLOCK_SIZE);
|
||||
sha384->buffLen = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Sha384Final(Sha384* sha384, byte* hash)
|
||||
{
|
||||
byte* local = (byte*)sha384->buffer;
|
||||
int ret;
|
||||
|
||||
AddLength384(sha384, sha384->buffLen); /* before adding pads */
|
||||
|
||||
local[sha384->buffLen++] = 0x80; /* add 1 */
|
||||
|
||||
/* pad with zeros */
|
||||
if (sha384->buffLen > SHA384_PAD_SIZE) {
|
||||
XMEMSET(&local[sha384->buffLen], 0, SHA384_BLOCK_SIZE -sha384->buffLen);
|
||||
sha384->buffLen += SHA384_BLOCK_SIZE - sha384->buffLen;
|
||||
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(sha384->buffer,sha384->buffer,SHA384_BLOCK_SIZE);
|
||||
#endif
|
||||
ret = Transform384(sha384);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
sha384->buffLen = 0;
|
||||
}
|
||||
XMEMSET(&local[sha384->buffLen], 0, SHA384_PAD_SIZE - sha384->buffLen);
|
||||
|
||||
/* put lengths in bits */
|
||||
sha384->hiLen = (sha384->loLen >> (8*sizeof(sha384->loLen) - 3)) +
|
||||
(sha384->hiLen << 3);
|
||||
sha384->loLen = sha384->loLen << 3;
|
||||
|
||||
/* store lengths */
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(sha384->buffer, sha384->buffer, SHA384_PAD_SIZE);
|
||||
#endif
|
||||
/* ! length ordering dependent on digest endian type ! */
|
||||
sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 2] = sha384->hiLen;
|
||||
sha384->buffer[SHA384_BLOCK_SIZE / sizeof(word64) - 1] = sha384->loLen;
|
||||
|
||||
ret = Transform384(sha384);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(sha384->digest, sha384->digest, SHA384_DIGEST_SIZE);
|
||||
#endif
|
||||
XMEMCPY(hash, sha384->digest, SHA384_DIGEST_SIZE);
|
||||
|
||||
return InitSha384(sha384); /* reset state */
|
||||
}
|
||||
|
||||
|
||||
int Sha384Hash(const byte* data, word32 len, byte* hash)
|
||||
{
|
||||
int ret = 0;
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
Sha384* sha384;
|
||||
#else
|
||||
Sha384 sha384[1];
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (sha384 == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
if ((ret = InitSha384(sha384)) != 0) {
|
||||
CYASSL_MSG("InitSha384 failed");
|
||||
}
|
||||
else if ((ret = Sha384Update(sha384, data, len)) != 0) {
|
||||
CYASSL_MSG("Sha384Update failed");
|
||||
}
|
||||
else if ((ret = Sha384Final(sha384, hash)) != 0) {
|
||||
CYASSL_MSG("Sha384Final failed");
|
||||
}
|
||||
|
||||
#ifdef CYASSL_SMALL_STACK
|
||||
XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CYASSL_SHA384 */
|
||||
|
||||
#endif /* CYASSL_SHA512 */
|
||||
/* dummy file for autoconf */
|
||||
|
@ -28,6 +28,12 @@
|
||||
|
||||
/* for reverse compatibility after name change */
|
||||
#include <cyassl/ctaocrypt/settings_comp.h>
|
||||
#if defined(WOLFSSL_LEANPSK) && !defined(CYASSL_LEANPSK)
|
||||
#define CYASSL_LEANPSK
|
||||
#endif
|
||||
#if defined(NO_WOLFSSL_MEMORY) && !defined(NO_CYASSL_MEMORY)
|
||||
#define NO_CYASSL_MEMORY
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -680,8 +686,9 @@
|
||||
#endif /* CYASSL_QL */
|
||||
|
||||
|
||||
#if !defined(USE_CYASSL_MEMORY) && defined(USE_WOLFSSL_MEMORY)
|
||||
#define USE_CYASSL_MEMORY USE_WOLFSSL_MEMORY
|
||||
#if !defined(XMALLOC_USER) && !defined(MICRIUM_MALLOC) && \
|
||||
!defined(CYASSL_LEANPSK) && !defined(NO_CYASSL_MEMORY)
|
||||
#define USE_CYASSL_MEMORY
|
||||
#endif
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user