]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/home/homework-fscrypt.c
ssh-generator: generate /etc/issue.d/ with VSOCK ssh info data (#37819)
[thirdparty/systemd.git] / src / home / homework-fscrypt.c
... / ...
CommitLineData
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3#include <linux/fscrypt.h>
4#include <openssl/evp.h>
5#include <openssl/sha.h>
6#include <sys/ioctl.h>
7#include <sys/mount.h>
8#include <sys/stat.h>
9#include <sys/xattr.h>
10#include <unistd.h>
11
12#include "alloc-util.h"
13#include "errno-util.h"
14#include "fd-util.h"
15#include "format-util.h"
16#include "hexdecoct.h"
17#include "homework-fscrypt.h"
18#include "homework-mount.h"
19#include "homework-password-cache.h"
20#include "homework-quota.h"
21#include "homework.h"
22#include "keyring-util.h"
23#include "log.h"
24#include "memory-util.h"
25#include "missing_keyctl.h"
26#include "missing_syscall.h"
27#include "mkdir.h"
28#include "mount-util.h"
29#include "nulstr-util.h"
30#include "openssl-util.h"
31#include "parse-util.h"
32#include "process-util.h"
33#include "random-util.h"
34#include "rm-rf.h"
35#include "stdio-util.h"
36#include "string-util.h"
37#include "strv.h"
38#include "tmpfile-util.h"
39#include "user-record-util.h"
40#include "user-record.h"
41#include "user-util.h"
42#include "xattr-util.h"
43
44static int fscrypt_unlink_key(UserRecord *h) {
45 _cleanup_free_ void *keyring = NULL;
46 size_t keyring_size = 0, n_keys = 0;
47 int r;
48
49 assert(h);
50 assert(user_record_storage(h) == USER_FSCRYPT);
51
52 r = fully_set_uid_gid(
53 h->uid,
54 user_record_gid(h),
55 /* supplementary_gids= */ NULL,
56 /* n_supplementary_gids= */ 0);
57 if (r < 0)
58 return log_error_errno(r, "Failed to change UID/GID to " UID_FMT "/" GID_FMT ": %m",
59 h->uid, user_record_gid(h));
60
61 r = keyring_read(KEY_SPEC_USER_KEYRING, &keyring, &keyring_size);
62 if (r < 0)
63 return log_error_errno(r, "Failed to read the keyring of user " UID_FMT ": %m", h->uid);
64
65 n_keys = keyring_size / sizeof(key_serial_t);
66 assert(keyring_size % sizeof(key_serial_t) == 0);
67
68 /* Find any key with a description starting with 'fscrypt:' and unlink it. We need to iterate as we
69 * store the key with a description that uses the hash of the secret key, that we do not have when
70 * we are deactivating. */
71 FOREACH_ARRAY(key, ((key_serial_t *) keyring), n_keys) {
72 _cleanup_free_ char *description = NULL;
73 char *d;
74
75 r = keyring_describe(*key, &description);
76 if (r < 0) {
77 if (r == -ENOKEY) /* Something else deleted it already, that's ok. */
78 continue;
79
80 return log_error_errno(r, "Failed to describe key id %d: %m", *key);
81 }
82
83 /* The description is the final element as per manpage. */
84 d = strrchr(description, ';');
85 if (!d)
86 return log_error_errno(
87 SYNTHETIC_ERRNO(EINVAL),
88 "Failed to parse description of key id %d: %s",
89 *key,
90 description);
91
92 if (!startswith(d + 1, "fscrypt:"))
93 continue;
94
95 r = keyctl(KEYCTL_UNLINK, *key, KEY_SPEC_USER_KEYRING, 0, 0);
96 if (r < 0) {
97 if (errno == ENOKEY) /* Something else deleted it already, that's ok. */
98 continue;
99
100 return log_error_errno(
101 errno,
102 "Failed to delete encryption key with id '%d' from the keyring of user " UID_FMT ": %m",
103 *key,
104 h->uid);
105 }
106
107 log_debug("Deleted encryption key with id '%d' from the keyring of user " UID_FMT ".", *key, h->uid);
108 }
109
110 return 0;
111}
112
113int home_flush_keyring_fscrypt(UserRecord *h) {
114 int r;
115
116 assert(h);
117 assert(user_record_storage(h) == USER_FSCRYPT);
118
119 if (!uid_is_valid(h->uid))
120 return 0;
121
122 r = safe_fork("(sd-delkey)",
123 FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_REOPEN_LOG,
124 NULL);
125 if (r < 0)
126 return r;
127 if (r == 0) {
128 if (fscrypt_unlink_key(h) < 0)
129 _exit(EXIT_FAILURE);
130 _exit(EXIT_SUCCESS);
131 }
132
133 return 0;
134}
135
136static int fscrypt_upload_volume_key(
137 const uint8_t key_descriptor[static FS_KEY_DESCRIPTOR_SIZE],
138 const void *volume_key,
139 size_t volume_key_size,
140 key_serial_t where) {
141
142 _cleanup_free_ char *hex = NULL;
143 const char *description;
144 struct fscrypt_key key;
145 key_serial_t serial;
146
147 assert(key_descriptor);
148 assert(volume_key);
149 assert(volume_key_size > 0);
150
151 if (volume_key_size > sizeof(key.raw))
152 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume key too long.");
153
154 hex = hexmem(key_descriptor, FS_KEY_DESCRIPTOR_SIZE);
155 if (!hex)
156 return log_oom();
157
158 description = strjoina("fscrypt:", hex);
159
160 key = (struct fscrypt_key) {
161 .size = volume_key_size,
162 };
163 memcpy(key.raw, volume_key, volume_key_size);
164
165 CLEANUP_ERASE(key);
166
167 /* Upload to the kernel */
168 serial = add_key("logon", description, &key, sizeof(key), where);
169 if (serial < 0)
170 return log_error_errno(errno, "Failed to install master key in keyring: %m");
171
172 log_info("Uploaded encryption key to kernel.");
173
174 return 0;
175}
176
177static void calculate_key_descriptor(
178 const void *key,
179 size_t key_size,
180 uint8_t ret_key_descriptor[static FS_KEY_DESCRIPTOR_SIZE]) {
181
182 uint8_t hashed[512 / 8] = {}, hashed2[512 / 8] = {};
183
184 /* Derive the key descriptor from the volume key via double SHA512, in order to be compatible with e4crypt */
185
186 assert_se(SHA512(key, key_size, hashed) == hashed);
187 assert_se(SHA512(hashed, sizeof(hashed), hashed2) == hashed2);
188
189 assert_cc(sizeof(hashed2) >= FS_KEY_DESCRIPTOR_SIZE);
190
191 memcpy(ret_key_descriptor, hashed2, FS_KEY_DESCRIPTOR_SIZE);
192}
193
194static int fscrypt_slot_try_one(
195 const char *password,
196 const void *salt, size_t salt_size,
197 const void *encrypted, size_t encrypted_size,
198 const uint8_t match_key_descriptor[static FS_KEY_DESCRIPTOR_SIZE],
199 void **ret_decrypted, size_t *ret_decrypted_size) {
200
201 _cleanup_(EVP_CIPHER_CTX_freep) EVP_CIPHER_CTX *context = NULL;
202 _cleanup_(erase_and_freep) void *decrypted = NULL;
203 uint8_t key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
204 int decrypted_size_out1, decrypted_size_out2;
205 uint8_t derived[512 / 8] = {};
206 size_t decrypted_size;
207 const EVP_CIPHER *cc;
208 int r;
209
210 assert(password);
211 assert(salt);
212 assert(salt_size > 0);
213 assert(encrypted);
214 assert(encrypted_size > 0);
215 assert(match_key_descriptor);
216
217 /* Our construction is like this:
218 *
219 * 1. In each key slot we store a salt value plus the encrypted volume key
220 *
221 * 2. Unlocking is via calculating PBKDF2-HMAC-SHA512 of the supplied password (in combination with
222 * the salt), then using the first 256 bit of the hash as key for decrypting the encrypted
223 * volume key in AES256 counter mode.
224 *
225 * 3. Writing a password is similar: calculate PBKDF2-HMAC-SHA512 of the supplied password (in
226 * combination with the salt), then encrypt the volume key in AES256 counter mode with the
227 * resulting hash.
228 */
229
230 CLEANUP_ERASE(derived);
231
232 if (PKCS5_PBKDF2_HMAC(
233 password, strlen(password),
234 salt, salt_size,
235 0xFFFF, EVP_sha512(),
236 sizeof(derived), derived) != 1)
237 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "PBKDF2 failed.");
238
239 context = EVP_CIPHER_CTX_new();
240 if (!context)
241 return log_oom();
242
243 /* We use AES256 in counter mode */
244 assert_se(cc = EVP_aes_256_ctr());
245
246 /* We only use the first half of the derived key */
247 assert(sizeof(derived) >= (size_t) EVP_CIPHER_key_length(cc));
248
249 if (EVP_DecryptInit_ex(context, cc, NULL, derived, NULL) != 1)
250 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize decryption context.");
251
252 decrypted_size = encrypted_size + EVP_CIPHER_key_length(cc) * 2;
253 decrypted = malloc(decrypted_size);
254 if (!decrypted)
255 return log_oom();
256
257 if (EVP_DecryptUpdate(context, (uint8_t*) decrypted, &decrypted_size_out1, encrypted, encrypted_size) != 1)
258 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to decrypt volume key.");
259
260 assert((size_t) decrypted_size_out1 <= decrypted_size);
261
262 if (EVP_DecryptFinal_ex(context, (uint8_t*) decrypted_size + decrypted_size_out1, &decrypted_size_out2) != 1)
263 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finish decryption of volume key.");
264
265 assert((size_t) decrypted_size_out1 + (size_t) decrypted_size_out2 < decrypted_size);
266 decrypted_size = (size_t) decrypted_size_out1 + (size_t) decrypted_size_out2;
267
268 calculate_key_descriptor(decrypted, decrypted_size, key_descriptor);
269
270 if (memcmp(key_descriptor, match_key_descriptor, FS_KEY_DESCRIPTOR_SIZE) != 0)
271 return -ENOANO; /* don't log here */
272
273 r = fscrypt_upload_volume_key(key_descriptor, decrypted, decrypted_size, KEY_SPEC_THREAD_KEYRING);
274 if (r < 0)
275 return r;
276
277 if (ret_decrypted)
278 *ret_decrypted = TAKE_PTR(decrypted);
279 if (ret_decrypted_size)
280 *ret_decrypted_size = decrypted_size;
281
282 return 0;
283}
284
285static int fscrypt_slot_try_many(
286 char **passwords,
287 const void *salt, size_t salt_size,
288 const void *encrypted, size_t encrypted_size,
289 const uint8_t match_key_descriptor[static FS_KEY_DESCRIPTOR_SIZE],
290 void **ret_decrypted, size_t *ret_decrypted_size) {
291
292 int r;
293
294 STRV_FOREACH(i, passwords) {
295 r = fscrypt_slot_try_one(*i, salt, salt_size, encrypted, encrypted_size, match_key_descriptor, ret_decrypted, ret_decrypted_size);
296 if (r != -ENOANO)
297 return r;
298 }
299
300 return -ENOANO;
301}
302
303static int fscrypt_setup(
304 const PasswordCache *cache,
305 char **password,
306 HomeSetup *setup,
307 void **ret_volume_key,
308 size_t *ret_volume_key_size) {
309
310 _cleanup_free_ char *xattr_buf = NULL;
311 int r;
312
313 assert(setup);
314 assert(setup->root_fd >= 0);
315
316 r = flistxattr_malloc(setup->root_fd, &xattr_buf);
317 if (r < 0)
318 return log_error_errno(r, "Failed to retrieve xattr list: %m");
319
320 NULSTR_FOREACH(xa, xattr_buf) {
321 _cleanup_free_ void *salt = NULL, *encrypted = NULL;
322 _cleanup_free_ char *value = NULL;
323 size_t salt_size, encrypted_size, vsize;
324 const char *nr, *e;
325
326 /* Check if this xattr has the format 'trusted.fscrypt_slot<nr>' where '<nr>' is a 32-bit unsigned integer */
327 nr = startswith(xa, "trusted.fscrypt_slot");
328 if (!nr)
329 continue;
330 if (safe_atou32(nr, NULL) < 0)
331 continue;
332
333 r = fgetxattr_malloc(setup->root_fd, xa, &value, &vsize);
334 if (r == -ENODATA) /* deleted by now? */
335 continue;
336 if (r < 0)
337 return log_error_errno(r, "Failed to read %s xattr: %m", xa);
338
339 e = memchr(value, ':', vsize);
340 if (!e)
341 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "xattr %s lacks ':' separator.", xa);
342
343 r = unbase64mem_full(value, e - value, /* secure = */ false, &salt, &salt_size);
344 if (r < 0)
345 return log_error_errno(r, "Failed to decode salt of %s: %m", xa);
346
347 r = unbase64mem_full(e + 1, vsize - (e - value) - 1, /* secure = */ false, &encrypted, &encrypted_size);
348 if (r < 0)
349 return log_error_errno(r, "Failed to decode encrypted key of %s: %m", xa);
350
351 r = -ENOANO;
352 char **list;
353 FOREACH_ARGUMENT(list, cache->pkcs11_passwords, cache->fido2_passwords, password) {
354 r = fscrypt_slot_try_many(
355 list,
356 salt, salt_size,
357 encrypted, encrypted_size,
358 setup->fscrypt_key_descriptor,
359 ret_volume_key, ret_volume_key_size);
360 if (r >= 0)
361 return 0;
362 if (r != -ENOANO)
363 return r;
364 }
365 }
366
367 return log_error_errno(SYNTHETIC_ERRNO(ENOKEY), "Failed to set up home directory with provided passwords.");
368}
369
370int home_setup_fscrypt(
371 UserRecord *h,
372 HomeSetup *setup,
373 const PasswordCache *cache) {
374
375 _cleanup_(erase_and_freep) void *volume_key = NULL;
376 struct fscrypt_policy policy = {};
377 size_t volume_key_size = 0;
378 const char *ip;
379 int r;
380
381 assert(h);
382 assert(user_record_storage(h) == USER_FSCRYPT);
383 assert(setup);
384 assert(setup->root_fd < 0);
385
386 assert_se(ip = user_record_image_path(h));
387
388 setup->root_fd = open(ip, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
389 if (setup->root_fd < 0)
390 return log_error_errno(errno, "Failed to open home directory: %m");
391
392 if (ioctl(setup->root_fd, FS_IOC_GET_ENCRYPTION_POLICY, &policy) < 0) {
393 if (errno == ENODATA)
394 return log_error_errno(errno, "Home directory %s is not encrypted.", ip);
395 if (ERRNO_IS_NOT_SUPPORTED(errno)) {
396 log_error_errno(errno, "File system does not support fscrypt: %m");
397 return -ENOLINK; /* make recognizable */
398 }
399 return log_error_errno(errno, "Failed to acquire encryption policy of %s: %m", ip);
400 }
401
402 memcpy(setup->fscrypt_key_descriptor, policy.master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE);
403
404 r = fscrypt_setup(
405 cache,
406 h->password,
407 setup,
408 &volume_key,
409 &volume_key_size);
410 if (r < 0)
411 return r;
412
413 /* Also install the access key in the user's own keyring */
414
415 if (uid_is_valid(h->uid)) {
416 r = safe_fork("(sd-addkey)",
417 FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_REOPEN_LOG,
418 NULL);
419 if (r < 0)
420 return log_error_errno(r, "Failed install encryption key in user's keyring: %m");
421 if (r == 0) {
422 /* Child */
423
424 r = fully_set_uid_gid(h->uid, user_record_gid(h), /* supplementary_gids= */ NULL, /* n_supplementary_gids= */ 0);
425 if (r < 0) {
426 log_error_errno(r, "Failed to change UID/GID to " UID_FMT "/" GID_FMT ": %m", h->uid, user_record_gid(h));
427 _exit(EXIT_FAILURE);
428 }
429
430 r = fscrypt_upload_volume_key(
431 setup->fscrypt_key_descriptor,
432 volume_key,
433 volume_key_size,
434 KEY_SPEC_USER_KEYRING);
435 if (r < 0)
436 _exit(EXIT_FAILURE);
437
438 _exit(EXIT_SUCCESS);
439 }
440 }
441
442 /* We'll bind mount the image directory to a new mount point where we'll start adjusting it. Only
443 * once that's complete we'll move the thing to its final place eventually. */
444 r = home_unshare_and_mkdir();
445 if (r < 0)
446 return r;
447
448 r = mount_follow_verbose(LOG_ERR, ip, HOME_RUNTIME_WORK_DIR, NULL, MS_BIND, NULL);
449 if (r < 0)
450 return r;
451
452 setup->undo_mount = true;
453
454 /* Turn off any form of propagation for this */
455 r = mount_nofollow_verbose(LOG_ERR, NULL, HOME_RUNTIME_WORK_DIR, NULL, MS_PRIVATE, NULL);
456 if (r < 0)
457 return r;
458
459 /* Adjust MS_SUID and similar flags */
460 r = mount_nofollow_verbose(LOG_ERR, NULL, HOME_RUNTIME_WORK_DIR, NULL, MS_BIND|MS_REMOUNT|user_record_mount_flags(h), NULL);
461 if (r < 0)
462 return r;
463
464 safe_close(setup->root_fd);
465 setup->root_fd = open(HOME_RUNTIME_WORK_DIR, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
466 if (setup->root_fd < 0)
467 return log_error_errno(errno, "Failed to open home directory: %m");
468
469 return 0;
470}
471
472static int fscrypt_slot_set(
473 int root_fd,
474 const void *volume_key,
475 size_t volume_key_size,
476 const char *password,
477 uint32_t nr) {
478
479 _cleanup_free_ char *salt_base64 = NULL, *encrypted_base64 = NULL, *joined = NULL;
480 char label[STRLEN("trusted.fscrypt_slot") + DECIMAL_STR_MAX(nr) + 1];
481 _cleanup_(EVP_CIPHER_CTX_freep) EVP_CIPHER_CTX *context = NULL;
482 int r, encrypted_size_out1, encrypted_size_out2;
483 uint8_t salt[64], derived[512 / 8] = {};
484 _cleanup_free_ void *encrypted = NULL;
485 const EVP_CIPHER *cc;
486 size_t encrypted_size;
487 ssize_t ss;
488
489 r = crypto_random_bytes(salt, sizeof(salt));
490 if (r < 0)
491 return log_error_errno(r, "Failed to generate salt: %m");
492
493 CLEANUP_ERASE(derived);
494
495 if (PKCS5_PBKDF2_HMAC(
496 password, strlen(password),
497 salt, sizeof(salt),
498 0xFFFF, EVP_sha512(),
499 sizeof(derived), derived) != 1)
500 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "PBKDF2 failed");
501
502 context = EVP_CIPHER_CTX_new();
503 if (!context)
504 return log_oom();
505
506 /* We use AES256 in counter mode */
507 cc = EVP_aes_256_ctr();
508
509 /* We only use the first half of the derived key */
510 assert(sizeof(derived) >= (size_t) EVP_CIPHER_key_length(cc));
511
512 if (EVP_EncryptInit_ex(context, cc, NULL, derived, NULL) != 1)
513 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize encryption context.");
514
515 encrypted_size = volume_key_size + EVP_CIPHER_key_length(cc) * 2;
516 encrypted = malloc(encrypted_size);
517 if (!encrypted)
518 return log_oom();
519
520 if (EVP_EncryptUpdate(context, (uint8_t*) encrypted, &encrypted_size_out1, volume_key, volume_key_size) != 1)
521 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to encrypt volume key.");
522
523 assert((size_t) encrypted_size_out1 <= encrypted_size);
524
525 if (EVP_EncryptFinal_ex(context, (uint8_t*) encrypted_size + encrypted_size_out1, &encrypted_size_out2) != 1)
526 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finish encryption of volume key.");
527
528 assert((size_t) encrypted_size_out1 + (size_t) encrypted_size_out2 < encrypted_size);
529 encrypted_size = (size_t) encrypted_size_out1 + (size_t) encrypted_size_out2;
530
531 ss = base64mem(salt, sizeof(salt), &salt_base64);
532 if (ss < 0)
533 return log_oom();
534
535 ss = base64mem(encrypted, encrypted_size, &encrypted_base64);
536 if (ss < 0)
537 return log_oom();
538
539 joined = strjoin(salt_base64, ":", encrypted_base64);
540 if (!joined)
541 return log_oom();
542
543 xsprintf(label, "trusted.fscrypt_slot%" PRIu32, nr);
544 if (fsetxattr(root_fd, label, joined, strlen(joined), 0) < 0)
545 return log_error_errno(errno, "Failed to write xattr %s: %m", label);
546
547 log_info("Written key slot %s.", label);
548
549 return 0;
550}
551
552int home_create_fscrypt(
553 UserRecord *h,
554 HomeSetup *setup,
555 char **effective_passwords,
556 UserRecord **ret_home) {
557
558 _cleanup_(rm_rf_physical_and_freep) char *temporary = NULL;
559 _cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
560 _cleanup_(erase_and_freep) void *volume_key = NULL;
561 _cleanup_close_ int mount_fd = -EBADF;
562 struct fscrypt_policy policy = {};
563 size_t volume_key_size = 512 / 8;
564 _cleanup_free_ char *d = NULL;
565 uint32_t nr = 0;
566 const char *ip;
567 int r;
568
569 assert(h);
570 assert(user_record_storage(h) == USER_FSCRYPT);
571 assert(setup);
572 assert(ret_home);
573
574 assert_se(ip = user_record_image_path(h));
575
576 r = tempfn_random(ip, "homework", &d);
577 if (r < 0)
578 return log_error_errno(r, "Failed to allocate temporary directory: %m");
579
580 (void) mkdir_parents(d, 0755);
581
582 if (mkdir(d, 0700) < 0)
583 return log_error_errno(errno, "Failed to create temporary home directory %s: %m", d);
584
585 temporary = TAKE_PTR(d); /* Needs to be destroyed now */
586
587 r = home_unshare_and_mkdir();
588 if (r < 0)
589 return r;
590
591 setup->root_fd = open(temporary, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
592 if (setup->root_fd < 0)
593 return log_error_errno(errno, "Failed to open temporary home directory: %m");
594
595 if (ioctl(setup->root_fd, FS_IOC_GET_ENCRYPTION_POLICY, &policy) < 0) {
596 if (ERRNO_IS_NOT_SUPPORTED(errno)) {
597 log_error_errno(errno, "File system does not support fscrypt: %m");
598 return -ENOLINK; /* make recognizable */
599 }
600 if (errno != ENODATA)
601 return log_error_errno(errno, "Failed to get fscrypt policy of directory: %m");
602 } else
603 return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Parent of %s already encrypted, refusing.", d);
604
605 volume_key = malloc(volume_key_size);
606 if (!volume_key)
607 return log_oom();
608
609 r = crypto_random_bytes(volume_key, volume_key_size);
610 if (r < 0)
611 return log_error_errno(r, "Failed to acquire volume key: %m");
612
613 log_info("Generated volume key of size %zu.", volume_key_size);
614
615 policy = (struct fscrypt_policy) {
616 .contents_encryption_mode = FS_ENCRYPTION_MODE_AES_256_XTS,
617 .filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_256_CTS,
618 .flags = FS_POLICY_FLAGS_PAD_32,
619 };
620
621 calculate_key_descriptor(volume_key, volume_key_size, policy.master_key_descriptor);
622
623 r = fscrypt_upload_volume_key(policy.master_key_descriptor, volume_key, volume_key_size, KEY_SPEC_THREAD_KEYRING);
624 if (r < 0)
625 return r;
626
627 log_info("Uploaded volume key to kernel.");
628
629 if (ioctl(setup->root_fd, FS_IOC_SET_ENCRYPTION_POLICY, &policy) < 0)
630 return log_error_errno(errno, "Failed to set fscrypt policy on directory: %m");
631
632 log_info("Encryption policy set.");
633
634 STRV_FOREACH(i, effective_passwords) {
635 r = fscrypt_slot_set(setup->root_fd, volume_key, volume_key_size, *i, nr);
636 if (r < 0)
637 return r;
638
639 nr++;
640 }
641
642 (void) home_update_quota_classic(h, setup->root_fd, temporary);
643
644 r = home_shift_uid(setup->root_fd, HOME_RUNTIME_WORK_DIR, h->uid, h->uid, &mount_fd);
645 if (r > 0)
646 setup->undo_mount = true; /* If uidmaps worked we have a mount to undo again */
647
648 if (mount_fd >= 0) {
649 /* If we have established a new mount, then we can use that as new root fd to our home directory. */
650 safe_close(setup->root_fd);
651
652 setup->root_fd = fd_reopen(mount_fd, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
653 if (setup->root_fd < 0)
654 return log_error_errno(setup->root_fd, "Unable to convert mount fd into proper directory fd: %m");
655
656 mount_fd = safe_close(mount_fd);
657 }
658
659 r = home_populate(h, setup->root_fd);
660 if (r < 0)
661 return r;
662
663 r = home_sync_and_statfs(setup->root_fd, NULL);
664 if (r < 0)
665 return r;
666
667 r = user_record_clone(h, USER_RECORD_LOAD_MASK_SECRET|USER_RECORD_PERMISSIVE, &new_home);
668 if (r < 0)
669 return log_error_errno(r, "Failed to clone record: %m");
670
671 r = user_record_add_binding(
672 new_home,
673 USER_FSCRYPT,
674 ip,
675 SD_ID128_NULL,
676 SD_ID128_NULL,
677 SD_ID128_NULL,
678 NULL,
679 NULL,
680 UINT64_MAX,
681 NULL,
682 NULL,
683 h->uid,
684 (gid_t) h->uid);
685 if (r < 0)
686 return log_error_errno(r, "Failed to add binding to record: %m");
687
688 setup->root_fd = safe_close(setup->root_fd);
689
690 r = home_setup_undo_mount(setup, LOG_ERR);
691 if (r < 0)
692 return r;
693
694 if (rename(temporary, ip) < 0)
695 return log_error_errno(errno, "Failed to rename %s to %s: %m", temporary, ip);
696
697 temporary = mfree(temporary);
698
699 log_info("Everything completed.");
700
701 *ret_home = TAKE_PTR(new_home);
702 return 0;
703}
704
705int home_passwd_fscrypt(
706 UserRecord *h,
707 HomeSetup *setup,
708 const PasswordCache *cache, /* the passwords acquired via PKCS#11/FIDO2 security tokens */
709 char **effective_passwords /* new passwords */) {
710
711 _cleanup_(erase_and_freep) void *volume_key = NULL;
712 _cleanup_free_ char *xattr_buf = NULL;
713 size_t volume_key_size = 0;
714 uint32_t slot = 0;
715 int r;
716
717 assert(h);
718 assert(user_record_storage(h) == USER_FSCRYPT);
719 assert(setup);
720
721 r = fscrypt_setup(
722 cache,
723 h->password,
724 setup,
725 &volume_key,
726 &volume_key_size);
727 if (r < 0)
728 return r;
729
730 STRV_FOREACH(p, effective_passwords) {
731 r = fscrypt_slot_set(setup->root_fd, volume_key, volume_key_size, *p, slot);
732 if (r < 0)
733 return r;
734
735 slot++;
736 }
737
738 r = flistxattr_malloc(setup->root_fd, &xattr_buf);
739 if (r < 0)
740 return log_error_errno(r, "Failed to retrieve xattr list: %m");
741
742 NULSTR_FOREACH(xa, xattr_buf) {
743 const char *nr;
744 uint32_t z;
745
746 /* Check if this xattr has the format 'trusted.fscrypt_slot<nr>' where '<nr>' is a 32-bit unsigned integer */
747 nr = startswith(xa, "trusted.fscrypt_slot");
748 if (!nr)
749 continue;
750 if (safe_atou32(nr, &z) < 0)
751 continue;
752
753 if (z < slot)
754 continue;
755
756 if (fremovexattr(setup->root_fd, xa) < 0)
757 if (errno != ENODATA)
758 log_warning_errno(errno, "Failed to remove xattr %s: %m", xa);
759 }
760
761 return 0;
762}