mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-30 12:49:19 +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);
|
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
|
// 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)
|
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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -386,6 +386,7 @@ public:
|
||||||
virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override;
|
virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override;
|
||||||
virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Object>> export_key(Bindings::KeyFormat, JS::NonnullGCPtr<CryptoKey>) override;
|
virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Object>> export_key(Bindings::KeyFormat, JS::NonnullGCPtr<CryptoKey>) override;
|
||||||
virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> encrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
|
virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> encrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
|
||||||
|
virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> decrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
|
||||||
|
|
||||||
static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new AesGcm(realm)); }
|
static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new AesGcm(realm)); }
|
||||||
|
|
||||||
|
|
|
@ -789,6 +789,7 @@ SupportedAlgorithmsMap supported_algorithms()
|
||||||
define_an_algorithm<AesGcm>("importKey"_string, "AES-GCM"_string);
|
define_an_algorithm<AesGcm>("importKey"_string, "AES-GCM"_string);
|
||||||
define_an_algorithm<AesGcm>("exportKey"_string, "AES-GCM"_string);
|
define_an_algorithm<AesGcm>("exportKey"_string, "AES-GCM"_string);
|
||||||
define_an_algorithm<AesGcm, AesGcmParams>("encrypt"_string, "AES-GCM"_string);
|
define_an_algorithm<AesGcm, AesGcmParams>("encrypt"_string, "AES-GCM"_string);
|
||||||
|
define_an_algorithm<AesGcm, AesGcmParams>("decrypt"_string, "AES-GCM"_string);
|
||||||
|
|
||||||
// https://w3c.github.io/webcrypto/#hkdf
|
// https://w3c.github.io/webcrypto/#hkdf
|
||||||
define_an_algorithm<HKDF>("importKey"_string, "HKDF"_string);
|
define_an_algorithm<HKDF>("importKey"_string, "HKDF"_string);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue