Allocate free loop devices instead of using hardcoded.
[platform/upstream/cryptsetup.git] / tests / api-test.c
1 /*
2  * cryptsetup library API check functions
3  *
4  * Copyright (C) 2009-2010 Red Hat, Inc. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * version 2 as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <linux/fs.h>
26 #include <errno.h>
27 #include <assert.h>
28 #include <sys/stat.h>
29 #include <sys/ioctl.h>
30 #include <linux/loop.h>
31
32 #include "libcryptsetup.h"
33
34 #define DMDIR "/dev/mapper/"
35
36 #define DEVICE_1_UUID "28632274-8c8a-493f-835b-da802e1c576b"
37 #define DEVICE_EMPTY_name "crypt_zero"
38 #define DEVICE_EMPTY DMDIR DEVICE_EMPTY_name
39 #define DEVICE_ERROR_name "crypt_error"
40 #define DEVICE_ERROR DMDIR DEVICE_ERROR_name
41
42 #define CDEVICE_1 "ctest1"
43 #define CDEVICE_2 "ctest2"
44 #define CDEVICE_WRONG "O_o"
45
46 #define IMAGE1 "compatimage.img"
47 #define IMAGE_EMPTY "empty.img"
48
49 #define KEYFILE1 "key1.file"
50 #define KEY1 "compatkey"
51
52 #define KEYFILE2 "key2.file"
53 #define KEY2 "0123456789abcdef"
54
55 #define PASSPHRASE "blabla"
56
57 #define DEVICE_TEST_UUID "12345678-1234-1234-1234-123456789abc"
58
59 static int _debug   = 0;
60 static int _verbose = 1;
61
62 static char global_log[4096];
63 static int global_lines = 0;
64
65 static char *DEVICE_1 = NULL;
66 static char *DEVICE_2 = NULL;
67
68 // Helpers
69 static int _prepare_keyfile(const char *name, const char *passphrase)
70 {
71         int fd, r;
72
73         fd = open(name, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR);
74         if (fd != -1) {
75                 r = write(fd, passphrase, strlen(passphrase));
76                 close(fd);
77         } else
78                 r = 0;
79
80         return r == strlen(passphrase) ? 0 : 1;
81 }
82
83 static void _remove_keyfiles(void)
84 {
85         remove(KEYFILE1);
86         remove(KEYFILE2);
87 }
88
89 char *_get_loop_device(void)
90 {
91         char dev[20];
92         int i, loop_fd;
93         struct stat st;
94         struct loop_info64 lo64 = {0};
95
96         for ( i = 0; i < 256; i++ ) {
97                 sprintf ( dev, "/dev/loop%d", i );
98                 if ( stat ( dev, &st ) || !S_ISBLK ( st.st_mode ) )
99                         goto bad;
100
101                 loop_fd = open ( dev, O_RDONLY );
102                 if ( loop_fd < 0 )
103                         goto bad;
104
105                 if ( ioctl ( loop_fd, LOOP_GET_STATUS64, &lo64 ) && errno == ENXIO ) {
106                         close ( loop_fd );
107                         return strdup ( dev );
108                 }
109                 close ( loop_fd );
110         }
111 bad:
112         printf("Cannot find free loop device.\n");
113         return NULL;
114 }
115
116 // Decode key from its hex representation
117 static int crypt_decode_key(char *key, char *hex, unsigned int size)
118 {
119         char buffer[3];
120         char *endp;
121         unsigned int i;
122
123         buffer[2] = '\0';
124
125         for (i = 0; i < size; i++) {
126                 buffer[0] = *hex++;
127                 buffer[1] = *hex++;
128
129                 key[i] = (unsigned char)strtoul(buffer, &endp, 16);
130
131                 if (endp != &buffer[2])
132                         return -1;
133         }
134
135         if (*hex != '\0')
136                 return -1;
137
138         return 0;
139 }
140
141 static int yesDialog(char *msg)
142 {
143         return 1;
144 }
145
146 static void cmdLineLog(int level, char *msg)
147 {
148         strncat(global_log, msg, sizeof(global_log) - strlen(global_log));
149         global_lines++;
150 }
151
152 static void new_log(int level, const char *msg, void *usrptr)
153 {
154         cmdLineLog(level, (char*)msg);
155 }
156
157
158 static void reset_log()
159 {
160         memset(global_log, 0, sizeof(global_log));
161         global_lines = 0;
162 }
163
164 static void _system(const char *command, int warn)
165 {
166         if (system(command) < 0 && warn)
167                 printf("System command failed: %s", command);
168 }
169
170 static struct interface_callbacks cmd_icb = {
171         .yesDialog = yesDialog,
172         .log = cmdLineLog,
173 };
174
175 static void _cleanup(void)
176 {
177         struct stat st;
178         char tmp[256];
179
180         //_system("udevadm settle", 0);
181
182         if (!stat(DMDIR CDEVICE_1, &st))
183                 _system("dmsetup remove " CDEVICE_1, 0);
184
185         if (!stat(DMDIR CDEVICE_2, &st))
186                 _system("dmsetup remove " CDEVICE_2, 0);
187
188         if (!stat(DEVICE_EMPTY, &st))
189                 _system("dmsetup remove " DEVICE_EMPTY_name, 0);
190
191         if (!stat(DEVICE_ERROR, &st))
192                 _system("dmsetup remove " DEVICE_ERROR_name, 0);
193
194         // FIXME: use internel loop lib when available
195         if (DEVICE_1 && !strncmp("/dev/loop", DEVICE_1, 9)) {
196                 snprintf(tmp, sizeof(tmp), "losetup -d %s", DEVICE_1);
197                 _system(tmp, 0);
198         }
199
200         if (DEVICE_2 && !strncmp("/dev/loop", DEVICE_2, 9)) {
201                 snprintf(tmp, sizeof(tmp), "losetup -d %s", DEVICE_2);
202                 _system(tmp, 0);
203         }
204
205         _system("rm -f " IMAGE_EMPTY, 0);
206         _remove_keyfiles();
207 }
208
209 static int _setup(void)
210 {
211         char tmp[256];
212
213         _system("dmsetup create " DEVICE_EMPTY_name " --table \"0 10000 zero\"", 1);
214         _system("dmsetup create " DEVICE_ERROR_name " --table \"0 10000 error\"", 1);
215         if (!DEVICE_1)
216                 DEVICE_1 = _get_loop_device();
217         if (!DEVICE_1)
218                 return 1;
219         if (!strncmp("/dev/loop", DEVICE_1, 9)) {
220                 _system(" [ ! -e " IMAGE1 " ] && bzip2 -dk " IMAGE1 ".bz2", 1);
221                 snprintf(tmp, sizeof(tmp), "losetup %s %s", DEVICE_1, IMAGE1);
222                 _system(tmp, 1);
223         }
224         if (!DEVICE_2)
225                 DEVICE_2 = _get_loop_device();
226         if (!DEVICE_2)
227                 return 1;
228         if (!strncmp("/dev/loop", DEVICE_2, 9)) {
229                 _system("dd if=/dev/zero of=" IMAGE_EMPTY " bs=1M count=4", 1);
230                 snprintf(tmp, sizeof(tmp), "losetup %s %s", DEVICE_2, IMAGE_EMPTY);
231                 _system(tmp, 1);
232         }
233         return 0;
234 }
235
236 void check_ok(int status, int line, const char *func)
237 {
238         char buf[256];
239
240         if (status) {
241                 crypt_get_error(buf, sizeof(buf));
242                 printf("FAIL line %d [%s]: code %d, %s\n", line, func, status, buf);
243                 _cleanup();
244                 exit(-1);
245         }
246 }
247
248 void check_ko(int status, int line, const char *func)
249 {
250         char buf[256];
251
252         memset(buf, 0, sizeof(buf));
253         crypt_get_error(buf, sizeof(buf));
254         if (status >= 0) {
255                 printf("FAIL line %d [%s]: code %d, %s\n", line, func, status, buf);
256                 _cleanup();
257                 exit(-1);
258         } else if (_verbose)
259                 printf("   => errno %d, errmsg: %s\n", status, buf);
260 }
261
262 void check_equal(int line, const char *func)
263 {
264         printf("FAIL line %d [%s]: expected equal values differs.\n", line, func);
265         _cleanup();
266         exit(-1);
267 }
268
269 void xlog(const char *msg, const char *tst, const char *func, int line, const char *txt)
270 {
271         if (_verbose) {
272                 if (txt)
273                         printf(" [%s,%s:%d] %s [%s]\n", msg, func, line, tst, txt);
274                 else
275                         printf(" [%s,%s:%d] %s\n", msg, func, line, tst);
276         }
277 }
278 #define OK_(x)          do { xlog("(success)", #x, __FUNCTION__, __LINE__, NULL); \
279                              check_ok((x), __LINE__, __FUNCTION__); \
280                         } while(0)
281 #define FAIL_(x, y)     do { xlog("(fail)   ", #x, __FUNCTION__, __LINE__, y); \
282                              check_ko((x), __LINE__, __FUNCTION__); \
283                         } while(0)
284 #define EQ_(x, y)       do { xlog("(equal)  ", #x " == " #y, __FUNCTION__, __LINE__, NULL); \
285                              if ((x) != (y)) check_equal(__LINE__, __FUNCTION__); \
286                         } while(0)
287
288 #define RUN_(x, y)              do { printf("%s: %s\n", #x, (y)); x(); } while (0)
289
290 // OLD API TESTS
291 static void LuksUUID(void)
292 {
293         struct crypt_options co = { .icb = &cmd_icb };
294
295         co.device = DEVICE_EMPTY;
296         EQ_(crypt_luksUUID(&co), -EINVAL);
297
298         co.device = DEVICE_ERROR;
299         EQ_(crypt_luksUUID(&co), -EINVAL);
300
301         reset_log();
302         co.device = DEVICE_1;
303         OK_(crypt_luksUUID(&co));
304         EQ_(strlen(global_log), 37); /* UUID + "\n" */
305         EQ_(strncmp(global_log, DEVICE_1_UUID, strlen(DEVICE_1_UUID)), 0);
306
307 }
308
309 static void IsLuks(void)
310 {
311         struct crypt_options co = {  .icb = &cmd_icb };
312
313         co.device = DEVICE_EMPTY;
314         EQ_(crypt_isLuks(&co), -EINVAL);
315
316         co.device = DEVICE_ERROR;
317         EQ_(crypt_isLuks(&co), -EINVAL);
318
319         co.device = DEVICE_1;
320         OK_(crypt_isLuks(&co));
321 }
322
323 static void LuksOpen(void)
324 {
325         struct crypt_options co = {
326                 .name = CDEVICE_1,
327                 //.passphrase = "blabla",
328                 .icb = &cmd_icb,
329         };
330
331         OK_(_prepare_keyfile(KEYFILE1, KEY1));
332         co.key_file = KEYFILE1;
333
334         co.device = DEVICE_EMPTY;
335         EQ_(crypt_luksOpen(&co), -EINVAL);
336
337         co.device = DEVICE_ERROR;
338         EQ_(crypt_luksOpen(&co), -EINVAL);
339
340         co.device = DEVICE_1;
341         OK_(crypt_luksOpen(&co));
342         FAIL_(crypt_luksOpen(&co), "already open");
343
344         _remove_keyfiles();
345 }
346
347 static void query_device(void)
348 {
349         struct crypt_options co = {.icb = &cmd_icb };
350
351         co.name = CDEVICE_WRONG;
352         EQ_(crypt_query_device(&co), 0);
353
354         co.name = CDEVICE_1;
355         EQ_(crypt_query_device(&co), 1);
356
357         OK_(strncmp(crypt_get_dir(), DMDIR, 11));
358         OK_(strcmp(co.cipher, "aes-cbc-essiv:sha256"));
359         EQ_(co.key_size, 16);
360         EQ_(co.offset, 1032);
361         EQ_(co.flags & CRYPT_FLAG_READONLY, 0);
362         EQ_(co.skip, 0);
363         crypt_put_options(&co);
364 }
365
366 static void remove_device(void)
367 {
368         int fd;
369         struct crypt_options co = {.icb = &cmd_icb };
370
371         co.name = CDEVICE_WRONG;
372         EQ_(crypt_remove_device(&co), -ENODEV);
373
374         fd = open(DMDIR CDEVICE_1, O_RDONLY);
375         co.name = CDEVICE_1;
376         FAIL_(crypt_remove_device(&co), "device busy");
377         close(fd);
378
379         OK_(crypt_remove_device(&co));
380 }
381
382 static void LuksFormat(void)
383 {
384         struct crypt_options co = {
385                 .device = DEVICE_2,
386                 .key_size = 256 / 8,
387                 .key_slot = -1,
388                 .cipher = "aes-cbc-essiv:sha256",
389                 .hash = "sha1",
390                 .flags = 0,
391                 .iteration_time = 10,
392                 .align_payload = 0,
393                 .icb = &cmd_icb,
394         };
395
396         OK_(_prepare_keyfile(KEYFILE1, KEY1));
397
398         co.new_key_file = KEYFILE1;
399         co.device = DEVICE_ERROR;
400         FAIL_(crypt_luksFormat(&co), "error device");
401
402         co.device = DEVICE_2;
403         OK_(crypt_luksFormat(&co));
404
405         co.new_key_file = NULL;
406         co.key_file = KEYFILE1;
407         co.name = CDEVICE_2;
408         OK_(crypt_luksOpen(&co));
409         OK_(crypt_remove_device(&co));
410         _remove_keyfiles();
411 }
412
413 static void LuksKeyGame(void)
414 {
415         int i;
416         struct crypt_options co = {
417                 .device = DEVICE_2,
418                 .key_size = 256 / 8,
419                 .key_slot = -1,
420                 .cipher = "aes-cbc-essiv:sha256",
421                 .hash = "sha1",
422                 .flags = 0,
423                 .iteration_time = 10,
424                 .align_payload = 0,
425                 .icb = &cmd_icb,
426         };
427
428         OK_(_prepare_keyfile(KEYFILE1, KEY1));
429         OK_(_prepare_keyfile(KEYFILE2, KEY2));
430
431         co.new_key_file = KEYFILE1;
432         co.device = DEVICE_2;
433         co.key_slot = 8;
434         FAIL_(crypt_luksFormat(&co), "wrong slot #");
435
436         co.key_slot = 7; // last slot
437         OK_(crypt_luksFormat(&co));
438
439         co.new_key_file = KEYFILE1;
440         co.key_file = KEYFILE1;
441         co.key_slot = 8;
442         FAIL_(crypt_luksAddKey(&co), "wrong slot #");
443         co.key_slot = 7;
444         FAIL_(crypt_luksAddKey(&co), "slot already used");
445
446         co.key_slot = 6;
447         OK_(crypt_luksAddKey(&co));
448
449         co.key_file = KEYFILE2 "blah";
450         co.key_slot = 5;
451         FAIL_(crypt_luksAddKey(&co), "keyfile not found");
452
453         co.new_key_file = KEYFILE2; // key to add
454         co.key_file = KEYFILE1;
455         co.key_slot = -1;
456         for (i = 0; i < 6; i++)
457                 OK_(crypt_luksAddKey(&co)); //FIXME: EQ_(i)?
458
459         FAIL_(crypt_luksAddKey(&co), "all slots full");
460
461         // REMOVE KEY
462         co.new_key_file = KEYFILE1; // key to remove
463         co.key_file = NULL;
464         co.key_slot = 8; // should be ignored
465          // only 2 slots should use KEYFILE1
466         OK_(crypt_luksRemoveKey(&co));
467         OK_(crypt_luksRemoveKey(&co));
468         FAIL_(crypt_luksRemoveKey(&co), "no slot with this passphrase");
469
470         co.new_key_file = KEYFILE2 "blah";
471         co.key_file = NULL;
472         FAIL_(crypt_luksRemoveKey(&co), "keyfile not found");
473
474         // KILL SLOT
475         co.new_key_file = NULL;
476         co.key_file = NULL;
477         co.key_slot = 8;
478         FAIL_(crypt_luksKillSlot(&co), "wrong slot #");
479         co.key_slot = 7;
480         FAIL_(crypt_luksKillSlot(&co), "slot already wiped");
481
482         co.key_slot = 5;
483         OK_(crypt_luksKillSlot(&co));
484
485         _remove_keyfiles();
486 }
487
488 size_t _get_device_size(const char *device)
489 {
490         unsigned long size = 0;
491         int fd;
492
493         fd = open(device, O_RDONLY);
494         if (fd == -1)
495                 return 0;
496         (void)ioctl(fd, BLKGETSIZE, &size);
497         close(fd);
498
499         return size;
500 }
501
502 void DeviceResizeGame(void)
503 {
504         size_t orig_size;
505         struct crypt_options co = {
506                 .name = CDEVICE_2,
507                 .device = DEVICE_2,
508                 .key_size = 128 / 8,
509                 .cipher = "aes-cbc-plain",
510                 .hash = "sha1",
511                 .offset = 333,
512                 .skip = 0,
513                 .icb = &cmd_icb,
514         };
515
516         orig_size = _get_device_size(DEVICE_2);
517
518         OK_(_prepare_keyfile(KEYFILE2, KEY2));
519
520         co.key_file = KEYFILE2;
521         co.size = 1000;
522         OK_(crypt_create_device(&co));
523         EQ_(_get_device_size(DMDIR CDEVICE_2), 1000);
524
525         co.size = 2000;
526         OK_(crypt_resize_device(&co));
527         EQ_(_get_device_size(DMDIR CDEVICE_2), 2000);
528
529         co.size = 0;
530         OK_(crypt_resize_device(&co));
531         EQ_(_get_device_size(DMDIR CDEVICE_2), (orig_size - 333));
532         co.size = 0;
533         co.offset = 444;
534         co.skip = 555;
535         co.cipher = "aes-cbc-essiv:sha256";
536         OK_(crypt_update_device(&co));
537         EQ_(_get_device_size(DMDIR CDEVICE_2), (orig_size - 444));
538
539         memset(&co, 0, sizeof(co));
540         co.icb = &cmd_icb,
541         co.name = CDEVICE_2;
542         EQ_(crypt_query_device(&co), 1);
543         EQ_(strcmp(co.cipher, "aes-cbc-essiv:sha256"), 0);
544         EQ_(co.key_size, 128 / 8);
545         EQ_(co.offset, 444);
546         EQ_(co.skip, 555);
547         crypt_put_options(&co);
548
549         // dangerous switch device still works
550         memset(&co, 0, sizeof(co));
551         co.name = CDEVICE_2,
552         co.device = DEVICE_1;
553         co.key_file = KEYFILE2;
554         co.key_size = 128 / 8;
555         co.cipher = "aes-cbc-plain";
556         co.hash = "sha1";
557         co.icb = &cmd_icb;
558         OK_(crypt_update_device(&co));
559
560         memset(&co, 0, sizeof(co));
561         co.icb = &cmd_icb,
562         co.name = CDEVICE_2;
563         EQ_(crypt_query_device(&co), 1);
564         EQ_(strcmp(co.cipher, "aes-cbc-plain"), 0);
565         EQ_(co.key_size, 128 / 8);
566         EQ_(co.offset, 0);
567         EQ_(co.skip, 0);
568         // This expect lookup returns prefered /dev/loopX
569         EQ_(strcmp(co.device, DEVICE_1), 0);
570         crypt_put_options(&co);
571
572         memset(&co, 0, sizeof(co));
573         co.icb = &cmd_icb,
574         co.name = CDEVICE_2;
575         OK_(crypt_remove_device(&co));
576
577         _remove_keyfiles();
578 }
579
580 // NEW API tests
581
582 static void AddDevicePlain(void)
583 {
584         struct crypt_device *cd;
585         struct crypt_params_plain params = {
586                 .hash = "sha1",
587                 .skip = 0,
588                 .offset = 0,
589         };
590         int fd;
591         char key[128], key2[128], path[128];
592
593         char *passphrase = PASSPHRASE;
594         char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
595         size_t key_size = strlen(mk_hex) / 2;
596         char *cipher = "aes";
597         char *cipher_mode = "cbc-essiv:sha256";
598
599         crypt_decode_key(key, mk_hex, key_size);
600
601         FAIL_(crypt_init(&cd, ""), "empty device string");
602
603         // default is "plain" hash - no password hash
604         OK_(crypt_init(&cd, DEVICE_1));
605         OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, NULL));
606         FAIL_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0), "cannot verify key with plain");
607         OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
608         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
609         // FIXME: this should get key from active device?
610         //OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)));
611         //OK_(memcmp(key, key2, key_size));
612         OK_(crypt_deactivate(cd, CDEVICE_1));
613         crypt_free(cd);
614
615         // Now use hashed password
616         OK_(crypt_init(&cd, DEVICE_1));
617         OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, &params));
618         FAIL_(crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0),
619               "cannot verify passphrase with plain" );
620         OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0));
621
622         // device status check
623         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
624         snprintf(path, sizeof(path), "%s/%s", crypt_get_dir(), CDEVICE_1);
625         fd = open(path, O_RDONLY);
626         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_BUSY);
627         FAIL_(crypt_deactivate(cd, CDEVICE_1), "Device is busy");
628         close(fd);
629         OK_(crypt_deactivate(cd, CDEVICE_1));
630         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_INACTIVE);
631
632         OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
633         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
634
635         // retrieve volume key check
636         memset(key2, 0, key_size);
637         key_size--;
638         // small buffer
639         FAIL_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)), "small buffer");
640         key_size++;
641         OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)));
642
643         OK_(memcmp(key, key2, key_size));
644         OK_(strcmp(cipher, crypt_get_cipher(cd)));
645         OK_(strcmp(cipher_mode, crypt_get_cipher_mode(cd)));
646         EQ_(key_size, crypt_get_volume_key_size(cd));
647         EQ_(0, crypt_get_data_offset(cd));
648         OK_(crypt_deactivate(cd, CDEVICE_1));
649
650         // now with keyfile
651         OK_(_prepare_keyfile(KEYFILE1, KEY1));
652         FAIL_(crypt_activate_by_keyfile(cd, NULL, CRYPT_ANY_SLOT, KEYFILE1, 0, 0), "cannot verify key with plain");
653         EQ_(0, crypt_activate_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0, 0));
654         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
655         OK_(crypt_deactivate(cd, CDEVICE_1));
656         _remove_keyfiles();
657
658         crypt_free(cd);
659 }
660
661 #define CALLBACK_ERROR "calback_error xyz"
662 static int pass_callback_err(const char *msg, char *buf, size_t length, void *usrptr)
663 {
664         struct crypt_device *cd = usrptr;
665
666         assert(cd);
667         assert(length);
668         assert(msg);
669
670         crypt_log(cd, CRYPT_LOG_ERROR, CALLBACK_ERROR);
671         return -EINVAL;
672 }
673
674 static int pass_callback_ok(const char *msg, char *buf, size_t length, void *usrptr)
675 {
676         assert(length);
677         assert(msg);
678         strcpy(buf, PASSPHRASE);
679         return strlen(buf);
680 }
681
682 static void CallbacksTest(void)
683 {
684         struct crypt_device *cd;
685         struct crypt_params_plain params = {
686                 .hash = "sha1",
687                 .skip = 0,
688                 .offset = 0,
689         };
690
691         size_t key_size = 256 / 8;
692         char *cipher = "aes";
693         char *cipher_mode = "cbc-essiv:sha256";
694         char *passphrase = PASSPHRASE;
695
696         OK_(crypt_init(&cd, DEVICE_1));
697         crypt_set_log_callback(cd, &new_log, NULL);
698         //crypt_set_log_callback(cd, NULL, NULL);
699
700         OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, &params));
701
702         OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0));
703         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
704         OK_(crypt_deactivate(cd, CDEVICE_1));
705
706         reset_log();
707         crypt_set_password_callback(cd, pass_callback_err, cd);
708         FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, NULL, 0, 0), "callback fails");
709         EQ_(strncmp(global_log, CALLBACK_ERROR, strlen(CALLBACK_ERROR)), 0);
710
711         crypt_set_password_callback(cd, pass_callback_ok, NULL);
712         OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, NULL, 0, 0));
713         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
714         OK_(crypt_deactivate(cd, CDEVICE_1));
715
716         crypt_free(cd);
717 }
718
719 static void UseLuksDevice(void)
720 {
721         struct crypt_device *cd;
722         char key[128];
723         size_t key_size;
724
725         OK_(crypt_init(&cd, DEVICE_1));
726         OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
727         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_INACTIVE);
728         OK_(crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0));
729         OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0));
730         FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0), "already open");
731         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
732         OK_(crypt_deactivate(cd, CDEVICE_1));
733         FAIL_(crypt_deactivate(cd, CDEVICE_1), "no such device");
734
735         key_size = 16;
736         OK_(strcmp("aes", crypt_get_cipher(cd)));
737         OK_(strcmp("cbc-essiv:sha256", crypt_get_cipher_mode(cd)));
738         OK_(strcmp(DEVICE_1_UUID, crypt_get_uuid(cd)));
739         EQ_(key_size, crypt_get_volume_key_size(cd));
740         EQ_(1032, crypt_get_data_offset(cd));
741
742         EQ_(0, crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, KEY1, strlen(KEY1)));
743         OK_(crypt_volume_key_verify(cd, key, key_size));
744         OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0));
745         OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
746         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
747         OK_(crypt_deactivate(cd, CDEVICE_1));
748
749         key[1] = ~key[1];
750         FAIL_(crypt_volume_key_verify(cd, key, key_size), "key mismatch");
751         FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0), "key mismatch");
752         crypt_free(cd);
753 }
754
755 static void SuspendDevice(void)
756 {
757         int suspend_status;
758         struct crypt_device *cd;
759
760         OK_(crypt_init(&cd, DEVICE_1));
761         OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
762         OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0));
763
764         suspend_status = crypt_suspend(cd, CDEVICE_1);
765         if (suspend_status == -ENOTSUP) {
766                 printf("WARNING: Suspend/Resume not supported, skipping test.\n");
767                 goto out;
768         }
769         OK_(suspend_status);
770         FAIL_(crypt_suspend(cd, CDEVICE_1), "already suspended");
771
772         FAIL_(crypt_resume_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1)-1), "wrong key");
773         OK_(crypt_resume_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1)));
774         FAIL_(crypt_resume_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1)), "not suspended");
775
776         OK_(_prepare_keyfile(KEYFILE1, KEY1));
777         OK_(crypt_suspend(cd, CDEVICE_1));
778         FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1 "blah", 0), "wrong keyfile");
779         OK_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0));
780         FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0), "not suspended");
781         _remove_keyfiles();
782 out:
783         OK_(crypt_deactivate(cd, CDEVICE_1));
784         crypt_free(cd);
785 }
786
787 static void AddDeviceLuks(void)
788 {
789         struct crypt_device *cd;
790         struct crypt_params_luks1 params = {
791                 .hash = "sha512",
792                 .data_alignment = 2048, // 4M, data offset will be 4096
793         };
794         char key[128], key2[128];
795
796         char *passphrase = "blabla";
797         char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
798         size_t key_size = strlen(mk_hex) / 2;
799         char *cipher = "aes";
800         char *cipher_mode = "cbc-essiv:sha256";
801
802         crypt_decode_key(key, mk_hex, key_size);
803
804         OK_(crypt_init(&cd, DEVICE_2));
805         OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params));
806
807         // even with no keyslots defined it can be activated by volume key
808         OK_(crypt_volume_key_verify(cd, key, key_size));
809         OK_(crypt_activate_by_volume_key(cd, CDEVICE_2, key, key_size, 0));
810         EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE);
811         OK_(crypt_deactivate(cd, CDEVICE_2));
812
813         // now with keyslot
814         EQ_(7, crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase)));
815         EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 7));
816         EQ_(7, crypt_activate_by_passphrase(cd, CDEVICE_2, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0));
817         EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE);
818         OK_(crypt_deactivate(cd, CDEVICE_2));
819
820         EQ_(1, crypt_keyslot_add_by_volume_key(cd, 1, key, key_size, KEY1, strlen(KEY1)));
821         OK_(_prepare_keyfile(KEYFILE1, KEY1));
822         OK_(_prepare_keyfile(KEYFILE2, KEY2));
823         EQ_(2, crypt_keyslot_add_by_keyfile(cd, 2, KEYFILE1, 0, KEYFILE2, 0));
824         FAIL_(crypt_activate_by_keyfile(cd, CDEVICE_2, CRYPT_ANY_SLOT, KEYFILE2, strlen(KEY2)-1, 0), "key mismatch");
825         EQ_(2, crypt_activate_by_keyfile(cd, NULL, CRYPT_ANY_SLOT, KEYFILE2, 0, 0));
826         EQ_(2, crypt_activate_by_keyfile(cd, CDEVICE_2, CRYPT_ANY_SLOT, KEYFILE2, 0, 0));
827         OK_(crypt_keyslot_destroy(cd, 1));
828         OK_(crypt_keyslot_destroy(cd, 2));
829         OK_(crypt_deactivate(cd, CDEVICE_2));
830         _remove_keyfiles();
831
832         FAIL_(crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase)), "slot used");
833         key[1] = ~key[1];
834         FAIL_(crypt_keyslot_add_by_volume_key(cd, 6, key, key_size, passphrase, strlen(passphrase)), "key mismatch");
835         key[1] = ~key[1];
836         EQ_(6, crypt_keyslot_add_by_volume_key(cd, 6, key, key_size, passphrase, strlen(passphrase)));
837         EQ_(CRYPT_SLOT_ACTIVE, crypt_keyslot_status(cd, 6));
838
839         FAIL_(crypt_keyslot_destroy(cd, 8), "invalid keyslot");
840         FAIL_(crypt_keyslot_destroy(cd, CRYPT_ANY_SLOT), "invalid keyslot");
841         FAIL_(crypt_keyslot_destroy(cd, 0), "keyslot not used");
842         OK_(crypt_keyslot_destroy(cd, 7));
843         EQ_(CRYPT_SLOT_INACTIVE, crypt_keyslot_status(cd, 7));
844         EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 6));
845
846         EQ_(6, crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)));
847         OK_(crypt_volume_key_verify(cd, key2, key_size));
848
849         OK_(memcmp(key, key2, key_size));
850         OK_(strcmp(cipher, crypt_get_cipher(cd)));
851         OK_(strcmp(cipher_mode, crypt_get_cipher_mode(cd)));
852         EQ_(key_size, crypt_get_volume_key_size(cd));
853         EQ_(4096, crypt_get_data_offset(cd));
854         OK_(strcmp(DEVICE_2, crypt_get_device_name(cd)));
855
856         reset_log();
857         crypt_set_log_callback(cd, &new_log, NULL);
858         OK_(crypt_dump(cd));
859         OK_(!(global_lines != 0));
860         crypt_set_log_callback(cd, NULL, NULL);
861         reset_log();
862
863         FAIL_(crypt_set_uuid(cd, "blah"), "wrong UUID format");
864         OK_(crypt_set_uuid(cd, DEVICE_TEST_UUID));
865         OK_(strcmp(DEVICE_TEST_UUID, crypt_get_uuid(cd)));
866
867         FAIL_(crypt_deactivate(cd, CDEVICE_2), "not active");
868         crypt_free(cd);
869 }
870
871 static void UseTempVolumes(void)
872 {
873         struct crypt_device *cd;
874         char tmp[256];
875
876         // Tepmporary device without keyslot but with on-disk LUKS header
877         OK_(crypt_init(&cd, DEVICE_2));
878         FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, NULL, 0, 0), "not yet formatted");
879         OK_(crypt_format(cd, CRYPT_LUKS1, "aes", "cbc-essiv:sha256", NULL, NULL, 16, NULL));
880         OK_(crypt_activate_by_volume_key(cd, CDEVICE_2, NULL, 0, 0));
881         EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE);
882         crypt_free(cd);
883
884         // Volume key is properly initialised from active device
885         OK_(crypt_init_by_name(&cd, CDEVICE_2));
886         OK_(crypt_deactivate(cd, CDEVICE_2));
887         OK_(crypt_activate_by_volume_key(cd, CDEVICE_2, NULL, 0, 0));
888         OK_(crypt_deactivate(cd, CDEVICE_2));
889         crypt_free(cd);
890
891         // Dirty checks: device without UUID
892         // we should be able to remove it but not manuipulate with it
893         snprintf(tmp, sizeof(tmp), "dmsetup create %s --table \""
894                 "0 100 crypt aes-cbc-essiv:sha256 deadbabedeadbabedeadbabedeadbabe 0 "
895                 "%s 2048\"", CDEVICE_2, DEVICE_2);
896         _system(tmp, 1);
897         OK_(crypt_init_by_name(&cd, CDEVICE_2));
898         OK_(crypt_deactivate(cd, CDEVICE_2));
899         FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, NULL, 0, 0), "No known device type");
900         crypt_free(cd);
901
902         // Dirty checks: device with UUID but LUKS header key fingerprint must fail)
903         snprintf(tmp, sizeof(tmp), "dmsetup create %s --table \""
904                 "0 100 crypt aes-cbc-essiv:sha256 deadbabedeadbabedeadbabedeadbabe 0 "
905                 "%s 2048\" -u CRYPT-LUKS1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-ctest1",
906                  CDEVICE_2, DEVICE_2);
907         _system(tmp, 1);
908         OK_(crypt_init_by_name(&cd, CDEVICE_2));
909         OK_(crypt_deactivate(cd, CDEVICE_2));
910         FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, NULL, 0, 0), "wrong volume key");
911         crypt_free(cd);
912
913         // No slots
914         OK_(crypt_init(&cd, DEVICE_2));
915         OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
916         FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, NULL, 0, 0), "volume key is lost");
917         crypt_free(cd);
918
919         // Plain device
920         OK_(crypt_init(&cd, DEVICE_2));
921         OK_(crypt_format(cd, CRYPT_PLAIN, "aes", "cbc-essiv:sha256", NULL, NULL, 16, NULL));
922         FAIL_(crypt_activate_by_volume_key(cd, NULL, "xxx", 3, 0), "cannot verify key with plain");
923         FAIL_(crypt_volume_key_verify(cd, "xxx", 3), "cannot verify key with plain");
924         FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, "xxx", 3, 0), "wrong key lenght");
925         OK_(crypt_activate_by_volume_key(cd, CDEVICE_2, "volumekeyvolumek", 16, 0));
926         EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE);
927         OK_(crypt_deactivate(cd, CDEVICE_2));
928         crypt_free(cd);
929 }
930
931 // Check that gcrypt is properly initialised in format
932 static void NonFIPSAlg(void)
933 {
934         struct crypt_device *cd;
935         struct crypt_params_luks1 params = {0};
936         char key[128] = "";
937         size_t key_size = 128;
938         char *cipher = "aes";
939         char *cipher_mode = "cbc-essiv:sha256";
940         int ret;
941
942         OK_(crypt_init(&cd, DEVICE_2));
943         params.hash = "sha256";
944         OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params));
945
946         params.hash = "whirlpool";
947         ret = crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params);
948         if (ret < 0) {
949                 printf("WARNING: whirlpool not supported, skipping test.\n");
950                 crypt_free(cd);
951                 return;
952         }
953
954         params.hash = "md5";
955         FAIL_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params),
956               "MD5 unsupported, too short");
957         crypt_free(cd);
958 }
959
960 int main (int argc, char *argv[])
961 {
962         int i;
963
964         if (getuid() != 0) {
965                 printf("You must be root to run this test.\n");
966                 exit(0);
967         }
968
969         for (i = 1; i < argc; i++) {
970                 if (!strcmp("-v", argv[i]) || !strcmp("--verbose", argv[i]))
971                         _verbose = 1;
972                 else if (!strcmp("--debug", argv[i]))
973                         _debug = _verbose = 1;
974         }
975
976         _cleanup();
977         if (_setup())
978                 goto out;
979
980         crypt_set_debug_level(_debug ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE);
981
982         RUN_(NonFIPSAlg, "Crypto is properly initialised in format"); //must be the first!
983
984         RUN_(LuksUUID, "luksUUID API call");
985         RUN_(IsLuks, "isLuks API call");
986         RUN_(LuksOpen, "luksOpen API call");
987         RUN_(query_device, "crypt_query_device API call");
988         RUN_(remove_device, "crypt_remove_device API call");
989         RUN_(LuksFormat, "luksFormat API call");
990         RUN_(LuksKeyGame, "luksAddKey, RemoveKey, KillSlot API calls");
991         RUN_(DeviceResizeGame, "regular crypto, resize calls");
992
993         RUN_(AddDevicePlain, "plain device API creation exercise");
994         RUN_(AddDeviceLuks, "Format and use LUKS device");
995         RUN_(UseLuksDevice, "Use pre-formated LUKS device");
996         RUN_(SuspendDevice, "Suspend/Resume test");
997         RUN_(UseTempVolumes, "Format and use temporary encrypted device");
998
999         RUN_(CallbacksTest, "API callbacks test");
1000 out:
1001         _cleanup();
1002         return 0;
1003 }