diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index cb392b361..cf02f8457 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -97,7 +97,6 @@ void wc_FreeDsaKey(DsaKey* key) mp_clear(&key->p); } -#ifdef WOLFSSL_KEY_GEN /* validate that (L,N) match allowed sizes from FIPS 186-4, Section 4.2. * l - represents L, the size of p in bits @@ -127,6 +126,9 @@ static int CheckDsaLN(int l, int n) return ret; } + +#ifdef WOLFSSL_KEY_GEN + /* Create DSA key pair (&dsa->x, &dsa->y) * * Based on NIST FIPS 186-4, @@ -221,6 +223,7 @@ int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa) return err; } + /* modulus_size in bits */ int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa) { @@ -423,6 +426,157 @@ int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa) #endif /* WOLFSSL_KEY_GEN */ +/* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(), + * input parameters (p,q,g) should be represented as ASCII hex values. + * + * dsa - pointer to initialized DsaKey structure + * p - DSA (p) parameter, ASCII hex string + * pSz - length of p + * q - DSA (q) parameter, ASCII hex string + * qSz - length of q + * g - DSA (g) parameter, ASCII hex string + * gSz - length of g + * + * returns 0 on success, negative upon failure + */ +int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q, + const char* g) +{ + int err; + word32 pSz, qSz; + + if (dsa == NULL || p == NULL || q == NULL || g == NULL) + return BAD_FUNC_ARG; + + /* read p */ + err = mp_read_radix(&dsa->p, p, MP_RADIX_HEX); + + /* read q */ + if (err == MP_OKAY) + err = mp_read_radix(&dsa->q, q, MP_RADIX_HEX); + + /* read g */ + if (err == MP_OKAY) + err = mp_read_radix(&dsa->g, g, MP_RADIX_HEX); + + /* verify (L,N) pair bit lengths */ + pSz = mp_unsigned_bin_size(&dsa->p); + qSz = mp_unsigned_bin_size(&dsa->q); + + if (CheckDsaLN(pSz * 8, qSz * 8) != 0) { + WOLFSSL_MSG("Invalid DSA p or q parameter size"); + err = BAD_FUNC_ARG; + } + + if (err != MP_OKAY) { + mp_clear(&dsa->p); + mp_clear(&dsa->q); + mp_clear(&dsa->g); + } + + return err; +} + + +/* Export raw DSA parameters from DsaKey structure + * + * dsa - pointer to initialized DsaKey structure + * p - output location for DSA (p) parameter + * pSz - [IN/OUT] size of output buffer for p, size of p + * q - output location for DSA (q) parameter + * qSz - [IN/OUT] size of output buffer for q, size of q + * g - output location for DSA (g) parameter + * gSz - [IN/OUT] size of output buffer for g, size of g + * + * returns 0 on success, negative upon failure + */ +int wc_DsaExportParamsRaw(DsaKey* dsa, byte* p, word32* pSz, + byte* q, word32* qSz, byte* g, word32* gSz) +{ + int err; + word32 tmp; + + if (dsa == NULL || p == NULL || pSz == NULL || q == NULL || + qSz == NULL || g == NULL || gSz == NULL) + return BAD_FUNC_ARG; + + /* export p */ + tmp = mp_unsigned_bin_size(&dsa->p); + if (*pSz < tmp) { + WOLFSSL_MSG("Output buffer for DSA p parameter too small"); + return BUFFER_E; + } + *pSz = tmp; + err = mp_to_unsigned_bin(&dsa->p, p); + + /* export q */ + if (err == MP_OKAY) { + tmp = mp_unsigned_bin_size(&dsa->q); + if (*qSz < tmp) { + WOLFSSL_MSG("Output buffer to DSA q parameter too small"); + return BUFFER_E; + } + *qSz = tmp; + err = mp_to_unsigned_bin(&dsa->q, q); + } + + /* export g */ + if (err == MP_OKAY) { + tmp = mp_unsigned_bin_size(&dsa->g); + if (*gSz < tmp) { + WOLFSSL_MSG("Output buffer to DSA g parameter too small"); + return BUFFER_E; + } + *gSz = tmp; + err = mp_to_unsigned_bin(&dsa->g, g); + } + + return err; +} + + +/* Export raw DSA key (x, y) from DsaKey structure + * + * dsa - pointer to initialized DsaKey structure + * x - output location for private key + * xSz - [IN/OUT] size of output buffer for x, size of x + * y - output location for public key + * ySz - [IN/OUT] size of output buffer for y, size of y + * + * returns 0 on success, negative upon failure + */ +int wc_DsaExportKeyRaw(DsaKey* dsa, byte* x, word32* xSz, byte* y, word32* ySz) +{ + int err; + word32 tmp; + + if (dsa == NULL || x == NULL || xSz == NULL || y == NULL || ySz == NULL) + return BAD_FUNC_ARG; + + /* export x */ + tmp = mp_unsigned_bin_size(&dsa->x); + if (*xSz < tmp) { + WOLFSSL_MSG("Output buffer for DSA private key (x) too small"); + return BUFFER_E; + } + *xSz = tmp; + err = mp_to_unsigned_bin(&dsa->x, x); + + /* export y */ + if (err == MP_OKAY) { + tmp = mp_unsigned_bin_size(&dsa->y); + if (*ySz < tmp) { + WOLFSSL_MSG("Output buffer to DSA public key (y) too small"); + return BUFFER_E; + } + *ySz = tmp; + err = mp_to_unsigned_bin(&dsa->y, y); + } + + return err; +} + + int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) { mp_int k, kInv, r, s, H; diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 68cc91a72..a42faaecb 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -4729,15 +4729,16 @@ LBL_U:mp_clear (&v); #endif /* WOLFSSL_KEY_GEN */ -#if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \ - defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) +#if !defined(NO_DSA) || defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || \ + defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) || \ + defined(DEBUG_WOLFSSL) /* chars used in radix conversions */ const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\ abcdefghijklmnopqrstuvwxyz+/"; #endif -#ifdef HAVE_ECC +#if !defined(NO_DSA) || defined(HAVE_ECC) /* read a string [ASCII] in a given radix */ int mp_read_radix (mp_int * a, const char *str, int radix) { @@ -4807,7 +4808,7 @@ int mp_read_radix (mp_int * a, const char *str, int radix) } return MP_OKAY; } -#endif /* HAVE_ECC */ +#endif /* !defined(NO_DSA) || defined(HAVE_ECC) */ #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \ defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 81edccd0b..98ec9b13f 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -3076,15 +3076,16 @@ int mp_add_d(fp_int *a, fp_digit b, fp_int *c) #endif /* HAVE_ECC || !NO_PWDBASED */ -#if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \ - defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) +#if !defined(NO_DSA) || defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || \ + defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) || \ + defined(DEBUG_WOLFSSL) /* chars used in radix conversions */ static const char* const fp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz+/"; #endif -#ifdef HAVE_ECC +#if !defined(NO_DSA) || defined(HAVE_ECC) #if DIGIT_BIT == 64 || DIGIT_BIT == 32 static int fp_read_radix_16(fp_int *a, const char *str) { @@ -3197,6 +3198,10 @@ int mp_read_radix(mp_int *a, const char *str, int radix) return fp_read_radix(a, str, radix); } +#endif /* !defined(NO_DSA) || defined(HAVE_ECC) */ + +#ifdef HAVE_ECC + /* fast math conversion */ int mp_sqr(fp_int *A, fp_int *B) { diff --git a/wolfssl/wolfcrypt/dsa.h b/wolfssl/wolfcrypt/dsa.h index 1dc738df6..19d19bc6a 100644 --- a/wolfssl/wolfcrypt/dsa.h +++ b/wolfssl/wolfcrypt/dsa.h @@ -74,6 +74,14 @@ WOLFSSL_API int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa); WOLFSSL_API int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa); #endif +/* raw export functions */ +WOLFSSL_API int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, + const char* q, const char* g); +WOLFSSL_API int wc_DsaExportParamsRaw(DsaKey* dsa, byte* p, word32* pSz, + byte* q, word32* qSz, byte* g, + word32* gSz); +WOLFSSL_API int wc_DsaExportKeyRaw(DsaKey* dsa, byte* x, word32* xSz, byte* y, + word32* ySz); #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/wolfcrypt/integer.h b/wolfssl/wolfcrypt/integer.h index 7b7c5c04a..f35c08bb0 100644 --- a/wolfssl/wolfcrypt/integer.h +++ b/wolfssl/wolfcrypt/integer.h @@ -364,7 +364,7 @@ MP_API int mp_radix_size (mp_int * a, int radix, int *size); #if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) MP_API int mp_sqrmod(mp_int* a, mp_int* b, mp_int* c); #endif -#if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) +#if !defined(NO_DSA) || defined(HAVE_ECC) MP_API int mp_read_radix(mp_int* a, const char* str, int radix); #endif diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index e0432311b..205302050 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -703,8 +703,11 @@ MP_API int mp_radix_size (mp_int * a, int radix, int *size); #define mp_dump(desc, a, verbose) #endif -#ifdef HAVE_ECC +#if !defined(NO_DSA) || defined(HAVE_ECC) MP_API int mp_read_radix(mp_int* a, const char* str, int radix); +#endif + +#ifdef HAVE_ECC MP_API int mp_sqr(fp_int *a, fp_int *b); MP_API int mp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp); MP_API int mp_montgomery_setup(fp_int *a, fp_digit *rho); diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index f3faad367..317abce36 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -350,7 +350,8 @@ #ifndef CTYPE_USER #include - #if defined(HAVE_ECC) || defined(HAVE_OCSP) || defined(WOLFSSL_KEY_GEN) + #if defined(HAVE_ECC) || defined(HAVE_OCSP) || \ + defined(WOLFSSL_KEY_GEN) || !defined(NO_DSA) #define XTOUPPER(c) toupper((c)) #define XISALPHA(c) isalpha((c)) #endif