]> git.proxmox.com Git - grub2.git/blob - grub-core/disk/luks2.c
894f155e6e746bfc88abb53b10344914aa6c920d
[grub2.git] / grub-core / disk / luks2.c
1 /*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2019 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 #include <base64.h>
31 #include <json.h>
32
33 GRUB_MOD_LICENSE ("GPLv3+");
34
35 #define LUKS_MAGIC_1ST "LUKS\xBA\xBE"
36 #define LUKS_MAGIC_2ND "SKUL\xBA\xBE"
37
38 #define MAX_PASSPHRASE 256
39
40 enum grub_luks2_kdf_type
41 {
42 LUKS2_KDF_TYPE_ARGON2I,
43 LUKS2_KDF_TYPE_PBKDF2
44 };
45 typedef enum grub_luks2_kdf_type grub_luks2_kdf_type_t;
46
47 /* On disk LUKS header */
48 struct grub_luks2_header
49 {
50 char magic[6];
51 grub_uint16_t version;
52 grub_uint64_t hdr_size;
53 grub_uint64_t seqid;
54 char label[48];
55 char csum_alg[32];
56 grub_uint8_t salt[64];
57 char uuid[40];
58 char subsystem[48];
59 grub_uint64_t hdr_offset;
60 char _padding[184];
61 grub_uint8_t csum[64];
62 char _padding4096[7*512];
63 } GRUB_PACKED;
64 typedef struct grub_luks2_header grub_luks2_header_t;
65
66 struct grub_luks2_keyslot
67 {
68 /* The integer key to the associative array of keyslots. */
69 grub_uint64_t idx;
70 grub_int64_t key_size;
71 grub_int64_t priority;
72 struct
73 {
74 const char *encryption;
75 grub_uint64_t offset;
76 grub_uint64_t size;
77 grub_int64_t key_size;
78 } area;
79 struct
80 {
81 const char *hash;
82 grub_int64_t stripes;
83 } af;
84 struct
85 {
86 grub_luks2_kdf_type_t type;
87 const char *salt;
88 union
89 {
90 struct
91 {
92 grub_int64_t time;
93 grub_int64_t memory;
94 grub_int64_t cpus;
95 } argon2i;
96 struct
97 {
98 const char *hash;
99 grub_int64_t iterations;
100 } pbkdf2;
101 } u;
102 } kdf;
103 };
104 typedef struct grub_luks2_keyslot grub_luks2_keyslot_t;
105
106 struct grub_luks2_segment
107 {
108 grub_uint64_t idx;
109 grub_uint64_t offset;
110 const char *size;
111 const char *encryption;
112 grub_int64_t sector_size;
113 };
114 typedef struct grub_luks2_segment grub_luks2_segment_t;
115
116 struct grub_luks2_digest
117 {
118 grub_uint64_t idx;
119 /* Both keyslots and segments are interpreted as bitfields here */
120 grub_uint64_t keyslots;
121 grub_uint64_t segments;
122 const char *salt;
123 const char *digest;
124 const char *hash;
125 grub_int64_t iterations;
126 };
127 typedef struct grub_luks2_digest grub_luks2_digest_t;
128
129 gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src,
130 grub_uint8_t * dst, grub_size_t blocksize,
131 grub_size_t blocknumbers);
132
133 static grub_err_t
134 luks2_parse_keyslot (grub_luks2_keyslot_t *out, const grub_json_t *keyslot)
135 {
136 grub_json_t area, af, kdf;
137 const char *type;
138
139 if (grub_json_getstring (&type, keyslot, "type"))
140 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing or invalid keyslot");
141 else if (grub_strcmp (type, "luks2"))
142 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported keyslot type %s", type);
143 else if (grub_json_getint64 (&out->key_size, keyslot, "key_size"))
144 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing keyslot information");
145 if (grub_json_getint64 (&out->priority, keyslot, "priority"))
146 out->priority = 1;
147
148 if (grub_json_getvalue (&area, keyslot, "area") ||
149 grub_json_getstring (&type, &area, "type"))
150 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing or invalid key area");
151 else if (grub_strcmp (type, "raw"))
152 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported key area type: %s", type);
153 else if (grub_json_getuint64 (&out->area.offset, &area, "offset") ||
154 grub_json_getuint64 (&out->area.size, &area, "size") ||
155 grub_json_getstring (&out->area.encryption, &area, "encryption") ||
156 grub_json_getint64 (&out->area.key_size, &area, "key_size"))
157 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing key area information");
158
159 if (grub_json_getvalue (&kdf, keyslot, "kdf") ||
160 grub_json_getstring (&type, &kdf, "type") ||
161 grub_json_getstring (&out->kdf.salt, &kdf, "salt"))
162 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing or invalid KDF");
163 else if (!grub_strcmp (type, "argon2i") || !grub_strcmp (type, "argon2id"))
164 {
165 out->kdf.type = LUKS2_KDF_TYPE_ARGON2I;
166 if (grub_json_getint64 (&out->kdf.u.argon2i.time, &kdf, "time") ||
167 grub_json_getint64 (&out->kdf.u.argon2i.memory, &kdf, "memory") ||
168 grub_json_getint64 (&out->kdf.u.argon2i.cpus, &kdf, "cpus"))
169 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing Argon2i parameters");
170 }
171 else if (!grub_strcmp (type, "pbkdf2"))
172 {
173 out->kdf.type = LUKS2_KDF_TYPE_PBKDF2;
174 if (grub_json_getstring (&out->kdf.u.pbkdf2.hash, &kdf, "hash") ||
175 grub_json_getint64 (&out->kdf.u.pbkdf2.iterations, &kdf, "iterations"))
176 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing PBKDF2 parameters");
177 }
178 else
179 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported KDF type %s", type);
180
181 if (grub_json_getvalue (&af, keyslot, "af") ||
182 grub_json_getstring (&type, &af, "type"))
183 return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing or invalid area");
184 if (grub_strcmp (type, "luks1"))
185 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported AF type %s", type);
186 if (grub_json_getint64 (&out->af.stripes, &af, "stripes") ||
187 grub_json_getstring (&out->af.hash, &af, "hash"))
188 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing AF parameters");
189
190 return GRUB_ERR_NONE;
191 }
192
193 static grub_err_t
194 luks2_parse_segment (grub_luks2_segment_t *out, const grub_json_t *segment)
195 {
196 const char *type;
197
198 if (grub_json_getstring (&type, segment, "type"))
199 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid segment type");
200 else if (grub_strcmp (type, "crypt"))
201 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported segment type %s", type);
202
203 if (grub_json_getuint64 (&out->offset, segment, "offset") ||
204 grub_json_getstring (&out->size, segment, "size") ||
205 grub_json_getstring (&out->encryption, segment, "encryption") ||
206 grub_json_getint64 (&out->sector_size, segment, "sector_size"))
207 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing segment parameters");
208
209 return GRUB_ERR_NONE;
210 }
211
212 static grub_err_t
213 luks2_parse_digest (grub_luks2_digest_t *out, const grub_json_t *digest)
214 {
215 grub_json_t segments, keyslots, o;
216 grub_size_t i, size;
217 grub_uint64_t bit;
218 const char *type;
219
220 if (grub_json_getstring (&type, digest, "type"))
221 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid digest type");
222 else if (grub_strcmp (type, "pbkdf2"))
223 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported digest type %s", type);
224
225 if (grub_json_getvalue (&segments, digest, "segments") ||
226 grub_json_getvalue (&keyslots, digest, "keyslots") ||
227 grub_json_getstring (&out->salt, digest, "salt") ||
228 grub_json_getstring (&out->digest, digest, "digest") ||
229 grub_json_getstring (&out->hash, digest, "hash") ||
230 grub_json_getint64 (&out->iterations, digest, "iterations"))
231 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing digest parameters");
232
233 if (grub_json_getsize (&size, &segments))
234 return grub_error (GRUB_ERR_BAD_ARGUMENT,
235 "Digest references no segments");
236
237 out->segments = 0;
238 for (i = 0; i < size; i++)
239 {
240 if (grub_json_getchild (&o, &segments, i) ||
241 grub_json_getuint64 (&bit, &o, NULL))
242 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid segment");
243 out->segments |= (1 << bit);
244 }
245
246 if (grub_json_getsize (&size, &keyslots))
247 return grub_error (GRUB_ERR_BAD_ARGUMENT,
248 "Digest references no keyslots");
249
250 out->keyslots = 0;
251 for (i = 0; i < size; i++)
252 {
253 if (grub_json_getchild (&o, &keyslots, i) ||
254 grub_json_getuint64 (&bit, &o, NULL))
255 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid keyslot");
256 out->keyslots |= (1 << bit);
257 }
258
259 return GRUB_ERR_NONE;
260 }
261
262 static grub_err_t
263 luks2_get_keyslot (grub_luks2_keyslot_t *k, grub_luks2_digest_t *d, grub_luks2_segment_t *s,
264 const grub_json_t *root, grub_size_t keyslot_json_idx)
265 {
266 grub_json_t keyslots, keyslot, digests, digest, segments, segment;
267 grub_size_t json_idx, size;
268
269 /* Get nth keyslot */
270 if (grub_json_getvalue (&keyslots, root, "keyslots") ||
271 grub_json_getchild (&keyslot, &keyslots, keyslot_json_idx) ||
272 grub_json_getuint64 (&k->idx, &keyslot, NULL) ||
273 grub_json_getchild (&keyslot, &keyslot, 0) ||
274 luks2_parse_keyslot (k, &keyslot))
275 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not parse keyslot index %"PRIuGRUB_SIZE, keyslot_json_idx);
276
277 /* Get digest that matches the keyslot. */
278 if (grub_json_getvalue (&digests, root, "digests") ||
279 grub_json_getsize (&size, &digests))
280 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not get digests");
281 for (json_idx = 0; json_idx < size; json_idx++)
282 {
283 if (grub_json_getchild (&digest, &digests, json_idx) ||
284 grub_json_getuint64 (&d->idx, &digest, NULL) ||
285 grub_json_getchild (&digest, &digest, 0) ||
286 luks2_parse_digest (d, &digest))
287 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not parse digest index %"PRIuGRUB_SIZE, json_idx);
288
289 if ((d->keyslots & (1 << k->idx)))
290 break;
291 }
292 if (json_idx == size)
293 return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No digest for keyslot \"%"PRIuGRUB_UINT64_T"\"", k->idx);
294
295 /* Get segment that matches the digest. */
296 if (grub_json_getvalue (&segments, root, "segments") ||
297 grub_json_getsize (&size, &segments))
298 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not get segments");
299 for (json_idx = 0; json_idx < size; json_idx++)
300 {
301 if (grub_json_getchild (&segment, &segments, json_idx) ||
302 grub_json_getuint64 (&s->idx, &segment, NULL) ||
303 grub_json_getchild (&segment, &segment, 0) ||
304 luks2_parse_segment (s, &segment))
305 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not parse segment index %"PRIuGRUB_SIZE, json_idx);
306
307 if ((d->segments & (1 << s->idx)))
308 break;
309 }
310 if (json_idx == size)
311 return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No segment for digest \"%"PRIuGRUB_UINT64_T"\"", d->idx);
312
313 return GRUB_ERR_NONE;
314 }
315
316 /* Determine whether to use primary or secondary header */
317 static grub_err_t
318 luks2_read_header (grub_disk_t disk, grub_luks2_header_t *outhdr)
319 {
320 grub_luks2_header_t primary, secondary, *header = &primary;
321 grub_err_t ret;
322
323 /* Read the primary LUKS header. */
324 ret = grub_disk_read (disk, 0, 0, sizeof (primary), &primary);
325 if (ret)
326 return ret;
327
328 /* Look for LUKS magic sequence. */
329 if (grub_memcmp (primary.magic, LUKS_MAGIC_1ST, sizeof (primary.magic)) ||
330 grub_be_to_cpu16 (primary.version) != 2)
331 return GRUB_ERR_BAD_SIGNATURE;
332
333 /* Read the secondary header. */
334 ret = grub_disk_read (disk, 0, grub_be_to_cpu64 (primary.hdr_size), sizeof (secondary), &secondary);
335 if (ret)
336 return ret;
337
338 /* Look for LUKS magic sequence. */
339 if (grub_memcmp (secondary.magic, LUKS_MAGIC_2ND, sizeof (secondary.magic)) ||
340 grub_be_to_cpu16 (secondary.version) != 2)
341 return GRUB_ERR_BAD_SIGNATURE;
342
343 if (grub_be_to_cpu64 (primary.seqid) < grub_be_to_cpu64 (secondary.seqid))
344 header = &secondary;
345 grub_memcpy (outhdr, header, sizeof (*header));
346
347 return GRUB_ERR_NONE;
348 }
349
350 static grub_cryptodisk_t
351 luks2_scan (grub_disk_t disk, const char *check_uuid, int check_boot)
352 {
353 grub_cryptodisk_t cryptodisk;
354 grub_luks2_header_t header;
355 char uuid[sizeof (header.uuid) + 1];
356 grub_size_t i, j;
357
358 if (check_boot)
359 return NULL;
360
361 if (luks2_read_header (disk, &header))
362 {
363 grub_errno = GRUB_ERR_NONE;
364 return NULL;
365 }
366
367 for (i = 0, j = 0; i < sizeof (header.uuid); i++)
368 if (header.uuid[i] != '-')
369 uuid[j++] = header.uuid[i];
370 uuid[j] = '\0';
371
372 if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0)
373 return NULL;
374
375 cryptodisk = grub_zalloc (sizeof (*cryptodisk));
376 if (!cryptodisk)
377 return NULL;
378
379 COMPILE_TIME_ASSERT (sizeof (cryptodisk->uuid) >= sizeof (uuid));
380 grub_memcpy (cryptodisk->uuid, uuid, sizeof (uuid));
381
382 cryptodisk->modname = "luks2";
383 return cryptodisk;
384 }
385
386 static grub_err_t
387 luks2_verify_key (grub_luks2_digest_t *d, grub_uint8_t *candidate_key,
388 grub_size_t candidate_key_len)
389 {
390 grub_uint8_t candidate_digest[GRUB_CRYPTODISK_MAX_KEYLEN];
391 grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN], salt[GRUB_CRYPTODISK_MAX_KEYLEN];
392 grub_size_t saltlen = sizeof (salt), digestlen = sizeof (digest);
393 const gcry_md_spec_t *hash;
394 gcry_err_code_t gcry_ret;
395
396 /* Decode both digest and salt */
397 if (!base64_decode (d->digest, grub_strlen (d->digest), (char *)digest, &digestlen))
398 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid digest");
399 if (!base64_decode (d->salt, grub_strlen (d->salt), (char *)salt, &saltlen))
400 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid digest salt");
401
402 /* Configure the hash used for the digest. */
403 hash = grub_crypto_lookup_md_by_name (d->hash);
404 if (!hash)
405 return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", d->hash);
406
407 /* Calculate the candidate key's digest */
408 gcry_ret = grub_crypto_pbkdf2 (hash,
409 candidate_key, candidate_key_len,
410 salt, saltlen,
411 d->iterations,
412 candidate_digest, digestlen);
413 if (gcry_ret)
414 return grub_crypto_gcry_error (gcry_ret);
415
416 if (grub_memcmp (candidate_digest, digest, digestlen) != 0)
417 return grub_error (GRUB_ERR_ACCESS_DENIED, "Mismatching digests");
418
419 return GRUB_ERR_NONE;
420 }
421
422 static grub_err_t
423 luks2_decrypt_key (grub_uint8_t *out_key,
424 grub_disk_t source, grub_cryptodisk_t crypt,
425 grub_luks2_keyslot_t *k,
426 const grub_uint8_t *passphrase, grub_size_t passphraselen)
427 {
428 grub_uint8_t area_key[GRUB_CRYPTODISK_MAX_KEYLEN];
429 grub_uint8_t salt[GRUB_CRYPTODISK_MAX_KEYLEN];
430 grub_uint8_t *split_key = NULL;
431 grub_size_t saltlen = sizeof (salt);
432 char cipher[32], *p;
433 const gcry_md_spec_t *hash;
434 gcry_err_code_t gcry_ret;
435 grub_err_t ret;
436
437 if (!base64_decode (k->kdf.salt, grub_strlen (k->kdf.salt),
438 (char *)salt, &saltlen))
439 {
440 ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid keyslot salt");
441 goto err;
442 }
443
444 /* Calculate the binary area key of the user supplied passphrase. */
445 switch (k->kdf.type)
446 {
447 case LUKS2_KDF_TYPE_ARGON2I:
448 ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Argon2 not supported");
449 goto err;
450 case LUKS2_KDF_TYPE_PBKDF2:
451 hash = grub_crypto_lookup_md_by_name (k->kdf.u.pbkdf2.hash);
452 if (!hash)
453 {
454 ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash",
455 k->kdf.u.pbkdf2.hash);
456 goto err;
457 }
458
459 gcry_ret = grub_crypto_pbkdf2 (hash, (grub_uint8_t *) passphrase,
460 passphraselen,
461 salt, saltlen,
462 k->kdf.u.pbkdf2.iterations,
463 area_key, k->area.key_size);
464 if (gcry_ret)
465 {
466 ret = grub_crypto_gcry_error (gcry_ret);
467 goto err;
468 }
469
470 break;
471 }
472
473 /* Set up disk encryption parameters for the key area */
474 grub_strncpy (cipher, k->area.encryption, sizeof (cipher));
475 p = grub_memchr (cipher, '-', grub_strlen (cipher));
476 if (!p)
477 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid encryption");
478 *p = '\0';
479
480 ret = grub_cryptodisk_setcipher (crypt, cipher, p + 1);
481 if (ret)
482 return ret;
483
484 gcry_ret = grub_cryptodisk_setkey (crypt, area_key, k->area.key_size);
485 if (gcry_ret)
486 {
487 ret = grub_crypto_gcry_error (gcry_ret);
488 goto err;
489 }
490
491 /* Read and decrypt the binary key area with the area key. */
492 split_key = grub_malloc (k->area.size);
493 if (!split_key)
494 {
495 ret = grub_errno;
496 goto err;
497 }
498
499 grub_errno = GRUB_ERR_NONE;
500 ret = grub_disk_read (source, 0, k->area.offset, k->area.size, split_key);
501 if (ret)
502 {
503 grub_error (GRUB_ERR_IO, "Read error: %s\n", grub_errmsg);
504 goto err;
505 }
506
507 /*
508 * The key slots area is always encrypted in 512-byte sectors,
509 * regardless of encrypted data sector size.
510 */
511 gcry_ret = grub_cryptodisk_decrypt (crypt, split_key, k->area.size, 0,
512 GRUB_LUKS1_LOG_SECTOR_SIZE);
513 if (gcry_ret)
514 {
515 ret = grub_crypto_gcry_error (gcry_ret);
516 goto err;
517 }
518
519 /* Configure the hash used for anti-forensic merging. */
520 hash = grub_crypto_lookup_md_by_name (k->af.hash);
521 if (!hash)
522 {
523 ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash",
524 k->af.hash);
525 goto err;
526 }
527
528 /* Merge the decrypted key material to get the candidate master key. */
529 gcry_ret = AF_merge (hash, split_key, out_key, k->key_size, k->af.stripes);
530 if (gcry_ret)
531 {
532 ret = grub_crypto_gcry_error (gcry_ret);
533 goto err;
534 }
535
536 grub_dprintf ("luks2", "Candidate key recovered\n");
537
538 err:
539 grub_free (split_key);
540 return ret;
541 }
542
543 static grub_err_t
544 luks2_recover_key (grub_disk_t source,
545 grub_cryptodisk_t crypt)
546 {
547 grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN];
548 char passphrase[MAX_PASSPHRASE], cipher[32];
549 char *json_header = NULL, *part = NULL, *ptr;
550 grub_size_t candidate_key_len = 0, json_idx, size;
551 grub_luks2_header_t header;
552 grub_luks2_keyslot_t keyslot;
553 grub_luks2_digest_t digest;
554 grub_luks2_segment_t segment;
555 gcry_err_code_t gcry_ret;
556 grub_json_t *json = NULL, keyslots;
557 grub_err_t ret;
558
559 ret = luks2_read_header (source, &header);
560 if (ret)
561 return ret;
562
563 json_header = grub_zalloc (grub_be_to_cpu64 (header.hdr_size) - sizeof (header));
564 if (!json_header)
565 return GRUB_ERR_OUT_OF_MEMORY;
566
567 /* Read the JSON area. */
568 ret = grub_disk_read (source, 0, grub_be_to_cpu64 (header.hdr_offset) + sizeof (header),
569 grub_be_to_cpu64 (header.hdr_size) - sizeof (header), json_header);
570 if (ret)
571 goto err;
572
573 ptr = grub_memchr (json_header, 0, grub_be_to_cpu64 (header.hdr_size) - sizeof (header));
574 if (!ptr)
575 goto err;
576
577 ret = grub_json_parse (&json, json_header, grub_be_to_cpu64 (header.hdr_size));
578 if (ret)
579 {
580 ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid LUKS2 JSON header");
581 goto err;
582 }
583
584 /* Get the passphrase from the user. */
585 if (source->partition)
586 part = grub_partition_get_name (source->partition);
587 grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
588 source->partition ? "," : "", part ? : "",
589 crypt->uuid);
590 if (!grub_password_get (passphrase, MAX_PASSPHRASE))
591 {
592 ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
593 goto err;
594 }
595
596 if (grub_json_getvalue (&keyslots, json, "keyslots") ||
597 grub_json_getsize (&size, &keyslots))
598 {
599 ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not get keyslots");
600 goto err;
601 }
602
603 if (grub_disk_native_sectors (source) == GRUB_DISK_SIZE_UNKNOWN)
604 {
605 /* FIXME: Allow use of source disk, and maybe cause errors in read. */
606 grub_dprintf ("luks2", "Source disk %s has an unknown size, "
607 "conservatively returning error\n", source->name);
608 ret = grub_error (GRUB_ERR_BUG, "Unknown size of luks2 source device");
609 goto err;
610 }
611
612 /* Try all keyslot */
613 for (json_idx = 0; json_idx < size; json_idx++)
614 {
615 typeof (source->total_sectors) max_crypt_sectors = 0;
616
617 grub_errno = GRUB_ERR_NONE;
618 ret = luks2_get_keyslot (&keyslot, &digest, &segment, json, json_idx);
619 if (ret)
620 goto err;
621 if (grub_errno != GRUB_ERR_NONE)
622 grub_dprintf ("luks2", "Ignoring unhandled error %d from luks2_get_keyslot\n", grub_errno);
623
624 if (keyslot.priority == 0)
625 {
626 grub_dprintf ("luks2", "Ignoring keyslot \"%"PRIuGRUB_UINT64_T"\" due to priority\n", keyslot.idx);
627 continue;
628 }
629
630 grub_dprintf ("luks2", "Trying keyslot \"%"PRIuGRUB_UINT64_T"\"\n", keyslot.idx);
631
632 /* Sector size should be one of 512, 1024, 2048, or 4096. */
633 if (!(segment.sector_size == 512 || segment.sector_size == 1024 ||
634 segment.sector_size == 2048 || segment.sector_size == 4096))
635 {
636 grub_dprintf ("luks2", "Segment \"%"PRIuGRUB_UINT64_T"\" sector"
637 " size %"PRIuGRUB_UINT64_T" is not one of"
638 " 512, 1024, 2048, or 4096\n",
639 segment.idx, segment.sector_size);
640 continue;
641 }
642
643 /* Set up disk according to keyslot's segment. */
644 crypt->offset_sectors = grub_divmod64 (segment.offset, segment.sector_size, NULL);
645 crypt->log_sector_size = sizeof (unsigned int) * 8
646 - __builtin_clz ((unsigned int) segment.sector_size) - 1;
647 /* Set to the source disk/partition size, which is the maximum we allow. */
648 max_crypt_sectors = grub_disk_native_sectors (source);
649 max_crypt_sectors = grub_convert_sector (max_crypt_sectors, GRUB_DISK_SECTOR_BITS,
650 crypt->log_sector_size);
651
652 if (max_crypt_sectors < crypt->offset_sectors)
653 {
654 grub_dprintf ("luks2", "Segment \"%"PRIuGRUB_UINT64_T"\" has offset"
655 " %"PRIuGRUB_UINT64_T" which is greater than"
656 " source disk size %"PRIuGRUB_UINT64_T","
657 " skipping\n", segment.idx, crypt->offset_sectors,
658 max_crypt_sectors);
659 continue;
660 }
661
662 if (grub_strcmp (segment.size, "dynamic") == 0)
663 crypt->total_sectors = max_crypt_sectors - crypt->offset_sectors;
664 else
665 {
666 grub_errno = GRUB_ERR_NONE;
667
668 /* Convert segment.size to sectors, rounding up to nearest sector */
669 crypt->total_sectors = grub_strtoull (segment.size, NULL, 10);
670
671 if (grub_errno == GRUB_ERR_NONE)
672 {
673 crypt->total_sectors = ALIGN_UP (crypt->total_sectors,
674 1 << crypt->log_sector_size);
675 crypt->total_sectors >>= crypt->log_sector_size;
676 }
677 else if (grub_errno == GRUB_ERR_BAD_NUMBER)
678 {
679 grub_dprintf ("luks2", "Segment \"%"PRIuGRUB_UINT64_T"\" size"
680 " \"%s\" is not a parsable number,"
681 " skipping keyslot\n",
682 segment.idx, segment.size);
683 continue;
684 }
685 else if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
686 {
687 /*
688 * There was an overflow in parsing segment.size, so disk must
689 * be very large or the string is incorrect.
690 *
691 * TODO: Allow reading of at least up max_crypt_sectors. Really,
692 * its very unlikely one would be booting from such a large drive
693 * anyway. Use another smaller LUKS2 boot device.
694 */
695 grub_dprintf ("luks2", "Segment \"%"PRIuGRUB_UINT64_T"\" size"
696 " %s overflowed 64-bit unsigned integer,"
697 " skipping keyslot\n", segment.idx, segment.size);
698 continue;
699 }
700 }
701
702 if (crypt->total_sectors == 0)
703 {
704 grub_dprintf ("luks2", "Segment \"%"PRIuGRUB_UINT64_T"\" has zero"
705 " sectors, skipping\n", segment.idx);
706 continue;
707 }
708 else if (max_crypt_sectors < (crypt->offset_sectors + crypt->total_sectors))
709 {
710 grub_dprintf ("luks2", "Segment \"%"PRIuGRUB_UINT64_T"\" has last"
711 " data position greater than source disk size,"
712 " the end of the crypto device will be"
713 " inaccessible\n", segment.idx);
714
715 /* Allow decryption up to the end of the source disk. */
716 crypt->total_sectors = max_crypt_sectors - crypt->offset_sectors;
717 }
718
719 ret = luks2_decrypt_key (candidate_key, source, crypt, &keyslot,
720 (const grub_uint8_t *) passphrase, grub_strlen (passphrase));
721 if (ret)
722 {
723 grub_dprintf ("luks2", "Decryption with keyslot \"%"PRIuGRUB_UINT64_T"\" failed: %s\n",
724 keyslot.idx, grub_errmsg);
725 continue;
726 }
727
728 ret = luks2_verify_key (&digest, candidate_key, keyslot.key_size);
729 if (ret)
730 {
731 grub_dprintf ("luks2", "Could not open keyslot \"%"PRIuGRUB_UINT64_T"\": %s\n",
732 keyslot.idx, grub_errmsg);
733 continue;
734 }
735
736 /*
737 * TRANSLATORS: It's a cryptographic key slot: one element of an array
738 * where each element is either empty or holds a key.
739 */
740 grub_printf_ (N_("Slot \"%"PRIuGRUB_UINT64_T"\" opened\n"), keyslot.idx);
741
742 candidate_key_len = keyslot.key_size;
743 break;
744 }
745 if (candidate_key_len == 0)
746 {
747 ret = grub_error (GRUB_ERR_ACCESS_DENIED, "Invalid passphrase");
748 goto err;
749 }
750
751 /* Set up disk cipher. */
752 grub_strncpy (cipher, segment.encryption, sizeof (cipher));
753 ptr = grub_memchr (cipher, '-', grub_strlen (cipher));
754 if (!ptr)
755 return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid encryption");
756 *ptr = '\0';
757
758 ret = grub_cryptodisk_setcipher (crypt, cipher, ptr + 1);
759 if (ret)
760 goto err;
761
762 /* Set the master key. */
763 gcry_ret = grub_cryptodisk_setkey (crypt, candidate_key, candidate_key_len);
764 if (gcry_ret)
765 {
766 ret = grub_crypto_gcry_error (gcry_ret);
767 goto err;
768 }
769
770 err:
771 grub_free (part);
772 grub_free (json_header);
773 grub_json_free (json);
774 return ret;
775 }
776
777 static struct grub_cryptodisk_dev luks2_crypto = {
778 .scan = luks2_scan,
779 .recover_key = luks2_recover_key
780 };
781
782 GRUB_MOD_INIT (luks2)
783 {
784 grub_cryptodisk_dev_register (&luks2_crypto);
785 }
786
787 GRUB_MOD_FINI (luks2)
788 {
789 grub_cryptodisk_dev_unregister (&luks2_crypto);
790 }