Imported Upstream version 0.3.5
[anytun.git] / src / keyDerivation.cpp
1 /*
2  *  anytun
3  *
4  *  The secure anycast tunneling protocol (satp) defines a protocol used
5  *  for communication between any combination of unicast and anycast
6  *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
7  *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
8  *  ethernet, ip, arp ...). satp directly includes cryptography and
9  *  message authentication based on the methods used by SRTP.  It is
10  *  intended to deliver a generic, scaleable and secure solution for
11  *  tunneling and relaying of packets of any protocol.
12  *
13  *
14  *  Copyright (C) 2007-2014 Markus Grüneis, Othmar Gsenger, Erwin Nindl,
15  *                          Christian Pointner <satp@wirdorange.org>
16  *
17  *  This file is part of Anytun.
18  *
19  *  Anytun is free software: you can redistribute it and/or modify
20  *  it under the terms of the GNU General Public License as published by
21  *  the Free Software Foundation, either version 3 of the License, or
22  *  any later version.
23  *
24  *  Anytun is distributed in the hope that it will be useful,
25  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
26  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  *  GNU General Public License for more details.
28  *
29  *  You should have received a copy of the GNU General Public License
30  *  along with Anytun.  If not, see <http://www.gnu.org/licenses/>.
31  *
32  *  In addition, as a special exception, the copyright holders give
33  *  permission to link the code of portions of this program with the
34  *  OpenSSL library under certain conditions as described in each
35  *  individual source file, and distribute linked combinations
36  *  including the two.
37  *  You must obey the GNU General Public License in all respects
38  *  for all of the code used other than OpenSSL.  If you modify
39  *  file(s) with this exception, you may extend this exception to your
40  *  version of the file(s), but you are not obligated to do so.  If you
41  *  do not wish to do so, delete this exception statement from your
42  *  version.  If you delete this exception statement from all source
43  *  files in the program, then also delete it here.
44  */
45
46
47 #include "log.h"
48 #include "anytunError.h"
49 #include "keyDerivation.h"
50 #include "threadUtils.hpp"
51 #include "datatypes.h"
52 #include "endian.h"
53
54 #include <stdexcept>
55 #include <iostream>
56 #include <sstream>
57 #include <string>
58 #include <cstring>
59
60 #ifndef NO_CRYPT
61 #ifndef NO_PASSPHRASE
62
63 #if defined(USE_SSL_CRYPTO)
64 #include <openssl/sha.h>
65 #elif defined(USE_NETTLE)
66 #include <nettle/sha1.h>
67 #include <nettle/sha2.h>
68 #include <nettle/ctr.h>
69 #endif
70
71 #endif
72 #endif
73
74 void KeyDerivation::setRole(const role_t role)
75 {
76   WritersLock lock(mutex_);
77   role_ = role;
78   cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: using role " << role_;
79 }
80
81 #ifndef NO_CRYPT
82 #ifndef NO_PASSPHRASE
83 void KeyDerivation::calcMasterKey(std::string passphrase, uint16_t length)
84 {
85   cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: calculating master key from passphrase";
86   if(!length) {
87     cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: bad master key length";
88     return;
89   }
90
91 #if defined(USE_SSL_CRYPTO)
92   if(length > SHA256_DIGEST_LENGTH) {
93 #elif defined(USE_NETTLE)
94   if(length > SHA256_DIGEST_SIZE) {
95 #else  // USE_GCRYPT is the default
96   if(length > gcry_md_get_algo_dlen(GCRY_MD_SHA256)) {
97 #endif
98     cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: master key too long for passphrase algorithm";
99     return;
100   }
101
102 #if defined(USE_SSL_CRYPTO)
103   Buffer digest(uint32_t(SHA256_DIGEST_LENGTH));
104   SHA256(reinterpret_cast<const unsigned char*>(passphrase.c_str()), passphrase.length(), digest.getBuf());
105 #elif defined(USE_NETTLE)
106   Buffer digest(uint32_t(SHA256_DIGEST_SIZE));
107   struct sha256_ctx ctx;
108   sha256_init(&ctx);
109   sha256_update(&ctx, passphrase.length(), reinterpret_cast<const unsigned char*>(passphrase.c_str()));
110   sha256_digest(&ctx, digest.getLength(), digest.getBuf());
111 #else  // USE_GCRYPT is the default
112   Buffer digest(static_cast<uint32_t>(gcry_md_get_algo_dlen(GCRY_MD_SHA256)));
113   gcry_md_hash_buffer(GCRY_MD_SHA256, digest.getBuf(), passphrase.c_str(), passphrase.length());
114 #endif
115   master_key_.setLength(length);
116
117   std::memcpy(master_key_.getBuf(), &digest.getBuf()[digest.getLength() - master_key_.getLength()], master_key_.getLength());
118 }
119
120 void KeyDerivation::calcMasterSalt(std::string passphrase, uint16_t length)
121 {
122   cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: calculating master salt from passphrase";
123   if(!length) {
124     cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: bad master salt length";
125     return;
126   }
127
128 #if defined(USE_SSL_CRYPTO)
129   if(length > SHA_DIGEST_LENGTH) {
130 #elif defined(USE_NETTLE)
131   if(length > SHA1_DIGEST_SIZE) {
132 #else  // USE_GCRYPT is the default
133   if(length > gcry_md_get_algo_dlen(GCRY_MD_SHA1)) {
134 #endif
135     cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: master key too long for passphrase algorithm";
136     return;
137   }
138
139 #if defined(USE_SSL_CRYPTO)
140   Buffer digest(uint32_t(SHA_DIGEST_LENGTH));
141   SHA1(reinterpret_cast<const unsigned char*>(passphrase.c_str()), passphrase.length(), digest.getBuf());
142 #elif defined(USE_NETTLE)
143   Buffer digest(uint32_t(SHA1_DIGEST_SIZE));
144   struct sha1_ctx ctx;
145   sha1_init(&ctx);
146   sha1_update(&ctx, passphrase.length(), reinterpret_cast<const unsigned char*>(passphrase.c_str()));
147   sha1_digest(&ctx, digest.getLength(), digest.getBuf());
148 #else  // USE_GCRYPT is the default
149   Buffer digest(static_cast<uint32_t>(gcry_md_get_algo_dlen(GCRY_MD_SHA1)));
150   gcry_md_hash_buffer(GCRY_MD_SHA1, digest.getBuf(), passphrase.c_str(), passphrase.length());
151 #endif
152   master_salt_.setLength(length);
153
154   std::memcpy(master_salt_.getBuf(), &digest.getBuf()[digest.getLength() - master_salt_.getLength()], master_salt_.getLength());
155 }
156 #endif
157 #endif
158
159 satp_prf_label_t KeyDerivation::convertLabel(kd_dir_t dir, satp_prf_label_t label)
160 {
161   switch(label) {
162   case LABEL_ENC: {
163     if(dir == KD_OUTBOUND) {
164       if(role_ == ROLE_LEFT) { return LABEL_LEFT_ENC; }
165       if(role_ == ROLE_RIGHT) { return LABEL_RIGHT_ENC; }
166     } else {
167       if(role_ == ROLE_LEFT) { return LABEL_RIGHT_ENC; }
168       if(role_ == ROLE_RIGHT) { return LABEL_LEFT_ENC; }
169     }
170     break;
171   }
172   case LABEL_SALT: {
173     if(dir == KD_OUTBOUND) {
174       if(role_ == ROLE_LEFT) { return LABEL_LEFT_SALT; }
175       if(role_ == ROLE_RIGHT) { return LABEL_RIGHT_SALT; }
176     } else {
177       if(role_ == ROLE_LEFT) { return LABEL_RIGHT_SALT; }
178       if(role_ == ROLE_RIGHT) { return LABEL_LEFT_SALT; }
179     }
180     break;
181   }
182   case LABEL_AUTH: {
183     if(dir == KD_OUTBOUND) {
184       if(role_ == ROLE_LEFT) { return LABEL_LEFT_AUTH; }
185       if(role_ == ROLE_RIGHT) { return LABEL_RIGHT_AUTH; }
186     } else {
187       if(role_ == ROLE_LEFT) { return LABEL_RIGHT_AUTH; }
188       if(role_ == ROLE_RIGHT) { return LABEL_LEFT_AUTH; }
189     }
190     break;
191   }
192   }
193
194   return label;
195 }
196
197 //****** NullKeyDerivation ******
198
199 bool NullKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key)
200 {
201   std::memset(key.getBuf(), 0, key.getLength());
202   return true;
203 }
204
205 #ifndef NO_CRYPT
206 //****** AesIcmKeyDerivation ******
207
208 AesIcmKeyDerivation::AesIcmKeyDerivation() : KeyDerivation(DEFAULT_KEY_LENGTH)
209 {
210 #if defined(USE_GCRYPT)
211   for(int i=0; i<2; i++) {
212     handle_[i] = NULL;
213   }
214 #endif
215 }
216
217 AesIcmKeyDerivation::AesIcmKeyDerivation(uint16_t key_length) : KeyDerivation(key_length)
218 {
219 #if defined(USE_GCRYPT)
220   for(int i=0; i<2; i++) {
221     handle_[i] = NULL;
222   }
223 #endif
224 }
225
226 AesIcmKeyDerivation::~AesIcmKeyDerivation()
227 {
228   WritersLock lock(mutex_);
229 #if defined(USE_GCRYPT)
230   for(int i=0; i<2; i++)
231     if(handle_[i]) {
232       gcry_cipher_close(handle_[i]);
233     }
234 #endif
235 }
236
237 void AesIcmKeyDerivation::init(Buffer key, Buffer salt, std::string passphrase)
238 {
239   WritersLock lock(mutex_);
240
241   is_initialized_ = false;
242 #ifndef NO_PASSPHRASE
243   if(passphrase != "" && !key.getLength()) {
244     calcMasterKey(passphrase, key_length_/8);
245   } else {
246     master_key_ = SyncBuffer(key);
247   }
248
249   if(passphrase != "" && !salt.getLength()) {
250     calcMasterSalt(passphrase, SALT_LENGTH);
251   } else {
252     master_salt_ = SyncBuffer(salt);
253   }
254 #else
255   master_key_ = SyncBuffer(key);
256   master_salt_ = SyncBuffer(salt);
257 #endif
258
259   updateMasterKey();
260 }
261
262 void AesIcmKeyDerivation::updateMasterKey()
263 {
264   if(master_key_.getLength()*8 != key_length_) {
265     cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: key lengths don't match";
266     return;
267   }
268
269   if(master_salt_.getLength() != SALT_LENGTH) {
270     cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: salt lengths don't match";
271     return;
272   }
273
274 #if defined(USE_SSL_CRYPTO)
275   for(int i=0; i<2; i++) {
276     int ret = AES_set_encrypt_key(master_key_.getBuf(), master_key_.getLength()*8, &aes_key_[i]);
277     if(ret) {
278       cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to set ssl key (code: " << ret << ")";
279       return;
280     }
281   }
282 #elif defined(USE_NETTLE)
283   for(int i=0; i<2; i++) {
284     aes_set_encrypt_key(&(ctx_[i]), master_key_.getLength(), master_key_.getBuf());
285   }
286 #else  // USE_GCRYPT is the default
287   int algo;
288   switch(key_length_) {
289   case 128:
290     algo = GCRY_CIPHER_AES128;
291     break;
292   case 192:
293     algo = GCRY_CIPHER_AES192;
294     break;
295   case 256:
296     algo = GCRY_CIPHER_AES256;
297     break;
298   default: {
299     cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: cipher key length of " << key_length_ << " Bits is not supported";
300     return;
301   }
302   }
303
304   for(int i=0; i<2; i++) {
305     if(handle_[i]) {
306       gcry_cipher_close(handle_[i]);
307     }
308
309     gcry_error_t err = gcry_cipher_open(&handle_[i], algo, GCRY_CIPHER_MODE_CTR, 0);
310     if(err) {
311       cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to open cipher: " << AnytunGpgError(err);
312       return;
313     }
314
315     err = gcry_cipher_setkey(handle_[i], master_key_.getBuf(), master_key_.getLength());
316     if(err) {
317       cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to set cipher key: " << AnytunGpgError(err);
318       return;
319     }
320   }
321 #endif
322   is_initialized_ = true;
323 }
324
325 std::string AesIcmKeyDerivation::printType()
326 {
327   ReadersLock lock(mutex_);
328
329   std::stringstream sstr;
330   sstr << "AesIcm" << key_length_ << "KeyDerivation";
331   return sstr.str();
332 }
333
334 bool AesIcmKeyDerivation::calcCtr(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr)
335 {
336   if(master_salt_.getLength() != SALT_LENGTH) {
337     cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::calcCtr: salt lengths don't match";
338     return false;
339   }
340   std::memcpy(ctr_[dir].salt_.buf_, master_salt_.getBuf(), SALT_LENGTH);
341   ctr_[dir].salt_.zero_ = 0;
342   ctr_[dir].params_.label_ ^= SATP_PRF_LABEL_T_HTON(convertLabel(dir, label));
343   ctr_[dir].params_.seq_ ^= SEQ_NR_T_HTON(seq_nr);
344
345   return true;
346 }
347
348 bool AesIcmKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key)
349 {
350   ReadersLock lock(mutex_);
351
352   if(!is_initialized_) {
353     return false;
354   }
355
356   if(!calcCtr(dir, label, seq_nr)) {
357     return false;
358   }
359
360 #if defined(USE_SSL_CRYPTO)
361   if(CTR_LENGTH != AES_BLOCK_SIZE) {
362     cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher CTR: size doesn't fit";
363     return false;
364   }
365   unsigned int num = 0;
366   std::memset(ecount_buf_[dir], 0, AES_BLOCK_SIZE);
367   std::memset(key.getBuf(), 0, key.getLength());
368   AES_ctr128_encrypt(key.getBuf(), key.getBuf(), key.getLength(), &aes_key_[dir], ctr_[dir].buf_, ecount_buf_[dir], &num);
369 #elif defined(USE_NETTLE)
370   if(CTR_LENGTH != AES_BLOCK_SIZE) {
371     cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher CTR: size doesn't fit";
372     return false;
373   }
374   std::memset(key.getBuf(), 0, key.getLength());
375   ctr_crypt(&(ctx_[dir]), (nettle_crypt_func *)(aes_encrypt), AES_BLOCK_SIZE, ctr_[dir].buf_, key.getLength(), key.getBuf(), key.getBuf());
376 #else  // USE_GCRYPT is the default
377   gcry_error_t err = gcry_cipher_reset(handle_[dir]);
378   if(err) {
379     cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to reset cipher: " << AnytunGpgError(err);
380   }
381
382   err = gcry_cipher_setctr(handle_[dir], ctr_[dir].buf_, CTR_LENGTH);
383   if(err) {
384     cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to set CTR: " << AnytunGpgError(err);
385     return false;
386   }
387
388   std::memset(key.getBuf(), 0, key.getLength());
389   err = gcry_cipher_encrypt(handle_[dir], key, key.getLength(), NULL, 0);
390   if(err) {
391     cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to generate cipher bitstream: " << AnytunGpgError(err);
392   }
393 #endif
394
395   return true;
396 }
397 #endif
398