* tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
* mode and allows tunneling of every ETHER TYPE protocol (e.g.
* ethernet, ip, arp ...). satp directly includes cryptography and
- * message authentication based on the methodes used by SRTP. It is
+ * message authentication based on the methods used by SRTP. It is
* intended to deliver a generic, scaleable and secure solution for
* tunneling and relaying of packets of any protocol.
- *
*
- * Copyright (C) 2007-2008 Christian Pointner <equinox@anytun.org>
+ *
+ * Copyright (C) 2007-2014 Christian Pointner <equinox@anytun.org>
*
* This file is part of uAnytun.
*
*
* You should have received a copy of the GNU General Public License
* along with uAnytun. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
*/
#include "datatypes.h"
#include "encrypted_packet.h"
#include "cipher.h"
+#if defined(USE_NETTLE)
+#include <nettle/ctr.h>
+#endif
#include "log.h"
int cipher_init(cipher_t* c, const char* type)
{
- if(!c)
+ if(!c)
return -1;
c->key_length_ = 0;
if(type[7] == 0) {
c->key_length_ = C_AESCTR_DEFAULT_KEY_LENGTH;
}
- else if(type[7] != '-')
+ else if(type[7] != '-')
return -1;
else {
const char* tmp = &type[8];
int cipher_encrypt(cipher_t* c, key_derivation_t* kd, key_derivation_dir_t dir, plain_packet_t* in, encrypted_packet_t* out, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
{
- if(!c)
+ if(!c)
return -1;
- int32_t len;
+ int32_t len;
if(c->type_ == c_null)
- len = cipher_null_crypt(plain_packet_get_packet(in), plain_packet_get_length(in),
+ len = cipher_null_crypt(plain_packet_get_packet(in), plain_packet_get_length(in),
encrypted_packet_get_payload(out), encrypted_packet_get_payload_length(out));
#ifndef NO_CRYPT
else if(c->type_ == c_aes_ctr)
if(len < 0)
return 0;
- encrypted_packet_set_sender_id(out, sender_id);
+ encrypted_packet_set_sender_id(out, sender_id);
encrypted_packet_set_seq_nr(out, seq_nr);
encrypted_packet_set_mux(out, mux);
int cipher_decrypt(cipher_t* c, key_derivation_t* kd, key_derivation_dir_t dir, encrypted_packet_t* in, plain_packet_t* out)
{
- if(!c)
+ if(!c)
return -1;
- int32_t len;
+ int32_t len;
if(c->type_ == c_null)
len = cipher_null_crypt(encrypted_packet_get_payload(in), encrypted_packet_get_payload_length(in),
plain_packet_get_packet(out), plain_packet_get_length(out));
log_printf(ERROR, "unknown cipher type");
return -1;
}
-
+
if(len < 0)
return 0;
- plain_packet_set_length(out, len);
+ plain_packet_set_length(out, len);
return 0;
}
int32_t cipher_null_crypt(u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen)
{
- memcpy(out, in, (ilen < olen) ? ilen : olen);
+ memcpy(out, in, (ilen < olen) ? ilen : olen);
return (ilen < olen) ? ilen : olen;
}
if(!c->params_)
return -2;
- cipher_aesctr_param_t* params = c->params_;
-
-#ifndef USE_SSL_CRYPTO
+#if defined(USE_SSL_CRYPTO)
+ // nothing here
+#elif defined(USE_NETTLE)
+ // nothing here
+#else // USE_GCRYPT is the default
int algo;
switch(c->key_length_) {
case 128: algo = GCRY_CIPHER_AES128; break;
}
}
+ cipher_aesctr_param_t* params = c->params_;
gcry_error_t err = gcry_cipher_open(¶ms->handle_, algo, GCRY_CIPHER_MODE_CTR, 0);
if(err) {
log_printf(ERROR, "failed to open cipher: %s", gcry_strerror(err));
return -1;
- }
+ }
#endif
return 0;
return;
if(c->params_) {
+#if defined(USE_SSL_CRYPTO)
+ // nothing here
+#elif defined(USE_NETTLE)
+ // nothing here
+#else // USE_GCRYPT is the default
cipher_aesctr_param_t* params = c->params_;
-
-#ifndef USE_SSL_CRYPTO
- if(params->handle_)
- gcry_cipher_close(params->handle_);
+ gcry_cipher_close(params->handle_);
#endif
-
free(c->params_);
}
}
{
if(!c || !c->params_)
return -1;
-
+
cipher_aesctr_param_t* params = c->params_;
int ret = key_derivation_generate(kd, dir, LABEL_SALT, seq_nr, c->salt_.buf_, C_AESCTR_SALT_LENGTH);
int ret = key_derivation_generate(kd, dir, LABEL_ENC, seq_nr, c->key_.buf_, c->key_.length_);
if(ret < 0)
return ret;
-
-#ifdef USE_SSL_CRYPTO
+
+#if defined(USE_SSL_CRYPTO)
ret = AES_set_encrypt_key(c->key_.buf_, c->key_length_, ¶ms->aes_key_);
if(ret) {
- log_printf(ERROR, "failed to set cipher ssl aes-key (code: %d)", ret);
+ log_printf(ERROR, "failed to set cipher key (code: %d)", ret);
return -1;
}
-#else
+#elif defined(USE_NETTLE)
+ aes_set_encrypt_key(¶ms->ctx_, c->key_.length_, c->key_.buf_);
+#else // USE_GCRYPT is the default
gcry_error_t err = gcry_cipher_setkey(params->handle_, c->key_.buf_, c->key_.length_);
if(err) {
log_printf(ERROR, "failed to set cipher key: %s", gcry_strerror(err));
log_printf(ERROR, "failed to calculate cipher CTR");
return ret;
}
-
-#ifndef USE_SSL_CRYPTO
+
+#if defined(USE_SSL_CRYPTO)
+ if(C_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) {
+ log_printf(ERROR, "failed to set cipher CTR: size doesn't fit");
+ return -1;
+ }
+ u_int32_t num = 0;
+ memset(params->ecount_buf_, 0, AES_BLOCK_SIZE);
+ AES_ctr128_encrypt(in, out, (ilen < olen) ? ilen : olen, ¶ms->aes_key_, params->ctr_.buf_, params->ecount_buf_, &num);
+#elif defined(USE_NETTLE)
+ if(C_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) {
+ log_printf(ERROR, "failed to set cipher CTR: size doesn't fit");
+ return -1;
+ }
+ ctr_crypt(¶ms->ctx_, (nettle_crypt_func *)(aes_encrypt), AES_BLOCK_SIZE, params->ctr_.buf_, (ilen < olen) ? ilen : olen, out, in);
+#else // USE_GCRYPT is the default
err = gcry_cipher_setctr(params->handle_, params->ctr_.buf_, C_AESCTR_CTR_LENGTH);
if(err) {
log_printf(ERROR, "failed to set cipher CTR: %s", gcry_strerror(err));
log_printf(ERROR, "failed to de/encrypt packet: %s", gcry_strerror(err));
return -1;
}
-#else
- if(C_AESCTR_CTR_LENGTH != AES_BLOCK_SIZE) {
- log_printf(ERROR, "failed to set cipher CTR: size don't fits");
- return -1;
- }
- u_int32_t num = 0;
- memset(params->ecount_buf_, 0, AES_BLOCK_SIZE);
- AES_ctr128_encrypt(in, out, (ilen < olen) ? ilen : olen, ¶ms->aes_key_, params->ctr_.buf_, params->ecount_buf_, &num);
#endif
- return (ilen < olen) ? ilen : olen;
+ return (ilen < olen) ? ilen : olen;
}
#endif