/src/cryptsetup/lib/luks1/keymanage.c
Line | Count | Source |
1 | | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | | /* |
3 | | * LUKS - Linux Unified Key Setup |
4 | | * |
5 | | * Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org> |
6 | | * Copyright (C) 2009-2026 Red Hat, Inc. All rights reserved. |
7 | | * Copyright (C) 2013-2026 Milan Broz |
8 | | */ |
9 | | |
10 | | #include <sys/types.h> |
11 | | #include <sys/stat.h> |
12 | | #include <errno.h> |
13 | | #include <unistd.h> |
14 | | #include <stdio.h> |
15 | | #include <stdlib.h> |
16 | | #include <string.h> |
17 | | #include <ctype.h> |
18 | | #include <uuid/uuid.h> |
19 | | #include <limits.h> |
20 | | |
21 | | #include "luks.h" |
22 | | #include "af.h" |
23 | | #include "internal.h" |
24 | | |
25 | | int LUKS_keyslot_area(const struct luks_phdr *hdr, |
26 | | int keyslot, |
27 | | uint64_t *offset, |
28 | | uint64_t *length) |
29 | 0 | { |
30 | 0 | if (keyslot >= LUKS_NUMKEYS || keyslot < 0) |
31 | 0 | return -EINVAL; |
32 | | |
33 | 0 | *offset = (uint64_t)hdr->keyblock[keyslot].keyMaterialOffset * SECTOR_SIZE; |
34 | 0 | *length = AF_split_sectors(hdr->keyBytes, LUKS_STRIPES) * SECTOR_SIZE; |
35 | |
|
36 | 0 | return 0; |
37 | 0 | } |
38 | | |
39 | | /* insertsort: because the array has 8 elements and it's mostly sorted. that's why */ |
40 | | static void LUKS_sort_keyslots(const struct luks_phdr *hdr, int *array) |
41 | 515 | { |
42 | 515 | int i, j, x; |
43 | | |
44 | 4.12k | for (i = 1; i < LUKS_NUMKEYS; i++) { |
45 | 3.60k | j = i; |
46 | 7.59k | while (j > 0 && hdr->keyblock[array[j-1]].keyMaterialOffset > hdr->keyblock[array[j]].keyMaterialOffset) { |
47 | 3.99k | x = array[j]; |
48 | 3.99k | array[j] = array[j-1]; |
49 | 3.99k | array[j-1] = x; |
50 | 3.99k | j--; |
51 | 3.99k | } |
52 | 3.60k | } |
53 | 515 | } |
54 | | |
55 | | static int _is_not_lower(char *str, unsigned max_len) |
56 | 0 | { |
57 | 0 | for(; *str && max_len; str++, max_len--) |
58 | 0 | if (isupper(*str)) |
59 | 0 | return 1; |
60 | 0 | return 0; |
61 | 0 | } |
62 | | |
63 | | static int _to_lower(char *str, unsigned max_len) |
64 | 0 | { |
65 | 0 | int r = 0; |
66 | |
|
67 | 0 | for(; *str && max_len; str++, max_len--) |
68 | 0 | if (isupper(*str)) { |
69 | 0 | *str = tolower(*str); |
70 | 0 | r = 1; |
71 | 0 | } |
72 | |
|
73 | 0 | return r; |
74 | 0 | } |
75 | | |
76 | | size_t LUKS_device_sectors(const struct luks_phdr *hdr) |
77 | 116 | { |
78 | 116 | int sorted_areas[LUKS_NUMKEYS] = { 0, 1, 2, 3, 4, 5, 6, 7 }; |
79 | | |
80 | 116 | LUKS_sort_keyslots(hdr, sorted_areas); |
81 | | |
82 | 116 | return hdr->keyblock[sorted_areas[LUKS_NUMKEYS-1]].keyMaterialOffset + AF_split_sectors(hdr->keyBytes, LUKS_STRIPES); |
83 | 116 | } |
84 | | |
85 | | size_t LUKS_keyslots_offset(const struct luks_phdr *hdr) |
86 | 0 | { |
87 | 0 | int sorted_areas[LUKS_NUMKEYS] = { 0, 1, 2, 3, 4, 5, 6, 7 }; |
88 | |
|
89 | 0 | LUKS_sort_keyslots(hdr, sorted_areas); |
90 | |
|
91 | 0 | return hdr->keyblock[sorted_areas[0]].keyMaterialOffset; |
92 | 0 | } |
93 | | |
94 | | static int LUKS_check_device_size(struct crypt_device *ctx, const struct luks_phdr *hdr, int falloc) |
95 | 116 | { |
96 | 116 | struct device *device = crypt_metadata_device(ctx); |
97 | 116 | uint64_t dev_sectors, hdr_sectors; |
98 | | |
99 | 116 | if (!hdr->keyBytes) |
100 | 0 | return -EINVAL; |
101 | | |
102 | 116 | if (device_size(device, &dev_sectors)) { |
103 | 0 | log_dbg(ctx, "Cannot get device size for device %s.", device_path(device)); |
104 | 0 | return -EIO; |
105 | 0 | } |
106 | | |
107 | 116 | dev_sectors >>= SECTOR_SHIFT; |
108 | 116 | hdr_sectors = LUKS_device_sectors(hdr); |
109 | 116 | log_dbg(ctx, "Key length %u, device size %" PRIu64 " sectors, header size %" |
110 | 116 | PRIu64 " sectors.", hdr->keyBytes, dev_sectors, hdr_sectors); |
111 | | |
112 | 116 | if (hdr_sectors > dev_sectors) { |
113 | | /* If it is header file, increase its size */ |
114 | 94 | if (falloc && !device_fallocate(device, hdr_sectors << SECTOR_SHIFT)) |
115 | 0 | return 0; |
116 | | |
117 | 94 | log_err(ctx, _("Device %s is too small. (LUKS1 requires at least %" PRIu64 " bytes.)"), |
118 | 94 | device_path(device), hdr_sectors * SECTOR_SIZE); |
119 | 94 | return -EINVAL; |
120 | 94 | } |
121 | | |
122 | 22 | return 0; |
123 | 116 | } |
124 | | |
125 | | static int LUKS_check_keyslots(struct crypt_device *ctx, const struct luks_phdr *phdr) |
126 | 633 | { |
127 | 633 | int i, prev, next, sorted_areas[LUKS_NUMKEYS] = { 0, 1, 2, 3, 4, 5, 6, 7 }; |
128 | 633 | uint32_t secs_per_stripes = AF_split_sectors(phdr->keyBytes, LUKS_STRIPES); |
129 | | |
130 | 633 | if (!secs_per_stripes) { |
131 | 234 | log_dbg(ctx, "Invalid volume key size."); |
132 | 234 | return -1; |
133 | 234 | } |
134 | | |
135 | 399 | LUKS_sort_keyslots(phdr, sorted_areas); |
136 | | |
137 | | /* Check keyslot to prevent access outside of header and keyslot area */ |
138 | 1.43k | for (i = 0; i < LUKS_NUMKEYS; i++) { |
139 | | /* enforce stripes == 4000 */ |
140 | 1.31k | if (phdr->keyblock[i].stripes != LUKS_STRIPES) { |
141 | 254 | log_dbg(ctx, "Invalid stripes count %u in keyslot %u.", |
142 | 254 | phdr->keyblock[i].stripes, i); |
143 | 254 | log_err(ctx, _("LUKS keyslot %u is invalid."), i); |
144 | 254 | return -1; |
145 | 254 | } |
146 | | |
147 | | /* First sectors is the header itself */ |
148 | 1.06k | if (phdr->keyblock[i].keyMaterialOffset * SECTOR_SIZE < sizeof(*phdr)) { |
149 | 1 | log_dbg(ctx, "Invalid offset %u in keyslot %u.", |
150 | 1 | phdr->keyblock[i].keyMaterialOffset, i); |
151 | 1 | log_err(ctx, _("LUKS keyslot %u is invalid."), i); |
152 | 1 | return -1; |
153 | 1 | } |
154 | | |
155 | | /* Ignore following check for detached header where offset can be zero. */ |
156 | 1.06k | if (phdr->payloadOffset == 0) |
157 | 235 | continue; |
158 | | |
159 | 829 | if (phdr->payloadOffset <= phdr->keyblock[i].keyMaterialOffset) { |
160 | 10 | log_dbg(ctx, "Invalid offset %u in keyslot %u (beyond data area offset %u).", |
161 | 10 | phdr->keyblock[i].keyMaterialOffset, i, |
162 | 10 | phdr->payloadOffset); |
163 | 10 | log_err(ctx, _("LUKS keyslot %u is invalid."), i); |
164 | 10 | return -1; |
165 | 10 | } |
166 | | |
167 | 819 | if (phdr->payloadOffset < (phdr->keyblock[i].keyMaterialOffset + secs_per_stripes)) { |
168 | 14 | log_dbg(ctx, "Invalid keyslot size %u (offset %u, stripes %u) in " |
169 | 14 | "keyslot %u (beyond data area offset %u).", |
170 | 14 | secs_per_stripes, |
171 | 14 | phdr->keyblock[i].keyMaterialOffset, |
172 | 14 | phdr->keyblock[i].stripes, |
173 | 14 | i, phdr->payloadOffset); |
174 | 14 | log_err(ctx, _("LUKS keyslot %u is invalid."), i); |
175 | 14 | return -1; |
176 | 14 | } |
177 | 819 | } |
178 | | |
179 | | /* check no keyslot overlaps with each other */ |
180 | 938 | for (i = 1; i < LUKS_NUMKEYS; i++) { |
181 | 822 | prev = sorted_areas[i-1]; |
182 | 822 | next = sorted_areas[i]; |
183 | 822 | if (phdr->keyblock[next].keyMaterialOffset < |
184 | 822 | (phdr->keyblock[prev].keyMaterialOffset + secs_per_stripes)) { |
185 | 4 | log_dbg(ctx, "Not enough space in LUKS keyslot %d.", prev); |
186 | 4 | log_err(ctx, _("LUKS keyslot %u is invalid."), prev); |
187 | 4 | return -1; |
188 | 4 | } |
189 | 822 | } |
190 | | /* do not check last keyslot on purpose, it must be tested in device size check */ |
191 | | |
192 | 116 | return 0; |
193 | 120 | } |
194 | | |
195 | | static const char *dbg_slot_state(crypt_keyslot_info ki) |
196 | 0 | { |
197 | 0 | switch(ki) { |
198 | 0 | case CRYPT_SLOT_INACTIVE: |
199 | 0 | return "INACTIVE"; |
200 | 0 | case CRYPT_SLOT_ACTIVE: |
201 | 0 | return "ACTIVE"; |
202 | 0 | case CRYPT_SLOT_ACTIVE_LAST: |
203 | 0 | return "ACTIVE_LAST"; |
204 | 0 | case CRYPT_SLOT_INVALID: |
205 | 0 | default: |
206 | 0 | return "INVALID"; |
207 | 0 | } |
208 | 0 | } |
209 | | |
210 | | int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx) |
211 | 0 | { |
212 | 0 | struct device *device = crypt_metadata_device(ctx); |
213 | 0 | struct luks_phdr hdr; |
214 | 0 | int fd, devfd, r = 0; |
215 | 0 | size_t hdr_size; |
216 | 0 | size_t buffer_size; |
217 | 0 | ssize_t ret; |
218 | 0 | char *buffer = NULL; |
219 | |
|
220 | 0 | r = LUKS_read_phdr(&hdr, 1, 0, ctx); |
221 | 0 | if (r) |
222 | 0 | return r; |
223 | | |
224 | 0 | hdr_size = LUKS_device_sectors(&hdr) << SECTOR_SHIFT; |
225 | 0 | buffer_size = size_round_up(hdr_size, crypt_getpagesize()); |
226 | |
|
227 | 0 | buffer = malloc(buffer_size); |
228 | 0 | if (!buffer || hdr_size < LUKS_ALIGN_KEYSLOTS || hdr_size > buffer_size) { |
229 | 0 | r = -ENOMEM; |
230 | 0 | goto out; |
231 | 0 | } |
232 | 0 | memset(buffer, 0, buffer_size); |
233 | |
|
234 | 0 | log_dbg(ctx, "Storing backup of header (%zu bytes) and keyslot area (%zu bytes).", |
235 | 0 | sizeof(hdr), hdr_size - LUKS_ALIGN_KEYSLOTS); |
236 | |
|
237 | 0 | log_dbg(ctx, "Output backup file size: %zu bytes.", buffer_size); |
238 | |
|
239 | 0 | devfd = device_open(ctx, device, O_RDONLY); |
240 | 0 | if (devfd < 0) { |
241 | 0 | log_err(ctx, _("Device %s is not a valid LUKS device."), device_path(device)); |
242 | 0 | r = -EINVAL; |
243 | 0 | goto out; |
244 | 0 | } |
245 | | |
246 | 0 | if (read_lseek_blockwise(devfd, device_block_size(ctx, device), device_alignment(device), |
247 | 0 | buffer, hdr_size, 0) < (ssize_t)hdr_size) { |
248 | 0 | r = -EIO; |
249 | 0 | goto out; |
250 | 0 | } |
251 | | |
252 | | /* Wipe unused area, so backup cannot contain old signatures */ |
253 | 0 | if (hdr.keyblock[0].keyMaterialOffset * SECTOR_SIZE == LUKS_ALIGN_KEYSLOTS) |
254 | 0 | memset(buffer + sizeof(hdr), 0, LUKS_ALIGN_KEYSLOTS - sizeof(hdr)); |
255 | |
|
256 | 0 | fd = open(backup_file, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR); |
257 | 0 | if (fd == -1) { |
258 | 0 | if (errno == EEXIST) |
259 | 0 | log_err(ctx, _("Requested header backup file %s already exists."), backup_file); |
260 | 0 | else |
261 | 0 | log_err(ctx, _("Cannot create header backup file %s."), backup_file); |
262 | 0 | r = -EINVAL; |
263 | 0 | goto out; |
264 | 0 | } |
265 | 0 | ret = write_buffer(fd, buffer, buffer_size); |
266 | 0 | close(fd); |
267 | 0 | if (ret < (ssize_t)buffer_size) { |
268 | 0 | log_err(ctx, _("Cannot write header backup file %s."), backup_file); |
269 | 0 | r = -EIO; |
270 | 0 | goto out; |
271 | 0 | } |
272 | | |
273 | 0 | r = 0; |
274 | 0 | out: |
275 | 0 | crypt_safe_memzero(&hdr, sizeof(hdr)); |
276 | 0 | crypt_safe_memzero(buffer, buffer_size); |
277 | 0 | free(buffer); |
278 | 0 | return r; |
279 | 0 | } |
280 | | |
281 | | int LUKS_hdr_restore( |
282 | | struct device *backup_device, |
283 | | struct luks_phdr *hdr, |
284 | | struct crypt_device *ctx) |
285 | 0 | { |
286 | 0 | struct device *device = crypt_metadata_device(ctx); |
287 | 0 | int fd, r = 0, devfd = -1, diff_uuid = 0; |
288 | 0 | ssize_t ret, buffer_size = 0; |
289 | 0 | char *buffer = NULL, msg[200]; |
290 | 0 | struct luks_phdr hdr_file; |
291 | |
|
292 | 0 | r = LUKS_read_phdr_backup(backup_device, &hdr_file, 0, ctx); |
293 | 0 | if (r == -ENOENT) |
294 | 0 | return r; |
295 | | |
296 | 0 | if (!r) |
297 | 0 | buffer_size = LUKS_device_sectors(&hdr_file) << SECTOR_SHIFT; |
298 | |
|
299 | 0 | if (r || buffer_size < LUKS_ALIGN_KEYSLOTS) { |
300 | 0 | log_err(ctx, _("Backup file does not contain valid LUKS header.")); |
301 | 0 | r = -EINVAL; |
302 | 0 | goto out; |
303 | 0 | } |
304 | | |
305 | 0 | buffer = malloc(buffer_size); |
306 | 0 | if (!buffer) { |
307 | 0 | r = -ENOMEM; |
308 | 0 | goto out; |
309 | 0 | } |
310 | | |
311 | 0 | fd = device_open(ctx, backup_device, O_RDONLY); |
312 | 0 | if (fd == -1) { |
313 | 0 | log_err(ctx, _("Cannot open header backup file %s."), device_path(backup_device)); |
314 | 0 | r = -EINVAL; |
315 | 0 | goto out; |
316 | 0 | } |
317 | | |
318 | 0 | ret = read_lseek_blockwise(fd, device_block_size(ctx, backup_device), |
319 | 0 | device_alignment(backup_device), buffer, buffer_size, 0); |
320 | 0 | if (ret < buffer_size) { |
321 | 0 | log_err(ctx, _("Cannot read header backup file %s."), device_path(backup_device)); |
322 | 0 | r = -EIO; |
323 | 0 | goto out; |
324 | 0 | } |
325 | | |
326 | 0 | r = LUKS_read_phdr(hdr, 0, 0, ctx); |
327 | 0 | if (r == 0) { |
328 | 0 | log_dbg(ctx, "Device %s already contains LUKS header, checking UUID and offset.", device_path(device)); |
329 | 0 | if(hdr->payloadOffset != hdr_file.payloadOffset || |
330 | 0 | hdr->keyBytes != hdr_file.keyBytes) { |
331 | 0 | log_err(ctx, _("Data offset or key size differs on device and backup, restore failed.")); |
332 | 0 | r = -EINVAL; |
333 | 0 | goto out; |
334 | 0 | } |
335 | 0 | if (memcmp(hdr->uuid, hdr_file.uuid, UUID_STRING_L)) |
336 | 0 | diff_uuid = 1; |
337 | 0 | } |
338 | | |
339 | 0 | if (snprintf(msg, sizeof(msg), _("Device %s %s%s"), device_path(device), |
340 | 0 | r ? _("does not contain LUKS header. Replacing header can destroy data on that device.") : |
341 | 0 | _("already contains LUKS header. Replacing header will destroy existing keyslots."), |
342 | 0 | diff_uuid ? _("\nWARNING: real device header has different UUID than backup!") : "") < 0) { |
343 | 0 | r = -ENOMEM; |
344 | 0 | goto out; |
345 | 0 | } |
346 | | |
347 | 0 | if (!crypt_confirm(ctx, msg)) { |
348 | 0 | r = -EINVAL; |
349 | 0 | goto out; |
350 | 0 | } |
351 | | |
352 | 0 | log_dbg(ctx, "Storing backup of header (%zu bytes) and keyslot area (%zu bytes) to device %s.", |
353 | 0 | sizeof(*hdr), buffer_size - LUKS_ALIGN_KEYSLOTS, device_path(device)); |
354 | |
|
355 | 0 | devfd = device_open(ctx, device, O_RDWR); |
356 | 0 | if (devfd < 0) { |
357 | 0 | if (errno == EACCES) |
358 | 0 | log_err(ctx, _("Cannot write to device %s, permission denied."), |
359 | 0 | device_path(device)); |
360 | 0 | else |
361 | 0 | log_err(ctx, _("Cannot open device %s."), device_path(device)); |
362 | 0 | r = -EINVAL; |
363 | 0 | goto out; |
364 | 0 | } |
365 | | |
366 | 0 | if (write_lseek_blockwise(devfd, device_block_size(ctx, device), device_alignment(device), |
367 | 0 | buffer, buffer_size, 0) < buffer_size) { |
368 | 0 | r = -EIO; |
369 | 0 | goto out; |
370 | 0 | } |
371 | | |
372 | | /* Be sure to reload new data */ |
373 | 0 | r = LUKS_read_phdr(hdr, 1, 0, ctx); |
374 | 0 | out: |
375 | 0 | device_sync(ctx, device); |
376 | 0 | crypt_safe_memzero(buffer, buffer_size); |
377 | 0 | free(buffer); |
378 | 0 | return r; |
379 | 0 | } |
380 | | |
381 | | /* This routine should do some just basic recovery for known problems. */ |
382 | | static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx) |
383 | 0 | { |
384 | 0 | struct luks_phdr temp_phdr; |
385 | 0 | const unsigned char *sector = (const unsigned char*)phdr; |
386 | 0 | struct volume_key *fake_vk; |
387 | 0 | int i, bad, r, need_write = 0; |
388 | |
|
389 | 0 | if (phdr->keyBytes != 16 && phdr->keyBytes != 32 && phdr->keyBytes != 64) { |
390 | 0 | log_err(ctx, _("Non standard key size, manual repair required.")); |
391 | 0 | return -EINVAL; |
392 | 0 | } |
393 | | |
394 | | /* |
395 | | * cryptsetup 1.0 did not align keyslots to 4k, cannot repair this one |
396 | | * Also we cannot trust possibly broken keyslots metadata here through LUKS_keyslots_offset(). |
397 | | * Expect first keyslot is aligned, if not, then manual repair is necessary. |
398 | | */ |
399 | 0 | if (phdr->keyblock[0].keyMaterialOffset < (LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE)) { |
400 | 0 | log_err(ctx, _("Non standard keyslots alignment, manual repair required.")); |
401 | 0 | return -EINVAL; |
402 | 0 | } |
403 | | |
404 | | /* |
405 | | * ECB mode does not use IV but legacy dmcrypt silently allows it. |
406 | | * Today device cannot be activated anyway, so we need to fix it here. |
407 | | */ |
408 | 0 | if (!strncmp(phdr->cipherMode, "ecb-", 4)) { |
409 | 0 | log_err(ctx, _("Cipher mode repaired (%s -> %s)."), phdr->cipherMode, "ecb"); |
410 | 0 | memset(phdr->cipherMode, 0, LUKS_CIPHERMODE_L); |
411 | 0 | strcpy(phdr->cipherMode, "ecb"); |
412 | 0 | need_write = 1; |
413 | 0 | } |
414 | | |
415 | | /* |
416 | | * Old cryptsetup expects "sha1", gcrypt allows case insensitive names, |
417 | | * so always convert hash to lower case in header |
418 | | */ |
419 | 0 | if (_to_lower(phdr->hashSpec, LUKS_HASHSPEC_L)) { |
420 | 0 | log_err(ctx, _("Cipher hash repaired to lowercase (%s)."), phdr->hashSpec); |
421 | 0 | if (crypt_hmac_size(phdr->hashSpec) < LUKS_DIGESTSIZE) { |
422 | 0 | log_err(ctx, _("Requested LUKS hash %s is not supported."), phdr->hashSpec); |
423 | 0 | return -EINVAL; |
424 | 0 | } |
425 | 0 | need_write = 1; |
426 | 0 | } |
427 | | |
428 | 0 | r = crypt_check_cipher(ctx, phdr->keyBytes, phdr->cipherName, phdr->cipherMode); |
429 | 0 | if (r < 0) |
430 | 0 | return -EINVAL; |
431 | | |
432 | 0 | fake_vk = crypt_generate_volume_key(ctx, phdr->keyBytes, KEY_QUALITY_EMPTY); |
433 | 0 | if (!fake_vk) |
434 | 0 | return -ENOMEM; |
435 | | |
436 | 0 | log_verbose(ctx, _("Repairing keyslots.")); |
437 | |
|
438 | 0 | log_dbg(ctx, "Generating second header with the same parameters for check."); |
439 | | /* cipherName, cipherMode, hashSpec, uuid are already null terminated */ |
440 | | /* payloadOffset - cannot check */ |
441 | 0 | r = LUKS_generate_phdr(&temp_phdr, fake_vk, phdr->cipherName, phdr->cipherMode, |
442 | 0 | phdr->hashSpec, phdr->uuid, |
443 | 0 | phdr->payloadOffset * SECTOR_SIZE, 0, 0, ctx); |
444 | 0 | if (r < 0) |
445 | 0 | goto out; |
446 | | |
447 | 0 | for(i = 0; i < LUKS_NUMKEYS; ++i) { |
448 | 0 | if (phdr->keyblock[i].active == LUKS_KEY_ENABLED) { |
449 | 0 | log_dbg(ctx, "Skipping repair for active keyslot %i.", i); |
450 | 0 | continue; |
451 | 0 | } |
452 | | |
453 | 0 | bad = 0; |
454 | 0 | if (phdr->keyblock[i].keyMaterialOffset != temp_phdr.keyblock[i].keyMaterialOffset) { |
455 | 0 | log_err(ctx, _("Keyslot %i: offset repaired (%u -> %u)."), i, |
456 | 0 | (unsigned)phdr->keyblock[i].keyMaterialOffset, |
457 | 0 | (unsigned)temp_phdr.keyblock[i].keyMaterialOffset); |
458 | 0 | phdr->keyblock[i].keyMaterialOffset = temp_phdr.keyblock[i].keyMaterialOffset; |
459 | 0 | bad = 1; |
460 | 0 | } |
461 | |
|
462 | 0 | if (phdr->keyblock[i].stripes != temp_phdr.keyblock[i].stripes) { |
463 | 0 | log_err(ctx, _("Keyslot %i: stripes repaired (%u -> %u)."), i, |
464 | 0 | (unsigned)phdr->keyblock[i].stripes, |
465 | 0 | (unsigned)temp_phdr.keyblock[i].stripes); |
466 | 0 | phdr->keyblock[i].stripes = temp_phdr.keyblock[i].stripes; |
467 | 0 | bad = 1; |
468 | 0 | } |
469 | | |
470 | | /* Known case - MSDOS partition table signature */ |
471 | 0 | if (i == 6 && sector[0x1fe] == 0x55 && sector[0x1ff] == 0xaa) { |
472 | 0 | log_err(ctx, _("Keyslot %i: bogus partition signature."), i); |
473 | 0 | bad = 1; |
474 | 0 | } |
475 | |
|
476 | 0 | if(bad) { |
477 | 0 | log_err(ctx, _("Keyslot %i: salt wiped."), i); |
478 | 0 | phdr->keyblock[i].active = LUKS_KEY_DISABLED; |
479 | 0 | memset(&phdr->keyblock[i].passwordSalt, 0x00, LUKS_SALTSIZE); |
480 | 0 | phdr->keyblock[i].passwordIterations = 0; |
481 | 0 | } |
482 | |
|
483 | 0 | if (bad) |
484 | 0 | need_write = 1; |
485 | 0 | } |
486 | | |
487 | | /* |
488 | | * check repair result before writing because repair can't fix out of order |
489 | | * keyslot offsets and would corrupt header again |
490 | | */ |
491 | 0 | if (LUKS_check_keyslots(ctx, phdr)) |
492 | 0 | r = -EINVAL; |
493 | 0 | else if (need_write) { |
494 | 0 | log_verbose(ctx, _("Writing LUKS header to disk.")); |
495 | 0 | r = LUKS_write_phdr(phdr, ctx); |
496 | 0 | } |
497 | 0 | out: |
498 | 0 | if (r) |
499 | 0 | log_err(ctx, _("Repair failed.")); |
500 | 0 | crypt_free_volume_key(fake_vk); |
501 | 0 | crypt_safe_memzero(&temp_phdr, sizeof(temp_phdr)); |
502 | 0 | return r; |
503 | 0 | } |
504 | | |
505 | | static int _check_and_convert_hdr(const struct device *device, |
506 | | struct luks_phdr *hdr, |
507 | | int require_luks_device, |
508 | | int repair, |
509 | | struct crypt_device *ctx) |
510 | 1.75k | { |
511 | 1.75k | int r = 0; |
512 | 1.75k | unsigned int i; |
513 | 1.75k | char luksMagic[] = LUKS_MAGIC; |
514 | | |
515 | 1.75k | hdr->version = be16_to_cpu(hdr->version); |
516 | 1.75k | if (memcmp(hdr->magic, luksMagic, LUKS_MAGIC_L)) { /* Check magic */ |
517 | 1.09k | log_dbg(ctx, "LUKS header not detected."); |
518 | 1.09k | if (require_luks_device) |
519 | 0 | log_err(ctx, _("Device %s is not a valid LUKS device."), device_path(device)); |
520 | 1.09k | return -EINVAL; |
521 | 1.09k | } else if (hdr->version != 1) { |
522 | 23 | log_err(ctx, _("Unsupported LUKS version %d."), hdr->version); |
523 | 23 | return -EINVAL; |
524 | 23 | } |
525 | | |
526 | 633 | hdr->hashSpec[LUKS_HASHSPEC_L - 1] = '\0'; |
527 | 633 | if (crypt_hmac_size(hdr->hashSpec) < LUKS_DIGESTSIZE) { |
528 | 492 | log_err(ctx, _("Requested LUKS hash %s is not supported."), hdr->hashSpec); |
529 | 492 | r = -EINVAL; |
530 | 492 | } |
531 | | |
532 | | /* Header detected */ |
533 | 633 | hdr->payloadOffset = be32_to_cpu(hdr->payloadOffset); |
534 | 633 | hdr->keyBytes = be32_to_cpu(hdr->keyBytes); |
535 | 633 | hdr->mkDigestIterations = be32_to_cpu(hdr->mkDigestIterations); |
536 | | |
537 | 5.69k | for (i = 0; i < LUKS_NUMKEYS; ++i) { |
538 | 5.06k | hdr->keyblock[i].active = be32_to_cpu(hdr->keyblock[i].active); |
539 | 5.06k | hdr->keyblock[i].passwordIterations = be32_to_cpu(hdr->keyblock[i].passwordIterations); |
540 | 5.06k | hdr->keyblock[i].keyMaterialOffset = be32_to_cpu(hdr->keyblock[i].keyMaterialOffset); |
541 | 5.06k | hdr->keyblock[i].stripes = be32_to_cpu(hdr->keyblock[i].stripes); |
542 | 5.06k | } |
543 | | |
544 | 633 | if (LUKS_check_keyslots(ctx, hdr)) |
545 | 517 | r = -EINVAL; |
546 | | |
547 | | /* Avoid unterminated strings */ |
548 | 633 | hdr->cipherName[LUKS_CIPHERNAME_L - 1] = '\0'; |
549 | 633 | hdr->cipherMode[LUKS_CIPHERMODE_L - 1] = '\0'; |
550 | 633 | hdr->uuid[UUID_STRING_L - 1] = '\0'; |
551 | | |
552 | 633 | if (repair) { |
553 | 0 | if (!strncmp(hdr->cipherMode, "ecb-", 4)) { |
554 | 0 | log_err(ctx, _("LUKS cipher mode %s is invalid."), hdr->cipherMode); |
555 | 0 | r = -EINVAL; |
556 | 0 | } |
557 | |
|
558 | 0 | if (_is_not_lower(hdr->hashSpec, LUKS_HASHSPEC_L)) { |
559 | 0 | log_err(ctx, _("LUKS hash %s is invalid."), hdr->hashSpec); |
560 | 0 | r = -EINVAL; |
561 | 0 | } |
562 | |
|
563 | 0 | if (r == -EINVAL) |
564 | 0 | r = _keyslot_repair(hdr, ctx); |
565 | 0 | else |
566 | 0 | log_verbose(ctx, _("No known problems detected for LUKS header.")); |
567 | 0 | } |
568 | | |
569 | 633 | return r; |
570 | 1.75k | } |
571 | | |
572 | | int LUKS_read_phdr_backup(struct device *backup_device, |
573 | | struct luks_phdr *hdr, |
574 | | int require_luks_device, |
575 | | struct crypt_device *ctx) |
576 | 0 | { |
577 | 0 | ssize_t hdr_size = sizeof(struct luks_phdr); |
578 | 0 | int devfd; |
579 | |
|
580 | 0 | log_dbg(ctx, "Reading LUKS header of size %d from backup file %s", |
581 | 0 | (int)hdr_size, device_path(backup_device)); |
582 | |
|
583 | 0 | devfd = device_open(ctx, backup_device, O_RDONLY); |
584 | 0 | if (devfd == -1) { |
585 | 0 | log_err(ctx, _("Cannot open header backup file %s."), device_path(backup_device)); |
586 | 0 | return -ENOENT; |
587 | 0 | } |
588 | | |
589 | 0 | if (read_lseek_blockwise(devfd, device_block_size(ctx, backup_device), |
590 | 0 | device_alignment(backup_device), hdr, hdr_size, 0) < hdr_size) |
591 | 0 | return -EIO; |
592 | | |
593 | 0 | return _check_and_convert_hdr(backup_device, hdr, require_luks_device, 0, ctx); |
594 | 0 | } |
595 | | |
596 | | int LUKS_read_phdr(struct luks_phdr *hdr, |
597 | | int require_luks_device, |
598 | | int repair, |
599 | | struct crypt_device *ctx) |
600 | 1.75k | { |
601 | 1.75k | int devfd, r = 0; |
602 | 1.75k | struct device *device = crypt_metadata_device(ctx); |
603 | 1.75k | ssize_t hdr_size = sizeof(struct luks_phdr); |
604 | | |
605 | | /* LUKS header starts at offset 0, first keyslot on LUKS_ALIGN_KEYSLOTS */ |
606 | 1.75k | assert(sizeof(struct luks_phdr) <= LUKS_ALIGN_KEYSLOTS); |
607 | | |
608 | | /* Stripes count cannot be changed without additional code fixes yet */ |
609 | 1.75k | assert(LUKS_STRIPES == 4000); |
610 | | |
611 | 1.75k | if (repair && !require_luks_device) |
612 | 0 | return -EINVAL; |
613 | | |
614 | 1.75k | log_dbg(ctx, "Reading LUKS header of size %zu from device %s", |
615 | 1.75k | hdr_size, device_path(device)); |
616 | | |
617 | 1.75k | devfd = device_open(ctx, device, O_RDONLY); |
618 | 1.75k | if (devfd < 0) { |
619 | 0 | log_err(ctx, _("Cannot open device %s."), device_path(device)); |
620 | 0 | return -EINVAL; |
621 | 0 | } |
622 | | |
623 | 1.75k | if (read_lseek_blockwise(devfd, device_block_size(ctx, device), device_alignment(device), |
624 | 1.75k | hdr, hdr_size, 0) < hdr_size) |
625 | 0 | r = -EIO; |
626 | 1.75k | else |
627 | 1.75k | r = _check_and_convert_hdr(device, hdr, require_luks_device, repair, ctx); |
628 | | |
629 | 1.75k | if (!r) |
630 | 116 | r = LUKS_check_device_size(ctx, hdr, 0); |
631 | | |
632 | | /* |
633 | | * Cryptsetup 1.0.0 did not align keyslots to 4k (very rare version). |
634 | | * Disable direct-io to avoid possible IO errors if underlying device |
635 | | * has bigger sector size. |
636 | | */ |
637 | 1.75k | if (!r && hdr->keyblock[0].keyMaterialOffset * SECTOR_SIZE < LUKS_ALIGN_KEYSLOTS) { |
638 | 5 | log_dbg(ctx, "Old unaligned LUKS keyslot detected, disabling direct-io."); |
639 | 5 | device_disable_direct_io(device); |
640 | 5 | } |
641 | | |
642 | 1.75k | return r; |
643 | 1.75k | } |
644 | | |
645 | | int LUKS_write_phdr(struct luks_phdr *hdr, |
646 | | struct crypt_device *ctx) |
647 | 0 | { |
648 | 0 | struct device *device = crypt_metadata_device(ctx); |
649 | 0 | ssize_t hdr_size = sizeof(struct luks_phdr); |
650 | 0 | int devfd = 0; |
651 | 0 | unsigned int i; |
652 | 0 | struct luks_phdr convHdr; |
653 | 0 | int r; |
654 | |
|
655 | 0 | log_dbg(ctx, "Updating LUKS header of size %zu on device %s", |
656 | 0 | sizeof(struct luks_phdr), device_path(device)); |
657 | |
|
658 | 0 | r = LUKS_check_device_size(ctx, hdr, 1); |
659 | 0 | if (r) |
660 | 0 | return r; |
661 | | |
662 | 0 | devfd = device_open(ctx, device, O_RDWR); |
663 | 0 | if (devfd < 0) { |
664 | 0 | if (errno == EACCES) |
665 | 0 | log_err(ctx, _("Cannot write to device %s, permission denied."), |
666 | 0 | device_path(device)); |
667 | 0 | else |
668 | 0 | log_err(ctx, _("Cannot open device %s."), device_path(device)); |
669 | 0 | return -EINVAL; |
670 | 0 | } |
671 | | |
672 | 0 | memcpy(&convHdr, hdr, hdr_size); |
673 | 0 | memset(&convHdr._padding, 0, sizeof(convHdr._padding)); |
674 | | |
675 | | /* Convert every uint16/32_t item to network byte order */ |
676 | 0 | convHdr.version = cpu_to_be16(hdr->version); |
677 | 0 | convHdr.payloadOffset = cpu_to_be32(hdr->payloadOffset); |
678 | 0 | convHdr.keyBytes = cpu_to_be32(hdr->keyBytes); |
679 | 0 | convHdr.mkDigestIterations = cpu_to_be32(hdr->mkDigestIterations); |
680 | 0 | for(i = 0; i < LUKS_NUMKEYS; ++i) { |
681 | 0 | convHdr.keyblock[i].active = cpu_to_be32(hdr->keyblock[i].active); |
682 | 0 | convHdr.keyblock[i].passwordIterations = cpu_to_be32(hdr->keyblock[i].passwordIterations); |
683 | 0 | convHdr.keyblock[i].keyMaterialOffset = cpu_to_be32(hdr->keyblock[i].keyMaterialOffset); |
684 | 0 | convHdr.keyblock[i].stripes = cpu_to_be32(hdr->keyblock[i].stripes); |
685 | 0 | } |
686 | |
|
687 | 0 | r = write_lseek_blockwise(devfd, device_block_size(ctx, device), device_alignment(device), |
688 | 0 | &convHdr, hdr_size, 0) < hdr_size ? -EIO : 0; |
689 | 0 | if (r) |
690 | 0 | log_err(ctx, _("Error during update of LUKS header on device %s."), device_path(device)); |
691 | |
|
692 | 0 | device_sync(ctx, device); |
693 | | |
694 | | /* Re-read header from disk to be sure that in-memory and on-disk data are the same. */ |
695 | 0 | if (!r) { |
696 | 0 | r = LUKS_read_phdr(hdr, 1, 0, ctx); |
697 | 0 | if (r) |
698 | 0 | log_err(ctx, _("Error re-reading LUKS header after update on device %s."), |
699 | 0 | device_path(device)); |
700 | 0 | } |
701 | |
|
702 | 0 | return r; |
703 | 0 | } |
704 | | |
705 | | int LUKS_generate_phdr(struct luks_phdr *header, |
706 | | const struct volume_key *vk, |
707 | | const char *cipherName, |
708 | | const char *cipherMode, |
709 | | const char *hashSpec, |
710 | | const char *uuid, |
711 | | uint64_t data_offset, /* in bytes */ |
712 | | uint64_t align_offset, /* in bytes */ |
713 | | uint64_t required_alignment, /* in bytes */ |
714 | | struct crypt_device *ctx) |
715 | 0 | { |
716 | 0 | int i, r; |
717 | 0 | size_t keyslot_sectors, header_sectors; |
718 | 0 | uuid_t partitionUuid; |
719 | 0 | struct crypt_pbkdf_type *pbkdf; |
720 | 0 | double PBKDF2_temp; |
721 | 0 | char luksMagic[] = LUKS_MAGIC; |
722 | |
|
723 | 0 | if (data_offset % SECTOR_SIZE || align_offset % SECTOR_SIZE || |
724 | 0 | required_alignment % SECTOR_SIZE) |
725 | 0 | return -EINVAL; |
726 | | |
727 | 0 | memset(header, 0, sizeof(struct luks_phdr)); |
728 | |
|
729 | 0 | keyslot_sectors = AF_split_sectors(crypt_volume_key_length(vk), LUKS_STRIPES); |
730 | 0 | header_sectors = LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE; |
731 | |
|
732 | 0 | for (i = 0; i < LUKS_NUMKEYS; i++) { |
733 | 0 | header->keyblock[i].active = LUKS_KEY_DISABLED; |
734 | 0 | header->keyblock[i].keyMaterialOffset = header_sectors; |
735 | 0 | header->keyblock[i].stripes = LUKS_STRIPES; |
736 | 0 | header_sectors = size_round_up(header_sectors + keyslot_sectors, |
737 | 0 | LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE); |
738 | 0 | } |
739 | | /* In sector is now size of all keyslot material space */ |
740 | | |
741 | | /* Data offset has priority */ |
742 | 0 | if (data_offset) |
743 | 0 | header->payloadOffset = data_offset / SECTOR_SIZE; |
744 | 0 | else if (required_alignment) { |
745 | 0 | header->payloadOffset = size_round_up(header_sectors, (required_alignment / SECTOR_SIZE)); |
746 | 0 | header->payloadOffset += (align_offset / SECTOR_SIZE); |
747 | 0 | } else |
748 | 0 | header->payloadOffset = 0; |
749 | |
|
750 | 0 | if (header->payloadOffset && header->payloadOffset < header_sectors) { |
751 | 0 | log_err(ctx, _("Data offset for LUKS header must be " |
752 | 0 | "either 0 or higher than header size.")); |
753 | 0 | return -EINVAL; |
754 | 0 | } |
755 | | |
756 | 0 | if (crypt_hmac_size(hashSpec) < LUKS_DIGESTSIZE) { |
757 | 0 | log_err(ctx, _("Requested LUKS hash %s is not supported."), hashSpec); |
758 | 0 | return -EINVAL; |
759 | 0 | } |
760 | | |
761 | 0 | if (uuid && uuid_parse(uuid, partitionUuid) == -1) { |
762 | 0 | log_err(ctx, _("Wrong LUKS UUID format provided.")); |
763 | 0 | return -EINVAL; |
764 | 0 | } |
765 | 0 | if (!uuid) |
766 | 0 | uuid_generate(partitionUuid); |
767 | | |
768 | | /* Set Magic */ |
769 | 0 | memcpy(header->magic,luksMagic,LUKS_MAGIC_L); |
770 | 0 | header->version=1; |
771 | 0 | strncpy(header->cipherName,cipherName,LUKS_CIPHERNAME_L-1); |
772 | 0 | strncpy(header->cipherMode,cipherMode,LUKS_CIPHERMODE_L-1); |
773 | 0 | strncpy(header->hashSpec,hashSpec,LUKS_HASHSPEC_L-1); |
774 | 0 | _to_lower(header->hashSpec, LUKS_HASHSPEC_L); |
775 | |
|
776 | 0 | header->keyBytes = crypt_volume_key_length(vk); |
777 | |
|
778 | 0 | log_dbg(ctx, "Generating LUKS header version %d using hash %s, %s, %s, MK %d bytes", |
779 | 0 | header->version, header->hashSpec ,header->cipherName, header->cipherMode, |
780 | 0 | header->keyBytes); |
781 | |
|
782 | 0 | r = crypt_random_get(ctx, header->mkDigestSalt, LUKS_SALTSIZE, CRYPT_RND_SALT); |
783 | 0 | if(r < 0) { |
784 | 0 | log_err(ctx, _("Cannot create LUKS header: reading random salt failed.")); |
785 | 0 | return r; |
786 | 0 | } |
787 | | |
788 | | /* Compute volume key digest */ |
789 | 0 | pbkdf = crypt_get_pbkdf(ctx); |
790 | 0 | r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, crypt_volume_key_length(vk)); |
791 | 0 | if (r < 0) |
792 | 0 | return r; |
793 | 0 | assert(pbkdf->iterations); |
794 | |
|
795 | 0 | if (pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK && pbkdf->time_ms == 0) |
796 | 0 | PBKDF2_temp = LUKS_MKD_ITERATIONS_MIN; |
797 | 0 | else /* iterations per ms * LUKS_MKD_ITERATIONS_MS */ |
798 | 0 | PBKDF2_temp = (double)pbkdf->iterations * LUKS_MKD_ITERATIONS_MS / pbkdf->time_ms; |
799 | |
|
800 | 0 | if (PBKDF2_temp > (double)UINT32_MAX) |
801 | 0 | return -EINVAL; |
802 | 0 | header->mkDigestIterations = AT_LEAST((uint32_t)PBKDF2_temp, LUKS_MKD_ITERATIONS_MIN); |
803 | 0 | assert(header->mkDigestIterations); |
804 | |
|
805 | 0 | r = crypt_pbkdf(CRYPT_KDF_PBKDF2, header->hashSpec, |
806 | 0 | crypt_volume_key_get_key(vk), |
807 | 0 | crypt_volume_key_length(vk), |
808 | 0 | header->mkDigestSalt, LUKS_SALTSIZE, |
809 | 0 | header->mkDigest,LUKS_DIGESTSIZE, |
810 | 0 | header->mkDigestIterations, 0, 0); |
811 | 0 | if (r < 0) { |
812 | 0 | log_err(ctx, _("Cannot create LUKS header: header digest failed (using hash %s)."), |
813 | 0 | header->hashSpec); |
814 | 0 | return r; |
815 | 0 | } |
816 | | |
817 | 0 | uuid_unparse(partitionUuid, header->uuid); |
818 | |
|
819 | 0 | log_dbg(ctx, "Data offset %d, UUID %s, digest iterations %" PRIu32, |
820 | 0 | header->payloadOffset, header->uuid, header->mkDigestIterations); |
821 | |
|
822 | 0 | return 0; |
823 | 0 | } |
824 | | |
825 | | int LUKS_hdr_uuid_set( |
826 | | struct luks_phdr *hdr, |
827 | | const char *uuid, |
828 | | struct crypt_device *ctx) |
829 | 0 | { |
830 | 0 | uuid_t partitionUuid; |
831 | |
|
832 | 0 | if (uuid && uuid_parse(uuid, partitionUuid) == -1) { |
833 | 0 | log_err(ctx, _("Wrong LUKS UUID format provided.")); |
834 | 0 | return -EINVAL; |
835 | 0 | } |
836 | 0 | if (!uuid) |
837 | 0 | uuid_generate(partitionUuid); |
838 | |
|
839 | 0 | uuid_unparse(partitionUuid, hdr->uuid); |
840 | |
|
841 | 0 | return LUKS_write_phdr(hdr, ctx); |
842 | 0 | } |
843 | | |
844 | | int LUKS_set_key(unsigned int keyIndex, |
845 | | const char *password, size_t passwordLen, |
846 | | struct luks_phdr *hdr, struct volume_key *vk, |
847 | | struct crypt_device *ctx) |
848 | 0 | { |
849 | 0 | struct volume_key *derived_vk = NULL; |
850 | 0 | char *AfKey = NULL; |
851 | 0 | void *derived_key = NULL; |
852 | 0 | size_t AFEKSize; |
853 | 0 | struct crypt_pbkdf_type *pbkdf; |
854 | 0 | int r; |
855 | |
|
856 | 0 | if(hdr->keyblock[keyIndex].active != LUKS_KEY_DISABLED) { |
857 | 0 | log_err(ctx, _("Key slot %d active, purge first."), keyIndex); |
858 | 0 | return -EINVAL; |
859 | 0 | } |
860 | | |
861 | | /* LUKS keyslot has always at least 4000 stripes according to specification */ |
862 | 0 | if(hdr->keyblock[keyIndex].stripes < 4000) { |
863 | 0 | log_err(ctx, _("Key slot %d material includes too few stripes. Header manipulation?"), |
864 | 0 | keyIndex); |
865 | 0 | return -EINVAL; |
866 | 0 | } |
867 | | |
868 | 0 | log_dbg(ctx, "Calculating data for key slot %d", keyIndex); |
869 | 0 | pbkdf = crypt_get_pbkdf(ctx); |
870 | 0 | r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, crypt_volume_key_length(vk)); |
871 | 0 | if (r < 0) |
872 | 0 | return r; |
873 | 0 | assert(pbkdf->iterations); |
874 | | |
875 | | /* |
876 | | * Final iteration count is at least LUKS_SLOT_ITERATIONS_MIN |
877 | | */ |
878 | 0 | hdr->keyblock[keyIndex].passwordIterations = |
879 | 0 | AT_LEAST(pbkdf->iterations, LUKS_SLOT_ITERATIONS_MIN); |
880 | 0 | log_dbg(ctx, "Key slot %d use %" PRIu32 " password iterations.", keyIndex, |
881 | 0 | hdr->keyblock[keyIndex].passwordIterations); |
882 | |
|
883 | 0 | derived_key = crypt_safe_alloc(hdr->keyBytes); |
884 | 0 | if (!derived_key) { |
885 | 0 | r = -ENOMEM; |
886 | 0 | goto out; |
887 | 0 | } |
888 | | |
889 | 0 | r = crypt_random_get(ctx, hdr->keyblock[keyIndex].passwordSalt, |
890 | 0 | LUKS_SALTSIZE, CRYPT_RND_SALT); |
891 | 0 | if (r < 0) |
892 | 0 | goto out; |
893 | | |
894 | 0 | r = crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, password, passwordLen, |
895 | 0 | hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE, |
896 | 0 | derived_key, hdr->keyBytes, |
897 | 0 | hdr->keyblock[keyIndex].passwordIterations, 0, 0); |
898 | 0 | if (r < 0) { |
899 | 0 | if ((crypt_backend_flags() & CRYPT_BACKEND_PBKDF2_INT) && |
900 | 0 | hdr->keyblock[keyIndex].passwordIterations > INT_MAX) |
901 | 0 | log_err(ctx, _("PBKDF2 iteration value overflow.")); |
902 | 0 | goto out; |
903 | 0 | } |
904 | | |
905 | 0 | derived_vk = crypt_alloc_volume_key_by_safe_alloc(&derived_key); |
906 | 0 | if (!derived_vk) { |
907 | 0 | r = -ENOMEM; |
908 | 0 | goto out; |
909 | 0 | } |
910 | | |
911 | | /* |
912 | | * AF splitting, the volume key stored in vk->key is split to AfKey |
913 | | */ |
914 | 0 | assert(crypt_volume_key_length(vk) == hdr->keyBytes); |
915 | 0 | AFEKSize = AF_split_sectors(crypt_volume_key_length(vk), hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE; |
916 | 0 | AfKey = crypt_safe_alloc(AFEKSize); |
917 | 0 | if (!AfKey) { |
918 | 0 | r = -ENOMEM; |
919 | 0 | goto out; |
920 | 0 | } |
921 | | |
922 | 0 | log_dbg(ctx, "Using hash %s for AF in key slot %d, %d stripes", |
923 | 0 | hdr->hashSpec, keyIndex, hdr->keyblock[keyIndex].stripes); |
924 | 0 | r = AF_split(ctx, crypt_volume_key_get_key(vk), AfKey, crypt_volume_key_length(vk), |
925 | 0 | hdr->keyblock[keyIndex].stripes, hdr->hashSpec); |
926 | 0 | if (r < 0) |
927 | 0 | goto out; |
928 | | |
929 | 0 | log_dbg(ctx, "Updating key slot %d [0x%04x] area.", keyIndex, |
930 | 0 | hdr->keyblock[keyIndex].keyMaterialOffset << 9); |
931 | | /* Encryption via dm */ |
932 | 0 | r = LUKS_encrypt_to_storage(AfKey, |
933 | 0 | AFEKSize, |
934 | 0 | hdr->cipherName, hdr->cipherMode, |
935 | 0 | derived_vk, |
936 | 0 | hdr->keyblock[keyIndex].keyMaterialOffset, |
937 | 0 | ctx); |
938 | 0 | if (r < 0) |
939 | 0 | goto out; |
940 | | |
941 | | /* Mark the key as active in phdr */ |
942 | 0 | r = LUKS_keyslot_set(hdr, (int)keyIndex, 1, ctx); |
943 | 0 | if (r < 0) |
944 | 0 | goto out; |
945 | | |
946 | 0 | r = LUKS_write_phdr(hdr, ctx); |
947 | 0 | if (r < 0) |
948 | 0 | goto out; |
949 | | |
950 | 0 | r = 0; |
951 | 0 | out: |
952 | 0 | crypt_safe_free(AfKey); |
953 | 0 | crypt_safe_free(derived_key); |
954 | 0 | crypt_free_volume_key(derived_vk); |
955 | 0 | return r; |
956 | 0 | } |
957 | | |
958 | | /* Check whether a volume key is invalid. */ |
959 | | int LUKS_verify_volume_key(const struct luks_phdr *hdr, |
960 | | const struct volume_key *vk) |
961 | 0 | { |
962 | 0 | char checkHashBuf[LUKS_DIGESTSIZE]; |
963 | |
|
964 | 0 | if (crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, crypt_volume_key_get_key(vk), |
965 | 0 | crypt_volume_key_length(vk), |
966 | 0 | hdr->mkDigestSalt, LUKS_SALTSIZE, |
967 | 0 | checkHashBuf, LUKS_DIGESTSIZE, |
968 | 0 | hdr->mkDigestIterations, 0, 0) < 0) |
969 | 0 | return -EINVAL; |
970 | | |
971 | 0 | if (crypt_backend_memeq(checkHashBuf, hdr->mkDigest, LUKS_DIGESTSIZE)) |
972 | 0 | return -EPERM; |
973 | | |
974 | 0 | if (hdr->keyBytes != crypt_volume_key_length(vk)) |
975 | 0 | return -EPERM; |
976 | | |
977 | 0 | return 0; |
978 | 0 | } |
979 | | |
980 | | /* Try to open a particular key slot */ |
981 | | static int LUKS_open_key(unsigned int keyIndex, |
982 | | const char *password, |
983 | | size_t passwordLen, |
984 | | struct luks_phdr *hdr, |
985 | | struct volume_key **r_vk, |
986 | | struct crypt_device *ctx) |
987 | 0 | { |
988 | 0 | crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex); |
989 | 0 | struct volume_key *derived_vk = NULL, *vk = NULL; |
990 | 0 | char *AfKey = NULL; |
991 | 0 | void *key = NULL, *derived_key = NULL; |
992 | 0 | size_t AFEKSize; |
993 | 0 | int r; |
994 | |
|
995 | 0 | log_dbg(ctx, "Trying to open key slot %d [%s].", keyIndex, |
996 | 0 | dbg_slot_state(ki)); |
997 | |
|
998 | 0 | if (ki < CRYPT_SLOT_ACTIVE) |
999 | 0 | return -ENOENT; |
1000 | | |
1001 | 0 | derived_key = crypt_safe_alloc(hdr->keyBytes); |
1002 | 0 | if (!derived_key) |
1003 | 0 | return -ENOMEM; |
1004 | | |
1005 | 0 | key = crypt_safe_alloc(hdr->keyBytes); |
1006 | 0 | if (!key) { |
1007 | 0 | r = -ENOMEM; |
1008 | 0 | goto out; |
1009 | 0 | } |
1010 | | |
1011 | 0 | AFEKSize = AF_split_sectors(hdr->keyBytes, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE; |
1012 | 0 | AfKey = crypt_safe_alloc(AFEKSize); |
1013 | 0 | if (!AfKey) { |
1014 | 0 | r = -ENOMEM; |
1015 | 0 | goto out; |
1016 | 0 | } |
1017 | | |
1018 | 0 | r = crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, password, passwordLen, |
1019 | 0 | hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE, |
1020 | 0 | derived_key, hdr->keyBytes, |
1021 | 0 | hdr->keyblock[keyIndex].passwordIterations, 0, 0); |
1022 | 0 | if (r < 0) { |
1023 | 0 | log_err(ctx, _("Cannot open keyslot (using hash %s)."), hdr->hashSpec); |
1024 | 0 | goto out; |
1025 | 0 | } |
1026 | | |
1027 | 0 | derived_vk = crypt_alloc_volume_key_by_safe_alloc(&derived_key); |
1028 | 0 | if (!derived_vk) { |
1029 | 0 | r = -ENOMEM; |
1030 | 0 | goto out; |
1031 | 0 | } |
1032 | | |
1033 | 0 | log_dbg(ctx, "Reading key slot %d area.", keyIndex); |
1034 | 0 | r = LUKS_decrypt_from_storage(AfKey, |
1035 | 0 | AFEKSize, |
1036 | 0 | hdr->cipherName, hdr->cipherMode, |
1037 | 0 | derived_vk, |
1038 | 0 | hdr->keyblock[keyIndex].keyMaterialOffset, |
1039 | 0 | ctx); |
1040 | 0 | if (r < 0) |
1041 | 0 | goto out; |
1042 | | |
1043 | 0 | r = AF_merge(AfKey, key, hdr->keyBytes, hdr->keyblock[keyIndex].stripes, hdr->hashSpec); |
1044 | 0 | if (r < 0) |
1045 | 0 | goto out; |
1046 | | |
1047 | 0 | vk = crypt_alloc_volume_key_by_safe_alloc(&key); |
1048 | 0 | if (!vk) { |
1049 | 0 | r = -ENOMEM; |
1050 | 0 | goto out; |
1051 | 0 | } |
1052 | | |
1053 | 0 | r = LUKS_verify_volume_key(hdr, vk); |
1054 | 0 | if (r < 0) |
1055 | 0 | goto out; |
1056 | | |
1057 | | /* Allow only empty passphrase with null cipher */ |
1058 | 0 | if (crypt_is_cipher_null(hdr->cipherName) && passwordLen) |
1059 | 0 | r = -EPERM; |
1060 | 0 | else |
1061 | 0 | *r_vk = vk; |
1062 | 0 | out: |
1063 | 0 | if (r < 0) { |
1064 | 0 | crypt_free_volume_key(vk); |
1065 | 0 | *r_vk = NULL; |
1066 | 0 | } |
1067 | 0 | crypt_safe_free(AfKey); |
1068 | 0 | crypt_safe_free(key); |
1069 | 0 | crypt_safe_free(derived_key); |
1070 | 0 | crypt_free_volume_key(derived_vk); |
1071 | 0 | return r; |
1072 | 0 | } |
1073 | | |
1074 | | int LUKS_open_key_with_hdr(int keyIndex, |
1075 | | const char *password, |
1076 | | size_t passwordLen, |
1077 | | struct luks_phdr *hdr, |
1078 | | struct volume_key **vk, |
1079 | | struct crypt_device *ctx) |
1080 | 0 | { |
1081 | 0 | unsigned int i, tried = 0; |
1082 | 0 | int r; |
1083 | |
|
1084 | 0 | if (keyIndex >= 0) { |
1085 | 0 | r = LUKS_open_key(keyIndex, password, passwordLen, hdr, vk, ctx); |
1086 | 0 | return (r < 0) ? r : keyIndex; |
1087 | 0 | } |
1088 | | |
1089 | 0 | for (i = 0; i < LUKS_NUMKEYS; i++) { |
1090 | 0 | r = LUKS_open_key(i, password, passwordLen, hdr, vk, ctx); |
1091 | 0 | if (r == 0) |
1092 | 0 | return i; |
1093 | | |
1094 | | /* Do not retry for errors that are no -EPERM or -ENOENT, |
1095 | | former meaning password wrong, latter key slot inactive */ |
1096 | 0 | if ((r != -EPERM) && (r != -ENOENT)) |
1097 | 0 | return r; |
1098 | 0 | if (r == -EPERM) |
1099 | 0 | tried++; |
1100 | 0 | } |
1101 | | /* Warning, early returns above */ |
1102 | 0 | return tried ? -EPERM : -ENOENT; |
1103 | 0 | } |
1104 | | |
1105 | | int LUKS_del_key(unsigned int keyIndex, |
1106 | | struct luks_phdr *hdr, |
1107 | | struct crypt_device *ctx) |
1108 | 0 | { |
1109 | 0 | struct device *device = crypt_metadata_device(ctx); |
1110 | 0 | unsigned int startOffset, endOffset; |
1111 | 0 | int r; |
1112 | |
|
1113 | 0 | r = LUKS_read_phdr(hdr, 1, 0, ctx); |
1114 | 0 | if (r) |
1115 | 0 | return r; |
1116 | | |
1117 | 0 | r = LUKS_keyslot_set(hdr, keyIndex, 0, ctx); |
1118 | 0 | if (r) { |
1119 | 0 | log_err(ctx, _("Key slot %d is invalid, please select keyslot between 0 and %d."), |
1120 | 0 | keyIndex, LUKS_NUMKEYS - 1); |
1121 | 0 | return r; |
1122 | 0 | } |
1123 | | |
1124 | | /* secure deletion of key material */ |
1125 | 0 | startOffset = hdr->keyblock[keyIndex].keyMaterialOffset; |
1126 | 0 | endOffset = startOffset + AF_split_sectors(hdr->keyBytes, hdr->keyblock[keyIndex].stripes); |
1127 | |
|
1128 | 0 | r = crypt_wipe_device(ctx, device, CRYPT_WIPE_SPECIAL, startOffset * SECTOR_SIZE, |
1129 | 0 | (endOffset - startOffset) * SECTOR_SIZE, |
1130 | 0 | (endOffset - startOffset) * SECTOR_SIZE, NULL, NULL); |
1131 | 0 | if (r) { |
1132 | 0 | if (r == -EACCES) { |
1133 | 0 | log_err(ctx, _("Cannot write to device %s, permission denied."), |
1134 | 0 | device_path(device)); |
1135 | 0 | r = -EINVAL; |
1136 | 0 | } else |
1137 | 0 | log_err(ctx, _("Cannot wipe device %s."), |
1138 | 0 | device_path(device)); |
1139 | 0 | return r; |
1140 | 0 | } |
1141 | | |
1142 | | /* Wipe keyslot info */ |
1143 | 0 | memset(&hdr->keyblock[keyIndex].passwordSalt, 0, LUKS_SALTSIZE); |
1144 | 0 | hdr->keyblock[keyIndex].passwordIterations = 0; |
1145 | |
|
1146 | 0 | r = LUKS_write_phdr(hdr, ctx); |
1147 | |
|
1148 | 0 | return r; |
1149 | 0 | } |
1150 | | |
1151 | | crypt_keyslot_info LUKS_keyslot_info(struct luks_phdr *hdr, int keyslot) |
1152 | 0 | { |
1153 | 0 | int i; |
1154 | |
|
1155 | 0 | if(keyslot >= LUKS_NUMKEYS || keyslot < 0) |
1156 | 0 | return CRYPT_SLOT_INVALID; |
1157 | | |
1158 | 0 | if (hdr->keyblock[keyslot].active == LUKS_KEY_DISABLED) |
1159 | 0 | return CRYPT_SLOT_INACTIVE; |
1160 | | |
1161 | 0 | if (hdr->keyblock[keyslot].active != LUKS_KEY_ENABLED) |
1162 | 0 | return CRYPT_SLOT_INVALID; |
1163 | | |
1164 | 0 | for(i = 0; i < LUKS_NUMKEYS; i++) |
1165 | 0 | if(i != keyslot && hdr->keyblock[i].active == LUKS_KEY_ENABLED) |
1166 | 0 | return CRYPT_SLOT_ACTIVE; |
1167 | | |
1168 | 0 | return CRYPT_SLOT_ACTIVE_LAST; |
1169 | 0 | } |
1170 | | |
1171 | | int LUKS_keyslot_find_empty(struct luks_phdr *hdr) |
1172 | 0 | { |
1173 | 0 | int i; |
1174 | |
|
1175 | 0 | for (i = 0; i < LUKS_NUMKEYS; i++) |
1176 | 0 | if(hdr->keyblock[i].active == LUKS_KEY_DISABLED) |
1177 | 0 | break; |
1178 | |
|
1179 | 0 | if (i == LUKS_NUMKEYS) |
1180 | 0 | return -EINVAL; |
1181 | | |
1182 | 0 | return i; |
1183 | 0 | } |
1184 | | |
1185 | | int LUKS_keyslot_active_count(struct luks_phdr *hdr) |
1186 | 0 | { |
1187 | 0 | int i, num = 0; |
1188 | |
|
1189 | 0 | for (i = 0; i < LUKS_NUMKEYS; i++) |
1190 | 0 | if(hdr->keyblock[i].active == LUKS_KEY_ENABLED) |
1191 | 0 | num++; |
1192 | |
|
1193 | 0 | return num; |
1194 | 0 | } |
1195 | | |
1196 | | int LUKS_keyslot_set(struct luks_phdr *hdr, int keyslot, int enable, struct crypt_device *ctx) |
1197 | 0 | { |
1198 | 0 | crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyslot); |
1199 | |
|
1200 | 0 | if (ki == CRYPT_SLOT_INVALID) |
1201 | 0 | return -EINVAL; |
1202 | | |
1203 | 0 | hdr->keyblock[keyslot].active = enable ? LUKS_KEY_ENABLED : LUKS_KEY_DISABLED; |
1204 | 0 | log_dbg(ctx, "Key slot %d was %s in LUKS header.", keyslot, enable ? "enabled" : "disabled"); |
1205 | 0 | return 0; |
1206 | 0 | } |
1207 | | |
1208 | | int LUKS1_activate(struct crypt_device *cd, |
1209 | | const char *name, |
1210 | | struct volume_key *vk, |
1211 | | uint32_t flags) |
1212 | 0 | { |
1213 | 0 | int r; |
1214 | 0 | struct crypt_dm_active_device dmd = { |
1215 | 0 | .flags = flags, |
1216 | 0 | .uuid = crypt_get_uuid(cd), |
1217 | 0 | }; |
1218 | |
|
1219 | 0 | r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd), |
1220 | 0 | vk, crypt_get_cipher_spec(cd), crypt_get_iv_offset(cd), |
1221 | 0 | crypt_get_data_offset(cd), NULL, 0, 0, crypt_get_sector_size(cd)); |
1222 | 0 | if (!r) |
1223 | 0 | r = create_or_reload_device(cd, name, CRYPT_LUKS1, &dmd); |
1224 | |
|
1225 | 0 | dm_targets_free(cd, &dmd); |
1226 | |
|
1227 | 0 | return r; |
1228 | 0 | } |
1229 | | |
1230 | | int LUKS_wipe_header_areas(struct luks_phdr *hdr, |
1231 | | struct crypt_device *ctx) |
1232 | 0 | { |
1233 | 0 | int i, r; |
1234 | 0 | uint64_t offset, length; |
1235 | 0 | size_t wipe_block; |
1236 | |
|
1237 | 0 | r = LUKS_check_device_size(ctx, hdr, 1); |
1238 | 0 | if (r) |
1239 | 0 | return r; |
1240 | | |
1241 | | /* Wipe complete header, keyslots and padding areas with zeroes. */ |
1242 | 0 | offset = 0; |
1243 | 0 | length = (uint64_t)hdr->payloadOffset * SECTOR_SIZE; |
1244 | 0 | wipe_block = 1024 * 1024; |
1245 | | |
1246 | | /* On detached header or bogus header, wipe at least the first 4k */ |
1247 | 0 | if (length == 0 || length > (LUKS_MAX_KEYSLOT_SIZE * LUKS_NUMKEYS)) { |
1248 | 0 | length = 4096; |
1249 | 0 | wipe_block = 4096; |
1250 | 0 | } |
1251 | |
|
1252 | 0 | log_dbg(ctx, "Wiping LUKS areas (0x%06" PRIx64 " - 0x%06" PRIx64") with zeroes.", |
1253 | 0 | offset, length + offset); |
1254 | |
|
1255 | 0 | r = crypt_wipe_device(ctx, crypt_metadata_device(ctx), CRYPT_WIPE_ZERO, |
1256 | 0 | offset, length, wipe_block, NULL, NULL); |
1257 | 0 | if (r < 0) |
1258 | 0 | return r; |
1259 | | |
1260 | | /* Wipe keyslots areas */ |
1261 | 0 | wipe_block = 1024 * 1024; |
1262 | 0 | for (i = 0; i < LUKS_NUMKEYS; i++) { |
1263 | 0 | r = LUKS_keyslot_area(hdr, i, &offset, &length); |
1264 | 0 | if (r < 0) |
1265 | 0 | return r; |
1266 | | |
1267 | | /* Ignore too big LUKS1 keyslots here */ |
1268 | 0 | if (length > LUKS_MAX_KEYSLOT_SIZE || |
1269 | 0 | offset > (LUKS_MAX_KEYSLOT_SIZE - length)) |
1270 | 0 | continue; |
1271 | | |
1272 | 0 | if (length == 0 || offset < 4096) |
1273 | 0 | return -EINVAL; |
1274 | | |
1275 | 0 | log_dbg(ctx, "Wiping keyslot %i area (0x%06" PRIx64 " - 0x%06" PRIx64") with random data.", |
1276 | 0 | i, offset, length + offset); |
1277 | |
|
1278 | 0 | r = crypt_wipe_device(ctx, crypt_metadata_device(ctx), CRYPT_WIPE_RANDOM, |
1279 | 0 | offset, length, wipe_block, NULL, NULL); |
1280 | 0 | if (r < 0) |
1281 | 0 | return r; |
1282 | 0 | } |
1283 | | |
1284 | 0 | return r; |
1285 | 0 | } |
1286 | | |
1287 | | int LUKS_keyslot_pbkdf(struct luks_phdr *hdr, int keyslot, struct crypt_pbkdf_type *pbkdf) |
1288 | 0 | { |
1289 | 0 | if (LUKS_keyslot_info(hdr, keyslot) < CRYPT_SLOT_ACTIVE) |
1290 | 0 | return -EINVAL; |
1291 | | |
1292 | 0 | pbkdf->type = CRYPT_KDF_PBKDF2; |
1293 | 0 | pbkdf->hash = hdr->hashSpec; |
1294 | 0 | pbkdf->iterations = hdr->keyblock[keyslot].passwordIterations; |
1295 | 0 | pbkdf->max_memory_kb = 0; |
1296 | 0 | pbkdf->parallel_threads = 0; |
1297 | 0 | pbkdf->time_ms = 0; |
1298 | 0 | pbkdf->flags = 0; |
1299 | 0 | return 0; |
1300 | 0 | } |