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