Imported Upstream version 0.3.6
[debian/uanytun.git] / src / cipher.c
1 /*
2  *  uAnytun
3  *
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 methods 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.
16  *
17  *
18  *  Copyright (C) 2007-2014 Christian Pointner <equinox@anytun.org>
19  *
20  *  This file is part of uAnytun.
21  *
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
25  *  any later version.
26  *
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.
31  *
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/>.
34  *
35  *  In addition, as a special exception, the copyright holders give
36  *  permission to link the code of portions of this program with the
37  *  OpenSSL library under certain conditions as described in each
38  *  individual source file, and distribute linked combinations
39  *  including the two.
40  *  You must obey the GNU General Public License in all respects
41  *  for all of the code used other than OpenSSL.  If you modify
42  *  file(s) with this exception, you may extend this exception to your
43  *  version of the file(s), but you are not obligated to do so.  If you
44  *  do not wish to do so, delete this exception statement from your
45  *  version.  If you delete this exception statement from all source
46  *  files in the program, then also delete it here.
47  */
48
49 #include "datatypes.h"
50
51 #include "plain_packet.h"
52 #include "encrypted_packet.h"
53
54 #include "cipher.h"
55 #if defined(USE_NETTLE)
56 #include <nettle/ctr.h>
57 #endif
58
59 #include "log.h"
60
61 #include <stdlib.h>
62 #include <string.h>
63
64 int cipher_init(cipher_t* c, const char* type)
65 {
66   if(!c)
67     return -1;
68
69   c->key_length_ = 0;
70
71   c->type_ = c_unknown;
72   if(!strcmp(type, "null"))
73     c->type_ = c_null;
74 #ifndef NO_CRYPT
75   else if(!strncmp(type, "aes-ctr", 7)) {
76     c->type_ = c_aes_ctr;
77     if(type[7] == 0) {
78       c->key_length_ = C_AESCTR_DEFAULT_KEY_LENGTH;
79     }
80     else if(type[7] != '-')
81       return -1;
82     else {
83       const char* tmp = &type[8];
84       c->key_length_ = atoi(tmp);
85     }
86   }
87 #endif
88   else {
89     log_printf(ERROR, "unknown cipher type");
90     return -1;
91   }
92
93   c->params_ = NULL;
94
95   c->key_.buf_ = NULL;
96   c->key_.length_ = 0;
97
98   c->salt_.buf_ = NULL;
99   c->salt_.length_ = 0;
100
101   int ret = 0;
102 #ifndef NO_CRYPT
103   if(c->type_ == c_aes_ctr)
104     ret = cipher_aesctr_init(c);
105 #endif
106
107   if(ret)
108     cipher_close(c);
109
110   return ret;
111 }
112
113 void cipher_close(cipher_t* c)
114 {
115   if(!c)
116     return;
117
118 #ifndef NO_CRYPT
119   if(c->type_ == c_aes_ctr)
120     cipher_aesctr_close(c);
121 #endif
122
123   if(c->key_.buf_)
124     free(c->key_.buf_);
125   if(c->salt_.buf_)
126     free(c->salt_.buf_);
127 }
128
129
130 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)
131 {
132   if(!c)
133     return -1;
134
135   int32_t len;
136   if(c->type_ == c_null)
137     len = cipher_null_crypt(plain_packet_get_packet(in), plain_packet_get_length(in),
138                             encrypted_packet_get_payload(out), encrypted_packet_get_payload_length(out));
139 #ifndef NO_CRYPT
140   else if(c->type_ == c_aes_ctr)
141     len = cipher_aesctr_crypt(c, kd, dir, plain_packet_get_packet(in), plain_packet_get_length(in),
142                               encrypted_packet_get_payload(out), encrypted_packet_get_payload_length(out),
143                               seq_nr, sender_id, mux);
144 #endif
145   else {
146     log_printf(ERROR, "unknown cipher type");
147     return -1;
148   }
149
150   if(len < 0)
151     return 0;
152
153   encrypted_packet_set_sender_id(out, sender_id);
154   encrypted_packet_set_seq_nr(out, seq_nr);
155   encrypted_packet_set_mux(out, mux);
156
157   encrypted_packet_set_payload_length(out, len);
158
159   return 0;
160 }
161
162 int cipher_decrypt(cipher_t* c, key_derivation_t* kd, key_derivation_dir_t dir, encrypted_packet_t* in, plain_packet_t* out)
163 {
164   if(!c)
165     return -1;
166
167   int32_t len;
168   if(c->type_ == c_null)
169     len = cipher_null_crypt(encrypted_packet_get_payload(in), encrypted_packet_get_payload_length(in),
170                             plain_packet_get_packet(out), plain_packet_get_length(out));
171 #ifndef NO_CRYPT
172   else if(c->type_ == c_aes_ctr)
173     len = cipher_aesctr_crypt(c, kd, dir, encrypted_packet_get_payload(in), encrypted_packet_get_payload_length(in),
174                               plain_packet_get_packet(out), plain_packet_get_length(out),
175                               encrypted_packet_get_seq_nr(in), encrypted_packet_get_sender_id(in),
176                               encrypted_packet_get_mux(in));
177 #endif
178   else {
179     log_printf(ERROR, "unknown cipher type");
180     return -1;
181   }
182
183   if(len < 0)
184     return 0;
185
186   plain_packet_set_length(out, len);
187
188   return 0;
189 }
190
191 /* ---------------- NULL Cipher ---------------- */
192
193 int32_t cipher_null_crypt(u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen)
194 {
195   memcpy(out, in, (ilen < olen) ? ilen : olen);
196   return (ilen < olen) ? ilen : olen;
197 }
198
199 #ifndef NO_CRYPT
200 /* ---------------- AES-Ctr Cipher ---------------- */
201
202 int cipher_aesctr_init(cipher_t* c)
203 {
204   if(!c)
205     return -1;
206
207   if(c->key_.buf_)
208     free(c->key_.buf_);
209
210   c->key_.length_ = c->key_length_/8;
211   c->key_.buf_ = malloc(c->key_.length_);
212   if(!c->key_.buf_)
213     return -2;
214
215   if(c->salt_.buf_)
216     free(c->salt_.buf_);
217
218   c->salt_.length_ = C_AESCTR_SALT_LENGTH;
219   c->salt_.buf_ = malloc(c->salt_.length_);
220   if(!c->salt_.buf_)
221     return -2;
222
223   if(c->params_)
224     free(c->params_);
225   c->params_ = malloc(sizeof(cipher_aesctr_param_t));
226   if(!c->params_)
227     return -2;
228
229 #if defined(USE_SSL_CRYPTO)
230   // nothing here
231 #elif defined(USE_NETTLE)
232   // nothing here
233 #else  // USE_GCRYPT is the default
234   int algo;
235   switch(c->key_length_) {
236   case 128: algo = GCRY_CIPHER_AES128; break;
237   case 192: algo = GCRY_CIPHER_AES192; break;
238   case 256: algo = GCRY_CIPHER_AES256; break;
239   default: {
240     log_printf(ERROR, "cipher key length of %d Bits is not supported", c->key_length_);
241     return -1;
242   }
243   }
244
245   cipher_aesctr_param_t* params = c->params_;
246   gcry_error_t err = gcry_cipher_open(&params->handle_, algo, GCRY_CIPHER_MODE_CTR, 0);
247   if(err) {
248     log_printf(ERROR, "failed to open cipher: %s", gcry_strerror(err));
249     return -1;
250   }
251 #endif
252
253   return 0;
254 }
255
256 void cipher_aesctr_close(cipher_t* c)
257 {
258   if(!c)
259     return;
260
261   if(c->params_) {
262 #if defined(USE_SSL_CRYPTO)
263     // nothing here
264 #elif defined(USE_NETTLE)
265     // nothing here
266 #else  // USE_GCRYPT is the default
267     cipher_aesctr_param_t* params = c->params_;
268     gcry_cipher_close(params->handle_);
269 #endif
270     free(c->params_);
271   }
272 }
273
274 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)
275 {
276   if(!c || !c->params_)
277     return -1;
278
279   cipher_aesctr_param_t* params = c->params_;
280
281   int ret = key_derivation_generate(kd, dir, LABEL_SALT, seq_nr, c->salt_.buf_, C_AESCTR_SALT_LENGTH);
282   if(ret < 0)
283     return ret;
284
285   memcpy(params->ctr_.salt_.buf_, c->salt_.buf_, C_AESCTR_SALT_LENGTH);
286   params->ctr_.salt_.zero_ = 0;
287   params->ctr_.params_.mux_ ^= MUX_T_HTON(mux);
288   params->ctr_.params_.sender_id_ ^= SENDER_ID_T_HTON(sender_id);
289   params->ctr_.params_.seq_nr_ ^= SEQ_NR_T_HTON(seq_nr);
290
291   return 0;
292 }
293
294 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)
295 {
296   if(!c || !c->params_) {
297     log_printf(ERROR, "cipher not initialized");
298     return -1;
299   }
300
301   if(!kd) {
302     log_printf(ERROR, "no key derivation supplied");
303     return -1;
304   }
305
306   cipher_aesctr_param_t* params = c->params_;
307
308   int ret = key_derivation_generate(kd, dir, LABEL_ENC, seq_nr, c->key_.buf_, c->key_.length_);
309   if(ret < 0)
310     return ret;
311
312 #if defined(USE_SSL_CRYPTO)
313   ret = AES_set_encrypt_key(c->key_.buf_, c->key_length_, &params->aes_key_);
314   if(ret) {
315     log_printf(ERROR, "failed to set cipher key (code: %d)", ret);
316     return -1;
317   }
318 #elif defined(USE_NETTLE)
319   aes_set_encrypt_key(&params->ctx_, c->key_.length_, c->key_.buf_);
320 #else  // USE_GCRYPT is the default
321   gcry_error_t err = gcry_cipher_setkey(params->handle_, c->key_.buf_, c->key_.length_);
322   if(err) {
323     log_printf(ERROR, "failed to set cipher key: %s", gcry_strerror(err));
324     return -1;
325   }
326 #endif
327
328   ret = cipher_aesctr_calc_ctr(c, kd, dir, seq_nr, sender_id, mux);
329   if(ret < 0) {
330     log_printf(ERROR, "failed to calculate cipher CTR");
331     return ret;
332   }
333
334 #if defined(USE_SSL_CRYPTO)
335   if(C_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) {
336     log_printf(ERROR, "failed to set cipher CTR: size doesn't fit");
337     return -1;
338   }
339   u_int32_t num = 0;
340   memset(params->ecount_buf_, 0, AES_BLOCK_SIZE);
341   AES_ctr128_encrypt(in, out, (ilen < olen) ? ilen : olen, &params->aes_key_, params->ctr_.buf_, params->ecount_buf_, &num);
342 #elif defined(USE_NETTLE)
343   if(C_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) {
344     log_printf(ERROR, "failed to set cipher CTR: size doesn't fit");
345     return -1;
346   }
347   ctr_crypt(&params->ctx_, (nettle_crypt_func *)(aes_encrypt), AES_BLOCK_SIZE, params->ctr_.buf_, (ilen < olen) ? ilen : olen, out, in);
348 #else  // USE_GCRYPT is the default
349   err = gcry_cipher_setctr(params->handle_, params->ctr_.buf_, C_AESCTR_CTR_LENGTH);
350   if(err) {
351     log_printf(ERROR, "failed to set cipher CTR: %s", gcry_strerror(err));
352     return -1;
353   }
354
355   err = gcry_cipher_encrypt(params->handle_, out, olen, in, ilen);
356   if(err) {
357     log_printf(ERROR, "failed to de/encrypt packet: %s", gcry_strerror(err));
358     return -1;
359   }
360 #endif
361
362   return (ilen < olen) ? ilen : olen;
363 }
364 #endif