split encrypt/decrypt functionality of crypto_cbc()
This commit is contained in:
@@ -544,42 +544,6 @@ static void do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key,
|
|||||||
(des_cblock *)iv, enc);
|
(des_cblock *)iv, enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf,
|
|
||||||
size_t size, struct state *st)
|
|
||||||
{
|
|
||||||
chunk_t data = { buf, size };
|
|
||||||
chunk_t iv;
|
|
||||||
char *new_iv;
|
|
||||||
size_t crypter_block_size;
|
|
||||||
encryption_algorithm_t enc_alg;
|
|
||||||
crypter_t *crypter;
|
|
||||||
|
|
||||||
enc_alg = oakley_to_encryption_algorithm(e->algo_id);
|
|
||||||
crypter = lib->crypto->create_crypter(lib->crypto, enc_alg, st->st_enc_key.len);
|
|
||||||
crypter->set_key(crypter, st->st_enc_key);
|
|
||||||
crypter_block_size = crypter->get_block_size(crypter);
|
|
||||||
|
|
||||||
/* form iv by truncation */
|
|
||||||
passert(st->st_new_iv_len >= crypter_block_size);
|
|
||||||
st->st_new_iv_len = crypter_block_size;
|
|
||||||
iv = chunk_create(st->st_new_iv, st->st_new_iv_len);
|
|
||||||
|
|
||||||
if (enc)
|
|
||||||
{
|
|
||||||
crypter->encrypt(crypter, data, iv, NULL);
|
|
||||||
new_iv = data.ptr + data.len - crypter_block_size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new_iv = alloca(crypter_block_size);
|
|
||||||
memcpy(new_iv, data.ptr + data.len - crypter_block_size,
|
|
||||||
crypter_block_size);
|
|
||||||
crypter->decrypt(crypter, data, iv, NULL);
|
|
||||||
}
|
|
||||||
crypter->destroy(crypter);
|
|
||||||
memcpy(st->st_new_iv, new_iv, crypter_block_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
encryption_algorithm_t oakley_to_encryption_algorithm(int alg)
|
encryption_algorithm_t oakley_to_encryption_algorithm(int alg)
|
||||||
{
|
{
|
||||||
switch (alg)
|
switch (alg)
|
||||||
|
|||||||
@@ -48,8 +48,6 @@ extern const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE];
|
|||||||
|
|
||||||
struct state; /* forward declaration, dammit */
|
struct state; /* forward declaration, dammit */
|
||||||
|
|
||||||
void crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf, size_t size, struct state *st);
|
|
||||||
|
|
||||||
#define update_iv(st) memcpy((st)->st_iv, (st)->st_new_iv \
|
#define update_iv(st) memcpy((st)->st_iv, (st)->st_new_iv \
|
||||||
, (st)->st_iv_len = (st)->st_new_iv_len)
|
, (st)->st_iv_len = (st)->st_new_iv_len)
|
||||||
|
|
||||||
|
|||||||
+25
-4
@@ -1780,9 +1780,17 @@ 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.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
const struct encrypt_desc *e = st->st_oakley.encrypter;
|
size_t crypter_block_size;
|
||||||
|
encryption_algorithm_t enc_alg;
|
||||||
|
crypter_t *crypter;
|
||||||
|
chunk_t data, iv;
|
||||||
|
char *new_iv;
|
||||||
|
|
||||||
if (pbs_left(&md->message_pbs) % e->enc_blocksize != 0)
|
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);
|
||||||
|
|
||||||
|
if (pbs_left(&md->message_pbs) % crypter_block_size != 0)
|
||||||
{
|
{
|
||||||
loglog(RC_LOG_SERIOUS, "malformed message: not a multiple of encryption blocksize");
|
loglog(RC_LOG_SERIOUS, "malformed message: not a multiple of encryption blocksize");
|
||||||
SEND_NOTIFICATION(PAYLOAD_MALFORMED);
|
SEND_NOTIFICATION(PAYLOAD_MALFORMED);
|
||||||
@@ -1795,6 +1803,8 @@ process_packet(struct msg_digest **mdp)
|
|||||||
md->raw_packet = chunk_create(md->packet_pbs.start, pbs_room(&md->packet_pbs));
|
md->raw_packet = chunk_create(md->packet_pbs.start, pbs_room(&md->packet_pbs));
|
||||||
md->raw_packet = chunk_clone(md->raw_packet);
|
md->raw_packet = chunk_clone(md->raw_packet);
|
||||||
|
|
||||||
|
data = chunk_create(md->message_pbs.cur, pbs_left(&md->message_pbs));
|
||||||
|
|
||||||
/* Decrypt everything after header */
|
/* Decrypt everything after header */
|
||||||
if (!new_iv_set)
|
if (!new_iv_set)
|
||||||
{
|
{
|
||||||
@@ -1803,8 +1813,19 @@ process_packet(struct msg_digest **mdp)
|
|||||||
st->st_new_iv_len = st->st_iv_len;
|
st->st_new_iv_len = st->st_iv_len;
|
||||||
memcpy(st->st_new_iv, st->st_iv, st->st_new_iv_len);
|
memcpy(st->st_new_iv, st->st_iv, st->st_new_iv_len);
|
||||||
}
|
}
|
||||||
crypto_cbc_encrypt(e, FALSE, md->message_pbs.cur,
|
|
||||||
pbs_left(&md->message_pbs) , st);
|
/* form iv by truncation */
|
||||||
|
st->st_new_iv_len = crypter_block_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);
|
||||||
|
|
||||||
|
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);
|
||||||
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);
|
||||||
|
|||||||
+19
-4
@@ -1857,18 +1857,25 @@ static notification_t accept_nonce(struct msg_digest *md, chunk_t *dest,
|
|||||||
bool
|
bool
|
||||||
encrypt_message(pb_stream *pbs, struct state *st)
|
encrypt_message(pb_stream *pbs, struct state *st)
|
||||||
{
|
{
|
||||||
const struct encrypt_desc *e = st->st_oakley.encrypter;
|
|
||||||
u_int8_t *enc_start = pbs->start + sizeof(struct isakmp_hdr);
|
u_int8_t *enc_start = pbs->start + sizeof(struct isakmp_hdr);
|
||||||
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;
|
||||||
|
char *new_iv;
|
||||||
|
size_t crypter_block_size;
|
||||||
|
encryption_algorithm_t enc_alg;
|
||||||
|
crypter_t *crypter;
|
||||||
|
|
||||||
DBG_cond_dump(DBG_CRYPT | DBG_RAW, "encrypting:\n", enc_start, enc_len);
|
DBG_cond_dump(DBG_CRYPT | DBG_RAW, "encrypting:\n", enc_start, enc_len);
|
||||||
|
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);
|
||||||
|
|
||||||
/* 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
|
||||||
* struct isakmp_hdr in packet.h.
|
* struct isakmp_hdr in packet.h.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
size_t padding = pad_up(enc_len, e->enc_blocksize);
|
size_t padding = pad_up(enc_len, crypter_block_size);
|
||||||
|
|
||||||
if (padding != 0)
|
if (padding != 0)
|
||||||
{
|
{
|
||||||
@@ -1879,10 +1886,18 @@ encrypt_message(pb_stream *pbs, struct state *st)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DBG(DBG_CRYPT, DBG_log("encrypting using %s", enum_show(&oakley_enc_names, st->st_oakley.encrypt)));
|
DBG(DBG_CRYPT, DBG_log("encrypting using %s", enum_show(&oakley_enc_names, st->st_oakley.encrypt)));
|
||||||
|
data = chunk_create(enc_start, enc_len);
|
||||||
|
|
||||||
/* e->crypt(TRUE, enc_start, enc_len, st); */
|
/* form iv by truncation */
|
||||||
crypto_cbc_encrypt(e, TRUE, enc_start, enc_len, st);
|
st->st_new_iv_len = crypter_block_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);
|
||||||
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user