pkey_pckmo.c (ea88e1710a9f19345c94c195f9cd7365e50343b0) pkey_pckmo.c (8fcc231ce3bea12b78bb94b280cdc03cff342435)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * pkey pckmo specific code
4 *
5 * Copyright IBM Corp. 2024
6 */
7
8#define KMSG_COMPONENT "pkey"
9#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
10
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * pkey pckmo 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/init.h>
12#include <linux/module.h>
13#include <linux/cpufeature.h>
11#include <asm/cpacf.h>
12#include <crypto/aes.h>
13#include <linux/random.h>
14
15#include "zcrypt_api.h"
16#include "zcrypt_ccamisc.h"
14#include <asm/cpacf.h>
15#include <crypto/aes.h>
16#include <linux/random.h>
17
18#include "zcrypt_api.h"
19#include "zcrypt_ccamisc.h"
17
18#include "pkey_base.h"
19
20#include "pkey_base.h"
21
20/*
21 * Prototypes
22 */
22MODULE_LICENSE("GPL");
23MODULE_AUTHOR("IBM Corporation");
24MODULE_DESCRIPTION("s390 protected key PCKMO handler");
23
25
24static bool is_pckmo_key(const u8 *key, u32 keylen);
25static int pckmo_key2protkey(const u8 *key, u32 keylen,
26 u8 *protkey, u32 *protkeylen, u32 *protkeytype);
27static int pckmo_gen_protkey(u32 keytype,
28 u8 *protkey, u32 *protkeylen, u32 *protkeytype);
29static int pckmo_clr2protkey(u32 keytype, const u8 *clrkey, u32 clrkeylen,
30 u8 *protkey, u32 *protkeylen, u32 *protkeytype);
31static int pckmo_verify_protkey(const u8 *protkey, u32 protkeylen,
32 u32 protkeytype);
33
34/*
26/*
35 * Wrapper functions
36 */
37
38bool pkey_is_pckmo_key(const u8 *key, u32 keylen)
39{
40 return is_pckmo_key(key, keylen);
41}
42
43int pkey_pckmo_key2protkey(u16 _card, u16 _dom,
44 const u8 *key, u32 keylen,
45 u8 *protkey, u32 *protkeylen, u32 *keyinfo)
46{
47 return pckmo_key2protkey(key, keylen,
48 protkey, protkeylen, keyinfo);
49}
50
51int pkey_pckmo_gen_key(u16 _card, u16 _dom,
52 u32 keytype, u32 _keysubtype,
53 u32 _keybitsize, u32 _flags,
54 u8 *keybuf, u32 *keybuflen, u32 *keyinfo)
55{
56 return pckmo_gen_protkey(keytype,
57 keybuf, keybuflen, keyinfo);
58}
59
60int pkey_pckmo_clr2key(u16 _card, u16 _dom,
61 u32 keytype, u32 _keysubtype,
62 u32 _keybitsize, u32 _flags,
63 const u8 *clrkey, u32 clrkeylen,
64 u8 *keybuf, u32 *keybuflen, u32 *keyinfo)
65{
66 return pckmo_clr2protkey(keytype, clrkey, clrkeylen,
67 keybuf, keybuflen, keyinfo);
68}
69
70int pkey_pckmo_verifykey(const u8 *key, u32 keylen,
71 u16 *_card, u16 *_dom,
72 u32 *keytype, u32 *_keybitsize, u32 *_flags)
73{
74 return pckmo_verify_protkey(key, keylen, *keytype);
75}
76
77/*
78 * Check key blob for known and supported here.
79 */
80static bool is_pckmo_key(const u8 *key, u32 keylen)
81{
82 struct keytoken_header *hdr = (struct keytoken_header *)key;
83 struct clearkeytoken *t = (struct clearkeytoken *)key;
84
85 if (keylen < sizeof(*hdr))

--- 21 unchanged lines hidden (view full) ---

107 default:
108 return false;
109 }
110 default:
111 return false;
112 }
113}
114
27 * Check key blob for known and supported here.
28 */
29static bool is_pckmo_key(const u8 *key, u32 keylen)
30{
31 struct keytoken_header *hdr = (struct keytoken_header *)key;
32 struct clearkeytoken *t = (struct clearkeytoken *)key;
33
34 if (keylen < sizeof(*hdr))

--- 21 unchanged lines hidden (view full) ---

56 default:
57 return false;
58 }
59 default:
60 return false;
61 }
62}
63
115static int pckmo_key2protkey(const u8 *key, u32 keylen,
116 u8 *protkey, u32 *protkeylen, u32 *protkeytype)
64static bool is_pckmo_keytype(enum pkey_key_type keytype)
117{
65{
118 struct keytoken_header *hdr = (struct keytoken_header *)key;
119 int rc = -EINVAL;
120
121 if (keylen < sizeof(*hdr))
122 return -EINVAL;
123 if (hdr->type != TOKTYPE_NON_CCA)
124 return -EINVAL;
125
126 switch (hdr->version) {
127 case TOKVER_PROTECTED_KEY: {
128 struct protaeskeytoken *t;
129
130 if (keylen != sizeof(struct protaeskeytoken))
131 goto out;
132 t = (struct protaeskeytoken *)key;
133 rc = pckmo_verify_protkey(t->protkey, t->len, t->keytype);
134 if (rc)
135 goto out;
136 memcpy(protkey, t->protkey, t->len);
137 *protkeylen = t->len;
138 *protkeytype = t->keytype;
139 break;
140 }
141 case TOKVER_CLEAR_KEY: {
142 struct clearkeytoken *t = (struct clearkeytoken *)key;
143 u32 keysize = 0;
144
145 if (keylen < sizeof(struct clearkeytoken) ||
146 keylen != sizeof(*t) + t->len)
147 goto out;
148 switch (t->keytype) {
149 case PKEY_KEYTYPE_AES_128:
150 case PKEY_KEYTYPE_AES_192:
151 case PKEY_KEYTYPE_AES_256:
152 keysize = pkey_keytype_aes_to_size(t->keytype);
153 break;
154 case PKEY_KEYTYPE_ECC_P256:
155 keysize = 32;
156 break;
157 case PKEY_KEYTYPE_ECC_P384:
158 keysize = 48;
159 break;
160 case PKEY_KEYTYPE_ECC_P521:
161 keysize = 80;
162 break;
163 case PKEY_KEYTYPE_ECC_ED25519:
164 keysize = 32;
165 break;
166 case PKEY_KEYTYPE_ECC_ED448:
167 keysize = 64;
168 break;
169 default:
170 break;
171 }
172 if (!keysize) {
173 PKEY_DBF_ERR("%s clear key token: unknown keytype %u\n",
174 __func__, t->keytype);
175 goto out;
176 }
177 if (t->len != keysize) {
178 PKEY_DBF_ERR("%s clear key token: invalid key len %u\n",
179 __func__, t->len);
180 goto out;
181 }
182 rc = pckmo_clr2protkey(t->keytype, t->clearkey, t->len,
183 protkey, protkeylen, protkeytype);
184 break;
185 }
66 switch (keytype) {
67 case PKEY_TYPE_PROTKEY:
68 return true;
186 default:
69 default:
187 PKEY_DBF_ERR("%s unknown non-CCA token version %d\n",
188 __func__, hdr->version);
189 break;
70 return false;
190 }
71 }
191
192out:
193 pr_debug("rc=%d\n", rc);
194 return rc;
195}
196
197/*
72}
73
74/*
198 * Generate a random protected key.
199 * Currently only the generation of AES protected keys
200 * is supported.
201 */
202static int pckmo_gen_protkey(u32 keytype, u8 *protkey,
203 u32 *protkeylen, u32 *protkeytype)
204{
205 u8 clrkey[32];
206 int keysize;
207 int rc;
208
209 keysize = pkey_keytype_aes_to_size(keytype);
210 if (!keysize) {
211 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", __func__,
212 keytype);
213 return -EINVAL;
214 }
215
216 /* generate a dummy random clear key */
217 get_random_bytes(clrkey, keysize);
218
219 /* convert it to a dummy protected key */
220 rc = pckmo_clr2protkey(keytype, clrkey, keysize,
221 protkey, protkeylen, protkeytype);
222 if (rc)
223 goto out;
224
225 /* replace the key part of the protected key with random bytes */
226 get_random_bytes(protkey, keysize);
227
228out:
229 pr_debug("rc=%d\n", rc);
230 return rc;
231}
232
233/*
234 * Create a protected key from a clear key value via PCKMO instruction.
235 */
236static int pckmo_clr2protkey(u32 keytype, const u8 *clrkey, u32 clrkeylen,
237 u8 *protkey, u32 *protkeylen, u32 *protkeytype)
238{
239 /* mask of available pckmo subfunctions */
240 static cpacf_mask_t pckmo_functions;
241

--- 99 unchanged lines hidden (view full) ---

341 rc = 0;
342
343out:
344 pr_debug("rc=%d\n", rc);
345 return rc;
346}
347
348/*
75 * Create a protected key from a clear key value via PCKMO instruction.
76 */
77static int pckmo_clr2protkey(u32 keytype, const u8 *clrkey, u32 clrkeylen,
78 u8 *protkey, u32 *protkeylen, u32 *protkeytype)
79{
80 /* mask of available pckmo subfunctions */
81 static cpacf_mask_t pckmo_functions;
82

--- 99 unchanged lines hidden (view full) ---

182 rc = 0;
183
184out:
185 pr_debug("rc=%d\n", rc);
186 return rc;
187}
188
189/*
349 * Verify a protected key blob.
190 * Verify a raw protected key blob.
350 * Currently only AES protected keys are supported.
351 */
352static int pckmo_verify_protkey(const u8 *protkey, u32 protkeylen,
353 u32 protkeytype)
354{
355 struct {
356 u8 iv[AES_BLOCK_SIZE];
357 u8 key[MAXPROTKEYSIZE];

--- 42 unchanged lines hidden (view full) ---

400 }
401
402 rc = 0;
403
404out:
405 pr_debug("rc=%d\n", rc);
406 return rc;
407}
191 * Currently only AES protected keys are supported.
192 */
193static int pckmo_verify_protkey(const u8 *protkey, u32 protkeylen,
194 u32 protkeytype)
195{
196 struct {
197 u8 iv[AES_BLOCK_SIZE];
198 u8 key[MAXPROTKEYSIZE];

--- 42 unchanged lines hidden (view full) ---

241 }
242
243 rc = 0;
244
245out:
246 pr_debug("rc=%d\n", rc);
247 return rc;
248}
249
250static int pckmo_key2protkey(const u8 *key, u32 keylen,
251 u8 *protkey, u32 *protkeylen, u32 *protkeytype)
252{
253 struct keytoken_header *hdr = (struct keytoken_header *)key;
254 int rc = -EINVAL;
255
256 if (keylen < sizeof(*hdr))
257 return -EINVAL;
258 if (hdr->type != TOKTYPE_NON_CCA)
259 return -EINVAL;
260
261 switch (hdr->version) {
262 case TOKVER_PROTECTED_KEY: {
263 struct protaeskeytoken *t;
264
265 if (keylen != sizeof(struct protaeskeytoken))
266 goto out;
267 t = (struct protaeskeytoken *)key;
268 rc = pckmo_verify_protkey(t->protkey, t->len, t->keytype);
269 if (rc)
270 goto out;
271 memcpy(protkey, t->protkey, t->len);
272 *protkeylen = t->len;
273 *protkeytype = t->keytype;
274 break;
275 }
276 case TOKVER_CLEAR_KEY: {
277 struct clearkeytoken *t = (struct clearkeytoken *)key;
278 u32 keysize = 0;
279
280 if (keylen < sizeof(struct clearkeytoken) ||
281 keylen != sizeof(*t) + t->len)
282 goto out;
283 switch (t->keytype) {
284 case PKEY_KEYTYPE_AES_128:
285 case PKEY_KEYTYPE_AES_192:
286 case PKEY_KEYTYPE_AES_256:
287 keysize = pkey_keytype_aes_to_size(t->keytype);
288 break;
289 case PKEY_KEYTYPE_ECC_P256:
290 keysize = 32;
291 break;
292 case PKEY_KEYTYPE_ECC_P384:
293 keysize = 48;
294 break;
295 case PKEY_KEYTYPE_ECC_P521:
296 keysize = 80;
297 break;
298 case PKEY_KEYTYPE_ECC_ED25519:
299 keysize = 32;
300 break;
301 case PKEY_KEYTYPE_ECC_ED448:
302 keysize = 64;
303 break;
304 default:
305 break;
306 }
307 if (!keysize) {
308 PKEY_DBF_ERR("%s clear key token: unknown keytype %u\n",
309 __func__, t->keytype);
310 goto out;
311 }
312 if (t->len != keysize) {
313 PKEY_DBF_ERR("%s clear key token: invalid key len %u\n",
314 __func__, t->len);
315 goto out;
316 }
317 rc = pckmo_clr2protkey(t->keytype, t->clearkey, t->len,
318 protkey, protkeylen, protkeytype);
319 break;
320 }
321 default:
322 PKEY_DBF_ERR("%s unknown non-CCA token version %d\n",
323 __func__, hdr->version);
324 break;
325 }
326
327out:
328 pr_debug("rc=%d\n", rc);
329 return rc;
330}
331
332/*
333 * Generate a random protected key.
334 * Currently only the generation of AES protected keys
335 * is supported.
336 */
337static int pckmo_gen_protkey(u32 keytype, u32 subtype,
338 u8 *protkey, u32 *protkeylen, u32 *protkeytype)
339{
340 u8 clrkey[32];
341 int keysize;
342 int rc;
343
344 keysize = pkey_keytype_aes_to_size(keytype);
345 if (!keysize) {
346 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", __func__,
347 keytype);
348 return -EINVAL;
349 }
350 if (subtype != PKEY_TYPE_PROTKEY) {
351 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
352 __func__, subtype);
353 return -EINVAL;
354 }
355
356 /* generate a dummy random clear key */
357 get_random_bytes(clrkey, keysize);
358
359 /* convert it to a dummy protected key */
360 rc = pckmo_clr2protkey(keytype, clrkey, keysize,
361 protkey, protkeylen, protkeytype);
362 if (rc)
363 goto out;
364
365 /* replace the key part of the protected key with random bytes */
366 get_random_bytes(protkey, keysize);
367
368out:
369 pr_debug("rc=%d\n", rc);
370 return rc;
371}
372
373/*
374 * Verify a protected key token blob.
375 * Currently only AES protected keys are supported.
376 */
377static int pckmo_verify_key(const u8 *key, u32 keylen)
378{
379 struct keytoken_header *hdr = (struct keytoken_header *)key;
380 int rc = -EINVAL;
381
382 if (keylen < sizeof(*hdr))
383 return -EINVAL;
384 if (hdr->type != TOKTYPE_NON_CCA)
385 return -EINVAL;
386
387 switch (hdr->version) {
388 case TOKVER_PROTECTED_KEY: {
389 struct protaeskeytoken *t;
390
391 if (keylen != sizeof(struct protaeskeytoken))
392 goto out;
393 t = (struct protaeskeytoken *)key;
394 rc = pckmo_verify_protkey(t->protkey, t->len, t->keytype);
395 break;
396 }
397 default:
398 PKEY_DBF_ERR("%s unknown non-CCA token version %d\n",
399 __func__, hdr->version);
400 break;
401 }
402
403out:
404 pr_debug("rc=%d\n", rc);
405 return rc;
406}
407
408/*
409 * Wrapper functions used for the pkey handler struct
410 */
411
412static int pkey_pckmo_key2protkey(const struct pkey_apqn *_apqns,
413 size_t _nr_apqns,
414 const u8 *key, u32 keylen,
415 u8 *protkey, u32 *protkeylen, u32 *keyinfo)
416{
417 return pckmo_key2protkey(key, keylen,
418 protkey, protkeylen, keyinfo);
419}
420
421static int pkey_pckmo_gen_key(const struct pkey_apqn *_apqns, size_t _nr_apqns,
422 u32 keytype, u32 keysubtype,
423 u32 _keybitsize, u32 _flags,
424 u8 *keybuf, u32 *keybuflen, u32 *keyinfo)
425{
426 return pckmo_gen_protkey(keytype, keysubtype,
427 keybuf, keybuflen, keyinfo);
428}
429
430static int pkey_pckmo_verifykey(const u8 *key, u32 keylen,
431 u16 *_card, u16 *_dom,
432 u32 *_keytype, u32 *_keybitsize, u32 *_flags)
433{
434 return pckmo_verify_key(key, keylen);
435}
436
437static struct pkey_handler pckmo_handler = {
438 .module = THIS_MODULE,
439 .name = "PKEY PCKMO handler",
440 .is_supported_key = is_pckmo_key,
441 .is_supported_keytype = is_pckmo_keytype,
442 .key_to_protkey = pkey_pckmo_key2protkey,
443 .gen_key = pkey_pckmo_gen_key,
444 .verify_key = pkey_pckmo_verifykey,
445};
446
447/*
448 * Module init
449 */
450static int __init pkey_pckmo_init(void)
451{
452 cpacf_mask_t func_mask;
453
454 /*
455 * The pckmo instruction should be available - even if we don't
456 * actually invoke it. This instruction comes with MSA 3 which
457 * is also the minimum level for the kmc instructions which
458 * are able to work with protected keys.
459 */
460 if (!cpacf_query(CPACF_PCKMO, &func_mask))
461 return -ENODEV;
462
463 /* register this module as pkey handler for all the pckmo stuff */
464 return pkey_handler_register(&pckmo_handler);
465}
466
467/*
468 * Module exit
469 */
470static void __exit pkey_pckmo_exit(void)
471{
472 /* unregister this module as pkey handler */
473 pkey_handler_unregister(&pckmo_handler);
474}
475
476module_cpu_feature_match(S390_CPU_FEATURE_MSA, pkey_pckmo_init);
477module_exit(pkey_pckmo_exit);