blob: 913870117b1ba48f6608904b039d9fe23c780ec5 [file] [log] [blame]
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento914d05f2019-07-13 16:20:19 -04002/*
Zhiyi Zhanga67fa462020-04-19 13:48:03 -07003 * Copyright (c) 2017-2020, Regents of the University of California.
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -07004 *
5 * This file is part of ndncert, a certificate management system based on NDN.
6 *
7 * ndncert is free software: you can redistribute it and/or modify it under the terms
8 * of the GNU General Public License as published by the Free Software Foundation, either
9 * version 3 of the License, or (at your option) any later version.
10 *
11 * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License along with
16 * ndncert, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * See AUTHORS.md for complete list of ndncert authors and contributors.
19 */
20
21#include "crypto-support/crypto-helper.hpp"
Zhiyi Zhang5d80e1e2020-09-25 11:34:54 -070022#include "test-common.hpp"
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070023
24namespace ndn {
25namespace ndncert {
26namespace tests {
27
28BOOST_AUTO_TEST_SUITE(TestCryptoHelper)
29
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070030BOOST_AUTO_TEST_CASE(EcdhWithRawKey)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070031{
32 ECDHState aliceState;
33 auto alicePub = aliceState.getRawSelfPubKey();
34 BOOST_CHECK(aliceState.context->publicKeyLen != 0);
35
36 ECDHState bobState;
37 auto bobPub = bobState.getRawSelfPubKey();
38 BOOST_CHECK(bobState.context->publicKeyLen != 0);
39
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070040 auto aliceResult = aliceState.deriveSecret(bobPub, bobState.context->publicKeyLen);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070041
42 BOOST_CHECK(aliceState.context->sharedSecretLen != 0);
43
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070044 auto bobResult = bobState.deriveSecret(alicePub, aliceState.context->publicKeyLen);
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070045
46 BOOST_CHECK(bobState.context->sharedSecretLen != 0);
47
48 BOOST_CHECK_EQUAL_COLLECTIONS(aliceResult, aliceResult + 32,
49 bobResult, bobResult + 32);
50}
51
Zhiyi Zhang8da54d62019-11-21 00:03:05 -080052BOOST_AUTO_TEST_CASE(EcdhWithRawKeyWrongInput)
53{
54 ECDHState aliceState;
55 auto alicePub = aliceState.getRawSelfPubKey();
56 BOOST_CHECK(alicePub != nullptr);
57 BOOST_CHECK(aliceState.context->publicKeyLen != 0);
58 uint8_t fakePub[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
59 BOOST_CHECK_THROW(aliceState.deriveSecret(fakePub, sizeof(fakePub)), CryptoError);
60}
61
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070062BOOST_AUTO_TEST_CASE(EcdhWithBase64Key)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070063{
64 ECDHState aliceState;
65 auto alicePub = aliceState.getBase64PubKey();
66 BOOST_CHECK(alicePub != "");
67
68 ECDHState bobState;
69 auto bobPub = bobState.getBase64PubKey();
70 BOOST_CHECK(bobPub != "");
71
72 auto aliceResult = aliceState.deriveSecret(bobPub);
73 BOOST_CHECK(aliceState.context->sharedSecretLen != 0);
74
75 auto bobResult = bobState.deriveSecret(alicePub);
76 BOOST_CHECK(bobState.context->sharedSecretLen != 0);
77
78 BOOST_CHECK_EQUAL_COLLECTIONS(aliceResult, aliceResult + 32,
79 bobResult, bobResult + 32);
80}
81
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070082BOOST_AUTO_TEST_CASE(HmacSha256)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070083{
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070084 // RFC5869 appendix A.1, IKM, Salt -> PRK
85 const uint8_t ikm[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
86 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
87 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
88 const uint8_t salt[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
89 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c};
90 const uint8_t expected[] = {0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf,
91 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
92 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
93 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5};
94 uint8_t result[32];
Zhiyi Zhang97bedb82020-10-10 11:11:35 -070095 hmac_sha256(ikm, sizeof(ikm), salt, sizeof(salt), result);
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070096 BOOST_CHECK_EQUAL_COLLECTIONS(result, result + sizeof(result), expected,
97 expected + sizeof(expected));
98}
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070099
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -0700100BOOST_AUTO_TEST_CASE(Hkdf1)
101{
102 // RFC5869 appendix A.1
103 const uint8_t ikm[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
104 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
105 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
106 const uint8_t salt[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
107 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c};
108 const uint8_t info[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
109 0xf5, 0xf6, 0xf7, 0xf8, 0xf9};
110 const uint8_t expected[] = {
111 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f,
112 0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a,
113 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34,
114 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65};
115 uint8_t result[42];
116 auto resultLen = hkdf(ikm, sizeof(ikm), salt, sizeof(salt), result,
117 sizeof(result), info, sizeof(info));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700118
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -0700119 BOOST_CHECK_EQUAL(resultLen, sizeof(result));
120 BOOST_CHECK_EQUAL_COLLECTIONS(result, result + sizeof(result), expected,
121 expected + sizeof(expected));
122}
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700123
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -0700124BOOST_AUTO_TEST_CASE(Hkdf2)
125{
126 // RFC5869 appendix A.2
127 const uint8_t ikm[] = {
128 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
129 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
130 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
131 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
132 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
133 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
134 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f};
135 const uint8_t salt[] = {
136 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
137 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
138 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
139 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
140 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
141 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
142 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf};
143 const uint8_t info[] = {
144 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb,
145 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
146 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,
147 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
148 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
149 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
150 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
151 const uint8_t expected[] = {
152 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, 0xc8, 0xe7, 0xf7, 0x8c,
153 0x59, 0x6a, 0x49, 0x34, 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
154 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c, 0x59, 0x04, 0x5a, 0x99,
155 0xca, 0xc7, 0x82, 0x72, 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
156 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8, 0x36, 0x77, 0x93, 0xa9,
157 0xac, 0xa3, 0xdb, 0x71, 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
158 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f, 0x1d, 0x87};
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700159
Davide Pesavento368341b2019-08-13 23:57:50 -0400160 uint8_t result[82];
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -0700161 auto resultLen = hkdf(ikm, sizeof(ikm), salt, sizeof(salt), result,
162 sizeof(result), info, sizeof(info));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700163
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -0700164 BOOST_CHECK_EQUAL(resultLen, sizeof(result));
165 BOOST_CHECK_EQUAL_COLLECTIONS(result, result + sizeof(result), expected,
166 expected + sizeof(expected));
167}
168
169BOOST_AUTO_TEST_CASE(Hkdf3)
170{
171 // RFC5869 appendix A.3
172 const uint8_t ikm[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
173 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
174 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
175 const uint8_t expected[] = {
176 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80,
177 0x2a, 0x06, 0x3c, 0x5a, 0x31, 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1,
178 0x87, 0x9e, 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, 0x9d,
179 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a, 0x96, 0xc8};
180 uint8_t result[42];
181
182 auto resultLen = hkdf(ikm, sizeof(ikm), nullptr, 0, result,
183 sizeof(result), nullptr, 0);
184
185 BOOST_CHECK_EQUAL(resultLen, sizeof(result));
186 BOOST_CHECK_EQUAL_COLLECTIONS(result, result + sizeof(result), expected,
187 expected + sizeof(expected));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700188}
189
Zhiyi Zhanga67fa462020-04-19 13:48:03 -0700190BOOST_AUTO_TEST_CASE(AesGcm1)
191{
192 // Test case from NIST Cryptographic Algorithm Validation Program
193 // https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/CAVP-TESTING-BLOCK-CIPHER-MODES
194 // Count = 0
195 // Key = cf063a34d4a9a76c2c86787d3f96db71
196 // IV = 113b9785971864c83b01c787
197 // CT =
198 // AAD =
199 // Tag = 72ac8493e3a5228b5d130a69d2510e42
200 // PT =
201 const uint8_t key[] = {0xcf, 0x06, 0x3a, 0x34, 0xd4, 0xa9, 0xa7, 0x6c,
202 0x2c, 0x86, 0x78, 0x7d, 0x3f, 0x96, 0xdb, 0x71};
203 const uint8_t iv[] = {0x11, 0x3b, 0x97, 0x85, 0x97, 0x18,
204 0x64, 0xc8, 0x3b, 0x01, 0xc7, 0x87};
205 const uint8_t expected_tag[] = {0x72, 0xac, 0x84, 0x93, 0xe3, 0xa5,
206 0x22, 0x8b, 0x5d, 0x13, 0x0a, 0x69,
207 0xd2, 0x51, 0x0e, 0x42};
208
209 uint8_t ciphertext[256] = {0};
210 uint8_t tag[16] = {0};
211 int size = aes_gcm_128_encrypt(nullptr, 0, nullptr, 0, key, iv, ciphertext, tag);
212 BOOST_CHECK(size == 0);
213 BOOST_CHECK_EQUAL_COLLECTIONS(tag, tag + 16, expected_tag, expected_tag + sizeof(expected_tag));
214
215 uint8_t decrypted[256] = {0};
216 size = aes_gcm_128_decrypt(ciphertext, size, nullptr, 0, tag, key, iv, decrypted);
217 BOOST_CHECK(size == 0);
218}
219
220BOOST_AUTO_TEST_CASE(AesGcm2)
221{
222 // Test case from NIST Cryptographic Algorithm Validation Program
223 // https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/CAVP-TESTING-BLOCK-CIPHER-MODES
224 // Count = 1
225 // Key = 2370e320d4344208e0ff5683f243b213
226 // IV = 04dbb82f044d30831c441228
227 // CT =
228 // AAD = d43a8e5089eea0d026c03a85178b27da
229 // Tag = 2a049c049d25aa95969b451d93c31c6e
230 // PT =
231 const uint8_t key[] = {0x23, 0x70, 0xe3, 0x20, 0xd4, 0x34, 0x42, 0x08,
232 0xe0, 0xff, 0x56, 0x83, 0xf2, 0x43, 0xb2, 0x13};
233 const uint8_t iv[] = {0x04, 0xdb, 0xb8, 0x2f, 0x04, 0x4d,
234 0x30, 0x83, 0x1c, 0x44, 0x12, 0x28};
235 const uint8_t aad[] = {0xd4, 0x3a, 0x8e, 0x50, 0x89, 0xee, 0xa0, 0xd0,
236 0x26, 0xc0, 0x3a, 0x85, 0x17, 0x8b, 0x27, 0xda};
237 const uint8_t expected_tag[] = {0x2a, 0x04, 0x9c, 0x04, 0x9d, 0x25,
238 0xaa, 0x95, 0x96, 0x9b, 0x45, 0x1d,
239 0x93, 0xc3, 0x1c, 0x6e};
240
241 uint8_t ciphertext[256] = {0};
242 uint8_t tag[16] = {0};
243 int size = aes_gcm_128_encrypt(nullptr, 0, aad, sizeof(aad), key, iv, ciphertext, tag);
244 BOOST_CHECK(size == 0);
245 BOOST_CHECK_EQUAL_COLLECTIONS(tag, tag + 16, expected_tag, expected_tag + sizeof(expected_tag));
246
247 uint8_t decrypted[256] = {0};
248 size = aes_gcm_128_decrypt(ciphertext, size, aad, sizeof(aad), tag, key, iv, decrypted);
249 BOOST_CHECK(size == 0);
250}
251
252BOOST_AUTO_TEST_CASE(AesGcm3)
253{
254 // Test case from NIST Cryptographic Algorithm Validation Program
255 // https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/CAVP-TESTING-BLOCK-CIPHER-MODES
256 // Count = 0
257 // Key = bc22f3f05cc40db9311e4192966fee92
258 // IV = 134988e662343c06d3ab83db
259 // CT = 4c0168ab95d3a10ef25e5924108389365c67d97778995892d9fd46897384af61fc559212b3267e90fe4df7bfd1fbed46f4b9ee
260 // AAD = 10087e6ed81049b509c31d12fee88c64
261 // Tag = 771357958a316f166bd0dacc98ea801a
262 // PT = 337c1bc992386cf0f957617fe4d5ec1218ae1cc40369305518eb177e9b15c1646b142ff71237efaa58790080cd82e8848b295c
263 const uint8_t key[] = {0xbc, 0x22, 0xf3, 0xf0, 0x5c, 0xc4, 0x0d, 0xb9,
264 0x31, 0x1e, 0x41, 0x92, 0x96, 0x6f, 0xee, 0x92};
265 const uint8_t iv[] = {0x13, 0x49, 0x88, 0xe6, 0x62, 0x34,
266 0x3c, 0x06, 0xd3, 0xab, 0x83, 0xdb};
267 const uint8_t aad[] = {0x10, 0x08, 0x7e, 0x6e, 0xd8, 0x10, 0x49, 0xb5,
268 0x09, 0xc3, 0x1d, 0x12, 0xfe, 0xe8, 0x8c, 0x64};
269 const uint8_t expected_ciphertext[] = {
270 0x4c, 0x01, 0x68, 0xab, 0x95, 0xd3, 0xa1, 0x0e, 0xf2, 0x5e, 0x59,
271 0x24, 0x10, 0x83, 0x89, 0x36, 0x5c, 0x67, 0xd9, 0x77, 0x78, 0x99,
272 0x58, 0x92, 0xd9, 0xfd, 0x46, 0x89, 0x73, 0x84, 0xaf, 0x61, 0xfc,
273 0x55, 0x92, 0x12, 0xb3, 0x26, 0x7e, 0x90, 0xfe, 0x4d, 0xf7, 0xbf,
274 0xd1, 0xfb, 0xed, 0x46, 0xf4, 0xb9, 0xee};
275 const uint8_t expected_tag[] = {0x77, 0x13, 0x57, 0x95, 0x8a, 0x31,
276 0x6f, 0x16, 0x6b, 0xd0, 0xda, 0xcc,
277 0x98, 0xea, 0x80, 0x1a};
278 const uint8_t plaintext[] = {
279 0x33, 0x7c, 0x1b, 0xc9, 0x92, 0x38, 0x6c, 0xf0, 0xf9, 0x57, 0x61,
280 0x7f, 0xe4, 0xd5, 0xec, 0x12, 0x18, 0xae, 0x1c, 0xc4, 0x03, 0x69,
281 0x30, 0x55, 0x18, 0xeb, 0x17, 0x7e, 0x9b, 0x15, 0xc1, 0x64, 0x6b,
282 0x14, 0x2f, 0xf7, 0x12, 0x37, 0xef, 0xaa, 0x58, 0x79, 0x00, 0x80,
283 0xcd, 0x82, 0xe8, 0x84, 0x8b, 0x29, 0x5c};
284
285 uint8_t ciphertext[256] = {0};
286 uint8_t tag[16] = {0};
287 int size = aes_gcm_128_encrypt(plaintext, sizeof(plaintext), aad, sizeof(aad), key, iv, ciphertext, tag);
288 BOOST_CHECK_EQUAL_COLLECTIONS(ciphertext, ciphertext + size,
289 expected_ciphertext, expected_ciphertext + sizeof(expected_ciphertext));
290 BOOST_CHECK_EQUAL_COLLECTIONS(tag, tag + 16, expected_tag, expected_tag + sizeof(expected_tag));
291
292 uint8_t decrypted[256] = {0};
293 size = aes_gcm_128_decrypt(ciphertext, size, aad, sizeof(aad), tag, key, iv, decrypted);
294 BOOST_CHECK(memcmp(decrypted, plaintext, sizeof(plaintext)) == 0);
295}
296
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700297BOOST_AUTO_TEST_SUITE_END()
298
299} // namespace tests
300} // namespace ndncert
301} // namespace ndn