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/>.
43 void Cipher::encrypt(KeyDerivation
& kd
, PlainPacket
& in
, EncryptedPacket
& out
, seq_nr_t seq_nr
, sender_id_t sender_id
, mux_t mux
)
45 u_int32_t len
= cipher(kd
, in
, in
.getLength(), out
.getPayload(), out
.getPayloadLength(), seq_nr
, sender_id
, mux
);
46 out
.setSenderId(sender_id
);
49 out
.setPayloadLength(len
);
52 void Cipher::decrypt(KeyDerivation
& kd
, EncryptedPacket
& in
, PlainPacket
& out
)
54 u_int32_t len
= decipher(kd
, in
.getPayload() , in
.getPayloadLength(), out
, out
.getLength(), in
.getSeqNr(), in
.getSenderId(), in
.getMux());
59 //******* NullCipher *******
61 u_int32_t
NullCipher::cipher(KeyDerivation
& kd
, u_int8_t
* in
, u_int32_t ilen
, u_int8_t
* out
, u_int32_t olen
, seq_nr_t seq_nr
, sender_id_t sender_id
, mux_t mux
)
63 std::memcpy(out
, in
, (ilen
< olen
) ? ilen
: olen
);
64 return (ilen
< olen
) ? ilen
: olen
;
67 u_int32_t
NullCipher::decipher(KeyDerivation
& kd
, u_int8_t
* in
, u_int32_t ilen
, u_int8_t
* out
, u_int32_t olen
, seq_nr_t seq_nr
, sender_id_t sender_id
, mux_t mux
)
69 std::memcpy(out
, in
, (ilen
< olen
) ? ilen
: olen
);
70 return (ilen
< olen
) ? ilen
: olen
;
74 //****** AesIcmCipher ******
76 AesIcmCipher::AesIcmCipher(kd_dir_t d
) : Cipher(d
), key_(u_int32_t(DEFAULT_KEY_LENGTH
/8)), salt_(u_int32_t(SALT_LENGTH
))
81 AesIcmCipher::AesIcmCipher(kd_dir_t d
, u_int16_t key_length
) : Cipher(d
), key_(u_int32_t(key_length
/8)), salt_(u_int32_t(SALT_LENGTH
))
86 void AesIcmCipher::init(u_int16_t key_length
)
88 #ifndef USE_SSL_CRYPTO
92 case 128: algo
= GCRY_CIPHER_AES128
; break;
93 case 192: algo
= GCRY_CIPHER_AES192
; break;
94 case 256: algo
= GCRY_CIPHER_AES256
; break;
96 cLog
.msg(Log::PRIO_CRIT
) << "AesIcmCipher::AesIcmCipher: cipher key length of " << key_length
<< " Bits is not supported";
101 gcry_error_t err
= gcry_cipher_open(&handle_
, algo
, GCRY_CIPHER_MODE_CTR
, 0);
103 cLog
.msg(Log::PRIO_CRIT
) << "AesIcmCipher::AesIcmCipher: Failed to open cipher" << LogGpgError(err
);
109 AesIcmCipher::~AesIcmCipher()
111 #ifndef USE_SSL_CRYPTO
113 gcry_cipher_close(handle_
);
117 u_int32_t
AesIcmCipher::cipher(KeyDerivation
& kd
, u_int8_t
* in
, u_int32_t ilen
, u_int8_t
* out
, u_int32_t olen
, seq_nr_t seq_nr
, sender_id_t sender_id
, mux_t mux
)
119 calc(kd
, in
, ilen
, out
, olen
, seq_nr
, sender_id
, mux
);
120 return (ilen
< olen
) ? ilen
: olen
;
123 u_int32_t
AesIcmCipher::decipher(KeyDerivation
& kd
, u_int8_t
* in
, u_int32_t ilen
, u_int8_t
* out
, u_int32_t olen
, seq_nr_t seq_nr
, sender_id_t sender_id
, mux_t mux
)
125 calc(kd
, in
, ilen
, out
, olen
, seq_nr
, sender_id
, mux
);
126 return (ilen
< olen
) ? ilen
: olen
;
129 void AesIcmCipher::calcCtr(KeyDerivation
& kd
, seq_nr_t seq_nr
, sender_id_t sender_id
, mux_t mux
)
131 kd
.generate(dir_
, LABEL_SATP_SALT
, seq_nr
, salt_
);
133 #ifdef ANYTUN_02_COMPAT
134 if(!salt_
[u_int32_t(0)])
135 salt_
[u_int32_t(0)] = 1;
138 std::memcpy(ctr_
.salt_
.buf_
, salt_
.getBuf(), SALT_LENGTH
);
139 ctr_
.salt_
.zero_
= 0;
140 ctr_
.params_
.mux_
^= MUX_T_HTON(mux
);
141 ctr_
.params_
.sender_id_
^= SENDER_ID_T_HTON(sender_id
);
142 ctr_
.params_
.seq_nr_
^= SEQ_NR_T_HTON(seq_nr
);
147 void AesIcmCipher::calc(KeyDerivation
& kd
, u_int8_t
* in
, u_int32_t ilen
, u_int8_t
* out
, u_int32_t olen
, seq_nr_t seq_nr
, sender_id_t sender_id
, mux_t mux
)
149 #ifndef USE_SSL_CRYPTO
154 kd
.generate(dir_
, LABEL_SATP_ENCRYPTION
, seq_nr
, key_
);
155 #ifdef USE_SSL_CRYPTO
156 int ret
= AES_set_encrypt_key(key_
.getBuf(), key_
.getLength()*8, &aes_key_
);
158 cLog
.msg(Log::PRIO_ERR
) << "AesIcmCipher: Failed to set cipher ssl key (code: " << ret
<< ")";
162 gcry_error_t err
= gcry_cipher_setkey(handle_
, key_
.getBuf(), key_
.getLength());
164 cLog
.msg(Log::PRIO_ERR
) << "AesIcmCipher: Failed to set cipher key: " << LogGpgError(err
);
169 calcCtr(kd
, seq_nr
, sender_id
, mux
);
171 #ifndef USE_SSL_CRYPTO
172 err
= gcry_cipher_setctr(handle_
, ctr_
.buf_
, CTR_LENGTH
);
174 cLog
.msg(Log::PRIO_ERR
) << "AesIcmCipher: Failed to set cipher CTR: " << LogGpgError(err
);
178 err
= gcry_cipher_encrypt(handle_
, out
, olen
, in
, ilen
);
180 cLog
.msg(Log::PRIO_ERR
) << "AesIcmCipher: Failed to de/encrypt packet: " << LogGpgError(err
);
184 if(CTR_LENGTH
!= AES_BLOCK_SIZE
) {
185 cLog
.msg(Log::PRIO_ERR
) << "AesIcmCipher: Failed to set cipher CTR: size don't fits";
188 unsigned int num
= 0;
189 std::memset(ecount_buf_
, 0, AES_BLOCK_SIZE
);
190 AES_ctr128_encrypt(in
, out
, (ilen
< olen
) ? ilen
: olen
, &aes_key_
, ctr_
.buf_
, ecount_buf_
, &num
);