Home | History | Annotate | Download | only in nss
      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