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