| Index: components/webcrypto/algorithms/aes_kw.cc
|
| diff --git a/components/webcrypto/algorithms/aes_kw.cc b/components/webcrypto/algorithms/aes_kw.cc
|
| index d1bf022726cbe6f68a8acd2fe104c98b63f2e087..f64e1db28228abba8ce3fc06edbd85bb41d2888b 100644
|
| --- a/components/webcrypto/algorithms/aes_kw.cc
|
| +++ b/components/webcrypto/algorithms/aes_kw.cc
|
| @@ -2,16 +2,18 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include <openssl/aes.h>
|
| +#include <openssl/aead.h>
|
| #include <stddef.h>
|
| #include <stdint.h>
|
|
|
| #include <vector>
|
|
|
| -#include "base/location.h"
|
| +#include "base/logging.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"
|
| @@ -21,6 +23,41 @@ 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()
|
| @@ -32,72 +69,14 @@ class AesKwImplementation : public AesAlgorithm {
|
| const blink::WebCryptoKey& key,
|
| const CryptoData& data,
|
| std::vector<uint8_t>* buffer) const override {
|
| - 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();
|
| + return AesKwEncryptDecrypt(ENCRYPT, algorithm, key, data, buffer);
|
| }
|
|
|
| Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
|
| const blink::WebCryptoKey& key,
|
| const CryptoData& data,
|
| std::vector<uint8_t>* buffer) const override {
|
| - 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();
|
| + return AesKwEncryptDecrypt(DECRYPT, algorithm, key, data, buffer);
|
| }
|
| };
|
|
|
|
|