* Add crypt_set_uuid() to API.
[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 <sys/stat.h>
28 #include <sys/ioctl.h>
29
30 #include "libcryptsetup.h"
31
32 #define DMDIR "/dev/mapper/"
33
34 #define DEVICE_1 "/dev/loop5"
35 #define DEVICE_1_UUID "28632274-8c8a-493f-835b-da802e1c576b"
36 #define DEVICE_2 "/dev/loop6"
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 DEVICE_TEST_UUID "12345678-1234-1234-1234-123456789abc"
56
57 static int _debug   = 0;
58 static int _verbose = 1;
59
60 static char global_log[4096];
61 static int global_lines = 0;
62
63 static int gcrypt_compatible = 0;
64
65 // Helpers
66 static int _prepare_keyfile(const char *name, const char *passphrase)
67 {
68         int fd, r;
69
70         fd = open(name, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR);
71         if (fd != -1) {
72                 r = write(fd, passphrase, strlen(passphrase));
73                 close(fd);
74         } else
75                 r = 0;
76
77         return r == strlen(passphrase) ? 0 : 1;
78 }
79
80 static void _remove_keyfiles(void)
81 {
82         remove(KEYFILE1);
83         remove(KEYFILE2);
84 }
85
86 // Decode key from its hex representation
87 static int crypt_decode_key(char *key, char *hex, unsigned int size)
88 {
89         char buffer[3];
90         char *endp;
91         unsigned int i;
92
93         buffer[2] = '\0';
94
95         for (i = 0; i < size; i++) {
96                 buffer[0] = *hex++;
97                 buffer[1] = *hex++;
98
99                 key[i] = (unsigned char)strtoul(buffer, &endp, 16);
100
101                 if (endp != &buffer[2])
102                         return -1;
103         }
104
105         if (*hex != '\0')
106                 return -1;
107
108         return 0;
109 }
110
111 static int yesDialog(char *msg)
112 {
113         return 1;
114 }
115
116 static void cmdLineLog(int level, char *msg)
117 {
118         strncat(global_log, msg, sizeof(global_log) - strlen(global_log));
119         global_lines++;
120 }
121
122 static void new_log(int level, const char *msg, void *usrptr)
123 {
124         cmdLineLog(level, (char*)msg);
125 }
126
127
128 static void reset_log()
129 {
130         memset(global_log, 0, sizeof(global_log));
131         global_lines = 0;
132 }
133
134 static struct interface_callbacks cmd_icb = {
135         .yesDialog = yesDialog,
136         .log = cmdLineLog,
137 };
138
139 static void _cleanup(void)
140 {
141         int r;
142         struct stat st;
143
144         //r = system("udevadm settle");
145
146         if (!stat(DMDIR CDEVICE_1, &st))
147                 r = system("dmsetup remove " CDEVICE_1);
148
149         if (!stat(DMDIR CDEVICE_2, &st))
150                 r = system("dmsetup remove " CDEVICE_2);
151
152         if (!stat(DEVICE_EMPTY, &st))
153                 r = system("dmsetup remove " DEVICE_EMPTY_name);
154
155         if (!stat(DEVICE_ERROR, &st))
156                 r = system("dmsetup remove " DEVICE_ERROR_name);
157
158         if (!strncmp("/dev/loop", DEVICE_1, 9))
159                 r = system("losetup -d " DEVICE_1);
160
161         if (!strncmp("/dev/loop", DEVICE_2, 9))
162                 r = system("losetup -d " DEVICE_2);
163
164         r = system("rm -f " IMAGE_EMPTY);
165         _remove_keyfiles();
166 }
167
168 static void _setup(void)
169 {
170         int r;
171
172         r = system("dmsetup create " DEVICE_EMPTY_name " --table \"0 10000 zero\"");
173         r = system("dmsetup create " DEVICE_ERROR_name " --table \"0 10000 error\"");
174         if (!strncmp("/dev/loop", DEVICE_1, 9)) {
175                 r = system(" [ ! -e " IMAGE1 " ] && bzip2 -dk " IMAGE1 ".bz2");
176                 r = system("losetup " DEVICE_1 " " IMAGE1);
177         }
178         if (!strncmp("/dev/loop", DEVICE_2, 9)) {
179                 r = system("dd if=/dev/zero of=" IMAGE_EMPTY " bs=1M count=4");
180                 r = system("losetup " DEVICE_2 " " IMAGE_EMPTY);
181         }
182
183 }
184
185 void check_ok(int status, int line, const char *func)
186 {
187         char buf[256];
188
189         if (status) {
190                 crypt_get_error(buf, sizeof(buf));
191                 printf("FAIL line %d [%s]: code %d, %s\n", line, func, status, buf);
192                 _cleanup();
193                 exit(-1);
194         }
195 }
196
197 void check_ko(int status, int line, const char *func)
198 {
199         char buf[256];
200
201         memset(buf, 0, sizeof(buf));
202         crypt_get_error(buf, sizeof(buf));
203         if (status >= 0) {
204                 printf("FAIL line %d [%s]: code %d, %s\n", line, func, status, buf);
205                 _cleanup();
206                 exit(-1);
207         } else if (_verbose)
208                 printf("   => errno %d, errmsg: %s\n", status, buf);
209 }
210
211 void check_equal(int line, const char *func)
212 {
213         printf("FAIL line %d [%s]: expected equal values differs.\n", line, func);
214         _cleanup();
215         exit(-1);
216 }
217
218 void xlog(const char *msg, const char *tst, const char *func, int line, const char *txt)
219 {
220         if (_verbose) {
221                 if (txt)
222                         printf(" [%s,%s:%d] %s [%s]\n", msg, func, line, tst, txt);
223                 else
224                         printf(" [%s,%s:%d] %s\n", msg, func, line, tst);
225         }
226 }
227 #define OK_(x)          do { xlog("(success)", #x, __FUNCTION__, __LINE__, NULL); \
228                              check_ok((x), __LINE__, __FUNCTION__); \
229                         } while(0)
230 #define FAIL_(x, y)     do { xlog("(fail)   ", #x, __FUNCTION__, __LINE__, y); \
231                              check_ko((x), __LINE__, __FUNCTION__); \
232                         } while(0)
233 #define EQ_(x, y)       do { xlog("(equal)  ", #x " == " #y, __FUNCTION__, __LINE__, NULL); \
234                              if ((x) != (y)) check_equal(__LINE__, __FUNCTION__); \
235                         } while(0)
236
237 #define RUN_(x, y)              do { printf("%s: %s\n", #x, (y)); x(); } while (0)
238
239 // OLD API TESTS
240 static void LuksUUID(void)
241 {
242         struct crypt_options co = { .icb = &cmd_icb };
243
244         co.device = DEVICE_EMPTY;
245         EQ_(crypt_luksUUID(&co), -EINVAL);
246
247         co.device = DEVICE_ERROR;
248         EQ_(crypt_luksUUID(&co), -EINVAL);
249
250         reset_log();
251         co.device = DEVICE_1;
252         OK_(crypt_luksUUID(&co));
253         EQ_(strlen(global_log), 37); /* UUID + "\n" */
254         EQ_(strncmp(global_log, DEVICE_1_UUID, strlen(DEVICE_1_UUID)), 0);
255
256 }
257
258 static void IsLuks(void)
259 {
260         struct crypt_options co = {  .icb = &cmd_icb };
261
262         co.device = DEVICE_EMPTY;
263         EQ_(crypt_isLuks(&co), -EINVAL);
264
265         co.device = DEVICE_ERROR;
266         EQ_(crypt_isLuks(&co), -EINVAL);
267
268         co.device = DEVICE_1;
269         OK_(crypt_isLuks(&co));
270 }
271
272 static void LuksOpen(void)
273 {
274         struct crypt_options co = {
275                 .name = CDEVICE_1,
276                 //.passphrase = "blabla",
277                 .icb = &cmd_icb,
278         };
279
280         OK_(_prepare_keyfile(KEYFILE1, KEY1));
281         co.key_file = KEYFILE1;
282
283         co.device = DEVICE_EMPTY;
284         EQ_(crypt_luksOpen(&co), -EINVAL);
285
286         co.device = DEVICE_ERROR;
287         EQ_(crypt_luksOpen(&co), -EINVAL);
288
289         co.device = DEVICE_1;
290         OK_(crypt_luksOpen(&co));
291         FAIL_(crypt_luksOpen(&co), "already open");
292
293         _remove_keyfiles();
294 }
295
296 static void query_device(void)
297 {
298         struct crypt_options co = {.icb = &cmd_icb };
299
300         co.name = CDEVICE_WRONG;
301         EQ_(crypt_query_device(&co), 0);
302
303         co.name = CDEVICE_1;
304         EQ_(crypt_query_device(&co), 1);
305
306         OK_(strncmp(crypt_get_dir(), DMDIR, 11));
307         OK_(strcmp(co.cipher, "aes-cbc-essiv:sha256"));
308         EQ_(co.key_size, 16);
309         EQ_(co.offset, 1032);
310         EQ_(co.flags & CRYPT_FLAG_READONLY, 0);
311         EQ_(co.skip, 0);
312         crypt_put_options(&co);
313 }
314
315 static void remove_device(void)
316 {
317         int fd;
318         struct crypt_options co = {.icb = &cmd_icb };
319
320         co.name = CDEVICE_WRONG;
321         EQ_(crypt_remove_device(&co), -ENODEV);
322
323         fd = open(DMDIR CDEVICE_1, O_RDONLY);
324         co.name = CDEVICE_1;
325         FAIL_(crypt_remove_device(&co), "device busy");
326         close(fd);
327
328         OK_(crypt_remove_device(&co));
329 }
330
331 static void LuksFormat(void)
332 {
333         struct crypt_options co = {
334                 .device = DEVICE_2,
335                 .key_size = 256 / 8,
336                 .key_slot = -1,
337                 .cipher = "aes-cbc-essiv:sha256",
338                 .hash = "sha1",
339                 .flags = 0,
340                 .iteration_time = 10,
341                 .align_payload = 0,
342                 .icb = &cmd_icb,
343         };
344
345         OK_(_prepare_keyfile(KEYFILE1, KEY1));
346
347         co.new_key_file = KEYFILE1;
348         co.device = DEVICE_ERROR;
349         FAIL_(crypt_luksFormat(&co), "error device");
350
351         co.device = DEVICE_2;
352         OK_(crypt_luksFormat(&co));
353
354         co.new_key_file = NULL;
355         co.key_file = KEYFILE1;
356         co.name = CDEVICE_2;
357         OK_(crypt_luksOpen(&co));
358         OK_(crypt_remove_device(&co));
359         _remove_keyfiles();
360 }
361
362 static void LuksKeyGame(void)
363 {
364         int i;
365         struct crypt_options co = {
366                 .device = DEVICE_2,
367                 .key_size = 256 / 8,
368                 .key_slot = -1,
369                 .cipher = "aes-cbc-essiv:sha256",
370                 .hash = "sha1",
371                 .flags = 0,
372                 .iteration_time = 10,
373                 .align_payload = 0,
374                 .icb = &cmd_icb,
375         };
376
377         OK_(_prepare_keyfile(KEYFILE1, KEY1));
378         OK_(_prepare_keyfile(KEYFILE2, KEY2));
379
380         co.new_key_file = KEYFILE1;
381         co.device = DEVICE_2;
382         co.key_slot = 8;
383         FAIL_(crypt_luksFormat(&co), "wrong slot #");
384
385         co.key_slot = 7; // last slot
386         OK_(crypt_luksFormat(&co));
387
388         co.new_key_file = KEYFILE1;
389         co.key_file = KEYFILE1;
390         co.key_slot = 8;
391         FAIL_(crypt_luksAddKey(&co), "wrong slot #");
392         co.key_slot = 7;
393         FAIL_(crypt_luksAddKey(&co), "slot already used");
394
395         co.key_slot = 6;
396         OK_(crypt_luksAddKey(&co));
397
398         co.key_file = KEYFILE2 "blah";
399         co.key_slot = 5;
400         FAIL_(crypt_luksAddKey(&co), "keyfile not found");
401
402         co.new_key_file = KEYFILE2; // key to add
403         co.key_file = KEYFILE1;
404         co.key_slot = -1;
405         for (i = 0; i < 6; i++)
406                 OK_(crypt_luksAddKey(&co)); //FIXME: EQ_(i)?
407
408         FAIL_(crypt_luksAddKey(&co), "all slots full");
409
410         // REMOVE KEY
411         co.new_key_file = KEYFILE1; // key to remove
412         co.key_file = NULL;
413         co.key_slot = 8; // should be ignored
414          // only 2 slots should use KEYFILE1
415         OK_(crypt_luksRemoveKey(&co));
416         OK_(crypt_luksRemoveKey(&co));
417         FAIL_(crypt_luksRemoveKey(&co), "no slot with this passphrase");
418
419         co.new_key_file = KEYFILE2 "blah";
420         co.key_file = NULL;
421         FAIL_(crypt_luksRemoveKey(&co), "keyfile not found");
422
423         // KILL SLOT
424         co.new_key_file = NULL;
425         co.key_file = NULL;
426         co.key_slot = 8;
427         FAIL_(crypt_luksKillSlot(&co), "wrong slot #");
428         co.key_slot = 7;
429         FAIL_(crypt_luksKillSlot(&co), "slot already wiped");
430
431         co.key_slot = 5;
432         OK_(crypt_luksKillSlot(&co));
433
434         _remove_keyfiles();
435 }
436
437 size_t _get_device_size(const char *device)
438 {
439         unsigned long size = 0;
440         int fd;
441
442         fd = open(device, O_RDONLY);
443         if (fd == -1)
444                 return 0;
445         (void)ioctl(fd, BLKGETSIZE, &size);
446         close(fd);
447
448         return size;
449 }
450
451 void DeviceResizeGame(void)
452 {
453         size_t orig_size;
454         struct crypt_options co = {
455                 .name = CDEVICE_2,
456                 .device = DEVICE_2,
457                 .key_size = 128 / 8,
458                 .cipher = "aes-cbc-plain",
459                 .hash = "sha1",
460                 .offset = 333,
461                 .skip = 0,
462                 .icb = &cmd_icb,
463         };
464
465         orig_size = _get_device_size(DEVICE_2);
466
467         OK_(_prepare_keyfile(KEYFILE2, KEY2));
468
469         co.key_file = KEYFILE2;
470         co.size = 1000;
471         OK_(crypt_create_device(&co));
472         EQ_(_get_device_size(DMDIR CDEVICE_2), 1000);
473
474         co.size = 2000;
475         OK_(crypt_resize_device(&co));
476         EQ_(_get_device_size(DMDIR CDEVICE_2), 2000);
477
478         co.size = 0;
479         OK_(crypt_resize_device(&co));
480         EQ_(_get_device_size(DMDIR CDEVICE_2), (orig_size - 333));
481         co.size = 0;
482         co.offset = 444;
483         co.skip = 555;
484         co.cipher = "aes-cbc-essiv:sha256";
485         OK_(crypt_update_device(&co));
486         EQ_(_get_device_size(DMDIR CDEVICE_2), (orig_size - 444));
487
488         memset(&co, 0, sizeof(co));
489         co.icb = &cmd_icb,
490         co.name = CDEVICE_2;
491         EQ_(crypt_query_device(&co), 1);
492         EQ_(strcmp(co.cipher, "aes-cbc-essiv:sha256"), 0);
493         EQ_(co.key_size, 128 / 8);
494         EQ_(co.offset, 444);
495         EQ_(co.skip, 555);
496         crypt_put_options(&co);
497
498         // dangerous switch device still works
499         memset(&co, 0, sizeof(co));
500         co.name = CDEVICE_2,
501         co.device = DEVICE_1;
502         co.key_file = KEYFILE2;
503         co.key_size = 128 / 8;
504         co.cipher = "aes-cbc-plain";
505         co.hash = "sha1";
506         co.icb = &cmd_icb;
507         OK_(crypt_update_device(&co));
508
509         memset(&co, 0, sizeof(co));
510         co.icb = &cmd_icb,
511         co.name = CDEVICE_2;
512         EQ_(crypt_query_device(&co), 1);
513         EQ_(strcmp(co.cipher, "aes-cbc-plain"), 0);
514         EQ_(co.key_size, 128 / 8);
515         EQ_(co.offset, 0);
516         EQ_(co.skip, 0);
517         // This expect lookup returns prefered /dev/loopX
518         EQ_(strcmp(co.device, DEVICE_1), 0);
519         crypt_put_options(&co);
520
521         memset(&co, 0, sizeof(co));
522         co.icb = &cmd_icb,
523         co.name = CDEVICE_2;
524         OK_(crypt_remove_device(&co));
525
526         _remove_keyfiles();
527 }
528
529 // NEW API tests
530
531 static void AddDevicePlain(void)
532 {
533         struct crypt_device *cd;
534         struct crypt_params_plain params = {
535                 .hash = "sha1",
536                 .skip = 0,
537                 .offset = 0,
538         };
539         int fd;
540         char key[128], key2[128], path[128];
541
542         char *passphrase = "blabla";
543         char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
544         size_t key_size = strlen(mk_hex) / 2;
545         char *cipher = "aes";
546         char *cipher_mode = "cbc-essiv:sha256";
547
548         crypt_decode_key(key, mk_hex, key_size);
549
550         FAIL_(crypt_init(&cd, ""), "empty device string");
551
552         // default is "plain" hash - no password hash
553         OK_(crypt_init(&cd, DEVICE_1));
554         OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, NULL));
555         FAIL_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0), "cannot verify key with plain");
556         OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
557         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
558         // FIXME: this should get key from active device?
559         //OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)));
560         //OK_(memcmp(key, key2, key_size));
561         OK_(crypt_deactivate(cd, CDEVICE_1));
562         crypt_free(cd);
563
564         // Now use hashed password
565         OK_(crypt_init(&cd, DEVICE_1));
566         OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, &params));
567         FAIL_(crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0),
568               "cannot verify passphrase with plain" );
569         OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0));
570
571         // device status check
572         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
573         snprintf(path, sizeof(path), "%s/%s", crypt_get_dir(), CDEVICE_1);
574         fd = open(path, O_RDONLY);
575         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_BUSY);
576         FAIL_(crypt_deactivate(cd, CDEVICE_1), "Device is busy");
577         close(fd);
578         OK_(crypt_deactivate(cd, CDEVICE_1));
579         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_INACTIVE);
580
581         OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
582         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
583
584         // retrieve volume key check
585         memset(key2, 0, key_size);
586         key_size--;
587         // small buffer
588         FAIL_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)), "small buffer");
589         key_size++;
590         OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)));
591
592         OK_(memcmp(key, key2, key_size));
593         OK_(strcmp(cipher, crypt_get_cipher(cd)));
594         OK_(strcmp(cipher_mode, crypt_get_cipher_mode(cd)));
595         EQ_(key_size, crypt_get_volume_key_size(cd));
596         EQ_(0, crypt_get_data_offset(cd));
597         OK_(crypt_deactivate(cd, CDEVICE_1));
598         crypt_free(cd);
599 }
600
601 static void UseLuksDevice(void)
602 {
603         struct crypt_device *cd;
604         char key[128];
605         size_t key_size;
606
607         OK_(crypt_init(&cd, DEVICE_1));
608         OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
609         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_INACTIVE);
610         OK_(crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0));
611         OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0));
612         FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0), "already open");
613         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
614         OK_(crypt_deactivate(cd, CDEVICE_1));
615         FAIL_(crypt_deactivate(cd, CDEVICE_1), "no such device");
616
617         key_size = 16;
618         OK_(strcmp("aes", crypt_get_cipher(cd)));
619         OK_(strcmp("cbc-essiv:sha256", crypt_get_cipher_mode(cd)));
620         OK_(strcmp(DEVICE_1_UUID, crypt_get_uuid(cd)));
621         EQ_(key_size, crypt_get_volume_key_size(cd));
622         EQ_(1032, crypt_get_data_offset(cd));
623
624         EQ_(0, crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, KEY1, strlen(KEY1)));
625         OK_(crypt_volume_key_verify(cd, key, key_size));
626         OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0));
627         OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
628         EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
629         OK_(crypt_deactivate(cd, CDEVICE_1));
630
631         key[1] = ~key[1];
632         FAIL_(crypt_volume_key_verify(cd, key, key_size), "key mismatch");
633         FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0), "key mismatch");
634         crypt_free(cd);
635 }
636
637 static void SuspendDevice(void)
638 {
639         int suspend_status;
640         struct crypt_device *cd;
641
642         OK_(crypt_init(&cd, DEVICE_1));
643         OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
644         OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0));
645
646         suspend_status = crypt_suspend(cd, CDEVICE_1);
647         if (suspend_status == -ENOTSUP) {
648                 printf("WARNING: Suspend/Resume not supported, skipping test.\n");
649                 goto out;
650         }
651         OK_(suspend_status);
652         FAIL_(crypt_suspend(cd, CDEVICE_1), "already suspended");
653
654         FAIL_(crypt_resume_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1)-1), "wrong key");
655         OK_(crypt_resume_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1)));
656         FAIL_(crypt_resume_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1)), "not suspended");
657
658         OK_(_prepare_keyfile(KEYFILE1, KEY1));
659         OK_(crypt_suspend(cd, CDEVICE_1));
660         FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1 "blah", 0), "wrong keyfile");
661         OK_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0));
662         FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0), "not suspended");
663         _remove_keyfiles();
664 out:
665         OK_(crypt_deactivate(cd, CDEVICE_1));
666         crypt_free(cd);
667 }
668
669 static void AddDeviceLuks(void)
670 {
671         struct crypt_device *cd;
672         struct crypt_params_luks1 params = {
673                 .hash = "sha512",
674                 .data_alignment = 2048, // 4M, data offset will be 4096
675         };
676         char key[128], key2[128];
677
678         char *passphrase = "blabla";
679         char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
680         size_t key_size = strlen(mk_hex) / 2;
681         char *cipher = "aes";
682         char *cipher_mode = "cbc-essiv:sha256";
683
684         crypt_decode_key(key, mk_hex, key_size);
685
686         OK_(crypt_init(&cd, DEVICE_2));
687         OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params));
688
689         // even with no keyslots defined it can be activated by volume key
690         OK_(crypt_volume_key_verify(cd, key, key_size));
691         OK_(crypt_activate_by_volume_key(cd, CDEVICE_2, key, key_size, 0));
692         EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE);
693         OK_(crypt_deactivate(cd, CDEVICE_2));
694
695         // now with keyslot
696         EQ_(7, crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase)));
697         EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 7));
698         EQ_(7, crypt_activate_by_passphrase(cd, CDEVICE_2, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0));
699         EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE);
700         OK_(crypt_deactivate(cd, CDEVICE_2));
701
702         EQ_(1, crypt_keyslot_add_by_volume_key(cd, 1, key, key_size, KEY1, strlen(KEY1)));
703         OK_(_prepare_keyfile(KEYFILE1, KEY1));
704         OK_(_prepare_keyfile(KEYFILE2, KEY2));
705         EQ_(2, crypt_keyslot_add_by_keyfile(cd, 2, KEYFILE1, 0, KEYFILE2, 0));
706         FAIL_(crypt_activate_by_keyfile(cd, CDEVICE_2, CRYPT_ANY_SLOT, KEYFILE2, strlen(KEY2)-1, 0), "key mismatch");
707         EQ_(2, crypt_activate_by_keyfile(cd, NULL, CRYPT_ANY_SLOT, KEYFILE2, 0, 0));
708         EQ_(2, crypt_activate_by_keyfile(cd, CDEVICE_2, CRYPT_ANY_SLOT, KEYFILE2, 0, 0));
709         OK_(crypt_keyslot_destroy(cd, 1));
710         OK_(crypt_keyslot_destroy(cd, 2));
711         OK_(crypt_deactivate(cd, CDEVICE_2));
712         _remove_keyfiles();
713
714         FAIL_(crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase)), "slot used");
715         key[1] = ~key[1];
716         FAIL_(crypt_keyslot_add_by_volume_key(cd, 6, key, key_size, passphrase, strlen(passphrase)), "key mismatch");
717         key[1] = ~key[1];
718         EQ_(6, crypt_keyslot_add_by_volume_key(cd, 6, key, key_size, passphrase, strlen(passphrase)));
719         EQ_(CRYPT_SLOT_ACTIVE, crypt_keyslot_status(cd, 6));
720
721         FAIL_(crypt_keyslot_destroy(cd, 8), "invalid keyslot");
722         FAIL_(crypt_keyslot_destroy(cd, CRYPT_ANY_SLOT), "invalid keyslot");
723         FAIL_(crypt_keyslot_destroy(cd, 0), "keyslot not used");
724         OK_(crypt_keyslot_destroy(cd, 7));
725         EQ_(CRYPT_SLOT_INACTIVE, crypt_keyslot_status(cd, 7));
726         EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 6));
727
728         EQ_(6, crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)));
729         OK_(crypt_volume_key_verify(cd, key2, key_size));
730
731         OK_(memcmp(key, key2, key_size));
732         OK_(strcmp(cipher, crypt_get_cipher(cd)));
733         OK_(strcmp(cipher_mode, crypt_get_cipher_mode(cd)));
734         EQ_(key_size, crypt_get_volume_key_size(cd));
735         EQ_(4096, crypt_get_data_offset(cd));
736         OK_(strcmp(DEVICE_2, crypt_get_device_name(cd)));
737
738         reset_log();
739         crypt_set_log_callback(cd, &new_log, NULL);
740         OK_(crypt_dump(cd));
741         OK_(!(global_lines != 0));
742         crypt_set_log_callback(cd, NULL, NULL);
743         reset_log();
744
745         FAIL_(crypt_set_uuid(cd, "blah"), "wrong UUID format");
746         OK_(crypt_set_uuid(cd, DEVICE_TEST_UUID));
747         OK_(strcmp(DEVICE_TEST_UUID, crypt_get_uuid(cd)));
748
749         FAIL_(crypt_deactivate(cd, CDEVICE_2), "not active");
750         crypt_free(cd);
751 }
752
753 // Check that gcrypt is properly initialised in format
754 static void NonFIPSAlg(void)
755 {
756         struct crypt_device *cd;
757         struct crypt_params_luks1 params = {
758                 .hash = "whirlpool",
759         };
760         char key[128] = "";
761         size_t key_size = 128;
762         char *cipher = "aes";
763         char *cipher_mode = "cbc-essiv:sha256";
764
765         if (!gcrypt_compatible) {
766                 printf("WARNING: old libgcrypt, skipping test.\n");
767                 return;
768         }
769         OK_(crypt_init(&cd, DEVICE_2));
770         OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params));
771
772         params.hash = "md5";
773         FAIL_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params),
774               "MD5 unsupported, too short");
775         crypt_free(cd);
776 }
777
778
779 static void _gcrypt_compatible()
780 {
781         int maj, min, patch;
782         FILE *f;
783
784         if (!(f = popen("libgcrypt-config --version", "r")))
785                 return;
786
787         if (fscanf(f, "%d.%d.%d", &maj, &min, &patch) == 3 &&
788             maj >= 1 && min >= 4)
789                 gcrypt_compatible = 1;
790         if (_debug)
791                 printf("libgcrypt version %d.%d.%d detected.\n", maj, min, patch);
792
793         (void)fclose(f);
794         return;
795 }
796
797 int main (int argc, char *argv[])
798 {
799         int i;
800
801         if (getuid() != 0) {
802                 printf("You must be root to run this test.\n");
803                 exit(0);
804         }
805
806         for (i = 1; i < argc; i++) {
807                 if (!strcmp("-v", argv[i]) || !strcmp("--verbose", argv[i]))
808                         _verbose = 1;
809                 else if (!strcmp("--debug", argv[i]))
810                         _debug = _verbose = 1;
811         }
812
813         _cleanup();
814         _setup();
815         _gcrypt_compatible();
816
817         crypt_set_debug_level(_debug ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE);
818
819         RUN_(NonFIPSAlg, "Crypto is properly initialised in format"); //must be the first!
820         RUN_(LuksUUID, "luksUUID API call");
821         RUN_(IsLuks, "isLuks API call");
822         RUN_(LuksOpen, "luksOpen API call");
823         RUN_(query_device, "crypt_query_device API call");
824         RUN_(remove_device, "crypt_remove_device API call");
825         RUN_(LuksFormat, "luksFormat API call");
826         RUN_(LuksKeyGame, "luksAddKey, RemoveKey, KillSlot API calls");
827         RUN_(DeviceResizeGame, "regular crypto, resize calls");
828
829         RUN_(AddDevicePlain, "plain device API creation exercise");
830         RUN_(AddDeviceLuks, "Format and use LUKS device");
831         RUN_(UseLuksDevice, "Use pre-formated LUKS device");
832         RUN_(SuspendDevice, "Suspend/Resume test");
833
834         _cleanup();
835         return 0;
836 }