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 "content/child/webcrypto/openssl/aes_key_openssl.h" 6 7 #include "base/logging.h" 8 #include "content/child/webcrypto/crypto_data.h" 9 #include "content/child/webcrypto/jwk.h" 10 #include "content/child/webcrypto/openssl/key_openssl.h" 11 #include "content/child/webcrypto/openssl/sym_key_openssl.h" 12 #include "content/child/webcrypto/status.h" 13 #include "content/child/webcrypto/webcrypto_util.h" 14 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" 15 16 namespace content { 17 18 namespace webcrypto { 19 20 AesAlgorithm::AesAlgorithm(blink::WebCryptoKeyUsageMask all_key_usages, 21 const std::string& jwk_suffix) 22 : all_key_usages_(all_key_usages), jwk_suffix_(jwk_suffix) { 23 } 24 25 AesAlgorithm::AesAlgorithm(const std::string& jwk_suffix) 26 : all_key_usages_(blink::WebCryptoKeyUsageEncrypt | 27 blink::WebCryptoKeyUsageDecrypt | 28 blink::WebCryptoKeyUsageWrapKey | 29 blink::WebCryptoKeyUsageUnwrapKey), 30 jwk_suffix_(jwk_suffix) { 31 } 32 33 Status AesAlgorithm::VerifyKeyUsagesBeforeGenerateKey( 34 blink::WebCryptoKeyUsageMask usage_mask) const { 35 return CheckKeyCreationUsages(all_key_usages_, usage_mask); 36 } 37 38 Status AesAlgorithm::GenerateSecretKey( 39 const blink::WebCryptoAlgorithm& algorithm, 40 bool extractable, 41 blink::WebCryptoKeyUsageMask usage_mask, 42 blink::WebCryptoKey* key) const { 43 unsigned int keylen_bits; 44 Status status = 45 GetAesKeyGenLengthInBits(algorithm.aesKeyGenParams(), &keylen_bits); 46 if (status.IsError()) 47 return status; 48 49 return GenerateSecretKeyOpenSsl( 50 blink::WebCryptoKeyAlgorithm::createAes(algorithm.id(), keylen_bits), 51 extractable, 52 usage_mask, 53 keylen_bits / 8, 54 key); 55 } 56 57 Status AesAlgorithm::VerifyKeyUsagesBeforeImportKey( 58 blink::WebCryptoKeyFormat format, 59 blink::WebCryptoKeyUsageMask usage_mask) const { 60 switch (format) { 61 case blink::WebCryptoKeyFormatRaw: 62 case blink::WebCryptoKeyFormatJwk: 63 return CheckKeyCreationUsages(all_key_usages_, usage_mask); 64 default: 65 return Status::ErrorUnsupportedImportKeyFormat(); 66 } 67 } 68 69 Status AesAlgorithm::ImportKeyRaw(const CryptoData& key_data, 70 const blink::WebCryptoAlgorithm& algorithm, 71 bool extractable, 72 blink::WebCryptoKeyUsageMask usage_mask, 73 blink::WebCryptoKey* key) const { 74 const unsigned int keylen_bytes = key_data.byte_length(); 75 Status status = VerifyAesKeyLengthForImport(keylen_bytes); 76 if (status.IsError()) 77 return status; 78 79 // No possibility of overflow. 80 unsigned int keylen_bits = keylen_bytes * 8; 81 82 return ImportKeyRawOpenSsl( 83 key_data, 84 blink::WebCryptoKeyAlgorithm::createAes(algorithm.id(), keylen_bits), 85 extractable, 86 usage_mask, 87 key); 88 } 89 90 Status AesAlgorithm::ImportKeyJwk(const CryptoData& key_data, 91 const blink::WebCryptoAlgorithm& algorithm, 92 bool extractable, 93 blink::WebCryptoKeyUsageMask usage_mask, 94 blink::WebCryptoKey* key) const { 95 std::vector<uint8_t> raw_data; 96 Status status = ReadAesSecretKeyJwk( 97 key_data, jwk_suffix_, extractable, usage_mask, &raw_data); 98 if (status.IsError()) 99 return status; 100 101 return ImportKeyRaw( 102 CryptoData(raw_data), algorithm, extractable, usage_mask, key); 103 } 104 105 Status AesAlgorithm::ExportKeyRaw(const blink::WebCryptoKey& key, 106 std::vector<uint8_t>* buffer) const { 107 *buffer = SymKeyOpenSsl::Cast(key)->raw_key_data(); 108 return Status::Success(); 109 } 110 111 Status AesAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key, 112 std::vector<uint8_t>* buffer) const { 113 const std::vector<uint8_t>& raw_data = 114 SymKeyOpenSsl::Cast(key)->raw_key_data(); 115 116 WriteSecretKeyJwk(CryptoData(raw_data), 117 MakeJwkAesAlgorithmName(jwk_suffix_, raw_data.size()), 118 key.extractable(), 119 key.usages(), 120 buffer); 121 122 return Status::Success(); 123 } 124 125 } // namespace webcrypto 126 127 } // namespace content 128