mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-10 01:50:53 +02:00
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:
+2
-2
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user