Allow restrict keys size in LuksOpen (thanks to Stefan Assmann)
[platform/upstream/cryptsetup.git] / lib / setup.c
1 #include <string.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <inttypes.h>
5 #include <sys/types.h>
6 #include <sys/ioctl.h>
7 #include <sys/mman.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <errno.h>
11 #include <signal.h>
12 #include <assert.h>
13
14 #include "libcryptsetup.h"
15 #include "internal.h"
16 #include "blockdev.h"
17 #include "luks.h"
18
19 struct device_infos {
20         uint64_t        size;
21         int             readonly;
22 };
23
24 static int memory_unsafe = 0;
25 static char *default_backend = NULL;
26
27 #define at_least_one(a) ({ __typeof__(a) __at_least_one=(a); (__at_least_one)?__at_least_one:1; })
28
29 static void logger(struct crypt_options *options, int class, char *format, ...) {
30         va_list argp;
31         char *target = NULL;
32
33         va_start(argp, format);
34
35         if (vasprintf(&target, format, argp) > 0)
36                 options->icb->log(class, target);
37
38         va_end(argp);
39         free(target);
40 }
41
42 static void hexprintICB(struct crypt_options *options, int class, char *d, int n)
43 {
44         int i;
45         for(i = 0; i < n; i++)
46                 logger(options, class, "%02hhx ", (char)d[i]);
47 }
48
49 static int setup_enter(struct setup_backend *backend, void (*log)(int, char *))
50 {
51         int r;
52
53         /*
54          * from here we could have sensible data in memory
55          * so protect it from being swapped out
56          */
57         r = mlockall(MCL_CURRENT | MCL_FUTURE);
58         if (r < 0) {
59                 perror("mlockall failed");
60                 log(CRYPT_LOG_ERROR, "WARNING!!! Possibly insecure memory. Are you root?\n");
61                 memory_unsafe = 1;
62         }
63
64         set_error(NULL);
65
66         if (backend) {
67                 r = backend->init();
68                 if (r < 0)
69                         return r;
70                 if (r > 0)
71                         memory_unsafe = 1;
72         }
73
74         return 0;
75 }
76
77 static int setup_leave(struct setup_backend *backend)
78 {
79         if (backend)
80                 backend->exit();
81
82         /* dangerous, we can't wipe all the memory */
83         if (!memory_unsafe)
84                 munlockall();
85
86         return 0;
87 }
88
89 /*
90  * Password processing behaviour matrix of process_key
91  * 
92  * from binary file: check if there is sufficently large key material
93  * interactive & from fd: hash if requested, otherwise crop or pad with '0'
94  */
95
96 static char *process_key(struct crypt_options *options, char *pass, int passLen) {
97         char *key = safe_alloc(options->key_size);
98         memset(key, 0, options->key_size);
99
100         /* key is coming from binary file */
101         if (options->key_file && strcmp(options->key_file, "-")) {
102                 if(passLen < options->key_size) {
103                         set_error("Could not read %d bytes from key file",
104                                   options->key_size);
105                         safe_free(key);
106                         return NULL;
107                 } 
108                 memcpy(key,pass,options->key_size);
109                 return key;
110         }
111
112         /* key is coming from tty, fd or binary stdin */
113         if (options->hash) {
114                 if (hash(NULL, options->hash,
115                          key, options->key_size,
116                          pass, passLen) < 0)
117                 {
118                         safe_free(key);
119                         return NULL;
120                 }
121         } else if (passLen > options->key_size) {
122                 memcpy(key, pass, options->key_size);
123         } else {
124                 memcpy(key, pass, passLen);
125         }
126
127         return key;
128 }
129
130 static int get_device_infos(const char *device, struct device_infos *infos)
131 {
132         char buf[128];
133         uint64_t size;
134         unsigned long size_small;
135         int readonly = 0;
136         int ret = -1;
137         int fd;
138
139         /* Try to open read-write to check whether it is a read-only device */
140         fd = open(device, O_RDWR);
141         if (fd < 0) {
142                 if (errno == EROFS) {
143                         readonly = 1;
144                         fd = open(device, O_RDONLY);
145                 }
146         } else {
147                 close(fd);
148                 fd = open(device, O_RDONLY);
149         }
150         if (fd < 0) {
151                 set_error("Error opening device: %s",
152                           strerror_r(errno, buf, 128));
153                 return -1;
154         }
155
156 #ifdef BLKROGET
157         /* If the device can be opened read-write, i.e. readonly is still 0, then
158          * check whether BKROGET says that it is read-only. E.g. read-only loop
159          * devices may be openend read-write but are read-only according to BLKROGET
160          */
161         if (readonly == 0) {
162                 if (ioctl(fd, BLKROGET, &readonly) < 0) {
163                         set_error("BLKROGET failed on device: %s",
164                                   strerror_r(errno, buf, 128));
165                         return -1;
166                 }
167         }
168 #else
169 #error BLKROGET not available
170 #endif
171
172 #ifdef BLKGETSIZE64
173         if (ioctl(fd, BLKGETSIZE64, &size) >= 0) {
174                 size >>= SECTOR_SHIFT;
175                 ret = 0;
176                 goto out;
177         }
178 #endif
179
180 #ifdef BLKGETSIZE
181         if (ioctl(fd, BLKGETSIZE, &size_small) >= 0) {
182                 size = (uint64_t)size_small;
183                 ret = 0;
184                 goto out;
185         }
186 #else
187 #       error Need at least the BLKGETSIZE ioctl!
188 #endif
189
190         set_error("BLKGETSIZE ioctl failed on device: %s",
191                   strerror_r(errno, buf, 128));
192
193 out:
194         if (ret == 0) {
195                 infos->size = size;
196                 infos->readonly = readonly;
197         }
198         close(fd);
199         return ret;
200 }
201
202 static int wipe_device_header(const char *device, int sectors)
203 {
204         char *buffer;
205         int size = sectors * SECTOR_SIZE;
206         int r = -1;
207         int devfd;
208
209         devfd = open(device, O_RDWR | O_DIRECT | O_SYNC);
210         if(devfd == -1) {
211                 set_error("Can't wipe header on device %s", device);
212                 return -EINVAL;
213         }
214
215         buffer = malloc(size);
216         if (!buffer) {
217                 close(devfd);
218                 return -ENOMEM;
219         }
220         memset(buffer, 0, size);
221
222         r = write_blockwise(devfd, buffer, size) < size ? -EIO : 0;
223
224         free(buffer);
225         close(devfd);
226
227         return r;
228 }
229
230 static int parse_into_name_and_mode(const char *nameAndMode, char *name,
231                                     char *mode)
232 {
233 /* Token content stringification, see info cpp/stringification */
234 #define str(s) #s
235 #define xstr(s) str(s)
236 #define scanpattern1 "%" xstr(LUKS_CIPHERNAME_L) "[^-]-%" xstr(LUKS_CIPHERMODE_L)  "s"
237 #define scanpattern2 "%" xstr(LUKS_CIPHERNAME_L) "[^-]"
238
239         int r;
240
241         if(sscanf(nameAndMode,scanpattern1, name, mode) != 2) {
242                 if((r = sscanf(nameAndMode,scanpattern2,name)) == 1) {
243                         strncpy(mode,"cbc-plain",10);
244                 } 
245                 else {
246                         set_error("no known cipher-spec pattern detected");
247                         return -EINVAL;
248                 }
249         }
250
251         return 0;
252
253 #undef sp1
254 #undef sp2
255 #undef str
256 #undef xstr
257 }
258
259 static int keyslot_is_valid(int keySlotIndex, struct crypt_options *options)
260 {
261         if(keySlotIndex >= LUKS_NUMKEYS || keySlotIndex < 0) {
262                 logger(options,CRYPT_LOG_ERROR,"Key slot %d is invalid, please pick between 0 and %d.\n", keySlotIndex, LUKS_NUMKEYS - 1);
263                 return 0;
264         }
265
266         return 1;
267 }
268
269 /* Select free keyslot or verifies that the one specified is empty */
270 static int keyslot_from_option(int keySlotOption, struct luks_phdr *hdr, struct crypt_options *options) {
271         if(keySlotOption >= 0) {
272                 if(!keyslot_is_valid(keySlotOption, options))
273                         return -EINVAL;
274                 else if(hdr->keyblock[keySlotOption].active != LUKS_KEY_DISABLED) {
275                         logger(options,CRYPT_LOG_ERROR,"Key slot %d is full, please pick another one", keySlotOption);
276                         return -EINVAL;
277                 } else {
278                         return keySlotOption;
279                 }
280         } else {
281                 int i;
282                 /* Find empty key slot */
283                 for(i=0; i<LUKS_NUMKEYS; i++) {
284                         if(hdr->keyblock[i].active == LUKS_KEY_DISABLED) break;
285                 }
286                 if(i==LUKS_NUMKEYS) {
287                         logger(options,CRYPT_LOG_ERROR,"All slots full");
288                         return -EINVAL;
289                 }
290                 return i;
291         }
292 }
293
294 static int __crypt_create_device(int reload, struct setup_backend *backend,
295                                  struct crypt_options *options)
296 {
297         struct crypt_options tmp = {
298                 .name = options->name,
299         };
300         struct device_infos infos;
301         char *key = NULL;
302         unsigned int keyLen;
303         char *processed_key = NULL;
304         int r;
305
306         r = backend->status(0, &tmp, NULL);
307         if (reload) {
308                 if (r < 0)
309                         return r;
310         } else {
311                 if (r >= 0) {
312                         set_error("Device %s already exists.", options->name);
313                         return -EEXIST;
314                 }
315                 if (r != -ENODEV)
316                         return r;
317         }
318
319         if (options->key_size < 0 || options->key_size > 1024) {
320                 set_error("Invalid key size");
321                 return -EINVAL;
322         }
323
324         if (get_device_infos(options->device, &infos) < 0)
325                 return -ENOTBLK;
326
327         if (!options->size) {
328                 options->size = infos.size;
329                 if (!options->size) {
330                         set_error("Not a block device");
331                         return -ENOTBLK;
332                 }
333                 if (options->size <= options->offset) {
334                         set_error("Invalid offset");
335                         return -EINVAL;
336                 }
337                 options->size -= options->offset;
338         }
339
340         if (infos.readonly)
341                 options->flags |= CRYPT_FLAG_READONLY;
342
343         get_key("Enter passphrase: ", &key, &keyLen, options->key_size, options->key_file, options->passphrase_fd, options->timeout, options->flags);
344         if (!key) {
345                 set_error("Key reading error");
346                 return -ENOENT;
347         }
348
349         processed_key = process_key(options,key,keyLen);
350         safe_free(key);
351
352         if (!processed_key) {
353                 const char *error=get_error();
354                 if(error) {
355                         char *c_error_handling_sucks = NULL;
356                         if (asprintf(&c_error_handling_sucks,"Key processing error: %s",error) > 0)
357                                 set_error(c_error_handling_sucks);
358                         free(c_error_handling_sucks);
359                 } else
360                         set_error("Key processing error");
361                 return -ENOENT;
362         }
363
364         r = backend->create(reload, options, processed_key, NULL);
365
366         safe_free(processed_key);
367
368         return r;
369 }
370
371 static int __crypt_query_device(int details, struct setup_backend *backend,
372                                 struct crypt_options *options)
373 {
374         int r = backend->status(details, options, NULL);
375         if (r == -ENODEV)
376                 return 0;
377         else if (r >= 0)
378                 return 1;
379         else
380                 return r;
381 }
382
383 static int __crypt_resize_device(int details, struct setup_backend *backend,
384                                 struct crypt_options *options)
385 {
386         struct crypt_options tmp = {
387                 .name = options->name,
388         };
389         struct device_infos infos;
390         char *key = NULL;
391         int r;
392
393         r = backend->status(1, &tmp, &key);
394         if (r < 0)
395                 return r;
396
397         if (get_device_infos(tmp.device, &infos) < 0)
398                 return -EINVAL;
399
400         if (!options->size) {
401                 options->size = infos.size;
402                 if (!options->size) {
403                         set_error("Not a block device");
404                         return -ENOTBLK;
405                 }
406                 if (options->size <= tmp.offset) {
407                         set_error("Invalid offset");
408                         return -EINVAL;
409                 }
410                 options->size -= tmp.offset;
411         }
412         tmp.size = options->size;
413
414         if (infos.readonly)
415                 options->flags |= CRYPT_FLAG_READONLY;
416
417         r = backend->create(1, &tmp, key, NULL);
418
419         safe_free(key);
420
421         return r;
422 }
423
424 static int __crypt_remove_device(int arg, struct setup_backend *backend,
425                                  struct crypt_options *options)
426 {
427         int r;
428
429         r = backend->status(0, options, NULL);
430         if (r < 0)
431                 return r;
432         if (r > 0) {
433                 set_error("Device busy");
434                 return -EBUSY;
435         }
436
437         return backend->remove(0, options);
438 }
439
440 static int __crypt_luks_format(int arg, struct setup_backend *backend, struct crypt_options *options)
441 {
442         int r;
443
444         struct luks_phdr header;
445         struct luks_masterkey *mk=NULL;
446         char *password=NULL; 
447         char cipherName[LUKS_CIPHERNAME_L];
448         char cipherMode[LUKS_CIPHERMODE_L];
449         unsigned int passwordLen;
450         unsigned int PBKDF2perSecond = 0;
451         int keyIndex;
452
453         if (!LUKS_device_ready(options->device, O_RDWR | O_EXCL))
454                 return -ENOTBLK;
455
456         mk = LUKS_generate_masterkey(options->key_size);
457         if(NULL == mk) return -ENOMEM; // FIXME This may be misleading, since we don't know what went wrong
458
459 #ifdef LUKS_DEBUG
460 #define printoffset(entry) \
461         logger(options, CRYPT_LOG_ERROR, \
462                 "offset of " #entry " = %d\n", (char *)(&header.entry)-(char *)(&header))
463
464         logger(options, CRYPT_LOG_ERROR,
465                 "sizeof phdr %d, sizeof key slot %d\n",
466                 sizeof(struct luks_phdr),
467                 sizeof(header.keyblock[0]));
468
469         printoffset(magic);
470         printoffset(version);
471         printoffset(cipherName);
472         printoffset(cipherMode);
473         printoffset(hashSpec);
474         printoffset(payloadOffset);
475         printoffset(keyBytes);
476         printoffset(mkDigest);
477         printoffset(mkDigestSalt);
478         printoffset(mkDigestIterations);
479         printoffset(uuid);
480 #endif
481
482         r = parse_into_name_and_mode(options->cipher, cipherName, cipherMode);
483         if(r < 0) return r;
484
485         r = LUKS_generate_phdr(&header, mk, cipherName, cipherMode, options->hash, LUKS_STRIPES, options->align_payload);
486         if(r < 0) return r;
487
488         keyIndex = keyslot_from_option(options->key_slot, &header, options);
489         if(keyIndex == -EINVAL) {
490                 r = -EINVAL; goto out;
491         }
492
493         r = LUKS_benchmarkt_iterations(options->hash, &PBKDF2perSecond);
494         if (r < 0) goto out;
495
496         header.keyblock[keyIndex].passwordIterations = at_least_one(PBKDF2perSecond * ((float)options->iteration_time / 1000.0));
497 #ifdef LUKS_DEBUG
498         logger(options, CRYPT_LOG_ERROR, "pitr %d\n", header.keyblock[0].passwordIterations);
499 #endif
500         get_key("Enter LUKS passphrase: ",&password,&passwordLen, 0, options->new_key_file, options->passphrase_fd, options->timeout, options->flags);
501         if(!password) {
502                 r = -EINVAL; goto out;
503         }
504
505         /* Wipe first 8 sectors - fs magic numbers etc. */
506         r = wipe_device_header(options->device, 8);
507         if(r < 0) goto out;
508
509         /* Set key, also writes phdr */
510         r = LUKS_set_key(options->device, keyIndex, password, passwordLen, &header, mk, backend);
511         if(r < 0) goto out; 
512
513         r = 0;
514 out:
515         LUKS_dealloc_masterkey(mk);
516         safe_free(password);
517         return r;
518 }
519
520 static int __crypt_luks_open(int arg, struct setup_backend *backend, struct crypt_options *options)
521 {
522         struct luks_masterkey *mk=NULL;
523         struct luks_phdr hdr;
524         char *prompt = NULL;
525         char *password;
526         unsigned int passwordLen;
527         struct device_infos infos;
528         struct crypt_options tmp = {
529                 .name = options->name,
530         };
531         char *dmCipherSpec = NULL;
532         int r, tries = options->tries;
533         int excl = (options->flags & CRYPT_FLAG_NON_EXCLUSIVE_ACCESS) ? 0 : O_EXCL ;
534
535         r = backend->status(0, &tmp, NULL);
536         if (r >= 0) {
537                 set_error("Device %s already exists.", options->name);
538                 return -EEXIST;
539         }
540
541         if (!LUKS_device_ready(options->device, O_RDONLY | excl))
542                 return -ENOTBLK;
543
544         if (get_device_infos(options->device, &infos) < 0) {
545                 set_error("Can't get device information.\n");
546                 return -ENOTBLK;
547         }
548
549         if (infos.readonly)
550                 options->flags |= CRYPT_FLAG_READONLY;
551
552         if(asprintf(&prompt, "Enter LUKS passphrase for %s: ", options->device) < 0)
553                 return -ENOMEM;
554
555 start:
556         mk=NULL;
557
558         if(options->passphrase) {
559                 passwordLen = strlen(options->passphrase);
560                 password = safe_alloc(passwordLen + 1);
561                 strncpy(password, options->passphrase, passwordLen + 1);
562                 tries = 0;
563         } else if(get_key(prompt, &password, &passwordLen, options->key_size, options->key_file, options->passphrase_fd, options->timeout, options->flags))
564                 tries--;
565         else
566                 tries = 0;
567
568         if(!password) {
569                 r = -EINVAL; goto out;
570         }
571
572         r = LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk, backend);
573         if (r == -EPERM)
574                 set_error("No key available with this passphrase.\n");
575         if (r < 0)
576                 goto out1;
577
578         logger(options, CRYPT_LOG_NORMAL,"key slot %d unlocked.\n", r);
579
580
581         options->offset = hdr.payloadOffset;
582         if (asprintf(&dmCipherSpec, "%s-%s", hdr.cipherName, hdr.cipherMode) < 0) {
583                 r = -ENOMEM;
584                 goto out2;
585         }
586         options->cipher = dmCipherSpec;
587         options->key_size = mk->keyLength;
588         options->skip = 0;
589
590         options->size = infos.size;
591         if (!options->size) {
592                 set_error("Not a block device.\n");
593                 r = -ENOTBLK; goto out2;
594         }
595         if (options->size <= options->offset) {
596                 set_error("Invalid offset");
597                 r = -EINVAL; goto out2;
598         }
599         options->size -= options->offset;
600         /* FIXME: code allows multiple crypt mapping, cannot use uuid then.
601          * anyway, it is dangerous and can corrupt data. Remove it in next version! */
602         r = backend->create(0, options, mk->key, excl ? hdr.uuid : NULL);
603
604  out2:
605         free(dmCipherSpec);
606         dmCipherSpec = NULL;
607  out1:
608         safe_free(password);
609  out:
610         LUKS_dealloc_masterkey(mk);
611         if (r == -EPERM && tries > 0)
612                 goto start;
613
614         free(prompt);
615
616         return r;
617 }
618
619 static int __crypt_luks_add_key(int arg, struct setup_backend *backend, struct crypt_options *options)
620 {
621         struct luks_masterkey *mk=NULL;
622         struct luks_phdr hdr;
623         char *password=NULL; unsigned int passwordLen;
624         unsigned int keyIndex;
625         unsigned int PBKDF2perSecond = 0;
626         const char *device = options->device;
627         int r;
628
629         if (!LUKS_device_ready(options->device, O_RDWR))
630                 return -ENOTBLK;
631
632         r = LUKS_read_phdr(device, &hdr);
633         if(r < 0) return r;
634
635
636         keyIndex = keyslot_from_option(options->key_slot, &hdr, options);
637         if(keyIndex == -EINVAL) {
638                 r = -EINVAL; goto out;
639         }
640
641         get_key("Enter any LUKS passphrase: ",
642                 &password,
643                 &passwordLen, 
644                 0,
645                 options->key_file, 
646                 options->passphrase_fd, 
647                 options->timeout, 
648                 options->flags & ~(CRYPT_FLAG_VERIFY | CRYPT_FLAG_VERIFY_IF_POSSIBLE));
649
650         if(!password) {
651                 r = -EINVAL; goto out;
652         }
653         r = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk, backend);
654         if(r < 0) {
655                 options->icb->log(CRYPT_LOG_ERROR,"No key available with this passphrase.\n");
656                 r = -EPERM; goto out;
657         } else
658                 logger(options, CRYPT_LOG_NORMAL,"key slot %d unlocked.\n", r);
659
660         safe_free(password);
661
662         get_key("Enter new passphrase for key slot: ",
663                 &password,
664                 &passwordLen,
665                 0,
666                 options->new_key_file,
667                 options->passphrase_fd,
668                 options->timeout, 
669                 options->flags);
670         if(!password) {
671                 r = -EINVAL; goto out;
672         }
673
674         r = LUKS_benchmarkt_iterations(hdr.hashSpec, &PBKDF2perSecond);
675         if (r < 0) goto out;
676         hdr.keyblock[keyIndex].passwordIterations = at_least_one(PBKDF2perSecond * ((float)options->iteration_time / 1000));
677
678         r = LUKS_set_key(device, keyIndex, password, passwordLen, &hdr, mk, backend);
679         if(r < 0) goto out;
680
681         r = 0;
682 out:
683         safe_free(password);
684         LUKS_dealloc_masterkey(mk);
685         return r;
686 }
687
688 static int luks_remove_helper(int arg, struct setup_backend *backend, struct crypt_options *options, int supply_it)
689 {
690         struct luks_masterkey *mk;
691         struct luks_phdr hdr;
692         char *password=NULL; 
693         unsigned int passwordLen;
694         const char *device = options->device;
695         int keyIndex;
696         int openedIndex;
697         int r, last_slot;
698
699         if (!LUKS_device_ready(options->device, O_RDWR))
700             return -ENOTBLK;
701
702         if(supply_it) {
703                 get_key("Enter LUKS passphrase to be deleted: ",&password,&passwordLen, 0, options->new_key_file,
704                         options->passphrase_fd, options->timeout, options->flags);
705                 if(!password) {
706                         r = -EINVAL; goto out;
707                 }
708
709                 keyIndex = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk, backend);
710                 if(keyIndex < 0) {
711                         options->icb->log(CRYPT_LOG_ERROR,"No remaining key available with this passphrase.\n");
712                         r = -EPERM; goto out;
713                 } else
714                         logger(options, CRYPT_LOG_NORMAL,"key slot %d selected for deletion.\n", keyIndex);
715
716                 safe_free(password);
717                 password = NULL;
718         } else {
719                 keyIndex = options->key_slot;
720                 if (!keyslot_is_valid(keyIndex, options)) {
721                         r = -EINVAL; goto out;
722                 }
723         }
724
725         last_slot = LUKS_is_last_keyslot(options->device, keyIndex);
726         if(last_slot && !(options->icb->yesDialog(_("This is the last keyslot. Device will become unusable after purging this key.")))) {
727                 r = -EINVAL; goto out;
728         }
729
730         if(options->flags & CRYPT_FLAG_VERIFY_ON_DELKEY) {
731                 options->flags &= ~CRYPT_FLAG_VERIFY_ON_DELKEY;
732                 get_key("Enter any remaining LUKS passphrase: ",&password,&passwordLen, 0, options->key_file, options->passphrase_fd, options->timeout, options->flags);
733                 if(!password) {
734                         r = -EINVAL; goto out;
735                 }
736
737                 r = LUKS_read_phdr(device, &hdr);
738                 if(r < 0) { 
739                         options->icb->log(CRYPT_LOG_ERROR,"Failed to access device.\n");
740                         r = -EIO; goto out;
741                 }
742
743                 if(!last_slot)
744                         hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED;
745
746                 openedIndex = LUKS_open_any_key_with_hdr(device, password, passwordLen, &hdr, &mk, backend);
747                 /* Clean up */
748                 if (openedIndex >= 0) {
749                         LUKS_dealloc_masterkey(mk);
750                         mk = NULL;
751                 }
752                 if(openedIndex < 0) {
753                             options->icb->log(CRYPT_LOG_ERROR,"No remaining key available with this passphrase.\n");
754                             r = -EPERM; goto out;
755                 } else
756                         logger(options, CRYPT_LOG_NORMAL,"key slot %d verified.\n", openedIndex);
757         }
758         r = LUKS_del_key(device, keyIndex);
759         if(r < 0) goto out;
760
761         r = 0;
762 out:
763         safe_free(password);
764         return r;
765 }
766
767 static int __crypt_luks_kill_slot(int arg, struct setup_backend *backend, struct crypt_options *options) {
768         return luks_remove_helper(arg, backend, options, 0);
769 }
770
771 static int __crypt_luks_remove_key(int arg, struct setup_backend *backend, struct crypt_options *options) {
772         return luks_remove_helper(arg, backend, options, 1);
773 }
774
775
776 static int crypt_job(int (*job)(int arg, struct setup_backend *backend,
777                                 struct crypt_options *options),
778                      int arg, struct crypt_options *options)
779 {
780         struct setup_backend *backend;
781         int r;
782
783         backend = get_setup_backend(default_backend);
784
785         if (setup_enter(backend,options->icb->log) < 0) {
786                 r = -ENOSYS;
787                 goto out;
788         }
789
790         if (!backend) {
791                 set_error("No setup backend available");
792                 r = -ENOSYS;
793                 goto out;
794         }
795
796         r = job(arg, backend, options);
797 out:
798         setup_leave(backend);
799         if (backend)
800                 put_setup_backend(backend);
801
802         if (r >= 0)
803                 set_error(NULL);
804
805         return r;
806 }
807
808 int crypt_create_device(struct crypt_options *options)
809 {
810         return crypt_job(__crypt_create_device, 0, options);
811 }
812
813 int crypt_update_device(struct crypt_options *options)
814 {
815         return crypt_job(__crypt_create_device, 1, options);
816 }
817
818 int crypt_resize_device(struct crypt_options *options)
819 {
820         return crypt_job(__crypt_resize_device, 0, options);
821 }
822
823 int crypt_query_device(struct crypt_options *options)
824 {
825         return crypt_job(__crypt_query_device, 1, options);
826 }
827
828 int crypt_remove_device(struct crypt_options *options)
829 {
830         return crypt_job(__crypt_remove_device, 0, options);
831
832 }
833
834 int crypt_luksFormat(struct crypt_options *options)
835 {
836         return crypt_job(__crypt_luks_format, 0, options);
837 }
838
839 int crypt_luksOpen(struct crypt_options *options)
840 {
841         return crypt_job(__crypt_luks_open, 0, options);
842 }
843
844 int crypt_luksKillSlot(struct crypt_options *options)
845 {
846         return crypt_job(__crypt_luks_kill_slot, 0, options);
847 }
848
849 int crypt_luksRemoveKey(struct crypt_options *options)
850 {
851         return crypt_job(__crypt_luks_remove_key, 0, options);
852 }
853
854 int crypt_luksAddKey(struct crypt_options *options)
855 {
856         return crypt_job(__crypt_luks_add_key, 0, options);
857 }
858
859 int crypt_luksUUID(struct crypt_options *options)
860 {
861         struct luks_phdr hdr;
862         int r;
863
864         r = LUKS_read_phdr(options->device,&hdr);
865         if(r < 0) return r;
866
867         options->icb->log(CRYPT_LOG_NORMAL,hdr.uuid);
868         options->icb->log(CRYPT_LOG_NORMAL,"\n");
869         return 0;
870 }
871
872 int crypt_isLuks(struct crypt_options *options)
873 {
874         struct luks_phdr hdr;
875         return LUKS_read_phdr(options->device,&hdr);
876 }
877
878 int crypt_luksDump(struct crypt_options *options)
879 {
880         struct luks_phdr hdr;
881         int r,i;
882
883         r = LUKS_read_phdr(options->device,&hdr);
884         if(r < 0) return r;
885
886         logger(options, CRYPT_LOG_NORMAL, "LUKS header information for %s\n\n",options->device);
887         logger(options, CRYPT_LOG_NORMAL, "Version:       \t%d\n",hdr.version);
888         logger(options, CRYPT_LOG_NORMAL, "Cipher name:   \t%s\n",hdr.cipherName);
889         logger(options, CRYPT_LOG_NORMAL, "Cipher mode:   \t%s\n",hdr.cipherMode);
890         logger(options, CRYPT_LOG_NORMAL, "Hash spec:     \t%s\n",hdr.hashSpec);
891         logger(options, CRYPT_LOG_NORMAL, "Payload offset:\t%d\n",hdr.payloadOffset);
892         logger(options, CRYPT_LOG_NORMAL, "MK bits:       \t%d\n",hdr.keyBytes*8);
893         logger(options, CRYPT_LOG_NORMAL, "MK digest:     \t");
894         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.mkDigest,LUKS_DIGESTSIZE);
895         logger(options, CRYPT_LOG_NORMAL, "\n");
896         logger(options, CRYPT_LOG_NORMAL, "MK salt:       \t");
897         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.mkDigestSalt,LUKS_SALTSIZE/2);
898         logger(options, CRYPT_LOG_NORMAL, "\n               \t");
899         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.mkDigestSalt+LUKS_SALTSIZE/2,LUKS_SALTSIZE/2);
900         logger(options, CRYPT_LOG_NORMAL, "\n");
901         logger(options, CRYPT_LOG_NORMAL, "MK iterations: \t%d\n",hdr.mkDigestIterations);
902         logger(options, CRYPT_LOG_NORMAL, "UUID:          \t%s\n\n",hdr.uuid);
903         for(i=0;i<LUKS_NUMKEYS;i++) {
904                 if(hdr.keyblock[i].active == LUKS_KEY_ENABLED) {
905                         logger(options, CRYPT_LOG_NORMAL, "Key Slot %d: ENABLED\n",i);
906                         logger(options, CRYPT_LOG_NORMAL, "\tIterations:         \t%d\n",hdr.keyblock[i].passwordIterations);
907                         logger(options, CRYPT_LOG_NORMAL, "\tSalt:               \t");
908                         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.keyblock[i].passwordSalt,LUKS_SALTSIZE/2);
909                         logger(options, CRYPT_LOG_NORMAL, "\n\t                      \t");
910                         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.keyblock[i].passwordSalt+LUKS_SALTSIZE/2,LUKS_SALTSIZE/2);
911                         logger(options, CRYPT_LOG_NORMAL, "\n");
912
913                         logger(options, CRYPT_LOG_NORMAL, "\tKey material offset:\t%d\n",hdr.keyblock[i].keyMaterialOffset);
914                         logger(options, CRYPT_LOG_NORMAL, "\tAF stripes:            \t%d\n",hdr.keyblock[i].stripes);
915                 }
916                 else 
917                         logger(options, CRYPT_LOG_NORMAL, "Key Slot %d: DISABLED\n",i);
918         }
919         return 0;
920 }
921
922
923 void crypt_get_error(char *buf, size_t size)
924 {
925         const char *error = get_error();
926
927         if (!buf || size < 1)
928                 set_error(NULL);
929         else if (error) {
930                 strncpy(buf, error, size - 1);
931                 buf[size - 1] = '\0';
932                 set_error(NULL);
933         } else
934                 buf[0] = '\0';
935 }
936
937 void crypt_put_options(struct crypt_options *options)
938 {
939         if (options->flags & CRYPT_FLAG_FREE_DEVICE) {
940                 free((char *)options->device);
941                 options->device = NULL;
942                 options->flags &= ~CRYPT_FLAG_FREE_DEVICE;
943         }
944         if (options->flags & CRYPT_FLAG_FREE_CIPHER) {
945                 free((char *)options->cipher);
946                 options->cipher = NULL;
947                 options->flags &= ~CRYPT_FLAG_FREE_CIPHER;
948         }
949 }
950
951 void crypt_set_default_backend(const char *backend)
952 {
953         if (default_backend)
954                 free(default_backend);
955         if (backend) 
956                 default_backend = strdup(backend);
957         else
958                 default_backend = NULL;
959 }
960
961 const char *crypt_get_dir(void)
962 {
963         struct setup_backend *backend;
964         const char *dir;
965
966         backend = get_setup_backend(default_backend);
967         if (!backend)
968                 return NULL;
969
970         dir = backend->dir();
971
972         put_setup_backend(backend);
973
974         return dir;
975 }
976
977 // Local Variables:
978 // c-basic-offset: 8
979 // indent-tabs-mode: nil
980 // End: