mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-09 09:49:59 +01:00
Introduce CRYPT_SLOT_UNBOUND keyslot status for LUKS2.
A keyslot not bound to any segment can store any key for any purpose. To easily check slot status, new enum value is introduced. This status is valid only for LUKS2, so the functions are backward compatible with LUKS1.
This commit is contained in:
@@ -956,6 +956,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
|
||||
#define CRYPT_ACTIVATE_IGNORE_PERSISTENT (1 << 14)
|
||||
/** dm-verity: check_at_most_once - check data blocks only the first time */
|
||||
#define CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE (1 << 15)
|
||||
/** allow activation check including unbound keyslots (kesylots without segments) */
|
||||
#define CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY (1 << 16)
|
||||
|
||||
/**
|
||||
* Active device runtime attributes
|
||||
@@ -1437,8 +1439,10 @@ typedef enum {
|
||||
CRYPT_SLOT_INVALID, /**< invalid keyslot */
|
||||
CRYPT_SLOT_INACTIVE, /**< keyslot is inactive (free) */
|
||||
CRYPT_SLOT_ACTIVE, /**< keyslot is active (used) */
|
||||
CRYPT_SLOT_ACTIVE_LAST /**< keylost is active (used)
|
||||
CRYPT_SLOT_ACTIVE_LAST,/**< keylost is active (used)
|
||||
* and last used at the same time */
|
||||
CRYPT_SLOT_UNBOUND /**< keyslot is active and not bound
|
||||
* to any crypt segment (LUKS2 only) */
|
||||
} crypt_keyslot_info;
|
||||
|
||||
/**
|
||||
|
||||
@@ -175,6 +175,7 @@ int LUKS2_digest_verify_by_segment(struct crypt_device *cd,
|
||||
return digest;
|
||||
}
|
||||
|
||||
/* FIXME: segment can have more digests */
|
||||
int LUKS2_digest_by_segment(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int segment)
|
||||
|
||||
@@ -882,17 +882,11 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* NOTE: is called before LUKS2 validation routines */
|
||||
static void LUKS2_hdr_free_unused_objects(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
/* erase unused digests (no assigned keyslot or segment) */
|
||||
LUKS2_digests_erase_unused(cd, hdr);
|
||||
}
|
||||
|
||||
int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
/* FIXME: we risk to hide future internal implementation bugs with this */
|
||||
LUKS2_hdr_free_unused_objects(cd, hdr);
|
||||
/* NOTE: is called before LUKS2 validation routines */
|
||||
/* erase unused digests (no assigned keyslot or segment) */
|
||||
LUKS2_digests_erase_unused(cd, hdr);
|
||||
|
||||
if (LUKS2_hdr_validate(hdr->jobj))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -63,14 +63,6 @@ static const keyslot_handler
|
||||
return LUKS2_keyslot_handler_type(cd, json_object_get_string(jobj2));
|
||||
}
|
||||
|
||||
static crypt_keyslot_info LUKS2_keyslot_active(struct luks2_hdr *hdr, int keyslot)
|
||||
{
|
||||
if (keyslot >= LUKS2_KEYSLOTS_MAX)
|
||||
return CRYPT_SLOT_INVALID;
|
||||
|
||||
return LUKS2_get_keyslot_jobj(hdr, keyslot) ? CRYPT_SLOT_ACTIVE : CRYPT_SLOT_INACTIVE;
|
||||
}
|
||||
|
||||
int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr, const char *type)
|
||||
{
|
||||
int i;
|
||||
@@ -82,6 +74,7 @@ int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr, const char *type)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check if a keyslot is asssigned to specific segment */
|
||||
int LUKS2_keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment)
|
||||
{
|
||||
int keyslot_digest, segment_digest;
|
||||
@@ -101,6 +94,7 @@ int LUKS2_keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment)
|
||||
return segment_digest == keyslot_digest ? 0 : -ENOENT;
|
||||
}
|
||||
|
||||
/* Number of keyslots assigned to a segment or all keyslots for CRYPT_ANY_SEGMENT */
|
||||
int LUKS2_keyslot_active_count(struct luks2_hdr *hdr, int segment)
|
||||
{
|
||||
int num = 0;
|
||||
@@ -176,18 +170,38 @@ int LUKS2_keyslot_params_default(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int LUKS2_keyslot_unbound(struct luks2_hdr *hdr, int keyslot)
|
||||
{
|
||||
json_object *jobj_digest, *jobj_segments;
|
||||
int digest = LUKS2_digest_by_keyslot(NULL, hdr, keyslot);
|
||||
|
||||
if (digest < 0)
|
||||
return 0;
|
||||
|
||||
if (!(jobj_digest = LUKS2_get_digest_jobj(hdr, digest)))
|
||||
return 0;
|
||||
|
||||
json_object_object_get_ex(jobj_digest, "segments", &jobj_segments);
|
||||
if (!jobj_segments || !json_object_is_type(jobj_segments, json_type_array) ||
|
||||
json_object_array_length(jobj_segments) == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
crypt_keyslot_info LUKS2_keyslot_info(struct luks2_hdr *hdr, int keyslot)
|
||||
{
|
||||
crypt_keyslot_info ki;
|
||||
|
||||
if(keyslot >= LUKS2_KEYSLOTS_MAX || keyslot < 0)
|
||||
return CRYPT_SLOT_INVALID;
|
||||
|
||||
ki = LUKS2_keyslot_active(hdr, keyslot);
|
||||
if (ki != CRYPT_SLOT_ACTIVE)
|
||||
return ki;
|
||||
if (!LUKS2_get_keyslot_jobj(hdr, keyslot))
|
||||
return CRYPT_SLOT_INACTIVE;
|
||||
|
||||
if (LUKS2_keyslot_active_count(hdr, CRYPT_DEFAULT_SEGMENT) == 1 && !LUKS2_keyslot_for_segment(hdr, keyslot, CRYPT_DEFAULT_SEGMENT))
|
||||
if (LUKS2_keyslot_unbound(hdr, keyslot))
|
||||
return CRYPT_SLOT_UNBOUND;
|
||||
|
||||
if (LUKS2_keyslot_active_count(hdr, CRYPT_DEFAULT_SEGMENT) == 1 &&
|
||||
!LUKS2_keyslot_for_segment(hdr, keyslot, CRYPT_DEFAULT_SEGMENT))
|
||||
return CRYPT_SLOT_ACTIVE_LAST;
|
||||
|
||||
return CRYPT_SLOT_ACTIVE;
|
||||
|
||||
@@ -397,7 +397,8 @@ int LUKS2_token_open_and_activate(struct crypt_device *cd,
|
||||
return r;
|
||||
|
||||
r = LUKS2_keyslot_open_by_token(cd, hdr, token,
|
||||
name ? CRYPT_DEFAULT_SEGMENT : CRYPT_ANY_SEGMENT,
|
||||
(flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ?
|
||||
CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT,
|
||||
buffer, buffer_len, &vk);
|
||||
|
||||
LUKS2_token_buffer_free(cd, token, buffer, buffer_len);
|
||||
@@ -442,7 +443,8 @@ int LUKS2_token_open_and_activate_any(struct crypt_device *cd,
|
||||
continue;
|
||||
|
||||
r = LUKS2_keyslot_open_by_token(cd, hdr, token,
|
||||
name ? CRYPT_DEFAULT_SEGMENT : CRYPT_ANY_SEGMENT,
|
||||
(flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ?
|
||||
CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT,
|
||||
buffer, buffer_len, &vk);
|
||||
LUKS2_token_buffer_free(cd, token, buffer, buffer_len);
|
||||
if (r >= 0)
|
||||
|
||||
@@ -2916,6 +2916,9 @@ static int _activate_by_passphrase(struct crypt_device *cd,
|
||||
if ((flags & CRYPT_ACTIVATE_KEYRING_KEY) && !crypt_use_keyring_for_vk(cd))
|
||||
return -EINVAL;
|
||||
|
||||
if ((flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) && name)
|
||||
return -EINVAL;
|
||||
|
||||
/* plain, use hashed passphrase */
|
||||
if (isPLAIN(cd->type)) {
|
||||
if (!name)
|
||||
@@ -2939,7 +2942,8 @@ static int _activate_by_passphrase(struct crypt_device *cd,
|
||||
}
|
||||
} else if (isLUKS2(cd->type)) {
|
||||
r = LUKS2_keyslot_open(cd, keyslot,
|
||||
name ? CRYPT_DEFAULT_SEGMENT : CRYPT_ANY_SEGMENT,
|
||||
(flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ?
|
||||
CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT,
|
||||
passphrase, passphrase_size, &vk);
|
||||
if (r >= 0) {
|
||||
keyslot = r;
|
||||
@@ -4025,6 +4029,9 @@ int crypt_activate_by_token(struct crypt_device *cd,
|
||||
if ((flags & CRYPT_ACTIVATE_KEYRING_KEY) && !crypt_use_keyring_for_vk(cd))
|
||||
return -EINVAL;
|
||||
|
||||
if ((flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) && name)
|
||||
return -EINVAL;
|
||||
|
||||
if (token == CRYPT_ANY_TOKEN)
|
||||
return LUKS2_token_open_and_activate_any(cd, &cd->u.luks2.hdr, name, flags);
|
||||
|
||||
|
||||
@@ -512,6 +512,8 @@ static PyObject *CryptSetup_killSlot(CryptSetupObject* self, PyObject *args, PyO
|
||||
case CRYPT_SLOT_INVALID:
|
||||
PyErr_SetString(PyExc_ValueError, "Invalid slot");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -156,6 +156,10 @@ static void _set_activation_flags(uint32_t *flags)
|
||||
/* In persistent mode, we use what is set on command line */
|
||||
if (opt_persistent)
|
||||
*flags |= CRYPT_ACTIVATE_IGNORE_PERSISTENT;
|
||||
|
||||
/* Only for LUKS2 but ignored elsewhere */
|
||||
if (opt_test_passphrase)
|
||||
*flags |= CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY;
|
||||
}
|
||||
|
||||
static int action_open_plain(void)
|
||||
@@ -1132,17 +1136,15 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int verify_keyslot(struct crypt_device *cd, int key_slot,
|
||||
static int verify_keyslot(struct crypt_device *cd, int key_slot, crypt_keyslot_info ki,
|
||||
char *msg_last, char *msg_pass, char *msg_fail,
|
||||
const char *key_file, uint64_t keyfile_offset,
|
||||
int keyfile_size)
|
||||
{
|
||||
crypt_keyslot_info ki;
|
||||
char *password = NULL;
|
||||
size_t passwordLen;
|
||||
int i, max, r;
|
||||
|
||||
ki = crypt_keyslot_status(cd, key_slot);
|
||||
if (ki == CRYPT_SLOT_ACTIVE_LAST && !opt_batch_mode && !key_file &&
|
||||
msg_last && !yesDialog(msg_last, msg_fail))
|
||||
return -EPERM;
|
||||
@@ -1188,6 +1190,7 @@ out:
|
||||
static int action_luksKillSlot(void)
|
||||
{
|
||||
struct crypt_device *cd = NULL;
|
||||
crypt_keyslot_info ki;
|
||||
int r;
|
||||
|
||||
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
|
||||
@@ -1198,9 +1201,11 @@ static int action_luksKillSlot(void)
|
||||
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
|
||||
goto out;
|
||||
|
||||
switch (crypt_keyslot_status(cd, opt_key_slot)) {
|
||||
ki = crypt_keyslot_status(cd, opt_key_slot);
|
||||
switch (ki) {
|
||||
case CRYPT_SLOT_ACTIVE_LAST:
|
||||
case CRYPT_SLOT_ACTIVE:
|
||||
case CRYPT_SLOT_UNBOUND:
|
||||
log_verbose(_("Keyslot %d is selected for deletion.\n"), opt_key_slot);
|
||||
break;
|
||||
case CRYPT_SLOT_INACTIVE:
|
||||
@@ -1211,7 +1216,7 @@ static int action_luksKillSlot(void)
|
||||
}
|
||||
|
||||
if (!opt_batch_mode || opt_key_file || !isatty(STDIN_FILENO)) {
|
||||
r = verify_keyslot(cd, opt_key_slot,
|
||||
r = verify_keyslot(cd, opt_key_slot, ki,
|
||||
_("This is the last keyslot. Device will become unusable after purging this key."),
|
||||
_("Enter any remaining passphrase: "),
|
||||
_("Operation aborted, the keyslot was NOT wiped.\n"),
|
||||
|
||||
@@ -533,8 +533,38 @@ static int set_pbkdf_params(struct crypt_device *cd, const char *dev_type)
|
||||
return crypt_set_pbkdf_type(cd, &pbkdf);
|
||||
}
|
||||
|
||||
static int create_new_header(struct reenc_ctx *rc, const char *cipher,
|
||||
const char *cipher_mode, const char *uuid,
|
||||
static int create_new_keyslot(struct reenc_ctx *rc, int keyslot,
|
||||
struct crypt_device *cd_old,
|
||||
struct crypt_device *cd_new)
|
||||
{
|
||||
int r;
|
||||
char *key = NULL;
|
||||
size_t key_size;
|
||||
|
||||
if (cd_old && crypt_keyslot_status(cd_old, keyslot) == CRYPT_SLOT_UNBOUND) {
|
||||
key_size = 4096;
|
||||
key = crypt_safe_alloc(key_size);
|
||||
if (!key)
|
||||
return -ENOMEM;
|
||||
r = crypt_volume_key_get(cd_old, keyslot, key, &key_size,
|
||||
rc->p[keyslot].password, rc->p[keyslot].passwordLen);
|
||||
if (r == keyslot) {
|
||||
r = crypt_keyslot_add_by_key(cd_new, keyslot, key, key_size,
|
||||
rc->p[keyslot].password, rc->p[keyslot].passwordLen,
|
||||
CRYPT_VOLUME_KEY_NO_SEGMENT);
|
||||
} else
|
||||
r = -EINVAL;
|
||||
crypt_safe_free(key);
|
||||
} else
|
||||
r = crypt_keyslot_add_by_volume_key(cd_new, keyslot, NULL, 0,
|
||||
rc->p[keyslot].password, rc->p[keyslot].passwordLen);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int create_new_header(struct reenc_ctx *rc, struct crypt_device *cd_old,
|
||||
const char *cipher, const char *cipher_mode,
|
||||
const char *uuid,
|
||||
const char *key, int key_size,
|
||||
const char *type,
|
||||
void *params)
|
||||
@@ -564,8 +594,9 @@ static int create_new_header(struct reenc_ctx *rc, const char *cipher,
|
||||
for (i = 0; i < crypt_keyslot_max(type); i++) {
|
||||
if (!rc->p[i].password)
|
||||
continue;
|
||||
if ((r = crypt_keyslot_add_by_volume_key(cd_new, i,
|
||||
NULL, 0, rc->p[i].password, rc->p[i].passwordLen)) < 0)
|
||||
|
||||
r = create_new_keyslot(rc, i, cd_old, cd_new);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
log_verbose(_("Activated keyslot %i.\n"), r);
|
||||
r = 0;
|
||||
@@ -732,7 +763,7 @@ static int backup_luks_headers(struct reenc_ctx *rc)
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = create_new_header(rc,
|
||||
r = create_new_header(rc, cd,
|
||||
opt_cipher ? cipher : crypt_get_cipher(cd),
|
||||
opt_cipher ? cipher_mode : crypt_get_cipher_mode(cd),
|
||||
crypt_get_uuid(cd),
|
||||
@@ -818,7 +849,7 @@ static int backup_fake_header(struct reenc_ctx *rc)
|
||||
goto out;
|
||||
|
||||
params2.data_alignment = params.data_alignment = ROUND_SECTOR(opt_reduce_size);
|
||||
r = create_new_header(rc,
|
||||
r = create_new_header(rc, NULL,
|
||||
opt_cipher ? cipher : DEFAULT_LUKS1_CIPHER,
|
||||
opt_cipher ? cipher_mode : DEFAULT_LUKS1_MODE,
|
||||
NULL, NULL,
|
||||
@@ -1195,10 +1226,19 @@ static int initialize_uuid(struct reenc_ctx *rc)
|
||||
static int init_passphrase1(struct reenc_ctx *rc, struct crypt_device *cd,
|
||||
const char *msg, int slot_to_check, int check, int verify)
|
||||
{
|
||||
crypt_keyslot_info ki;
|
||||
char *password;
|
||||
int r = -EINVAL, retry_count;
|
||||
size_t passwordLen;
|
||||
|
||||
/* mode ENCRYPT call this without header */
|
||||
if (cd && slot_to_check != CRYPT_ANY_SLOT) {
|
||||
ki = crypt_keyslot_status(cd, slot_to_check);
|
||||
if (ki < CRYPT_SLOT_ACTIVE)
|
||||
return -ENOENT;
|
||||
} else
|
||||
ki = CRYPT_SLOT_ACTIVE;
|
||||
|
||||
retry_count = opt_tries ?: 1;
|
||||
while (retry_count--) {
|
||||
r = tools_get_key(msg, &password, &passwordLen, 0, 0,
|
||||
@@ -1214,7 +1254,7 @@ static int init_passphrase1(struct reenc_ctx *rc, struct crypt_device *cd,
|
||||
|
||||
if (check)
|
||||
r = crypt_activate_by_passphrase(cd, NULL, slot_to_check,
|
||||
password, passwordLen, 0);
|
||||
password, passwordLen, CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY);
|
||||
else
|
||||
r = (slot_to_check == CRYPT_ANY_SLOT) ? 0 : slot_to_check;
|
||||
|
||||
@@ -1225,10 +1265,12 @@ static int init_passphrase1(struct reenc_ctx *rc, struct crypt_device *cd,
|
||||
}
|
||||
if (r < 0 && r != -EPERM)
|
||||
return r;
|
||||
|
||||
if (r >= 0) {
|
||||
rc->keyslot = r;
|
||||
rc->p[r].password = password;
|
||||
rc->p[r].passwordLen = passwordLen;
|
||||
if (ki != CRYPT_SLOT_UNBOUND)
|
||||
rc->keyslot = r;
|
||||
break;
|
||||
}
|
||||
tools_passphrase_msg(r);
|
||||
@@ -1283,11 +1325,10 @@ static int init_keyfile(struct reenc_ctx *rc, struct crypt_device *cd, int slot_
|
||||
static int initialize_passphrase(struct reenc_ctx *rc, const char *device)
|
||||
{
|
||||
struct crypt_device *cd = NULL;
|
||||
crypt_keyslot_info ki;
|
||||
char msg[256];
|
||||
int i, r;
|
||||
|
||||
log_dbg("Passhrases initialization.");
|
||||
log_dbg("Passphrases initialization.");
|
||||
|
||||
if (rc->reencrypt_mode == ENCRYPT && !rc->in_progress) {
|
||||
r = init_passphrase1(rc, cd, _("Enter new passphrase: "), opt_key_slot, 0, 1);
|
||||
@@ -1314,12 +1355,12 @@ static int initialize_passphrase(struct reenc_ctx *rc, const char *device)
|
||||
rc->reencrypt_mode == DECRYPT) {
|
||||
r = init_passphrase1(rc, cd, msg, opt_key_slot, 1, 0);
|
||||
} else for (i = 0; i < crypt_keyslot_max(crypt_get_type(cd)); i++) {
|
||||
ki = crypt_keyslot_status(cd, i);
|
||||
if (ki != CRYPT_SLOT_ACTIVE && ki != CRYPT_SLOT_ACTIVE_LAST)
|
||||
continue;
|
||||
|
||||
snprintf(msg, sizeof(msg), _("Enter passphrase for key slot %u: "), i);
|
||||
r = init_passphrase1(rc, cd, msg, i, 1, 0);
|
||||
if (r == -ENOENT) {
|
||||
r = 0;
|
||||
continue;
|
||||
}
|
||||
if (r < 0)
|
||||
break;
|
||||
}
|
||||
@@ -1504,6 +1545,7 @@ static int run_reencrypt(const char *device)
|
||||
if ((r = initialize_passphrase(&rc, hdr_device(&rc))))
|
||||
goto out;
|
||||
|
||||
log_dbg("Storing backup of LUKS headers.");
|
||||
if (rc.reencrypt_mode == ENCRYPT) {
|
||||
/* Create fake header for exising device */
|
||||
if ((r = backup_fake_header(&rc)))
|
||||
|
||||
@@ -1544,7 +1544,7 @@ static void Tokens(void)
|
||||
EQ_(crypt_token_assign_keyslot(cd, 0, 3), 0);
|
||||
|
||||
EQ_(crypt_activate_by_token(cd, NULL, 2, PASSPHRASE, 0), 0);
|
||||
EQ_(crypt_activate_by_token(cd, NULL, 0, PASSPHRASE1, 0), 3);
|
||||
EQ_(crypt_activate_by_token(cd, NULL, 0, PASSPHRASE1, CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY), 3);
|
||||
// FIXME: useless error message here (or missing one to be specific)
|
||||
FAIL_(crypt_activate_by_token(cd, CDEVICE_1, 0, PASSPHRASE1, 0), "No volume key available in token keyslots");
|
||||
EQ_(crypt_activate_by_token(cd, CDEVICE_1, 2, PASSPHRASE, 0), 0);
|
||||
@@ -2317,7 +2317,7 @@ static void Luks2KeyslotAdd(void)
|
||||
EQ_(crypt_keyslot_add_by_key(cd, 1, key2, key_size, PASSPHRASE1, strlen(PASSPHRASE1), CRYPT_VOLUME_KEY_NO_SEGMENT), 1);
|
||||
EQ_(crypt_keyslot_add_by_volume_key(cd, 0, key, key_size, PASSPHRASE, strlen(PASSPHRASE)), 0);
|
||||
EQ_(crypt_keyslot_status(cd, 0), CRYPT_SLOT_ACTIVE_LAST);
|
||||
EQ_(crypt_keyslot_status(cd, 1), CRYPT_SLOT_ACTIVE);
|
||||
EQ_(crypt_keyslot_status(cd, 1), CRYPT_SLOT_UNBOUND);
|
||||
/* must not activate volume with keyslot unassigned to a segment */
|
||||
FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key2, key_size, 0), "Key doesn't match volume key digest");
|
||||
FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, 1, PASSPHRASE1, strlen(PASSPHRASE1), 0), "Keyslot not assigned to volume");
|
||||
@@ -2325,8 +2325,8 @@ static void Luks2KeyslotAdd(void)
|
||||
/* unusable for volume activation even in test mode */
|
||||
FAIL_(crypt_activate_by_volume_key(cd, NULL, key2, key_size, 0), "Key doesn't match volume key digest");
|
||||
/* otoh passphrase check should pass */
|
||||
EQ_(crypt_activate_by_passphrase(cd, NULL, 1, PASSPHRASE1, strlen(PASSPHRASE1), 0), 1);
|
||||
EQ_(crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, PASSPHRASE1, strlen(PASSPHRASE1), 0), 1);
|
||||
EQ_(crypt_activate_by_passphrase(cd, NULL, 1, PASSPHRASE1, strlen(PASSPHRASE1), CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY), 1);
|
||||
EQ_(crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, PASSPHRASE1, strlen(PASSPHRASE1), CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY), 1);
|
||||
/* in general crypt_keyslot_add_by_key must allow any reasonable key size
|
||||
* even though such keyslot will not be usable for segment encryption */
|
||||
EQ_(crypt_keyslot_add_by_key(cd, 2, key2, key_size-1, PASSPHRASE1, strlen(PASSPHRASE1), CRYPT_VOLUME_KEY_NO_SEGMENT), 2);
|
||||
@@ -2391,7 +2391,7 @@ static void Luks2ActivateByKeyring(void)
|
||||
FAIL_(crypt_activate_by_keyring(cd, CDEVICE_1, KEY_DESC_TEST0, 0, 0), "already open");
|
||||
OK_(crypt_deactivate(cd, CDEVICE_1));
|
||||
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_INACTIVE);
|
||||
EQ_(crypt_activate_by_keyring(cd, NULL, KEY_DESC_TEST1, 1, 0), 1);
|
||||
EQ_(crypt_activate_by_keyring(cd, NULL, KEY_DESC_TEST1, 1, CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY), 1);
|
||||
EQ_(crypt_activate_by_keyring(cd, NULL, KEY_DESC_TEST1, 2, 0), 2);
|
||||
FAIL_(crypt_activate_by_keyring(cd, CDEVICE_1, KEY_DESC_TEST1, 1, 0), "Keyslot not assigned to volume");
|
||||
EQ_(crypt_activate_by_keyring(cd, CDEVICE_1, KEY_DESC_TEST1, 2, 0), 2);
|
||||
|
||||
@@ -792,21 +792,30 @@ $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV $KEY5 --key-slot
|
||||
# unbound key may have arbitrary size
|
||||
echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --unbound -s 16 $LOOPDEV || fail
|
||||
echo $PWD2 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --unbound -s 32 -S 2 $LOOPDEV || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "2: luks2 (unbound)" || fail
|
||||
echo $PWD3 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --unbound -s 8 -S 3 --master-key-file /dev/urandom $LOOPDEV || fail
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "3: luks2 (unbound)" || fail
|
||||
# unbound key size is required
|
||||
echo $PWD1 | $CRYPTSETUP -q luksAddKey --unbound $LOOPDEV 2>/dev/null && fail
|
||||
echo $PWD3 | $CRYPTSETUP -q luksAddKey --unbound --master-key-file /dev/urandom $LOOPDEV 2> /dev/null && fail
|
||||
# do not allow to replace keyslot by unbound slot
|
||||
echo $PWD1 | $CRYPTSETUP -q luksAddKey -S5 --unbound -s 32 $LOOPDEV 2>/dev/null && fail
|
||||
echo $PWD2 | $CRYPTSETUP -q open $LOOPDDEV $DEV_NAME 2> /dev/null && fail
|
||||
echo $PWD2 | $CRYPTSETUP -q open -S2 $LOOPDDEV $DEV_NAME 2> /dev/null && fail
|
||||
echo $PWD1 | $CRYPTSETUP -q open $LOOPDDEV $DEV_NAME 2> /dev/null && fail
|
||||
echo $PWD2 | $CRYPTSETUP -q open $LOOPDEV $DEV_NAME 2> /dev/null && fail
|
||||
echo $PWD2 | $CRYPTSETUP -q open $LOOPDEV --test-passphrase || fail
|
||||
echo $PWD2 | $CRYPTSETUP -q open -S2 $LOOPDEV $DEV_NAME 2> /dev/null && fail
|
||||
echo $PWD2 | $CRYPTSETUP -q open -S2 $LOOPDEV --test-passphrase || fail
|
||||
echo $PWD1 | $CRYPTSETUP -q open $LOOPDEV $DEV_NAME 2> /dev/null && fail
|
||||
echo $PWD1 | $CRYPTSETUP -q open $LOOPDEV --test-passphrase || fail
|
||||
# do not allow adding keyslot by unbound keyslot
|
||||
echo -e "$PWD2\n$PWD1" | $CRYPTSETUP -q luksAddKey $LOOPDEV 2> /dev/null && fail
|
||||
# check adding keyslot works when there's unbound keyslot
|
||||
echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV --key-file $KEY5 -S8 || fail
|
||||
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME || fail
|
||||
$CRYPTSETUP close $DEV_NAME || fail
|
||||
$CRYPTSETUP luksKillSlot -q $LOOPDEV 2
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "2: luks2 (unbound)" && fail
|
||||
$CRYPTSETUP luksKillSlot -q $LOOPDEV 3
|
||||
$CRYPTSETUP luksDump $LOOPDEV | grep -q "3: luks2 (unbound)" && fail
|
||||
|
||||
remove_mapping
|
||||
exit 0
|
||||
|
||||
@@ -398,5 +398,16 @@ $CRYPTSETUP isLuks $IMG && fail
|
||||
$CRYPTSETUP isLuks $IMG_HDR || fail
|
||||
$CRYPTSETUP luksDump $IMG_HDR | grep -q "0: luks2" || fail
|
||||
|
||||
echo "[14] Reencryption with unbound keyslot"
|
||||
prepare 8192
|
||||
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG || fail
|
||||
echo $PWD2 | $CRYPTSETUP -q luksAddKey -S 3 --unbound --key-size 64 $FAST_PBKDF_ARGON $IMG || fail
|
||||
wipe $PWD1
|
||||
check_hash $PWD1 $HASH5
|
||||
$CRYPTSETUP luksDump $IMG | grep -q "3: luks2 (unbound)" || fail
|
||||
echo $PWD2 | $REENC $IMG -q $FAST_PBKDF 2>/dev/null && fail
|
||||
echo -e "$PWD1\n$PWD2" | $REENC $IMG -q $FAST_PBKDF || fail
|
||||
$CRYPTSETUP luksDump $IMG | grep -q "3: luks2 (unbound)" || fail
|
||||
|
||||
remove_mapping
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user