blob: d6c0451827c4484bd65af654cd52de0d11160fb9 [file] [log] [blame]
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2015, Regents of the University of California
4 *
5 * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
6 * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
7 *
8 * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * ndn-group-encrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ndn-group-encrypt, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "random-number-generator.hpp"
21#include "encrypted-content.hpp"
Yingdi Yu3decf4e2015-11-02 12:33:31 -080022#include "algo/encryptor.hpp"
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -070023#include "algo/rsa.hpp"
24#include "algo/aes.hpp"
25
26#include <boost/mpl/list.hpp>
27#include "boost-test.hpp"
28#include <algorithm>
29
30namespace ndn {
31namespace gep {
32namespace algo {
33namespace tests {
34
35BOOST_AUTO_TEST_SUITE(TestEncryptor)
36
37class TestDataAesEcb
38{
39public:
40 TestDataAesEcb()
41 : keyName("/test")
42 , encryptParams(tlv::AlgorithmAesEcb)
43 {
44 const uint8_t raw_content[] = {
45 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
46 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
47 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73
48 };
49 plainText = Buffer(raw_content, sizeof(raw_content));
50
51 const uint8_t aes_key[] = {
52 0xdd, 0x60, 0x77, 0xec, 0xa9, 0x6b, 0x23, 0x1b,
53 0x40, 0x6b, 0x5a, 0xf8, 0x7d, 0x3d, 0x55, 0x32
54 };
55 key = Buffer(aes_key, sizeof(aes_key));
56
57 const uint8_t encrypted_content[] = {
58 0x15, 0x31,
59 0x82, 0x2f,
60 0x1c, 0x08,
61 0x07, 0x06,
62 0x08, 0x04, 0x74, 0x65, 0x73, 0x74,
63 0x83, 0x01,
64 0x00,
65 0x84, 0x20,
66 0x13, 0x80, 0x1a, 0xc0, 0x4c, 0x75, 0xa7, 0x7f,
67 0x43, 0x5e, 0xd7, 0xa6, 0x3f, 0xd3, 0x68, 0x94,
68 0xe2, 0xcf, 0x54, 0xb1, 0xc2, 0xce, 0xad, 0x9b,
69 0x56, 0x6e, 0x1c, 0xe6, 0x55, 0x1d, 0x79, 0x04
70 };
71 encryptedContent = Buffer(encrypted_content, sizeof(encrypted_content));
72 }
73
74public:
75 Buffer plainText;
76 Buffer key;
77 Name keyName;
78 EncryptParams encryptParams;
79 Buffer encryptedContent;
80};
81
82class TestDataAesCbc
83{
84public:
85 TestDataAesCbc()
86 : keyName("/test")
87 , encryptParams(tlv::AlgorithmAesCbc)
88 {
89 const uint8_t raw_content[] = {
90 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
91 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
92 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73
93 };
94 plainText = Buffer(raw_content, sizeof(raw_content));
95
96 const uint8_t aes_key[] = {
97 0xdd, 0x60, 0x77, 0xec, 0xa9, 0x6b, 0x23, 0x1b,
98 0x40, 0x6b, 0x5a, 0xf8, 0x7d, 0x3d, 0x55, 0x32
99 };
100 key = Buffer(aes_key, sizeof(aes_key));
101
102 const uint8_t iv[] = {
103 0x73, 0x6f, 0x6d, 0x65, 0x72, 0x61, 0x6e, 0x64,
104 0x6f, 0x6d, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72
105 };
106
107 encryptParams.setIV(iv, sizeof(iv));
108
109 const uint8_t encrypted_content[] = {
110 0x15, 0x43, // Content
111 0x82, 0x41, // EncryptedContent
112 0x1c, 0x08, // KeyLocator /test
113 0x07, 0x06,
114 0x08, 0x04, 0x74, 0x65, 0x73, 0x74,
115 0x83, 0x01, // EncryptedAlgorithm
116 0x01, // AlgorithmAesCbc
117 0x85, 0x10,
118 0x73, 0x6f, 0x6d, 0x65, 0x72, 0x61, 0x6e, 0x64,
119 0x6f, 0x6d, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72,
120 0x84, 0x20, // EncryptedPayLoad
121 0x6a, 0x6b, 0x58, 0x9c, 0x30, 0x3b, 0xd9, 0xa6,
122 0xed, 0xd2, 0x12, 0xef, 0x29, 0xad, 0xc3, 0x60,
123 0x1f, 0x1b, 0x6b, 0xc7, 0x03, 0xff, 0x53, 0x52,
124 0x82, 0x6d, 0x82, 0x73, 0x05, 0xf9, 0x03, 0xdc
125 };
126 encryptedContent = Buffer(encrypted_content, sizeof(encrypted_content));
127 }
128
129public:
130 Buffer plainText;
131 Buffer key;
132 Name keyName;
133 EncryptParams encryptParams;
134 Buffer encryptedContent;
135};
136
137typedef boost::mpl::list<TestDataAesCbc,
138 TestDataAesEcb> EncryptorAesTestInputs;
139
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -0700140BOOST_AUTO_TEST_CASE_TEMPLATE(ContentSymmetricEncrypt, T, EncryptorAesTestInputs)
141{
142 T input;
143
144 Data data;
145 encryptData(data, input.plainText.buf(), input.plainText.size(),
146 input.keyName, input.key.buf(), input.key.size(), input.encryptParams);
147
Yingdi Yu3decf4e2015-11-02 12:33:31 -0800148 BOOST_CHECK_EQUAL(data.getName(), Name("/FOR").append(input.keyName));
149
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -0700150 BOOST_CHECK_EQUAL_COLLECTIONS(input.encryptedContent.begin(), input.encryptedContent.end(),
151 data.getContent().wire(), data.getContent().wire() + data.getContent().size());
152
153 EncryptedContent content(data.getContent().blockFromValue());
154 const Buffer& decryptedOutput = Aes::decrypt(input.key.buf(), input.key.size(),
155 content.getPayload().buf(), content.getPayload().size(),
156 input.encryptParams);
157
158 BOOST_CHECK_EQUAL_COLLECTIONS(input.plainText.begin(), input.plainText.end(),
159 decryptedOutput.begin(), decryptedOutput.end());
160}
161
162class TestDataRsaOaep
163{
164public:
165 TestDataRsaOaep()
166 : type(tlv::AlgorithmRsaOaep)
167 {
168 }
169public:
170 tlv::AlgorithmTypeValue type;
171};
172
173class TestDataRsaPkcs
174{
175public:
176 TestDataRsaPkcs()
177 : type(tlv::AlgorithmRsaPkcs)
178 {
179 }
180public:
181 tlv::AlgorithmTypeValue type;
182};
183
184typedef boost::mpl::list<TestDataRsaOaep,
185 TestDataRsaPkcs> EncryptorRsaTestInputs;
186
187BOOST_AUTO_TEST_CASE_TEMPLATE(ContentAsymmetricEncryptSmall, T, EncryptorRsaTestInputs)
188{
189 T type;
190
191 const uint8_t raw_content[] = {
192 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
193 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
194 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73
195 };
196
197 Data data;
198 RandomNumberGenerator rng;
199 RsaKeyParams rsaParams(1024);
200
201 Name keyName("test");
202
203 DecryptKey<Rsa> decryptKey = Rsa::generateKey(rng, rsaParams);
204 EncryptKey<Rsa> encryptKey = Rsa::deriveEncryptKey(decryptKey.getKeyBits());
205
206 Buffer eKey = encryptKey.getKeyBits();
207 Buffer dKey = decryptKey.getKeyBits();
208
209 EncryptParams encryptParams(type.type);
210
211 encryptData(data, raw_content, sizeof(raw_content),
212 keyName, eKey.buf(), eKey.size(), encryptParams);
213
Yingdi Yu3decf4e2015-11-02 12:33:31 -0800214 BOOST_CHECK_EQUAL(data.getName(), Name("/FOR").append(keyName));
215
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -0700216 Block dataContent = data.getContent();
217 dataContent.parse();
218 BOOST_CHECK_EQUAL(dataContent.elements_size(), 1);
219
220 EncryptedContent extractContent(data.getContent().blockFromValue());
221 BOOST_CHECK_EQUAL(extractContent.getKeyLocator().getName(), keyName);
222 BOOST_CHECK_EQUAL(extractContent.getInitialVector().size(), 0);
223 BOOST_CHECK_EQUAL(extractContent.getAlgorithmType(), type.type);
224
225 const Buffer& recovered = extractContent.getPayload();
226 Buffer decrypted = Rsa::decrypt(dKey.buf(), dKey.size(), recovered.buf(), recovered.size(), encryptParams);
227 BOOST_CHECK_EQUAL_COLLECTIONS(raw_content, raw_content + sizeof(raw_content),
228 decrypted.begin(), decrypted.end());
229}
230
231BOOST_AUTO_TEST_CASE_TEMPLATE(ContentAsymmetricEncryptLarge, T, EncryptorRsaTestInputs)
232{
233 T type;
234
235 const uint8_t large_content[] = {
236 0x73, 0x5a, 0xbd, 0x47, 0x0c, 0xfe, 0xf8, 0x7d,
237 0x2e, 0x17, 0xaa, 0x11, 0x6f, 0x23, 0xc5, 0x10,
238 0x23, 0x36, 0x88, 0xc4, 0x2a, 0x0f, 0x9a, 0x72,
239 0x54, 0x31, 0xa8, 0xb3, 0x51, 0x18, 0x9f, 0x0e,
240 0x1b, 0x93, 0x62, 0xd9, 0xc4, 0xf5, 0xf4, 0x3d,
241 0x61, 0x9a, 0xca, 0x05, 0x65, 0x6b, 0xc6, 0x41,
242 0xf9, 0xd5, 0x1c, 0x67, 0xc1, 0xd0, 0xd5, 0x6f,
243 0x7b, 0x70, 0xb8, 0x8f, 0xdb, 0x19, 0x68, 0x7c,
244 0xe0, 0x2d, 0x04, 0x49, 0xa9, 0xa2, 0x77, 0x4e,
245 0xfc, 0x60, 0x0d, 0x7c, 0x1b, 0x93, 0x6c, 0xd2,
246 0x61, 0xc4, 0x6b, 0x01, 0xe9, 0x12, 0x28, 0x6d,
247 0xf5, 0x78, 0xe9, 0x99, 0x0b, 0x9c, 0x4f, 0x90,
248 0x34, 0x3e, 0x06, 0x92, 0x57, 0xe3, 0x7a, 0x8f,
249 0x13, 0xc7, 0xf3, 0xfe, 0xf0, 0xe2, 0x59, 0x48,
250 0x15, 0xb9, 0xdb, 0x77, 0x07, 0x1d, 0x6d, 0xb5,
251 0x65, 0x17, 0xdf, 0x76, 0x6f, 0xb5, 0x43, 0xde,
252 0x71, 0xac, 0xf1, 0x22, 0xbf, 0xb2, 0xe5, 0xd9,
253 0x22, 0xf1, 0x67, 0x76, 0x71, 0x0c, 0xff, 0x99,
254 0x7b, 0x94, 0x9b, 0x24, 0x20, 0x80, 0xe3, 0xcc,
255 0x06, 0x4a, 0xed, 0xdf, 0xec, 0x50, 0xd5, 0x87,
256 0x3d, 0xa0, 0x7d, 0x9c, 0xe5, 0x13, 0x10, 0x98,
257 0x14, 0xc3, 0x90, 0x10, 0xd9, 0x25, 0x9a, 0x59,
258 0xe9, 0x37, 0x26, 0xfd, 0x87, 0xd7, 0xf4, 0xf9,
259 0x11, 0x91, 0xad, 0x5c, 0x00, 0x95, 0xf5, 0x2b,
260 0x37, 0xf7, 0x4e, 0xb4, 0x4b, 0x42, 0x7c, 0xb3,
261 0xad, 0xd6, 0x33, 0x5f, 0x0b, 0x84, 0x57, 0x7f,
262 0xa7, 0x07, 0x73, 0x37, 0x4b, 0xab, 0x2e, 0xfb,
263 0xfe, 0x1e, 0xcb, 0xb6, 0x4a, 0xc1, 0x21, 0x5f,
264 0xec, 0x92, 0xb7, 0xac, 0x97, 0x75, 0x20, 0xc9,
265 0xd8, 0x9e, 0x93, 0xd5, 0x12, 0x7a, 0x64, 0xb9,
266 0x4c, 0xed, 0x49, 0x87, 0x44, 0x5b, 0x4f, 0x90,
267 0x34, 0x3e, 0x06, 0x92, 0x57, 0xe3, 0x7a, 0x8f,
268 0x13, 0xc7, 0xf3, 0xfe, 0xf0, 0xe2, 0x59, 0x48,
269 0x15, 0xb9, 0xdb, 0x77, 0x07, 0x1d, 0x6d, 0xb5,
270 0x65, 0x17, 0xdf, 0x76, 0x6f, 0xb5, 0x43, 0xde,
271 0x71, 0xac, 0xf1, 0x22, 0xbf, 0xb2, 0xe5, 0xd9
272 };
273
274 Data data;
275 RandomNumberGenerator rng;
276 RsaKeyParams rsaParams(1024);
277
278 Name keyName("test");
279
280 DecryptKey<Rsa> decryptKey = Rsa::generateKey(rng, rsaParams);
281 EncryptKey<Rsa> encryptKey = Rsa::deriveEncryptKey(decryptKey.getKeyBits());
282
283 Buffer eKey = encryptKey.getKeyBits();
284 Buffer dKey = decryptKey.getKeyBits();
285
286 EncryptParams encryptParams(type.type);
287 encryptData(data, large_content, sizeof(large_content),
288 keyName, eKey.buf(), eKey.size(), encryptParams);
289
Yingdi Yu3decf4e2015-11-02 12:33:31 -0800290 BOOST_CHECK_EQUAL(data.getName(), Name("/FOR").append(keyName));
291
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -0700292 Block largeDataContent = data.getContent();
293 largeDataContent.parse();
294 BOOST_CHECK_EQUAL(largeDataContent.elements_size(), 2);
295
296 Block::element_const_iterator it = largeDataContent.elements_begin();
297
298 BOOST_CHECK(it != largeDataContent.elements_end());
299 Block nonceContent(*it);
300 BOOST_CHECK_EQUAL(nonceContent.type(), tlv::EncryptedContent);
301 EncryptedContent encryptedNonce(nonceContent);
302 BOOST_CHECK_EQUAL(encryptedNonce.getKeyLocator().getName(), keyName);
303 BOOST_CHECK_EQUAL(encryptedNonce.getInitialVector().size(), 0);
304 BOOST_CHECK_EQUAL(encryptedNonce.getAlgorithmType(), type.type);
305
306 it++;
307 BOOST_CHECK(it != largeDataContent.elements_end());
308 Block payloadContent(*it);
309 BOOST_CHECK_EQUAL(payloadContent.type(), tlv::EncryptedContent);
310 EncryptedContent encryptedPayload(payloadContent);
311 Name nonceKeyName = keyName.append("nonce");
312 BOOST_CHECK_EQUAL(encryptedPayload.getKeyLocator().getName(), nonceKeyName);
313 BOOST_CHECK_EQUAL(encryptedPayload.getInitialVector().size(), 16);
314 BOOST_CHECK_EQUAL(encryptedPayload.getAlgorithmType(), tlv::AlgorithmAesCbc);
315
316 it++;
317 BOOST_CHECK(it == largeDataContent.elements_end());
318
319 const Buffer& bufferNonce = encryptedNonce.getPayload();
320 Buffer nonce = Rsa::decrypt(dKey.buf(), dKey.size(), bufferNonce.buf(), bufferNonce.size(), encryptParams);
321
322 encryptParams.setAlgorithmType(tlv::AlgorithmAesCbc);
323 encryptParams.setIV(encryptedPayload.getInitialVector().buf(), encryptedPayload.getInitialVector().size());
324 const Buffer& bufferPayload = encryptedPayload.getPayload();
325 Buffer largePayload = Aes::decrypt(nonce.buf(), nonce.size(), bufferPayload.buf(), bufferPayload.size(), encryptParams);
326
327 BOOST_CHECK_EQUAL_COLLECTIONS(large_content, large_content + sizeof(large_content),
328 largePayload.begin(), largePayload.end());
329}
330
331BOOST_AUTO_TEST_SUITE_END()
332
333} // namespace algo
334} // namespace tests
335} // namespace gep
336} // namespace ndn