mirror of
https://github.com/pocoproject/poco.git
synced 2025-11-11 00:44:48 +01:00
GH #2129: Add support for AES-GCM ciphers
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include "Poco/Crypto/CipherImpl.h"
|
||||
#include "Poco/Crypto/CryptoTransform.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Buffer.h"
|
||||
#include <openssl/err.h>
|
||||
|
||||
|
||||
@@ -60,8 +61,9 @@ namespace
|
||||
~CryptoTransformImpl();
|
||||
|
||||
std::size_t blockSize() const;
|
||||
|
||||
int setPadding(int padding);
|
||||
std::string getTag(std::size_t tagSize) const;
|
||||
void setTag(const std::string& tag);
|
||||
|
||||
std::streamsize transform(
|
||||
const unsigned char* input,
|
||||
@@ -110,6 +112,18 @@ namespace
|
||||
_iv.empty() ? 0 : &_iv[0],
|
||||
(dir == DIR_ENCRYPT) ? 1 : 0);
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
if (_iv.size() != EVP_CIPHER_iv_length(_pCipher) && EVP_CIPHER_mode(_pCipher) == EVP_CIPH_GCM_MODE)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
int rc = EVP_CIPHER_CTX_ctrl(_pContext, EVP_CTRL_GCM_SET_IVLEN, _iv.size(), NULL);
|
||||
#else
|
||||
int rc = EVP_CIPHER_CTX_ctrl(&_context, EVP_CTRL_GCM_SET_IVLEN, _iv.size(), NULL);
|
||||
#endif
|
||||
if (rc == 0) throwError();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -144,6 +158,36 @@ namespace
|
||||
}
|
||||
|
||||
|
||||
std::string CryptoTransformImpl::getTag(std::size_t tagSize) const
|
||||
{
|
||||
std::string tag;
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
Poco::Buffer<char> buffer(tagSize);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
int rc = EVP_CIPHER_CTX_ctrl(_pContext, EVP_CTRL_GCM_GET_TAG, tagSize, buffer.begin());
|
||||
#else
|
||||
int rc = EVP_CIPHER_CTX_ctrl(&_context, EVP_CTRL_GCM_GET_TAG, tagSize, buffer.begin());
|
||||
#endif
|
||||
if (rc == 0) throwError();
|
||||
tag.assign(buffer.begin(), tagSize);
|
||||
#endif
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
void CryptoTransformImpl::setTag(const std::string& tag)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
int rc = EVP_CIPHER_CTX_ctrl(_pContext, EVP_CTRL_GCM_SET_TAG, tag.size(), const_cast<char*>(tag.data()));
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
int rc = EVP_CIPHER_CTX_ctrl(&_context, EVP_CTRL_GCM_SET_TAG, tag.size(), const_cast<char*>(tag.data()));
|
||||
#else
|
||||
int rc = 0;
|
||||
#endif
|
||||
if (rc == 0) throwError();
|
||||
}
|
||||
|
||||
|
||||
std::streamsize CryptoTransformImpl::transform(
|
||||
const unsigned char* input,
|
||||
std::streamsize inputLength,
|
||||
|
||||
@@ -63,7 +63,7 @@ CipherKeyImpl::CipherKeyImpl(const std::string& name,
|
||||
_key(key),
|
||||
_iv(iv)
|
||||
{
|
||||
// dummy access to Cipherfactory so that the EVP lib is initilaized
|
||||
// dummy access to Cipherfactory so that the EVP lib is initialized
|
||||
CipherFactory::defaultFactory();
|
||||
_pCipher = EVP_get_cipherbyname(name.c_str());
|
||||
|
||||
@@ -115,6 +115,7 @@ CipherKeyImpl::Mode CipherKeyImpl::mode() const
|
||||
case EVP_CIPH_OFB_MODE:
|
||||
return MODE_OFB;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
case EVP_CIPH_CTR_MODE:
|
||||
return MODE_CTR;
|
||||
|
||||
@@ -123,6 +124,7 @@ CipherKeyImpl::Mode CipherKeyImpl::mode() const
|
||||
|
||||
case EVP_CIPH_CCM_MODE:
|
||||
return MODE_CCM;
|
||||
#endif
|
||||
}
|
||||
throw Poco::IllegalStateException("Unexpected value of EVP_CIPHER_mode()");
|
||||
}
|
||||
@@ -212,4 +214,11 @@ int CipherKeyImpl::ivSize() const
|
||||
}
|
||||
|
||||
|
||||
void CipherKeyImpl::setIV(const ByteVec& iv)
|
||||
{
|
||||
poco_assert(mode() == MODE_GCM || iv.size() == static_cast<ByteVec::size_type>(ivSize()));
|
||||
_iv = iv;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Crypto
|
||||
|
||||
@@ -69,6 +69,8 @@ namespace
|
||||
|
||||
std::size_t blockSize() const;
|
||||
std::size_t maxDataSize() const;
|
||||
std::string getTag(std::size_t) const;
|
||||
void setTag(const std::string&);
|
||||
|
||||
std::streamsize transform(
|
||||
const unsigned char* input,
|
||||
@@ -127,6 +129,17 @@ namespace
|
||||
}
|
||||
|
||||
|
||||
std::string RSAEncryptImpl::getTag(std::size_t) const
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
void RSAEncryptImpl::setTag(const std::string&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::streamsize RSAEncryptImpl::transform(
|
||||
const unsigned char* input,
|
||||
std::streamsize inputLength,
|
||||
@@ -192,6 +205,8 @@ namespace
|
||||
~RSADecryptImpl();
|
||||
|
||||
std::size_t blockSize() const;
|
||||
std::string getTag(std::size_t) const;
|
||||
void setTag(const std::string&);
|
||||
|
||||
std::streamsize transform(
|
||||
const unsigned char* input,
|
||||
@@ -233,6 +248,17 @@ namespace
|
||||
}
|
||||
|
||||
|
||||
std::string RSADecryptImpl::getTag(std::size_t) const
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
void RSADecryptImpl::setTag(const std::string&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::streamsize RSADecryptImpl::transform(
|
||||
const unsigned char* input,
|
||||
std::streamsize inputLength,
|
||||
|
||||
Reference in New Issue
Block a user