RSA fips mode

This commit is contained in:
toddouska
2014-04-01 13:08:48 -07:00
parent 348f50b4b1
commit c210600d93
11 changed files with 126 additions and 46 deletions

View File

@@ -800,7 +800,11 @@ void bench_rsa(void)
printf("InitRNG failed\n"); printf("InitRNG failed\n");
return; return;
} }
InitRsaKey(&rsaKey, 0); ret = InitRsaKey(&rsaKey, 0);
if (ret < 0) {
printf("InitRsaKey failed\n");
return;
}
ret = RsaPrivateKeyDecode(tmp, &idx, &rsaKey, (word32)bytes); ret = RsaPrivateKeyDecode(tmp, &idx, &rsaKey, (word32)bytes);
start = current_time(1); start = current_time(1);

View File

@@ -2759,7 +2759,8 @@ static int ConfirmSignature(const byte* buf, word32 bufSz,
return 0; return 0;
} }
InitRsaKey(&pubKey, heap); ret = InitRsaKey(&pubKey, heap);
if (ret != 0) return ret;
if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0) { if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0) {
CYASSL_MSG("ASN Key decode error RSA"); CYASSL_MSG("ASN Key decode error RSA");
ret = 0; ret = 0;

View File

@@ -434,7 +434,7 @@ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
attribSetSz = SetSet(flatSignedAttribsSz, attribSet); attribSetSz = SetSet(flatSignedAttribsSz, attribSet);
ret = InitSha(&esd.sha); ret = InitSha(&esd.sha);
if (result < 0) { if (ret < 0) {
XFREE(flatSignedAttribs, 0, NULL); XFREE(flatSignedAttribs, 0, NULL);
return ret; return ret;
} }
@@ -458,9 +458,10 @@ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
XMEMCPY(digestInfo + digIdx, esd.contentAttribsDigest, SHA_DIGEST_SIZE); XMEMCPY(digestInfo + digIdx, esd.contentAttribsDigest, SHA_DIGEST_SIZE);
digIdx += SHA_DIGEST_SIZE; digIdx += SHA_DIGEST_SIZE;
InitRsaKey(&privKey, NULL); result = InitRsaKey(&privKey, NULL);
result = RsaPrivateKeyDecode(pkcs7->privateKey, &scratch, &privKey, if (result == 0)
pkcs7->privateKeySz); result = RsaPrivateKeyDecode(pkcs7->privateKey, &scratch, &privKey,
pkcs7->privateKeySz);
if (result < 0) { if (result < 0) {
XFREE(flatSignedAttribs, 0, NULL); XFREE(flatSignedAttribs, 0, NULL);
return PUBLIC_KEY_E; return PUBLIC_KEY_E;
@@ -580,7 +581,7 @@ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
int PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz) int PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
{ {
word32 idx, contentType; word32 idx, contentType;
int length, version; int length, version, ret;
byte* content = NULL; byte* content = NULL;
byte* sig = NULL; byte* sig = NULL;
byte* cert = NULL; byte* cert = NULL;
@@ -781,7 +782,8 @@ int PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
pkcs7->content = content; pkcs7->content = content;
pkcs7->contentSz = contentSz; pkcs7->contentSz = contentSz;
InitRsaKey(&key, NULL); ret = InitRsaKey(&key, NULL);
if (ret != 0) return ret;
if (RsaPublicKeyDecode(pkcs7->publicKey, &scratch, &key, if (RsaPublicKeyDecode(pkcs7->publicKey, &scratch, &key,
pkcs7->publicKeySz) < 0) { pkcs7->publicKeySz) < 0) {
CYASSL_MSG("ASN RSA key decode error"); CYASSL_MSG("ASN RSA key decode error");
@@ -859,7 +861,8 @@ CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz,
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
/* EncryptedKey */ /* EncryptedKey */
InitRsaKey(&pubKey, 0); ret = InitRsaKey(&pubKey, 0);
if (ret != 0) return ret;
if (RsaPublicKeyDecode(decoded.publicKey, &idx, &pubKey, if (RsaPublicKeyDecode(decoded.publicKey, &idx, &pubKey,
decoded.pubKeySize) < 0) { decoded.pubKeySize) < 0) {
CYASSL_MSG("ASN RSA key decode error"); CYASSL_MSG("ASN RSA key decode error");
@@ -1045,7 +1048,7 @@ int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
ret = Des_SetKey(&des, contentKeyPlain, tmpIv, DES_ENCRYPTION); ret = Des_SetKey(&des, contentKeyPlain, tmpIv, DES_ENCRYPTION);
if (ret == 0) if (ret == 0)
ret = Des_CbcEncrypt(&des, encryptedContent, plain, desOutSz); Des_CbcEncrypt(&des, encryptedContent, plain, desOutSz);
if (ret != 0) { if (ret != 0) {
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
@@ -1178,7 +1181,8 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
/* load private key */ /* load private key */
InitRsaKey(&privKey, 0); ret = InitRsaKey(&privKey, 0);
if (ret != 0) return ret;
ret = RsaPrivateKeyDecode(pkcs7->privateKey, &idx, &privKey, ret = RsaPrivateKeyDecode(pkcs7->privateKey, &idx, &privKey,
pkcs7->privateKeySz); pkcs7->privateKeySz);
if (ret != 0) { if (ret != 0) {
@@ -1337,7 +1341,7 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
ret = Des_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION); ret = Des_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION);
if (ret == 0) if (ret == 0)
ret = Des_CbcDecrypt(&des, encryptedContent, encryptedContent, Des_CbcDecrypt(&des, encryptedContent, encryptedContent,
encryptedContentSz); encryptedContentSz);
if (ret != 0) { if (ret != 0) {

View File

@@ -28,6 +28,11 @@
#ifndef NO_RSA #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/rsa.h>
#include <cyassl/ctaocrypt/random.h> #include <cyassl/ctaocrypt/random.h>
#include <cyassl/ctaocrypt/error-crypt.h> #include <cyassl/ctaocrypt/error-crypt.h>
@@ -42,8 +47,8 @@
#endif #endif
#ifdef HAVE_CAVIUM #ifdef HAVE_CAVIUM
static void InitCaviumRsaKey(RsaKey* key, void* heap); static int InitCaviumRsaKey(RsaKey* key, void* heap);
static void FreeCaviumRsaKey(RsaKey* key); static int FreeCaviumRsaKey(RsaKey* key);
static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out, static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
word32 outLen, RsaKey* key); word32 outLen, RsaKey* key);
static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
@@ -70,7 +75,7 @@ enum {
}; };
void InitRsaKey(RsaKey* key, void* heap) int InitRsaKey(RsaKey* key, void* heap)
{ {
#ifdef HAVE_CAVIUM #ifdef HAVE_CAVIUM
if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
@@ -88,10 +93,12 @@ void InitRsaKey(RsaKey* key, void* heap)
key->q.dp = key->dP.dp = 0; key->q.dp = key->dP.dp = 0;
key->u.dp = key->dQ.dp = 0; key->u.dp = key->dQ.dp = 0;
#endif #endif
return 0;
} }
void FreeRsaKey(RsaKey* key) int FreeRsaKey(RsaKey* key)
{ {
(void)key; (void)key;
@@ -113,6 +120,8 @@ void FreeRsaKey(RsaKey* key)
mp_clear(&key->e); mp_clear(&key->e);
mp_clear(&key->n); mp_clear(&key->n);
#endif #endif
return 0;
} }
static void RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, static void RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
@@ -664,10 +673,10 @@ void RsaFreeCavium(RsaKey* rsa)
/* Initialize cavium RSA key */ /* Initialize cavium RSA key */
static void InitCaviumRsaKey(RsaKey* key, void* heap) static int InitCaviumRsaKey(RsaKey* key, void* heap)
{ {
if (key == NULL) if (key == NULL)
return; return BAD_FUNC_ARG;
key->heap = heap; key->heap = heap;
key->type = -1; /* don't know yet */ key->type = -1; /* don't know yet */
@@ -689,14 +698,16 @@ static void InitCaviumRsaKey(RsaKey* key, void* heap)
key->c_dP_Sz = 0; key->c_dP_Sz = 0;
key->c_dQ_Sz = 0; key->c_dQ_Sz = 0;
key->c_uSz = 0; key->c_uSz = 0;
return 0;
} }
/* Free cavium RSA key */ /* Free cavium RSA key */
static void FreeCaviumRsaKey(RsaKey* key) static int FreeCaviumRsaKey(RsaKey* key)
{ {
if (key == NULL) if (key == NULL)
return; return BAD_FUNC_ARG;
XFREE(key->c_n, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); XFREE(key->c_n, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
XFREE(key->c_e, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); XFREE(key->c_e, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
@@ -707,7 +718,7 @@ static void FreeCaviumRsaKey(RsaKey* key)
XFREE(key->c_dQ, 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); XFREE(key->c_u, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
InitCaviumRsaKey(key, key->heap); /* reset pointers */ return InitCaviumRsaKey(key, key->heap); /* reset pointers */
} }

View File

@@ -2681,7 +2681,8 @@ int rsa_test(void)
#ifdef HAVE_CAVIUM #ifdef HAVE_CAVIUM
RsaInitCavium(&key, CAVIUM_DEV_ID); RsaInitCavium(&key, CAVIUM_DEV_ID);
#endif #endif
InitRsaKey(&key, 0); ret = InitRsaKey(&key, 0);
if (ret != 0) return -39;
ret = RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes); ret = RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes);
if (ret != 0) return -41; if (ret != 0) return -41;
@@ -2751,7 +2752,8 @@ int rsa_test(void)
FILE* keyFile; FILE* keyFile;
FILE* pemFile; FILE* pemFile;
InitRsaKey(&genKey, 0); ret = InitRsaKey(&genKey, 0);
if (ret != 0) return -300;
ret = MakeRsaKey(&genKey, 1024, 65537, &rng); ret = MakeRsaKey(&genKey, 1024, 65537, &rng);
if (ret != 0) if (ret != 0)
return -301; return -301;
@@ -2783,7 +2785,8 @@ int rsa_test(void)
ret = (int)fwrite(pem, pemSz, 1, pemFile); ret = (int)fwrite(pem, pemSz, 1, pemFile);
fclose(pemFile); fclose(pemFile);
InitRsaKey(&derIn, 0); ret = InitRsaKey(&derIn, 0);
if (ret != 0) return -3060;
idx = 0; idx = 0;
ret = RsaPrivateKeyDecode(der, &idx, &derIn, derSz); ret = RsaPrivateKeyDecode(der, &idx, &derIn, derSz);
if (ret != 0) if (ret != 0)
@@ -2891,7 +2894,8 @@ int rsa_test(void)
bytes3 = fread(tmp, 1, FOURK_BUF, file3); bytes3 = fread(tmp, 1, FOURK_BUF, file3);
fclose(file3); fclose(file3);
InitRsaKey(&caKey, 0); ret = InitRsaKey(&caKey, 0);
if (ret != 0) return -411;
ret = RsaPrivateKeyDecode(tmp, &idx3, &caKey, (word32)bytes3); ret = RsaPrivateKeyDecode(tmp, &idx3, &caKey, (word32)bytes3);
if (ret != 0) return -413; if (ret != 0) return -413;
@@ -3092,7 +3096,8 @@ int rsa_test(void)
bytes = fread(tmp, 1, FOURK_BUF, caFile); bytes = fread(tmp, 1, FOURK_BUF, caFile);
fclose(caFile); fclose(caFile);
InitRsaKey(&caKey, 0); ret = InitRsaKey(&caKey, 0);
if (ret != 0) return -459;
ret = RsaPrivateKeyDecode(tmp, &idx, &caKey, (word32)bytes); ret = RsaPrivateKeyDecode(tmp, &idx, &caKey, (word32)bytes);
if (ret != 0) return -454; if (ret != 0) return -454;

View File

@@ -61,8 +61,8 @@ typedef struct RsaKey {
} RsaKey; } RsaKey;
CYASSL_API void InitRsaKey(RsaKey* key, void*); CYASSL_API int InitRsaKey(RsaKey* key, void*);
CYASSL_API void FreeRsaKey(RsaKey* key); CYASSL_API int FreeRsaKey(RsaKey* key);
CYASSL_API int RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, CYASSL_API int RsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
word32 outLen, RsaKey* key, RNG* rng); word32 outLen, RsaKey* key, RNG* rng);
@@ -93,6 +93,46 @@ CYASSL_API int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey*,
#endif #endif
#ifdef HAVE_FIPS
/* fips wrapper calls, user can call direct */
CYASSL_API int InitRsaKey_fips(RsaKey* key, void*);
CYASSL_API int FreeRsaKey_fips(RsaKey* key);
CYASSL_API int RsaPublicEncrypt_fips(const byte* in,word32 inLen,byte* out,
word32 outLen, RsaKey* key, RNG* rng);
CYASSL_API int RsaPrivateDecryptInline_fips(byte* in, word32 inLen,
byte** out, RsaKey* key);
CYASSL_API int RsaPrivateDecrypt_fips(const byte* in, word32 inLen,
byte* out,word32 outLen,RsaKey* key);
CYASSL_API int RsaSSL_Sign_fips(const byte* in, word32 inLen, byte* out,
word32 outLen, RsaKey* key, RNG* rng);
CYASSL_API int RsaSSL_VerifyInline_fips(byte* in, word32 inLen, byte** out,
RsaKey* key);
CYASSL_API int RsaSSL_Verify_fips(const byte* in, word32 inLen, byte* out,
word32 outLen, RsaKey* key);
CYASSL_API int RsaEncryptSize_fips(RsaKey* key);
CYASSL_API int RsaPrivateKeyDecode_fips(const byte* input, word32* inOutIdx,
RsaKey*, word32);
CYASSL_API int RsaPublicKeyDecode_fips(const byte* input, word32* inOutIdx,
RsaKey*, word32);
#ifndef FIPS_NO_WRAPPERS
/* if not impl or fips.c impl wrapper force fips calls if fips build */
#define InitRsaKey InitRsaKey_fips
#define FreeRsaKey FreeRsaKey_fips
#define RsaPublicEncrypt RsaPublicEncrypt_fips
#define RsaPrivateDecryptInline RsaPrivateDecryptInline_fips
#define RsaPrivateDecrypt RsaPrivateDecrypt_fips
#define RsaSSL_Sign RsaSSL_Sign_fips
#define RsaSSL_VerifyInline RsaSSL_VerifyInline_fips
#define RsaSSL_Verify RsaSSL_Verify_fips
#define RsaEncryptSize RsaEncryptSize_fips
/* no implicit KeyDecodes since in asn.c (not rsa.c) */
#endif /* FIPS_NO_WRAPPERS */
#endif /* HAVE_FIPS */
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif

View File

@@ -461,9 +461,7 @@ int CRYPT_RSA_Initialize(CRYPT_RSA_CTX* rsa)
if (rsa->holder == NULL) if (rsa->holder == NULL)
return -1; return -1;
InitRsaKey((RsaKey*)rsa->holder, NULL); return InitRsaKey((RsaKey*)rsa->holder, NULL);
return 0;
} }

View File

@@ -1219,8 +1219,9 @@ static int check_rsa(void)
byte out1[256]; byte out1[256];
byte out2[256]; byte out2[256];
InitRsaKey(&defRsa, NULL); ret = InitRsaKey(&defRsa, NULL);
ret = CRYPT_RSA_Initialize(&mcRsa); if (ret == 0)
ret = CRYPT_RSA_Initialize(&mcRsa);
if (ret != 0) { if (ret != 0) {
printf("mcapi rsa init failed\n"); printf("mcapi rsa init failed\n");
return -1; return -1;

View File

@@ -1696,7 +1696,8 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
CYASSL_MSG("PeerRsaKey Memory error"); CYASSL_MSG("PeerRsaKey Memory error");
return MEMORY_E; return MEMORY_E;
} }
InitRsaKey(ssl->peerRsaKey, ctx->heap); ret = InitRsaKey(ssl->peerRsaKey, ctx->heap);
if (ret != 0) return ret;
#endif #endif
#ifndef NO_CERTS #ifndef NO_CERTS
/* make sure server has cert and key unless using PSK */ /* make sure server has cert and key unless using PSK */
@@ -8483,6 +8484,7 @@ static void PickHashSigAlgo(CYASSL* ssl,
word32 sigOutSz = 0; word32 sigOutSz = 0;
#ifndef NO_RSA #ifndef NO_RSA
RsaKey key; RsaKey key;
int initRsaKey = 0;
#endif #endif
int usingEcc = 0; int usingEcc = 0;
#ifdef HAVE_ECC #ifdef HAVE_ECC
@@ -8508,9 +8510,11 @@ static void PickHashSigAlgo(CYASSL* ssl,
ecc_init(&eccKey); ecc_init(&eccKey);
#endif #endif
#ifndef NO_RSA #ifndef NO_RSA
InitRsaKey(&key, ssl->heap); ret = InitRsaKey(&key, ssl->heap);
ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key, if (ret == 0) initRsaKey = 1;
ssl->buffers.key.length); if (ret == 0)
ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
ssl->buffers.key.length);
if (ret == 0) if (ret == 0)
sigOutSz = RsaEncryptSize(&key); sigOutSz = RsaEncryptSize(&key);
else else
@@ -8711,7 +8715,8 @@ static void PickHashSigAlgo(CYASSL* ssl,
} }
} }
#ifndef NO_RSA #ifndef NO_RSA
FreeRsaKey(&key); if (initRsaKey)
FreeRsaKey(&key);
#endif #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
ecc_free(&eccKey); ecc_free(&eccKey);
@@ -8960,7 +8965,8 @@ static void PickHashSigAlgo(CYASSL* ssl,
preSigIdx = idx; preSigIdx = idx;
#ifndef NO_RSA #ifndef NO_RSA
InitRsaKey(&rsaKey, ssl->heap); ret = InitRsaKey(&rsaKey, ssl->heap);
if (ret != 0) return ret;
#endif #endif
ecc_init(&dsaKey); ecc_init(&dsaKey);
@@ -9293,7 +9299,10 @@ static void PickHashSigAlgo(CYASSL* ssl,
&ssl->buffers.serverDH_Pub.length); &ssl->buffers.serverDH_Pub.length);
FreeDhKey(&dhKey); FreeDhKey(&dhKey);
InitRsaKey(&rsaKey, ssl->heap); if (ret == 0) {
ret = InitRsaKey(&rsaKey, ssl->heap);
if (ret != 0) return ret;
}
if (ret == 0) { if (ret == 0) {
length = LENGTH_SZ * 3; /* p, g, pub */ length = LENGTH_SZ * 3; /* p, g, pub */
length += ssl->buffers.serverDH_P.length + length += ssl->buffers.serverDH_P.length +
@@ -10807,7 +10816,8 @@ static void PickHashSigAlgo(CYASSL* ssl,
doUserRsa = 1; doUserRsa = 1;
#endif #endif
InitRsaKey(&key, ssl->heap); ret = InitRsaKey(&key, ssl->heap);
if (ret != 0) return ret;
if (ssl->buffers.key.buffer) if (ssl->buffers.key.buffer)
ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx,

View File

@@ -1044,9 +1044,9 @@ static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
RsaKey key; RsaKey key;
int ret; int ret;
InitRsaKey(&key, 0); ret = InitRsaKey(&key, 0);
if (ret == 0)
ret = RsaPrivateKeyDecode(session->context->ctx->privateKey.buffer, ret = RsaPrivateKeyDecode(session->context->ctx->privateKey.buffer,
&idx, &key, session->context->ctx->privateKey.length); &idx, &key, session->context->ctx->privateKey.length);
if (ret == 0) { if (ret == 0) {
int length = RsaEncryptSize(&key); int length = RsaEncryptSize(&key);

View File

@@ -2121,7 +2121,8 @@ int CyaSSL_Init(void)
RsaKey key; RsaKey key;
word32 idx = 0; word32 idx = 0;
InitRsaKey(&key, 0); ret = InitRsaKey(&key, 0);
if (ret != 0) return ret;
if (RsaPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) { if (RsaPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) {
#ifdef HAVE_ECC #ifdef HAVE_ECC
/* could have DER ECC (or pkcs8 ecc), no easy way to tell */ /* could have DER ECC (or pkcs8 ecc), no easy way to tell */
@@ -10341,7 +10342,12 @@ static int initGlobalRNG = 0;
} }
InitCyaSSL_Rsa(external); InitCyaSSL_Rsa(external);
InitRsaKey(key, NULL); if (InitRsaKey(key, NULL) != 0) {
CYASSL_MSG("InitRsaKey CYASSL_RSA failure");
XFREE(external, NULL, DYNAMIC_TYPE_RSA);
XFREE(key, NULL, DYNAMIC_TYPE_RSA);
return NULL;
}
external->internal = key; external->internal = key;
return external; return external;