1 /* sh-dmcrypt.c - The DM-Crypt part for g13-syshelp
2  * Copyright (C) 2015, 2016 Werner Koch
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <sys/types.h>
28 #ifdef HAVE_SYS_MKDEV_H
29 #include <sys/mkdev.h>
30 #endif
31 #ifdef HAVE_SYS_SYSMACROS_H
32 # include <sys/sysmacros.h>
33 #endif
34 #ifdef HAVE_STAT
35 # include <sys/stat.h>
36 #endif
37 #include <unistd.h>
38 
39 #include "g13-syshelp.h"
40 #include <assuan.h>
41 #include "../common/i18n.h"
42 #include "g13tuple.h"
43 #include "../common/exectool.h"
44 #include "../common/sysutils.h"
45 #include "keyblob.h"
46 
47 /* The standard disk block size (logical).  */
48 #define SECTOR_SIZE 512
49 
50 /* The physical block size used by modern devices.  */
51 #define PHY_SECTOR_SIZE  (SECTOR_SIZE*8)  /* 4 KiB */
52 
53 /* The length of the crypto setup area in sectors.  16 KiB is a nice
54    multiple of a modern block size and should be sufficient for all
55    kind of extra public key encryption packets.  */
56 #define SETUP_AREA_SECTORS 32  /* 16 KiB */
57 
58 /* The number of header block copies stored at the begin and end of
59    the device.  */
60 #define HEADER_SETUP_AREA_COPIES 2
61 #define FOOTER_SETUP_AREA_COPIES 2
62 
63 /* The length in blocks of the space we put at the start and at the
64    end of the device.  This space is used to store N copies of the
65    setup area for the actual encrypted container in between.  */
66 #define HEADER_SECTORS (SETUP_AREA_SECTORS * HEADER_SETUP_AREA_COPIES)
67 #define FOOTER_SECTORS (SETUP_AREA_SECTORS * FOOTER_SETUP_AREA_COPIES)
68 
69 /* Minimim size of the encrypted space in blocks.  This is more or
70    less an arbitrary value.  */
71 #define MIN_ENCRYPTED_SPACE 32
72 
73 /* Some consistency checks for the above constants.  */
74 #if (PHY_SECTOR_SIZE % SECTOR_SIZE)
75 # error the physical secotor size should be a multiple of 512
76 #endif
77 #if ((SETUP_AREA_SECTORS*SECTOR_SIZE) % PHY_SECTOR_SIZE)
78 # error The setup area size should be a multiple of the phy. sector size.
79 #endif
80 
81 
82 /*
83  * Check whether the block device DEVNAME is used by device mapper.
84  * If EXPECT_BUSY is set no error message is printed if the device is
85  * busy.  Returns: 0 if the device is good and not yet used by DM.
86  */
87 static gpg_error_t
check_blockdev(const char * devname,int expect_busy)88 check_blockdev (const char *devname, int expect_busy)
89 {
90   gpg_error_t err;
91   struct stat sb;
92   unsigned int devmajor, devminor;
93   char *result = NULL;
94   char **lines = NULL;
95   char **fields = NULL;
96   int lno, count;
97 
98   if (gnupg_stat (devname, &sb))
99     {
100       err = gpg_error_from_syserror ();
101       log_error ("error stating '%s': %s\n", devname, gpg_strerror (err));
102       return err;
103     }
104   if (!S_ISBLK (sb.st_mode))
105     {
106       err = gpg_error (GPG_ERR_ENOTBLK);
107       log_error ("can't use '%s': %s\n", devname, gpg_strerror (err));
108       return err;
109     }
110   devmajor = major (sb.st_rdev);
111   devminor = minor (sb.st_rdev);
112 
113   {
114     const char *argv[2];
115 
116     argv[0] = "deps";
117     argv[1] = NULL;
118     err = gnupg_exec_tool ("/sbin/dmsetup", argv, NULL, &result, NULL);
119   }
120   if (err)
121     {
122       log_error ("error running '%s' to search for '%s': %s\n",
123                  "dmsetup deps", devname, gpg_strerror (err));
124       goto leave;
125     }
126   lines = strsplit (result, '\n', 0, NULL);
127   if (!lines)
128     {
129       err = gpg_error_from_syserror ();
130       goto leave;
131     }
132   if (lines[0] && !strcmp (lines[0], "No devices found"))
133     ;
134   else
135     {
136       for (lno=0; lines[lno]; lno++)
137         {
138           unsigned int xmajor, xminor;
139 
140           if (!*lines[lno])
141             continue;
142           xfree (fields);
143           fields = strsplit (lines[lno], ':', 0, &count);
144           if (!fields)
145             {
146               err = gpg_error_from_syserror ();
147               goto leave;
148             }
149           if (count < 3
150               || sscanf (fields[2], " (%u,%u)", &xmajor, &xminor) != 2)
151             {
152               log_error ("error running '%s' to search for '%s': %s\n",
153                          "dmsetup deps", devname, "unexpected output");
154               err = gpg_error (GPG_ERR_INV_VALUE);
155               goto leave;
156             }
157 
158           if (xmajor == devmajor && xminor == devminor)
159             {
160               if (!expect_busy)
161                 log_error ("device '%s' (%u:%u)"
162                            " already in use by device mapper\n",
163                            devname, devmajor, devminor);
164               err = gpg_error (GPG_ERR_EBUSY);
165               goto leave;
166             }
167         }
168     }
169 
170 
171  leave:
172   xfree (fields);
173   xfree (lines);
174   xfree (result);
175   return err;
176 }
177 
178 
179 /* Return a malloced buffer with the prefix of the setup area.  This
180    is the data written right before the encrypted keyblob.  Return NULL
181    on error and sets ERRNO.  */
182 static void *
mk_setup_area_prefix(size_t * r_length)183 mk_setup_area_prefix (size_t *r_length)
184 {
185   unsigned char *packet;
186   size_t setuparealen;
187 
188   packet = xtrymalloc (32);
189   if (!packet)
190     return NULL;
191   *r_length = 32;
192 
193   setuparealen = SETUP_AREA_SECTORS * SECTOR_SIZE;
194 
195   packet[0] = (0xc0|61); /* CTB for the private packet type 0x61.  */
196   packet[1] = 0xff;      /* 5 byte length packet, value 20.  */
197   packet[2] = 0;
198   packet[3] = 0;
199   packet[4] = 0;
200   packet[5] = 26;
201   memcpy (packet+6, "GnuPG/G13", 10); /* Packet subtype.  */
202   packet[16] = 1;   /* G13 packet format version.  */
203   packet[17] = 0;   /* Reserved.  */
204   packet[18] = 0;   /* Reserved.  */
205   packet[19] = 1;   /* OS Flag = Linux  */
206   packet[20] = (setuparealen >> 24);  /* Total length of header.  */
207   packet[21] = (setuparealen >> 16);
208   packet[22] = (setuparealen >> 8);
209   packet[23] = (setuparealen);
210   packet[24] = HEADER_SETUP_AREA_COPIES;
211   packet[25] = FOOTER_SETUP_AREA_COPIES;
212   packet[26] = 0;   /* Reserved.  */
213   packet[27] = 0;   /* Reserved.  */
214   packet[28] = 0;   /* Reserved.  */
215   packet[29] = 0;   /* Reserved.  */
216   packet[30] = 0;   /* Reserved.  */
217   packet[31] = 0;   /* Reserved.  */
218 
219   return packet;
220 }
221 
222 
223 /* Create a new g13 styloe DM-Crypt container on devoce DEVNAME.  */
224 gpg_error_t
sh_dmcrypt_create_container(ctrl_t ctrl,const char * devname,estream_t devfp)225 sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp)
226 {
227   gpg_error_t err;
228   char *header_space;
229   size_t header_space_size, header_space_used;
230   size_t paddinglen;
231   char *targetname = NULL;
232   size_t nread;
233   char *p;
234   char hexkey[16*2+1];
235   char *table = NULL;
236   unsigned long long nblocks;
237   char *result = NULL;
238   unsigned char twobyte[2];
239   membuf_t keyblob;
240   void  *keyblob_buf = NULL;
241   size_t keyblob_len;
242   size_t n;
243   const char *s;
244   unsigned char *packet;
245   int copy;
246 
247   if (!ctrl->devti)
248     return gpg_error (GPG_ERR_INV_ARG);
249 
250   g13_syshelp_i_know_what_i_am_doing ();
251 
252   header_space_size = SETUP_AREA_SECTORS * SECTOR_SIZE;
253   header_space = xtrymalloc (header_space_size);
254   if (!header_space)
255     return gpg_error_from_syserror ();
256 
257   /* Start building the keyblob.  */
258   init_membuf (&keyblob, 512);
259   append_tuple (&keyblob, KEYBLOB_TAG_BLOBVERSION, "\x01", 1);
260   n = CONTTYPE_DM_CRYPT;
261   twobyte[0] = (n >> 8);
262   twobyte[1] = n;
263   append_tuple (&keyblob, KEYBLOB_TAG_CONTTYPE, twobyte, 2);
264   {
265     gnupg_isotime_t tbuf;
266 
267     gnupg_get_isotime (tbuf);
268     append_tuple (&keyblob, KEYBLOB_TAG_CREATED, tbuf, strlen (tbuf));
269   }
270 
271   /* Rewind device stream.  */
272   if (es_fseeko (devfp, 0, SEEK_SET))
273     {
274       err = gpg_error_from_syserror ();
275       log_error ("error seeking to begin of '%s': %s\n",
276                  devname, gpg_strerror (err));
277       goto leave;
278     }
279   es_clearerr (devfp);
280 
281   /* Extra check that the device is empty.  */
282   if (es_read (devfp, header_space, header_space_size, &nread))
283     err = gpg_error_from_syserror ();
284   else if (nread != header_space_size)
285     err = gpg_error (GPG_ERR_TOO_SHORT);
286   else
287     err = 0;
288   if (err)
289     {
290       log_error ("error reading header space of '%s': %s\n",
291                  devname, gpg_strerror (err));
292       goto leave;
293     }
294   for (p=header_space; nread && !*p; nread--, p++)
295     ;
296   if (nread)
297     {
298       log_error ("header space of '%s' already used - use %s to override\n",
299                  devname, "--force");
300       err = gpg_error (GPG_ERR_NOT_SUPPORTED);
301       goto leave;
302     }
303 
304   /* Check that the device is not used by device mapper. */
305   err = check_blockdev (devname, 0);
306   if (err)
307     goto leave;
308 
309   /* Compute the number of blocks.  */
310   err = sh_blockdev_getsz (devname, &nblocks);
311   if (err)
312     {
313       log_error ("error getting size of '%s': %s\n",
314                  devname, gpg_strerror (err));
315       goto leave;
316     }
317   if (nblocks <= HEADER_SECTORS + MIN_ENCRYPTED_SPACE + FOOTER_SECTORS)
318     {
319       log_error ("device '%s' is too small (min=%d blocks)\n",
320                  devname,
321                  HEADER_SECTORS + MIN_ENCRYPTED_SPACE + FOOTER_SECTORS);
322       err = gpg_error (GPG_ERR_TOO_SHORT);
323       goto leave;
324     }
325   append_tuple_uint (&keyblob, KEYBLOB_TAG_CONT_NSEC, nblocks);
326   nblocks -= HEADER_SECTORS + FOOTER_SECTORS;
327   append_tuple_uint (&keyblob, KEYBLOB_TAG_ENC_NSEC, nblocks);
328   append_tuple_uint (&keyblob, KEYBLOB_TAG_ENC_OFF, HEADER_SECTORS);
329 
330   /* Device mapper needs a name for the device: Take it from the label
331      or use "0".  */
332   targetname = strconcat ("g13-", ctrl->client.uname, "-",
333                           ctrl->devti->label? ctrl->devti->label : "0",
334                           NULL);
335   if (!targetname)
336     {
337       err = gpg_error_from_syserror ();
338       goto leave;
339     }
340 
341   /* Create the key.  */
342   {
343     char key[16];
344     gcry_randomize (key, sizeof key, GCRY_STRONG_RANDOM);
345     append_tuple (&keyblob, KEYBLOB_TAG_ENCKEY, key, sizeof key);
346     bin2hex (key, 16, hexkey);
347     wipememory (key, 16);
348     /* Add a 2*(4+16) byte filler to conceal the fact that we use
349        AES-128.  If we ever want to switch to 256 bit we can resize
350        that filler to keep the keyblob at the same size.  */
351     append_tuple (&keyblob, KEYBLOB_TAG_FILLER, key, sizeof key);
352     append_tuple (&keyblob, KEYBLOB_TAG_FILLER, key, sizeof key);
353   }
354 
355   /* Build dmcrypt table. */
356   s = "aes-cbc-essiv:sha256";
357   append_tuple (&keyblob, KEYBLOB_TAG_ALGOSTR, s, strlen (s));
358   table = es_bsprintf ("0 %llu crypt %s %s 0 %s %d",
359                        nblocks, s, hexkey, devname, HEADER_SECTORS);
360   if (!table)
361     {
362       err = gpg_error_from_syserror ();
363       goto leave;
364     }
365   wipememory (hexkey, sizeof hexkey);
366 
367   /* Add a copy of the setup area prefix to the keyblob.  */
368   p = mk_setup_area_prefix (&n);
369   if (!p)
370     {
371       err = gpg_error_from_syserror ();
372       goto leave;
373     }
374   append_tuple (&keyblob, KEYBLOB_TAG_HDRCOPY, p, n);
375   assert (n < header_space_size);
376   memcpy (header_space, p, n);
377   header_space_used = n;
378 
379   /* Turn the keyblob into a buffer and callback to encrypt it.  */
380   keyblob_buf = get_membuf (&keyblob, &keyblob_len);
381   if (!keyblob_buf)
382     {
383       err = gpg_error_from_syserror ();
384       goto leave;
385     }
386   err = sh_encrypt_keyblob (ctrl, keyblob_buf, keyblob_len, &p, &n);
387   if (err)
388     {
389       log_error ("encrypting the keyblob failed: %s\n", gpg_strerror (err));
390       goto leave;
391     }
392   log_debug ("plain setuparea=%p %zu bytes\n", keyblob_buf, keyblob_len);
393   wipememory (keyblob_buf, keyblob_len);
394   xfree (keyblob_buf);
395   keyblob_buf = NULL;
396 
397   log_debug ("encry setuparea=%p %zu bytes\n", p, n);
398   if (n >= header_space_size || (header_space_used + n) >= header_space_size)
399     {
400       err = gpg_error (GPG_ERR_TOO_LARGE);
401       log_error ("setup area would overflow: %s\n", gpg_strerror (err));
402       goto leave;
403     }
404   memcpy (header_space + header_space_used, p, n);
405   header_space_used += n;
406 
407   /* Write the padding.  */
408   packet = header_space + header_space_used;
409   paddinglen = header_space_size - header_space_used;
410   if (paddinglen < 16)
411     {
412       err = gpg_error (GPG_ERR_TOO_LARGE);
413       log_error ("setup area too short for padding: %s\n", gpg_strerror (err));
414       goto leave;
415     }
416   packet[0] = (0xc0|61); /* CTB for Private packet type 0x61.  */
417   packet[1] = 0xff;      /* 5 byte length packet, value 20.  */
418   packet[2] = (paddinglen-6) >> 24;
419   packet[3] = (paddinglen-6) >> 16;
420   packet[4] = (paddinglen-6) >> 8;
421   packet[5] = (paddinglen-6);
422   packet += 6;
423   paddinglen -= 6;
424   header_space_used += 6;
425   for ( ;paddinglen >= 10;
426         paddinglen -= 10, packet += 10, header_space_used += 10)
427     memcpy (packet, "GnuPG/PAD", 10);
428   for ( ;paddinglen; paddinglen--, packet++, header_space_used++)
429     *packet = 0;
430 
431   if (header_space_used != header_space_size)
432     BUG ();
433 
434   /* Create the container.  */
435   {
436     const char *argv[3];
437 
438     argv[0] = "create";
439     argv[1] = targetname;
440     argv[2] = NULL;
441     log_debug ("now running \"dmsetup create %s\"\n", targetname);
442     log_debug ("  with table='%s'\"\n", table);
443     err = gnupg_exec_tool ("/sbin/dmsetup", argv, table, &result, NULL);
444   }
445   if (err)
446     {
447       log_error ("error running dmsetup for '%s': %s\n",
448                  devname, gpg_strerror (err));
449       goto leave;
450     }
451   if (result && *result)
452     log_debug ("dmsetup result: %s\n", result);
453 
454   /* Write the setup area.  */
455   if (es_fseeko (devfp, 0, SEEK_SET))
456     {
457       err = gpg_error_from_syserror ();
458       log_error ("error seeking to begin of '%s': %s\n",
459                  devname, gpg_strerror (err));
460       goto leave;
461     }
462   es_clearerr (devfp);
463 
464   for (copy = 0; copy < HEADER_SETUP_AREA_COPIES; copy++)
465     {
466       size_t nwritten;
467 
468       if (es_write (devfp, header_space, header_space_size, &nwritten))
469         {
470           err = gpg_error_from_syserror ();
471           break;
472         }
473       else if (nwritten != header_space_size)
474         {
475           err = gpg_error (GPG_ERR_TOO_SHORT);
476           break;
477         }
478     }
479   if (err)
480     {
481       log_error ("error writing header space copy %d of '%s': %s\n",
482                  copy, devname, gpg_strerror (err));
483       goto leave;
484     }
485 
486   if (es_fseeko (devfp,
487                  (- header_space_size * FOOTER_SETUP_AREA_COPIES), SEEK_END))
488     {
489       err = gpg_error_from_syserror ();
490       log_error ("error seeking to end of '%s': %s\n",
491                  devname, gpg_strerror (err));
492       goto leave;
493     }
494   es_clearerr (devfp);
495 
496   for (copy = 0; copy < FOOTER_SETUP_AREA_COPIES; copy++)
497     {
498       size_t nwritten;
499 
500       if (es_write (devfp, header_space, header_space_size, &nwritten))
501         {
502           err = gpg_error_from_syserror ();
503           break;
504         }
505       else if (nwritten != header_space_size)
506         {
507           err = gpg_error (GPG_ERR_TOO_SHORT);
508           break;
509         }
510     }
511   if (!err && es_fflush (devfp))
512     err = gpg_error_from_syserror ();
513   if (err)
514     {
515       log_error ("error writing footer space copy %d of '%s': %s\n",
516                  copy, devname, gpg_strerror (err));
517       goto leave;
518     }
519 
520  leave:
521   wipememory (hexkey, sizeof hexkey);
522   if (table)
523     {
524       wipememory (table, strlen (table));
525       xfree (table);
526     }
527   if (keyblob_buf)
528     {
529       wipememory (keyblob_buf, keyblob_len);
530       xfree (keyblob_buf);
531     }
532   xfree (get_membuf (&keyblob, NULL));
533   xfree (targetname);
534   xfree (result);
535   xfree (header_space);
536   return err;
537 }
538 
539 
540 /* Mount a DM-Crypt container on device DEVNAME taking keys and other
541  * meta data from KEYBLOB.  */
542 gpg_error_t
sh_dmcrypt_mount_container(ctrl_t ctrl,const char * devname,tupledesc_t keyblob)543 sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname,
544                             tupledesc_t keyblob)
545 {
546   gpg_error_t err;
547   char *targetname_abs = NULL;
548   const char *targetname;
549   char hexkey[16*2+1];
550   char *table = NULL;
551   unsigned long long nblocks, nblocks2;
552   char *result = NULL;
553   size_t n;
554   const char *s;
555   const char *algostr;
556   size_t algostrlen;
557 
558   if (!ctrl->devti)
559     return gpg_error (GPG_ERR_INV_ARG);
560 
561   g13_syshelp_i_know_what_i_am_doing ();
562 
563   /* Check that the device is not yet used by device mapper. */
564   err = check_blockdev (devname, 0);
565   if (err)
566     goto leave;
567 
568   /* Compute the number of blocks and compare them to the value
569      provided as meta data.  */
570   err = sh_blockdev_getsz (devname, &nblocks);
571   if (err)
572     {
573       log_error ("error getting size of '%s': %s\n",
574                  devname, gpg_strerror (err));
575       goto leave;
576     }
577   err = find_tuple_uint (keyblob, KEYBLOB_TAG_CONT_NSEC, &nblocks2);
578   if (err)
579     {
580       log_error ("error getting size from keyblob: %s\n", gpg_strerror (err));
581       goto leave;
582     }
583   if (nblocks != nblocks2)
584     {
585       log_error ("inconsistent size of container: expected==%llu got=%llu\n",
586                  nblocks2, nblocks);
587       err = gpg_error (GPG_ERR_INV_DATA);
588       goto leave;
589     }
590   if (nblocks <= HEADER_SECTORS + MIN_ENCRYPTED_SPACE + FOOTER_SECTORS)
591     {
592       log_error ("device '%s' is too small (min=%d blocks)\n",
593                  devname,
594                  HEADER_SECTORS + MIN_ENCRYPTED_SPACE + FOOTER_SECTORS);
595       err = gpg_error (GPG_ERR_TOO_SHORT);
596       goto leave;
597     }
598   nblocks -= HEADER_SECTORS + FOOTER_SECTORS;
599   err = find_tuple_uint (keyblob, KEYBLOB_TAG_ENC_NSEC, &nblocks2);
600   if (err)
601     {
602       log_error ("error getting enc size from keyblob: %s\n",
603                  gpg_strerror (err));
604       goto leave;
605     }
606   if (nblocks != nblocks2)
607     {
608       log_error ("inconsistent size of enc data: expected==%llu got=%llu\n",
609                  nblocks2, nblocks);
610       err = gpg_error (GPG_ERR_INV_DATA);
611       goto leave;
612     }
613   /* Check that the offset is consistent.  */
614   err = find_tuple_uint (keyblob, KEYBLOB_TAG_ENC_OFF, &nblocks2);
615   if (err)
616     {
617       log_error ("error getting enc offset from keyblob: %s\n",
618                  gpg_strerror (err));
619       goto leave;
620     }
621   if (nblocks2 != HEADER_SECTORS)
622     {
623       log_error ("inconsistent offset of enc data: expected==%llu got=%d\n",
624                  nblocks2, HEADER_SECTORS);
625       err = gpg_error (GPG_ERR_INV_DATA);
626       goto leave;
627     }
628 
629   /* Device mapper needs a name for the device: Take it from the label
630      or use "0".  */
631   targetname_abs = strconcat ("/dev/mapper/",
632                               "g13-", ctrl->client.uname, "-",
633                               ctrl->devti->label? ctrl->devti->label : "0",
634                               NULL);
635   if (!targetname_abs)
636     {
637       err = gpg_error_from_syserror ();
638       goto leave;
639     }
640   targetname = strrchr (targetname_abs, '/');
641   if (!targetname)
642     BUG ();
643   targetname++;
644 
645   /* Get the algorithm string.  */
646   algostr = find_tuple (keyblob, KEYBLOB_TAG_ALGOSTR, &algostrlen);
647   if (!algostr || algostrlen > 100)
648     {
649       log_error ("algo string not found in keyblob or too long\n");
650       err = gpg_error (GPG_ERR_INV_DATA);
651       goto leave;
652     }
653 
654   /* Get the key.  */
655   s = find_tuple (keyblob, KEYBLOB_TAG_ENCKEY, &n);
656   if (!s || n != 16)
657     {
658       if (!s)
659         log_error ("no key found in keyblob\n");
660       else
661         log_error ("unexpected size of key (%zu)\n", n);
662       err = gpg_error (GPG_ERR_INV_KEYLEN);
663       goto leave;
664     }
665   bin2hex (s, 16, hexkey);
666 
667   /* Build dmcrypt table. */
668   table = es_bsprintf ("0 %llu crypt %.*s %s 0 %s %d",
669                        nblocks, (int)algostrlen, algostr,
670                        hexkey, devname, HEADER_SECTORS);
671   wipememory (hexkey, sizeof hexkey);
672   if (!table)
673     {
674       err = gpg_error_from_syserror ();
675       goto leave;
676     }
677 
678   /* Load the table.  */
679   {
680     const char *argv[3];
681 
682     argv[0] = "create";
683     argv[1] = targetname;
684     argv[2] = NULL;
685     log_debug ("now running \"dmsetup create %s\"\n", targetname);
686     err = gnupg_exec_tool ("/sbin/dmsetup", argv, table, &result, NULL);
687   }
688   if (err)
689     {
690       log_error ("error running dmsetup for '%s': %s\n",
691                  devname, gpg_strerror (err));
692       goto leave;
693     }
694   if (result && *result)
695     log_debug ("dmsetup result: %s\n", result);
696   xfree (result);
697   result = NULL;
698 
699   /* Mount if a mountpoint has been given.  */
700   if (ctrl->devti->mountpoint)
701     {
702       const char *argv[3];
703 
704       argv[0] = targetname_abs;
705       argv[1] = ctrl->devti->mountpoint;
706       argv[2] = NULL;
707       log_debug ("now running \"mount %s %s\"\n",
708                  targetname_abs, ctrl->devti->mountpoint);
709       err = gnupg_exec_tool ("/bin/mount", argv, NULL, &result, NULL);
710       if (err)
711         {
712           log_error ("error running mount: %s\n", gpg_strerror (err));
713           goto leave;
714         }
715       if (result && *result)  /* (We should not see output to stdout).  */
716         log_info ("WARNING: mount returned data on stdout! (%s)\n", result);
717     }
718 
719 
720  leave:
721   wipememory (hexkey, sizeof hexkey);
722   if (table)
723     {
724       wipememory (table, strlen (table));
725       xfree (table);
726     }
727   xfree (targetname_abs);
728   xfree (result);
729   return err;
730 }
731 
732 
733 /* Unmount a DM-Crypt container on device DEVNAME and wipe the keys.  */
734 gpg_error_t
sh_dmcrypt_umount_container(ctrl_t ctrl,const char * devname)735 sh_dmcrypt_umount_container (ctrl_t ctrl, const char *devname)
736 {
737   gpg_error_t err;
738   char *targetname_abs = NULL;
739   char *result = NULL;
740 
741   if (!ctrl->devti)
742     return gpg_error (GPG_ERR_INV_ARG);
743 
744   g13_syshelp_i_know_what_i_am_doing ();
745 
746   /* Check that the device is used by device mapper. */
747   err = check_blockdev (devname, 1);
748   if (gpg_err_code (err) != GPG_ERR_EBUSY)
749     {
750       log_error ("device '%s' is not used by the device mapper: %s\n",
751                  devname, gpg_strerror (err));
752       goto leave;
753     }
754 
755   /* Fixme: Check that this is really a g13 partition.  */
756 
757   /* Device mapper needs a name for the device: Take it from the label
758      or use "0".  */
759   targetname_abs = strconcat ("/dev/mapper/",
760                               "g13-", ctrl->client.uname, "-",
761                               ctrl->devti->label? ctrl->devti->label : "0",
762                               NULL);
763   if (!targetname_abs)
764     {
765       err = gpg_error_from_syserror ();
766       goto leave;
767     }
768 
769   /* Run the regular umount command.  */
770   {
771     const char *argv[2];
772 
773     argv[0] = targetname_abs;
774     argv[1] = NULL;
775     log_debug ("now running \"umount %s\"\n", targetname_abs);
776     err = gnupg_exec_tool ("/bin/umount", argv, NULL, &result, NULL);
777   }
778   if (err)
779     {
780       log_error ("error running umount: %s\n", gpg_strerror (err));
781       if (1)
782         {
783           /* Try to show some info about processes using the partition. */
784           const char *argv[3];
785 
786           argv[0] = "-mv";
787           argv[1] = targetname_abs;
788           argv[2] = NULL;
789           gnupg_exec_tool ("/bin/fuser", argv, NULL, &result, NULL);
790         }
791       goto leave;
792     }
793   if (result && *result)  /* (We should not see output to stdout).  */
794     log_info ("WARNING: umount returned data on stdout! (%s)\n", result);
795   xfree (result);
796   result = NULL;
797 
798   /* Run the dmsetup remove command.  */
799   {
800     const char *argv[3];
801 
802     argv[0] = "remove";
803     argv[1] = targetname_abs;
804     argv[2] = NULL;
805     log_debug ("now running \"dmsetup remove %s\"\n", targetname_abs);
806     err = gnupg_exec_tool ("/sbin/dmsetup", argv, NULL, &result, NULL);
807   }
808   if (err)
809     {
810       log_error ("error running \"dmsetup remove %s\": %s\n",
811                  targetname_abs, gpg_strerror (err));
812       goto leave;
813     }
814   if (result && *result)
815     log_debug ("dmsetup result: %s\n", result);
816   xfree (result);
817   result = NULL;
818 
819  leave:
820   xfree (targetname_abs);
821   xfree (result);
822   return err;
823 }
824 
825 
826 /* Suspend a DM-Crypt container on device DEVNAME and wipe the keys.  */
827 gpg_error_t
sh_dmcrypt_suspend_container(ctrl_t ctrl,const char * devname)828 sh_dmcrypt_suspend_container (ctrl_t ctrl, const char *devname)
829 {
830   gpg_error_t err;
831   char *targetname_abs = NULL;
832   const char *targetname;
833   char *result = NULL;
834 
835   if (!ctrl->devti)
836     return gpg_error (GPG_ERR_INV_ARG);
837 
838   g13_syshelp_i_know_what_i_am_doing ();
839 
840   /* Check that the device is used by device mapper. */
841   err = check_blockdev (devname, 1);
842   if (gpg_err_code (err) != GPG_ERR_EBUSY)
843     {
844       log_error ("device '%s' is not used by the device mapper: %s\n",
845                  devname, gpg_strerror (err));
846       goto leave;
847     }
848 
849   /* Fixme: Check that this is really a g13 partition.  */
850 
851   /* Device mapper needs a name for the device: Take it from the label
852      or use "0".  */
853   targetname_abs = strconcat ("/dev/mapper/",
854                               "g13-", ctrl->client.uname, "-",
855                               ctrl->devti->label? ctrl->devti->label : "0",
856                               NULL);
857   if (!targetname_abs)
858     {
859       err = gpg_error_from_syserror ();
860       goto leave;
861     }
862   targetname = strrchr (targetname_abs, '/');
863   if (!targetname)
864     BUG ();
865   targetname++;
866 
867   /* Send the suspend command.  */
868   {
869     const char *argv[3];
870 
871     argv[0] = "suspend";
872     argv[1] = targetname;
873     argv[2] = NULL;
874     log_debug ("now running \"dmsetup suspend %s\"\n", targetname);
875     err = gnupg_exec_tool ("/sbin/dmsetup", argv, NULL, &result, NULL);
876   }
877   if (err)
878     {
879       log_error ("error running \"dmsetup suspend %s\": %s\n",
880                  targetname, gpg_strerror (err));
881       goto leave;
882     }
883   if (result && *result)
884     log_debug ("dmsetup result: %s\n", result);
885   xfree (result);
886   result = NULL;
887 
888   /* Send the wipe key command.  */
889   {
890     const char *argv[5];
891 
892     argv[0] = "message";
893     argv[1] = targetname;
894     argv[2] = "0";
895     argv[3] = "key wipe";
896     argv[4] = NULL;
897     log_debug ("now running \"dmsetup message %s 0 key wipe\"\n", targetname);
898     err = gnupg_exec_tool ("/sbin/dmsetup", argv, NULL, &result, NULL);
899   }
900   if (err)
901     {
902       log_error ("error running \"dmsetup message %s 0 key wipe\": %s\n",
903                  targetname, gpg_strerror (err));
904       goto leave;
905     }
906   if (result && *result)
907     log_debug ("dmsetup result: %s\n", result);
908   xfree (result);
909   result = NULL;
910 
911 
912  leave:
913   xfree (targetname_abs);
914   xfree (result);
915   return err;
916 }
917 
918 
919 /* Resume a DM-Crypt container on device DEVNAME taking keys and other
920  * meta data from KEYBLOB.  */
921 gpg_error_t
sh_dmcrypt_resume_container(ctrl_t ctrl,const char * devname,tupledesc_t keyblob)922 sh_dmcrypt_resume_container (ctrl_t ctrl, const char *devname,
923                              tupledesc_t keyblob)
924 {
925   gpg_error_t err;
926   char *targetname_abs = NULL;
927   const char *targetname;
928   char hexkey[8+16*2+1]; /* 8 is used to prepend "key set ".  */
929   char *table = NULL;
930   char *result = NULL;
931   size_t n;
932   const char *s;
933   const char *algostr;
934   size_t algostrlen;
935 
936   if (!ctrl->devti)
937     return gpg_error (GPG_ERR_INV_ARG);
938 
939   g13_syshelp_i_know_what_i_am_doing ();
940 
941   /* Check that the device is used by device mapper. */
942   err = check_blockdev (devname, 1);
943   if (gpg_err_code (err) != GPG_ERR_EBUSY)
944     {
945       log_error ("device '%s' is not used by the device mapper: %s\n",
946                  devname, gpg_strerror (err));
947       goto leave;
948     }
949 
950   /* Device mapper needs a name for the device: Take it from the label
951      or use "0".  */
952   targetname_abs = strconcat ("/dev/mapper/",
953                               "g13-", ctrl->client.uname, "-",
954                               ctrl->devti->label? ctrl->devti->label : "0",
955                               NULL);
956   if (!targetname_abs)
957     {
958       err = gpg_error_from_syserror ();
959       goto leave;
960     }
961   targetname = strrchr (targetname_abs, '/');
962   if (!targetname)
963     BUG ();
964   targetname++;
965 
966   /* Get the algorithm string.  */
967   algostr = find_tuple (keyblob, KEYBLOB_TAG_ALGOSTR, &algostrlen);
968   if (!algostr || algostrlen > 100)
969     {
970       log_error ("algo string not found in keyblob or too long\n");
971       err = gpg_error (GPG_ERR_INV_DATA);
972       goto leave;
973     }
974 
975   /* Get the key.  */
976   s = find_tuple (keyblob, KEYBLOB_TAG_ENCKEY, &n);
977   if (!s || n != 16)
978     {
979       if (!s)
980         log_error ("no key found in keyblob\n");
981       else
982         log_error ("unexpected size of key (%zu)\n", n);
983       err = gpg_error (GPG_ERR_INV_KEYLEN);
984       goto leave;
985     }
986   strcpy (hexkey, "key set ");
987   bin2hex (s, 16, hexkey+8);
988 
989   /* Send the key */
990   {
991     const char *argv[4];
992 
993     argv[0] = "message";
994     argv[1] = targetname;
995     argv[2] = "0";
996     argv[3] = NULL;
997     log_debug ("now running \"dmsetup message %s 0 [key set]\"\n", targetname);
998     err = gnupg_exec_tool ("/sbin/dmsetup", argv, hexkey, &result, NULL);
999   }
1000   wipememory (hexkey, sizeof hexkey);
1001   if (err)
1002     {
1003       log_error ("error running \"dmsetup message %s 0 [key set]\": %s\n",
1004                  devname, gpg_strerror (err));
1005       goto leave;
1006     }
1007   if (result && *result)
1008     log_debug ("dmsetup result: %s\n", result);
1009   xfree (result);
1010   result = NULL;
1011 
1012   /* Send the resume command. */
1013   {
1014     const char *argv[3];
1015 
1016     argv[0] = "resume";
1017     argv[1] = targetname;
1018     argv[2] = NULL;
1019     log_debug ("now running \"dmsetup resume %s\"\n", targetname);
1020     err = gnupg_exec_tool ("/sbin/dmsetup", argv, NULL, &result, NULL);
1021   }
1022   if (err)
1023     {
1024       log_error ("error running \"dmsetup resume %s\": %s\n",
1025                  targetname, gpg_strerror (err));
1026       goto leave;
1027     }
1028   if (result && *result)
1029     log_debug ("dmsetup result: %s\n", result);
1030   xfree (result);
1031   result = NULL;
1032 
1033  leave:
1034   wipememory (hexkey, sizeof hexkey);
1035   if (table)
1036     {
1037       wipememory (table, strlen (table));
1038       xfree (table);
1039     }
1040   xfree (targetname_abs);
1041   xfree (result);
1042   return err;
1043 }
1044