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