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-2010 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 as published by
24 * the Free Software Foundation, either version 3 of the License, or
27 * uAnytun is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public License
33 * along with uAnytun. If not, see <http://www.gnu.org/licenses/>.
36 #include "datatypes.h"
38 #include "plain_packet.h"
39 #include "encrypted_packet.h"
48 int cipher_init(cipher_t* c, const char* type)
56 if(!strcmp(type, "null"))
59 else if(!strncmp(type, "aes-ctr", 7)) {
62 c->key_length_ = C_AESCTR_DEFAULT_KEY_LENGTH;
64 else if(type[7] != '-')
67 const char* tmp = &type[8];
68 c->key_length_ = atoi(tmp);
73 log_printf(ERROR, "unknown cipher type");
87 if(c->type_ == c_aes_ctr)
88 ret = cipher_aesctr_init(c);
97 void cipher_close(cipher_t* c)
103 if(c->type_ == c_aes_ctr)
104 cipher_aesctr_close(c);
114 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)
120 if(c->type_ == c_null)
121 len = cipher_null_crypt(plain_packet_get_packet(in), plain_packet_get_length(in),
122 encrypted_packet_get_payload(out), encrypted_packet_get_payload_length(out));
124 else if(c->type_ == c_aes_ctr)
125 len = cipher_aesctr_crypt(c, kd, dir, plain_packet_get_packet(in), plain_packet_get_length(in),
126 encrypted_packet_get_payload(out), encrypted_packet_get_payload_length(out),
127 seq_nr, sender_id, mux);
130 log_printf(ERROR, "unknown cipher type");
137 encrypted_packet_set_sender_id(out, sender_id);
138 encrypted_packet_set_seq_nr(out, seq_nr);
139 encrypted_packet_set_mux(out, mux);
141 encrypted_packet_set_payload_length(out, len);
146 int cipher_decrypt(cipher_t* c, key_derivation_t* kd, key_derivation_dir_t dir, encrypted_packet_t* in, plain_packet_t* out)
152 if(c->type_ == c_null)
153 len = cipher_null_crypt(encrypted_packet_get_payload(in), encrypted_packet_get_payload_length(in),
154 plain_packet_get_packet(out), plain_packet_get_length(out));
156 else if(c->type_ == c_aes_ctr)
157 len = cipher_aesctr_crypt(c, kd, dir, encrypted_packet_get_payload(in), encrypted_packet_get_payload_length(in),
158 plain_packet_get_packet(out), plain_packet_get_length(out),
159 encrypted_packet_get_seq_nr(in), encrypted_packet_get_sender_id(in),
160 encrypted_packet_get_mux(in));
163 log_printf(ERROR, "unknown cipher type");
170 plain_packet_set_length(out, len);
175 /* ---------------- NULL Cipher ---------------- */
177 int32_t cipher_null_crypt(u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen)
179 memcpy(out, in, (ilen < olen) ? ilen : olen);
180 return (ilen < olen) ? ilen : olen;
184 /* ---------------- AES-Ctr Cipher ---------------- */
186 int cipher_aesctr_init(cipher_t* c)
194 c->key_.length_ = c->key_length_/8;
195 c->key_.buf_ = malloc(c->key_.length_);
202 c->salt_.length_ = C_AESCTR_SALT_LENGTH;
203 c->salt_.buf_ = malloc(c->salt_.length_);
209 c->params_ = malloc(sizeof(cipher_aesctr_param_t));
213 cipher_aesctr_param_t* params = c->params_;
215 #ifndef USE_SSL_CRYPTO
217 switch(c->key_length_) {
218 case 128: algo = GCRY_CIPHER_AES128; break;
219 case 192: algo = GCRY_CIPHER_AES192; break;
220 case 256: algo = GCRY_CIPHER_AES256; break;
222 log_printf(ERROR, "cipher key length of %d Bits is not supported", c->key_length_);
227 gcry_error_t err = gcry_cipher_open(¶ms->handle_, algo, GCRY_CIPHER_MODE_CTR, 0);
229 log_printf(ERROR, "failed to open cipher: %s", gcry_strerror(err));
237 void cipher_aesctr_close(cipher_t* c)
243 cipher_aesctr_param_t* params = c->params_;
245 #ifndef USE_SSL_CRYPTO
247 gcry_cipher_close(params->handle_);
254 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)
256 if(!c || !c->params_)
259 cipher_aesctr_param_t* params = c->params_;
261 int ret = key_derivation_generate(kd, dir, LABEL_SALT, seq_nr, c->salt_.buf_, C_AESCTR_SALT_LENGTH);
265 memcpy(params->ctr_.salt_.buf_, c->salt_.buf_, C_AESCTR_SALT_LENGTH);
266 params->ctr_.salt_.zero_ = 0;
267 params->ctr_.params_.mux_ ^= MUX_T_HTON(mux);
268 params->ctr_.params_.sender_id_ ^= SENDER_ID_T_HTON(sender_id);
269 params->ctr_.params_.seq_nr_ ^= SEQ_NR_T_HTON(seq_nr);
274 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)
276 if(!c || !c->params_) {
277 log_printf(ERROR, "cipher not initialized");
282 log_printf(ERROR, "no key derivation supplied");
286 cipher_aesctr_param_t* params = c->params_;
288 int ret = key_derivation_generate(kd, dir, LABEL_ENC, seq_nr, c->key_.buf_, c->key_.length_);
292 #ifdef USE_SSL_CRYPTO
293 ret = AES_set_encrypt_key(c->key_.buf_, c->key_length_, ¶ms->aes_key_);
295 log_printf(ERROR, "failed to set cipher ssl aes-key (code: %d)", ret);
299 gcry_error_t err = gcry_cipher_setkey(params->handle_, c->key_.buf_, c->key_.length_);
301 log_printf(ERROR, "failed to set cipher key: %s", gcry_strerror(err));
306 ret = cipher_aesctr_calc_ctr(c, kd, dir, seq_nr, sender_id, mux);
308 log_printf(ERROR, "failed to calculate cipher CTR");
312 #ifndef USE_SSL_CRYPTO
313 err = gcry_cipher_setctr(params->handle_, params->ctr_.buf_, C_AESCTR_CTR_LENGTH);
315 log_printf(ERROR, "failed to set cipher CTR: %s", gcry_strerror(err));
319 err = gcry_cipher_encrypt(params->handle_, out, olen, in, ilen);
321 log_printf(ERROR, "failed to de/encrypt packet: %s", gcry_strerror(err));
325 if(C_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) {
326 log_printf(ERROR, "failed to set cipher CTR: size don't fits");
330 memset(params->ecount_buf_, 0, AES_BLOCK_SIZE);
331 AES_ctr128_encrypt(in, out, (ilen < olen) ? ilen : olen, ¶ms->aes_key_, params->ctr_.buf_, params->ecount_buf_, &num);
334 return (ilen < olen) ? ilen : olen;