LibWeb: Stub out AES-GCM.decrypt

This commit is contained in:
stelar7 2024-10-31 16:37:51 +01:00 committed by Andreas Kling
parent 2672acf9c4
commit 196d99352a
Notes: github-actions[bot] 2024-10-31 22:34:55 +00:00
3 changed files with 68 additions and 0 deletions

View file

@ -2041,6 +2041,72 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> AesGcm::encrypt(Algorithm
return JS::ArrayBuffer::create(m_realm, ciphertext);
}
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> AesGcm::decrypt(AlgorithmParams const& params, JS::NonnullGCPtr<CryptoKey> key, ByteBuffer const& ciphertext)
{
auto const& normalized_algorithm = static_cast<AesGcmParams const&>(params);
// 1. If the tagLength member of normalizedAlgorithm is not present: Let tagLength be 128.
u32 tag_length = 0;
auto to_compare_against = Vector<u32> { 32, 64, 96, 104, 112, 120, 128 };
if (!normalized_algorithm.tag_length.has_value())
tag_length = 128;
// If the tagLength member of normalizedAlgorithm is one of 32, 64, 96, 104, 112, 120 or 128: Let tagLength be equal to the tagLength member of normalizedAlgorithm
else if (to_compare_against.contains_slow(normalized_algorithm.tag_length.value()))
tag_length = normalized_algorithm.tag_length.value();
// Otherwise: throw an OperationError.
else
return WebIDL::OperationError::create(m_realm, "Invalid tag length"_string);
// 2. If ciphertext has a length less than tagLength bits, then throw an OperationError.
if (ciphertext.size() < tag_length / 8)
return WebIDL::OperationError::create(m_realm, "Invalid ciphertext length"_string);
// FIXME: 3. If the iv member of normalizedAlgorithm has a length greater than 2^64 - 1 bytes, then throw an OperationError.
// FIXME: 4. If the additionalData member of normalizedAlgorithm is present and has a length greater than 2^64 - 1 bytes, then throw an OperationError.
// 5. Let tag be the last tagLength bits of ciphertext.
auto tag_bits = tag_length / 8;
auto tag = TRY_OR_THROW_OOM(m_realm->vm(), ciphertext.slice(ciphertext.size() - tag_bits, tag_bits));
// 6. Let actualCiphertext be the result of removing the last tagLength bits from ciphertext.
auto actual_ciphertext = TRY_OR_THROW_OOM(m_realm->vm(), ciphertext.slice(0, ciphertext.size() - tag_bits));
// 7. Let additionalData be the contents of the additionalData member of normalizedAlgorithm if present or the empty octet string otherwise.
auto additional_data = normalized_algorithm.additional_data.value_or(ByteBuffer {});
// 8. Perform the Authenticated Decryption Function described in Section 7.2 of [NIST-SP800-38D] using
// AES as the block cipher,
// the contents of the iv member of normalizedAlgorithm as the IV input parameter,
// the contents of additionalData as the A input parameter,
// tagLength as the t pre-requisite,
// the contents of actualCiphertext as the input ciphertext, C
// and the contents of tag as the authentication tag, T.
auto& aes_algorithm = static_cast<AesKeyAlgorithm const&>(*key->algorithm());
auto key_length = aes_algorithm.length();
auto key_bytes = key->handle().get<ByteBuffer>();
::Crypto::Cipher::AESCipher::GCMMode cipher(key_bytes, key_length, ::Crypto::Cipher::Intent::Decryption);
ByteBuffer plaintext = TRY_OR_THROW_OOM(m_realm->vm(), ByteBuffer::create_zeroed(actual_ciphertext.size()));
[[maybe_unused]] Bytes plaintext_span = plaintext.bytes();
[[maybe_unused]] Bytes actual_ciphertext_span = actual_ciphertext.bytes();
[[maybe_unused]] Bytes tag_span = tag.bytes();
// FIXME: auto result = cipher.decrypt(ciphertext, plaintext_span, normalized_algorithm.iv, additional_data, tag_span);
auto result = ::Crypto::VerificationConsistency::Inconsistent;
// If the result of the algorithm is the indication of inauthenticity, "FAIL": throw an OperationError
if (result == ::Crypto::VerificationConsistency::Inconsistent)
return WebIDL::OperationError::create(m_realm, "Decryption failed"_string);
// Otherwise: Let plaintext be the output P of the Authenticated Decryption Function.
// 9. Return the result of creating an ArrayBuffer containing plaintext.
return JS::ArrayBuffer::create(m_realm, plaintext);
}
// https://w3c.github.io/webcrypto/#hkdf-operations
WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> HKDF::import_key(AlgorithmParams const&, Bindings::KeyFormat format, CryptoKey::InternalKeyData key_data, bool extractable, Vector<Bindings::KeyUsage> const& key_usages)
{