blob: 7c89d760d797336b31ff272300d4f4a19d78bc04 [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"
22#include "encryptor.hpp"
23#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
140
141BOOST_AUTO_TEST_CASE_TEMPLATE(ContentSymmetricEncrypt, T, EncryptorAesTestInputs)
142{
143 T input;
144
145 Data data;
146 encryptData(data, input.plainText.buf(), input.plainText.size(),
147 input.keyName, input.key.buf(), input.key.size(), input.encryptParams);
148
149 BOOST_CHECK_EQUAL_COLLECTIONS(input.encryptedContent.begin(), input.encryptedContent.end(),
150 data.getContent().wire(), data.getContent().wire() + data.getContent().size());
151
152 EncryptedContent content(data.getContent().blockFromValue());
153 const Buffer& decryptedOutput = Aes::decrypt(input.key.buf(), input.key.size(),
154 content.getPayload().buf(), content.getPayload().size(),
155 input.encryptParams);
156
157 BOOST_CHECK_EQUAL_COLLECTIONS(input.plainText.begin(), input.plainText.end(),
158 decryptedOutput.begin(), decryptedOutput.end());
159}
160
161class TestDataRsaOaep
162{
163public:
164 TestDataRsaOaep()
165 : type(tlv::AlgorithmRsaOaep)
166 {
167 }
168public:
169 tlv::AlgorithmTypeValue type;
170};
171
172class TestDataRsaPkcs
173{
174public:
175 TestDataRsaPkcs()
176 : type(tlv::AlgorithmRsaPkcs)
177 {
178 }
179public:
180 tlv::AlgorithmTypeValue type;
181};
182
183typedef boost::mpl::list<TestDataRsaOaep,
184 TestDataRsaPkcs> EncryptorRsaTestInputs;
185
186BOOST_AUTO_TEST_CASE_TEMPLATE(ContentAsymmetricEncryptSmall, T, EncryptorRsaTestInputs)
187{
188 T type;
189
190 const uint8_t raw_content[] = {
191 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
192 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
193 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73
194 };
195
196 Data data;
197 RandomNumberGenerator rng;
198 RsaKeyParams rsaParams(1024);
199
200 Name keyName("test");
201
202 DecryptKey<Rsa> decryptKey = Rsa::generateKey(rng, rsaParams);
203 EncryptKey<Rsa> encryptKey = Rsa::deriveEncryptKey(decryptKey.getKeyBits());
204
205 Buffer eKey = encryptKey.getKeyBits();
206 Buffer dKey = decryptKey.getKeyBits();
207
208 EncryptParams encryptParams(type.type);
209
210 encryptData(data, raw_content, sizeof(raw_content),
211 keyName, eKey.buf(), eKey.size(), encryptParams);
212
213 Block dataContent = data.getContent();
214 dataContent.parse();
215 BOOST_CHECK_EQUAL(dataContent.elements_size(), 1);
216
217 EncryptedContent extractContent(data.getContent().blockFromValue());
218 BOOST_CHECK_EQUAL(extractContent.getKeyLocator().getName(), keyName);
219 BOOST_CHECK_EQUAL(extractContent.getInitialVector().size(), 0);
220 BOOST_CHECK_EQUAL(extractContent.getAlgorithmType(), type.type);
221
222 const Buffer& recovered = extractContent.getPayload();
223 Buffer decrypted = Rsa::decrypt(dKey.buf(), dKey.size(), recovered.buf(), recovered.size(), encryptParams);
224 BOOST_CHECK_EQUAL_COLLECTIONS(raw_content, raw_content + sizeof(raw_content),
225 decrypted.begin(), decrypted.end());
226}
227
228BOOST_AUTO_TEST_CASE_TEMPLATE(ContentAsymmetricEncryptLarge, T, EncryptorRsaTestInputs)
229{
230 T type;
231
232 const uint8_t large_content[] = {
233 0x73, 0x5a, 0xbd, 0x47, 0x0c, 0xfe, 0xf8, 0x7d,
234 0x2e, 0x17, 0xaa, 0x11, 0x6f, 0x23, 0xc5, 0x10,
235 0x23, 0x36, 0x88, 0xc4, 0x2a, 0x0f, 0x9a, 0x72,
236 0x54, 0x31, 0xa8, 0xb3, 0x51, 0x18, 0x9f, 0x0e,
237 0x1b, 0x93, 0x62, 0xd9, 0xc4, 0xf5, 0xf4, 0x3d,
238 0x61, 0x9a, 0xca, 0x05, 0x65, 0x6b, 0xc6, 0x41,
239 0xf9, 0xd5, 0x1c, 0x67, 0xc1, 0xd0, 0xd5, 0x6f,
240 0x7b, 0x70, 0xb8, 0x8f, 0xdb, 0x19, 0x68, 0x7c,
241 0xe0, 0x2d, 0x04, 0x49, 0xa9, 0xa2, 0x77, 0x4e,
242 0xfc, 0x60, 0x0d, 0x7c, 0x1b, 0x93, 0x6c, 0xd2,
243 0x61, 0xc4, 0x6b, 0x01, 0xe9, 0x12, 0x28, 0x6d,
244 0xf5, 0x78, 0xe9, 0x99, 0x0b, 0x9c, 0x4f, 0x90,
245 0x34, 0x3e, 0x06, 0x92, 0x57, 0xe3, 0x7a, 0x8f,
246 0x13, 0xc7, 0xf3, 0xfe, 0xf0, 0xe2, 0x59, 0x48,
247 0x15, 0xb9, 0xdb, 0x77, 0x07, 0x1d, 0x6d, 0xb5,
248 0x65, 0x17, 0xdf, 0x76, 0x6f, 0xb5, 0x43, 0xde,
249 0x71, 0xac, 0xf1, 0x22, 0xbf, 0xb2, 0xe5, 0xd9,
250 0x22, 0xf1, 0x67, 0x76, 0x71, 0x0c, 0xff, 0x99,
251 0x7b, 0x94, 0x9b, 0x24, 0x20, 0x80, 0xe3, 0xcc,
252 0x06, 0x4a, 0xed, 0xdf, 0xec, 0x50, 0xd5, 0x87,
253 0x3d, 0xa0, 0x7d, 0x9c, 0xe5, 0x13, 0x10, 0x98,
254 0x14, 0xc3, 0x90, 0x10, 0xd9, 0x25, 0x9a, 0x59,
255 0xe9, 0x37, 0x26, 0xfd, 0x87, 0xd7, 0xf4, 0xf9,
256 0x11, 0x91, 0xad, 0x5c, 0x00, 0x95, 0xf5, 0x2b,
257 0x37, 0xf7, 0x4e, 0xb4, 0x4b, 0x42, 0x7c, 0xb3,
258 0xad, 0xd6, 0x33, 0x5f, 0x0b, 0x84, 0x57, 0x7f,
259 0xa7, 0x07, 0x73, 0x37, 0x4b, 0xab, 0x2e, 0xfb,
260 0xfe, 0x1e, 0xcb, 0xb6, 0x4a, 0xc1, 0x21, 0x5f,
261 0xec, 0x92, 0xb7, 0xac, 0x97, 0x75, 0x20, 0xc9,
262 0xd8, 0x9e, 0x93, 0xd5, 0x12, 0x7a, 0x64, 0xb9,
263 0x4c, 0xed, 0x49, 0x87, 0x44, 0x5b, 0x4f, 0x90,
264 0x34, 0x3e, 0x06, 0x92, 0x57, 0xe3, 0x7a, 0x8f,
265 0x13, 0xc7, 0xf3, 0xfe, 0xf0, 0xe2, 0x59, 0x48,
266 0x15, 0xb9, 0xdb, 0x77, 0x07, 0x1d, 0x6d, 0xb5,
267 0x65, 0x17, 0xdf, 0x76, 0x6f, 0xb5, 0x43, 0xde,
268 0x71, 0xac, 0xf1, 0x22, 0xbf, 0xb2, 0xe5, 0xd9
269 };
270
271 Data data;
272 RandomNumberGenerator rng;
273 RsaKeyParams rsaParams(1024);
274
275 Name keyName("test");
276
277 DecryptKey<Rsa> decryptKey = Rsa::generateKey(rng, rsaParams);
278 EncryptKey<Rsa> encryptKey = Rsa::deriveEncryptKey(decryptKey.getKeyBits());
279
280 Buffer eKey = encryptKey.getKeyBits();
281 Buffer dKey = decryptKey.getKeyBits();
282
283 EncryptParams encryptParams(type.type);
284 encryptData(data, large_content, sizeof(large_content),
285 keyName, eKey.buf(), eKey.size(), encryptParams);
286
287 Block largeDataContent = data.getContent();
288 largeDataContent.parse();
289 BOOST_CHECK_EQUAL(largeDataContent.elements_size(), 2);
290
291 Block::element_const_iterator it = largeDataContent.elements_begin();
292
293 BOOST_CHECK(it != largeDataContent.elements_end());
294 Block nonceContent(*it);
295 BOOST_CHECK_EQUAL(nonceContent.type(), tlv::EncryptedContent);
296 EncryptedContent encryptedNonce(nonceContent);
297 BOOST_CHECK_EQUAL(encryptedNonce.getKeyLocator().getName(), keyName);
298 BOOST_CHECK_EQUAL(encryptedNonce.getInitialVector().size(), 0);
299 BOOST_CHECK_EQUAL(encryptedNonce.getAlgorithmType(), type.type);
300
301 it++;
302 BOOST_CHECK(it != largeDataContent.elements_end());
303 Block payloadContent(*it);
304 BOOST_CHECK_EQUAL(payloadContent.type(), tlv::EncryptedContent);
305 EncryptedContent encryptedPayload(payloadContent);
306 Name nonceKeyName = keyName.append("nonce");
307 BOOST_CHECK_EQUAL(encryptedPayload.getKeyLocator().getName(), nonceKeyName);
308 BOOST_CHECK_EQUAL(encryptedPayload.getInitialVector().size(), 16);
309 BOOST_CHECK_EQUAL(encryptedPayload.getAlgorithmType(), tlv::AlgorithmAesCbc);
310
311 it++;
312 BOOST_CHECK(it == largeDataContent.elements_end());
313
314 const Buffer& bufferNonce = encryptedNonce.getPayload();
315 Buffer nonce = Rsa::decrypt(dKey.buf(), dKey.size(), bufferNonce.buf(), bufferNonce.size(), encryptParams);
316
317 encryptParams.setAlgorithmType(tlv::AlgorithmAesCbc);
318 encryptParams.setIV(encryptedPayload.getInitialVector().buf(), encryptedPayload.getInitialVector().size());
319 const Buffer& bufferPayload = encryptedPayload.getPayload();
320 Buffer largePayload = Aes::decrypt(nonce.buf(), nonce.size(), bufferPayload.buf(), bufferPayload.size(), encryptParams);
321
322 BOOST_CHECK_EQUAL_COLLECTIONS(large_content, large_content + sizeof(large_content),
323 largePayload.begin(), largePayload.end());
324}
325
326BOOST_AUTO_TEST_SUITE_END()
327
328} // namespace algo
329} // namespace tests
330} // namespace gep
331} // namespace ndn