blob: f8ec1a4720d86c4eb31ef731d9faa8d16777dbb2 [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/*
Davide Pesaventoa3dbb942023-09-16 22:30:35 -04003 * Copyright (c) 2017-2023, 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
Zhiyi Zhangdc25ddf2020-10-20 14:28:55 -070021#include "detail/crypto-helpers.hpp"
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040022
Davide Pesavento829aff62022-05-15 20:30:34 -040023#include "tests/boost-test.hpp"
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070024
Davide Pesaventoa3dbb942023-09-16 22:30:35 -040025#include <boost/endian/conversion.hpp>
26
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040027namespace ndncert::tests {
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070028
Zhiyi Zhangb40027f2020-10-20 18:35:27 -070029BOOST_AUTO_TEST_SUITE(TestCryptoHelpers)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070030
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070031BOOST_AUTO_TEST_CASE(EcdhWithRawKey)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070032{
33 ECDHState aliceState;
Zhiyi Zhangbed854c2020-10-20 18:25:35 -070034 auto alicePub = aliceState.getSelfPubKey();
35 BOOST_CHECK(!alicePub.empty());
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070036
37 ECDHState bobState;
Zhiyi Zhangbed854c2020-10-20 18:25:35 -070038 auto bobPub = bobState.getSelfPubKey();
39 BOOST_CHECK(!bobPub.empty());
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070040
Zhiyi Zhangbed854c2020-10-20 18:25:35 -070041 auto aliceResult = aliceState.deriveSecret(bobPub);
42 BOOST_CHECK(!aliceResult.empty());
43 auto bobResult = bobState.deriveSecret(alicePub);
44 BOOST_CHECK(!bobResult.empty());
45 BOOST_CHECK_EQUAL_COLLECTIONS(aliceResult.begin(), aliceResult.end(), bobResult.begin(), bobResult.end());
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070046}
47
Zhiyi Zhang8da54d62019-11-21 00:03:05 -080048BOOST_AUTO_TEST_CASE(EcdhWithRawKeyWrongInput)
49{
50 ECDHState aliceState;
Zhiyi Zhangbed854c2020-10-20 18:25:35 -070051 auto alicePub = aliceState.getSelfPubKey();
52 BOOST_CHECK(!alicePub.empty());
Zhiyi Zhang0eb74242020-10-20 18:33:22 -070053 std::vector<uint8_t> fakePub(10, 0x0b);
54 BOOST_CHECK_THROW(aliceState.deriveSecret(fakePub), std::runtime_error);
Zhiyi Zhang8da54d62019-11-21 00:03:05 -080055}
56
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070057BOOST_AUTO_TEST_CASE(HmacSha256)
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070058{
Zhiyi Zhangdd308932020-10-16 21:59:06 -070059 const uint8_t input[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
60 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
61 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
tylerliu00de2c32020-10-20 17:33:08 -070062 const uint8_t key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070063 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c};
64 const uint8_t expected[] = {0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf,
65 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
66 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
67 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5};
68 uint8_t result[32];
tylerliu00de2c32020-10-20 17:33:08 -070069 hmacSha256(input, sizeof(input), key, sizeof(key), result);
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070070 BOOST_CHECK_EQUAL_COLLECTIONS(result, result + sizeof(result), expected,
71 expected + sizeof(expected));
72}
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070073
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070074BOOST_AUTO_TEST_CASE(Hkdf1)
75{
76 // RFC5869 appendix A.1
77 const uint8_t ikm[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
78 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
79 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
80 const uint8_t salt[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
81 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c};
82 const uint8_t info[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
83 0xf5, 0xf6, 0xf7, 0xf8, 0xf9};
84 const uint8_t expected[] = {
85 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f,
86 0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a,
87 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34,
88 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65};
89 uint8_t result[42];
90 auto resultLen = hkdf(ikm, sizeof(ikm), salt, sizeof(salt), result,
91 sizeof(result), info, sizeof(info));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070092
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070093 BOOST_CHECK_EQUAL(resultLen, sizeof(result));
94 BOOST_CHECK_EQUAL_COLLECTIONS(result, result + sizeof(result), expected,
95 expected + sizeof(expected));
96}
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -070097
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -070098BOOST_AUTO_TEST_CASE(Hkdf2)
99{
100 // RFC5869 appendix A.2
101 const uint8_t ikm[] = {
102 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
103 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
104 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
105 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
106 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
107 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
108 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f};
109 const uint8_t salt[] = {
110 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
111 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
112 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
113 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
114 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
115 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
116 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf};
117 const uint8_t info[] = {
118 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb,
119 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
120 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,
121 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
122 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
123 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
124 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
125 const uint8_t expected[] = {
126 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, 0xc8, 0xe7, 0xf7, 0x8c,
127 0x59, 0x6a, 0x49, 0x34, 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
128 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c, 0x59, 0x04, 0x5a, 0x99,
129 0xca, 0xc7, 0x82, 0x72, 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
130 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8, 0x36, 0x77, 0x93, 0xa9,
131 0xac, 0xa3, 0xdb, 0x71, 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
132 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f, 0x1d, 0x87};
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700133
Davide Pesavento368341b2019-08-13 23:57:50 -0400134 uint8_t result[82];
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -0700135 auto resultLen = hkdf(ikm, sizeof(ikm), salt, sizeof(salt), result,
136 sizeof(result), info, sizeof(info));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700137
Zhiyi Zhanga2ce5992019-08-14 17:35:00 -0700138 BOOST_CHECK_EQUAL(resultLen, sizeof(result));
139 BOOST_CHECK_EQUAL_COLLECTIONS(result, result + sizeof(result), expected,
140 expected + sizeof(expected));
141}
142
143BOOST_AUTO_TEST_CASE(Hkdf3)
144{
145 // RFC5869 appendix A.3
146 const uint8_t ikm[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
147 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
148 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
149 const uint8_t expected[] = {
150 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80,
151 0x2a, 0x06, 0x3c, 0x5a, 0x31, 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1,
152 0x87, 0x9e, 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, 0x9d,
153 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a, 0x96, 0xc8};
154 uint8_t result[42];
155
156 auto resultLen = hkdf(ikm, sizeof(ikm), nullptr, 0, result,
157 sizeof(result), nullptr, 0);
158
159 BOOST_CHECK_EQUAL(resultLen, sizeof(result));
160 BOOST_CHECK_EQUAL_COLLECTIONS(result, result + sizeof(result), expected,
161 expected + sizeof(expected));
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700162}
163
Zhiyi Zhanga67fa462020-04-19 13:48:03 -0700164BOOST_AUTO_TEST_CASE(AesGcm1)
165{
166 // Test case from NIST Cryptographic Algorithm Validation Program
167 // https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/CAVP-TESTING-BLOCK-CIPHER-MODES
168 // Count = 0
169 // Key = cf063a34d4a9a76c2c86787d3f96db71
170 // IV = 113b9785971864c83b01c787
171 // CT =
172 // AAD =
173 // Tag = 72ac8493e3a5228b5d130a69d2510e42
174 // PT =
175 const uint8_t key[] = {0xcf, 0x06, 0x3a, 0x34, 0xd4, 0xa9, 0xa7, 0x6c,
176 0x2c, 0x86, 0x78, 0x7d, 0x3f, 0x96, 0xdb, 0x71};
177 const uint8_t iv[] = {0x11, 0x3b, 0x97, 0x85, 0x97, 0x18,
178 0x64, 0xc8, 0x3b, 0x01, 0xc7, 0x87};
179 const uint8_t expected_tag[] = {0x72, 0xac, 0x84, 0x93, 0xe3, 0xa5,
180 0x22, 0x8b, 0x5d, 0x13, 0x0a, 0x69,
181 0xd2, 0x51, 0x0e, 0x42};
182
183 uint8_t ciphertext[256] = {0};
184 uint8_t tag[16] = {0};
tylerliu06aa3682020-10-12 22:03:42 -0700185 const uint8_t empty_buffer[1] = {0};
Zhiyi Zhang11cf7eb2020-10-20 15:43:36 -0700186 int size = aesGcm128Encrypt(empty_buffer, 0, empty_buffer, 0, key, iv, ciphertext, tag);
Zhiyi Zhanga67fa462020-04-19 13:48:03 -0700187 BOOST_CHECK(size == 0);
188 BOOST_CHECK_EQUAL_COLLECTIONS(tag, tag + 16, expected_tag, expected_tag + sizeof(expected_tag));
189
190 uint8_t decrypted[256] = {0};
Zhiyi Zhang11cf7eb2020-10-20 15:43:36 -0700191 size = aesGcm128Decrypt(ciphertext, size, empty_buffer, 0, tag, key, iv, decrypted);
Zhiyi Zhanga67fa462020-04-19 13:48:03 -0700192 BOOST_CHECK(size == 0);
193}
194
195BOOST_AUTO_TEST_CASE(AesGcm2)
196{
197 // Test case from NIST Cryptographic Algorithm Validation Program
198 // https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/CAVP-TESTING-BLOCK-CIPHER-MODES
199 // Count = 1
200 // Key = 2370e320d4344208e0ff5683f243b213
201 // IV = 04dbb82f044d30831c441228
202 // CT =
203 // AAD = d43a8e5089eea0d026c03a85178b27da
204 // Tag = 2a049c049d25aa95969b451d93c31c6e
205 // PT =
206 const uint8_t key[] = {0x23, 0x70, 0xe3, 0x20, 0xd4, 0x34, 0x42, 0x08,
207 0xe0, 0xff, 0x56, 0x83, 0xf2, 0x43, 0xb2, 0x13};
208 const uint8_t iv[] = {0x04, 0xdb, 0xb8, 0x2f, 0x04, 0x4d,
209 0x30, 0x83, 0x1c, 0x44, 0x12, 0x28};
210 const uint8_t aad[] = {0xd4, 0x3a, 0x8e, 0x50, 0x89, 0xee, 0xa0, 0xd0,
211 0x26, 0xc0, 0x3a, 0x85, 0x17, 0x8b, 0x27, 0xda};
212 const uint8_t expected_tag[] = {0x2a, 0x04, 0x9c, 0x04, 0x9d, 0x25,
213 0xaa, 0x95, 0x96, 0x9b, 0x45, 0x1d,
214 0x93, 0xc3, 0x1c, 0x6e};
215
216 uint8_t ciphertext[256] = {0};
217 uint8_t tag[16] = {0};
tylerliu06aa3682020-10-12 22:03:42 -0700218 const uint8_t empty_buffer[1] = {0};
Zhiyi Zhang11cf7eb2020-10-20 15:43:36 -0700219 int size = aesGcm128Encrypt(empty_buffer, 0, aad, sizeof(aad), key, iv, ciphertext, tag);
Zhiyi Zhanga67fa462020-04-19 13:48:03 -0700220 BOOST_CHECK(size == 0);
221 BOOST_CHECK_EQUAL_COLLECTIONS(tag, tag + 16, expected_tag, expected_tag + sizeof(expected_tag));
222
223 uint8_t decrypted[256] = {0};
Zhiyi Zhang11cf7eb2020-10-20 15:43:36 -0700224 size = aesGcm128Decrypt(ciphertext, size, aad, sizeof(aad), tag, key, iv, decrypted);
Zhiyi Zhanga67fa462020-04-19 13:48:03 -0700225 BOOST_CHECK(size == 0);
226}
227
228BOOST_AUTO_TEST_CASE(AesGcm3)
229{
230 // Test case from NIST Cryptographic Algorithm Validation Program
231 // https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/CAVP-TESTING-BLOCK-CIPHER-MODES
232 // Count = 0
233 // Key = bc22f3f05cc40db9311e4192966fee92
234 // IV = 134988e662343c06d3ab83db
235 // CT = 4c0168ab95d3a10ef25e5924108389365c67d97778995892d9fd46897384af61fc559212b3267e90fe4df7bfd1fbed46f4b9ee
236 // AAD = 10087e6ed81049b509c31d12fee88c64
237 // Tag = 771357958a316f166bd0dacc98ea801a
238 // PT = 337c1bc992386cf0f957617fe4d5ec1218ae1cc40369305518eb177e9b15c1646b142ff71237efaa58790080cd82e8848b295c
239 const uint8_t key[] = {0xbc, 0x22, 0xf3, 0xf0, 0x5c, 0xc4, 0x0d, 0xb9,
240 0x31, 0x1e, 0x41, 0x92, 0x96, 0x6f, 0xee, 0x92};
241 const uint8_t iv[] = {0x13, 0x49, 0x88, 0xe6, 0x62, 0x34,
242 0x3c, 0x06, 0xd3, 0xab, 0x83, 0xdb};
243 const uint8_t aad[] = {0x10, 0x08, 0x7e, 0x6e, 0xd8, 0x10, 0x49, 0xb5,
244 0x09, 0xc3, 0x1d, 0x12, 0xfe, 0xe8, 0x8c, 0x64};
245 const uint8_t expected_ciphertext[] = {
246 0x4c, 0x01, 0x68, 0xab, 0x95, 0xd3, 0xa1, 0x0e, 0xf2, 0x5e, 0x59,
247 0x24, 0x10, 0x83, 0x89, 0x36, 0x5c, 0x67, 0xd9, 0x77, 0x78, 0x99,
248 0x58, 0x92, 0xd9, 0xfd, 0x46, 0x89, 0x73, 0x84, 0xaf, 0x61, 0xfc,
249 0x55, 0x92, 0x12, 0xb3, 0x26, 0x7e, 0x90, 0xfe, 0x4d, 0xf7, 0xbf,
250 0xd1, 0xfb, 0xed, 0x46, 0xf4, 0xb9, 0xee};
251 const uint8_t expected_tag[] = {0x77, 0x13, 0x57, 0x95, 0x8a, 0x31,
252 0x6f, 0x16, 0x6b, 0xd0, 0xda, 0xcc,
253 0x98, 0xea, 0x80, 0x1a};
254 const uint8_t plaintext[] = {
255 0x33, 0x7c, 0x1b, 0xc9, 0x92, 0x38, 0x6c, 0xf0, 0xf9, 0x57, 0x61,
256 0x7f, 0xe4, 0xd5, 0xec, 0x12, 0x18, 0xae, 0x1c, 0xc4, 0x03, 0x69,
257 0x30, 0x55, 0x18, 0xeb, 0x17, 0x7e, 0x9b, 0x15, 0xc1, 0x64, 0x6b,
258 0x14, 0x2f, 0xf7, 0x12, 0x37, 0xef, 0xaa, 0x58, 0x79, 0x00, 0x80,
259 0xcd, 0x82, 0xe8, 0x84, 0x8b, 0x29, 0x5c};
260
261 uint8_t ciphertext[256] = {0};
262 uint8_t tag[16] = {0};
Zhiyi Zhang11cf7eb2020-10-20 15:43:36 -0700263 int size = aesGcm128Encrypt(plaintext, sizeof(plaintext), aad, sizeof(aad), key, iv, ciphertext, tag);
Zhiyi Zhanga67fa462020-04-19 13:48:03 -0700264 BOOST_CHECK_EQUAL_COLLECTIONS(ciphertext, ciphertext + size,
265 expected_ciphertext, expected_ciphertext + sizeof(expected_ciphertext));
266 BOOST_CHECK_EQUAL_COLLECTIONS(tag, tag + 16, expected_tag, expected_tag + sizeof(expected_tag));
267
268 uint8_t decrypted[256] = {0};
Zhiyi Zhang11cf7eb2020-10-20 15:43:36 -0700269 size = aesGcm128Decrypt(ciphertext, size, aad, sizeof(aad), tag, key, iv, decrypted);
Zhiyi Zhang82e0c722020-10-14 17:51:29 -0700270 BOOST_CHECK_EQUAL_COLLECTIONS(decrypted, decrypted + size,
271 plaintext, plaintext + sizeof(plaintext));
Zhiyi Zhanga67fa462020-04-19 13:48:03 -0700272}
273
Zhiyi Zhang222810b2020-10-16 21:50:35 -0700274BOOST_AUTO_TEST_CASE(AesIV)
275{
Davide Pesaventoa3dbb942023-09-16 22:30:35 -0400276 namespace be = boost::endian;
277
Zhiyi Zhang222810b2020-10-16 21:50:35 -0700278 const uint8_t key[] = {0xbc, 0x22, 0xf3, 0xf0, 0x5c, 0xc4, 0x0d, 0xb9,
279 0x31, 0x1e, 0x41, 0x92, 0x96, 0x6f, 0xee, 0x92};
280 const std::string plaintext = "alongstringalongstringalongstringalongstringalongstringalongstringalongstringalongstring";
281 const std::string associatedData = "test";
Zhiyi Zhang4f1c0102020-12-21 15:08:09 -0800282 std::vector<uint8_t> encryptionIv = {};
Zhiyi Zhang222810b2020-10-16 21:50:35 -0700283 auto block = encodeBlockWithAesGcm128(ndn::tlv::Content, key, (uint8_t*)plaintext.c_str(), plaintext.size(),
Zhiyi Zhang4f1c0102020-12-21 15:08:09 -0800284 (uint8_t*)associatedData.c_str(), associatedData.size(), encryptionIv);
Zhiyi Zhang222810b2020-10-16 21:50:35 -0700285 block.parse();
286 auto ivBlock = block.get(tlv::InitializationVector);
Davide Pesavento0dc02012021-11-23 22:55:03 -0500287 ndn::Buffer ivBuf(ivBlock.value(), ivBlock.value_size());
Zhiyi Zhang222810b2020-10-16 21:50:35 -0700288 BOOST_CHECK_EQUAL(ivBuf.size(), 12);
Davide Pesaventoa3dbb942023-09-16 22:30:35 -0400289 BOOST_CHECK_EQUAL((be::endian_load<uint32_t, 4, be::order::big>(&encryptionIv[8])), 6);
290 BOOST_CHECK_EQUAL((be::endian_load<uint32_t, 4, be::order::big>(&ivBuf[8])), 0);
Zhiyi Zhang4f1c0102020-12-21 15:08:09 -0800291
Zhiyi Zhang222810b2020-10-16 21:50:35 -0700292 block = encodeBlockWithAesGcm128(ndn::tlv::ApplicationParameters, key, (uint8_t*)plaintext.c_str(), plaintext.size(),
Zhiyi Zhang4f1c0102020-12-21 15:08:09 -0800293 (uint8_t*)associatedData.c_str(), associatedData.size(), encryptionIv);
Zhiyi Zhang222810b2020-10-16 21:50:35 -0700294 block.parse();
295 ivBlock = block.get(tlv::InitializationVector);
Davide Pesavento0dc02012021-11-23 22:55:03 -0500296 ndn::Buffer ivBuf2(ivBlock.value(), ivBlock.value_size());
Zhiyi Zhang4f1c0102020-12-21 15:08:09 -0800297 BOOST_CHECK_EQUAL(std::memcmp(ivBuf2.data(), encryptionIv.data(), 8), 0);
Zhiyi Zhang222810b2020-10-16 21:50:35 -0700298}
299
Zhiyi Zhangc5d93a92020-10-14 17:07:35 -0700300BOOST_AUTO_TEST_CASE(BlockEncodingDecoding)
301{
302 const uint8_t key[] = {0xbc, 0x22, 0xf3, 0xf0, 0x5c, 0xc4, 0x0d, 0xb9,
303 0x31, 0x1e, 0x41, 0x92, 0x96, 0x6f, 0xee, 0x92};
304 const std::string plaintext = "alongstringalongstringalongstringalongstringalongstringalongstringalongstringalongstring";
Zhiyi Zhang0fe18652020-10-21 13:07:31 -0700305 const std::string plaintext2 = "shortstring";
Zhiyi Zhangdd308932020-10-16 21:59:06 -0700306 const std::string associatedData = "right";
307 const std::string wrongAssociatedData = "wrong";
Zhiyi Zhang4f1c0102020-12-21 15:08:09 -0800308 std::vector<uint8_t> encryptionIv;
309 std::vector<uint8_t> decryptionIv;
Zhiyi Zhang0fe18652020-10-21 13:07:31 -0700310 // long string encryption
Zhiyi Zhangc5d93a92020-10-14 17:07:35 -0700311 auto block = encodeBlockWithAesGcm128(ndn::tlv::Content, key, (uint8_t*)plaintext.c_str(), plaintext.size(),
Zhiyi Zhang4f1c0102020-12-21 15:08:09 -0800312 (uint8_t*)associatedData.c_str(), associatedData.size(), encryptionIv);
Zhiyi Zhang3b9a5032021-02-18 11:15:09 -0800313 BOOST_CHECK_EQUAL(encryptionIv.size(), 12);
314 // the decryption's random component cannot be the same as encryption IV
315 BOOST_CHECK_THROW(decodeBlockWithAesGcm128(block, key,
316 (uint8_t*)associatedData.c_str(),
317 associatedData.size(), decryptionIv, encryptionIv),
318 std::runtime_error);
Zhiyi Zhang4f1c0102020-12-21 15:08:09 -0800319 auto decoded = decodeBlockWithAesGcm128(block, key, (uint8_t*)associatedData.c_str(), associatedData.size(),
Zhiyi Zhang3b9a5032021-02-18 11:15:09 -0800320 decryptionIv, std::vector<uint8_t>());
321 BOOST_CHECK_EQUAL(decryptionIv.size(), 12);
Zhiyi Zhangdd308932020-10-16 21:59:06 -0700322 BOOST_CHECK_EQUAL(plaintext, std::string(decoded.get<char>(), decoded.size()));
Zhiyi Zhang0fe18652020-10-21 13:07:31 -0700323
324 // short string encryption
325 block = encodeBlockWithAesGcm128(ndn::tlv::Content, key, (uint8_t*)plaintext2.c_str(), plaintext2.size(),
Zhiyi Zhang4f1c0102020-12-21 15:08:09 -0800326 (uint8_t*)associatedData.c_str(), associatedData.size(), encryptionIv);
327 decoded = decodeBlockWithAesGcm128(block, key, (uint8_t*)associatedData.c_str(), associatedData.size(),
Zhiyi Zhang3b9a5032021-02-18 11:15:09 -0800328 decryptionIv, std::vector<uint8_t>());
Zhiyi Zhang0fe18652020-10-21 13:07:31 -0700329 BOOST_CHECK_EQUAL(plaintext2, std::string(decoded.get<char>(), decoded.size()));
330
331 // use wrong associated data
Zhiyi Zhang199508a2020-10-21 10:45:50 -0700332 BOOST_CHECK_THROW(decodeBlockWithAesGcm128(block, key,
333 (uint8_t*)wrongAssociatedData.c_str(),
Zhiyi Zhang3b9a5032021-02-18 11:15:09 -0800334 wrongAssociatedData.size(), decryptionIv, std::vector<uint8_t>()),
335 std::runtime_error);
Zhiyi Zhang4f1c0102020-12-21 15:08:09 -0800336 // use wrong last observed IV
337 decryptionIv[0] += 1;
338 BOOST_CHECK_THROW(decodeBlockWithAesGcm128(block, key,
339 (uint8_t*)associatedData.c_str(),
Zhiyi Zhang3b9a5032021-02-18 11:15:09 -0800340 associatedData.size(), decryptionIv, std::vector<uint8_t>()),
341 std::runtime_error);
Zhiyi Zhangc5d93a92020-10-14 17:07:35 -0700342}
343
Davide Pesavento0dc02012021-11-23 22:55:03 -0500344BOOST_AUTO_TEST_SUITE_END() // TestCryptoHelpers
Zhiyi Zhangaf7c2902019-03-14 22:13:21 -0700345
Davide Pesavento0d1d11c2022-04-11 22:11:34 -0400346} // namespace ndncert::tests