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