aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Freudenberger <freude@linux.vnet.ibm.com>2016-11-02 09:37:20 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2017-02-23 04:06:40 -0500
commite80d4af0a320972aac58e2004d0ba4e44ef4c5c7 (patch)
tree551dffc1e632d0a2c49a04079be59350e6a7f15d
parenta1d001e26d5386c934345dc91f16b530e352f8d7 (diff)
s390/pkey: Introduce pkey kernel module
This patch introcudes a new kernel module pkey which is providing protected key handling and management functions. The pkey API is available within the kernel for other s390 specific code to create and manage protected keys. Additionally the functions are exported to user space via IOCTL calls. The implementation makes extensive use of functions provided by the zcrypt device driver. For generating protected keys from secure keys there is also a CEX coprocessor card needed. Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/configs/default_defconfig1
-rw-r--r--arch/s390/configs/performance_defconfig1
-rw-r--r--arch/s390/defconfig1
-rw-r--r--arch/s390/include/asm/pkey.h90
-rw-r--r--arch/s390/include/uapi/asm/Kbuild1
-rw-r--r--arch/s390/include/uapi/asm/pkey.h112
-rw-r--r--drivers/crypto/Kconfig16
-rw-r--r--drivers/s390/crypto/Makefile4
-rw-r--r--drivers/s390/crypto/pkey_api.c1148
9 files changed, 1374 insertions, 0 deletions
diff --git a/arch/s390/configs/default_defconfig b/arch/s390/configs/default_defconfig
index e00975361fec..143b1e00b818 100644
--- a/arch/s390/configs/default_defconfig
+++ b/arch/s390/configs/default_defconfig
@@ -678,6 +678,7 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
678CONFIG_CRYPTO_USER_API_RNG=m 678CONFIG_CRYPTO_USER_API_RNG=m
679CONFIG_CRYPTO_USER_API_AEAD=m 679CONFIG_CRYPTO_USER_API_AEAD=m
680CONFIG_ZCRYPT=m 680CONFIG_ZCRYPT=m
681CONFIG_PKEY=m
681CONFIG_CRYPTO_SHA1_S390=m 682CONFIG_CRYPTO_SHA1_S390=m
682CONFIG_CRYPTO_SHA256_S390=m 683CONFIG_CRYPTO_SHA256_S390=m
683CONFIG_CRYPTO_SHA512_S390=m 684CONFIG_CRYPTO_SHA512_S390=m
diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig
index 2cf87343b590..2358bf33c5ef 100644
--- a/arch/s390/configs/performance_defconfig
+++ b/arch/s390/configs/performance_defconfig
@@ -628,6 +628,7 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
628CONFIG_CRYPTO_USER_API_RNG=m 628CONFIG_CRYPTO_USER_API_RNG=m
629CONFIG_CRYPTO_USER_API_AEAD=m 629CONFIG_CRYPTO_USER_API_AEAD=m
630CONFIG_ZCRYPT=m 630CONFIG_ZCRYPT=m
631CONFIG_PKEY=m
631CONFIG_CRYPTO_SHA1_S390=m 632CONFIG_CRYPTO_SHA1_S390=m
632CONFIG_CRYPTO_SHA256_S390=m 633CONFIG_CRYPTO_SHA256_S390=m
633CONFIG_CRYPTO_SHA512_S390=m 634CONFIG_CRYPTO_SHA512_S390=m
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index d00e368fb5e6..68bfd09f1b02 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -229,6 +229,7 @@ CONFIG_CRYPTO_USER_API_HASH=m
229CONFIG_CRYPTO_USER_API_SKCIPHER=m 229CONFIG_CRYPTO_USER_API_SKCIPHER=m
230CONFIG_CRYPTO_USER_API_RNG=m 230CONFIG_CRYPTO_USER_API_RNG=m
231CONFIG_ZCRYPT=m 231CONFIG_ZCRYPT=m
232CONFIG_PKEY=m
232CONFIG_CRYPTO_SHA1_S390=m 233CONFIG_CRYPTO_SHA1_S390=m
233CONFIG_CRYPTO_SHA256_S390=m 234CONFIG_CRYPTO_SHA256_S390=m
234CONFIG_CRYPTO_SHA512_S390=m 235CONFIG_CRYPTO_SHA512_S390=m
diff --git a/arch/s390/include/asm/pkey.h b/arch/s390/include/asm/pkey.h
new file mode 100644
index 000000000000..b48aef4188f6
--- /dev/null
+++ b/arch/s390/include/asm/pkey.h
@@ -0,0 +1,90 @@
1/*
2 * Kernelspace interface to the pkey device driver
3 *
4 * Copyright IBM Corp. 2016
5 *
6 * Author: Harald Freudenberger <freude@de.ibm.com>
7 *
8 */
9
10#ifndef _KAPI_PKEY_H
11#define _KAPI_PKEY_H
12
13#include <linux/ioctl.h>
14#include <linux/types.h>
15#include <uapi/asm/pkey.h>
16
17/*
18 * Generate (AES) random secure key.
19 * @param cardnr may be -1 (use default card)
20 * @param domain may be -1 (use default domain)
21 * @param keytype one of the PKEY_KEYTYPE values
22 * @param seckey pointer to buffer receiving the secure key
23 * @return 0 on success, negative errno value on failure
24 */
25int pkey_genseckey(__u16 cardnr, __u16 domain,
26 __u32 keytype, struct pkey_seckey *seckey);
27
28/*
29 * Generate (AES) secure key with given key value.
30 * @param cardnr may be -1 (use default card)
31 * @param domain may be -1 (use default domain)
32 * @param keytype one of the PKEY_KEYTYPE values
33 * @param clrkey pointer to buffer with clear key data
34 * @param seckey pointer to buffer receiving the secure key
35 * @return 0 on success, negative errno value on failure
36 */
37int pkey_clr2seckey(__u16 cardnr, __u16 domain, __u32 keytype,
38 const struct pkey_clrkey *clrkey,
39 struct pkey_seckey *seckey);
40
41/*
42 * Derive (AES) proteced key from the (AES) secure key blob.
43 * @param cardnr may be -1 (use default card)
44 * @param domain may be -1 (use default domain)
45 * @param seckey pointer to buffer with the input secure key
46 * @param protkey pointer to buffer receiving the protected key and
47 * additional info (type, length)
48 * @return 0 on success, negative errno value on failure
49 */
50int pkey_sec2protkey(__u16 cardnr, __u16 domain,
51 const struct pkey_seckey *seckey,
52 struct pkey_protkey *protkey);
53
54/*
55 * Derive (AES) protected key from a given clear key value.
56 * @param keytype one of the PKEY_KEYTYPE values
57 * @param clrkey pointer to buffer with clear key data
58 * @param protkey pointer to buffer receiving the protected key and
59 * additional info (type, length)
60 * @return 0 on success, negative errno value on failure
61 */
62int pkey_clr2protkey(__u32 keytype,
63 const struct pkey_clrkey *clrkey,
64 struct pkey_protkey *protkey);
65
66/*
67 * Search for a matching crypto card based on the Master Key
68 * Verification Pattern provided inside a secure key.
69 * @param seckey pointer to buffer with the input secure key
70 * @param cardnr pointer to cardnr, receives the card number on success
71 * @param domain pointer to domain, receives the domain number on success
72 * @param verify if set, always verify by fetching verification pattern
73 * from card
74 * @return 0 on success, negative errno value on failure. If no card could be
75 * found, -ENODEV is returned.
76 */
77int pkey_findcard(const struct pkey_seckey *seckey,
78 __u16 *cardnr, __u16 *domain, int verify);
79
80/*
81 * Find card and transform secure key to protected key.
82 * @param seckey pointer to buffer with the input secure key
83 * @param protkey pointer to buffer receiving the protected key and
84 * additional info (type, length)
85 * @return 0 on success, negative errno value on failure
86 */
87int pkey_skey2pkey(const struct pkey_seckey *seckey,
88 struct pkey_protkey *protkey);
89
90#endif /* _KAPI_PKEY_H */
diff --git a/arch/s390/include/uapi/asm/Kbuild b/arch/s390/include/uapi/asm/Kbuild
index bf736e764cb4..6848ba5c1454 100644
--- a/arch/s390/include/uapi/asm/Kbuild
+++ b/arch/s390/include/uapi/asm/Kbuild
@@ -24,6 +24,7 @@ header-y += mman.h
24header-y += monwriter.h 24header-y += monwriter.h
25header-y += msgbuf.h 25header-y += msgbuf.h
26header-y += param.h 26header-y += param.h
27header-y += pkey.h
27header-y += poll.h 28header-y += poll.h
28header-y += posix_types.h 29header-y += posix_types.h
29header-y += ptrace.h 30header-y += ptrace.h
diff --git a/arch/s390/include/uapi/asm/pkey.h b/arch/s390/include/uapi/asm/pkey.h
new file mode 100644
index 000000000000..ed7f19c27ce5
--- /dev/null
+++ b/arch/s390/include/uapi/asm/pkey.h
@@ -0,0 +1,112 @@
1/*
2 * Userspace interface to the pkey device driver
3 *
4 * Copyright IBM Corp. 2017
5 *
6 * Author: Harald Freudenberger <freude@de.ibm.com>
7 *
8 */
9
10#ifndef _UAPI_PKEY_H
11#define _UAPI_PKEY_H
12
13#include <linux/ioctl.h>
14#include <linux/types.h>
15
16/*
17 * Ioctl calls supported by the pkey device driver
18 */
19
20#define PKEY_IOCTL_MAGIC 'p'
21
22#define SECKEYBLOBSIZE 64 /* secure key blob size is always 64 bytes */
23#define MAXPROTKEYSIZE 64 /* a protected key blob may be up to 64 bytes */
24#define MAXCLRKEYSIZE 32 /* a clear key value may be up to 32 bytes */
25
26/* defines for the type field within the pkey_protkey struct */
27#define PKEY_KEYTYPE_AES_128 1
28#define PKEY_KEYTYPE_AES_192 2
29#define PKEY_KEYTYPE_AES_256 3
30
31/* Struct to hold a secure key blob */
32struct pkey_seckey {
33 __u8 seckey[SECKEYBLOBSIZE]; /* the secure key blob */
34};
35
36/* Struct to hold protected key and length info */
37struct pkey_protkey {
38 __u32 type; /* key type, one of the PKEY_KEYTYPE values */
39 __u32 len; /* bytes actually stored in protkey[] */
40 __u8 protkey[MAXPROTKEYSIZE]; /* the protected key blob */
41};
42
43/* Struct to hold a clear key value */
44struct pkey_clrkey {
45 __u8 clrkey[MAXCLRKEYSIZE]; /* 16, 24, or 32 byte clear key value */
46};
47
48/*
49 * Generate secure key
50 */
51struct pkey_genseck {
52 __u16 cardnr; /* in: card to use or FFFF for any */
53 __u16 domain; /* in: domain or FFFF for any */
54 __u32 keytype; /* in: key type to generate */
55 struct pkey_seckey seckey; /* out: the secure key blob */
56};
57#define PKEY_GENSECK _IOWR(PKEY_IOCTL_MAGIC, 0x01, struct pkey_genseck)
58
59/*
60 * Construct secure key from clear key value
61 */
62struct pkey_clr2seck {
63 __u16 cardnr; /* in: card to use or FFFF for any */
64 __u16 domain; /* in: domain or FFFF for any */
65 __u32 keytype; /* in: key type to generate */
66 struct pkey_clrkey clrkey; /* in: the clear key value */
67 struct pkey_seckey seckey; /* out: the secure key blob */
68};
69#define PKEY_CLR2SECK _IOWR(PKEY_IOCTL_MAGIC, 0x02, struct pkey_clr2seck)
70
71/*
72 * Fabricate protected key from a secure key
73 */
74struct pkey_sec2protk {
75 __u16 cardnr; /* in: card to use or FFFF for any */
76 __u16 domain; /* in: domain or FFFF for any */
77 struct pkey_seckey seckey; /* in: the secure key blob */
78 struct pkey_protkey protkey; /* out: the protected key */
79};
80#define PKEY_SEC2PROTK _IOWR(PKEY_IOCTL_MAGIC, 0x03, struct pkey_sec2protk)
81
82/*
83 * Fabricate protected key from an clear key value
84 */
85struct pkey_clr2protk {
86 __u32 keytype; /* in: key type to generate */
87 struct pkey_clrkey clrkey; /* in: the clear key value */
88 struct pkey_protkey protkey; /* out: the protected key */
89};
90#define PKEY_CLR2PROTK _IOWR(PKEY_IOCTL_MAGIC, 0x04, struct pkey_clr2protk)
91
92/*
93 * Search for matching crypto card based on the Master Key
94 * Verification Pattern provided inside a secure key.
95 */
96struct pkey_findcard {
97 struct pkey_seckey seckey; /* in: the secure key blob */
98 __u16 cardnr; /* out: card number */
99 __u16 domain; /* out: domain number */
100};
101#define PKEY_FINDCARD _IOWR(PKEY_IOCTL_MAGIC, 0x05, struct pkey_findcard)
102
103/*
104 * Combined together: findcard + sec2prot
105 */
106struct pkey_skey2pkey {
107 struct pkey_seckey seckey; /* in: the secure key blob */
108 struct pkey_protkey protkey; /* out: the protected key */
109};
110#define PKEY_SKEY2PKEY _IOWR(PKEY_IOCTL_MAGIC, 0x06, struct pkey_skey2pkey)
111
112#endif /* _UAPI_PKEY_H */
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index ae20ec55ab58..57c2d434ea4b 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -73,6 +73,22 @@ config ZCRYPT
73 + Crypto Express 2,3,4 or 5 Accelerator (CEXxA) 73 + Crypto Express 2,3,4 or 5 Accelerator (CEXxA)
74 + Crypto Express 4 or 5 EP11 Coprocessor (CEXxP) 74 + Crypto Express 4 or 5 EP11 Coprocessor (CEXxP)
75 75
76config PKEY
77 tristate "Kernel API for protected key handling"
78 depends on S390
79 depends on ZCRYPT
80 help
81 With this option enabled the pkey kernel module provides an API
82 for creation and handling of protected keys. Other parts of the
83 kernel or userspace applications may use these functions.
84
85 Select this option if you want to enable the kernel and userspace
86 API for proteced key handling.
87
88 Please note that creation of protected keys from secure keys
89 requires to have at least one CEX card in coprocessor mode
90 available at runtime.
91
76config CRYPTO_SHA1_S390 92config CRYPTO_SHA1_S390
77 tristate "SHA1 digest algorithm" 93 tristate "SHA1 digest algorithm"
78 depends on S390 94 depends on S390
diff --git a/drivers/s390/crypto/Makefile b/drivers/s390/crypto/Makefile
index 0a7fb83f35e5..be36f1010d75 100644
--- a/drivers/s390/crypto/Makefile
+++ b/drivers/s390/crypto/Makefile
@@ -10,3 +10,7 @@ zcrypt-objs += zcrypt_msgtype6.o zcrypt_msgtype50.o
10obj-$(CONFIG_ZCRYPT) += zcrypt.o 10obj-$(CONFIG_ZCRYPT) += zcrypt.o
11# adapter drivers depend on ap.o and zcrypt.o 11# adapter drivers depend on ap.o and zcrypt.o
12obj-$(CONFIG_ZCRYPT) += zcrypt_pcixcc.o zcrypt_cex2a.o zcrypt_cex4.o 12obj-$(CONFIG_ZCRYPT) += zcrypt_pcixcc.o zcrypt_cex2a.o zcrypt_cex4.o
13
14# pkey kernel module
15pkey-objs := pkey_api.o
16obj-$(CONFIG_PKEY) += pkey.o
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
new file mode 100644
index 000000000000..40f1136f5568
--- /dev/null
+++ b/drivers/s390/crypto/pkey_api.c
@@ -0,0 +1,1148 @@
1/*
2 * pkey device driver
3 *
4 * Copyright IBM Corp. 2017
5 * Author(s): Harald Freudenberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License (version 2 only)
9 * as published by the Free Software Foundation.
10 *
11 */
12
13#define KMSG_COMPONENT "pkey"
14#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
15
16#include <linux/fs.h>
17#include <linux/init.h>
18#include <linux/miscdevice.h>
19#include <linux/module.h>
20#include <linux/slab.h>
21#include <linux/kallsyms.h>
22#include <linux/debugfs.h>
23#include <asm/zcrypt.h>
24#include <asm/cpacf.h>
25#include <asm/pkey.h>
26
27#include "zcrypt_api.h"
28
29MODULE_LICENSE("GPL");
30MODULE_AUTHOR("IBM Corporation");
31MODULE_DESCRIPTION("s390 protected key interface");
32
33/* Size of parameter block used for all cca requests/replies */
34#define PARMBSIZE 512
35
36/* Size of vardata block used for some of the cca requests/replies */
37#define VARDATASIZE 4096
38
39/*
40 * debug feature data and functions
41 */
42
43static debug_info_t *debug_info;
44
45#define DEBUG_DBG(...) debug_sprintf_event(debug_info, 6, ##__VA_ARGS__)
46#define DEBUG_INFO(...) debug_sprintf_event(debug_info, 5, ##__VA_ARGS__)
47#define DEBUG_WARN(...) debug_sprintf_event(debug_info, 4, ##__VA_ARGS__)
48#define DEBUG_ERR(...) debug_sprintf_event(debug_info, 3, ##__VA_ARGS__)
49
50static void __init pkey_debug_init(void)
51{
52 debug_info = debug_register("pkey", 1, 1, 4 * sizeof(long));
53 debug_register_view(debug_info, &debug_sprintf_view);
54 debug_set_level(debug_info, 3);
55}
56
57static void __exit pkey_debug_exit(void)
58{
59 debug_unregister(debug_info);
60}
61
62/* inside view of a secure key token (only type 0x01 version 0x04) */
63struct secaeskeytoken {
64 u8 type; /* 0x01 for internal key token */
65 u8 res0[3];
66 u8 version; /* should be 0x04 */
67 u8 res1[1];
68 u8 flag; /* key flags */
69 u8 res2[1];
70 u64 mkvp; /* master key verification pattern */
71 u8 key[32]; /* key value (encrypted) */
72 u8 cv[8]; /* control vector */
73 u16 bitsize; /* key bit size */
74 u16 keysize; /* key byte size */
75 u8 tvv[4]; /* token validation value */
76} __packed;
77
78/*
79 * Simple check if the token is a valid CCA secure AES key
80 * token. If keybitsize is given, the bitsize of the key is
81 * also checked. Returns 0 on success or errno value on failure.
82 */
83static int check_secaeskeytoken(u8 *token, int keybitsize)
84{
85 struct secaeskeytoken *t = (struct secaeskeytoken *) token;
86
87 if (t->type != 0x01) {
88 DEBUG_ERR(
89 "check_secaeskeytoken secure token check failed, type mismatch 0x%02x != 0x01\n",
90 (int) t->type);
91 return -EINVAL;
92 }
93 if (t->version != 0x04) {
94 DEBUG_ERR(
95 "check_secaeskeytoken secure token check failed, version mismatch 0x%02x != 0x04\n",
96 (int) t->version);
97 return -EINVAL;
98 }
99 if (keybitsize > 0 && t->bitsize != keybitsize) {
100 DEBUG_ERR(
101 "check_secaeskeytoken secure token check failed, bitsize mismatch %d != %d\n",
102 (int) t->bitsize, keybitsize);
103 return -EINVAL;
104 }
105
106 return 0;
107}
108
109/*
110 * Allocate consecutive memory for request CPRB, request param
111 * block, reply CPRB and reply param block and fill in values
112 * for the common fields. Returns 0 on success or errno value
113 * on failure.
114 */
115static int alloc_and_prep_cprbmem(size_t paramblen,
116 u8 **pcprbmem,
117 struct CPRBX **preqCPRB,
118 struct CPRBX **prepCPRB)
119{
120 u8 *cprbmem;
121 size_t cprbplusparamblen = sizeof(struct CPRBX) + paramblen;
122 struct CPRBX *preqcblk, *prepcblk;
123
124 /*
125 * allocate consecutive memory for request CPRB, request param
126 * block, reply CPRB and reply param block
127 */
128 cprbmem = kmalloc(2 * cprbplusparamblen, GFP_KERNEL);
129 if (!cprbmem)
130 return -ENOMEM;
131 memset(cprbmem, 0, 2 * cprbplusparamblen);
132
133 preqcblk = (struct CPRBX *) cprbmem;
134 prepcblk = (struct CPRBX *) (cprbmem + cprbplusparamblen);
135
136 /* fill request cprb struct */
137 preqcblk->cprb_len = sizeof(struct CPRBX);
138 preqcblk->cprb_ver_id = 0x02;
139 memcpy(preqcblk->func_id, "T2", 2);
140 preqcblk->rpl_msgbl = cprbplusparamblen;
141 if (paramblen) {
142 preqcblk->req_parmb =
143 ((u8 *) preqcblk) + sizeof(struct CPRBX);
144 preqcblk->rpl_parmb =
145 ((u8 *) prepcblk) + sizeof(struct CPRBX);
146 }
147
148 *pcprbmem = cprbmem;
149 *preqCPRB = preqcblk;
150 *prepCPRB = prepcblk;
151
152 return 0;
153}
154
155/*
156 * Free the cprb memory allocated with the function above.
157 * If the scrub value is not zero, the memory is filled
158 * with zeros before freeing (useful if there was some
159 * clear key material in there).
160 */
161static void free_cprbmem(void *mem, size_t paramblen, int scrub)
162{
163 if (scrub)
164 memzero_explicit(mem, 2 * (sizeof(struct CPRBX) + paramblen));
165 kfree(mem);
166}
167
168/*
169 * Helper function to prepare the xcrb struct
170 */
171static inline void prep_xcrb(struct ica_xcRB *pxcrb,
172 u16 cardnr,
173 struct CPRBX *preqcblk,
174 struct CPRBX *prepcblk)
175{
176 memset(pxcrb, 0, sizeof(*pxcrb));
177 pxcrb->agent_ID = 0x4341; /* 'CA' */
178 pxcrb->user_defined = (cardnr == 0xFFFF ? AUTOSELECT : cardnr);
179 pxcrb->request_control_blk_length =
180 preqcblk->cprb_len + preqcblk->req_parml;
181 pxcrb->request_control_blk_addr = (void *) preqcblk;
182 pxcrb->reply_control_blk_length = preqcblk->rpl_msgbl;
183 pxcrb->reply_control_blk_addr = (void *) prepcblk;
184}
185
186/*
187 * Helper function which calls zcrypt_send_cprb with
188 * memory management segment adjusted to kernel space
189 * so that the copy_from_user called within this
190 * function do in fact copy from kernel space.
191 */
192static inline int _zcrypt_send_cprb(struct ica_xcRB *xcrb)
193{
194 int rc;
195 mm_segment_t old_fs = get_fs();
196
197 set_fs(KERNEL_DS);
198 rc = zcrypt_send_cprb(xcrb);
199 set_fs(old_fs);
200
201 return rc;
202}
203
204/*
205 * Generate (random) AES secure key.
206 */
207int pkey_genseckey(u16 cardnr, u16 domain,
208 u32 keytype, struct pkey_seckey *seckey)
209{
210 int i, rc, keysize;
211 int seckeysize;
212 u8 *mem;
213 struct CPRBX *preqcblk, *prepcblk;
214 struct ica_xcRB xcrb;
215 struct kgreqparm {
216 u8 subfunc_code[2];
217 u16 rule_array_len;
218 struct lv1 {
219 u16 len;
220 char key_form[8];
221 char key_length[8];
222 char key_type1[8];
223 char key_type2[8];
224 } lv1;
225 struct lv2 {
226 u16 len;
227 struct keyid {
228 u16 len;
229 u16 attr;
230 u8 data[SECKEYBLOBSIZE];
231 } keyid[6];
232 } lv2;
233 } *preqparm;
234 struct kgrepparm {
235 u8 subfunc_code[2];
236 u16 rule_array_len;
237 struct lv3 {
238 u16 len;
239 u16 keyblocklen;
240 struct {
241 u16 toklen;
242 u16 tokattr;
243 u8 tok[0];
244 /* ... some more data ... */
245 } keyblock;
246 } lv3;
247 } *prepparm;
248
249 /* get already prepared memory for 2 cprbs with param block each */
250 rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
251 if (rc)
252 return rc;
253
254 /* fill request cprb struct */
255 preqcblk->domain = domain;
256
257 /* fill request cprb param block with KG request */
258 preqparm = (struct kgreqparm *) preqcblk->req_parmb;
259 memcpy(preqparm->subfunc_code, "KG", 2);
260 preqparm->rule_array_len = sizeof(preqparm->rule_array_len);
261 preqparm->lv1.len = sizeof(struct lv1);
262 memcpy(preqparm->lv1.key_form, "OP ", 8);
263 switch (keytype) {
264 case PKEY_KEYTYPE_AES_128:
265 keysize = 16;
266 memcpy(preqparm->lv1.key_length, "KEYLN16 ", 8);
267 break;
268 case PKEY_KEYTYPE_AES_192:
269 keysize = 24;
270 memcpy(preqparm->lv1.key_length, "KEYLN24 ", 8);
271 break;
272 case PKEY_KEYTYPE_AES_256:
273 keysize = 32;
274 memcpy(preqparm->lv1.key_length, "KEYLN32 ", 8);
275 break;
276 default:
277 DEBUG_ERR(
278 "pkey_genseckey unknown/unsupported keytype %d\n",
279 keytype);
280 rc = -EINVAL;
281 goto out;
282 }
283 memcpy(preqparm->lv1.key_type1, "AESDATA ", 8);
284 preqparm->lv2.len = sizeof(struct lv2);
285 for (i = 0; i < 6; i++) {
286 preqparm->lv2.keyid[i].len = sizeof(struct keyid);
287 preqparm->lv2.keyid[i].attr = (i == 2 ? 0x30 : 0x10);
288 }
289 preqcblk->req_parml = sizeof(struct kgreqparm);
290
291 /* fill xcrb struct */
292 prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
293
294 /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
295 rc = _zcrypt_send_cprb(&xcrb);
296 if (rc) {
297 DEBUG_ERR(
298 "pkey_genseckey zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
299 (int) cardnr, (int) domain, rc);
300 goto out;
301 }
302
303 /* check response returncode and reasoncode */
304 if (prepcblk->ccp_rtcode != 0) {
305 DEBUG_ERR(
306 "pkey_genseckey secure key generate failure, card response %d/%d\n",
307 (int) prepcblk->ccp_rtcode,
308 (int) prepcblk->ccp_rscode);
309 rc = -EIO;
310 goto out;
311 }
312
313 /* process response cprb param block */
314 prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX);
315 prepparm = (struct kgrepparm *) prepcblk->rpl_parmb;
316
317 /* check length of the returned secure key token */
318 seckeysize = prepparm->lv3.keyblock.toklen
319 - sizeof(prepparm->lv3.keyblock.toklen)
320 - sizeof(prepparm->lv3.keyblock.tokattr);
321 if (seckeysize != SECKEYBLOBSIZE) {
322 DEBUG_ERR(
323 "pkey_genseckey secure token size mismatch %d != %d bytes\n",
324 seckeysize, SECKEYBLOBSIZE);
325 rc = -EIO;
326 goto out;
327 }
328
329 /* check secure key token */
330 rc = check_secaeskeytoken(prepparm->lv3.keyblock.tok, 8*keysize);
331 if (rc) {
332 rc = -EIO;
333 goto out;
334 }
335
336 /* copy the generated secure key token */
337 memcpy(seckey->seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE);
338
339out:
340 free_cprbmem(mem, PARMBSIZE, 0);
341 return rc;
342}
343EXPORT_SYMBOL(pkey_genseckey);
344
345/*
346 * Generate an AES secure key with given key value.
347 */
348int pkey_clr2seckey(u16 cardnr, u16 domain, u32 keytype,
349 const struct pkey_clrkey *clrkey,
350 struct pkey_seckey *seckey)
351{
352 int rc, keysize, seckeysize;
353 u8 *mem;
354 struct CPRBX *preqcblk, *prepcblk;
355 struct ica_xcRB xcrb;
356 struct cmreqparm {
357 u8 subfunc_code[2];
358 u16 rule_array_len;
359 char rule_array[8];
360 struct lv1 {
361 u16 len;
362 u8 clrkey[0];
363 } lv1;
364 struct lv2 {
365 u16 len;
366 struct keyid {
367 u16 len;
368 u16 attr;
369 u8 data[SECKEYBLOBSIZE];
370 } keyid;
371 } lv2;
372 } *preqparm;
373 struct lv2 *plv2;
374 struct cmrepparm {
375 u8 subfunc_code[2];
376 u16 rule_array_len;
377 struct lv3 {
378 u16 len;
379 u16 keyblocklen;
380 struct {
381 u16 toklen;
382 u16 tokattr;
383 u8 tok[0];
384 /* ... some more data ... */
385 } keyblock;
386 } lv3;
387 } *prepparm;
388
389 /* get already prepared memory for 2 cprbs with param block each */
390 rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
391 if (rc)
392 return rc;
393
394 /* fill request cprb struct */
395 preqcblk->domain = domain;
396
397 /* fill request cprb param block with CM request */
398 preqparm = (struct cmreqparm *) preqcblk->req_parmb;
399 memcpy(preqparm->subfunc_code, "CM", 2);
400 memcpy(preqparm->rule_array, "AES ", 8);
401 preqparm->rule_array_len =
402 sizeof(preqparm->rule_array_len) + sizeof(preqparm->rule_array);
403 switch (keytype) {
404 case PKEY_KEYTYPE_AES_128:
405 keysize = 16;
406 break;
407 case PKEY_KEYTYPE_AES_192:
408 keysize = 24;
409 break;
410 case PKEY_KEYTYPE_AES_256:
411 keysize = 32;
412 break;
413 default:
414 DEBUG_ERR(
415 "pkey_clr2seckey unknown/unsupported keytype %d\n",
416 keytype);
417 rc = -EINVAL;
418 goto out;
419 }
420 preqparm->lv1.len = sizeof(struct lv1) + keysize;
421 memcpy(preqparm->lv1.clrkey, clrkey->clrkey, keysize);
422 plv2 = (struct lv2 *) (((u8 *) &preqparm->lv2) + keysize);
423 plv2->len = sizeof(struct lv2);
424 plv2->keyid.len = sizeof(struct keyid);
425 plv2->keyid.attr = 0x30;
426 preqcblk->req_parml = sizeof(struct cmreqparm) + keysize;
427
428 /* fill xcrb struct */
429 prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
430
431 /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
432 rc = _zcrypt_send_cprb(&xcrb);
433 if (rc) {
434 DEBUG_ERR(
435 "pkey_clr2seckey zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
436 (int) cardnr, (int) domain, rc);
437 goto out;
438 }
439
440 /* check response returncode and reasoncode */
441 if (prepcblk->ccp_rtcode != 0) {
442 DEBUG_ERR(
443 "pkey_clr2seckey clear key import failure, card response %d/%d\n",
444 (int) prepcblk->ccp_rtcode,
445 (int) prepcblk->ccp_rscode);
446 rc = -EIO;
447 goto out;
448 }
449
450 /* process response cprb param block */
451 prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX);
452 prepparm = (struct cmrepparm *) prepcblk->rpl_parmb;
453
454 /* check length of the returned secure key token */
455 seckeysize = prepparm->lv3.keyblock.toklen
456 - sizeof(prepparm->lv3.keyblock.toklen)
457 - sizeof(prepparm->lv3.keyblock.tokattr);
458 if (seckeysize != SECKEYBLOBSIZE) {
459 DEBUG_ERR(
460 "pkey_clr2seckey secure token size mismatch %d != %d bytes\n",
461 seckeysize, SECKEYBLOBSIZE);
462 rc = -EIO;
463 goto out;
464 }
465
466 /* check secure key token */
467 rc = check_secaeskeytoken(prepparm->lv3.keyblock.tok, 8*keysize);
468 if (rc) {
469 rc = -EIO;
470 goto out;
471 }
472
473 /* copy the generated secure key token */
474 memcpy(seckey->seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE);
475
476out:
477 free_cprbmem(mem, PARMBSIZE, 1);
478 return rc;
479}
480EXPORT_SYMBOL(pkey_clr2seckey);
481
482/*
483 * Derive a proteced key from the secure key blob.
484 */
485int pkey_sec2protkey(u16 cardnr, u16 domain,
486 const struct pkey_seckey *seckey,
487 struct pkey_protkey *protkey)
488{
489 int rc;
490 u8 *mem;
491 struct CPRBX *preqcblk, *prepcblk;
492 struct ica_xcRB xcrb;
493 struct uskreqparm {
494 u8 subfunc_code[2];
495 u16 rule_array_len;
496 struct lv1 {
497 u16 len;
498 u16 attr_len;
499 u16 attr_flags;
500 } lv1;
501 struct lv2 {
502 u16 len;
503 u16 attr_len;
504 u16 attr_flags;
505 u8 token[0]; /* cca secure key token */
506 } lv2 __packed;
507 } *preqparm;
508 struct uskrepparm {
509 u8 subfunc_code[2];
510 u16 rule_array_len;
511 struct lv3 {
512 u16 len;
513 u16 attr_len;
514 u16 attr_flags;
515 struct cpacfkeyblock {
516 u8 version; /* version of this struct */
517 u8 flags[2];
518 u8 algo;
519 u8 form;
520 u8 pad1[3];
521 u16 keylen;
522 u8 key[64]; /* the key (keylen bytes) */
523 u16 keyattrlen;
524 u8 keyattr[32];
525 u8 pad2[1];
526 u8 vptype;
527 u8 vp[32]; /* verification pattern */
528 } keyblock;
529 } lv3 __packed;
530 } *prepparm;
531
532 /* get already prepared memory for 2 cprbs with param block each */
533 rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
534 if (rc)
535 return rc;
536
537 /* fill request cprb struct */
538 preqcblk->domain = domain;
539
540 /* fill request cprb param block with USK request */
541 preqparm = (struct uskreqparm *) preqcblk->req_parmb;
542 memcpy(preqparm->subfunc_code, "US", 2);
543 preqparm->rule_array_len = sizeof(preqparm->rule_array_len);
544 preqparm->lv1.len = sizeof(struct lv1);
545 preqparm->lv1.attr_len = sizeof(struct lv1) - sizeof(preqparm->lv1.len);
546 preqparm->lv1.attr_flags = 0x0001;
547 preqparm->lv2.len = sizeof(struct lv2) + SECKEYBLOBSIZE;
548 preqparm->lv2.attr_len = sizeof(struct lv2)
549 - sizeof(preqparm->lv2.len) + SECKEYBLOBSIZE;
550 preqparm->lv2.attr_flags = 0x0000;
551 memcpy(preqparm->lv2.token, seckey->seckey, SECKEYBLOBSIZE);
552 preqcblk->req_parml = sizeof(struct uskreqparm) + SECKEYBLOBSIZE;
553
554 /* fill xcrb struct */
555 prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
556
557 /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
558 rc = _zcrypt_send_cprb(&xcrb);
559 if (rc) {
560 DEBUG_ERR(
561 "pkey_sec2protkey zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
562 (int) cardnr, (int) domain, rc);
563 goto out;
564 }
565
566 /* check response returncode and reasoncode */
567 if (prepcblk->ccp_rtcode != 0) {
568 DEBUG_ERR(
569 "pkey_sec2protkey unwrap secure key failure, card response %d/%d\n",
570 (int) prepcblk->ccp_rtcode,
571 (int) prepcblk->ccp_rscode);
572 rc = -EIO;
573 goto out;
574 }
575
576 /* process response cprb param block */
577 prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX);
578 prepparm = (struct uskrepparm *) prepcblk->rpl_parmb;
579
580 /* check the returned keyblock */
581 if (prepparm->lv3.keyblock.version != 0x01) {
582 DEBUG_ERR(
583 "pkey_sec2protkey reply param keyblock version mismatch 0x%02x != 0x01\n",
584 (int) prepparm->lv3.keyblock.version);
585 rc = -EIO;
586 goto out;
587 }
588
589 /* copy the tanslated protected key */
590 switch (prepparm->lv3.keyblock.keylen) {
591 case 16+32:
592 protkey->type = PKEY_KEYTYPE_AES_128;
593 break;
594 case 24+32:
595 protkey->type = PKEY_KEYTYPE_AES_192;
596 break;
597 case 32+32:
598 protkey->type = PKEY_KEYTYPE_AES_256;
599 break;
600 default:
601 DEBUG_ERR("pkey_sec2protkey unknown/unsupported keytype %d\n",
602 prepparm->lv3.keyblock.keylen);
603 rc = -EIO;
604 goto out;
605 }
606 protkey->len = prepparm->lv3.keyblock.keylen;
607 memcpy(protkey->protkey, prepparm->lv3.keyblock.key, protkey->len);
608
609out:
610 free_cprbmem(mem, PARMBSIZE, 0);
611 return rc;
612}
613EXPORT_SYMBOL(pkey_sec2protkey);
614
615/*
616 * Create a protected key from a clear key value.
617 */
618int pkey_clr2protkey(u32 keytype,
619 const struct pkey_clrkey *clrkey,
620 struct pkey_protkey *protkey)
621{
622 long fc;
623 int keysize;
624 u8 paramblock[64];
625
626 switch (keytype) {
627 case PKEY_KEYTYPE_AES_128:
628 keysize = 16;
629 fc = CPACF_PCKMO_ENC_AES_128_KEY;
630 break;
631 case PKEY_KEYTYPE_AES_192:
632 keysize = 24;
633 fc = CPACF_PCKMO_ENC_AES_192_KEY;
634 break;
635 case PKEY_KEYTYPE_AES_256:
636 keysize = 32;
637 fc = CPACF_PCKMO_ENC_AES_256_KEY;
638 break;
639 default:
640 DEBUG_ERR("pkey_clr2protkey unknown/unsupported keytype %d\n",
641 keytype);
642 return -EINVAL;
643 }
644
645 /* prepare param block */
646 memset(paramblock, 0, sizeof(paramblock));
647 memcpy(paramblock, clrkey->clrkey, keysize);
648
649 /* call the pckmo instruction */
650 cpacf_pckmo(fc, paramblock);
651
652 /* copy created protected key */
653 protkey->type = keytype;
654 protkey->len = keysize + 32;
655 memcpy(protkey->protkey, paramblock, keysize + 32);
656
657 return 0;
658}
659EXPORT_SYMBOL(pkey_clr2protkey);
660
661/*
662 * query cryptographic facility from adapter
663 */
664static int query_crypto_facility(u16 cardnr, u16 domain,
665 const char *keyword,
666 u8 *rarray, size_t *rarraylen,
667 u8 *varray, size_t *varraylen)
668{
669 int rc;
670 u16 len;
671 u8 *mem, *ptr;
672 struct CPRBX *preqcblk, *prepcblk;
673 struct ica_xcRB xcrb;
674 struct fqreqparm {
675 u8 subfunc_code[2];
676 u16 rule_array_len;
677 char rule_array[8];
678 struct lv1 {
679 u16 len;
680 u8 data[VARDATASIZE];
681 } lv1;
682 u16 dummylen;
683 } *preqparm;
684 size_t parmbsize = sizeof(struct fqreqparm);
685 struct fqrepparm {
686 u8 subfunc_code[2];
687 u8 lvdata[0];
688 } *prepparm;
689
690 /* get already prepared memory for 2 cprbs with param block each */
691 rc = alloc_and_prep_cprbmem(parmbsize, &mem, &preqcblk, &prepcblk);
692 if (rc)
693 return rc;
694
695 /* fill request cprb struct */
696 preqcblk->domain = domain;
697
698 /* fill request cprb param block with FQ request */
699 preqparm = (struct fqreqparm *) preqcblk->req_parmb;
700 memcpy(preqparm->subfunc_code, "FQ", 2);
701 strncpy(preqparm->rule_array, keyword, sizeof(preqparm->rule_array));
702 preqparm->rule_array_len =
703 sizeof(preqparm->rule_array_len) + sizeof(preqparm->rule_array);
704 preqparm->lv1.len = sizeof(preqparm->lv1);
705 preqparm->dummylen = sizeof(preqparm->dummylen);
706 preqcblk->req_parml = parmbsize;
707
708 /* fill xcrb struct */
709 prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
710
711 /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
712 rc = _zcrypt_send_cprb(&xcrb);
713 if (rc) {
714 DEBUG_ERR(
715 "query_crypto_facility zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
716 (int) cardnr, (int) domain, rc);
717 goto out;
718 }
719
720 /* check response returncode and reasoncode */
721 if (prepcblk->ccp_rtcode != 0) {
722 DEBUG_ERR(
723 "query_crypto_facility unwrap secure key failure, card response %d/%d\n",
724 (int) prepcblk->ccp_rtcode,
725 (int) prepcblk->ccp_rscode);
726 rc = -EIO;
727 goto out;
728 }
729
730 /* process response cprb param block */
731 prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX);
732 prepparm = (struct fqrepparm *) prepcblk->rpl_parmb;
733 ptr = prepparm->lvdata;
734
735 /* check and possibly copy reply rule array */
736 len = *((u16 *) ptr);
737 if (len > sizeof(u16)) {
738 ptr += sizeof(u16);
739 len -= sizeof(u16);
740 if (rarray && rarraylen && *rarraylen > 0) {
741 *rarraylen = (len > *rarraylen ? *rarraylen : len);
742 memcpy(rarray, ptr, *rarraylen);
743 }
744 ptr += len;
745 }
746 /* check and possible copy reply var array */
747 len = *((u16 *) ptr);
748 if (len > sizeof(u16)) {
749 ptr += sizeof(u16);
750 len -= sizeof(u16);
751 if (varray && varraylen && *varraylen > 0) {
752 *varraylen = (len > *varraylen ? *varraylen : len);
753 memcpy(varray, ptr, *varraylen);
754 }
755 ptr += len;
756 }
757
758out:
759 free_cprbmem(mem, parmbsize, 0);
760 return rc;
761}
762
763/*
764 * Fetch just the mkvp value via query_crypto_facility from adapter.
765 */
766static int fetch_mkvp(u16 cardnr, u16 domain, u64 *mkvp)
767{
768 int rc, found = 0;
769 size_t rlen, vlen;
770 u8 *rarray, *varray, *pg;
771
772 pg = (u8 *) __get_free_page(GFP_KERNEL);
773 if (!pg)
774 return -ENOMEM;
775 rarray = pg;
776 varray = pg + PAGE_SIZE/2;
777 rlen = vlen = PAGE_SIZE/2;
778
779 rc = query_crypto_facility(cardnr, domain, "STATICSA",
780 rarray, &rlen, varray, &vlen);
781 if (rc == 0 && rlen > 8*8 && vlen > 184+8) {
782 if (rarray[64] == '2') {
783 /* current master key state is valid */
784 *mkvp = *((u64 *)(varray + 184));
785 found = 1;
786 }
787 }
788
789 free_page((unsigned long) pg);
790
791 return found ? 0 : -ENOENT;
792}
793
794/* struct to hold cached mkvp info for each card/domain */
795struct mkvp_info {
796 struct list_head list;
797 u16 cardnr;
798 u16 domain;
799 u64 mkvp;
800};
801
802/* a list with mkvp_info entries */
803static LIST_HEAD(mkvp_list);
804static DEFINE_SPINLOCK(mkvp_list_lock);
805
806static int mkvp_cache_fetch(u16 cardnr, u16 domain, u64 *mkvp)
807{
808 int rc = -ENOENT;
809 struct mkvp_info *ptr;
810
811 spin_lock_bh(&mkvp_list_lock);
812 list_for_each_entry(ptr, &mkvp_list, list) {
813 if (ptr->cardnr == cardnr &&
814 ptr->domain == domain) {
815 *mkvp = ptr->mkvp;
816 rc = 0;
817 break;
818 }
819 }
820 spin_unlock_bh(&mkvp_list_lock);
821
822 return rc;
823}
824
825static void mkvp_cache_update(u16 cardnr, u16 domain, u64 mkvp)
826{
827 int found = 0;
828 struct mkvp_info *ptr;
829
830 spin_lock_bh(&mkvp_list_lock);
831 list_for_each_entry(ptr, &mkvp_list, list) {
832 if (ptr->cardnr == cardnr &&
833 ptr->domain == domain) {
834 ptr->mkvp = mkvp;
835 found = 1;
836 break;
837 }
838 }
839 if (!found) {
840 ptr = kmalloc(sizeof(*ptr), GFP_ATOMIC);
841 if (!ptr) {
842 spin_unlock_bh(&mkvp_list_lock);
843 return;
844 }
845 ptr->cardnr = cardnr;
846 ptr->domain = domain;
847 ptr->mkvp = mkvp;
848 list_add(&ptr->list, &mkvp_list);
849 }
850 spin_unlock_bh(&mkvp_list_lock);
851}
852
853static void mkvp_cache_scrub(u16 cardnr, u16 domain)
854{
855 struct mkvp_info *ptr;
856
857 spin_lock_bh(&mkvp_list_lock);
858 list_for_each_entry(ptr, &mkvp_list, list) {
859 if (ptr->cardnr == cardnr &&
860 ptr->domain == domain) {
861 list_del(&ptr->list);
862 kfree(ptr);
863 break;
864 }
865 }
866 spin_unlock_bh(&mkvp_list_lock);
867}
868
869static void __exit mkvp_cache_free(void)
870{
871 struct mkvp_info *ptr, *pnext;
872
873 spin_lock_bh(&mkvp_list_lock);
874 list_for_each_entry_safe(ptr, pnext, &mkvp_list, list) {
875 list_del(&ptr->list);
876 kfree(ptr);
877 }
878 spin_unlock_bh(&mkvp_list_lock);
879}
880
881/*
882 * Search for a matching crypto card based on the Master Key
883 * Verification Pattern provided inside a secure key.
884 */
885int pkey_findcard(const struct pkey_seckey *seckey,
886 u16 *pcardnr, u16 *pdomain, int verify)
887{
888 struct secaeskeytoken *t = (struct secaeskeytoken *) seckey;
889 struct zcrypt_device_matrix *device_matrix;
890 u16 card, dom;
891 u64 mkvp;
892 int i, rc;
893
894 /* mkvp must not be zero */
895 if (t->mkvp == 0)
896 return -EINVAL;
897
898 /* fetch status of all crypto cards */
899 device_matrix = kmalloc(sizeof(struct zcrypt_device_matrix),
900 GFP_KERNEL);
901 if (!device_matrix)
902 return -ENOMEM;
903 zcrypt_device_status_mask(device_matrix);
904
905 /* walk through all crypto cards */
906 for (i = 0; i < MAX_ZDEV_ENTRIES; i++) {
907 card = AP_QID_CARD(device_matrix->device[i].qid);
908 dom = AP_QID_QUEUE(device_matrix->device[i].qid);
909 if (device_matrix->device[i].online &&
910 device_matrix->device[i].functions & 0x04) {
911 /* an enabled CCA Coprocessor card */
912 /* try cached mkvp */
913 if (mkvp_cache_fetch(card, dom, &mkvp) == 0 &&
914 t->mkvp == mkvp) {
915 if (!verify)
916 break;
917 /* verify: fetch mkvp from adapter */
918 if (fetch_mkvp(card, dom, &mkvp) == 0) {
919 mkvp_cache_update(card, dom, mkvp);
920 if (t->mkvp == mkvp)
921 break;
922 }
923 }
924 } else {
925 /* Card is offline and/or not a CCA card. */
926 /* del mkvp entry from cache if it exists */
927 mkvp_cache_scrub(card, dom);
928 }
929 }
930 if (i >= MAX_ZDEV_ENTRIES) {
931 /* nothing found, so this time without cache */
932 for (i = 0; i < MAX_ZDEV_ENTRIES; i++) {
933 if (!(device_matrix->device[i].online &&
934 device_matrix->device[i].functions & 0x04))
935 continue;
936 card = AP_QID_CARD(device_matrix->device[i].qid);
937 dom = AP_QID_QUEUE(device_matrix->device[i].qid);
938 /* fresh fetch mkvp from adapter */
939 if (fetch_mkvp(card, dom, &mkvp) == 0) {
940 mkvp_cache_update(card, dom, mkvp);
941 if (t->mkvp == mkvp)
942 break;
943 }
944 }
945 }
946 if (i < MAX_ZDEV_ENTRIES) {
947 if (pcardnr)
948 *pcardnr = card;
949 if (pdomain)
950 *pdomain = dom;
951 rc = 0;
952 } else
953 rc = -ENODEV;
954
955 kfree(device_matrix);
956 return rc;
957}
958EXPORT_SYMBOL(pkey_findcard);
959
960/*
961 * Find card and transform secure key into protected key.
962 */
963int pkey_skey2pkey(const struct pkey_seckey *seckey,
964 struct pkey_protkey *protkey)
965{
966 u16 cardnr, domain;
967 int rc, verify;
968
969 /*
970 * The pkey_sec2protkey call may fail when a card has been
971 * addressed where the master key was changed after last fetch
972 * of the mkvp into the cache. So first try without verify then
973 * with verify enabled (thus refreshing the mkvp for each card).
974 */
975 for (verify = 0; verify < 2; verify++) {
976 rc = pkey_findcard(seckey, &cardnr, &domain, verify);
977 if (rc)
978 continue;
979 rc = pkey_sec2protkey(cardnr, domain, seckey, protkey);
980 if (rc == 0)
981 break;
982 }
983
984 if (rc)
985 DEBUG_DBG("pkey_skey2pkey failed rc=%d\n", rc);
986
987 return rc;
988}
989EXPORT_SYMBOL(pkey_skey2pkey);
990
991/*
992 * File io functions
993 */
994
995static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
996 unsigned long arg)
997{
998 int rc;
999
1000 switch (cmd) {
1001 case PKEY_GENSECK: {
1002 struct pkey_genseck __user *ugs = (void __user *) arg;
1003 struct pkey_genseck kgs;
1004
1005 if (copy_from_user(&kgs, ugs, sizeof(kgs)))
1006 return -EFAULT;
1007 rc = pkey_genseckey(kgs.cardnr, kgs.domain,
1008 kgs.keytype, &kgs.seckey);
1009 DEBUG_DBG("pkey_ioctl pkey_genseckey()=%d\n", rc);
1010 if (rc)
1011 break;
1012 if (copy_to_user(ugs, &kgs, sizeof(kgs)))
1013 return -EFAULT;
1014 break;
1015 }
1016 case PKEY_CLR2SECK: {
1017 struct pkey_clr2seck __user *ucs = (void __user *) arg;
1018 struct pkey_clr2seck kcs;
1019
1020 if (copy_from_user(&kcs, ucs, sizeof(kcs)))
1021 return -EFAULT;
1022 rc = pkey_clr2seckey(kcs.cardnr, kcs.domain, kcs.keytype,
1023 &kcs.clrkey, &kcs.seckey);
1024 DEBUG_DBG("pkey_ioctl pkey_clr2seckey()=%d\n", rc);
1025 if (rc)
1026 break;
1027 if (copy_to_user(ucs, &kcs, sizeof(kcs)))
1028 return -EFAULT;
1029 memzero_explicit(&kcs, sizeof(kcs));
1030 break;
1031 }
1032 case PKEY_SEC2PROTK: {
1033 struct pkey_sec2protk __user *usp = (void __user *) arg;
1034 struct pkey_sec2protk ksp;
1035
1036 if (copy_from_user(&ksp, usp, sizeof(ksp)))
1037 return -EFAULT;
1038 rc = pkey_sec2protkey(ksp.cardnr, ksp.domain,
1039 &ksp.seckey, &ksp.protkey);
1040 DEBUG_DBG("pkey_ioctl pkey_sec2protkey()=%d\n", rc);
1041 if (rc)
1042 break;
1043 if (copy_to_user(usp, &ksp, sizeof(ksp)))
1044 return -EFAULT;
1045 break;
1046 }
1047 case PKEY_CLR2PROTK: {
1048 struct pkey_clr2protk __user *ucp = (void __user *) arg;
1049 struct pkey_clr2protk kcp;
1050
1051 if (copy_from_user(&kcp, ucp, sizeof(kcp)))
1052 return -EFAULT;
1053 rc = pkey_clr2protkey(kcp.keytype,
1054 &kcp.clrkey, &kcp.protkey);
1055 DEBUG_DBG("pkey_ioctl pkey_clr2protkey()=%d\n", rc);
1056 if (rc)
1057 break;
1058 if (copy_to_user(ucp, &kcp, sizeof(kcp)))
1059 return -EFAULT;
1060 memzero_explicit(&kcp, sizeof(kcp));
1061 break;
1062 }
1063 case PKEY_FINDCARD: {
1064 struct pkey_findcard __user *ufc = (void __user *) arg;
1065 struct pkey_findcard kfc;
1066
1067 if (copy_from_user(&kfc, ufc, sizeof(kfc)))
1068 return -EFAULT;
1069 rc = pkey_findcard(&kfc.seckey,
1070 &kfc.cardnr, &kfc.domain, 1);
1071 DEBUG_DBG("pkey_ioctl pkey_findcard()=%d\n", rc);
1072 if (rc)
1073 break;
1074 if (copy_to_user(ufc, &kfc, sizeof(kfc)))
1075 return -EFAULT;
1076 break;
1077 }
1078 case PKEY_SKEY2PKEY: {
1079 struct pkey_skey2pkey __user *usp = (void __user *) arg;
1080 struct pkey_skey2pkey ksp;
1081
1082 if (copy_from_user(&ksp, usp, sizeof(ksp)))
1083 return -EFAULT;
1084 rc = pkey_skey2pkey(&ksp.seckey, &ksp.protkey);
1085 DEBUG_DBG("pkey_ioctl pkey_skey2pkey()=%d\n", rc);
1086 if (rc)
1087 break;
1088 if (copy_to_user(usp, &ksp, sizeof(ksp)))
1089 return -EFAULT;
1090 break;
1091 }
1092 default:
1093 /* unknown/unsupported ioctl cmd */
1094 return -ENOTTY;
1095 }
1096
1097 return rc;
1098}
1099
1100/*
1101 * Sysfs and file io operations
1102 */
1103static const struct file_operations pkey_fops = {
1104 .owner = THIS_MODULE,
1105 .open = nonseekable_open,
1106 .llseek = no_llseek,
1107 .unlocked_ioctl = pkey_unlocked_ioctl,
1108};
1109
1110static struct miscdevice pkey_dev = {
1111 .name = "pkey",
1112 .minor = MISC_DYNAMIC_MINOR,
1113 .mode = 0666,
1114 .fops = &pkey_fops,
1115};
1116
1117/*
1118 * Module init
1119 */
1120int __init pkey_init(void)
1121{
1122 cpacf_mask_t pckmo_functions;
1123
1124 /* check for pckmo instructions available */
1125 if (!cpacf_query(CPACF_PCKMO, &pckmo_functions))
1126 return -EOPNOTSUPP;
1127 if (!cpacf_test_func(&pckmo_functions, CPACF_PCKMO_ENC_AES_128_KEY) ||
1128 !cpacf_test_func(&pckmo_functions, CPACF_PCKMO_ENC_AES_192_KEY) ||
1129 !cpacf_test_func(&pckmo_functions, CPACF_PCKMO_ENC_AES_256_KEY))
1130 return -EOPNOTSUPP;
1131
1132 pkey_debug_init();
1133
1134 return misc_register(&pkey_dev);
1135}
1136
1137/*
1138 * Module exit
1139 */
1140static void __exit pkey_exit(void)
1141{
1142 misc_deregister(&pkey_dev);
1143 mkvp_cache_free();
1144 pkey_debug_exit();
1145}
1146
1147module_init(pkey_init);
1148module_exit(pkey_exit);