wc_EccPublicKeyToDer_ex: exporting the public key in compressed form

This commit is contained in:
Juliusz Sosinowicz
2022-06-13 17:43:28 +02:00
parent 448cde5a4b
commit ee3636f2e7
4 changed files with 39 additions and 13 deletions

View File

@ -22091,7 +22091,7 @@ enum {
* @return MEMORY_E when dynamic memory allocation failed. * @return MEMORY_E when dynamic memory allocation failed.
*/ */
static int SetEccPublicKey(byte* output, ecc_key* key, int outLen, static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
int with_header) int with_header, int comp)
{ {
#ifndef WOLFSSL_ASN_TEMPLATE #ifndef WOLFSSL_ASN_TEMPLATE
int ret, idx = 0, algoSz, curveSz, bitStringSz; int ret, idx = 0, algoSz, curveSz, bitStringSz;
@ -22101,7 +22101,10 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
/* public size */ /* public size */
pubSz = key->dp ? key->dp->size : MAX_ECC_BYTES; pubSz = key->dp ? key->dp->size : MAX_ECC_BYTES;
pubSz = 1 + 2 * pubSz; if (comp)
pubSz = 1 + pubSz;
else
pubSz = 1 + 2 * pubSz;
/* check for buffer overflow */ /* check for buffer overflow */
if (output != NULL && pubSz > (word32)outLen) { if (output != NULL && pubSz > (word32)outLen) {
@ -22144,7 +22147,7 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
/* pub */ /* pub */
if (output) { if (output) {
PRIVATE_KEY_UNLOCK(); PRIVATE_KEY_UNLOCK();
ret = wc_ecc_export_x963(key, output + idx, &pubSz); ret = wc_ecc_export_x963_ex(key, output + idx, &pubSz, comp);
PRIVATE_KEY_LOCK(); PRIVATE_KEY_LOCK();
if (ret != 0) { if (ret != 0) {
return ret; return ret;
@ -22168,7 +22171,7 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
if (ret == 0) { if (ret == 0) {
/* Calculate the size of the encoded public point. */ /* Calculate the size of the encoded public point. */
PRIVATE_KEY_UNLOCK(); PRIVATE_KEY_UNLOCK();
ret = wc_ecc_export_x963(key, NULL, &pubSz); ret = wc_ecc_export_x963_ex(key, NULL, &pubSz, comp);
PRIVATE_KEY_LOCK(); PRIVATE_KEY_LOCK();
/* LENGTH_ONLY_E on success. */ /* LENGTH_ONLY_E on success. */
if (ret == LENGTH_ONLY_E) { if (ret == LENGTH_ONLY_E) {
@ -22238,7 +22241,7 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
if ((ret == 0) && (output != NULL)) { if ((ret == 0) && (output != NULL)) {
/* Encode public point. */ /* Encode public point. */
PRIVATE_KEY_UNLOCK(); PRIVATE_KEY_UNLOCK();
ret = wc_ecc_export_x963(key, output, &pubSz); ret = wc_ecc_export_x963_ex(key, output, &pubSz, comp);
PRIVATE_KEY_LOCK(); PRIVATE_KEY_LOCK();
} }
if (ret == 0) { if (ret == 0) {
@ -22266,12 +22269,18 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen, int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen,
int with_AlgCurve) int with_AlgCurve)
{ {
return SetEccPublicKey(output, key, inLen, with_AlgCurve); return SetEccPublicKey(output, key, inLen, with_AlgCurve, 0);
}
int wc_EccPublicKeyToDer_ex(ecc_key* key, byte* output, word32 inLen,
int with_AlgCurve, int comp)
{
return SetEccPublicKey(output, key, inLen, with_AlgCurve, comp);
} }
int wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve) int wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve)
{ {
return SetEccPublicKey(NULL, key, 0, with_AlgCurve); return SetEccPublicKey(NULL, key, 0, with_AlgCurve, 0);
} }
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */ #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
@ -24131,7 +24140,7 @@ static int EncodePublicKey(int keyType, byte* output, int outLen,
#endif #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
case ECC_KEY: case ECC_KEY:
ret = SetEccPublicKey(output, eccKey, outLen, 1); ret = SetEccPublicKey(output, eccKey, outLen, 1, 0);
if (ret <= 0) { if (ret <= 0) {
ret = PUBLIC_KEY_E; ret = PUBLIC_KEY_E;
} }
@ -24811,7 +24820,7 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
if (eccKey == NULL) if (eccKey == NULL)
return PUBLIC_KEY_E; return PUBLIC_KEY_E;
der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey,
sizeof(der->publicKey), 1); sizeof(der->publicKey), 1, 0);
} }
#endif #endif
@ -26066,7 +26075,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
if (eccKey == NULL) if (eccKey == NULL)
return PUBLIC_KEY_E; return PUBLIC_KEY_E;
der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey,
sizeof(der->publicKey), 1); sizeof(der->publicKey), 1, 0);
} }
#endif #endif
@ -26799,7 +26808,7 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
#ifdef HAVE_ECC #ifdef HAVE_ECC
/* ECC public key */ /* ECC public key */
if (eckey != NULL) if (eckey != NULL)
bufferSz = SetEccPublicKey(buf, eckey, MAX_PUBLIC_KEY_SZ, 0); bufferSz = SetEccPublicKey(buf, eckey, MAX_PUBLIC_KEY_SZ, 0, 0);
#endif #endif
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
/* ED25519 public key */ /* ED25519 public key */

View File

@ -13715,7 +13715,7 @@ static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen
word32 numlen; word32 numlen;
int ret = MP_OKAY; int ret = MP_OKAY;
if (key == NULL || out == NULL || outLen == NULL) if (key == NULL || outLen == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
if (key->type == ECC_PRIVATEKEY_ONLY) if (key->type == ECC_PRIVATEKEY_ONLY)
@ -13729,9 +13729,12 @@ static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen
if (*outLen < (1 + numlen)) { if (*outLen < (1 + numlen)) {
*outLen = 1 + numlen; *outLen = 1 + numlen;
return BUFFER_E; return LENGTH_ONLY_E;
} }
if (out == NULL)
return BAD_FUNC_ARG;
/* store first byte */ /* store first byte */
out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN; out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;

View File

@ -22571,6 +22571,17 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize)
ERROR_OUT(-9890, done); ERROR_OUT(-9890, done);
} }
#ifdef HAVE_COMP_KEY
/* test export of compressed public key */
derSz = wc_EccPublicKeyToDer_ex(userA, der, ECC_BUFSIZE, 1, 1);
if (derSz < 0) {
ERROR_OUT(derSz, done);
}
if (derSz == 0) {
ERROR_OUT(-9890, done);
}
#endif
ret = SaveDerAndPem(der, derSz, eccPubKeyDerFile, NULL, 0, -8348); ret = SaveDerAndPem(der, derSz, eccPubKeyDerFile, NULL, 0, -8348);
if (ret != 0) { if (ret != 0) {
goto done; goto done;

View File

@ -657,6 +657,9 @@ WOLFSSL_API int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz);
ecc_key* key, word32 inSz); ecc_key* key, word32 inSz);
WOLFSSL_API int wc_EccPublicKeyToDer(ecc_key* key, byte* output, WOLFSSL_API int wc_EccPublicKeyToDer(ecc_key* key, byte* output,
word32 inLen, int with_AlgCurve); word32 inLen, int with_AlgCurve);
WOLFSSL_API int wc_EccPublicKeyToDer_ex(ecc_key* key, byte* output,
word32 inLen, int with_AlgCurve,
int comp);
WOLFSSL_API int wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve); WOLFSSL_API int wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve);
#endif #endif