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 "key_derivation.h"
40 #include <openssl/sha.h>
48 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)
56 kd->type_ = kd_unknown;
57 if(!strcmp(type, "null"))
59 else if(!strncmp(type, "aes-ctr", 7)) {
60 kd->type_ = kd_aes_ctr;
62 kd->key_length_ = KD_AESCTR_DEFAULT_KEY_LENGTH;
64 else if(type[7] != '-')
67 const char* tmp = &type[8];
68 kd->key_length_ = atoi(tmp);
72 log_printf(ERROR, "unknown key derivation type");
77 case ROLE_LEFT: log_printf(NOTICE, "key derivation role: left"); break;
78 case ROLE_RIGHT: log_printf(NOTICE, "key derivation role: right"); break;
79 default: log_printf(NOTICE, "key derivation role: unknown"); break;
84 kd->master_key_.buf_ = NULL;
85 kd->master_key_.length_ = 0;
88 kd->master_key_.buf_ = malloc(key_len);
89 if(!kd->master_key_.buf_)
91 memcpy(kd->master_key_.buf_, key, key_len);
92 kd->master_key_.length_ = key_len;
96 kd->master_salt_.buf_ = NULL;
97 kd->master_salt_.length_ = 0;
100 kd->master_salt_.buf_ = malloc(salt_len);
101 if(!kd->master_salt_.buf_) {
102 if(kd->master_key_.buf_)
103 free(kd->master_key_.buf_);
106 memcpy(kd->master_salt_.buf_, salt, salt_len);
107 kd->master_salt_.length_ = salt_len;
111 if(kd->type_ == kd_aes_ctr)
112 ret = key_derivation_aesctr_init(kd, passphrase);
115 key_derivation_close(kd);
120 #ifndef NO_PASSPHRASE
121 int key_derivation_generate_master_key(key_derivation_t* kd, const char* passphrase, u_int16_t key_length)
123 if(!kd || !passphrase)
126 if(kd->master_key_.buf_) {
127 log_printf(WARNING, "master key and passphrase provided, ignoring passphrase");
130 log_printf(NOTICE, "using passphrase to generate master key");
132 if(!key_length || (key_length % 8)) {
133 log_printf(ERROR, "bad master key length");
137 #ifndef USE_SSL_CRYPTO
138 if(key_length > (gcry_md_get_algo_dlen(GCRY_MD_SHA256) * 8)) {
140 if(key_length > (SHA256_DIGEST_LENGTH * 8)) {
142 log_printf(ERROR, "master key too long for passphrase algorithm");
147 #ifndef USE_SSL_CRYPTO
148 digest.length_ = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
150 digest.length_ = SHA256_DIGEST_LENGTH;
152 digest.buf_ = malloc(digest.length_);
157 #ifndef USE_SSL_CRYPTO
158 gcry_md_hash_buffer(GCRY_MD_SHA256, digest.buf_, passphrase, strlen(passphrase));
160 SHA256(passphrase, strlen(passphrase), digest.buf_);
163 kd->master_key_.length_ = key_length/8;
164 kd->master_key_.buf_ = malloc(kd->master_key_.length_);
165 if(!kd->master_key_.buf_) {
166 kd->master_key_.length_ = 0;
171 memcpy(kd->master_key_.buf_, &digest.buf_[digest.length_ - kd->master_key_.length_], kd->master_key_.length_);
177 int key_derivation_generate_master_salt(key_derivation_t* kd, const char* passphrase, u_int16_t salt_length)
179 if(!kd || !passphrase)
182 if(kd->master_salt_.buf_) {
183 log_printf(WARNING, "master salt and passphrase provided, ignoring passphrase");
186 log_printf(NOTICE, "using passphrase to generate master salt");
188 if(!salt_length || (salt_length % 8)) {
189 log_printf(ERROR, "bad master salt length");
193 #ifndef USE_SSL_CRYPTO
194 if(salt_length > (gcry_md_get_algo_dlen(GCRY_MD_SHA1) * 8)) {
196 if(salt_length > (SHA_DIGEST_LENGTH * 8)) {
198 log_printf(ERROR, "master salt too long for passphrase algorithm");
203 #ifndef USE_SSL_CRYPTO
204 digest.length_ = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
206 digest.length_ = SHA_DIGEST_LENGTH;
208 digest.buf_ = malloc(digest.length_);
212 #ifndef USE_SSL_CRYPTO
213 gcry_md_hash_buffer(GCRY_MD_SHA1, digest.buf_, passphrase, strlen(passphrase));
215 SHA1(passphrase, strlen(passphrase), digest.buf_);
218 kd->master_salt_.length_ = salt_length/8;
219 kd->master_salt_.buf_ = malloc(kd->master_salt_.length_);
220 if(!kd->master_salt_.buf_) {
221 kd->master_salt_.length_ = 0;
226 memcpy(kd->master_salt_.buf_, &digest.buf_[digest.length_ - kd->master_salt_.length_], kd->master_salt_.length_);
233 void key_derivation_close(key_derivation_t* kd)
238 if(kd->type_ == kd_aes_ctr)
239 key_derivation_aesctr_close(kd);
241 if(kd->master_key_.buf_)
242 free(kd->master_key_.buf_);
243 if(kd->master_salt_.buf_)
244 free(kd->master_salt_.buf_);
247 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)
252 if(label >= LABEL_NIL) {
253 log_printf(ERROR, "unknown label 0x%02X", label);
258 if(kd->type_ == kd_null)
259 ret = key_derivation_null_generate(key, len);
260 else if(kd->type_ == kd_aes_ctr)
261 ret = key_derivation_aesctr_generate(kd, dir, label, seq_nr, key, len);
263 log_printf(ERROR, "unknown key derivation type");
269 satp_prf_label_t convert_label(role_t role, key_derivation_dir_t dir, satp_prf_label_t label)
273 if(dir == kd_outbound) {
274 if(role == ROLE_LEFT) return LABEL_LEFT_ENC;
275 if(role == ROLE_RIGHT) return LABEL_RIGHT_ENC;
278 if(role == ROLE_LEFT) return LABEL_RIGHT_ENC;
279 if(role == ROLE_RIGHT) return LABEL_LEFT_ENC;
284 if(dir == kd_outbound) {
285 if(role == ROLE_LEFT) return LABEL_LEFT_SALT;
286 if(role == ROLE_RIGHT) return LABEL_RIGHT_SALT;
289 if(role == ROLE_LEFT) return LABEL_RIGHT_SALT;
290 if(role == ROLE_RIGHT) return LABEL_LEFT_SALT;
295 if(dir == kd_outbound) {
296 if(role == ROLE_LEFT) return LABEL_LEFT_AUTH;
297 if(role == ROLE_RIGHT) return LABEL_RIGHT_AUTH;
300 if(role == ROLE_LEFT) return LABEL_RIGHT_AUTH;
301 if(role == ROLE_RIGHT) return LABEL_LEFT_AUTH;
310 /* ---------------- NULL Key Derivation ---------------- */
312 int key_derivation_null_generate(u_int8_t* key, u_int32_t len)
318 /* ---------------- AES-Ctr Key Derivation ---------------- */
320 int key_derivation_aesctr_init(key_derivation_t* kd, const char* passphrase)
327 kd->params_ = malloc(sizeof(key_derivation_aesctr_param_t));
331 key_derivation_aesctr_param_t* params = kd->params_;
332 #ifndef USE_SSL_CRYPTO
336 #ifndef NO_PASSPHRASE
338 int ret = key_derivation_generate_master_key(kd, passphrase, kd->key_length_);
341 ret = key_derivation_generate_master_salt(kd, passphrase, KD_AESCTR_SALT_LENGTH*8);
347 #ifndef USE_SSL_CRYPTO
349 switch(kd->key_length_) {
350 case 128: algo = GCRY_CIPHER_AES128; break;
351 case 192: algo = GCRY_CIPHER_AES192; break;
352 case 256: algo = GCRY_CIPHER_AES256; break;
354 log_printf(ERROR, "key derivation key length of %d Bits is not supported", kd->key_length_);
359 gcry_error_t err = gcry_cipher_open(¶ms->handle_, algo, GCRY_CIPHER_MODE_CTR, 0);
361 log_printf(ERROR, "failed to open key derivation cipher: %s", gcry_strerror(err));
365 err = gcry_cipher_setkey(params->handle_, kd->master_key_.buf_, kd->master_key_.length_);
367 log_printf(ERROR, "failed to set key derivation key: %s", gcry_strerror(err));
371 int ret = AES_set_encrypt_key(kd->master_key_.buf_, kd->master_key_.length_*8, ¶ms->aes_key_);
373 log_printf(ERROR, "failed to set key derivation ssl aes-key (code: %d)", ret);
381 void key_derivation_aesctr_close(key_derivation_t* kd)
387 key_derivation_aesctr_param_t* params = kd->params_;
389 #ifndef USE_SSL_CRYPTO
391 gcry_cipher_close(params->handle_);
398 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)
400 if(!kd || !kd->params_)
403 key_derivation_aesctr_param_t* params = kd->params_;
405 if(kd->master_salt_.length_ != KD_AESCTR_SALT_LENGTH) {
406 log_printf(ERROR, "master salt has wrong length");
409 memcpy(params->ctr_.salt_.buf_, kd->master_salt_.buf_, KD_AESCTR_SALT_LENGTH);
410 params->ctr_.salt_.zero_ = 0;
411 params->ctr_.params_.label_ ^= SATP_PRF_LABEL_T_HTON(convert_label(kd->role_, dir, label));
412 params->ctr_.params_.seq_ ^= SEQ_NR_T_HTON(seq_nr);
417 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)
419 if(!kd || !kd->params_ || !kd->master_key_.buf_ || !kd->master_salt_.buf_) {
420 log_printf(ERROR, "key derivation not initialized or no key or salt set");
424 key_derivation_aesctr_param_t* params = kd->params_;
426 if(key_derivation_aesctr_calc_ctr(kd, dir, label, seq_nr)) {
427 log_printf(ERROR, "failed to calculate key derivation CTR");
431 #ifndef USE_SSL_CRYPTO
432 gcry_error_t err = gcry_cipher_reset(params->handle_);
434 log_printf(ERROR, "failed to reset key derivation cipher: %s", gcry_strerror(err));
438 err = gcry_cipher_setctr(params->handle_, params->ctr_.buf_, KD_AESCTR_CTR_LENGTH);
440 log_printf(ERROR, "failed to set key derivation CTR: %s", gcry_strerror(err));
445 err = gcry_cipher_encrypt(params->handle_, key, len, NULL, 0);
447 log_printf(ERROR, "failed to generate key derivation bitstream: %s", gcry_strerror(err));
451 if(KD_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) {
452 log_printf(ERROR, "failed to set key derivation CTR: size don't fits");
456 memset(params->ecount_buf_, 0, AES_BLOCK_SIZE);
458 AES_ctr128_encrypt(key, key, len, ¶ms->aes_key_, params->ctr_.buf_, params->ecount_buf_, &num);