mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-15 23:09:05 +00:00
LibWeb: Implement WebCrypto AES-CBC decrypt operation
This lets us pass an additional (roughly) 15 WPT tests: WebCryptoAPI/encrypt_decrypt/aes_cbc.https.any
This commit is contained in:
parent
eb193251b8
commit
b1056121f2
Notes:
github-actions[bot]
2024-10-26 15:51:20 +00:00
Author: https://github.com/BenWiederhake
Commit: b1056121f2
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1971
2 changed files with 37 additions and 3 deletions
|
@ -1063,9 +1063,43 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> AesCbc::encrypt(Algorithm
|
|||
return JS::ArrayBuffer::create(m_realm, move(ciphertext));
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> AesCbc::decrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&)
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> AesCbc::decrypt(AlgorithmParams const& params, JS::NonnullGCPtr<CryptoKey> key, ByteBuffer const& ciphertext)
|
||||
{
|
||||
VERIFY_NOT_REACHED();
|
||||
auto const& normalized_algorithm = static_cast<AesCbcParams const&>(params);
|
||||
|
||||
// 1. If the iv member of normalizedAlgorithm does not have length 16 bytes, then throw an OperationError.
|
||||
if (normalized_algorithm.iv.size() != 16)
|
||||
return WebIDL::OperationError::create(m_realm, "IV to AES-CBC must be exactly 16 bytes"_string);
|
||||
|
||||
// Spec bug? TODO: https://github.com/w3c/webcrypto/issues/381
|
||||
// If ciphertext does not have a length that is a multiple of 16 bytes, then throw an OperationError. (Note that a zero-length ciphertext will result in an OperationError in all cases.)
|
||||
if (ciphertext.size() % 16 != 0)
|
||||
return WebIDL::OperationError::create(m_realm, "Ciphertext length must be a multiple of 16 bytes"_string);
|
||||
|
||||
// 2. Let paddedPlaintext be the result of performing the CBC Decryption operation described in Section 6.2 of [NIST-SP800-38A] using AES as the block cipher, the contents of the iv member of normalizedAlgorithm as the IV input parameter and the contents of ciphertext as the input ciphertext.
|
||||
auto mode = ::Crypto::Cipher::PaddingMode::CMS;
|
||||
auto key_bytes = key->handle().get<ByteBuffer>();
|
||||
auto key_bits = key_bytes.size() * 8;
|
||||
::Crypto::Cipher::AESCipher::CBCMode cipher(key_bytes, key_bits, ::Crypto::Cipher::Intent::Decryption, mode);
|
||||
auto iv = normalized_algorithm.iv;
|
||||
auto plaintext = TRY_OR_THROW_OOM(m_realm->vm(), cipher.create_aligned_buffer(ciphertext.size()));
|
||||
auto plaintext_view = plaintext.bytes();
|
||||
cipher.decrypt(ciphertext, plaintext_view, iv);
|
||||
plaintext.trim(plaintext_view.size(), false);
|
||||
|
||||
// 3. Let p be the value of the last octet of paddedPlaintext.
|
||||
// 4. If p is zero or greater than 16, or if any of the last p octets of paddedPlaintext have a value which is not p, then throw an OperationError.
|
||||
// 5. Let plaintext be the result of removing p octets from the end of paddedPlaintext.
|
||||
// Note that LibCrypto already does the padding removal for us.
|
||||
// In the case that any issues arise (e.g. inconsistent padding), the padding is instead not trimmed.
|
||||
// This is *ONLY* meaningful for the specific case of PaddingMode::CMS, as this is the only padding mode that always appends a block.
|
||||
if (plaintext.size() == ciphertext.size()) {
|
||||
// Padding was not removed for an unknown reason. Apply Step 4:
|
||||
return WebIDL::OperationError::create(m_realm, "Inconsistent padding"_string);
|
||||
}
|
||||
|
||||
// 6. Return the result of creating an ArrayBuffer containing plaintext.
|
||||
return JS::ArrayBuffer::create(m_realm, move(plaintext));
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> AesCbc::import_key(AlgorithmParams const&, Bindings::KeyFormat format, CryptoKey::InternalKeyData key_data, bool extractable, Vector<Bindings::KeyUsage> const& key_usages)
|
||||
|
|
|
@ -770,7 +770,7 @@ SupportedAlgorithmsMap supported_algorithms()
|
|||
|
||||
// https://w3c.github.io/webcrypto/#aes-cbc-registration
|
||||
define_an_algorithm<AesCbc, AesCbcParams>("encrypt"_string, "AES-CBC"_string);
|
||||
// FIXME: define_an_algorithm<AesCbc, AesCbcParams>("decrypt"_string, "AES-CBC"_string);
|
||||
define_an_algorithm<AesCbc, AesCbcParams>("decrypt"_string, "AES-CBC"_string);
|
||||
define_an_algorithm<AesCbc, AesKeyGenParams>("generateKey"_string, "AES-CBC"_string);
|
||||
define_an_algorithm<AesCbc>("importKey"_string, "AES-CBC"_string);
|
||||
define_an_algorithm<AesCbc>("exportKey"_string, "AES-CBC"_string);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue