diffie-hellman: Verify public DH values in backends
This commit is contained in:
parent
a777155ffe
commit
0356089d0f
|
@ -501,3 +501,75 @@ bool diffie_hellman_group_is_ec(diffie_hellman_group_t group)
|
||||||
return FALSE;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
* Check if a given DH group is an ECDH group
|
||||||
*
|
*
|
||||||
* @param group group to check
|
* @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);
|
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_ @}*/
|
#endif /** DIFFIE_HELLMAN_H_ @}*/
|
||||||
|
|
|
@ -79,6 +79,11 @@ METHOD(diffie_hellman_t, set_other_public_value, bool,
|
||||||
gcry_mpi_t p_min_1;
|
gcry_mpi_t p_min_1;
|
||||||
gcry_error_t err;
|
gcry_error_t err;
|
||||||
|
|
||||||
|
if (!diffie_hellman_verify_value(this->group, value))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->yb)
|
if (this->yb)
|
||||||
{
|
{
|
||||||
gcry_mpi_release(this->yb);
|
gcry_mpi_release(this->yb);
|
||||||
|
|
|
@ -90,6 +90,11 @@ METHOD(diffie_hellman_t, set_other_public_value, bool,
|
||||||
{
|
{
|
||||||
mpz_t p_min_1;
|
mpz_t p_min_1;
|
||||||
|
|
||||||
|
if (!diffie_hellman_verify_value(this->group, value))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
mpz_init(p_min_1);
|
mpz_init(p_min_1);
|
||||||
mpz_sub_ui(p_min_1, this->p, 1);
|
mpz_sub_ui(p_min_1, this->p, 1);
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,11 @@ METHOD(diffie_hellman_t, set_other_public_value, bool,
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
if (!diffie_hellman_verify_value(this->group, value))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
BN_bin2bn(value.ptr, value.len, this->pub_key);
|
BN_bin2bn(value.ptr, value.len, this->pub_key);
|
||||||
chunk_clear(&this->shared_secret);
|
chunk_clear(&this->shared_secret);
|
||||||
this->shared_secret.ptr = malloc(DH_size(this->dh));
|
this->shared_secret.ptr = malloc(DH_size(this->dh));
|
||||||
|
|
|
@ -219,6 +219,11 @@ error:
|
||||||
METHOD(diffie_hellman_t, set_other_public_value, bool,
|
METHOD(diffie_hellman_t, set_other_public_value, bool,
|
||||||
private_openssl_ec_diffie_hellman_t *this, chunk_t value)
|
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))
|
if (!chunk2ecp(this->ec_group, value, this->pub_key))
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "ECDH public value is malformed");
|
DBG1(DBG_LIB, "ECDH public value is malformed");
|
||||||
|
|
|
@ -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,
|
METHOD(diffie_hellman_t, set_other_public_value, bool,
|
||||||
private_pkcs11_dh_t *this, chunk_t value)
|
private_pkcs11_dh_t *this, chunk_t value)
|
||||||
{
|
{
|
||||||
|
if (!diffie_hellman_verify_value(this->group, value))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
switch (this->group)
|
switch (this->group)
|
||||||
{
|
{
|
||||||
case ECP_192_BIT:
|
case ECP_192_BIT:
|
||||||
|
|
Loading…
Reference in New Issue