Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(380)

Side by Side Diff: components/gcm_driver/crypto/gcm_message_cryptographer_unittest.cc

Issue 2716443002: Implement support for draft-ietf-webpush-encryption-08 (Closed)
Patch Set: fix windows^2 Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/gcm_driver/crypto/gcm_message_cryptographer.h" 5 #include "components/gcm_driver/crypto/gcm_message_cryptographer.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/base64url.h" 9 #include "base/base64url.h"
10 #include "base/big_endian.h"
10 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/strings/string_piece.h"
11 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
12 #include "components/gcm_driver/crypto/p256_key_util.h" 14 #include "components/gcm_driver/crypto/p256_key_util.h"
13 #include "crypto/random.h" 15 #include "crypto/random.h"
14 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
15 17
16 namespace gcm { 18 namespace gcm {
17 19
18 namespace { 20 namespace {
19 21
20 // Example plaintext data to use in the tests. 22 // Example plaintext data to use in the tests.
21 const char kExamplePlaintext[] = "Example plaintext"; 23 const char kExamplePlaintext[] = "Example plaintext";
22 24
23 // Expected sizes of the different input given to the cryptographer. 25 // Expected sizes of the different input given to the cryptographer.
26 constexpr size_t kUncompressedPointSize = 65;
24 constexpr size_t kEcdhSharedSecretSize = 32; 27 constexpr size_t kEcdhSharedSecretSize = 32;
25 constexpr size_t kAuthSecretSize = 16; 28 constexpr size_t kAuthSecretSize = 16;
26 constexpr size_t kSaltSize = 16; 29 constexpr size_t kSaltSize = 16;
27 30
28 // Keying material for both parties as P-256 EC points. Used to make sure that 31 // Keying material for both parties as P-256 EC points. Used to make sure that
29 // the test vectors are reproducible. 32 // the test vectors are reproducible.
30 const unsigned char kCommonSenderPublicKey[] = { 33 const unsigned char kCommonSenderPublicKey[] = {
31 0x04, 0x05, 0x3C, 0xA1, 0xB9, 0xA5, 0xAB, 0xB8, 0x2D, 0x88, 0x48, 34 0x04, 0x05, 0x3C, 0xA1, 0xB9, 0xA5, 0xAB, 0xB8, 0x2D, 0x88, 0x48,
32 0x82, 0xC9, 0x49, 0x19, 0x91, 0xD5, 0xFD, 0xD1, 0x92, 0xDB, 0xA7, 35 0x82, 0xC9, 0x49, 0x19, 0x91, 0xD5, 0xFD, 0xD1, 0x92, 0xDB, 0xA7,
33 0x7E, 0x70, 0x48, 0x37, 0x41, 0xCD, 0x90, 0x05, 0x80, 0xDF, 0x65, 36 0x7E, 0x70, 0x48, 0x37, 0x41, 0xCD, 0x90, 0x05, 0x80, 0xDF, 0x65,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 0x2C, 0x34, 0x11, 0x8C, 0xB4, 0x37, 0x85, 0xB8, 0xDF, 0xFB, 0x5E, 0x68, 76 0x2C, 0x34, 0x11, 0x8C, 0xB4, 0x37, 0x85, 0xB8, 0xDF, 0xFB, 0x5E, 0x68,
74 0xD5, 0xAA, 0xBC, 0x29, 0x2B, 0xE1, 0x8C, 0xA2, 0x76, 0xAA, 0x59, 0x2D, 77 0xD5, 0xAA, 0xBC, 0x29, 0x2B, 0xE1, 0x8C, 0xA2, 0x76, 0xAA, 0x59, 0x2D,
75 0x8D, 0xB9, 0xC0, 0x11, 0xC8, 0xA9, 0x01, 0xD6, 0xB3, 0xBD, 0xEE}; 78 0x8D, 0xB9, 0xC0, 0x11, 0xC8, 0xA9, 0x01, 0xD6, 0xB3, 0xBD, 0xEE};
76 79
77 const unsigned char kCommonAuthSecret[] = {0x25, 0xF2, 0xC2, 0xB8, 0x19, 0xD8, 80 const unsigned char kCommonAuthSecret[] = {0x25, 0xF2, 0xC2, 0xB8, 0x19, 0xD8,
78 0xFD, 0x35, 0x97, 0xDF, 0xFB, 0x5E, 81 0xFD, 0x35, 0x97, 0xDF, 0xFB, 0x5E,
79 0xF6, 0x0B, 0xD7, 0xA4}; 82 0xF6, 0x0B, 0xD7, 0xA4};
80 static_assert(arraysize(kCommonAuthSecret) == 16, 83 static_assert(arraysize(kCommonAuthSecret) == 16,
81 "Auth secrets must be 16 bytes in size."); 84 "Auth secrets must be 16 bytes in size.");
82 85
83 // Test vectors containing reference input for draft-ietf-webpush-encryption-03 86 // Test vectors containing reference input for draft-ietf-webpush-encryption
84 // that was created using an separate JavaScript implementation of the draft. 87 // that was created using an separate JavaScript implementation of the draft.
85 struct TestVector { 88 struct TestVector {
86 const char* const input; 89 const char* const input;
87 const unsigned char ecdh_shared_secret[kEcdhSharedSecretSize]; 90 const unsigned char ecdh_shared_secret[kEcdhSharedSecretSize];
88 const unsigned char auth_secret[kAuthSecretSize]; 91 const unsigned char auth_secret[kAuthSecretSize];
89 const unsigned char salt[kSaltSize]; 92 const unsigned char salt[kSaltSize];
90 size_t record_size; 93 size_t record_size;
91 const char* const output; 94 const char* const output;
92 }; 95 };
93 96
(...skipping 14 matching lines...) Expand all
108 {0x3F, 0xD8, 0x95, 0x2C, 0xA2, 0x11, 0xBD, 0x7B, 0x57, 0xB2, 0x00, 111 {0x3F, 0xD8, 0x95, 0x2C, 0xA2, 0x11, 0xBD, 0x7B, 0x57, 0xB2, 0x00,
109 0xBD, 0x57, 0x68, 0x3F, 0xF0, 0x14, 0x57, 0x5F, 0xB1, 0x9F, 0x15, 112 0xBD, 0x57, 0x68, 0x3F, 0xF0, 0x14, 0x57, 0x5F, 0xB1, 0x9F, 0x15,
110 0x4F, 0x11, 0xF0, 0x4D, 0xA2, 0xE8, 0x4C, 0xEA, 0x74, 0x3B}, 113 0x4F, 0x11, 0xF0, 0x4D, 0xA2, 0xE8, 0x4C, 0xEA, 0x74, 0x3B},
111 {0xB1, 0xE1, 0xC7, 0x32, 0x4C, 0xAA, 0x56, 0x32, 0x68, 0x20, 0x0F, 0x26, 114 {0xB1, 0xE1, 0xC7, 0x32, 0x4C, 0xAA, 0x56, 0x32, 0x68, 0x20, 0x0F, 0x26,
112 0x3F, 0x48, 0x4D, 0x99}, 115 0x3F, 0x48, 0x4D, 0x99},
113 {0xE9, 0x39, 0x45, 0xBC, 0x96, 0x96, 0x88, 0x76, 0xFC, 0xA1, 0xAD, 0xE4, 116 {0xE9, 0x39, 0x45, 0xBC, 0x96, 0x96, 0x88, 0x76, 0xFC, 0xA1, 0xAD, 0xE4,
114 0x9D, 0x28, 0xF3, 0x73}, 117 0x9D, 0x28, 0xF3, 0x73},
115 4096, 118 4096,
116 "8s-Tzq8Cn_eobL6uEcNDXL7K"}}; 119 "8s-Tzq8Cn_eobL6uEcNDXL7K"}};
117 120
121 const TestVector kEncryptionTestVectorsDraft08[] = {
122 // Simple message.
123 {"Hello, world!",
124 {0x0B, 0x32, 0xE2, 0xD1, 0x6A, 0xBF, 0x4F, 0x2C, 0x49, 0xEA, 0xF7,
125 0x5D, 0x71, 0x7D, 0x89, 0xA9, 0xA7, 0x5E, 0x21, 0xB2, 0xB5, 0x51,
126 0xE6, 0x4C, 0x08, 0x68, 0xD3, 0x6F, 0x8F, 0x72, 0x7E, 0x14},
127 {0xD3, 0xF2, 0x78, 0xBD, 0x8D, 0xDD, 0x84, 0x99, 0x66, 0x08, 0xD7, 0x0F,
128 0xBA, 0x9B, 0x60, 0xFC},
129 {0x15, 0x4A, 0xD7, 0x73, 0x92, 0xBD, 0x3B, 0xCF, 0x6F, 0x98, 0xDC, 0x9B,
130 0x8B, 0x56, 0xFB, 0xBD},
131 4096,
132 "3biYN3Aa30D30bKJMdGlEyYPrz7Wg293NYc31rb6"},
133 // Empty message.
134 {"",
135 {0x3F, 0xD8, 0x95, 0x2C, 0xA2, 0x11, 0xBD, 0x7B, 0x57, 0xB2, 0x00,
136 0xBD, 0x57, 0x68, 0x3F, 0xF0, 0x14, 0x57, 0x5F, 0xB1, 0x9F, 0x15,
137 0x4F, 0x11, 0xF0, 0x4D, 0xA2, 0xE8, 0x4C, 0xEA, 0x74, 0x3B},
138 {0xB1, 0xE1, 0xC7, 0x32, 0x4C, 0xAA, 0x56, 0x32, 0x68, 0x20, 0x0F, 0x26,
139 0x3F, 0x48, 0x4D, 0x99},
140 {0xE9, 0x39, 0x45, 0xBC, 0x96, 0x96, 0x88, 0x76, 0xFC, 0xA1, 0xAD, 0xE4,
141 0x9D, 0x28, 0xF3, 0x73},
142 4096,
143 "5OXY345WYPyIvsF7hx4swuA"}};
144
118 const TestVector kDecryptionTestVectorsDraft03[] = { 145 const TestVector kDecryptionTestVectorsDraft03[] = {
119 // Simple message. 146 // Simple message.
120 {"lsemWwzlFoJzoidHCnVuxRiJpotTcYokJHKzmQ2FsA", 147 {"lsemWwzlFoJzoidHCnVuxRiJpotTcYokJHKzmQ2FsA",
121 {0x4D, 0x3A, 0x6C, 0xBA, 0xD8, 0x1D, 0x8E, 0x68, 0x8B, 0xE6, 0x76, 148 {0x4D, 0x3A, 0x6C, 0xBA, 0xD8, 0x1D, 0x8E, 0x68, 0x8B, 0xE6, 0x76,
122 0xA7, 0xFF, 0x60, 0xC7, 0xFE, 0x77, 0xE2, 0x6D, 0x37, 0xF6, 0x12, 149 0xA7, 0xFF, 0x60, 0xC7, 0xFE, 0x77, 0xE2, 0x6D, 0x37, 0xF6, 0x12,
123 0x44, 0xE2, 0x25, 0xFE, 0xE1, 0xD8, 0xCF, 0x8A, 0xA8, 0x33}, 150 0x44, 0xE2, 0x25, 0xFE, 0xE1, 0xD8, 0xCF, 0x8A, 0xA8, 0x33},
124 {0x62, 0x36, 0xAC, 0xCA, 0x74, 0xD4, 0x49, 0x49, 0x6B, 0x27, 0xB4, 0xF7, 151 {0x62, 0x36, 0xAC, 0xCA, 0x74, 0xD4, 0x49, 0x49, 0x6B, 0x27, 0xB4, 0xF7,
125 0xC1, 0xE5, 0x30, 0x9A}, 152 0xC1, 0xE5, 0x30, 0x9A},
126 {0x1C, 0xA7, 0xFD, 0x98, 0x1A, 0xE4, 0xA7, 0x92, 0xE1, 0xB6, 0xA1, 0xE3, 153 {0x1C, 0xA7, 0xFD, 0x98, 0x1A, 0xE4, 0xA7, 0x92, 0xE1, 0xB6, 0xA1, 0xE3,
127 0x41, 0x63, 0x87, 0x76}, 154 0x41, 0x63, 0x87, 0x76},
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 {0xC6, 0x16, 0x6F, 0xAF, 0xE1, 0xB6, 0x8F, 0x2B, 0x0F, 0x67, 0x5A, 203 {0xC6, 0x16, 0x6F, 0xAF, 0xE1, 0xB6, 0x8F, 0x2B, 0x0F, 0x67, 0x5A,
177 0xC7, 0xAC, 0x7E, 0xF6, 0x7C, 0x33, 0xA2, 0xA1, 0x11, 0xB0, 0xB0, 204 0xC7, 0xAC, 0x7E, 0xF6, 0x7C, 0x33, 0xA2, 0xA1, 0x11, 0xB0, 0xB0,
178 0xAB, 0xAC, 0x37, 0x61, 0xF4, 0xCB, 0x98, 0xFF, 0x00, 0x51}, 205 0xAB, 0xAC, 0x37, 0x61, 0xF4, 0xCB, 0x98, 0xFF, 0x00, 0x51},
179 {0xAE, 0xDA, 0x86, 0xDF, 0x6B, 0x03, 0x88, 0xDE, 0x90, 0xBB, 0xB7, 0xA0, 206 {0xAE, 0xDA, 0x86, 0xDF, 0x6B, 0x03, 0x88, 0xDE, 0x90, 0xBB, 0xB7, 0xA0,
180 0x78, 0x91, 0x3A, 0x36}, 207 0x78, 0x91, 0x3A, 0x36},
181 {0x4C, 0x4E, 0x2A, 0x8D, 0x88, 0x82, 0xCF, 0xC2, 0xF9, 0x8A, 0xFD, 0x31, 208 {0x4C, 0x4E, 0x2A, 0x8D, 0x88, 0x82, 0xCF, 0xC2, 0xF9, 0x8A, 0xFD, 0x31,
182 0xF8, 0xD1, 0xF6, 0xB5}, 209 0xF8, 0xD1, 0xF6, 0xB5},
183 8, 210 8,
184 nullptr}}; 211 nullptr}};
185 212
213 const TestVector kDecryptionTestVectorsDraft08[] = {
214 // Simple message.
215 {"baIDPDv-Do_x1RVtlFDex2uCvd3Ugrv-gJG3sWeg",
216 {0x4D, 0x3A, 0x6C, 0xBA, 0xD8, 0x1D, 0x8E, 0x68, 0x8B, 0xE6, 0x76,
217 0xA7, 0xFF, 0x60, 0xC7, 0xFE, 0x77, 0xE2, 0x6D, 0x37, 0xF6, 0x12,
218 0x44, 0xE2, 0x25, 0xFE, 0xE1, 0xD8, 0xCF, 0x8A, 0xA8, 0x33},
219 {0x62, 0x36, 0xAC, 0xCA, 0x74, 0xD4, 0x49, 0x49, 0x6B, 0x27, 0xB4, 0xF7,
220 0xC1, 0xE5, 0x30, 0x9A},
221 {0x1C, 0xA7, 0xFD, 0x98, 0x1A, 0xE4, 0xA7, 0x92, 0xE1, 0xB6, 0xA1, 0xE3,
222 0x41, 0x63, 0x87, 0x76},
223 4096,
224 "Hello, world!"},
225 // Simple message with 16 bytes of padding.
226 {"6Zq7GKQ7zRxeOWoYR71Nx7xJzCZUUNhz6bhV1-ZIg6dVra0x1uWXms5gHp6F6A",
227 {0x8B, 0x38, 0x8E, 0x22, 0xD5, 0xC4, 0xFD, 0x65, 0x8A, 0xBB, 0xD9,
228 0x58, 0xBD, 0xF5, 0xFF, 0x79, 0xCF, 0x9D, 0xBD, 0x87, 0x16, 0x7E,
229 0x93, 0x84, 0x20, 0x8E, 0x8D, 0x49, 0x41, 0x7D, 0x8E, 0x8F},
230 {0x3E, 0x65, 0xC7, 0x1F, 0x75, 0x7A, 0x43, 0xC4, 0x78, 0x6C, 0x64, 0x99,
231 0x49, 0xA0, 0xC4, 0xB2},
232 {0x43, 0x4D, 0x30, 0x8E, 0xE4, 0x76, 0xB5, 0xD0, 0x87, 0xFC, 0x04, 0xD1,
233 0x2E, 0x35, 0x75, 0x63},
234 4096,
235 "Hello, world!"},
236 // Empty message.
237 {"bHU7ponA7WAGB0onUybG9nQ",
238 {0x68, 0x72, 0x3D, 0x13, 0xE7, 0x50, 0xFA, 0x3E, 0xA0, 0x59, 0x33,
239 0xF1, 0x73, 0xA8, 0xE8, 0xCD, 0x8D, 0xD4, 0x3C, 0xDC, 0xDE, 0x06,
240 0x35, 0x5F, 0x51, 0xBB, 0xB2, 0x57, 0x97, 0x72, 0x9D, 0xFB},
241 {0x84, 0xB2, 0x2A, 0xE7, 0xC6, 0xC0, 0xCE, 0x5F, 0xAD, 0x37, 0x06, 0x7F,
242 0xD1, 0xFD, 0x10, 0x87},
243 {0x9B, 0xC5, 0x8D, 0x5F, 0xD6, 0xD2, 0xA6, 0xBD, 0xAF, 0x4B, 0xD9, 0x60,
244 0xC6, 0xB4, 0x50, 0x0F},
245 4096,
246 ""}};
247
186 } // namespace 248 } // namespace
187 249
188 class GCMMessageCryptographerTest : public ::testing::Test { 250 class GCMMessageCryptographerTestBase : public ::testing::Test {
189 public: 251 public:
190 void SetUp() override { 252 void SetUp() override {
191 cryptographer_ = base::MakeUnique<GCMMessageCryptographer>(
192 GCMMessageCryptographer::Version::DRAFT_03);
193
194 recipient_public_key_.assign( 253 recipient_public_key_.assign(
195 kCommonRecipientPublicKey, 254 kCommonRecipientPublicKey,
196 kCommonRecipientPublicKey + arraysize(kCommonRecipientPublicKey)); 255 kCommonRecipientPublicKey + arraysize(kCommonRecipientPublicKey));
197 sender_public_key_.assign( 256 sender_public_key_.assign(
198 kCommonSenderPublicKey, 257 kCommonSenderPublicKey,
199 kCommonSenderPublicKey + arraysize(kCommonSenderPublicKey)); 258 kCommonSenderPublicKey + arraysize(kCommonSenderPublicKey));
200 259
201 std::string recipient_private_key( 260 std::string recipient_private_key(
202 kCommonRecipientPrivateKey, 261 kCommonRecipientPrivateKey,
203 kCommonRecipientPrivateKey + arraysize(kCommonRecipientPrivateKey)); 262 kCommonRecipientPrivateKey + arraysize(kCommonRecipientPrivateKey));
204 263
205 // TODO(peter): Remove the dependency on the x509 keying material when 264 // TODO(peter): Remove the dependency on the x509 keying material when
206 // crbug.com/618025 has been resolved. 265 // crbug.com/618025 has been resolved.
207 std::string recipient_public_key_x509( 266 std::string recipient_public_key_x509(
208 kCommonRecipientPublicKeyX509, 267 kCommonRecipientPublicKeyX509,
209 kCommonRecipientPublicKeyX509 + 268 kCommonRecipientPublicKeyX509 +
210 arraysize(kCommonRecipientPublicKeyX509)); 269 arraysize(kCommonRecipientPublicKeyX509));
211 270
212 ASSERT_TRUE(ComputeSharedP256Secret( 271 ASSERT_TRUE(ComputeSharedP256Secret(
213 recipient_private_key, recipient_public_key_x509, sender_public_key_, 272 recipient_private_key, recipient_public_key_x509, sender_public_key_,
214 &ecdh_shared_secret_)); 273 &ecdh_shared_secret_));
215 274
216 auth_secret_.assign(kCommonAuthSecret, 275 auth_secret_.assign(kCommonAuthSecret,
217 kCommonAuthSecret + arraysize(kCommonAuthSecret)); 276 kCommonAuthSecret + arraysize(kCommonAuthSecret));
218 } 277 }
219 278
220 protected: 279 protected:
221 // Generates a cryptographically secure random salt of 16-octets in size, the
222 // required length as expected by the HKDF.
223 std::string GenerateRandomSalt() {
224 std::string salt;
225
226 crypto::RandBytes(base::WriteInto(&salt, kSaltSize + 1), kSaltSize);
227 return salt;
228 }
229
230 // Public keys of the recipient and sender as uncompressed P-256 EC points. 280 // Public keys of the recipient and sender as uncompressed P-256 EC points.
231 std::string recipient_public_key_; 281 std::string recipient_public_key_;
232 std::string sender_public_key_; 282 std::string sender_public_key_;
233 283
234 // Shared secret to use in transformations. Associated with the keys above. 284 // Shared secret to use in transformations. Associated with the keys above.
235 std::string ecdh_shared_secret_; 285 std::string ecdh_shared_secret_;
236 286
237 // Authentication secret to use in tests where no specific value is expected. 287 // Authentication secret to use in tests where no specific value is expected.
238 std::string auth_secret_; 288 std::string auth_secret_;
289 };
290
291 class GCMMessageCryptographerTest
292 : public GCMMessageCryptographerTestBase,
293 public testing::WithParamInterface<GCMMessageCryptographer::Version> {
294 public:
295 void SetUp() override {
296 GCMMessageCryptographerTestBase::SetUp();
297
298 cryptographer_ = base::MakeUnique<GCMMessageCryptographer>(GetParam());
299 }
300
301 protected:
302 // Generates a cryptographically secure random salt of 16-octets in size, the
303 // required length as expected by the HKDF.
304 std::string GenerateRandomSalt() {
305 std::string salt;
306
307 crypto::RandBytes(base::WriteInto(&salt, kSaltSize + 1), kSaltSize);
308 return salt;
309 }
239 310
240 // The GCMMessageCryptographer instance to use for the tests. 311 // The GCMMessageCryptographer instance to use for the tests.
241 std::unique_ptr<GCMMessageCryptographer> cryptographer_; 312 std::unique_ptr<GCMMessageCryptographer> cryptographer_;
242 }; 313 };
243 314
244 TEST_F(GCMMessageCryptographerTest, RoundTrip) { 315 TEST_P(GCMMessageCryptographerTest, RoundTrip) {
245 const std::string salt = GenerateRandomSalt(); 316 const std::string salt = GenerateRandomSalt();
246 317
247 size_t record_size = 0; 318 size_t record_size = 0;
248 319
249 std::string ciphertext, plaintext; 320 std::string ciphertext, plaintext;
250 ASSERT_TRUE(cryptographer_->Encrypt( 321 ASSERT_TRUE(cryptographer_->Encrypt(
251 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, 322 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
252 auth_secret_, salt, kExamplePlaintext, &record_size, &ciphertext)); 323 auth_secret_, salt, kExamplePlaintext, &record_size, &ciphertext));
253 324
254 EXPECT_GT(record_size, ciphertext.size() - 16); 325 EXPECT_GT(record_size, ciphertext.size() - 16);
255 EXPECT_GT(ciphertext.size(), 0u); 326 EXPECT_GT(ciphertext.size(), 0u);
256 327
257 ASSERT_TRUE(cryptographer_->Decrypt(recipient_public_key_, sender_public_key_, 328 ASSERT_TRUE(cryptographer_->Decrypt(recipient_public_key_, sender_public_key_,
258 ecdh_shared_secret_, auth_secret_, salt, 329 ecdh_shared_secret_, auth_secret_, salt,
259 ciphertext, record_size, &plaintext)); 330 ciphertext, record_size, &plaintext));
260 331
261 EXPECT_EQ(kExamplePlaintext, plaintext); 332 EXPECT_EQ(kExamplePlaintext, plaintext);
262 } 333 }
263 334
264 TEST_F(GCMMessageCryptographerTest, RoundTripEmptyMessage) { 335 TEST_P(GCMMessageCryptographerTest, RoundTripEmptyMessage) {
265 const std::string salt = GenerateRandomSalt(); 336 const std::string salt = GenerateRandomSalt();
266 const std::string message = ""; 337 const std::string message = "";
267 338
268 size_t record_size = 0; 339 size_t record_size = 0;
269 340
270 std::string ciphertext, plaintext; 341 std::string ciphertext, plaintext;
271 ASSERT_TRUE(cryptographer_->Encrypt(recipient_public_key_, sender_public_key_, 342 ASSERT_TRUE(cryptographer_->Encrypt(recipient_public_key_, sender_public_key_,
272 ecdh_shared_secret_, auth_secret_, salt, 343 ecdh_shared_secret_, auth_secret_, salt,
273 message, &record_size, &ciphertext)); 344 message, &record_size, &ciphertext));
274 345
275 EXPECT_GT(record_size, ciphertext.size() - 16); 346 EXPECT_GT(record_size, ciphertext.size() - 16);
276 EXPECT_GT(ciphertext.size(), 0u); 347 EXPECT_GT(ciphertext.size(), 0u);
277 348
278 ASSERT_TRUE(cryptographer_->Decrypt(recipient_public_key_, sender_public_key_, 349 ASSERT_TRUE(cryptographer_->Decrypt(recipient_public_key_, sender_public_key_,
279 ecdh_shared_secret_, auth_secret_, salt, 350 ecdh_shared_secret_, auth_secret_, salt,
280 ciphertext, record_size, &plaintext)); 351 ciphertext, record_size, &plaintext));
281 352
282 EXPECT_EQ(message, plaintext); 353 EXPECT_EQ(message, plaintext);
283 } 354 }
284 355
285 TEST_F(GCMMessageCryptographerTest, InvalidRecordSize) { 356 TEST_P(GCMMessageCryptographerTest, InvalidRecordSize) {
286 const std::string salt = GenerateRandomSalt(); 357 const std::string salt = GenerateRandomSalt();
287 358
288 size_t record_size = 0; 359 size_t record_size = 0;
289 360
290 std::string ciphertext, plaintext; 361 std::string ciphertext, plaintext;
291 ASSERT_TRUE(cryptographer_->Encrypt( 362 ASSERT_TRUE(cryptographer_->Encrypt(
292 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, 363 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
293 auth_secret_, salt, kExamplePlaintext, &record_size, &ciphertext)); 364 auth_secret_, salt, kExamplePlaintext, &record_size, &ciphertext));
294 365
295 EXPECT_GT(record_size, ciphertext.size() - 16); 366 EXPECT_GT(record_size, ciphertext.size() - 16);
296 367
297 EXPECT_FALSE(cryptographer_->Decrypt( 368 EXPECT_FALSE(cryptographer_->Decrypt(
298 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, 369 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
299 auth_secret_, salt, ciphertext, 0 /* record_size */, &plaintext)); 370 auth_secret_, salt, ciphertext, 0 /* record_size */, &plaintext));
300 371
301 EXPECT_FALSE(cryptographer_->Decrypt( 372 EXPECT_FALSE(cryptographer_->Decrypt(
302 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, 373 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
303 auth_secret_, salt, ciphertext, ciphertext.size() - 17, &plaintext)); 374 auth_secret_, salt, ciphertext, ciphertext.size() - 17, &plaintext));
304 375
305 EXPECT_TRUE(cryptographer_->Decrypt( 376 EXPECT_TRUE(cryptographer_->Decrypt(
306 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, 377 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
307 auth_secret_, salt, ciphertext, ciphertext.size() - 16, &plaintext)); 378 auth_secret_, salt, ciphertext, ciphertext.size() - 16, &plaintext));
308 } 379 }
309 380
310 TEST_F(GCMMessageCryptographerTest, InvalidRecordPadding) { 381 TEST_P(GCMMessageCryptographerTest, InvalidRecordPadding) {
311 std::string message = std::string(sizeof(uint16_t), '\0') + kExamplePlaintext; 382 std::string message;
383 switch (GetParam()) {
384 case GCMMessageCryptographer::Version::DRAFT_03:
385 message.append(sizeof(uint8_t), '\00'); // padding length octets
386 message.append(sizeof(uint8_t), '\01');
387
388 message.append(sizeof(uint8_t), '\00'); // padding octet
389 message.append(kExamplePlaintext);
390 break;
391 case GCMMessageCryptographer::Version::DRAFT_08:
392 message.append(kExamplePlaintext);
393 message.append(sizeof(uint8_t), '\x02'); // padding delimiter octet
394 message.append(sizeof(uint8_t), '\x00'); // padding octet
395 break;
396 }
312 397
313 const std::string salt = GenerateRandomSalt(); 398 const std::string salt = GenerateRandomSalt();
314 399
315 const std::string prk = 400 const std::string prk =
316 cryptographer_->encryption_scheme_->DerivePseudoRandomKey( 401 cryptographer_->encryption_scheme_->DerivePseudoRandomKey(
317 ecdh_shared_secret_, auth_secret_); 402 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
403 auth_secret_);
318 const std::string content_encryption_key = 404 const std::string content_encryption_key =
319 cryptographer_->DeriveContentEncryptionKey(recipient_public_key_, 405 cryptographer_->DeriveContentEncryptionKey(recipient_public_key_,
320 sender_public_key_, prk, salt); 406 sender_public_key_, prk, salt);
321 const std::string nonce = cryptographer_->DeriveNonce( 407 const std::string nonce = cryptographer_->DeriveNonce(
322 recipient_public_key_, sender_public_key_, prk, salt); 408 recipient_public_key_, sender_public_key_, prk, salt);
323 409
324 ASSERT_GT(message.size(), 1u); 410 ASSERT_GT(message.size(), 2u);
325 const size_t record_size = message.size() + 1; 411 const size_t record_size = message.size() + 1;
326 412
327 std::string ciphertext, plaintext; 413 std::string ciphertext, plaintext;
328 ASSERT_TRUE(cryptographer_->TransformRecord( 414 ASSERT_TRUE(cryptographer_->TransformRecord(
329 GCMMessageCryptographer::Direction::ENCRYPT, message, 415 GCMMessageCryptographer::Direction::ENCRYPT, message,
330 content_encryption_key, nonce, &ciphertext)); 416 content_encryption_key, nonce, &ciphertext));
331 417
332 ASSERT_TRUE(cryptographer_->Decrypt(recipient_public_key_, sender_public_key_, 418 ASSERT_TRUE(cryptographer_->Decrypt(recipient_public_key_, sender_public_key_,
333 ecdh_shared_secret_, auth_secret_, salt, 419 ecdh_shared_secret_, auth_secret_, salt,
334 ciphertext, record_size, &plaintext)); 420 ciphertext, record_size, &plaintext));
335 421
336 // Note that GCMMessageCryptographer::Decrypt removes the padding. 422 // Note that GCMMessageCryptographer::Decrypt removes the padding.
337 EXPECT_EQ(kExamplePlaintext, plaintext); 423 EXPECT_EQ(kExamplePlaintext, plaintext);
338 424
339 // Now run the same steps again, but say that there are four padding octets. 425 // Now run the same steps again, but have invalid padding length indicators.
340 // This should be rejected because the padding will not be all zeros. 426 // (Only applicable to draft-ietf-webpush-encryption-03.)
341 message[0] = 4; 427 if (GetParam() == GCMMessageCryptographer::Version::DRAFT_03) {
428 // Padding that will spill over in the payload.
429 {
430 message[1] = 4;
431
432 ASSERT_TRUE(cryptographer_->TransformRecord(
433 GCMMessageCryptographer::Direction::ENCRYPT, message,
434 content_encryption_key, nonce, &ciphertext));
435
436 ASSERT_FALSE(cryptographer_->Decrypt(
437 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
438 auth_secret_, salt, ciphertext, record_size, &plaintext));
439 }
440
441 // More padding octets than the length of the message.
442 {
443 message[1] = 64;
444
445 ASSERT_TRUE(cryptographer_->TransformRecord(
446 GCMMessageCryptographer::Direction::ENCRYPT, message,
447 content_encryption_key, nonce, &ciphertext));
448
449 ASSERT_FALSE(cryptographer_->Decrypt(
450 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
451 auth_secret_, salt, ciphertext, record_size, &plaintext));
452 }
453
454 // Correct the |message| to be valid again. (A single byte of padding.)
455 message[1] = 1;
456 }
457
458 // Run tests for a missing delimiter in the record.
459 // (Only applicable to draft-ietf-webpush-encryption-03.)
460 if (GetParam() == GCMMessageCryptographer::Version::DRAFT_08) {
461 message[message.size() - 2] = 0x00;
462
463 ASSERT_TRUE(cryptographer_->TransformRecord(
464 GCMMessageCryptographer::Direction::ENCRYPT, message,
465 content_encryption_key, nonce, &ciphertext));
466
467 ASSERT_FALSE(cryptographer_->Decrypt(
468 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
469 auth_secret_, salt, ciphertext, record_size, &plaintext));
470
471 // Correct the |message| to be valid again. (Proper padding delimiter.)
472 message[message.size() - 2] = 0x02;
473 }
474
475 // Finally run a test to make sure that we validate that all padding bytes are
476 // set to zeros. The position of the padding byte depends on the version.
477 switch (GetParam()) {
478 case GCMMessageCryptographer::Version::DRAFT_03:
479 message[2] = 0x13;
480 break;
481 case GCMMessageCryptographer::Version::DRAFT_08:
482 message[message.size() - 1] = 0x13;
483 break;
484 }
342 485
343 ASSERT_TRUE(cryptographer_->TransformRecord( 486 ASSERT_TRUE(cryptographer_->TransformRecord(
344 GCMMessageCryptographer::Direction::ENCRYPT, message, 487 GCMMessageCryptographer::Direction::ENCRYPT, message,
345 content_encryption_key, nonce, &ciphertext)); 488 content_encryption_key, nonce, &ciphertext));
346
347 ASSERT_FALSE(cryptographer_->Decrypt(
348 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
349 auth_secret_, salt, ciphertext, record_size, &plaintext));
350
351 // Do the same but changing the second octet indicating padding size, leaving
352 // the first octet at zero.
353 message[0] = 0;
354 message[1] = 4;
355
356 ASSERT_TRUE(cryptographer_->TransformRecord(
357 GCMMessageCryptographer::Direction::ENCRYPT, message,
358 content_encryption_key, nonce, &ciphertext));
359
360 ASSERT_FALSE(cryptographer_->Decrypt(
361 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
362 auth_secret_, salt, ciphertext, record_size, &plaintext));
363
364 // Run the same steps again, but say that there are more padding octets than
365 // the length of the message.
366 message[0] = 64;
367
368 EXPECT_GT(static_cast<size_t>(message[0]), message.size());
369 ASSERT_TRUE(cryptographer_->TransformRecord(
370 GCMMessageCryptographer::Direction::ENCRYPT, message,
371 content_encryption_key, nonce, &ciphertext));
372 489
373 ASSERT_FALSE(cryptographer_->Decrypt( 490 ASSERT_FALSE(cryptographer_->Decrypt(
374 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, 491 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
375 auth_secret_, salt, ciphertext, record_size, &plaintext)); 492 auth_secret_, salt, ciphertext, record_size, &plaintext));
376 } 493 }
377 494
378 TEST_F(GCMMessageCryptographerTest, AuthSecretAffectsPRK) { 495 TEST_P(GCMMessageCryptographerTest, AuthSecretAffectsPRK) {
379 std::string first_auth_secret, second_auth_secret; 496 std::string first_auth_secret, second_auth_secret;
380 497
381 crypto::RandBytes(base::WriteInto(&first_auth_secret, kAuthSecretSize + 1), 498 crypto::RandBytes(base::WriteInto(&first_auth_secret, kAuthSecretSize + 1),
382 kAuthSecretSize); 499 kAuthSecretSize);
383 crypto::RandBytes(base::WriteInto(&second_auth_secret, kAuthSecretSize + 1), 500 crypto::RandBytes(base::WriteInto(&second_auth_secret, kAuthSecretSize + 1),
384 kAuthSecretSize); 501 kAuthSecretSize);
385 502
386 ASSERT_NE(cryptographer_->encryption_scheme_->DerivePseudoRandomKey( 503 ASSERT_NE(cryptographer_->encryption_scheme_->DerivePseudoRandomKey(
387 ecdh_shared_secret_, first_auth_secret), 504 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
505 first_auth_secret),
388 cryptographer_->encryption_scheme_->DerivePseudoRandomKey( 506 cryptographer_->encryption_scheme_->DerivePseudoRandomKey(
389 ecdh_shared_secret_, second_auth_secret)); 507 recipient_public_key_, sender_public_key_, ecdh_shared_secret_,
508 second_auth_secret));
390 509
391 std::string salt = GenerateRandomSalt(); 510 std::string salt = GenerateRandomSalt();
392 511
393 // Verify that the IKM actually gets used by the transformations. 512 // Verify that the IKM actually gets used by the transformations.
394 size_t first_record_size, second_record_size; 513 size_t first_record_size, second_record_size;
395 std::string first_ciphertext, second_ciphertext; 514 std::string first_ciphertext, second_ciphertext;
396 515
397 ASSERT_TRUE(cryptographer_->Encrypt(recipient_public_key_, sender_public_key_, 516 ASSERT_TRUE(cryptographer_->Encrypt(recipient_public_key_, sender_public_key_,
398 ecdh_shared_secret_, first_auth_secret, 517 ecdh_shared_secret_, first_auth_secret,
399 salt, kExamplePlaintext, 518 salt, kExamplePlaintext,
(...skipping 19 matching lines...) Expand all
419 538
420 ASSERT_TRUE(cryptographer_->Decrypt(recipient_public_key_, sender_public_key_, 539 ASSERT_TRUE(cryptographer_->Decrypt(recipient_public_key_, sender_public_key_,
421 ecdh_shared_secret_, second_auth_secret, 540 ecdh_shared_secret_, second_auth_secret,
422 salt, second_ciphertext, 541 salt, second_ciphertext,
423 second_record_size, &second_plaintext)); 542 second_record_size, &second_plaintext));
424 543
425 EXPECT_EQ(kExamplePlaintext, first_plaintext); 544 EXPECT_EQ(kExamplePlaintext, first_plaintext);
426 EXPECT_EQ(kExamplePlaintext, second_plaintext); 545 EXPECT_EQ(kExamplePlaintext, second_plaintext);
427 } 546 }
428 547
548 INSTANTIATE_TEST_CASE_P(
549 GCMMessageCryptographerTestBase,
550 GCMMessageCryptographerTest,
551 ::testing::Values(GCMMessageCryptographer::Version::DRAFT_03,
552 GCMMessageCryptographer::Version::DRAFT_08));
553
429 class GCMMessageCryptographerTestVectorTest 554 class GCMMessageCryptographerTestVectorTest
430 : public GCMMessageCryptographerTest {}; 555 : public GCMMessageCryptographerTestBase {};
431 556
432 TEST_F(GCMMessageCryptographerTestVectorTest, EncryptionVectorsDraft03) { 557 TEST_F(GCMMessageCryptographerTestVectorTest, EncryptionVectorsDraft03) {
558 GCMMessageCryptographer cryptographer(
559 GCMMessageCryptographer::Version::DRAFT_03);
560
433 std::string ecdh_shared_secret, auth_secret, salt, ciphertext, output; 561 std::string ecdh_shared_secret, auth_secret, salt, ciphertext, output;
434 size_t record_size = 0; 562 size_t record_size = 0;
435 563
436 for (size_t i = 0; i < arraysize(kEncryptionTestVectorsDraft03); ++i) { 564 for (size_t i = 0; i < arraysize(kEncryptionTestVectorsDraft03); ++i) {
437 SCOPED_TRACE(i); 565 SCOPED_TRACE(i);
438 566
439 ecdh_shared_secret.assign( 567 ecdh_shared_secret.assign(
440 kEncryptionTestVectorsDraft03[i].ecdh_shared_secret, 568 kEncryptionTestVectorsDraft03[i].ecdh_shared_secret,
441 kEncryptionTestVectorsDraft03[i].ecdh_shared_secret + 569 kEncryptionTestVectorsDraft03[i].ecdh_shared_secret +
442 kEcdhSharedSecretSize); 570 kEcdhSharedSecretSize);
443 571
444 auth_secret.assign( 572 auth_secret.assign(
445 kEncryptionTestVectorsDraft03[i].auth_secret, 573 kEncryptionTestVectorsDraft03[i].auth_secret,
446 kEncryptionTestVectorsDraft03[i].auth_secret + kAuthSecretSize); 574 kEncryptionTestVectorsDraft03[i].auth_secret + kAuthSecretSize);
447 575
448 salt.assign(kEncryptionTestVectorsDraft03[i].salt, 576 salt.assign(kEncryptionTestVectorsDraft03[i].salt,
449 kEncryptionTestVectorsDraft03[i].salt + kSaltSize); 577 kEncryptionTestVectorsDraft03[i].salt + kSaltSize);
450 578
451 ASSERT_TRUE(cryptographer_->Encrypt( 579 ASSERT_TRUE(cryptographer.Encrypt(recipient_public_key_, sender_public_key_,
452 recipient_public_key_, sender_public_key_, ecdh_shared_secret, 580 ecdh_shared_secret, auth_secret, salt,
453 auth_secret, salt, kEncryptionTestVectorsDraft03[i].input, &record_size, 581 kEncryptionTestVectorsDraft03[i].input,
454 &ciphertext)); 582 &record_size, &ciphertext));
455 583
456 base::Base64UrlEncode(ciphertext, base::Base64UrlEncodePolicy::OMIT_PADDING, 584 base::Base64UrlEncode(ciphertext, base::Base64UrlEncodePolicy::OMIT_PADDING,
457 &output); 585 &output);
458 586
459 EXPECT_EQ(kEncryptionTestVectorsDraft03[i].record_size, record_size); 587 EXPECT_EQ(kEncryptionTestVectorsDraft03[i].record_size, record_size);
460 EXPECT_EQ(kEncryptionTestVectorsDraft03[i].output, output); 588 EXPECT_EQ(kEncryptionTestVectorsDraft03[i].output, output);
461 } 589 }
462 } 590 }
463 591
464 TEST_F(GCMMessageCryptographerTestVectorTest, DecryptionVectorsDraft03) { 592 TEST_F(GCMMessageCryptographerTestVectorTest, DecryptionVectorsDraft03) {
593 GCMMessageCryptographer cryptographer(
594 GCMMessageCryptographer::Version::DRAFT_03);
595
465 std::string input, ecdh_shared_secret, auth_secret, salt, plaintext; 596 std::string input, ecdh_shared_secret, auth_secret, salt, plaintext;
466 for (size_t i = 0; i < arraysize(kDecryptionTestVectorsDraft03); ++i) { 597 for (size_t i = 0; i < arraysize(kDecryptionTestVectorsDraft03); ++i) {
467 SCOPED_TRACE(i); 598 SCOPED_TRACE(i);
468 599
469 ASSERT_TRUE(base::Base64UrlDecode( 600 ASSERT_TRUE(base::Base64UrlDecode(
470 kDecryptionTestVectorsDraft03[i].input, 601 kDecryptionTestVectorsDraft03[i].input,
471 base::Base64UrlDecodePolicy::IGNORE_PADDING, &input)); 602 base::Base64UrlDecodePolicy::IGNORE_PADDING, &input));
472 603
473 ecdh_shared_secret.assign( 604 ecdh_shared_secret.assign(
474 kDecryptionTestVectorsDraft03[i].ecdh_shared_secret, 605 kDecryptionTestVectorsDraft03[i].ecdh_shared_secret,
475 kDecryptionTestVectorsDraft03[i].ecdh_shared_secret + 606 kDecryptionTestVectorsDraft03[i].ecdh_shared_secret +
476 kEcdhSharedSecretSize); 607 kEcdhSharedSecretSize);
477 608
478 auth_secret.assign( 609 auth_secret.assign(
479 kDecryptionTestVectorsDraft03[i].auth_secret, 610 kDecryptionTestVectorsDraft03[i].auth_secret,
480 kDecryptionTestVectorsDraft03[i].auth_secret + kAuthSecretSize); 611 kDecryptionTestVectorsDraft03[i].auth_secret + kAuthSecretSize);
481 612
482 salt.assign(kDecryptionTestVectorsDraft03[i].salt, 613 salt.assign(kDecryptionTestVectorsDraft03[i].salt,
483 kDecryptionTestVectorsDraft03[i].salt + kSaltSize); 614 kDecryptionTestVectorsDraft03[i].salt + kSaltSize);
484 615
485 const bool has_output = kDecryptionTestVectorsDraft03[i].output; 616 const bool has_output = kDecryptionTestVectorsDraft03[i].output;
486 const bool result = cryptographer_->Decrypt( 617 const bool result = cryptographer.Decrypt(
487 recipient_public_key_, sender_public_key_, ecdh_shared_secret, 618 recipient_public_key_, sender_public_key_, ecdh_shared_secret,
488 auth_secret, salt, input, kDecryptionTestVectorsDraft03[i].record_size, 619 auth_secret, salt, input, kDecryptionTestVectorsDraft03[i].record_size,
489 &plaintext); 620 &plaintext);
490 621
491 if (!has_output) { 622 if (!has_output) {
492 EXPECT_FALSE(result); 623 EXPECT_FALSE(result);
493 continue; 624 continue;
494 } 625 }
495 626
496 EXPECT_TRUE(result); 627 EXPECT_TRUE(result);
497 EXPECT_EQ(kDecryptionTestVectorsDraft03[i].output, plaintext); 628 EXPECT_EQ(kDecryptionTestVectorsDraft03[i].output, plaintext);
498 } 629 }
499 } 630 }
500 631
632 TEST_F(GCMMessageCryptographerTestVectorTest, EncryptionVectorsDraft08) {
633 GCMMessageCryptographer cryptographer(
634 GCMMessageCryptographer::Version::DRAFT_08);
635
636 std::string ecdh_shared_secret, auth_secret, salt, ciphertext, output;
637 size_t record_size = 0;
638
639 for (size_t i = 0; i < arraysize(kEncryptionTestVectorsDraft08); ++i) {
640 SCOPED_TRACE(i);
641
642 ecdh_shared_secret.assign(
643 kEncryptionTestVectorsDraft08[i].ecdh_shared_secret,
644 kEncryptionTestVectorsDraft08[i].ecdh_shared_secret +
645 kEcdhSharedSecretSize);
646
647 auth_secret.assign(
648 kEncryptionTestVectorsDraft08[i].auth_secret,
649 kEncryptionTestVectorsDraft08[i].auth_secret + kAuthSecretSize);
650
651 salt.assign(kEncryptionTestVectorsDraft08[i].salt,
652 kEncryptionTestVectorsDraft08[i].salt + kSaltSize);
653
654 ASSERT_TRUE(cryptographer.Encrypt(recipient_public_key_, sender_public_key_,
655 ecdh_shared_secret, auth_secret, salt,
656 kEncryptionTestVectorsDraft08[i].input,
657 &record_size, &ciphertext));
658
659 base::Base64UrlEncode(ciphertext, base::Base64UrlEncodePolicy::OMIT_PADDING,
660 &output);
661
662 EXPECT_EQ(kEncryptionTestVectorsDraft08[i].record_size, record_size);
663 EXPECT_EQ(kEncryptionTestVectorsDraft08[i].output, output);
664 }
665 }
666
667 TEST_F(GCMMessageCryptographerTestVectorTest, DecryptionVectorsDraft08) {
668 GCMMessageCryptographer cryptographer(
669 GCMMessageCryptographer::Version::DRAFT_08);
670
671 std::string input, ecdh_shared_secret, auth_secret, salt, plaintext;
672
673 for (size_t i = 0; i < arraysize(kDecryptionTestVectorsDraft08); ++i) {
674 SCOPED_TRACE(i);
675
676 ASSERT_TRUE(base::Base64UrlDecode(
677 kDecryptionTestVectorsDraft08[i].input,
678 base::Base64UrlDecodePolicy::IGNORE_PADDING, &input));
679
680 ecdh_shared_secret.assign(
681 kDecryptionTestVectorsDraft08[i].ecdh_shared_secret,
682 kDecryptionTestVectorsDraft08[i].ecdh_shared_secret +
683 kEcdhSharedSecretSize);
684
685 auth_secret.assign(
686 kDecryptionTestVectorsDraft08[i].auth_secret,
687 kDecryptionTestVectorsDraft08[i].auth_secret + kAuthSecretSize);
688
689 salt.assign(kDecryptionTestVectorsDraft08[i].salt,
690 kDecryptionTestVectorsDraft08[i].salt + kSaltSize);
691
692 const bool has_output = kDecryptionTestVectorsDraft08[i].output;
693 const bool result = cryptographer.Decrypt(
694 recipient_public_key_, sender_public_key_, ecdh_shared_secret,
695 auth_secret, salt, input, kDecryptionTestVectorsDraft08[i].record_size,
696 &plaintext);
697
698 if (!has_output) {
699 EXPECT_FALSE(result);
700 continue;
701 }
702
703 EXPECT_TRUE(result);
704 EXPECT_EQ(kDecryptionTestVectorsDraft08[i].output, plaintext);
705 }
706 }
707
501 class GCMMessageCryptographerReferenceTest : public ::testing::Test { 708 class GCMMessageCryptographerReferenceTest : public ::testing::Test {
502 protected: 709 protected:
503 // Computes the shared secret between the sender and the receiver. The sender 710 // Computes the shared secret between the sender and the receiver. The sender
504 // must have a key-pair containing a X.509 SubjectPublicKeyInfo block and a 711 // must have a key-pair containing a X.509 SubjectPublicKeyInfo block and a
505 // ASN.1-encoded PKCS #8 EncryptedPrivateKeyInfo block, whereas the receiver 712 // ASN.1-encoded PKCS #8 EncryptedPrivateKeyInfo block, whereas the receiver
506 // must have a public key in uncompressed EC point format. 713 // must have a public key in uncompressed EC point format.
507 void ComputeSharedSecret(const char* encoded_sender_private_key, 714 void ComputeSharedSecret(
508 const char* encoded_sender_public_key_x509, 715 const base::StringPiece& encoded_sender_private_key,
509 const char* encoded_receiver_public_key, 716 const base::StringPiece& encoded_sender_public_key_x509,
510 std::string* shared_secret) const { 717 const base::StringPiece& encoded_receiver_public_key,
718 std::string* shared_secret) const {
511 std::string sender_private_key, sender_public_key_x509, receiver_public_key; 719 std::string sender_private_key, sender_public_key_x509, receiver_public_key;
512 ASSERT_TRUE(base::Base64UrlDecode( 720 ASSERT_TRUE(base::Base64UrlDecode(
513 encoded_sender_private_key, 721 encoded_sender_private_key,
514 base::Base64UrlDecodePolicy::IGNORE_PADDING, &sender_private_key)); 722 base::Base64UrlDecodePolicy::IGNORE_PADDING, &sender_private_key));
515 ASSERT_TRUE(base::Base64UrlDecode( 723 ASSERT_TRUE(base::Base64UrlDecode(
516 encoded_sender_public_key_x509, 724 encoded_sender_public_key_x509,
517 base::Base64UrlDecodePolicy::IGNORE_PADDING, &sender_public_key_x509)); 725 base::Base64UrlDecodePolicy::IGNORE_PADDING, &sender_public_key_x509));
518 ASSERT_TRUE(base::Base64UrlDecode( 726 ASSERT_TRUE(base::Base64UrlDecode(
519 encoded_receiver_public_key, 727 encoded_receiver_public_key,
520 base::Base64UrlDecodePolicy::IGNORE_PADDING, &receiver_public_key)); 728 base::Base64UrlDecodePolicy::IGNORE_PADDING, &receiver_public_key));
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 ASSERT_EQ(kCiphertext, encoded_ciphertext); 816 ASSERT_EQ(kCiphertext, encoded_ciphertext);
609 817
610 // And verify that decrypting the message yields the plaintext again. 818 // And verify that decrypting the message yields the plaintext again.
611 ASSERT_TRUE(cryptographer.Decrypt(recipient_public_key, sender_public_key, 819 ASSERT_TRUE(cryptographer.Decrypt(recipient_public_key, sender_public_key,
612 sender_shared_secret, auth_secret, salt, 820 sender_shared_secret, auth_secret, salt,
613 ciphertext, record_size, &plaintext)); 821 ciphertext, record_size, &plaintext));
614 822
615 ASSERT_EQ(kPlaintext, plaintext); 823 ASSERT_EQ(kPlaintext, plaintext);
616 } 824 }
617 825
826 // Reference test included for the Version::DRAFT_08 implementation.
827 // https://tools.ietf.org/html/draft-ietf-webpush-encryption-08
828 // https://tools.ietf.org/html/draft-ietf-httpbis-encryption-encoding-07
829 TEST_F(GCMMessageCryptographerReferenceTest, ReferenceDraft08) {
830 // The 16-byte prearranged secret between the sender and receiver.
831 const char kAuthSecret[] = "BTBZMqHH6r4Tts7J_aSIgg";
832
833 // The keying material used by the sender to encrypt the |kCiphertext|.
834 const char kSenderPrivate[] =
835 "MIGxMBwGCiqGSIb3DQEMAQMwDgQIScUGT5GSrLoCAggABIGQMr4LCZNVg8uqAo5MSUrI5cCV"
836 "AyQzjG7jdSXooDx_yPXgwMskoNzKhBXIG0AZF7MBimdXFTg_wlv38empWRr_-x4fnQiIBKya"
837 "pt6uBOfYVuE_nnhqudqvSxiiv6hikBvxS2zabgph8-vFPQG10uUv8xkAO6vPdtTABCUzCXQU"
838 "p1QmuP471ZdaNAMuCPmxry-C";
839 const char kSenderPublicX509[] =
840 "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE_jP0qw3qcZFNtVgj9ztUlI9BMG2SBzLbuaWa"
841 "UyhkgiAOWXp7e8JguhwieZhYCZLpOXMALzASooro8Gu7eOXsDw";
842
843 // The keying material used by the recipient to decrypt the |kCiphertext|.
844 const char kRecipientPrivate[] =
845 "MIGxMBwGCiqGSIb3DQEMAQMwDgQIFMj5PQ6zlvwCAggABIGQfr9ZUZd5kr5Wf3AnThoNI8mr"
846 "V3dkpfaKWc725soIIny8V1l_-8AkfbsisM7VpEmZMWKhjSoCKtq970vb-27xUGUCtxy6Mhij"
847 "r4suUqirpM1noA1oKd0O0ap7_zHG4X6j2iA-4UPC0T4lSIscgmRZJWKQeA_7U0pUfryhTolM"
848 "o175tTl399amT66tOGI2wn3O";
849 const char kRecipientPublicKeyUncompressed[] =
850 "BCVxsr7N_eNgVRqvHtD0zTZsEc6-VV-JvLexhqUzORcxaOzi6-AYWXvTBHm4bjyPjs7Vd8pZ"
851 "GH6SRpkNtoIAiw4";
852 const char kRecipientPublicX509[] =
853 "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJXGyvs3942BVGq8e0PTNNmwRzr5VX4m8t7GG"
854 "pTM5FzFo7OLr4BhZe9MEebhuPI-OztV3ylkYfpJGmQ22ggCLDg";
855
856 // The plain text of the message, as well as the encrypted reference message.
857 const char kPlaintext[] = "When I grow up, I want to be a watermelon";
858 const char kReferenceMessage[] =
859 "DGv6ra1nlYgDCS1FRnbzlwAAEABBBP4z9KsN6nGRTbVYI_"
860 "c7VJSPQTBtkgcy27mlmlMoZIIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A_"
861 "yl95bQpu6cVPTpK4Mqgkf1CXztLVBSt2Ks3oZwbuwXPXLWyouBWLVWGNWQexSgSxsj_"
862 "Qulcy4a-fN";
863
864 std::string message;
865 ASSERT_TRUE(base::Base64UrlDecode(kReferenceMessage,
866 base::Base64UrlDecodePolicy::IGNORE_PADDING,
867 &message));
868
869 // TODO(peter): Break out the following in a separate message parser class so
870 // that it can be reused by the GCMEncryptionProvider (on the receiving path)
871 // and the gcm_crypto_test_helpers.cc file (on the sending path) too.
872 //
873 // The message contains a binary header in the following format:
874 // [ salt(16) | record_size(4) | sender_public_key_len(1) |
875 // sender_public_key(sender_public_key_len) ]
876 //
877 // For Web Push Encryption, which uses a P-256 sender key as uncompressed
878 // P-256 EC points, the length of the sender key is 65 bytes, making the
879 // total, fixed length of the header 86 bytes.
880 //
881 // The regular AEAD_AES_128_GCM ciphertext follows immediately after this. The
882 // minimum overhead for a single record is 18 bytes. This means that an
883 // incoming message must be at least 104 bytes in size.
884 ASSERT_GE(message.size(), 104u);
885
886 const char* current = &message.front();
887
888 uint32_t record_size;
889 uint8_t sender_public_key_length;
890
891 base::StringPiece salt(current, kSaltSize);
892 current += kSaltSize;
893
894 base::ReadBigEndian(current, &record_size);
895 current += sizeof(record_size);
896
897 base::ReadBigEndian(current, &sender_public_key_length);
898 current += sizeof(sender_public_key_length);
899
900 ASSERT_EQ(sender_public_key_length, kUncompressedPointSize);
901
902 base::StringPiece sender_public_key(current, sender_public_key_length);
903 current += sender_public_key_length;
904
905 base::StringPiece ciphertext(
906 current, message.size() - kSaltSize - sizeof(record_size) -
907 sizeof(sender_public_key_length) - sender_public_key_length);
908
909 std::string sender_shared_secret, receiver_shared_secret;
910
911 // Compute the shared secrets between the sender and receiver's keys.
912 ASSERT_NO_FATAL_FAILURE(ComputeSharedSecret(kSenderPrivate, kSenderPublicX509,
913 kRecipientPublicKeyUncompressed,
914 &sender_shared_secret));
915
916 // Compute the shared secret based on the sender's public key, which isn't a
917 // constant but instead is included in the message's binary header.
918 std::string sender_private_key, sender_public_key_x509;
919 ASSERT_TRUE(base::Base64UrlDecode(kRecipientPrivate,
920 base::Base64UrlDecodePolicy::IGNORE_PADDING,
921 &sender_private_key));
922 ASSERT_TRUE(base::Base64UrlDecode(kRecipientPublicX509,
923 base::Base64UrlDecodePolicy::IGNORE_PADDING,
924 &sender_public_key_x509));
925
926 ASSERT_TRUE(ComputeSharedP256Secret(sender_private_key,
927 sender_public_key_x509, sender_public_key,
928 &receiver_shared_secret));
929
930 ASSERT_GT(sender_shared_secret.size(), 0u);
931 ASSERT_EQ(sender_shared_secret, receiver_shared_secret);
932
933 // Decode the public keys of both parties and the auth secret.
934 std::string recipient_public_key, auth_secret;
935 ASSERT_TRUE(base::Base64UrlDecode(kRecipientPublicKeyUncompressed,
936 base::Base64UrlDecodePolicy::IGNORE_PADDING,
937 &recipient_public_key));
938 ASSERT_TRUE(base::Base64UrlDecode(
939 kAuthSecret, base::Base64UrlDecodePolicy::IGNORE_PADDING, &auth_secret));
940
941 // Attempt to decrypt the message using a GCMMessageCryptographer for this
942 // version of the draft, and then re-encrypt it agian to make sure it matches.
943 GCMMessageCryptographer cryptographer(
944 GCMMessageCryptographer::Version::DRAFT_08);
945
946 std::string plaintext;
947
948 ASSERT_TRUE(cryptographer.Decrypt(recipient_public_key, sender_public_key,
949 sender_shared_secret, auth_secret, salt,
950 ciphertext, record_size, &plaintext));
951 ASSERT_EQ(kPlaintext, plaintext);
952
953 size_t record_size2;
954 std::string ciphertext2;
955
956 ASSERT_TRUE(cryptographer.Encrypt(recipient_public_key, sender_public_key,
957 sender_shared_secret, auth_secret, salt,
958 kPlaintext, &record_size2, &ciphertext2));
959
960 EXPECT_GE(record_size2, record_size);
961 EXPECT_EQ(ciphertext2, ciphertext);
962 }
963
618 } // namespace gcm 964 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698