xref: /linux/drivers/s390/crypto/pkey_uv.c (revision fb7399cf2d0b33825b8039f95c45395c7deba25c)
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  */
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 
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 
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 
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 
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 
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 
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  */
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  */
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