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:
parent
3ebc31f959
commit
a070f75b7d
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user