mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
s390/uv: Provide host-key hashes in sysfs
Utilize the new Query Ultravisor Keys UVC to give user space the information which host-keys are installed on the system. Create a new sysfs directory 'firmware/uv/keys' that contains the hash of the host-key and the backup host-key of that system. Additionally, the file 'all' contains the response from the UVC possibly containing more key-hashes than currently known. Reviewed-by: Janosch Frank <frankja@linux.ibm.com> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com> Link: https://lore.kernel.org/r/20241023075529.2561384-1-seiden@linux.ibm.com Signed-off-by: Janosch Frank <frankja@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
This commit is contained in:
parent
bb4ad73a28
commit
28a51ee8eb
|
|
@ -31,6 +31,7 @@
|
|||
#define UVC_RC_NEED_DESTROY 0x8000
|
||||
|
||||
#define UVC_CMD_QUI 0x0001
|
||||
#define UVC_CMD_QUERY_KEYS 0x0002
|
||||
#define UVC_CMD_INIT_UV 0x000f
|
||||
#define UVC_CMD_CREATE_SEC_CONF 0x0100
|
||||
#define UVC_CMD_DESTROY_SEC_CONF 0x0101
|
||||
|
|
@ -94,6 +95,7 @@ enum uv_cmds_inst {
|
|||
BIT_UVC_CMD_ADD_SECRET = 29,
|
||||
BIT_UVC_CMD_LIST_SECRETS = 30,
|
||||
BIT_UVC_CMD_LOCK_SECRETS = 31,
|
||||
BIT_UVC_CMD_QUERY_KEYS = 34,
|
||||
};
|
||||
|
||||
enum uv_feat_ind {
|
||||
|
|
@ -145,6 +147,21 @@ struct uv_cb_qui {
|
|||
u8 reserved112[0x120 - 0x112]; /* 0x0112 */
|
||||
} __packed __aligned(8);
|
||||
|
||||
struct uv_key_hash {
|
||||
u64 dword[4];
|
||||
} __packed __aligned(8);
|
||||
|
||||
#define UVC_QUERY_KEYS_IDX_HK 0
|
||||
#define UVC_QUERY_KEYS_IDX_BACK_HK 1
|
||||
|
||||
/* Query Ultravisor Keys */
|
||||
struct uv_cb_query_keys {
|
||||
struct uv_cb_header header; /* 0x0000 */
|
||||
u64 reserved08[3]; /* 0x0008 */
|
||||
struct uv_key_hash key_hashes[15]; /* 0x0020 */
|
||||
} __packed __aligned(8);
|
||||
static_assert(sizeof(struct uv_cb_query_keys) == 0x200);
|
||||
|
||||
/* Initialize Ultravisor */
|
||||
struct uv_cb_init {
|
||||
struct uv_cb_header header;
|
||||
|
|
|
|||
|
|
@ -722,10 +722,76 @@ static struct attribute *uv_query_attrs[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
static inline struct uv_cb_query_keys uv_query_keys(void)
|
||||
{
|
||||
struct uv_cb_query_keys uvcb = {
|
||||
.header.cmd = UVC_CMD_QUERY_KEYS,
|
||||
.header.len = sizeof(uvcb)
|
||||
};
|
||||
|
||||
uv_call(0, (uint64_t)&uvcb);
|
||||
return uvcb;
|
||||
}
|
||||
|
||||
static inline ssize_t emit_hash(struct uv_key_hash *hash, char *buf, int at)
|
||||
{
|
||||
return sysfs_emit_at(buf, at, "%016llx%016llx%016llx%016llx\n",
|
||||
hash->dword[0], hash->dword[1], hash->dword[2], hash->dword[3]);
|
||||
}
|
||||
|
||||
static ssize_t uv_keys_host_key(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct uv_cb_query_keys uvcb = uv_query_keys();
|
||||
|
||||
return emit_hash(&uvcb.key_hashes[UVC_QUERY_KEYS_IDX_HK], buf, 0);
|
||||
}
|
||||
|
||||
static struct kobj_attribute uv_keys_host_key_attr =
|
||||
__ATTR(host_key, 0444, uv_keys_host_key, NULL);
|
||||
|
||||
static ssize_t uv_keys_backup_host_key(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct uv_cb_query_keys uvcb = uv_query_keys();
|
||||
|
||||
return emit_hash(&uvcb.key_hashes[UVC_QUERY_KEYS_IDX_BACK_HK], buf, 0);
|
||||
}
|
||||
|
||||
static struct kobj_attribute uv_keys_backup_host_key_attr =
|
||||
__ATTR(backup_host_key, 0444, uv_keys_backup_host_key, NULL);
|
||||
|
||||
static ssize_t uv_keys_all(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct uv_cb_query_keys uvcb = uv_query_keys();
|
||||
ssize_t len = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(uvcb.key_hashes); i++)
|
||||
len += emit_hash(uvcb.key_hashes + i, buf, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static struct kobj_attribute uv_keys_all_attr =
|
||||
__ATTR(all, 0444, uv_keys_all, NULL);
|
||||
|
||||
static struct attribute_group uv_query_attr_group = {
|
||||
.attrs = uv_query_attrs,
|
||||
};
|
||||
|
||||
static struct attribute *uv_keys_attrs[] = {
|
||||
&uv_keys_host_key_attr.attr,
|
||||
&uv_keys_backup_host_key_attr.attr,
|
||||
&uv_keys_all_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group uv_keys_attr_group = {
|
||||
.attrs = uv_keys_attrs,
|
||||
};
|
||||
|
||||
static ssize_t uv_is_prot_virt_guest(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
|
|
@ -751,6 +817,7 @@ static const struct attribute *uv_prot_virt_attrs[] = {
|
|||
};
|
||||
|
||||
static struct kset *uv_query_kset;
|
||||
static struct kset *uv_keys_kset;
|
||||
static struct kobject *uv_kobj;
|
||||
|
||||
static int __init uv_sysfs_dir_init(const struct attribute_group *grp,
|
||||
|
|
@ -789,6 +856,10 @@ static int __init uv_sysfs_init(void)
|
|||
if (rc)
|
||||
goto out_ind_files;
|
||||
|
||||
/* Get installed key hashes if available, ignore any errors */
|
||||
if (test_bit_inv(BIT_UVC_CMD_QUERY_KEYS, uv_info.inst_calls_list))
|
||||
uv_sysfs_dir_init(&uv_keys_attr_group, &uv_keys_kset, "keys");
|
||||
|
||||
return 0;
|
||||
|
||||
out_ind_files:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user