diff options
-rw-r--r-- | src/Makefile | 10 | ||||
-rw-r--r-- | src/auth_algo.c | 245 | ||||
-rw-r--r-- | src/auth_algo.h | 63 | ||||
-rw-r--r-- | src/cipher.c | 29 | ||||
-rw-r--r-- | src/cipher.h | 2 | ||||
-rw-r--r-- | src/encrypted_packet.c | 72 | ||||
-rw-r--r-- | src/encrypted_packet.h | 11 | ||||
-rw-r--r-- | src/options.c | 6 | ||||
-rw-r--r-- | src/plain_packet.c | 2 | ||||
-rw-r--r-- | src/uanytun.c | 19 |
10 files changed, 435 insertions, 24 deletions
diff --git a/src/Makefile b/src/Makefile index 3c0edba..1431568 100644 --- a/src/Makefile +++ b/src/Makefile @@ -34,7 +34,7 @@ TARGET=$(shell uname -s) CC = gcc -CCFLAGS = -g -O2 # -DANYTUN_02_COMPAT +CCFLAGS = -g -O2 #-DANYTUN_02_COMPAT LD = gcc LDFLAGS = -g -Wall -O2 -lgcrypt -lgpg-error -lgmp @@ -54,8 +54,9 @@ OBJS = log.o \ plain_packet.o \ encrypted_packet.o \ seq_window.o \ - cipher.o \ key_derivation.o \ + cipher.o \ + auth_algo.o \ uanytun.o EXECUTABLE = uanytun @@ -92,10 +93,13 @@ encrypted_packet.o: encrypted_packet.c encrypted_packet.h seq_window.o: seq_window.c seq_window.h $(CC) $(CCFLAGS) $< -c +key_derivation.o: key_derivation.c key_derivation.h + $(CC) $(CCFLAGS) $< -c + cipher.o: cipher.c cipher.h $(CC) $(CCFLAGS) $< -c -key_derivation.o: key_derivation.c key_derivation.h +auth_algo.o: auth_algo.c auth_algo.h $(CC) $(CCFLAGS) $< -c distclean: clean diff --git a/src/auth_algo.c b/src/auth_algo.c new file mode 100644 index 0000000..4f91338 --- /dev/null +++ b/src/auth_algo.c @@ -0,0 +1,245 @@ +/* + * ľAnytun + * + * ľAnytun is a tiny implementation of SATP. Unlike Anytun which is a full + * featured implementation ľAnytun has no support for multiple connections + * or synchronisation. It is a small single threaded implementation intended + * to act as a client on small platforms. + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Christian Pointner <equinox@anytun.org> + * + * This file is part of ľAnytun. + * + * ľAnytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * ľAnytun is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ľAnytun. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "datatypes.h" + +#include "encrypted_packet.h" + +#include "auth_algo.h" + +#include "log.h" + +#include <stdlib.h> +#include <string.h> + +int auth_algo_init(auth_algo_t* aa, const char* type) +{ + if(!aa) + return -1; + + aa->type_ = aa_unknown; + if(!strcmp(type, "null")) + aa->type_ = aa_null; + else if(!strcmp(type, "sha1")) + aa->type_ = aa_sha1; + else { + log_printf(ERR, "unknown auth algo type"); + return -1; + } + + aa->handle_ = 0; + + aa->key_.buf_ = NULL; + aa->key_.length_ = 0; + + int ret = 0; + if(aa->type_ == aa_sha1) + ret = auth_algo_sha1_init(aa); + + if(ret) + auth_algo_close(aa); + + return ret; +} + +void auth_algo_close(auth_algo_t* aa) +{ + if(!aa) + return; + + if(aa->type_ == aa_sha1) + auth_algo_sha1_close(aa); + + if(aa->key_.buf_) + free(aa->key_.buf_); +} + +void auth_algo_generate(auth_algo_t* aa, key_derivation_t* kd, encrypted_packet_t* packet) +{ + if(!aa) + return; + + u_int32_t len; + if(aa->type_ == aa_null) + return; + else if(aa->type_ == aa_sha1) + auth_algo_sha1_generate(aa, kd, packet); + else { + log_printf(ERR, "unknown auth algo type"); + return; + } +} + +int auth_algo_check_tag(auth_algo_t* aa, key_derivation_t* kd, encrypted_packet_t* packet) +{ + if(!aa) + return; + + u_int32_t len; + if(aa->type_ == aa_null) + return 1; + else if(aa->type_ == aa_sha1) + return auth_algo_sha1_check_tag(aa, kd, packet); + else { + log_printf(ERR, "unknown auth algo type"); + return; + } +} + +/* ---------------- HMAC Sha1 Auth Algo ---------------- */ + +int auth_algo_sha1_init(auth_algo_t* aa) +{ + if(!aa) + return -1; + + gcry_error_t err = gcry_md_open(&aa->handle_, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC); + if(err) { + log_printf(ERR, "failed to open message digest algo: %s/%s", gcry_strerror(err), gcry_strsource(err)); + return -1; + } + + return 0; +} + +void auth_algo_sha1_close(auth_algo_t* aa) +{ + if(!aa) + return; + + if(aa->handle_) + gcry_md_close(aa->handle_); +} + + +void auth_algo_sha1_generate(auth_algo_t* aa, key_derivation_t* kd, encrypted_packet_t* packet) +{ + if(!aa) { + log_printf(ERR, "auth algo not initialized"); + return; + } + if(!kd) { + log_printf(ERR, "no key derivation supplied"); + return; + } + + + if(!aa->key_.buf_) { + aa->key_.length_ = SHA1_LENGTH; + aa->key_.buf_ = malloc(aa->key_.length_); + if(!aa->key_.buf_) { + log_printf(ERR, "memory error at auth algo generate"); + return; + } + } + + int ret = key_derivation_generate(kd, LABEL_SATP_MSG_AUTH, encrypted_packet_get_seq_nr(packet), aa->key_.buf_, aa->key_.length_); + if(ret < 0) + return; + gcry_error_t err = gcry_md_setkey(aa->handle_, aa->key_.buf_, aa->key_.length_); + if(err) { + log_printf(ERR, "failed to set hmac key: %s/%s", gcry_strerror(err), gcry_strsource(err)); + return; + } + + encrypted_packet_add_auth_tag(packet); + + gcry_md_reset(aa->handle_); + + gcry_md_write(aa->handle_, encrypted_packet_get_auth_portion(packet), encrypted_packet_get_auth_portion_length(packet)); + gcry_md_final(aa->handle_); + + u_int8_t* tag = encrypted_packet_get_auth_tag(packet); + u_int8_t* hmac = gcry_md_read(aa->handle_, 0); + u_int32_t length = (encrypted_packet_get_auth_tag_length(packet) < SHA1_LENGTH) ? encrypted_packet_get_auth_tag_length(packet) : SHA1_LENGTH; + + if(length > SHA1_LENGTH) + memset(tag, 0, encrypted_packet_get_auth_tag_length(packet)); + + memcpy(&tag[encrypted_packet_get_auth_tag_length(packet) - length], &hmac[SHA1_LENGTH - length], length); +} + + +int auth_algo_sha1_check_tag(auth_algo_t* aa, key_derivation_t* kd, encrypted_packet_t* packet) +{ + if(!aa) { + log_printf(ERR, "auth algo not initialized"); + return 0; + } + if(!kd) { + log_printf(ERR, "no key derivation supplied"); + return 0; + } + + if(!aa->key_.buf_) { + aa->key_.length_ = SHA1_LENGTH; + aa->key_.buf_ = malloc(aa->key_.length_); + if(!aa->key_.buf_) { + log_printf(ERR, "memory error at auth algo check tag"); + return; + } + } + + int ret = key_derivation_generate(kd, LABEL_SATP_MSG_AUTH, encrypted_packet_get_seq_nr(packet), aa->key_.buf_, aa->key_.length_); + if(ret < 0) + return 0; + gcry_error_t err = gcry_md_setkey(aa->handle_, aa->key_.buf_, aa->key_.length_); + if(err) { + log_printf(ERR, "failed to set hmac key: %s/%s", gcry_strerror(err), gcry_strsource(err)); + return; + } + + gcry_md_reset(aa->handle_); + + gcry_md_write(aa->handle_, encrypted_packet_get_auth_portion(packet), encrypted_packet_get_auth_portion_length(packet)); + gcry_md_final(aa->handle_); + + u_int8_t* tag = encrypted_packet_get_auth_tag(packet); + u_int8_t* hmac = gcry_md_read(aa->handle_, 0); + u_int32_t length = (encrypted_packet_get_auth_tag_length(packet) < SHA1_LENGTH) ? encrypted_packet_get_auth_tag_length(packet) : SHA1_LENGTH; + + if(length > SHA1_LENGTH) { + u_int32_t i; + for(i=0; i < (encrypted_packet_get_auth_tag_length(packet) - SHA1_LENGTH); ++i) + if(tag[i]) return 0; + } + + int result = memcmp(&tag[encrypted_packet_get_auth_tag_length(packet) - length], &hmac[SHA1_LENGTH - length], length); + encrypted_packet_remove_auth_tag(packet); + + if(result) + return 0; + + return 1; +} diff --git a/src/auth_algo.h b/src/auth_algo.h new file mode 100644 index 0000000..b22ea46 --- /dev/null +++ b/src/auth_algo.h @@ -0,0 +1,63 @@ +/* + * ľAnytun + * + * ľAnytun is a tiny implementation of SATP. Unlike Anytun which is a full + * featured implementation ľAnytun has no support for multiple connections + * or synchronisation. It is a small single threaded implementation intended + * to act as a client on small platforms. + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Christian Pointner <equinox@anytun.org> + * + * This file is part of ľAnytun. + * + * ľAnytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * ľAnytun is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ľAnytun. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _AUTH_ALGO_H_ +#define _AUTH_ALGO_H_ + +#include <gcrypt.h> +#include "key_derivation.h" + +enum auth_algo_type_enum { aa_unknown, aa_null, aa_sha1 }; +typedef enum auth_algo_type_enum auth_algo_type_t; + +struct auth_algo_struct { + auth_algo_type_t type_; + buffer_t key_; + gcry_md_hd_t handle_; +}; +typedef struct auth_algo_struct auth_algo_t; + +int auth_algo_init(auth_algo_t* aa, const char* type); +void auth_algo_close(auth_algo_t* aa); + +void auth_algo_generate(auth_algo_t* aa, key_derivation_t* kd, encrypted_packet_t* packet); +int auth_algo_check_tag(auth_algo_t* aa, key_derivation_t* kd, encrypted_packet_t* packet); + +#define SHA1_LENGTH 20 +int auth_algo_sha1_init(auth_algo_t* aa); +void auth_algo_sha1_close(auth_algo_t* aa); +void auth_algo_sha1_generate(auth_algo_t* aa, key_derivation_t* kd, encrypted_packet_t* packet); +int auth_algo_sha1_check_tag(auth_algo_t* aa, key_derivation_t* kd, encrypted_packet_t* packet); + +#endif diff --git a/src/cipher.c b/src/cipher.c index b61dd22..f640d6d 100644 --- a/src/cipher.c +++ b/src/cipher.c @@ -53,11 +53,11 @@ int cipher_init(cipher_t* c, const char* type) c->key_length_ = 0; - c->type_ = unknown; + c->type_ = c_unknown; if(!strcmp(type, "null")) - c->type_ = null; + c->type_ = c_null; else if(!strncmp(type, "aes-ctr", 7)) { - c->type_ = aes_ctr; + c->type_ = c_aes_ctr; if(type[7] == 0) { c->key_length_ = 128; } @@ -82,9 +82,12 @@ int cipher_init(cipher_t* c, const char* type) c->salt_.length_ = 0; int ret = 0; - if(c->type_ == aes_ctr) + if(c->type_ == c_aes_ctr) ret = cipher_aesctr_init(c); + if(ret) + cipher_close(c); + return ret; } @@ -93,7 +96,7 @@ void cipher_close(cipher_t* c) if(!c) return; - if(c->type_ == aes_ctr) + if(c->type_ == c_aes_ctr) cipher_aesctr_close(c); if(c->key_.buf_) @@ -109,10 +112,10 @@ void cipher_encrypt(cipher_t* c, key_derivation_t* kd, plain_packet_t* in, encry return; u_int32_t len; - if(c->type_ == null) + if(c->type_ == c_null) len = cipher_null_crypt(plain_packet_get_packet(in), plain_packet_get_length(in), encrypted_packet_get_payload(out), encrypted_packet_get_payload_length(out)); - else if(c->type_ == aes_ctr) + else if(c->type_ == c_aes_ctr) len = cipher_aesctr_crypt(c, kd, plain_packet_get_packet(in), plain_packet_get_length(in), encrypted_packet_get_payload(out), encrypted_packet_get_payload_length(out), seq_nr, sender_id, mux); @@ -134,10 +137,10 @@ void cipher_decrypt(cipher_t* c, key_derivation_t* kd, encrypted_packet_t* in, p return; u_int32_t len; - if(c->type_ == null) + if(c->type_ == c_null) len = cipher_null_crypt(encrypted_packet_get_payload(in), encrypted_packet_get_payload_length(in), plain_packet_get_packet(out), plain_packet_get_length(out)); - else if(c->type_ == aes_ctr) + else if(c->type_ == c_aes_ctr) len = cipher_aesctr_crypt(c, kd, encrypted_packet_get_payload(in), encrypted_packet_get_payload_length(in), plain_packet_get_packet(out), plain_packet_get_length(out), encrypted_packet_get_seq_nr(in), encrypted_packet_get_sender_id(in), @@ -206,8 +209,10 @@ buffer_t cipher_aesctr_calc_ctr(cipher_t* c, key_derivation_t* kd, seq_nr_t seq_ if(!c->salt_.buf_) { c->salt_.length_ = 14; c->salt_.buf_ = malloc(c->salt_.length_); - if(!c->salt_.buf_) + if(!c->salt_.buf_) { + log_printf(ERR, "memory error aes-ctr calc ctr"); return result; + } } int ret = key_derivation_generate(kd, LABEL_SATP_SALT, seq_nr, c->salt_.buf_, c->salt_.length_); if(ret < 0) @@ -269,8 +274,10 @@ u_int32_t cipher_aesctr_crypt(cipher_t* c, key_derivation_t* kd, u_int8_t* in, u if(!c->key_.buf_) { c->key_.length_ = c->key_length_/8; c->key_.buf_ = malloc(c->key_.length_); - if(c->key_.buf_) + if(!c->key_.buf_) { + log_printf(ERR, "memory error aes-ctr crypt"); return 0; + } } int ret = key_derivation_generate(kd, LABEL_SATP_ENCRYPTION, seq_nr, c->key_.buf_, c->key_.length_); diff --git a/src/cipher.h b/src/cipher.h index 58e1290..9406761 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -38,7 +38,7 @@ #include <gcrypt.h> #include "key_derivation.h" -enum cipher_type_enum { unknown, null, aes_ctr }; +enum cipher_type_enum { c_unknown, c_null, c_aes_ctr }; typedef enum cipher_type_enum cipher_type_t; struct cipher_struct { diff --git a/src/encrypted_packet.c b/src/encrypted_packet.c index 176241b..eb21828 100644 --- a/src/encrypted_packet.c +++ b/src/encrypted_packet.c @@ -76,11 +76,18 @@ void encrypted_packet_set_length(encrypted_packet_t* packet, u_int32_t len) len -= sizeof(encrypted_packet_header_t); packet->payload_length_ = len; + + if(len >= ENCRYPTED_PACKET_AUTHTAG_SIZE) { + packet->auth_tag_ = packet->data_.buf_ + sizeof(encrypted_packet_header_t); + packet->auth_tag_ += packet->payload_length_ - ENCRYPTED_PACKET_AUTHTAG_SIZE; + } + else + packet->auth_tag_ = NULL; } u_int8_t* encrypted_packet_get_payload(encrypted_packet_t* packet) { - if(!packet) + if(!packet || !packet->payload_length_) return NULL; return (packet->data_.buf_ + sizeof(encrypted_packet_header_t)); @@ -103,8 +110,71 @@ void encrypted_packet_set_payload_length(encrypted_packet_t* packet, u_int32_t l len = ENCRYPTED_PACKET_SIZE_MAX - sizeof(encrypted_packet_header_t); packet->payload_length_ = len; + + if(len >= ENCRYPTED_PACKET_AUTHTAG_SIZE) { + packet->auth_tag_ = packet->data_.buf_ + sizeof(encrypted_packet_header_t); + packet->auth_tag_ += packet->payload_length_ - ENCRYPTED_PACKET_AUTHTAG_SIZE; + } + else + packet->auth_tag_ = NULL; +} + +u_int8_t* encrypted_packet_get_auth_portion(encrypted_packet_t* packet) +{ + if(!packet) + return NULL; + + return packet->data_.buf_; +} + +u_int32_t encrypted_packet_get_auth_portion_length(encrypted_packet_t* packet) +{ + if(!packet) + return 0; + + u_int32_t len = packet->payload_length_ + sizeof(encrypted_packet_header_t); + + if(!packet->auth_tag_) + return len; + + return (len > ENCRYPTED_PACKET_AUTHTAG_SIZE) ? (len - ENCRYPTED_PACKET_AUTHTAG_SIZE) : 0; +} + + +u_int8_t* encrypted_packet_get_auth_tag(encrypted_packet_t* packet) +{ + if(!packet) + return NULL; + + return packet->auth_tag_; +} + +u_int32_t encrypted_packet_get_auth_tag_length(encrypted_packet_t* packet) +{ + if(!packet || !packet->auth_tag_) + return 0; + + return ENCRYPTED_PACKET_AUTHTAG_SIZE; +} + +void encrypted_packet_add_auth_tag(encrypted_packet_t* packet) +{ + if(!packet) + return; + + encrypted_packet_set_payload_length(packet, packet->payload_length_ + ENCRYPTED_PACKET_AUTHTAG_SIZE); } +void encrypted_packet_remove_auth_tag(encrypted_packet_t* packet) +{ + if(!packet || !packet->auth_tag_) + return; + + packet->auth_tag_ = NULL; + packet->payload_length_ = (packet->payload_length_ > ENCRYPTED_PACKET_AUTHTAG_SIZE) ? packet->payload_length_ - ENCRYPTED_PACKET_AUTHTAG_SIZE: 0; +} + + seq_nr_t encrypted_packet_get_seq_nr(encrypted_packet_t* packet) { if(!packet) diff --git a/src/encrypted_packet.h b/src/encrypted_packet.h index a77e663..e35ca25 100644 --- a/src/encrypted_packet.h +++ b/src/encrypted_packet.h @@ -36,6 +36,7 @@ #define _ENCRYPTED_PACKET_H_ #define ENCRYPTED_PACKET_SIZE_MAX 1600 +#define ENCRYPTED_PACKET_AUTHTAG_SIZE 10 #define PAYLOAD_TYPE_TAP 0x6558 #define PAYLOAD_TYPE_TUN 0x0000 @@ -51,6 +52,7 @@ typedef struct encrypted_packet_header_struct encrypted_packet_header_t; struct encrypted_packet_struct { u_int32_t payload_length_; + u_int8_t* auth_tag_; union __attribute__ ((__packed__)) { u_int8_t buf_[ENCRYPTED_PACKET_SIZE_MAX]; encrypted_packet_header_t header_; @@ -68,6 +70,15 @@ u_int8_t* encrypted_packet_get_payload(encrypted_packet_t* packet); u_int32_t encrypted_packet_get_payload_length(encrypted_packet_t* packet); void encrypted_packet_set_payload_length(encrypted_packet_t* packet, u_int32_t len); +u_int8_t* encrypted_packet_get_auth_portion(encrypted_packet_t* packet); +u_int32_t encrypted_packet_get_auth_portion_length(encrypted_packet_t* packet); + +u_int8_t* encrypted_packet_get_auth_tag(encrypted_packet_t* packet); +u_int32_t encrypted_packet_get_auth_tag_length(encrypted_packet_t* packet); + +void encrypted_packet_add_auth_tag(encrypted_packet_t* packet); +void encrypted_packet_remove_auth_tag(encrypted_packet_t* packet); + seq_nr_t encrypted_packet_get_seq_nr(encrypted_packet_t* packet); void encrypted_packet_set_seq_nr(encrypted_packet_t* packet, seq_nr_t seq_nr); diff --git a/src/options.c b/src/options.c index b74092b..b430eba 100644 --- a/src/options.c +++ b/src/options.c @@ -222,10 +222,10 @@ void options_default(options_t* opt) opt->ifconfig_param_remote_netmask_ = NULL; opt->post_up_script_ = NULL; opt->seq_window_size_ = 100; - opt->cipher_ = strdup("null"); - opt->kd_prf_ = strdup("null"); + opt->cipher_ = strdup("aes-ctr"); + opt->kd_prf_ = strdup("aes-ctr"); opt->ld_kdr_ = 0; - opt->auth_algo_ = strdup("null"); + opt->auth_algo_ = strdup("sha1"); opt->mux_ = 0; opt->key_.buf_ = NULL; opt->key_.length_ = 0; diff --git a/src/plain_packet.c b/src/plain_packet.c index 6eca0af..8b63e4a 100644 --- a/src/plain_packet.c +++ b/src/plain_packet.c @@ -83,7 +83,7 @@ void plain_packet_set_length(plain_packet_t* packet, u_int32_t len) u_int8_t* plain_packet_get_payload(plain_packet_t* packet) { - if(!packet) + if(!packet || !packet->payload_length_) return NULL; return (packet->data_.buf_ + sizeof(payload_type_t)); diff --git a/src/uanytun.c b/src/uanytun.c index 8ad6ed7..55a73a2 100644 --- a/src/uanytun.c +++ b/src/uanytun.c @@ -50,15 +50,15 @@ #include "encrypted_packet.h" #include "seq_window.h" -#include "cipher.h" #include "key_derivation.h" +#include "cipher.h" +#include "auth_algo.h" #include "daemon.h" #include "sysexec.h" #include <gcrypt.h> - #define MIN_GCRYPT_VERSION "1.2.0" int init_libgcrypt() @@ -104,6 +104,13 @@ int main_loop(tun_device_t* dev, udp_socket_t* sock, options_t* opt) log_printf(ERR, "could not initialize cipher of type %s", opt->cipher_); return_value = ret; } + + auth_algo_t aa; + ret = auth_algo_init(&aa, opt->auth_algo_); + if(ret) { + log_printf(ERR, "could not initialize auth algo of type %s", opt->auth_algo_); + return_value = ret; + } key_derivation_t kd_in; ret = key_derivation_init(&kd_in, opt->kd_prf_, opt->ld_kdr_, opt->key_.buf_, opt->key_.length_, opt->salt_.buf_, opt->salt_.length_); @@ -168,7 +175,7 @@ int main_loop(tun_device_t* dev, udp_socket_t* sock, options_t* opt) cipher_encrypt(&c, &kd_out, &plain_packet, &encrypted_packet, seq_nr, opt->sender_id_, opt->mux_); seq_nr++; - // TODO: add auth-tag + auth_algo_generate(&aa, &kd_out, &encrypted_packet); len = udp_write(sock, encrypted_packet_get_packet(&encrypted_packet), encrypted_packet_get_length(&encrypted_packet)); if(len == -1) @@ -184,7 +191,10 @@ int main_loop(tun_device_t* dev, udp_socket_t* sock, options_t* opt) encrypted_packet_set_length(&encrypted_packet, len); - // TODO: check auth-tag + if(!auth_algo_check_tag(&aa, &kd_out, &encrypted_packet)) { + log_printf(WARNING, "wrong authentication tag, discarding packet"); + continue; + } if(encrypted_packet_get_mux(&encrypted_packet) != opt->mux_) continue; @@ -217,6 +227,7 @@ int main_loop(tun_device_t* dev, udp_socket_t* sock, options_t* opt) } cipher_close(&c); + auth_algo_close(&aa); key_derivation_close(&kd_out); key_derivation_close(&kd_in); seq_win_clear(&seq_win); |