1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * pkey uv specific code
4 *
5 * Copyright IBM Corp. 2024
6 */
7
8 #define KMSG_COMPONENT "pkey"
9 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
10
11 #include <linux/cpufeature.h>
12 #include <linux/init.h>
13 #include <linux/module.h>
14 #include <asm/uv.h>
15
16 #include "zcrypt_ccamisc.h"
17 #include "pkey_base.h"
18
19 MODULE_LICENSE("GPL");
20 MODULE_AUTHOR("IBM Corporation");
21 MODULE_DESCRIPTION("s390 protected key UV handler");
22
23 /*
24 * One pre-allocated uv_secret_list for use with uv_find_secret()
25 */
26 static struct uv_secret_list *uv_list;
27 static DEFINE_MUTEX(uv_list_mutex);
28
29 /*
30 * UV secret token struct and defines.
31 */
32
33 #define TOKVER_UV_SECRET 0x09
34
35 struct uvsecrettoken {
36 u8 type; /* 0x00 = TOKTYPE_NON_CCA */
37 u8 res0[3];
38 u8 version; /* 0x09 = TOKVER_UV_SECRET */
39 u8 res1[3];
40 u16 secret_type; /* one of enum uv_secret_types from uv.h */
41 u16 secret_len; /* length in bytes of the secret */
42 u8 secret_id[UV_SECRET_ID_LEN]; /* the secret id for this secret */
43 } __packed;
44
45 /*
46 * Check key blob for known and supported UV key.
47 */
is_uv_key(const u8 * key,u32 keylen)48 static bool is_uv_key(const u8 *key, u32 keylen)
49 {
50 struct uvsecrettoken *t = (struct uvsecrettoken *)key;
51
52 if (keylen < sizeof(*t))
53 return false;
54
55 switch (t->type) {
56 case TOKTYPE_NON_CCA:
57 switch (t->version) {
58 case TOKVER_UV_SECRET:
59 switch (t->secret_type) {
60 case UV_SECRET_AES_128:
61 case UV_SECRET_AES_192:
62 case UV_SECRET_AES_256:
63 case UV_SECRET_AES_XTS_128:
64 case UV_SECRET_AES_XTS_256:
65 case UV_SECRET_HMAC_SHA_256:
66 case UV_SECRET_HMAC_SHA_512:
67 case UV_SECRET_ECDSA_P256:
68 case UV_SECRET_ECDSA_P384:
69 case UV_SECRET_ECDSA_P521:
70 case UV_SECRET_ECDSA_ED25519:
71 case UV_SECRET_ECDSA_ED448:
72 return true;
73 default:
74 return false;
75 }
76 default:
77 return false;
78 }
79 default:
80 return false;
81 }
82 }
83
is_uv_keytype(enum pkey_key_type keytype)84 static bool is_uv_keytype(enum pkey_key_type keytype)
85 {
86 switch (keytype) {
87 case PKEY_TYPE_UVSECRET:
88 return true;
89 default:
90 return false;
91 }
92 }
93
get_secret_metadata(const u8 secret_id[UV_SECRET_ID_LEN],struct uv_secret_list_item_hdr * secret)94 static int get_secret_metadata(const u8 secret_id[UV_SECRET_ID_LEN],
95 struct uv_secret_list_item_hdr *secret)
96 {
97 int rc;
98
99 mutex_lock(&uv_list_mutex);
100 memset(uv_list, 0, sizeof(*uv_list));
101 rc = uv_find_secret(secret_id, uv_list, secret);
102 mutex_unlock(&uv_list_mutex);
103
104 return rc;
105 }
106
retrieve_secret(const u8 secret_id[UV_SECRET_ID_LEN],u16 * secret_type,u8 * buf,u32 * buflen)107 static int retrieve_secret(const u8 secret_id[UV_SECRET_ID_LEN],
108 u16 *secret_type, u8 *buf, u32 *buflen)
109 {
110 struct uv_secret_list_item_hdr secret_meta_data;
111 int rc;
112
113 rc = get_secret_metadata(secret_id, &secret_meta_data);
114 if (rc)
115 return rc;
116
117 if (*buflen < secret_meta_data.length)
118 return -EINVAL;
119
120 rc = uv_retrieve_secret(secret_meta_data.index,
121 buf, secret_meta_data.length);
122 if (rc)
123 return rc;
124
125 *secret_type = secret_meta_data.type;
126 *buflen = secret_meta_data.length;
127
128 return 0;
129 }
130
uv_get_size_and_type(u16 secret_type,u32 * pkeysize,u32 * pkeytype)131 static int uv_get_size_and_type(u16 secret_type, u32 *pkeysize, u32 *pkeytype)
132 {
133 int rc = 0;
134
135 switch (secret_type) {
136 case UV_SECRET_AES_128:
137 *pkeysize = 16 + AES_WK_VP_SIZE;
138 *pkeytype = PKEY_KEYTYPE_AES_128;
139 break;
140 case UV_SECRET_AES_192:
141 *pkeysize = 24 + AES_WK_VP_SIZE;
142 *pkeytype = PKEY_KEYTYPE_AES_192;
143 break;
144 case UV_SECRET_AES_256:
145 *pkeysize = 32 + AES_WK_VP_SIZE;
146 *pkeytype = PKEY_KEYTYPE_AES_256;
147 break;
148 case UV_SECRET_AES_XTS_128:
149 *pkeysize = 16 + 16 + AES_WK_VP_SIZE;
150 *pkeytype = PKEY_KEYTYPE_AES_XTS_128;
151 break;
152 case UV_SECRET_AES_XTS_256:
153 *pkeysize = 32 + 32 + AES_WK_VP_SIZE;
154 *pkeytype = PKEY_KEYTYPE_AES_XTS_256;
155 break;
156 case UV_SECRET_HMAC_SHA_256:
157 *pkeysize = 64 + AES_WK_VP_SIZE;
158 *pkeytype = PKEY_KEYTYPE_HMAC_512;
159 break;
160 case UV_SECRET_HMAC_SHA_512:
161 *pkeysize = 128 + AES_WK_VP_SIZE;
162 *pkeytype = PKEY_KEYTYPE_HMAC_1024;
163 break;
164 case UV_SECRET_ECDSA_P256:
165 *pkeysize = 32 + AES_WK_VP_SIZE;
166 *pkeytype = PKEY_KEYTYPE_ECC_P256;
167 break;
168 case UV_SECRET_ECDSA_P384:
169 *pkeysize = 48 + AES_WK_VP_SIZE;
170 *pkeytype = PKEY_KEYTYPE_ECC_P384;
171 break;
172 case UV_SECRET_ECDSA_P521:
173 *pkeysize = 80 + AES_WK_VP_SIZE;
174 *pkeytype = PKEY_KEYTYPE_ECC_P521;
175 break;
176 case UV_SECRET_ECDSA_ED25519:
177 *pkeysize = 32 + AES_WK_VP_SIZE;
178 *pkeytype = PKEY_KEYTYPE_ECC_ED25519;
179 break;
180 case UV_SECRET_ECDSA_ED448:
181 *pkeysize = 64 + AES_WK_VP_SIZE;
182 *pkeytype = PKEY_KEYTYPE_ECC_ED448;
183 break;
184 default:
185 rc = -EINVAL;
186 }
187
188 return rc;
189 }
190
uv_key2protkey(const struct pkey_apqn * _apqns __always_unused,size_t _nr_apqns __always_unused,const u8 * key,u32 keylen,u8 * protkey,u32 * protkeylen,u32 * keyinfo,u32 _xflags __always_unused)191 static int uv_key2protkey(const struct pkey_apqn *_apqns __always_unused,
192 size_t _nr_apqns __always_unused,
193 const u8 *key, u32 keylen,
194 u8 *protkey, u32 *protkeylen, u32 *keyinfo,
195 u32 _xflags __always_unused)
196 {
197 struct uvsecrettoken *t = (struct uvsecrettoken *)key;
198 u32 pkeysize, pkeytype;
199 u16 secret_type;
200 int rc;
201
202 rc = uv_get_size_and_type(t->secret_type, &pkeysize, &pkeytype);
203 if (rc)
204 goto out;
205
206 if (*protkeylen < pkeysize) {
207 PKEY_DBF_ERR("%s prot key buffer size too small: %u < %u\n",
208 __func__, *protkeylen, pkeysize);
209 rc = -EINVAL;
210 goto out;
211 }
212
213 rc = retrieve_secret(t->secret_id, &secret_type, protkey, protkeylen);
214 if (rc) {
215 PKEY_DBF_ERR("%s retrieve_secret() failed with %d\n",
216 __func__, rc);
217 goto out;
218 }
219 if (secret_type != t->secret_type) {
220 PKEY_DBF_ERR("%s retrieved secret type %u != expected type %u\n",
221 __func__, secret_type, t->secret_type);
222 rc = -EINVAL;
223 goto out;
224 }
225
226 if (keyinfo)
227 *keyinfo = pkeytype;
228
229 out:
230 pr_debug("rc=%d\n", rc);
231 return rc;
232 }
233
uv_verifykey(const u8 * key,u32 keylen,u16 * _card __always_unused,u16 * _dom __always_unused,u32 * keytype,u32 * keybitsize,u32 * flags,u32 xflags __always_unused)234 static int uv_verifykey(const u8 *key, u32 keylen,
235 u16 *_card __always_unused,
236 u16 *_dom __always_unused,
237 u32 *keytype, u32 *keybitsize, u32 *flags,
238 u32 xflags __always_unused)
239 {
240 struct uvsecrettoken *t = (struct uvsecrettoken *)key;
241 struct uv_secret_list_item_hdr secret_meta_data;
242 u32 pkeysize, pkeytype, bitsize;
243 int rc;
244
245 rc = uv_get_size_and_type(t->secret_type, &pkeysize, &pkeytype);
246 if (rc)
247 goto out;
248
249 rc = get_secret_metadata(t->secret_id, &secret_meta_data);
250 if (rc)
251 goto out;
252
253 if (secret_meta_data.type != t->secret_type) {
254 rc = -EINVAL;
255 goto out;
256 }
257
258 /* set keytype; keybitsize and flags are not supported */
259 if (keytype)
260 *keytype = PKEY_TYPE_UVSECRET;
261 if (keybitsize) {
262 bitsize = 8 * pkey_keytype_to_size(pkeytype);
263 *keybitsize = bitsize ?: PKEY_SIZE_UNKNOWN;
264 }
265 if (flags)
266 *flags = pkeytype;
267
268 out:
269 pr_debug("rc=%d\n", rc);
270 return rc;
271 }
272
273 static struct pkey_handler uv_handler = {
274 .module = THIS_MODULE,
275 .name = "PKEY UV handler",
276 .is_supported_key = is_uv_key,
277 .is_supported_keytype = is_uv_keytype,
278 .key_to_protkey = uv_key2protkey,
279 .verify_key = uv_verifykey,
280 };
281
282 /*
283 * Module init
284 */
pkey_uv_init(void)285 static int __init pkey_uv_init(void)
286 {
287 int rc;
288
289 if (!is_prot_virt_guest())
290 return -ENODEV;
291
292 if (!test_bit_inv(BIT_UVC_CMD_RETR_SECRET, uv_info.inst_calls_list))
293 return -ENODEV;
294
295 uv_list = kmalloc(sizeof(*uv_list), GFP_KERNEL);
296 if (!uv_list)
297 return -ENOMEM;
298
299 rc = pkey_handler_register(&uv_handler);
300 if (rc)
301 kfree(uv_list);
302
303 return rc;
304 }
305
306 /*
307 * Module exit
308 */
pkey_uv_exit(void)309 static void __exit pkey_uv_exit(void)
310 {
311 pkey_handler_unregister(&uv_handler);
312 mutex_lock(&uv_list_mutex);
313 kvfree(uv_list);
314 mutex_unlock(&uv_list_mutex);
315 }
316
317 module_cpu_feature_match(S390_CPU_FEATURE_UV, pkey_uv_init);
318 module_exit(pkey_uv_exit);
319