add cavium RSA to ctaocrypt

This commit is contained in:
Todd Ouska 2013-01-31 15:55:29 -08:00
parent d799898a36
commit 01703281cc
6 changed files with 347 additions and 4 deletions

View File

@ -650,6 +650,10 @@ void bench_rsa(void)
bytes = fread(tmp, 1, sizeof(tmp), file); bytes = fread(tmp, 1, sizeof(tmp), file);
#endif /* USE_CERT_BUFFERS */ #endif /* USE_CERT_BUFFERS */
#ifdef HAVE_CAVIUM
if (RsaInitCavium(&rsaKey, CAVIUM_DEV_ID) != 0)
printf("RSA init cavium failed\n");
#endif
InitRng(&rng); InitRng(&rng);
InitRsaKey(&rsaKey, 0); InitRsaKey(&rsaKey, 0);
bytes = RsaPrivateKeyDecode(tmp, &idx, &rsaKey, (word32)bytes); bytes = RsaPrivateKeyDecode(tmp, &idx, &rsaKey, (word32)bytes);
@ -684,6 +688,9 @@ void bench_rsa(void)
fclose(file); fclose(file);
#endif #endif
FreeRsaKey(&rsaKey); FreeRsaKey(&rsaKey);
#ifdef HAVE_CAVIUM
RsaFreeCavium(&rsaKey);
#endif
} }
#endif #endif

View File

