aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2006-09-20 09:58:32 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-09-20 09:58:32 -0400
commit6684af1a07a1f88f3970bc90e5aed173d39168db (patch)
treede3056173598cced75379f04427702497466b515 /drivers/s390/crypto
parent963ed931c3fd18082bfde0e8704a28955663abf4 (diff)
[S390] zcrypt PCICC, PCIXCC coprocessor card ap bus drivers.
Signed-off-by: Ralph Wuerthner <rwuerthn@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/crypto')
-rw-r--r--drivers/s390/crypto/zcrypt_cca_key.h350
-rw-r--r--drivers/s390/crypto/zcrypt_pcicc.c630
-rw-r--r--drivers/s390/crypto/zcrypt_pcicc.h176
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c714
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.h79
5 files changed, 1949 insertions, 0 deletions
diff --git a/drivers/s390/crypto/zcrypt_cca_key.h b/drivers/s390/crypto/zcrypt_cca_key.h
new file mode 100644
index 000000000000..c80f40d44197
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_cca_key.h
@@ -0,0 +1,350 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_cca_key.h
3 *
4 * zcrypt 2.0.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#ifndef _ZCRYPT_CCA_KEY_H_
29#define _ZCRYPT_CCA_KEY_H_
30
31struct T6_keyBlock_hdr {
32 unsigned short blen;
33 unsigned short ulen;
34 unsigned short flags;
35};
36
37/**
38 * mapping for the cca private ME key token.
39 * Three parts of interest here: the header, the private section and
40 * the public section.
41 *
42 * mapping for the cca key token header
43 */
44struct cca_token_hdr {
45 unsigned char token_identifier;
46 unsigned char version;
47 unsigned short token_length;
48 unsigned char reserved[4];
49} __attribute__((packed));
50
51#define CCA_TKN_HDR_ID_EXT 0x1E
52
53/**
54 * mapping for the cca private ME section
55 */
56struct cca_private_ext_ME_sec {
57 unsigned char section_identifier;
58 unsigned char version;
59 unsigned short section_length;
60 unsigned char private_key_hash[20];
61 unsigned char reserved1[4];
62 unsigned char key_format;
63 unsigned char reserved2;
64 unsigned char key_name_hash[20];
65 unsigned char key_use_flags[4];
66 unsigned char reserved3[6];
67 unsigned char reserved4[24];
68 unsigned char confounder[24];
69 unsigned char exponent[128];
70 unsigned char modulus[128];
71} __attribute__((packed));
72
73#define CCA_PVT_USAGE_ALL 0x80
74
75/**
76 * mapping for the cca public section
77 * In a private key, the modulus doesn't appear in the public
78 * section. So, an arbitrary public exponent of 0x010001 will be
79 * used, for a section length of 0x0F always.
80 */
81struct cca_public_sec {
82 unsigned char section_identifier;
83 unsigned char version;
84 unsigned short section_length;
85 unsigned char reserved[2];
86 unsigned short exponent_len;
87 unsigned short modulus_bit_len;
88 unsigned short modulus_byte_len; /* In a private key, this is 0 */
89} __attribute__((packed));
90
91/**
92 * mapping for the cca private CRT key 'token'
93 * The first three parts (the only parts considered in this release)
94 * are: the header, the private section and the public section.
95 * The header and public section are the same as for the
96 * struct cca_private_ext_ME
97 *
98 * Following the structure are the quantities p, q, dp, dq, u, pad,
99 * and modulus, in that order, where pad_len is the modulo 8
100 * complement of the residue modulo 8 of the sum of
101 * (p_len + q_len + dp_len + dq_len + u_len).
102 */
103struct cca_pvt_ext_CRT_sec {
104 unsigned char section_identifier;
105 unsigned char version;
106 unsigned short section_length;
107 unsigned char private_key_hash[20];
108 unsigned char reserved1[4];
109 unsigned char key_format;
110 unsigned char reserved2;
111 unsigned char key_name_hash[20];
112 unsigned char key_use_flags[4];
113 unsigned short p_len;
114 unsigned short q_len;
115 unsigned short dp_len;
116 unsigned short dq_len;
117 unsigned short u_len;
118 unsigned short mod_len;
119 unsigned char reserved3[4];
120 unsigned short pad_len;
121 unsigned char reserved4[52];
122 unsigned char confounder[8];
123} __attribute__((packed));
124
125#define CCA_PVT_EXT_CRT_SEC_ID_PVT 0x08
126#define CCA_PVT_EXT_CRT_SEC_FMT_CL 0x40
127
128/**
129 * Set up private key fields of a type6 MEX message.
130 * Note that all numerics in the key token are big-endian,
131 * while the entries in the key block header are little-endian.
132 *
133 * @mex: pointer to user input data
134 * @p: pointer to memory area for the key
135 *
136 * Returns the size of the key area or -EFAULT
137 */
138static inline int zcrypt_type6_mex_key_de(struct ica_rsa_modexpo *mex,
139 void *p, int big_endian)
140{
141 static struct cca_token_hdr static_pvt_me_hdr = {
142 .token_identifier = 0x1E,
143 .token_length = 0x0183,
144 };
145 static struct cca_private_ext_ME_sec static_pvt_me_sec = {
146 .section_identifier = 0x02,
147 .section_length = 0x016C,
148 .key_use_flags = {0x80,0x00,0x00,0x00},
149 };
150 static struct cca_public_sec static_pub_me_sec = {
151 .section_identifier = 0x04,
152 .section_length = 0x000F,
153 .exponent_len = 0x0003,
154 };
155 static char pk_exponent[3] = { 0x01, 0x00, 0x01 };
156 struct {
157 struct T6_keyBlock_hdr t6_hdr;
158 struct cca_token_hdr pvtMeHdr;
159 struct cca_private_ext_ME_sec pvtMeSec;
160 struct cca_public_sec pubMeSec;
161 char exponent[3];
162 } __attribute__((packed)) *key = p;
163 unsigned char *temp;
164
165 memset(key, 0, sizeof(*key));
166
167 if (big_endian) {
168 key->t6_hdr.blen = cpu_to_be16(0x189);
169 key->t6_hdr.ulen = cpu_to_be16(0x189 - 2);
170 } else {
171 key->t6_hdr.blen = cpu_to_le16(0x189);
172 key->t6_hdr.ulen = cpu_to_le16(0x189 - 2);
173 }
174 key->pvtMeHdr = static_pvt_me_hdr;
175 key->pvtMeSec = static_pvt_me_sec;
176 key->pubMeSec = static_pub_me_sec;
177 /**
178 * In a private key, the modulus doesn't appear in the public
179 * section. So, an arbitrary public exponent of 0x010001 will be
180 * used.
181 */
182 memcpy(key->exponent, pk_exponent, 3);
183
184 /* key parameter block */
185 temp = key->pvtMeSec.exponent +
186 sizeof(key->pvtMeSec.exponent) - mex->inputdatalength;
187 if (copy_from_user(temp, mex->b_key, mex->inputdatalength))
188 return -EFAULT;
189
190 /* modulus */
191 temp = key->pvtMeSec.modulus +
192 sizeof(key->pvtMeSec.modulus) - mex->inputdatalength;
193 if (copy_from_user(temp, mex->n_modulus, mex->inputdatalength))
194 return -EFAULT;
195 key->pubMeSec.modulus_bit_len = 8 * mex->inputdatalength;
196 return sizeof(*key);
197}
198
199/**
200 * Set up private key fields of a type6 MEX message. The _pad variant
201 * strips leading zeroes from the b_key.
202 * Note that all numerics in the key token are big-endian,
203 * while the entries in the key block header are little-endian.
204 *
205 * @mex: pointer to user input data
206 * @p: pointer to memory area for the key
207 *
208 * Returns the size of the key area or -EFAULT
209 */
210static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo *mex,
211 void *p, int big_endian)
212{
213 static struct cca_token_hdr static_pub_hdr = {
214 .token_identifier = 0x1E,
215 };
216 static struct cca_public_sec static_pub_sec = {
217 .section_identifier = 0x04,
218 };
219 struct {
220 struct T6_keyBlock_hdr t6_hdr;
221 struct cca_token_hdr pubHdr;
222 struct cca_public_sec pubSec;
223 char exponent[0];
224 } __attribute__((packed)) *key = p;
225 unsigned char *temp;
226 int i;
227
228 memset(key, 0, sizeof(*key));
229
230 key->pubHdr = static_pub_hdr;
231 key->pubSec = static_pub_sec;
232
233 /* key parameter block */
234 temp = key->exponent;
235 if (copy_from_user(temp, mex->b_key, mex->inputdatalength))
236 return -EFAULT;
237 /* Strip leading zeroes from b_key. */
238 for (i = 0; i < mex->inputdatalength; i++)
239 if (temp[i])
240 break;
241 if (i >= mex->inputdatalength)
242 return -EINVAL;
243 memmove(temp, temp + i, mex->inputdatalength - i);
244 temp += mex->inputdatalength - i;
245 /* modulus */
246 if (copy_from_user(temp, mex->n_modulus, mex->inputdatalength))
247 return -EFAULT;
248
249 key->pubSec.modulus_bit_len = 8 * mex->inputdatalength;
250 key->pubSec.modulus_byte_len = mex->inputdatalength;
251 key->pubSec.exponent_len = mex->inputdatalength - i;
252 key->pubSec.section_length = sizeof(key->pubSec) +
253 2*mex->inputdatalength - i;
254 key->pubHdr.token_length =
255 key->pubSec.section_length + sizeof(key->pubHdr);
256 if (big_endian) {
257 key->t6_hdr.ulen = cpu_to_be16(key->pubHdr.token_length + 4);
258 key->t6_hdr.blen = cpu_to_be16(key->pubHdr.token_length + 6);
259 } else {
260 key->t6_hdr.ulen = cpu_to_le16(key->pubHdr.token_length + 4);
261 key->t6_hdr.blen = cpu_to_le16(key->pubHdr.token_length + 6);
262 }
263 return sizeof(*key) + 2*mex->inputdatalength - i;
264}
265
266/**
267 * Set up private key fields of a type6 CRT message.
268 * Note that all numerics in the key token are big-endian,
269 * while the entries in the key block header are little-endian.
270 *
271 * @mex: pointer to user input data
272 * @p: pointer to memory area for the key
273 *
274 * Returns the size of the key area or -EFAULT
275 */
276static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt,
277 void *p, int big_endian)
278{
279 static struct cca_public_sec static_cca_pub_sec = {
280 .section_identifier = 4,
281 .section_length = 0x000f,
282 .exponent_len = 0x0003,
283 };
284 static char pk_exponent[3] = { 0x01, 0x00, 0x01 };
285 struct {
286 struct T6_keyBlock_hdr t6_hdr;
287 struct cca_token_hdr token;
288 struct cca_pvt_ext_CRT_sec pvt;
289 char key_parts[0];
290 } __attribute__((packed)) *key = p;
291 struct cca_public_sec *pub;
292 int short_len, long_len, pad_len, key_len, size;
293
294 memset(key, 0, sizeof(*key));
295
296 short_len = crt->inputdatalength / 2;
297 long_len = short_len + 8;
298 pad_len = -(3*long_len + 2*short_len) & 7;
299 key_len = 3*long_len + 2*short_len + pad_len + crt->inputdatalength;
300 size = sizeof(*key) + key_len + sizeof(*pub) + 3;
301
302 /* parameter block.key block */
303 if (big_endian) {
304 key->t6_hdr.blen = cpu_to_be16(size);
305 key->t6_hdr.ulen = cpu_to_be16(size - 2);
306 } else {
307 key->t6_hdr.blen = cpu_to_le16(size);
308 key->t6_hdr.ulen = cpu_to_le16(size - 2);
309 }
310
311 /* key token header */
312 key->token.token_identifier = CCA_TKN_HDR_ID_EXT;
313 key->token.token_length = size - 6;
314
315 /* private section */
316 key->pvt.section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT;
317 key->pvt.section_length = sizeof(key->pvt) + key_len;
318 key->pvt.key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL;
319 key->pvt.key_use_flags[0] = CCA_PVT_USAGE_ALL;
320 key->pvt.p_len = key->pvt.dp_len = key->pvt.u_len = long_len;
321 key->pvt.q_len = key->pvt.dq_len = short_len;
322 key->pvt.mod_len = crt->inputdatalength;
323 key->pvt.pad_len = pad_len;
324
325 /* key parts */
326 if (copy_from_user(key->key_parts, crt->np_prime, long_len) ||
327 copy_from_user(key->key_parts + long_len,
328 crt->nq_prime, short_len) ||
329 copy_from_user(key->key_parts + long_len + short_len,
330 crt->bp_key, long_len) ||
331 copy_from_user(key->key_parts + 2*long_len + short_len,
332 crt->bq_key, short_len) ||
333 copy_from_user(key->key_parts + 2*long_len + 2*short_len,
334 crt->u_mult_inv, long_len))
335 return -EFAULT;
336 memset(key->key_parts + 3*long_len + 2*short_len + pad_len,
337 0xff, crt->inputdatalength);
338 pub = (struct cca_public_sec *)(key->key_parts + key_len);
339 *pub = static_cca_pub_sec;
340 pub->modulus_bit_len = 8 * crt->inputdatalength;
341 /**
342 * In a private key, the modulus doesn't appear in the public
343 * section. So, an arbitrary public exponent of 0x010001 will be
344 * used.
345 */
346 memcpy((char *) (pub + 1), pk_exponent, 3);
347 return size;
348}
349
350#endif /* _ZCRYPT_CCA_KEY_H_ */
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c
new file mode 100644
index 000000000000..900362983fec
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_pcicc.c
@@ -0,0 +1,630 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_pcicc.c
3 *
4 * zcrypt 2.0.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 * Ralph Wuerthner <rwuerthn@de.ibm.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/err.h>
32#include <asm/atomic.h>
33#include <asm/uaccess.h>
34
35#include "ap_bus.h"
36#include "zcrypt_api.h"
37#include "zcrypt_error.h"
38#include "zcrypt_pcicc.h"
39#include "zcrypt_cca_key.h"
40
41#define PCICC_MIN_MOD_SIZE 64 /* 512 bits */
42#define PCICC_MAX_MOD_SIZE_OLD 128 /* 1024 bits */
43#define PCICC_MAX_MOD_SIZE 256 /* 2048 bits */
44
45/**
46 * PCICC cards need a speed rating of 0. This keeps them at the end of
47 * the zcrypt device list (see zcrypt_api.c). PCICC cards are only
48 * used if no other cards are present because they are slow and can only
49 * cope with PKCS12 padded requests. The logic is queer. PKCS11 padded
50 * requests are rejected. The modexpo function encrypts PKCS12 padded data
51 * and decrypts any non-PKCS12 padded data (except PKCS11) in the assumption
52 * that it's encrypted PKCS12 data. The modexpo_crt function always decrypts
53 * the data in the assumption that its PKCS12 encrypted data.
54 */
55#define PCICC_SPEED_RATING 0
56
57#define PCICC_MAX_MESSAGE_SIZE 0x710 /* max size type6 v1 crt message */
58#define PCICC_MAX_RESPONSE_SIZE 0x710 /* max size type86 v1 reply */
59
60#define PCICC_CLEANUP_TIME (15*HZ)
61
62static struct ap_device_id zcrypt_pcicc_ids[] = {
63 { AP_DEVICE(AP_DEVICE_TYPE_PCICC) },
64 { /* end of list */ },
65};
66
67#ifndef CONFIG_ZCRYPT_MONOLITHIC
68MODULE_DEVICE_TABLE(ap, zcrypt_pcicc_ids);
69MODULE_AUTHOR("IBM Corporation");
70MODULE_DESCRIPTION("PCICC Cryptographic Coprocessor device driver, "
71 "Copyright 2001, 2006 IBM Corporation");
72MODULE_LICENSE("GPL");
73#endif
74
75static int zcrypt_pcicc_probe(struct ap_device *ap_dev);
76static void zcrypt_pcicc_remove(struct ap_device *ap_dev);
77static void zcrypt_pcicc_receive(struct ap_device *, struct ap_message *,
78 struct ap_message *);
79
80static struct ap_driver zcrypt_pcicc_driver = {
81 .probe = zcrypt_pcicc_probe,
82 .remove = zcrypt_pcicc_remove,
83 .receive = zcrypt_pcicc_receive,
84 .ids = zcrypt_pcicc_ids,
85};
86
87/**
88 * The following is used to initialize the CPRB passed to the PCICC card
89 * in a type6 message. The 3 fields that must be filled in at execution
90 * time are req_parml, rpl_parml and usage_domain. Note that all three
91 * fields are *little*-endian. Actually, everything about this interface
92 * is ascii/little-endian, since the device has 'Intel inside'.
93 *
94 * The CPRB is followed immediately by the parm block.
95 * The parm block contains:
96 * - function code ('PD' 0x5044 or 'PK' 0x504B)
97 * - rule block (0x0A00 'PKCS-1.2' or 0x0A00 'ZERO-PAD')
98 * - VUD block
99 */
100static struct CPRB static_cprb = {
101 .cprb_len = __constant_cpu_to_le16(0x0070),
102 .cprb_ver_id = 0x41,
103 .func_id = {0x54,0x32},
104 .checkpoint_flag= 0x01,
105 .svr_namel = __constant_cpu_to_le16(0x0008),
106 .svr_name = {'I','C','S','F',' ',' ',' ',' '}
107};
108
109/**
110 * Check the message for PKCS11 padding.
111 */
112static inline int is_PKCS11_padded(unsigned char *buffer, int length)
113{
114 int i;
115 if ((buffer[0] != 0x00) || (buffer[1] != 0x01))
116 return 0;
117 for (i = 2; i < length; i++)
118 if (buffer[i] != 0xFF)
119 break;
120 if (i < 10 || i == length)
121 return 0;
122 if (buffer[i] != 0x00)
123 return 0;
124 return 1;
125}
126
127/**
128 * Check the message for PKCS12 padding.
129 */
130static inline int is_PKCS12_padded(unsigned char *buffer, int length)
131{
132 int i;
133 if ((buffer[0] != 0x00) || (buffer[1] != 0x02))
134 return 0;
135 for (i = 2; i < length; i++)
136 if (buffer[i] == 0x00)
137 break;
138 if ((i < 10) || (i == length))
139 return 0;
140 if (buffer[i] != 0x00)
141 return 0;
142 return 1;
143}
144
145/**
146 * Convert a ICAMEX message to a type6 MEX message.
147 *
148 * @zdev: crypto device pointer
149 * @zreq: crypto request pointer
150 * @mex: pointer to user input data
151 *
152 * Returns 0 on success or -EFAULT.
153 */
154static int ICAMEX_msg_to_type6MEX_msg(struct zcrypt_device *zdev,
155 struct ap_message *ap_msg,
156 struct ica_rsa_modexpo *mex)
157{
158 static struct type6_hdr static_type6_hdr = {
159 .type = 0x06,
160 .offset1 = 0x00000058,
161 .agent_id = {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
162 0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
163 .function_code = {'P','K'},
164 };
165 static struct function_and_rules_block static_pke_function_and_rules ={
166 .function_code = {'P','K'},
167 .ulen = __constant_cpu_to_le16(10),
168 .only_rule = {'P','K','C','S','-','1','.','2'}
169 };
170 struct {
171 struct type6_hdr hdr;
172 struct CPRB cprb;
173 struct function_and_rules_block fr;
174 unsigned short length;
175 char text[0];
176 } __attribute__((packed)) *msg = ap_msg->message;
177 int vud_len, pad_len, size;
178
179 /* VUD.ciphertext */
180 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
181 return -EFAULT;
182
183 if (is_PKCS11_padded(msg->text, mex->inputdatalength))
184 return -EINVAL;
185
186 /* static message header and f&r */
187 msg->hdr = static_type6_hdr;
188 msg->fr = static_pke_function_and_rules;
189
190 if (is_PKCS12_padded(msg->text, mex->inputdatalength)) {
191 /* strip the padding and adjust the data length */
192 pad_len = strnlen(msg->text + 2, mex->inputdatalength - 2) + 3;
193 if (pad_len <= 9 || pad_len >= mex->inputdatalength)
194 return -ENODEV;
195 vud_len = mex->inputdatalength - pad_len;
196 memmove(msg->text, msg->text + pad_len, vud_len);
197 msg->length = cpu_to_le16(vud_len + 2);
198
199 /* Set up key after the variable length text. */
200 size = zcrypt_type6_mex_key_en(mex, msg->text + vud_len, 0);
201 if (size < 0)
202 return size;
203 size += sizeof(*msg) + vud_len; /* total size of msg */
204 } else {
205 vud_len = mex->inputdatalength;
206 msg->length = cpu_to_le16(2 + vud_len);
207
208 msg->hdr.function_code[1] = 'D';
209 msg->fr.function_code[1] = 'D';
210
211 /* Set up key after the variable length text. */
212 size = zcrypt_type6_mex_key_de(mex, msg->text + vud_len, 0);
213 if (size < 0)
214 return size;
215 size += sizeof(*msg) + vud_len; /* total size of msg */
216 }
217
218 /* message header, cprb and f&r */
219 msg->hdr.ToCardLen1 = (size - sizeof(msg->hdr) + 3) & -4;
220 msg->hdr.FromCardLen1 = PCICC_MAX_RESPONSE_SIZE - sizeof(msg->hdr);
221
222 msg->cprb = static_cprb;
223 msg->cprb.usage_domain[0]= AP_QID_QUEUE(zdev->ap_dev->qid);
224 msg->cprb.req_parml = cpu_to_le16(size - sizeof(msg->hdr) -
225 sizeof(msg->cprb));
226 msg->cprb.rpl_parml = cpu_to_le16(msg->hdr.FromCardLen1);
227
228 ap_msg->length = (size + 3) & -4;
229 return 0;
230}
231
232/**
233 * Convert a ICACRT message to a type6 CRT message.
234 *
235 * @zdev: crypto device pointer
236 * @zreq: crypto request pointer
237 * @crt: pointer to user input data
238 *
239 * Returns 0 on success or -EFAULT.
240 */
241static int ICACRT_msg_to_type6CRT_msg(struct zcrypt_device *zdev,
242 struct ap_message *ap_msg,
243 struct ica_rsa_modexpo_crt *crt)
244{
245 static struct type6_hdr static_type6_hdr = {
246 .type = 0x06,
247 .offset1 = 0x00000058,
248 .agent_id = {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
249 0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
250 .function_code = {'P','D'},
251 };
252 static struct function_and_rules_block static_pkd_function_and_rules ={
253 .function_code = {'P','D'},
254 .ulen = __constant_cpu_to_le16(10),
255 .only_rule = {'P','K','C','S','-','1','.','2'}
256 };
257 struct {
258 struct type6_hdr hdr;
259 struct CPRB cprb;
260 struct function_and_rules_block fr;
261 unsigned short length;
262 char text[0];
263 } __attribute__((packed)) *msg = ap_msg->message;
264 int size;
265
266 /* VUD.ciphertext */
267 msg->length = cpu_to_le16(2 + crt->inputdatalength);
268 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
269 return -EFAULT;
270
271 if (is_PKCS11_padded(msg->text, crt->inputdatalength))
272 return -EINVAL;
273
274 /* Set up key after the variable length text. */
275 size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 0);
276 if (size < 0)
277 return size;
278 size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */
279
280 /* message header, cprb and f&r */
281 msg->hdr = static_type6_hdr;
282 msg->hdr.ToCardLen1 = (size - sizeof(msg->hdr) + 3) & -4;
283 msg->hdr.FromCardLen1 = PCICC_MAX_RESPONSE_SIZE - sizeof(msg->hdr);
284
285 msg->cprb = static_cprb;
286 msg->cprb.usage_domain[0] = AP_QID_QUEUE(zdev->ap_dev->qid);
287 msg->cprb.req_parml = msg->cprb.rpl_parml =
288 cpu_to_le16(size - sizeof(msg->hdr) - sizeof(msg->cprb));
289
290 msg->fr = static_pkd_function_and_rules;
291
292 ap_msg->length = (size + 3) & -4;
293 return 0;
294}
295
296/**
297 * Copy results from a type 86 reply message back to user space.
298 *
299 * @zdev: crypto device pointer
300 * @reply: reply AP message.
301 * @data: pointer to user output data
302 * @length: size of user output data
303 *
304 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
305 */
306struct type86_reply {
307 struct type86_hdr hdr;
308 struct type86_fmt2_ext fmt2;
309 struct CPRB cprb;
310 unsigned char pad[4]; /* 4 byte function code/rules block ? */
311 unsigned short length;
312 char text[0];
313} __attribute__((packed));
314
315static int convert_type86(struct zcrypt_device *zdev,
316 struct ap_message *reply,
317 char __user *outputdata,
318 unsigned int outputdatalength)
319{
320 static unsigned char static_pad[] = {
321 0x00,0x02,
322 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
323 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
324 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
325 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
326 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
327 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
328 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
329 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
330 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
331 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
332 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
333 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
334 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
335 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
336 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
337 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
338 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
339 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
340 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
341 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
342 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
343 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
344 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
345 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
346 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
347 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
348 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
349 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
350 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
351 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
352 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
353 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
354 };
355 struct type86_reply *msg = reply->message;
356 unsigned short service_rc, service_rs;
357 unsigned int reply_len, pad_len;
358 char *data;
359
360 service_rc = le16_to_cpu(msg->cprb.ccp_rtcode);
361 if (unlikely(service_rc != 0)) {
362 service_rs = le16_to_cpu(msg->cprb.ccp_rscode);
363 if (service_rc == 8 && service_rs == 66) {
364 PDEBUG("Bad block format on PCICC\n");
365 return -EINVAL;
366 }
367 if (service_rc == 8 && service_rs == 65) {
368 PDEBUG("Probably an even modulus on PCICC\n");
369 return -EINVAL;
370 }
371 if (service_rc == 8 && service_rs == 770) {
372 PDEBUG("Invalid key length on PCICC\n");
373 zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
374 return -EAGAIN;
375 }
376 if (service_rc == 8 && service_rs == 783) {
377 PDEBUG("Extended bitlengths not enabled on PCICC\n");
378 zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
379 return -EAGAIN;
380 }
381 PRINTK("Unknown service rc/rs (PCICC): %d/%d\n",
382 service_rc, service_rs);
383 zdev->online = 0;
384 return -EAGAIN; /* repeat the request on a different device. */
385 }
386 data = msg->text;
387 reply_len = le16_to_cpu(msg->length) - 2;
388 if (reply_len > outputdatalength)
389 return -EINVAL;
390 /**
391 * For all encipher requests, the length of the ciphertext (reply_len)
392 * will always equal the modulus length. For MEX decipher requests
393 * the output needs to get padded. Minimum pad size is 10.
394 *
395 * Currently, the cases where padding will be added is for:
396 * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
397 * ZERO-PAD and CRT is only supported for PKD requests)
398 * - PCICC, always
399 */
400 pad_len = outputdatalength - reply_len;
401 if (pad_len > 0) {
402 if (pad_len < 10)
403 return -EINVAL;
404 /* 'restore' padding left in the PCICC/PCIXCC card. */
405 if (copy_to_user(outputdata, static_pad, pad_len - 1))
406 return -EFAULT;
407 if (put_user(0, outputdata + pad_len - 1))
408 return -EFAULT;
409 }
410 /* Copy the crypto response to user space. */
411 if (copy_to_user(outputdata + pad_len, data, reply_len))
412 return -EFAULT;
413 return 0;
414}
415
416static int convert_response(struct zcrypt_device *zdev,
417 struct ap_message *reply,
418 char __user *outputdata,
419 unsigned int outputdatalength)
420{
421 struct type86_reply *msg = reply->message;
422
423 /* Response type byte is the second byte in the response. */
424 switch (msg->hdr.type) {
425 case TYPE82_RSP_CODE:
426 case TYPE88_RSP_CODE:
427 return convert_error(zdev, reply);
428 case TYPE86_RSP_CODE:
429 if (msg->hdr.reply_code)
430 return convert_error(zdev, reply);
431 if (msg->cprb.cprb_ver_id == 0x01)
432 return convert_type86(zdev, reply,
433 outputdata, outputdatalength);
434 /* no break, incorrect cprb version is an unknown response */
435 default: /* Unknown response type, this should NEVER EVER happen */
436 PRINTK("Unrecognized Message Header: %08x%08x\n",
437 *(unsigned int *) reply->message,
438 *(unsigned int *) (reply->message+4));
439 zdev->online = 0;
440 return -EAGAIN; /* repeat the request on a different device. */
441 }
442}
443
444/**
445 * This function is called from the AP bus code after a crypto request
446 * "msg" has finished with the reply message "reply".
447 * It is called from tasklet context.
448 * @ap_dev: pointer to the AP device
449 * @msg: pointer to the AP message
450 * @reply: pointer to the AP reply message
451 */
452static void zcrypt_pcicc_receive(struct ap_device *ap_dev,
453 struct ap_message *msg,
454 struct ap_message *reply)
455{
456 static struct error_hdr error_reply = {
457 .type = TYPE82_RSP_CODE,
458 .reply_code = REP82_ERROR_MACHINE_FAILURE,
459 };
460 struct type86_reply *t86r = reply->message;
461 int length;
462
463 /* Copy the reply message to the request message buffer. */
464 if (IS_ERR(reply))
465 memcpy(msg->message, &error_reply, sizeof(error_reply));
466 else if (t86r->hdr.type == TYPE86_RSP_CODE &&
467 t86r->cprb.cprb_ver_id == 0x01) {
468 length = sizeof(struct type86_reply) + t86r->length - 2;
469 length = min(PCICC_MAX_RESPONSE_SIZE, length);
470 memcpy(msg->message, reply->message, length);
471 } else
472 memcpy(msg->message, reply->message, sizeof error_reply);
473 complete((struct completion *) msg->private);
474}
475
476static atomic_t zcrypt_step = ATOMIC_INIT(0);
477
478/**
479 * The request distributor calls this function if it picked the PCICC
480 * device to handle a modexpo request.
481 * @zdev: pointer to zcrypt_device structure that identifies the
482 * PCICC device to the request distributor
483 * @mex: pointer to the modexpo request buffer
484 */
485static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev,
486 struct ica_rsa_modexpo *mex)
487{
488 struct ap_message ap_msg;
489 struct completion work;
490 int rc;
491
492 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
493 if (!ap_msg.message)
494 return -ENOMEM;
495 ap_msg.length = PAGE_SIZE;
496 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
497 atomic_inc_return(&zcrypt_step);
498 ap_msg.private = &work;
499 rc = ICAMEX_msg_to_type6MEX_msg(zdev, &ap_msg, mex);
500 if (rc)
501 goto out_free;
502 init_completion(&work);
503 ap_queue_message(zdev->ap_dev, &ap_msg);
504 rc = wait_for_completion_interruptible_timeout(
505 &work, PCICC_CLEANUP_TIME);
506 if (rc > 0)
507 rc = convert_response(zdev, &ap_msg, mex->outputdata,
508 mex->outputdatalength);
509 else {
510 /* Signal pending or message timed out. */
511 ap_cancel_message(zdev->ap_dev, &ap_msg);
512 if (rc == 0)
513 /* Message timed out. */
514 rc = -ETIME;
515 }
516out_free:
517 free_page((unsigned long) ap_msg.message);
518 return rc;
519}
520
521/**
522 * The request distributor calls this function if it picked the PCICC
523 * device to handle a modexpo_crt request.
524 * @zdev: pointer to zcrypt_device structure that identifies the
525 * PCICC device to the request distributor
526 * @crt: pointer to the modexpoc_crt request buffer
527 */
528static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev,
529 struct ica_rsa_modexpo_crt *crt)
530{
531 struct ap_message ap_msg;
532 struct completion work;
533 int rc;
534
535 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
536 if (!ap_msg.message)
537 return -ENOMEM;
538 ap_msg.length = PAGE_SIZE;
539 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
540 atomic_inc_return(&zcrypt_step);
541 ap_msg.private = &work;
542 rc = ICACRT_msg_to_type6CRT_msg(zdev, &ap_msg, crt);
543 if (rc)
544 goto out_free;
545 init_completion(&work);
546 ap_queue_message(zdev->ap_dev, &ap_msg);
547 rc = wait_for_completion_interruptible_timeout(
548 &work, PCICC_CLEANUP_TIME);
549 if (rc > 0)
550 rc = convert_response(zdev, &ap_msg, crt->outputdata,
551 crt->outputdatalength);
552 else {
553 /* Signal pending or message timed out. */
554 ap_cancel_message(zdev->ap_dev, &ap_msg);
555 if (rc == 0)
556 /* Message timed out. */
557 rc = -ETIME;
558 }
559out_free:
560 free_page((unsigned long) ap_msg.message);
561 return rc;
562}
563
564/**
565 * The crypto operations for a PCICC card.
566 */
567static struct zcrypt_ops zcrypt_pcicc_ops = {
568 .rsa_modexpo = zcrypt_pcicc_modexpo,
569 .rsa_modexpo_crt = zcrypt_pcicc_modexpo_crt,
570};
571
572/**
573 * Probe function for PCICC cards. It always accepts the AP device
574 * since the bus_match already checked the hardware type.
575 * @ap_dev: pointer to the AP device.
576 */
577static int zcrypt_pcicc_probe(struct ap_device *ap_dev)
578{
579 struct zcrypt_device *zdev;
580 int rc;
581
582 zdev = zcrypt_device_alloc(PCICC_MAX_RESPONSE_SIZE);
583 if (!zdev)
584 return -ENOMEM;
585 zdev->ap_dev = ap_dev;
586 zdev->ops = &zcrypt_pcicc_ops;
587 zdev->online = 1;
588 zdev->user_space_type = ZCRYPT_PCICC;
589 zdev->type_string = "PCICC";
590 zdev->min_mod_size = PCICC_MIN_MOD_SIZE;
591 zdev->max_mod_size = PCICC_MAX_MOD_SIZE;
592 zdev->speed_rating = PCICC_SPEED_RATING;
593 ap_dev->reply = &zdev->reply;
594 ap_dev->private = zdev;
595 rc = zcrypt_device_register(zdev);
596 if (rc)
597 goto out_free;
598 return 0;
599
600 out_free:
601 ap_dev->private = NULL;
602 zcrypt_device_free(zdev);
603 return rc;
604}
605
606/**
607 * This is called to remove the extended PCICC driver information
608 * if an AP device is removed.
609 */
610static void zcrypt_pcicc_remove(struct ap_device *ap_dev)
611{
612 struct zcrypt_device *zdev = ap_dev->private;
613
614 zcrypt_device_unregister(zdev);
615}
616
617int __init zcrypt_pcicc_init(void)
618{
619 return ap_driver_register(&zcrypt_pcicc_driver, THIS_MODULE, "pcicc");
620}
621
622void zcrypt_pcicc_exit(void)
623{
624 ap_driver_unregister(&zcrypt_pcicc_driver);
625}
626
627#ifndef CONFIG_ZCRYPT_MONOLITHIC
628module_init(zcrypt_pcicc_init);
629module_exit(zcrypt_pcicc_exit);
630#endif
diff --git a/drivers/s390/crypto/zcrypt_pcicc.h b/drivers/s390/crypto/zcrypt_pcicc.h
new file mode 100644
index 000000000000..027bafc7312a
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_pcicc.h
@@ -0,0 +1,176 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_pcicc.h
3 *
4 * zcrypt 2.0.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#ifndef _ZCRYPT_PCICC_H_
29#define _ZCRYPT_PCICC_H_
30
31/**
32 * The type 6 message family is associated with PCICC or PCIXCC cards.
33 *
34 * It contains a message header followed by a CPRB, both of which
35 * are described below.
36 *
37 * Note that all reserved fields must be zeroes.
38 */
39struct type6_hdr {
40 unsigned char reserved1; /* 0x00 */
41 unsigned char type; /* 0x06 */
42 unsigned char reserved2[2]; /* 0x0000 */
43 unsigned char right[4]; /* 0x00000000 */
44 unsigned char reserved3[2]; /* 0x0000 */
45 unsigned char reserved4[2]; /* 0x0000 */
46 unsigned char apfs[4]; /* 0x00000000 */
47 unsigned int offset1; /* 0x00000058 (offset to CPRB) */
48 unsigned int offset2; /* 0x00000000 */
49 unsigned int offset3; /* 0x00000000 */
50 unsigned int offset4; /* 0x00000000 */
51 unsigned char agent_id[16]; /* PCICC: */
52 /* 0x0100 */
53 /* 0x4343412d4150504c202020 */
54 /* 0x010101 */
55 /* PCIXCC: */
56 /* 0x4341000000000000 */
57 /* 0x0000000000000000 */
58 unsigned char rqid[2]; /* rqid. internal to 603 */
59 unsigned char reserved5[2]; /* 0x0000 */
60 unsigned char function_code[2]; /* for PKD, 0x5044 (ascii 'PD') */
61 unsigned char reserved6[2]; /* 0x0000 */
62 unsigned int ToCardLen1; /* (request CPRB len + 3) & -4 */
63 unsigned int ToCardLen2; /* db len 0x00000000 for PKD */
64 unsigned int ToCardLen3; /* 0x00000000 */
65 unsigned int ToCardLen4; /* 0x00000000 */
66 unsigned int FromCardLen1; /* response buffer length */
67 unsigned int FromCardLen2; /* db len 0x00000000 for PKD */
68 unsigned int FromCardLen3; /* 0x00000000 */
69 unsigned int FromCardLen4; /* 0x00000000 */
70} __attribute__((packed));
71
72/**
73 * CPRB
74 * Note that all shorts, ints and longs are little-endian.
75 * All pointer fields are 32-bits long, and mean nothing
76 *
77 * A request CPRB is followed by a request_parameter_block.
78 *
79 * The request (or reply) parameter block is organized thus:
80 * function code
81 * VUD block
82 * key block
83 */
84struct CPRB {
85 unsigned short cprb_len; /* CPRB length */
86 unsigned char cprb_ver_id; /* CPRB version id. */
87 unsigned char pad_000; /* Alignment pad byte. */
88 unsigned char srpi_rtcode[4]; /* SRPI return code LELONG */
89 unsigned char srpi_verb; /* SRPI verb type */
90 unsigned char flags; /* flags */
91 unsigned char func_id[2]; /* function id */
92 unsigned char checkpoint_flag; /* */
93 unsigned char resv2; /* reserved */
94 unsigned short req_parml; /* request parameter buffer */
95 /* length 16-bit little endian */
96 unsigned char req_parmp[4]; /* request parameter buffer *
97 * pointer (means nothing: the *
98 * parameter buffer follows *
99 * the CPRB). */
100 unsigned char req_datal[4]; /* request data buffer */
101 /* length ULELONG */
102 unsigned char req_datap[4]; /* request data buffer */
103 /* pointer */
104 unsigned short rpl_parml; /* reply parameter buffer */
105 /* length 16-bit little endian */
106 unsigned char pad_001[2]; /* Alignment pad bytes. ULESHORT */
107 unsigned char rpl_parmp[4]; /* reply parameter buffer *
108 * pointer (means nothing: the *
109 * parameter buffer follows *
110 * the CPRB). */
111 unsigned char rpl_datal[4]; /* reply data buffer len ULELONG */
112 unsigned char rpl_datap[4]; /* reply data buffer */
113 /* pointer */
114 unsigned short ccp_rscode; /* server reason code ULESHORT */
115 unsigned short ccp_rtcode; /* server return code ULESHORT */
116 unsigned char repd_parml[2]; /* replied parameter len ULESHORT*/
117 unsigned char mac_data_len[2]; /* Mac Data Length ULESHORT */
118 unsigned char repd_datal[4]; /* replied data length ULELONG */
119 unsigned char req_pc[2]; /* PC identifier */
120 unsigned char res_origin[8]; /* resource origin */
121 unsigned char mac_value[8]; /* Mac Value */
122 unsigned char logon_id[8]; /* Logon Identifier */
123 unsigned char usage_domain[2]; /* cdx */
124 unsigned char resv3[18]; /* reserved for requestor */
125 unsigned short svr_namel; /* server name length ULESHORT */
126 unsigned char svr_name[8]; /* server name */
127} __attribute__((packed));
128
129/**
130 * The type 86 message family is associated with PCICC and PCIXCC cards.
131 *
132 * It contains a message header followed by a CPRB. The CPRB is
133 * the same as the request CPRB, which is described above.
134 *
135 * If format is 1, an error condition exists and no data beyond
136 * the 8-byte message header is of interest.
137 *
138 * The non-error message is shown below.
139 *
140 * Note that all reserved fields must be zeroes.
141 */
142struct type86_hdr {
143 unsigned char reserved1; /* 0x00 */
144 unsigned char type; /* 0x86 */
145 unsigned char format; /* 0x01 (error) or 0x02 (ok) */
146 unsigned char reserved2; /* 0x00 */
147 unsigned char reply_code; /* reply code (see above) */
148 unsigned char reserved3[3]; /* 0x000000 */
149} __attribute__((packed));
150
151#define TYPE86_RSP_CODE 0x86
152#define TYPE86_FMT2 0x02
153
154struct type86_fmt2_ext {
155 unsigned char reserved[4]; /* 0x00000000 */
156 unsigned char apfs[4]; /* final status */
157 unsigned int count1; /* length of CPRB + parameters */
158 unsigned int offset1; /* offset to CPRB */
159 unsigned int count2; /* 0x00000000 */
160 unsigned int offset2; /* db offset 0x00000000 for PKD */
161 unsigned int count3; /* 0x00000000 */
162 unsigned int offset3; /* 0x00000000 */
163 unsigned int count4; /* 0x00000000 */
164 unsigned int offset4; /* 0x00000000 */
165} __attribute__((packed));
166
167struct function_and_rules_block {
168 unsigned char function_code[2];
169 unsigned short ulen;
170 unsigned char only_rule[8];
171} __attribute__((packed));
172
173int zcrypt_pcicc_init(void);
174void zcrypt_pcicc_exit(void);
175
176#endif /* _ZCRYPT_PCICC_H_ */
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
new file mode 100644
index 000000000000..6064cf58be43
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -0,0 +1,714 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_pcixcc.c
3 *
4 * zcrypt 2.0.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 * Ralph Wuerthner <rwuerthn@de.ibm.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/err.h>
32#include <linux/delay.h>
33#include <asm/atomic.h>
34#include <asm/uaccess.h>
35
36#include "ap_bus.h"
37#include "zcrypt_api.h"
38#include "zcrypt_error.h"
39#include "zcrypt_pcicc.h"
40#include "zcrypt_pcixcc.h"
41#include "zcrypt_cca_key.h"
42
43#define PCIXCC_MIN_MOD_SIZE 16 /* 128 bits */
44#define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */
45#define PCIXCC_MAX_MOD_SIZE 256 /* 2048 bits */
46
47#define PCIXCC_MCL2_SPEED_RATING 7870 /* FIXME: needs finetuning */
48#define PCIXCC_MCL3_SPEED_RATING 7870
49#define CEX2C_SPEED_RATING 8540
50
51#define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c /* max size type6 v2 crt message */
52#define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */
53
54#define PCIXCC_MAX_XCRB_MESSAGE_SIZE (12*1024)
55#define PCIXCC_MAX_XCRB_RESPONSE_SIZE PCIXCC_MAX_XCRB_MESSAGE_SIZE
56#define PCIXCC_MAX_XCRB_DATA_SIZE (11*1024)
57#define PCIXCC_MAX_XCRB_REPLY_SIZE (5*1024)
58
59#define PCIXCC_MAX_RESPONSE_SIZE PCIXCC_MAX_XCRB_RESPONSE_SIZE
60
61#define PCIXCC_CLEANUP_TIME (15*HZ)
62
63static struct ap_device_id zcrypt_pcixcc_ids[] = {
64 { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
65 { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
66 { /* end of list */ },
67};
68
69#ifndef CONFIG_ZCRYPT_MONOLITHIC
70MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
71MODULE_AUTHOR("IBM Corporation");
72MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, "
73 "Copyright 2001, 2006 IBM Corporation");
74MODULE_LICENSE("GPL");
75#endif
76
77static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
78static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
79static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *,
80 struct ap_message *);
81
82static struct ap_driver zcrypt_pcixcc_driver = {
83 .probe = zcrypt_pcixcc_probe,
84 .remove = zcrypt_pcixcc_remove,
85 .receive = zcrypt_pcixcc_receive,
86 .ids = zcrypt_pcixcc_ids,
87};
88
89/**
90 * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
91 * card in a type6 message. The 3 fields that must be filled in at execution
92 * time are req_parml, rpl_parml and usage_domain.
93 * Everything about this interface is ascii/big-endian, since the
94 * device does *not* have 'Intel inside'.
95 *
96 * The CPRBX is followed immediately by the parm block.
97 * The parm block contains:
98 * - function code ('PD' 0x5044 or 'PK' 0x504B)
99 * - rule block (one of:)
100 * + 0x000A 'PKCS-1.2' (MCL2 'PD')
101 * + 0x000A 'ZERO-PAD' (MCL2 'PK')
102 * + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
103 * + 0x000A 'MRP ' (MCL3 'PK' or CEX2C 'PK')
104 * - VUD block
105 */
106static struct CPRBX static_cprbx = {
107 .cprb_len = 0x00DC,
108 .cprb_ver_id = 0x02,
109 .func_id = {0x54,0x32},
110};
111
112/**
113 * Convert a ICAMEX message to a type6 MEX message.
114 *
115 * @zdev: crypto device pointer
116 * @ap_msg: pointer to AP message
117 * @mex: pointer to user input data
118 *
119 * Returns 0 on success or -EFAULT.
120 */
121static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev,
122 struct ap_message *ap_msg,
123 struct ica_rsa_modexpo *mex)
124{
125 static struct type6_hdr static_type6_hdrX = {
126 .type = 0x06,
127 .offset1 = 0x00000058,
128 .agent_id = {'C','A',},
129 .function_code = {'P','K'},
130 };
131 static struct function_and_rules_block static_pke_fnr = {
132 .function_code = {'P','K'},
133 .ulen = 10,
134 .only_rule = {'M','R','P',' ',' ',' ',' ',' '}
135 };
136 static struct function_and_rules_block static_pke_fnr_MCL2 = {
137 .function_code = {'P','K'},
138 .ulen = 10,
139 .only_rule = {'Z','E','R','O','-','P','A','D'}
140 };
141 struct {
142 struct type6_hdr hdr;
143 struct CPRBX cprbx;
144 struct function_and_rules_block fr;
145 unsigned short length;
146 char text[0];
147 } __attribute__((packed)) *msg = ap_msg->message;
148 int size;
149
150 /* VUD.ciphertext */
151 msg->length = mex->inputdatalength + 2;
152 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
153 return -EFAULT;
154
155 /* Set up key which is located after the variable length text. */
156 size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
157 if (size < 0)
158 return size;
159 size += sizeof(*msg) + mex->inputdatalength;
160
161 /* message header, cprbx and f&r */
162 msg->hdr = static_type6_hdrX;
163 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
164 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
165
166 msg->cprbx = static_cprbx;
167 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
168 msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
169
170 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
171 static_pke_fnr_MCL2 : static_pke_fnr;
172
173 msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
174
175 ap_msg->length = size;
176 return 0;
177}
178
179/**
180 * Convert a ICACRT message to a type6 CRT message.
181 *
182 * @zdev: crypto device pointer
183 * @ap_msg: pointer to AP message
184 * @crt: pointer to user input data
185 *
186 * Returns 0 on success or -EFAULT.
187 */
188static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
189 struct ap_message *ap_msg,
190 struct ica_rsa_modexpo_crt *crt)
191{
192 static struct type6_hdr static_type6_hdrX = {
193 .type = 0x06,
194 .offset1 = 0x00000058,
195 .agent_id = {'C','A',},
196 .function_code = {'P','D'},
197 };
198 static struct function_and_rules_block static_pkd_fnr = {
199 .function_code = {'P','D'},
200 .ulen = 10,
201 .only_rule = {'Z','E','R','O','-','P','A','D'}
202 };
203
204 static struct function_and_rules_block static_pkd_fnr_MCL2 = {
205 .function_code = {'P','D'},
206 .ulen = 10,
207 .only_rule = {'P','K','C','S','-','1','.','2'}
208 };
209 struct {
210 struct type6_hdr hdr;
211 struct CPRBX cprbx;
212 struct function_and_rules_block fr;
213 unsigned short length;
214 char text[0];
215 } __attribute__((packed)) *msg = ap_msg->message;
216 int size;
217
218 /* VUD.ciphertext */
219 msg->length = crt->inputdatalength + 2;
220 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
221 return -EFAULT;
222
223 /* Set up key which is located after the variable length text. */
224 size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
225 if (size < 0)
226 return size;
227 size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */
228
229 /* message header, cprbx and f&r */
230 msg->hdr = static_type6_hdrX;
231 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
232 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
233
234 msg->cprbx = static_cprbx;
235 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
236 msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
237 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
238
239 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
240 static_pkd_fnr_MCL2 : static_pkd_fnr;
241
242 ap_msg->length = size;
243 return 0;
244}
245
246/**
247 * Copy results from a type 86 ICA reply message back to user space.
248 *
249 * @zdev: crypto device pointer
250 * @reply: reply AP message.
251 * @data: pointer to user output data
252 * @length: size of user output data
253 *
254 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
255 */
256struct type86x_reply {
257 struct type86_hdr hdr;
258 struct type86_fmt2_ext fmt2;
259 struct CPRBX cprbx;
260 unsigned char pad[4]; /* 4 byte function code/rules block ? */
261 unsigned short length;
262 char text[0];
263} __attribute__((packed));
264
265static int convert_type86_ica(struct zcrypt_device *zdev,
266 struct ap_message *reply,
267 char __user *outputdata,
268 unsigned int outputdatalength)
269{
270 static unsigned char static_pad[] = {
271 0x00,0x02,
272 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
273 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
274 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
275 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
276 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
277 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
278 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
279 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
280 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
281 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
282 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
283 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
284 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
285 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
286 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
287 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
288 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
289 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
290 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
291 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
292 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
293 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
294 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
295 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
296 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
297 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
298 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
299 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
300 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
301 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
302 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
303 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
304 };
305 struct type86x_reply *msg = reply->message;
306 unsigned short service_rc, service_rs;
307 unsigned int reply_len, pad_len;
308 char *data;
309
310 service_rc = msg->cprbx.ccp_rtcode;
311 if (unlikely(service_rc != 0)) {
312 service_rs = msg->cprbx.ccp_rscode;
313 if (service_rc == 8 && service_rs == 66) {
314 PDEBUG("Bad block format on PCIXCC/CEX2C\n");
315 return -EINVAL;
316 }
317 if (service_rc == 8 && service_rs == 65) {
318 PDEBUG("Probably an even modulus on PCIXCC/CEX2C\n");
319 return -EINVAL;
320 }
321 if (service_rc == 8 && service_rs == 770) {
322 PDEBUG("Invalid key length on PCIXCC/CEX2C\n");
323 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
324 return -EAGAIN;
325 }
326 if (service_rc == 8 && service_rs == 783) {
327 PDEBUG("Extended bitlengths not enabled on PCIXCC/CEX2C\n");
328 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
329 return -EAGAIN;
330 }
331 PRINTK("Unknown service rc/rs (PCIXCC/CEX2C): %d/%d\n",
332 service_rc, service_rs);
333 zdev->online = 0;
334 return -EAGAIN; /* repeat the request on a different device. */
335 }
336 data = msg->text;
337 reply_len = msg->length - 2;
338 if (reply_len > outputdatalength)
339 return -EINVAL;
340 /**
341 * For all encipher requests, the length of the ciphertext (reply_len)
342 * will always equal the modulus length. For MEX decipher requests
343 * the output needs to get padded. Minimum pad size is 10.
344 *
345 * Currently, the cases where padding will be added is for:
346 * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
347 * ZERO-PAD and CRT is only supported for PKD requests)
348 * - PCICC, always
349 */
350 pad_len = outputdatalength - reply_len;
351 if (pad_len > 0) {
352 if (pad_len < 10)
353 return -EINVAL;
354 /* 'restore' padding left in the PCICC/PCIXCC card. */
355 if (copy_to_user(outputdata, static_pad, pad_len - 1))
356 return -EFAULT;
357 if (put_user(0, outputdata + pad_len - 1))
358 return -EFAULT;
359 }
360 /* Copy the crypto response to user space. */
361 if (copy_to_user(outputdata + pad_len, data, reply_len))
362 return -EFAULT;
363 return 0;
364}
365
366static int convert_response_ica(struct zcrypt_device *zdev,
367 struct ap_message *reply,
368 char __user *outputdata,
369 unsigned int outputdatalength)
370{
371 struct type86x_reply *msg = reply->message;
372
373 /* Response type byte is the second byte in the response. */
374 switch (((unsigned char *) reply->message)[1]) {
375 case TYPE82_RSP_CODE:
376 case TYPE88_RSP_CODE:
377 return convert_error(zdev, reply);
378 case TYPE86_RSP_CODE:
379 if (msg->hdr.reply_code)
380 return convert_error(zdev, reply);
381 if (msg->cprbx.cprb_ver_id == 0x02)
382 return convert_type86_ica(zdev, reply,
383 outputdata, outputdatalength);
384 /* no break, incorrect cprb version is an unknown response */
385 default: /* Unknown response type, this should NEVER EVER happen */
386 PRINTK("Unrecognized Message Header: %08x%08x\n",
387 *(unsigned int *) reply->message,
388 *(unsigned int *) (reply->message+4));
389 zdev->online = 0;
390 return -EAGAIN; /* repeat the request on a different device. */
391 }
392}
393
394/**
395 * This function is called from the AP bus code after a crypto request
396 * "msg" has finished with the reply message "reply".
397 * It is called from tasklet context.
398 * @ap_dev: pointer to the AP device
399 * @msg: pointer to the AP message
400 * @reply: pointer to the AP reply message
401 */
402static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
403 struct ap_message *msg,
404 struct ap_message *reply)
405{
406 static struct error_hdr error_reply = {
407 .type = TYPE82_RSP_CODE,
408 .reply_code = REP82_ERROR_MACHINE_FAILURE,
409 };
410 struct type86x_reply *t86r = reply->message;
411 int length;
412
413 /* Copy the reply message to the request message buffer. */
414 if (IS_ERR(reply))
415 memcpy(msg->message, &error_reply, sizeof(error_reply));
416 else if (t86r->hdr.type == TYPE86_RSP_CODE &&
417 t86r->cprbx.cprb_ver_id == 0x02) {
418 length = sizeof(struct type86x_reply) + t86r->length - 2;
419 length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
420 memcpy(msg->message, reply->message, length);
421 } else
422 memcpy(msg->message, reply->message, sizeof error_reply);
423 complete((struct completion *) msg->private);
424}
425
426static atomic_t zcrypt_step = ATOMIC_INIT(0);
427
428/**
429 * The request distributor calls this function if it picked the PCIXCC/CEX2C
430 * device to handle a modexpo request.
431 * @zdev: pointer to zcrypt_device structure that identifies the
432 * PCIXCC/CEX2C device to the request distributor
433 * @mex: pointer to the modexpo request buffer
434 */
435static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
436 struct ica_rsa_modexpo *mex)
437{
438 struct ap_message ap_msg;
439 struct completion work;
440 int rc;
441
442 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
443 if (!ap_msg.message)
444 return -ENOMEM;
445 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
446 atomic_inc_return(&zcrypt_step);
447 ap_msg.private = &work;
448 rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
449 if (rc)
450 goto out_free;
451 init_completion(&work);
452 ap_queue_message(zdev->ap_dev, &ap_msg);
453 rc = wait_for_completion_interruptible_timeout(
454 &work, PCIXCC_CLEANUP_TIME);
455 if (rc > 0)
456 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
457 mex->outputdatalength);
458 else {
459 /* Signal pending or message timed out. */
460 ap_cancel_message(zdev->ap_dev, &ap_msg);
461 if (rc == 0)
462 /* Message timed out. */
463 rc = -ETIME;
464 }
465out_free:
466 free_page((unsigned long) ap_msg.message);
467 return rc;
468}
469
470/**
471 * The request distributor calls this function if it picked the PCIXCC/CEX2C
472 * device to handle a modexpo_crt request.
473 * @zdev: pointer to zcrypt_device structure that identifies the
474 * PCIXCC/CEX2C device to the request distributor
475 * @crt: pointer to the modexpoc_crt request buffer
476 */
477static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
478 struct ica_rsa_modexpo_crt *crt)
479{
480 struct ap_message ap_msg;
481 struct completion work;
482 int rc;
483
484 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
485 if (!ap_msg.message)
486 return -ENOMEM;
487 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
488 atomic_inc_return(&zcrypt_step);
489 ap_msg.private = &work;
490 rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
491 if (rc)
492 goto out_free;
493 init_completion(&work);
494 ap_queue_message(zdev->ap_dev, &ap_msg);
495 rc = wait_for_completion_interruptible_timeout(
496 &work, PCIXCC_CLEANUP_TIME);
497 if (rc > 0)
498 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
499 crt->outputdatalength);
500 else {
501 /* Signal pending or message timed out. */
502 ap_cancel_message(zdev->ap_dev, &ap_msg);
503 if (rc == 0)
504 /* Message timed out. */
505 rc = -ETIME;
506 }
507out_free:
508 free_page((unsigned long) ap_msg.message);
509 return rc;
510}
511
512/**
513 * The crypto operations for a PCIXCC/CEX2C card.
514 */
515static struct zcrypt_ops zcrypt_pcixcc_ops = {
516 .rsa_modexpo = zcrypt_pcixcc_modexpo,
517 .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
518};
519
520/**
521 * Micro-code detection function. Its sends a message to a pcixcc card
522 * to find out the microcode level.
523 * @ap_dev: pointer to the AP device.
524 */
525static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
526{
527 static unsigned char msg[] = {
528 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
529 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
530 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
531 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
532 0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
533 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
534 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
535 0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
536 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
537 0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
538 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
539 0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
540 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
541 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
542 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
543 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
544 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
545 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
546 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
547 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
548 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
549 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
550 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
551 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
552 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
553 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
554 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
555 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
556 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
557 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
558 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
560 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,
561 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
562 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
563 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
564 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
565 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
566 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,
567 0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
568 0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
569 0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
570 0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
571 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
572 0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
573 0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
574 0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
575 0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
576 0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
577 0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
578 0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
579 0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
580 0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
581 0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
582 0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
583 0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
584 0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
585 0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
586 0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
587 0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
588 0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
589 0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
590 0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
591 0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
592 0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
593 0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
594 0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
595 0xF1,0x3D,0x93,0x53
596 };
597 unsigned long long psmid;
598 struct CPRBX *cprbx;
599 char *reply;
600 int rc, i;
601
602 reply = (void *) get_zeroed_page(GFP_KERNEL);
603 if (!reply)
604 return -ENOMEM;
605
606 rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
607 if (rc)
608 goto out_free;
609
610 /* Wait for the test message to complete. */
611 for (i = 0; i < 6; i++) {
612 mdelay(300);
613 rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
614 if (rc == 0 && psmid == 0x0102030405060708ULL)
615 break;
616 }
617
618 if (i >= 6) {
619 /* Got no answer. */
620 rc = -ENODEV;
621 goto out_free;
622 }
623
624 cprbx = (struct CPRBX *) (reply + 48);
625 if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
626 rc = ZCRYPT_PCIXCC_MCL2;
627 else
628 rc = ZCRYPT_PCIXCC_MCL3;
629out_free:
630 free_page((unsigned long) reply);
631 return rc;
632}
633
634/**
635 * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
636 * since the bus_match already checked the hardware type. The PCIXCC
637 * cards come in two flavours: micro code level 2 and micro code level 3.
638 * This is checked by sending a test message to the device.
639 * @ap_dev: pointer to the AP device.
640 */
641static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
642{
643 struct zcrypt_device *zdev;
644 int rc;
645
646 zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE);
647 if (!zdev)
648 return -ENOMEM;
649 zdev->ap_dev = ap_dev;
650 zdev->ops = &zcrypt_pcixcc_ops;
651 zdev->online = 1;
652 if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) {
653 rc = zcrypt_pcixcc_mcl(ap_dev);
654 if (rc < 0) {
655 zcrypt_device_free(zdev);
656 return rc;
657 }
658 zdev->user_space_type = rc;
659 if (rc == ZCRYPT_PCIXCC_MCL2) {
660 zdev->type_string = "PCIXCC_MCL2";
661 zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
662 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
663 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
664 } else {
665 zdev->type_string = "PCIXCC_MCL3";
666 zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
667 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
668 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
669 }
670 } else {
671 zdev->user_space_type = ZCRYPT_CEX2C;
672 zdev->type_string = "CEX2C";
673 zdev->speed_rating = CEX2C_SPEED_RATING;
674 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
675 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
676 }
677 ap_dev->reply = &zdev->reply;
678 ap_dev->private = zdev;
679 rc = zcrypt_device_register(zdev);
680 if (rc)
681 goto out_free;
682 return 0;
683
684 out_free:
685 ap_dev->private = NULL;
686 zcrypt_device_free(zdev);
687 return rc;
688}
689
690/**
691 * This is called to remove the extended PCIXCC/CEX2C driver information
692 * if an AP device is removed.
693 */
694static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
695{
696 struct zcrypt_device *zdev = ap_dev->private;
697
698 zcrypt_device_unregister(zdev);
699}
700
701int __init zcrypt_pcixcc_init(void)
702{
703 return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
704}
705
706void zcrypt_pcixcc_exit(void)
707{
708 ap_driver_unregister(&zcrypt_pcixcc_driver);
709}
710
711#ifndef CONFIG_ZCRYPT_MONOLITHIC
712module_init(zcrypt_pcixcc_init);
713module_exit(zcrypt_pcixcc_exit);
714#endif
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.h b/drivers/s390/crypto/zcrypt_pcixcc.h
new file mode 100644
index 000000000000..d4c44c4d7ad0
--- /dev/null
+++ b/drivers/s390/crypto/zcrypt_pcixcc.h
@@ -0,0 +1,79 @@
1/*
2 * linux/drivers/s390/crypto/zcrypt_pcixcc.h
3 *
4 * zcrypt 2.0.0
5 *
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#ifndef _ZCRYPT_PCIXCC_H_
29#define _ZCRYPT_PCIXCC_H_
30
31/**
32 * CPRBX
33 * Note that all shorts and ints are big-endian.
34 * All pointer fields are 16 bytes long, and mean nothing.
35 *
36 * A request CPRB is followed by a request_parameter_block.
37 *
38 * The request (or reply) parameter block is organized thus:
39 * function code
40 * VUD block
41 * key block
42 */
43struct CPRBX {
44 unsigned short cprb_len; /* CPRB length 220 */
45 unsigned char cprb_ver_id; /* CPRB version id. 0x02 */
46 unsigned char pad_000[3]; /* Alignment pad bytes */
47 unsigned char func_id[2]; /* function id 0x5432 */
48 unsigned char cprb_flags[4]; /* Flags */
49 unsigned int req_parml; /* request parameter buffer len */
50 unsigned int req_datal; /* request data buffer */
51 unsigned int rpl_msgbl; /* reply message block length */
52 unsigned int rpld_parml; /* replied parameter block len */
53 unsigned int rpl_datal; /* reply data block len */
54 unsigned int rpld_datal; /* replied data block len */
55 unsigned int req_extbl; /* request extension block len */
56 unsigned char pad_001[4]; /* reserved */
57 unsigned int rpld_extbl; /* replied extension block len */
58 unsigned char req_parmb[16]; /* request parm block 'address' */
59 unsigned char req_datab[16]; /* request data block 'address' */
60 unsigned char rpl_parmb[16]; /* reply parm block 'address' */
61 unsigned char rpl_datab[16]; /* reply data block 'address' */
62 unsigned char req_extb[16]; /* request extension block 'addr'*/
63 unsigned char rpl_extb[16]; /* reply extension block 'addres'*/
64 unsigned short ccp_rtcode; /* server return code */
65 unsigned short ccp_rscode; /* server reason code */
66 unsigned int mac_data_len; /* Mac Data Length */
67 unsigned char logon_id[8]; /* Logon Identifier */
68 unsigned char mac_value[8]; /* Mac Value */
69 unsigned char mac_content_flgs;/* Mac content flag byte */
70 unsigned char pad_002; /* Alignment */
71 unsigned short domain; /* Domain */
72 unsigned char pad_003[12]; /* Domain masks */
73 unsigned char pad_004[36]; /* reserved */
74} __attribute__((packed));
75
76int zcrypt_pcixcc_init(void);
77void zcrypt_pcixcc_exit(void);
78
79#endif /* _ZCRYPT_PCIXCC_H_ */