return EVP_CIPHER_CTX_ctrl(m_ctx, type, arg, ptr);
}
+ virtual void AppendAAD(const T&) = 0;
virtual T Append(const T&) = 0;
virtual T Finalize() = 0;
virtual ~Base(){
EVP_CIPHER_CTX_set_padding(m_ctx, 1);
}
+ void AppendAAD(const T& data) {
+ static_assert(sizeof(typename T::value_type) == 1, "Unsupported type inside container.");
+ int bytesLen;
+ if (1 != EVP_CipherUpdate(m_ctx, NULL, &bytesLen, data.data(), data.size())) {
+ ThrowErr(Exc::Crypto::InternalError, "AppendAAD(): Failed in EVP_CipherUpdate");
+ }
+ }
+
T Append(const T& data) {
static_assert(sizeof(typename T::value_type) == 1, "Unsupported type inside container.");
int bytesLen = static_cast<int>(data.size() + EVP_CIPHER_CTX_block_size(m_ctx));
T output(bytesLen);
if (1 != EVP_CipherUpdate(m_ctx, output.data(), &bytesLen, data.data(), data.size())) {
- ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherUpdate");
+ ThrowErr(Exc::Crypto::InternalError, "Append(): Failed in EVP_CipherUpdate");
}
output.resize(bytesLen);
return output;
const RawBuffer &key,
const RawBuffer &data,
const RawBuffer &iv,
- int tagSize)
+ int tagSize,
+ const RawBuffer &aad)
{
RawBuffer tag(tagSize);
EvpCipherPtr enc;
selectCipher(AlgoType::AES_GCM, key.size())(enc, key, iv);
+
+ if (!aad.empty())
+ enc->AppendAAD(aad);
+
RawBuffer result = enc->Append(data);
RawBuffer tmp = enc->Finalize();
std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
const RawBuffer &key,
const RawBuffer &data,
const RawBuffer &iv,
- int tagSize)
+ int tagSize,
+ const RawBuffer &aad)
{
- auto pair = encryptDataAesGcm(key, data, iv, tagSize);
+ auto pair = encryptDataAesGcm(key, data, iv, tagSize, aad);
std::copy(pair.second.begin(), pair.second.end(), std::back_inserter(pair.first));
return pair.first;
}
const RawBuffer &key,
const RawBuffer &data,
const RawBuffer &iv,
- const RawBuffer &tag)
+ const RawBuffer &tag,
+ const RawBuffer &aad)
{
EvpCipherPtr dec;
selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv);
ThrowErr(Exc::Crypto::InternalError,
"Error in AES control function. Set tag failed.");
}
+ if (!aad.empty())
+ dec->AppendAAD(aad);
+
RawBuffer result = dec->Append(data);
RawBuffer tmp = dec->Finalize();
std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
const RawBuffer &key,
const RawBuffer &data,
const RawBuffer &iv,
- int tagSize)
+ int tagSize,
+ const RawBuffer &aad)
{
if (tagSize > static_cast<int>(data.size()))
ThrowErr(Exc::Crypto::InputParam, "Wrong size of tag");
key,
RawBuffer(data.data(), tagPos),
iv,
- RawBuffer(tagPos, data.data() + data.size()));
+ RawBuffer(tagPos, data.data() + data.size()),
+ aad);
}
RawBuffer symmetricEncrypt(const RawBuffer &key,
{
int tagLenBits = DEFAULT_AES_GCM_TAG_LEN;
alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
+ RawBuffer aad;
+ alg.getParam(ParamName::ED_AAD, aad);
return encryptDataAesGcmPacked(key,
data,
unpack<RawBuffer>(alg, ParamName::ED_IV),
- tagLenBits/8);
+ tagLenBits/8,
+ aad);
}
default:
break;
{
int tagLenBits = DEFAULT_AES_GCM_TAG_LEN;
alg.getParam(ParamName::ED_TAG_LEN, tagLenBits);
+ RawBuffer aad;
+ alg.getParam(ParamName::ED_AAD, aad);
return decryptDataAesGcmPacked(key,
data,
unpack<RawBuffer>(alg, ParamName::ED_IV),
- tagLenBits/8);
+ tagLenBits/8,
+ aad);
}
default:
break;