const RawBuffer &tag,
const RawBuffer &aad)
{
- RawBuffer result, tmp;
-
- auto decrypt = [&](const RawBuffer &actualIv){
- EvpCipherPtr dec;
- selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, actualIv);
- void *ptr = (void *)tag.data();
+ EvpCipherPtr dec;
+ selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv);
+ void *ptr = (void *)tag.data();
- dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr);
+ dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr);
- if (!aad.empty())
- dec->AppendAAD(aad);
-
- result = dec->Append(data);
- try {
- tmp = dec->Finalize();
- } catch (const Exc::Exception &e) {
- ThrowErr(Exc::InputParam,
- "Tag authentication failed in AES finalize function (the tag doesn't match).");
- }
- };
+ if (!aad.empty())
+ dec->AppendAAD(aad);
+ RawBuffer result = dec->Append(data);
+ RawBuffer tmp;
try {
- decrypt(iv);
- } catch (const Exc::InputParam &e) {
- LogDebug("AES GCM decryption failed. Retry with default iv length.");
- RawBuffer shortIv = iv;
- shortIv.resize(Params::DEFAULT_AES_GCM_IV_LEN);
- decrypt(shortIv);
+ tmp = dec->Finalize();
+ } catch (const Exc::Exception &e) {
+ ThrowErr(Exc::InputParam, "Tag authentication failed in AES finalize function (the tag doesn't match).");
}
std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
return result;
BOOST_REQUIRE_THROW(key->decrypt(ca2, encrypted), Exc::Crypto::InputParam);
}
-POSITIVE_TEST_CASE(gcmIvLengthScrewUpWorkaround)
-{
- const auto key = generateAes(128);
- const auto data = createRandom(128);
- const auto iv = createRandom(Params::DEFAULT_AES_IV_LEN);
- CryptoAlgorithm ca;
- RawBuffer encrypted, decrypted;
- auto shortIv = iv;
- shortIv.resize(Params::DEFAULT_AES_GCM_IV_LEN);
-
- ca.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM);
- ca.setParam(ParamName::ED_IV, shortIv);
- ca.setParam(ParamName::ED_TAG_LEN, 128);
-
- // encrypt with 12B IV
- BOOST_REQUIRE_NO_THROW(encrypted = key->encrypt(ca, data));
-
- // decrypt with 12B IV
- BOOST_REQUIRE_NO_THROW(decrypted = key->decrypt(ca, encrypted));
- BOOST_REQUIRE(decrypted == data);
-
- // decrypt with 16B IV should also succeed (workaround)
- ca.setParam(ParamName::ED_IV, iv);
- BOOST_REQUIRE_NO_THROW(decrypted = key->decrypt(ca, encrypted));
- BOOST_REQUIRE(decrypted == data);
-
- // encrypt with 16B IV
- BOOST_REQUIRE_NO_THROW(encrypted = key->encrypt(ca, data));
-
- // decrypt with 16B IV
- BOOST_REQUIRE_NO_THROW(decrypted = key->decrypt(ca, encrypted));
- BOOST_REQUIRE(decrypted == data);
-
- // decrypt with 12B IV should fail
- ca.setParam(ParamName::ED_IV, shortIv);
- BOOST_REQUIRE_THROW(key->decrypt(ca, encrypted), Exc::Crypto::InputParam);
-}
-
NEGATIVE_TEST_CASE(symmetricEncryptDecryptCtr)
{
const auto key = generateAes(128);