add ECC export raw, sig to (R,S), helper functions
This commit is contained in:
parent
fc8ab42612
commit
f6647fbf84
@ -2452,6 +2452,55 @@ int wc_ecc_is_valid_idx(int n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the curve name that corresponds to an ecc_curve_id identifier
|
||||
*
|
||||
* id curve id, from ecc_curve_id enum in ecc.h
|
||||
* return const char* representing curve name, from ecc_sets[] on success,
|
||||
* otherwise NULL if id not found.
|
||||
*/
|
||||
const char* wc_ecc_get_curve_name_from_id(int id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; ecc_sets[i].size != 0; i++) {
|
||||
if (id == ecc_sets[i].id)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ecc_sets[i].size == 0) {
|
||||
WOLFSSL_MSG("ecc_set curve not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ecc_sets[i].name;
|
||||
}
|
||||
|
||||
|
||||
/* Returns the curve size that corresponds to a given ecc_curve_id identifier
|
||||
*
|
||||
* id curve id, from ecc_curve_id enum in ecc.h
|
||||
* return curve size, from ecc_sets[] on success, negative on error
|
||||
*/
|
||||
int wc_ecc_get_curve_size_from_id(int id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; ecc_sets[i].size != 0; i++) {
|
||||
if (id == ecc_sets[i].id)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ecc_sets[i].size == 0) {
|
||||
WOLFSSL_MSG("ecc_set curve not found");
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
|
||||
return ecc_sets[i].size;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_ECC_DHE
|
||||
/**
|
||||
Create an ECC shared secret between two keys
|
||||
@ -4341,6 +4390,14 @@ int wc_ecc_check_key(ecc_key* key)
|
||||
b = curve->Bf;
|
||||
#endif
|
||||
|
||||
/* Qx must be in the range [0, p-1] */
|
||||
if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT)
|
||||
err = ECC_OUT_OF_RANGE_E;
|
||||
|
||||
/* Qy must be in the range [0, p-1] */
|
||||
if (mp_cmp(key->pubkey.y, curve->prime) != MP_LT)
|
||||
err = ECC_OUT_OF_RANGE_E;
|
||||
|
||||
/* make sure point is actually on curve */
|
||||
if (err == MP_OKAY)
|
||||
err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
|
||||
@ -4557,6 +4614,102 @@ int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
|
||||
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 (wc_ecc_is_valid_idx(key->idx) == 0) {
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
numLen = key->dp->size;
|
||||
|
||||
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);
|
||||
|
||||
/* private key, d */
|
||||
err = mp_to_unsigned_bin(&key->k, d +
|
||||
(numLen - mp_unsigned_bin_size(&key->k)));
|
||||
if (err != MP_OKAY)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* export public key to raw elements including public (Qx,Qy)
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
/* export ecc key to raw elements including public (Qx,Qy) and private (d)
|
||||
* 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);
|
||||
}
|
||||
|
||||
#endif /* HAVE_ECC_KEY_EXPORT */
|
||||
|
||||
#ifdef HAVE_ECC_KEY_IMPORT
|
||||
@ -4638,6 +4791,62 @@ int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Convert ECC signature to R,S
|
||||
sig DER-encoded ECDSA signature
|
||||
sigLen length of signature in octets
|
||||
r R component of signature
|
||||
rLen [in/out] output "r" buffer size, output "r" size
|
||||
s S component of signature
|
||||
sLen [in/out] output "s" buffer size, output "s" size
|
||||
return MP_OKAY on success, negative on error
|
||||
*/
|
||||
int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
|
||||
byte* s, word32* sLen)
|
||||
{
|
||||
int err;
|
||||
word32 x = 0;
|
||||
mp_int rtmp;
|
||||
mp_int stmp;
|
||||
|
||||
if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
|
||||
return ECC_BAD_ARG_E;
|
||||
|
||||
err = DecodeECC_DSA_Sig(sig, sigLen, &rtmp, &stmp);
|
||||
|
||||
/* extract r */
|
||||
if (err == MP_OKAY) {
|
||||
x = mp_unsigned_bin_size(&rtmp);
|
||||
if (*rLen < x)
|
||||
err = BUFFER_E;
|
||||
|
||||
if (err == MP_OKAY) {
|
||||
*rLen = x;
|
||||
err = mp_to_unsigned_bin(&rtmp, r);
|
||||
}
|
||||
}
|
||||
|
||||
/* extract s */
|
||||
if (err == MP_OKAY) {
|
||||
x = mp_unsigned_bin_size(&stmp);
|
||||
if (*sLen < x)
|
||||
err = BUFFER_E;
|
||||
|
||||
if (err == MP_OKAY) {
|
||||
*sLen = x;
|
||||
err = mp_to_unsigned_bin(&stmp, s);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef USE_FAST_MATH
|
||||
mp_clear(&rtmp);
|
||||
mp_clear(&stmp);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif /* !NO_ASN */
|
||||
|
||||
#ifdef HAVE_ECC_KEY_IMPORT
|
||||
@ -4646,7 +4855,8 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
||||
{
|
||||
int err = MP_OKAY;
|
||||
|
||||
if (key == NULL || qx == NULL || qy == NULL || d == NULL) {
|
||||
/* if d is NULL, only import as public key using Qx,Qy */
|
||||
if (key == NULL || qx == NULL || qy == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
@ -4691,8 +4901,12 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
||||
|
||||
/* import private key */
|
||||
if (err == MP_OKAY) {
|
||||
key->type = ECC_PRIVATEKEY;
|
||||
err = mp_read_radix(&key->k, d, 16);
|
||||
if (d != NULL) {
|
||||
key->type = ECC_PRIVATEKEY;
|
||||
err = mp_read_radix(&key->k, d, 16);
|
||||
} else {
|
||||
key->type = ECC_PUBLICKEY;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
|
||||
@ -4716,7 +4930,8 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
||||
key The destination ecc_key structure
|
||||
qx x component of the public key, as ASCII hex string
|
||||
qy y component of the public key, as ASCII hex string
|
||||
d private key, as ASCII hex string
|
||||
d private key, as ASCII hex string, optional if importing public
|
||||
key only
|
||||
dp Custom ecc_set_type
|
||||
return MP_OKAY on success
|
||||
*/
|
||||
@ -4732,7 +4947,8 @@ int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
|
||||
key The destination ecc_key structure
|
||||
qx x component of the public key, as ASCII hex string
|
||||
qy y component of the public key, as ASCII hex string
|
||||
d private key, as ASCII hex string
|
||||
d private key, as ASCII hex string, optional if importing public
|
||||
key only
|
||||
curveName ECC curve name, from ecc_sets[]
|
||||
return MP_OKAY on success
|
||||
*/
|
||||
@ -4741,8 +4957,8 @@ int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
|
||||
{
|
||||
int err, x;
|
||||
|
||||
if (key == NULL || qx == NULL || qy == NULL || d == NULL ||
|
||||
curveName == NULL) {
|
||||
/* if d is NULL, only import as public key using Qx,Qy */
|
||||
if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
|
@ -338,6 +338,9 @@ const char* wc_GetErrorString(int error)
|
||||
case ECC_INF_E:
|
||||
return " ECC point at infinity error";
|
||||
|
||||
case ECC_OUT_OF_RANGE_E:
|
||||
return " ECC Qx or Qy out of range error";
|
||||
|
||||
case ECC_PRIV_KEY_E:
|
||||
return " ECC private key is not valid error";
|
||||
|
||||
|
@ -331,6 +331,10 @@ void wc_ecc_fp_free(void);
|
||||
|
||||
WOLFSSL_API
|
||||
int wc_ecc_is_valid_idx(int n);
|
||||
WOLFSSL_API
|
||||
const char* wc_ecc_get_curve_name_from_id(int curve_id);
|
||||
WOLFSSL_API
|
||||
int wc_ecc_get_curve_size_from_id(int curve_id);
|
||||
|
||||
#ifndef WOLFSSL_ATECC508A
|
||||
|
||||
@ -381,6 +385,9 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
|
||||
WOLFSSL_API
|
||||
int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen);
|
||||
WOLFSSL_API
|
||||
int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
|
||||
byte* s, word32* sLen);
|
||||
WOLFSSL_API
|
||||
int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
|
||||
const char* d, const char* curveName);
|
||||
WOLFSSL_API
|
||||
@ -391,6 +398,12 @@ int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
|
||||
#ifdef HAVE_ECC_KEY_EXPORT
|
||||
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);
|
||||
#endif /* HAVE_ECC_KEY_EXPORT */
|
||||
|
||||
#ifdef HAVE_ECC_KEY_EXPORT
|
||||
|
@ -153,13 +153,14 @@ enum {
|
||||
IS_POINT_E = -214, /* ECC is point on curve failed */
|
||||
ECC_INF_E = -215, /* ECC point infinity error */
|
||||
ECC_PRIV_KEY_E = -216, /* ECC private key not valid error */
|
||||
ECC_OUT_OF_RANGE_E = -217, /* ECC key component out of range */
|
||||
|
||||
SRP_CALL_ORDER_E = -217, /* SRP function called in the wrong order. */
|
||||
SRP_VERIFY_E = -218, /* SRP proof verification failed. */
|
||||
SRP_BAD_KEY_E = -219, /* SRP bad ephemeral values. */
|
||||
SRP_CALL_ORDER_E = -218, /* SRP function called in the wrong order. */
|
||||
SRP_VERIFY_E = -219, /* SRP proof verification failed. */
|
||||
SRP_BAD_KEY_E = -220, /* SRP bad ephemeral values. */
|
||||
|
||||
ASN_NO_SKID = -220, /* ASN no Subject Key Identifier found */
|
||||
ASN_NO_AKID = -221, /* ASN no Authority Key Identifier found */
|
||||
ASN_NO_SKID = -221, /* ASN no Subject Key Identifier found */
|
||||
ASN_NO_AKID = -222, /* ASN no Authority Key Identifier found */
|
||||
ASN_NO_KEYUSAGE = -223, /* ASN no Key Usage found */
|
||||
SKID_E = -224, /* setting Subject Key Identifier error */
|
||||
AKID_E = -225, /* setting Authority Key Identifier error */
|
||||
|
Loading…
x
Reference in New Issue
Block a user