Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / content / child / webcrypto / openssl / util_openssl.cc
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