X-Git-Url: http://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fsptps.c;h=b36079d3d73b33472c4294ee9d5bda394cc0cc19;hb=e994222a4370621a9ac69c13ed23531c1eaa6809;hp=500bf83d5ff02fa6d8121c5489f104e277d5812a;hpb=9ce00234190baec0eaa608a5093bb3823487ef0c;p=tinc diff --git a/src/sptps.c b/src/sptps.c index 500bf83d..b36079d3 100644 --- a/src/sptps.c +++ b/src/sptps.c @@ -1,6 +1,6 @@ /* sptps.c -- Simple Peer-to-Peer Security - Copyright (C) 2011-2015 Guus Sliepen , + Copyright (C) 2011-2021 Guus Sliepen , 2010 Brandon L. Black This program is free software; you can redistribute it and/or modify @@ -20,7 +20,7 @@ #include "system.h" -#include "chacha-poly1305/chacha-poly1305.h" +#include "chacha-poly1305/chachapoly.h" #include "ecdh.h" #include "ecdsa.h" #include "prf.h" @@ -32,6 +32,8 @@ #include #endif +#define CIPHER_KEYLEN 64 + unsigned int sptps_replaywin = 16; /* @@ -113,37 +115,37 @@ static void free_sptps_key(sptps_key_t *key) { } static bool cipher_init(uint8_t suite, void **ctx, const sptps_key_t *keys, bool key_half) { - const uint8_t *key = key_half ? keys->key1 : keys->key0; + const uint8_t *key = key_half ? keys->key1 : keys->key0; switch(suite) { #ifndef HAVE_OPENSSL case SPTPS_CHACHA_POLY1305: - *ctx = chacha_poly1305_init(); - return ctx && chacha_poly1305_set_key(*ctx, key); + *ctx = malloc(sizeof(struct chachapoly_ctx)); + return *ctx && chachapoly_init(*ctx, key, 256) == CHACHAPOLY_OK; #else case SPTPS_CHACHA_POLY1305: - *ctx = EVP_CIPHER_CTX_new(); +#ifdef EVP_F_EVP_AEAD_CTX_INIT + *ctx = malloc(sizeof(EVP_AEAD_CTX)); - if(!ctx) { - return false; - } + return *ctx && EVP_AEAD_CTX_init(*ctx, EVP_aead_chacha20_poly1305(), key + (key_half ? CIPHER_KEYLEN : 0), 32, 16, NULL); +#else + *ctx = EVP_CIPHER_CTX_new(); - return EVP_EncryptInit_ex(*ctx, EVP_chacha20_poly1305(), NULL, NULL, NULL) - && EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL) + return *ctx + && EVP_EncryptInit_ex(*ctx, EVP_chacha20_poly1305(), NULL, NULL, NULL) + && EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL) && EVP_EncryptInit_ex(*ctx, NULL, NULL, key, key + 32); +#endif case SPTPS_AES256_GCM: *ctx = EVP_CIPHER_CTX_new(); - if(!ctx) { - return false; - } - - return EVP_EncryptInit_ex(*ctx, EVP_aes_256_gcm(), NULL, NULL, NULL) - && EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL) + return *ctx + && EVP_EncryptInit_ex(*ctx, EVP_aes_256_gcm(), NULL, NULL, NULL) + && EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL) && EVP_EncryptInit_ex(*ctx, NULL, NULL, key, key + 32); #endif @@ -157,12 +159,18 @@ static void cipher_exit(uint8_t suite, void *ctx) { #ifndef HAVE_OPENSSL case SPTPS_CHACHA_POLY1305: - chacha_poly1305_exit(ctx); + free(ctx); break; #else case SPTPS_CHACHA_POLY1305: +#ifdef EVP_F_EVP_AEAD_CTX_INIT + EVP_AEAD_CTX_cleanup(ctx); + free(ctx); + break; +#endif + case SPTPS_AES256_GCM: EVP_CIPHER_CTX_free(ctx); break; @@ -177,13 +185,38 @@ static bool cipher_encrypt(uint8_t suite, void *ctx, uint32_t seqno, const uint8 switch(suite) { #ifndef HAVE_OPENSSL - case SPTPS_CHACHA_POLY1305: - chacha_poly1305_encrypt(ctx, seqno, in, inlen, out, outlen); + case SPTPS_CHACHA_POLY1305: { + if(chachapoly_crypt(ctx, nonce, (void *)in, inlen, out, out + inlen, 16, 1) != CHACHAPOLY_OK) { + return false; + } + + if(outlen) { + *outlen = inlen + 16; + } + return true; + } #else case SPTPS_CHACHA_POLY1305: +#ifdef EVP_F_EVP_AEAD_CTX_INIT + { + size_t outlen1; + + if(!EVP_AEAD_CTX_seal(ctx, out, &outlen1, inlen + 16, nonce, sizeof(nonce), in, inlen, NULL, 0)) { + return false; + } + + if(outlen) { + *outlen = outlen1; + } + + return true; + } + +#endif + case SPTPS_AES256_GCM: { uint8_t nonce[12] = {seqno, seqno >> 8, seqno >> 16, seqno >> 24}; @@ -224,22 +257,47 @@ static bool cipher_encrypt(uint8_t suite, void *ctx, uint32_t seqno, const uint8 } static bool cipher_decrypt(uint8_t suite, void *ctx, uint32_t seqno, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) { + if(inlen < 16) { + return false; + } + + inlen -= 16; + switch(suite) { #ifndef HAVE_OPENSSL case SPTPS_CHACHA_POLY1305: - return chacha_poly1305_decrypt(ctx, seqno, in, inlen, out, outlen); + if(chachapoly_crypt(ctx, nonce, (void *)in, inlen, out, (void *)(in + inlen), 16, 0) != CHACHAPOLY_OK) { + return false; + } + + if(outlen) { + *outlen = inlen; + } + + return true; #else case SPTPS_CHACHA_POLY1305: - case SPTPS_AES256_GCM: { - if(inlen < 16) { - return false; +#ifdef EVP_F_EVP_AEAD_CTX_INIT + { + size_t outlen1; + + if(!EVP_AEAD_CTX_open(ctx, out, &outlen1, inlen, nonce, sizeof(nonce), in, inlen + 16, NULL, 0)) { + return false; + } + + if(outlen) { + *outlen = outlen1; + } + + return true; } - inlen -= 16; +#endif + case SPTPS_AES256_GCM: { uint8_t nonce[12] = {seqno, seqno >> 8, seqno >> 16, seqno >> 24}; if(!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, nonce)) {