block_size = this->crypter->get_block_size(this->crypter);
length += block_size - length % block_size;
/* add iv */
- length += block_size;
+ length += this->crypter->get_iv_size(this->crypter);
/* add signature */
length += this->signer->get_block_size(this->signer);
}
*(to_crypt.ptr + to_crypt.len - 1) = padding.len;
/* build iv */
- iv.len = block_size;
+ iv.len = this->crypter->get_iv_size(this->crypter);
rng->allocate_bytes(rng, iv.len, &iv);
rng->destroy(rng);
}
/* get IV */
- iv.len = this->crypter->get_block_size(this->crypter);
-
+ iv.len = this->crypter->get_iv_size(this->crypter);
+ if (iv.len > this->encrypted.len)
+ {
+ DBG1(DBG_ENC, "could not decrypt, input too short");
+ return FAILED;
+ }
iv.ptr = this->encrypted.ptr;
- /* point concatenated to data + padding + padding_length*/
+ /* point concatenated to data + padding + padding_length */
concatenated.ptr = this->encrypted.ptr + iv.len;
concatenated.len = this->encrypted.len - iv.len -
this->signer->get_block_size(this->signer);
/* concatenated must be a multiple of block_size of crypter */
- if (concatenated.len < iv.len || concatenated.len % iv.len)
+ if (concatenated.len < iv.len ||
+ concatenated.len % this->crypter->get_block_size(this->crypter))
{
DBG1(DBG_ENC, "could not decrypt, invalid input");
return FAILED;
crypter = this->crypto->get_crypter(this->crypto);
bs = crypter->get_block_size(crypter);
+ iv.len = crypter->get_iv_size(crypter);
/* add AT_PADDING attribute */
padding = bs - ((sizeof(encr_buf) - encr.len) % bs);
/* add IV attribute */
hdr = (attr_hdr_t*)out.ptr;
hdr->type = AT_IV;
- hdr->length = bs / 4 + 1;
+ hdr->length = iv.len / 4 + 1;
memset(out.ptr + 2, 0, 2);
out = chunk_skip(out, 4);
rng = this->crypto->get_rng(this->crypto);
- rng->get_bytes(rng, bs, out.ptr);
+ rng->get_bytes(rng, iv.len, out.ptr);
- iv = chunk_clonea(chunk_create(out.ptr, bs));
- out = chunk_skip(out, bs);
+ iv = chunk_clonea(chunk_create(out.ptr, iv.len));
+ out = chunk_skip(out, iv.len);
/* inline encryption */
crypter->encrypt(crypter, encr, iv, NULL);
key = chunk_create(vector->key, crypter->get_key_size(crypter));
crypter->set_key(crypter, key);
- iv = chunk_create(vector->iv, crypter->get_block_size(crypter));
+ iv = chunk_create(vector->iv, crypter->get_iv_size(crypter));
/* allocated encryption */
plain = chunk_create(vector->plain, vector->len);
DBG1(DBG_LIB, "IV could not be parsed");
goto end;
}
- if (iv.len != crypter->get_block_size(crypter))
+ if (iv.len != crypter->get_iv_size(crypter))
{
DBG1(DBG_LIB, "IV has wrong length");
goto end;
rng->destroy(rng);
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
- rng->allocate_bytes(rng, crypter->get_block_size(crypter), &iv);
+ rng->allocate_bytes(rng, crypter->get_iv_size(crypter), &iv);
DBG4(DBG_LIB, " initialization vector: %B", &iv);
rng->destroy(rng);
}
}
crypter->set_key(crypter, key);
- if (iv.len != crypter->get_block_size(crypter) ||
- blob->len % iv.len)
+ if (iv.len != crypter->get_iv_size(crypter) ||
+ blob->len % crypter->get_block_size(crypter))
{
crypter->destroy(crypter);
DBG1(DBG_LIB, " data size is not multiple of block size");
eks = this->crypter_out->get_key_size(this->crypter_out);
if (this->tls->get_version(this->tls) < TLS_1_1)
{
- ivs = this->crypter_out->get_block_size(this->crypter_out);
+ ivs = this->crypter_out->get_iv_size(this->crypter_out);
}
}
seed = chunk_cata("cc", server_random, client_random);
u_int8_t bs, padding_length;
bs = this->crypter_in->get_block_size(this->crypter_in);
- if (data.len < bs || data.len % bs)
- {
- DBG1(DBG_IKE, "encrypted TLS record not multiple of block size");
- return FAILED;
- }
if (this->iv_in.len)
{ /* < TLSv1.1 uses IV from key derivation/last block */
+ if (data.len < bs || data.len % bs)
+ {
+ DBG1(DBG_IKE, "encrypted TLS record length invalid");
+ return FAILED;
+ }
iv = this->iv_in;
next_iv = chunk_clone(chunk_create(data.ptr + data.len - bs, bs));
}
else
{ /* TLSv1.1 uses random IVs, prepended to record */
- iv = chunk_create(data.ptr, bs);
- data = chunk_skip(data, bs);
- if (data.len < bs)
+ iv.len = this->crypter_in->get_iv_size(this->crypter_in);
+ iv = chunk_create(data.ptr, iv.len);
+ data = chunk_skip(data, iv.len);
+ if (data.len < bs || data.len % bs)
{
- DBG1(DBG_IKE, "TLS record too short to decrypt");
+ DBG1(DBG_IKE, "encrypted TLS record length invalid");
return FAILED;
}
}
free(data->ptr);
return FAILED;
}
- this->rng->allocate_bytes(this->rng, bs, &iv);
+ iv.len = this->crypter_out->get_iv_size(this->crypter_out);
+ this->rng->allocate_bytes(this->rng, iv.len, &iv);
}
*data = chunk_cat("mmcc", *data, mac, padding,
* the last phase 1 block, not the last block sent.
*/
{
- size_t crypter_block_size;
+ size_t crypter_block_size, crypter_iv_size;
encryption_algorithm_t enc_alg;
crypter_t *crypter;
chunk_t data, iv;
enc_alg = oakley_to_encryption_algorithm(st->st_oakley.encrypt);
crypter = lib->crypto->create_crypter(lib->crypto, enc_alg, st->st_enc_key.len);
crypter_block_size = crypter->get_block_size(crypter);
+ crypter_iv_size = crypter->get_iv_size(crypter);
if (pbs_left(&md->message_pbs) % crypter_block_size != 0)
{
}
/* form iv by truncation */
- st->st_new_iv_len = crypter_block_size;
+ st->st_new_iv_len = crypter_iv_size;
iv = chunk_create(st->st_new_iv, st->st_new_iv_len);
- new_iv = alloca(crypter_block_size);
- memcpy(new_iv, data.ptr + data.len - crypter_block_size,
- crypter_block_size);
+ new_iv = alloca(crypter_iv_size);
+ memcpy(new_iv, data.ptr + data.len - crypter_iv_size,
+ crypter_iv_size);
crypter->set_key(crypter, st->st_enc_key);
crypter->decrypt(crypter, data, iv, NULL);
crypter->destroy(crypter);
- memcpy(st->st_new_iv, new_iv, crypter_block_size);
+ memcpy(st->st_new_iv, new_iv, crypter_iv_size);
if (restore_iv)
{
memcpy(st->st_new_iv, new_iv, new_iv_len);
size_t enc_len = pbs_offset(pbs) - sizeof(struct isakmp_hdr);
chunk_t data, iv;
char *new_iv;
- size_t crypter_block_size;
+ size_t crypter_block_size, crypter_iv_size;
encryption_algorithm_t enc_alg;
crypter_t *crypter;
enc_alg = oakley_to_encryption_algorithm(st->st_oakley.encrypt);
crypter = lib->crypto->create_crypter(lib->crypto, enc_alg, st->st_enc_key.len);
crypter_block_size = crypter->get_block_size(crypter);
+ crypter_iv_size = crypter->get_iv_size(crypter);
/* Pad up to multiple of encryption blocksize.
* See the description associated with the definition of
data = chunk_create(enc_start, enc_len);
/* form iv by truncation */
- st->st_new_iv_len = crypter_block_size;
+ st->st_new_iv_len = crypter_iv_size;
iv = chunk_create(st->st_new_iv, st->st_new_iv_len);
crypter->set_key(crypter, st->st_enc_key);
crypter->encrypt(crypter, data, iv, NULL);
crypter->destroy(crypter);
- new_iv = data.ptr + data.len - crypter_block_size;
- memcpy(st->st_new_iv, new_iv, crypter_block_size);
+ new_iv = data.ptr + data.len - crypter_iv_size;
+ memcpy(st->st_new_iv, new_iv, crypter_iv_size);
update_iv(st);
DBG_cond_dump(DBG_CRYPT, "next IV:", st->st_iv, st->st_iv_len);
close_message(pbs);
DBG1(DBG_LIB, "symmetric key length %d is wrong", symmetric_key.len);
goto failed;
}
- if (iv.len != crypter->get_block_size(crypter))
+ if (iv.len != crypter->get_iv_size(crypter))
{
DBG1(DBG_LIB, "IV length %d is wrong", iv.len);
goto failed;
rng->destroy(rng);
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
- rng->allocate_bytes(rng, crypter->get_block_size(crypter), &iv);
+ rng->allocate_bytes(rng, crypter->get_iv_size(crypter), &iv);
DBG4(DBG_LIB, "initialization vector: %B", &iv);
rng->destroy(rng);
}