// 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 #include #include #include #include "base/logging.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" #include "crypto/openssl_util.h" #include "crypto/scoped_openssl_types.h" 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* 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& 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() : AesAlgorithm( blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, "KW") {} Status Encrypt(const blink::WebCryptoAlgorithm& algorithm, const blink::WebCryptoKey& key, const CryptoData& data, std::vector* buffer) const override { return AesKwEncryptDecrypt(ENCRYPT, algorithm, key, data, buffer); } Status Decrypt(const blink::WebCryptoAlgorithm& algorithm, const blink::WebCryptoKey& key, const CryptoData& data, std::vector* buffer) const override { return AesKwEncryptDecrypt(DECRYPT, algorithm, key, data, buffer); } }; } // namespace scoped_ptr CreateAesKwImplementation() { return make_scoped_ptr(new AesKwImplementation); } } // namespace webcrypto