2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2003,2007,2010,2011 Free Software Foundation, Inc.
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.
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.
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/>.
19 #include <grub/cryptodisk.h>
20 #include <grub/types.h>
21 #include <grub/misc.h>
25 #include <grub/disk.h>
26 #include <grub/crypto.h>
27 #include <grub/partition.h>
28 #include <grub/i18n.h>
30 GRUB_MOD_LICENSE ("GPLv3+");
32 #define MAX_PASSPHRASE 256
34 #define LUKS_KEY_ENABLED 0x00AC71F3
36 /* On disk LUKS header */
39 grub_uint8_t magic
[6];
40 #define LUKS_MAGIC "LUKS\xBA\xBE"
41 grub_uint16_t version
;
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
;
54 grub_uint32_t passwordIterations
;
55 grub_uint8_t passwordSalt
[32];
56 grub_uint32_t keyMaterialOffset
;
57 grub_uint32_t stripes
;
61 typedef struct grub_luks_phdr
*grub_luks_phdr_t
;
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
);
67 static grub_cryptodisk_t
68 configure_ciphers (grub_disk_t disk
, const char *check_uuid
,
71 grub_cryptodisk_t newdev
;
73 struct grub_luks_phdr header
;
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
;
92 /* Read the LUKS header. */
93 err
= grub_disk_read (disk
, 0, 0, sizeof (header
), &header
);
96 if (err
== GRUB_ERR_OUT_OF_RANGE
)
97 grub_errno
= GRUB_ERR_NONE
;
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)
107 for (iptr
= header
.uuid
; iptr
< &header
.uuid
[ARRAY_SIZE (header
.uuid
)];
115 if (check_uuid
&& grub_strcasecmp (check_uuid
, uuid
) != 0)
117 grub_dprintf ("luks", "%s != %s\n", uuid
, check_uuid
);
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;
129 ciph
= grub_crypto_lookup_cipher_by_name (ciphername
);
132 grub_error (GRUB_ERR_FILE_NOT_FOUND
, "Cipher %s isn't available",
137 /* Configure the cipher used for the bulk data. */
138 cipher
= grub_crypto_cipher_open (ciph
);
142 if (grub_be_to_cpu32 (header
.keyBytes
) > 1024)
144 grub_error (GRUB_ERR_BAD_ARGUMENT
, "invalid keysize %d",
145 grub_be_to_cpu32 (header
.keyBytes
));
146 grub_crypto_cipher_close (cipher
);
150 /* Configure the cipher mode. */
151 if (grub_strcmp (ciphermode
, "ecb") == 0)
153 mode
= GRUB_CRYPTODISK_MODE_ECB
;
154 mode_iv
= GRUB_CRYPTODISK_MODE_IV_PLAIN
;
157 else if (grub_strcmp (ciphermode
, "plain") == 0)
159 mode
= GRUB_CRYPTODISK_MODE_CBC
;
160 mode_iv
= GRUB_CRYPTODISK_MODE_IV_PLAIN
;
163 else if (grub_memcmp (ciphermode
, "cbc-", sizeof ("cbc-") - 1) == 0)
165 mode
= GRUB_CRYPTODISK_MODE_CBC
;
166 cipheriv
= ciphermode
+ sizeof ("cbc-") - 1;
168 else if (grub_memcmp (ciphermode
, "pcbc-", sizeof ("pcbc-") - 1) == 0)
170 mode
= GRUB_CRYPTODISK_MODE_PCBC
;
171 cipheriv
= ciphermode
+ sizeof ("pcbc-") - 1;
173 else if (grub_memcmp (ciphermode
, "xts-", sizeof ("xts-") - 1) == 0)
175 mode
= GRUB_CRYPTODISK_MODE_XTS
;
176 cipheriv
= ciphermode
+ sizeof ("xts-") - 1;
177 secondary_cipher
= grub_crypto_cipher_open (ciph
);
178 if (!secondary_cipher
)
180 grub_crypto_cipher_close (cipher
);
183 if (cipher
->cipher
->blocksize
!= GRUB_CRYPTODISK_GF_BYTES
)
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
);
191 if (secondary_cipher
->cipher
->blocksize
!= GRUB_CRYPTODISK_GF_BYTES
)
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
);
200 else if (grub_memcmp (ciphermode
, "lrw-", sizeof ("lrw-") - 1) == 0)
202 mode
= GRUB_CRYPTODISK_MODE_LRW
;
203 cipheriv
= ciphermode
+ sizeof ("lrw-") - 1;
204 if (cipher
->cipher
->blocksize
!= GRUB_CRYPTODISK_GF_BYTES
)
206 grub_error (GRUB_ERR_BAD_ARGUMENT
, "Unsupported LRW block size: %d",
207 cipher
->cipher
->blocksize
);
208 grub_crypto_cipher_close (cipher
);
214 grub_crypto_cipher_close (cipher
);
215 grub_error (GRUB_ERR_BAD_ARGUMENT
, "Unknown cipher mode: %s",
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)
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? */
233 (cipher
->cipher
->blocksize
<< benbi_log
) < GRUB_DISK_SECTOR_SIZE
;
235 mode_iv
= GRUB_CRYPTODISK_MODE_IV_BENBI
;
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)
241 char *hash_str
= cipheriv
+ 6;
243 mode_iv
= GRUB_CRYPTODISK_MODE_IV_ESSIV
;
245 /* Configure the hash and cipher used for ESSIV. */
246 essiv_hash
= grub_crypto_lookup_md_by_name (hash_str
);
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
);
255 essiv_cipher
= grub_crypto_cipher_open (ciph
);
258 grub_crypto_cipher_close (cipher
);
259 grub_crypto_cipher_close (secondary_cipher
);
265 grub_crypto_cipher_close (cipher
);
266 grub_crypto_cipher_close (secondary_cipher
);
267 grub_error (GRUB_ERR_BAD_ARGUMENT
, "Unknown IV mode: %s",
272 /* Configure the hash used for the AF splitter and HMAC. */
273 hash
= grub_crypto_lookup_md_by_name (hashspec
);
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",
284 newdev
= grub_zalloc (sizeof (struct grub_cryptodisk
));
287 grub_crypto_cipher_close (cipher
);
288 grub_crypto_cipher_close (essiv_cipher
);
289 grub_crypto_cipher_close (secondary_cipher
);
292 newdev
->cipher
= cipher
;
293 newdev
->offset
= grub_be_to_cpu32 (header
.payloadOffset
);
294 newdev
->source_disk
= NULL
;
295 newdev
->benbi_log
= benbi_log
;
297 newdev
->mode_iv
= mode_iv
;
298 newdev
->secondary_cipher
= secondary_cipher
;
299 newdev
->essiv_cipher
= essiv_cipher
;
300 newdev
->essiv_hash
= essiv_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
));
311 luks_recover_key (grub_disk_t source
,
312 grub_cryptodisk_t dev
)
314 struct grub_luks_phdr header
;
316 grub_uint8_t
*split_key
= NULL
;
317 char passphrase
[MAX_PASSPHRASE
] = "";
318 grub_uint8_t candidate_digest
[sizeof (header
.mkDigest
)];
322 grub_size_t max_stripes
= 1;
325 err
= grub_disk_read (source
, 0, 0, sizeof (header
), &header
);
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");
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
);
339 split_key
= grub_malloc (keysize
* max_stripes
);
343 /* Get the passphrase from the user. */
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
? : "",
351 if (!grub_password_get (passphrase
, MAX_PASSPHRASE
))
353 grub_free (split_key
);
354 return grub_error (GRUB_ERR_BAD_ARGUMENT
, "Passphrase not supplied");
357 /* Try to recover master key from each active keyslot. */
358 for (i
= 0; i
< ARRAY_SIZE (header
.keyblock
); i
++)
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
];
364 /* Check if keyslot is enabled. */
365 if (grub_be_to_cpu32 (header
.keyblock
[i
].active
) != LUKS_KEY_ENABLED
)
368 grub_dprintf ("luks", "Trying keyslot %d\n", i
);
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
].
381 grub_free (split_key
);
382 return grub_crypto_gcry_error (gcry_err
);
385 grub_dprintf ("luks", "PBKDF2 done\n");
387 gcry_err
= grub_cryptodisk_setkey (dev
, digest
, keysize
);
390 grub_free (split_key
);
391 return grub_crypto_gcry_error (gcry_err
);
394 length
= (keysize
* grub_be_to_cpu32 (header
.keyblock
[i
].stripes
));
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,
403 grub_free (split_key
);
407 gcry_err
= grub_cryptodisk_decrypt (dev
, split_key
, length
, 0);
410 grub_free (split_key
);
411 return grub_crypto_gcry_error (gcry_err
);
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
));
419 grub_free (split_key
);
420 return grub_crypto_gcry_error (gcry_err
);
423 grub_dprintf ("luks", "candidate key recovered\n");
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
),
429 sizeof (header
.mkDigestSalt
),
431 (header
.mkDigestIterations
),
433 sizeof (candidate_digest
));
436 grub_free (split_key
);
437 return grub_crypto_gcry_error (gcry_err
);
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)
445 grub_dprintf ("luks", "bad digest\n");
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
);
453 /* Set the master key. */
454 gcry_err
= grub_cryptodisk_setkey (dev
, candidate_key
, keysize
);
457 grub_free (split_key
);
458 return grub_crypto_gcry_error (gcry_err
);
461 grub_free (split_key
);
463 return GRUB_ERR_NONE
;
466 grub_free (split_key
);
467 return GRUB_ACCESS_DENIED
;
470 struct grub_cryptodisk_dev luks_crypto
= {
471 .scan
= configure_ciphers
,
472 .recover_key
= luks_recover_key
477 COMPILE_TIME_ASSERT (sizeof (((struct grub_luks_phdr
*) 0)->uuid
)
478 < GRUB_CRYPTODISK_MAX_UUID_LENGTH
);
479 grub_cryptodisk_dev_register (&luks_crypto
);
484 grub_cryptodisk_dev_unregister (&luks_crypto
);