Merge pull request #1745 from dgarske/ecc_export_hex

Added new ECC export API's to support export as hex string
This commit is contained in:
toddouska
2018-08-14 14:19:23 -07:00
committed by GitHub
10 changed files with 137 additions and 136 deletions

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);

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;

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
@@ -8959,7 +8959,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)
@@ -12494,7 +12494,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,
@@ -12697,6 +12697,7 @@ int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
return ret;
}
#endif /* HAVE_ECC_KEY_EXPORT */
#endif /* HAVE_ECC */

View File

@@ -6399,143 +6399,97 @@ 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)
{
word32 numlen;
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;
return BUFFER_E;
}
*outLen = numlen;
XMEMSET(out, 0, *outLen);
#ifdef WOLFSSL_ATECC508A
/* TODO: Implement equiv call to ATECC508A */
return BAD_COND_E;
#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
* encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
* 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 wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
{
int err;
byte exportPriv = 0;
word32 numLen;
int err = 0;
word32 keySz;
if (key == NULL || qx == NULL || qxLen == NULL || qy == NULL ||
qyLen == NULL) {
if (key == NULL) {
return BAD_FUNC_ARG;
}
if (key->type == ECC_PRIVATEKEY_ONLY) {
return ECC_PRIVATEONLY_E;
}
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_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_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_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,
WC_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,
WC_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,
WC_TYPE_UNSIGNED_BIN);
}
#endif /* HAVE_ECC_KEY_EXPORT */
@@ -6853,7 +6807,7 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
/* read Qx */
if (err == MP_OKAY) {
if (encType == ECC_TYPE_HEX_STR)
if (encType == WC_TYPE_HEX_STR)
err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
else
err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
@@ -6862,7 +6816,7 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
/* read Qy */
if (err == MP_OKAY) {
if (encType == ECC_TYPE_HEX_STR)
if (encType == WC_TYPE_HEX_STR)
err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
else
err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
@@ -6878,7 +6832,7 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
if (d != NULL) {
key->type = ECC_PRIVATEKEY;
if (encType == ECC_TYPE_HEX_STR)
if (encType == WC_TYPE_HEX_STR)
err = mp_read_radix(&key->k, d, MP_RADIX_HEX);
else
err = mp_read_unsigned_bin(&key->k, (const byte*)d,
@@ -6919,7 +6873,7 @@ int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
const char* d, int curve_id)
{
return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
ECC_TYPE_HEX_STR);
WC_TYPE_HEX_STR);
}
@@ -6928,7 +6882,7 @@ int wc_ecc_import_unsigned(ecc_key* key, byte* qx, byte* qy,
byte* d, int curve_id)
{
return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
(const char*)d, curve_id, ECC_TYPE_UNSIGNED_BIN);
(const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);
}
/**
@@ -6964,7 +6918,7 @@ int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
err = ASN_PARSE_E;
} else {
return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
ECC_TYPE_HEX_STR);
WC_TYPE_HEX_STR);
}
return err;

View File

@@ -4913,9 +4913,7 @@ int mp_read_radix (mp_int * a, const char *str, int radix)
}
#endif /* !defined(NO_DSA) || defined(HAVE_ECC) */
#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \
defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) || \
defined(WOLFSSL_PUBLIC_MP)
#ifdef WC_MP_TO_RADIX
/* returns size of ASCII representation */
int mp_radix_size (mp_int *a, int radix, int *size)
@@ -5055,7 +5053,7 @@ void mp_dump(const char* desc, mp_int* a, byte verbose)
}
#endif /* WOLFSSL_DEBUG_MATH */
#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) */
#endif /* WC_MP_TO_RADIX */
#endif /* WOLFSSL_SP_MATH */

View File

