diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h index 407defed..0a7ebdba 100644 --- a/lib/libcryptsetup.h +++ b/lib/libcryptsetup.h @@ -1525,6 +1525,18 @@ int crypt_keyslot_area(struct crypt_device *cd, uint64_t *offset, uint64_t *length); +/** + * Get size (in bytes) of key for particular keyslot. + * Use for LUKS2 unbound keyslots, for other keyslots it is the same as @ref crypt_get_volume_key_size + * + * @param cd crypt device handle + * @param keyslot keyslot number + * + * @return volume key size or negative errno value otherwise. + * + */ +int crypt_keyslot_get_key_size(struct crypt_device *cd, int keyslot); + /** * Get directory where mapped crypt devices are created * diff --git a/lib/libcryptsetup.sym b/lib/libcryptsetup.sym index fb5db714..c4d2c43f 100644 --- a/lib/libcryptsetup.sym +++ b/lib/libcryptsetup.sym @@ -90,6 +90,7 @@ CRYPTSETUP_2.0 { crypt_keyslot_max; crypt_keyslot_area; crypt_keyslot_status; + crypt_keyslot_get_key_size; crypt_get_dir; crypt_set_debug_level; crypt_log; diff --git a/lib/setup.c b/lib/setup.c index b2bb404b..020c5456 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -3782,6 +3782,23 @@ int crypt_get_volume_key_size(struct crypt_device *cd) return 0; } +int crypt_keyslot_get_key_size(struct crypt_device *cd, int keyslot) +{ + if (!cd || !isLUKS(cd->type)) + return -EINVAL; + + if (keyslot < 0 || keyslot >= crypt_keyslot_max(cd->type)) + return -EINVAL; + + if (isLUKS1(cd->type)) + return cd->u.luks1.hdr.keyBytes; + + if (isLUKS2(cd->type)) + return LUKS2_get_keyslot_key_size(&cd->u.luks2.hdr, keyslot); + + return -EINVAL; +} + uint64_t crypt_get_data_offset(struct crypt_device *cd) { if (!cd) diff --git a/tests/api-test-2.c b/tests/api-test-2.c index da3e1922..7ec80c44 100644 --- a/tests/api-test-2.c +++ b/tests/api-test-2.c @@ -2332,6 +2332,13 @@ static void Luks2KeyslotAdd(void) 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); + FAIL_(crypt_keyslot_get_key_size(cd, CRYPT_ANY_SLOT), "Bad keyslot specification."); + EQ_(crypt_get_volume_key_size(cd), key_size); + EQ_(crypt_keyslot_get_key_size(cd, 0), key_size); + EQ_(crypt_keyslot_get_key_size(cd, 1), key_size); + EQ_(crypt_keyslot_get_key_size(cd, 2), key_size-1); + EQ_(crypt_keyslot_get_key_size(cd, 3), 13); + key_ret_len = key_size - 1; FAIL_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key_ret, &key_ret_len, PASSPHRASE1, strlen(PASSPHRASE1)), "Wrong size or fips");