4 * uAnytun is a tiny implementation of SATP. Unlike Anytun which is a full
5 * featured implementation uAnytun has no support for multiple connections
6 * or synchronisation. It is a small single threaded implementation intended
7 * to act as a client on small platforms.
8 * The secure anycast tunneling protocol (satp) defines a protocol used
9 * for communication between any combination of unicast and anycast
10 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
11 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
12 * ethernet, ip, arp ...). satp directly includes cryptography and
13 * message authentication based on the methodes used by SRTP. It is
14 * intended to deliver a generic, scaleable and secure solution for
15 * tunneling and relaying of packets of any protocol.
18 * Copyright (C) 2007-2008 Christian Pointner <equinox@anytun.org>
20 * This file is part of uAnytun.
22 * uAnytun is free software: you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License version 3 as
24 * published by the Free Software Foundation.
26 * uAnytun is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with uAnytun. If not, see <http://www.gnu.org/licenses/>.
35 #include "datatypes.h"
37 #include "plain_packet.h"
38 #include "encrypted_packet.h"
47 int cipher_init(cipher_t* c, const char* type)
55 if(!strcmp(type, "null"))
58 else if(!strncmp(type, "aes-ctr", 7)) {
61 c->key_length_ = C_AESCTR_DEFAULT_KEY_LENGTH;
63 else if(type[7] != '-')
66 const char* tmp = &type[8];
67 c->key_length_ = atoi(tmp);
72 log_printf(ERROR, "unknown cipher type");
86 if(c->type_ == c_aes_ctr)
87 ret = cipher_aesctr_init(c);
96 void cipher_close(cipher_t* c)
102 if(c->type_ == c_aes_ctr)
103 cipher_aesctr_close(c);
113 int cipher_encrypt(cipher_t* c, key_derivation_t* kd, key_derivation_dir_t dir, plain_packet_t* in, encrypted_packet_t* out, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
119 if(c->type_ == c_null)
120 len = cipher_null_crypt(plain_packet_get_packet(in), plain_packet_get_length(in),
121 encrypted_packet_get_payload(out), encrypted_packet_get_payload_length(out));
123 else if(c->type_ == c_aes_ctr)
124 len = cipher_aesctr_crypt(c, kd, dir, plain_packet_get_packet(in), plain_packet_get_length(in),
125 encrypted_packet_get_payload(out), encrypted_packet_get_payload_length(out),
126 seq_nr, sender_id, mux);
129 log_printf(ERROR, "unknown cipher type");
136 encrypted_packet_set_sender_id(out, sender_id);
137 encrypted_packet_set_seq_nr(out, seq_nr);
138 encrypted_packet_set_mux(out, mux);
140 encrypted_packet_set_payload_length(out, len);
145 int cipher_decrypt(cipher_t* c, key_derivation_t* kd, key_derivation_dir_t dir, encrypted_packet_t* in, plain_packet_t* out)
151 if(c->type_ == c_null)
152 len = cipher_null_crypt(encrypted_packet_get_payload(in), encrypted_packet_get_payload_length(in),
153 plain_packet_get_packet(out), plain_packet_get_length(out));
155 else if(c->type_ == c_aes_ctr)
156 len = cipher_aesctr_crypt(c, kd, dir, encrypted_packet_get_payload(in), encrypted_packet_get_payload_length(in),
157 plain_packet_get_packet(out), plain_packet_get_length(out),
158 encrypted_packet_get_seq_nr(in), encrypted_packet_get_sender_id(in),
159 encrypted_packet_get_mux(in));
162 log_printf(ERROR, "unknown cipher type");
169 plain_packet_set_length(out, len);
174 /* ---------------- NULL Cipher ---------------- */
176 int32_t cipher_null_crypt(u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen)
178 memcpy(out, in, (ilen < olen) ? ilen : olen);
179 return (ilen < olen) ? ilen : olen;
183 /* ---------------- AES-Ctr Cipher ---------------- */
185 int cipher_aesctr_init(cipher_t* c)
193 c->key_.length_ = c->key_length_/8;
194 c->key_.buf_ = malloc(c->key_.length_);
201 c->salt_.length_ = C_AESCTR_SALT_LENGTH;
202 c->salt_.buf_ = malloc(c->salt_.length_);
208 c->params_ = malloc(sizeof(cipher_aesctr_param_t));
212 cipher_aesctr_param_t* params = c->params_;
214 #ifndef USE_SSL_CRYPTO
216 switch(c->key_length_) {
217 case 128: algo = GCRY_CIPHER_AES128; break;
218 case 192: algo = GCRY_CIPHER_AES192; break;
219 case 256: algo = GCRY_CIPHER_AES256; break;
221 log_printf(ERROR, "cipher key length of %d Bits is not supported", c->key_length_);
226 gcry_error_t err = gcry_cipher_open(¶ms->handle_, algo, GCRY_CIPHER_MODE_CTR, 0);
228 log_printf(ERROR, "failed to open cipher: %s", gcry_strerror(err));
236 void cipher_aesctr_close(cipher_t* c)
242 cipher_aesctr_param_t* params = c->params_;
244 #ifndef USE_SSL_CRYPTO
246 gcry_cipher_close(params->handle_);
253 int cipher_aesctr_calc_ctr(cipher_t* c, key_derivation_t* kd, key_derivation_dir_t dir, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
255 if(!c || !c->params_)
258 cipher_aesctr_param_t* params = c->params_;
260 int ret = key_derivation_generate(kd, dir, LABEL_SALT, seq_nr, c->salt_.buf_, C_AESCTR_SALT_LENGTH);
264 memcpy(params->ctr_.salt_.buf_, c->salt_.buf_, C_AESCTR_SALT_LENGTH);
265 params->ctr_.salt_.zero_ = 0;
266 params->ctr_.params_.mux_ ^= MUX_T_HTON(mux);
267 params->ctr_.params_.sender_id_ ^= SENDER_ID_T_HTON(sender_id);
268 params->ctr_.params_.seq_nr_ ^= SEQ_NR_T_HTON(seq_nr);
273 int32_t cipher_aesctr_crypt(cipher_t* c, key_derivation_t* kd, key_derivation_dir_t dir, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
275 if(!c || !c->params_) {
276 log_printf(ERROR, "cipher not initialized");
281 log_printf(ERROR, "no key derivation supplied");
285 cipher_aesctr_param_t* params = c->params_;
287 int ret = key_derivation_generate(kd, dir, LABEL_ENC, seq_nr, c->key_.buf_, c->key_.length_);
291 #ifdef USE_SSL_CRYPTO
292 ret = AES_set_encrypt_key(c->key_.buf_, c->key_length_, ¶ms->aes_key_);
294 log_printf(ERROR, "failed to set cipher ssl aes-key (code: %d)", ret);
298 gcry_error_t err = gcry_cipher_setkey(params->handle_, c->key_.buf_, c->key_.length_);
300 log_printf(ERROR, "failed to set cipher key: %s", gcry_strerror(err));
305 ret = cipher_aesctr_calc_ctr(c, kd, dir, seq_nr, sender_id, mux);
307 log_printf(ERROR, "failed to calculate cipher CTR");
311 #ifndef USE_SSL_CRYPTO
312 err = gcry_cipher_setctr(params->handle_, params->ctr_.buf_, C_AESCTR_CTR_LENGTH);
314 log_printf(ERROR, "failed to set cipher CTR: %s", gcry_strerror(err));
318 err = gcry_cipher_encrypt(params->handle_, out, olen, in, ilen);
320 log_printf(ERROR, "failed to de/encrypt packet: %s", gcry_strerror(err));
324 if(C_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) {
325 log_printf(ERROR, "failed to set cipher CTR: size don't fits");
329 memset(params->ecount_buf_, 0, AES_BLOCK_SIZE);
330 AES_ctr128_encrypt(in, out, (ilen < olen) ? ilen : olen, ¶ms->aes_key_, params->ctr_.buf_, params->ecount_buf_, &num);
333 return (ilen < olen) ? ilen : olen;