diff options
author | Martin Willi <martin@revosec.ch> | 2015-03-23 14:32:11 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2015-03-23 17:54:03 +0100 |
commit | 0356089d0f94ab86dd82fd686703560988833e3c (patch) | |
tree | 43201d2caf56388bcddc82795962b95504a07482 /src | |
parent | a777155ffed7fc6382a2e344ebd748f70b1c61c2 (diff) | |
download | strongswan-0356089d0f94ab86dd82fd686703560988833e3c.tar.bz2 strongswan-0356089d0f94ab86dd82fd686703560988833e3c.tar.xz |
diffie-hellman: Verify public DH values in backends
Diffstat (limited to 'src')
-rw-r--r-- | src/libstrongswan/crypto/diffie_hellman.c | 72 | ||||
-rw-r--r-- | src/libstrongswan/crypto/diffie_hellman.h | 11 | ||||
-rw-r--r-- | src/libstrongswan/plugins/gcrypt/gcrypt_dh.c | 5 | ||||
-rw-r--r-- | src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c | 5 | ||||
-rw-r--r-- | src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c | 5 | ||||
-rw-r--r-- | src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c | 5 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs11/pkcs11_dh.c | 5 |
7 files changed, 107 insertions, 1 deletions
diff --git a/src/libstrongswan/crypto/diffie_hellman.c b/src/libstrongswan/crypto/diffie_hellman.c index ac106e9c4..0d4cd9109 100644 --- a/src/libstrongswan/crypto/diffie_hellman.c +++ b/src/libstrongswan/crypto/diffie_hellman.c @@ -501,3 +501,75 @@ bool diffie_hellman_group_is_ec(diffie_hellman_group_t group) return FALSE; } } + +/** + * See header. + */ +bool diffie_hellman_verify_value(diffie_hellman_group_t group, chunk_t value) +{ + diffie_hellman_params_t *params; + bool valid = FALSE; + + switch (group) + { + case MODP_768_BIT: + case MODP_1024_BIT: + case MODP_1536_BIT: + case MODP_2048_BIT: + case MODP_3072_BIT: + case MODP_4096_BIT: + case MODP_6144_BIT: + case MODP_8192_BIT: + case MODP_1024_160: + case MODP_2048_224: + case MODP_2048_256: + params = diffie_hellman_get_params(group); + if (params) + { + valid = value.len == params->prime.len; + } + break; + case ECP_192_BIT: + valid = value.len == 48; + break; + case ECP_224_BIT: + case ECP_224_BP: + valid = value.len == 56; + break; + case ECP_256_BIT: + case ECP_256_BP: + valid = value.len == 64; + break; + case ECP_384_BIT: + case ECP_384_BP: + valid = value.len == 96; + break; + case ECP_512_BP: + valid = value.len == 128; + break; + case ECP_521_BIT: + valid = value.len == 132; + break; + case NTRU_112_BIT: + case NTRU_128_BIT: + case NTRU_192_BIT: + case NTRU_256_BIT: + /* verification currently not supported, do in plugin */ + valid = FALSE; + break; + case MODP_NULL: + case MODP_CUSTOM: + valid = TRUE; + break; + case MODP_NONE: + /* fail */ + break; + /* compile-warn unhandled groups, fail verification */ + } + if (!valid) + { + DBG1(DBG_ENC, "invalid DH public value size (%zu bytes) for %N", + value.len, diffie_hellman_group_names, group); + } + return valid; +} diff --git a/src/libstrongswan/crypto/diffie_hellman.h b/src/libstrongswan/crypto/diffie_hellman.h index 99df3cb6b..4704cd0da 100644 --- a/src/libstrongswan/crypto/diffie_hellman.h +++ b/src/libstrongswan/crypto/diffie_hellman.h @@ -175,8 +175,17 @@ diffie_hellman_params_t *diffie_hellman_get_params(diffie_hellman_group_t group) * Check if a given DH group is an ECDH group * * @param group group to check - * @return TUE if group is an ECP group + * @return TRUE if group is an ECP group */ bool diffie_hellman_group_is_ec(diffie_hellman_group_t group); +/** + * Check if a diffie hellman public value is valid for given group. + * + * @param group group the value is used in + * @param value public DH value to check + * @return TRUE if value looks valid for group + */ +bool diffie_hellman_verify_value(diffie_hellman_group_t group, chunk_t value); + #endif /** DIFFIE_HELLMAN_H_ @}*/ diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c index 80bd85d87..744ec0bbf 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c @@ -79,6 +79,11 @@ METHOD(diffie_hellman_t, set_other_public_value, bool, gcry_mpi_t p_min_1; gcry_error_t err; + if (!diffie_hellman_verify_value(this->group, value)) + { + return FALSE; + } + if (this->yb) { gcry_mpi_release(this->yb); diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c index 0fbfc24aa..0ca24d76a 100644 --- a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c +++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c @@ -90,6 +90,11 @@ METHOD(diffie_hellman_t, set_other_public_value, bool, { mpz_t p_min_1; + if (!diffie_hellman_verify_value(this->group, value)) + { + return FALSE; + } + mpz_init(p_min_1); mpz_sub_ui(p_min_1, this->p, 1); diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c index 7a0aa1a6a..2615d60a2 100644 --- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c +++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c @@ -92,6 +92,11 @@ METHOD(diffie_hellman_t, set_other_public_value, bool, { int len; + if (!diffie_hellman_verify_value(this->group, value)) + { + return FALSE; + } + BN_bin2bn(value.ptr, value.len, this->pub_key); chunk_clear(&this->shared_secret); this->shared_secret.ptr = malloc(DH_size(this->dh)); diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c index 9ef15b41e..550a5432f 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c +++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c @@ -219,6 +219,11 @@ error: METHOD(diffie_hellman_t, set_other_public_value, bool, private_openssl_ec_diffie_hellman_t *this, chunk_t value) { + if (!diffie_hellman_verify_value(this->group, value)) + { + return FALSE; + } + if (!chunk2ecp(this->ec_group, value, this->pub_key)) { DBG1(DBG_LIB, "ECDH public value is malformed"); diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c index 56102c5a4..c0033bd8e 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c @@ -116,6 +116,11 @@ static bool derive_secret(private_pkcs11_dh_t *this, chunk_t other) METHOD(diffie_hellman_t, set_other_public_value, bool, private_pkcs11_dh_t *this, chunk_t value) { + if (!diffie_hellman_verify_value(this->group, value)) + { + return FALSE; + } + switch (this->group) { case ECP_192_BIT: |