mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-14 04:10:06 +01:00
Add api test for CRYPT_ACTIVATE_REFRESH flag.
This commit is contained in:
committed by
Milan Broz
parent
df2111eb4f
commit
545b347ca5
@@ -2954,6 +2954,177 @@ static void Luks2Integrity(void)
|
|||||||
crypt_free(cd);
|
crypt_free(cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_fast_pbkdf(struct crypt_device *cd)
|
||||||
|
{
|
||||||
|
struct crypt_pbkdf_type pbkdf = {
|
||||||
|
.type = "argon2id",
|
||||||
|
.hash = "sha256",
|
||||||
|
.iterations = 4,
|
||||||
|
.max_memory_kb = 32,
|
||||||
|
.parallel_threads = 1,
|
||||||
|
.flags = CRYPT_PBKDF_NO_BENCHMARK
|
||||||
|
};
|
||||||
|
return crypt_set_pbkdf_type(cd, &pbkdf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_flag(uint32_t flags, uint32_t flag)
|
||||||
|
{
|
||||||
|
return (flags & flag) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Luks2Refresh(void)
|
||||||
|
{
|
||||||
|
uint64_t r_payload_offset;
|
||||||
|
struct crypt_device *cd1, *cd2;
|
||||||
|
char key[128], key1[128];
|
||||||
|
const char *cipher = "aes", *mode = "xts-plain64";
|
||||||
|
const char *mk_hex = "bb21158c733229347bd4e681891e213d94c645be6a5b84818afe7a78a6de7a1a";
|
||||||
|
const char *mk_hex2 = "bb22158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e";
|
||||||
|
size_t key_size = strlen(mk_hex) / 2;
|
||||||
|
struct crypt_params_luks2 params = {
|
||||||
|
.sector_size = 512,
|
||||||
|
.integrity = "aead"
|
||||||
|
};
|
||||||
|
struct crypt_active_device cad = {};
|
||||||
|
|
||||||
|
crypt_decode_key(key, mk_hex, key_size);
|
||||||
|
crypt_decode_key(key1, mk_hex2, key_size);
|
||||||
|
|
||||||
|
OK_(get_luks2_offsets(0, 8192, 0, 0, NULL, &r_payload_offset));
|
||||||
|
OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1000));
|
||||||
|
OK_(create_dmdevice_over_loop(L_DEVICE_WRONG, r_payload_offset + 5000));
|
||||||
|
OK_(create_dmdevice_over_loop(L_DEVICE_1S, r_payload_offset + 1));
|
||||||
|
OK_(create_dmdevice_over_loop(H_DEVICE, r_payload_offset));
|
||||||
|
|
||||||
|
/* prepare test device */
|
||||||
|
OK_(crypt_init(&cd1, DMDIR L_DEVICE_OK));
|
||||||
|
OK_(set_fast_pbkdf(cd1));
|
||||||
|
OK_(crypt_format(cd1, CRYPT_LUKS2, cipher, mode, NULL, key, 32, NULL));
|
||||||
|
OK_(crypt_keyslot_add_by_volume_key(cd1, CRYPT_ANY_SLOT, key, 32, "aaa", 3));
|
||||||
|
OK_(crypt_activate_by_passphrase(cd1, CDEVICE_1, 0, "aaa", 3, 0));
|
||||||
|
|
||||||
|
/* check we can refresh significant flags */
|
||||||
|
if (t_dm_crypt_discard_support()) {
|
||||||
|
OK_(crypt_activate_by_passphrase(cd1, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_ALLOW_DISCARDS));
|
||||||
|
OK_(crypt_get_active_device(cd1, CDEVICE_1, &cad));
|
||||||
|
OK_(check_flag(cad.flags, CRYPT_ACTIVATE_ALLOW_DISCARDS));
|
||||||
|
cad.flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t_dm_crypt_cpu_switch_support()) {
|
||||||
|
OK_(crypt_activate_by_passphrase(cd1, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_SAME_CPU_CRYPT));
|
||||||
|
OK_(crypt_get_active_device(cd1, CDEVICE_1, &cad));
|
||||||
|
OK_(check_flag(cad.flags, CRYPT_ACTIVATE_SAME_CPU_CRYPT));
|
||||||
|
cad.flags = 0;
|
||||||
|
|
||||||
|
OK_(crypt_activate_by_passphrase(cd1, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS));
|
||||||
|
OK_(crypt_get_active_device(cd1, CDEVICE_1, &cad));
|
||||||
|
OK_(check_flag(cad.flags, CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS));
|
||||||
|
cad.flags = 0;
|
||||||
|
|
||||||
|
OK_(crypt_activate_by_passphrase(cd1, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS));
|
||||||
|
OK_(crypt_get_active_device(cd1, CDEVICE_1, &cad));
|
||||||
|
OK_(check_flag(cad.flags, CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS));
|
||||||
|
cad.flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
OK_(crypt_volume_key_keyring(cd1, 0));
|
||||||
|
OK_(crypt_activate_by_passphrase(cd1, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH));
|
||||||
|
OK_(crypt_get_active_device(cd1, CDEVICE_1, &cad));
|
||||||
|
FAIL_(check_flag(cad.flags, CRYPT_ACTIVATE_KEYRING_KEY), "Unexpected flag raised.");
|
||||||
|
cad.flags = 0;
|
||||||
|
|
||||||
|
#ifdef KERNEL_KEYRING
|
||||||
|
if (t_dm_crypt_keyring_support()) {
|
||||||
|
OK_(crypt_volume_key_keyring(cd1, 1));
|
||||||
|
OK_(crypt_activate_by_passphrase(cd1, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH));
|
||||||
|
OK_(crypt_get_active_device(cd1, CDEVICE_1, &cad));
|
||||||
|
OK_(check_flag(cad.flags, CRYPT_ACTIVATE_KEYRING_KEY));
|
||||||
|
cad.flags = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* multiple flags at once */
|
||||||
|
if (t_dm_crypt_discard_support() && t_dm_crypt_cpu_switch_support()) {
|
||||||
|
OK_(crypt_activate_by_passphrase(cd1, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS | CRYPT_ACTIVATE_ALLOW_DISCARDS));
|
||||||
|
OK_(crypt_get_active_device(cd1, CDEVICE_1, &cad));
|
||||||
|
OK_(check_flag(cad.flags, CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS | CRYPT_ACTIVATE_ALLOW_DISCARDS));
|
||||||
|
cad.flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do not allow reactivation with read-only (and drop flag silently because activation behaves exactly same) */
|
||||||
|
OK_(crypt_activate_by_passphrase(cd1, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_READONLY));
|
||||||
|
OK_(crypt_get_active_device(cd1, CDEVICE_1, &cad));
|
||||||
|
FAIL_(check_flag(cad.flags, CRYPT_ACTIVATE_READONLY), "Reactivated with read-only flag.");
|
||||||
|
cad.flags = 0;
|
||||||
|
|
||||||
|
/* reload flag is dropped silently */
|
||||||
|
OK_(crypt_deactivate(cd1, CDEVICE_1));
|
||||||
|
OK_(crypt_activate_by_passphrase(cd1, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH));
|
||||||
|
|
||||||
|
/* check read-only flag is not lost after reload */
|
||||||
|
OK_(crypt_deactivate(cd1, CDEVICE_1));
|
||||||
|
OK_(crypt_activate_by_passphrase(cd1, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_READONLY));
|
||||||
|
OK_(crypt_activate_by_passphrase(cd1, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH));
|
||||||
|
OK_(crypt_get_active_device(cd1, CDEVICE_1, &cad));
|
||||||
|
OK_(check_flag(cad.flags, CRYPT_ACTIVATE_READONLY));
|
||||||
|
cad.flags = 0;
|
||||||
|
|
||||||
|
/* check LUKS2 with auth. enc. reload */
|
||||||
|
OK_(crypt_init(&cd2, DMDIR L_DEVICE_WRONG));
|
||||||
|
if (!crypt_format(cd2, CRYPT_LUKS2, "aes", "gcm-random", crypt_get_uuid(cd1), key, 32, ¶ms)) {
|
||||||
|
OK_(crypt_keyslot_add_by_volume_key(cd2, 0, key, 32, "aaa", 3));
|
||||||
|
OK_(crypt_activate_by_volume_key(cd2, CDEVICE_2, key, 32, 0));
|
||||||
|
OK_(crypt_activate_by_volume_key(cd2, CDEVICE_2, key, 32, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_NO_JOURNAL));
|
||||||
|
OK_(crypt_get_active_device(cd2, CDEVICE_2, &cad));
|
||||||
|
OK_(check_flag(cad.flags, CRYPT_ACTIVATE_NO_JOURNAL));
|
||||||
|
cad.flags = 0;
|
||||||
|
OK_(crypt_activate_by_volume_key(cd2, CDEVICE_2, key, 32, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_NO_JOURNAL | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS));
|
||||||
|
OK_(crypt_get_active_device(cd2, CDEVICE_2, &cad));
|
||||||
|
OK_(check_flag(cad.flags, CRYPT_ACTIVATE_NO_JOURNAL | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS));
|
||||||
|
cad.flags = 0;
|
||||||
|
OK_(crypt_activate_by_passphrase(cd2, CDEVICE_2, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH));
|
||||||
|
OK_(crypt_get_active_device(cd2, CDEVICE_2, &cad));
|
||||||
|
FAIL_(check_flag(cad.flags, CRYPT_ACTIVATE_NO_JOURNAL), "");
|
||||||
|
FAIL_(check_flag(cad.flags, CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS), "");
|
||||||
|
FAIL_(crypt_activate_by_passphrase(cd2, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH), "Refreshed LUKS2 device with LUKS2/aead context");
|
||||||
|
OK_(crypt_deactivate(cd2, CDEVICE_2));
|
||||||
|
} else {
|
||||||
|
printf("WARNING: cannot format integrity device, skipping few reload tests.\n");
|
||||||
|
}
|
||||||
|
crypt_free(cd2);
|
||||||
|
|
||||||
|
/* Use LUKS1 context on LUKS2 device */
|
||||||
|
OK_(crypt_init(&cd2, DMDIR L_DEVICE_1S));
|
||||||
|
OK_(crypt_format(cd2, CRYPT_LUKS1, cipher, mode, crypt_get_uuid(cd1), key, 32, NULL));
|
||||||
|
OK_(crypt_keyslot_add_by_volume_key(cd2, CRYPT_ANY_SLOT, NULL, 32, "aaa", 3));
|
||||||
|
FAIL_(crypt_activate_by_passphrase(cd2, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH), "Refreshed LUKS2 device with LUKS1 context");
|
||||||
|
crypt_free(cd2);
|
||||||
|
|
||||||
|
/* Use PLAIN context on LUKS2 device */
|
||||||
|
OK_(crypt_init(&cd2, DMDIR L_DEVICE_1S));
|
||||||
|
OK_(crypt_format(cd2, CRYPT_PLAIN, cipher, mode, NULL, key, 32, NULL));
|
||||||
|
OK_(crypt_activate_by_volume_key(cd2, CDEVICE_2, key, key_size, 0));
|
||||||
|
FAIL_(crypt_activate_by_volume_key(cd2, CDEVICE_1, key, key_size, CRYPT_ACTIVATE_REFRESH), "Refreshed LUKS2 device with PLAIN context");
|
||||||
|
OK_(crypt_deactivate(cd2, CDEVICE_2));
|
||||||
|
crypt_free(cd2);
|
||||||
|
|
||||||
|
/* (snapshot-like case) */
|
||||||
|
/* try to refresh almost identical device (differs only in major:minor of data device) */
|
||||||
|
OK_(crypt_init(&cd2, DMDIR L_DEVICE_WRONG));
|
||||||
|
OK_(set_fast_pbkdf(cd2));
|
||||||
|
OK_(crypt_format(cd2, CRYPT_LUKS2, cipher, mode, crypt_get_uuid(cd1), key, 32, NULL));
|
||||||
|
OK_(crypt_keyslot_add_by_volume_key(cd2, CRYPT_ANY_SLOT, key, 32, "aaa", 3));
|
||||||
|
FAIL_(crypt_activate_by_passphrase(cd2, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH), "Refreshed dm-crypt mapped over mismatching data device");
|
||||||
|
|
||||||
|
OK_(crypt_deactivate(cd1, CDEVICE_1));
|
||||||
|
|
||||||
|
crypt_free(cd1);
|
||||||
|
crypt_free(cd2);
|
||||||
|
|
||||||
|
_cleanup_dmdevices();
|
||||||
|
}
|
||||||
|
|
||||||
static void Luks2Flags(void)
|
static void Luks2Flags(void)
|
||||||
{
|
{
|
||||||
struct crypt_device *cd;
|
struct crypt_device *cd;
|
||||||
@@ -3085,6 +3256,7 @@ int main(int argc, char *argv[])
|
|||||||
RUN_(Luks2ActivateByKeyring, "LUKS2 activation by passphrase in keyring");
|
RUN_(Luks2ActivateByKeyring, "LUKS2 activation by passphrase in keyring");
|
||||||
RUN_(Luks2Requirements, "LUKS2 requirements flags");
|
RUN_(Luks2Requirements, "LUKS2 requirements flags");
|
||||||
RUN_(Luks2Integrity, "LUKS2 with data integrity");
|
RUN_(Luks2Integrity, "LUKS2 with data integrity");
|
||||||
|
RUN_(Luks2Refresh, "Active device table refresh");
|
||||||
RUN_(Luks2Flags, "LUKS2 persistent flags");
|
RUN_(Luks2Flags, "LUKS2 persistent flags");
|
||||||
RUN_(Luks2Repair, "LUKS2 repair"); // test disables metadata locking. Run always last!
|
RUN_(Luks2Repair, "LUKS2 repair"); // test disables metadata locking. Run always last!
|
||||||
out:
|
out:
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ extern uint64_t t_dev_offset;
|
|||||||
int t_device_size(const char *device, uint64_t *size);
|
int t_device_size(const char *device, uint64_t *size);
|
||||||
int t_dm_check_versions(void);
|
int t_dm_check_versions(void);
|
||||||
int t_dm_crypt_keyring_support(void);
|
int t_dm_crypt_keyring_support(void);
|
||||||
|
int t_dm_crypt_cpu_switch_support(void);
|
||||||
|
int t_dm_crypt_discard_support(void);
|
||||||
|
|
||||||
int fips_mode(void);
|
int fips_mode(void);
|
||||||
|
|
||||||
|
|||||||
@@ -421,6 +421,17 @@ int t_dm_crypt_keyring_support(void)
|
|||||||
return t_dm_crypt_flags & T_DM_KERNEL_KEYRING_SUPPORTED;
|
return t_dm_crypt_flags & T_DM_KERNEL_KEYRING_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int t_dm_crypt_cpu_switch_support(void)
|
||||||
|
{
|
||||||
|
return t_dm_crypt_flags & (T_DM_SAME_CPU_CRYPT_SUPPORTED |
|
||||||
|
T_DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
int t_dm_crypt_discard_support(void)
|
||||||
|
{
|
||||||
|
return t_dm_crypt_flags & T_DM_DISCARDS_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
/* loop helpers */
|
/* loop helpers */
|
||||||
|
|
||||||
#define LOOP_DEV_MAJOR 7
|
#define LOOP_DEV_MAJOR 7
|
||||||
|
|||||||
Reference in New Issue
Block a user