1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "cryptenroll-pkcs11.h"
6 #include "memory-util.h"
7 #include "openssl-util.h"
8 #include "pkcs11-util.h"
9 #include "random-util.h"
12 struct crypt_device
*cd
,
13 const void *volume_key
,
14 size_t volume_key_size
,
17 _cleanup_(erase_and_freep
) void *decrypted_key
= NULL
;
18 _cleanup_(erase_and_freep
) char *base64_encoded
= NULL
;
19 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
20 _cleanup_free_
char *keyslot_as_string
= NULL
;
21 size_t decrypted_key_size
, encrypted_key_size
;
22 _cleanup_free_
void *encrypted_key
= NULL
;
23 _cleanup_(X509_freep
) X509
*cert
= NULL
;
24 ssize_t base64_encoded_size
;
30 assert_se(volume_key
);
31 assert_se(volume_key_size
> 0);
34 assert_se(node
= crypt_get_device_name(cd
));
36 r
= pkcs11_acquire_certificate(uri
, "volume enrollment operation", "drive-harddisk", &cert
, NULL
);
40 pkey
= X509_get0_pubkey(cert
);
42 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to extract public key from X.509 certificate.");
44 r
= rsa_pkey_to_suitable_key_size(pkey
, &decrypted_key_size
);
46 return log_error_errno(r
, "Failed to determine RSA public key size.");
48 log_debug("Generating %zu bytes random key.", decrypted_key_size
);
50 decrypted_key
= malloc(decrypted_key_size
);
54 r
= crypto_random_bytes(decrypted_key
, decrypted_key_size
);
56 return log_error_errno(r
, "Failed to generate random key: %m");
58 r
= rsa_encrypt_bytes(pkey
, decrypted_key
, decrypted_key_size
, &encrypted_key
, &encrypted_key_size
);
60 return log_error_errno(r
, "Failed to encrypt key: %m");
62 /* Let's base64 encode the key to use, for compat with homed (and it's easier to type it in by
63 * keyboard, if that might ever end up being necessary.) */
64 base64_encoded_size
= base64mem(decrypted_key
, decrypted_key_size
, &base64_encoded
);
65 if (base64_encoded_size
< 0)
66 return log_error_errno(base64_encoded_size
, "Failed to base64 encode secret key: %m");
68 r
= cryptsetup_set_minimal_pbkdf(cd
);
70 return log_error_errno(r
, "Failed to set minimal PBKDF: %m");
72 keyslot
= crypt_keyslot_add_by_volume_key(
80 return log_error_errno(keyslot
, "Failed to add new PKCS#11 key to %s: %m", node
);
82 if (asprintf(&keyslot_as_string
, "%i", keyslot
) < 0)
87 JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("systemd-pkcs11")),
88 JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string
))),
89 JSON_BUILD_PAIR("pkcs11-uri", JSON_BUILD_STRING(uri
)),
90 JSON_BUILD_PAIR("pkcs11-key", JSON_BUILD_BASE64(encrypted_key
, encrypted_key_size
))));
92 return log_error_errno(r
, "Failed to prepare PKCS#11 JSON token object: %m");
94 r
= cryptsetup_add_token_json(cd
, v
);
96 return log_error_errno(r
, "Failed to add PKCS#11 JSON token to LUKS2 header: %m");
98 log_info("New PKCS#11 token enrolled as key slot %i.", keyslot
);