Merge pull request #3931 from julek-wolfssl/dsa-engine

Add more DSA parameters support
This commit is contained in:
Chris Conlon
2021-05-24 14:57:02 -06:00
committed by GitHub
3 changed files with 82 additions and 24 deletions

View File

@@ -4714,6 +4714,7 @@ int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
int length;
int ret = 0;
word32 oid;
word32 maxIdx;
if (input == NULL || inOutIdx == NULL || key == NULL)
return BAD_FUNC_ARG;
@@ -4721,10 +4722,11 @@ int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E;
if (GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
GetInt(&key->q, input, inOutIdx, inSz) < 0 ||
GetInt(&key->g, input, inOutIdx, inSz) < 0 ||
GetInt(&key->y, input, inOutIdx, inSz) < 0 )
maxIdx = (word32)(*inOutIdx + length);
if (GetInt(&key->p, input, inOutIdx, maxIdx) < 0 ||
GetInt(&key->q, input, inOutIdx, maxIdx) < 0 ||
GetInt(&key->g, input, inOutIdx, maxIdx) < 0 ||
GetInt(&key->y, input, inOutIdx, maxIdx) < 0 )
ret = ASN_DH_KEY_E;
if (ret != 0) {
@@ -4756,6 +4758,27 @@ int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
return ret;
}
int wc_DsaParamsDecode(const byte* input, word32* inOutIdx, DsaKey* key,
word32 inSz)
{
int length;
word32 maxIdx;
if (input == NULL || inOutIdx == NULL || key == NULL)
return BAD_FUNC_ARG;
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E;
maxIdx = (word32)(*inOutIdx + length);
if (GetInt(&key->p, input, inOutIdx, maxIdx) < 0 ||
GetInt(&key->q, input, inOutIdx, maxIdx) < 0 ||
GetInt(&key->g, input, inOutIdx, maxIdx) < 0)
return ASN_DH_KEY_E;
return 0;
}
int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
word32 inSz)
@@ -4834,6 +4857,7 @@ int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
static mp_int* GetDsaInt(DsaKey* key, int idx)
{
/* Other functions depend on this order. Please don't change it. */
if (idx == 0)
return &key->p;
if (idx == 1)
@@ -4849,11 +4873,11 @@ static mp_int* GetDsaInt(DsaKey* key, int idx)
}
/* Release Tmp DSA resources */
static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap)
static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap, int ints)
{
int i;
for (i = 0; i < DSA_INTS; i++)
for (i = 0; i < ints; i++)
XFREE(tmps[i], heap, DYNAMIC_TYPE_DSA);
(void)heap;
@@ -5053,11 +5077,10 @@ int wc_DsaKeyToPublicDer(DsaKey* key, byte* output, word32 inLen)
}
#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) */
/* Convert private DsaKey key to DER format, write to output (inLen),
return bytes written */
int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
static int DsaKeyIntsToDer(DsaKey* key, byte* output, word32 inLen,
int ints, int includeVersion)
{
word32 seqSz, verSz, rawLen, intTotalLen = 0;
word32 seqSz = 0, verSz = 0, rawLen, intTotalLen = 0;
word32 sizes[DSA_INTS];
int i, j, outLen, ret = 0, mpSz;
@@ -5065,17 +5088,14 @@ int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
byte ver[MAX_VERSION_SZ];
byte* tmps[DSA_INTS];
if (!key || !output)
if (ints > DSA_INTS)
return BAD_FUNC_ARG;
if (key->type != DSA_PRIVATE)
return BAD_FUNC_ARG;
for (i = 0; i < DSA_INTS; i++)
for (i = 0; i < ints; i++)
tmps[i] = NULL;
/* write all big ints from key to DER tmps */
for (i = 0; i < DSA_INTS; i++) {
for (i = 0; i < ints; i++) {
mp_int* keyInt = GetDsaInt(key, i);
rawLen = mp_unsigned_bin_size(keyInt) + 1;
@@ -5095,35 +5115,62 @@ int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
}
if (ret != 0) {
FreeTmpDsas(tmps, key->heap);
FreeTmpDsas(tmps, key->heap, ints);
return ret;
}
/* make headers */
verSz = SetMyVersion(0, ver, FALSE);
if (includeVersion)
verSz = SetMyVersion(0, ver, FALSE);
seqSz = SetSequence(verSz + intTotalLen, seq);
outLen = seqSz + verSz + intTotalLen;
if (outLen > (int)inLen) {
FreeTmpDsas(tmps, key->heap);
FreeTmpDsas(tmps, key->heap, ints);
return BAD_FUNC_ARG;
}
/* write to output */
XMEMCPY(output, seq, seqSz);
j = seqSz;
XMEMCPY(output + j, ver, verSz);
j += verSz;
if (includeVersion) {
XMEMCPY(output + j, ver, verSz);
j += verSz;
}
for (i = 0; i < DSA_INTS; i++) {
for (i = 0; i < ints; i++) {
XMEMCPY(output + j, tmps[i], sizes[i]);
j += sizes[i];
}
FreeTmpDsas(tmps, key->heap);
FreeTmpDsas(tmps, key->heap, ints);
return outLen;
}
/* Convert private DsaKey key to DER format, write to output (inLen),
return bytes written */
int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
{
if (!key || !output)
return BAD_FUNC_ARG;
if (key->type != DSA_PRIVATE)
return BAD_FUNC_ARG;
return DsaKeyIntsToDer(key, output, inLen, DSA_INTS, 1);
}
/* Convert DsaKey parameters to DER format, write to output (inLen),
return bytes written. Version is excluded to be compatible with
OpenSSL d2i_DSAparams */
int wc_DsaKeyToParamsDer(DsaKey* key, byte* output, word32 inLen)
{
if (!key || !output)
return BAD_FUNC_ARG;
return DsaKeyIntsToDer(key, output, inLen, DSA_PARAM_INTS, 0);
}
#endif /* NO_DSA */
void InitDecodedCert(DecodedCert* cert,

View File

@@ -198,6 +198,7 @@ extern const WOLFSSL_ObjectInfo wolfssl_object_info[];
#define WOLFSSL_TLS_FEATURE_SUM 92
#endif
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
/* NIDs */
enum
{
@@ -257,6 +258,7 @@ enum
NID_X9_62_prime_field = 406 /* 1.2.840.10045.1.1 */
};
#endif /* OPENSSL_EXTRA */
enum ECC_TYPES
{
@@ -308,6 +310,7 @@ enum Misc_ASN {
KEYID_SIZE = WC_SHA_DIGEST_SIZE,
#endif
RSA_INTS = 8, /* RSA ints in private key */
DSA_PARAM_INTS = 3, /* DSA paramater ints */
DSA_INTS = 5, /* DSA ints in private key */
MIN_DATE_SIZE = 12,
MAX_DATE_SIZE = 32,
@@ -333,7 +336,7 @@ enum Misc_ASN {
MAX_ENCODED_DIG_ASN_SZ= 9, /* enum(bit or octet) + length(4) */
MAX_ENCODED_DIG_SZ = 64 + MAX_ENCODED_DIG_ASN_SZ, /* asn header + sha512 */
MAX_RSA_INT_SZ = 517, /* RSA raw sz 4096 for bits + tag + len(4) */
MAX_DSA_INT_SZ = 261, /* DSA raw sz 2048 for bits + tag + len(4) */
MAX_DSA_INT_SZ = 389, /* DSA raw sz 3072 for bits + tag + len(4) */
MAX_NTRU_KEY_SZ = 610, /* NTRU 112 bit public key */
MAX_NTRU_ENC_SZ = 628, /* NTRU 112 bit DER public encoding */
MAX_LENGTH_SZ = 4, /* Max length size for DER encoding */

View File

@@ -32,6 +32,7 @@ This library defines the interface APIs for X509 certificates.
#define WOLF_CRYPT_ASN_PUBLIC_H
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/dsa.h>
#ifdef __cplusplus
extern "C" {
@@ -509,6 +510,13 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer);
WOLFSSL_API int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header);
#endif
#ifndef NO_DSA
/* DSA parameter DER helper functions */
WOLFSSL_API int wc_DsaParamsDecode(const byte* input, word32* inOutIdx,
DsaKey*, word32);
WOLFSSL_API int wc_DsaKeyToParamsDer(DsaKey* key, byte* output, word32 inLen);
#endif
#ifdef HAVE_ECC
/* private key helpers */
WOLFSSL_API int wc_EccPrivateKeyDecode(const byte*, word32*,