xref: /linux/drivers/s390/crypto/pkey_uv.c (revision 7fc2cd2e4b398c57c9cf961cfea05eadbf34c05c)
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  */
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 
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 
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 
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 
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 
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 
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  */
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(sizeof(*uv_list), GFP_KERNEL);
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  */
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