@ -531,11 +531,78 @@ static int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
#ifndef NO_RSA #ifndef NO_RSA
#ifdef HAVE_CAVIUM
static int GetCaviumInt(byte** buff, word16* buffSz, const byte* input,
word32* inOutIdx, word32 maxIdx, void* heap)
{
word32 i = *inOutIdx;
byte b = input[i++];
int length;
if (b != ASN_INTEGER)
return ASN_PARSE_E;
if (GetLength(input, &i, &length, maxIdx) < 0)
return ASN_PARSE_E;
if ( (b = input[i++]) == 0x00)
length--;
else
i--;
*buffSz = (word16)length;
*buff = XMALLOC(*buffSz, heap, DYNAMIC_TYPE_CAVIUM_RSA);
if (*buff == NULL)
return MEMORY_E;
XMEMCPY(*buff, input + i, *buffSz);
*inOutIdx = i + length;
return 0;
}
static int CaviumRsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
RsaKey* key, word32 inSz)
{
int version, length;
void* h = key->heap;
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E;
if (GetMyVersion(input, inOutIdx, &version) < 0)
return ASN_PARSE_E;
key->type = RSA_PRIVATE;
if (GetCaviumInt(&key->c_n, &key->c_nSz, input, inOutIdx, inSz, h) < 0 ||
GetCaviumInt(&key->c_e, &key->c_eSz, input, inOutIdx, inSz, h) < 0 ||
GetCaviumInt(&key->c_d, &key->c_dSz, input, inOutIdx, inSz, h) < 0 ||
GetCaviumInt(&key->c_p, &key->c_pSz, input, inOutIdx, inSz, h) < 0 ||
GetCaviumInt(&key->c_q, &key->c_qSz, input, inOutIdx, inSz, h) < 0 ||
GetCaviumInt(&key->c_dP, &key->c_dP_Sz, input, inOutIdx, inSz, h) < 0 ||
GetCaviumInt(&key->c_dQ, &key->c_dQ_Sz, input, inOutIdx, inSz, h) < 0 ||
GetCaviumInt(&key->c_u, &key->c_uSz, input, inOutIdx, inSz, h) < 0 )
return ASN_RSA_KEY_E;
return 0;
}
#endif /* HAVE_CAVIUM */
int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
word32 inSz) word32 inSz)
{ {
int version, length; int version, length;
#ifdef HAVE_CAVIUM
if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
return CaviumRsaPrivateKeyDecode(input, inOutIdx, key, inSz);
#endif
if (GetSequence(input, inOutIdx, &length, inSz) < 0) if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E; return ASN_PARSE_E;

View File

@ -39,6 +39,18 @@
#endif #endif
#endif #endif
#ifdef HAVE_CAVIUM
static void InitCaviumRsaKey(RsaKey* key, void* heap);
static void 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 { enum {
RSA_PUBLIC_ENCRYPT = 0, RSA_PUBLIC_ENCRYPT = 0,
@ -58,6 +70,11 @@ enum {
void InitRsaKey(RsaKey* key, void* heap) void 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->type = -1; /* haven't decided yet */
key->heap = heap; key->heap = heap;
@ -75,6 +92,12 @@ void InitRsaKey(RsaKey* key, void* heap)
void FreeRsaKey(RsaKey* key) void FreeRsaKey(RsaKey* key)
{ {
(void)key; (void)key;
#ifdef HAVE_CAVIUM
if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
return FreeCaviumRsaKey(key);
#endif
/* TomsFastMath doesn't use memory allocation */ /* TomsFastMath doesn't use memory allocation */
#ifndef USE_FAST_MATH #ifndef USE_FAST_MATH
if (key->type == RSA_PRIVATE) { if (key->type == RSA_PRIVATE) {
@ -249,8 +272,14 @@ done:
int RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen, int RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
RsaKey* key, RNG* rng) RsaKey* key, RNG* rng)
{ {
int sz = mp_unsigned_bin_size(&key->n), ret; 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) if (sz > (int)outLen)
return RSA_BUFFER_E; return RSA_BUFFER_E;
@ -270,6 +299,15 @@ int RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
{ {
int plainLen, ret; int plainLen, 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)) if ((ret = RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key))
< 0) { < 0) {
return ret; return ret;
@ -288,6 +326,11 @@ int RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
byte* tmp; byte* tmp;
byte* pad = 0; 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); tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA);
if (tmp == NULL) { if (tmp == NULL) {
return MEMORY_E; return MEMORY_E;
@ -316,6 +359,15 @@ int RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
{ {
int plainLen, ret; int plainLen, 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)) if ((ret = RsaFunction(in, inLen, in, &inLen, RSA_PUBLIC_DECRYPT, key))
< 0) { < 0) {
return ret; return ret;
@ -334,6 +386,11 @@ int RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
byte* tmp; byte* tmp;
byte* pad = 0; 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); tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA);
if (tmp == NULL) { if (tmp == NULL) {
return MEMORY_E; return MEMORY_E;
@ -362,8 +419,14 @@ int RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
int RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, int RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
RsaKey* key, RNG* rng) RsaKey* key, RNG* rng)
{ {
int sz = mp_unsigned_bin_size(&key->n), ret; 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) if (sz > (int)outLen)
return RSA_BUFFER_E; return RSA_BUFFER_E;
@ -381,6 +444,10 @@ int RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
int RsaEncryptSize(RsaKey* key) 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); return mp_unsigned_bin_size(&key->n);
} }
@ -561,4 +628,180 @@ int MakeRsaKey(RsaKey* key, int size, long e, RNG* rng)
#endif /* CYASSL_KEY_GEN */ #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 void InitCaviumRsaKey(RsaKey* key, void* heap)
{
if (key == NULL)
return;
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;
}
/* Free cavium RSA key */
static void FreeCaviumRsaKey(RsaKey* key)
{
if (key == NULL)
return;
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);
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 */ #endif /* NO_RSA */

View File

@ -2109,6 +2109,9 @@ int rsa_test(void)
bytes = fread(tmp, 1, FOURK_BUF, file); bytes = fread(tmp, 1, FOURK_BUF, file);
#endif /* USE_CERT_BUFFERS */ #endif /* USE_CERT_BUFFERS */
#ifdef HAVE_CAVIUM
RsaInitCavium(&key, CAVIUM_DEV_ID);
#endif
InitRsaKey(&key, 0); InitRsaKey(&key, 0);
ret = RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes); ret = RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes);
if (ret != 0) return -41; if (ret != 0) return -41;
@ -2488,6 +2491,9 @@ int rsa_test(void)
#endif /* CYASSL_CERT_GEN */ #endif /* CYASSL_CERT_GEN */
FreeRsaKey(&key); FreeRsaKey(&key);
#ifdef HAVE_CAVIUM
RsaFreeCavium(&key);
#endif
free(tmp); free(tmp);
return 0; return 0;

View File

@ -32,6 +32,7 @@
extern "C" { extern "C" {
#endif #endif
#define CYASSL_RSA_CAVIUM_MAGIC 0xBEEF0006
enum { enum {
RSA_PUBLIC = 0, RSA_PUBLIC = 0,
@ -43,6 +44,20 @@ typedef struct RsaKey {
mp_int n, e, d, p, q, dP, dQ, u; mp_int n, e, d, p, q, dP, dQ, u;
int type; /* public or private */ int type; /* public or private */
void* heap; /* for user memory overrides */ void* heap; /* for user memory overrides */
#ifdef HAVE_CAVIUM
int devId; /* nitrox device id */
word32 magic; /* using cavium magic */
word64 contextHandle; /* nitrox context memory handle */
byte* c_n; /* cavium byte buffers for key parts */
byte* c_e;
byte* c_d;
byte* c_p;
byte* c_q;
byte* c_dP;
byte* c_dQ;
byte* c_u; /* sizes in bytes */
word16 c_nSz, c_eSz, c_dSz, c_pSz, c_qSz, c_dP_Sz, c_dQ_Sz, c_uSz;
#endif
} RsaKey; } RsaKey;
@ -72,6 +87,10 @@ CYASSL_API int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey*,
CYASSL_API int RsaKeyToDer(RsaKey*, byte* output, word32 inLen); CYASSL_API int RsaKeyToDer(RsaKey*, byte* output, word32 inLen);
#endif #endif
#ifdef HAVE_CAVIUM
CYASSL_API int RsaInitCavium(RsaKey*, int);
CYASSL_API void RsaFreeCavium(RsaKey*);
#endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -230,7 +230,8 @@ enum {
DYNAMIC_TYPE_LIBZ = 36, DYNAMIC_TYPE_LIBZ = 36,
DYNAMIC_TYPE_ECC = 37, DYNAMIC_TYPE_ECC = 37,
DYNAMIC_TYPE_TMP_BUFFER = 38, DYNAMIC_TYPE_TMP_BUFFER = 38,
DYNAMIC_TYPE_CAVIUM_TMP = 40 DYNAMIC_TYPE_CAVIUM_TMP = 40,
DYNAMIC_TYPE_CAVIUM_RSA = 41
}; };
/* stack protection */ /* stack protection */