SILC_FSM_CALL(ske->key_op =
silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
payload->sign_len, hash, hash_len, NULL,
- ske->rng, silc_ske_verify_cb, ske));
+ silc_ske_verify_cb, ske));
/* NOT REACHED */
}
SilcSKE ske = fsm_context;
SilcUInt32 error = SILC_SKE_STATUS_ERROR;
- if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
+ if (ske->packet && ske->packet->type == SILC_PACKET_FAILURE &&
+ silc_buffer_len(&ske->packet->buffer) == 4) {
SILC_GET32_MSB(error, ske->packet->buffer.data);
ske->status = error;
silc_packet_free(ske->packet);
silc_pkcs_verify(ske->prop->public_key,
recv_payload->sign_data,
recv_payload->sign_len,
- hash, hash_len, NULL, ske->rng,
+ hash, hash_len, NULL,
silc_ske_verify_cb, ske));
/* NOT REACHED */
}
SILC_LOG_DEBUG(("Key exchange protocol failed"));
- if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
+ if (ske->packet && ske->packet->type == SILC_PACKET_FAILURE &&
+ silc_buffer_len(&ske->packet->buffer) == 4) {
SILC_GET32_MSB(error, ske->packet->buffer.data);
ske->status = error;
silc_packet_free(ske->packet);
SilcHmac *ret_hmac_receive,
SilcHash *ret_hash)
{
- unsigned char iv[32];
+ unsigned char iv[SILC_HASH_MAXLEN];
SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
/* Allocate ciphers to be used in the communication */
return FALSE;
}
+ /* Allocate hash */
+ if (ret_hash) {
+ if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
+ return FALSE;
+ }
+
/* Set key material */
memset(iv, 0, sizeof(iv));
if (ske->responder) {
keymat->enc_key_len, TRUE);
if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
- memcpy(iv, ske->hash, 4);
- memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
+ /* Counter mode */
+ if (!ske->rekeying) {
+ /* Set IV. */
+ memcpy(iv, ske->hash, 4);
+ if (!iv_included)
+ memcpy(iv + 4, keymat->receive_iv, 8);
+ } else {
+ /* Rekey, recompute the truncated hash value. */
+ silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
+ if (!iv_included)
+ memcpy(iv + 4, keymat->receive_iv, 8);
+ else
+ memset(iv + 4, 0, 12);
+ }
+
silc_cipher_set_iv(*ret_send_key, iv);
} else {
+ /* Other modes */
silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
}
}
keymat->enc_key_len, FALSE);
if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
- memcpy(iv, ske->hash, 4);
- memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
+ /* Counter mode */
+ if (!ske->rekeying) {
+ /* Set IV. */
+ memcpy(iv, ske->hash, 4);
+ if (!iv_included)
+ memcpy(iv + 4, keymat->send_iv, 8);
+ } else {
+ /* Rekey, recompute the truncated hash value. */
+ silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
+ if (!iv_included)
+ memcpy(iv + 4, keymat->send_iv, 8);
+ else
+ memset(iv + 4, 0, 12);
+ }
+
silc_cipher_set_iv(*ret_receive_key, iv);
} else {
+ /* Other modes */
silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
}
}
keymat->enc_key_len, TRUE);
if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
- memcpy(iv, ske->hash, 4);
- memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
+ /* Counter mode */
+ if (!ske->rekeying) {
+ /* Set IV. */
+ memcpy(iv, ske->hash, 4);
+ if (!iv_included)
+ memcpy(iv + 4, keymat->send_iv, 8);
+ } else {
+ /* Rekey, recompute the truncated hash value. */
+ silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
+ if (!iv_included)
+ memcpy(iv + 4, keymat->send_iv, 8);
+ else
+ memset(iv + 4, 0, 12);
+ }
+
silc_cipher_set_iv(*ret_send_key, iv);
} else {
+ /* Other modes */
silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
}
}
keymat->enc_key_len, FALSE);
if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
- memcpy(iv, ske->hash, 4);
- memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
+ /* Counter mode */
+ if (!ske->rekeying) {
+ /* Set IV. If IV Included flag was negotiated we only set the
+ truncated hash value. */
+ memcpy(iv, ske->hash, 4);
+ if (!iv_included)
+ memcpy(iv + 4, keymat->receive_iv, 8);
+ } else {
+ /* Rekey, recompute the truncated hash value. */
+ silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
+ if (!iv_included)
+ memcpy(iv + 4, keymat->receive_iv, 8);
+ else
+ memset(iv + 4, 0, 12);
+ }
+
silc_cipher_set_iv(*ret_receive_key, iv);
} else {
+ /* Other modes */
silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
}
}
keymat->hmac_key_len);
}
- /* Allocate hash */
- if (ret_hash) {
- if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
- return FALSE;
- }
-
return TRUE;
}