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 #ifndef COMPONENTS_GCM_DRIVER_CRYPTO_GCM_MESSAGE_CRYPTOGRAPHER_H_
6 #define COMPONENTS_GCM_DRIVER_CRYPTO_GCM_MESSAGE_CRYPTOGRAPHER_H_
11 #include "base/compiler_specific.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/strings/string_piece.h"
17 // Messages delivered through GCM may be encrypted according to the IETF Web
18 // Push protocol, as described in draft-thomson-webpush-encryption-01:
20 // https://tools.ietf.org/html/draft-thomson-webpush-encryption-01
22 // This class implements the ability to encrypt or decrypt such messages using
23 // AEAD_AES_128_GCM with a 16-octet authentication tag. The encrypted payload
24 // will be stored in a single record as described in
25 // draft-thomson-http-encryption-01:
27 // https://tools.ietf.org/html/draft-thomson-http-encryption-01
29 // Note that while this class is not responsible for creating or storing the
30 // actual keys, it uses a key derivation function for the actual message
31 // encryption/decryption, thus allowing for the safe re-use of keys in multiple
32 // messages provided that a cryptographically-strong random salt is used.
33 class GCMMessageCryptographer
{
35 GCMMessageCryptographer();
36 ~GCMMessageCryptographer();
38 // Encrypts |plaintext| using the |key| and the |salt|, both of which must be
39 // 16 octets in length. The |plaintext| will be written to a single record,
40 // and will include a 16 octet authentication tag. The encrypted result will
41 // be written to |ciphertext|, the record size to |record_size|. This
42 // implementation does not support prepending padding to the |plaintext|.
43 bool Encrypt(const base::StringPiece
& plaintext
,
44 const base::StringPiece
& key
,
45 const base::StringPiece
& salt
,
47 std::string
* ciphertext
) const WARN_UNUSED_RESULT
;
49 // Decrypts |ciphertext| using the |key| and the |salt|, both of which must be
50 // 16 octets in length. The result will be stored in |plaintext|. Note that
51 // there must only be a single record, per draft-thomson-http-encryption-01.
52 bool Decrypt(const base::StringPiece
& ciphertext
,
53 const base::StringPiece
& key
,
54 const base::StringPiece
& salt
,
56 std::string
* plaintext
) const WARN_UNUSED_RESULT
;
59 FRIEND_TEST_ALL_PREFIXES(GCMMessageCryptographerTest
, InvalidRecordPadding
);
60 FRIEND_TEST_ALL_PREFIXES(GCMMessageCryptographerTest
, NonceGeneration
);
62 // Size, in bytes, of the authentication tag included in the messages.
63 static const size_t kAuthenticationTagBytes
;
65 enum Mode
{ ENCRYPT
, DECRYPT
};
67 // Private implementation of the encryption and decryption routines, provided
68 // by either NSS or BoringSSL depending on the platform.
69 bool EncryptDecryptRecordInternal(Mode mode
,
70 const base::StringPiece
& input
,
71 const base::StringPiece
& key
,
72 const base::StringPiece
& nonce
,
73 std::string
* output
) const;
75 // Derives the content encryption key from |key| and |salt|.
76 std::string
DeriveContentEncryptionKey(const base::StringPiece
& key
,
77 const base::StringPiece
& salt
) const;
79 // Derives the nonce from |key| and |salt|.
80 std::string
DeriveNonce(const base::StringPiece
& key
,
81 const base::StringPiece
& salt
) const;
86 #endif // COMPONENTS_GCM_DRIVER_CRYPTO_GCM_MESSAGE_CRYPTOGRAPHER_H_