]> git.proxmox.com Git - grub2.git/blob - grub-core/disk/luks.c
Import grub2_2.02+dfsg1.orig.tar.xz
[grub2.git] / grub-core / disk / luks.c
1 /*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2003,2007,2010,2011 Free Software Foundation, Inc.
4 *
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <grub/cryptodisk.h>
20 #include <grub/types.h>
21 #include <grub/misc.h>
22 #include <grub/mm.h>
23 #include <grub/dl.h>
24 #include <grub/err.h>
25 #include <grub/disk.h>
26 #include <grub/crypto.h>
27 #include <grub/partition.h>
28 #include <grub/i18n.h>
29
30 GRUB_MOD_LICENSE ("GPLv3+");
31
32 #define MAX_PASSPHRASE 256
33
34 #define LUKS_KEY_ENABLED 0x00AC71F3
35
36 /* On disk LUKS header */
37 struct grub_luks_phdr
38 {
39 grub_uint8_t magic[6];
40 #define LUKS_MAGIC "LUKS\xBA\xBE"
41 grub_uint16_t version;
42 char cipherName[32];
43 char cipherMode[32];
44 char hashSpec[32];
45 grub_uint32_t payloadOffset;
46 grub_uint32_t keyBytes;
47 grub_uint8_t mkDigest[20];
48 grub_uint8_t mkDigestSalt[32];
49 grub_uint32_t mkDigestIterations;
50 char uuid[40];
51 struct
52 {
53 grub_uint32_t active;
54 grub_uint32_t passwordIterations;
55 grub_uint8_t passwordSalt[32];
56 grub_uint32_t keyMaterialOffset;
57 grub_uint32_t stripes;
58 } keyblock[8];
59 } GRUB_PACKED;
60
61 typedef struct grub_luks_phdr *grub_luks_phdr_t;
62
63 gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src,
64 grub_uint8_t * dst, grub_size_t blocksize,
65 grub_size_t blocknumbers);
66
67 static grub_cryptodisk_t
68 configure_ciphers (grub_disk_t disk, const char *check_uuid,
69 int check_boot)
70 {
71 grub_cryptodisk_t newdev;
72 const char *iptr;
73 struct grub_luks_phdr header;
74 char *optr;
75 char uuid[sizeof (header.uuid) + 1];
76 char ciphername[sizeof (header.cipherName) + 1];
77 char ciphermode[sizeof (header.cipherMode) + 1];
78 char *cipheriv = NULL;
79 char hashspec[sizeof (header.hashSpec) + 1];
80 grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL;
81 grub_crypto_cipher_handle_t essiv_cipher = NULL;
82 const gcry_md_spec_t *hash = NULL, *essiv_hash = NULL;
83 const struct gcry_cipher_spec *ciph;
84 grub_cryptodisk_mode_t mode;
85 grub_cryptodisk_mode_iv_t mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
86 int benbi_log = 0;
87 grub_err_t err;
88
89 if (check_boot)
90 return NULL;
91
92 /* Read the LUKS header. */
93 err = grub_disk_read (disk, 0, 0, sizeof (header), &header);
94 if (err)
95 {
96 if (err == GRUB_ERR_OUT_OF_RANGE)
97 grub_errno = GRUB_ERR_NONE;
98 return NULL;
99 }
100
101 /* Look for LUKS magic sequence. */
102 if (grub_memcmp (header.magic, LUKS_MAGIC, sizeof (header.magic))
103 || grub_be_to_cpu16 (header.version) != 1)
104 return NULL;
105
106 optr = uuid;
107 for (iptr = header.uuid; iptr < &header.uuid[ARRAY_SIZE (header.uuid)];
108 iptr++)
109 {
110 if (*iptr != '-')
111 *optr++ = *iptr;
112 }
113 *optr = 0;
114
115 if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0)
116 {
117 grub_dprintf ("luks", "%s != %s\n", uuid, check_uuid);
118 return NULL;
119 }
120
121 /* Make sure that strings are null terminated. */
122 grub_memcpy (ciphername, header.cipherName, sizeof (header.cipherName));
123 ciphername[sizeof (header.cipherName)] = 0;
124 grub_memcpy (ciphermode, header.cipherMode, sizeof (header.cipherMode));
125 ciphermode[sizeof (header.cipherMode)] = 0;
126 grub_memcpy (hashspec, header.hashSpec, sizeof (header.hashSpec));
127 hashspec[sizeof (header.hashSpec)] = 0;
128
129 ciph = grub_crypto_lookup_cipher_by_name (ciphername);
130 if (!ciph)
131 {
132 grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available",
133 ciphername);
134 return NULL;
135 }
136
137 /* Configure the cipher used for the bulk data. */
138 cipher = grub_crypto_cipher_open (ciph);
139 if (!cipher)
140 return NULL;
141
142 if (grub_be_to_cpu32 (header.keyBytes) > 1024)
143 {
144 grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d",
145 grub_be_to_cpu32 (header.keyBytes));
146 grub_crypto_cipher_close (cipher);
147 return NULL;
148 }
149
150 /* Configure the cipher mode. */
151 if (grub_strcmp (ciphermode, "ecb") == 0)
152 {
153 mode = GRUB_CRYPTODISK_MODE_ECB;
154 mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
155 cipheriv = NULL;
156 }
157 else if (grub_strcmp (ciphermode, "plain") == 0)
158 {
159 mode = GRUB_CRYPTODISK_MODE_CBC;
160 mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
161 cipheriv = NULL;
162 }
163 else if (grub_memcmp (ciphermode, "cbc-", sizeof ("cbc-") - 1) == 0)
164 {
165 mode = GRUB_CRYPTODISK_MODE_CBC;
166 cipheriv = ciphermode + sizeof ("cbc-") - 1;
167 }
168 else if (grub_memcmp (ciphermode, "pcbc-", sizeof ("pcbc-") - 1) == 0)
169 {
170 mode = GRUB_CRYPTODISK_MODE_PCBC;
171 cipheriv = ciphermode + sizeof ("pcbc-") - 1;
172 }
173 else if (grub_memcmp (ciphermode, "xts-", sizeof ("xts-") - 1) == 0)
174 {
175 mode = GRUB_CRYPTODISK_MODE_XTS;
176 cipheriv = ciphermode + sizeof ("xts-") - 1;
177 secondary_cipher = grub_crypto_cipher_open (ciph);
178 if (!secondary_cipher)
179 {
180 grub_crypto_cipher_close (cipher);
181 return NULL;
182 }
183 if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
184 {
185 grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d",
186 cipher->cipher->blocksize);
187 grub_crypto_cipher_close (cipher);
188 grub_crypto_cipher_close (secondary_cipher);
189 return NULL;
190 }
191 if (secondary_cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
192 {
193 grub_crypto_cipher_close (cipher);
194 grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d",
195 secondary_cipher->cipher->blocksize);
196 grub_crypto_cipher_close (secondary_cipher);
197 return NULL;
198 }
199 }
200 else if (grub_memcmp (ciphermode, "lrw-", sizeof ("lrw-") - 1) == 0)
201 {
202 mode = GRUB_CRYPTODISK_MODE_LRW;
203 cipheriv = ciphermode + sizeof ("lrw-") - 1;
204 if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
205 {
206 grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported LRW block size: %d",
207 cipher->cipher->blocksize);
208 grub_crypto_cipher_close (cipher);
209 return NULL;
210 }
211 }
212 else
213 {
214 grub_crypto_cipher_close (cipher);
215 grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s",
216 ciphermode);
217 return NULL;
218 }
219
220 if (cipheriv == NULL);
221 else if (grub_memcmp (cipheriv, "plain", sizeof ("plain") - 1) == 0)
222 mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
223 else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0)
224 mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
225 else if (grub_memcmp (cipheriv, "benbi", sizeof ("benbi") - 1) == 0)
226 {
227 if (cipher->cipher->blocksize & (cipher->cipher->blocksize - 1)
228 || cipher->cipher->blocksize == 0)
229 grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported benbi blocksize: %d",
230 cipher->cipher->blocksize);
231 /* FIXME should we return an error here? */
232 for (benbi_log = 0;
233 (cipher->cipher->blocksize << benbi_log) < GRUB_DISK_SECTOR_SIZE;
234 benbi_log++);
235 mode_iv = GRUB_CRYPTODISK_MODE_IV_BENBI;
236 }
237 else if (grub_memcmp (cipheriv, "null", sizeof ("null") - 1) == 0)
238 mode_iv = GRUB_CRYPTODISK_MODE_IV_NULL;
239 else if (grub_memcmp (cipheriv, "essiv:", sizeof ("essiv:") - 1) == 0)
240 {
241 char *hash_str = cipheriv + 6;
242
243 mode_iv = GRUB_CRYPTODISK_MODE_IV_ESSIV;
244
245 /* Configure the hash and cipher used for ESSIV. */
246 essiv_hash = grub_crypto_lookup_md_by_name (hash_str);
247 if (!essiv_hash)
248 {
249 grub_crypto_cipher_close (cipher);
250 grub_crypto_cipher_close (secondary_cipher);
251 grub_error (GRUB_ERR_FILE_NOT_FOUND,
252 "Couldn't load %s hash", hash_str);
253 return NULL;
254 }
255 essiv_cipher = grub_crypto_cipher_open (ciph);
256 if (!essiv_cipher)
257 {
258 grub_crypto_cipher_close (cipher);
259 grub_crypto_cipher_close (secondary_cipher);
260 return NULL;
261 }
262 }
263 else
264 {
265 grub_crypto_cipher_close (cipher);
266 grub_crypto_cipher_close (secondary_cipher);
267 grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s",
268 cipheriv);
269 return NULL;
270 }
271
272 /* Configure the hash used for the AF splitter and HMAC. */
273 hash = grub_crypto_lookup_md_by_name (hashspec);
274 if (!hash)
275 {
276 grub_crypto_cipher_close (cipher);
277 grub_crypto_cipher_close (essiv_cipher);
278 grub_crypto_cipher_close (secondary_cipher);
279 grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash",
280 hashspec);
281 return NULL;
282 }
283
284 newdev = grub_zalloc (sizeof (struct grub_cryptodisk));
285 if (!newdev)
286 {
287 grub_crypto_cipher_close (cipher);
288 grub_crypto_cipher_close (essiv_cipher);
289 grub_crypto_cipher_close (secondary_cipher);
290 return NULL;
291 }
292 newdev->cipher = cipher;
293 newdev->offset = grub_be_to_cpu32 (header.payloadOffset);
294 newdev->source_disk = NULL;
295 newdev->benbi_log = benbi_log;
296 newdev->mode = mode;
297 newdev->mode_iv = mode_iv;
298 newdev->secondary_cipher = secondary_cipher;
299 newdev->essiv_cipher = essiv_cipher;
300 newdev->essiv_hash = essiv_hash;
301 newdev->hash = hash;
302 newdev->log_sector_size = 9;
303 newdev->total_length = grub_disk_get_size (disk) - newdev->offset;
304 grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid));
305 newdev->modname = "luks";
306 COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid));
307 return newdev;
308 }
309
310 static grub_err_t
311 luks_recover_key (grub_disk_t source,
312 grub_cryptodisk_t dev)
313 {
314 struct grub_luks_phdr header;
315 grub_size_t keysize;
316 grub_uint8_t *split_key = NULL;
317 char passphrase[MAX_PASSPHRASE] = "";
318 grub_uint8_t candidate_digest[sizeof (header.mkDigest)];
319 unsigned i;
320 grub_size_t length;
321 grub_err_t err;
322 grub_size_t max_stripes = 1;
323 char *tmp;
324
325 err = grub_disk_read (source, 0, 0, sizeof (header), &header);
326 if (err)
327 return err;
328
329 grub_puts_ (N_("Attempting to decrypt master key..."));
330 keysize = grub_be_to_cpu32 (header.keyBytes);
331 if (keysize > GRUB_CRYPTODISK_MAX_KEYLEN)
332 return grub_error (GRUB_ERR_BAD_FS, "key is too long");
333
334 for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
335 if (grub_be_to_cpu32 (header.keyblock[i].active) == LUKS_KEY_ENABLED
336 && grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes)
337 max_stripes = grub_be_to_cpu32 (header.keyblock[i].stripes);
338
339 split_key = grub_malloc (keysize * max_stripes);
340 if (!split_key)
341 return grub_errno;
342
343 /* Get the passphrase from the user. */
344 tmp = NULL;
345 if (source->partition)
346 tmp = grub_partition_get_name (source->partition);
347 grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
348 source->partition ? "," : "", tmp ? : "",
349 dev->uuid);
350 grub_free (tmp);
351 if (!grub_password_get (passphrase, MAX_PASSPHRASE))
352 {
353 grub_free (split_key);
354 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
355 }
356
357 /* Try to recover master key from each active keyslot. */
358 for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
359 {
360 gcry_err_code_t gcry_err;
361 grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN];
362 grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN];
363
364 /* Check if keyslot is enabled. */
365 if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED)
366 continue;
367
368 grub_dprintf ("luks", "Trying keyslot %d\n", i);
369
370 /* Calculate the PBKDF2 of the user supplied passphrase. */
371 gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase,
372 grub_strlen (passphrase),
373 header.keyblock[i].passwordSalt,
374 sizeof (header.keyblock[i].passwordSalt),
375 grub_be_to_cpu32 (header.keyblock[i].
376 passwordIterations),
377 digest, keysize);
378
379 if (gcry_err)
380 {
381 grub_free (split_key);
382 return grub_crypto_gcry_error (gcry_err);
383 }
384
385 grub_dprintf ("luks", "PBKDF2 done\n");
386
387 gcry_err = grub_cryptodisk_setkey (dev, digest, keysize);
388 if (gcry_err)
389 {
390 grub_free (split_key);
391 return grub_crypto_gcry_error (gcry_err);
392 }
393
394 length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes));
395
396 /* Read and decrypt the key material from the disk. */
397 err = grub_disk_read (source,
398 grub_be_to_cpu32 (header.keyblock
399 [i].keyMaterialOffset), 0,
400 length, split_key);
401 if (err)
402 {
403 grub_free (split_key);
404 return err;
405 }
406
407 gcry_err = grub_cryptodisk_decrypt (dev, split_key, length, 0);
408 if (gcry_err)
409 {
410 grub_free (split_key);
411 return grub_crypto_gcry_error (gcry_err);
412 }
413
414 /* Merge the decrypted key material to get the candidate master key. */
415 gcry_err = AF_merge (dev->hash, split_key, candidate_key, keysize,
416 grub_be_to_cpu32 (header.keyblock[i].stripes));
417 if (gcry_err)
418 {
419 grub_free (split_key);
420 return grub_crypto_gcry_error (gcry_err);
421 }
422
423 grub_dprintf ("luks", "candidate key recovered\n");
424
425 /* Calculate the PBKDF2 of the candidate master key. */
426 gcry_err = grub_crypto_pbkdf2 (dev->hash, candidate_key,
427 grub_be_to_cpu32 (header.keyBytes),
428 header.mkDigestSalt,
429 sizeof (header.mkDigestSalt),
430 grub_be_to_cpu32
431 (header.mkDigestIterations),
432 candidate_digest,
433 sizeof (candidate_digest));
434 if (gcry_err)
435 {
436 grub_free (split_key);
437 return grub_crypto_gcry_error (gcry_err);
438 }
439
440 /* Compare the calculated PBKDF2 to the digest stored
441 in the header to see if it's correct. */
442 if (grub_memcmp (candidate_digest, header.mkDigest,
443 sizeof (header.mkDigest)) != 0)
444 {
445 grub_dprintf ("luks", "bad digest\n");
446 continue;
447 }
448
449 /* TRANSLATORS: It's a cryptographic key slot: one element of an array
450 where each element is either empty or holds a key. */
451 grub_printf_ (N_("Slot %d opened\n"), i);
452
453 /* Set the master key. */
454 gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize);
455 if (gcry_err)
456 {
457 grub_free (split_key);
458 return grub_crypto_gcry_error (gcry_err);
459 }
460
461 grub_free (split_key);
462
463 return GRUB_ERR_NONE;
464 }
465
466 grub_free (split_key);
467 return GRUB_ACCESS_DENIED;
468 }
469
470 struct grub_cryptodisk_dev luks_crypto = {
471 .scan = configure_ciphers,
472 .recover_key = luks_recover_key
473 };
474
475 GRUB_MOD_INIT (luks)
476 {
477 COMPILE_TIME_ASSERT (sizeof (((struct grub_luks_phdr *) 0)->uuid)
478 < GRUB_CRYPTODISK_MAX_UUID_LENGTH);
479 grub_cryptodisk_dev_register (&luks_crypto);
480 }
481
482 GRUB_MOD_FINI (luks)
483 {
484 grub_cryptodisk_dev_unregister (&luks_crypto);
485 }