LibWeb: Stub out AES-GCM.encrypt
This commit is contained in:
parent
3dd80d2a6e
commit
2672acf9c4
Notes:
github-actions[bot]
2024-10-31 22:35:01 +00:00
Author: https://github.com/stelar7 Commit: https://github.com/LadybirdBrowser/ladybird/commit/2672acf9c40 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2085
3 changed files with 103 additions and 0 deletions
|
@ -296,6 +296,37 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> AesCtrParams::from_value(J
|
|||
return adopt_own<AlgorithmParams>(*new AesCtrParams { name, iv, length });
|
||||
}
|
||||
|
||||
AesGcmParams::~AesGcmParams() = default;
|
||||
|
||||
JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> AesGcmParams::from_value(JS::VM& vm, JS::Value value)
|
||||
{
|
||||
auto& object = value.as_object();
|
||||
|
||||
auto name_value = TRY(object.get("name"));
|
||||
auto name = TRY(name_value.to_string(vm));
|
||||
|
||||
auto iv_value = TRY(object.get("iv"));
|
||||
if (!iv_value.is_object() || !(is<JS::TypedArrayBase>(iv_value.as_object()) || is<JS::ArrayBuffer>(iv_value.as_object()) || is<JS::DataView>(iv_value.as_object())))
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "BufferSource");
|
||||
auto iv = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(iv_value.as_object()));
|
||||
|
||||
auto maybe_additional_data = Optional<ByteBuffer> {};
|
||||
if (MUST(object.has_property("additionalData"))) {
|
||||
auto additional_data_value = TRY(object.get("additionalData"));
|
||||
if (!additional_data_value.is_object() || !(is<JS::TypedArrayBase>(additional_data_value.as_object()) || is<JS::ArrayBuffer>(additional_data_value.as_object()) || is<JS::DataView>(additional_data_value.as_object())))
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "BufferSource");
|
||||
maybe_additional_data = TRY_OR_THROW_OOM(vm, WebIDL::get_buffer_source_copy(additional_data_value.as_object()));
|
||||
}
|
||||
|
||||
auto maybe_tag_length = Optional<u8> {};
|
||||
if (MUST(object.has_property("tagLength"))) {
|
||||
auto tag_length_value = TRY(object.get("tagLength"));
|
||||
maybe_tag_length = TRY(tag_length_value.to_u8(vm));
|
||||
}
|
||||
|
||||
return adopt_own<AlgorithmParams>(*new AesGcmParams { name, iv, maybe_additional_data, maybe_tag_length });
|
||||
}
|
||||
|
||||
HKDFParams::~HKDFParams() = default;
|
||||
|
||||
JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> HKDFParams::from_value(JS::VM& vm, JS::Value value)
|
||||
|
@ -1958,6 +1989,58 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Object>> AesGcm::export_key(Bindings::K
|
|||
return JS::NonnullGCPtr { *result };
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> AesGcm::encrypt(AlgorithmParams const& params, JS::NonnullGCPtr<CryptoKey> key, ByteBuffer const& plaintext)
|
||||
{
|
||||
auto const& normalized_algorithm = static_cast<AesGcmParams const&>(params);
|
||||
|
||||
// FIXME: 1. If plaintext has a length greater than 2^39 - 256 bytes, then throw an OperationError.
|
||||
|
||||
// FIXME: 2. If the iv member of normalizedAlgorithm has a length greater than 2^64 - 1 bytes, then throw an OperationError.
|
||||
|
||||
// FIXME: 3. If the additionalData member of normalizedAlgorithm is present and has a length greater than 2^64 - 1 bytes, then throw an OperationError.
|
||||
|
||||
// 4. If the tagLength member of normalizedAlgorithm is not present: Let tagLength be 128.
|
||||
auto tag_length = 0;
|
||||
auto to_compare_against = Vector<int> { 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);
|
||||
|
||||
// 5. 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 {});
|
||||
|
||||
// 6. Let C and T be the outputs that result from performing the Authenticated Encryption Function described in Section 7.1 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
|
||||
// and the contents of plaintext as the input plaintext.
|
||||
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::Encryption);
|
||||
ByteBuffer ciphertext = TRY_OR_THROW_OOM(m_realm->vm(), ByteBuffer::create_zeroed(plaintext.size()));
|
||||
ByteBuffer tag = TRY_OR_THROW_OOM(m_realm->vm(), ByteBuffer::create_zeroed(tag_length / 8));
|
||||
[[maybe_unused]] Bytes ciphertext_span = ciphertext.bytes();
|
||||
[[maybe_unused]] Bytes tag_span = tag.bytes();
|
||||
|
||||
// FIXME: cipher.encrypt(plaintext, ciphertext_span, normalized_algorithm.iv, additional_data, tag_span);
|
||||
|
||||
// 7. Let ciphertext be equal to C | T, where '|' denotes concatenation.
|
||||
TRY_OR_THROW_OOM(m_realm->vm(), ciphertext.try_append(tag));
|
||||
|
||||
// 8. Return the result of creating an ArrayBuffer containing ciphertext.
|
||||
return JS::ArrayBuffer::create(m_realm, ciphertext);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
|
|
@ -83,6 +83,24 @@ struct AesCtrParams : public AlgorithmParams {
|
|||
static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
|
||||
};
|
||||
|
||||
// https://w3c.github.io/webcrypto/#dfn-AesGcmParams
|
||||
struct AesGcmParams : public AlgorithmParams {
|
||||
virtual ~AesGcmParams() override;
|
||||
AesGcmParams(String name, ByteBuffer iv, Optional<ByteBuffer> additional_data, Optional<u8> tag_length)
|
||||
: AlgorithmParams(move(name))
|
||||
, iv(move(iv))
|
||||
, additional_data(move(additional_data))
|
||||
, tag_length(tag_length)
|
||||
{
|
||||
}
|
||||
|
||||
ByteBuffer iv;
|
||||
Optional<ByteBuffer> additional_data;
|
||||
Optional<u8> tag_length;
|
||||
|
||||
static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
|
||||
};
|
||||
|
||||
// https://w3c.github.io/webcrypto/#hkdf-params
|
||||
struct HKDFParams : public AlgorithmParams {
|
||||
virtual ~HKDFParams() override;
|
||||
|
@ -367,6 +385,7 @@ public:
|
|||
virtual WebIDL::ExceptionOr<JS::Value> get_key_length(AlgorithmParams 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::ArrayBuffer>> encrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
|
||||
|
||||
static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new AesGcm(realm)); }
|
||||
|
||||
|
|
|
@ -788,6 +788,7 @@ SupportedAlgorithmsMap supported_algorithms()
|
|||
define_an_algorithm<AesGcm, AesDerivedKeyParams>("get key length"_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, AesGcmParams>("encrypt"_string, "AES-GCM"_string);
|
||||
|
||||
// https://w3c.github.io/webcrypto/#hkdf
|
||||
define_an_algorithm<HKDF>("importKey"_string, "HKDF"_string);
|
||||
|
|
Loading…
Add table
Reference in a new issue