From 58c92b8405f5da687734c1b0d6f7ec63dbb2d3b0 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 Jun 2018 12:56:47 -0400 Subject: [PATCH] aead/chacha20/poly1305 from openssl 1.1 --- libi2pd/Crypto.cpp | 40 ++++++++++++++++++++++++++++++++++++---- libi2pd/Crypto.h | 3 ++- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index bdcf5acd..f8fb9946 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -8,9 +8,13 @@ #include #include "TunnelBase.h" #include -#include "I2PEndian.h" +#if LEGACY_OPENSSL #include "ChaCha20.h" #include "Poly1305.h" +#else +#include +#endif +#include "I2PEndian.h" #include "Log.h" #include "Crypto.h" @@ -1064,7 +1068,10 @@ namespace crypto bool AEADChaCha20Poly1305 (const uint8_t * msg, size_t msgLen, const uint8_t * ad, size_t adLen, const uint8_t * key, const uint8_t * nonce, uint8_t * buf, size_t len, bool encrypt) { - if (encrypt && msgLen + 16 < len) return 0; + if (len < msgLen) return false; + if (encrypt && len < msgLen + 16) return false; + bool ret = true; +#if LEGACY_OPENSSL // generate one time poly key uint8_t polyKey[64]; memset(polyKey, 0, sizeof(polyKey)); @@ -1106,9 +1113,34 @@ namespace crypto uint32_t tag[8]; // calculate Poly1305 tag Poly1305HMAC (tag, (uint32_t *)polyKey, polyMsg.data (), offset); - if (memcmp (tag, msg + msgLen, 16)) return false; // compare with provided + if (memcmp (tag, msg + msgLen, 16)) ret = false; // compare with provided } - return true; +#else + int outlen = 0; + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new (); + if (encrypt) + { + EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), 0, 0, 0); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, 12, 0); + EVP_EncryptInit_ex(ctx, NULL, NULL, key, nonce); + EVP_EncryptUpdate(ctx, NULL, &outlen, ad, adLen); + EVP_EncryptUpdate(ctx, buf, &outlen, msg, msgLen); + EVP_EncryptFinal_ex(ctx, buf, &outlen); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, buf + msgLen); + } + else + { + EVP_DecryptInit_ex(ctx, EVP_chacha20_poly1305(), 0, 0, 0); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, 12, 0); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, (uint8_t *)(msg + msgLen)); + EVP_DecryptInit_ex(ctx, NULL, NULL, key, nonce); + EVP_DecryptUpdate(ctx, NULL, &outlen, ad, adLen); + ret = EVP_DecryptUpdate(ctx, buf, &outlen, msg, msgLen) > 0; + } + + EVP_CIPHER_CTX_free (ctx); +#endif + return ret; } // init and terminate diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index af4ec1f8..25646dbb 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -265,7 +265,8 @@ namespace crypto // take care about openssl version #include -#if (OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER) // 1.1.0 or LibreSSL +#define LEGACY_OPENSSL ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL +#if LEGACY_OPENSSL // define getters and setters introduced in 1.1.0 inline int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) {