Remove precompiled pot files.
[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 wipe_device_header(const char *device, int sectors)
202 {
203         char *buffer;
204         int size = sectors * SECTOR_SIZE;
205         int r = -1;
206         int devfd;
207
208         devfd = open(device, O_RDWR | O_DIRECT | O_SYNC);
209         if(devfd == -1) {
210                 set_error("Can't wipe header on device %s", device);
211                 return -EINVAL;
212         }
213
214         buffer = malloc(size);
215         if (!buffer) {
216                 close(devfd);
217                 return -ENOMEM;
218         }
219         memset(buffer, 0, size);
220
221         r = write_blockwise(devfd, buffer, size) < size ? -EIO : 0;
222
223         free(buffer);
224         close(devfd);
225
226         return r;
227 }
228
229 static int parse_into_name_and_mode(const char *nameAndMode, char *name,
230                                     char *mode)
231 {
232 /* Token content stringification, see info cpp/stringification */
233 #define str(s) #s
234 #define xstr(s) str(s)
235 #define scanpattern1 "%" xstr(LUKS_CIPHERNAME_L) "[^-]-%" xstr(LUKS_CIPHERMODE_L)  "s"
236 #define scanpattern2 "%" xstr(LUKS_CIPHERNAME_L) "[^-]"
237
238         int r;
239
240         if(sscanf(nameAndMode,scanpattern1, name, mode) != 2) {
241                 if((r = sscanf(nameAndMode,scanpattern2,name)) == 1) {
242                         strncpy(mode,"cbc-plain",10);
243                 } 
244                 else {
245                         set_error("no known cipher-spec pattern detected");
246                         return -EINVAL;
247                 }
248         }
249
250         return 0;
251
252 #undef sp1
253 #undef sp2
254 #undef str
255 #undef xstr
256 }
257
258 /* Select free keyslot or verifies that the one specified is empty */
259 static int keyslot_from_option(int keySlotOption, struct luks_phdr *hdr) {
260         if(keySlotOption != -1) {
261                 if(keySlotOption >= LUKS_NUMKEYS) {
262                         set_error("slot %d too high, please pick between 0 and %d", keySlotOption, LUKS_NUMKEYS);
263                         return -EINVAL;
264                 } else if(hdr->keyblock[keySlotOption].active != LUKS_KEY_DISABLED) {
265                         set_error("slot %d full, please pick another one", keySlotOption);
266                         return -EINVAL;
267                 } else {
268                         return keySlotOption;
269                 }
270         } else {
271                 int i;
272                 /* Find empty key slot */
273                 for(i=0; i<LUKS_NUMKEYS; i++) {
274                         if(hdr->keyblock[i].active == LUKS_KEY_DISABLED) break;
275                 }
276                 if(i==LUKS_NUMKEYS) {
277                         set_error("All slots full");
278                         return -EINVAL;
279                 }
280                 return i;
281         }
282 }
283
284 static int __crypt_create_device(int reload, struct setup_backend *backend,
285                                  struct crypt_options *options)
286 {
287         struct crypt_options tmp = {
288                 .name = options->name,
289         };
290         struct device_infos infos;
291         char *key = NULL;
292         unsigned int keyLen;
293         char *processed_key = NULL;
294         int r;
295
296         r = backend->status(0, &tmp, NULL);
297         if (reload) {
298                 if (r < 0)
299                         return r;
300         } else {
301                 if (r >= 0) {
302                         set_error("Device already exists");
303                         return -EEXIST;
304                 }
305                 if (r != -ENODEV)
306                         return r;
307         }
308
309         if (options->key_size < 0 || options->key_size > 1024) {
310                 set_error("Invalid key size");
311                 return -EINVAL;
312         }
313
314         if (get_device_infos(options->device, &infos) < 0)
315                 return -ENOTBLK;
316
317         if (!options->size) {
318                 options->size = infos.size;
319                 if (!options->size) {
320                         set_error("Not a block device");
321                         return -ENOTBLK;
322                 }
323                 if (options->size <= options->offset) {
324                         set_error("Invalid offset");
325                         return -EINVAL;
326                 }
327                 options->size -= options->offset;
328         }
329
330         if (infos.readonly)
331                 options->flags |= CRYPT_FLAG_READONLY;
332
333         get_key("Enter passphrase: ", &key, &keyLen, options->key_size, options->key_file, options->passphrase_fd, options->timeout, options->flags);
334         if (!key) {
335                 set_error("Key reading error");
336                 return -ENOENT;
337         }
338         
339         processed_key = process_key(options,key,keyLen);
340         safe_free(key);
341         
342         if (!processed_key) {
343                 const char *error=get_error();
344                 if(error) {
345                         char *c_error_handling_sucks;
346                         asprintf(&c_error_handling_sucks,"Key processing error: %s",error);
347                         set_error(c_error_handling_sucks);
348                         free(c_error_handling_sucks);
349                 } else
350                         set_error("Key processing error");
351                 return -ENOENT;
352         }
353         
354         r = backend->create(reload, options, processed_key);
355         
356         safe_free(processed_key);
357
358         return r;
359 }
360
361 static int __crypt_query_device(int details, struct setup_backend *backend,
362                                 struct crypt_options *options)
363 {
364         int r = backend->status(details, options, NULL);
365         if (r == -ENODEV)
366                 return 0;
367         else if (r >= 0)
368                 return 1;
369         else
370                 return r;
371 }
372
373 static int __crypt_resize_device(int details, struct setup_backend *backend,
374                                 struct crypt_options *options)
375 {
376         struct crypt_options tmp = {
377                 .name = options->name,
378         };
379         struct device_infos infos;
380         char *key = NULL;
381         int r;
382
383         r = backend->status(1, &tmp, &key);
384         if (r < 0)
385                 return r;
386
387         if (get_device_infos(tmp.device, &infos) < 0)
388                 return -EINVAL;
389
390         if (!options->size) {
391                 options->size = infos.size;
392                 if (!options->size) {
393                         set_error("Not a block device");
394                         return -ENOTBLK;
395                 }
396                 if (options->size <= tmp.offset) {
397                         set_error("Invalid offset");
398                         return -EINVAL;
399                 }
400                 options->size -= tmp.offset;
401         }
402         tmp.size = options->size;
403
404         if (infos.readonly)
405                 options->flags |= CRYPT_FLAG_READONLY;
406
407         r = backend->create(1, &tmp, key);
408
409         safe_free(key);
410
411         return r;
412 }
413
414 static int __crypt_remove_device(int arg, struct setup_backend *backend,
415                                  struct crypt_options *options)
416 {
417         int r;
418
419         r = backend->status(0, options, NULL);
420         if (r < 0)
421                 return r;
422         if (r > 0) {
423                 set_error("Device busy");
424                 return -EBUSY;
425         }
426
427         return backend->remove(0, options);
428 }
429
430 static int __crypt_luks_format(int arg, struct setup_backend *backend, struct crypt_options *options)
431 {
432         int r;
433         
434         struct luks_phdr header;
435         struct luks_masterkey *mk=NULL;
436         char *password=NULL; 
437         char cipherName[LUKS_CIPHERNAME_L];
438         char cipherMode[LUKS_CIPHERMODE_L];
439         unsigned int passwordLen;
440         int PBKDF2perSecond;
441         int keyIndex;
442
443         if (!LUKS_device_ready(options->device, O_RDWR | O_EXCL)) {
444                 set_error("Can not access device");
445                 r = -ENOTBLK; goto out;
446         }
447
448         mk = LUKS_generate_masterkey(options->key_size);
449         if(NULL == mk) return -ENOMEM; // FIXME This may be misleading, since we don't know what went wrong
450
451 #ifdef LUKS_DEBUG
452 #define printoffset(entry) logger(options, CRYPT_LOG_ERROR, ("offset of " #entry " = %d\n", (char *)(&header.entry)-(char *)(&header))
453
454         logger(options, CRYPT_LOG_ERROR, "sizeof phdr %d, key slot %d\n",sizeof(struct luks_phdr),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) return r;
471
472         r = LUKS_generate_phdr(&header,mk,cipherName, cipherMode,LUKS_STRIPES, options->align_payload);
473         if(r < 0) {
474                 set_error("Can't generate phdr");
475                 return r; 
476         }
477
478         keyIndex = keyslot_from_option(options->key_slot, &header);
479
480         PBKDF2perSecond = LUKS_benchmarkt_iterations();
481         header.keyblock[keyIndex].passwordIterations = at_least_one(PBKDF2perSecond * ((float)options->iteration_time / 1000.0));
482 #ifdef LUKS_DEBUG
483         logger(options->icb->log,CRYPT_LOG_ERROR, "pitr %d\n", header.keyblock[0].passwordIterations);
484 #endif
485         get_key("Enter LUKS passphrase: ",&password,&passwordLen, 0, options->new_key_file, options->passphrase_fd, options->timeout, options->flags);
486         if(!password) {
487                 r = -EINVAL; goto out;
488         }
489
490         /* Wipe first 8 sectors - fs magic numbers etc. */
491         r = wipe_device_header(options->device, 8);
492         if(r < 0) goto out;
493
494         /* Set key, also writes phdr */
495         r = LUKS_set_key(options->device, keyIndex, password, passwordLen, &header, mk, backend);
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 static int __crypt_luks_open(int arg, struct setup_backend *backend, struct crypt_options *options)
506 {
507         struct luks_masterkey *mk=NULL;
508         struct luks_phdr hdr;
509         char *password;
510         unsigned int passwordLen;
511         struct device_infos infos;
512         struct crypt_options tmp = {
513                 .name = options->name,
514         };
515         char *dmCipherSpec;
516         int r, tries = options->tries;
517         int excl = (options->flags & CRYPT_FLAG_NON_EXCLUSIVE_ACCESS) ? 0 : O_EXCL ;
518
519         r = backend->status(0, &tmp, NULL);
520         if (r >= 0) {
521                 set_error("Device already exists");
522                 return -EEXIST;
523         }
524
525         if (!LUKS_device_ready(options->device, O_RDONLY | excl)) {
526                 set_error("Can not access device");
527                 return -ENOTBLK;
528         }
529
530         if (get_device_infos(options->device, &infos) < 0) {
531                 set_error("Can't get device information.\n");
532                 return -ENOTBLK;
533         }
534
535         if (infos.readonly)
536                 options->flags |= CRYPT_FLAG_READONLY;
537
538 start:
539         mk=NULL;
540
541         if(get_key("Enter LUKS passphrase: ",&password,&passwordLen, 0, options->key_file,  options->passphrase_fd, options->timeout, options->flags))
542                 tries--;
543         else
544                 tries = 0;
545
546         if(!password) {
547                 r = -EINVAL; goto out;
548         }
549
550         r = LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk, backend);
551         if (r == -EPERM)
552                 set_error("No key available with this passphrase.\n");
553         if (r < 0)
554                 goto out1;
555
556         logger(options, CRYPT_LOG_NORMAL,"key slot %d unlocked.\n", r);
557
558         
559         options->offset = hdr.payloadOffset;
560         asprintf(&dmCipherSpec, "%s-%s", hdr.cipherName, hdr.cipherMode);
561         if(!dmCipherSpec) {
562                 r = -ENOMEM;
563                 goto out2;
564         }
565         options->cipher = dmCipherSpec;
566         options->key_size = mk->keyLength;
567         options->skip = 0;
568
569         options->size = infos.size;
570         if (!options->size) {
571                 set_error("Not a block device.\n");
572                 r = -ENOTBLK; goto out2;
573         }
574         if (options->size <= options->offset) {
575                 set_error("Invalid offset");
576                 r = -EINVAL; goto out2;
577         }
578         options->size -= options->offset;
579         r = backend->create(0, options, mk->key);
580
581  out2:
582         free(dmCipherSpec);
583  out1:
584         safe_free(password);
585  out:
586         LUKS_dealloc_masterkey(mk);
587         if (r == -EPERM && tries > 0)
588                 goto start;
589
590         return r;
591 }
592
593 static int __crypt_luks_add_key(int arg, struct setup_backend *backend, struct crypt_options *options)
594 {
595         struct luks_masterkey *mk=NULL;
596         struct luks_phdr hdr;
597         char *password=NULL; unsigned int passwordLen;
598         unsigned int keyIndex;
599         const char *device = options->device;
600         int r;
601         
602         if (!LUKS_device_ready(options->device, O_RDWR)) {
603                 set_error("Can not access device");
604                 r = -ENOTBLK; goto out;
605         }
606
607         r = LUKS_read_phdr(device, &hdr);
608         if(r < 0) return r;
609
610
611         keyIndex = keyslot_from_option(options->key_slot, &hdr);
612
613         get_key("Enter any LUKS passphrase: ",
614                 &password,
615                 &passwordLen, 
616                 0,
617                 options->key_file, 
618                 options->passphrase_fd, 
619                 options->timeout, 
620                 options->flags & ~(CRYPT_FLAG_VERIFY | CRYPT_FLAG_VERIFY_IF_POSSIBLE));
621
622         if(!password) {
623                 r = -EINVAL; goto out;
624         }
625         r = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk, backend);
626         if(r < 0) {
627                 options->icb->log(CRYPT_LOG_ERROR,"No key available with this passphrase.\n");
628                 r = -EPERM; goto out;
629         } else
630                 logger(options, CRYPT_LOG_NORMAL,"key slot %d unlocked.\n", r);
631
632         safe_free(password);
633         
634         get_key("Enter new passphrase for key slot: ",
635                 &password,
636                 &passwordLen,
637                 0,
638                 options->new_key_file,
639                 options->passphrase_fd,
640                 options->timeout, 
641                 options->flags);
642         if(!password) {
643                 r = -EINVAL; goto out;
644         }
645
646         hdr.keyblock[keyIndex].passwordIterations = at_least_one(LUKS_benchmarkt_iterations() * ((float)options->iteration_time / 1000));
647
648         r = LUKS_set_key(device, keyIndex, password, passwordLen, &hdr, mk, backend);
649         if(r < 0) goto out;
650
651         r = 0;
652 out:
653         safe_free(password);
654         LUKS_dealloc_masterkey(mk);
655         return r;
656 }
657
658 static int luks_remove_helper(int arg, struct setup_backend *backend, struct crypt_options *options, int supply_it)
659 {
660         struct luks_masterkey *mk;
661         struct luks_phdr hdr;
662         char *password=NULL; 
663         unsigned int passwordLen;
664         const char *device = options->device;
665         int keyIndex;
666         int openedIndex;
667         int r;
668         if (!LUKS_device_ready(options->device, O_RDWR)) {
669             set_error("Can not access device");
670             r = -ENOTBLK; goto out;
671         }
672
673         if(supply_it) {
674             get_key("Enter LUKS passphrase to be deleted: ",&password,&passwordLen, 0, options->new_key_file, options->passphrase_fd, options->timeout, options->flags);
675             if(!password) {
676                     r = -EINVAL; goto out;
677             }
678             keyIndex = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk, backend);
679             if(keyIndex < 0) {
680                     options->icb->log(CRYPT_LOG_ERROR,"No remaining key available with this passphrase.\n");
681                     r = -EPERM; goto out;
682             } else
683                 logger(options, CRYPT_LOG_NORMAL,"key slot %d selected for deletion.\n", keyIndex);
684             safe_free(password);
685         } else {
686             keyIndex = options->key_slot;
687         }
688
689         if(LUKS_is_last_keyslot(options->device, keyIndex) && 
690            !(options->icb->yesDialog(_("This is the last keyslot. Device will become unusable after purging this key.")))) {
691                 r = -EINVAL;
692                 goto out;
693         } 
694
695         if(options->flags & CRYPT_FLAG_VERIFY_ON_DELKEY) {
696                 options->flags &= ~CRYPT_FLAG_VERIFY_ON_DELKEY;
697                 get_key("Enter any remaining LUKS passphrase: ",&password,&passwordLen, 0, options->key_file, options->passphrase_fd, options->timeout, options->flags);
698                 if(!password) {
699                         r = -EINVAL; goto out;
700                 }
701
702                 r = LUKS_read_phdr(device, &hdr);
703                 if(r < 0) { 
704                         options->icb->log(CRYPT_LOG_ERROR,"Failed to access device.\n");
705                         r = -EIO; goto out;
706                 }
707                 hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED;
708
709                 openedIndex = LUKS_open_any_key_with_hdr(device, password, passwordLen, &hdr, &mk, backend);
710                 /* Clean up */
711                 if (openedIndex >= 0) {
712                         LUKS_dealloc_masterkey(mk);
713                         mk = NULL;
714                 }
715                 if(openedIndex < 0) {
716                             options->icb->log(CRYPT_LOG_ERROR,"No remaining key available with this passphrase.\n");
717                             r = -EPERM; goto out;
718                 } else
719                         logger(options, CRYPT_LOG_NORMAL,"key slot %d verified.\n", openedIndex);
720         }
721         r = LUKS_del_key(device, keyIndex);
722         if(r < 0) goto out;
723
724         r = 0;
725 out:
726         safe_free(password);
727         return r;
728 }
729
730 static int __crypt_luks_kill_slot(int arg, struct setup_backend *backend, struct crypt_options *options) {
731         return luks_remove_helper(arg, backend, options, 0);
732 }
733
734 static int __crypt_luks_remove_key(int arg, struct setup_backend *backend, struct crypt_options *options) {
735         return luks_remove_helper(arg, backend, options, 1);
736 }
737
738
739 static int crypt_job(int (*job)(int arg, struct setup_backend *backend,
740                                 struct crypt_options *options),
741                      int arg, struct crypt_options *options)
742 {
743         struct setup_backend *backend;
744         int r;
745
746         backend = get_setup_backend(default_backend);
747
748         if (setup_enter(backend,options->icb->log) < 0) {
749                 r = -ENOSYS;
750                 goto out;
751         }
752
753         if (!backend) {
754                 set_error("No setup backend available");
755                 r = -ENOSYS;
756                 goto out;
757         }
758
759         r = job(arg, backend, options);
760 out:
761         setup_leave(backend);
762         if (backend)
763                 put_setup_backend(backend);
764
765         if (r >= 0)
766                 set_error(NULL);
767
768         return r;
769 }
770
771 int crypt_create_device(struct crypt_options *options)
772 {
773         return crypt_job(__crypt_create_device, 0, options);
774 }
775
776 int crypt_update_device(struct crypt_options *options)
777 {
778         return crypt_job(__crypt_create_device, 1, options);
779 }
780
781 int crypt_resize_device(struct crypt_options *options)
782 {
783         return crypt_job(__crypt_resize_device, 0, options);
784 }
785
786 int crypt_query_device(struct crypt_options *options)
787 {
788         return crypt_job(__crypt_query_device, 1, options);
789 }
790
791 int crypt_remove_device(struct crypt_options *options)
792 {
793         return crypt_job(__crypt_remove_device, 0, options);
794
795 }
796
797 int crypt_luksFormat(struct crypt_options *options)
798 {
799         return crypt_job(__crypt_luks_format, 0, options);
800 }
801
802 int crypt_luksOpen(struct crypt_options *options)
803 {
804         return crypt_job(__crypt_luks_open, 0, options);
805 }
806
807 int crypt_luksKillSlot(struct crypt_options *options)
808 {
809         return crypt_job(__crypt_luks_kill_slot, 0, options);
810 }
811
812 int crypt_luksRemoveKey(struct crypt_options *options)
813 {
814         return crypt_job(__crypt_luks_remove_key, 0, options);
815 }
816
817 int crypt_luksAddKey(struct crypt_options *options)
818 {
819         return crypt_job(__crypt_luks_add_key, 0, options);
820 }
821
822 int crypt_luksUUID(struct crypt_options *options)
823 {
824         struct luks_phdr hdr;
825         int r;
826
827         r = LUKS_read_phdr(options->device,&hdr);
828         if(r < 0) return r;
829
830         options->icb->log(CRYPT_LOG_NORMAL,hdr.uuid);
831         options->icb->log(CRYPT_LOG_NORMAL,"\n");
832         return 0;
833 }
834
835 int crypt_isLuks(struct crypt_options *options)
836 {
837         struct luks_phdr hdr;
838         return LUKS_read_phdr(options->device,&hdr);
839 }
840
841 int crypt_luksDump(struct crypt_options *options)
842 {
843         struct luks_phdr hdr;
844         int r,i;
845
846         r = LUKS_read_phdr(options->device,&hdr);
847         if(r < 0) return r;
848
849         logger(options, CRYPT_LOG_NORMAL, "LUKS header information for %s\n\n",options->device);
850         logger(options, CRYPT_LOG_NORMAL, "Version:       \t%d\n",hdr.version);
851         logger(options, CRYPT_LOG_NORMAL, "Cipher name:   \t%s\n",hdr.cipherName);
852         logger(options, CRYPT_LOG_NORMAL, "Cipher mode:   \t%s\n",hdr.cipherMode);
853         logger(options, CRYPT_LOG_NORMAL, "Hash spec:     \t%s\n",hdr.hashSpec);
854         logger(options, CRYPT_LOG_NORMAL, "Payload offset:\t%d\n",hdr.payloadOffset);
855         logger(options, CRYPT_LOG_NORMAL, "MK bits:       \t%d\n",hdr.keyBytes*8);
856         logger(options, CRYPT_LOG_NORMAL, "MK digest:     \t");
857         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.mkDigest,LUKS_DIGESTSIZE);
858         logger(options, CRYPT_LOG_NORMAL, "\n");
859         logger(options, CRYPT_LOG_NORMAL, "MK salt:       \t");
860         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.mkDigestSalt,LUKS_SALTSIZE/2);
861         logger(options, CRYPT_LOG_NORMAL, "\n               \t");
862         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.mkDigestSalt+LUKS_SALTSIZE/2,LUKS_SALTSIZE/2);
863         logger(options, CRYPT_LOG_NORMAL, "\n");
864         logger(options, CRYPT_LOG_NORMAL, "MK iterations: \t%d\n",hdr.mkDigestIterations);
865         logger(options, CRYPT_LOG_NORMAL, "UUID:          \t%s\n\n",hdr.uuid);
866         for(i=0;i<LUKS_NUMKEYS;i++) {
867                 if(hdr.keyblock[i].active == LUKS_KEY_ENABLED) {
868                         logger(options, CRYPT_LOG_NORMAL, "Key Slot %d: ENABLED\n",i);
869                         logger(options, CRYPT_LOG_NORMAL, "\tIterations:         \t%d\n",hdr.keyblock[i].passwordIterations);
870                         logger(options, CRYPT_LOG_NORMAL, "\tSalt:               \t");
871                         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.keyblock[i].passwordSalt,LUKS_SALTSIZE/2);
872                         logger(options, CRYPT_LOG_NORMAL, "\n\t                      \t");
873                         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.keyblock[i].passwordSalt+LUKS_SALTSIZE/2,LUKS_SALTSIZE/2);
874                         logger(options, CRYPT_LOG_NORMAL, "\n");
875
876                         logger(options, CRYPT_LOG_NORMAL, "\tKey material offset:\t%d\n",hdr.keyblock[i].keyMaterialOffset);
877                         logger(options, CRYPT_LOG_NORMAL, "\tAF stripes:            \t%d\n",hdr.keyblock[i].stripes);
878                 }               
879                 else 
880                         logger(options, CRYPT_LOG_NORMAL, "Key Slot %d: DISABLED\n",i);
881         }
882         return 0;
883 }
884
885
886 void crypt_get_error(char *buf, size_t size)
887 {
888         const char *error = get_error();
889
890         if (!buf || size < 1)
891                 set_error(NULL);
892         else if (error) {
893                 strncpy(buf, error, size - 1);
894                 buf[size - 1] = '\0';
895                 set_error(NULL);
896         } else
897                 buf[0] = '\0';
898 }
899
900 void crypt_put_options(struct crypt_options *options)
901 {
902         if (options->flags & CRYPT_FLAG_FREE_DEVICE) {
903                 free((char *)options->device);
904                 options->device = NULL;
905                 options->flags &= ~CRYPT_FLAG_FREE_DEVICE;
906         }
907         if (options->flags & CRYPT_FLAG_FREE_CIPHER) {
908                 free((char *)options->cipher);
909                 options->cipher = NULL;
910                 options->flags &= ~CRYPT_FLAG_FREE_CIPHER;
911         }
912 }
913
914 void crypt_set_default_backend(const char *backend)
915 {
916         if (default_backend)
917                 free(default_backend);
918         if (backend) 
919                 default_backend = strdup(backend);
920         else
921                 default_backend = NULL;
922 }
923
924 const char *crypt_get_dir(void)
925 {
926         struct setup_backend *backend;
927         const char *dir;
928
929         backend = get_setup_backend(default_backend);
930         if (!backend)
931                 return NULL;
932
933         dir = backend->dir();
934
935         put_setup_backend(backend);
936
937         return dir;
938 }
939
940 // Local Variables:
941 // c-basic-offset: 8
942 // indent-tabs-mode: nil
943 // End: