diff --git a/tests/api.c b/tests/api.c index 856434644..6f9605f09 100644 --- a/tests/api.c +++ b/tests/api.c @@ -122,6 +122,22 @@ #include #endif +#ifndef NO_DSA + #include + #ifndef BYTE1024 + #define BYTE1024 1024 + #endif + #ifndef BYTE2048 + #define BYTE2048 2048 + #endif + #ifndef FOURK_BUF + #define FOURK_BUF 4096 + #endif + #ifndef DSA_SIG_SIZE + #define DSA_SIG_SIZE 40 + #endif +#endif + #ifdef OPENSSL_EXTRA #include #include @@ -8471,6 +8487,379 @@ static int test_wc_Hc128_Process (void) } /* END test_wc_Hc128_Process */ +/* + * Testing wc_InitDsaKey() + */ +static int test_wc_InitDsaKey (void) +{ + int ret = 0; + +#ifndef NO_DSA + DsaKey key; + + printf(testingFmt, "wc_InitDsaKey()"); + + ret = wc_InitDsaKey(&key); + + /* Pass in bad args. */ + if (ret == 0) { + ret = wc_InitDsaKey(NULL); + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else { + ret = SSL_FATAL_ERROR; + } + } + + printf(resultFmt, ret == 0 ? passed : failed); + + wc_FreeDsaKey(&key); + +#endif + return ret; + +} /* END test_wc_InitDsaKey */ + +/* + * Testing wc_DsaSign() and wc_DsaVerify() + */ +static int test_wc_DsaSignVerify (void) +{ + int ret = 0; + +#if !defined(NO_DSA) && (defined(USE_CERT_BUFFERS_1024)\ + || defined(USE_CERT_BUFFERS_2048)) + DsaKey key; + WC_RNG rng; + Sha sha; + byte signature[DSA_SIG_SIZE]; + byte hash[SHA_DIGEST_SIZE]; + word32 idx = 0; + word32 bytes; + int answer; + +#ifdef USE_CERT_BUFFERS_1024 + byte tmp[BYTE1024]; + XMEMCPY(tmp, dsa_key_der_1024, sizeof_dsa_key_der_1024); + bytes = sizeof_dsa_key_der_1024; +#else + byte tmp[BYTE2048]; + XMEMCPY(tmp, dsa_key_der_2048, sizeof_dsa_key_der_2048); + bytes = sizeof_dsa_key_der_2048; +#endif + + ret = wc_InitSha(&sha); + if (ret == 0) { + ret = wc_ShaUpdate(&sha, tmp, bytes); + if (ret == 0) { + ret = wc_ShaFinal(&sha, hash); + } + if (ret == 0) { + ret = wc_InitDsaKey(&key); + } + if (ret == 0) { + ret = wc_DsaPrivateKeyDecode(tmp, &idx, &key, bytes); + } + if (ret == 0) { + ret = wc_InitRng(&rng); + } + } + + printf(testingFmt, "wc_DsaSign()"); + /* Sign. */ + if (ret == 0) { + ret = wc_DsaSign(hash, signature, &key, &rng); + } + + /* Test bad args. */ + if (ret == 0) { + ret = wc_DsaSign(NULL, signature, &key, &rng); + if (ret == BAD_FUNC_ARG) { + ret = wc_DsaSign(hash, NULL, &key, &rng); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_DsaSign(hash, signature, NULL, &rng); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_DsaSign(hash, signature, &key, NULL); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else { + ret = SSL_FATAL_ERROR; + } + } + + printf(resultFmt, ret == 0 ? passed : failed); + + if (ret != 0) { + return ret; + } + + /* Verify. */ + printf(testingFmt, "wc_DsaVerify()"); + + ret = wc_DsaVerify(hash, signature, &key, &answer); + if (ret != 0 || answer != 1) { + ret = SSL_FATAL_ERROR; + } else { + ret = 0; + } + + /* Pass in bad args. */ + if (ret == 0) { + ret = wc_DsaVerify(NULL, signature, &key, &answer); + if (ret == BAD_FUNC_ARG) { + ret = wc_DsaVerify(hash, NULL, &key, &answer); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_DsaVerify(hash, signature, NULL, &answer); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_DsaVerify(hash, signature, &key, NULL); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else { + ret = SSL_FATAL_ERROR; + } + } + + if (wc_FreeRng(&rng) && ret == 0) { + ret = SSL_FATAL_ERROR; + } + + printf(resultFmt, ret == 0 ? passed : failed); + + wc_FreeDsaKey(&key); + wc_ShaFree(&sha); + +#endif + return ret; + +} /* END test_wc_DsaSign */ + +/* + * Testing wc_DsaPrivateKeyDecode() and wc_DsaPublicKeyDecode() + */ +static int test_wc_DsaPublicPrivateKeyDecode (void) +{ + int ret = 0; + +#if !defined(NO_DSA) && (defined(USE_CERT_BUFFERS_1024)\ + || defined(USE_CERT_BUFFERS_2048)) + DsaKey key; + word32 bytes; + word32 idx = 0; + int priv = SSL_FATAL_ERROR; + int pub = SSL_FATAL_ERROR; + +#ifdef USE_CERT_BUFFERS_1024 + byte tmp[BYTE1024]; + XMEMCPY(tmp, dsa_key_der_1024, sizeof_dsa_key_der_1024); + bytes = sizeof_dsa_key_der_1024; +#else + byte tmp[BYTE2048]; + XMEMCPY(tmp, dsa_key_der_2048, sizeof_dsa_key_der_2048); + bytes = sizeof_dsa_key_der_2048; +#endif + + ret = wc_InitDsaKey(&key); + + printf(testingFmt, "wc_DsaPrivateKeyDecode()"); + if (ret == 0) { + priv = wc_DsaPrivateKeyDecode(tmp, &idx, &key, bytes); + + /* Test bad args. */ + if (priv == 0) { + priv = wc_DsaPrivateKeyDecode(NULL, &idx, &key, bytes); + if (priv == BAD_FUNC_ARG) { + priv = wc_DsaPrivateKeyDecode(tmp, NULL, &key, bytes); + } + if (priv == BAD_FUNC_ARG) { + priv = wc_DsaPrivateKeyDecode(tmp, &idx, NULL, bytes); + } + if (priv == BAD_FUNC_ARG) { + priv = wc_DsaPrivateKeyDecode(tmp, &idx, &key, bytes); + } + if (priv == ASN_PARSE_E) { + priv = 0; + } else { + priv = SSL_FATAL_ERROR; + } + } + } /* END Private Key */ + + printf(resultFmt, priv == 0 ? passed : failed); + + printf(testingFmt, "wc_DsaPublicKeyDecode()"); + if (ret == 0) { + idx = 0; /* Reset */ + pub = wc_DsaPublicKeyDecode(tmp, &idx, &key, bytes); + /* Test bad args. */ + if (pub == 0) { + pub = wc_DsaPublicKeyDecode(NULL, &idx, &key, bytes); + if (pub == BAD_FUNC_ARG) { + pub = wc_DsaPublicKeyDecode(tmp, NULL, &key, bytes); + } + if (pub == BAD_FUNC_ARG) { + pub = wc_DsaPublicKeyDecode(tmp, &idx, NULL, bytes); + } + if (pub == BAD_FUNC_ARG) { + pub = wc_DsaPublicKeyDecode(tmp, &idx, &key, bytes); + } + if (pub == ASN_PARSE_E) { + pub = 0; + } else { + pub = SSL_FATAL_ERROR; + } + } + + } /* END Public Key */ + + printf(resultFmt, pub == 0 ? passed : failed); + + wc_FreeDsaKey(&key); + +#endif + return ret; + +} /* END test_wc_DsaPublicPrivateKeyDecode */ + + +/* + * Testing wc_MakeDsaKey() and wc_MakeDsaParameters() + */ +static int test_wc_MakeDsaKey (void) +{ + int ret = 0; + +#if !defined(NO_DSA) && defined(WOLFSSL_KEY_GEN) + DsaKey genKey; + WC_RNG rng; + + ret = wc_InitRng(&rng); + if (ret == 0) { + ret = wc_InitDsaKey(&genKey); + } + + printf(testingFmt, "wc_MakeDsaParameters()"); + if (ret == 0) { + ret = wc_MakeDsaParameters(&rng, BYTE1024, &genKey); + } + /* Test bad args. */ + if (ret == 0) { + ret = wc_MakeDsaParameters(NULL, BYTE1024, &genKey); + if (ret == BAD_FUNC_ARG) { + ret = wc_MakeDsaParameters(&rng, BYTE1024, NULL); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_MakeDsaParameters(&rng, BYTE1024 + 1, &genKey); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else { + ret = SSL_FATAL_ERROR; + } + } + + printf(resultFmt, ret == 0 ? passed : failed); + + printf(testingFmt, "wc_MakeDsaKey()"); + + if (ret == 0) { + ret = wc_MakeDsaKey(&rng, &genKey); + } + + /* Test bad args. */ + if (ret == 0) { + ret = wc_MakeDsaKey(NULL, &genKey); + if (ret == BAD_FUNC_ARG) { + ret = wc_MakeDsaKey(&rng, NULL); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else { + ret = SSL_FATAL_ERROR; + } + } + + if (wc_FreeRng(&rng) && ret == 0) { + ret = SSL_FAILURE; + } + + printf(resultFmt, ret == 0 ? passed : failed); + + wc_FreeDsaKey(&genKey); +#endif + return ret; +} /* END test_wc_MakeDsaKey */ + +/* + * Testing wc_DsaKeyToDer() + */ +static int test_wc_DsaKeyToDer (void) +{ + int ret = 0; + +#if !defined(NO_DSA) && defined(WOLFSSL_KEY_GEN) + DsaKey genKey; + WC_RNG rng; + byte* der = NULL; + + ret = wc_InitRng(&rng); + if (ret == 0) { + ret = wc_InitDsaKey(&genKey); + } + if (ret == 0) { + ret = wc_MakeDsaParameters(&rng, BYTE1024, &genKey); + } + if (ret == 0) { + ret = wc_MakeDsaKey(&rng, &genKey); + } + if (ret == 0) { + der = (byte*)XMALLOC(FOURK_BUF, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (der == NULL) { + ret = SSL_FATAL_ERROR; + } + } + printf(testingFmt, "wc_DsaKeyToDer()"); + + if (ret == 0) { + ret = wc_DsaKeyToDer(&genKey, der, FOURK_BUF); + if (ret >= 0) { + ret = 0; + } else { + ret = SSL_FATAL_ERROR; + } + } + + /* Test bad args. */ + if (ret == 0) { + ret = wc_DsaKeyToDer(NULL, der, FOURK_BUF); + if (ret == BAD_FUNC_ARG) { + ret = wc_DsaKeyToDer(&genKey, NULL, FOURK_BUF); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else { + ret = SSL_FATAL_ERROR; + } + } + + if (wc_FreeRng(&rng) && ret == 0) { + ret = SSL_FATAL_ERROR; + } + + printf(resultFmt, ret == 0 ? passed : failed); + + wc_FreeDsaKey(&genKey); + +#endif + + return ret; + +} /* END test_wc_DsaKeyToDer */ @@ -9993,6 +10382,11 @@ void ApiTest(void) AssertIntEQ(test_wc_AesCcmEncryptDecrypt(), 0); AssertIntEQ(test_wc_Hc128_SetKey(), 0); AssertIntEQ(test_wc_Hc128_Process(), 0); + AssertIntEQ(test_wc_InitDsaKey(), 0); + AssertIntEQ(test_wc_DsaSignVerify(), 0); + AssertIntEQ(test_wc_DsaPublicPrivateKeyDecode(), 0); + AssertIntEQ(test_wc_MakeDsaKey(), 0); + AssertIntEQ(test_wc_DsaKeyToDer(), 0); printf(" End API Tests\n"); } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index e94c131bf..2256c3b0e 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -2943,6 +2943,10 @@ int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key, { int length; + if (input == NULL || inOutIdx == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + if (GetSequence(input, inOutIdx, &length, inSz) < 0) return ASN_PARSE_E; @@ -2962,6 +2966,11 @@ int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key, { int length, version; + /* Sanity checks on input */ + if (input == NULL || inOutIdx == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + if (GetSequence(input, inOutIdx, &length, inSz) < 0) return ASN_PARSE_E; diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index ea092e459..b327d331a 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -366,7 +366,13 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) mp_int k, kInv, r, s, H; int ret, sz; byte buffer[DSA_HALF_SIZE]; - byte* tmp = out; /* initial output pointer */ + byte* tmp; /* initial output pointer */ + + if (digest == NULL || out == NULL || key == NULL || rng == NULL) { + return BAD_FUNC_ARG; + } + + tmp = out; sz = min((int)sizeof(buffer), mp_unsigned_bin_size(&key->q)); @@ -456,6 +462,10 @@ int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer) mp_int w, u1, u2, v, r, s; int ret = 0; + if (digest == NULL || sig == NULL || key == NULL || answer == NULL) { + return BAD_FUNC_ARG; + } + if (mp_init_multi(&w, &u1, &u2, &v, &r, &s) != MP_OKAY) return MP_INIT_E;