mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Add keyslot_context for volume key stored in a keyring.
This commit is contained in:
@@ -362,6 +362,42 @@ static int get_luks1_volume_key_by_keyring(struct crypt_device *cd,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_key_by_vk_in_keyring(struct crypt_device *cd,
|
||||||
|
struct crypt_keyslot_context *kc,
|
||||||
|
int keyslot __attribute__((unused)),
|
||||||
|
int segment __attribute__((unused)),
|
||||||
|
struct volume_key **r_vk)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(cd);
|
||||||
|
assert(kc && kc->type == CRYPT_KC_TYPE_VK_KEYRING);
|
||||||
|
assert(r_vk);
|
||||||
|
|
||||||
|
r = keyring_read_by_id(kc->u.vk_kr.key_description, &kc->i_volume_key, &kc->i_volume_key_size);
|
||||||
|
if (r < 0) {
|
||||||
|
log_err(cd, _("Failed to read volume key from keyring."));
|
||||||
|
kc->error = -EINVAL;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*r_vk = crypt_alloc_volume_key(kc->i_volume_key_size, kc->i_volume_key);
|
||||||
|
if (!*r_vk) {
|
||||||
|
kc->error = -ENOMEM;
|
||||||
|
return kc->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_volume_key_by_vk_in_keyring(struct crypt_device *cd,
|
||||||
|
struct crypt_keyslot_context *kc,
|
||||||
|
int keyslot __attribute__((unused)),
|
||||||
|
struct volume_key **r_vk)
|
||||||
|
{
|
||||||
|
return get_key_by_vk_in_keyring(cd, kc, -2 /* unused */, -2 /* unused */, r_vk);
|
||||||
|
}
|
||||||
|
|
||||||
static void unlock_method_init_internal(struct crypt_keyslot_context *kc)
|
static void unlock_method_init_internal(struct crypt_keyslot_context *kc)
|
||||||
{
|
{
|
||||||
assert(kc);
|
assert(kc);
|
||||||
@@ -369,6 +405,8 @@ static void unlock_method_init_internal(struct crypt_keyslot_context *kc)
|
|||||||
kc->error = 0;
|
kc->error = 0;
|
||||||
kc->i_passphrase = NULL;
|
kc->i_passphrase = NULL;
|
||||||
kc->i_passphrase_size = 0;
|
kc->i_passphrase_size = 0;
|
||||||
|
kc->i_volume_key = NULL;
|
||||||
|
kc->i_volume_key_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void crypt_keyslot_unlock_by_keyring_internal(struct crypt_keyslot_context *kc,
|
void crypt_keyslot_unlock_by_keyring_internal(struct crypt_keyslot_context *kc,
|
||||||
@@ -483,6 +521,27 @@ void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *k
|
|||||||
unlock_method_init_internal(kc);
|
unlock_method_init_internal(kc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void crypt_keyslot_unlock_by_vk_in_keyring_internal(struct crypt_keyslot_context *kc,
|
||||||
|
const char *key_description)
|
||||||
|
{
|
||||||
|
assert(kc);
|
||||||
|
|
||||||
|
kc->type = CRYPT_KC_TYPE_VK_KEYRING;
|
||||||
|
kc->u.vk_kr.key_description = key_description;
|
||||||
|
|
||||||
|
kc->get_luks2_key = get_key_by_vk_in_keyring;
|
||||||
|
kc->get_luks2_volume_key = get_volume_key_by_vk_in_keyring;
|
||||||
|
kc->get_luks1_volume_key = NULL;
|
||||||
|
kc->get_passphrase = NULL; /* keyslot key context does not provide passphrase */
|
||||||
|
kc->get_plain_volume_key = NULL;
|
||||||
|
kc->get_bitlk_volume_key = NULL;
|
||||||
|
kc->get_fvault2_volume_key = NULL;
|
||||||
|
kc->get_verity_volume_key = NULL;
|
||||||
|
kc->get_integrity_volume_key = NULL;
|
||||||
|
unlock_method_init_internal(kc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *kc)
|
void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *kc)
|
||||||
{
|
{
|
||||||
if (!kc)
|
if (!kc)
|
||||||
@@ -491,6 +550,9 @@ void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *kc)
|
|||||||
crypt_safe_free(kc->i_passphrase);
|
crypt_safe_free(kc->i_passphrase);
|
||||||
kc->i_passphrase = NULL;
|
kc->i_passphrase = NULL;
|
||||||
kc->i_passphrase_size = 0;
|
kc->i_passphrase_size = 0;
|
||||||
|
crypt_safe_free(kc->i_volume_key);
|
||||||
|
kc->i_volume_key = NULL;
|
||||||
|
kc->i_volume_key_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void crypt_keyslot_context_free(struct crypt_keyslot_context *kc)
|
void crypt_keyslot_context_free(struct crypt_keyslot_context *kc)
|
||||||
@@ -606,6 +668,26 @@ int crypt_keyslot_context_init_by_keyring(struct crypt_device *cd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int crypt_keyslot_context_init_by_vk_in_keyring(struct crypt_device *cd,
|
||||||
|
const char *key_description,
|
||||||
|
struct crypt_keyslot_context **kc)
|
||||||
|
{
|
||||||
|
struct crypt_keyslot_context *tmp;
|
||||||
|
|
||||||
|
if (!kc)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
tmp = malloc(sizeof(*tmp));
|
||||||
|
if (!tmp)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
crypt_keyslot_unlock_by_vk_in_keyring_internal(tmp, key_description);
|
||||||
|
|
||||||
|
*kc = tmp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int crypt_keyslot_context_get_error(struct crypt_keyslot_context *kc)
|
int crypt_keyslot_context_get_error(struct crypt_keyslot_context *kc)
|
||||||
{
|
{
|
||||||
return kc ? kc->error : -EINVAL;
|
return kc ? kc->error : -EINVAL;
|
||||||
@@ -645,6 +727,8 @@ const char *keyslot_context_type_string(const struct crypt_keyslot_context *kc)
|
|||||||
return "key";
|
return "key";
|
||||||
case CRYPT_KC_TYPE_KEYRING:
|
case CRYPT_KC_TYPE_KEYRING:
|
||||||
return "keyring";
|
return "keyring";
|
||||||
|
case CRYPT_KC_TYPE_VK_KEYRING:
|
||||||
|
return "volume key in keyring";
|
||||||
default:
|
default:
|
||||||
return "<unknown>";
|
return "<unknown>";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,12 +79,17 @@ struct crypt_keyslot_context {
|
|||||||
struct {
|
struct {
|
||||||
const char *key_description;
|
const char *key_description;
|
||||||
} kr;
|
} kr;
|
||||||
|
struct {
|
||||||
|
const char *key_description;
|
||||||
|
} vk_kr;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
char *i_passphrase;
|
char *i_passphrase;
|
||||||
size_t i_passphrase_size;
|
size_t i_passphrase_size;
|
||||||
|
char *i_volume_key;
|
||||||
|
size_t i_volume_key_size;
|
||||||
|
|
||||||
keyslot_context_get_key get_luks2_key;
|
keyslot_context_get_key get_luks2_key;
|
||||||
keyslot_context_get_volume_key get_luks1_volume_key;
|
keyslot_context_get_volume_key get_luks1_volume_key;
|
||||||
@@ -122,6 +127,9 @@ void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *k
|
|||||||
void crypt_keyslot_unlock_by_keyring_internal(struct crypt_keyslot_context *kc,
|
void crypt_keyslot_unlock_by_keyring_internal(struct crypt_keyslot_context *kc,
|
||||||
const char *key_description);
|
const char *key_description);
|
||||||
|
|
||||||
|
void crypt_keyslot_unlock_by_vk_in_keyring_internal(struct crypt_keyslot_context *kc,
|
||||||
|
const char *key_description);
|
||||||
|
|
||||||
const char *keyslot_context_type_string(const struct crypt_keyslot_context *kc);
|
const char *keyslot_context_type_string(const struct crypt_keyslot_context *kc);
|
||||||
|
|
||||||
#endif /* KEYSLOT_CONTEXT_H */
|
#endif /* KEYSLOT_CONTEXT_H */
|
||||||
|
|||||||
@@ -1294,6 +1294,22 @@ int crypt_keyslot_context_init_by_keyring(struct crypt_device *cd,
|
|||||||
const char *key_description,
|
const char *key_description,
|
||||||
struct crypt_keyslot_context **kc);
|
struct crypt_keyslot_context **kc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize keyslot context via volume key stored in a keyring.
|
||||||
|
*
|
||||||
|
* @param cd crypt device handle initialized to LUKS device context
|
||||||
|
*
|
||||||
|
* @param key_description kernel keyring key description library should look
|
||||||
|
* for passphrase in. The key can be passed either as number in ASCII,
|
||||||
|
* or a text representation in the form "%<key_type>:<key_name>"
|
||||||
|
* @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEYRING
|
||||||
|
*
|
||||||
|
* @return zero on success or negative errno otherwise.
|
||||||
|
*/
|
||||||
|
int crypt_keyslot_context_init_by_vk_in_keyring(struct crypt_device *cd,
|
||||||
|
const char *key_description,
|
||||||
|
struct crypt_keyslot_context **kc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get error code per keyslot context from last failed call.
|
* Get error code per keyslot context from last failed call.
|
||||||
*
|
*
|
||||||
@@ -1341,6 +1357,10 @@ int crypt_keyslot_context_set_pin(struct crypt_device *cd,
|
|||||||
* (@link crypt_keyslot_context_init_by_keyring @endlink)
|
* (@link crypt_keyslot_context_init_by_keyring @endlink)
|
||||||
*/
|
*/
|
||||||
#define CRYPT_KC_TYPE_KEYRING INT16_C(5)
|
#define CRYPT_KC_TYPE_KEYRING INT16_C(5)
|
||||||
|
/** keyslot context initialized by description of a keyring key containing the volume key
|
||||||
|
* (@link crypt_keyslot_context_init_by_vk_in_keyring @endlink)
|
||||||
|
*/
|
||||||
|
#define CRYPT_KC_TYPE_VK_KEYRING INT16_C(6)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ CRYPTSETUP_2.7 {
|
|||||||
crypt_get_hw_encryption_key_size;
|
crypt_get_hw_encryption_key_size;
|
||||||
crypt_get_vk_keyring_type;
|
crypt_get_vk_keyring_type;
|
||||||
crypt_keyslot_context_init_by_keyring;
|
crypt_keyslot_context_init_by_keyring;
|
||||||
|
crypt_keyslot_context_init_by_vk_in_keyring;
|
||||||
crypt_resume_by_keyslot_context;
|
crypt_resume_by_keyslot_context;
|
||||||
crypt_set_keyring_to_link;
|
crypt_set_keyring_to_link;
|
||||||
crypt_set_vk_keyring_type;
|
crypt_set_vk_keyring_type;
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ static key_serial_t keyring_process_proc_keys_line(char *line, const char *type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* inspired by keyutils written by David Howells (dhowells@redhat.com), returns 0 ID on failure */
|
/* inspired by keyutils written by David Howells (dhowells@redhat.com), returns 0 ID on failure */
|
||||||
|
|
||||||
static key_serial_t find_key_by_type_and_desc(const char *type, const char *desc, key_serial_t destringid)
|
static key_serial_t find_key_by_type_and_desc(const char *type, const char *desc, key_serial_t destringid)
|
||||||
{
|
{
|
||||||
key_serial_t id;
|
key_serial_t id;
|
||||||
@@ -264,6 +265,54 @@ int keyring_get_key(const char *key_desc,
|
|||||||
return keyring_get_passphrase(key_desc, key, key_size);
|
return keyring_get_passphrase(key_desc, key, key_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int keyring_read_by_id(const char *key_desc,
|
||||||
|
char **passphrase,
|
||||||
|
size_t *passphrase_len)
|
||||||
|
{
|
||||||
|
#ifdef KERNEL_KEYRING
|
||||||
|
int err;
|
||||||
|
key_serial_t kid;
|
||||||
|
long ret;
|
||||||
|
char *buf = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
kid = request_key(key_type_name(USER_KEY), key_desc, NULL, 0);
|
||||||
|
while (kid < 0 && errno == EINTR);
|
||||||
|
|
||||||
|
kid = keyring_by_name(key_desc);
|
||||||
|
if (kid < 0)
|
||||||
|
return kid;
|
||||||
|
else if (kid == 0)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
/* just get payload size */
|
||||||
|
ret = keyctl_read(kid, NULL, 0);
|
||||||
|
if (ret > 0) {
|
||||||
|
len = ret;
|
||||||
|
buf = crypt_safe_alloc(len);
|
||||||
|
if (!buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* retrieve actual payload data */
|
||||||
|
ret = keyctl_read(kid, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
err = errno;
|
||||||
|
crypt_safe_free(buf);
|
||||||
|
return -err;
|
||||||
|
}
|
||||||
|
|
||||||
|
*passphrase = buf;
|
||||||
|
*passphrase_len = len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
return -ENOTSUP;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int keyring_get_passphrase(const char *key_desc,
|
int keyring_get_passphrase(const char *key_desc,
|
||||||
char **passphrase,
|
char **passphrase,
|
||||||
size_t *passphrase_len)
|
size_t *passphrase_len)
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ int keyring_get_key(const char *key_desc,
|
|||||||
char **key,
|
char **key,
|
||||||
size_t *key_size);
|
size_t *key_size);
|
||||||
|
|
||||||
|
int keyring_read_by_id(const char *key_desc,
|
||||||
|
char **passphrase,
|
||||||
|
size_t *passphrase_len);
|
||||||
|
|
||||||
int keyring_get_passphrase(const char *key_desc,
|
int keyring_get_passphrase(const char *key_desc,
|
||||||
char **passphrase,
|
char **passphrase,
|
||||||
size_t *passphrase_len);
|
size_t *passphrase_len);
|
||||||
|
|||||||
Reference in New Issue
Block a user