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.
14 * Copyright (C) 2007-2014 Markus Grüneis, Othmar Gsenger, Erwin Nindl,
15 * Christian Pointner <satp@wirdorange.org>
17 * This file is part of Anytun.
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
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.
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/>.
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
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.
48 #include "anytunError.h"
49 #include "keyDerivation.h"
50 #include "threadUtils.hpp"
51 #include "datatypes.h"
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>
74 void KeyDerivation::setRole(const role_t role)
76 WritersLock lock(mutex_);
78 cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: using role " << role_;
83 void KeyDerivation::calcMasterKey(std::string passphrase, uint16_t length)
85 cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: calculating master key from passphrase";
87 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: bad master key length";
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)) {
98 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: master key too long for passphrase algorithm";
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;
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());
115 master_key_.setLength(length);
117 std::memcpy(master_key_.getBuf(), &digest.getBuf()[digest.getLength() - master_key_.getLength()], master_key_.getLength());
120 void KeyDerivation::calcMasterSalt(std::string passphrase, uint16_t length)
122 cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: calculating master salt from passphrase";
124 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: bad master salt length";
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)) {
135 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: master key too long for passphrase algorithm";
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));
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());
152 master_salt_.setLength(length);
154 std::memcpy(master_salt_.getBuf(), &digest.getBuf()[digest.getLength() - master_salt_.getLength()], master_salt_.getLength());
159 satp_prf_label_t KeyDerivation::convertLabel(kd_dir_t dir, satp_prf_label_t label)
163 if(dir == KD_OUTBOUND) {
164 if(role_ == ROLE_LEFT) { return LABEL_LEFT_ENC; }
165 if(role_ == ROLE_RIGHT) { return LABEL_RIGHT_ENC; }
167 if(role_ == ROLE_LEFT) { return LABEL_RIGHT_ENC; }
168 if(role_ == ROLE_RIGHT) { return LABEL_LEFT_ENC; }
173 if(dir == KD_OUTBOUND) {
174 if(role_ == ROLE_LEFT) { return LABEL_LEFT_SALT; }
175 if(role_ == ROLE_RIGHT) { return LABEL_RIGHT_SALT; }
177 if(role_ == ROLE_LEFT) { return LABEL_RIGHT_SALT; }
178 if(role_ == ROLE_RIGHT) { return LABEL_LEFT_SALT; }
183 if(dir == KD_OUTBOUND) {
184 if(role_ == ROLE_LEFT) { return LABEL_LEFT_AUTH; }
185 if(role_ == ROLE_RIGHT) { return LABEL_RIGHT_AUTH; }
187 if(role_ == ROLE_LEFT) { return LABEL_RIGHT_AUTH; }
188 if(role_ == ROLE_RIGHT) { return LABEL_LEFT_AUTH; }
197 //****** NullKeyDerivation ******
199 bool NullKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key)
201 std::memset(key.getBuf(), 0, key.getLength());
206 //****** AesIcmKeyDerivation ******
208 AesIcmKeyDerivation::AesIcmKeyDerivation() : KeyDerivation(DEFAULT_KEY_LENGTH)
210 #if defined(USE_GCRYPT)
211 for(int i=0; i<2; i++) {
217 AesIcmKeyDerivation::AesIcmKeyDerivation(uint16_t key_length) : KeyDerivation(key_length)
219 #if defined(USE_GCRYPT)
220 for(int i=0; i<2; i++) {
226 AesIcmKeyDerivation::~AesIcmKeyDerivation()
228 WritersLock lock(mutex_);
229 #if defined(USE_GCRYPT)
230 for(int i=0; i<2; i++)
232 gcry_cipher_close(handle_[i]);
237 void AesIcmKeyDerivation::init(Buffer key, Buffer salt, std::string passphrase)
239 WritersLock lock(mutex_);
241 is_initialized_ = false;
242 #ifndef NO_PASSPHRASE
243 if(passphrase != "" && !key.getLength()) {
244 calcMasterKey(passphrase, key_length_/8);
246 master_key_ = SyncBuffer(key);
249 if(passphrase != "" && !salt.getLength()) {
250 calcMasterSalt(passphrase, SALT_LENGTH);
252 master_salt_ = SyncBuffer(salt);
255 master_key_ = SyncBuffer(key);
256 master_salt_ = SyncBuffer(salt);
262 void AesIcmKeyDerivation::updateMasterKey()
264 if(master_key_.getLength()*8 != key_length_) {
265 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: key lengths don't match";
269 if(master_salt_.getLength() != SALT_LENGTH) {
270 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: salt lengths don't match";
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]);
278 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to set ssl key (code: " << ret << ")";
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());
286 #else // USE_GCRYPT is the default
288 switch(key_length_) {
290 algo = GCRY_CIPHER_AES128;
293 algo = GCRY_CIPHER_AES192;
296 algo = GCRY_CIPHER_AES256;
299 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: cipher key length of " << key_length_ << " Bits is not supported";
304 for(int i=0; i<2; i++) {
306 gcry_cipher_close(handle_[i]);
309 gcry_error_t err = gcry_cipher_open(&handle_[i], algo, GCRY_CIPHER_MODE_CTR, 0);
311 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to open cipher: " << AnytunGpgError(err);
315 err = gcry_cipher_setkey(handle_[i], master_key_.getBuf(), master_key_.getLength());
317 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to set cipher key: " << AnytunGpgError(err);
322 is_initialized_ = true;
325 std::string AesIcmKeyDerivation::printType()
327 ReadersLock lock(mutex_);
329 std::stringstream sstr;
330 sstr << "AesIcm" << key_length_ << "KeyDerivation";
334 bool AesIcmKeyDerivation::calcCtr(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr)
336 if(master_salt_.getLength() != SALT_LENGTH) {
337 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::calcCtr: salt lengths don't match";
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);
348 bool AesIcmKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key)
350 ReadersLock lock(mutex_);
352 if(!is_initialized_) {
356 if(!calcCtr(dir, label, seq_nr)) {
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";
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";
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]);
379 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to reset cipher: " << AnytunGpgError(err);
382 err = gcry_cipher_setctr(handle_[dir], ctr_[dir].buf_, CTR_LENGTH);
384 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to set CTR: " << AnytunGpgError(err);
388 std::memset(key.getBuf(), 0, key.getLength());
389 err = gcry_cipher_encrypt(handle_[dir], key, key.getLength(), NULL, 0);
391 cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to generate cipher bitstream: " << AnytunGpgError(err);