0
0
mirror of https://github.com/OpenVPN/openvpn.git synced 2024-09-20 12:02:28 +02:00

Change openvpn_encrypt() to append to work buffer only

Preparation for AEAD cipher modes, which also have to authenticate the
opcode and peer-id of packets.  To supply that information to
openvpn_encrypt(), I want to simply write those to the work buffer
before calling openvpn_encrypt().  That however requires that
openvpn_encrypt() never prepends something to the work buffer.

Signed-off-by: Steffan Karger <steffan@karger.me>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <1454874438-5081-7-git-send-email-steffan@karger.me>
URL: http://article.gmane.org/gmane.network.openvpn.devel/11074
Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
Steffan Karger 2016-02-07 20:47:14 +01:00 committed by Gert Doering
parent 3ebc31f959
commit a070f75b7d

View File

@ -93,6 +93,8 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
if (buf->len > 0 && opt)
{
const struct key_ctx *ctx = &opt->key_ctx_bi.encrypt;
uint8_t *mac_out = NULL;
const uint8_t *hmac_start = NULL;
/* Do Encrypt from buf -> work */
if (ctx->cipher)
@ -102,6 +104,17 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
int outlen;
/* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */
ASSERT (buf_init (&work, FRAME_HEADROOM (frame)));
/* Reserve space for HMAC */
if (ctx->hmac)
{
mac_out = buf_write_alloc (&work, hmac_ctx_size(ctx->hmac));
ASSERT (mac_out);
hmac_start = BEND(&work);
}
if (cipher_kt_mode_cbc(cipher_kt))
{
CLEAR (iv_buf);
@ -137,12 +150,12 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
ASSERT (0);
}
/* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */
ASSERT (buf_init (&work, FRAME_HEADROOM (frame)));
/* set the IV pseudo-randomly */
if (opt->flags & CO_USE_IV)
dmsg (D_PACKET_CONTENT, "ENCRYPT IV: %s", format_hex (iv_buf, iv_size, 0, &gc));
{
ASSERT (buf_write(&work, iv_buf, iv_size));
dmsg (D_PACKET_CONTENT, "ENCRYPT IV: %s", format_hex (iv_buf, iv_size, 0, &gc));
}
dmsg (D_PACKET_CONTENT, "ENCRYPT FROM: %s",
format_hex (BPTR (buf), BLEN (buf), 80, &gc));
@ -165,27 +178,16 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
}
/* Encrypt packet ID, payload */
ASSERT (cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf)));
ASSERT (cipher_ctx_update (ctx->cipher, BEND (&work), &outlen, BPTR (buf), BLEN (buf)));
ASSERT (buf_inc_len(&work, outlen));
/* Flush the encryption buffer */
ASSERT (cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen));
ASSERT (cipher_ctx_final(ctx->cipher, BEND (&work), &outlen));
ASSERT (buf_inc_len(&work, outlen));
/* For all CBC mode ciphers, check the last block is complete */
ASSERT (cipher_kt_mode (cipher_kt) != OPENVPN_MODE_CBC ||
outlen == iv_size);
/* prepend the IV to the ciphertext */
if (opt->flags & CO_USE_IV)
{
uint8_t *output = buf_prepend (&work, iv_size);
ASSERT (output);
memcpy (output, iv_buf, iv_size);
}
dmsg (D_PACKET_CONTENT, "ENCRYPT TO: %s",
format_hex (BPTR (&work), BLEN (&work), 80, &gc));
}
else /* No Encryption */
{
@ -195,22 +197,29 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
packet_id_alloc_outgoing (&opt->packet_id.send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM));
ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true));
}
if (ctx->hmac)
{
hmac_start = BPTR(buf);
ASSERT (mac_out = buf_prepend (buf, hmac_ctx_size(ctx->hmac)));
}
buf_write_prepend(buf, BPTR(&work), BLEN(&work));
work = *buf;
}
/* HMAC the ciphertext (or plaintext if !cipher) */
if (ctx->hmac)
{
uint8_t *output = NULL;
hmac_ctx_reset (ctx->hmac);
hmac_ctx_update (ctx->hmac, BPTR(&work), BLEN(&work));
output = buf_prepend (&work, hmac_ctx_size(ctx->hmac));
ASSERT (output);
hmac_ctx_final (ctx->hmac, output);
hmac_ctx_update (ctx->hmac, hmac_start, BEND(&work) - hmac_start);
hmac_ctx_final (ctx->hmac, mac_out);
dmsg (D_PACKET_CONTENT, "ENCRYPT HMAC: %s",
format_hex (mac_out, hmac_ctx_size(ctx->hmac), 80, &gc));
}
*buf = work;
dmsg (D_PACKET_CONTENT, "ENCRYPT TO: %s",
format_hex (BPTR (&work), BLEN (&work), 80, &gc));
}
gc_free (&gc);