Fixes for DH Pub key import/export and new test case. Improve wc_DhParamsToDer
.
This commit is contained in:
parent
6db0b42c7f
commit
9b215c5138
BIN
certs/statickeys/dh-ffdhe2048-pub.der
Normal file
BIN
certs/statickeys/dh-ffdhe2048-pub.der
Normal file
Binary file not shown.
14
certs/statickeys/dh-ffdhe2048-pub.pem
Normal file
14
certs/statickeys/dh-ffdhe2048-pub.pem
Normal file
@ -0,0 +1,14 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIICJDCCARcGCSqGSIb3DQEDATCCAQgCggEBAP//////////rfhUWKK7Spqv3FYg
|
||||
Jz088di5xYPOLTaVqeE2QRRkM/vMk53OJJs++X0v42NjDHXY9oGyAq7EYXrT3x7V
|
||||
1f1lYSQz9R9fBm7QhWNlVT3tGvO1VxNef1fJNZhPDHDg5ot34qaJ2vPv6HId8Vih
|
||||
Nq3nNTCsyk9IOnl6vAqxgrMk+2HRCKlLssjj+7lq2rdg1/RoHU9Co945TfSuVu3n
|
||||
Y3K7GQsHp8juCm1wngL84c334uzANATNKDQvYZFy/pzphYP/jk8SMu7ygYPD/jsb
|
||||
TG+tczu1/LwuwiAFxY7xg30Wg7LG80omwbLv+ohrQjhhKFyX//////////8CAQID
|
||||
ggEFAAKCAQBNP0zkbEZx/2ECcwtlT0bnLg+eQQRVQVGJqV6EvHoKNTQVvrHDHs3H
|
||||
WheYX/+WPRub+swfHqcii5XuK9R04mPi/ZyqT75kaYMxXpBchV2ymeAFtfK2Gc0G
|
||||
zaizWY2HhH+PCe69YW/FzbicpxWX0EQuLS4yIMU731BvjRe4hKNnJH6j7IwIeGwl
|
||||
iALToGjOGiVGLptMgvTrs8kdFwySlFQPtd8/cUUzl02HGktACnG0Gb4zvc/zFWMG
|
||||
N1yhncDnp4vToms/8ULINmsKQ4vp0IzNDzHNIuc5yI3rXZGLBm4fB9urK0+F+LtV
|
||||
471wUVxzZl3RtvhEEODyCRxtAl38egiC
|
||||
-----END PUBLIC KEY-----
|
@ -10,3 +10,7 @@ openssl ec -inform pem -in certs/statickeys/ecc-secp256r1.pem -outform der -out
|
||||
# Using one generated and capture with wolfSSL using wc_DhGenerateKeyPair (openssl generates DH keys with 2048-bits... based on the DH "p" prime size)
|
||||
#openssl genpkey -paramfile certs/statickeys/dh-ffdhe2048-params.pem -out certs/statickeys/dh-ffdhe2048.der
|
||||
openssl pkey -inform der -in certs/statickeys/dh-ffdhe2048.der -outform pem -out certs/statickeys/dh-ffdhe2048.pem
|
||||
openssl pkey -inform der -in certs/statickeys/dh-ffdhe2048.der -outform der -out certs/statickeys/dh-ffdhe2048-pub.der -pubout
|
||||
# Export DH public key as DER and convert to PEM
|
||||
openssl pkey -inform der -in certs/statickeys/dh-ffdhe2048-pub.der -outform pem -out certs/statickeys/dh-ffdhe2048-pub.pem
|
||||
openssl pkey -inform der -in certs/statickeys/dh-ffdhe2048-pub.der -outform pem -out certs/statickeys/dh-ffdhe2048-pub.pem -pubin
|
||||
|
@ -14,4 +14,6 @@ EXTRA_DIST += \
|
||||
EXTRA_DIST += \
|
||||
certs/statickeys/dh-ffdhe2048-params.pem \
|
||||
certs/statickeys/dh-ffdhe2048.der \
|
||||
certs/statickeys/dh-ffdhe2048.pem
|
||||
certs/statickeys/dh-ffdhe2048.pem \
|
||||
certs/statickeys/dh-ffdhe2048-pub.der \
|
||||
certs/statickeys/dh-ffdhe2048-pub.pem
|
||||
|
@ -4731,11 +4731,10 @@ int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
|
||||
if (ret == ASN_DH_KEY_E) {
|
||||
*inOutIdx = temp;
|
||||
|
||||
/* the version (0) */
|
||||
if (GetASNInt(input, inOutIdx, &length, inSz) < 0) {
|
||||
return ASN_PARSE_E;
|
||||
/* the version (0) - private only (for public skip) */
|
||||
if (GetASNInt(input, inOutIdx, &length, inSz) == 0) {
|
||||
*inOutIdx += length;
|
||||
}
|
||||
*inOutIdx += length;
|
||||
|
||||
/* Size of dhKeyAgreement section */
|
||||
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
|
||||
@ -4796,7 +4795,7 @@ int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
|
||||
/* Export DH Key (private or public) */
|
||||
int wc_DhKeyToDer(DhKey* key, byte* output, word32* outSz, int exportPriv)
|
||||
{
|
||||
int privSz = 0, pubSz = 0, keySz;
|
||||
int ret, privSz = 0, pubSz = 0, keySz;
|
||||
word32 idx, total;
|
||||
|
||||
if (key == NULL || outSz == NULL) {
|
||||
@ -4815,19 +4814,23 @@ int wc_DhKeyToDer(DhKey* key, byte* output, word32* outSz, int exportPriv)
|
||||
idx = 1 + SetLength(pubSz, NULL) + pubSz; /* +1 for ASN_BIT_STRING */
|
||||
}
|
||||
keySz = idx;
|
||||
/* integer - g */
|
||||
idx += SetASNIntMP(&key->g, -1, NULL);
|
||||
/* integer - p */
|
||||
idx += SetASNIntMP(&key->p, -1, NULL);
|
||||
/* sequence */
|
||||
idx += SetSequence(idx, NULL);
|
||||
|
||||
/* DH Parameters sequence with P and G */
|
||||
total = 0;
|
||||
ret = wc_DhParamsToDer(key, NULL, &total);
|
||||
if (ret != LENGTH_ONLY_E)
|
||||
return ret;
|
||||
idx += total;
|
||||
|
||||
/* object dhKeyAgreement 1.2.840.113549.1.3.1 */
|
||||
idx += SetObjectId(sizeof(keyDhOid), NULL);
|
||||
idx += sizeof(keyDhOid);
|
||||
/* sequence */
|
||||
idx += SetSequence(idx, NULL);
|
||||
/* version: 0 (ASN_INTEGER, 0x01, 0x00) */
|
||||
idx += 3;
|
||||
if (exportPriv) {
|
||||
/* version: 0 (ASN_INTEGER, 0x01, 0x00) */
|
||||
idx += 3;
|
||||
}
|
||||
/* sequence */
|
||||
total = idx + SetSequence(idx, NULL);
|
||||
|
||||
@ -4845,20 +4848,24 @@ int wc_DhKeyToDer(DhKey* key, byte* output, word32* outSz, int exportPriv)
|
||||
|
||||
/* sequence */
|
||||
idx = SetSequence(total, output);
|
||||
/* version: 0 */
|
||||
idx += SetMyVersion(0, output + idx, 0);
|
||||
if (exportPriv) {
|
||||
/* version: 0 */
|
||||
idx += SetMyVersion(0, output + idx, 0);
|
||||
}
|
||||
/* sequence - all but pub/priv */
|
||||
idx += SetSequence(total - keySz - idx, output + idx);
|
||||
/* object dhKeyAgreement 1.2.840.113549.1.3.1 */
|
||||
idx += SetObjectId(sizeof(keyDhOid), output + idx);
|
||||
XMEMCPY(output + idx, keyDhOid, sizeof(keyDhOid));
|
||||
idx += sizeof(keyDhOid);
|
||||
/* sequence */
|
||||
idx += SetSequence(total - keySz - idx, output + idx);
|
||||
/* integer - p */
|
||||
idx += SetASNIntMP(&key->p, -1, output + idx);
|
||||
/* integer - g */
|
||||
idx += SetASNIntMP(&key->g, -1, output + idx);
|
||||
|
||||
/* DH Parameters sequence with P and G */
|
||||
total = *outSz - idx;
|
||||
ret = wc_DhParamsToDer(key, output + idx, &total);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
idx += total;
|
||||
|
||||
/* octect string: priv */
|
||||
if (exportPriv) {
|
||||
idx += SetOctetString(privSz, output + idx);
|
||||
@ -4892,77 +4899,42 @@ int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz)
|
||||
* version 2 build.
|
||||
*
|
||||
* return bytes written on success */
|
||||
int wc_DhParamsToDer(DhKey* key, byte* out, word32* outSz)
|
||||
int wc_DhParamsToDer(DhKey* key, byte* output, word32* outSz)
|
||||
{
|
||||
word32 sz = 0, idx = 0;
|
||||
int pSz = 0, gSz = 0, ret;
|
||||
byte scratch[MAX_LENGTH_SZ];
|
||||
word32 idx, total;
|
||||
|
||||
if (key == NULL || outSz == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
pSz = mp_unsigned_bin_size(&key->p);
|
||||
if (pSz < 0) {
|
||||
return pSz;
|
||||
}
|
||||
if (mp_leading_bit(&key->p)) {
|
||||
pSz++;
|
||||
}
|
||||
/* determine size */
|
||||
/* integer - g */
|
||||
idx = SetASNIntMP(&key->g, -1, NULL);
|
||||
/* integer - p */
|
||||
idx += SetASNIntMP(&key->p, -1, NULL);
|
||||
total = idx;
|
||||
/* sequence */
|
||||
idx += SetSequence(idx, NULL);
|
||||
|
||||
gSz = mp_unsigned_bin_size(&key->g);
|
||||
if (gSz < 0) {
|
||||
return gSz;
|
||||
}
|
||||
if (mp_leading_bit(&key->g)) {
|
||||
gSz++;
|
||||
}
|
||||
|
||||
sz = ASN_TAG_SZ; /* Integer */
|
||||
sz += SetLength(pSz, scratch);
|
||||
sz += ASN_TAG_SZ; /* Integer */
|
||||
sz += SetLength(gSz, scratch);
|
||||
sz += gSz + pSz;
|
||||
|
||||
if (out == NULL) {
|
||||
byte seqScratch[MAX_SEQ_SZ];
|
||||
|
||||
*outSz = sz + SetSequence(sz, seqScratch);
|
||||
if (output == NULL) {
|
||||
*outSz = idx;
|
||||
return LENGTH_ONLY_E;
|
||||
}
|
||||
|
||||
if (*outSz < MAX_SEQ_SZ || *outSz < sz) {
|
||||
/* make sure output fits in buffer */
|
||||
if (idx > *outSz) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
idx += SetSequence(sz, out);
|
||||
if (*outSz < idx + sz) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
out[idx++] = ASN_INTEGER;
|
||||
idx += SetLength(pSz, out + idx);
|
||||
if (mp_leading_bit(&key->p)) {
|
||||
out[idx++] = 0x00;
|
||||
pSz -= 1; /* subtract 1 from size to account for leading 0 */
|
||||
}
|
||||
ret = mp_to_unsigned_bin(&key->p, out + idx);
|
||||
if (ret != MP_OKAY) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
idx += pSz;
|
||||
/* write DH parameters */
|
||||
/* sequence - for P and G only */
|
||||
idx = SetSequence(total, output);
|
||||
/* integer - p */
|
||||
idx += SetASNIntMP(&key->p, -1, output + idx);
|
||||
/* integer - g */
|
||||
idx += SetASNIntMP(&key->g, -1, output + idx);
|
||||
*outSz = idx;
|
||||
|
||||
out[idx++] = ASN_INTEGER;
|
||||
idx += SetLength(gSz, out + idx);
|
||||
if (mp_leading_bit(&key->g)) {
|
||||
out[idx++] = 0x00;
|
||||
gSz -= 1; /* subtract 1 from size to account for leading 0 */
|
||||
}
|
||||
ret = mp_to_unsigned_bin(&key->g, out + idx);
|
||||
if (ret != MP_OKAY) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
idx += gSz;
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
@ -11997,6 +11997,7 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out)
|
||||
#if defined(WOLFSSL_DH_EXTRA) && (!defined(HAVE_FIPS) || \
|
||||
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
|
||||
static const char* dhKeyFile = CERT_ROOT "statickeys/dh-ffdhe2048.der";
|
||||
static const char* dhKeyPubFile = CERT_ROOT "statickeys/dh-ffdhe2048-pub.der";
|
||||
#endif
|
||||
#endif
|
||||
#ifndef NO_DSA
|
||||
@ -16657,8 +16658,9 @@ WOLFSSL_TEST_SUBROUTINE int dh_test(void)
|
||||
ERROR_OUT(-8120, done);
|
||||
}
|
||||
|
||||
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM)
|
||||
#ifndef NO_ASN
|
||||
{
|
||||
/* DH Private - Key Export / Import */
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte *tmp2;
|
||||
#else
|
||||
@ -16666,19 +16668,19 @@ WOLFSSL_TEST_SUBROUTINE int dh_test(void)
|
||||
#endif
|
||||
XFILE file = XFOPEN(dhKeyFile, "rb");
|
||||
if (!file)
|
||||
ERROR_OUT(-8121, done);
|
||||
ERROR_OUT(-8130, done);
|
||||
bytes = (word32)XFREAD(tmp, 1, DH_TEST_TMP_SIZE, file);
|
||||
XFCLOSE(file);
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
tmp2 = (byte*)XMALLOC(DH_TEST_TMP_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (tmp2 == NULL)
|
||||
ERROR_OUT(-8122, done);
|
||||
ERROR_OUT(-8131, done);
|
||||
#endif
|
||||
idx = 0;
|
||||
XMEMSET(tmp2, 0, DH_TEST_TMP_SIZE);
|
||||
|
||||
/* Import DH key as DER */
|
||||
/* Import DH Private key as DER */
|
||||
ret = wc_DhKeyDecode(tmp, &idx, key, bytes);
|
||||
if (ret == 0) {
|
||||
/* Export as DER */
|
||||
@ -16688,7 +16690,31 @@ WOLFSSL_TEST_SUBROUTINE int dh_test(void)
|
||||
|
||||
/* Verify export matches original */
|
||||
if (ret <= 0 || bytes != idx || XMEMCMP(tmp, tmp2, bytes) != 0) {
|
||||
ERROR_OUT(-8123, done);
|
||||
ERROR_OUT(-8132, done);
|
||||
}
|
||||
|
||||
|
||||
/* DH Public Key - Export / Import */
|
||||
file = XFOPEN(dhKeyPubFile, "rb");
|
||||
if (!file)
|
||||
ERROR_OUT(-8133, done);
|
||||
bytes = (word32)XFREAD(tmp, 1, DH_TEST_TMP_SIZE, file);
|
||||
XFCLOSE(file);
|
||||
|
||||
idx = 0;
|
||||
XMEMSET(tmp2, 0, DH_TEST_TMP_SIZE);
|
||||
|
||||
/* Import DH Public key as DER */
|
||||
ret = wc_DhKeyDecode(tmp, &idx, key, bytes);
|
||||
if (ret == 0) {
|
||||
/* Export as DER */
|
||||
idx = DH_TEST_TMP_SIZE;
|
||||
ret = wc_DhPubKeyToDer(key, tmp2, &idx);
|
||||
}
|
||||
|
||||
/* Verify export matches original */
|
||||
if (ret <= 0 || bytes != idx || XMEMCMP(tmp, tmp2, bytes) != 0) {
|
||||
ERROR_OUT(-8134, done);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
@ -16698,37 +16724,36 @@ WOLFSSL_TEST_SUBROUTINE int dh_test(void)
|
||||
#else
|
||||
ret = wc_DhSetKey(key, dh_p, sizeof(dh_p), dh_g, sizeof(dh_g));
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(-8123, done);
|
||||
ERROR_OUT(-8121, done);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !NO_ASN */
|
||||
|
||||
privSz = DH_TEST_BUF_SIZE;
|
||||
pubSz = DH_TEST_BUF_SIZE;
|
||||
ret = wc_DhExportKeyPair(key, priv, &privSz, pub, &pubSz);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(-8124, done);
|
||||
ERROR_OUT(-8122, done);
|
||||
}
|
||||
ret = wc_DhImportKeyPair(key2, priv, privSz, pub, pubSz);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(-8125, done);
|
||||
}
|
||||
#endif /* WOLFSSL_DH_EXTRA */
|
||||
#endif /* WOLFSSL_DH_EXTRA && !NO_FILESYSTEM && !FIPS <= 2 */
|
||||
|
||||
#ifndef WC_NO_RNG
|
||||
ret = dh_generate_test(&rng);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(-8126, done);
|
||||
ERROR_OUT(-8123, done);
|
||||
|
||||
ret = dh_fips_generate_test(&rng);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(-8127, done);
|
||||
ERROR_OUT(-8124, done);
|
||||
#endif /* !WC_NO_RNG */
|
||||
|
||||
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
|
||||
ret = dh_test_check_pubvalue();
|
||||
if (ret != 0)
|
||||
ERROR_OUT(-8128, done);
|
||||
ERROR_OUT(-8125, done);
|
||||
#endif
|
||||
|
||||
#ifndef WC_NO_RNG
|
||||
@ -16736,17 +16761,17 @@ WOLFSSL_TEST_SUBROUTINE int dh_test(void)
|
||||
#ifdef HAVE_FFDHE_2048
|
||||
ret = dh_ffdhe_test(&rng, wc_Dh_ffdhe2048_Get());
|
||||
if (ret != 0)
|
||||
ERROR_OUT(-8129, done);
|
||||
ERROR_OUT(-8126, done);
|
||||
#endif
|
||||
#ifdef HAVE_FFDHE_3072
|
||||
ret = dh_ffdhe_test(&rng, wc_Dh_ffdhe3072_Get());
|
||||
if (ret != 0)
|
||||
ERROR_OUT(-8130, done);
|
||||
ERROR_OUT(-8127, done);
|
||||
#endif
|
||||
#ifdef HAVE_FFDHE_4096
|
||||
ret = dh_ffdhe_test(&rng, wc_Dh_ffdhe4096_Get());
|
||||
if (ret != 0)
|
||||
ERROR_OUT(-8131, done);
|
||||
ERROR_OUT(-8128, done);
|
||||
#endif
|
||||
#endif /* !WC_NO_RNG */
|
||||
|
||||
@ -16759,7 +16784,7 @@ WOLFSSL_TEST_SUBROUTINE int dh_test(void)
|
||||
ret = wc_DhSetCheckKey(key, dh_p, sizeof(dh_p), dh_g, sizeof(dh_g),
|
||||
NULL, 0, 0, &rng);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(-8132, done);
|
||||
ERROR_OUT(-8129, done);
|
||||
keyInit = 1; /* DhSetCheckKey also initializes the key, free it */
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user