Commit 319fd19b authored by Milan Broz's avatar Milan Broz

Add implementation of crypt_keyslot_pbkdf().

This function allows to get PBKDF parameters per-keyslot.
parent 4edd7965
......@@ -1658,6 +1658,17 @@ int crypt_keyslot_get_key_size(struct crypt_device *cd, int keyslot);
*/
const char *crypt_keyslot_get_encryption(struct crypt_device *cd, int keyslot, size_t *key_size);
/**
* Get PBKDF parameters for keyslot.
*
* @param cd crypt device handle
* @param keyslot keyslot number
* @param pbkdf struct with returned PBKDF parameters
*
* @return @e 0 on success or negative errno value otherwise.
*/
int crypt_keyslot_get_pbkdf(struct crypt_device *cd, int keyslot, struct crypt_pbkdf_type *pbkdf);
/**
* Set encryption for keyslot.
* Use for LUKS2 keyslot to set different encryption type than for data encryption.
......
......@@ -100,6 +100,8 @@ CRYPTSETUP_2.0 {
crypt_keyslot_get_key_size;
crypt_keyslot_set_encryption;
crypt_keyslot_get_encryption;
crypt_keyslot_get_pbkdf;
crypt_get_dir;
crypt_set_debug_level;
crypt_log;
......
......@@ -1226,3 +1226,18 @@ int LUKS_wipe_header_areas(struct luks_phdr *hdr,
return r;
}
int LUKS_keyslot_pbkdf(struct luks_phdr *hdr, int keyslot, struct crypt_pbkdf_type *pbkdf)
{
if (keyslot >= LUKS_NUMKEYS || keyslot < 0)
return -EINVAL;
pbkdf->type = CRYPT_KDF_PBKDF2;
pbkdf->hash = hdr->hashSpec;
pbkdf->iterations = hdr->keyblock[keyslot].passwordIterations;
pbkdf->max_memory_kb = 0;
pbkdf->parallel_threads = 0;
pbkdf->time_ms = 0;
pbkdf->flags = 0;
return 0;
}
......@@ -183,6 +183,8 @@ int LUKS_keyslot_area(const struct luks_phdr *hdr,
uint64_t *length);
size_t LUKS_device_sectors(const struct luks_phdr *hdr);
size_t LUKS_keyslots_offset(const struct luks_phdr *hdr);
int LUKS_keyslot_pbkdf(struct luks_phdr *hdr, int keyslot,
struct crypt_pbkdf_type *pbkdf);
int LUKS1_activate(struct crypt_device *cd,
const char *name,
......
......@@ -354,6 +354,8 @@ int LUKS2_keyslot_area(struct luks2_hdr *hdr,
int keyslot,
uint64_t *offset,
uint64_t *length);
int LUKS2_keyslot_pbkdf(struct luks2_hdr *hdr, int keyslot, struct crypt_pbkdf_type *pbkdf);
/*
* Permanent activation flags stored in header
*/
......
......@@ -173,6 +173,43 @@ int LUKS2_keyslot_params_default(struct crypt_device *cd, struct luks2_hdr *hdr,
return 0;
}
int LUKS2_keyslot_pbkdf(struct luks2_hdr *hdr, int keyslot, struct crypt_pbkdf_type *pbkdf)
{
json_object *jobj_keyslot, *jobj_kdf, *jobj;
if (!hdr || !pbkdf)
return -EINVAL;
if (LUKS2_keyslot_info(hdr, keyslot) == CRYPT_SLOT_INVALID)
return -EINVAL;
jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
if (!jobj_keyslot)
return -ENOENT;
if (!json_object_object_get_ex(jobj_keyslot, "kdf", &jobj_kdf))
return -EINVAL;
if (!json_object_object_get_ex(jobj_kdf, "type", &jobj))
return -EINVAL;
memset(pbkdf, 0, sizeof(*pbkdf));
pbkdf->type = json_object_get_string(jobj);
if (json_object_object_get_ex(jobj_kdf, "hash", &jobj))
pbkdf->hash = json_object_get_string(jobj);
if (json_object_object_get_ex(jobj_kdf, "iterations", &jobj))
pbkdf->iterations = json_object_get_int(jobj);
if (json_object_object_get_ex(jobj_kdf, "time", &jobj))
pbkdf->iterations = json_object_get_int(jobj);
if (json_object_object_get_ex(jobj_kdf, "memory", &jobj))
pbkdf->max_memory_kb = json_object_get_int(jobj);
if (json_object_object_get_ex(jobj_kdf, "cpus", &jobj))
pbkdf->parallel_threads = json_object_get_int(jobj);
return 0;
}
static int LUKS2_keyslot_unbound(struct luks2_hdr *hdr, int keyslot)
{
json_object *jobj_digest, *jobj_segments;
......
......@@ -4640,6 +4640,19 @@ const char *crypt_keyslot_get_encryption(struct crypt_device *cd, int keyslot, s
return DEFAULT_LUKS2_KEYSLOT_CIPHER;
}
int crypt_keyslot_get_pbkdf(struct crypt_device *cd, int keyslot, struct crypt_pbkdf_type *pbkdf)
{
if (!cd || !pbkdf || keyslot == CRYPT_ANY_SLOT)
return -EINVAL;
if (isLUKS1(cd->type))
return LUKS_keyslot_pbkdf(&cd->u.luks1.hdr, keyslot, pbkdf);
else if (isLUKS2(cd->type))
return LUKS2_keyslot_pbkdf(&cd->u.luks2.hdr, keyslot, pbkdf);
return -EINVAL;
}
int crypt_set_data_offset(struct crypt_device *cd, uint64_t data_offset)
{
if (!cd)
......
......@@ -579,7 +579,7 @@ static void AddDeviceLuks2(void)
.parallel_threads = 4,
.max_memory_kb = 1024,
.time_ms = 1
};
}, pbkdf_tmp;
struct crypt_params_luks2 params = {
.pbkdf = &pbkdf,
.data_device = DEVICE_2,
......@@ -748,6 +748,15 @@ static void AddDeviceLuks2(void)
EQ_((int)key_size, crypt_get_volume_key_size(cd));
EQ_(crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase)), 7);
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 7, passphrase, strlen(passphrase) ,0), 7);
OK_(crypt_keyslot_get_pbkdf(cd, 7, &pbkdf_tmp));
OK_(strcmp(pbkdf_tmp.type, pbkdf.type));
NULL_(pbkdf_tmp.hash);
EQ_(0, pbkdf_tmp.time_ms); /* not usable in per-keyslot call */
OK_(!(pbkdf_tmp.iterations >= 4));
OK_(!(pbkdf_tmp.max_memory_kb >= 32));
OK_(!(pbkdf_tmp.parallel_threads >= 1));
crypt_free(cd);
OK_(crypt_init_by_name_and_header(&cd, CDEVICE_1, DMDIR H_DEVICE));
FAIL_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, &params), "Context is already formatted");
......
......@@ -750,6 +750,7 @@ static void AddDeviceLuks(void)
const char *cipher = "aes";
const char *cipher_mode = "cbc-essiv:sha256";
uint64_t r_payload_offset, r_header_size, r_size_1;
struct crypt_pbkdf_type pbkdf;
crypt_decode_key(key, mk_hex, key_size);
crypt_decode_key(key3, mk_hex2, key_size);
......@@ -913,6 +914,16 @@ static void AddDeviceLuks(void)
crypt_set_iteration_time(cd, 1);
EQ_(1, crypt_keyslot_add_by_volume_key(cd, 1, key, key_size, KEY1, strlen(KEY1)));
// PBKDF info (in LUKS1 slots are ther same)
FAIL_(crypt_keyslot_get_pbkdf(cd, 1, NULL), "PBKDF struct required");
OK_(crypt_keyslot_get_pbkdf(cd, 1, &pbkdf));
OK_(strcmp(pbkdf.type, CRYPT_KDF_PBKDF2));
OK_(strcmp(pbkdf.hash, params.hash));
EQ_(1000, pbkdf.iterations); /* set by minimum iterations above */
EQ_(0, pbkdf.max_memory_kb);
EQ_(0, pbkdf.parallel_threads);
OK_(prepare_keyfile(KEYFILE1, KEY1, strlen(KEY1)));
OK_(prepare_keyfile(KEYFILE2, KEY2, strlen(KEY2)));
EQ_(2, crypt_keyslot_add_by_keyfile(cd, 2, KEYFILE1, 0, KEYFILE2, 0));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment