From 4f8fffbc37c5cc8073d6b498e32aca628dff19ab Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 1 Apr 2016 10:43:45 -0600 Subject: [PATCH 1/2] add wc_EccPublicKeyToDer function --- .gitignore | 1 + wolfcrypt/src/asn.c | 37 ++++++++++++++++++++++++++++++---- wolfcrypt/test/test.c | 20 ++++++++++++++++++ wolfssl/wolfcrypt/asn_public.h | 4 ++++ 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 999db3fe8..47c38e3f1 100644 --- a/.gitignore +++ b/.gitignore @@ -71,6 +71,7 @@ ntru-cert.pem ntru-key.raw key.der key.pem +ecc-public-key.der ecc-key.der ecc-key.pem certreq.der diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 25f5450dc..53c84c198 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5877,9 +5877,8 @@ static int SetSerial(const byte* serial, byte* output) return length + CTC_SERIAL_SIZE; } - -#ifdef HAVE_ECC - +#endif /* defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA) */ +#if defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) /* Write a public ECC key to output */ static int SetEccPublicKey(byte* output, ecc_key* key, int with_header) @@ -5978,8 +5977,38 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int with_header) } -#endif /* HAVE_ECC */ +/* returns the size of buffer used, the public ECC key in DER format is stored + in output buffer + with_AlgCurve is a flag for when to include a header that has the Algorithm + and Curve infromation */ +int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen, + int with_AlgCurve) +{ + word32 infoSz = 0; + if (output == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + + if (with_AlgCurve) { + int maxSetLength = 4; /* max buffer space needed for SetLength */ + int asnBit = 1; /* buffer space needed for asn bit string macro */ + + infoSz += asnBit; + infoSz += maxSetLength + asnBit; /* SetSequence buffer needed */ + infoSz += 2 * MAX_ALGO_SZ; /* buffer space for algorithm/curve */ + infoSz += asnBit; + infoSz += maxSetLength; + } + + if (inLen < wc_ecc_size(key) + infoSz) { + return BAD_FUNC_ARG; + } + + return SetEccPublicKey(output, key, with_AlgCurve); +} +#endif /* HAVE_ECC && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */ +#if defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA) static INLINE byte itob(int number) { diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 741d4da36..97cf2b888 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -5001,6 +5001,7 @@ int rsa_test(void) free(tmp); return -5415; } + fclose(pemFile); free(pem); free(derCert); @@ -6486,6 +6487,25 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize) return -1029; } + /* test export of public key */ + derSz = wc_EccPublicKeyToDer(&userA, der, FOURK_BUF, 1); + if (derSz <= 0) { + return -5516; + } +#ifdef FREESCALE_MQX + keyFile = fopen("a:\\certs\\ecc-public-key.der", "wb"); +#else + keyFile = fopen("./ecc-public-key.der", "wb"); +#endif + if (!keyFile) { + return -5417; + } + ret = (int)fwrite(der, 1, derSz, keyFile); + fclose(keyFile); + if (ret != derSz) { + return -5418; + } + wc_ecc_free(&userA); return 0; diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 4fdaf7005..1e8d4634b 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -259,6 +259,10 @@ WOLFSSL_API int wc_SetCertificatePolicies(Cert *cert, const char **input); /* public key helper */ WOLFSSL_API int wc_EccPublicKeyDecode(const byte*, word32*, ecc_key*, word32); + #if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) + WOLFSSL_API int wc_EccPublicKeyToDer(ecc_key*, byte* output, + word32 inLen, int with_AlgCurve); + #endif #endif /* DER encode signature */ From 665fb3076ce9b8a6f26c50a422570252f8a24849 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Mon, 4 Apr 2016 17:47:11 -0600 Subject: [PATCH 2/2] add trailing zero enum and correct call for export key size --- wolfcrypt/src/asn.c | 28 +++++++++++++++++----------- wolfssl/wolfcrypt/asn.h | 3 ++- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 53c84c198..c68d5c645 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5883,7 +5883,7 @@ static int SetSerial(const byte* serial, byte* output) /* Write a public ECC key to output */ static int SetEccPublicKey(byte* output, ecc_key* key, int with_header) { - byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */ + byte len[MAX_LENGTH_SZ + TRAILING_ZERO]; int algoSz; int curveSz; int lenSz; @@ -5941,7 +5941,7 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int with_header) #endif algoSz = SetAlgoID(ECDSAk, algo, oidKeyType, curveSz); - lenSz = SetLength(pubSz + 1, len); + lenSz = SetLength(pubSz + TRAILING_ZERO, len); len[lenSz++] = 0; /* trailing 0 */ /* write, 1 is for ASN_BIT_STRING */ @@ -5985,24 +5985,30 @@ int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen, int with_AlgCurve) { word32 infoSz = 0; + word32 keySz = 0; + int ret; if (output == NULL || key == NULL) { return BAD_FUNC_ARG; } if (with_AlgCurve) { - int maxSetLength = 4; /* max buffer space needed for SetLength */ - int asnBit = 1; /* buffer space needed for asn bit string macro */ + /* buffer space for algorithm/curve */ + infoSz += MAX_SEQ_SZ; + infoSz += 2 * MAX_ALGO_SZ; - infoSz += asnBit; - infoSz += maxSetLength + asnBit; /* SetSequence buffer needed */ - infoSz += 2 * MAX_ALGO_SZ; /* buffer space for algorithm/curve */ - infoSz += asnBit; - infoSz += maxSetLength; + /* buffer space for public key sequence */ + infoSz += MAX_SEQ_SZ; + infoSz += TRAILING_ZERO; } - if (inLen < wc_ecc_size(key) + infoSz) { - return BAD_FUNC_ARG; + if ((ret = wc_ecc_export_x963(key, NULL, &keySz)) != LENGTH_ONLY_E) { + WOLFSSL_MSG("Error in getting ECC public key size"); + return ret; + } + + if (inLen < keySz + infoSz) { + return BUFFER_E; } return SetEccPublicKey(output, key, with_AlgCurve); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 50d0c6c4f..dd54ffb5b 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -195,7 +195,8 @@ enum Misc_ASN { EIGHTK_BUF = 8192, /* Tmp buffer size */ MAX_PUBLIC_KEY_SZ = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2, /* use bigger NTRU size */ - HEADER_ENCRYPTED_KEY_SIZE = 88 /* Extra header size for encrypted key */ + HEADER_ENCRYPTED_KEY_SIZE = 88,/* Extra header size for encrypted key */ + TRAILING_ZERO = 1 /* Used for size of zero pad */ };