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