OLD | NEW |
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/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
12 #include "components/gcm_driver/crypto/p256_key_util.h" | 12 #include "components/gcm_driver/crypto/p256_key_util.h" |
13 #include "crypto/random.h" | 13 #include "crypto/random.h" |
14 #include "crypto/symmetric_key.h" | |
15 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
16 | 15 |
17 namespace gcm { | 16 namespace gcm { |
18 | 17 |
19 namespace { | 18 namespace { |
20 | 19 |
21 // Example plaintext data to use in the tests. | 20 // Example plaintext data to use in the tests. |
22 const char kExamplePlaintext[] = "Example plaintext"; | 21 const char kExamplePlaintext[] = "Example plaintext"; |
23 | 22 |
24 // The number of bits of the key in AEAD_AES_128_GCM. | 23 // Expected sizes of the different input given to the cryptographer. |
25 const size_t kKeySizeBits = 128; | 24 constexpr size_t kEcdhSharedSecretSize = 32; |
| 25 constexpr size_t kAuthSecretSize = 16; |
| 26 constexpr size_t kSaltSize = 16; |
26 | 27 |
27 // Public keys of both the sender and the recipient as base64url-encoded | 28 // Keying material for both parties as P-256 EC points. Used to make sure that |
28 // uncompressed P-256 EC points, as well as an authentication secret used for | 29 // the test vectors are reproducible. |
29 // the reference vectors. All used to create stable output. | 30 const unsigned char kCommonSenderPublicKey[] = { |
30 const char kCommonRecipientPublicKey[] = | 31 0x04, 0x05, 0x3C, 0xA1, 0xB9, 0xA5, 0xAB, 0xB8, 0x2D, 0x88, 0x48, |
31 "BIXzEKOFquzVlr_1tS1bhmobZU3IJq2bswDflMJsizixqd_HFSvCJaCAotNjBw6A-iKQk7FshA" | 32 0x82, 0xC9, 0x49, 0x19, 0x91, 0xD5, 0xFD, 0xD1, 0x92, 0xDB, 0xA7, |
32 "jdAA-T9Rh1a7U"; | 33 0x7E, 0x70, 0x48, 0x37, 0x41, 0xCD, 0x90, 0x05, 0x80, 0xDF, 0x65, |
33 const char kCommonSenderPublicKey[] = | 34 0x9A, 0xA1, 0x1A, 0x04, 0xF1, 0x98, 0x25, 0xF2, 0xC2, 0x13, 0x5D, |
34 "BAuzSrdIyKZsHnuOhqklkIKi6fl65V9OdPy6nFwI2SywL5-6I5SkkDtfIL9y7NkoEE345jv2Eo" | 35 0xD9, 0x72, 0x35, 0x75, 0x24, 0xF9, 0xFF, 0x25, 0xD1, 0xBC, 0x84, |
35 "5n4NIbLJIBjTM"; | 36 0x46, 0x4E, 0x88, 0x08, 0x55, 0x70, 0x9F, 0xA7, 0x07, 0xD9}; |
36 const char kCommonAuthSecret[] = "MyAuthenticationSecret"; | 37 static_assert(arraysize(kCommonSenderPublicKey) == 65, |
| 38 "Raw P-256 public keys must be 65 bytes in size."); |
| 39 |
| 40 const unsigned char kCommonRecipientPublicKey[] = { |
| 41 0x04, 0x35, 0x02, 0x67, 0xB9, 0x10, 0x8F, 0x9B, 0xF1, 0x85, 0xF5, |
| 42 0x1B, 0xD7, 0xA4, 0xEF, 0xBD, 0x28, 0xB3, 0x11, 0x40, 0xBA, 0xD0, |
| 43 0xEE, 0xB2, 0x97, 0xDA, 0x6A, 0x93, 0x2D, 0x26, 0x45, 0xBD, 0xB2, |
| 44 0x9A, 0x9F, 0xB8, 0x19, 0xD8, 0x21, 0x6F, 0x66, 0xE3, 0xF6, 0x0B, |
| 45 0x74, 0xB2, 0x28, 0x38, 0xDC, 0xA7, 0x8A, 0x58, 0x0D, 0x56, 0x47, |
| 46 0x3E, 0xD0, 0x5B, 0x5C, 0x93, 0x4E, 0xB3, 0x89, 0x87, 0x64}; |
| 47 static_assert(arraysize(kCommonRecipientPublicKey) == 65, |
| 48 "Raw P-256 public keys must be 65 bytes in size."); |
| 49 |
| 50 const unsigned char kCommonRecipientPublicKeyX509[] = { |
| 51 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, |
| 52 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, |
| 53 0x42, 0x00, 0x04, 0x35, 0x02, 0x67, 0xB9, 0x10, 0x8F, 0x9B, 0xF1, 0x85, |
| 54 0xF5, 0x1B, 0xD7, 0xA4, 0xEF, 0xBD, 0x28, 0xB3, 0x11, 0x40, 0xBA, 0xD0, |
| 55 0xEE, 0xB2, 0x97, 0xDA, 0x6A, 0x93, 0x2D, 0x26, 0x45, 0xBD, 0xB2, 0x9A, |
| 56 0x9F, 0xB8, 0x19, 0xD8, 0x21, 0x6F, 0x66, 0xE3, 0xF6, 0x0B, 0x74, 0xB2, |
| 57 0x28, 0x38, 0xDC, 0xA7, 0x8A, 0x58, 0x0D, 0x56, 0x47, 0x3E, 0xD0, 0x5B, |
| 58 0x5C, 0x93, 0x4E, 0xB3, 0x89, 0x87, 0x64}; |
| 59 |
| 60 const unsigned char kCommonRecipientPrivateKey[] = { |
| 61 0x30, 0x81, 0xB0, 0x30, 0x1B, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86, 0xF7, |
| 62 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, 0x0D, 0x04, 0x08, 0xF3, 0xD6, 0x39, |
| 63 0xB0, 0xBF, 0xC2, 0xF7, 0xEF, 0x02, 0x01, 0x01, 0x04, 0x81, 0x90, 0x0C, |
| 64 0xBC, 0xC9, 0x5F, 0x95, 0x6C, 0x4C, 0x6A, 0x57, 0xC4, 0x04, 0x47, 0x8F, |
| 65 0x59, 0xFD, 0x35, 0x97, 0x3B, 0xF3, 0x66, 0xA7, 0xEB, 0x8D, 0x44, 0x1E, |
| 66 0xCB, 0x4D, 0xFC, 0xD8, 0x8A, 0x38, 0xCA, 0xA8, 0xD7, 0x93, 0x45, 0x61, |
| 67 0xCC, 0xC7, 0xD8, 0x24, 0x16, 0xBF, 0xFC, 0xF4, 0x20, 0x54, 0x53, 0xB1, |
| 68 0x20, 0x3E, 0x19, 0x62, 0x08, 0xBE, 0x3D, 0x5B, 0x56, 0x60, 0x2D, 0x0C, |
| 69 0xDB, 0x29, 0x4A, 0x0B, 0xC8, 0xE0, 0x58, 0xAA, 0xE0, 0xAE, 0xE5, 0x91, |
| 70 0xEA, 0x6E, 0x40, 0x39, 0xD7, 0x3A, 0x1D, 0x75, 0x1E, 0xFF, 0xE3, 0xA7, |
| 71 0x64, 0x53, 0x50, 0x4A, 0xC1, 0xE9, 0x31, 0x9F, 0x0E, 0xB5, 0x12, 0x3E, |
| 72 0x57, 0xD7, 0x96, 0x5D, 0x69, 0xD5, 0x5A, 0xF8, 0x7C, 0x21, 0xF2, 0x43, |
| 73 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, |
| 75 0x8D, 0xB9, 0xC0, 0x11, 0xC8, 0xA9, 0x01, 0xD6, 0xB3, 0xBD, 0xEE}; |
| 76 |
| 77 const unsigned char kCommonAuthSecret[] = {0x25, 0xF2, 0xC2, 0xB8, 0x19, 0xD8, |
| 78 0xFD, 0x35, 0x97, 0xDF, 0xFB, 0x5E, |
| 79 0xF6, 0x0B, 0xD7, 0xA4}; |
| 80 static_assert(arraysize(kCommonAuthSecret) == 16, |
| 81 "Auth secrets must be 16 bytes in size."); |
37 | 82 |
38 // Test vectors containing reference input for draft-ietf-webpush-encryption-03 | 83 // Test vectors containing reference input for draft-ietf-webpush-encryption-03 |
39 // that was created using an separate JavaScript implementation of the draft. | 84 // that was created using an separate JavaScript implementation of the draft. |
40 struct TestVector { | 85 struct TestVector { |
41 const char* const input; | 86 const char* const input; |
42 const char* const ecdh_shared_secret; | 87 const unsigned char ecdh_shared_secret[kEcdhSharedSecretSize]; |
43 const char* const salt; | 88 const unsigned char auth_secret[kAuthSecretSize]; |
| 89 const unsigned char salt[kSaltSize]; |
44 size_t record_size; | 90 size_t record_size; |
45 const char* const output; | 91 const char* const output; |
46 }; | 92 }; |
47 | 93 |
48 const TestVector kEncryptionTestVectorsDraft03[] = { | 94 const TestVector kEncryptionTestVectorsDraft03[] = { |
49 // Simple message. | 95 // Simple message. |
50 {"Hello, world!", "AhA6n2oFYPWIh-cXwyv1m2C0JvmjHB4ZkXj8QylESXU", | 96 {"Hello, world!", |
51 "tsJYqAGvFDk6lDEv7daecw", 4096, | 97 {0x0B, 0x32, 0xE2, 0xD1, 0x6A, 0xBF, 0x4F, 0x2C, 0x49, 0xEA, 0xF7, |
52 "FgWrrnZq79oI_N4ORkVLHx1jfVmjeiIk-xFX8PzVuA"}, | 98 0x5D, 0x71, 0x7D, 0x89, 0xA9, 0xA7, 0x5E, 0x21, 0xB2, 0xB5, 0x51, |
| 99 0xE6, 0x4C, 0x08, 0x68, 0xD3, 0x6F, 0x8F, 0x72, 0x7E, 0x14}, |
| 100 {0xD3, 0xF2, 0x78, 0xBD, 0x8D, 0xDD, 0x84, 0x99, 0x66, 0x08, 0xD7, 0x0F, |
| 101 0xBA, 0x9B, 0x60, 0xFC}, |
| 102 {0x15, 0x4A, 0xD7, 0x73, 0x92, 0xBD, 0x3B, 0xCF, 0x6F, 0x98, 0xDC, 0x9B, |
| 103 0x8B, 0x56, 0xFB, 0xBD}, |
| 104 4096, |
| 105 "T4SXCyj84drA6wRaBNLGDMzeyOEBWjsIEkS2ros6Aw"}, |
53 // Empty message. | 106 // Empty message. |
54 {"", "lMyvTong4VR053jfCpWmMDGW5dEDAqiTZUIU-inhTjU", | 107 {"", |
55 "wH3uvZqcN6oey9whiGpn1A", 4096, "MTI9zZ8CJTUzbZ4qNDoQZs0k"}, | 108 {0x3F, 0xD8, 0x95, 0x2C, 0xA2, 0x11, 0xBD, 0x7B, 0x57, 0xB2, 0x00, |
56 // Message with an invalid salt size. | 109 0xBD, 0x57, 0x68, 0x3F, 0xF0, 0x14, 0x57, 0x5F, 0xB1, 0x9F, 0x15, |
57 { | 110 0x4F, 0x11, 0xF0, 0x4D, 0xA2, 0xE8, 0x4C, 0xEA, 0x74, 0x3B}, |
58 "Hello, world!", "CcdxzkR6z1EY9vSrM7_IxYVxDxu46hV638EZQTPd7XI", | 111 {0xB1, 0xE1, 0xC7, 0x32, 0x4C, 0xAA, 0x56, 0x32, 0x68, 0x20, 0x0F, 0x26, |
59 "aRr1fI1YSGVi5XU", 4096, | 112 0x3F, 0x48, 0x4D, 0x99}, |
60 nullptr // expected to fail | 113 {0xE9, 0x39, 0x45, 0xBC, 0x96, 0x96, 0x88, 0x76, 0xFC, 0xA1, 0xAD, 0xE4, |
61 }}; | 114 0x9D, 0x28, 0xF3, 0x73}, |
| 115 4096, |
| 116 "8s-Tzq8Cn_eobL6uEcNDXL7K"}}; |
62 | 117 |
63 const TestVector kDecryptionTestVectorsDraft03[] = { | 118 const TestVector kDecryptionTestVectorsDraft03[] = { |
64 // Simple message. | 119 // Simple message. |
65 {"ceiEu_YpmqLoakD4smdzvy2XKRQrJ9vBzB2aqYEfzw", | 120 {"lsemWwzlFoJzoidHCnVuxRiJpotTcYokJHKzmQ2FsA", |
66 "47ZytAw9qHlm-Q8g-7rH81rUPzaCgGcoFvlS1qxQtQk", "EuR7EVetcaWpndXd_dKeyA", | 121 {0x4D, 0x3A, 0x6C, 0xBA, 0xD8, 0x1D, 0x8E, 0x68, 0x8B, 0xE6, 0x76, |
67 4096, "Hello, world!"}, | 122 0xA7, 0xFF, 0x60, 0xC7, 0xFE, 0x77, 0xE2, 0x6D, 0x37, 0xF6, 0x12, |
| 123 0x44, 0xE2, 0x25, 0xFE, 0xE1, 0xD8, 0xCF, 0x8A, 0xA8, 0x33}, |
| 124 {0x62, 0x36, 0xAC, 0xCA, 0x74, 0xD4, 0x49, 0x49, 0x6B, 0x27, 0xB4, 0xF7, |
| 125 0xC1, 0xE5, 0x30, 0x9A}, |
| 126 {0x1C, 0xA7, 0xFD, 0x98, 0x1A, 0xE4, 0xA7, 0x92, 0xE1, 0xB6, 0xA1, 0xE3, |
| 127 0x41, 0x63, 0x87, 0x76}, |
| 128 4096, |
| 129 "Hello, world!"}, |
68 // Simple message with 16 bytes of padding. | 130 // Simple message with 16 bytes of padding. |
69 {"WSf6fz1O0aIJyaPTCnvk83OqIQxsRKeFOvblPLsPpFB_1AV9ROk09TE1cGrB6zQ", | 131 {"VQB6Ds-q9xRqyM1tj_gksSgc78vCWEhphZ-NF1E7_yMfPuRRZlC_Xt9_2NsX3SU", |
70 "MYSsNybwrTzRIzQYUq_yFPc6ugcTrJdEZJDM4NswvUg", "8sEAMQYnufo2UkKl80cUGQ", | 132 {0x8B, 0x38, 0x8E, 0x22, 0xD5, 0xC4, 0xFD, 0x65, 0x8A, 0xBB, 0xD9, |
71 4096, "Hello, world!"}, | 133 0x58, 0xBD, 0xF5, 0xFF, 0x79, 0xCF, 0x9D, 0xBD, 0x87, 0x16, 0x7E, |
| 134 0x93, 0x84, 0x20, 0x8E, 0x8D, 0x49, 0x41, 0x7D, 0x8E, 0x8F}, |
| 135 {0x3E, 0x65, 0xC7, 0x1F, 0x75, 0x7A, 0x43, 0xC4, 0x78, 0x6C, 0x64, 0x99, |
| 136 0x49, 0xA0, 0xC4, 0xB2}, |
| 137 {0x43, 0x4D, 0x30, 0x8E, 0xE4, 0x76, 0xB5, 0xD0, 0x87, 0xFC, 0x04, 0xD1, |
| 138 0x2E, 0x35, 0x75, 0x63}, |
| 139 4096, |
| 140 "Hello, world!"}, |
72 // Empty message. | 141 // Empty message. |
73 {"Ur3vHedGDO5IPYDvbhHYjbjG", "S3-Ki_-XtzR66gUp_zR75CC5JXO62pyr5fWfneTYwFE", | 142 {"xU8a499UHB_-YSV4VOm-JZnT", |
74 "4RM6s19jJHdmqiVEJDp9jg", 4096, ""}, | 143 {0x68, 0x72, 0x3D, 0x13, 0xE7, 0x50, 0xFA, 0x3E, 0xA0, 0x59, 0x33, |
75 // Message with an invalid salt size. | 144 0xF1, 0x73, 0xA8, 0xE8, 0xCD, 0x8D, 0xD4, 0x3C, 0xDC, 0xDE, 0x06, |
76 { | 145 0x35, 0x5F, 0x51, 0xBB, 0xB2, 0x57, 0x97, 0x72, 0x9D, 0xFB}, |
77 "iGrOpmJC5XTTf7wtgdhZ_qT", | 146 {0x84, 0xB2, 0x2A, 0xE7, 0xC6, 0xC0, 0xCE, 0x5F, 0xAD, 0x37, 0x06, 0x7F, |
78 "wW3Iy5ma803lLd-ysPdHUe2NB3HqXbY0XhCCdG5Y1Gw", "N7oMH_xohAhMhOY", 4096, | 147 0xD1, 0xFD, 0x10, 0x87}, |
79 nullptr // expected to fail | 148 {0x9B, 0xC5, 0x8D, 0x5F, 0xD6, 0xD2, 0xA6, 0xBD, 0xAF, 0x4B, 0xD9, 0x60, |
80 }, | 149 0xC6, 0xB4, 0x50, 0x0F}, |
| 150 4096, |
| 151 ""}, |
81 // Message with an invalid record size. | 152 // Message with an invalid record size. |
82 { | 153 {"gfB-_edj7qEVokyVHpkDJN6FVKHnlWs1RCDw5bmrwQ", |
83 "iGrOpmJC5XTTf7wtgdhZ_qT", | 154 {0x5F, 0xE1, 0x7C, 0x4B, 0xFF, 0x04, 0xBF, 0x2C, 0x70, 0x67, 0xFA, |
84 "kR5BMfqMKOD1yrLKE2giObXHI7merrMtnoO2oqneqXA", "SQeJSPrqHvTdSfAMF8bBzQ", | 155 0xF8, 0xB0, 0x07, 0x4F, 0xF6, 0x3C, 0x03, 0x6F, 0xBE, 0xA1, 0x1F, |
85 8, | 156 0x4B, 0x99, 0x25, 0x4F, 0xB9, 0x5F, 0xC4, 0x78, 0x76, 0xDE}, |
86 nullptr // expected to fail | 157 {0x59, 0xAB, 0x45, 0xFC, 0x6A, 0xF5, 0xB3, 0xE0, 0xF5, 0x40, 0xD7, 0x98, |
87 }, | 158 0x0F, 0xF0, 0xA4, 0xCB}, |
| 159 {0xDB, 0xA0, 0xF2, 0x91, 0x8D, 0x50, 0x42, 0xE0, 0x17, 0x68, 0x5B, 0x9B, |
| 160 0xF2, 0xA2, 0xC3, 0xF9}, |
| 161 7, |
| 162 nullptr}, |
| 163 // Message with four bytes of invalid, non-zero padding. |
| 164 {"2FJmrF95yVU8Q8cYQy9OoOwCb59ZoRlxazPE0T-MNOSMbr0", |
| 165 {0x6B, 0x82, 0x92, 0xD3, 0x71, 0x9A, 0x97, 0x76, 0x45, 0x11, 0x99, |
| 166 0x6D, 0xBF, 0x56, 0xCC, 0x81, 0x98, 0x56, 0x80, 0xF5, 0x78, 0x36, |
| 167 0xD6, 0x43, 0x95, 0x68, 0xDB, 0x0F, 0x23, 0x39, 0xF3, 0x6E}, |
| 168 {0x02, 0x16, 0xDC, 0xC3, 0xDE, 0x2C, 0xB5, 0x08, 0x89, 0xDB, 0xD8, 0x18, |
| 169 0x68, 0x83, 0x1C, 0xDB}, |
| 170 {0xB7, 0x85, 0x5D, 0x8E, 0x84, 0xC3, 0x2D, 0x61, 0x9B, 0x78, 0x3B, 0x60, |
| 171 0x0E, 0x70, 0x84, 0xF3}, |
| 172 4096, |
| 173 nullptr}, |
88 // Message with multiple (2) records. | 174 // Message with multiple (2) records. |
89 { | 175 {"reI6sW6y67FI8Kxk-x9GNwiu77His_f5GioDBiKS7IzjDQ", |
90 "RqQVHRXlfYjzW9xhzh3V_KijLKjZiKzGXosqN_" | 176 {0xC6, 0x16, 0x6F, 0xAF, 0xE1, 0xB6, 0x8F, 0x2B, 0x0F, 0x67, 0x5A, |
91 "IaMzi0zI0tXXhC1urtrk3iWRoqttNXpkD2r" | 177 0xC7, 0xAC, 0x7E, 0xF6, 0x7C, 0x33, 0xA2, 0xA1, 0x11, 0xB0, 0xB0, |
92 "UCgLy8A1FnTjw", | 178 0xAB, 0xAC, 0x37, 0x61, 0xF4, 0xCB, 0x98, 0xFF, 0x00, 0x51}, |
93 "W3W4gx7sqcfmBnvNNdO9d4MBCC1bvJkvsNjZOGD-CCg", "xG0TPGi9aIcxjpXKmaYBBQ", | 179 {0xAE, 0xDA, 0x86, 0xDF, 0x6B, 0x03, 0x88, 0xDE, 0x90, 0xBB, 0xB7, 0xA0, |
94 7, | 180 0x78, 0x91, 0x3A, 0x36}, |
95 nullptr // expected to fail | 181 {0x4C, 0x4E, 0x2A, 0x8D, 0x88, 0x82, 0xCF, 0xC2, 0xF9, 0x8A, 0xFD, 0x31, |
96 }}; | 182 0xF8, 0xD1, 0xF6, 0xB5}, |
| 183 8, |
| 184 nullptr}}; |
97 | 185 |
98 } // namespace | 186 } // namespace |
99 | 187 |
100 class GCMMessageCryptographerTest : public ::testing::Test { | 188 class GCMMessageCryptographerTest : public ::testing::Test { |
101 public: | 189 public: |
102 void SetUp() override { | 190 void SetUp() override { |
103 cryptographer_ = base::MakeUnique<GCMMessageCryptographer>( | 191 cryptographer_ = base::MakeUnique<GCMMessageCryptographer>( |
104 GCMMessageCryptographer::Version::DRAFT_03); | 192 GCMMessageCryptographer::Version::DRAFT_03); |
105 | 193 |
106 ASSERT_TRUE(base::Base64UrlDecode( | 194 recipient_public_key_.assign( |
107 kCommonRecipientPublicKey, base::Base64UrlDecodePolicy::IGNORE_PADDING, | 195 kCommonRecipientPublicKey, |
108 &recipient_public_key_)); | 196 kCommonRecipientPublicKey + arraysize(kCommonRecipientPublicKey)); |
109 ASSERT_TRUE(base::Base64UrlDecode( | 197 sender_public_key_.assign( |
110 kCommonSenderPublicKey, base::Base64UrlDecodePolicy::IGNORE_PADDING, | 198 kCommonSenderPublicKey, |
111 &sender_public_key_)); | 199 kCommonSenderPublicKey + arraysize(kCommonSenderPublicKey)); |
112 | 200 |
113 std::unique_ptr<crypto::SymmetricKey> random_key( | 201 std::string recipient_private_key( |
114 crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, | 202 kCommonRecipientPrivateKey, |
115 kKeySizeBits)); | 203 kCommonRecipientPrivateKey + arraysize(kCommonRecipientPrivateKey)); |
116 | 204 |
117 ASSERT_TRUE(random_key->GetRawKey(&ecdh_shared_secret_)); | 205 // TODO(peter): Remove the dependency on the x509 keying material when |
| 206 // crbug.com/618025 has been resolved. |
| 207 std::string recipient_public_key_x509( |
| 208 kCommonRecipientPublicKeyX509, |
| 209 kCommonRecipientPublicKeyX509 + |
| 210 arraysize(kCommonRecipientPublicKeyX509)); |
| 211 |
| 212 ASSERT_TRUE(ComputeSharedP256Secret( |
| 213 recipient_private_key, recipient_public_key_x509, sender_public_key_, |
| 214 &ecdh_shared_secret_)); |
| 215 |
| 216 auth_secret_.assign(kCommonAuthSecret, |
| 217 kCommonAuthSecret + arraysize(kCommonAuthSecret)); |
118 } | 218 } |
119 | 219 |
120 protected: | 220 protected: |
121 // Generates a cryptographically secure random salt of 16-octets in size, the | 221 // Generates a cryptographically secure random salt of 16-octets in size, the |
122 // required length as expected by the HKDF. | 222 // required length as expected by the HKDF. |
123 std::string GenerateRandomSalt() { | 223 std::string GenerateRandomSalt() { |
124 const size_t kSaltSize = 16; | |
125 | |
126 std::string salt; | 224 std::string salt; |
127 | 225 |
128 crypto::RandBytes(base::WriteInto(&salt, kSaltSize + 1), kSaltSize); | 226 crypto::RandBytes(base::WriteInto(&salt, kSaltSize + 1), kSaltSize); |
129 return salt; | 227 return salt; |
130 } | 228 } |
131 | 229 |
132 // Public keys of the recipient and sender as uncompressed P-256 EC points. | 230 // Public keys of the recipient and sender as uncompressed P-256 EC points. |
133 std::string recipient_public_key_; | 231 std::string recipient_public_key_; |
134 std::string sender_public_key_; | 232 std::string sender_public_key_; |
135 | 233 |
136 // Shared secret to use in transformations. Unrelated to the keys above. | 234 // Shared secret to use in transformations. Associated with the keys above. |
137 std::string ecdh_shared_secret_; | 235 std::string ecdh_shared_secret_; |
138 | 236 |
| 237 // Authentication secret to use in tests where no specific value is expected. |
| 238 std::string auth_secret_; |
| 239 |
139 // The GCMMessageCryptographer instance to use for the tests. | 240 // The GCMMessageCryptographer instance to use for the tests. |
140 std::unique_ptr<GCMMessageCryptographer> cryptographer_; | 241 std::unique_ptr<GCMMessageCryptographer> cryptographer_; |
141 }; | 242 }; |
142 | 243 |
143 TEST_F(GCMMessageCryptographerTest, RoundTrip) { | 244 TEST_F(GCMMessageCryptographerTest, RoundTrip) { |
144 const std::string salt = GenerateRandomSalt(); | 245 const std::string salt = GenerateRandomSalt(); |
145 | 246 |
146 size_t record_size = 0; | 247 size_t record_size = 0; |
147 | 248 |
148 std::string ciphertext, plaintext; | 249 std::string ciphertext, plaintext; |
149 ASSERT_TRUE(cryptographer_->Encrypt( | 250 ASSERT_TRUE(cryptographer_->Encrypt( |
150 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, | 251 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, |
151 kCommonAuthSecret, salt, kExamplePlaintext, &record_size, &ciphertext)); | 252 auth_secret_, salt, kExamplePlaintext, &record_size, &ciphertext)); |
152 | 253 |
153 EXPECT_GT(record_size, ciphertext.size() - 16); | 254 EXPECT_GT(record_size, ciphertext.size() - 16); |
154 EXPECT_GT(ciphertext.size(), 0u); | 255 EXPECT_GT(ciphertext.size(), 0u); |
155 | 256 |
156 ASSERT_TRUE(cryptographer_->Decrypt( | 257 ASSERT_TRUE(cryptographer_->Decrypt(recipient_public_key_, sender_public_key_, |
157 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, | 258 ecdh_shared_secret_, auth_secret_, salt, |
158 kCommonAuthSecret, salt, ciphertext, record_size, &plaintext)); | 259 ciphertext, record_size, &plaintext)); |
159 | 260 |
160 EXPECT_EQ(kExamplePlaintext, plaintext); | 261 EXPECT_EQ(kExamplePlaintext, plaintext); |
161 } | 262 } |
162 | 263 |
163 TEST_F(GCMMessageCryptographerTest, RoundTripEmptyMessage) { | 264 TEST_F(GCMMessageCryptographerTest, RoundTripEmptyMessage) { |
164 const std::string salt = GenerateRandomSalt(); | 265 const std::string salt = GenerateRandomSalt(); |
165 const std::string message = ""; | 266 const std::string message = ""; |
166 | 267 |
167 size_t record_size = 0; | 268 size_t record_size = 0; |
168 | 269 |
169 std::string ciphertext, plaintext; | 270 std::string ciphertext, plaintext; |
170 ASSERT_TRUE(cryptographer_->Encrypt( | 271 ASSERT_TRUE(cryptographer_->Encrypt(recipient_public_key_, sender_public_key_, |
171 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, | 272 ecdh_shared_secret_, auth_secret_, salt, |
172 kCommonAuthSecret, salt, message, &record_size, &ciphertext)); | 273 message, &record_size, &ciphertext)); |
173 | 274 |
174 EXPECT_GT(record_size, ciphertext.size() - 16); | 275 EXPECT_GT(record_size, ciphertext.size() - 16); |
175 EXPECT_GT(ciphertext.size(), 0u); | 276 EXPECT_GT(ciphertext.size(), 0u); |
176 | 277 |
177 ASSERT_TRUE(cryptographer_->Decrypt( | 278 ASSERT_TRUE(cryptographer_->Decrypt(recipient_public_key_, sender_public_key_, |
178 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, | 279 ecdh_shared_secret_, auth_secret_, salt, |
179 kCommonAuthSecret, salt, ciphertext, record_size, &plaintext)); | 280 ciphertext, record_size, &plaintext)); |
180 | 281 |
181 EXPECT_EQ(message, plaintext); | 282 EXPECT_EQ(message, plaintext); |
182 } | 283 } |
183 | 284 |
184 TEST_F(GCMMessageCryptographerTest, InvalidRecordSize) { | 285 TEST_F(GCMMessageCryptographerTest, InvalidRecordSize) { |
185 const std::string salt = GenerateRandomSalt(); | 286 const std::string salt = GenerateRandomSalt(); |
186 | 287 |
187 size_t record_size = 0; | 288 size_t record_size = 0; |
188 | 289 |
189 std::string ciphertext, plaintext; | 290 std::string ciphertext, plaintext; |
190 ASSERT_TRUE(cryptographer_->Encrypt( | 291 ASSERT_TRUE(cryptographer_->Encrypt( |
191 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, | 292 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, |
192 kCommonAuthSecret, salt, kExamplePlaintext, &record_size, &ciphertext)); | 293 auth_secret_, salt, kExamplePlaintext, &record_size, &ciphertext)); |
193 | 294 |
194 EXPECT_GT(record_size, ciphertext.size() - 16); | 295 EXPECT_GT(record_size, ciphertext.size() - 16); |
195 | 296 |
196 EXPECT_FALSE(cryptographer_->Decrypt( | 297 EXPECT_FALSE(cryptographer_->Decrypt( |
197 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, | 298 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, |
198 kCommonAuthSecret, salt, ciphertext, 0 /* record_size */, &plaintext)); | 299 auth_secret_, salt, ciphertext, 0 /* record_size */, &plaintext)); |
199 | 300 |
200 EXPECT_FALSE(cryptographer_->Decrypt( | 301 EXPECT_FALSE(cryptographer_->Decrypt( |
201 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, | 302 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, |
202 kCommonAuthSecret, salt, ciphertext, ciphertext.size() - 17, &plaintext)); | 303 auth_secret_, salt, ciphertext, ciphertext.size() - 17, &plaintext)); |
203 | 304 |
204 EXPECT_TRUE(cryptographer_->Decrypt( | 305 EXPECT_TRUE(cryptographer_->Decrypt( |
205 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, | 306 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, |
206 kCommonAuthSecret, salt, ciphertext, ciphertext.size() - 16, &plaintext)); | 307 auth_secret_, salt, ciphertext, ciphertext.size() - 16, &plaintext)); |
207 } | 308 } |
208 | 309 |
209 TEST_F(GCMMessageCryptographerTest, InvalidRecordPadding) { | 310 TEST_F(GCMMessageCryptographerTest, InvalidRecordPadding) { |
210 std::string message = std::string(sizeof(uint16_t), '\0') + kExamplePlaintext; | 311 std::string message = std::string(sizeof(uint16_t), '\0') + kExamplePlaintext; |
211 | 312 |
212 const std::string salt = GenerateRandomSalt(); | 313 const std::string salt = GenerateRandomSalt(); |
213 | 314 |
214 const std::string prk = | 315 const std::string prk = |
215 cryptographer_->encryption_scheme_->DerivePseudoRandomKey( | 316 cryptographer_->encryption_scheme_->DerivePseudoRandomKey( |
216 ecdh_shared_secret_, kCommonAuthSecret); | 317 ecdh_shared_secret_, auth_secret_); |
217 const std::string content_encryption_key = | 318 const std::string content_encryption_key = |
218 cryptographer_->DeriveContentEncryptionKey(recipient_public_key_, | 319 cryptographer_->DeriveContentEncryptionKey(recipient_public_key_, |
219 sender_public_key_, prk, salt); | 320 sender_public_key_, prk, salt); |
220 const std::string nonce = cryptographer_->DeriveNonce( | 321 const std::string nonce = cryptographer_->DeriveNonce( |
221 recipient_public_key_, sender_public_key_, prk, salt); | 322 recipient_public_key_, sender_public_key_, prk, salt); |
222 | 323 |
223 ASSERT_GT(message.size(), 1u); | 324 ASSERT_GT(message.size(), 1u); |
224 const size_t record_size = message.size() + 1; | 325 const size_t record_size = message.size() + 1; |
225 | 326 |
226 std::string ciphertext, plaintext; | 327 std::string ciphertext, plaintext; |
227 ASSERT_TRUE(cryptographer_->TransformRecord( | 328 ASSERT_TRUE(cryptographer_->TransformRecord( |
228 GCMMessageCryptographer::Direction::ENCRYPT, message, | 329 GCMMessageCryptographer::Direction::ENCRYPT, message, |
229 content_encryption_key, nonce, &ciphertext)); | 330 content_encryption_key, nonce, &ciphertext)); |
230 | 331 |
231 ASSERT_TRUE(cryptographer_->Decrypt( | 332 ASSERT_TRUE(cryptographer_->Decrypt(recipient_public_key_, sender_public_key_, |
232 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, | 333 ecdh_shared_secret_, auth_secret_, salt, |
233 kCommonAuthSecret, salt, ciphertext, record_size, &plaintext)); | 334 ciphertext, record_size, &plaintext)); |
234 | 335 |
235 // Note that GCMMessageCryptographer::Decrypt removes the padding. | 336 // Note that GCMMessageCryptographer::Decrypt removes the padding. |
236 EXPECT_EQ(kExamplePlaintext, plaintext); | 337 EXPECT_EQ(kExamplePlaintext, plaintext); |
237 | 338 |
238 // Now run the same steps again, but say that there are four padding octets. | 339 // Now run the same steps again, but say that there are four padding octets. |
239 // This should be rejected because the padding will not be all zeros. | 340 // This should be rejected because the padding will not be all zeros. |
240 message[0] = 4; | 341 message[0] = 4; |
241 | 342 |
242 ASSERT_TRUE(cryptographer_->TransformRecord( | 343 ASSERT_TRUE(cryptographer_->TransformRecord( |
243 GCMMessageCryptographer::Direction::ENCRYPT, message, | 344 GCMMessageCryptographer::Direction::ENCRYPT, message, |
244 content_encryption_key, nonce, &ciphertext)); | 345 content_encryption_key, nonce, &ciphertext)); |
245 | 346 |
246 ASSERT_FALSE(cryptographer_->Decrypt( | 347 ASSERT_FALSE(cryptographer_->Decrypt( |
247 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, | 348 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, |
248 kCommonAuthSecret, salt, ciphertext, record_size, &plaintext)); | 349 auth_secret_, salt, ciphertext, record_size, &plaintext)); |
249 | 350 |
250 // Do the same but changing the second octet indicating padding size, leaving | 351 // Do the same but changing the second octet indicating padding size, leaving |
251 // the first octet at zero. | 352 // the first octet at zero. |
252 message[0] = 0; | 353 message[0] = 0; |
253 message[1] = 4; | 354 message[1] = 4; |
254 | 355 |
255 ASSERT_TRUE(cryptographer_->TransformRecord( | 356 ASSERT_TRUE(cryptographer_->TransformRecord( |
256 GCMMessageCryptographer::Direction::ENCRYPT, message, | 357 GCMMessageCryptographer::Direction::ENCRYPT, message, |
257 content_encryption_key, nonce, &ciphertext)); | 358 content_encryption_key, nonce, &ciphertext)); |
258 | 359 |
259 ASSERT_FALSE(cryptographer_->Decrypt( | 360 ASSERT_FALSE(cryptographer_->Decrypt( |
260 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, | 361 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, |
261 kCommonAuthSecret, salt, ciphertext, record_size, &plaintext)); | 362 auth_secret_, salt, ciphertext, record_size, &plaintext)); |
262 | 363 |
263 // Run the same steps again, but say that there are more padding octets than | 364 // Run the same steps again, but say that there are more padding octets than |
264 // the length of the message. | 365 // the length of the message. |
265 message[0] = 64; | 366 message[0] = 64; |
266 | 367 |
267 EXPECT_GT(static_cast<size_t>(message[0]), message.size()); | 368 EXPECT_GT(static_cast<size_t>(message[0]), message.size()); |
268 ASSERT_TRUE(cryptographer_->TransformRecord( | 369 ASSERT_TRUE(cryptographer_->TransformRecord( |
269 GCMMessageCryptographer::Direction::ENCRYPT, message, | 370 GCMMessageCryptographer::Direction::ENCRYPT, message, |
270 content_encryption_key, nonce, &ciphertext)); | 371 content_encryption_key, nonce, &ciphertext)); |
271 | 372 |
272 ASSERT_FALSE(cryptographer_->Decrypt( | 373 ASSERT_FALSE(cryptographer_->Decrypt( |
273 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, | 374 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, |
274 kCommonAuthSecret, salt, ciphertext, record_size, &plaintext)); | 375 auth_secret_, salt, ciphertext, record_size, &plaintext)); |
275 } | 376 } |
276 | 377 |
277 TEST_F(GCMMessageCryptographerTest, AuthSecretAffectsPRK) { | 378 TEST_F(GCMMessageCryptographerTest, AuthSecretAffectsPRK) { |
| 379 std::string first_auth_secret, second_auth_secret; |
| 380 |
| 381 crypto::RandBytes(base::WriteInto(&first_auth_secret, kAuthSecretSize + 1), |
| 382 kAuthSecretSize); |
| 383 crypto::RandBytes(base::WriteInto(&second_auth_secret, kAuthSecretSize + 1), |
| 384 kAuthSecretSize); |
| 385 |
278 ASSERT_NE(cryptographer_->encryption_scheme_->DerivePseudoRandomKey( | 386 ASSERT_NE(cryptographer_->encryption_scheme_->DerivePseudoRandomKey( |
279 ecdh_shared_secret_, "Hello"), | 387 ecdh_shared_secret_, first_auth_secret), |
280 cryptographer_->encryption_scheme_->DerivePseudoRandomKey( | 388 cryptographer_->encryption_scheme_->DerivePseudoRandomKey( |
281 ecdh_shared_secret_, "World")); | 389 ecdh_shared_secret_, second_auth_secret)); |
282 | 390 |
283 std::string salt = GenerateRandomSalt(); | 391 std::string salt = GenerateRandomSalt(); |
284 | 392 |
285 // Verify that the IKM actually gets used by the transformations. | 393 // Verify that the IKM actually gets used by the transformations. |
286 size_t hello_record_size, world_record_size; | 394 size_t first_record_size, second_record_size; |
287 std::string hello_ciphertext, world_ciphertext; | 395 std::string first_ciphertext, second_ciphertext; |
288 | 396 |
289 ASSERT_TRUE(cryptographer_->Encrypt( | 397 ASSERT_TRUE(cryptographer_->Encrypt(recipient_public_key_, sender_public_key_, |
290 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, "Hello", | 398 ecdh_shared_secret_, first_auth_secret, |
291 salt, kExamplePlaintext, &hello_record_size, &hello_ciphertext)); | 399 salt, kExamplePlaintext, |
| 400 &first_record_size, &first_ciphertext)); |
292 | 401 |
293 ASSERT_TRUE(cryptographer_->Encrypt( | 402 ASSERT_TRUE(cryptographer_->Encrypt(recipient_public_key_, sender_public_key_, |
294 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, "World", | 403 ecdh_shared_secret_, second_auth_secret, |
295 salt, kExamplePlaintext, &world_record_size, &world_ciphertext)); | 404 salt, kExamplePlaintext, |
| 405 &second_record_size, &second_ciphertext)); |
296 | 406 |
297 // If the ciphertexts differ despite the same key and salt, it got used. | 407 // If the ciphertexts differ despite the same key and salt, it got used. |
298 ASSERT_NE(hello_ciphertext, world_ciphertext); | 408 ASSERT_NE(first_ciphertext, second_ciphertext); |
299 EXPECT_EQ(hello_record_size, world_record_size); | 409 EXPECT_EQ(first_record_size, second_record_size); |
300 | 410 |
301 // Verify that the different ciphertexts can also be translated back to the | 411 // Verify that the different ciphertexts can also be translated back to the |
302 // plaintext content. This will fail if the auth secret isn't considered. | 412 // plaintext content. This will fail if the auth secret isn't considered. |
303 std::string hello_plaintext, world_plaintext; | 413 std::string first_plaintext, second_plaintext; |
304 | 414 |
305 ASSERT_TRUE(cryptographer_->Decrypt( | 415 ASSERT_TRUE(cryptographer_->Decrypt(recipient_public_key_, sender_public_key_, |
306 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, "Hello", | 416 ecdh_shared_secret_, first_auth_secret, |
307 salt, hello_ciphertext, hello_record_size, &hello_plaintext)); | 417 salt, first_ciphertext, first_record_size, |
| 418 &first_plaintext)); |
308 | 419 |
309 ASSERT_TRUE(cryptographer_->Decrypt( | 420 ASSERT_TRUE(cryptographer_->Decrypt(recipient_public_key_, sender_public_key_, |
310 recipient_public_key_, sender_public_key_, ecdh_shared_secret_, "World", | 421 ecdh_shared_secret_, second_auth_secret, |
311 salt, world_ciphertext, world_record_size, &world_plaintext)); | 422 salt, second_ciphertext, |
| 423 second_record_size, &second_plaintext)); |
312 | 424 |
313 EXPECT_EQ(kExamplePlaintext, hello_plaintext); | 425 EXPECT_EQ(kExamplePlaintext, first_plaintext); |
314 EXPECT_EQ(kExamplePlaintext, world_plaintext); | 426 EXPECT_EQ(kExamplePlaintext, second_plaintext); |
315 } | 427 } |
316 | 428 |
317 class GCMMessageCryptographerTestVectorTest | 429 class GCMMessageCryptographerTestVectorTest |
318 : public GCMMessageCryptographerTest {}; | 430 : public GCMMessageCryptographerTest {}; |
319 | 431 |
320 TEST_F(GCMMessageCryptographerTestVectorTest, EncryptionVectorsDraft03) { | 432 TEST_F(GCMMessageCryptographerTestVectorTest, EncryptionVectorsDraft03) { |
321 std::string ecdh_shared_secret, salt, output, ciphertext; | 433 std::string ecdh_shared_secret, auth_secret, salt, ciphertext, output; |
322 size_t record_size = 0; | 434 size_t record_size = 0; |
323 | 435 |
324 for (size_t i = 0; i < arraysize(kEncryptionTestVectorsDraft03); ++i) { | 436 for (size_t i = 0; i < arraysize(kEncryptionTestVectorsDraft03); ++i) { |
325 SCOPED_TRACE(i); | 437 SCOPED_TRACE(i); |
326 | 438 |
327 ASSERT_TRUE(base::Base64UrlDecode( | 439 ecdh_shared_secret.assign( |
328 kEncryptionTestVectorsDraft03[i].ecdh_shared_secret, | 440 kEncryptionTestVectorsDraft03[i].ecdh_shared_secret, |
329 base::Base64UrlDecodePolicy::IGNORE_PADDING, &ecdh_shared_secret)); | 441 kEncryptionTestVectorsDraft03[i].ecdh_shared_secret + |
330 ASSERT_TRUE(base::Base64UrlDecode( | 442 kEcdhSharedSecretSize); |
331 kEncryptionTestVectorsDraft03[i].salt, | |
332 base::Base64UrlDecodePolicy::IGNORE_PADDING, &salt)); | |
333 | 443 |
334 const bool has_output = kEncryptionTestVectorsDraft03[i].output; | 444 auth_secret.assign( |
335 const bool result = cryptographer_->Encrypt( | 445 kEncryptionTestVectorsDraft03[i].auth_secret, |
| 446 kEncryptionTestVectorsDraft03[i].auth_secret + kAuthSecretSize); |
| 447 |
| 448 salt.assign(kEncryptionTestVectorsDraft03[i].salt, |
| 449 kEncryptionTestVectorsDraft03[i].salt + kSaltSize); |
| 450 |
| 451 ASSERT_TRUE(cryptographer_->Encrypt( |
336 recipient_public_key_, sender_public_key_, ecdh_shared_secret, | 452 recipient_public_key_, sender_public_key_, ecdh_shared_secret, |
337 kCommonAuthSecret, salt, kEncryptionTestVectorsDraft03[i].input, | 453 auth_secret, salt, kEncryptionTestVectorsDraft03[i].input, &record_size, |
338 &record_size, &ciphertext); | 454 &ciphertext)); |
339 | 455 |
340 if (!has_output) { | 456 base::Base64UrlEncode(ciphertext, base::Base64UrlEncodePolicy::OMIT_PADDING, |
341 EXPECT_FALSE(result); | 457 &output); |
342 continue; | |
343 } | |
344 | |
345 EXPECT_TRUE(result); | |
346 ASSERT_TRUE(base::Base64UrlDecode( | |
347 kEncryptionTestVectorsDraft03[i].output, | |
348 base::Base64UrlDecodePolicy::IGNORE_PADDING, &output)); | |
349 | 458 |
350 EXPECT_EQ(kEncryptionTestVectorsDraft03[i].record_size, record_size); | 459 EXPECT_EQ(kEncryptionTestVectorsDraft03[i].record_size, record_size); |
351 EXPECT_EQ(output, ciphertext); | 460 EXPECT_EQ(kEncryptionTestVectorsDraft03[i].output, output); |
352 } | 461 } |
353 } | 462 } |
354 | 463 |
355 TEST_F(GCMMessageCryptographerTestVectorTest, DecryptionVectorsDraft03) { | 464 TEST_F(GCMMessageCryptographerTestVectorTest, DecryptionVectorsDraft03) { |
356 std::string input, ecdh_shared_secret, salt, plaintext; | 465 std::string input, ecdh_shared_secret, auth_secret, salt, plaintext; |
357 for (size_t i = 0; i < arraysize(kDecryptionTestVectorsDraft03); ++i) { | 466 for (size_t i = 0; i < arraysize(kDecryptionTestVectorsDraft03); ++i) { |
358 SCOPED_TRACE(i); | 467 SCOPED_TRACE(i); |
359 | 468 |
360 ASSERT_TRUE(base::Base64UrlDecode( | 469 ASSERT_TRUE(base::Base64UrlDecode( |
361 kDecryptionTestVectorsDraft03[i].input, | 470 kDecryptionTestVectorsDraft03[i].input, |
362 base::Base64UrlDecodePolicy::IGNORE_PADDING, &input)); | 471 base::Base64UrlDecodePolicy::IGNORE_PADDING, &input)); |
363 ASSERT_TRUE(base::Base64UrlDecode( | 472 |
| 473 ecdh_shared_secret.assign( |
364 kDecryptionTestVectorsDraft03[i].ecdh_shared_secret, | 474 kDecryptionTestVectorsDraft03[i].ecdh_shared_secret, |
365 base::Base64UrlDecodePolicy::IGNORE_PADDING, &ecdh_shared_secret)); | 475 kDecryptionTestVectorsDraft03[i].ecdh_shared_secret + |
366 ASSERT_TRUE(base::Base64UrlDecode( | 476 kEcdhSharedSecretSize); |
367 kDecryptionTestVectorsDraft03[i].salt, | 477 |
368 base::Base64UrlDecodePolicy::IGNORE_PADDING, &salt)); | 478 auth_secret.assign( |
| 479 kDecryptionTestVectorsDraft03[i].auth_secret, |
| 480 kDecryptionTestVectorsDraft03[i].auth_secret + kAuthSecretSize); |
| 481 |
| 482 salt.assign(kDecryptionTestVectorsDraft03[i].salt, |
| 483 kDecryptionTestVectorsDraft03[i].salt + kSaltSize); |
369 | 484 |
370 const bool has_output = kDecryptionTestVectorsDraft03[i].output; | 485 const bool has_output = kDecryptionTestVectorsDraft03[i].output; |
371 const bool result = cryptographer_->Decrypt( | 486 const bool result = cryptographer_->Decrypt( |
372 recipient_public_key_, sender_public_key_, ecdh_shared_secret, | 487 recipient_public_key_, sender_public_key_, ecdh_shared_secret, |
373 kCommonAuthSecret, salt, input, | 488 auth_secret, salt, input, kDecryptionTestVectorsDraft03[i].record_size, |
374 kDecryptionTestVectorsDraft03[i].record_size, &plaintext); | 489 &plaintext); |
375 | 490 |
376 if (!has_output) { | 491 if (!has_output) { |
377 EXPECT_FALSE(result); | 492 EXPECT_FALSE(result); |
378 continue; | 493 continue; |
379 } | 494 } |
380 | 495 |
381 EXPECT_TRUE(result); | 496 EXPECT_TRUE(result); |
382 EXPECT_EQ(kDecryptionTestVectorsDraft03[i].output, plaintext); | 497 EXPECT_EQ(kDecryptionTestVectorsDraft03[i].output, plaintext); |
383 } | 498 } |
384 } | 499 } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 | 609 |
495 // And verify that decrypting the message yields the plaintext again. | 610 // And verify that decrypting the message yields the plaintext again. |
496 ASSERT_TRUE(cryptographer.Decrypt(recipient_public_key, sender_public_key, | 611 ASSERT_TRUE(cryptographer.Decrypt(recipient_public_key, sender_public_key, |
497 sender_shared_secret, auth_secret, salt, | 612 sender_shared_secret, auth_secret, salt, |
498 ciphertext, record_size, &plaintext)); | 613 ciphertext, record_size, &plaintext)); |
499 | 614 |
500 ASSERT_EQ(kPlaintext, plaintext); | 615 ASSERT_EQ(kPlaintext, plaintext); |
501 } | 616 } |
502 | 617 |
503 } // namespace gcm | 618 } // namespace gcm |
OLD | NEW |