Use better error messages if device doesn't exist
[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, struct crypt_options *options) {
260         if(keySlotOption >= 0) {
261                 if(keySlotOption >= LUKS_NUMKEYS) {
262                         logger(options,CRYPT_LOG_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                         logger(options,CRYPT_LOG_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                         logger(options,CRYPT_LOG_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 %s already exists.", options->name);
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                 return -ENOTBLK;
445
446         mk = LUKS_generate_masterkey(options->key_size);
447         if(NULL == mk) return -ENOMEM; // FIXME This may be misleading, since we don't know what went wrong
448
449 #ifdef LUKS_DEBUG
450 #define printoffset(entry) logger(options, CRYPT_LOG_ERROR, ("offset of " #entry " = %d\n", (char *)(&header.entry)-(char *)(&header))
451
452         logger(options, CRYPT_LOG_ERROR, "sizeof phdr %d, key slot %d\n",sizeof(struct luks_phdr),sizeof(header.keyblock[0]));
453
454         printoffset(magic);
455         printoffset(version);
456         printoffset(cipherName);
457         printoffset(cipherMode);
458         printoffset(hashSpec);
459         printoffset(payloadOffset);
460         printoffset(keyBytes);
461         printoffset(mkDigest);
462         printoffset(mkDigestSalt);
463         printoffset(mkDigestIterations);
464         printoffset(uuid);
465 #endif
466
467         r = parse_into_name_and_mode(options->cipher, cipherName, cipherMode);
468         if(r < 0) return r;
469
470         r = LUKS_generate_phdr(&header,mk,cipherName, cipherMode,LUKS_STRIPES, options->align_payload);
471         if(r < 0) {
472                 set_error("Can't generate phdr");
473                 return r; 
474         }
475
476         keyIndex = keyslot_from_option(options->key_slot, &header, options);
477         if(keyIndex == -EINVAL) {
478                 r = -EINVAL; goto out;
479         }
480
481         PBKDF2perSecond = LUKS_benchmarkt_iterations();
482         header.keyblock[keyIndex].passwordIterations = at_least_one(PBKDF2perSecond * ((float)options->iteration_time / 1000.0));
483 #ifdef LUKS_DEBUG
484         logger(options->icb->log,CRYPT_LOG_ERROR, "pitr %d\n", header.keyblock[0].passwordIterations);
485 #endif
486         get_key("Enter LUKS passphrase: ",&password,&passwordLen, 0, options->new_key_file, options->passphrase_fd, options->timeout, options->flags);
487         if(!password) {
488                 r = -EINVAL; goto out;
489         }
490
491         /* Wipe first 8 sectors - fs magic numbers etc. */
492         r = wipe_device_header(options->device, 8);
493         if(r < 0) goto out;
494
495         /* Set key, also writes phdr */
496         r = LUKS_set_key(options->device, keyIndex, password, passwordLen, &header, mk, backend);
497         if(r < 0) goto out; 
498
499         r = 0;
500 out:
501         LUKS_dealloc_masterkey(mk);
502         safe_free(password);
503         return r;
504 }
505
506 static int __crypt_luks_open(int arg, struct setup_backend *backend, struct crypt_options *options)
507 {
508         struct luks_masterkey *mk=NULL;
509         struct luks_phdr hdr;
510         char *password;
511         unsigned int passwordLen;
512         struct device_infos infos;
513         struct crypt_options tmp = {
514                 .name = options->name,
515         };
516         char *dmCipherSpec;
517         int r, tries = options->tries;
518         int excl = (options->flags & CRYPT_FLAG_NON_EXCLUSIVE_ACCESS) ? 0 : O_EXCL ;
519
520         r = backend->status(0, &tmp, NULL);
521         if (r >= 0) {
522                 set_error("Device %s already exists.", options->name);
523                 return -EEXIST;
524         }
525
526         if (!LUKS_device_ready(options->device, O_RDONLY | excl))
527                 return -ENOTBLK;
528
529         if (get_device_infos(options->device, &infos) < 0) {
530                 set_error("Can't get device information.\n");
531                 return -ENOTBLK;
532         }
533
534         if (infos.readonly)
535                 options->flags |= CRYPT_FLAG_READONLY;
536
537 start:
538         mk=NULL;
539
540         if(get_key("Enter LUKS passphrase: ",&password,&passwordLen, 0, options->key_file,  options->passphrase_fd, options->timeout, options->flags))
541                 tries--;
542         else
543                 tries = 0;
544
545         if(!password) {
546                 r = -EINVAL; goto out;
547         }
548
549         r = LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk, backend);
550         if (r == -EPERM)
551                 set_error("No key available with this passphrase.\n");
552         if (r < 0)
553                 goto out1;
554
555         logger(options, CRYPT_LOG_NORMAL,"key slot %d unlocked.\n", r);
556
557         
558         options->offset = hdr.payloadOffset;
559         asprintf(&dmCipherSpec, "%s-%s", hdr.cipherName, hdr.cipherMode);
560         if(!dmCipherSpec) {
561                 r = -ENOMEM;
562                 goto out2;
563         }
564         options->cipher = dmCipherSpec;
565         options->key_size = mk->keyLength;
566         options->skip = 0;
567
568         options->size = infos.size;
569         if (!options->size) {
570                 set_error("Not a block device.\n");
571                 r = -ENOTBLK; goto out2;
572         }
573         if (options->size <= options->offset) {
574                 set_error("Invalid offset");
575                 r = -EINVAL; goto out2;
576         }
577         options->size -= options->offset;
578         r = backend->create(0, options, mk->key);
579
580  out2:
581         free(dmCipherSpec);
582  out1:
583         safe_free(password);
584  out:
585         LUKS_dealloc_masterkey(mk);
586         if (r == -EPERM && tries > 0)
587                 goto start;
588
589         return r;
590 }
591
592 static int __crypt_luks_add_key(int arg, struct setup_backend *backend, struct crypt_options *options)
593 {
594         struct luks_masterkey *mk=NULL;
595         struct luks_phdr hdr;
596         char *password=NULL; unsigned int passwordLen;
597         unsigned int keyIndex;
598         const char *device = options->device;
599         int r;
600
601         if (!LUKS_device_ready(options->device, O_RDWR))
602                 return -ENOTBLK;
603
604         r = LUKS_read_phdr(device, &hdr);
605         if(r < 0) return r;
606
607
608         keyIndex = keyslot_from_option(options->key_slot, &hdr, options);
609         if(keyIndex == -EINVAL) {
610                 r = -EINVAL; goto out;
611         }
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
669         if (!LUKS_device_ready(options->device, O_RDWR))
670             return -ENOTBLK;
671
672         if(supply_it) {
673             get_key("Enter LUKS passphrase to be deleted: ",&password,&passwordLen, 0, options->new_key_file, options->passphrase_fd, options->timeout, options->flags);
674             if(!password) {
675                     r = -EINVAL; goto out;
676             }
677             keyIndex = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk, backend);
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             safe_free(password);
684         } else {
685             keyIndex = options->key_slot;
686         }
687
688         if(LUKS_is_last_keyslot(options->device, keyIndex) && 
689            !(options->icb->yesDialog(_("This is the last keyslot. Device will become unusable after purging this key.")))) {
690                 r = -EINVAL;
691                 goto out;
692         } 
693
694         if(options->flags & CRYPT_FLAG_VERIFY_ON_DELKEY) {
695                 options->flags &= ~CRYPT_FLAG_VERIFY_ON_DELKEY;
696                 get_key("Enter any remaining LUKS passphrase: ",&password,&passwordLen, 0, options->key_file, options->passphrase_fd, options->timeout, options->flags);
697                 if(!password) {
698                         r = -EINVAL; goto out;
699                 }
700
701                 r = LUKS_read_phdr(device, &hdr);
702                 if(r < 0) { 
703                         options->icb->log(CRYPT_LOG_ERROR,"Failed to access device.\n");
704                         r = -EIO; goto out;
705                 }
706                 hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED;
707
708                 openedIndex = LUKS_open_any_key_with_hdr(device, password, passwordLen, &hdr, &mk, backend);
709                 /* Clean up */
710                 if (openedIndex >= 0) {
711                         LUKS_dealloc_masterkey(mk);
712                         mk = NULL;
713                 }
714                 if(openedIndex < 0) {
715                             options->icb->log(CRYPT_LOG_ERROR,"No remaining key available with this passphrase.\n");
716                             r = -EPERM; goto out;
717                 } else
718                         logger(options, CRYPT_LOG_NORMAL,"key slot %d verified.\n", openedIndex);
719         }
720         r = LUKS_del_key(device, keyIndex);
721         if(r < 0) goto out;
722
723         r = 0;
724 out:
725         safe_free(password);
726         return r;
727 }
728
729 static int __crypt_luks_kill_slot(int arg, struct setup_backend *backend, struct crypt_options *options) {
730         return luks_remove_helper(arg, backend, options, 0);
731 }
732
733 static int __crypt_luks_remove_key(int arg, struct setup_backend *backend, struct crypt_options *options) {
734         return luks_remove_helper(arg, backend, options, 1);
735 }
736
737
738 static int crypt_job(int (*job)(int arg, struct setup_backend *backend,
739                                 struct crypt_options *options),
740                      int arg, struct crypt_options *options)
741 {
742         struct setup_backend *backend;
743         int r;
744
745         backend = get_setup_backend(default_backend);
746
747         if (setup_enter(backend,options->icb->log) < 0) {
748                 r = -ENOSYS;
749                 goto out;
750         }
751
752         if (!backend) {
753                 set_error("No setup backend available");
754                 r = -ENOSYS;
755                 goto out;
756         }
757
758         r = job(arg, backend, options);
759 out:
760         setup_leave(backend);
761         if (backend)
762                 put_setup_backend(backend);
763
764         if (r >= 0)
765                 set_error(NULL);
766
767         return r;
768 }
769
770 int crypt_create_device(struct crypt_options *options)
771 {
772         return crypt_job(__crypt_create_device, 0, options);
773 }
774
775 int crypt_update_device(struct crypt_options *options)
776 {
777         return crypt_job(__crypt_create_device, 1, options);
778 }
779
780 int crypt_resize_device(struct crypt_options *options)
781 {
782         return crypt_job(__crypt_resize_device, 0, options);
783 }
784
785 int crypt_query_device(struct crypt_options *options)
786 {
787         return crypt_job(__crypt_query_device, 1, options);
788 }
789
790 int crypt_remove_device(struct crypt_options *options)
791 {
792         return crypt_job(__crypt_remove_device, 0, options);
793
794 }
795
796 int crypt_luksFormat(struct crypt_options *options)
797 {
798         return crypt_job(__crypt_luks_format, 0, options);
799 }
800
801 int crypt_luksOpen(struct crypt_options *options)
802 {
803         return crypt_job(__crypt_luks_open, 0, options);
804 }
805
806 int crypt_luksKillSlot(struct crypt_options *options)
807 {
808         return crypt_job(__crypt_luks_kill_slot, 0, options);
809 }
810
811 int crypt_luksRemoveKey(struct crypt_options *options)
812 {
813         return crypt_job(__crypt_luks_remove_key, 0, options);
814 }
815
816 int crypt_luksAddKey(struct crypt_options *options)
817 {
818         return crypt_job(__crypt_luks_add_key, 0, options);
819 }
820
821 int crypt_luksUUID(struct crypt_options *options)
822 {
823         struct luks_phdr hdr;
824         int r;
825
826         r = LUKS_read_phdr(options->device,&hdr);
827         if(r < 0) return r;
828
829         options->icb->log(CRYPT_LOG_NORMAL,hdr.uuid);
830         options->icb->log(CRYPT_LOG_NORMAL,"\n");
831         return 0;
832 }
833
834 int crypt_isLuks(struct crypt_options *options)
835 {
836         struct luks_phdr hdr;
837         return LUKS_read_phdr(options->device,&hdr);
838 }
839
840 int crypt_luksDump(struct crypt_options *options)
841 {
842         struct luks_phdr hdr;
843         int r,i;
844
845         r = LUKS_read_phdr(options->device,&hdr);
846         if(r < 0) return r;
847
848         logger(options, CRYPT_LOG_NORMAL, "LUKS header information for %s\n\n",options->device);
849         logger(options, CRYPT_LOG_NORMAL, "Version:       \t%d\n",hdr.version);
850         logger(options, CRYPT_LOG_NORMAL, "Cipher name:   \t%s\n",hdr.cipherName);
851         logger(options, CRYPT_LOG_NORMAL, "Cipher mode:   \t%s\n",hdr.cipherMode);
852         logger(options, CRYPT_LOG_NORMAL, "Hash spec:     \t%s\n",hdr.hashSpec);
853         logger(options, CRYPT_LOG_NORMAL, "Payload offset:\t%d\n",hdr.payloadOffset);
854         logger(options, CRYPT_LOG_NORMAL, "MK bits:       \t%d\n",hdr.keyBytes*8);
855         logger(options, CRYPT_LOG_NORMAL, "MK digest:     \t");
856         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.mkDigest,LUKS_DIGESTSIZE);
857         logger(options, CRYPT_LOG_NORMAL, "\n");
858         logger(options, CRYPT_LOG_NORMAL, "MK salt:       \t");
859         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.mkDigestSalt,LUKS_SALTSIZE/2);
860         logger(options, CRYPT_LOG_NORMAL, "\n               \t");
861         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.mkDigestSalt+LUKS_SALTSIZE/2,LUKS_SALTSIZE/2);
862         logger(options, CRYPT_LOG_NORMAL, "\n");
863         logger(options, CRYPT_LOG_NORMAL, "MK iterations: \t%d\n",hdr.mkDigestIterations);
864         logger(options, CRYPT_LOG_NORMAL, "UUID:          \t%s\n\n",hdr.uuid);
865         for(i=0;i<LUKS_NUMKEYS;i++) {
866                 if(hdr.keyblock[i].active == LUKS_KEY_ENABLED) {
867                         logger(options, CRYPT_LOG_NORMAL, "Key Slot %d: ENABLED\n",i);
868                         logger(options, CRYPT_LOG_NORMAL, "\tIterations:         \t%d\n",hdr.keyblock[i].passwordIterations);
869                         logger(options, CRYPT_LOG_NORMAL, "\tSalt:               \t");
870                         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.keyblock[i].passwordSalt,LUKS_SALTSIZE/2);
871                         logger(options, CRYPT_LOG_NORMAL, "\n\t                      \t");
872                         hexprintICB(options, CRYPT_LOG_NORMAL, hdr.keyblock[i].passwordSalt+LUKS_SALTSIZE/2,LUKS_SALTSIZE/2);
873                         logger(options, CRYPT_LOG_NORMAL, "\n");
874
875                         logger(options, CRYPT_LOG_NORMAL, "\tKey material offset:\t%d\n",hdr.keyblock[i].keyMaterialOffset);
876                         logger(options, CRYPT_LOG_NORMAL, "\tAF stripes:            \t%d\n",hdr.keyblock[i].stripes);
877                 }               
878                 else 
879                         logger(options, CRYPT_LOG_NORMAL, "Key Slot %d: DISABLED\n",i);
880         }
881         return 0;
882 }
883
884
885 void crypt_get_error(char *buf, size_t size)
886 {
887         const char *error = get_error();
888
889         if (!buf || size < 1)
890                 set_error(NULL);
891         else if (error) {
892                 strncpy(buf, error, size - 1);
893                 buf[size - 1] = '\0';
894                 set_error(NULL);
895         } else
896                 buf[0] = '\0';
897 }
898
899 void crypt_put_options(struct crypt_options *options)
900 {
901         if (options->flags & CRYPT_FLAG_FREE_DEVICE) {
902                 free((char *)options->device);
903                 options->device = NULL;
904                 options->flags &= ~CRYPT_FLAG_FREE_DEVICE;
905         }
906         if (options->flags & CRYPT_FLAG_FREE_CIPHER) {
907                 free((char *)options->cipher);
908                 options->cipher = NULL;
909                 options->flags &= ~CRYPT_FLAG_FREE_CIPHER;
910         }
911 }
912
913 void crypt_set_default_backend(const char *backend)
914 {
915         if (default_backend)
916                 free(default_backend);
917         if (backend) 
918                 default_backend = strdup(backend);
919         else
920                 default_backend = NULL;
921 }
922
923 const char *crypt_get_dir(void)
924 {
925         struct setup_backend *backend;
926         const char *dir;
927
928         backend = get_setup_backend(default_backend);
929         if (!backend)
930                 return NULL;
931
932         dir = backend->dir();
933
934         put_setup_backend(backend);
935
936         return dir;
937 }
938
939 // Local Variables:
940 // c-basic-offset: 8
941 // indent-tabs-mode: nil
942 // End: