got rid of NOPACKED (struct alignment works now under Windows)
[anytun.git] / src / keyDerivation.h
blob926d35f6a49bcfe6e6966b678381034ef1bc5de8
1 /*
2 * anytun
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 methodes 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-2008 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 version 3 as
21 * published by the Free Software Foundation.
23 * Anytun is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with anytun. If not, see <http://www.gnu.org/licenses/>.
32 #ifndef _KEYDERIVATION_H_
33 #define _KEYDERIVATION_H_
35 #include "datatypes.h"
36 #include "buffer.h"
37 #include "threadUtils.hpp"
38 #include "syncBuffer.h"
40 #ifndef NOCRYPT
41 #ifndef USE_SSL_CRYPTO
42 #include <gcrypt.h>
43 #else
44 #include <openssl/aes.h>
45 #endif
46 #endif
47 #include <boost/archive/text_oarchive.hpp>
48 #include <boost/archive/text_iarchive.hpp>
50 #define KD_LABEL_COUNT 3
51 typedef enum {
52 LABEL_SATP_ENCRYPTION = 0x00,
53 LABEL_SATP_MSG_AUTH = 0x01,
54 LABEL_SATP_SALT = 0x02,
55 } satp_prf_label_t;
57 typedef enum {
58 KD_INBOUND = 0,
59 KD_OUTBOUND = 1
60 } kd_dir_t;
62 typedef struct {
63 Buffer key_;
64 seq_nr_t r_;
65 } key_store_t;
67 class KeyDerivation
69 public:
70 KeyDerivation() : is_initialized_(false), ld_kdr_(0), key_length_(0), master_salt_(0), master_key_(0) {};
71 KeyDerivation(u_int16_t key_length) : is_initialized_(false), ld_kdr_(0), key_length_(key_length), master_salt_(0), master_key_(0) {};
72 virtual ~KeyDerivation() {};
74 void setLogKDRate(const int8_t ld_rate);
76 virtual void init(Buffer key, Buffer salt) = 0;
77 virtual bool generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key) = 0;
79 virtual std::string printType() { return "GenericKeyDerivation"; };
81 protected:
82 virtual void updateMasterKey() = 0;
84 KeyDerivation(const KeyDerivation & src);
85 friend class boost::serialization::access;
86 template<class Archive>
87 void serialize(Archive & ar, const unsigned int version)
89 WritersLock lock(mutex_);
90 ar & ld_kdr_;
91 ar & key_length_;
92 ar & master_salt_;
93 ar & master_key_;
94 updateMasterKey();
97 bool is_initialized_;
98 int8_t ld_kdr_; // ld(key_derivation_rate)
99 u_int16_t key_length_;
100 SyncBuffer master_salt_;
101 SyncBuffer master_key_;
103 SharedMutex mutex_;
106 BOOST_IS_ABSTRACT(KeyDerivation)
108 //****** NullKeyDerivation ******
110 class NullKeyDerivation : public KeyDerivation
112 public:
113 NullKeyDerivation() {};
114 ~NullKeyDerivation() {};
116 void init(Buffer key, Buffer salt) {};
117 bool generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key);
119 std::string printType() { return "NullKeyDerivation"; };
121 private:
122 void updateMasterKey() {};
124 friend class boost::serialization::access;
125 template<class Archive>
126 void serialize(Archive & ar, const unsigned int version)
128 ar & boost::serialization::base_object<KeyDerivation>(*this);
133 #ifndef NOCRYPT
134 //****** AesIcmKeyDerivation ******
136 class AesIcmKeyDerivation : public KeyDerivation
138 public:
139 AesIcmKeyDerivation();
140 AesIcmKeyDerivation(u_int16_t key_length);
141 ~AesIcmKeyDerivation();
143 static const u_int16_t DEFAULT_KEY_LENGTH = 128;
144 static const u_int16_t CTR_LENGTH = 16;
145 static const u_int16_t SALT_LENGTH = 14;
147 void init(Buffer key, Buffer salt);
148 bool generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key);
150 std::string printType();
152 private:
153 void updateMasterKey();
155 bool calcCtr(kd_dir_t dir, seq_nr_t* r, satp_prf_label_t label, seq_nr_t seq_nr);
157 friend class boost::serialization::access;
158 template<class Archive>
159 void serialize(Archive & ar, const unsigned int version)
161 ar & boost::serialization::base_object<KeyDerivation>(*this);
164 #ifndef USE_SSL_CRYPTO
165 gcry_cipher_hd_t handle_[2];
166 #else
167 AES_KEY aes_key_[2];
168 u_int8_t ecount_buf_[2][AES_BLOCK_SIZE];
169 #endif
171 key_store_t key_store_[2][KD_LABEL_COUNT];
173 #ifdef _MSC_VER
174 #pragma pack(push, 1)
175 #endif
176 union ATTR_PACKED key_derivation_aesctr_ctr_union {
177 u_int8_t buf_[CTR_LENGTH];
178 struct ATTR_PACKED {
179 u_int8_t buf_[SALT_LENGTH];
180 u_int16_t zero_;
181 } salt_;
182 #ifndef ANYTUN_02_COMPAT
183 struct ATTR_PACKED {
184 u_int8_t fill_[SALT_LENGTH - sizeof(u_int8_t) - sizeof(seq_nr_t)];
185 u_int8_t label_;
186 seq_nr_t r_;
187 u_int16_t zero_;
188 } params_;
189 #else
190 struct ATTR_PACKED {
191 u_int8_t fill_[SALT_LENGTH - sizeof(u_int8_t) - 2 - sizeof(seq_nr_t)];
192 u_int8_t label_;
193 u_int8_t r_fill_[2];
194 seq_nr_t r_;
195 u_int16_t zero_;
196 } params_;
197 #endif
198 } ctr_[2];
199 #ifdef _MSC_VER
200 #pragma pack(pop)
201 #endif
204 #endif
206 #endif