| 76 | } |
| 77 | |
| 78 | std::optional<std::vector<uint8_t>> AesEncryptor::decryptWithAd(const uint8_t* cipherText, |
| 79 | size_t len, |
| 80 | const uint8_t* additionalData, |
| 81 | size_t adLen) { |
| 82 | SC_ASSERT_NOTNULL(cipherText); |
| 83 | EVP_AEAD_CTX ctx; |
| 84 | if (EVP_AEAD_CTX_init(&ctx, _cipher, _key.data(), _key.size(), EVP_AEAD_max_tag_len(_cipher), nullptr) == 0) { |
| 85 | SCLOGE(kTag, "Failed to initialize decryption key"); |
| 86 | logCryptoErrors(); |
| 87 | SC_ASSERT(false, "Bad key"); |
| 88 | return std::nullopt; |
| 89 | } |
| 90 | const auto maxOverheadLen = EVP_AEAD_max_overhead(_cipher); |
| 91 | if (len < maxOverheadLen) { |
| 92 | SCLOGW(kTag, "Invalid cipherText length {}. Min expected: {}", len, maxOverheadLen); |
| 93 | return std::nullopt; |
| 94 | } |
| 95 | std::vector<uint8_t> plainText(len - maxOverheadLen, 0); |
| 96 | size_t outLen; |
| 97 | if (EVP_AEAD_CTX_open(&ctx, |
| 98 | plainText.data(), |
| 99 | &outLen, |
| 100 | plainText.capacity(), |
| 101 | _iv.data(), |
| 102 | _iv.size(), |
| 103 | cipherText, |
| 104 | len, |
| 105 | additionalData, |
| 106 | adLen) == 0) { |
| 107 | SCLOGE(kTag, "Failed decryption"); |
| 108 | logCryptoErrors(); |
| 109 | return {}; |
| 110 | } |
| 111 | SC_ASSERT(outLen == plainText.size()); |
| 112 | EVP_AEAD_CTX_cleanup(&ctx); |
| 113 | return {plainText}; |
| 114 | } |
| 115 | |
| 116 | std::optional<std::vector<uint8_t>> AesEncryptor::encrypt(const std::vector<uint8_t>& plainText) { |
| 117 | return encrypt(plainText.data(), plainText.size()); |
nothing calls this directly
no test coverage detected