mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-22 18:31:13 +00:00
LibWeb/Crypto: Fix sizes being passed into generate_aes_key()
Previously, callers were passing the size in bytes, but the method expected bits. This caused a crash in LibCrypto when verifying the key size later on. Also make the naming of local variables and parameters a little more clear between the different AES algorithms :^)
This commit is contained in:
parent
64747c0397
commit
0db171c36e
Notes:
github-actions[bot]
2024-11-03 20:56:39 +00:00
Author: https://github.com/rmg-x
Commit: 0db171c36e
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2143
Reviewed-by: https://github.com/gmta ✅
3 changed files with 39 additions and 14 deletions
|
@ -0,0 +1,3 @@
|
||||||
|
exported 128 bit key length: 16
|
||||||
|
exported 192 bit key length: 24
|
||||||
|
exported 256 bit key length: 32
|
22
Tests/LibWeb/Text/input/Crypto/SubtleCrypto-aesgcm.html
Normal file
22
Tests/LibWeb/Text/input/Crypto/SubtleCrypto-aesgcm.html
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
<script>
|
||||||
|
asyncTest(async (done) => {
|
||||||
|
const algorithm = "AES-GCM";
|
||||||
|
|
||||||
|
// Generate keys and export them, verify length
|
||||||
|
const aesGcm128bitKey = await crypto.subtle.generateKey({ name: algorithm, length: 128 }, true, ["encrypt"]);
|
||||||
|
const aesGcm192bitKey = await crypto.subtle.generateKey({ name: algorithm, length: 192 }, true, ["encrypt"]);
|
||||||
|
const aesGcm256bitKey = await crypto.subtle.generateKey({ name: algorithm, length: 256 }, true, ["encrypt"]);
|
||||||
|
|
||||||
|
const exported128bitKey = await crypto.subtle.exportKey("raw", aesGcm128bitKey);
|
||||||
|
const exported192bitKey = await crypto.subtle.exportKey("raw", aesGcm192bitKey);
|
||||||
|
const exported256bitKey = await crypto.subtle.exportKey("raw", aesGcm256bitKey);
|
||||||
|
|
||||||
|
println("exported 128 bit key length: " + exported128bitKey.byteLength);
|
||||||
|
println("exported 192 bit key length: " + exported192bitKey.byteLength);
|
||||||
|
println("exported 256 bit key length: " + exported256bitKey.byteLength);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -240,9 +240,9 @@ static WebIDL::ExceptionOr<ByteBuffer> parse_jwk_symmetric_key(JS::Realm& realm,
|
||||||
return base64_url_bytes_decode(realm, *jwk.k);
|
return base64_url_bytes_decode(realm, *jwk.k);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WebIDL::ExceptionOr<ByteBuffer> generate_aes_key(JS::VM& vm, u16 bits)
|
static WebIDL::ExceptionOr<ByteBuffer> generate_aes_key(JS::VM& vm, u16 const size_in_bits)
|
||||||
{
|
{
|
||||||
auto key_buffer = TRY_OR_THROW_OOM(vm, ByteBuffer::create_uninitialized(bits / 8));
|
auto key_buffer = TRY_OR_THROW_OOM(vm, ByteBuffer::create_uninitialized(size_in_bits / 8));
|
||||||
fill_with_random(key_buffer);
|
fill_with_random(key_buffer);
|
||||||
return key_buffer;
|
return key_buffer;
|
||||||
}
|
}
|
||||||
|
@ -1358,13 +1358,13 @@ WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<Crypto
|
||||||
auto const& normalized_algorithm = static_cast<AesKeyGenParams const&>(params);
|
auto const& normalized_algorithm = static_cast<AesKeyGenParams const&>(params);
|
||||||
|
|
||||||
// 2. If the length member of normalizedAlgorithm is not equal to one of 128, 192 or 256, then throw an OperationError.
|
// 2. If the length member of normalizedAlgorithm is not equal to one of 128, 192 or 256, then throw an OperationError.
|
||||||
auto bits = normalized_algorithm.length;
|
auto const bits = normalized_algorithm.length;
|
||||||
if (bits != 128 && bits != 192 && bits != 256) {
|
if (bits != 128 && bits != 192 && bits != 256) {
|
||||||
return WebIDL::OperationError::create(m_realm, MUST(String::formatted("Cannot create AES-CBC key with unusual amount of {} bits", bits)));
|
return WebIDL::OperationError::create(m_realm, MUST(String::formatted("Cannot create AES-CBC key with unusual amount of {} bits", bits)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Generate an AES key of length equal to the length member of normalizedAlgorithm.
|
// 3. Generate an AES key of length equal to the length member of normalizedAlgorithm.
|
||||||
auto key_buffer = TRY(generate_aes_key(m_realm->vm(), bits / 8));
|
auto key_buffer = TRY(generate_aes_key(m_realm->vm(), bits));
|
||||||
|
|
||||||
// 4. If the key generation step fails, then throw an OperationError.
|
// 4. If the key generation step fails, then throw an OperationError.
|
||||||
// Note: Cannot happen in our implementation; and if we OOM, then allocating the Exception is probably going to crash anyway.
|
// Note: Cannot happen in our implementation; and if we OOM, then allocating the Exception is probably going to crash anyway.
|
||||||
|
@ -1689,14 +1689,14 @@ WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<Crypto
|
||||||
|
|
||||||
// 2. If the length member of normalizedAlgorithm is not equal to one of 128, 192 or 256, then throw an OperationError.
|
// 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<AesKeyGenParams const&>(params);
|
auto const& normalized_algorithm = static_cast<AesKeyGenParams const&>(params);
|
||||||
auto length = normalized_algorithm.length;
|
auto const bits = normalized_algorithm.length;
|
||||||
if (length != 128 && length != 192 && length != 256) {
|
if (bits != 128 && bits != 192 && bits != 256) {
|
||||||
return WebIDL::OperationError::create(m_realm, MUST(String::formatted("Cannot create AES-CTR key with unusual amount of {} bits", length)));
|
return WebIDL::OperationError::create(m_realm, MUST(String::formatted("Cannot create AES-CTR key with unusual amount of {} bits", bits)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Generate an AES key of length equal to the length member of normalizedAlgorithm.
|
// 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.
|
// 4. If the key generation step fails, then throw an OperationError.
|
||||||
auto key_buffer = TRY(generate_aes_key(m_realm->vm(), length / 8));
|
auto key_buffer = TRY(generate_aes_key(m_realm->vm(), bits));
|
||||||
|
|
||||||
// 5. Let key be a new CryptoKey object representing the generated AES key.
|
// 5. Let key be a new CryptoKey object representing the generated AES key.
|
||||||
auto key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { key_buffer });
|
auto key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { key_buffer });
|
||||||
|
@ -1708,7 +1708,7 @@ WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<Crypto
|
||||||
algorithm->set_name("AES-CTR"_string);
|
algorithm->set_name("AES-CTR"_string);
|
||||||
|
|
||||||
// 8. Set the length attribute of algorithm to equal the length member of normalizedAlgorithm.
|
// 8. Set the length attribute of algorithm to equal the length member of normalizedAlgorithm.
|
||||||
algorithm->set_length(length);
|
algorithm->set_length(bits);
|
||||||
|
|
||||||
// 9. Set the [[type]] internal slot of key to "secret".
|
// 9. Set the [[type]] internal slot of key to "secret".
|
||||||
key->set_type(Bindings::KeyType::Secret);
|
key->set_type(Bindings::KeyType::Secret);
|
||||||
|
@ -2118,14 +2118,14 @@ WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<Crypto
|
||||||
|
|
||||||
// 2. If the length member of normalizedAlgorithm is not equal to one of 128, 192 or 256, then throw an OperationError.
|
// 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<AesKeyGenParams const&>(params);
|
auto const& normalized_algorithm = static_cast<AesKeyGenParams const&>(params);
|
||||||
auto length = normalized_algorithm.length;
|
auto const bits = normalized_algorithm.length;
|
||||||
if (length != 128 && length != 192 && length != 256) {
|
if (bits != 128 && bits != 192 && bits != 256) {
|
||||||
return WebIDL::OperationError::create(m_realm, MUST(String::formatted("Cannot create AES-CTR key with unusual amount of {} bits", length)));
|
return WebIDL::OperationError::create(m_realm, MUST(String::formatted("Cannot create AES-GCM key with unusual amount of {} bits", bits)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Generate an AES key of length equal to the length member of normalizedAlgorithm.
|
// 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.
|
// 4. If the key generation step fails, then throw an OperationError.
|
||||||
auto key_buffer = TRY(generate_aes_key(m_realm->vm(), length / 8));
|
auto key_buffer = TRY(generate_aes_key(m_realm->vm(), bits));
|
||||||
|
|
||||||
// 5. Let key be a new CryptoKey object representing the generated AES key.
|
// 5. Let key be a new CryptoKey object representing the generated AES key.
|
||||||
auto key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { key_buffer });
|
auto key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { key_buffer });
|
||||||
|
@ -2137,7 +2137,7 @@ WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<Crypto
|
||||||
algorithm->set_name("AES-GCM"_string);
|
algorithm->set_name("AES-GCM"_string);
|
||||||
|
|
||||||
// 8. Set the length attribute of algorithm to equal the length member of normalizedAlgorithm.
|
// 8. Set the length attribute of algorithm to equal the length member of normalizedAlgorithm.
|
||||||
algorithm->set_length(length);
|
algorithm->set_length(bits);
|
||||||
|
|
||||||
// 9. Set the [[type]] internal slot of key to "secret".
|
// 9. Set the [[type]] internal slot of key to "secret".
|
||||||
key->set_type(Bindings::KeyType::Secret);
|
key->set_type(Bindings::KeyType::Secret);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue