diff options
author | Christian Pointner <equinox@anytun.org> | 2009-03-13 01:50:09 +0000 |
---|---|---|
committer | Christian Pointner <equinox@anytun.org> | 2009-03-13 01:50:09 +0000 |
commit | 63910439f77b91848dda094ef6e90523e1f7efa6 (patch) | |
tree | 75660603d4b79520ffea0a1b1b2edb25b8a08371 /src | |
parent | moved hex-dump function to log_* (diff) |
added command line option for auth tag length
Diffstat (limited to 'src')
-rw-r--r-- | src/auth_algo.c | 31 | ||||
-rw-r--r-- | src/auth_algo.h | 3 | ||||
-rw-r--r-- | src/encrypted_packet.c | 71 | ||||
-rw-r--r-- | src/encrypted_packet.h | 12 | ||||
-rw-r--r-- | src/options.c | 16 | ||||
-rw-r--r-- | src/options.h | 1 | ||||
-rw-r--r-- | src/uanytun.c | 4 |
7 files changed, 69 insertions, 69 deletions
diff --git a/src/auth_algo.c b/src/auth_algo.c index db57418..1cec7ba 100644 --- a/src/auth_algo.c +++ b/src/auth_algo.c @@ -43,17 +43,32 @@ #include <stdlib.h> #include <string.h> +auth_algo_type_t auth_algo_get_type(const char* type) +{ + if(!strcmp(type, "null")) + return aa_null; + else if(!strcmp(type, "sha1")) + return aa_sha1; + + return aa_unknown; +} + +u_int32_t auth_algo_get_max_length(const char* type) +{ + switch(auth_algo_get_type(type)) { + case aa_null: return 0; + case aa_sha1: return SHA1_LENGTH; + default: return 0; + } +} + 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 { + aa->type_ = auth_algo_get_type(type); + if(aa->type_ == aa_unknown) { log_printf(ERROR, "unknown auth algo type"); return -1; } @@ -174,7 +189,6 @@ void auth_algo_sha1_close(auth_algo_t* aa) void auth_algo_sha1_generate(auth_algo_t* aa, key_derivation_t* kd, key_store_dir_t dir, encrypted_packet_t* packet) { - encrypted_packet_add_auth_tag(packet); if(!encrypted_packet_get_auth_tag_length(packet)) return; @@ -224,7 +238,7 @@ void auth_algo_sha1_generate(auth_algo_t* aa, key_derivation_t* kd, key_store_di int auth_algo_sha1_check_tag(auth_algo_t* aa, key_derivation_t* kd, key_store_dir_t dir, encrypted_packet_t* packet) { if(!encrypted_packet_get_auth_tag_length(packet)) - return 0; + return 1; if(!aa || !aa->params_) { log_printf(ERROR, "auth algo not initialized"); @@ -269,7 +283,6 @@ int auth_algo_sha1_check_tag(auth_algo_t* aa, key_derivation_t* kd, key_store_di } 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; diff --git a/src/auth_algo.h b/src/auth_algo.h index 7202b47..1b0aa01 100644 --- a/src/auth_algo.h +++ b/src/auth_algo.h @@ -41,6 +41,7 @@ #include <openssl/hmac.h> #endif #include "key_derivation.h" +#include "encrypted_packet.h" enum auth_algo_type_enum { aa_unknown, aa_null, aa_sha1 }; typedef enum auth_algo_type_enum auth_algo_type_t; @@ -52,6 +53,8 @@ struct auth_algo_struct { }; typedef struct auth_algo_struct auth_algo_t; +auth_algo_type_t auth_algo_get_type(const char* type); +u_int32_t auth_algo_get_max_length(const char* type); int auth_algo_init(auth_algo_t* aa, const char* type); void auth_algo_close(auth_algo_t* aa); diff --git a/src/encrypted_packet.c b/src/encrypted_packet.c index 151683f..53387f3 100644 --- a/src/encrypted_packet.c +++ b/src/encrypted_packet.c @@ -39,17 +39,24 @@ #include <stdlib.h> #include <string.h> -void encrypted_packet_init(encrypted_packet_t* packet) +void encrypted_packet_init(encrypted_packet_t* packet, u_int32_t auth_tag_length) { if(!packet) return; memset (packet, 0, sizeof(*packet)); + if(auth_tag_length > (ENCRYPTED_PACKET_SIZE_MAX - sizeof(encrypted_packet_header_t))) + packet->auth_tag_length_ = ENCRYPTED_PACKET_SIZE_MAX - sizeof(encrypted_packet_header_t); + else + packet->auth_tag_length_ = auth_tag_length; } -u_int32_t encrypted_packet_get_header_length() +u_int32_t encrypted_packet_get_minimum_length(encrypted_packet_t* packet) { - return sizeof(encrypted_packet_header_t); + if(!packet) + return 0; + + return (sizeof(encrypted_packet_header_t) + packet->auth_tag_length_); } u_int8_t* encrypted_packet_get_packet(encrypted_packet_t* packet) @@ -65,7 +72,7 @@ u_int32_t encrypted_packet_get_length(encrypted_packet_t* packet) if(!packet) return 0; - return (packet->payload_length_ + sizeof(encrypted_packet_header_t)); + return (packet->payload_length_ + sizeof(encrypted_packet_header_t) + packet->auth_tag_length_); } void encrypted_packet_set_length(encrypted_packet_t* packet, u_int32_t len) @@ -74,20 +81,13 @@ void encrypted_packet_set_length(encrypted_packet_t* packet, u_int32_t len) return; if(len > ENCRYPTED_PACKET_SIZE_MAX) - len = ENCRYPTED_PACKET_SIZE_MAX - sizeof(encrypted_packet_header_t); - else if(len < sizeof(encrypted_packet_header_t)) + len = ENCRYPTED_PACKET_SIZE_MAX - sizeof(encrypted_packet_header_t) - packet->auth_tag_length_; + else if(len < (sizeof(encrypted_packet_header_t) + packet->auth_tag_length_)) len = 0; else - len -= sizeof(encrypted_packet_header_t); + len -= (sizeof(encrypted_packet_header_t) + packet->auth_tag_length_); 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) @@ -111,17 +111,10 @@ void encrypted_packet_set_payload_length(encrypted_packet_t* packet, u_int32_t l if(!packet) return; - if(len > ENCRYPTED_PACKET_SIZE_MAX || (len + sizeof(encrypted_packet_header_t)) > ENCRYPTED_PACKET_SIZE_MAX) - len = ENCRYPTED_PACKET_SIZE_MAX - sizeof(encrypted_packet_header_t); + if(len > (ENCRYPTED_PACKET_SIZE_MAX - sizeof(encrypted_packet_header_t) - packet->auth_tag_length_)) + len = ENCRYPTED_PACKET_SIZE_MAX - sizeof(encrypted_packet_header_t) - packet->auth_tag_length_; 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) @@ -137,46 +130,24 @@ 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; + return packet->payload_length_ + sizeof(encrypted_packet_header_t); } u_int8_t* encrypted_packet_get_auth_tag(encrypted_packet_t* packet) { - if(!packet) + if(!packet || !packet->auth_tag_length_) return NULL; - return packet->auth_tag_; + return (packet->data_.buf_ + sizeof(encrypted_packet_header_t) + packet->payload_length_); } 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; + return 0; - packet->auth_tag_ = NULL; - packet->payload_length_ = (packet->payload_length_ > ENCRYPTED_PACKET_AUTHTAG_SIZE) ? packet->payload_length_ - ENCRYPTED_PACKET_AUTHTAG_SIZE: 0; + return packet->auth_tag_length_; } diff --git a/src/encrypted_packet.h b/src/encrypted_packet.h index 2e6c1b7..e9cdc59 100644 --- a/src/encrypted_packet.h +++ b/src/encrypted_packet.h @@ -36,12 +36,11 @@ #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 #define PAYLOAD_TYPE_TUN4 0x0800 -#define PAYLOAD_TYPE_TUN6 0x86DD +#define PAYLOAD_TYPE_TUN6 0x86DD struct __attribute__ ((__packed__)) encrypted_packet_header_struct { seq_nr_t seq_nr_; @@ -52,7 +51,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_; + u_int32_t auth_tag_length_; union __attribute__ ((__packed__)) { u_int8_t buf_[ENCRYPTED_PACKET_SIZE_MAX]; encrypted_packet_header_t header_; @@ -60,9 +59,9 @@ struct encrypted_packet_struct { }; typedef struct encrypted_packet_struct encrypted_packet_t; -void encrypted_packet_init(encrypted_packet_t* packet); +void encrypted_packet_init(encrypted_packet_t* packet, u_int32_t auth_tag_length); -u_int32_t encrypted_packet_get_header_length(); +u_int32_t encrypted_packet_get_minimum_length(encrypted_packet_t* packet); u_int8_t* encrypted_packet_get_packet(encrypted_packet_t* packet); u_int32_t encrypted_packet_get_length(encrypted_packet_t* packet); @@ -78,9 +77,6 @@ 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 f15d6b8..09265da 100644 --- a/src/options.c +++ b/src/options.c @@ -43,6 +43,10 @@ #include "log.h" +#ifndef NO_CRYPT +#include "auth_algo.h" +#endif + #define PARSE_BOOL_PARAM(SHORT, LONG, VALUE) \ else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \ VALUE = 1; @@ -257,6 +261,7 @@ int options_parse(options_t* opt, int argc, char* argv[]) PARSE_HEXSTRING_PARAM_SEC("-A","--salt", opt->salt_) PARSE_STRING_PARAM("-c","--cipher", opt->cipher_) PARSE_STRING_PARAM("-a","--auth-algo", opt->auth_algo_) + PARSE_INT_PARAM("-b","--auth-tag-length", opt->auth_tag_length_) #endif else return i; @@ -294,6 +299,13 @@ void options_parse_post(options_t* opt) !strcmp(opt->kd_prf_, "null")) { log_printf(WARNING, "using NULL key derivation with encryption and or authentication enabled!"); } + + u_int32_t tag_len_max = auth_algo_get_max_length(opt->auth_algo_); + if(!tag_len_max) opt->auth_tag_length_ = 0; + else if(tag_len_max < opt->auth_tag_length_) { + log_printf(WARNING, "%s auth algo can't generate tags of length %d, using maximum tag length(%d)", opt->auth_algo_, opt->auth_tag_length_, tag_len_max); + opt->auth_tag_length_ = tag_len_max; + } #endif if(!(opt->dev_name_) && !(opt->dev_type_)) @@ -331,8 +343,10 @@ void options_default(options_t* opt) opt->passphrase_ = NULL; opt->cipher_ = strdup("aes-ctr"); opt->auth_algo_ = strdup("sha1"); + opt->auth_tag_length_ = 10; #else opt->cipher_ = strdup("null"); + opt->auth_tag_length_ = 0; #endif opt->anytun02_compat_ = 0; opt->key_.buf_ = NULL; @@ -426,6 +440,7 @@ void options_print_usage() printf(" [-A|--salt] <master salt> master salt to use for encryption\n"); printf(" [-c|--cipher] <cipher type> payload encryption algorithm\n"); printf(" [-a|--auth-algo] <algo type> message authentication algorithm\n"); + printf(" [-b|--auth-tag-length] <length> length of the auth tag\n"); #endif } @@ -464,6 +479,7 @@ void options_print(options_t* opt) printf("cipher: '%s'\n", opt->cipher_); #ifndef NO_CRYPT printf("auth_algo: '%s'\n", opt->auth_algo_); + printf("auth_tag_length: %d\n", opt->auth_tag_length_); printf("kd_prf: '%s'\n", opt->kd_prf_); printf("ld_kdr: %d\n", opt->ld_kdr_); printf("passphrase: '%s'\n", opt->passphrase_); diff --git a/src/options.h b/src/options.h index 688a50d..cfac90d 100644 --- a/src/options.h +++ b/src/options.h @@ -74,6 +74,7 @@ struct options_struct { char* passphrase_; #endif int anytun02_compat_; + u_int32_t auth_tag_length_; buffer_t key_; buffer_t salt_; }; diff --git a/src/uanytun.c b/src/uanytun.c index 5c81dc9..72a0fab 100644 --- a/src/uanytun.c +++ b/src/uanytun.c @@ -189,7 +189,7 @@ int process_sock_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, pla log_printf(ERROR, "error on receiving udp packet: %s", strerror(errno)); return 0; } - else if(len < encrypted_packet_get_header_length()) { + else if(len < encrypted_packet_get_minimum_length(encrypted_packet)) { log_printf(WARNING, "received packet is to short"); return 0; } @@ -249,7 +249,7 @@ int main_loop(tun_device_t* dev, udp_socket_t* sock, options_t* opt) plain_packet_t plain_packet; plain_packet_init(&plain_packet); encrypted_packet_t encrypted_packet; - encrypted_packet_init(&encrypted_packet); + encrypted_packet_init(&encrypted_packet, opt->auth_tag_length_); seq_nr_t seq_nr = 0; fd_set readfds; |