1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <vector> 6#include <openssl/evp.h> 7 8#include "base/logging.h" 9#include "base/numerics/safe_math.h" 10#include "base/stl_util.h" 11#include "content/child/webcrypto/crypto_data.h" 12#include "content/child/webcrypto/openssl/aes_key_openssl.h" 13#include "content/child/webcrypto/openssl/key_openssl.h" 14#include "content/child/webcrypto/openssl/util_openssl.h" 15#include "content/child/webcrypto/status.h" 16#include "crypto/openssl_util.h" 17#include "crypto/scoped_openssl_types.h" 18 19namespace content { 20 21namespace webcrypto { 22 23namespace { 24 25const EVP_AEAD* GetAesKwAlgorithmFromKeySize(unsigned int key_size_bytes) { 26 switch (key_size_bytes) { 27 case 16: 28 return EVP_aead_aes_128_key_wrap(); 29 case 32: 30 return EVP_aead_aes_256_key_wrap(); 31 default: 32 return NULL; 33 } 34} 35 36Status AesKwEncryptDecrypt(EncryptOrDecrypt mode, 37 const blink::WebCryptoAlgorithm& algorithm, 38 const blink::WebCryptoKey& key, 39 const CryptoData& data, 40 std::vector<uint8_t>* buffer) { 41 // These length checks are done so the returned error matches that of NSS 42 // implementation. Other than giving a more specific error, these are not 43 // required. 44 if ((mode == ENCRYPT && data.byte_length() < 16) || 45 (mode == DECRYPT && data.byte_length() < 24)) { 46 return Status::ErrorDataTooSmall(); 47 } 48 if (data.byte_length() % 8) 49 return Status::ErrorInvalidAesKwDataLength(); 50 51 const std::vector<uint8_t>& raw_key = 52 SymKeyOpenSsl::Cast(key)->raw_key_data(); 53 54 return AeadEncryptDecrypt(mode, 55 raw_key, 56 data, 57 8, // tag_length_bytes 58 CryptoData(), // iv 59 CryptoData(), // additional_data 60 GetAesKwAlgorithmFromKeySize(raw_key.size()), 61 buffer); 62} 63 64class AesKwImplementation : public AesAlgorithm { 65 public: 66 AesKwImplementation() 67 : AesAlgorithm( 68 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, 69 "KW") {} 70 71 virtual Status Encrypt(const blink::WebCryptoAlgorithm& algorithm, 72 const blink::WebCryptoKey& key, 73 const CryptoData& data, 74 std::vector<uint8_t>* buffer) const OVERRIDE { 75 return AesKwEncryptDecrypt(ENCRYPT, algorithm, key, data, buffer); 76 } 77 78 virtual Status Decrypt(const blink::WebCryptoAlgorithm& algorithm, 79 const blink::WebCryptoKey& key, 80 const CryptoData& data, 81 std::vector<uint8_t>* buffer) const OVERRIDE { 82 return AesKwEncryptDecrypt(DECRYPT, algorithm, key, data, buffer); 83 } 84}; 85 86} // namespace 87 88AlgorithmImplementation* CreatePlatformAesKwImplementation() { 89 return new AesKwImplementation; 90} 91 92} // namespace webcrypto 93 94} // namespace content 95