1 // Copyright 2015 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.
5 #include "components/gcm_driver/crypto/gcm_message_cryptographer.h"
7 #include <openssl/aead.h>
9 #include "base/logging.h"
10 #include "base/numerics/safe_math.h"
11 #include "base/strings/string_util.h"
17 // The BoringSSL functions used to seal (encrypt) and open (decrypt) a payload
18 // follow the same prototype, declared as follows.
19 using EVP_AEAD_CTX_TransformFunction
=
20 int(const EVP_AEAD_CTX
*ctx
, uint8_t *out
, size_t *out_len
,
21 size_t max_out_len
, const uint8_t *nonce
, size_t nonce_len
,
22 const uint8_t *in
, size_t in_len
, const uint8_t *ad
, size_t ad_len
);
26 bool GCMMessageCryptographer::EncryptDecryptRecordInternal(
28 const base::StringPiece
& input
,
29 const base::StringPiece
& key
,
30 const base::StringPiece
& nonce
,
31 std::string
* output
) const {
34 const EVP_AEAD
* aead
= EVP_aead_aes_128_gcm();
37 if (!EVP_AEAD_CTX_init(&context
, aead
,
38 reinterpret_cast<const uint8_t*>(key
.data()),
39 key
.size(), EVP_AEAD_DEFAULT_TAG_LENGTH
, nullptr)) {
43 base::CheckedNumeric
<size_t> maximum_output_length(input
.size());
45 maximum_output_length
+= kAuthenticationTagBytes
;
47 // WriteInto requires the buffer to finish with a NULL-byte.
48 maximum_output_length
+= 1;
50 size_t output_length
= 0;
51 uint8_t* raw_output
= reinterpret_cast<uint8_t*>(
52 base::WriteInto(output
, maximum_output_length
.ValueOrDie()));
54 EVP_AEAD_CTX_TransformFunction
* transform_function
=
55 mode
== ENCRYPT
? EVP_AEAD_CTX_seal
: EVP_AEAD_CTX_open
;
57 if (!transform_function(
58 &context
, raw_output
, &output_length
, output
->size(),
59 reinterpret_cast<const uint8_t*>(nonce
.data()), nonce
.size(),
60 reinterpret_cast<const uint8_t*>(input
.data()), input
.size(),
62 EVP_AEAD_CTX_cleanup(&context
);
66 EVP_AEAD_CTX_cleanup(&context
);
68 base::CheckedNumeric
<size_t> expected_output_length(input
.size());
70 expected_output_length
+= kAuthenticationTagBytes
;
72 expected_output_length
-= kAuthenticationTagBytes
;
74 DCHECK_EQ(expected_output_length
.ValueOrDie(), output_length
);
76 output
->resize(output_length
);