Added new ECC export API's to support export as hex string. New API's are wc_ecc_export_ex and wc_ecc_export_int. For hex string use ECC_TYPE_HEX_STR as encType arg. Refactor to reduce duplicate code. Build fixes for NO_ECC_KEY_EXPORT.

This commit is contained in:
David Garske
2018-08-07 15:51:59 -07:00
parent 64f553d944
commit c073aee87c
7 changed files with 106 additions and 113 deletions
+2 -2
View File
@@ -19347,7 +19347,7 @@ int SendClientKeyExchange(WOLFSSL* ssl)
break;
}
#endif
#ifdef HAVE_ECC
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
#ifdef HAVE_PK_CALLBACKS
/* if callback then use it for shared secret */
if (ssl->ctx->EccSharedSecretCb != NULL) {
@@ -21272,7 +21272,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
else
#endif
{
#ifdef HAVE_ECC
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
if (wc_ecc_export_x963(ssl->eccTempKey,
args->exportBuf, &args->exportSz) != 0) {
ERROR_OUT(ECC_EXPORT_ERROR, exit_sske);
+8 -6
View File
@@ -12883,7 +12883,7 @@ static int test_wc_ecc_export_x963 (void)
{
int ret = 0;
#ifdef HAVE_ECC
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
ecc_key key;
WC_RNG rng;
byte out[ECC_ASN963_MAX_BUF_SZ];
@@ -12945,7 +12945,7 @@ static int test_wc_ecc_export_x963_ex (void)
{
int ret = 0;
#if defined(HAVE_ECC)
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
ecc_key key;
WC_RNG rng;
byte out[ECC_ASN963_MAX_BUF_SZ];
@@ -13043,7 +13043,8 @@ static int test_wc_ecc_import_x963 (void)
{
int ret = 0;
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_IMPORT)
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_IMPORT) && \
defined(HAVE_ECC_KEY_EXPORT)
ecc_key pubKey, key;
WC_RNG rng;
byte x963[ECC_ASN963_MAX_BUF_SZ];
@@ -13106,7 +13107,8 @@ static int ecc_import_private_key (void)
{
int ret = 0;
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_IMPORT)
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_IMPORT) && \
defined(HAVE_ECC_KEY_EXPORT)
ecc_key key, keyImp;
WC_RNG rng;
byte privKey[ECC_PRIV_KEY_BUF]; /* Raw private key.*/
@@ -13784,7 +13786,7 @@ static int test_wc_ecc_pointFns (void)
{
int ret = 0;
#if defined(HAVE_ECC)
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
ecc_key key;
WC_RNG rng;
ecc_point* point = NULL;
@@ -18217,7 +18219,7 @@ static void test_wolfSSL_d2i_PrivateKeys_bio(void)
EVP_PKEY* pkey = NULL;
RSA* rsa = NULL;
WOLFSSL_CTX* ctx;
#if defined(WOLFSSL_KEY_GEN)
unsigned char buffer[4096];
unsigned char* bufPtr;
+7 -6
View File
@@ -816,7 +816,7 @@ static int CheckBitString(const byte* input, word32* inOutIdx, int* len,
/* RSA (with CertGen or KeyGen) OR ECC OR ED25519 (with CertGen or KeyGen) */
#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && \
(defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))) || \
defined(HAVE_ECC) || \
(defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)) || \
(defined(HAVE_ED25519) && \
(defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)))
@@ -2403,7 +2403,7 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
else
#endif /* NO_RSA */
#ifdef HAVE_ECC
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
if (der->keyOID == ECDSAk) {
#ifdef WOLFSSL_SMALL_STACK
ecc_key* key_pair = NULL;
@@ -5100,7 +5100,7 @@ WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output)
}
#if defined(HAVE_ECC)
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
static int SetCurve(ecc_key* key, byte* output)
{
@@ -5139,7 +5139,7 @@ static int SetCurve(ecc_key* key, byte* output)
return idx;
}
#endif /* HAVE_ECC */
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
#ifdef HAVE_ECC
@@ -8972,7 +8972,7 @@ static word32 SetUTF8String(word32 len, byte* output)
#endif /*WOLFSSL_CERT_GEN */
#if defined(HAVE_ECC)
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
/* Write a public ECC key to output */
static int SetEccPublicKey(byte* output, ecc_key* key, int with_header)
@@ -12507,7 +12507,7 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
return 0;
}
#if defined(HAVE_ECC_KEY_EXPORT)
/* build DER formatted ECC key, include optional public key if requested,
* return length on success, negative on error */
static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen,
@@ -12710,6 +12710,7 @@ int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
return ret;
}
#endif /* HAVE_ECC_KEY_EXPORT */
#endif /* HAVE_ECC */
+77 -96
View File
@@ -6399,143 +6399,124 @@ int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
#endif /* HAVE_ECC_KEY_IMPORT */
#ifdef HAVE_ECC_KEY_EXPORT
/* export ecc private key only raw, outLen is in/out size
return MP_OKAY on success */
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
/* export an mp_int as unsigned char or hex string
* encType is ECC_TYPE_UNSIGNED_BIN or ECC_TYPE_HEX_STR
* return MP_OKAY on success */
int wc_ecc_export_int(mp_int* mp, byte* buf, word32* len, word32 keySz,
int encType)
{
word32 numlen;
int err;
if (key == NULL || out == NULL || outLen == NULL) {
return BAD_FUNC_ARG;
}
if (wc_ecc_is_valid_idx(key->idx) == 0) {
return ECC_BAD_ARG_E;
}
numlen = key->dp->size;
if (*outLen < numlen) {
*outLen = numlen;
/* check buffer size */
if (*len < keySz) {
*len = keySz;
return BUFFER_E;
}
*outLen = numlen;
XMEMSET(out, 0, *outLen);
#ifdef WOLFSSL_ATECC508A
/* TODO: Implement equiv call to ATECC508A */
return BAD_COND_E;
*len = keySz;
XMEMSET(buf, 0, *len);
#else
return mp_to_unsigned_bin(&key->k, out + (numlen -
mp_unsigned_bin_size(&key->k)));
#endif /* WOLFSSL_ATECC508A */
}
/* export ecc key to component form, d is optional if only exporting public
* return MP_OKAY on success */
static int wc_ecc_export_raw(ecc_key* key, byte* qx, word32* qxLen,
byte* qy, word32* qyLen, byte* d, word32* dLen)
{
int err;
byte exportPriv = 0;
word32 numLen;
if (key == NULL || qx == NULL || qxLen == NULL || qy == NULL ||
qyLen == NULL) {
return BAD_FUNC_ARG;
if (encType == ECC_TYPE_HEX_STR) {
err = mp_tohex(mp, (char*)buf);
}
else {
err = mp_to_unsigned_bin(mp, buf + (keySz - mp_unsigned_bin_size(mp)));
}
if (key->type == ECC_PRIVATEKEY_ONLY) {
return ECC_PRIVATEONLY_E;
return err;
}
/* export ecc key to component form, d is optional if only exporting public
* encType is ECC_TYPE_UNSIGNED_BIN or ECC_TYPE_HEX_STR
* return MP_OKAY on success */
int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
{
int err = 0;
word32 keySz;
if (key == NULL) {
return BAD_FUNC_ARG;
}
if (wc_ecc_is_valid_idx(key->idx) == 0) {
return ECC_BAD_ARG_E;
}
numLen = key->dp->size;
keySz = key->dp->size;
/* private key, d */
if (d != NULL) {
if (dLen == NULL || key->type != ECC_PRIVATEKEY)
return BAD_FUNC_ARG;
exportPriv = 1;
}
/* check public buffer sizes */
if ((*qxLen < numLen) || (*qyLen < numLen)) {
*qxLen = numLen;
*qyLen = numLen;
return BUFFER_E;
}
*qxLen = numLen;
*qyLen = numLen;
XMEMSET(qx, 0, *qxLen);
XMEMSET(qy, 0, *qyLen);
/* private d component */
if (exportPriv == 1) {
/* check private buffer size */
if (*dLen < numLen) {
*dLen = numLen;
return BUFFER_E;
}
*dLen = numLen;
XMEMSET(d, 0, *dLen);
#ifdef WOLFSSL_ATECC508A
/* TODO: Implement equiv call to ATECC508A */
return BAD_COND_E;
/* Hardware cannot export private portion */
return BAD_COND_E;
#else
/* private key, d */
err = mp_to_unsigned_bin(&key->k, d +
(numLen - mp_unsigned_bin_size(&key->k)));
err = wc_ecc_export_int(&key->k, d, dLen, keySz, encType);
if (err != MP_OKAY)
return err;
#endif /* WOLFSSL_ATECC508A */
#endif
}
/* public x component */
err = mp_to_unsigned_bin(key->pubkey.x, qx +
(numLen - mp_unsigned_bin_size(key->pubkey.x)));
if (err != MP_OKAY)
return err;
if (qx != NULL) {
if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
return BAD_FUNC_ARG;
err = wc_ecc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);
if (err != MP_OKAY)
return err;
}
/* public y component */
err = mp_to_unsigned_bin(key->pubkey.y, qy +
(numLen - mp_unsigned_bin_size(key->pubkey.y)));
if (err != MP_OKAY)
return err;
if (qy != NULL) {
if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
return BAD_FUNC_ARG;
return 0;
err = wc_ecc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);
if (err != MP_OKAY)
return err;
}
return err;
}
/* export public key to raw elements including public (Qx,Qy)
/* export ecc private key only raw, outLen is in/out size as unsigned bin
return MP_OKAY on success */
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
{
if (out == NULL || outLen == NULL) {
return BAD_FUNC_ARG;
}
return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
ECC_TYPE_UNSIGNED_BIN);
}
/* export public key to raw elements including public (Qx,Qy) as unsigned bin
* return MP_OKAY on success, negative on error */
int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
byte* qy, word32* qyLen)
{
return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, NULL, NULL);
if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {
return BAD_FUNC_ARG;
}
return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,
ECC_TYPE_UNSIGNED_BIN);
}
/* export ecc key to raw elements including public (Qx,Qy) and private (d)
/* export ecc key to raw elements including public (Qx,Qy) and
* private (d) as unsigned bin
* return MP_OKAY on success, negative on error */
int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
byte* qy, word32* qyLen, byte* d, word32* dLen)
{
/* sanitize d and dLen, other args are checked later */
if (d == NULL || dLen == NULL)
return BAD_FUNC_ARG;
return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, d, dLen);
return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,
ECC_TYPE_UNSIGNED_BIN);
}
#endif /* HAVE_ECC_KEY_EXPORT */
+2 -1
View File
@@ -4915,7 +4915,8 @@ int mp_read_radix (mp_int * a, const char *str, int radix)
#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \
defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) || \
defined(WOLFSSL_PUBLIC_MP)
defined(WOLFSSL_PUBLIC_MP) || \
(defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT))
/* returns size of ASCII representation */
int mp_radix_size (mp_int *a, int radix, int *size)
+2 -1
View File
@@ -3370,7 +3370,8 @@ int mp_set(fp_int *a, fp_digit b)
#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \
defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) || \
defined(WOLFSSL_PUBLIC_MP)
defined(WOLFSSL_PUBLIC_MP) || \
(defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT))
/* returns size of ASCII representation */
int mp_radix_size (mp_int *a, int radix, int *size)
+8 -1
View File
@@ -560,13 +560,20 @@ int wc_ecc_import_unsigned(ecc_key* key, byte* qx, byte* qy,
#ifdef HAVE_ECC_KEY_EXPORT
WOLFSSL_API
int wc_ecc_export_int(mp_int* mp, byte* buf, word32* len, word32 keySz,
int encType);
WOLFSSL_API
int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
byte* qy, word32* qyLen, byte* d, word32* dLen,
int encType);
WOLFSSL_API
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen);
WOLFSSL_API
int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
byte* qy, word32* qyLen);
WOLFSSL_API
int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
byte* qy, word32* qyLen, byte* d, word32* dLen);
byte* qy, word32* qyLen, byte* d, word32* dLen);
#endif /* HAVE_ECC_KEY_EXPORT */
#ifdef HAVE_ECC_KEY_EXPORT