pkey_cca.c (ea88e1710a9f19345c94c195f9cd7365e50343b0) pkey_cca.c (8fcc231ce3bea12b78bb94b280cdc03cff342435)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * pkey cca 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 cca 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>
14
11#include "zcrypt_api.h"
12#include "zcrypt_ccamisc.h"
15#include "zcrypt_api.h"
16#include "zcrypt_ccamisc.h"
13
14#include "pkey_base.h"
15
17#include "pkey_base.h"
18
19MODULE_LICENSE("GPL");
20MODULE_AUTHOR("IBM Corporation");
21MODULE_DESCRIPTION("s390 protected key CCA handler");
22
23#if IS_MODULE(CONFIG_PKEY_CCA)
24static struct ap_device_id pkey_cca_card_ids[] = {
25 { .dev_type = AP_DEVICE_TYPE_CEX4 },
26 { .dev_type = AP_DEVICE_TYPE_CEX5 },
27 { .dev_type = AP_DEVICE_TYPE_CEX6 },
28 { .dev_type = AP_DEVICE_TYPE_CEX7 },
29 { .dev_type = AP_DEVICE_TYPE_CEX8 },
30 { /* end of list */ },
31};
32MODULE_DEVICE_TABLE(ap, pkey_cca_card_ids);
33#endif
34
16/*
17 * Check key blob for known and supported CCA key.
18 */
35/*
36 * Check key blob for known and supported CCA key.
37 */
19bool pkey_is_cca_key(const u8 *key, u32 keylen)
38static bool is_cca_key(const u8 *key, u32 keylen)
20{
21 struct keytoken_header *hdr = (struct keytoken_header *)key;
22
23 if (keylen < sizeof(*hdr))
24 return false;
25
26 switch (hdr->type) {
27 case TOKTYPE_CCA_INTERNAL:

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

34 }
35 case TOKTYPE_CCA_INTERNAL_PKA:
36 return true;
37 default:
38 return false;
39 }
40}
41
39{
40 struct keytoken_header *hdr = (struct keytoken_header *)key;
41
42 if (keylen < sizeof(*hdr))
43 return false;
44
45 switch (hdr->type) {
46 case TOKTYPE_CCA_INTERNAL:

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

53 }
54 case TOKTYPE_CCA_INTERNAL_PKA:
55 return true;
56 default:
57 return false;
58 }
59}
60
42bool pkey_is_cca_keytype(enum pkey_key_type key_type)
61static bool is_cca_keytype(enum pkey_key_type key_type)
43{
44 switch (key_type) {
45 case PKEY_TYPE_CCA_DATA:
46 case PKEY_TYPE_CCA_CIPHER:
47 case PKEY_TYPE_CCA_ECC:
48 return true;
49 default:
50 return false;
51 }
52}
53
62{
63 switch (key_type) {
64 case PKEY_TYPE_CCA_DATA:
65 case PKEY_TYPE_CCA_CIPHER:
66 case PKEY_TYPE_CCA_ECC:
67 return true;
68 default:
69 return false;
70 }
71}
72
54int pkey_cca_key2protkey(u16 card, u16 dom,
55 const u8 *key, u32 keylen,
56 u8 *protkey, u32 *protkeylen, u32 *protkeytype)
73static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
74 struct pkey_apqn *apqns, size_t *nr_apqns)
57{
58 struct keytoken_header *hdr = (struct keytoken_header *)key;
75{
76 struct keytoken_header *hdr = (struct keytoken_header *)key;
77 u32 _nr_apqns, *_apqns = NULL;
59 int rc;
60
78 int rc;
79
61 if (keylen < sizeof(*hdr))
80 if (!flags)
81 flags = PKEY_FLAGS_MATCH_CUR_MKVP | PKEY_FLAGS_MATCH_ALT_MKVP;
82
83 if (keylen < sizeof(struct keytoken_header))
62 return -EINVAL;
63
64 zcrypt_wait_api_operational();
65
84 return -EINVAL;
85
86 zcrypt_wait_api_operational();
87
88 if (hdr->type == TOKTYPE_CCA_INTERNAL) {
89 u64 cur_mkvp = 0, old_mkvp = 0;
90 int minhwtype = ZCRYPT_CEX3C;
91
92 if (hdr->version == TOKVER_CCA_AES) {
93 struct secaeskeytoken *t = (struct secaeskeytoken *)key;
94
95 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
96 cur_mkvp = t->mkvp;
97 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
98 old_mkvp = t->mkvp;
99 } else if (hdr->version == TOKVER_CCA_VLSC) {
100 struct cipherkeytoken *t = (struct cipherkeytoken *)key;
101
102 minhwtype = ZCRYPT_CEX6;
103 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
104 cur_mkvp = t->mkvp0;
105 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
106 old_mkvp = t->mkvp0;
107 } else {
108 /* unknown CCA internal token type */
109 return -EINVAL;
110 }
111 rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
112 minhwtype, AES_MK_SET,
113 cur_mkvp, old_mkvp, 1);
114 if (rc)
115 goto out;
116
117 } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) {
118 struct eccprivkeytoken *t = (struct eccprivkeytoken *)key;
119 u64 cur_mkvp = 0, old_mkvp = 0;
120
121 if (t->secid == 0x20) {
122 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
123 cur_mkvp = t->mkvp;
124 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
125 old_mkvp = t->mkvp;
126 } else {
127 /* unknown CCA internal 2 token type */
128 return -EINVAL;
129 }
130 rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
131 ZCRYPT_CEX7, APKA_MK_SET,
132 cur_mkvp, old_mkvp, 1);
133 if (rc)
134 goto out;
135
136 } else {
137 PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",
138 __func__, hdr->type, hdr->version);
139 return -EINVAL;
140 }
141
142 if (apqns) {
143 if (*nr_apqns < _nr_apqns)
144 rc = -ENOSPC;
145 else
146 memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));
147 }
148 *nr_apqns = _nr_apqns;
149
150out:
151 kfree(_apqns);
152 pr_debug("rc=%d\n", rc);
153 return rc;
154}
155
156static int cca_apqns4type(enum pkey_key_type ktype,
157 u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
158 struct pkey_apqn *apqns, size_t *nr_apqns)
159{
160 u32 _nr_apqns, *_apqns = NULL;
161 int rc;
162
163 zcrypt_wait_api_operational();
164
165 if (ktype == PKEY_TYPE_CCA_DATA || ktype == PKEY_TYPE_CCA_CIPHER) {
166 u64 cur_mkvp = 0, old_mkvp = 0;
167 int minhwtype = ZCRYPT_CEX3C;
168
169 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
170 cur_mkvp = *((u64 *)cur_mkvp);
171 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
172 old_mkvp = *((u64 *)alt_mkvp);
173 if (ktype == PKEY_TYPE_CCA_CIPHER)
174 minhwtype = ZCRYPT_CEX6;
175 rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
176 minhwtype, AES_MK_SET,
177 cur_mkvp, old_mkvp, 1);
178 if (rc)
179 goto out;
180
181 } else if (ktype == PKEY_TYPE_CCA_ECC) {
182 u64 cur_mkvp = 0, old_mkvp = 0;
183
184 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
185 cur_mkvp = *((u64 *)cur_mkvp);
186 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
187 old_mkvp = *((u64 *)alt_mkvp);
188 rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
189 ZCRYPT_CEX7, APKA_MK_SET,
190 cur_mkvp, old_mkvp, 1);
191 if (rc)
192 goto out;
193
194 } else {
195 PKEY_DBF_ERR("%s unknown/unsupported key type %d",
196 __func__, (int)ktype);
197 return -EINVAL;
198 }
199
200 if (apqns) {
201 if (*nr_apqns < _nr_apqns)
202 rc = -ENOSPC;
203 else
204 memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));
205 }
206 *nr_apqns = _nr_apqns;
207
208out:
209 kfree(_apqns);
210 pr_debug("rc=%d\n", rc);
211 return rc;
212}
213
214static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
215 const u8 *key, u32 keylen,
216 u8 *protkey, u32 *protkeylen, u32 *protkeytype)
217{
218 struct keytoken_header *hdr = (struct keytoken_header *)key;
219 struct pkey_apqn *local_apqns = NULL;
220 int i, rc;
221
222 if (keylen < sizeof(*hdr))
223 return -EINVAL;
224
66 if (hdr->type == TOKTYPE_CCA_INTERNAL &&
67 hdr->version == TOKVER_CCA_AES) {
68 /* CCA AES data key */
69 if (keylen != sizeof(struct secaeskeytoken))
70 return -EINVAL;
71 if (cca_check_secaeskeytoken(pkey_dbf_info, 3, key, 0))
72 return -EINVAL;
225 if (hdr->type == TOKTYPE_CCA_INTERNAL &&
226 hdr->version == TOKVER_CCA_AES) {
227 /* CCA AES data key */
228 if (keylen != sizeof(struct secaeskeytoken))
229 return -EINVAL;
230 if (cca_check_secaeskeytoken(pkey_dbf_info, 3, key, 0))
231 return -EINVAL;
73 rc = cca_sec2protkey(card, dom, key, protkey,
74 protkeylen, protkeytype);
75 } else if (hdr->type == TOKTYPE_CCA_INTERNAL &&
76 hdr->version == TOKVER_CCA_VLSC) {
77 /* CCA AES cipher key */
78 if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE)
79 return -EINVAL;
80 if (cca_check_secaescipherkey(pkey_dbf_info,
81 3, key, 0, 1))
82 return -EINVAL;
232 } else if (hdr->type == TOKTYPE_CCA_INTERNAL &&
233 hdr->version == TOKVER_CCA_VLSC) {
234 /* CCA AES cipher key */
235 if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE)
236 return -EINVAL;
237 if (cca_check_secaescipherkey(pkey_dbf_info,
238 3, key, 0, 1))
239 return -EINVAL;
83 rc = cca_cipher2protkey(card, dom, key, protkey,
84 protkeylen, protkeytype);
85 } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) {
86 /* CCA ECC (private) key */
87 if (keylen < sizeof(struct eccprivkeytoken))
88 return -EINVAL;
89 if (cca_check_sececckeytoken(pkey_dbf_info, 3, key, keylen, 1))
90 return -EINVAL;
240 } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) {
241 /* CCA ECC (private) key */
242 if (keylen < sizeof(struct eccprivkeytoken))
243 return -EINVAL;
244 if (cca_check_sececckeytoken(pkey_dbf_info, 3, key, keylen, 1))
245 return -EINVAL;
91 rc = cca_ecc2protkey(card, dom, key, protkey,
92 protkeylen, protkeytype);
93 } else {
94 PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",
95 __func__, hdr->type, hdr->version);
246 } else {
247 PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",
248 __func__, hdr->type, hdr->version);
96 rc = -EINVAL;
249 return -EINVAL;
97 }
98
250 }
251
99 pr_debug("card=%d dom=%d rc=%d\n", card, dom, rc);
252 zcrypt_wait_api_operational();
253
254 if (!apqns || (nr_apqns == 1 &&
255 apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
256 nr_apqns = MAXAPQNSINLIST;
257 local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
258 GFP_KERNEL);
259 if (!local_apqns)
260 return -ENOMEM;
261 rc = cca_apqns4key(key, keylen, 0, local_apqns, &nr_apqns);
262 if (rc)
263 goto out;
264 apqns = local_apqns;
265 }
266
267 for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
268 if (hdr->type == TOKTYPE_CCA_INTERNAL &&
269 hdr->version == TOKVER_CCA_AES) {
270 rc = cca_sec2protkey(apqns[i].card, apqns[i].domain,
271 key, protkey,
272 protkeylen, protkeytype);
273 } else if (hdr->type == TOKTYPE_CCA_INTERNAL &&
274 hdr->version == TOKVER_CCA_VLSC) {
275 rc = cca_cipher2protkey(apqns[i].card, apqns[i].domain,
276 key, protkey,
277 protkeylen, protkeytype);
278 } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) {
279 rc = cca_ecc2protkey(apqns[i].card, apqns[i].domain,
280 key, protkey,
281 protkeylen, protkeytype);
282 } else {
283 rc = -EINVAL;
284 break;
285 }
286 }
287
288out:
289 kfree(local_apqns);
290 pr_debug("rc=%d\n", rc);
100 return rc;
101}
102
103/*
104 * Generate CCA secure key.
105 * As of now only CCA AES Data or Cipher secure keys are
106 * supported.
107 * keytype is one of the PKEY_KEYTYPE_* constants,
108 * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER,
109 * keybitsize is the bit size of the key (may be 0 for
110 * keytype PKEY_KEYTYPE_AES_*).
111 */
291 return rc;
292}
293
294/*
295 * Generate CCA secure key.
296 * As of now only CCA AES Data or Cipher secure keys are
297 * supported.
298 * keytype is one of the PKEY_KEYTYPE_* constants,
299 * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER,
300 * keybitsize is the bit size of the key (may be 0 for
301 * keytype PKEY_KEYTYPE_AES_*).
302 */
112int pkey_cca_gen_key(u16 card, u16 dom,
113 u32 keytype, u32 subtype,
114 u32 keybitsize, u32 flags,
115 u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
303static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
304 u32 keytype, u32 subtype,
305 u32 keybitsize, u32 flags,
306 u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
116{
307{
117 int len, rc;
308 struct pkey_apqn *local_apqns = NULL;
309 int i, len, rc;
118
119 /* check keytype, subtype, keybitsize */
120 switch (keytype) {
121 case PKEY_KEYTYPE_AES_128:
122 case PKEY_KEYTYPE_AES_192:
123 case PKEY_KEYTYPE_AES_256:
124 len = pkey_keytype_aes_to_size(keytype);
125 if (keybitsize && keybitsize != 8 * len) {
126 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
127 __func__, keybitsize);
128 return -EINVAL;
129 }
130 keybitsize = 8 * len;
131 switch (subtype) {
310
311 /* check keytype, subtype, keybitsize */
312 switch (keytype) {
313 case PKEY_KEYTYPE_AES_128:
314 case PKEY_KEYTYPE_AES_192:
315 case PKEY_KEYTYPE_AES_256:
316 len = pkey_keytype_aes_to_size(keytype);
317 if (keybitsize && keybitsize != 8 * len) {
318 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
319 __func__, keybitsize);
320 return -EINVAL;
321 }
322 keybitsize = 8 * len;
323 switch (subtype) {
132 case 0:
133 case PKEY_TYPE_CCA_DATA:
134 case PKEY_TYPE_CCA_CIPHER:
135 break;
136 default:
137 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
138 __func__, subtype);
139 return -EINVAL;
140 }
141 break;
142 default:
143 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
144 __func__, keytype);
145 return -EINVAL;
146 }
147
148 zcrypt_wait_api_operational();
149
324 case PKEY_TYPE_CCA_DATA:
325 case PKEY_TYPE_CCA_CIPHER:
326 break;
327 default:
328 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
329 __func__, subtype);
330 return -EINVAL;
331 }
332 break;
333 default:
334 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
335 __func__, keytype);
336 return -EINVAL;
337 }
338
339 zcrypt_wait_api_operational();
340
150 if (subtype == PKEY_TYPE_CCA_CIPHER) {
151 rc = cca_gencipherkey(card, dom, keybitsize, flags,
152 keybuf, keybuflen);
153 } else {
154 /* 0 or PKEY_TYPE_CCA_DATA */
155 rc = cca_genseckey(card, dom, keybitsize, keybuf);
156 *keybuflen = (rc ? 0 : SECKEYBLOBSIZE);
341 if (!apqns || (nr_apqns == 1 &&
342 apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
343 nr_apqns = MAXAPQNSINLIST;
344 local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
345 GFP_KERNEL);
346 if (!local_apqns)
347 return -ENOMEM;
348 rc = cca_apqns4type(subtype, NULL, NULL, 0,
349 local_apqns, &nr_apqns);
350 if (rc)
351 goto out;
352 apqns = local_apqns;
157 }
158
353 }
354
159 pr_debug("card=%d dom=%d rc=%d\n", card, dom, rc);
355 for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
356 if (subtype == PKEY_TYPE_CCA_CIPHER) {
357 rc = cca_gencipherkey(apqns[i].card, apqns[i].domain,
358 keybitsize, flags,
359 keybuf, keybuflen);
360 } else {
361 /* PKEY_TYPE_CCA_DATA */
362 rc = cca_genseckey(apqns[i].card, apqns[i].domain,
363 keybitsize, keybuf);
364 *keybuflen = (rc ? 0 : SECKEYBLOBSIZE);
365 }
366 }
367
368out:
369 kfree(local_apqns);
370 pr_debug("rc=%d\n", rc);
160 return rc;
161}
162
163/*
164 * Generate CCA secure key with given clear key value.
165 * As of now only CCA AES Data or Cipher secure keys are
166 * supported.
167 * keytype is one of the PKEY_KEYTYPE_* constants,
168 * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER,
169 * keybitsize is the bit size of the key (may be 0 for
170 * keytype PKEY_KEYTYPE_AES_*).
171 */
371 return rc;
372}
373
374/*
375 * Generate CCA secure key with given clear key value.
376 * As of now only CCA AES Data or Cipher secure keys are
377 * supported.
378 * keytype is one of the PKEY_KEYTYPE_* constants,
379 * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER,
380 * keybitsize is the bit size of the key (may be 0 for
381 * keytype PKEY_KEYTYPE_AES_*).
382 */
172int pkey_cca_clr2key(u16 card, u16 dom,
173 u32 keytype, u32 subtype,
174 u32 keybitsize, u32 flags,
175 const u8 *clrkey, u32 clrkeylen,
176 u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
383static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
384 u32 keytype, u32 subtype,
385 u32 keybitsize, u32 flags,
386 const u8 *clrkey, u32 clrkeylen,
387 u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
177{
388{
178 int len, rc;
389 struct pkey_apqn *local_apqns = NULL;
390 int i, len, rc;
179
180 /* check keytype, subtype, clrkeylen, keybitsize */
181 switch (keytype) {
182 case PKEY_KEYTYPE_AES_128:
183 case PKEY_KEYTYPE_AES_192:
184 case PKEY_KEYTYPE_AES_256:
185 len = pkey_keytype_aes_to_size(keytype);
186 if (keybitsize && keybitsize != 8 * len) {
187 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
188 __func__, keybitsize);
189 return -EINVAL;
190 }
191 keybitsize = 8 * len;
192 if (clrkeylen != len) {
193 PKEY_DBF_ERR("%s invalid clear key len %d != %d\n",
194 __func__, clrkeylen, len);
195 return -EINVAL;
196 }
197 switch (subtype) {
391
392 /* check keytype, subtype, clrkeylen, keybitsize */
393 switch (keytype) {
394 case PKEY_KEYTYPE_AES_128:
395 case PKEY_KEYTYPE_AES_192:
396 case PKEY_KEYTYPE_AES_256:
397 len = pkey_keytype_aes_to_size(keytype);
398 if (keybitsize && keybitsize != 8 * len) {
399 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
400 __func__, keybitsize);
401 return -EINVAL;
402 }
403 keybitsize = 8 * len;
404 if (clrkeylen != len) {
405 PKEY_DBF_ERR("%s invalid clear key len %d != %d\n",
406 __func__, clrkeylen, len);
407 return -EINVAL;
408 }
409 switch (subtype) {
198 case 0:
199 case PKEY_TYPE_CCA_DATA:
200 case PKEY_TYPE_CCA_CIPHER:
201 break;
202 default:
203 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
204 __func__, subtype);
205 return -EINVAL;
206 }
207 break;
208 default:
209 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
210 __func__, keytype);
211 return -EINVAL;
212 }
213
214 zcrypt_wait_api_operational();
215
410 case PKEY_TYPE_CCA_DATA:
411 case PKEY_TYPE_CCA_CIPHER:
412 break;
413 default:
414 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
415 __func__, subtype);
416 return -EINVAL;
417 }
418 break;
419 default:
420 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
421 __func__, keytype);
422 return -EINVAL;
423 }
424
425 zcrypt_wait_api_operational();
426
216 if (subtype == PKEY_TYPE_CCA_CIPHER) {
217 rc = cca_clr2cipherkey(card, dom, keybitsize,
218 flags, clrkey, keybuf, keybuflen);
219 } else {
220 /* 0 or PKEY_TYPE_CCA_DATA */
221 rc = cca_clr2seckey(card, dom, keybitsize,
222 clrkey, keybuf);
223 *keybuflen = (rc ? 0 : SECKEYBLOBSIZE);
427 if (!apqns || (nr_apqns == 1 &&
428 apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
429 nr_apqns = MAXAPQNSINLIST;
430 local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
431 GFP_KERNEL);
432 if (!local_apqns)
433 return -ENOMEM;
434 rc = cca_apqns4type(subtype, NULL, NULL, 0,
435 local_apqns, &nr_apqns);
436 if (rc)
437 goto out;
438 apqns = local_apqns;
224 }
225
439 }
440
226 pr_debug("card=%d dom=%d rc=%d\n", card, dom, rc);
441 for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
442 if (subtype == PKEY_TYPE_CCA_CIPHER) {
443 rc = cca_clr2cipherkey(apqns[i].card, apqns[i].domain,
444 keybitsize, flags, clrkey,
445 keybuf, keybuflen);
446 } else {
447 /* PKEY_TYPE_CCA_DATA */
448 rc = cca_clr2seckey(apqns[i].card, apqns[i].domain,
449 keybitsize, clrkey, keybuf);
450 *keybuflen = (rc ? 0 : SECKEYBLOBSIZE);
451 }
452 }
453
454out:
455 kfree(local_apqns);
456 pr_debug("rc=%d\n", rc);
227 return rc;
228}
229
457 return rc;
458}
459
230int pkey_cca_verifykey(const u8 *key, u32 keylen,
231 u16 *card, u16 *dom,
232 u32 *keytype, u32 *keybitsize, u32 *flags)
460static int cca_verifykey(const u8 *key, u32 keylen,
461 u16 *card, u16 *dom,
462 u32 *keytype, u32 *keybitsize, u32 *flags)
233{
234 struct keytoken_header *hdr = (struct keytoken_header *)key;
235 u32 nr_apqns, *apqns = NULL;
236 int rc;
237
238 if (keylen < sizeof(*hdr))
239 return -EINVAL;
240

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

306 }
307
308out:
309 kfree(apqns);
310 pr_debug("rc=%d\n", rc);
311 return rc;
312}
313
463{
464 struct keytoken_header *hdr = (struct keytoken_header *)key;
465 u32 nr_apqns, *apqns = NULL;
466 int rc;
467
468 if (keylen < sizeof(*hdr))
469 return -EINVAL;
470

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

536 }
537
538out:
539 kfree(apqns);
540 pr_debug("rc=%d\n", rc);
541 return rc;
542}
543
314int pkey_cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
315 struct pkey_apqn *apqns, size_t *nr_apqns)
316{
317 struct keytoken_header *hdr = (struct keytoken_header *)key;
318 u32 _nr_apqns, *_apqns = NULL;
319 int rc;
544static struct pkey_handler cca_handler = {
545 .module = THIS_MODULE,
546 .name = "PKEY CCA handler",
547 .is_supported_key = is_cca_key,
548 .is_supported_keytype = is_cca_keytype,
549 .key_to_protkey = cca_key2protkey,
550 .gen_key = cca_gen_key,
551 .clr_to_key = cca_clr2key,
552 .verify_key = cca_verifykey,
553 .apqns_for_key = cca_apqns4key,
554 .apqns_for_keytype = cca_apqns4type,
555};
320
556
321 if (!flags)
322 flags = PKEY_FLAGS_MATCH_CUR_MKVP | PKEY_FLAGS_MATCH_ALT_MKVP;
323
324 if (keylen < sizeof(struct keytoken_header))
325 return -EINVAL;
326
327 zcrypt_wait_api_operational();
328
329 if (hdr->type == TOKTYPE_CCA_INTERNAL) {
330 u64 cur_mkvp = 0, old_mkvp = 0;
331 int minhwtype = ZCRYPT_CEX3C;
332
333 if (hdr->version == TOKVER_CCA_AES) {
334 struct secaeskeytoken *t = (struct secaeskeytoken *)key;
335
336 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
337 cur_mkvp = t->mkvp;
338 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
339 old_mkvp = t->mkvp;
340 } else if (hdr->version == TOKVER_CCA_VLSC) {
341 struct cipherkeytoken *t = (struct cipherkeytoken *)key;
342
343 minhwtype = ZCRYPT_CEX6;
344 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
345 cur_mkvp = t->mkvp0;
346 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
347 old_mkvp = t->mkvp0;
348 } else {
349 /* unknown CCA internal token type */
350 return -EINVAL;
351 }
352 rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
353 minhwtype, AES_MK_SET,
354 cur_mkvp, old_mkvp, 1);
355 if (rc)
356 goto out;
357
358 } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) {
359 struct eccprivkeytoken *t = (struct eccprivkeytoken *)key;
360 u64 cur_mkvp = 0, old_mkvp = 0;
361
362 if (t->secid == 0x20) {
363 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
364 cur_mkvp = t->mkvp;
365 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
366 old_mkvp = t->mkvp;
367 } else {
368 /* unknown CCA internal 2 token type */
369 return -EINVAL;
370 }
371 rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
372 ZCRYPT_CEX7, APKA_MK_SET,
373 cur_mkvp, old_mkvp, 1);
374 if (rc)
375 goto out;
376
377 } else {
378 PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",
379 __func__, hdr->type, hdr->version);
380 return -EINVAL;
381 }
382
383 if (apqns) {
384 if (*nr_apqns < _nr_apqns)
385 rc = -ENOSPC;
386 else
387 memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));
388 }
389 *nr_apqns = _nr_apqns;
390
391out:
392 kfree(_apqns);
393 pr_debug("rc=%d\n", rc);
394 return rc;
557/*
558 * Module init
559 */
560static int __init pkey_cca_init(void)
561{
562 /* register this module as pkey handler for all the cca stuff */
563 return pkey_handler_register(&cca_handler);
395}
396
564}
565
397int pkey_cca_apqns4type(enum pkey_key_type ktype,
398 u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
399 struct pkey_apqn *apqns, size_t *nr_apqns)
566/*
567 * Module exit
568 */
569static void __exit pkey_cca_exit(void)
400{
570{
401 u32 _nr_apqns, *_apqns = NULL;
402 int rc;
403
404 zcrypt_wait_api_operational();
405
406 if (ktype == PKEY_TYPE_CCA_DATA || ktype == PKEY_TYPE_CCA_CIPHER) {
407 u64 cur_mkvp = 0, old_mkvp = 0;
408 int minhwtype = ZCRYPT_CEX3C;
409
410 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
411 cur_mkvp = *((u64 *)cur_mkvp);
412 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
413 old_mkvp = *((u64 *)alt_mkvp);
414 if (ktype == PKEY_TYPE_CCA_CIPHER)
415 minhwtype = ZCRYPT_CEX6;
416 rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
417 minhwtype, AES_MK_SET,
418 cur_mkvp, old_mkvp, 1);
419 if (rc)
420 goto out;
421
422 } else if (ktype == PKEY_TYPE_CCA_ECC) {
423 u64 cur_mkvp = 0, old_mkvp = 0;
424
425 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
426 cur_mkvp = *((u64 *)cur_mkvp);
427 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
428 old_mkvp = *((u64 *)alt_mkvp);
429 rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
430 ZCRYPT_CEX7, APKA_MK_SET,
431 cur_mkvp, old_mkvp, 1);
432 if (rc)
433 goto out;
434
435 } else {
436 PKEY_DBF_ERR("%s unknown/unsupported key type %d",
437 __func__, (int)ktype);
438 return -EINVAL;
439 }
440
441 if (apqns) {
442 if (*nr_apqns < _nr_apqns)
443 rc = -ENOSPC;
444 else
445 memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));
446 }
447 *nr_apqns = _nr_apqns;
448
449out:
450 kfree(_apqns);
451 pr_debug("rc=%d\n", rc);
452 return rc;
571 /* unregister this module as pkey handler */
572 pkey_handler_unregister(&cca_handler);
453}
573}
574
575module_init(pkey_cca_init);
576module_exit(pkey_cca_exit);