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 40namespace blink { 41 42namespace { 43 44// A mapping from the algorithm ID to information about the algorithm. 45const 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. 206COMPILE_ASSERT(WebCryptoAlgorithmIdAesCbc == 0, AesCbc_idDoesntMatch); 207COMPILE_ASSERT(WebCryptoAlgorithmIdHmac == 1, Hmac_idDoesntMatch); 208COMPILE_ASSERT(WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 == 2, RsaSsaPkcs1v1_5_idDoesntMatch); 209COMPILE_ASSERT(WebCryptoAlgorithmIdSha1 == 3, Sha1_idDoesntMatch); 210COMPILE_ASSERT(WebCryptoAlgorithmIdSha256 == 4, Sha256_idDoesntMatch); 211COMPILE_ASSERT(WebCryptoAlgorithmIdSha384 == 5, Sha384_idDoesntMatch); 212COMPILE_ASSERT(WebCryptoAlgorithmIdSha512 == 6, Sha512_idDoesntMatch); 213COMPILE_ASSERT(WebCryptoAlgorithmIdAesGcm == 7, AesGcm_idDoesntMatch); 214COMPILE_ASSERT(WebCryptoAlgorithmIdRsaOaep == 8, RsaOaep_idDoesntMatch); 215COMPILE_ASSERT(WebCryptoAlgorithmIdAesCtr == 9, AesCtr_idDoesntMatch); 216COMPILE_ASSERT(WebCryptoAlgorithmIdAesKw == 10, AesKw_idDoesntMatch); 217COMPILE_ASSERT(WebCryptoAlgorithmIdLast == 10, Last_idDoesntMatch); 218COMPILE_ASSERT(10 == WebCryptoOperationLast, UpdateParamsMapping); 219 220} // namespace 221 222class WebCryptoAlgorithmPrivate : public ThreadSafeRefCounted<WebCryptoAlgorithmPrivate> { 223public: 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 234WebCryptoAlgorithm::WebCryptoAlgorithm(WebCryptoAlgorithmId id, PassOwnPtr<WebCryptoAlgorithmParams> params) 235 : m_private(adoptRef(new WebCryptoAlgorithmPrivate(id, params))) 236{ 237} 238 239WebCryptoAlgorithm WebCryptoAlgorithm::createNull() 240{ 241 return WebCryptoAlgorithm(); 242} 243 244WebCryptoAlgorithm WebCryptoAlgorithm::adoptParamsAndCreate(WebCryptoAlgorithmId id, WebCryptoAlgorithmParams* params) 245{ 246 return WebCryptoAlgorithm(id, adoptPtr(params)); 247} 248 249const WebCryptoAlgorithmInfo* WebCryptoAlgorithm::lookupAlgorithmInfo(WebCryptoAlgorithmId id) 250{ 251 if (id < 0 || id >= WTF_ARRAY_LENGTH(algorithmIdToInfo)) 252 return 0; 253 return &algorithmIdToInfo[id]; 254} 255 256bool WebCryptoAlgorithm::isNull() const 257{ 258 return m_private.isNull(); 259} 260 261WebCryptoAlgorithmId WebCryptoAlgorithm::id() const 262{ 263 ASSERT(!isNull()); 264 return m_private->id; 265} 266 267WebCryptoAlgorithmParamsType WebCryptoAlgorithm::paramsType() const 268{ 269 ASSERT(!isNull()); 270 if (!m_private->params) 271 return WebCryptoAlgorithmParamsTypeNone; 272 return m_private->params->type(); 273} 274 275const 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 283const 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 291const 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 299const 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 307const 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 315const 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 323const 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 331const 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 339const 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 347bool 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 367void WebCryptoAlgorithm::assign(const WebCryptoAlgorithm& other) 368{ 369 m_private = other.m_private; 370} 371 372void WebCryptoAlgorithm::reset() 373{ 374 m_private.reset(); 375} 376 377} // namespace blink 378