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/openssl/util_openssl.h" 6 7 #include <openssl/evp.h> 8 9 #include "base/stl_util.h" 10 #include "content/child/webcrypto/crypto_data.h" 11 #include "content/child/webcrypto/openssl/key_openssl.h" 12 #include "content/child/webcrypto/platform_crypto.h" 13 #include "content/child/webcrypto/status.h" 14 #include "crypto/openssl_util.h" 15 16 namespace content { 17 18 namespace webcrypto { 19 20 void PlatformInit() { 21 crypto::EnsureOpenSSLInit(); 22 } 23 24 const EVP_MD* GetDigest(blink::WebCryptoAlgorithmId id) { 25 switch (id) { 26 case blink::WebCryptoAlgorithmIdSha1: 27 return EVP_sha1(); 28 case blink::WebCryptoAlgorithmIdSha256: 29 return EVP_sha256(); 30 case blink::WebCryptoAlgorithmIdSha384: 31 return EVP_sha384(); 32 case blink::WebCryptoAlgorithmIdSha512: 33 return EVP_sha512(); 34 default: 35 return NULL; 36 } 37 } 38 39 Status AeadEncryptDecrypt(EncryptOrDecrypt mode, 40 const std::vector<uint8_t>& raw_key, 41 const CryptoData& data, 42 unsigned int tag_length_bytes, 43 const CryptoData& iv, 44 const CryptoData& additional_data, 45 const EVP_AEAD* aead_alg, 46 std::vector<uint8_t>* buffer) { 47 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 48 EVP_AEAD_CTX ctx; 49 50 if (!aead_alg) 51 return Status::ErrorUnexpected(); 52 53 if (!EVP_AEAD_CTX_init(&ctx, 54 aead_alg, 55 vector_as_array(&raw_key), 56 raw_key.size(), 57 tag_length_bytes, 58 NULL)) { 59 return Status::OperationError(); 60 } 61 62 crypto::ScopedOpenSSL<EVP_AEAD_CTX, EVP_AEAD_CTX_cleanup>::Type ctx_cleanup( 63 &ctx); 64 65 size_t len; 66 int ok; 67 68 if (mode == DECRYPT) { 69 if (data.byte_length() < tag_length_bytes) 70 return Status::ErrorDataTooSmall(); 71 72 buffer->resize(data.byte_length() - tag_length_bytes); 73 74 ok = EVP_AEAD_CTX_open(&ctx, 75 vector_as_array(buffer), 76 &len, 77 buffer->size(), 78 iv.bytes(), 79 iv.byte_length(), 80 data.bytes(), 81 data.byte_length(), 82 additional_data.bytes(), 83 additional_data.byte_length()); 84 } else { 85 // No need to check for unsigned integer overflow here (seal fails if 86 // the output buffer is too small). 87 buffer->resize(data.byte_length() + EVP_AEAD_max_overhead(aead_alg)); 88 89 ok = EVP_AEAD_CTX_seal(&ctx, 90 vector_as_array(buffer), 91 &len, 92 buffer->size(), 93 iv.bytes(), 94 iv.byte_length(), 95 data.bytes(), 96 data.byte_length(), 97 additional_data.bytes(), 98 additional_data.byte_length()); 99 } 100 101 if (!ok) 102 return Status::OperationError(); 103 buffer->resize(len); 104 return Status::Success(); 105 } 106 107 } // namespace webcrypto 108 109 } // namespace content 110