mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 12:14:38 +02:00
add DSA 186-4 key generation
This commit is contained in:
@@ -99,64 +99,126 @@ void wc_FreeDsaKey(DsaKey* key)
|
|||||||
|
|
||||||
#ifdef WOLFSSL_KEY_GEN
|
#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
|
||||||
|
* n - represents N, the size of q in bits
|
||||||
|
* return 0 on success, -1 on error */
|
||||||
|
static int CheckDsaLN(int l, int n)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
switch (l) {
|
||||||
|
case 1024:
|
||||||
|
if (n == 160)
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
case 2048:
|
||||||
|
if (n == 224 || n == 256)
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
case 3072:
|
||||||
|
if (n == 256)
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create DSA key pair (&dsa->x, &dsa->y)
|
||||||
|
*
|
||||||
|
* Based on NIST FIPS 186-4,
|
||||||
|
* "B.1.1 Key Pair Generation Using Extra Random Bits"
|
||||||
|
*
|
||||||
|
* rng - pointer to initialized WC_RNG structure
|
||||||
|
* dsa - pointer to initialized DsaKey structure, will hold generated key
|
||||||
|
*
|
||||||
|
* return 0 on success, negative on error */
|
||||||
int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa)
|
int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa)
|
||||||
{
|
{
|
||||||
unsigned char *buf;
|
byte* cBuf;
|
||||||
int qsize, err;
|
int qSz, pSz, cSz, err;
|
||||||
|
mp_int tmpQ;
|
||||||
|
|
||||||
if (rng == NULL || dsa == NULL)
|
if (rng == NULL || dsa == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
qsize = mp_unsigned_bin_size(&dsa->q);
|
qSz = mp_unsigned_bin_size(&dsa->q);
|
||||||
if (qsize == 0)
|
pSz = mp_unsigned_bin_size(&dsa->p);
|
||||||
|
|
||||||
|
/* verify (L,N) pair bit lengths */
|
||||||
|
if (CheckDsaLN(pSz * 8, qSz * 8) != 0)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
/* allocate ram */
|
/* generate extra 64 bits so that bias from mod function is negligible */
|
||||||
buf = (unsigned char *)XMALLOC(qsize, dsa->heap,
|
cSz = qSz + 8;
|
||||||
DYNAMIC_TYPE_TMP_BUFFER);
|
cBuf = (byte*)XMALLOC(cSz, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
if (buf == NULL)
|
if (cBuf == NULL) {
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
|
|
||||||
if (mp_init(&dsa->x) != MP_OKAY) {
|
|
||||||
XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
return MP_INIT_E;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
if ((err = mp_init_multi(&dsa->x, &dsa->y, &tmpQ, NULL, NULL, NULL))
|
||||||
/* make a random exponent mod q */
|
!= MP_OKAY) {
|
||||||
err = wc_RNG_GenerateBlock(rng, buf, qsize);
|
XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
if (err != MP_OKAY) {
|
|
||||||
mp_clear(&dsa->x);
|
|
||||||
XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mp_read_unsigned_bin(&dsa->x, buf, qsize);
|
do {
|
||||||
|
/* generate N+64 bits (c) from RBG into &dsa->x, making sure positive.
|
||||||
|
* Hash_DRBG uses SHA-256 which matches maximum
|
||||||
|
* requested_security_strength of (L,N) */
|
||||||
|
err = wc_RNG_GenerateBlock(rng, cBuf, cSz);
|
||||||
if (err != MP_OKAY) {
|
if (err != MP_OKAY) {
|
||||||
mp_clear(&dsa->x);
|
mp_clear(&dsa->x);
|
||||||
XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
mp_clear(&dsa->y);
|
||||||
|
mp_clear(&tmpQ);
|
||||||
|
XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = mp_read_unsigned_bin(&dsa->x, cBuf, cSz);
|
||||||
|
if (err != MP_OKAY) {
|
||||||
|
mp_clear(&dsa->x);
|
||||||
|
mp_clear(&dsa->y);
|
||||||
|
mp_clear(&tmpQ);
|
||||||
|
XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
} while (mp_cmp_d(&dsa->x, 1) != MP_GT);
|
} while (mp_cmp_d(&dsa->x, 1) != MP_GT);
|
||||||
|
|
||||||
XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
if (mp_init(&dsa->y) != MP_OKAY) {
|
/* tmpQ = q - 1 */
|
||||||
mp_clear(&dsa->x);
|
if (err == MP_OKAY)
|
||||||
return MP_INIT_E;
|
err = mp_copy(&dsa->q, &tmpQ);
|
||||||
}
|
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_sub_d(&tmpQ, 1, &tmpQ);
|
||||||
|
|
||||||
|
/* x = c mod (q-1), &dsa->x holds c */
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_mod(&dsa->x, &tmpQ, &dsa->x);
|
||||||
|
|
||||||
|
/* x = c mod (q-1) + 1 */
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_add_d(&dsa->x, 1, &dsa->x);
|
||||||
|
|
||||||
/* public key : y = g^x mod p */
|
/* public key : y = g^x mod p */
|
||||||
|
if (err == MP_OKAY)
|
||||||
err = mp_exptmod(&dsa->g, &dsa->x, &dsa->p, &dsa->y);
|
err = mp_exptmod(&dsa->g, &dsa->x, &dsa->p, &dsa->y);
|
||||||
|
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
dsa->type = DSA_PRIVATE;
|
||||||
|
|
||||||
if (err != MP_OKAY) {
|
if (err != MP_OKAY) {
|
||||||
mp_clear(&dsa->x);
|
mp_clear(&dsa->x);
|
||||||
mp_clear(&dsa->y);
|
mp_clear(&dsa->y);
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
mp_clear(&tmpQ);
|
||||||
|
|
||||||
dsa->type = DSA_PRIVATE;
|
return err;
|
||||||
|
|
||||||
return MP_OKAY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* modulus_size in bits */
|
/* modulus_size in bits */
|
||||||
|
Reference in New Issue
Block a user