Home | History | Annotate | Download | only in exported
      1 /*
      2  * Copyright (C) 2013 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "public/platform/WebCryptoAlgorithm.h"
     33 
     34 #include "public/platform/WebCryptoAlgorithmParams.h"
     35 #include "wtf/Assertions.h"
     36 #include "wtf/OwnPtr.h"
     37 #include "wtf/StdLibExtras.h"
     38 #include "wtf/ThreadSafeRefCounted.h"
     39 
     40 namespace blink {
     41 
     42 namespace {
     43 
     44 // A mapping from the algorithm ID to information about the algorithm.
     45 const WebCryptoAlgorithmInfo algorithmIdToInfo[] = {
     46     { // Index 0
     47         "AES-CBC", {
     48             WebCryptoAlgorithmParamsTypeAesCbcParams, // Encrypt
     49             WebCryptoAlgorithmParamsTypeAesCbcParams, // Decrypt
     50             WebCryptoAlgorithmInfo::Undefined, // Sign
     51             WebCryptoAlgorithmInfo::Undefined, // Verify
     52             WebCryptoAlgorithmInfo::Undefined, // Digest
     53             WebCryptoAlgorithmParamsTypeAesKeyGenParams, // GenerateKey
     54             WebCryptoAlgorithmParamsTypeNone, // ImportKey
     55             WebCryptoAlgorithmInfo::Undefined, // DeriveKey
     56             WebCryptoAlgorithmInfo::Undefined, // DeriveBits
     57             WebCryptoAlgorithmParamsTypeAesCbcParams, // WrapKey
     58             WebCryptoAlgorithmParamsTypeAesCbcParams // UnwrapKey
     59         }
     60     }, { // Index 1
     61         "HMAC", {
     62             WebCryptoAlgorithmInfo::Undefined, // Encrypt
     63             WebCryptoAlgorithmInfo::Undefined, // Decrypt
     64             WebCryptoAlgorithmParamsTypeNone, // Sign
     65             WebCryptoAlgorithmParamsTypeNone, // Verify
     66             WebCryptoAlgorithmInfo::Undefined, // Digest
     67             WebCryptoAlgorithmParamsTypeHmacKeyGenParams, // GenerateKey
     68             WebCryptoAlgorithmParamsTypeHmacImportParams, // ImportKey
     69             WebCryptoAlgorithmInfo::Undefined, // DeriveKey
     70             WebCryptoAlgorithmInfo::Undefined, // DeriveBits
     71             WebCryptoAlgorithmInfo::Undefined, // WrapKey
     72             WebCryptoAlgorithmInfo::Undefined // UnwrapKey
     73         }
     74     }, { // Index 2
     75         "RSASSA-PKCS1-v1_5", {
     76             WebCryptoAlgorithmInfo::Undefined, // Encrypt
     77             WebCryptoAlgorithmInfo::Undefined, // Decrypt
     78             WebCryptoAlgorithmParamsTypeNone, // Sign
     79             WebCryptoAlgorithmParamsTypeNone, // Verify
     80             WebCryptoAlgorithmInfo::Undefined, // Digest
     81             WebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams, // GenerateKey
     82             WebCryptoAlgorithmParamsTypeRsaHashedImportParams, // ImportKey
     83             WebCryptoAlgorithmInfo::Undefined, // DeriveKey
     84             WebCryptoAlgorithmInfo::Undefined, // DeriveBits
     85             WebCryptoAlgorithmInfo::Undefined, // WrapKey
     86             WebCryptoAlgorithmInfo::Undefined // UnwrapKey
     87         }
     88     }, { // Index 3
     89         "SHA-1", {
     90             WebCryptoAlgorithmInfo::Undefined, // Encrypt
     91             WebCryptoAlgorithmInfo::Undefined, // Decrypt
     92             WebCryptoAlgorithmInfo::Undefined, // Sign
     93             WebCryptoAlgorithmInfo::Undefined, // Verify
     94             WebCryptoAlgorithmParamsTypeNone, // Digest
     95             WebCryptoAlgorithmInfo::Undefined, // GenerateKey
     96             WebCryptoAlgorithmInfo::Undefined, // ImportKey
     97             WebCryptoAlgorithmInfo::Undefined, // DeriveKey
     98             WebCryptoAlgorithmInfo::Undefined, // DeriveBits
     99             WebCryptoAlgorithmInfo::Undefined, // WrapKey
    100             WebCryptoAlgorithmInfo::Undefined // UnwrapKey
    101         }
    102     }, { // Index 4
    103         "SHA-256", {
    104             WebCryptoAlgorithmInfo::Undefined, // Encrypt
    105             WebCryptoAlgorithmInfo::Undefined, // Decrypt
    106             WebCryptoAlgorithmInfo::Undefined, // Sign
    107             WebCryptoAlgorithmInfo::Undefined, // Verify
    108             WebCryptoAlgorithmParamsTypeNone, // Digest
    109             WebCryptoAlgorithmInfo::Undefined, // GenerateKey
    110             WebCryptoAlgorithmInfo::Undefined, // ImportKey
    111             WebCryptoAlgorithmInfo::Undefined, // DeriveKey
    112             WebCryptoAlgorithmInfo::Undefined, // DeriveBits
    113             WebCryptoAlgorithmInfo::Undefined, // WrapKey
    114             WebCryptoAlgorithmInfo::Undefined // UnwrapKey
    115         }
    116     }, { // Index 5
    117         "SHA-384", {
    118             WebCryptoAlgorithmInfo::Undefined, // Encrypt
    119             WebCryptoAlgorithmInfo::Undefined, // Decrypt
    120             WebCryptoAlgorithmInfo::Undefined, // Sign
    121             WebCryptoAlgorithmInfo::Undefined, // Verify
    122             WebCryptoAlgorithmParamsTypeNone, // Digest
    123             WebCryptoAlgorithmInfo::Undefined, // GenerateKey
    124             WebCryptoAlgorithmInfo::Undefined, // ImportKey
    125             WebCryptoAlgorithmInfo::Undefined, // DeriveKey
    126             WebCryptoAlgorithmInfo::Undefined, // DeriveBits
    127             WebCryptoAlgorithmInfo::Undefined, // WrapKey
    128             WebCryptoAlgorithmInfo::Undefined // UnwrapKey
    129         }
    130     }, { // Index 6
    131         "SHA-512", {
    132             WebCryptoAlgorithmInfo::Undefined, // Encrypt
    133             WebCryptoAlgorithmInfo::Undefined, // Decrypt
    134             WebCryptoAlgorithmInfo::Undefined, // Sign
    135             WebCryptoAlgorithmInfo::Undefined, // Verify
    136             WebCryptoAlgorithmParamsTypeNone, // Digest
    137             WebCryptoAlgorithmInfo::Undefined, // GenerateKey
    138             WebCryptoAlgorithmInfo::Undefined, // ImportKey
    139             WebCryptoAlgorithmInfo::Undefined, // DeriveKey
    140             WebCryptoAlgorithmInfo::Undefined, // DeriveBits
    141             WebCryptoAlgorithmInfo::Undefined, // WrapKey
    142             WebCryptoAlgorithmInfo::Undefined // UnwrapKey
    143         }
    144     }, { // Index 7
    145         "AES-GCM", {
    146             WebCryptoAlgorithmParamsTypeAesGcmParams, // Encrypt
    147             WebCryptoAlgorithmParamsTypeAesGcmParams, // Decrypt
    148             WebCryptoAlgorithmInfo::Undefined, // Sign
    149             WebCryptoAlgorithmInfo::Undefined, // Verify
    150             WebCryptoAlgorithmInfo::Undefined, // Digest
    151             WebCryptoAlgorithmParamsTypeAesKeyGenParams, // GenerateKey
    152             WebCryptoAlgorithmParamsTypeNone, // ImportKey
    153             WebCryptoAlgorithmInfo::Undefined, // DeriveKey
    154             WebCryptoAlgorithmInfo::Undefined, // DeriveBits
    155             WebCryptoAlgorithmParamsTypeAesGcmParams, // WrapKey
    156             WebCryptoAlgorithmParamsTypeAesGcmParams // UnwrapKey
    157         }
    158     }, { // Index 8
    159         "RSA-OAEP", {
    160             WebCryptoAlgorithmParamsTypeRsaOaepParams, // Encrypt
    161             WebCryptoAlgorithmParamsTypeRsaOaepParams, // Decrypt
    162             WebCryptoAlgorithmInfo::Undefined, // Sign
    163             WebCryptoAlgorithmInfo::Undefined, // Verify
    164             WebCryptoAlgorithmInfo::Undefined, // Digest
    165             WebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams, // GenerateKey
    166             WebCryptoAlgorithmParamsTypeRsaHashedImportParams, // ImportKey
    167             WebCryptoAlgorithmInfo::Undefined, // DeriveKey
    168             WebCryptoAlgorithmInfo::Undefined, // DeriveBits
    169             WebCryptoAlgorithmParamsTypeRsaOaepParams, // WrapKey
    170             WebCryptoAlgorithmParamsTypeRsaOaepParams // UnwrapKey
    171         }
    172     }, { // Index 9
    173         "AES-CTR", {
    174             WebCryptoAlgorithmParamsTypeAesCtrParams, // Encrypt
    175             WebCryptoAlgorithmParamsTypeAesCtrParams, // Decrypt
    176             WebCryptoAlgorithmInfo::Undefined, // Sign
    177             WebCryptoAlgorithmInfo::Undefined, // Verify
    178             WebCryptoAlgorithmInfo::Undefined, // Digest
    179             WebCryptoAlgorithmParamsTypeAesKeyGenParams, // GenerateKey
    180             WebCryptoAlgorithmParamsTypeNone, // ImportKey
    181             WebCryptoAlgorithmInfo::Undefined, // DeriveKey
    182             WebCryptoAlgorithmInfo::Undefined, // DeriveBits
    183             WebCryptoAlgorithmParamsTypeAesCtrParams, // WrapKey
    184             WebCryptoAlgorithmParamsTypeAesCtrParams // UnwrapKey
    185         }
    186     }, { // Index 10
    187         "AES-KW", {
    188             WebCryptoAlgorithmInfo::Undefined, // Encrypt
    189             WebCryptoAlgorithmInfo::Undefined, // Decrypt
    190             WebCryptoAlgorithmInfo::Undefined, // Sign
    191             WebCryptoAlgorithmInfo::Undefined, // Verify
    192             WebCryptoAlgorithmInfo::Undefined, // Digest
    193             WebCryptoAlgorithmParamsTypeAesKeyGenParams, // GenerateKey
    194             WebCryptoAlgorithmParamsTypeNone, // ImportKey
    195             WebCryptoAlgorithmInfo::Undefined, // DeriveKey
    196             WebCryptoAlgorithmInfo::Undefined, // DeriveBits
    197             WebCryptoAlgorithmParamsTypeNone, // WrapKey
    198             WebCryptoAlgorithmParamsTypeNone // UnwrapKey
    199         }
    200     },
    201 };
    202 
    203 // Initializing the algorithmIdToInfo table above depends on knowing the enum
    204 // values for algorithm IDs. If those ever change, the table will need to be
    205 // updated.
    206 COMPILE_ASSERT(WebCryptoAlgorithmIdAesCbc == 0, AesCbc_idDoesntMatch);
    207 COMPILE_ASSERT(WebCryptoAlgorithmIdHmac == 1, Hmac_idDoesntMatch);
    208 COMPILE_ASSERT(WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 == 2, RsaSsaPkcs1v1_5_idDoesntMatch);
    209 COMPILE_ASSERT(WebCryptoAlgorithmIdSha1 == 3, Sha1_idDoesntMatch);
    210 COMPILE_ASSERT(WebCryptoAlgorithmIdSha256 == 4, Sha256_idDoesntMatch);
    211 COMPILE_ASSERT(WebCryptoAlgorithmIdSha384 == 5, Sha384_idDoesntMatch);
    212 COMPILE_ASSERT(WebCryptoAlgorithmIdSha512 == 6, Sha512_idDoesntMatch);
    213 COMPILE_ASSERT(WebCryptoAlgorithmIdAesGcm == 7, AesGcm_idDoesntMatch);
    214 COMPILE_ASSERT(WebCryptoAlgorithmIdRsaOaep == 8, RsaOaep_idDoesntMatch);
    215 COMPILE_ASSERT(WebCryptoAlgorithmIdAesCtr == 9, AesCtr_idDoesntMatch);
    216 COMPILE_ASSERT(WebCryptoAlgorithmIdAesKw == 10, AesKw_idDoesntMatch);
    217 COMPILE_ASSERT(WebCryptoAlgorithmIdLast == 10, Last_idDoesntMatch);
    218 COMPILE_ASSERT(10 == WebCryptoOperationLast, UpdateParamsMapping);
    219 
    220 } // namespace
    221 
    222 class WebCryptoAlgorithmPrivate : public ThreadSafeRefCounted<WebCryptoAlgorithmPrivate> {
    223 public:
    224     WebCryptoAlgorithmPrivate(WebCryptoAlgorithmId id, PassOwnPtr<WebCryptoAlgorithmParams> params)
    225         : id(id)
    226         , params(params)
    227     {
    228     }
    229 
    230     WebCryptoAlgorithmId id;
    231     OwnPtr<WebCryptoAlgorithmParams> params;
    232 };
    233 
    234 WebCryptoAlgorithm::WebCryptoAlgorithm(WebCryptoAlgorithmId id, PassOwnPtr<WebCryptoAlgorithmParams> params)
    235     : m_private(adoptRef(new WebCryptoAlgorithmPrivate(id, params)))
    236 {
    237 }
    238 
    239 WebCryptoAlgorithm WebCryptoAlgorithm::createNull()
    240 {
    241     return WebCryptoAlgorithm();
    242 }
    243 
    244 WebCryptoAlgorithm WebCryptoAlgorithm::adoptParamsAndCreate(WebCryptoAlgorithmId id, WebCryptoAlgorithmParams* params)
    245 {
    246     return WebCryptoAlgorithm(id, adoptPtr(params));
    247 }
    248 
    249 const WebCryptoAlgorithmInfo* WebCryptoAlgorithm::lookupAlgorithmInfo(WebCryptoAlgorithmId id)
    250 {
    251     if (id < 0 || id >= WTF_ARRAY_LENGTH(algorithmIdToInfo))
    252         return 0;
    253     return &algorithmIdToInfo[id];
    254 }
    255 
    256 bool WebCryptoAlgorithm::isNull() const
    257 {
    258     return m_private.isNull();
    259 }
    260 
    261 WebCryptoAlgorithmId WebCryptoAlgorithm::id() const
    262 {
    263     ASSERT(!isNull());
    264     return m_private->id;
    265 }
    266 
    267 WebCryptoAlgorithmParamsType WebCryptoAlgorithm::paramsType() const
    268 {
    269     ASSERT(!isNull());
    270     if (!m_private->params)
    271         return WebCryptoAlgorithmParamsTypeNone;
    272     return m_private->params->type();
    273 }
    274 
    275 const WebCryptoAesCbcParams* WebCryptoAlgorithm::aesCbcParams() const
    276 {
    277     ASSERT(!isNull());
    278     if (paramsType() == WebCryptoAlgorithmParamsTypeAesCbcParams)
    279         return static_cast<WebCryptoAesCbcParams*>(m_private->params.get());
    280     return 0;
    281 }
    282 
    283 const WebCryptoAesCtrParams* WebCryptoAlgorithm::aesCtrParams() const
    284 {
    285     ASSERT(!isNull());
    286     if (paramsType() == WebCryptoAlgorithmParamsTypeAesCtrParams)
    287         return static_cast<WebCryptoAesCtrParams*>(m_private->params.get());
    288     return 0;
    289 }
    290 
    291 const WebCryptoAesKeyGenParams* WebCryptoAlgorithm::aesKeyGenParams() const
    292 {
    293     ASSERT(!isNull());
    294     if (paramsType() == WebCryptoAlgorithmParamsTypeAesKeyGenParams)
    295         return static_cast<WebCryptoAesKeyGenParams*>(m_private->params.get());
    296     return 0;
    297 }
    298 
    299 const WebCryptoHmacImportParams* WebCryptoAlgorithm::hmacImportParams() const
    300 {
    301     ASSERT(!isNull());
    302     if (paramsType() == WebCryptoAlgorithmParamsTypeHmacImportParams)
    303         return static_cast<WebCryptoHmacImportParams*>(m_private->params.get());
    304     return 0;
    305 }
    306 
    307 const WebCryptoHmacKeyGenParams* WebCryptoAlgorithm::hmacKeyGenParams() const
    308 {
    309     ASSERT(!isNull());
    310     if (paramsType() == WebCryptoAlgorithmParamsTypeHmacKeyGenParams)
    311         return static_cast<WebCryptoHmacKeyGenParams*>(m_private->params.get());
    312     return 0;
    313 }
    314 
    315 const WebCryptoAesGcmParams* WebCryptoAlgorithm::aesGcmParams() const
    316 {
    317     ASSERT(!isNull());
    318     if (paramsType() == WebCryptoAlgorithmParamsTypeAesGcmParams)
    319         return static_cast<WebCryptoAesGcmParams*>(m_private->params.get());
    320     return 0;
    321 }
    322 
    323 const WebCryptoRsaOaepParams* WebCryptoAlgorithm::rsaOaepParams() const
    324 {
    325     ASSERT(!isNull());
    326     if (paramsType() == WebCryptoAlgorithmParamsTypeRsaOaepParams)
    327         return static_cast<WebCryptoRsaOaepParams*>(m_private->params.get());
    328     return 0;
    329 }
    330 
    331 const WebCryptoRsaHashedImportParams* WebCryptoAlgorithm::rsaHashedImportParams() const
    332 {
    333     ASSERT(!isNull());
    334     if (paramsType() == WebCryptoAlgorithmParamsTypeRsaHashedImportParams)
    335         return static_cast<WebCryptoRsaHashedImportParams*>(m_private->params.get());
    336     return 0;
    337 }
    338 
    339 const WebCryptoRsaHashedKeyGenParams* WebCryptoAlgorithm::rsaHashedKeyGenParams() const
    340 {
    341     ASSERT(!isNull());
    342     if (paramsType() == WebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams)
    343         return static_cast<WebCryptoRsaHashedKeyGenParams*>(m_private->params.get());
    344     return 0;
    345 }
    346 
    347 bool WebCryptoAlgorithm::isHash(WebCryptoAlgorithmId id)
    348 {
    349     switch (id) {
    350     case WebCryptoAlgorithmIdSha1:
    351     case WebCryptoAlgorithmIdSha256:
    352     case WebCryptoAlgorithmIdSha384:
    353     case WebCryptoAlgorithmIdSha512:
    354         return true;
    355     case WebCryptoAlgorithmIdAesCbc:
    356     case WebCryptoAlgorithmIdHmac:
    357     case WebCryptoAlgorithmIdRsaSsaPkcs1v1_5:
    358     case WebCryptoAlgorithmIdAesGcm:
    359     case WebCryptoAlgorithmIdRsaOaep:
    360     case WebCryptoAlgorithmIdAesCtr:
    361     case WebCryptoAlgorithmIdAesKw:
    362         break;
    363     }
    364     return false;
    365 }
    366 
    367 void WebCryptoAlgorithm::assign(const WebCryptoAlgorithm& other)
    368 {
    369     m_private = other.m_private;
    370 }
    371 
    372 void WebCryptoAlgorithm::reset()
    373 {
    374     m_private.reset();
    375 }
    376 
    377 } // namespace blink
    378