1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
// Copyright 2014 The Chromium Authors
// 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 "components/webcrypto/algorithms/aes.h"
#include "components/webcrypto/algorithms/util.h"
#include "components/webcrypto/blink_key_handle.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,
base::span<const uint8_t> 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,
params->Iv(), 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,
base::span<const uint8_t> 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,
base::span<const uint8_t> 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
|