allow DSA raw export functions to return buffer sizes

This commit is contained in:
Chris Conlon
2018-01-10 10:21:58 -07:00
parent 09bb2e5837
commit d78a6cebd8
2 changed files with 70 additions and 28 deletions

View File

@@ -10828,7 +10828,7 @@ static int test_wc_DsaExportParamsRaw (void)
NULL, &gOutSz); NULL, &gOutSz);
} }
if (ret == BAD_FUNC_ARG) { if (ret == LENGTH_ONLY_E) {
/* null output size pointers */ /* null output size pointers */
ret = wc_DsaExportParamsRaw(&key, pOut, NULL, qOut, NULL, ret = wc_DsaExportParamsRaw(&key, pOut, NULL, qOut, NULL,
gOut, NULL); gOut, NULL);
@@ -10877,7 +10877,7 @@ static int test_wc_DsaExportKeyRaw (void)
{ {
int ret = 0; int ret = 0;
#if !defined(NO_DSA) && defined(HAVE_KEY_GEN) #if !defined(NO_DSA) && defined(WOLFSSL_KEY_GEN)
DsaKey key; DsaKey key;
WC_RNG rng; WC_RNG rng;
@@ -10917,7 +10917,7 @@ static int test_wc_DsaExportKeyRaw (void)
ret = wc_DsaExportKeyRaw(&key, NULL, &xOutSz, NULL, &yOutSz); ret = wc_DsaExportKeyRaw(&key, NULL, &xOutSz, NULL, &yOutSz);
} }
if (ret == BAD_FUNC_ARG) { if (ret == LENGTH_ONLY_E) {
/* null output size pointers */ /* null output size pointers */
ret = wc_DsaExportKeyRaw(&key, xOut, NULL, yOut, NULL); ret = wc_DsaExportKeyRaw(&key, xOut, NULL, yOut, NULL);
} }

View File

@@ -488,46 +488,68 @@ int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q,
* g - output location for DSA (g) parameter * g - output location for DSA (g) parameter
* gSz - [IN/OUT] size of output buffer for g, size of g * gSz - [IN/OUT] size of output buffer for g, size of g
* *
* If p, q, and g pointers are all passed in as NULL, the function
* will set pSz, qSz, and gSz to the required output buffer sizes for p,
* q, and g. In this case, the function will return LENGTH_ONLY_E.
*
* returns 0 on success, negative upon failure * returns 0 on success, negative upon failure
*/ */
int wc_DsaExportParamsRaw(DsaKey* dsa, byte* p, word32* pSz, int wc_DsaExportParamsRaw(DsaKey* dsa, byte* p, word32* pSz,
byte* q, word32* qSz, byte* g, word32* gSz) byte* q, word32* qSz, byte* g, word32* gSz)
{ {
int err; int err;
word32 tmp; word32 pLen, qLen, gLen;
if (dsa == NULL || p == NULL || pSz == NULL || q == NULL || if (dsa == NULL || pSz == NULL || qSz == NULL || gSz == NULL)
qSz == NULL || g == NULL || gSz == NULL) return BAD_FUNC_ARG;
/* get required output buffer sizes */
pLen = mp_unsigned_bin_size(&dsa->p);
qLen = mp_unsigned_bin_size(&dsa->q);
gLen = mp_unsigned_bin_size(&dsa->g);
/* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
if (p == NULL && q == NULL && g == NULL) {
*pSz = pLen;
*qSz = qLen;
*gSz = gLen;
return LENGTH_ONLY_E;
}
if (p == NULL || q == NULL || g == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
/* export p */ /* export p */
tmp = mp_unsigned_bin_size(&dsa->p); if (*pSz < pLen) {
if (*pSz < tmp) { WOLFSSL_MSG("Output buffer for DSA p parameter too small, "
WOLFSSL_MSG("Output buffer for DSA p parameter too small"); "required size placed into pSz");
*pSz = pLen;
return BUFFER_E; return BUFFER_E;
} }
*pSz = tmp; *pSz = pLen;
err = mp_to_unsigned_bin(&dsa->p, p); err = mp_to_unsigned_bin(&dsa->p, p);
/* export q */ /* export q */
if (err == MP_OKAY) { if (err == MP_OKAY) {
tmp = mp_unsigned_bin_size(&dsa->q); if (*qSz < qLen) {
if (*qSz < tmp) { WOLFSSL_MSG("Output buffer for DSA q parameter too small, "
WOLFSSL_MSG("Output buffer to DSA q parameter too small"); "required size placed into qSz");
*qSz = qLen;
return BUFFER_E; return BUFFER_E;
} }
*qSz = tmp; *qSz = qLen;
err = mp_to_unsigned_bin(&dsa->q, q); err = mp_to_unsigned_bin(&dsa->q, q);
} }
/* export g */ /* export g */
if (err == MP_OKAY) { if (err == MP_OKAY) {
tmp = mp_unsigned_bin_size(&dsa->g); if (*gSz < gLen) {
if (*gSz < tmp) { WOLFSSL_MSG("Output buffer for DSA g parameter too small, "
WOLFSSL_MSG("Output buffer to DSA g parameter too small"); "required size placed into gSz");
*gSz = gLen;
return BUFFER_E; return BUFFER_E;
} }
*gSz = tmp; *gSz = gLen;
err = mp_to_unsigned_bin(&dsa->g, g); err = mp_to_unsigned_bin(&dsa->g, g);
} }
@@ -543,33 +565,53 @@ int wc_DsaExportParamsRaw(DsaKey* dsa, byte* p, word32* pSz,
* y - output location for public key * y - output location for public key
* ySz - [IN/OUT] size of output buffer for y, size of y * ySz - [IN/OUT] size of output buffer for y, size of y
* *
* If x and y pointers are all passed in as NULL, the function
* will set xSz and ySz to the required output buffer sizes for x
* and y. In this case, the function will return LENGTH_ONLY_E.
*
* returns 0 on success, negative upon failure * returns 0 on success, negative upon failure
*/ */
int wc_DsaExportKeyRaw(DsaKey* dsa, byte* x, word32* xSz, byte* y, word32* ySz) int wc_DsaExportKeyRaw(DsaKey* dsa, byte* x, word32* xSz, byte* y, word32* ySz)
{ {
int err; int err;
word32 tmp; word32 xLen, yLen;
if (dsa == NULL || x == NULL || xSz == NULL || y == NULL || ySz == NULL) if (dsa == NULL || xSz == NULL || ySz == NULL)
return BAD_FUNC_ARG;
/* get required output buffer sizes */
xLen = mp_unsigned_bin_size(&dsa->x);
yLen = mp_unsigned_bin_size(&dsa->y);
/* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
if (x == NULL && y == NULL) {
*xSz = xLen;
*ySz = yLen;
return LENGTH_ONLY_E;
}
if (x == NULL || y == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
/* export x */ /* export x */
tmp = mp_unsigned_bin_size(&dsa->x); if (*xSz < xLen) {
if (*xSz < tmp) { WOLFSSL_MSG("Output buffer for DSA private key (x) too small, "
WOLFSSL_MSG("Output buffer for DSA private key (x) too small"); "required size placed into xSz");
*xSz = xLen;
return BUFFER_E; return BUFFER_E;
} }
*xSz = tmp; *xSz = xLen;
err = mp_to_unsigned_bin(&dsa->x, x); err = mp_to_unsigned_bin(&dsa->x, x);
/* export y */ /* export y */
if (err == MP_OKAY) { if (err == MP_OKAY) {
tmp = mp_unsigned_bin_size(&dsa->y); if (*ySz < yLen) {
if (*ySz < tmp) { WOLFSSL_MSG("Output buffer to DSA public key (y) too small, "
WOLFSSL_MSG("Output buffer to DSA public key (y) too small"); "required size placed into ySz");
*ySz = yLen;
return BUFFER_E; return BUFFER_E;
} }
*ySz = tmp; *ySz = yLen;
err = mp_to_unsigned_bin(&dsa->y, y); err = mp_to_unsigned_bin(&dsa->y, y);
} }