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 anytun.org <satp@wirdorange.org>
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2
18 * as published by the Free Software Foundation.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program (see the file COPYING included with this
27 * distribution); if not, write to the Free Software Foundation, Inc.,
28 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41 void Cypher::encrypt(const PlainPacket
& in
,EncryptedPacket
& out
, seq_nr_t seq_nr
, sender_id_t sender_id
)
43 cypher(out
.payload_
, in
.complete_payload_
, in
.complete_payload_length_
, seq_nr
, sender_id
);
44 out
.setSenderId(sender_id
);
46 out
.setPayloadLength(in
.complete_payload_length_
);
49 void Cypher::decrypt(const EncryptedPacket
& in
,PlainPacket
& out
)
51 cypher(out
.complete_payload_
, in
.payload_
, in
.payload_length_
, in
.getSeqNr(), in
.getSenderId());
52 out
.setCompletePayloadLength(in
.payload_length_
);
55 void NullCypher::cypher(u_int8_t
* out
, u_int8_t
* in
, u_int32_t length
, seq_nr_t seq_nr
, sender_id_t sender_id
)
57 std::memcpy(out
, in
, length
);
60 const char* AesIcmCypher::MIN_GCRYPT_VERSION
= "1.2.3";
62 AesIcmCypher::AesIcmCypher() : salt_(Buffer(14))
66 // No other library has already initialized libgcrypt.
67 if( !gcry_control(GCRYCTL_ANY_INITIALIZATION_P
) )
69 if( !gcry_check_version( MIN_GCRYPT_VERSION
) ) {
70 cLog
.msg(Log::PRIO_ERR
) << "AesIcmCypher::AesIcmCypher: Invalid Version of libgcrypt, should be >= " << MIN_GCRYPT_VERSION
;
74 /* Allocate a pool of secure memory. This also drops priviliges
76 err
= gcry_control(GCRYCTL_INIT_SECMEM
, GCRYPT_SEC_MEM
, 0);
78 cLog
.msg(Log::PRIO_ERR
) << "Failed to allocate " << GCRYPT_SEC_MEM
<< "bytes of secure memory: " << gpg_strerror( err
);
82 /* Tell Libgcrypt that initialization has completed. */
83 err
= gcry_control(GCRYCTL_INITIALIZATION_FINISHED
);
85 cLog
.msg(Log::PRIO_CRIT
) << "AesIcmCypher::AesIcmCypher: Failed to finish the initialization of libgcrypt: " << gpg_strerror( err
);
88 cLog
.msg(Log::PRIO_DEBUG
) << "AesIcmCypher::AesIcmCypher: libgcrypt init finished";
92 err
= gcry_cipher_open( &cipher_
, GCRY_CIPHER_AES128
, GCRY_CIPHER_MODE_CTR
, 0 );
94 cLog
.msg(Log::PRIO_CRIT
) << "AesIcmCypher::AesIcmCypher: Failed to open cypher";
98 AesIcmCypher::~AesIcmCypher()
100 gcry_cipher_close( cipher_
);
101 cLog
.msg(Log::PRIO_DEBUG
) << "AesIcmCypher::~AesIcmCypher: closed cipher";
105 void AesIcmCypher::setKey(Buffer key
)
108 // FIXXME: hardcoded keysize
109 err
= gcry_cipher_setkey( cipher_
, key
.getBuf(), 16 );
111 cLog
.msg(Log::PRIO_ERR
) << "AesIcmCypher::setKey: Failed to set cipher key: " << gpg_strerror( err
);
114 void AesIcmCypher::setSalt(Buffer salt
)
119 void AesIcmCypher::cypher(u_int8_t
* out
, u_int8_t
* in
, u_int32_t length
, seq_nr_t seq_nr
, sender_id_t sender_id
)
124 //==========================================================================
125 // // where the 128-bit integer value IV SHALL be defined by the SSRC, the
126 // // SRTP packet index i, and the SRTP session salting key k_s, as below.
128 // // IV = (k_s * 2^16) XOR (SSRC * 2^64) XOR (i * 2^16)
129 // // sizeof(k_s) = 112 bit, random
132 Mpi salt
= Mpi(salt_
.getBuf(), salt_
.getLength());
136 iv
= salt
.mul2exp(16) ^ sid
.mul2exp(64) ^ seq
.mul2exp(16);
138 u_int8_t
*iv_buf
= iv
.getNewBuf(16);
139 err
= gcry_cipher_setiv( cipher_
, iv_buf
, 16 );
142 cLog
.msg(Log::PRIO_ERR
) << "AesIcmCypher: Failed to set cipher IV: " << gpg_strerror( err
);
146 err
= gcry_cipher_reset( cipher_
);
148 cLog
.msg(Log::PRIO_ERR
) << "AesIcmCypher: Failed to reset cipher: " << gpg_strerror( err
);
152 err
= gcry_cipher_encrypt( cipher_
, out
, length
, in
, length
);
154 cLog
.msg(Log::PRIO_ERR
) << "AesIcmCypher: Failed to generate cipher bitstream: " << gpg_strerror( err
);