1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2025-07-06 07:44:57 +03:00

Mayaqua/Encrypt: add CipherProcessAead() function to encrypt/decrypt with AEAD ciphers

This commit is contained in:
Davide Beatrici
2018-11-03 15:14:56 +01:00
parent 8b7b45b301
commit aae9ec0492
2 changed files with 73 additions and 1 deletions

View File

@ -570,6 +570,7 @@ CIPHER *NewCipher(char *name)
EVP_CIPHER_CTX_init(c->Ctx);
#endif
c->IsAeadCipher = EVP_CIPHER_flags(c->Cipher) & EVP_CIPH_FLAG_AEAD_CIPHER;
c->BlockSize = EVP_CIPHER_block_size(c->Cipher);
c->KeySize = EVP_CIPHER_key_length(c->Cipher);
c->IvSize = EVP_CIPHER_iv_length(c->Cipher);
@ -634,6 +635,74 @@ UINT CipherProcess(CIPHER *c, void *iv, void *dest, void *src, UINT size)
return r + r2;
}
// Process encryption / decryption (AEAD)
UINT CipherProcessAead(CIPHER *c, void *iv, void *tag, UINT tag_size, void *dest, void *src, UINT src_size, void *aad, UINT aad_size)
{
int r = src_size;
int r2 = 0;
// Validate arguments
if (c == NULL)
{
return 0;
}
else if (c->IsNullCipher)
{
Copy(dest, src, src_size);
return src_size;
}
else if (c->IsAeadCipher == false || iv == NULL || tag == NULL || tag_size == 0 || dest == NULL || src == NULL || src_size == 0)
{
return 0;
}
if (EVP_CipherInit_ex(c->Ctx, NULL, NULL, NULL, iv, c->Encrypt) == false)
{
Debug("CipherProcessAead(): EVP_CipherInit_ex() failed with error: %s\n", OpenSSL_Error());
return 0;
}
if (c->Encrypt == false)
{
if (EVP_CIPHER_CTX_ctrl(c->Ctx, EVP_CTRL_AEAD_SET_TAG, tag_size, tag) == false)
{
Debug("CipherProcessAead(): EVP_CIPHER_CTX_ctrl() failed to set the tag!\n");
return 0;
}
}
if (aad != NULL && aad_size != 0)
{
if (EVP_CipherUpdate(c->Ctx, NULL, &r, aad, aad_size) == false)
{
Debug("CipherProcessAead(): EVP_CipherUpdate() failed with error: %s\n", OpenSSL_Error());
return 0;
}
}
if (EVP_CipherUpdate(c->Ctx, dest, &r, src, src_size) == false)
{
Debug("CipherProcessAead(): EVP_CipherUpdate() failed with error: %s\n", OpenSSL_Error());
return 0;
}
if (EVP_CipherFinal_ex(c->Ctx, ((UCHAR *)dest) + (UINT)r, &r2) == false)
{
Debug("CipherProcessAead(): EVP_CipherFinal_ex() failed with error: %s\n", OpenSSL_Error());
return 0;
}
if (c->Encrypt)
{
if (EVP_CIPHER_CTX_ctrl(c->Ctx, EVP_CTRL_AEAD_GET_TAG, tag_size, tag) == false)
{
Debug("CipherProcessAead(): EVP_CIPHER_CTX_ctrl() failed to get the tag!\n");
return 0;
}
}
return r + r2;
}
// Release of the cipher object
void FreeCipher(CIPHER *c)
{