@@ -2606,9 +2606,7 @@ int mp_montgomery_calc_normalization(mp_int *a, mp_int *b)
#endif /* WOLFSSL_KEYGEN || HAVE_ECC */
#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \
defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) || \
defined(WOLFSSL_PUBLIC_MP) || !defined(NO_DH) || !defined(NO_DSA) || \
#if defined(WC_MP_TO_RADIX) || !defined(NO_DH) || !defined(NO_DSA) || \
!defined(NO_RSA)
#ifdef WOLFSSL_KEY_GEN
@@ -2755,10 +2753,11 @@ int mp_mod_d(fp_int *a, fp_digit b, fp_digit *c)
return fp_mod_d(a, b, c);
}
#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) */
#endif /* WC_MP_TO_RADIX || !NO_DH || !NO_DSA || !NO_RSA */
#if !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA) || defined(WOLFSSL_KEY_GEN)
#if !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA) || \
defined(WOLFSSL_KEY_GEN)
static int fp_isprime_ex(fp_int *a, int t);
/* static int fp_isprime(fp_int *a); */
@@ -3368,9 +3367,7 @@ int mp_set(fp_int *a, fp_digit b)
}
#endif
#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \
defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) || \
defined(WOLFSSL_PUBLIC_MP)
#ifdef WC_MP_TO_RADIX
/* returns size of ASCII representation */
int mp_radix_size (mp_int *a, int radix, int *size)
@@ -3504,7 +3501,7 @@ void mp_dump(const char* desc, mp_int* a, byte verbose)
}
#endif /* WOLFSSL_DEBUG_MATH */
#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) */
#endif /* WC_MP_TO_RADIX */
int mp_abs(mp_int* a, mp_int* b)

View File

@@ -150,6 +150,40 @@ exit:
}
#endif /* WC_RSA_BLINDING */
/* export an mp_int as unsigned char or hex string
* encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
* return MP_OKAY on success */
int wc_export_int(mp_int* mp, byte* buf, word32* len, word32 keySz,
int encType)
{
int err;
if (mp == NULL)
return BAD_FUNC_ARG;
/* check buffer size */
if (*len < keySz) {
*len = keySz;
return BUFFER_E;
}
*len = keySz;
XMEMSET(buf, 0, *len);
if (encType == WC_TYPE_HEX_STR) {
#ifdef WC_MP_TO_RADIX
err = mp_tohex(mp, (char*)buf);
#else
err = NOT_COMPILED_IN;
#endif
}
else {
err = mp_to_unsigned_bin(mp, buf + (keySz - mp_unsigned_bin_size(mp)));
}
return err;
}
#ifdef HAVE_WOLF_BIGINT
void wc_bigint_init(WC_BIGINT* a)

View File

@@ -127,10 +127,6 @@ enum {
ECC_MAX_CRYPTO_HW_SIZE = 32,
#endif
/* point encoding type */
ECC_TYPE_HEX_STR = 1,
ECC_TYPE_UNSIGNED_BIN = 2,
/* point compression type */
ECC_POINT_COMP_EVEN = 0x02,
ECC_POINT_COMP_ODD = 0x03,
@@ -559,6 +555,10 @@ int wc_ecc_import_unsigned(ecc_key* key, byte* qx, byte* qy,
#endif /* HAVE_ECC_KEY_IMPORT */
#ifdef HAVE_ECC_KEY_EXPORT
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
@@ -566,7 +566,7 @@ 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

View File

@@ -712,6 +712,13 @@
#define WC_NORETURN
#endif
#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \
defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) || \
defined(WOLFSSL_PUBLIC_MP) || \
(defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT))
#undef WC_MP_TO_RADIX
#define WC_MP_TO_RADIX
#endif
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -51,6 +51,14 @@
int get_rand_digit(WC_RNG* rng, mp_digit* d);
int mp_rand(mp_int* a, int digits, WC_RNG* rng);
enum {
/* format type */
WC_TYPE_HEX_STR = 1,
WC_TYPE_UNSIGNED_BIN = 2,
};
WOLFSSL_API int wc_export_int(mp_int* mp, byte* buf, word32* len,
word32 keySz, int encType);
#ifdef HAVE_WOLF_BIGINT
void wc_bigint_init(WC_BIGINT* a);