/src/cryptsetup/lib/keyslot_context.c
Line | Count | Source |
1 | | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | | /* |
3 | | * LUKS - Linux Unified Key Setup, keyslot unlock helpers |
4 | | * |
5 | | * Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved. |
6 | | * Copyright (C) 2022-2025 Ondrej Kozina |
7 | | */ |
8 | | |
9 | | #include <errno.h> |
10 | | |
11 | | #include "bitlk/bitlk.h" |
12 | | #include "fvault2/fvault2.h" |
13 | | #include "luks1/luks.h" |
14 | | #include "luks2/luks2.h" |
15 | | #include "keyslot_context.h" |
16 | | |
17 | | static int get_luks2_key_by_passphrase(struct crypt_device *cd, |
18 | | struct crypt_keyslot_context *kc, |
19 | | int keyslot, |
20 | | int segment, |
21 | | struct volume_key **r_vk) |
22 | 0 | { |
23 | 0 | int r; |
24 | |
|
25 | 0 | assert(cd); |
26 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE); |
27 | 0 | assert(r_vk); |
28 | |
|
29 | 0 | r = LUKS2_keyslot_open(cd, keyslot, segment, kc->u.p.passphrase, kc->u.p.passphrase_size, r_vk); |
30 | 0 | if (r < 0) |
31 | 0 | kc->error = r; |
32 | |
|
33 | 0 | return r; |
34 | 0 | } |
35 | | |
36 | | static int get_luks1_volume_key_by_passphrase(struct crypt_device *cd, |
37 | | struct crypt_keyslot_context *kc, |
38 | | int keyslot, |
39 | | struct volume_key **r_vk) |
40 | 0 | { |
41 | 0 | int r; |
42 | |
|
43 | 0 | assert(cd); |
44 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE); |
45 | 0 | assert(r_vk); |
46 | |
|
47 | 0 | r = LUKS_open_key_with_hdr(keyslot, kc->u.p.passphrase, kc->u.p.passphrase_size, |
48 | 0 | crypt_get_hdr(cd, CRYPT_LUKS1), r_vk, cd); |
49 | 0 | if (r < 0) |
50 | 0 | kc->error = r; |
51 | |
|
52 | 0 | return r; |
53 | 0 | } |
54 | | |
55 | | static int get_luks2_volume_key_by_passphrase(struct crypt_device *cd, |
56 | | struct crypt_keyslot_context *kc, |
57 | | int keyslot, |
58 | | struct volume_key **r_vk) |
59 | 0 | { |
60 | 0 | return get_luks2_key_by_passphrase(cd, kc, keyslot, CRYPT_DEFAULT_SEGMENT, r_vk); |
61 | 0 | } |
62 | | |
63 | | static int get_bitlk_volume_key_by_passphrase(struct crypt_device *cd, |
64 | | struct crypt_keyslot_context *kc, |
65 | | const struct bitlk_metadata *params, |
66 | | struct volume_key **r_vk) |
67 | 0 | { |
68 | 0 | int r; |
69 | |
|
70 | 0 | assert(cd); |
71 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE); |
72 | 0 | assert(params); |
73 | 0 | assert(r_vk); |
74 | |
|
75 | 0 | r = BITLK_get_volume_key(cd, kc->u.p.passphrase, kc->u.p.passphrase_size, params, r_vk); |
76 | 0 | if (r < 0) |
77 | 0 | kc->error = r; |
78 | |
|
79 | 0 | return r; |
80 | 0 | } |
81 | | |
82 | | static int get_fvault2_volume_key_by_passphrase(struct crypt_device *cd, |
83 | | struct crypt_keyslot_context *kc, |
84 | | const struct fvault2_params *params, |
85 | | struct volume_key **r_vk) |
86 | 0 | { |
87 | 0 | int r; |
88 | |
|
89 | 0 | assert(cd); |
90 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE); |
91 | 0 | assert(params); |
92 | 0 | assert(r_vk); |
93 | |
|
94 | 0 | r = FVAULT2_get_volume_key(cd, kc->u.p.passphrase, kc->u.p.passphrase_size, params, r_vk); |
95 | 0 | if (r < 0) |
96 | 0 | kc->error = r; |
97 | |
|
98 | 0 | return r; |
99 | 0 | } |
100 | | |
101 | | static int get_passphrase_by_passphrase(struct crypt_device *cd, |
102 | | struct crypt_keyslot_context *kc, |
103 | | const char **r_passphrase, |
104 | | size_t *r_passphrase_size) |
105 | 0 | { |
106 | 0 | assert(cd); |
107 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE); |
108 | 0 | assert(r_passphrase); |
109 | 0 | assert(r_passphrase_size); |
110 | |
|
111 | 0 | *r_passphrase = kc->u.p.passphrase; |
112 | 0 | *r_passphrase_size = kc->u.p.passphrase_size; |
113 | |
|
114 | 0 | return 0; |
115 | 0 | } |
116 | | |
117 | | static int get_passphrase_by_keyfile(struct crypt_device *cd, |
118 | | struct crypt_keyslot_context *kc, |
119 | | const char **r_passphrase, |
120 | | size_t *r_passphrase_size) |
121 | 0 | { |
122 | 0 | int r; |
123 | |
|
124 | 0 | assert(cd); |
125 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE); |
126 | 0 | assert(r_passphrase); |
127 | 0 | assert(r_passphrase_size); |
128 | |
|
129 | 0 | if (!kc->i_passphrase) { |
130 | 0 | r = crypt_keyfile_device_read(cd, kc->u.kf.keyfile, |
131 | 0 | &kc->i_passphrase, &kc->i_passphrase_size, |
132 | 0 | kc->u.kf.keyfile_offset, kc->u.kf.keyfile_size, 0); |
133 | 0 | if (r < 0) { |
134 | 0 | kc->error = r; |
135 | 0 | return r; |
136 | 0 | } |
137 | 0 | } |
138 | | |
139 | 0 | *r_passphrase = kc->i_passphrase; |
140 | 0 | *r_passphrase_size = kc->i_passphrase_size; |
141 | |
|
142 | 0 | return 0; |
143 | 0 | } |
144 | | |
145 | | static int get_luks2_key_by_keyfile(struct crypt_device *cd, |
146 | | struct crypt_keyslot_context *kc, |
147 | | int keyslot, |
148 | | int segment, |
149 | | struct volume_key **r_vk) |
150 | 0 | { |
151 | 0 | int r; |
152 | 0 | const char *passphrase; |
153 | 0 | size_t passphrase_size; |
154 | |
|
155 | 0 | assert(cd); |
156 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE); |
157 | 0 | assert(r_vk); |
158 | |
|
159 | 0 | r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size); |
160 | 0 | if (r) |
161 | 0 | return r; |
162 | | |
163 | 0 | r = LUKS2_keyslot_open(cd, keyslot, segment, passphrase, passphrase_size, r_vk); |
164 | 0 | if (r < 0) |
165 | 0 | kc->error = r; |
166 | |
|
167 | 0 | return r; |
168 | 0 | } |
169 | | |
170 | | static int get_luks2_volume_key_by_keyfile(struct crypt_device *cd, |
171 | | struct crypt_keyslot_context *kc, |
172 | | int keyslot, |
173 | | struct volume_key **r_vk) |
174 | 0 | { |
175 | 0 | return get_luks2_key_by_keyfile(cd, kc, keyslot, CRYPT_DEFAULT_SEGMENT, r_vk); |
176 | 0 | } |
177 | | |
178 | | static int get_luks1_volume_key_by_keyfile(struct crypt_device *cd, |
179 | | struct crypt_keyslot_context *kc, |
180 | | int keyslot, |
181 | | struct volume_key **r_vk) |
182 | 0 | { |
183 | 0 | int r; |
184 | 0 | const char *passphrase; |
185 | 0 | size_t passphrase_size; |
186 | |
|
187 | 0 | assert(cd); |
188 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE); |
189 | 0 | assert(r_vk); |
190 | |
|
191 | 0 | r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size); |
192 | 0 | if (r) |
193 | 0 | return r; |
194 | | |
195 | 0 | r = LUKS_open_key_with_hdr(keyslot, passphrase, passphrase_size, |
196 | 0 | crypt_get_hdr(cd, CRYPT_LUKS1), r_vk, cd); |
197 | 0 | if (r < 0) |
198 | 0 | kc->error = r; |
199 | |
|
200 | 0 | return r; |
201 | 0 | } |
202 | | |
203 | | static int get_bitlk_volume_key_by_keyfile(struct crypt_device *cd, |
204 | | struct crypt_keyslot_context *kc, |
205 | | const struct bitlk_metadata *params, |
206 | | struct volume_key **r_vk) |
207 | 0 | { |
208 | 0 | int r; |
209 | 0 | const char *passphrase; |
210 | 0 | size_t passphrase_size; |
211 | |
|
212 | 0 | assert(cd); |
213 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE); |
214 | 0 | assert(params); |
215 | 0 | assert(r_vk); |
216 | |
|
217 | 0 | r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size); |
218 | 0 | if (r < 0) |
219 | 0 | return r; |
220 | | |
221 | 0 | r = BITLK_get_volume_key(cd, passphrase, passphrase_size, params, r_vk); |
222 | 0 | if (r < 0) |
223 | 0 | kc->error = r; |
224 | |
|
225 | 0 | return r; |
226 | 0 | } |
227 | | |
228 | | static int get_fvault2_volume_key_by_keyfile(struct crypt_device *cd, |
229 | | struct crypt_keyslot_context *kc, |
230 | | const struct fvault2_params *params, |
231 | | struct volume_key **r_vk) |
232 | 0 | { |
233 | 0 | int r; |
234 | 0 | const char *passphrase; |
235 | 0 | size_t passphrase_size; |
236 | |
|
237 | 0 | assert(cd); |
238 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE); |
239 | 0 | assert(params); |
240 | 0 | assert(r_vk); |
241 | |
|
242 | 0 | r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size); |
243 | 0 | if (r < 0) |
244 | 0 | return r; |
245 | | |
246 | 0 | r = FVAULT2_get_volume_key(cd, passphrase, passphrase_size, params, r_vk); |
247 | 0 | if (r < 0) |
248 | 0 | kc->error = r; |
249 | |
|
250 | 0 | return r; |
251 | 0 | } |
252 | | |
253 | | static int get_key_by_key(struct crypt_device *cd __attribute__((unused)), |
254 | | struct crypt_keyslot_context *kc, |
255 | | int keyslot __attribute__((unused)), |
256 | | int segment __attribute__((unused)), |
257 | | struct volume_key **r_vk) |
258 | 0 | { |
259 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_KEY); |
260 | 0 | assert(r_vk); |
261 | |
|
262 | 0 | if (!kc->u.k.volume_key) { |
263 | 0 | kc->error = -ENOENT; |
264 | 0 | return kc->error; |
265 | 0 | } |
266 | | |
267 | 0 | *r_vk = crypt_alloc_volume_key(kc->u.k.volume_key_size, kc->u.k.volume_key); |
268 | 0 | if (!*r_vk) { |
269 | 0 | kc->error = -ENOMEM; |
270 | 0 | return kc->error; |
271 | 0 | } |
272 | | |
273 | 0 | return 0; |
274 | 0 | } |
275 | | |
276 | | static int get_volume_key_by_key(struct crypt_device *cd, |
277 | | struct crypt_keyslot_context *kc, |
278 | | int keyslot __attribute__((unused)), |
279 | | struct volume_key **r_vk) |
280 | 0 | { |
281 | 0 | return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk); |
282 | 0 | } |
283 | | |
284 | | static int get_generic_volume_key_by_key(struct crypt_device *cd, |
285 | | struct crypt_keyslot_context *kc, |
286 | | struct volume_key **r_vk) |
287 | 0 | { |
288 | 0 | return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk); |
289 | 0 | } |
290 | | |
291 | | static int get_bitlk_volume_key_by_key(struct crypt_device *cd, |
292 | | struct crypt_keyslot_context *kc, |
293 | | const struct bitlk_metadata *params __attribute__((unused)), |
294 | | struct volume_key **r_vk) |
295 | 0 | { |
296 | 0 | return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk); |
297 | 0 | } |
298 | | |
299 | | static int get_fvault2_volume_key_by_key(struct crypt_device *cd, |
300 | | struct crypt_keyslot_context *kc, |
301 | | const struct fvault2_params *params __attribute__((unused)), |
302 | | struct volume_key **r_vk) |
303 | 0 | { |
304 | 0 | return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk); |
305 | 0 | } |
306 | | |
307 | | static int get_generic_signed_key_by_key(struct crypt_device *cd, |
308 | | struct crypt_keyslot_context *kc, |
309 | | struct volume_key **r_vk, |
310 | | struct volume_key **r_signature) |
311 | 0 | { |
312 | 0 | struct volume_key *vk, *vk_sig; |
313 | |
|
314 | 0 | assert(kc && ((kc->type == CRYPT_KC_TYPE_KEY) || |
315 | 0 | (kc->type == CRYPT_KC_TYPE_SIGNED_KEY))); |
316 | 0 | assert(r_vk); |
317 | 0 | assert(r_signature); |
318 | | |
319 | | /* return key with no signature */ |
320 | 0 | if (kc->type == CRYPT_KC_TYPE_KEY) { |
321 | 0 | *r_signature = NULL; |
322 | 0 | return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk); |
323 | 0 | } |
324 | | |
325 | 0 | if (!kc->u.ks.volume_key || !kc->u.ks.signature) { |
326 | 0 | kc->error = -EINVAL; |
327 | 0 | return kc->error; |
328 | 0 | } |
329 | | |
330 | 0 | vk = crypt_alloc_volume_key(kc->u.ks.volume_key_size, kc->u.ks.volume_key); |
331 | 0 | if (!vk) { |
332 | 0 | kc->error = -ENOMEM; |
333 | 0 | return kc->error; |
334 | 0 | } |
335 | | |
336 | 0 | vk_sig = crypt_alloc_volume_key(kc->u.ks.signature_size, kc->u.ks.signature); |
337 | 0 | if (!vk_sig) { |
338 | 0 | crypt_free_volume_key(vk); |
339 | 0 | kc->error = -ENOMEM; |
340 | 0 | return kc->error; |
341 | 0 | } |
342 | | |
343 | 0 | *r_vk = vk; |
344 | 0 | *r_signature = vk_sig; |
345 | |
|
346 | 0 | return 0; |
347 | 0 | } |
348 | | |
349 | | static int get_luks2_key_by_token(struct crypt_device *cd, |
350 | | struct crypt_keyslot_context *kc, |
351 | | int keyslot, |
352 | | int segment, |
353 | | struct volume_key **r_vk) |
354 | 0 | { |
355 | 0 | int r; |
356 | 0 | struct luks2_hdr *hdr; |
357 | |
|
358 | 0 | assert(cd); |
359 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_TOKEN); |
360 | 0 | assert(r_vk); |
361 | |
|
362 | 0 | hdr = crypt_get_hdr(cd, CRYPT_LUKS2); |
363 | 0 | if (!hdr) |
364 | 0 | return -EINVAL; |
365 | | |
366 | 0 | r = LUKS2_token_unlock_key(cd, hdr, keyslot, kc->u.t.id, kc->u.t.type, |
367 | 0 | kc->u.t.pin, kc->u.t.pin_size, segment, kc->u.t.usrptr, r_vk); |
368 | 0 | if (r < 0) |
369 | 0 | kc->error = r; |
370 | |
|
371 | 0 | return r; |
372 | 0 | } |
373 | | |
374 | | static int get_luks2_volume_key_by_token(struct crypt_device *cd, |
375 | | struct crypt_keyslot_context *kc, |
376 | | int keyslot, |
377 | | struct volume_key **r_vk) |
378 | 0 | { |
379 | 0 | return get_luks2_key_by_token(cd, kc, keyslot, CRYPT_DEFAULT_SEGMENT, r_vk); |
380 | 0 | } |
381 | | |
382 | | static int get_passphrase_by_token(struct crypt_device *cd, |
383 | | struct crypt_keyslot_context *kc, |
384 | | const char **r_passphrase, |
385 | | size_t *r_passphrase_size) |
386 | 0 | { |
387 | 0 | int r; |
388 | |
|
389 | 0 | assert(cd); |
390 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_TOKEN); |
391 | 0 | assert(r_passphrase); |
392 | 0 | assert(r_passphrase_size); |
393 | |
|
394 | 0 | if (!kc->i_passphrase) { |
395 | 0 | r = LUKS2_token_unlock_passphrase(cd, crypt_get_hdr(cd, CRYPT_LUKS2), kc->u.t.id, |
396 | 0 | kc->u.t.type, kc->u.t.pin, kc->u.t.pin_size, |
397 | 0 | kc->u.t.usrptr, &kc->i_passphrase, &kc->i_passphrase_size); |
398 | 0 | if (r < 0) { |
399 | 0 | kc->error = r; |
400 | 0 | return r; |
401 | 0 | } |
402 | 0 | kc->u.t.id = r; |
403 | 0 | } |
404 | | |
405 | 0 | *r_passphrase = kc->i_passphrase; |
406 | 0 | *r_passphrase_size = kc->i_passphrase_size; |
407 | |
|
408 | 0 | return kc->u.t.id; |
409 | 0 | } |
410 | | |
411 | | static int get_passphrase_by_keyring(struct crypt_device *cd, |
412 | | struct crypt_keyslot_context *kc, |
413 | | const char **r_passphrase, |
414 | | size_t *r_passphrase_size) |
415 | 0 | { |
416 | 0 | int r; |
417 | |
|
418 | 0 | assert(cd); |
419 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_KEYRING); |
420 | 0 | assert(r_passphrase); |
421 | 0 | assert(r_passphrase_size); |
422 | |
|
423 | 0 | if (!kc->i_passphrase) { |
424 | 0 | r = crypt_keyring_get_user_key(cd, kc->u.kr.key_description, |
425 | 0 | &kc->i_passphrase, &kc->i_passphrase_size); |
426 | 0 | if (r < 0) { |
427 | 0 | log_err(cd, _("Failed to read passphrase from keyring.")); |
428 | 0 | kc->error = -EINVAL; |
429 | 0 | return -EINVAL; |
430 | 0 | } |
431 | 0 | } |
432 | | |
433 | 0 | *r_passphrase = kc->i_passphrase; |
434 | 0 | *r_passphrase_size = kc->i_passphrase_size; |
435 | |
|
436 | 0 | return 0; |
437 | 0 | } |
438 | | |
439 | | static int get_luks2_key_by_keyring(struct crypt_device *cd, |
440 | | struct crypt_keyslot_context *kc, |
441 | | int keyslot, |
442 | | int segment, |
443 | | struct volume_key **r_vk) |
444 | 0 | { |
445 | 0 | int r; |
446 | |
|
447 | 0 | assert(cd); |
448 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_KEYRING); |
449 | 0 | assert(r_vk); |
450 | |
|
451 | 0 | r = get_passphrase_by_keyring(cd, kc, CONST_CAST(const char **) &kc->i_passphrase, |
452 | 0 | &kc->i_passphrase_size); |
453 | 0 | if (r < 0) { |
454 | 0 | log_err(cd, _("Failed to read passphrase from keyring.")); |
455 | 0 | kc->error = -EINVAL; |
456 | 0 | return -EINVAL; |
457 | 0 | } |
458 | | |
459 | 0 | r = LUKS2_keyslot_open(cd, keyslot, segment, kc->i_passphrase, kc->i_passphrase_size, r_vk); |
460 | 0 | if (r < 0) |
461 | 0 | kc->error = r; |
462 | |
|
463 | 0 | return r; |
464 | 0 | } |
465 | | |
466 | | static int get_luks2_volume_key_by_keyring(struct crypt_device *cd, |
467 | | struct crypt_keyslot_context *kc, |
468 | | int keyslot, |
469 | | struct volume_key **r_vk) |
470 | 0 | { |
471 | 0 | return get_luks2_key_by_keyring(cd, kc, keyslot, CRYPT_DEFAULT_SEGMENT, r_vk); |
472 | 0 | } |
473 | | |
474 | | static int get_luks1_volume_key_by_keyring(struct crypt_device *cd, |
475 | | struct crypt_keyslot_context *kc, |
476 | | int keyslot, |
477 | | struct volume_key **r_vk) |
478 | 0 | { |
479 | 0 | int r; |
480 | |
|
481 | 0 | assert(cd); |
482 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_KEYRING); |
483 | 0 | assert(r_vk); |
484 | |
|
485 | 0 | r = get_passphrase_by_keyring(cd, kc, CONST_CAST(const char **) &kc->i_passphrase, |
486 | 0 | &kc->i_passphrase_size); |
487 | 0 | if (r < 0) { |
488 | 0 | log_err(cd, _("Failed to read passphrase from keyring.")); |
489 | 0 | kc->error = -EINVAL; |
490 | 0 | return -EINVAL; |
491 | 0 | } |
492 | | |
493 | 0 | r = LUKS_open_key_with_hdr(keyslot, kc->i_passphrase, kc->i_passphrase_size, |
494 | 0 | crypt_get_hdr(cd, CRYPT_LUKS1), r_vk, cd); |
495 | 0 | if (r < 0) |
496 | 0 | kc->error = r; |
497 | |
|
498 | 0 | return r; |
499 | 0 | } |
500 | | |
501 | | static int get_key_by_vk_in_keyring(struct crypt_device *cd, |
502 | | struct crypt_keyslot_context *kc, |
503 | | int keyslot __attribute__((unused)), |
504 | | int segment __attribute__((unused)), |
505 | | struct volume_key **r_vk) |
506 | 0 | { |
507 | 0 | char *key; |
508 | 0 | size_t key_size; |
509 | 0 | int r; |
510 | |
|
511 | 0 | assert(cd); |
512 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_VK_KEYRING); |
513 | 0 | assert(r_vk); |
514 | |
|
515 | 0 | r = crypt_keyring_get_key_by_name(cd, kc->u.vk_kr.key_description, |
516 | 0 | &key, &key_size); |
517 | 0 | if (r < 0) { |
518 | 0 | log_err(cd, _("Failed to read volume key candidate from keyring.")); |
519 | 0 | kc->error = -EINVAL; |
520 | 0 | return -EINVAL; |
521 | 0 | } |
522 | | |
523 | 0 | *r_vk = crypt_alloc_volume_key_by_safe_alloc((void **)&key); |
524 | 0 | if (!*r_vk) { |
525 | 0 | crypt_safe_free(key); |
526 | 0 | kc->error = -ENOMEM; |
527 | 0 | return kc->error; |
528 | 0 | } |
529 | | |
530 | 0 | return 0; |
531 | 0 | } |
532 | | |
533 | | static int get_volume_key_by_vk_in_keyring(struct crypt_device *cd, |
534 | | struct crypt_keyslot_context *kc, |
535 | | int keyslot __attribute__((unused)), |
536 | | struct volume_key **r_vk) |
537 | 0 | { |
538 | 0 | return get_key_by_vk_in_keyring(cd, kc, -2 /* unused */, -2 /* unused */, r_vk); |
539 | 0 | } |
540 | | |
541 | | static void crypt_keyslot_context_init_common(struct crypt_keyslot_context *kc) |
542 | 0 | { |
543 | 0 | assert(kc); |
544 | |
|
545 | 0 | kc->version = KC_VERSION_BASIC; |
546 | 0 | kc->error = 0; |
547 | 0 | kc->i_passphrase = NULL; |
548 | 0 | kc->i_passphrase_size = 0; |
549 | 0 | } |
550 | | |
551 | | static void keyring_context_free(struct crypt_keyslot_context *kc) |
552 | 0 | { |
553 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_KEYRING); |
554 | |
|
555 | 0 | free(kc->u.kr.i_key_description); |
556 | 0 | } |
557 | | |
558 | | static int keyring_get_key_size(struct crypt_device *cd, struct crypt_keyslot_context *kc, size_t *r_key_size) |
559 | 0 | { |
560 | 0 | int r; |
561 | |
|
562 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_VK_KEYRING); |
563 | 0 | assert(r_key_size); |
564 | |
|
565 | 0 | if (!kc->u.vk_kr.i_key_size) { |
566 | 0 | r = crypt_keyring_get_keysize_by_name(cd, kc->u.vk_kr.key_description, &kc->u.vk_kr.i_key_size); |
567 | 0 | if (r < 0) |
568 | 0 | return r; |
569 | 0 | } |
570 | | |
571 | 0 | *r_key_size = kc->u.vk_kr.i_key_size; |
572 | 0 | return 0; |
573 | 0 | } |
574 | | |
575 | | void crypt_keyslot_context_init_by_keyring_internal(struct crypt_keyslot_context *kc, |
576 | | const char *key_description) |
577 | 0 | { |
578 | 0 | assert(kc); |
579 | |
|
580 | 0 | kc->type = CRYPT_KC_TYPE_KEYRING; |
581 | 0 | kc->u.kr.key_description = key_description; |
582 | |
|
583 | 0 | kc->get_luks2_key = get_luks2_key_by_keyring; |
584 | 0 | kc->get_luks1_volume_key = get_luks1_volume_key_by_keyring; |
585 | 0 | kc->get_luks2_volume_key = get_luks2_volume_key_by_keyring; |
586 | 0 | kc->get_passphrase = get_passphrase_by_keyring; |
587 | 0 | kc->context_free = keyring_context_free; |
588 | 0 | crypt_keyslot_context_init_common(kc); |
589 | 0 | } |
590 | | |
591 | | static void key_context_free(struct crypt_keyslot_context *kc) |
592 | 0 | { |
593 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_KEY); |
594 | |
|
595 | 0 | crypt_free_volume_key(kc->u.k.i_vk); |
596 | 0 | } |
597 | | |
598 | | static int key_get_key_size(struct crypt_device *cd __attribute__((unused)), |
599 | | struct crypt_keyslot_context *kc, |
600 | | size_t *r_key_size) |
601 | 0 | { |
602 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_KEY); |
603 | 0 | assert(r_key_size); |
604 | |
|
605 | 0 | *r_key_size = kc->u.k.volume_key_size; |
606 | 0 | return 0; |
607 | 0 | } |
608 | | |
609 | | void crypt_keyslot_context_init_by_key_internal(struct crypt_keyslot_context *kc, |
610 | | const char *volume_key, |
611 | | size_t volume_key_size) |
612 | 0 | { |
613 | 0 | assert(kc); |
614 | |
|
615 | 0 | kc->type = CRYPT_KC_TYPE_KEY; |
616 | 0 | kc->u.k.volume_key = volume_key; |
617 | 0 | kc->u.k.volume_key_size = volume_key_size; |
618 | |
|
619 | 0 | kc->get_luks2_key = get_key_by_key; |
620 | 0 | kc->get_luks1_volume_key = get_volume_key_by_key; |
621 | 0 | kc->get_luks2_volume_key = get_volume_key_by_key; |
622 | 0 | kc->get_plain_volume_key = get_generic_volume_key_by_key; |
623 | 0 | kc->get_bitlk_volume_key = get_bitlk_volume_key_by_key; |
624 | 0 | kc->get_fvault2_volume_key = get_fvault2_volume_key_by_key; |
625 | 0 | kc->get_verity_volume_key = get_generic_signed_key_by_key; |
626 | 0 | kc->get_integrity_volume_key = get_generic_volume_key_by_key; |
627 | 0 | kc->get_key_size = key_get_key_size; |
628 | 0 | kc->context_free = key_context_free; |
629 | 0 | crypt_keyslot_context_init_common(kc); |
630 | 0 | } |
631 | | |
632 | | static void signed_key_context_free(struct crypt_keyslot_context *kc) |
633 | 0 | { |
634 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_SIGNED_KEY); |
635 | |
|
636 | 0 | crypt_free_volume_key(kc->u.ks.i_vk); |
637 | 0 | crypt_free_volume_key(kc->u.ks.i_vk_sig); |
638 | 0 | } |
639 | | |
640 | | void crypt_keyslot_context_init_by_signed_key_internal(struct crypt_keyslot_context *kc, |
641 | | const char *volume_key, |
642 | | size_t volume_key_size, |
643 | | const char *signature, |
644 | | size_t signature_size) |
645 | 0 | { |
646 | 0 | assert(kc); |
647 | |
|
648 | 0 | kc->type = CRYPT_KC_TYPE_SIGNED_KEY; |
649 | 0 | kc->u.ks.volume_key = volume_key; |
650 | 0 | kc->u.ks.volume_key_size = volume_key_size; |
651 | 0 | kc->u.ks.signature = signature; |
652 | 0 | kc->u.ks.signature_size = signature_size; |
653 | |
|
654 | 0 | kc->get_verity_volume_key = get_generic_signed_key_by_key; |
655 | 0 | kc->context_free = signed_key_context_free; |
656 | 0 | crypt_keyslot_context_init_common(kc); |
657 | 0 | } |
658 | | |
659 | | void crypt_keyslot_context_init_by_passphrase_internal(struct crypt_keyslot_context *kc, |
660 | | const char *passphrase, |
661 | | size_t passphrase_size) |
662 | 0 | { |
663 | 0 | assert(kc); |
664 | |
|
665 | 0 | kc->type = CRYPT_KC_TYPE_PASSPHRASE; |
666 | 0 | kc->u.p.passphrase = passphrase; |
667 | 0 | kc->u.p.passphrase_size = passphrase_size; |
668 | |
|
669 | 0 | kc->get_luks2_key = get_luks2_key_by_passphrase; |
670 | 0 | kc->get_luks1_volume_key = get_luks1_volume_key_by_passphrase; |
671 | 0 | kc->get_luks2_volume_key = get_luks2_volume_key_by_passphrase; |
672 | 0 | kc->get_bitlk_volume_key = get_bitlk_volume_key_by_passphrase; |
673 | 0 | kc->get_fvault2_volume_key = get_fvault2_volume_key_by_passphrase; |
674 | 0 | kc->get_passphrase = get_passphrase_by_passphrase; |
675 | 0 | crypt_keyslot_context_init_common(kc); |
676 | 0 | } |
677 | | |
678 | | static void keyfile_context_free(struct crypt_keyslot_context *kc) |
679 | 0 | { |
680 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE); |
681 | |
|
682 | 0 | free(kc->u.kf.i_keyfile); |
683 | 0 | } |
684 | | |
685 | | void crypt_keyslot_context_init_by_keyfile_internal(struct crypt_keyslot_context *kc, |
686 | | const char *keyfile, |
687 | | size_t keyfile_size, |
688 | | uint64_t keyfile_offset) |
689 | 0 | { |
690 | 0 | assert(kc); |
691 | |
|
692 | 0 | kc->type = CRYPT_KC_TYPE_KEYFILE; |
693 | 0 | kc->u.kf.keyfile = keyfile; |
694 | 0 | kc->u.kf.keyfile_offset = keyfile_offset; |
695 | 0 | kc->u.kf.keyfile_size = keyfile_size; |
696 | |
|
697 | 0 | kc->get_luks2_key = get_luks2_key_by_keyfile; |
698 | 0 | kc->get_luks1_volume_key = get_luks1_volume_key_by_keyfile; |
699 | 0 | kc->get_luks2_volume_key = get_luks2_volume_key_by_keyfile; |
700 | 0 | kc->get_bitlk_volume_key = get_bitlk_volume_key_by_keyfile; |
701 | 0 | kc->get_fvault2_volume_key = get_fvault2_volume_key_by_keyfile; |
702 | 0 | kc->get_passphrase = get_passphrase_by_keyfile; |
703 | 0 | kc->context_free = keyfile_context_free; |
704 | 0 | crypt_keyslot_context_init_common(kc); |
705 | 0 | } |
706 | | |
707 | | static void token_context_free(struct crypt_keyslot_context *kc) |
708 | 0 | { |
709 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_TOKEN); |
710 | |
|
711 | 0 | free(kc->u.t.i_type); |
712 | 0 | crypt_safe_free(kc->u.t.i_pin); |
713 | 0 | } |
714 | | |
715 | | void crypt_keyslot_context_init_by_token_internal(struct crypt_keyslot_context *kc, |
716 | | int token, |
717 | | const char *type, |
718 | | const char *pin, |
719 | | size_t pin_size, |
720 | | void *usrptr) |
721 | 0 | { |
722 | 0 | assert(kc); |
723 | |
|
724 | 0 | kc->type = CRYPT_KC_TYPE_TOKEN; |
725 | 0 | kc->u.t.id = token; |
726 | 0 | kc->u.t.type = type; |
727 | 0 | kc->u.t.pin = pin; |
728 | 0 | kc->u.t.pin_size = pin_size; |
729 | 0 | kc->u.t.usrptr = usrptr; |
730 | |
|
731 | 0 | kc->get_luks2_key = get_luks2_key_by_token; |
732 | 0 | kc->get_luks2_volume_key = get_luks2_volume_key_by_token; |
733 | 0 | kc->get_passphrase = get_passphrase_by_token; |
734 | 0 | kc->context_free = token_context_free; |
735 | 0 | crypt_keyslot_context_init_common(kc); |
736 | 0 | } |
737 | | |
738 | | static void vk_in_keyring_context_free(struct crypt_keyslot_context *kc) |
739 | 0 | { |
740 | 0 | assert(kc && kc->type == CRYPT_KC_TYPE_VK_KEYRING); |
741 | |
|
742 | 0 | free(kc->u.vk_kr.i_key_description); |
743 | 0 | } |
744 | | |
745 | | void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *kc) |
746 | 0 | { |
747 | 0 | if (!kc) |
748 | 0 | return; |
749 | | |
750 | 0 | if (kc->context_free) |
751 | 0 | kc->context_free(kc); |
752 | |
|
753 | 0 | crypt_safe_free(kc->i_passphrase); |
754 | 0 | } |
755 | | |
756 | | void crypt_keyslot_context_free(struct crypt_keyslot_context *kc) |
757 | 0 | { |
758 | 0 | crypt_keyslot_context_destroy_internal(kc); |
759 | 0 | free(kc); |
760 | 0 | } |
761 | | |
762 | | static int _crypt_keyslot_context_init_by_passphrase(const char *passphrase, |
763 | | size_t passphrase_size, |
764 | | struct crypt_keyslot_context **kc, |
765 | | bool self_contained) |
766 | 0 | { |
767 | 0 | struct crypt_keyslot_context *tmp; |
768 | 0 | char *i_passphrase = NULL; |
769 | |
|
770 | 0 | if (!kc || !passphrase) |
771 | 0 | return -EINVAL; |
772 | | |
773 | 0 | tmp = crypt_zalloc(sizeof(*tmp)); |
774 | 0 | if (!tmp) |
775 | 0 | return -ENOMEM; |
776 | | |
777 | 0 | if (self_contained) { |
778 | 0 | if (passphrase_size) { |
779 | 0 | i_passphrase = crypt_safe_alloc(passphrase_size); |
780 | 0 | if (!i_passphrase) { |
781 | 0 | free(tmp); |
782 | 0 | return -ENOMEM; |
783 | 0 | } |
784 | 0 | crypt_safe_memcpy(i_passphrase, passphrase, passphrase_size); |
785 | 0 | passphrase = i_passphrase; |
786 | 0 | } else |
787 | | /* |
788 | | * some crypto backend libraries expect a pointer even though |
789 | | * passed passphrase size is set to zero. |
790 | | */ |
791 | 0 | passphrase = ""; |
792 | 0 | } |
793 | | |
794 | 0 | crypt_keyslot_context_init_by_passphrase_internal(tmp, passphrase, passphrase_size); |
795 | |
|
796 | 0 | if (self_contained) { |
797 | 0 | tmp->i_passphrase = i_passphrase; |
798 | 0 | tmp->i_passphrase_size = passphrase_size; |
799 | 0 | tmp->version = KC_VERSION_SELF_CONTAINED; |
800 | 0 | } |
801 | |
|
802 | 0 | *kc = tmp; |
803 | |
|
804 | 0 | return 0; |
805 | 0 | } |
806 | | |
807 | | CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_passphrase, 2, 8, |
808 | | /* crypt_keyslot_context_init_by_passphrase parameters follows */ |
809 | | struct crypt_device *cd __attribute__((unused)), |
810 | | const char *passphrase, |
811 | | size_t passphrase_size, |
812 | | struct crypt_keyslot_context **kc) |
813 | 0 | { |
814 | 0 | return _crypt_keyslot_context_init_by_passphrase(passphrase, passphrase_size, kc, true); |
815 | 0 | } |
816 | | |
817 | | CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_passphrase, 2, 6, |
818 | | /* crypt_keyslot_context_init_by_passphrase parameters follows */ |
819 | | struct crypt_device *cd __attribute__((unused)), |
820 | | const char *passphrase, |
821 | | size_t passphrase_size, |
822 | | struct crypt_keyslot_context **kc) |
823 | 0 | { |
824 | 0 | return _crypt_keyslot_context_init_by_passphrase(passphrase, passphrase_size, kc, false); |
825 | 0 | } |
826 | | |
827 | | static int _crypt_keyslot_context_init_by_keyfile(const char *keyfile, |
828 | | size_t keyfile_size, |
829 | | uint64_t keyfile_offset, |
830 | | struct crypt_keyslot_context **kc, |
831 | | bool self_contained) |
832 | 0 | { |
833 | 0 | char *i_keyfile; |
834 | 0 | struct crypt_keyslot_context *tmp; |
835 | |
|
836 | 0 | if (!kc || !keyfile) |
837 | 0 | return -EINVAL; |
838 | | |
839 | 0 | tmp = crypt_zalloc(sizeof(*tmp)); |
840 | 0 | if (!tmp) |
841 | 0 | return -ENOMEM; |
842 | | |
843 | 0 | if (self_contained) { |
844 | 0 | i_keyfile = strdup(keyfile); |
845 | 0 | if (!i_keyfile) { |
846 | 0 | free(tmp); |
847 | 0 | return -ENOMEM; |
848 | 0 | } |
849 | 0 | keyfile = i_keyfile; |
850 | 0 | } |
851 | | |
852 | 0 | crypt_keyslot_context_init_by_keyfile_internal(tmp, keyfile, keyfile_size, keyfile_offset); |
853 | |
|
854 | 0 | if (self_contained) { |
855 | 0 | tmp->u.kf.i_keyfile = i_keyfile; |
856 | 0 | tmp->version = KC_VERSION_SELF_CONTAINED; |
857 | 0 | } |
858 | |
|
859 | 0 | *kc = tmp; |
860 | |
|
861 | 0 | return 0; |
862 | 0 | } |
863 | | |
864 | | CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_keyfile, 2, 8, |
865 | | /* crypt_keyslot_context_init_by_keyfile parameters follows */ |
866 | | struct crypt_device *cd __attribute__((unused)), |
867 | | const char *keyfile, |
868 | | size_t keyfile_size, |
869 | | uint64_t keyfile_offset, |
870 | | struct crypt_keyslot_context **kc) |
871 | 0 | { |
872 | 0 | return _crypt_keyslot_context_init_by_keyfile(keyfile, keyfile_size, keyfile_offset, kc, true); |
873 | 0 | } |
874 | | |
875 | | CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_keyfile, 2, 6, |
876 | | /* crypt_keyslot_context_init_by_keyfile parameters follows */ |
877 | | struct crypt_device *cd __attribute__((unused)), |
878 | | const char *keyfile, |
879 | | size_t keyfile_size, |
880 | | uint64_t keyfile_offset, |
881 | | struct crypt_keyslot_context **kc) |
882 | 0 | { |
883 | 0 | return _crypt_keyslot_context_init_by_keyfile(keyfile, keyfile_size, keyfile_offset, kc, false); |
884 | 0 | } |
885 | | |
886 | | static int _crypt_keyslot_context_init_by_token(int token, |
887 | | const char *type, |
888 | | const char *pin, size_t pin_size, |
889 | | void *usrptr, |
890 | | struct crypt_keyslot_context **kc, |
891 | | bool self_contained) |
892 | 0 | { |
893 | 0 | char *i_type = NULL, *i_pin = NULL; |
894 | 0 | struct crypt_keyslot_context *tmp; |
895 | |
|
896 | 0 | if (!kc || (token < 0 && token != CRYPT_ANY_TOKEN) || |
897 | 0 | (pin && !pin_size)) |
898 | 0 | return -EINVAL; |
899 | | |
900 | 0 | tmp = crypt_zalloc(sizeof(*tmp)); |
901 | 0 | if (!tmp) |
902 | 0 | return -ENOMEM; |
903 | | |
904 | 0 | if (self_contained && type) { |
905 | 0 | if (!(i_type = strdup(type))) |
906 | 0 | goto err; |
907 | 0 | type = i_type; |
908 | 0 | } |
909 | | |
910 | 0 | if (self_contained && pin) { |
911 | 0 | if (!(i_pin = crypt_safe_alloc(pin_size))) |
912 | 0 | goto err; |
913 | 0 | crypt_safe_memcpy(i_pin, pin, pin_size); |
914 | 0 | pin = i_pin; |
915 | 0 | } |
916 | | |
917 | 0 | crypt_keyslot_context_init_by_token_internal(tmp, token, type, pin, pin_size, usrptr); |
918 | |
|
919 | 0 | if (self_contained) { |
920 | 0 | tmp->u.t.i_pin = i_pin; |
921 | 0 | tmp->u.t.i_type = i_type; |
922 | 0 | tmp->version = KC_VERSION_SELF_CONTAINED; |
923 | 0 | } |
924 | |
|
925 | 0 | *kc = tmp; |
926 | |
|
927 | 0 | return 0; |
928 | 0 | err: |
929 | 0 | crypt_safe_free(i_pin); |
930 | 0 | free(i_type); |
931 | 0 | free(tmp); |
932 | |
|
933 | 0 | return -ENOMEM; |
934 | 0 | } |
935 | | |
936 | | CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_token, 2, 8, |
937 | | /* crypt_keyslot_context_init_by_token parameters follows */ |
938 | | struct crypt_device *cd __attribute__((unused)), |
939 | | int token, |
940 | | const char *type, |
941 | | const char *pin, size_t pin_size, |
942 | | void *usrptr, |
943 | | struct crypt_keyslot_context **kc) |
944 | 0 | { |
945 | 0 | return _crypt_keyslot_context_init_by_token(token, type, pin, pin_size, usrptr, kc, true); |
946 | 0 | } |
947 | | |
948 | | CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_token, 2, 6, |
949 | | /* crypt_keyslot_context_init_by_token parameters follows */ |
950 | | struct crypt_device *cd __attribute__((unused)), |
951 | | int token, |
952 | | const char *type, |
953 | | const char *pin, size_t pin_size, |
954 | | void *usrptr, |
955 | | struct crypt_keyslot_context **kc) |
956 | 0 | { |
957 | 0 | return _crypt_keyslot_context_init_by_token(token, type, pin, pin_size, usrptr, kc, false); |
958 | 0 | } |
959 | | |
960 | | static int _crypt_keyslot_context_init_by_volume_key(const char *volume_key, |
961 | | size_t volume_key_size, |
962 | | struct crypt_keyslot_context **kc, |
963 | | bool self_contained) |
964 | 0 | { |
965 | 0 | struct volume_key *i_vk = NULL; |
966 | 0 | struct crypt_keyslot_context *tmp; |
967 | |
|
968 | 0 | if (!kc) |
969 | 0 | return -EINVAL; |
970 | | |
971 | 0 | tmp = crypt_zalloc(sizeof(*tmp)); |
972 | 0 | if (!tmp) |
973 | 0 | return -ENOMEM; |
974 | | |
975 | 0 | if (self_contained && volume_key) { |
976 | 0 | if (!(i_vk = crypt_alloc_volume_key(volume_key_size, volume_key))) { |
977 | 0 | free(tmp); |
978 | 0 | return -ENOMEM; |
979 | 0 | } |
980 | 0 | volume_key = crypt_volume_key_get_key(i_vk); |
981 | 0 | } |
982 | | |
983 | 0 | crypt_keyslot_context_init_by_key_internal(tmp, volume_key, volume_key_size); |
984 | |
|
985 | 0 | if (self_contained) { |
986 | 0 | tmp->u.k.i_vk = i_vk; |
987 | 0 | tmp->version = KC_VERSION_SELF_CONTAINED; |
988 | 0 | } |
989 | |
|
990 | 0 | *kc = tmp; |
991 | |
|
992 | 0 | return 0; |
993 | 0 | } |
994 | | |
995 | | CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_volume_key, 2, 8, |
996 | | /* crypt_keyslot_context_init_by_volume_key parameters follows */ |
997 | | struct crypt_device *cd __attribute__((unused)), |
998 | | const char *volume_key, |
999 | | size_t volume_key_size, |
1000 | | struct crypt_keyslot_context **kc) |
1001 | 0 | { |
1002 | 0 | return _crypt_keyslot_context_init_by_volume_key(volume_key, volume_key_size, kc, true); |
1003 | 0 | } |
1004 | | |
1005 | | CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_volume_key, 2, 6, |
1006 | | /* crypt_keyslot_context_init_by_volume_key parameters follows */ |
1007 | | struct crypt_device *cd __attribute__((unused)), |
1008 | | const char *volume_key, |
1009 | | size_t volume_key_size, |
1010 | | struct crypt_keyslot_context **kc) |
1011 | 0 | { |
1012 | 0 | return _crypt_keyslot_context_init_by_volume_key(volume_key, volume_key_size, kc, false); |
1013 | 0 | } |
1014 | | |
1015 | | static int _crypt_keyslot_context_init_by_signed_key(const char *volume_key, |
1016 | | size_t volume_key_size, |
1017 | | const char *signature, |
1018 | | size_t signature_size, |
1019 | | struct crypt_keyslot_context **kc, |
1020 | | bool self_contained) |
1021 | 0 | { |
1022 | 0 | struct volume_key *i_vk = NULL, *i_vk_sig = NULL; |
1023 | 0 | struct crypt_keyslot_context *tmp; |
1024 | |
|
1025 | 0 | if (!kc) |
1026 | 0 | return -EINVAL; |
1027 | | |
1028 | 0 | tmp = crypt_zalloc(sizeof(*tmp)); |
1029 | 0 | if (!tmp) |
1030 | 0 | return -ENOMEM; |
1031 | | |
1032 | 0 | if (self_contained && volume_key) { |
1033 | 0 | if (!(i_vk = crypt_alloc_volume_key(volume_key_size, volume_key))) |
1034 | 0 | goto err; |
1035 | 0 | volume_key = crypt_volume_key_get_key(i_vk); |
1036 | 0 | } |
1037 | | |
1038 | 0 | if (self_contained && signature) { |
1039 | 0 | if (!(i_vk_sig = crypt_alloc_volume_key(signature_size, signature))) |
1040 | 0 | goto err; |
1041 | 0 | signature = crypt_volume_key_get_key(i_vk_sig); |
1042 | 0 | } |
1043 | | |
1044 | 0 | crypt_keyslot_context_init_by_signed_key_internal(tmp, volume_key, volume_key_size, |
1045 | 0 | signature, signature_size); |
1046 | |
|
1047 | 0 | if (self_contained) { |
1048 | 0 | tmp->u.ks.i_vk = i_vk; |
1049 | 0 | tmp->u.ks.i_vk_sig = i_vk_sig; |
1050 | 0 | tmp->version = KC_VERSION_SELF_CONTAINED; |
1051 | 0 | } |
1052 | |
|
1053 | 0 | *kc = tmp; |
1054 | |
|
1055 | 0 | return 0; |
1056 | 0 | err: |
1057 | 0 | crypt_free_volume_key(i_vk); |
1058 | 0 | crypt_free_volume_key(i_vk_sig); |
1059 | 0 | free(tmp); |
1060 | |
|
1061 | 0 | return -ENOMEM; |
1062 | 0 | } |
1063 | | |
1064 | | CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_signed_key, 2, 8, |
1065 | | /* crypt_keyslot_context_init_by_signed_key parameters follows */ |
1066 | | struct crypt_device *cd __attribute__((unused)), |
1067 | | const char *volume_key, |
1068 | | size_t volume_key_size, |
1069 | | const char *signature, |
1070 | | size_t signature_size, |
1071 | | struct crypt_keyslot_context **kc) |
1072 | 0 | { |
1073 | 0 | return _crypt_keyslot_context_init_by_signed_key(volume_key, volume_key_size, signature, signature_size, kc, true); |
1074 | 0 | } |
1075 | | |
1076 | | CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_signed_key, 2, 7, |
1077 | | /* crypt_keyslot_context_init_by_signed_key parameters follows */ |
1078 | | struct crypt_device *cd __attribute__((unused)), |
1079 | | const char *volume_key, |
1080 | | size_t volume_key_size, |
1081 | | const char *signature, |
1082 | | size_t signature_size, |
1083 | | struct crypt_keyslot_context **kc) |
1084 | 0 | { |
1085 | 0 | return _crypt_keyslot_context_init_by_signed_key(volume_key, volume_key_size, signature, signature_size, kc, false); |
1086 | 0 | } |
1087 | | |
1088 | | static int _crypt_keyslot_context_init_by_keyring(const char *key_description, |
1089 | | struct crypt_keyslot_context **kc, |
1090 | | bool self_contained) |
1091 | 0 | { |
1092 | 0 | char *i_key_description; |
1093 | 0 | struct crypt_keyslot_context *tmp; |
1094 | |
|
1095 | 0 | if (!kc || !key_description) |
1096 | 0 | return -EINVAL; |
1097 | | |
1098 | 0 | tmp = crypt_zalloc(sizeof(*tmp)); |
1099 | 0 | if (!tmp) |
1100 | 0 | return -ENOMEM; |
1101 | | |
1102 | 0 | if (self_contained) { |
1103 | 0 | if (!(i_key_description = strdup(key_description))) { |
1104 | 0 | free(tmp); |
1105 | 0 | return -ENOMEM; |
1106 | 0 | } |
1107 | 0 | key_description = i_key_description; |
1108 | 0 | } |
1109 | | |
1110 | 0 | crypt_keyslot_context_init_by_keyring_internal(tmp, key_description); |
1111 | |
|
1112 | 0 | if (self_contained) { |
1113 | 0 | tmp->u.kr.i_key_description = i_key_description; |
1114 | 0 | tmp->version = KC_VERSION_SELF_CONTAINED; |
1115 | 0 | } |
1116 | |
|
1117 | 0 | *kc = tmp; |
1118 | |
|
1119 | 0 | return 0; |
1120 | 0 | } |
1121 | | |
1122 | | CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_keyring, 2, 8, |
1123 | | /* crypt_keyslot_context_init_by_keyring parameters follows */ |
1124 | | struct crypt_device *cd __attribute__((unused)), |
1125 | | const char *key_description, |
1126 | | struct crypt_keyslot_context **kc) |
1127 | 0 | { |
1128 | 0 | return _crypt_keyslot_context_init_by_keyring(key_description, kc, true); |
1129 | 0 | } |
1130 | | |
1131 | | CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_keyring, 2, 7, |
1132 | | /* crypt_keyslot_context_init_by_keyring parameters follows */ |
1133 | | struct crypt_device *cd __attribute__((unused)), |
1134 | | const char *key_description, |
1135 | | struct crypt_keyslot_context **kc) |
1136 | 0 | { |
1137 | 0 | return _crypt_keyslot_context_init_by_keyring(key_description, kc, false); |
1138 | 0 | } |
1139 | | |
1140 | | static int _crypt_keyslot_context_init_by_vk_in_keyring(const char *key_description, |
1141 | | struct crypt_keyslot_context **kc, |
1142 | | bool self_contained) |
1143 | 0 | { |
1144 | 0 | char *i_key_description; |
1145 | 0 | struct crypt_keyslot_context *tmp; |
1146 | |
|
1147 | 0 | if (!kc || !key_description) |
1148 | 0 | return -EINVAL; |
1149 | | |
1150 | 0 | tmp = crypt_zalloc(sizeof(*tmp)); |
1151 | 0 | if (!tmp) |
1152 | 0 | return -ENOMEM; |
1153 | | |
1154 | 0 | if (self_contained) { |
1155 | 0 | if (!(i_key_description = strdup(key_description))) { |
1156 | 0 | free(tmp); |
1157 | 0 | return -ENOMEM; |
1158 | 0 | } |
1159 | 0 | key_description = i_key_description; |
1160 | 0 | } |
1161 | | |
1162 | 0 | tmp->type = CRYPT_KC_TYPE_VK_KEYRING; |
1163 | 0 | tmp->u.vk_kr.key_description = key_description; |
1164 | |
|
1165 | 0 | tmp->get_luks2_key = get_key_by_vk_in_keyring; |
1166 | 0 | tmp->get_luks2_volume_key = get_volume_key_by_vk_in_keyring; |
1167 | 0 | tmp->get_key_size = keyring_get_key_size; |
1168 | 0 | tmp->context_free = vk_in_keyring_context_free; |
1169 | 0 | crypt_keyslot_context_init_common(tmp); |
1170 | |
|
1171 | 0 | if (self_contained) { |
1172 | 0 | tmp->u.vk_kr.i_key_description = i_key_description; |
1173 | 0 | tmp->version = KC_VERSION_SELF_CONTAINED; |
1174 | 0 | } |
1175 | |
|
1176 | 0 | *kc = tmp; |
1177 | |
|
1178 | 0 | return 0; |
1179 | 0 | } |
1180 | | |
1181 | | CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_vk_in_keyring, 2, 8, |
1182 | | /* crypt_keyslot_context_init_by_vk_in_keyring parameters follows */ |
1183 | | struct crypt_device *cd __attribute__((unused)), |
1184 | | const char *key_description, |
1185 | | struct crypt_keyslot_context **kc) |
1186 | 0 | { |
1187 | 0 | return _crypt_keyslot_context_init_by_vk_in_keyring(key_description, kc, true); |
1188 | 0 | } |
1189 | | |
1190 | | CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_vk_in_keyring, 2, 7, |
1191 | | /* crypt_keyslot_context_init_by_vk_in_keyring parameters follows */ |
1192 | | struct crypt_device *cd __attribute__((unused)), |
1193 | | const char *key_description, |
1194 | | struct crypt_keyslot_context **kc) |
1195 | 0 | { |
1196 | 0 | return _crypt_keyslot_context_init_by_vk_in_keyring(key_description, kc, false); |
1197 | 0 | } |
1198 | | |
1199 | | int crypt_keyslot_context_get_error(struct crypt_keyslot_context *kc) |
1200 | 0 | { |
1201 | 0 | return kc ? kc->error : -EINVAL; |
1202 | 0 | } |
1203 | | |
1204 | | int crypt_keyslot_context_set_pin(struct crypt_device *cd __attribute__((unused)), |
1205 | | const char *pin, size_t pin_size, |
1206 | | struct crypt_keyslot_context *kc) |
1207 | 0 | { |
1208 | 0 | char *i_pin = NULL; |
1209 | |
|
1210 | 0 | if (!kc || kc->type != CRYPT_KC_TYPE_TOKEN) |
1211 | 0 | return -EINVAL; |
1212 | | |
1213 | 0 | if (kc->version >= KC_VERSION_SELF_CONTAINED && pin) { |
1214 | 0 | if (!(i_pin = crypt_safe_alloc(pin_size))) |
1215 | 0 | return -ENOMEM; |
1216 | 0 | crypt_safe_memcpy(i_pin, pin, pin_size); |
1217 | 0 | } |
1218 | | |
1219 | 0 | crypt_safe_free(kc->u.t.i_pin); |
1220 | 0 | kc->u.t.i_pin = i_pin; |
1221 | |
|
1222 | 0 | kc->u.t.pin = i_pin ?: pin; |
1223 | 0 | kc->u.t.pin_size = pin_size; |
1224 | 0 | kc->error = 0; |
1225 | |
|
1226 | 0 | return 0; |
1227 | 0 | } |
1228 | | |
1229 | | int crypt_keyslot_context_get_type(const struct crypt_keyslot_context *kc) |
1230 | 0 | { |
1231 | 0 | return kc ? kc->type : -EINVAL; |
1232 | 0 | } |
1233 | | |
1234 | | const char *keyslot_context_type_string(const struct crypt_keyslot_context *kc) |
1235 | 0 | { |
1236 | 0 | assert(kc); |
1237 | |
|
1238 | 0 | switch (kc->type) { |
1239 | 0 | case CRYPT_KC_TYPE_PASSPHRASE: |
1240 | 0 | return "passphrase"; |
1241 | 0 | case CRYPT_KC_TYPE_KEYFILE: |
1242 | 0 | return "keyfile"; |
1243 | 0 | case CRYPT_KC_TYPE_TOKEN: |
1244 | 0 | return "token"; |
1245 | 0 | case CRYPT_KC_TYPE_KEY: |
1246 | 0 | return "key"; |
1247 | 0 | case CRYPT_KC_TYPE_KEYRING: |
1248 | 0 | return "keyring"; |
1249 | 0 | case CRYPT_KC_TYPE_VK_KEYRING: |
1250 | 0 | return "volume key in keyring"; |
1251 | 0 | case CRYPT_KC_TYPE_SIGNED_KEY: |
1252 | 0 | return "signed key"; |
1253 | 0 | default: |
1254 | 0 | return "<unknown>"; |
1255 | 0 | } |
1256 | 0 | } |