blob: dbf1a8f49105a08aa409091c29e1b6e3ef13dadb [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <vector>
#include "base/logging.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"
#include "crypto/openssl_util.h"
#include "third_party/blink/public/platform/web_crypto_algorithm_params.h"
#include "third_party/boringssl/src/include/openssl/aead.h"
namespace webcrypto {
namespace {
const EVP_AEAD* GetAesGcmAlgorithmFromKeySize(size_t key_size_bytes) {
switch (key_size_bytes) {
case 16:
return EVP_aead_aes_128_gcm();
case 32:
return EVP_aead_aes_256_gcm();
default:
return nullptr;
}
}
Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
std::vector<uint8_t>* buffer) {
const std::vector<uint8_t>& raw_key = GetSymmetricKeyData(key);
const blink::WebCryptoAesGcmParams* params = algorithm.AesGcmParams();
// The WebCrypto spec defines the default value for the tag length, as well as
// the allowed values for tag length.
unsigned int tag_length_bits = 128;
if (params->HasTagLengthBits()) {
tag_length_bits = params->OptionalTagLengthBits();
if (tag_length_bits != 32 && tag_length_bits != 64 &&
tag_length_bits != 96 && tag_length_bits != 104 &&
tag_length_bits != 112 && tag_length_bits != 120 &&
tag_length_bits != 128) {
return Status::ErrorInvalidAesGcmTagLength();
}
}
return AeadEncryptDecrypt(
mode, raw_key, data, tag_length_bits / 8, CryptoData(params->Iv()),
CryptoData(params->OptionalAdditionalData()),
GetAesGcmAlgorithmFromKeySize(raw_key.size()), buffer);
}
class AesGcmImplementation : public AesAlgorithm {
public:
AesGcmImplementation() : AesAlgorithm("GCM") {}
Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
const blink::WebCryptoKey& key,
const CryptoData& data,
std::vector<uint8_t>* buffer) const override {
return AesGcmEncryptDecrypt(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 {
return AesGcmEncryptDecrypt(DECRYPT, algorithm, key, data, buffer);
}
};
} // namespace
std::unique_ptr<AlgorithmImplementation> CreateAesGcmImplementation() {
return std::make_unique<AesGcmImplementation>();
}
} // namespace webcrypto