diff --git a/Userland/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp b/Userland/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp index 8053cf07768..c94d601b171 100644 --- a/Userland/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp +++ b/Userland/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp @@ -1597,6 +1597,54 @@ WebIDL::ExceptionOr AesCtr::get_key_length(AlgorithmParams const& par return JS::Value(length); } +WebIDL::ExceptionOr, JS::NonnullGCPtr>> AesCtr::generate_key(AlgorithmParams const& params, bool extractable, Vector const& key_usages) +{ + // 1. If usages contains any entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError. + for (auto const& usage : key_usages) { + if (usage != Bindings::KeyUsage::Encrypt && usage != Bindings::KeyUsage::Decrypt && usage != Bindings::KeyUsage::Wrapkey && usage != Bindings::KeyUsage::Unwrapkey) { + return WebIDL::SyntaxError::create(m_realm, MUST(String::formatted("Invalid key usage '{}'", idl_enum_to_string(usage)))); + } + } + + // 2. If the length member of normalizedAlgorithm is not equal to one of 128, 192 or 256, then throw an OperationError. + auto const& normalized_algorithm = static_cast(params); + auto length = normalized_algorithm.length; + if (length != 128 && length != 192 && length != 256) { + return WebIDL::OperationError::create(m_realm, MUST(String::formatted("Cannot create AES-CTR key with unusual amount of {} bits", length))); + } + + // 3. Generate an AES key of length equal to the length member of normalizedAlgorithm. + // 4. If the key generation step fails, then throw an OperationError. + auto key_buffer = TRY(generate_aes_key(m_realm->vm(), length / 8)); + + // 5. Let key be a new CryptoKey object representing the generated AES key. + auto key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { key_buffer }); + + // 6. Let algorithm be a new AesKeyAlgorithm. + auto algorithm = AesKeyAlgorithm::create(m_realm); + + // 7. Set the name attribute of algorithm to "AES-CTR". + algorithm->set_name("AES-CTR"_string); + + // 8. Set the length attribute of algorithm to equal the length member of normalizedAlgorithm. + algorithm->set_length(length); + + // 9. Set the [[type]] internal slot of key to "secret". + key->set_type(Bindings::KeyType::Secret); + + // 10. Set the [[algorithm]] internal slot of key to algorithm. + key->set_algorithm(algorithm); + + // 11. Set the [[extractable]] internal slot of key to be extractable. + key->set_extractable(extractable); + + // 12. Set the [[usages]] internal slot of key to be usages. + key->set_usages(key_usages); + + // 13. Return key. + return { key }; +} + // https://w3c.github.io/webcrypto/#hkdf-operations WebIDL::ExceptionOr> HKDF::import_key(AlgorithmParams const&, Bindings::KeyFormat format, CryptoKey::InternalKeyData key_data, bool extractable, Vector const& key_usages) { diff --git a/Userland/Libraries/LibWeb/Crypto/CryptoAlgorithms.h b/Userland/Libraries/LibWeb/Crypto/CryptoAlgorithms.h index 4d25ad44a39..70a1e6fb6ac 100644 --- a/Userland/Libraries/LibWeb/Crypto/CryptoAlgorithms.h +++ b/Userland/Libraries/LibWeb/Crypto/CryptoAlgorithms.h @@ -332,6 +332,7 @@ public: virtual WebIDL::ExceptionOr> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector const&) override; virtual WebIDL::ExceptionOr> export_key(Bindings::KeyFormat, JS::NonnullGCPtr) override; virtual WebIDL::ExceptionOr get_key_length(AlgorithmParams const&) override; + virtual WebIDL::ExceptionOr, JS::NonnullGCPtr>> generate_key(AlgorithmParams const&, bool, Vector const&) override; static NonnullOwnPtr create(JS::Realm& realm) { return adopt_own(*new AesCtr(realm)); } diff --git a/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp b/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp index 3f62fbe70ef..5d7aac3be65 100644 --- a/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp +++ b/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp @@ -780,6 +780,7 @@ SupportedAlgorithmsMap supported_algorithms() define_an_algorithm("importKey"_string, "AES-CTR"_string); define_an_algorithm("exportKey"_string, "AES-CTR"_string); define_an_algorithm("get key length"_string, "AES-CTR"_string); + define_an_algorithm("generateKey"_string, "AES-CTR"_string); // https://w3c.github.io/webcrypto/#hkdf define_an_algorithm("importKey"_string, "HKDF"_string);