Use IV length of a crypter instead of block size for IV calculations
This commit is contained in:
@@ -199,7 +199,7 @@ static void compute_length(private_encryption_payload_t *this)
|
|||||||
block_size = this->crypter->get_block_size(this->crypter);
|
block_size = this->crypter->get_block_size(this->crypter);
|
||||||
length += block_size - length % block_size;
|
length += block_size - length % block_size;
|
||||||
/* add iv */
|
/* add iv */
|
||||||
length += block_size;
|
length += this->crypter->get_iv_size(this->crypter);
|
||||||
/* add signature */
|
/* add signature */
|
||||||
length += this->signer->get_block_size(this->signer);
|
length += this->signer->get_block_size(this->signer);
|
||||||
}
|
}
|
||||||
@@ -355,7 +355,7 @@ static status_t encrypt(private_encryption_payload_t *this)
|
|||||||
*(to_crypt.ptr + to_crypt.len - 1) = padding.len;
|
*(to_crypt.ptr + to_crypt.len - 1) = padding.len;
|
||||||
|
|
||||||
/* build iv */
|
/* build iv */
|
||||||
iv.len = block_size;
|
iv.len = this->crypter->get_iv_size(this->crypter);
|
||||||
rng->allocate_bytes(rng, iv.len, &iv);
|
rng->allocate_bytes(rng, iv.len, &iv);
|
||||||
rng->destroy(rng);
|
rng->destroy(rng);
|
||||||
|
|
||||||
@@ -450,8 +450,12 @@ static status_t decrypt(private_encryption_payload_t *this)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get IV */
|
/* 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;
|
iv.ptr = this->encrypted.ptr;
|
||||||
|
|
||||||
/* point concatenated to data + padding + padding_length */
|
/* point concatenated to data + padding + padding_length */
|
||||||
@@ -460,7 +464,8 @@ static status_t decrypt(private_encryption_payload_t *this)
|
|||||||
this->signer->get_block_size(this->signer);
|
this->signer->get_block_size(this->signer);
|
||||||
|
|
||||||
/* concatenated must be a multiple of block_size of crypter */
|
/* 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");
|
DBG1(DBG_ENC, "could not decrypt, invalid input");
|
||||||
return FAILED;
|
return FAILED;
|
||||||
|
|||||||
@@ -741,6 +741,7 @@ static eap_payload_t* generate(private_simaka_message_t *this, chunk_t sigdata)
|
|||||||
|
|
||||||
crypter = this->crypto->get_crypter(this->crypto);
|
crypter = this->crypto->get_crypter(this->crypto);
|
||||||
bs = crypter->get_block_size(crypter);
|
bs = crypter->get_block_size(crypter);
|
||||||
|
iv.len = crypter->get_iv_size(crypter);
|
||||||
|
|
||||||
/* add AT_PADDING attribute */
|
/* add AT_PADDING attribute */
|
||||||
padding = bs - ((sizeof(encr_buf) - encr.len) % bs);
|
padding = bs - ((sizeof(encr_buf) - encr.len) % bs);
|
||||||
@@ -757,15 +758,15 @@ static eap_payload_t* generate(private_simaka_message_t *this, chunk_t sigdata)
|
|||||||
/* add IV attribute */
|
/* add IV attribute */
|
||||||
hdr = (attr_hdr_t*)out.ptr;
|
hdr = (attr_hdr_t*)out.ptr;
|
||||||
hdr->type = AT_IV;
|
hdr->type = AT_IV;
|
||||||
hdr->length = bs / 4 + 1;
|
hdr->length = iv.len / 4 + 1;
|
||||||
memset(out.ptr + 2, 0, 2);
|
memset(out.ptr + 2, 0, 2);
|
||||||
out = chunk_skip(out, 4);
|
out = chunk_skip(out, 4);
|
||||||
|
|
||||||
rng = this->crypto->get_rng(this->crypto);
|
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));
|
iv = chunk_clonea(chunk_create(out.ptr, iv.len));
|
||||||
out = chunk_skip(out, bs);
|
out = chunk_skip(out, iv.len);
|
||||||
|
|
||||||
/* inline encryption */
|
/* inline encryption */
|
||||||
crypter->encrypt(crypter, encr, iv, NULL);
|
crypter->encrypt(crypter, encr, iv, NULL);
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ static bool test_crypter(private_crypto_tester_t *this,
|
|||||||
|
|
||||||
key = chunk_create(vector->key, crypter->get_key_size(crypter));
|
key = chunk_create(vector->key, crypter->get_key_size(crypter));
|
||||||
crypter->set_key(crypter, key);
|
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 */
|
/* allocated encryption */
|
||||||
plain = chunk_create(vector->plain, vector->len);
|
plain = chunk_create(vector->plain, vector->len);
|
||||||
|
|||||||
@@ -559,7 +559,7 @@ static bool parse_envelopedData(private_pkcs7_t *this, chunk_t serialNumber,
|
|||||||
DBG1(DBG_LIB, "IV could not be parsed");
|
DBG1(DBG_LIB, "IV could not be parsed");
|
||||||
goto end;
|
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");
|
DBG1(DBG_LIB, "IV has wrong length");
|
||||||
goto end;
|
goto end;
|
||||||
@@ -752,7 +752,7 @@ bool build_envelopedData(private_pkcs7_t *this, x509_t *cert,
|
|||||||
rng->destroy(rng);
|
rng->destroy(rng);
|
||||||
|
|
||||||
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
|
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);
|
DBG4(DBG_LIB, " initialization vector: %B", &iv);
|
||||||
rng->destroy(rng);
|
rng->destroy(rng);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,8 +127,8 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg,
|
|||||||
}
|
}
|
||||||
crypter->set_key(crypter, key);
|
crypter->set_key(crypter, key);
|
||||||
|
|
||||||
if (iv.len != crypter->get_block_size(crypter) ||
|
if (iv.len != crypter->get_iv_size(crypter) ||
|
||||||
blob->len % iv.len)
|
blob->len % crypter->get_block_size(crypter))
|
||||||
{
|
{
|
||||||
crypter->destroy(crypter);
|
crypter->destroy(crypter);
|
||||||
DBG1(DBG_LIB, " data size is not multiple of block size");
|
DBG1(DBG_LIB, " data size is not multiple of block size");
|
||||||
|
|||||||
@@ -772,7 +772,7 @@ METHOD(tls_crypto_t, derive_secrets, void,
|
|||||||
eks = this->crypter_out->get_key_size(this->crypter_out);
|
eks = this->crypter_out->get_key_size(this->crypter_out);
|
||||||
if (this->tls->get_version(this->tls) < TLS_1_1)
|
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);
|
seed = chunk_cata("cc", server_random, client_random);
|
||||||
|
|||||||
+12
-10
@@ -112,23 +112,24 @@ METHOD(tls_protection_t, process, status_t,
|
|||||||
u_int8_t bs, padding_length;
|
u_int8_t bs, padding_length;
|
||||||
|
|
||||||
bs = this->crypter_in->get_block_size(this->crypter_in);
|
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)
|
if (this->iv_in.len)
|
||||||
{ /* < TLSv1.1 uses IV from key derivation/last block */
|
{ /* < 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;
|
iv = this->iv_in;
|
||||||
next_iv = chunk_clone(chunk_create(data.ptr + data.len - bs, bs));
|
next_iv = chunk_clone(chunk_create(data.ptr + data.len - bs, bs));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* TLSv1.1 uses random IVs, prepended to record */
|
{ /* TLSv1.1 uses random IVs, prepended to record */
|
||||||
iv = chunk_create(data.ptr, bs);
|
iv.len = this->crypter_in->get_iv_size(this->crypter_in);
|
||||||
data = chunk_skip(data, bs);
|
iv = chunk_create(data.ptr, iv.len);
|
||||||
if (data.len < bs)
|
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;
|
return FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,7 +232,8 @@ METHOD(tls_protection_t, build, status_t,
|
|||||||
free(data->ptr);
|
free(data->ptr);
|
||||||
return FAILED;
|
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,
|
*data = chunk_cat("mmcc", *data, mac, padding,
|
||||||
|
|||||||
+7
-6
@@ -1782,7 +1782,7 @@ process_packet(struct msg_digest **mdp)
|
|||||||
* the last phase 1 block, not the last block sent.
|
* 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;
|
encryption_algorithm_t enc_alg;
|
||||||
crypter_t *crypter;
|
crypter_t *crypter;
|
||||||
chunk_t data, iv;
|
chunk_t data, iv;
|
||||||
@@ -1791,6 +1791,7 @@ process_packet(struct msg_digest **mdp)
|
|||||||
enc_alg = oakley_to_encryption_algorithm(st->st_oakley.encrypt);
|
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 = lib->crypto->create_crypter(lib->crypto, enc_alg, st->st_enc_key.len);
|
||||||
crypter_block_size = crypter->get_block_size(crypter);
|
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)
|
if (pbs_left(&md->message_pbs) % crypter_block_size != 0)
|
||||||
{
|
{
|
||||||
@@ -1817,17 +1818,17 @@ process_packet(struct msg_digest **mdp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* form iv by truncation */
|
/* 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);
|
iv = chunk_create(st->st_new_iv, st->st_new_iv_len);
|
||||||
new_iv = alloca(crypter_block_size);
|
new_iv = alloca(crypter_iv_size);
|
||||||
memcpy(new_iv, data.ptr + data.len - crypter_block_size,
|
memcpy(new_iv, data.ptr + data.len - crypter_iv_size,
|
||||||
crypter_block_size);
|
crypter_iv_size);
|
||||||
|
|
||||||
crypter->set_key(crypter, st->st_enc_key);
|
crypter->set_key(crypter, st->st_enc_key);
|
||||||
crypter->decrypt(crypter, data, iv, NULL);
|
crypter->decrypt(crypter, data, iv, NULL);
|
||||||
crypter->destroy(crypter);
|
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)
|
if (restore_iv)
|
||||||
{
|
{
|
||||||
memcpy(st->st_new_iv, new_iv, new_iv_len);
|
memcpy(st->st_new_iv, new_iv, new_iv_len);
|
||||||
|
|||||||
@@ -1753,7 +1753,7 @@ bool encrypt_message(pb_stream *pbs, struct state *st)
|
|||||||
size_t enc_len = pbs_offset(pbs) - sizeof(struct isakmp_hdr);
|
size_t enc_len = pbs_offset(pbs) - sizeof(struct isakmp_hdr);
|
||||||
chunk_t data, iv;
|
chunk_t data, iv;
|
||||||
char *new_iv;
|
char *new_iv;
|
||||||
size_t crypter_block_size;
|
size_t crypter_block_size, crypter_iv_size;
|
||||||
encryption_algorithm_t enc_alg;
|
encryption_algorithm_t enc_alg;
|
||||||
crypter_t *crypter;
|
crypter_t *crypter;
|
||||||
|
|
||||||
@@ -1761,6 +1761,7 @@ bool encrypt_message(pb_stream *pbs, struct state *st)
|
|||||||
enc_alg = oakley_to_encryption_algorithm(st->st_oakley.encrypt);
|
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 = lib->crypto->create_crypter(lib->crypto, enc_alg, st->st_enc_key.len);
|
||||||
crypter_block_size = crypter->get_block_size(crypter);
|
crypter_block_size = crypter->get_block_size(crypter);
|
||||||
|
crypter_iv_size = crypter->get_iv_size(crypter);
|
||||||
|
|
||||||
/* Pad up to multiple of encryption blocksize.
|
/* Pad up to multiple of encryption blocksize.
|
||||||
* See the description associated with the definition of
|
* See the description associated with the definition of
|
||||||
@@ -1781,15 +1782,15 @@ bool encrypt_message(pb_stream *pbs, struct state *st)
|
|||||||
data = chunk_create(enc_start, enc_len);
|
data = chunk_create(enc_start, enc_len);
|
||||||
|
|
||||||
/* form iv by truncation */
|
/* 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);
|
iv = chunk_create(st->st_new_iv, st->st_new_iv_len);
|
||||||
|
|
||||||
crypter->set_key(crypter, st->st_enc_key);
|
crypter->set_key(crypter, st->st_enc_key);
|
||||||
crypter->encrypt(crypter, data, iv, NULL);
|
crypter->encrypt(crypter, data, iv, NULL);
|
||||||
crypter->destroy(crypter);
|
crypter->destroy(crypter);
|
||||||
|
|
||||||
new_iv = data.ptr + data.len - crypter_block_size;
|
new_iv = data.ptr + data.len - crypter_iv_size;
|
||||||
memcpy(st->st_new_iv, new_iv, crypter_block_size);
|
memcpy(st->st_new_iv, new_iv, crypter_iv_size);
|
||||||
update_iv(st);
|
update_iv(st);
|
||||||
DBG_cond_dump(DBG_CRYPT, "next IV:", st->st_iv, st->st_iv_len);
|
DBG_cond_dump(DBG_CRYPT, "next IV:", st->st_iv, st->st_iv_len);
|
||||||
close_message(pbs);
|
close_message(pbs);
|
||||||
|
|||||||
+2
-2
@@ -473,7 +473,7 @@ end:
|
|||||||
DBG1(DBG_LIB, "symmetric key length %d is wrong", symmetric_key.len);
|
DBG1(DBG_LIB, "symmetric key length %d is wrong", symmetric_key.len);
|
||||||
goto failed;
|
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);
|
DBG1(DBG_LIB, "IV length %d is wrong", iv.len);
|
||||||
goto failed;
|
goto failed;
|
||||||
@@ -668,7 +668,7 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, certificate_t *cert, int enc_alg
|
|||||||
rng->destroy(rng);
|
rng->destroy(rng);
|
||||||
|
|
||||||
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
|
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);
|
DBG4(DBG_LIB, "initialization vector: %B", &iv);
|
||||||
rng->destroy(rng);
|
rng->destroy(rng);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user