for (round = 0; round < rounds; round++)
{
assert(l[round]->get_my_public_value(l[round], &chunk));
- r->set_other_public_value(r, chunk);
+ assert(r->set_other_public_value(r, chunk));
chunk_free(&chunk);
}
start_timing(&timing);
for (round = 0; round < rounds; round++)
{
- l[round]->set_other_public_value(l[round], chunk);
+ assert(l[round]->set_other_public_value(l[round], chunk));
}
printf(" | S = B^a/s: %8.1f\n", rounds / end_timing(&timing));
chunk_free(&chunk);
}
return 0;
}
-
}
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_tkm_diffie_hellman_t *this, chunk_t value)
{
- // TODO: unvoid this function
-
dh_pubvalue_type othervalue;
othervalue.size = value.len;
memcpy(&othervalue.data, value.ptr, value.len);
- ike_dh_generate_key(this->context_id, othervalue);
+ return ike_dh_generate_key(this->context_id, othervalue) == TKM_OK;
}
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
/* Use the same pubvalue for both sides */
chunk_t pubvalue;
ck_assert(dh->dh.get_my_public_value(&dh->dh, &pubvalue));
- dh->dh.set_other_public_value(&dh->dh, pubvalue);
+ ck_assert(dh->dh.set_other_public_value(&dh->dh, pubvalue));
fail_unless(keymat->keymat_v2.derive_ike_keys(&keymat->keymat_v2, proposal,
&dh->dh, nonce, nonce, ike_sa_id, PRF_UNDEFINED, chunk_empty),
return TRUE;
}
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
load_tester_diffie_hellman_t *this, chunk_t value)
{
+ return TRUE;
}
METHOD(diffie_hellman_t, get_shared_secret, bool,
return FALSE;
}
this->dh_value = chunk_clone(ke_payload->get_key_exchange_data(ke_payload));
- this->dh->set_other_public_value(this->dh, this->dh_value);
+ if (!this->dh->set_other_public_value(this->dh, this->dh_value))
+ {
+ DBG1(DBG_IKE, "unable to apply received KE value");
+ return FALSE;
+ }
nonce_payload = (nonce_payload_t*)message->get_payload(message, PLV1_NONCE);
if (!nonce_payload)
DBG1(DBG_IKE, "KE payload missing");
return FALSE;
}
- this->dh->set_other_public_value(this->dh,
- ke_payload->get_key_exchange_data(ke_payload));
+ if (this->dh->set_other_public_value(this->dh,
+ ke_payload->get_key_exchange_data(ke_payload)))
+ {
+ DBG1(DBG_IKE, "unable to apply received KE value");
+ return FALSE;
+ }
return TRUE;
}
*/
diffie_hellman_t *dh;
+ /**
+ * Applying DH public value failed?
+ */
+ bool dh_failed;
+
/**
* group used for DH exchange
*/
}
if (this->dh)
{
- this->dh->set_other_public_value(this->dh,
+ this->dh_failed = !this->dh->set_other_public_value(this->dh,
ke_payload->get_key_exchange_data(ke_payload));
}
break;
case IKE_SA_INIT:
return get_nonce(message, &this->my_nonce);
case CREATE_CHILD_SA:
- if (generate_nonce(this) != SUCCESS)
+ if (generate_nonce(this) != SUCCESS )
+ {
+ message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
+ chunk_empty);
+ return SUCCESS;
+ }
+ if (this->dh_failed)
{
+ DBG1(DBG_IKE, "applying DH public value failed");
message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
chunk_empty);
return SUCCESS;
return delete_failed_sa(this);
}
+ if (this->dh_failed)
+ {
+ DBG1(DBG_IKE, "applying DH public value failed");
+ handle_child_sa_failure(this, message);
+ return delete_failed_sa(this);
+ }
+
if (select_and_install(this, no_dh, ike_auth) == SUCCESS)
{
if (!this->rekey)
DESTROY_IF(this->child_sa);
DESTROY_IF(this->proposal);
DESTROY_IF(this->dh);
+ this->dh_failed = FALSE;
if (this->proposals)
{
this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
*/
diffie_hellman_t *dh;
+ /**
+ * Applying DH public value failed?
+ */
+ bool dh_failed;
+
/**
* Keymat derivation (from IKE_SA)
*/
}
if (this->dh)
{
- this->dh->set_other_public_value(this->dh,
+ this->dh_failed = !this->dh->set_other_public_value(this->dh,
ke_payload->get_key_exchange_data(ke_payload));
}
}
return FAILED;
}
+ if (this->dh_failed)
+ {
+ DBG1(DBG_IKE, "applying DH public value failed");
+ message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
+ return FAILED;
+ }
+
if (!derive_keys(this, this->other_nonce, this->my_nonce))
{
DBG1(DBG_IKE, "key derivation failed");
return FAILED;
}
+ if (this->dh_failed)
+ {
+ DBG1(DBG_IKE, "applying DH public value failed");
+ return FAILED;
+ }
+
if (!derive_keys(this, this->my_nonce, this->other_nonce))
{
DBG1(DBG_IKE, "key derivation failed");
this->ike_sa = ike_sa;
this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
this->proposal = NULL;
+ this->dh_failed = FALSE;
if (this->dh && this->dh->get_dh_group(this->dh) != this->dh_group)
{ /* reset DH value only if group changed (INVALID_KE_PAYLOAD) */
this->dh->destroy(this->dh);
METHOD(pts_t, set_peer_public_value, bool,
private_pts_t *this, chunk_t value, chunk_t nonce)
{
- this->dh->set_other_public_value(this->dh, value);
+ if (!this->dh->set_other_public_value(this->dh, value))
+ {
+ return FALSE;
+ }
nonce = chunk_clone(nonce);
if (this->is_imc)
* Chunk gets cloned and can be destroyed afterwards.
*
* @param value public value of partner
+ * @return TRUE if other public value verified and set
*/
- void (*set_other_public_value) (diffie_hellman_t *this, chunk_t value);
+ bool (*set_other_public_value)(diffie_hellman_t *this, chunk_t value)
+ __attribute__((warn_unused_result));
/**
* Gets the own public value to transmit.
size_t p_len;
};
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_gcrypt_dh_t *this, chunk_t value)
{
gcry_mpi_t p_min_1;
if (err)
{
DBG1(DBG_LIB, "importing mpi yb failed: %s", gpg_strerror(err));
- return;
+ return FALSE;
}
p_min_1 = gcry_mpi_new(this->p_len * 8);
" y < 2 || y > p - 1 ");
}
gcry_mpi_release(p_min_1);
+ return this->zz != NULL;
}
/**
bool computed;
};
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_gmp_diffie_hellman_t *this, chunk_t value)
{
mpz_t p_min_1;
" y < 2 || y > p - 1 ");
}
mpz_clear(p_min_1);
+ return this->computed;
}
METHOD(diffie_hellman_t, get_my_public_value, bool,
/**
* Deterministic Random Bit Generator
*/
- ntru_drbg_t *drbg;
+ ntru_drbg_t *drbg;
};
METHOD(diffie_hellman_t, get_my_public_value, bool,
return TRUE;
}
-
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_ntru_ke_t *this, chunk_t value)
{
if (this->privkey)
if (value.len == 0)
{
DBG1(DBG_LIB, "empty NTRU ciphertext");
- return;
+ return FALSE;
}
DBG3(DBG_LIB, "NTRU ciphertext: %B", &value);
/* decrypt the shared secret */
- if (!this->privkey->decrypt(this->privkey, value, &this->shared_secret))
+ if (!this->privkey->decrypt(this->privkey, value, &this->shared_secret))
{
DBG1(DBG_LIB, "NTRU decryption of shared secret failed");
- return;
+ return FALSE;
}
this->computed = TRUE;
}
pubkey = ntru_public_key_create_from_data(this->drbg, value);
if (!pubkey)
{
- return;
+ return FALSE;
}
if (pubkey->get_id(pubkey) != this->param_set->id)
{
DBG1(DBG_LIB, "received NTRU public key with wrong OUI");
pubkey->destroy(pubkey);
- return;
+ return FALSE;
}
this->pubkey = pubkey;
{
DBG1(DBG_LIB, "generation of shared secret failed");
chunk_free(&this->shared_secret);
- return;
+ return FALSE;
}
this->computed = TRUE;
if (!pubkey->encrypt(pubkey, this->shared_secret, &this->ciphertext))
{
DBG1(DBG_LIB, "NTRU encryption of shared secret failed");
- return;
+ return FALSE;
}
DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext);
}
+ return this->computed;
}
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
drbg = ntru_drbg_create(strength, chunk_from_str("IKE NTRU-KE"), entropy);
if (!drbg)
- {
+ {
DBG1(DBG_LIB, "could not instantiate DRBG at %u bit security", strength);
entropy->destroy(entropy);
- return NULL;
+ return NULL;
}
INIT(this,
return &this->public;
}
-
}
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_openssl_diffie_hellman_t *this, chunk_t value)
{
int len;
if (len < 0)
{
DBG1(DBG_LIB, "DH shared secret computation failed");
- return;
+ return FALSE;
}
this->shared_secret.len = len;
this->computed = TRUE;
+ return TRUE;
}
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
return ret;
}
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_openssl_ec_diffie_hellman_t *this, chunk_t value)
{
if (!chunk2ecp(this->ec_group, value, this->pub_key))
{
DBG1(DBG_LIB, "ECDH public value is malformed");
- return;
+ return FALSE;
}
chunk_clear(&this->shared_secret);
if (!compute_shared_key(this, &this->shared_secret)) {
DBG1(DBG_LIB, "ECDH shared secret computation failed");
- return;
+ return FALSE;
}
this->computed = TRUE;
+ return TRUE;
}
METHOD(diffie_hellman_t, get_my_public_value, bool,
*
* If this succeeds the shared secret is stored in this->secret.
*/
-static void derive_secret(private_pkcs11_dh_t *this, chunk_t other)
+static bool derive_secret(private_pkcs11_dh_t *this, chunk_t other)
{
CK_OBJECT_CLASS klass = CKO_SECRET_KEY;
CK_KEY_TYPE type = CKK_GENERIC_SECRET;
if (rv != CKR_OK)
{
DBG1(DBG_CFG, "C_DeriveKey() error: %N", ck_rv_names, rv);
- return;
+ return FALSE;
}
if (!this->lib->get_ck_attribute(this->lib, this->session, secret,
CKA_VALUE, &this->secret))
{
chunk_free(&this->secret);
- return;
+ return FALSE;
}
+ return TRUE;
}
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_pkcs11_dh_t *this, chunk_t value)
{
switch (this->group)
if (!lib->settings->get_bool(lib->settings,
"%s.ecp_x_coordinate_only", TRUE, lib->ns))
{ /* we only get the x coordinate back */
- return;
+ return FALSE;
}
value = chunk_from_thing(params);
break;
default:
break;
}
- derive_secret(this, value);
+ return derive_secret(this, value);
}
METHOD(diffie_hellman_t, get_my_public_value, bool,
}
return NULL;
}
-
r_ntru = lib->crypto->create_dh(lib->crypto, params[k].group);
ck_assert(r_ntru != NULL);
- r_ntru->set_other_public_value(r_ntru, pub_key);
+ ck_assert(r_ntru->set_other_public_value(r_ntru, pub_key));
ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text));
ck_assert(cipher_text.len > 0);
ck_assert(r_ntru->get_shared_secret(r_ntru, &r_shared_secret));
ck_assert(r_shared_secret.len > 0);
- i_ntru->set_other_public_value(i_ntru, cipher_text);
+ ck_assert(i_ntru->set_other_public_value(i_ntru, cipher_text));
ck_assert(i_ntru->get_shared_secret(i_ntru, &i_shared_secret));
ck_assert(chunk_equals(i_shared_secret, r_shared_secret));
chunk_t cipher_text;
r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
- r_ntru->set_other_public_value(r_ntru, oid_tests[_i]);
+ ck_assert(!r_ntru->set_other_public_value(r_ntru, oid_tests[_i]));
ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text));
ck_assert(cipher_text.len == 0);
r_ntru->destroy(r_ntru);
"libstrongswan.plugins.ntru.parameter_set",
"optimum");
r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT);
- r_ntru->set_other_public_value(r_ntru, pub_key);
+ ck_assert(!r_ntru->set_other_public_value(r_ntru, pub_key));
ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text));
ck_assert(cipher_text.len == 0);
{
i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key));
- i_ntru->set_other_public_value(i_ntru, test[i]);
+ ck_assert(!i_ntru->set_other_public_value(i_ntru, test[i]));
ck_assert(!i_ntru->get_shared_secret(i_ntru, &shared_secret));
ck_assert(shared_secret.len == 0);
ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key_i));
ck_assert(m_ntru->get_my_public_value(m_ntru, &pub_key_m));
- r_ntru->set_other_public_value(r_ntru, pub_key_m);
+ ck_assert(r_ntru->set_other_public_value(r_ntru, pub_key_m));
ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text));
- i_ntru->set_other_public_value(i_ntru, cipher_text);
+ ck_assert(!i_ntru->set_other_public_value(i_ntru, cipher_text));
ck_assert(!i_ntru->get_shared_secret(i_ntru, &shared_secret));
ck_assert(shared_secret.len == 0);
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
return NEED_MORE;
}
- this->dh->set_other_public_value(this->dh, pub);
+ if (!this->dh->set_other_public_value(this->dh, pub))
+ {
+ DBG1(DBG_TLS, "applying DH public value failed");
+ this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+ return NEED_MORE;
+ }
this->state = STATE_KEY_EXCHANGE_RECEIVED;
return NEED_MORE;
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
return NEED_MORE;
}
- this->dh->set_other_public_value(this->dh, chunk_skip(pub, 1));
+ if (!this->dh->set_other_public_value(this->dh, chunk_skip(pub, 1)))
+ {
+ DBG1(DBG_TLS, "applying DH public value failed");
+ this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+ return NEED_MORE;
+ }
this->state = STATE_KEY_EXCHANGE_RECEIVED;
return NEED_MORE;
}
pub = chunk_skip(pub, 1);
}
- this->dh->set_other_public_value(this->dh, pub);
+ if (!this->dh->set_other_public_value(this->dh, pub))
+ {
+ DBG1(DBG_TLS, "applying DH public value failed");
+ this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+ return NEED_MORE;
+ }
if (!this->dh->get_shared_secret(this->dh, &premaster))
{
DBG1(DBG_TLS, "calculating premaster from DH failed");