mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-07 00:29:15 +00:00
LibWeb: Implement AES-CTR.encrypt
This commit is contained in:
parent
55ef1c758a
commit
74403d7f1e
Notes:
github-actions[bot]
2024-10-31 07:15:58 +00:00
Author: https://github.com/stelar7
Commit: 74403d7f1e
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2070
3 changed files with 69 additions and 0 deletions
|
@ -267,6 +267,26 @@ JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> AesCbcParams::from_value(J
|
||||||
return adopt_own<AlgorithmParams>(*new AesCbcParams { name, iv });
|
return adopt_own<AlgorithmParams>(*new AesCbcParams { name, iv });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AesCtrParams::~AesCtrParams() = default;
|
||||||
|
|
||||||
|
JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> AesCtrParams::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("counter"));
|
||||||
|
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 length_value = TRY(object.get("length"));
|
||||||
|
auto length = TRY(length_value.to_u8(vm));
|
||||||
|
|
||||||
|
return adopt_own<AlgorithmParams>(*new AesCtrParams { name, iv, length });
|
||||||
|
}
|
||||||
|
|
||||||
HKDFParams::~HKDFParams() = default;
|
HKDFParams::~HKDFParams() = default;
|
||||||
|
|
||||||
JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> HKDFParams::from_value(JS::VM& vm, JS::Value value)
|
JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> HKDFParams::from_value(JS::VM& vm, JS::Value value)
|
||||||
|
@ -1645,6 +1665,37 @@ WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<Crypto
|
||||||
return { key };
|
return { key };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> AesCtr::encrypt(AlgorithmParams const& params, JS::NonnullGCPtr<CryptoKey> key, ByteBuffer const& plaintext)
|
||||||
|
{
|
||||||
|
// 1. If the counter member of normalizedAlgorithm does not have length 16 bytes, then throw an OperationError.
|
||||||
|
auto const& normalized_algorithm = static_cast<AesCtrParams const&>(params);
|
||||||
|
auto const& counter = normalized_algorithm.counter;
|
||||||
|
if (counter.size() != 16)
|
||||||
|
return WebIDL::OperationError::create(m_realm, "Invalid counter length"_string);
|
||||||
|
|
||||||
|
// 2. If the length member of normalizedAlgorithm is zero or is greater than 128, then throw an OperationError.
|
||||||
|
auto const& length = normalized_algorithm.length;
|
||||||
|
if (length == 0 || length > 128)
|
||||||
|
return WebIDL::OperationError::create(m_realm, "Invalid length"_string);
|
||||||
|
|
||||||
|
// 3. Let ciphertext be the result of performing the CTR Encryption operation described in Section 6.5 of [NIST-SP800-38A] using
|
||||||
|
// AES as the block cipher,
|
||||||
|
// the contents of the counter member of normalizedAlgorithm as the initial value of the counter block,
|
||||||
|
// the length member of normalizedAlgorithm as the input parameter m to the standard counter block incrementing function defined in Appendix B.1 of [NIST-SP800-38A]
|
||||||
|
// 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::CTRMode cipher(key_bytes, key_length, ::Crypto::Cipher::Intent::Encryption);
|
||||||
|
ByteBuffer ciphertext = TRY_OR_THROW_OOM(m_realm->vm(), ByteBuffer::create_zeroed(plaintext.size()));
|
||||||
|
Bytes ciphertext_span = ciphertext.bytes();
|
||||||
|
cipher.encrypt(plaintext, ciphertext_span, counter);
|
||||||
|
|
||||||
|
// 4. Return the result of creating an ArrayBuffer containing plaintext.
|
||||||
|
return JS::ArrayBuffer::create(m_realm, ciphertext);
|
||||||
|
}
|
||||||
|
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,6 +66,22 @@ struct AesCbcParams : public AlgorithmParams {
|
||||||
static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
|
static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://w3c.github.io/webcrypto/#dfn-AesCtrParams
|
||||||
|
struct AesCtrParams : public AlgorithmParams {
|
||||||
|
virtual ~AesCtrParams() override;
|
||||||
|
AesCtrParams(String name, ByteBuffer counter, u8 length)
|
||||||
|
: AlgorithmParams(move(name))
|
||||||
|
, counter(move(counter))
|
||||||
|
, length(length)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer counter;
|
||||||
|
u8 length;
|
||||||
|
|
||||||
|
static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
|
||||||
|
};
|
||||||
|
|
||||||
// https://w3c.github.io/webcrypto/#hkdf-params
|
// https://w3c.github.io/webcrypto/#hkdf-params
|
||||||
struct HKDFParams : public AlgorithmParams {
|
struct HKDFParams : public AlgorithmParams {
|
||||||
virtual ~HKDFParams() override;
|
virtual ~HKDFParams() override;
|
||||||
|
@ -333,6 +349,7 @@ public:
|
||||||
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::Value> get_key_length(AlgorithmParams const&) override;
|
virtual WebIDL::ExceptionOr<JS::Value> get_key_length(AlgorithmParams const&) override;
|
||||||
virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
|
virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) 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 AesCtr(realm)); }
|
static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new AesCtr(realm)); }
|
||||||
|
|
||||||
|
|
|
@ -777,6 +777,7 @@ SupportedAlgorithmsMap supported_algorithms()
|
||||||
define_an_algorithm<AesCbc, AesDerivedKeyParams>("get key length"_string, "AES-CBC"_string);
|
define_an_algorithm<AesCbc, AesDerivedKeyParams>("get key length"_string, "AES-CBC"_string);
|
||||||
|
|
||||||
// https://w3c.github.io/webcrypto/#aes-ctr-registration
|
// https://w3c.github.io/webcrypto/#aes-ctr-registration
|
||||||
|
define_an_algorithm<AesCtr, AesCtrParams>("encrypt"_string, "AES-CTR"_string);
|
||||||
define_an_algorithm<AesCtr>("importKey"_string, "AES-CTR"_string);
|
define_an_algorithm<AesCtr>("importKey"_string, "AES-CTR"_string);
|
||||||
define_an_algorithm<AesCtr>("exportKey"_string, "AES-CTR"_string);
|
define_an_algorithm<AesCtr>("exportKey"_string, "AES-CTR"_string);
|
||||||
define_an_algorithm<AesCtr, AesDerivedKeyParams>("get key length"_string, "AES-CTR"_string);
|
define_an_algorithm<AesCtr, AesDerivedKeyParams>("get key length"_string, "AES-CTR"_string);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue