1 /*===========================================================================
2 *
3 * PUBLIC DOMAIN NOTICE
4 * National Center for Biotechnology Information
5 *
6 * This software/database is a "United States Government Work" under the
7 * terms of the United States Copyright Act. It was written as part of
8 * the author's official duties as a United States Government employee and
9 * thus cannot be copyrighted. This software/database is freely available
10 * to the public for use. The National Library of Medicine and the U.S.
11 * Government have not placed any restriction on its use or reproduction.
12 *
13 * Although all reasonable efforts have been taken to ensure the accuracy
14 * and reliability of the software and data, the NLM and the U.S.
15 * Government do not and cannot warrant the performance or results that
16 * may be obtained by using this software or data. The NLM and the U.S.
17 * Government disclaim all warranties, express or implied, including
18 * warranties of performance, merchantability or fitness for any particular
19 * purpose.
20 *
21 * Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26
27 /**
28 * Unit tests for KEncDecTestSuite
29 */
30
31 #include <ktst/unit_test.hpp>
32 #include <krypto/key.h>
33 #include <krypto/encfile.h>
34 #include <krypto/encfile-priv.h>
35 #include <krypto/reencfile.h>
36 #include <kfs/impl.h>
37 #include <klib/rc.h>
38 #include <klib/log.h>
39 #include <kapp/args.h>
40 #include <kfg/config.h>
41
42 #include "test-cmn.hpp"
43
44 #include <string.h>
45 #include <stdio.h>
46
47 TEST_SUITE(KEncDecTestSuite);
48
TEST_CASE(KEncryptDecrypt)49 TEST_CASE(KEncryptDecrypt)
50 {
51 const char pw [] = "first pw";
52 KKey key;
53 REQUIRE_RC (KKeyInitUpdate (&key, kkeyAES128, pw, strlen (pw)));
54
55 const char enc_file_path_fmt [] = TMP_FOLDER "/enc_file%llu";
56
57 KFile * enc_file, * pt_file;
58
59 struct KDirectory * current_dir;
60 REQUIRE_RC ( KDirectoryNativeDir ( ¤t_dir ) );
61
62 // just in case if it still there
63 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
64
65 uint64_t file_sizes_n_32k[] = { 0, 1, 2, 10, 46, 51 };
66 int8_t file_size_variants[] = { -2, -1, 0, 1, 2 };
67
68 const uint8_t* file_fillers[] = { (const uint8_t *)"\0", (const uint8_t *)"\1\2\3\0" };
69 size_t file_fillers_sizes[] = { 1, 4 };
70
71 assert( sizeof file_fillers / sizeof file_fillers[0] == sizeof file_fillers_sizes / sizeof file_fillers_sizes[0] );
72
73 for (size_t filler_index = 0; filler_index < sizeof file_fillers / sizeof file_fillers[0]; ++filler_index )
74 {
75 printf("filler pattern: ");
76 for (size_t i = 0; i < file_fillers_sizes[filler_index]; ++i)
77 {
78 printf("0x%X ", file_fillers[filler_index][i]);
79 }
80 printf("\n");
81 for (size_t i = 0; i < sizeof file_sizes_n_32k / sizeof file_sizes_n_32k[0]; ++i)
82 {
83 for (size_t j = 0; j < sizeof file_size_variants / sizeof file_size_variants[0]; ++j)
84 {
85 if (file_sizes_n_32k[i] == 0 && file_size_variants[j] <= 0)
86 {
87 continue;
88 }
89
90 uint64_t file_size = file_sizes_n_32k[i] * BLOCK_32K_SIZE + file_size_variants[j];
91
92 char file_path[1024];
93 sprintf(file_path, enc_file_path_fmt, ( long long unsigned int ) file_size);
94
95 printf("encrypting/decrypting file %s, size: %llu, i: %zu, j: %zu\n", file_path, ( long long unsigned int ) file_size, i, j);
96
97 // create file
98 REQUIRE_RC ( TCreateEncFile( current_dir, file_path, TFileOpenMode_ReadWrite, &key, &enc_file ) );
99
100 // write file
101 REQUIRE_RC ( TFillFile( enc_file, file_fillers[filler_index], file_fillers_sizes[filler_index], file_size ) );
102
103 uint64_t size_data_actual;
104 REQUIRE_RC ( KFileSize ( enc_file, &size_data_actual ) );
105
106 // check content size
107 REQUIRE ( file_size == size_data_actual );
108
109 REQUIRE_RC ( KFileRelease ( enc_file ) );
110
111 // check raw file size and checksums
112 REQUIRE_RC ( TOpenPtFile ( current_dir, file_path, TFileOpenMode_Read, &pt_file ) );
113
114 uint64_t size_raw;
115 REQUIRE_RC ( KFileSize ( pt_file, &size_raw ) );
116 REQUIRE ( size_raw == TEncSizeFromPtSize(size_data_actual) );
117
118 REQUIRE_RC ( KEncFileValidate( pt_file ) );
119
120 REQUIRE_RC ( KFileRelease ( pt_file ) );
121
122 // check file content
123 REQUIRE_RC ( TOpenEncFile( current_dir, file_path, TFileOpenMode_Read, &key, &enc_file ) );
124
125 REQUIRE_RC ( TCheckFileContent( enc_file, file_fillers[filler_index], file_fillers_sizes[filler_index] ) );
126
127 REQUIRE_RC ( KFileRelease ( enc_file ) );
128 }
129 }
130 }
131
132 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
133 REQUIRE_RC ( KDirectoryRelease ( current_dir ) );
134 }
135
TEST_CASE(KDecryptZeroRawSize)136 TEST_CASE(KDecryptZeroRawSize)
137 {
138 const char pw [] = "first pw";
139 KKey key;
140 REQUIRE_RC (KKeyInitUpdate (&key, kkeyAES128, pw, strlen (pw)));
141
142 const char file_path [] = TMP_FOLDER "/zero_size_file_to_dec";
143
144 KFile * enc_file, * pt_file;
145
146 uint64_t file_size;
147
148 struct KDirectory * current_dir;
149 REQUIRE_RC ( KDirectoryNativeDir ( ¤t_dir ) );
150
151 // just in case if it still there
152 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
153 // create file
154 REQUIRE_RC ( TCreatePtFile( current_dir, file_path, TFileOpenMode_ReadWrite, &pt_file ) );
155 REQUIRE_RC ( KFileSize ( pt_file, &file_size ) );
156 REQUIRE ( file_size == 0 );
157 REQUIRE_RC ( KFileRelease ( pt_file ) );
158
159 LOGMSG ( klogWarn, "Expect errors after this line:" );
160 REQUIRE ( TOpenEncFile( current_dir, file_path, TFileOpenMode_Read, &key, &enc_file ) == RC( rcKrypto, rcFile, rcConstructing, rcSize, rcIncorrect ) );
161 LOGMSG ( klogWarn, "No more errors are expected" );
162
163 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
164 REQUIRE_RC ( KDirectoryRelease ( current_dir ) );
165 }
166
TEST_CASE(KDecryptZeroContentSizeRW)167 TEST_CASE(KDecryptZeroContentSizeRW)
168 {
169 const char pw [] = "first pw";
170 KKey key;
171 REQUIRE_RC (KKeyInitUpdate (&key, kkeyAES128, pw, strlen (pw)));
172
173 const char file_path [] = TMP_FOLDER "/zero_content_rw_file_to_dec";
174
175 KFile * enc_file, * pt_file;
176
177 uint64_t file_size;
178
179 struct KDirectory * current_dir;
180 REQUIRE_RC ( KDirectoryNativeDir ( ¤t_dir ) );
181
182 // just in case if it still there
183 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
184 // create file
185 REQUIRE_RC ( TCreateEncFile( current_dir, file_path, TFileOpenMode_ReadWrite, &key, &enc_file ) );
186 REQUIRE_RC ( KFileRelease ( enc_file ) );
187
188 // check raw size
189 REQUIRE_RC ( TOpenPtFile( current_dir, file_path, TFileOpenMode_Read, &pt_file ) );
190 REQUIRE_RC ( KFileSize ( pt_file, &file_size ) );
191 REQUIRE ( file_size == sizeof(KEncFileHeader) + sizeof(KEncFileFooter) );
192 REQUIRE_RC ( KEncFileValidate( pt_file ) );
193 REQUIRE_RC ( KFileRelease ( pt_file ) );
194
195 // check enc open
196 REQUIRE_RC ( TOpenEncFile( current_dir, file_path, TFileOpenMode_Read, &key, &enc_file ) );
197 REQUIRE_RC ( KFileRelease ( enc_file ) );
198
199 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
200 REQUIRE_RC ( KDirectoryRelease ( current_dir ) );
201 }
202
TEST_CASE(KDecryptZeroContentSizeWOnly)203 TEST_CASE(KDecryptZeroContentSizeWOnly)
204 {
205 const char pw [] = "first pw";
206 KKey key;
207 REQUIRE_RC (KKeyInitUpdate (&key, kkeyAES128, pw, strlen (pw)));
208
209 const char file_path [] = TMP_FOLDER "/zero_content_w_file_to_dec";
210
211 KFile * enc_file, * pt_file;
212
213 uint64_t file_size;
214
215 struct KDirectory * current_dir;
216 REQUIRE_RC ( KDirectoryNativeDir ( ¤t_dir ) );
217
218 // just in case if it still there
219 KDirectoryRemove ( current_dir, true, "temp"
220 #if defined(__APPLE__)
221 "mac");
222 #else
223 "linux");
224 #endif
225
226 // create file
227 REQUIRE_RC ( TCreateEncFile( current_dir, file_path, TFileOpenMode_Write, &key, &enc_file ) );
228 REQUIRE_RC ( KFileRelease ( enc_file ) );
229
230 // check raw size
231 REQUIRE_RC ( TOpenPtFile( current_dir, file_path, TFileOpenMode_Read, &pt_file ) );
232 REQUIRE_RC ( KFileSize ( pt_file, &file_size ) );
233 REQUIRE ( file_size == sizeof(KEncFileHeader) + sizeof(KEncFileFooter) );
234 REQUIRE_RC ( KEncFileValidate( pt_file ) );
235 REQUIRE_RC ( KFileRelease ( pt_file ) );
236
237 // check enc open
238 REQUIRE_RC ( TOpenEncFile( current_dir, file_path, TFileOpenMode_Read, &key, &enc_file ) );
239 REQUIRE_RC ( KFileRelease ( enc_file ) );
240
241 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
242 REQUIRE_RC ( KDirectoryRelease ( current_dir ) );
243 }
244
245
TEST_CASE(KDectryptOnlyHeader)246 TEST_CASE(KDectryptOnlyHeader)
247 {
248 const char pw [] = "first pw";
249 KKey key;
250 REQUIRE_RC (KKeyInitUpdate (&key, kkeyAES128, pw, strlen (pw)));
251
252 const char file_path [] = TMP_FOLDER "/file_only_header";
253
254 KFile * enc_file, * pt_file;
255
256 struct KDirectory * current_dir;
257 REQUIRE_RC ( KDirectoryNativeDir ( ¤t_dir ) );
258
259 // just in case if it still there
260 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
261 // create file
262 REQUIRE_RC ( TCreateEncFile( current_dir, file_path, TFileOpenMode_Write, &key, &enc_file ) );
263 REQUIRE_RC ( TFillFile( enc_file, (const uint8_t *)"\0\1", 2, 500 ) );
264 REQUIRE_RC ( KFileRelease ( enc_file ) );
265
266 // truncate it to header size
267 REQUIRE_RC ( TOpenPtFile ( current_dir, file_path, TFileOpenMode_ReadWrite, &pt_file ) );
268 REQUIRE_RC ( KFileSetSize ( pt_file, sizeof(KEncFileHeader) ) );
269 REQUIRE_RC ( KFileRelease ( pt_file ) );
270
271 LOGMSG ( klogWarn, "Expect errors after this line:" );
272 REQUIRE ( TOpenEncFile( current_dir, file_path, TFileOpenMode_Read, &key, &enc_file ) == RC( rcKrypto, rcFile, rcConstructing, rcSize, rcIncorrect ) );
273 LOGMSG ( klogWarn, "No more errors are expected" );
274
275 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
276 REQUIRE_RC ( KDirectoryRelease ( current_dir ) );
277 }
278
TEST_CASE(KDectryptWithoutFooter)279 TEST_CASE(KDectryptWithoutFooter)
280 {
281 const char pw [] = "first pw";
282 KKey key;
283 REQUIRE_RC (KKeyInitUpdate (&key, kkeyAES128, pw, strlen (pw)));
284
285 const char file_path [] = TMP_FOLDER "/file_no_footer";
286 KFile * enc_file, * pt_file;
287
288 uint64_t file_size;
289
290 struct KDirectory * current_dir;
291 REQUIRE_RC ( KDirectoryNativeDir ( ¤t_dir ) );
292
293 // just in case if it still there
294 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
295 // create file
296 REQUIRE_RC ( TCreateEncFile( current_dir, file_path, TFileOpenMode_Write, &key, &enc_file ) );
297 REQUIRE_RC ( TFillFile( enc_file, (const uint8_t *)"\0\1", 2, 500 ) );
298 REQUIRE_RC ( KFileRelease ( enc_file ) );
299
300 // truncate footer
301 REQUIRE_RC ( TOpenPtFile ( current_dir, file_path, TFileOpenMode_ReadWrite, &pt_file ) );
302 REQUIRE_RC ( KFileSize ( pt_file, &file_size ) );
303 REQUIRE_RC ( KFileSetSize ( pt_file, file_size - sizeof(KEncFileFooter) ) );
304 REQUIRE_RC ( KFileRelease ( pt_file ) );
305
306 LOGMSG ( klogWarn, "Expect errors after this line:" );
307 REQUIRE ( TOpenEncFile( current_dir, file_path, TFileOpenMode_Read, &key, &enc_file ) == RC( rcKrypto, rcFile, rcConstructing, rcSize, rcIncorrect ) );
308 LOGMSG ( klogWarn, "No more errors are expected" );
309
310 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
311 REQUIRE_RC ( KDirectoryRelease ( current_dir ) );
312 }
313
TEST_CASE(KDectryptCorruptHeader)314 TEST_CASE(KDectryptCorruptHeader)
315 {
316 const char pw [] = "first pw";
317 KKey key;
318 REQUIRE_RC (KKeyInitUpdate (&key, kkeyAES128, pw, strlen (pw)));
319
320 const char file_path [] = TMP_FOLDER "/file_corrupt_header";
321
322 KFile * enc_file, * pt_file;
323
324 const size_t buffer_size = sizeof(KEncFileHeader);
325 size_t num_written;
326 uint8_t buffer[buffer_size];
327
328 struct KDirectory * current_dir;
329 REQUIRE_RC ( KDirectoryNativeDir ( ¤t_dir ) );
330
331 // just in case if it still there
332 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
333
334 // create file
335 REQUIRE_RC ( TCreateEncFile( current_dir, file_path, TFileOpenMode_Write, &key, &enc_file ) );
336 REQUIRE_RC ( TFillFile( enc_file, (const uint8_t *)"\0\1", 2, 500 ) );
337 REQUIRE_RC ( KFileRelease ( enc_file ) );
338
339 // corrupt header
340 REQUIRE_RC ( TOpenPtFile ( current_dir, file_path, TFileOpenMode_ReadWrite, &pt_file ) );
341 REQUIRE_RC ( KFileReadAll ( pt_file, 0, buffer, buffer_size, &num_written ) );
342 buffer[0] ^= 4;
343 REQUIRE_RC ( KFileWriteAll ( pt_file, 0, buffer, buffer_size, &num_written ) );
344 assert(buffer_size == num_written);
345 REQUIRE_RC ( KFileRelease ( pt_file ) );
346
347 LOGMSG ( klogWarn, "Expect errors after this line:" );
348 REQUIRE ( TOpenEncFile( current_dir, file_path, TFileOpenMode_Read, &key, &enc_file ) == RC( rcFS, rcFile, rcConstructing, rcHeader, rcInvalid ) );
349 LOGMSG ( klogWarn, "No more errors are expected" );
350
351 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
352 REQUIRE_RC ( KDirectoryRelease ( current_dir ) );
353 }
354
TEST_CASE(KDectryptCorruptFooterCrc)355 TEST_CASE(KDectryptCorruptFooterCrc)
356 {
357 const char pw [] = "first pw";
358 KKey key;
359 REQUIRE_RC (KKeyInitUpdate (&key, kkeyAES128, pw, strlen (pw)));
360
361 const char file_path [] = TMP_FOLDER "/file_corrupt_footer_crc";
362
363 KFile * enc_file, * pt_file;
364
365 uint64_t file_size;
366 const size_t buffer_size = sizeof(KEncFileFooter);
367 size_t num_written, num_read;
368 uint8_t buffer[buffer_size];
369
370 struct KDirectory * current_dir;
371 REQUIRE_RC ( KDirectoryNativeDir ( ¤t_dir ) );
372
373 // just in case if it still there
374 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
375
376 // create file
377 REQUIRE_RC ( TCreateEncFile( current_dir, file_path, TFileOpenMode_Write, &key, &enc_file ) );
378 REQUIRE_RC ( TFillFile( enc_file, (const uint8_t *)"\0\1", 2, 500 ) );
379 REQUIRE_RC ( KFileRelease ( enc_file ) );
380
381 // corrupt footer
382 REQUIRE_RC ( TOpenPtFile ( current_dir, file_path, TFileOpenMode_ReadWrite, &pt_file ) );
383 REQUIRE_RC ( KFileSize ( pt_file, &file_size ) );
384 REQUIRE_RC ( KFileReadAll ( pt_file, file_size - buffer_size, buffer, buffer_size, &num_read ) );
385 assert(buffer_size == num_read);
386 ((KEncFileFooter*)&buffer)->crc_checksum ^= 4;
387 REQUIRE_RC ( KFileWriteAll ( pt_file, file_size - buffer_size, buffer, buffer_size, &num_written ) );
388 assert(buffer_size == num_written);
389 REQUIRE_RC ( KFileRelease ( pt_file ) );
390
391 REQUIRE_RC ( TOpenPtFile( current_dir, file_path, TFileOpenMode_Read, &pt_file ) );
392 LOGMSG ( klogWarn, "Expect errors after this line:" );
393 REQUIRE ( KEncFileValidate( pt_file ) == RC(rcKrypto, rcFile, rcValidating, rcChecksum, rcCorrupt) );
394 LOGMSG ( klogWarn, "No more errors are expected" );
395 REQUIRE_RC ( KFileRelease ( pt_file ) );
396
397 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
398
399 REQUIRE_RC ( KDirectoryRelease ( current_dir ) );
400 }
401
TEST_CASE(KDectryptCorruptFooterBlockCount)402 TEST_CASE(KDectryptCorruptFooterBlockCount)
403 {
404 const char pw [] = "first pw";
405 KKey key;
406 REQUIRE_RC (KKeyInitUpdate (&key, kkeyAES128, pw, strlen (pw)));
407
408 const char file_path [] = TMP_FOLDER "/file_corrupt_footer_block_count";
409
410 KFile * enc_file, * pt_file;
411
412 uint64_t file_size;
413 const size_t buffer_size = sizeof(KEncFileFooter);
414 size_t num_written, num_read;
415 uint8_t buffer[buffer_size];
416
417 struct KDirectory * current_dir;
418 REQUIRE_RC ( KDirectoryNativeDir ( ¤t_dir ) );
419
420 // just in case if it still there
421 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
422
423 // create file
424 REQUIRE_RC ( TCreateEncFile( current_dir, file_path, TFileOpenMode_Write, &key, &enc_file ) );
425 REQUIRE_RC ( TFillFile( enc_file, (const uint8_t *)"\0\1", 2, 500 ) );
426 REQUIRE_RC ( KFileRelease ( enc_file ) );
427
428 // corrupt footer
429 REQUIRE_RC ( TOpenPtFile ( current_dir, file_path, TFileOpenMode_ReadWrite, &pt_file ) );
430 REQUIRE_RC ( KFileSize ( pt_file, &file_size ) );
431 REQUIRE_RC ( KFileReadAll ( pt_file, file_size - buffer_size, buffer, buffer_size, &num_read ) );
432 assert(buffer_size == num_read);
433 ((KEncFileFooter*)&buffer)->block_count ^= 4;
434 REQUIRE_RC ( KFileWriteAll ( pt_file, file_size - buffer_size, buffer, buffer_size, &num_written ) );
435 assert(buffer_size == num_written);
436 REQUIRE_RC ( KFileRelease ( pt_file ) );
437
438 REQUIRE_RC ( TOpenPtFile( current_dir, file_path, TFileOpenMode_Read, &pt_file ) );
439 LOGMSG ( klogWarn, "Expect errors after this line:" );
440 REQUIRE ( KEncFileValidate( pt_file ) == RC(rcKrypto, rcFile, rcValidating, rcSize, rcIncorrect) );
441 LOGMSG ( klogWarn, "No more errors are expected" );
442 REQUIRE_RC ( KFileRelease ( pt_file ) );
443
444 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
445
446 REQUIRE_RC ( KDirectoryRelease ( current_dir ) );
447 }
448
TEST_CASE(KDectryptCorruptBlockStruct)449 TEST_CASE(KDectryptCorruptBlockStruct)
450 {
451 const char pw [] = "first pw";
452 KKey key;
453 REQUIRE_RC (KKeyInitUpdate (&key, kkeyAES128, pw, strlen (pw)));
454
455 const char file_path [] = TMP_FOLDER "/file_corrupt_block_struct";
456
457 KFile * enc_file, * pt_file;
458
459 uint64_t file_size;
460 const size_t buffer_size = sizeof(KEncFileBlock);
461 size_t num_written, num_read;
462 uint8_t buffer[buffer_size];
463
464 struct KDirectory * current_dir;
465 REQUIRE_RC ( KDirectoryNativeDir ( ¤t_dir ) );
466
467 // just in case if it still there
468 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
469
470 // create file
471 REQUIRE_RC ( TCreateEncFile( current_dir, file_path, TFileOpenMode_Write, &key, &enc_file ) );
472 REQUIRE_RC ( TFillFile( enc_file, (const uint8_t *)"\0\1", 2, 500 ) );
473 REQUIRE_RC ( KFileRelease ( enc_file ) );
474
475 // corrupt block struct
476 REQUIRE_RC ( TOpenPtFile ( current_dir, file_path, TFileOpenMode_ReadWrite, &pt_file ) );
477 REQUIRE_RC ( KFileSize ( pt_file, &file_size ) );
478 REQUIRE_RC ( KFileReadAll ( pt_file, file_size - sizeof(KEncFileFooter) - buffer_size, buffer, buffer_size, &num_read ) );
479 assert(buffer_size == num_read);
480 buffer[0] ^= 4;
481 REQUIRE_RC ( KFileWriteAll ( pt_file, file_size - sizeof(KEncFileFooter) - buffer_size, buffer, buffer_size, &num_written ) );
482 assert(buffer_size == num_written);
483 REQUIRE_RC ( KFileRelease ( pt_file ) );
484
485 REQUIRE_RC ( TOpenPtFile( current_dir, file_path, TFileOpenMode_Read, &pt_file ) );
486 LOGMSG ( klogWarn, "Expect errors after this line:" );
487 REQUIRE ( KEncFileValidate( pt_file ) == RC(rcKrypto, rcFile, rcValidating, rcChecksum, rcCorrupt) );
488 LOGMSG ( klogWarn, "No more errors are expected" );
489 REQUIRE_RC ( KFileRelease ( pt_file ) );
490
491 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
492
493 REQUIRE_RC ( KDirectoryRelease ( current_dir ) );
494 }
495
TEST_CASE(KDectryptCorruptBlockData)496 TEST_CASE(KDectryptCorruptBlockData)
497 {
498 const char pw [] = "first pw";
499 KKey key;
500 REQUIRE_RC (KKeyInitUpdate (&key, kkeyAES128, pw, strlen (pw)));
501
502 const char file_path [] = TMP_FOLDER "/file_corrupt_block_data";
503
504 KFile * enc_file, * pt_file;
505
506 uint64_t file_size;
507 const size_t buffer_size = sizeof(KEncFileBlock);
508 size_t num_written, num_read;
509 uint8_t buffer[buffer_size];
510
511 struct KDirectory * current_dir;
512 REQUIRE_RC ( KDirectoryNativeDir ( ¤t_dir ) );
513
514 // just in case if it still there
515 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
516
517 // create file
518 REQUIRE_RC ( TCreateEncFile( current_dir, file_path, TFileOpenMode_Write, &key, &enc_file ) );
519 REQUIRE_RC ( TFillFile( enc_file, (const uint8_t *)"\0\1", 2, 500 ) );
520 REQUIRE_RC ( KFileRelease ( enc_file ) );
521
522 // corrupt block struct
523 REQUIRE_RC ( TOpenPtFile ( current_dir, file_path, TFileOpenMode_ReadWrite, &pt_file ) );
524 REQUIRE_RC ( KFileSize ( pt_file, &file_size ) );
525 REQUIRE_RC ( KFileReadAll ( pt_file, file_size - sizeof(KEncFileFooter) - buffer_size, buffer, buffer_size, &num_read ) );
526 assert(buffer_size == num_read);
527 ((KEncFileBlock*)&buffer)->data[0] ^= 4;
528 REQUIRE_RC ( KFileWriteAll ( pt_file, file_size - sizeof(KEncFileFooter) - buffer_size, buffer, buffer_size, &num_written ) );
529 assert(buffer_size == num_written);
530 REQUIRE_RC ( KFileRelease ( pt_file ) );
531
532 REQUIRE_RC ( TOpenPtFile( current_dir, file_path, TFileOpenMode_Read, &pt_file ) );
533 LOGMSG ( klogWarn, "Expect errors after this line:" );
534 REQUIRE ( KEncFileValidate( pt_file ) == RC(rcKrypto, rcFile, rcValidating, rcChecksum, rcCorrupt) );
535 LOGMSG ( klogWarn, "No more errors are expected" );
536 REQUIRE_RC ( KFileRelease ( pt_file ) );
537
538 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
539
540 REQUIRE_RC ( KDirectoryRelease ( current_dir ) );
541 }
542
543
TEST_CASE(KDectryptInvalidKey)544 TEST_CASE(KDectryptInvalidKey)
545 {
546 const char pw1 [] = "first pw";
547 const char pw2 [] = "second pw";
548 KKey key1, key2;
549 REQUIRE_RC (KKeyInitUpdate (&key1, kkeyAES128, pw1, strlen (pw1)));
550 REQUIRE_RC (KKeyInitUpdate (&key2, kkeyAES128, pw2, strlen (pw2)));
551
552 const char file_path [] = TMP_FOLDER "/enc_file_invalid_key";
553
554 KFile * enc_file;
555
556 struct KDirectory * current_dir;
557 REQUIRE_RC ( KDirectoryNativeDir ( ¤t_dir ) );
558
559 // just in case if it still there
560 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
561
562 // create file
563 REQUIRE_RC ( TCreateEncFile( current_dir, file_path, TFileOpenMode_Write, &key1, &enc_file ) );
564 REQUIRE_RC ( TFillFile( enc_file, (const uint8_t *)"\0\1", 2, 500 ) );
565 REQUIRE_RC ( KFileRelease ( enc_file ) );
566
567 REQUIRE_RC ( TOpenEncFile( current_dir, file_path, TFileOpenMode_Read, &key2, &enc_file ) );
568 LOGMSG ( klogWarn, "Expect errors after this line:" );
569 REQUIRE ( TCheckFileContent( enc_file, (const uint8_t *)"\0\1", 2 ) == RC( rcKrypto, rcFile, rcValidating, rcEncryption, rcCorrupt ) );
570 LOGMSG ( klogWarn, "No more errors are expected" );
571 REQUIRE_RC ( KFileRelease ( enc_file ) );
572
573 KDirectoryRemove ( current_dir, true, TMP_FOLDER );
574
575 REQUIRE_RC ( KDirectoryRelease ( current_dir ) );
576 }
577
578 //////////////////////////////////////////// Main
579
580 extern "C"
581 {
582
KAppVersion(void)583 ver_t CC KAppVersion ( void )
584 {
585 return 0x1000000;
586 }
587
UsageSummary(const char * prog_name)588 rc_t CC UsageSummary (const char * prog_name)
589 {
590 return 0;
591 }
592
Usage(const Args * args)593 rc_t CC Usage ( const Args * args)
594 {
595 return 0;
596 }
597
598 const char UsageDefaultName[] = "test-encdec";
599
KMain(int argc,char * argv[])600 rc_t CC KMain ( int argc, char *argv [] )
601 {
602 KConfigDisableUserSettings();
603 rc_t rc=KEncDecTestSuite(argc, argv);
604 return rc;
605 }
606
607 }
608