Imported Upstream version 0.3.6
[debian/uanytun.git] / src / key_derivation.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 "key_derivation.h"
52
53 #if defined(USE_SSL_CRYPTO)
54 #include <openssl/sha.h>
55 #elif defined(USE_NETTLE)
56 #include <nettle/sha1.h>
57 #include <nettle/sha2.h>
58 #include <nettle/ctr.h>
59 #endif
60
61 #include "log.h"
62
63 #include <stdlib.h>
64 #include <string.h>
65
66 int key_derivation_init(key_derivation_t* kd, const char* type, role_t role, const char* passphrase, u_int8_t* key, u_int32_t key_len, u_int8_t* salt, u_int32_t salt_len)
67 {
68   if(!kd)
69     return -1;
70
71   kd->role_ = role;
72   kd->key_length_ = 0;
73
74   kd->type_ = kd_unknown;
75   if(!strcmp(type, "null"))
76     kd->type_ = kd_null;
77   else if(!strncmp(type, "aes-ctr", 7)) {
78     kd->type_ = kd_aes_ctr;
79     if(type[7] == 0) {
80       kd->key_length_ = KD_AESCTR_DEFAULT_KEY_LENGTH;
81     }
82     else if(type[7] != '-')
83       return -1;
84     else {
85       const char* tmp = &type[8];
86       kd->key_length_ = atoi(tmp);
87     }
88   }
89   else {
90     log_printf(ERROR, "unknown key derivation type");
91     return -1;
92   }
93
94   switch(role) {
95   case ROLE_LEFT: log_printf(NOTICE, "key derivation role: left"); break;
96   case ROLE_RIGHT: log_printf(NOTICE, "key derivation role: right"); break;
97   default: log_printf(NOTICE, "key derivation role: unknown"); break;
98   }
99   kd->params_ = NULL;
100
101   if(!key) {
102     kd->master_key_.buf_ = NULL;
103     kd->master_key_.length_ = 0;
104   }
105   else {
106     kd->master_key_.buf_ = malloc(key_len);
107     if(!kd->master_key_.buf_)
108       return -2;
109     memcpy(kd->master_key_.buf_, key, key_len);
110     kd->master_key_.length_ = key_len;
111   }
112
113   if(!salt) {
114     kd->master_salt_.buf_ = NULL;
115     kd->master_salt_.length_ = 0;
116   }
117   else {
118     kd->master_salt_.buf_ = malloc(salt_len);
119     if(!kd->master_salt_.buf_) {
120       if(kd->master_key_.buf_)
121         free(kd->master_key_.buf_);
122       return -2;
123     }
124     memcpy(kd->master_salt_.buf_, salt, salt_len);
125     kd->master_salt_.length_ = salt_len;
126   }
127
128   int ret = 0;
129   if(kd->type_ == kd_aes_ctr)
130     ret = key_derivation_aesctr_init(kd, passphrase);
131
132   if(ret)
133     key_derivation_close(kd);
134
135   return ret;
136 }
137
138 #ifndef NO_PASSPHRASE
139 int key_derivation_generate_master_key(key_derivation_t* kd, const char* passphrase, u_int16_t key_length)
140 {
141   if(!kd || !passphrase)
142     return -1;
143
144   if(kd->master_key_.buf_) {
145     log_printf(WARNING, "master key and passphrase provided, ignoring passphrase");
146     return 0;
147   }
148   log_printf(NOTICE, "using passphrase to generate master key");
149
150   if(!key_length || (key_length % 8)) {
151     log_printf(ERROR, "bad master key length");
152     return -1;
153   }
154
155 #if defined(USE_SSL_CRYPTO)
156   if(key_length > (SHA256_DIGEST_LENGTH * 8)) {
157 #elif defined(USE_NETTLE)
158   if(key_length > (SHA256_DIGEST_SIZE * 8)) {
159 #else  // USE_GCRYPT is the default
160   if(key_length > (gcry_md_get_algo_dlen(GCRY_MD_SHA256) * 8)) {
161 #endif
162     log_printf(ERROR, "master key too long for passphrase algorithm");
163     return -1;
164   }
165
166   buffer_t digest;
167 #if defined(USE_SSL_CRYPTO)
168   digest.length_ = SHA256_DIGEST_LENGTH;
169 #elif defined(USE_NETTLE)
170   digest.length_ = SHA256_DIGEST_SIZE;
171 #else  // USE_GCRYPT is the default
172   digest.length_ = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
173 #endif
174   digest.buf_ = malloc(digest.length_);
175   if(!digest.buf_)
176     return -2;
177
178
179 #if defined(USE_SSL_CRYPTO)
180   SHA256((const u_int8_t*)passphrase, strlen(passphrase), digest.buf_);
181 #elif defined(USE_NETTLE)
182   struct sha256_ctx ctx;
183   sha256_init(&ctx);
184   sha256_update(&ctx, strlen(passphrase), (const u_int8_t*)passphrase);
185   sha256_digest(&ctx, digest.length_, digest.buf_);
186 #else  // USE_GCRYPT is the default
187   gcry_md_hash_buffer(GCRY_MD_SHA256, digest.buf_, passphrase, strlen(passphrase));
188 #endif
189
190   kd->master_key_.length_ = key_length/8;
191   kd->master_key_.buf_ = malloc(kd->master_key_.length_);
192   if(!kd->master_key_.buf_) {
193     kd->master_key_.length_ = 0;
194     free(digest.buf_);
195     return -2;
196   }
197
198   memcpy(kd->master_key_.buf_, &digest.buf_[digest.length_ - kd->master_key_.length_], kd->master_key_.length_);
199   free(digest.buf_);
200
201   return 0;
202 }
203
204 int key_derivation_generate_master_salt(key_derivation_t* kd, const char* passphrase, u_int16_t salt_length)
205 {
206   if(!kd || !passphrase)
207     return -1;
208
209   if(kd->master_salt_.buf_) {
210     log_printf(WARNING, "master salt and passphrase provided, ignoring passphrase");
211     return 0;
212   }
213   log_printf(NOTICE, "using passphrase to generate master salt");
214
215   if(!salt_length || (salt_length % 8)) {
216     log_printf(ERROR, "bad master salt length");
217     return -1;
218   }
219
220 #if defined(USE_SSL_CRYPTO)
221   if(salt_length > (SHA_DIGEST_LENGTH * 8)) {
222 #elif defined(USE_NETTLE)
223   if(salt_length > (SHA1_DIGEST_SIZE * 8)) {
224 #else  // USE_GCRYPT is the default
225   if(salt_length > (gcry_md_get_algo_dlen(GCRY_MD_SHA1) * 8)) {
226 #endif
227     log_printf(ERROR, "master salt too long for passphrase algorithm");
228     return -1;
229   }
230
231   buffer_t digest;
232 #if defined(USE_SSL_CRYPTO)
233   digest.length_ = SHA_DIGEST_LENGTH;
234 #elif defined(USE_NETTLE)
235   digest.length_ = SHA1_DIGEST_SIZE;
236 #else  // USE_GCRYPT is the default
237   digest.length_ = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
238 #endif
239   digest.buf_ = malloc(digest.length_);
240   if(!digest.buf_)
241     return -2;
242
243 #if defined(USE_SSL_CRYPTO)
244   SHA1((const u_int8_t*)passphrase, strlen(passphrase), digest.buf_);
245 #elif defined(USE_NETTLE)
246   struct sha1_ctx ctx;
247   sha1_init(&ctx);
248   sha1_update(&ctx, strlen(passphrase), (const u_int8_t*)passphrase);
249   sha1_digest(&ctx, digest.length_, digest.buf_);
250 #else  // USE_GCRYPT is the default
251   gcry_md_hash_buffer(GCRY_MD_SHA1, digest.buf_, passphrase, strlen(passphrase));
252 #endif
253
254   kd->master_salt_.length_ = salt_length/8;
255   kd->master_salt_.buf_ = malloc(kd->master_salt_.length_);
256   if(!kd->master_salt_.buf_) {
257     kd->master_salt_.length_ = 0;
258     free(digest.buf_);
259     return -2;
260   }
261
262   memcpy(kd->master_salt_.buf_, &digest.buf_[digest.length_ - kd->master_salt_.length_], kd->master_salt_.length_);
263   free(digest.buf_);
264
265   return 0;
266 }
267 #endif
268
269 void key_derivation_close(key_derivation_t* kd)
270 {
271   if(!kd)
272     return;
273
274   if(kd->type_ == kd_aes_ctr)
275     key_derivation_aesctr_close(kd);
276
277   if(kd->master_key_.buf_)
278     free(kd->master_key_.buf_);
279   if(kd->master_salt_.buf_)
280     free(kd->master_salt_.buf_);
281 }
282
283 int key_derivation_generate(key_derivation_t* kd, key_derivation_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, u_int8_t* key, u_int32_t len)
284 {
285   if(!kd || !key)
286     return -1;
287
288   if(label >= LABEL_NIL) {
289     log_printf(ERROR, "unknown label 0x%02X", label);
290     return -1;
291   }
292
293   int ret = 0;
294   if(kd->type_ == kd_null)
295     ret = key_derivation_null_generate(key, len);
296   else if(kd->type_ == kd_aes_ctr)
297     ret = key_derivation_aesctr_generate(kd, dir, label, seq_nr, key, len);
298   else {
299     log_printf(ERROR, "unknown key derivation type");
300     return -1;
301   }
302   return ret;
303 }
304
305 satp_prf_label_t convert_label(role_t role, key_derivation_dir_t dir, satp_prf_label_t label)
306 {
307   switch(label) {
308   case LABEL_ENC: {
309     if(dir == kd_outbound) {
310       if(role == ROLE_LEFT) return LABEL_LEFT_ENC;
311       if(role == ROLE_RIGHT) return LABEL_RIGHT_ENC;
312     }
313     else {
314       if(role == ROLE_LEFT) return LABEL_RIGHT_ENC;
315       if(role == ROLE_RIGHT) return LABEL_LEFT_ENC;
316     }
317     break;
318   }
319   case LABEL_SALT: {
320     if(dir == kd_outbound) {
321       if(role == ROLE_LEFT) return LABEL_LEFT_SALT;
322       if(role == ROLE_RIGHT) return LABEL_RIGHT_SALT;
323     }
324     else {
325       if(role == ROLE_LEFT) return LABEL_RIGHT_SALT;
326       if(role == ROLE_RIGHT) return LABEL_LEFT_SALT;
327     }
328     break;
329   }
330   case LABEL_AUTH: {
331     if(dir == kd_outbound) {
332       if(role == ROLE_LEFT) return LABEL_LEFT_AUTH;
333       if(role == ROLE_RIGHT) return LABEL_RIGHT_AUTH;
334     }
335     else {
336       if(role == ROLE_LEFT) return LABEL_RIGHT_AUTH;
337       if(role == ROLE_RIGHT) return LABEL_LEFT_AUTH;
338     }
339     break;
340   }
341   }
342
343   return label;
344 }
345
346 /* ---------------- NULL Key Derivation ---------------- */
347
348 int key_derivation_null_generate(u_int8_t* key, u_int32_t len)
349 {
350   memset(key, 0, len);
351   return 1;
352 }
353
354 /* ---------------- AES-Ctr Key Derivation ---------------- */
355
356 int key_derivation_aesctr_init(key_derivation_t* kd, const char* passphrase)
357 {
358   if(!kd)
359     return -1;
360
361   if(kd->params_)
362     free(kd->params_);
363   kd->params_ = malloc(sizeof(key_derivation_aesctr_param_t));
364   if(!kd->params_)
365     return -2;
366
367   key_derivation_aesctr_param_t* params = kd->params_;
368 #ifdef USE_GCRYPT
369   params->handle_ = 0;
370 #endif
371
372 #ifndef NO_PASSPHRASE
373   if(passphrase) {
374     int ret = key_derivation_generate_master_key(kd, passphrase, kd->key_length_);
375     if(ret)
376       return ret;
377     ret = key_derivation_generate_master_salt(kd, passphrase, KD_AESCTR_SALT_LENGTH*8);
378     if(ret)
379       return ret;
380   }
381 #endif
382
383 #if defined(USE_SSL_CRYPTO)
384   int ret = AES_set_encrypt_key(kd->master_key_.buf_, kd->master_key_.length_*8, &params->aes_key_);
385   if(ret) {
386     log_printf(ERROR, "failed to set key derivation ssl aes-key (code: %d)", ret);
387     return -1;
388   }
389 #elif defined(USE_NETTLE)
390   aes_set_encrypt_key(&params->ctx_, kd->master_key_.length_, kd->master_key_.buf_);
391 #else  // USE_GCRYPT is the default
392   int algo;
393   switch(kd->key_length_) {
394   case 128: algo = GCRY_CIPHER_AES128; break;
395   case 192: algo = GCRY_CIPHER_AES192; break;
396   case 256: algo = GCRY_CIPHER_AES256; break;
397   default: {
398     log_printf(ERROR, "key derivation key length of %d Bits is not supported", kd->key_length_);
399     return -1;
400   }
401   }
402
403   gcry_error_t err = gcry_cipher_open(&params->handle_, algo, GCRY_CIPHER_MODE_CTR, 0);
404   if(err) {
405     log_printf(ERROR, "failed to open key derivation cipher: %s", gcry_strerror(err));
406     return -1;
407   }
408
409   err = gcry_cipher_setkey(params->handle_, kd->master_key_.buf_, kd->master_key_.length_);
410   if(err) {
411     log_printf(ERROR, "failed to set key derivation key: %s", gcry_strerror(err));
412     return -1;
413   }
414 #endif
415
416   return 0;
417 }
418
419 void key_derivation_aesctr_close(key_derivation_t* kd)
420 {
421   if(!kd)
422     return;
423
424   if(kd->params_) {
425 #ifdef USE_GCRYPT
426     key_derivation_aesctr_param_t* params = kd->params_;
427     if(params->handle_)
428       gcry_cipher_close(params->handle_);
429 #endif
430
431     free(kd->params_);
432   }
433 }
434
435 int key_derivation_aesctr_calc_ctr(key_derivation_t* kd, key_derivation_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr)
436 {
437   if(!kd || !kd->params_)
438     return -1;
439
440   key_derivation_aesctr_param_t* params = kd->params_;
441
442   if(kd->master_salt_.length_ != KD_AESCTR_SALT_LENGTH) {
443     log_printf(ERROR, "master salt has wrong length");
444     return -1;
445   }
446   memcpy(params->ctr_.salt_.buf_, kd->master_salt_.buf_, KD_AESCTR_SALT_LENGTH);
447   params->ctr_.salt_.zero_ = 0;
448   params->ctr_.params_.label_ ^= SATP_PRF_LABEL_T_HTON(convert_label(kd->role_, dir, label));
449   params->ctr_.params_.seq_ ^= SEQ_NR_T_HTON(seq_nr);
450
451   return 0;
452 }
453
454 int key_derivation_aesctr_generate(key_derivation_t* kd, key_derivation_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, u_int8_t* key, u_int32_t len)
455 {
456   if(!kd || !kd->params_ || !kd->master_key_.buf_ || !kd->master_salt_.buf_) {
457     log_printf(ERROR, "key derivation not initialized or no key or salt set");
458     return -1;
459   }
460
461   key_derivation_aesctr_param_t* params = kd->params_;
462
463   if(key_derivation_aesctr_calc_ctr(kd, dir, label, seq_nr)) {
464     log_printf(ERROR, "failed to calculate key derivation CTR");
465     return -1;
466   }
467
468 #if defined(USE_SSL_CRYPTO)
469   if(KD_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) {
470     log_printf(ERROR, "failed to set key derivation CTR: size don't fits");
471     return -1;
472   }
473   u_int32_t num = 0;
474   memset(params->ecount_buf_, 0, AES_BLOCK_SIZE);
475   memset(key, 0, len);
476   AES_ctr128_encrypt(key, key, len, &params->aes_key_, params->ctr_.buf_, params->ecount_buf_, &num);
477 #elif defined(USE_NETTLE)
478   if(KD_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) {
479     log_printf(ERROR, "failed to set cipher CTR: size doesn't fit");
480     return -1;
481   }
482   memset(key, 0, len);
483   ctr_crypt(&params->ctx_, (nettle_crypt_func *)(aes_encrypt), AES_BLOCK_SIZE, params->ctr_.buf_, len, key, key);
484 #else  // USE_GCRYPT is the default
485   gcry_error_t err = gcry_cipher_reset(params->handle_);
486   if(err) {
487     log_printf(ERROR, "failed to reset key derivation cipher: %s", gcry_strerror(err));
488     return -1;
489   }
490
491   err = gcry_cipher_setctr(params->handle_, params->ctr_.buf_, KD_AESCTR_CTR_LENGTH);
492   if(err) {
493     log_printf(ERROR, "failed to set key derivation CTR: %s", gcry_strerror(err));
494     return -1;
495   }
496
497   memset(key, 0, len);
498   err = gcry_cipher_encrypt(params->handle_, key, len, NULL, 0);
499   if(err) {
500     log_printf(ERROR, "failed to generate key derivation bitstream: %s", gcry_strerror(err));
501     return -1;
502   }
503 #endif
504
505   return 0;
506 }