mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-28 14:02:51 +00:00
LibWeb: Stub out AES-GCM.decrypt
This commit is contained in:
parent
2672acf9c4
commit
196d99352a
Notes:
github-actions[bot]
2024-10-31 22:34:55 +00:00
Author: https://github.com/stelar7
Commit: 196d99352a
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2085
3 changed files with 68 additions and 0 deletions
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue