* Replace global options struct with separate parameters in helper functions.
[platform/upstream/cryptsetup.git] / lib / setup.c
1 #include <string.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <stdarg.h>
5 #include <fcntl.h>
6 #include <errno.h>
7
8 #include "libcryptsetup.h"
9 #include "luks.h"
10 #include "internal.h"
11
12 struct crypt_device {
13         /* callbacks definitions */
14         void (*log)(int class, const char *msg, void *usrptr);
15         void *log_usrptr;
16 };
17
18 /* Log helper */
19 static void (*_default_log)(int class, char *msg) = NULL;
20 static int _debug_level = 0;
21
22 void crypt_set_debug_level(int level)
23 {
24         _debug_level = level;
25 }
26
27 void set_default_log(void (*log)(int class, char *msg))
28 {
29         _default_log = log;
30 }
31
32 void logger(struct crypt_device *cd, int class, const char *file,
33             int line, const char *format, ...)
34 {
35         va_list argp;
36         char *target = NULL;
37
38         va_start(argp, format);
39
40         if (vasprintf(&target, format, argp) > 0) {
41                 if (class >= 0) {
42                         if (cd && cd->log)
43                                 cd->log(class, target, cd->log_usrptr);
44                         else if (_default_log)
45                                 _default_log(class, target);
46 #ifdef CRYPT_DEBUG
47                 } else if (_debug_level)
48                         printf("# %s:%d %s\n", file ?: "?", line, target);
49 #else
50                 } else if (_debug_level)
51                         printf("# %s\n", target);
52 #endif
53         }
54
55         va_end(argp);
56         free(target);
57 }
58
59 static void hexprintICB(struct crypt_device *cd, char *d, int n)
60 {
61         int i;
62         for(i = 0; i < n; i++)
63                 log_std(cd, "%02hhx ", (char)d[i]);
64 }
65
66 /*
67  * Password processing behaviour matrix of process_key
68  *
69  * from binary file: check if there is sufficently large key material
70  * interactive & from fd: hash if requested, otherwise crop or pad with '0'
71  */
72 static char *process_key(struct crypt_device *cd, const char *hash_name,
73                          const char *key_file, size_t key_size,
74                          const char *pass, size_t passLen)
75 {
76         char *key = safe_alloc(key_size);
77         memset(key, 0, key_size);
78
79         /* key is coming from binary file */
80         if (key_file && strcmp(key_file, "-")) {
81                 if(passLen < key_size) {
82                         log_err(cd, _("Cannot not read %d bytes from key file %s.\n"),
83                                 key_size, key_file);
84                         safe_free(key);
85                         return NULL;
86                 }
87                 memcpy(key, pass, key_size);
88                 return key;
89         }
90
91         /* key is coming from tty, fd or binary stdin */
92         if (hash_name) {
93                 if (hash(NULL, hash_name, key, key_size, pass, passLen) < 0) {
94                         log_err(cd, _("Key processing error.\n"));
95                         safe_free(key);
96                         return NULL;
97                 }
98         } else if (passLen > key_size) {
99                 memcpy(key, pass, key_size);
100         } else {
101                 memcpy(key, pass, passLen);
102         }
103
104         return key;
105 }
106
107 int parse_into_name_and_mode(const char *nameAndMode, char *name, char *mode)
108 {
109 /* Token content stringification, see info cpp/stringification */
110 #define str(s) #s
111 #define xstr(s) str(s)
112 #define scanpattern1 "%" xstr(LUKS_CIPHERNAME_L) "[^-]-%" xstr(LUKS_CIPHERMODE_L)  "s"
113 #define scanpattern2 "%" xstr(LUKS_CIPHERNAME_L) "[^-]"
114
115         int r;
116
117         if(sscanf(nameAndMode,scanpattern1, name, mode) != 2) {
118                 if((r = sscanf(nameAndMode,scanpattern2,name)) == 1)
119                         strncpy(mode,"cbc-plain",10);
120                 else
121                         return -EINVAL;
122         }
123
124         return 0;
125
126 #undef scanpattern1
127 #undef scanpattern2
128 #undef str
129 #undef xstr
130 }
131
132 /* keyslot helpers */
133 static int keyslot_is_valid(struct crypt_device *cd, int keySlotIndex)
134 {
135         if(keySlotIndex >= LUKS_NUMKEYS || keySlotIndex < 0) {
136                         log_err(cd, _("Key slot %d is invalid, please select between 0 and %d.\n"),
137                                 keySlotIndex, LUKS_NUMKEYS - 1);
138                 return 0;
139         }
140
141         return 1;
142 }
143
144 /* Select free keyslot or verifies that the one specified is empty */
145 static int keyslot_from_option(struct crypt_device *cd, int keySlotOption, struct luks_phdr *hdr) {
146         if(keySlotOption >= 0) {
147                 if(!keyslot_is_valid(cd, keySlotOption))
148                         return -EINVAL;
149                 else if(hdr->keyblock[keySlotOption].active != LUKS_KEY_DISABLED) {
150                         log_err(cd, _("Key slot %d is full, please select another one.\n"),
151                                 keySlotOption);
152                         return -EINVAL;
153                 } else {
154                         return keySlotOption;
155                 }
156         } else {
157                 int i;
158                 /* Find empty key slot */
159                 for(i=0; i<LUKS_NUMKEYS; i++) {
160                         if(hdr->keyblock[i].active == LUKS_KEY_DISABLED) break;
161                 }
162                 if(i==LUKS_NUMKEYS) {
163                         log_err(cd, _("All key slots full.\n"));
164                         return -EINVAL;
165                 }
166                 return i;
167         }
168 }
169
170 static int device_check_and_adjust(struct crypt_device *cd,
171                                    const char *device,
172                                    uint64_t *size, uint64_t *offset,
173                                    int *read_only)
174 {
175         struct device_infos infos;
176
177         if (get_device_infos(device, &infos, cd) < 0) {
178                 log_err(cd, _("Cannot get info about device %s.\n"), device);
179                 return -ENOTBLK;
180         }
181
182         if (!*size) {
183                 *size = infos.size;
184                 if (!*size) {
185                         log_err(cd, _("Device %s has zero size.\n"), device);
186                         return -ENOTBLK;
187                 }
188                 if (*size <= *offset) {
189                         log_err(cd, _("Device %s is too small.\n"), device);
190                         return -EINVAL;
191                 }
192                 *size -= *offset;
193         }
194
195         if (infos.readonly)
196                 *read_only = 1;
197
198         return 0;
199 }
200
201 static int create_device_helper(int reload, struct crypt_options *options)
202 {
203         struct crypt_device *cd = NULL;
204         char *key = NULL;
205         unsigned int keyLen;
206         char *processed_key = NULL;
207         int read_only;
208         int r;
209
210         r = dm_status_device(options->name);
211         if (reload) {
212                 if (r < 0)
213                         return r;
214         } else {
215                 if (r >= 0) {
216                         log_err(cd, _("Device %s already exists.\n"), options->name);
217                         return -EEXIST;
218                 }
219                 if (r != -ENODEV)
220                         return r;
221         }
222
223         if (options->key_size < 0 || options->key_size > 1024) {
224                 log_err(cd, _("Invalid key size %d.\n"), options->key_size);
225                 return -EINVAL;
226         }
227
228         read_only = (options->flags & CRYPT_FLAG_READONLY);
229         r = device_check_and_adjust(cd, options->device, &options->size, &options->offset, &read_only);
230         if (r)
231                 return r;
232
233         get_key("Enter passphrase: ", &key, &keyLen, options->key_size,
234                 options->key_file, options->timeout, options->flags, NULL);
235         if (!key) {
236                 log_err(cd, "Key reading error");
237                 return -ENOENT;
238         }
239
240         processed_key = process_key(cd, options->hash, options->key_file, options->key_size, key, keyLen);
241         safe_free(key);
242
243         if (!processed_key)
244                 return -ENOENT;
245
246         r = dm_create_device(options->name, options->device, options->cipher,
247                              NULL, options->size, options->skip, options->offset,
248                              options->key_size, processed_key,
249                              read_only, reload);
250
251         safe_free(processed_key);
252
253         return r;
254 }
255
256 static int luks_remove_helper(struct crypt_device *cd,
257                               struct crypt_options *options, int supply_it)
258 {
259         struct luks_masterkey *mk;
260         struct luks_phdr hdr;
261         char *password=NULL;
262         unsigned int passwordLen;
263         const char *device = options->device;
264         int keyIndex;
265         int openedIndex;
266         int r, last_slot;
267
268         r = LUKS_read_phdr(options->device, &hdr, 1, cd);
269         if(r < 0)
270                 return r;
271
272         if(supply_it) {
273                 get_key("Enter LUKS passphrase to be deleted: ",&password,&passwordLen, 0, options->new_key_file,
274                         options->timeout, options->flags, cd);
275                 if(!password) {
276                         r = -EINVAL; goto out;
277                 }
278
279                 keyIndex = LUKS_open_key_with_hdr(device, CRYPT_ANY_SLOT, password, passwordLen, &hdr, &mk, cd);
280                 if(keyIndex < 0) {
281                         log_err(cd, "No remaining key available with this passphrase.\n");
282                         r = -EPERM; goto out;
283                 } else
284                         log_std(cd ,"key slot %d selected for deletion.\n", keyIndex);
285
286                 safe_free(password);
287                 password = NULL;
288         } else {
289                 keyIndex = options->key_slot;
290                 if (!keyslot_is_valid(cd, keyIndex)) {
291                         r = -EINVAL; goto out;
292                 }
293         }
294
295         if (LUKS_keyslot_info(&hdr, keyIndex) == SLOT_INACTIVE) {
296                 log_err(cd, _("Key %d not active. Can't wipe.\n"), keyIndex);
297                 r = -EINVAL;
298                 goto out;
299         }
300
301         last_slot = (LUKS_keyslot_info(&hdr, keyIndex) == SLOT_ACTIVE_LAST);
302         if(last_slot && !(options->icb->yesDialog(_("This is the last keyslot. Device will become unusable after purging this key.")))) {
303                 r = -EINVAL; goto out;
304         }
305
306         if(options->flags & CRYPT_FLAG_VERIFY_ON_DELKEY) {
307                 options->flags &= ~CRYPT_FLAG_VERIFY_ON_DELKEY;
308                 get_key("Enter any remaining LUKS passphrase: ",&password,&passwordLen, 0, options->key_file,
309                         options->timeout, options->flags, cd);
310                 if(!password) {
311                         r = -EINVAL; goto out;
312                 }
313
314                 r = LUKS_read_phdr(device, &hdr, 1, cd);
315                 if(r < 0) {
316                         options->icb->log(CRYPT_LOG_ERROR,"Failed to access device.\n");
317                         r = -EIO; goto out;
318                 }
319
320                 if(!last_slot)
321                         hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED;
322
323                 openedIndex = LUKS_open_key_with_hdr(device, CRYPT_ANY_SLOT, password, passwordLen, &hdr, &mk, cd);
324                 /* Clean up */
325                 if (openedIndex >= 0) {
326                         LUKS_dealloc_masterkey(mk);
327                         mk = NULL;
328                 }
329                 if(openedIndex < 0) {
330                             log_err(cd, "No remaining key available with this passphrase.\n");
331                             r = -EPERM; goto out;
332                 } else
333                         log_std(cd, "key slot %d verified.\n", openedIndex);
334         }
335         r = LUKS_del_key(device, keyIndex, cd);
336         if(r < 0) goto out;
337
338         r = 0;
339 out:
340         safe_free(password);
341         return r;
342 }
343
344 /* OPTIONS: name, cipher, device, hash, key_file, key_size, key_slot,
345  *          offset, size, skip, timeout, tries, passphrase_fd (ignored),
346  *          flags, icb */
347 int crypt_create_device(struct crypt_options *options)
348 {
349         return create_device_helper(0, options);
350 }
351
352 /* OPTIONS: same as create above */
353 int crypt_update_device(struct crypt_options *options)
354 {
355         return create_device_helper(1, options);
356 }
357
358 /* OPTIONS: name, size, icb */
359 int crypt_resize_device(struct crypt_options *options)
360 {
361         struct crypt_device *cd = NULL;
362         char *device, *cipher, *key = NULL;
363         uint64_t size, skip, offset;
364         int key_size, read_only, r;
365
366         r = dm_query_device(options->name, &device, &size, &skip, &offset,
367                             &cipher, &key_size, &key, &read_only);
368         if (r < 0)
369                 return r;
370
371         size = options->size;
372         r = device_check_and_adjust(cd, device, &size, &offset, &read_only);
373         if (r)
374                 return r;
375
376         r = dm_create_device(options->name, device, cipher, NULL, size, skip, offset,
377                              key_size, key, read_only, 1);
378
379         safe_free(key);
380         free(cipher);
381         free(device);
382
383         return r;
384 }
385
386 /* OPTIONS: name, icb */
387 int crypt_query_device(struct crypt_options *options)
388 {
389         int read_only, r;
390
391         r = dm_status_device(options->name);
392         if (r == -ENODEV)
393                 return 0;
394
395         r = dm_query_device(options->name, (char **)&options->device, &options->size,
396                             &options->skip, &options->offset, (char **)&options->cipher,
397                             &options->key_size, NULL, &read_only);
398
399         if (r < 0)
400                 return r;
401
402         if (read_only)
403                 options->flags |= CRYPT_FLAG_READONLY;
404
405         options->flags |= CRYPT_FLAG_FREE_DEVICE;
406         options->flags |= CRYPT_FLAG_FREE_CIPHER;
407
408         return 1;
409 }
410
411 /* OPTIONS: name, icb */
412 int crypt_remove_device(struct crypt_options *options)
413 {
414         int r;
415
416         r = dm_status_device(options->name);
417         if (r < 0)
418                 return r;
419         if (r > 0) {
420                 log_err(NULL, "Device busy");
421                 return -EBUSY;
422         }
423
424         return dm_remove_device(options->name, 0, 0);
425 }
426
427 /* OPTIONS: device, cipher, hash, align_payload, key_size (master key), key_slot
428  *          new_key_file, iteration_time, timeout, flags, icb */
429 int crypt_luksFormat(struct crypt_options *options)
430 {
431         struct crypt_device *cd = NULL;
432         struct luks_phdr header;
433         struct luks_masterkey *mk=NULL;
434         char *password=NULL; 
435         char cipherName[LUKS_CIPHERNAME_L];
436         char cipherMode[LUKS_CIPHERMODE_L];
437         unsigned int passwordLen;
438         uint64_t PBKDF2perSecond = 0;
439         int r, keyIndex;
440
441         if (!device_ready(cd, options->device, O_RDWR | O_EXCL))
442                 return -ENOTBLK;
443
444         mk = LUKS_generate_masterkey(options->key_size);
445         if(NULL == mk) return -ENOMEM; // FIXME This may be misleading, since we don't know what went wrong
446
447 #ifdef LUKS_DEBUG
448 #define printoffset(entry) \
449         logger(options, CRYPT_LOG_ERROR, \
450                 "offset of " #entry " = %d\n", (char *)(&header.entry)-(char *)(&header))
451
452         log_err("sizeof phdr %d, sizeof key slot %d\n",
453                 sizeof(struct luks_phdr),
454                 sizeof(header.keyblock[0]));
455
456         printoffset(magic);
457         printoffset(version);
458         printoffset(cipherName);
459         printoffset(cipherMode);
460         printoffset(hashSpec);
461         printoffset(payloadOffset);
462         printoffset(keyBytes);
463         printoffset(mkDigest);
464         printoffset(mkDigestSalt);
465         printoffset(mkDigestIterations);
466         printoffset(uuid);
467 #endif
468
469         r = parse_into_name_and_mode(options->cipher, cipherName, cipherMode);
470         if(r < 0) {
471                 log_err(cd, _("No known cipher specification pattern detected.\n"));
472                 return r;
473         }
474
475         r = LUKS_generate_phdr(&header, mk, cipherName, cipherMode, options->hash, NULL, LUKS_STRIPES, options->align_payload, NULL);
476         if(r < 0) return r;
477
478         keyIndex = keyslot_from_option(NULL, options->key_slot, &header);
479         if(keyIndex == -EINVAL) {
480                 r = -EINVAL; goto out;
481         }
482
483         get_key("Enter LUKS passphrase: ",&password,&passwordLen, 0, options->new_key_file,
484                 options->timeout, options->flags, NULL);
485         if(!password) {
486                 r = -EINVAL; goto out;
487         }
488
489         /* Wipe first 8 sectors - fs magic numbers etc. */
490         r = wipe_device_header(options->device, 8);
491         if(r < 0) goto out;
492
493         /* Set key, also writes phdr */
494         r = LUKS_set_key(options->device, keyIndex, password, passwordLen, &header, mk,
495                          options->iteration_time, &PBKDF2perSecond, NULL);
496         if(r < 0) goto out; 
497
498         r = 0;
499 out:
500         LUKS_dealloc_masterkey(mk);
501         safe_free(password);
502         return r;
503 }
504
505 /* OPTIONS: name, device, key_size, key_file, timeout, tries, flags, icb */
506 int crypt_luksOpen(struct crypt_options *options)
507 {
508         struct crypt_device *cd = NULL;
509         struct luks_masterkey *mk=NULL;
510         struct luks_phdr hdr;
511         char *prompt = NULL;
512         char *password;
513         unsigned int passwordLen;
514         char *dmCipherSpec = NULL;
515         int read_only;
516         int r, tries = options->tries;
517         int excl = (options->flags & CRYPT_FLAG_NON_EXCLUSIVE_ACCESS) ? 0 : O_EXCL ;
518
519         r = dm_status_device(options->name);
520         if (r >= 0) {
521                 log_err(cd, "Device %s already exists.", options->name);
522                 return -EEXIST;
523         }
524
525         if (!device_ready(cd, options->device, O_RDONLY | excl))
526                 return -ENOTBLK;
527
528         if(asprintf(&prompt, "Enter LUKS passphrase for %s: ", options->device) < 0)
529                 return -ENOMEM;
530
531 start:
532         mk=NULL;
533
534         if(options->passphrase) {
535                 passwordLen = strlen(options->passphrase);
536                 password = safe_alloc(passwordLen + 1);
537                 strncpy(password, options->passphrase, passwordLen + 1);
538                 tries = 0;
539         } else {
540                 get_key(prompt, &password, &passwordLen, options->key_size, options->key_file,
541                         options->timeout, options->flags, cd);
542                 if (password)
543                         tries--;
544                 else
545                         tries = 0;
546         }
547
548         if(!password) {
549                 r = -EINVAL; goto out;
550         }
551
552         r = LUKS_read_phdr(options->device, &hdr, 1, cd);
553         if(r < 0)
554                 return r;
555
556         r = LUKS_open_key_with_hdr(options->device, CRYPT_ANY_SLOT, password, passwordLen, &hdr, &mk, cd);
557         if (r == -EPERM)
558                 log_err(cd, "No key available with this passphrase.\n");
559         if (r < 0)
560                 goto out1;
561
562         log_err(NULL, "key slot %d unlocked.\n", r);
563
564
565         options->offset = hdr.payloadOffset;
566         if (asprintf(&dmCipherSpec, "%s-%s", hdr.cipherName, hdr.cipherMode) < 0) {
567                 r = -ENOMEM;
568                 goto out2;
569         }
570         options->cipher = dmCipherSpec;
571         options->key_size = mk->keyLength;
572         options->skip = 0;
573         options->size = 0;
574
575         read_only = (options->flags & CRYPT_FLAG_READONLY);
576         r = device_check_and_adjust(cd, options->device, &options->size, &options->offset, &read_only);
577         if (r)
578                 return r;
579
580         /* FIXME: code allows multiple crypt mapping, cannot use uuid then.
581          * anyway, it is dangerous and can corrupt data. Remove it in next version! */
582         r = dm_create_device(options->name, options->device, options->cipher,
583                              excl ? hdr.uuid : NULL, options->size,
584                              0, options->offset, mk->keyLength, mk->key,
585                              options->flags & CRYPT_FLAG_READONLY, 0);
586
587  out2:
588         free(dmCipherSpec);
589         dmCipherSpec = NULL;
590  out1:
591         safe_free(password);
592  out:
593         LUKS_dealloc_masterkey(mk);
594         if (r == -EPERM && tries > 0)
595                 goto start;
596
597         free(prompt);
598
599         return r;
600 }
601
602 /* OPTIONS: device, keys_slot, key_file, timeout, flags, icb */
603 int crypt_luksKillSlot(struct crypt_options *options)
604 {
605         return luks_remove_helper(NULL, options, 0);
606 }
607
608 /* OPTIONS: device, new_key_file, key_file, timeout, flags, icb */
609 int crypt_luksRemoveKey(struct crypt_options *options)
610 {
611         return luks_remove_helper(NULL, options, 1);
612 }
613
614 /* OPTIONS: device, new_key_file, key_file, key_slot, flags,
615             iteration_time, timeout, icb */
616 int crypt_luksAddKey(struct crypt_options *options)
617 {
618         struct crypt_device *cd = NULL;
619         struct luks_masterkey *mk=NULL;
620         struct luks_phdr hdr;
621         char *password=NULL; unsigned int passwordLen;
622         unsigned int keyIndex;
623         uint64_t PBKDF2perSecond = 0;
624         const char *device = options->device;
625         int r;
626
627         if (!device_ready(cd, options->device, O_RDWR))
628                 return -ENOTBLK;
629
630         r = LUKS_read_phdr(device, &hdr, 1, cd);
631         if(r < 0) return r;
632
633
634         keyIndex = keyslot_from_option(cd, options->key_slot, &hdr);
635         if(keyIndex == -EINVAL) {
636                 r = -EINVAL; goto out;
637         }
638
639         get_key("Enter any LUKS passphrase: ",
640                 &password,
641                 &passwordLen, 
642                 0,
643                 options->key_file, 
644                 options->timeout, 
645                 options->flags & ~(CRYPT_FLAG_VERIFY | CRYPT_FLAG_VERIFY_IF_POSSIBLE), cd);
646
647         if(!password) {
648                 r = -EINVAL; goto out;
649         }
650         r = LUKS_open_key_with_hdr(device, CRYPT_ANY_SLOT, password, passwordLen, &hdr, &mk, cd);
651         if(r < 0) {
652                 options->icb->log(CRYPT_LOG_ERROR,"No key available with this passphrase.\n");
653                 r = -EPERM; goto out;
654         }
655         safe_free(password);
656
657         get_key("Enter new passphrase for key slot: ",
658                 &password,
659                 &passwordLen,
660                 0,
661                 options->new_key_file,
662                 options->timeout, 
663                 options->flags, cd);
664         if(!password) {
665                 r = -EINVAL; goto out;
666         }
667
668         r = LUKS_set_key(device, keyIndex, password, passwordLen, &hdr, mk, options->iteration_time, &PBKDF2perSecond, cd);
669         if(r < 0) goto out;
670
671         r = 0;
672 out:
673         safe_free(password);
674         LUKS_dealloc_masterkey(mk);
675         return r;
676 }
677
678 /* OPTIONS: device, icb */
679 int crypt_luksUUID(struct crypt_options *options)
680 {
681         struct crypt_device *cd = NULL;
682         struct luks_phdr hdr;
683         int r;
684
685         r = LUKS_read_phdr(options->device, &hdr, 1, cd);
686         if(r < 0) return r;
687
688         options->icb->log(CRYPT_LOG_NORMAL,hdr.uuid);
689         options->icb->log(CRYPT_LOG_NORMAL,"\n");
690         return 0;
691 }
692
693 /* OPTIONS: device, icb */
694 int crypt_isLuks(struct crypt_options *options)
695 {
696         struct crypt_device *cd = NULL;
697         struct luks_phdr hdr;
698         return LUKS_read_phdr(options->device, &hdr, 0, cd);
699 }
700
701 /* OPTIONS: device, icb */
702 int crypt_luksDump(struct crypt_options *options)
703 {
704         struct crypt_device *cd = NULL;
705         struct luks_phdr hdr;
706         int r,i;
707
708         r = LUKS_read_phdr(options->device, &hdr, 1, cd);
709         if(r < 0) return r;
710
711         log_std(cd, "LUKS header information for %s\n\n", options->device);
712         log_std(cd, "Version:       \t%d\n", hdr.version);
713         log_std(cd, "Cipher name:   \t%s\n", hdr.cipherName);
714         log_std(cd, "Cipher mode:   \t%s\n", hdr.cipherMode);
715         log_std(cd, "Hash spec:     \t%s\n", hdr.hashSpec);
716         log_std(cd, "Payload offset:\t%d\n", hdr.payloadOffset);
717         log_std(cd, "MK bits:       \t%d\n", hdr.keyBytes * 8);
718         log_std(cd, "MK digest:     \t");
719         hexprintICB(cd, hdr.mkDigest, LUKS_DIGESTSIZE);
720         log_std(cd, "\n");
721         log_std(cd, "MK salt:       \t");
722         hexprintICB(cd, hdr.mkDigestSalt, LUKS_SALTSIZE/2);
723         log_std(cd, "\n               \t");
724         hexprintICB(cd, hdr.mkDigestSalt+LUKS_SALTSIZE/2, LUKS_SALTSIZE/2);
725         log_std(cd, "\n");
726         log_std(cd, "MK iterations: \t%d\n", hdr.mkDigestIterations);
727         log_std(cd, "UUID:          \t%s\n\n", hdr.uuid);
728         for(i = 0; i < LUKS_NUMKEYS; i++) {
729                 if(hdr.keyblock[i].active == LUKS_KEY_ENABLED) {
730                         log_std(cd, "Key Slot %d: ENABLED\n",i);
731                         log_std(cd, "\tIterations:         \t%d\n",
732                                 hdr.keyblock[i].passwordIterations);
733                         log_std(cd, "\tSalt:               \t");
734                         hexprintICB(cd, hdr.keyblock[i].passwordSalt,
735                                     LUKS_SALTSIZE/2);
736                         log_std(cd, "\n\t                      \t");
737                         hexprintICB(cd, hdr.keyblock[i].passwordSalt +
738                                     LUKS_SALTSIZE/2, LUKS_SALTSIZE/2);
739                         log_std(cd, "\n");
740
741                         log_std(cd, "\tKey material offset:\t%d\n",
742                                 hdr.keyblock[i].keyMaterialOffset);
743                         log_std(cd, "\tAF stripes:            \t%d\n",
744                                 hdr.keyblock[i].stripes);
745                 }
746                 else 
747                         log_std(cd, "Key Slot %d: DISABLED\n", i);
748         }
749         return 0;
750 }
751
752 void crypt_get_error(char *buf, size_t size)
753 {
754         const char *error = get_error();
755
756         if (!buf || size < 1)
757                 set_error(NULL);
758         else if (error) {
759                 strncpy(buf, error, size - 1);
760                 buf[size - 1] = '\0';
761                 set_error(NULL);
762         } else
763                 buf[0] = '\0';
764 }
765
766 void crypt_put_options(struct crypt_options *options)
767 {
768         if (options->flags & CRYPT_FLAG_FREE_DEVICE) {
769                 free((char *)options->device);
770                 options->device = NULL;
771                 options->flags &= ~CRYPT_FLAG_FREE_DEVICE;
772         }
773         if (options->flags & CRYPT_FLAG_FREE_CIPHER) {
774                 free((char *)options->cipher);
775                 options->cipher = NULL;
776                 options->flags &= ~CRYPT_FLAG_FREE_CIPHER;
777         }
778 }
779
780 const char *crypt_get_dir(void)
781 {
782         return dm_get_dir();
783 }