/*
sptps.c -- Simple Peer-to-Peer Security
- Copyright (C) 2011-2015 Guus Sliepen <guus@tinc-vpn.org>,
+ Copyright (C) 2011-2021 Guus Sliepen <guus@tinc-vpn.org>,
2010 Brandon L. Black <blblack@gmail.com>
This program is free software; you can redistribute it and/or modify
#include "system.h"
-#include "chacha-poly1305/chacha-poly1305.h"
+#include "chacha-poly1305/chachapoly.h"
#include "ecdh.h"
#include "ecdsa.h"
#include "prf.h"
#include <openssl/evp.h>
#endif
+#define CIPHER_KEYLEN 64
+
unsigned int sptps_replaywin = 16;
/*
}
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
#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;
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};
}
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)) {