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.
18 * Copyright (C) 2007-2014 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/>.
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
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.
49 #include "datatypes.h"
51 #include "key_derivation.h"
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>
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)
74 kd->type_ = kd_unknown;
75 if(!strcmp(type, "null"))
77 else if(!strncmp(type, "aes-ctr", 7)) {
78 kd->type_ = kd_aes_ctr;
80 kd->key_length_ = KD_AESCTR_DEFAULT_KEY_LENGTH;
82 else if(type[7] != '-')
85 const char* tmp = &type[8];
86 kd->key_length_ = atoi(tmp);
90 log_printf(ERROR, "unknown key derivation type");
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;
102 kd->master_key_.buf_ = NULL;
103 kd->master_key_.length_ = 0;
106 kd->master_key_.buf_ = malloc(key_len);
107 if(!kd->master_key_.buf_)
109 memcpy(kd->master_key_.buf_, key, key_len);
110 kd->master_key_.length_ = key_len;
114 kd->master_salt_.buf_ = NULL;
115 kd->master_salt_.length_ = 0;
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_);
124 memcpy(kd->master_salt_.buf_, salt, salt_len);
125 kd->master_salt_.length_ = salt_len;
129 if(kd->type_ == kd_aes_ctr)
130 ret = key_derivation_aesctr_init(kd, passphrase);
133 key_derivation_close(kd);
138 #ifndef NO_PASSPHRASE
139 int key_derivation_generate_master_key(key_derivation_t* kd, const char* passphrase, u_int16_t key_length)
141 if(!kd || !passphrase)
144 if(kd->master_key_.buf_) {
145 log_printf(WARNING, "master key and passphrase provided, ignoring passphrase");
148 log_printf(NOTICE, "using passphrase to generate master key");
150 if(!key_length || (key_length % 8)) {
151 log_printf(ERROR, "bad master key length");
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)) {
162 log_printf(ERROR, "master key too long for passphrase algorithm");
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);
174 digest.buf_ = malloc(digest.length_);
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;
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));
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;
198 memcpy(kd->master_key_.buf_, &digest.buf_[digest.length_ - kd->master_key_.length_], kd->master_key_.length_);
204 int key_derivation_generate_master_salt(key_derivation_t* kd, const char* passphrase, u_int16_t salt_length)
206 if(!kd || !passphrase)
209 if(kd->master_salt_.buf_) {
210 log_printf(WARNING, "master salt and passphrase provided, ignoring passphrase");
213 log_printf(NOTICE, "using passphrase to generate master salt");
215 if(!salt_length || (salt_length % 8)) {
216 log_printf(ERROR, "bad master salt length");
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)) {
227 log_printf(ERROR, "master salt too long for passphrase algorithm");
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);
239 digest.buf_ = malloc(digest.length_);
243 #if defined(USE_SSL_CRYPTO)
244 SHA1((const u_int8_t*)passphrase, strlen(passphrase), digest.buf_);
245 #elif defined(USE_NETTLE)
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));
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;
262 memcpy(kd->master_salt_.buf_, &digest.buf_[digest.length_ - kd->master_salt_.length_], kd->master_salt_.length_);
269 void key_derivation_close(key_derivation_t* kd)
274 if(kd->type_ == kd_aes_ctr)
275 key_derivation_aesctr_close(kd);
277 if(kd->master_key_.buf_)
278 free(kd->master_key_.buf_);
279 if(kd->master_salt_.buf_)
280 free(kd->master_salt_.buf_);
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)
288 if(label >= LABEL_NIL) {
289 log_printf(ERROR, "unknown label 0x%02X", label);
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);
299 log_printf(ERROR, "unknown key derivation type");
305 satp_prf_label_t convert_label(role_t role, key_derivation_dir_t dir, satp_prf_label_t label)
309 if(dir == kd_outbound) {
310 if(role == ROLE_LEFT) return LABEL_LEFT_ENC;
311 if(role == ROLE_RIGHT) return LABEL_RIGHT_ENC;
314 if(role == ROLE_LEFT) return LABEL_RIGHT_ENC;
315 if(role == ROLE_RIGHT) return LABEL_LEFT_ENC;
320 if(dir == kd_outbound) {
321 if(role == ROLE_LEFT) return LABEL_LEFT_SALT;
322 if(role == ROLE_RIGHT) return LABEL_RIGHT_SALT;
325 if(role == ROLE_LEFT) return LABEL_RIGHT_SALT;
326 if(role == ROLE_RIGHT) return LABEL_LEFT_SALT;
331 if(dir == kd_outbound) {
332 if(role == ROLE_LEFT) return LABEL_LEFT_AUTH;
333 if(role == ROLE_RIGHT) return LABEL_RIGHT_AUTH;
336 if(role == ROLE_LEFT) return LABEL_RIGHT_AUTH;
337 if(role == ROLE_RIGHT) return LABEL_LEFT_AUTH;
346 /* ---------------- NULL Key Derivation ---------------- */
348 int key_derivation_null_generate(u_int8_t* key, u_int32_t len)
354 /* ---------------- AES-Ctr Key Derivation ---------------- */
356 int key_derivation_aesctr_init(key_derivation_t* kd, const char* passphrase)
363 kd->params_ = malloc(sizeof(key_derivation_aesctr_param_t));
367 key_derivation_aesctr_param_t* params = kd->params_;
372 #ifndef NO_PASSPHRASE
374 int ret = key_derivation_generate_master_key(kd, passphrase, kd->key_length_);
377 ret = key_derivation_generate_master_salt(kd, passphrase, KD_AESCTR_SALT_LENGTH*8);
383 #if defined(USE_SSL_CRYPTO)
384 int ret = AES_set_encrypt_key(kd->master_key_.buf_, kd->master_key_.length_*8, ¶ms->aes_key_);
386 log_printf(ERROR, "failed to set key derivation ssl aes-key (code: %d)", ret);
389 #elif defined(USE_NETTLE)
390 aes_set_encrypt_key(¶ms->ctx_, kd->master_key_.length_, kd->master_key_.buf_);
391 #else // USE_GCRYPT is the default
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;
398 log_printf(ERROR, "key derivation key length of %d Bits is not supported", kd->key_length_);
403 gcry_error_t err = gcry_cipher_open(¶ms->handle_, algo, GCRY_CIPHER_MODE_CTR, 0);
405 log_printf(ERROR, "failed to open key derivation cipher: %s", gcry_strerror(err));
409 err = gcry_cipher_setkey(params->handle_, kd->master_key_.buf_, kd->master_key_.length_);
411 log_printf(ERROR, "failed to set key derivation key: %s", gcry_strerror(err));
419 void key_derivation_aesctr_close(key_derivation_t* kd)
426 key_derivation_aesctr_param_t* params = kd->params_;
428 gcry_cipher_close(params->handle_);
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)
437 if(!kd || !kd->params_)
440 key_derivation_aesctr_param_t* params = kd->params_;
442 if(kd->master_salt_.length_ != KD_AESCTR_SALT_LENGTH) {
443 log_printf(ERROR, "master salt has wrong length");
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);
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)
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");
461 key_derivation_aesctr_param_t* params = kd->params_;
463 if(key_derivation_aesctr_calc_ctr(kd, dir, label, seq_nr)) {
464 log_printf(ERROR, "failed to calculate key derivation CTR");
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");
474 memset(params->ecount_buf_, 0, AES_BLOCK_SIZE);
476 AES_ctr128_encrypt(key, key, len, ¶ms->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");
483 ctr_crypt(¶ms->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_);
487 log_printf(ERROR, "failed to reset key derivation cipher: %s", gcry_strerror(err));
491 err = gcry_cipher_setctr(params->handle_, params->ctr_.buf_, KD_AESCTR_CTR_LENGTH);
493 log_printf(ERROR, "failed to set key derivation CTR: %s", gcry_strerror(err));
498 err = gcry_cipher_encrypt(params->handle_, key, len, NULL, 0);
500 log_printf(ERROR, "failed to generate key derivation bitstream: %s", gcry_strerror(err));