|
|
|
@ -9,8 +9,7 @@
@@ -9,8 +9,7 @@
|
|
|
|
|
#include "TunnelBase.h" |
|
|
|
|
#include <openssl/ssl.h> |
|
|
|
|
#include "Crypto.h" |
|
|
|
|
#if LEGACY_OPENSSL |
|
|
|
|
#include <openssl/conf.h> |
|
|
|
|
#if !OPENSSL_AEAD_CHACHA20_POLY1305 |
|
|
|
|
#include "ChaCha20.h" |
|
|
|
|
#include "Poly1305.h" |
|
|
|
|
#endif |
|
|
|
@ -1091,7 +1090,32 @@ namespace crypto
@@ -1091,7 +1090,32 @@ namespace crypto
|
|
|
|
|
if (len < msgLen) return false; |
|
|
|
|
if (encrypt && len < msgLen + 16) return false; |
|
|
|
|
bool ret = true; |
|
|
|
|
#if LEGACY_OPENSSL |
|
|
|
|
#if OPENSSL_AEAD_CHACHA20_POLY1305 |
|
|
|
|
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); |
|
|
|
|
EVP_DecryptUpdate(ctx, buf, &outlen, msg, msgLen); |
|
|
|
|
ret = EVP_DecryptFinal_ex(ctx, buf + outlen, &outlen) > 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
EVP_CIPHER_CTX_free (ctx); |
|
|
|
|
#else |
|
|
|
|
chacha::Chacha20State state; |
|
|
|
|
// generate one time poly key
|
|
|
|
|
chacha::Chacha20Init (state, nonce, key, 0); |
|
|
|
@ -1150,31 +1174,6 @@ namespace crypto
@@ -1150,31 +1174,6 @@ namespace crypto
|
|
|
|
|
polyHash.Finish (tag); |
|
|
|
|
if (memcmp (tag, msg + msgLen, 16)) ret = false; // compare with provided
|
|
|
|
|
} |
|
|
|
|
#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); |
|
|
|
|
EVP_DecryptUpdate(ctx, buf, &outlen, msg, msgLen); |
|
|
|
|
ret = EVP_DecryptFinal_ex(ctx, buf + outlen, &outlen) > 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
EVP_CIPHER_CTX_free (ctx); |
|
|
|
|
#endif |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
@ -1182,7 +1181,18 @@ namespace crypto
@@ -1182,7 +1181,18 @@ namespace crypto
|
|
|
|
|
void AEADChaCha20Poly1305Encrypt (const std::vector<std::pair<uint8_t *, size_t> >& bufs, const uint8_t * key, const uint8_t * nonce, uint8_t * mac) |
|
|
|
|
{ |
|
|
|
|
if (bufs.empty ()) return; |
|
|
|
|
#if LEGACY_OPENSSL |
|
|
|
|
#if OPENSSL_AEAD_CHACHA20_POLY1305 |
|
|
|
|
int outlen = 0; |
|
|
|
|
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new (); |
|
|
|
|
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); |
|
|
|
|
for (const auto& it: bufs) |
|
|
|
|
EVP_EncryptUpdate(ctx, it.first, &outlen, it.first, it.second); |
|
|
|
|
EVP_EncryptFinal_ex(ctx, NULL, &outlen); |
|
|
|
|
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, mac); |
|
|
|
|
EVP_CIPHER_CTX_free (ctx); |
|
|
|
|
#else |
|
|
|
|
chacha::Chacha20State state; |
|
|
|
|
// generate one time poly key
|
|
|
|
|
chacha::Chacha20Init (state, nonce, key, 0); |
|
|
|
@ -1214,18 +1224,7 @@ namespace crypto
@@ -1214,18 +1224,7 @@ namespace crypto
|
|
|
|
|
htole64buf (padding + 8, size); |
|
|
|
|
polyHash.Update (padding, 16); |
|
|
|
|
// MAC
|
|
|
|
|
polyHash.Finish ((uint64_t *)mac); |
|
|
|
|
#else |
|
|
|
|
int outlen = 0; |
|
|
|
|
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new (); |
|
|
|
|
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); |
|
|
|
|
for (const auto& it: bufs) |
|
|
|
|
EVP_EncryptUpdate(ctx, it.first, &outlen, it.first, it.second); |
|
|
|
|
EVP_EncryptFinal_ex(ctx, NULL, &outlen); |
|
|
|
|
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, mac); |
|
|
|
|
EVP_CIPHER_CTX_free (ctx); |
|
|
|
|
polyHash.Finish ((uint64_t *)mac); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|