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 "key_derivation.h"
41 #include <openssl/sha.h>
49 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)
57 kd->type_ = kd_unknown;
58 if(!strcmp(type, "null"))
60 else if(!strncmp(type, "aes-ctr", 7)) {
61 kd->type_ = kd_aes_ctr;
63 kd->key_length_ = KD_AESCTR_DEFAULT_KEY_LENGTH;
65 else if(type[7] != '-')
68 const char* tmp = &type[8];
69 kd->key_length_ = atoi(tmp);
73 log_printf(ERROR, "unknown key derivation type");
78 case ROLE_LEFT: log_printf(NOTICE, "key derivation role: left"); break;
79 case ROLE_RIGHT: log_printf(NOTICE, "key derivation role: right"); break;
80 default: log_printf(NOTICE, "key derivation role: unknown"); break;
85 kd->master_key_.buf_ = NULL;
86 kd->master_key_.length_ = 0;
89 kd->master_key_.buf_ = malloc(key_len);
90 if(!kd->master_key_.buf_)
92 memcpy(kd->master_key_.buf_, key, key_len);
93 kd->master_key_.length_ = key_len;
97 kd->master_salt_.buf_ = NULL;
98 kd->master_salt_.length_ = 0;
101 kd->master_salt_.buf_ = malloc(salt_len);
102 if(!kd->master_salt_.buf_) {
103 if(kd->master_key_.buf_)
104 free(kd->master_key_.buf_);
107 memcpy(kd->master_salt_.buf_, salt, salt_len);
108 kd->master_salt_.length_ = salt_len;
112 if(kd->type_ == kd_aes_ctr)
113 ret = key_derivation_aesctr_init(kd, passphrase);
116 key_derivation_close(kd);
121 #ifndef NO_PASSPHRASE
122 int key_derivation_generate_master_key(key_derivation_t* kd, const char* passphrase, u_int16_t key_length)
124 if(!kd || !passphrase)
127 if(kd->master_key_.buf_) {
128 log_printf(WARNING, "master key and passphrase provided, ignoring passphrase");
131 log_printf(NOTICE, "using passphrase to generate master key");
133 if(!key_length || (key_length % 8)) {
134 log_printf(ERROR, "bad master key length");
138 #ifndef USE_SSL_CRYPTO
139 if(key_length > (gcry_md_get_algo_dlen(GCRY_MD_SHA256) * 8)) {
141 if(key_length > (SHA256_DIGEST_LENGTH * 8)) {
143 log_printf(ERROR, "master key too long for passphrase algorithm");
148 #ifndef USE_SSL_CRYPTO
149 digest.length_ = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
151 digest.length_ = SHA256_DIGEST_LENGTH;
153 digest.buf_ = malloc(digest.length_);
158 #ifndef USE_SSL_CRYPTO
159 gcry_md_hash_buffer(GCRY_MD_SHA256, digest.buf_, passphrase, strlen(passphrase));
161 SHA256(passphrase, strlen(passphrase), digest.buf_);
164 kd->master_key_.length_ = key_length/8;
165 kd->master_key_.buf_ = malloc(kd->master_key_.length_);
166 if(!kd->master_key_.buf_) {
167 kd->master_key_.length_ = 0;
172 memcpy(kd->master_key_.buf_, &digest.buf_[digest.length_ - kd->master_key_.length_], kd->master_key_.length_);
178 int key_derivation_generate_master_salt(key_derivation_t* kd, const char* passphrase, u_int16_t salt_length)
180 if(!kd || !passphrase)
183 if(kd->master_salt_.buf_) {
184 log_printf(WARNING, "master salt and passphrase provided, ignoring passphrase");
187 log_printf(NOTICE, "using passphrase to generate master salt");
189 if(!salt_length || (salt_length % 8)) {
190 log_printf(ERROR, "bad master salt length");
194 #ifndef USE_SSL_CRYPTO
195 if(salt_length > (gcry_md_get_algo_dlen(GCRY_MD_SHA1) * 8)) {
197 if(salt_length > (SHA_DIGEST_LENGTH * 8)) {
199 log_printf(ERROR, "master salt too long for passphrase algorithm");
204 #ifndef USE_SSL_CRYPTO
205 digest.length_ = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
207 digest.length_ = SHA_DIGEST_LENGTH;
209 digest.buf_ = malloc(digest.length_);
213 #ifndef USE_SSL_CRYPTO
214 gcry_md_hash_buffer(GCRY_MD_SHA1, digest.buf_, passphrase, strlen(passphrase));
216 SHA1(passphrase, strlen(passphrase), digest.buf_);
219 kd->master_salt_.length_ = salt_length/8;
220 kd->master_salt_.buf_ = malloc(kd->master_salt_.length_);
221 if(!kd->master_salt_.buf_) {
222 kd->master_salt_.length_ = 0;
227 memcpy(kd->master_salt_.buf_, &digest.buf_[digest.length_ - kd->master_salt_.length_], kd->master_salt_.length_);
234 void key_derivation_close(key_derivation_t* kd)
239 if(kd->type_ == kd_aes_ctr)
240 key_derivation_aesctr_close(kd);
242 if(kd->master_key_.buf_)
243 free(kd->master_key_.buf_);
244 if(kd->master_salt_.buf_)
245 free(kd->master_salt_.buf_);
248 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)
253 if(label >= LABEL_NIL) {
254 log_printf(ERROR, "unknown label 0x%02X", label);
259 if(kd->type_ == kd_null)
260 ret = key_derivation_null_generate(key, len);
261 else if(kd->type_ == kd_aes_ctr)
262 ret = key_derivation_aesctr_generate(kd, dir, label, seq_nr, key, len);
264 log_printf(ERROR, "unknown key derivation type");
270 satp_prf_label_t convert_label(role_t role, key_derivation_dir_t dir, satp_prf_label_t label)
274 if(dir == kd_outbound) {
275 if(role == ROLE_LEFT) return LABEL_LEFT_ENC;
276 if(role == ROLE_RIGHT) return LABEL_RIGHT_ENC;
279 if(role == ROLE_LEFT) return LABEL_RIGHT_ENC;
280 if(role == ROLE_RIGHT) return LABEL_LEFT_ENC;
285 if(dir == kd_outbound) {
286 if(role == ROLE_LEFT) return LABEL_LEFT_SALT;
287 if(role == ROLE_RIGHT) return LABEL_RIGHT_SALT;
290 if(role == ROLE_LEFT) return LABEL_RIGHT_SALT;
291 if(role == ROLE_RIGHT) return LABEL_LEFT_SALT;
296 if(dir == kd_outbound) {
297 if(role == ROLE_LEFT) return LABEL_LEFT_AUTH;
298 if(role == ROLE_RIGHT) return LABEL_RIGHT_AUTH;
301 if(role == ROLE_LEFT) return LABEL_RIGHT_AUTH;
302 if(role == ROLE_RIGHT) return LABEL_LEFT_AUTH;
311 /* ---------------- NULL Key Derivation ---------------- */
313 int key_derivation_null_generate(u_int8_t* key, u_int32_t len)
319 /* ---------------- AES-Ctr Key Derivation ---------------- */
321 int key_derivation_aesctr_init(key_derivation_t* kd, const char* passphrase)
328 kd->params_ = malloc(sizeof(key_derivation_aesctr_param_t));
332 key_derivation_aesctr_param_t* params = kd->params_;
333 #ifndef USE_SSL_CRYPTO
337 #ifndef NO_PASSPHRASE
339 int ret = key_derivation_generate_master_key(kd, passphrase, kd->key_length_);
342 ret = key_derivation_generate_master_salt(kd, passphrase, KD_AESCTR_SALT_LENGTH*8);
348 #ifndef USE_SSL_CRYPTO
350 switch(kd->key_length_) {
351 case 128: algo = GCRY_CIPHER_AES128; break;
352 case 192: algo = GCRY_CIPHER_AES192; break;
353 case 256: algo = GCRY_CIPHER_AES256; break;
355 log_printf(ERROR, "key derivation key length of %d Bits is not supported", kd->key_length_);
360 gcry_error_t err = gcry_cipher_open(¶ms->handle_, algo, GCRY_CIPHER_MODE_CTR, 0);
362 log_printf(ERROR, "failed to open key derivation cipher: %s", gcry_strerror(err));
366 err = gcry_cipher_setkey(params->handle_, kd->master_key_.buf_, kd->master_key_.length_);
368 log_printf(ERROR, "failed to set key derivation key: %s", gcry_strerror(err));
372 int ret = AES_set_encrypt_key(kd->master_key_.buf_, kd->master_key_.length_*8, ¶ms->aes_key_);
374 log_printf(ERROR, "failed to set key derivation ssl aes-key (code: %d)", ret);
382 void key_derivation_aesctr_close(key_derivation_t* kd)
388 key_derivation_aesctr_param_t* params = kd->params_;
390 #ifndef USE_SSL_CRYPTO
392 gcry_cipher_close(params->handle_);
399 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)
401 if(!kd || !kd->params_)
404 key_derivation_aesctr_param_t* params = kd->params_;
406 if(kd->master_salt_.length_ != KD_AESCTR_SALT_LENGTH) {
407 log_printf(ERROR, "master salt has wrong length");
410 memcpy(params->ctr_.salt_.buf_, kd->master_salt_.buf_, KD_AESCTR_SALT_LENGTH);
411 params->ctr_.salt_.zero_ = 0;
412 params->ctr_.params_.label_ ^= SATP_PRF_LABEL_T_HTON(convert_label(kd->role_, dir, label));
413 params->ctr_.params_.seq_ ^= SEQ_NR_T_HTON(seq_nr);
418 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)
420 if(!kd || !kd->params_ || !kd->master_key_.buf_ || !kd->master_salt_.buf_) {
421 log_printf(ERROR, "key derivation not initialized or no key or salt set");
425 key_derivation_aesctr_param_t* params = kd->params_;
427 if(key_derivation_aesctr_calc_ctr(kd, dir, label, seq_nr)) {
428 log_printf(ERROR, "failed to calculate key derivation CTR");
432 #ifndef USE_SSL_CRYPTO
433 gcry_error_t err = gcry_cipher_reset(params->handle_);
435 log_printf(ERROR, "failed to reset key derivation cipher: %s", gcry_strerror(err));
439 err = gcry_cipher_setctr(params->handle_, params->ctr_.buf_, KD_AESCTR_CTR_LENGTH);
441 log_printf(ERROR, "failed to set key derivation CTR: %s", gcry_strerror(err));
446 err = gcry_cipher_encrypt(params->handle_, key, len, NULL, 0);
448 log_printf(ERROR, "failed to generate key derivation bitstream: %s", gcry_strerror(err));
452 if(KD_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) {
453 log_printf(ERROR, "failed to set key derivation CTR: size don't fits");
457 memset(params->ecount_buf_, 0, AES_BLOCK_SIZE);
459 AES_ctr128_encrypt(key, key, len, ¶ms->aes_key_, params->ctr_.buf_, params->ecount_buf_, &num);