Skip to content

Commit 776e707

Browse files
author
Mete Durlu
committed
s390/uv: Provide host-key hashes in sysfs
JIRA: https://issues.redhat.com/browse/RHEL-50752 Build-Info: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=66103044 commit 28a51ee Author: Steffen Eiden <seiden@linux.ibm.com> Date: Wed Oct 23 09:55:28 2024 +0200 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> Signed-off-by: Mete Durlu <mdurlu@redhat.com>
1 parent 9534e92 commit 776e707

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

arch/s390/include/asm/uv.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#define UVC_RC_NEED_DESTROY 0x8000
3333

3434
#define UVC_CMD_QUI 0x0001
35+
#define UVC_CMD_QUERY_KEYS 0x0002
3536
#define UVC_CMD_INIT_UV 0x000f
3637
#define UVC_CMD_CREATE_SEC_CONF 0x0100
3738
#define UVC_CMD_DESTROY_SEC_CONF 0x0101
@@ -97,6 +98,7 @@ enum uv_cmds_inst {
9798
BIT_UVC_CMD_LIST_SECRETS = 30,
9899
BIT_UVC_CMD_LOCK_SECRETS = 31,
99100
BIT_UVC_CMD_RETR_SECRET = 33,
101+
BIT_UVC_CMD_QUERY_KEYS = 34,
100102
};
101103

102104
enum uv_feat_ind {
@@ -149,6 +151,21 @@ struct uv_cb_qui {
149151
u8 reserved114[0x120 - 0x114]; /* 0x0114 */
150152
} __packed __aligned(8);
151153

154+
struct uv_key_hash {
155+
u64 dword[4];
156+
} __packed __aligned(8);
157+
158+
#define UVC_QUERY_KEYS_IDX_HK 0
159+
#define UVC_QUERY_KEYS_IDX_BACK_HK 1
160+
161+
/* Query Ultravisor Keys */
162+
struct uv_cb_query_keys {
163+
struct uv_cb_header header; /* 0x0000 */
164+
u64 reserved08[3]; /* 0x0008 */
165+
struct uv_key_hash key_hashes[15]; /* 0x0020 */
166+
} __packed __aligned(8);
167+
static_assert(sizeof(struct uv_cb_query_keys) == 0x200);
168+
152169
/* Initialize Ultravisor */
153170
struct uv_cb_init {
154171
struct uv_cb_header header;

arch/s390/kernel/uv.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,10 +667,76 @@ static struct attribute *uv_query_attrs[] = {
667667
NULL,
668668
};
669669

670+
static inline struct uv_cb_query_keys uv_query_keys(void)
671+
{
672+
struct uv_cb_query_keys uvcb = {
673+
.header.cmd = UVC_CMD_QUERY_KEYS,
674+
.header.len = sizeof(uvcb)
675+
};
676+
677+
uv_call(0, (uint64_t)&uvcb);
678+
return uvcb;
679+
}
680+
681+
static inline ssize_t emit_hash(struct uv_key_hash *hash, char *buf, int at)
682+
{
683+
return sysfs_emit_at(buf, at, "%016llx%016llx%016llx%016llx\n",
684+
hash->dword[0], hash->dword[1], hash->dword[2], hash->dword[3]);
685+
}
686+
687+
static ssize_t uv_keys_host_key(struct kobject *kobj,
688+
struct kobj_attribute *attr, char *buf)
689+
{
690+
struct uv_cb_query_keys uvcb = uv_query_keys();
691+
692+
return emit_hash(&uvcb.key_hashes[UVC_QUERY_KEYS_IDX_HK], buf, 0);
693+
}
694+
695+
static struct kobj_attribute uv_keys_host_key_attr =
696+
__ATTR(host_key, 0444, uv_keys_host_key, NULL);
697+
698+
static ssize_t uv_keys_backup_host_key(struct kobject *kobj,
699+
struct kobj_attribute *attr, char *buf)
700+
{
701+
struct uv_cb_query_keys uvcb = uv_query_keys();
702+
703+
return emit_hash(&uvcb.key_hashes[UVC_QUERY_KEYS_IDX_BACK_HK], buf, 0);
704+
}
705+
706+
static struct kobj_attribute uv_keys_backup_host_key_attr =
707+
__ATTR(backup_host_key, 0444, uv_keys_backup_host_key, NULL);
708+
709+
static ssize_t uv_keys_all(struct kobject *kobj,
710+
struct kobj_attribute *attr, char *buf)
711+
{
712+
struct uv_cb_query_keys uvcb = uv_query_keys();
713+
ssize_t len = 0;
714+
int i;
715+
716+
for (i = 0; i < ARRAY_SIZE(uvcb.key_hashes); i++)
717+
len += emit_hash(uvcb.key_hashes + i, buf, len);
718+
719+
return len;
720+
}
721+
722+
static struct kobj_attribute uv_keys_all_attr =
723+
__ATTR(all, 0444, uv_keys_all, NULL);
724+
670725
static struct attribute_group uv_query_attr_group = {
671726
.attrs = uv_query_attrs,
672727
};
673728

729+
static struct attribute *uv_keys_attrs[] = {
730+
&uv_keys_host_key_attr.attr,
731+
&uv_keys_backup_host_key_attr.attr,
732+
&uv_keys_all_attr.attr,
733+
NULL,
734+
};
735+
736+
static struct attribute_group uv_keys_attr_group = {
737+
.attrs = uv_keys_attrs,
738+
};
739+
674740
static ssize_t uv_is_prot_virt_guest(struct kobject *kobj,
675741
struct kobj_attribute *attr, char *buf)
676742
{
@@ -696,6 +762,7 @@ static const struct attribute *uv_prot_virt_attrs[] = {
696762
};
697763

698764
static struct kset *uv_query_kset;
765+
static struct kset *uv_keys_kset;
699766
static struct kobject *uv_kobj;
700767

701768
static int __init uv_sysfs_dir_init(const struct attribute_group *grp,
@@ -734,6 +801,10 @@ static int __init uv_sysfs_init(void)
734801
if (rc)
735802
goto out_ind_files;
736803

804+
/* Get installed key hashes if available, ignore any errors */
805+
if (test_bit_inv(BIT_UVC_CMD_QUERY_KEYS, uv_info.inst_calls_list))
806+
uv_sysfs_dir_init(&uv_keys_attr_group, &uv_keys_kset, "keys");
807+
737808
return 0;
738809

739810
out_ind_files:

0 commit comments

Comments
 (0)