File Index
Files and directories
Sign in
FILE

pkey_sysfs.c

File preview with syntax highlighting.

linux-6.19.14/drivers/s390/crypto/pkey_sysfs.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 *  pkey module sysfs related functions
  4 *
  5 *  Copyright IBM Corp. 2024
  6 */
  7
  8#define pr_fmt(fmt) "pkey: " fmt
  9
 10#include <linux/sysfs.h>
 11
 12#include "zcrypt_ccamisc.h"
 13#include "zcrypt_ep11misc.h"
 14
 15#include "pkey_base.h"
 16
 17/*
 18 * Wrapper around pkey_handler_gen_key() which deals with the
 19 * ENODEV return code and then tries to enforce a pkey handler
 20 * module load.
 21 */
 22static int sys_pkey_handler_gen_key(u32 keytype, u32 keysubtype,
 23				    u32 keybitsize, u32 flags,
 24				    u8 *keybuf, u32 *keybuflen, u32 *keyinfo)
 25{
 26	int rc;
 27
 28	rc = pkey_handler_gen_key(NULL, 0,
 29				  keytype, keysubtype,
 30				  keybitsize, flags,
 31				  keybuf, keybuflen, keyinfo, 0);
 32	if (rc == -ENODEV) {
 33		pkey_handler_request_modules();
 34		rc = pkey_handler_gen_key(NULL, 0,
 35					  keytype, keysubtype,
 36					  keybitsize, flags,
 37					  keybuf, keybuflen, keyinfo, 0);
 38	}
 39
 40	return rc;
 41}
 42
 43/*
 44 * Sysfs attribute read function for all protected key binary attributes.
 45 * The implementation can not deal with partial reads, because a new random
 46 * protected key blob is generated with each read. In case of partial reads
 47 * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
 48 */
 49static ssize_t pkey_protkey_aes_attr_read(u32 keytype, bool is_xts, char *buf,
 50					  loff_t off, size_t count)
 51{
 52	struct protaeskeytoken protkeytoken;
 53	struct pkey_protkey protkey;
 54	int rc;
 55
 56	if (off != 0 || count < sizeof(protkeytoken))
 57		return -EINVAL;
 58	if (is_xts)
 59		if (count < 2 * sizeof(protkeytoken))
 60			return -EINVAL;
 61
 62	memset(&protkeytoken, 0, sizeof(protkeytoken));
 63	protkeytoken.type = TOKTYPE_NON_CCA;
 64	protkeytoken.version = TOKVER_PROTECTED_KEY;
 65	protkeytoken.keytype = keytype;
 66
 67	protkey.len = sizeof(protkey.protkey);
 68	rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_PROTKEY, 0, 0,
 69				      protkey.protkey, &protkey.len,
 70				      &protkey.type);
 71	if (rc)
 72		return rc;
 73
 74	protkeytoken.len = protkey.len;
 75	memcpy(&protkeytoken.protkey, &protkey.protkey, protkey.len);
 76
 77	memcpy(buf, &protkeytoken, sizeof(protkeytoken));
 78
 79	if (is_xts) {
 80		/* xts needs a second protected key, reuse protkey struct */
 81		protkey.len = sizeof(protkey.protkey);
 82		rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_PROTKEY, 0, 0,
 83					      protkey.protkey, &protkey.len,
 84					      &protkey.type);
 85		if (rc)
 86			return rc;
 87
 88		protkeytoken.len = protkey.len;
 89		memcpy(&protkeytoken.protkey, &protkey.protkey, protkey.len);
 90
 91		memcpy(buf + sizeof(protkeytoken), &protkeytoken,
 92		       sizeof(protkeytoken));
 93
 94		return 2 * sizeof(protkeytoken);
 95	}
 96
 97	return sizeof(protkeytoken);
 98}
 99
