mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Add internal code for LUKS2 keyslot params.
This fixes crypt_keyslot_add_by_key where we were unable to store keyslot (unbound to segment) with different key_size. The code used (new) volume key size implicitly which could be wrong if new size was not compatible with cipher parameter for keyslot area.
This commit is contained in:
committed by
Milan Broz
parent
d399dfa792
commit
08e7c143b3
@@ -95,6 +95,25 @@ struct luks2_hdr {
|
|||||||
json_object *jobj;
|
json_object *jobj;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct luks2_keyslot_params {
|
||||||
|
enum { LUKS2_KEYSLOT_AF_LUKS1 = 0 } af_type;
|
||||||
|
enum { LUKS2_KEYSLOT_AREA_RAW = 0 } area_type;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
char hash[LUKS2_CHECKSUM_ALG_L]; // or include luks.h
|
||||||
|
unsigned int stripes;
|
||||||
|
} luks1;
|
||||||
|
} af;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
char encryption[65]; // or include utils_crypt.h
|
||||||
|
size_t key_size;
|
||||||
|
} raw;
|
||||||
|
} area;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Supportable header sizes (hdr_disk + JSON area)
|
* Supportable header sizes (hdr_disk + JSON area)
|
||||||
* Also used as offset for the 2nd header.
|
* Also used as offset for the 2nd header.
|
||||||
@@ -151,7 +170,8 @@ int LUKS2_keyslot_store(struct crypt_device *cd,
|
|||||||
int keyslot,
|
int keyslot,
|
||||||
const char *password,
|
const char *password,
|
||||||
size_t password_len,
|
size_t password_len,
|
||||||
const struct volume_key *vk);
|
const struct volume_key *vk,
|
||||||
|
const struct luks2_keyslot_params *params);
|
||||||
|
|
||||||
int LUKS2_keyslot_wipe(struct crypt_device *cd,
|
int LUKS2_keyslot_wipe(struct crypt_device *cd,
|
||||||
struct luks2_hdr *hdr,
|
struct luks2_hdr *hdr,
|
||||||
@@ -299,6 +319,10 @@ uint64_t LUKS2_get_data_offset(struct luks2_hdr *hdr);
|
|||||||
int LUKS2_get_sector_size(struct luks2_hdr *hdr);
|
int LUKS2_get_sector_size(struct luks2_hdr *hdr);
|
||||||
const char *LUKS2_get_cipher(struct luks2_hdr *hdr, int segment);
|
const char *LUKS2_get_cipher(struct luks2_hdr *hdr, int segment);
|
||||||
const char *LUKS2_get_integrity(struct luks2_hdr *hdr, int segment);
|
const char *LUKS2_get_integrity(struct luks2_hdr *hdr, int segment);
|
||||||
|
int LUKS2_keyslot_params_default(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||||
|
size_t key_size, struct luks2_keyslot_params *params);
|
||||||
|
int LUKS2_get_keyslot_params(struct luks2_hdr *hdr, int keyslot,
|
||||||
|
struct luks2_keyslot_params *params);
|
||||||
int LUKS2_get_volume_key_size(struct luks2_hdr *hdr, int segment);
|
int LUKS2_get_volume_key_size(struct luks2_hdr *hdr, int segment);
|
||||||
int LUKS2_get_keyslot_key_size(struct luks2_hdr *hdr, int keyslot);
|
int LUKS2_get_keyslot_key_size(struct luks2_hdr *hdr, int keyslot);
|
||||||
int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr, const char *type);
|
int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr, const char *type);
|
||||||
|
|||||||
@@ -83,7 +83,8 @@ struct json_object *LUKS2_array_remove(struct json_object *array, const char *nu
|
|||||||
* LUKS2 keyslots handlers (EXPERIMENTAL)
|
* LUKS2 keyslots handlers (EXPERIMENTAL)
|
||||||
*/
|
*/
|
||||||
typedef int (*keyslot_alloc_func)(struct crypt_device *cd, int keyslot,
|
typedef int (*keyslot_alloc_func)(struct crypt_device *cd, int keyslot,
|
||||||
size_t volume_key_len);
|
size_t volume_key_len,
|
||||||
|
const struct luks2_keyslot_params *params);
|
||||||
typedef int (*keyslot_open_func) (struct crypt_device *cd, int keyslot,
|
typedef int (*keyslot_open_func) (struct crypt_device *cd, int keyslot,
|
||||||
const char *password, size_t password_len,
|
const char *password, size_t password_len,
|
||||||
char *volume_key, size_t volume_key_len);
|
char *volume_key, size_t volume_key_len);
|
||||||
@@ -96,7 +97,8 @@ typedef int (*keyslot_validate_func) (struct crypt_device *cd, int keyslot);
|
|||||||
|
|
||||||
int luks2_keyslot_alloc(struct crypt_device *cd,
|
int luks2_keyslot_alloc(struct crypt_device *cd,
|
||||||
int keyslot,
|
int keyslot,
|
||||||
size_t volume_key_len);
|
size_t volume_key_len,
|
||||||
|
const struct luks2_keyslot_params *params);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <uuid/uuid.h>
|
#include <uuid/uuid.h>
|
||||||
|
|
||||||
|
#define LUKS_STRIPES 4000
|
||||||
|
|
||||||
struct interval {
|
struct interval {
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
uint64_t length;
|
uint64_t length;
|
||||||
@@ -1611,6 +1613,78 @@ const char *LUKS2_get_cipher(struct luks2_hdr *hdr, int segment)
|
|||||||
return json_object_get_string(jobj3);
|
return json_object_get_string(jobj3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int luks2_keyslot_af_params(json_object *jobj_af, struct luks2_keyslot_params *params)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
json_object *jobj_type, *jobj1;
|
||||||
|
|
||||||
|
/* currently we only support luks1 AF */
|
||||||
|
json_object_object_get_ex(jobj_af, "type", &jobj_type);
|
||||||
|
if (strcmp(json_object_get_string(jobj_type), "luks1"))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* process luks1 af params */
|
||||||
|
json_object_object_get_ex(jobj_af, "stripes", &jobj1);
|
||||||
|
params->af.luks1.stripes = json_object_get_int(jobj1);
|
||||||
|
if (params->af.luks1.stripes != LUKS_STRIPES)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
json_object_object_get_ex(jobj_af, "hash", &jobj1);
|
||||||
|
r = snprintf(params->af.luks1.hash, sizeof(params->af.luks1.hash), "%s",
|
||||||
|
json_object_get_string(jobj1));
|
||||||
|
if (r < 0 || (size_t)r >= sizeof(params->af.luks1.hash))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
params->af_type = LUKS2_KEYSLOT_AF_LUKS1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int luks2_keyslot_area_params(json_object *jobj_area, struct luks2_keyslot_params *params)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
json_object *jobj_type, *jobj1;
|
||||||
|
|
||||||
|
/* currently we only support raw length preserving area encryption */
|
||||||
|
json_object_object_get_ex(jobj_area, "type", &jobj_type);
|
||||||
|
if (strcmp(json_object_get_string(jobj_type), "raw"))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* process raw area encryption params */
|
||||||
|
json_object_object_get_ex(jobj_area, "encryption", &jobj1);
|
||||||
|
r = snprintf(params->area.raw.encryption, sizeof(params->area.raw.encryption), "%s",
|
||||||
|
json_object_get_string(jobj1));
|
||||||
|
if (r < 0 || (size_t)r >= sizeof(params->area.raw.encryption))
|
||||||
|
return 1;
|
||||||
|
json_object_object_get_ex(jobj_area, "key_size", &jobj1);
|
||||||
|
params->area.raw.key_size = json_object_get_int(jobj1);
|
||||||
|
|
||||||
|
params->area_type = LUKS2_KEYSLOT_AREA_RAW;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* keyslot must be validated */
|
||||||
|
int LUKS2_get_keyslot_params(struct luks2_hdr *hdr, int keyslot, struct luks2_keyslot_params *params)
|
||||||
|
{
|
||||||
|
json_object *jobj_keyslot, *jobj_af, *jobj_area;
|
||||||
|
|
||||||
|
jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
|
||||||
|
if (!jobj_keyslot)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
if (!json_object_object_get_ex(jobj_keyslot, "area", &jobj_area) ||
|
||||||
|
!json_object_object_get_ex(jobj_keyslot, "af", &jobj_af))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (luks2_keyslot_af_params(jobj_af, params))
|
||||||
|
return -EINVAL;
|
||||||
|
if (luks2_keyslot_area_params(jobj_area, params))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const char *LUKS2_get_integrity(struct luks2_hdr *hdr, int segment)
|
const char *LUKS2_get_integrity(struct luks2_hdr *hdr, int segment)
|
||||||
{
|
{
|
||||||
json_object *jobj1, *jobj2, *jobj3, *jobj4;
|
json_object *jobj1, *jobj2, *jobj3, *jobj4;
|
||||||
|
|||||||
@@ -117,6 +117,50 @@ int LUKS2_keyslot_active_count(struct luks2_hdr *hdr, int segment)
|
|||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LUKS2_keyslot_params_default(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||||
|
size_t key_size, struct luks2_keyslot_params *params)
|
||||||
|
{
|
||||||
|
int r, integrity_key_size = crypt_get_integrity_key_size(cd);
|
||||||
|
const struct crypt_pbkdf_type *pbkdf = crypt_get_pbkdf_type(cd);
|
||||||
|
|
||||||
|
if (!hdr || !pbkdf || !params)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
params->af_type = LUKS2_KEYSLOT_AF_LUKS1;
|
||||||
|
params->area_type = LUKS2_KEYSLOT_AREA_RAW;
|
||||||
|
|
||||||
|
/* set keyslot AF parameters */
|
||||||
|
/* currently we use hash for AF from pbkdf settings */
|
||||||
|
r = snprintf(params->af.luks1.hash, sizeof(params->af.luks1.hash),
|
||||||
|
"%s", pbkdf->hash);
|
||||||
|
if (r < 0 || (size_t)r >= sizeof(params->af.luks1.hash))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
params->af.luks1.stripes = 4000;
|
||||||
|
|
||||||
|
/* set keyslot area encryption parameters */
|
||||||
|
/* short circuit authenticated encryption hardcoded defaults */
|
||||||
|
if (crypt_get_integrity_tag_size(cd) || key_size == 0) {
|
||||||
|
// FIXME: fixed cipher and key size can be wrong
|
||||||
|
snprintf(params->area.raw.encryption, sizeof(params->area.raw.encryption),
|
||||||
|
"aes-xts-plain64");
|
||||||
|
params->area.raw.key_size = 32;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = snprintf(params->area.raw.encryption, sizeof(params->area.raw.encryption),
|
||||||
|
"%s", LUKS2_get_cipher(hdr, CRYPT_DEFAULT_SEGMENT));
|
||||||
|
if (r < 0 || (size_t)r >= sizeof(params->area.raw.encryption))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Slot encryption tries to use the same key size as for the main algorithm */
|
||||||
|
if (integrity_key_size > key_size)
|
||||||
|
return -EINVAL;
|
||||||
|
params->area.raw.key_size = key_size - integrity_key_size;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
crypt_keyslot_info LUKS2_keyslot_info(struct luks2_hdr *hdr, int keyslot)
|
crypt_keyslot_info LUKS2_keyslot_info(struct luks2_hdr *hdr, int keyslot)
|
||||||
{
|
{
|
||||||
crypt_keyslot_info ki;
|
crypt_keyslot_info ki;
|
||||||
@@ -281,7 +325,8 @@ int LUKS2_keyslot_store(struct crypt_device *cd,
|
|||||||
int keyslot,
|
int keyslot,
|
||||||
const char *password,
|
const char *password,
|
||||||
size_t password_len,
|
size_t password_len,
|
||||||
const struct volume_key *vk)
|
const struct volume_key *vk,
|
||||||
|
const struct luks2_keyslot_params *params)
|
||||||
{
|
{
|
||||||
const keyslot_handler *h;
|
const keyslot_handler *h;
|
||||||
int r;
|
int r;
|
||||||
@@ -295,7 +340,7 @@ int LUKS2_keyslot_store(struct crypt_device *cd,
|
|||||||
if (!h)
|
if (!h)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
r = h->alloc(cd, keyslot, vk->keylength);
|
r = h->alloc(cd, keyslot, vk->keylength, params);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
} else if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
|
} else if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
|
||||||
|
|||||||
@@ -376,18 +376,24 @@ static int luks2_keyslot_get_key(struct crypt_device *cd,
|
|||||||
|
|
||||||
int luks2_keyslot_alloc(struct crypt_device *cd,
|
int luks2_keyslot_alloc(struct crypt_device *cd,
|
||||||
int keyslot,
|
int keyslot,
|
||||||
size_t volume_key_len)
|
size_t volume_key_len,
|
||||||
|
const struct luks2_keyslot_params *params)
|
||||||
{
|
{
|
||||||
struct luks2_hdr *hdr;
|
struct luks2_hdr *hdr;
|
||||||
const struct crypt_pbkdf_type *pbkdf;
|
const struct crypt_pbkdf_type *pbkdf;
|
||||||
char cipher[2 * MAX_CIPHER_LEN + 1], num[16];
|
char num[16];
|
||||||
uint64_t area_offset, area_length;
|
uint64_t area_offset, area_length;
|
||||||
json_object *jobj_keyslots, *jobj_keyslot, *jobj_kdf, *jobj_af, *jobj_area;
|
json_object *jobj_keyslots, *jobj_keyslot, *jobj_kdf, *jobj_af, *jobj_area;
|
||||||
size_t keyslot_key_len;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
log_dbg("Trying to allocate LUKS2 keyslot %d.", keyslot);
|
log_dbg("Trying to allocate LUKS2 keyslot %d.", keyslot);
|
||||||
|
|
||||||
|
if (!params || params->area_type != LUKS2_KEYSLOT_AREA_RAW ||
|
||||||
|
params->af_type != LUKS2_KEYSLOT_AF_LUKS1) {
|
||||||
|
log_dbg("Invalid LUKS2 keyslot parameters.");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2)))
|
if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@@ -439,28 +445,15 @@ int luks2_keyslot_alloc(struct crypt_device *cd,
|
|||||||
/* AF object */
|
/* AF object */
|
||||||
jobj_af = json_object_new_object();
|
jobj_af = json_object_new_object();
|
||||||
json_object_object_add(jobj_af, "type", json_object_new_string("luks1"));
|
json_object_object_add(jobj_af, "type", json_object_new_string("luks1"));
|
||||||
json_object_object_add(jobj_af, "hash", json_object_new_string(pbkdf->hash));
|
json_object_object_add(jobj_af, "hash", json_object_new_string(params->af.luks1.hash));
|
||||||
json_object_object_add(jobj_af, "stripes", json_object_new_int(4000));
|
json_object_object_add(jobj_af, "stripes", json_object_new_int(params->af.luks1.stripes));
|
||||||
json_object_object_add(jobj_keyslot, "af", jobj_af);
|
json_object_object_add(jobj_keyslot, "af", jobj_af);
|
||||||
|
|
||||||
/* Area object */
|
/* Area object */
|
||||||
jobj_area = json_object_new_object();
|
jobj_area = json_object_new_object();
|
||||||
json_object_object_add(jobj_area, "type", json_object_new_string("raw"));
|
json_object_object_add(jobj_area, "type", json_object_new_string("raw"));
|
||||||
|
json_object_object_add(jobj_area, "encryption", json_object_new_string(params->area.raw.encryption));
|
||||||
/* Slot encryption tries to use the same key size as fot the main algorithm */
|
json_object_object_add(jobj_area, "key_size", json_object_new_int(params->area.raw.key_size));
|
||||||
keyslot_key_len = volume_key_len - crypt_get_integrity_key_size(cd);
|
|
||||||
|
|
||||||
/* Cannot use metadata tags in keyslot */
|
|
||||||
if (crypt_get_integrity_tag_size(cd)) {
|
|
||||||
snprintf(cipher, sizeof(cipher), "aes-xts-plain64"); // FIXME: fixed cipher and key size can be wrong
|
|
||||||
keyslot_key_len = 32;
|
|
||||||
} else if (crypt_get_cipher_mode(cd))
|
|
||||||
snprintf(cipher, sizeof(cipher), "%s-%s", crypt_get_cipher(cd), crypt_get_cipher_mode(cd));
|
|
||||||
else
|
|
||||||
snprintf(cipher, sizeof(cipher), "%s", crypt_get_cipher(cd));
|
|
||||||
|
|
||||||
json_object_object_add(jobj_area, "encryption", json_object_new_string(cipher));
|
|
||||||
json_object_object_add(jobj_area, "key_size", json_object_new_int(keyslot_key_len));
|
|
||||||
json_object_object_add(jobj_area, "offset", json_object_new_uint64(area_offset));
|
json_object_object_add(jobj_area, "offset", json_object_new_uint64(area_offset));
|
||||||
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_length));
|
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_length));
|
||||||
json_object_object_add(jobj_keyslot, "area", jobj_area);
|
json_object_object_add(jobj_keyslot, "area", jobj_area);
|
||||||
|
|||||||
@@ -611,6 +611,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
|
|||||||
int i, r, last_active = 0;
|
int i, r, last_active = 0;
|
||||||
uint64_t offset, area_length;
|
uint64_t offset, area_length;
|
||||||
char buf[256], luksMagic[] = LUKS_MAGIC;
|
char buf[256], luksMagic[] = LUKS_MAGIC;
|
||||||
|
struct luks2_keyslot_params params;
|
||||||
|
|
||||||
jobj_digest = LUKS2_get_digest_jobj(hdr2, 0);
|
jobj_digest = LUKS2_get_digest_jobj(hdr2, 0);
|
||||||
if (!jobj_digest)
|
if (!jobj_digest)
|
||||||
@@ -628,10 +629,17 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
key_size = r = LUKS2_get_volume_key_size(hdr2, 0);
|
/* We really do not care about params later except keys_size */
|
||||||
|
r = LUKS2_keyslot_params_default(cd, hdr2, 0, ¶ms);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
r = LUKS2_get_volume_key_size(hdr2, 0);
|
||||||
|
if (r < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
key_size = r;
|
||||||
|
params.area.raw.key_size = key_size;
|
||||||
|
|
||||||
for (i = 0; i < LUKS2_KEYSLOTS_MAX; i++) {
|
for (i = 0; i < LUKS2_KEYSLOTS_MAX; i++) {
|
||||||
if (LUKS2_keyslot_info(hdr2, i) == CRYPT_SLOT_INACTIVE)
|
if (LUKS2_keyslot_info(hdr2, i) == CRYPT_SLOT_INACTIVE)
|
||||||
continue;
|
continue;
|
||||||
@@ -670,7 +678,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
|
|||||||
if (LUKS2_find_area_gap(cd, hdr2, key_size, &offset, &area_length))
|
if (LUKS2_find_area_gap(cd, hdr2, key_size, &offset, &area_length))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
/* FIXME: luks2 reload is required! */
|
/* FIXME: luks2 reload is required! */
|
||||||
if (luks2_keyslot_alloc(cd, i, key_size))
|
if (luks2_keyslot_alloc(cd, i, key_size, ¶ms))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
36
lib/setup.c
36
lib/setup.c
@@ -2563,6 +2563,7 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
|
|||||||
size_t new_passphrase_size)
|
size_t new_passphrase_size)
|
||||||
{
|
{
|
||||||
int digest, r, active_slots;
|
int digest, r, active_slots;
|
||||||
|
struct luks2_keyslot_params params;
|
||||||
struct volume_key *vk = NULL;
|
struct volume_key *vk = NULL;
|
||||||
|
|
||||||
log_dbg("Adding new keyslot, existing passphrase %sprovided,"
|
log_dbg("Adding new keyslot, existing passphrase %sprovided,"
|
||||||
@@ -2614,13 +2615,16 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
|
|||||||
r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
|
r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
|
||||||
digest = r;
|
digest = r;
|
||||||
|
|
||||||
|
if (r >= 0)
|
||||||
|
r = LUKS2_keyslot_params_default(cd, &cd->u.luks2.hdr, vk->keylength, ¶ms);
|
||||||
|
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
r = LUKS2_digest_assign(cd, &cd->u.luks2.hdr, keyslot, digest, 1, 0);
|
r = LUKS2_digest_assign(cd, &cd->u.luks2.hdr, keyslot, digest, 1, 0);
|
||||||
|
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
r = LUKS2_keyslot_store(cd, &cd->u.luks2.hdr, keyslot,
|
r = LUKS2_keyslot_store(cd, &cd->u.luks2.hdr, keyslot,
|
||||||
CONST_CAST(char*)new_passphrase,
|
CONST_CAST(char*)new_passphrase,
|
||||||
new_passphrase_size, vk);
|
new_passphrase_size, vk, ¶ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@@ -2645,6 +2649,7 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
|
|||||||
size_t new_passphrase_size)
|
size_t new_passphrase_size)
|
||||||
{
|
{
|
||||||
int digest, r;
|
int digest, r;
|
||||||
|
struct luks2_keyslot_params params;
|
||||||
struct volume_key *vk = NULL;
|
struct volume_key *vk = NULL;
|
||||||
|
|
||||||
if (!passphrase || !new_passphrase)
|
if (!passphrase || !new_passphrase)
|
||||||
@@ -2696,6 +2701,9 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
|
|||||||
r = LUKS_set_key(keyslot_new, new_passphrase, new_passphrase_size,
|
r = LUKS_set_key(keyslot_new, new_passphrase, new_passphrase_size,
|
||||||
&cd->u.luks1.hdr, vk, cd);
|
&cd->u.luks1.hdr, vk, cd);
|
||||||
} else if (isLUKS2(cd->type)) {
|
} else if (isLUKS2(cd->type)) {
|
||||||
|
r = LUKS2_get_keyslot_params(&cd->u.luks2.hdr, keyslot_old, ¶ms);
|
||||||
|
if (r)
|
||||||
|
goto out;
|
||||||
if (keyslot_old != keyslot_new) {
|
if (keyslot_old != keyslot_new) {
|
||||||
r = LUKS2_digest_assign(cd, &cd->u.luks2.hdr, keyslot_new, digest, 1, 0);
|
r = LUKS2_digest_assign(cd, &cd->u.luks2.hdr, keyslot_new, digest, 1, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@@ -2713,7 +2721,7 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
|
|||||||
|
|
||||||
r = LUKS2_keyslot_store(cd, &cd->u.luks2.hdr,
|
r = LUKS2_keyslot_store(cd, &cd->u.luks2.hdr,
|
||||||
keyslot_new, new_passphrase,
|
keyslot_new, new_passphrase,
|
||||||
new_passphrase_size, vk);
|
new_passphrase_size, vk, ¶ms);
|
||||||
} else
|
} else
|
||||||
r = -EINVAL;
|
r = -EINVAL;
|
||||||
|
|
||||||
@@ -2748,6 +2756,7 @@ int crypt_keyslot_add_by_keyfile_device_offset(struct crypt_device *cd,
|
|||||||
{
|
{
|
||||||
int digest, r, active_slots;
|
int digest, r, active_slots;
|
||||||
size_t passwordLen, new_passwordLen;
|
size_t passwordLen, new_passwordLen;
|
||||||
|
struct luks2_keyslot_params params;
|
||||||
char *password = NULL, *new_password = NULL;
|
char *password = NULL, *new_password = NULL;
|
||||||
struct volume_key *vk = NULL;
|
struct volume_key *vk = NULL;
|
||||||
|
|
||||||
@@ -2807,12 +2816,15 @@ int crypt_keyslot_add_by_keyfile_device_offset(struct crypt_device *cd,
|
|||||||
r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
|
r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
|
||||||
digest = r;
|
digest = r;
|
||||||
|
|
||||||
|
if (r >= 0)
|
||||||
|
r = LUKS2_keyslot_params_default(cd, &cd->u.luks2.hdr, vk->keylength, ¶ms);
|
||||||
|
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
r = LUKS2_digest_assign(cd, &cd->u.luks2.hdr, keyslot, digest, 1, 0);
|
r = LUKS2_digest_assign(cd, &cd->u.luks2.hdr, keyslot, digest, 1, 0);
|
||||||
|
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
r = LUKS2_keyslot_store(cd, &cd->u.luks2.hdr, keyslot,
|
r = LUKS2_keyslot_store(cd, &cd->u.luks2.hdr, keyslot,
|
||||||
new_password, new_passwordLen, vk);
|
new_password, new_passwordLen, vk, ¶ms);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
crypt_safe_free(password);
|
crypt_safe_free(password);
|
||||||
@@ -4385,6 +4397,7 @@ int crypt_keyslot_add_by_key(struct crypt_device *cd,
|
|||||||
uint32_t flags)
|
uint32_t flags)
|
||||||
{
|
{
|
||||||
int digest, r;
|
int digest, r;
|
||||||
|
struct luks2_keyslot_params params;
|
||||||
struct volume_key *vk = NULL;
|
struct volume_key *vk = NULL;
|
||||||
|
|
||||||
if (!passphrase)
|
if (!passphrase)
|
||||||
@@ -4411,13 +4424,20 @@ int crypt_keyslot_add_by_key(struct crypt_device *cd,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* no segment means we're going to store key without assigned segment (unused in dm-crypt) */
|
/* no segment means we're going to store key without assigned segment (unused in dm-crypt) */
|
||||||
if (flags & CRYPT_VOLUME_KEY_NO_SEGMENT)
|
if (flags & CRYPT_VOLUME_KEY_NO_SEGMENT) {
|
||||||
digest = LUKS2_digest_create(cd, "pbkdf2", &cd->u.luks2.hdr, vk);
|
digest = LUKS2_digest_create(cd, "pbkdf2", &cd->u.luks2.hdr, vk);
|
||||||
else
|
r = LUKS2_keyslot_params_default(cd, &cd->u.luks2.hdr, 0, ¶ms);
|
||||||
|
} else {
|
||||||
digest = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
|
digest = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
|
||||||
|
r = LUKS2_keyslot_params_default(cd, &cd->u.luks2.hdr, vk->keylength, ¶ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r < 0) {
|
||||||
|
log_err(cd, _("Failed to initialise default LUKS2 keyslot parameters.\n"));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
r = digest;
|
r = digest;
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_err(cd, _("Volume key does not match the volume.\n"));
|
log_err(cd, _("Volume key does not match the volume.\n"));
|
||||||
goto out;
|
goto out;
|
||||||
@@ -4429,8 +4449,8 @@ int crypt_keyslot_add_by_key(struct crypt_device *cd,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = LUKS2_keyslot_store(cd, &cd->u.luks2.hdr, keyslot,
|
r = LUKS2_keyslot_store(cd, &cd->u.luks2.hdr, keyslot,
|
||||||
passphrase, passphrase_size, vk);
|
passphrase, passphrase_size, vk, ¶ms);
|
||||||
out:
|
out:
|
||||||
crypt_free_volume_key(vk);
|
crypt_free_volume_key(vk);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
|||||||
@@ -2262,6 +2262,11 @@ static void Luks2KeyslotAdd(void)
|
|||||||
/* otoh passphrase check should pass */
|
/* 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, 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, CRYPT_ANY_SLOT, PASSPHRASE1, strlen(PASSPHRASE1), 0), 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);
|
||||||
|
EQ_(crypt_keyslot_add_by_key(cd, 3, key2, 13, PASSPHRASE1, strlen(PASSPHRASE1), CRYPT_VOLUME_KEY_NO_SEGMENT), 3);
|
||||||
|
|
||||||
crypt_free(cd);
|
crypt_free(cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user