diff --git a/src/wp_dh_kmgmt.c b/src/wp_dh_kmgmt.c index 442f1c40..30f71d4a 100644 --- a/src/wp_dh_kmgmt.c +++ b/src/wp_dh_kmgmt.c @@ -2223,7 +2223,9 @@ static int wp_dh_decode_pki(wp_Dh* dh, unsigned char* data, word32 len) { int ok = 1; int rc; + int baseSz = 0; word32 idx = 0; + word32 pubLen = 0; unsigned char* base = NULL; WOLFPROV_ENTER_SILENT(WP_LOG_COMP_DH, WOLFPROV_FUNC_NAME); @@ -2247,7 +2249,13 @@ static int wp_dh_decode_pki(wp_Dh* dh, unsigned char* data, word32 len) } /* Calculate the public key. base ^ priv using key agree. */ if (ok) { - base = OPENSSL_malloc(mp_unsigned_bin_size(&dh->key.g)); + baseSz = mp_unsigned_bin_size(&dh->key.g); + if (baseSz <= 0) { + ok = 0; + } + } + if (ok) { + base = OPENSSL_malloc(baseSz); if (base == NULL) { ok = 0; } @@ -2259,7 +2267,8 @@ static int wp_dh_decode_pki(wp_Dh* dh, unsigned char* data, word32 len) } } if (ok) { - dh->pub = OPENSSL_malloc(mp_unsigned_bin_size(&dh->key.p)); + pubLen = (word32)mp_unsigned_bin_size(&dh->key.p); + dh->pub = OPENSSL_malloc(pubLen); if (dh->pub == NULL) { ok = 0; } @@ -2271,14 +2280,14 @@ static int wp_dh_decode_pki(wp_Dh* dh, unsigned char* data, word32 len) } #endif if (ok) { - rc = wc_DhAgree(&dh->key, dh->pub, &idx, dh->priv, (word32)dh->privSz, - base, 1); + rc = wc_DhAgree(&dh->key, dh->pub, &pubLen, dh->priv, + (word32)dh->privSz, base, (word32)baseSz); if (rc != 0) { ok = 0; } } if (ok) { - dh->pubSz = idx; + dh->pubSz = pubLen; dh->bits = mp_count_bits(&dh->key.p); } diff --git a/test/test_dh.c b/test/test_dh.c index da5baf82..7fe84554 100644 --- a/test/test_dh.c +++ b/test/test_dh.c @@ -77,6 +77,60 @@ static const unsigned char dh_der[] = { 0xDF, 0x31, }; +/* dh pkcs8 private key der on the RFC 5114 dh_2048_224 group, whose + * generator is a full 2048-bit value rather than a single byte. */ +static const unsigned char dh_big_g_der[] = { + 0x30, 0x82, 0x02, 0x40, 0x02, 0x01, 0x00, 0x30, 0x82, 0x02, 0x19, 0x06, + 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x03, 0x01, 0x30, 0x82, + 0x02, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xAD, 0x10, 0x7E, 0x1E, 0x91, + 0x23, 0xA9, 0xD0, 0xD6, 0x60, 0xFA, 0xA7, 0x95, 0x59, 0xC5, 0x1F, 0xA2, + 0x0D, 0x64, 0xE5, 0x68, 0x3B, 0x9F, 0xD1, 0xB5, 0x4B, 0x15, 0x97, 0xB6, + 0x1D, 0x0A, 0x75, 0xE6, 0xFA, 0x14, 0x1D, 0xF9, 0x5A, 0x56, 0xDB, 0xAF, + 0x9A, 0x3C, 0x40, 0x7B, 0xA1, 0xDF, 0x15, 0xEB, 0x3D, 0x68, 0x8A, 0x30, + 0x9C, 0x18, 0x0E, 0x1D, 0xE6, 0xB8, 0x5A, 0x12, 0x74, 0xA0, 0xA6, 0x6D, + 0x3F, 0x81, 0x52, 0xAD, 0x6A, 0xC2, 0x12, 0x90, 0x37, 0xC9, 0xED, 0xEF, + 0xDA, 0x4D, 0xF8, 0xD9, 0x1E, 0x8F, 0xEF, 0x55, 0xB7, 0x39, 0x4B, 0x7A, + 0xD5, 0xB7, 0xD0, 0xB6, 0xC1, 0x22, 0x07, 0xC9, 0xF9, 0x8D, 0x11, 0xED, + 0x34, 0xDB, 0xF6, 0xC6, 0xBA, 0x0B, 0x2C, 0x8B, 0xBC, 0x27, 0xBE, 0x6A, + 0x00, 0xE0, 0xA0, 0xB9, 0xC4, 0x97, 0x08, 0xB3, 0xBF, 0x8A, 0x31, 0x70, + 0x91, 0x88, 0x36, 0x81, 0x28, 0x61, 0x30, 0xBC, 0x89, 0x85, 0xDB, 0x16, + 0x02, 0xE7, 0x14, 0x41, 0x5D, 0x93, 0x30, 0x27, 0x82, 0x73, 0xC7, 0xDE, + 0x31, 0xEF, 0xDC, 0x73, 0x10, 0xF7, 0x12, 0x1F, 0xD5, 0xA0, 0x74, 0x15, + 0x98, 0x7D, 0x9A, 0xDC, 0x0A, 0x48, 0x6D, 0xCD, 0xF9, 0x3A, 0xCC, 0x44, + 0x32, 0x83, 0x87, 0x31, 0x5D, 0x75, 0xE1, 0x98, 0xC6, 0x41, 0xA4, 0x80, + 0xCD, 0x86, 0xA1, 0xB9, 0xE5, 0x87, 0xE8, 0xBE, 0x60, 0xE6, 0x9C, 0xC9, + 0x28, 0xB2, 0xB9, 0xC5, 0x21, 0x72, 0xE4, 0x13, 0x04, 0x2E, 0x9B, 0x23, + 0xF1, 0x0B, 0x0E, 0x16, 0xE7, 0x97, 0x63, 0xC9, 0xB5, 0x3D, 0xCF, 0x4B, + 0xA8, 0x0A, 0x29, 0xE3, 0xFB, 0x73, 0xC1, 0x6B, 0x8E, 0x75, 0xB9, 0x7E, + 0xF3, 0x63, 0xE2, 0xFF, 0xA3, 0x1F, 0x71, 0xCF, 0x9D, 0xE5, 0x38, 0x4E, + 0x71, 0xB8, 0x1C, 0x0A, 0xC4, 0xDF, 0xFE, 0x0C, 0x10, 0xE6, 0x4F, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xAC, 0x40, 0x32, 0xEF, 0x4F, 0x2D, 0x9A, 0xE3, + 0x9D, 0xF3, 0x0B, 0x5C, 0x8F, 0xFD, 0xAC, 0x50, 0x6C, 0xDE, 0xBE, 0x7B, + 0x89, 0x99, 0x8C, 0xAF, 0x74, 0x86, 0x6A, 0x08, 0xCF, 0xE4, 0xFF, 0xE3, + 0xA6, 0x82, 0x4A, 0x4E, 0x10, 0xB9, 0xA6, 0xF0, 0xDD, 0x92, 0x1F, 0x01, + 0xA7, 0x0C, 0x4A, 0xFA, 0xAB, 0x73, 0x9D, 0x77, 0x00, 0xC2, 0x9F, 0x52, + 0xC5, 0x7D, 0xB1, 0x7C, 0x62, 0x0A, 0x86, 0x52, 0xBE, 0x5E, 0x90, 0x01, + 0xA8, 0xD6, 0x6A, 0xD7, 0xC1, 0x76, 0x69, 0x10, 0x19, 0x99, 0x02, 0x4A, + 0xF4, 0xD0, 0x27, 0x27, 0x5A, 0xC1, 0x34, 0x8B, 0xB8, 0xA7, 0x62, 0xD0, + 0x52, 0x1B, 0xC9, 0x8A, 0xE2, 0x47, 0x15, 0x04, 0x22, 0xEA, 0x1E, 0xD4, + 0x09, 0x93, 0x9D, 0x54, 0xDA, 0x74, 0x60, 0xCD, 0xB5, 0xF6, 0xC6, 0xB2, + 0x50, 0x71, 0x7C, 0xBE, 0xF1, 0x80, 0xEB, 0x34, 0x11, 0x8E, 0x98, 0xD1, + 0x19, 0x52, 0x9A, 0x45, 0xD6, 0xF8, 0x34, 0x56, 0x6E, 0x30, 0x25, 0xE3, + 0x16, 0xA3, 0x30, 0xEF, 0xBB, 0x77, 0xA8, 0x6F, 0x0C, 0x1A, 0xB1, 0x5B, + 0x05, 0x1A, 0xE3, 0xD4, 0x28, 0xC8, 0xF8, 0xAC, 0xB7, 0x0A, 0x81, 0x37, + 0x15, 0x0B, 0x8E, 0xEB, 0x10, 0xE1, 0x83, 0xED, 0xD1, 0x99, 0x63, 0xDD, + 0xD9, 0xE2, 0x63, 0xE4, 0x77, 0x05, 0x89, 0xEF, 0x6A, 0xA2, 0x1E, 0x7F, + 0x5F, 0x2F, 0xF3, 0x81, 0xB5, 0x39, 0xCC, 0xE3, 0x40, 0x9D, 0x13, 0xCD, + 0x56, 0x6A, 0xFB, 0xB4, 0x8D, 0x6C, 0x01, 0x91, 0x81, 0xE1, 0xBC, 0xFE, + 0x94, 0xB3, 0x02, 0x69, 0xED, 0xFE, 0x72, 0xFE, 0x9B, 0x6A, 0xA4, 0xBD, + 0x7B, 0x5A, 0x0F, 0x1C, 0x71, 0xCF, 0xFF, 0x4C, 0x19, 0xC4, 0x18, 0xE1, + 0xF6, 0xEC, 0x01, 0x79, 0x81, 0xBC, 0x08, 0x7F, 0x2A, 0x70, 0x65, 0xB3, + 0x84, 0xB8, 0x90, 0xD3, 0x19, 0x1F, 0x2B, 0xFA, 0x04, 0x1E, 0x02, 0x1C, + 0x37, 0x66, 0x33, 0x2E, 0x1E, 0x5B, 0x8D, 0xDE, 0x57, 0x76, 0xFF, 0x82, + 0x15, 0x5C, 0x9E, 0x56, 0x51, 0xCE, 0xAF, 0x81, 0x68, 0xBA, 0xEE, 0x71, + 0xBF, 0x06, 0x38, 0x10, +}; + /* Random 2048-bit DH prime (not a named group) */ static const unsigned char dh_p[] = { @@ -503,7 +557,7 @@ int test_dh_invalid_kdf_strings(void *data) return err; } -int test_dh_decode(void *data) +static int test_dh_decode_der(const unsigned char* der, int derLen) { int err = 0; const unsigned char *p = NULL; @@ -522,10 +576,8 @@ int test_dh_decode(void *data) const BIGNUM *priv2 = NULL; const BIGNUM *pub2 = NULL; - (void)data; - - p = &dh_der[0]; - len = sizeof(dh_der); + p = der; + len = derLen; p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, (const unsigned char **)&p, len); err = p8inf == NULL; @@ -572,6 +624,9 @@ int test_dh_decode(void *data) } if (err == 0) { err = BN_cmp(pub1, pub2) != 0; + if (err != 0) { + PRINT_ERR_MSG("Public keys differ"); + } } DH_free(dh1); @@ -582,6 +637,25 @@ int test_dh_decode(void *data) return err; } +/* Compare a decode of the same PKCS#8 DH key by OpenSSL and by wolfProvider. */ +int test_dh_decode(void *data) +{ + (void)data; + + return test_dh_decode_der(dh_der, (int)sizeof(dh_der)); +} + +/* A generator wider than one byte must be used in full when the decoder + * rebuilds the public key from the private value. */ +int test_dh_decode_big_g(void *data) +{ + (void)data; + + PRINT_MSG("Decode DH key with a multi-byte generator"); + + return test_dh_decode_der(dh_big_g_der, (int)sizeof(dh_big_g_der)); +} + int test_dh_get_params(void *data) { (void)data; diff --git a/test/unit.c b/test/unit.c index c5543dd0..f5325f4b 100644 --- a/test/unit.c +++ b/test/unit.c @@ -354,6 +354,7 @@ TEST_CASE test_case[] = { TEST_DECL(test_dh_encode_epki, NULL), #endif TEST_DECL(test_dh_decode, NULL), + TEST_DECL(test_dh_decode_big_g, NULL), TEST_DECL(test_dh_krb5_keygen, NULL), TEST_DECL(test_dh_pad, NULL), TEST_DECL(test_dh_derive_small_buffer, NULL), diff --git a/test/unit.h b/test/unit.h index f7910ba1..6a33554d 100644 --- a/test/unit.h +++ b/test/unit.h @@ -408,6 +408,7 @@ int test_dh_invalid_kdf_strings(void *data); int test_dh_encode_epki(void *data); #endif int test_dh_decode(void *data); +int test_dh_decode_big_g(void *data); int test_dh_get_params(void *data); int test_dh_krb5_keygen(void *data); int test_dh_pad(void *data);