100/*
101 * Sysfs attribute read function for the AES XTS prot key binary attributes.
102 * The implementation can not deal with partial reads, because a new random
103 * protected key blob is generated with each read. In case of partial reads
104 * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
105 */
106static ssize_t pkey_protkey_aes_xts_attr_read(u32 keytype, char *buf,
107					      loff_t off, size_t count)
108{
109	struct protkeytoken *t = (struct protkeytoken *)buf;
110	u32 protlen, prottype;
111	int rc;
112
113	switch (keytype) {
114	case PKEY_KEYTYPE_AES_XTS_128:
115		protlen = 64;
116		break;
117	case PKEY_KEYTYPE_AES_XTS_256:
118		protlen = 96;
119		break;
120	default:
121		return -EINVAL;
122	}
123
124	if (off != 0 || count < sizeof(*t) + protlen)
125		return -EINVAL;
126
127	memset(t, 0, sizeof(*t) + protlen);
128	t->type = TOKTYPE_NON_CCA;
129	t->version = TOKVER_PROTECTED_KEY;
130	t->keytype = keytype;
131
132	rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_PROTKEY, 0, 0,
133				      t->protkey, &protlen, &prottype);
134	if (rc)
135		return rc;
136
137	t->len = protlen;
138
139	return sizeof(*t) + protlen;
140}
141
142/*
143 * Sysfs attribute read function for the HMAC prot key binary attributes.
144 * The implementation can not deal with partial reads, because a new random
145 * protected key blob is generated with each read. In case of partial reads
146 * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
147 */
148static ssize_t pkey_protkey_hmac_attr_read(u32 keytype, char *buf,
149					   loff_t off, size_t count)
150{
151	struct protkeytoken *t = (struct protkeytoken *)buf;
152	u32 protlen, prottype;
153	int rc;
154
155	switch (keytype) {
156	case PKEY_KEYTYPE_HMAC_512:
157		protlen = 96;
158		break;
159	case PKEY_KEYTYPE_HMAC_1024:
160		protlen = 160;
161		break;
162	default:
163		return -EINVAL;
164	}
165
166	if (off != 0 || count < sizeof(*t) + protlen)
167		return -EINVAL;
168
169	memset(t, 0, sizeof(*t) + protlen);
170	t->type = TOKTYPE_NON_CCA;
171	t->version = TOKVER_PROTECTED_KEY;
172	t->keytype = keytype;
173
174	rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_PROTKEY, 0, 0,
175				      t->protkey, &protlen, &prottype);
176	if (rc)
177		return rc;
178
179	t->len = protlen;
180
181	return sizeof(*t) + protlen;
182}
183
184static ssize_t protkey_aes_128_read(struct file *filp,
185				    struct kobject *kobj,
186				    const struct bin_attribute *attr,
187				    char *buf, loff_t off,
188				    size_t count)
189{
190	return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_128, false, buf,
191					  off, count);
192}
193
194static ssize_t protkey_aes_192_read(struct file *filp,
195				    struct kobject *kobj,
196				    const struct bin_attribute *attr,
197				    char *buf, loff_t off,
198				    size_t count)
199{
200	return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_192, false, buf,
201					  off, count);
202}
203
204static ssize_t protkey_aes_256_read(struct file *filp,
205				    struct kobject *kobj,
206				    const struct bin_attribute *attr,
207				    char *buf, loff_t off,
208				    size_t count)
209{
210	return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_256, false, buf,
211					  off, count);
212}
213
214static ssize_t protkey_aes_128_xts_read(struct file *filp,
215					struct kobject *kobj,
216					const struct bin_attribute *attr,
217					char *buf, loff_t off,
218					size_t count)
219{
220	return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_128, true, buf,
221					  off, count);
222}
223
224static ssize_t protkey_aes_256_xts_read(struct file *filp,
225					struct kobject *kobj,
226					const struct bin_attribute *attr,
227					char *buf, loff_t off,
228					size_t count)
229{
230	return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_256, true, buf,
231					  off, count);
232}
233
234static ssize_t protkey_aes_xts_128_read(struct file *filp,
235					struct kobject *kobj,
236					const struct bin_attribute *attr,
237					char *buf, loff_t off,
238					size_t count)
239{
240	return pkey_protkey_aes_xts_attr_read(PKEY_KEYTYPE_AES_XTS_128,
241					      buf, off, count);
242}
243
244static ssize_t protkey_aes_xts_256_read(struct file *filp,
245					struct kobject *kobj,
246					const struct bin_attribute *attr,
247					char *buf, loff_t off,
248					size_t count)
249{
250	return pkey_protkey_aes_xts_attr_read(PKEY_KEYTYPE_AES_XTS_256,
251					      buf, off, count);
252}
253
254static ssize_t protkey_hmac_512_read(struct file *filp,
255				     struct kobject *kobj,
256				     const struct bin_attribute *attr,
257				     char *buf, loff_t off,
258				     size_t count)
259{
260	return pkey_protkey_hmac_attr_read(PKEY_KEYTYPE_HMAC_512,
261					   buf, off, count);
262}
263
264static ssize_t protkey_hmac_1024_read(struct file *filp,
265				      struct kobject *kobj,
266				      const struct bin_attribute *attr,
267				      char *buf, loff_t off,
268				      size_t count)
269{
270	return pkey_protkey_hmac_attr_read(PKEY_KEYTYPE_HMAC_1024,
271					   buf, off, count);
272}
273
274static const BIN_ATTR_RO(protkey_aes_128, sizeof(struct protaeskeytoken));
275static const BIN_ATTR_RO(protkey_aes_192, sizeof(struct protaeskeytoken));
276static const BIN_ATTR_RO(protkey_aes_256, sizeof(struct protaeskeytoken));
277static const BIN_ATTR_RO(protkey_aes_128_xts, 2 * sizeof(struct protaeskeytoken));
278static const BIN_ATTR_RO(protkey_aes_256_xts, 2 * sizeof(struct protaeskeytoken));
279static const BIN_ATTR_RO(protkey_aes_xts_128, sizeof(struct protkeytoken) + 64);
280static const BIN_ATTR_RO(protkey_aes_xts_256, sizeof(struct protkeytoken) + 96);
281static const BIN_ATTR_RO(protkey_hmac_512, sizeof(struct protkeytoken) + 96);
282static const BIN_ATTR_RO(protkey_hmac_1024, sizeof(struct protkeytoken) + 160);
283
284static const struct bin_attribute *const protkey_attrs[] = {
285	&bin_attr_protkey_aes_128,
286	&bin_attr_protkey_aes_192,
287	&bin_attr_protkey_aes_256,
288	&bin_attr_protkey_aes_128_xts,
289	&bin_attr_protkey_aes_256_xts,
290	&bin_attr_protkey_aes_xts_128,
291	&bin_attr_protkey_aes_xts_256,
292	&bin_attr_protkey_hmac_512,
293	&bin_attr_protkey_hmac_1024,
294	NULL
295};
296
297static const struct attribute_group protkey_attr_group = {
298	.name	       = "protkey",
299	.bin_attrs = protkey_attrs,
300};
301
302/*
303 * Sysfs attribute read function for all secure key ccadata binary attributes.
304 * The implementation can not deal with partial reads, because a new random
305 * protected key blob is generated with each read. In case of partial reads
306 * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
307 */
308static ssize_t pkey_ccadata_aes_attr_read(u32 keytype, bool is_xts, char *buf,
309					  loff_t off, size_t count)
310{
311	struct pkey_seckey *seckey = (struct pkey_seckey *)buf;
312	u32 buflen;
313	int rc;
314
315	if (off != 0 || count < sizeof(struct secaeskeytoken))
316		return -EINVAL;
317	if (is_xts)
318		if (count < 2 * sizeof(struct secaeskeytoken))
319			return -EINVAL;
320
321	buflen = sizeof(seckey->seckey);
322	rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_CCA_DATA, 0, 0,
323				      seckey->seckey, &buflen, NULL);
324	if (rc)
325		return rc;
326
327	if (is_xts) {
328		seckey++;
329		buflen = sizeof(seckey->seckey);
330		rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_CCA_DATA, 0, 0,
331					      seckey->seckey, &buflen, NULL);
332		if (rc)
333			return rc;
334
335		return 2 * sizeof(struct secaeskeytoken);
336	}
337
338	return sizeof(struct secaeskeytoken);
339}
340
341static ssize_t ccadata_aes_128_read(struct file *filp,
342				    struct kobject *kobj,
343				    const struct bin_attribute *attr,
344				    char *buf, loff_t off,
345				    size_t count)
346{
347	return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_128, false, buf,
348					  off, count);
349}
350
351static ssize_t ccadata_aes_192_read(struct file *filp,
352				    struct kobject *kobj,
353				    const struct bin_attribute *attr,
354				    char *buf, loff_t off,
355				    size_t count)
356{
357	return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_192, false, buf,
358					  off, count);
359}
360
361static ssize_t ccadata_aes_256_read(struct file *filp,
362				    struct kobject *kobj,
363				    const struct bin_attribute *attr,
364				    char *buf, loff_t off,
365				    size_t count)
366{
367	return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_256, false, buf,
368					  off, count);
369}
370
371static ssize_t ccadata_aes_128_xts_read(struct file *filp,
372					struct kobject *kobj,
373					const struct bin_attribute *attr,
374					char *buf, loff_t off,
375					size_t count)
376{
377	return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_128, true, buf,
378					  off, count);
379}
380
381static ssize_t ccadata_aes_256_xts_read(struct file *filp,
382					struct kobject *kobj,
383					const struct bin_attribute *attr,
384					char *buf, loff_t off,
385					size_t count)
386{
387	return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_256, true, buf,
388					  off, count);
389}
390
391static const BIN_ATTR_RO(ccadata_aes_128, sizeof(struct secaeskeytoken));
392static const BIN_ATTR_RO(ccadata_aes_192, sizeof(struct secaeskeytoken));
393static const BIN_ATTR_RO(ccadata_aes_256, sizeof(struct secaeskeytoken));
394static const BIN_ATTR_RO(ccadata_aes_128_xts, 2 * sizeof(struct secaeskeytoken));
395static const BIN_ATTR_RO(ccadata_aes_256_xts, 2 * sizeof(struct secaeskeytoken));
396
397static const struct bin_attribute *const ccadata_attrs[] = {
398	&bin_attr_ccadata_aes_128,
399	&bin_attr_ccadata_aes_192,
400	&bin_attr_ccadata_aes_256,
401	&bin_attr_ccadata_aes_128_xts,
402	&bin_attr_ccadata_aes_256_xts,
403	NULL
404};
405
406static const struct attribute_group ccadata_attr_group = {
407	.name	       = "ccadata",
408	.bin_attrs = ccadata_attrs,
409};
410
411#define CCACIPHERTOKENSIZE	(sizeof(struct cipherkeytoken) + 80)
412
413/*
414 * Sysfs attribute read function for all secure key ccacipher binary attributes.
415 * The implementation can not deal with partial reads, because a new random
416 * secure key blob is generated with each read. In case of partial reads
417 * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
418 */
419static ssize_t pkey_ccacipher_aes_attr_read(enum pkey_key_size keybits,
420					    bool is_xts, char *buf, loff_t off,
421					    size_t count)
422{
423	u32 keysize = CCACIPHERTOKENSIZE;
424	int rc;
425
426	if (off != 0 || count < CCACIPHERTOKENSIZE)
427		return -EINVAL;
428	if (is_xts)
429		if (count < 2 * CCACIPHERTOKENSIZE)
430			return -EINVAL;
431
432	memset(buf, 0, is_xts ? 2 * keysize : keysize);
433
434	rc = sys_pkey_handler_gen_key(pkey_aes_bitsize_to_keytype(keybits),
435				      PKEY_TYPE_CCA_CIPHER, keybits, 0,
436				      buf, &keysize, NULL);
437	if (rc)
438		return rc;
439
440	if (is_xts) {
441		keysize = CCACIPHERTOKENSIZE;
442		buf += CCACIPHERTOKENSIZE;
443		rc = sys_pkey_handler_gen_key(
444			pkey_aes_bitsize_to_keytype(keybits),
445			PKEY_TYPE_CCA_CIPHER, keybits, 0,
446			buf, &keysize, NULL);
447		if (rc)
448			return rc;
449		return 2 * CCACIPHERTOKENSIZE;
450	}
451
452	return CCACIPHERTOKENSIZE;
453}
454
455static ssize_t ccacipher_aes_128_read(struct file *filp,
456				      struct kobject *kobj,
457				      const struct bin_attribute *attr,
458				      char *buf, loff_t off,
459				      size_t count)
460{
461	return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_128, false, buf,
462					    off, count);
463}
464
465static ssize_t ccacipher_aes_192_read(struct file *filp,
466				      struct kobject *kobj,
467				      const struct bin_attribute *attr,
468				      char *buf, loff_t off,
469				      size_t count)
470{
471	return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_192, false, buf,
472					    off, count);
473}
474
475static ssize_t ccacipher_aes_256_read(struct file *filp,
476				      struct kobject *kobj,
477				      const struct bin_attribute *attr,
478				      char *buf, loff_t off,
479				      size_t count)
480{
481	return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_256, false, buf,
482					    off, count);
483}
484
485static ssize_t ccacipher_aes_128_xts_read(struct file *filp,
486					  struct kobject *kobj,
487					  const struct bin_attribute *attr,
488					  char *buf, loff_t off,
489					  size_t count)
490{
491	return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_128, true, buf,
492					    off, count);
493}
494
495static ssize_t ccacipher_aes_256_xts_read(struct file *filp,
496					  struct kobject *kobj,
497					  const struct bin_attribute *attr,
498					  char *buf, loff_t off,
499					  size_t count)
500{
501	return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_256, true, buf,
502					    off, count);
503}
504
505static const BIN_ATTR_RO(ccacipher_aes_128, CCACIPHERTOKENSIZE);
506static const BIN_ATTR_RO(ccacipher_aes_192, CCACIPHERTOKENSIZE);
507static const BIN_ATTR_RO(ccacipher_aes_256, CCACIPHERTOKENSIZE);
508static const BIN_ATTR_RO(ccacipher_aes_128_xts, 2 * CCACIPHERTOKENSIZE);
509static const BIN_ATTR_RO(ccacipher_aes_256_xts, 2 * CCACIPHERTOKENSIZE);
510
511static const struct bin_attribute *const ccacipher_attrs[] = {
512	&bin_attr_ccacipher_aes_128,
513	&bin_attr_ccacipher_aes_192,
514	&bin_attr_ccacipher_aes_256,
515	&bin_attr_ccacipher_aes_128_xts,
516	&bin_attr_ccacipher_aes_256_xts,
517	NULL
518};
519
520static const struct attribute_group ccacipher_attr_group = {
521	.name	       = "ccacipher",
522	.bin_attrs = ccacipher_attrs,
523};
524
525/*
526 * Sysfs attribute read function for all ep11 aes key binary attributes.
527 * The implementation can not deal with partial reads, because a new random
528 * secure key blob is generated with each read. In case of partial reads
529 * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
530 * This function and the sysfs attributes using it provide EP11 key blobs
531 * padded to the upper limit of MAXEP11AESKEYBLOBSIZE which is currently
532 * 336 bytes.
533 */
534static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits,
535				       bool is_xts, char *buf, loff_t off,
536				       size_t count)
537{
538	u32 keysize = MAXEP11AESKEYBLOBSIZE;
539	int rc;
540
541	if (off != 0 || count < MAXEP11AESKEYBLOBSIZE)
542		return -EINVAL;
543	if (is_xts)
544		if (count < 2 * MAXEP11AESKEYBLOBSIZE)
545			return -EINVAL;
546
547	memset(buf, 0, is_xts ? 2 * keysize : keysize);
548
549	rc = sys_pkey_handler_gen_key(pkey_aes_bitsize_to_keytype(keybits),
550				      PKEY_TYPE_EP11_AES, keybits, 0,
551				      buf, &keysize, NULL);
552	if (rc)
553		return rc;
554
555	if (is_xts) {
556		keysize = MAXEP11AESKEYBLOBSIZE;
557		buf += MAXEP11AESKEYBLOBSIZE;
558		rc = sys_pkey_handler_gen_key(
559			pkey_aes_bitsize_to_keytype(keybits),
560			PKEY_TYPE_EP11_AES, keybits, 0,
561			buf, &keysize, NULL);
562		if (rc)
563			return rc;
564		return 2 * MAXEP11AESKEYBLOBSIZE;
565	}
566
567	return MAXEP11AESKEYBLOBSIZE;
568}
569
570static ssize_t ep11_aes_128_read(struct file *filp,
571				 struct kobject *kobj,
572				 const struct bin_attribute *attr,
573				 char *buf, loff_t off,
574				 size_t count)
575{
576	return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, false, buf,
577				       off, count);
578}
579
580static ssize_t ep11_aes_192_read(struct file *filp,
581				 struct kobject *kobj,
582				 const struct bin_attribute *attr,
583				 char *buf, loff_t off,
584				 size_t count)
585{
586	return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_192, false, buf,
587				       off, count);
588}
589
590static ssize_t ep11_aes_256_read(struct file *filp,
591				 struct kobject *kobj,
592				 const struct bin_attribute *attr,
593				 char *buf, loff_t off,
594				 size_t count)
595{
596	return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, false, buf,
597				       off, count);
598}
599
600static ssize_t ep11_aes_128_xts_read(struct file *filp,
601				     struct kobject *kobj,
602				     const struct bin_attribute *attr,
603				     char *buf, loff_t off,
604				     size_t count)
605{
606	return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, true, buf,
607				       off, count);
608}
609
610static ssize_t ep11_aes_256_xts_read(struct file *filp,
611				     struct kobject *kobj,
612				     const struct bin_attribute *attr,
613				     char *buf, loff_t off,
614				     size_t count)
615{
616	return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, true, buf,
617				       off, count);
618}
619
620static const BIN_ATTR_RO(ep11_aes_128, MAXEP11AESKEYBLOBSIZE);
621static const BIN_ATTR_RO(ep11_aes_192, MAXEP11AESKEYBLOBSIZE);
622static const BIN_ATTR_RO(ep11_aes_256, MAXEP11AESKEYBLOBSIZE);
623static const BIN_ATTR_RO(ep11_aes_128_xts, 2 * MAXEP11AESKEYBLOBSIZE);
624static const BIN_ATTR_RO(ep11_aes_256_xts, 2 * MAXEP11AESKEYBLOBSIZE);
625
626static const struct bin_attribute *const ep11_attrs[] = {
627	&bin_attr_ep11_aes_128,
628	&bin_attr_ep11_aes_192,
629	&bin_attr_ep11_aes_256,
630	&bin_attr_ep11_aes_128_xts,
631	&bin_attr_ep11_aes_256_xts,
632	NULL
633};
634
635static const struct attribute_group ep11_attr_group = {
636	.name	   = "ep11",
637	.bin_attrs = ep11_attrs,
638};
639
640const struct attribute_group *pkey_attr_groups[] = {
641	&protkey_attr_group,
642	&ccadata_attr_group,
643	&ccacipher_attr_group,
644	&ep11_attr_group,
645	NULL,
646};
~/ Read-only file preview.