| Index: components/webcrypto/algorithms/aes_kw.cc
|
| diff --git a/components/webcrypto/algorithms/aes_kw.cc b/components/webcrypto/algorithms/aes_kw.cc
|
| index f64e1db28228abba8ce3fc06edbd85bb41d2888b..d1bf022726cbe6f68a8acd2fe104c98b63f2e087 100644
|
| --- a/components/webcrypto/algorithms/aes_kw.cc
|
| +++ b/components/webcrypto/algorithms/aes_kw.cc
|
| @@ -2,18 +2,16 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include <openssl/aead.h>
|
| +#include <openssl/aes.h>
|
| #include <stddef.h>
|
| #include <stdint.h>
|
|
|
| #include <vector>
|
|
|
| -#include "base/logging.h"
|
| +#include "base/location.h"
|
| #include "base/memory/ptr_util.h"
|
| #include "base/numerics/safe_math.h"
|
| -#include "base/stl_util.h"
|
| #include "components/webcrypto/algorithms/aes.h"
|
| -#include "components/webcrypto/algorithms/util.h"
|
| #include "components/webcrypto/blink_key_handle.h"
|
| #include "components/webcrypto/crypto_data.h"
|
| #include "components/webcrypto/status.h"
|
| @@ -23,41 +21,6 @@ namespace webcrypto {
|
|
|
| namespace {
|
|
|
| -const EVP_AEAD* GetAesKwAlgorithmFromKeySize(size_t key_size_bytes) {
|
| - switch (key_size_bytes) {
|
| - case 16:
|
| - return EVP_aead_aes_128_key_wrap();
|
| - case 32:
|
| - return EVP_aead_aes_256_key_wrap();
|
| - default:
|
| - return NULL;
|
| - }
|
| -}
|
| -
|
| -Status AesKwEncryptDecrypt(EncryptOrDecrypt mode,
|
| - const blink::WebCryptoAlgorithm& algorithm,
|
| - const blink::WebCryptoKey& key,
|
| - const CryptoData& data,
|
| - std::vector<uint8_t>* buffer) {
|
| - // These length checks are done in order to give a more specific error. These
|
| - // are not required for correctness.
|
| - if ((mode == ENCRYPT && data.byte_length() < 16) ||
|
| - (mode == DECRYPT && data.byte_length() < 24)) {
|
| - return Status::ErrorDataTooSmall();
|
| - }
|
| - if (data.byte_length() % 8)
|
| - return Status::ErrorInvalidAesKwDataLength();
|
| -
|
| - const std::vector<uint8_t>& raw_key = GetSymmetricKeyData(key);
|
| -
|
| - return AeadEncryptDecrypt(mode, raw_key, data,
|
| - 8, // tag_length_bytes
|
| - CryptoData(), // iv
|
| - CryptoData(), // additional_data
|
| - GetAesKwAlgorithmFromKeySize(raw_key.size()),
|
| - buffer);
|
| -}
|
| -
|
| class AesKwImplementation : public AesAlgorithm {
|
| public:
|
| AesKwImplementation()
|
| @@ -69,14 +32,72 @@ class AesKwImplementation : public AesAlgorithm {
|
| const blink::WebCryptoKey& key,
|
| const CryptoData& data,
|
| std::vector<uint8_t>* buffer) const override {
|
| - return AesKwEncryptDecrypt(ENCRYPT, algorithm, key, data, buffer);
|
| + crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
|
| +
|
| + // These length checks are done in order to give a more specific
|
| + // error. These are not required for correctness.
|
| + if (data.byte_length() < 16)
|
| + return Status::ErrorDataTooSmall();
|
| + if (data.byte_length() % 8)
|
| + return Status::ErrorInvalidAesKwDataLength();
|
| +
|
| + // Key import validates key sizes, so the bits computation will not
|
| + // overflow.
|
| + const std::vector<uint8_t>& raw_key = GetSymmetricKeyData(key);
|
| + AES_KEY aes_key;
|
| + if (AES_set_encrypt_key(raw_key.data(),
|
| + static_cast<unsigned>(raw_key.size() * 8),
|
| + &aes_key) < 0) {
|
| + return Status::OperationError();
|
| + }
|
| +
|
| + // Key wrap's overhead is 8 bytes.
|
| + base::CheckedNumeric<size_t> length(data.byte_length());
|
| + length += 8;
|
| + if (!length.IsValid())
|
| + return Status::ErrorDataTooLarge();
|
| +
|
| + buffer->resize(length.ValueOrDie());
|
| + if (AES_wrap_key(&aes_key, nullptr /* default IV */, buffer->data(),
|
| + data.bytes(), data.byte_length()) < 0) {
|
| + return Status::OperationError();
|
| + }
|
| +
|
| + return Status::Success();
|
| }
|
|
|
| Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
|
| const blink::WebCryptoKey& key,
|
| const CryptoData& data,
|
| std::vector<uint8_t>* buffer) const override {
|
| - return AesKwEncryptDecrypt(DECRYPT, algorithm, key, data, buffer);
|
| + crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
|
| +
|
| + // These length checks are done in order to give a more specific
|
| + // error. These are not required for correctness.
|
| + if (data.byte_length() < 24)
|
| + return Status::ErrorDataTooSmall();
|
| + if (data.byte_length() % 8)
|
| + return Status::ErrorInvalidAesKwDataLength();
|
| +
|
| + // Key import validates key sizes, so the bits computation will not
|
| + // overflow.
|
| + const std::vector<uint8_t>& raw_key = GetSymmetricKeyData(key);
|
| + AES_KEY aes_key;
|
| + if (AES_set_decrypt_key(raw_key.data(),
|
| + static_cast<unsigned>(raw_key.size() * 8),
|
| + &aes_key) < 0) {
|
| + return Status::OperationError();
|
| + }
|
| +
|
| + // Key wrap's overhead is 8 bytes.
|
| + buffer->resize(data.byte_length() - 8);
|
| +
|
| + if (AES_unwrap_key(&aes_key, nullptr /* default IV */, buffer->data(),
|
| + data.bytes(), data.byte_length()) < 0) {
|
| + return Status::OperationError();
|
| + }
|
| +
|
| + return Status::Success();
|
| }
|
| };
|
|
|
|
|