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/nss/aes_key_nss.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/nss/key_nss.h" 11 #include "content/child/webcrypto/nss/sym_key_nss.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(CK_MECHANISM_TYPE import_mechanism, 21 CK_FLAGS import_flags, 22 blink::WebCryptoKeyUsageMask all_key_usages, 23 const std::string& jwk_suffix) 24 : import_mechanism_(import_mechanism), 25 import_flags_(import_flags), 26 all_key_usages_(all_key_usages), 27 jwk_suffix_(jwk_suffix) { 28 } 29 30 AesAlgorithm::AesAlgorithm(CK_MECHANISM_TYPE import_mechanism, 31 const std::string& jwk_suffix) 32 : import_mechanism_(import_mechanism), 33 import_flags_(CKF_ENCRYPT | CKF_DECRYPT), 34 all_key_usages_(blink::WebCryptoKeyUsageEncrypt | 35 blink::WebCryptoKeyUsageDecrypt | 36 blink::WebCryptoKeyUsageWrapKey | 37 blink::WebCryptoKeyUsageUnwrapKey), 38 jwk_suffix_(jwk_suffix) { 39 } 40 41 Status AesAlgorithm::VerifyKeyUsagesBeforeGenerateKey( 42 blink::WebCryptoKeyUsageMask usage_mask) const { 43 return CheckKeyCreationUsages(all_key_usages_, usage_mask); 44 } 45 46 Status AesAlgorithm::GenerateSecretKey( 47 const blink::WebCryptoAlgorithm& algorithm, 48 bool extractable, 49 blink::WebCryptoKeyUsageMask usage_mask, 50 blink::WebCryptoKey* key) const { 51 unsigned int keylen_bits; 52 Status status = 53 GetAesKeyGenLengthInBits(algorithm.aesKeyGenParams(), &keylen_bits); 54 if (status.IsError()) 55 return status; 56 57 return GenerateSecretKeyNss( 58 blink::WebCryptoKeyAlgorithm::createAes(algorithm.id(), keylen_bits), 59 extractable, 60 usage_mask, 61 keylen_bits / 8, 62 CKM_AES_KEY_GEN, 63 key); 64 } 65 66 Status AesAlgorithm::VerifyKeyUsagesBeforeImportKey( 67 blink::WebCryptoKeyFormat format, 68 blink::WebCryptoKeyUsageMask usage_mask) const { 69 switch (format) { 70 case blink::WebCryptoKeyFormatRaw: 71 case blink::WebCryptoKeyFormatJwk: 72 return CheckKeyCreationUsages(all_key_usages_, usage_mask); 73 default: 74 return Status::ErrorUnsupportedImportKeyFormat(); 75 } 76 } 77 Status AesAlgorithm::ImportKeyRaw(const CryptoData& key_data, 78 const blink::WebCryptoAlgorithm& algorithm, 79 bool extractable, 80 blink::WebCryptoKeyUsageMask usage_mask, 81 blink::WebCryptoKey* key) const { 82 const unsigned int keylen_bytes = key_data.byte_length(); 83 Status status = VerifyAesKeyLengthForImport(keylen_bytes); 84 if (status.IsError()) 85 return status; 86 87 // No possibility of overflow. 88 unsigned int keylen_bits = keylen_bytes * 8; 89 90 return ImportKeyRawNss( 91 key_data, 92 blink::WebCryptoKeyAlgorithm::createAes(algorithm.id(), keylen_bits), 93 extractable, 94 usage_mask, 95 import_mechanism_, 96 import_flags_, 97 key); 98 } 99 100 Status AesAlgorithm::ImportKeyJwk(const CryptoData& key_data, 101 const blink::WebCryptoAlgorithm& algorithm, 102 bool extractable, 103 blink::WebCryptoKeyUsageMask usage_mask, 104 blink::WebCryptoKey* key) const { 105 std::vector<uint8_t> raw_data; 106 Status status = ReadAesSecretKeyJwk( 107 key_data, jwk_suffix_, extractable, usage_mask, &raw_data); 108 if (status.IsError()) 109 return status; 110 111 return ImportKeyRaw( 112 CryptoData(raw_data), algorithm, extractable, usage_mask, key); 113 } 114 115 Status AesAlgorithm::ExportKeyRaw(const blink::WebCryptoKey& key, 116 std::vector<uint8_t>* buffer) const { 117 *buffer = SymKeyNss::Cast(key)->raw_key_data(); 118 return Status::Success(); 119 } 120 121 Status AesAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key, 122 std::vector<uint8_t>* buffer) const { 123 SymKeyNss* sym_key = SymKeyNss::Cast(key); 124 const std::vector<uint8_t>& raw_data = sym_key->raw_key_data(); 125 126 WriteSecretKeyJwk(CryptoData(raw_data), 127 MakeJwkAesAlgorithmName(jwk_suffix_, raw_data.size()), 128 key.extractable(), 129 key.usages(), 130 buffer); 131 132 return Status::Success(); 133 } 134 135 } // namespace webcrypto 136 137 } // namespace content 138