Skip to content

Commit

Permalink
Add ESP decryption (unused)
Browse files Browse the repository at this point in the history
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Jan 26, 2015
1 parent 539158a commit 2fea605
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 2 deletions.
66 changes: 64 additions & 2 deletions gnutls-esp.c
Expand Up @@ -109,8 +109,8 @@ int setup_esp_keys(struct openconnect_info *vpninfo)
return -EINVAL;
}

ret = gnutls_rnd(GNUTLS_RND_NONCE, &vpninfo->esp_in.secrets,
sizeof(vpninfo->esp_in.secrets));
ret = gnutls_rnd(GNUTLS_RND_NONCE, &vpninfo->esp_in.spi,
sizeof(vpninfo->esp_in.secrets) + sizeof(vpninfo->esp_in.spi));
if (ret) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to generate random keys for ESP: %s\n"),
Expand All @@ -131,3 +131,65 @@ int setup_esp_keys(struct openconnect_info *vpninfo)
vpninfo->dtls_state = DTLS_SECRET;
return 0;
}


int decrypt_and_queue_esp_packet(struct openconnect_info *vpninfo, unsigned char *esp, int len)
{
struct pkt *pkt;
unsigned char hmac_buf[20];
const int ivsize = 16; /* We don't support anything different... yet. */

if (len < 20 + ivsize)
return -EINVAL;

if (memcmp(esp, vpninfo->esp_in.spi, 4)) {
vpn_progress(vpninfo, PRG_DEBUG,
_("Received ESP packet with invalid SPI %02x%02x%02x%02x\n"),
esp[0], esp[1], esp[2], esp[3]);
return -EINVAL;
}

/* XXX: Implement seq checking. Record the highest seq# received, and keep
a small bitmap covering a sliding window just before that, so out-of-order
packets can be accepted within reason but each packet only once. */

gnutls_hmac(vpninfo->esp_in.hmac, esp, len - 12);
gnutls_hmac_output(vpninfo->esp_in.hmac, hmac_buf);
if (memcmp(hmac_buf, esp + len - 12, 12)) {
vpn_progress(vpninfo, PRG_DEBUG,
_("Received ESP packet with invalid HMAC\n"));
return -EINVAL;
}

gnutls_cipher_set_iv(vpninfo->esp_in.cipher, esp + 8, ivsize);

len -= 20 + ivsize;

pkt = malloc(sizeof(struct pkt) + len);
if (!pkt)
return -ENOMEM;

if (gnutls_cipher_decrypt2(vpninfo->esp_in.cipher,
pkt->data + 8 + ivsize, len,
pkt->data, len)) {
printf("decrypt fail\n");
return -EINVAL;
}

if (pkt->data[len - 1] != 0x04 && pkt->data[len - 1] != 0x29) {
/* 0x05 is LZO compressed. */
vpn_progress(vpninfo, PRG_ERR,
_("Received ESP packet with unrecognised payload type %02x\n"),
pkt->data[len-1]);
return -EINVAL;
}
if (len <= 2 + pkt->data[len - 2]) {
printf("Invalid padding length %02x in ESP\n",
pkt->data[len - 2]);
return -EINVAL;
}
pkt->len = len - 2 + pkt->data[len - 2];

queue_packet(&vpninfo->incoming_queue, pkt);
return 0;
}
1 change: 1 addition & 0 deletions openconnect-internal.h
Expand Up @@ -751,6 +751,7 @@ int load_pkcs11_certificate(struct openconnect_info *vpninfo);
/* gnutls-esp.c */
int setup_esp_keys(struct openconnect_info *vpninfo);
void destroy_esp_ciphers(struct esp *esp);
int decrypt_and_queue_esp_packet(struct openconnect_info *vpninfo, unsigned char *esp, int len);

/* {gnutls,openssl}.c */
int ssl_nonblock_read(struct openconnect_info *vpninfo, void *buf, int maxlen);
Expand Down

0 comments on commit 2fea605

Please sign in to comment.