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/>.
35 #include "encryptedPacket.h"
40 //****** NullAuthAlgo ******
41 void NullAuthAlgo::generate(KeyDerivation
& kd
, EncryptedPacket
& packet
)
45 bool NullAuthAlgo::checkTag(KeyDerivation
& kd
, EncryptedPacket
& packet
)
51 //****** Sha1AuthAlgo ******
53 Sha1AuthAlgo::Sha1AuthAlgo(kd_dir_t d
) : AuthAlgo(d
), key_(DIGEST_LENGTH
)
55 #ifndef USE_SSL_CRYPTO
56 gcry_error_t err
= gcry_md_open(&handle_
, GCRY_MD_SHA1
, GCRY_MD_FLAG_HMAC
);
58 cLog
.msg(Log::PRIO_CRIT
) << "Sha1AuthAlgo::Sha1AuthAlgo: Failed to open message digest algo";
63 HMAC_Init_ex(&ctx_
, NULL
, 0, EVP_sha1(), NULL
);
67 Sha1AuthAlgo::~Sha1AuthAlgo()
69 #ifndef USE_SSL_CRYPTO
71 gcry_md_close(handle_
);
73 HMAC_CTX_cleanup(&ctx_
);
77 void Sha1AuthAlgo::generate(KeyDerivation
& kd
, EncryptedPacket
& packet
)
79 #ifndef USE_SSL_CRYPTO
85 if(!packet
.getAuthTagLength())
88 kd
.generate(dir_
, LABEL_SATP_MSG_AUTH
, packet
.getSeqNr(), key_
);
89 #ifndef USE_SSL_CRYPTO
90 gcry_error_t err
= gcry_md_setkey(handle_
, key_
.getBuf(), key_
.getLength());
92 cLog
.msg(Log::PRIO_ERR
) << "Sha1AuthAlgo::setKey: Failed to set hmac key: " << LogGpgError(err
);
96 gcry_md_reset(handle_
);
97 gcry_md_write(handle_
, packet
.getAuthenticatedPortion(), packet
.getAuthenticatedPortionLength());
98 gcry_md_final(handle_
);
99 u_int8_t
* hmac
= gcry_md_read(handle_
, 0);
101 HMAC_Init_ex(&ctx_
, key_
.getBuf(), key_
.getLength(), EVP_sha1(), NULL
);
103 u_int8_t hmac
[DIGEST_LENGTH
];
104 HMAC_Update(&ctx_
, packet
.getAuthenticatedPortion(), packet
.getAuthenticatedPortionLength());
105 HMAC_Final(&ctx_
, hmac
, NULL
);
108 u_int8_t
* tag
= packet
.getAuthTag();
109 u_int32_t length
= (packet
.getAuthTagLength() < DIGEST_LENGTH
) ? packet
.getAuthTagLength() : DIGEST_LENGTH
;
111 if(length
> DIGEST_LENGTH
)
112 std::memset(tag
, 0, packet
.getAuthTagLength());
114 std::memcpy(&tag
[packet
.getAuthTagLength() - length
], &hmac
[DIGEST_LENGTH
- length
], length
);
117 bool Sha1AuthAlgo::checkTag(KeyDerivation
& kd
, EncryptedPacket
& packet
)
119 #ifndef USE_SSL_CRYPTO
124 packet
.withAuthTag(true);
125 if(!packet
.getAuthTagLength())
128 kd
.generate(dir_
, LABEL_SATP_MSG_AUTH
, packet
.getSeqNr(), key_
);
129 #ifndef USE_SSL_CRYPTO
130 gcry_error_t err
= gcry_md_setkey(handle_
, key_
.getBuf(), key_
.getLength());
132 cLog
.msg(Log::PRIO_ERR
) << "Sha1AuthAlgo::setKey: Failed to set hmac key: " << LogGpgError(err
);
136 gcry_md_reset(handle_
);
137 gcry_md_write(handle_
, packet
.getAuthenticatedPortion(), packet
.getAuthenticatedPortionLength());
138 gcry_md_final(handle_
);
139 u_int8_t
* hmac
= gcry_md_read(handle_
, 0);
141 HMAC_Init_ex(&ctx_
, key_
.getBuf(), key_
.getLength(), EVP_sha1(), NULL
);
143 u_int8_t hmac
[DIGEST_LENGTH
];
144 HMAC_Update(&ctx_
, packet
.getAuthenticatedPortion(), packet
.getAuthenticatedPortionLength());
145 HMAC_Final(&ctx_
, hmac
, NULL
);
148 u_int8_t
* tag
= packet
.getAuthTag();
149 u_int32_t length
= (packet
.getAuthTagLength() < DIGEST_LENGTH
) ? packet
.getAuthTagLength() : DIGEST_LENGTH
;
151 if(length
> DIGEST_LENGTH
)
152 for(u_int32_t i
=0; i
< (packet
.getAuthTagLength() - DIGEST_LENGTH
); ++i
)
153 if(tag
[i
]) return false;
155 int ret
= std::memcmp(&tag
[packet
.getAuthTagLength() - length
], &hmac
[DIGEST_LENGTH
- length
], length
);
156 packet
.removeAuthTag();