[S390] zcrypt: make init/exit functions static.
[linux-2.6-block.git] / drivers / s390 / crypto / zcrypt_pcixcc.c
CommitLineData
6684af1a
MS
1/*
2 * linux/drivers/s390/crypto/zcrypt_pcixcc.c
3 *
5432114b 4 * zcrypt 2.1.0
6684af1a
MS
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
5432114b
RW
63#define CEIL4(x) ((((x)+3)/4)*4)
64
65struct response_type {
66 struct completion work;
67 int type;
68};
69#define PCIXCC_RESPONSE_TYPE_ICA 0
70#define PCIXCC_RESPONSE_TYPE_XCRB 1
71
6684af1a
MS
72static struct ap_device_id zcrypt_pcixcc_ids[] = {
73 { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
74 { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
75 { /* end of list */ },
76};
77
78#ifndef CONFIG_ZCRYPT_MONOLITHIC
79MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
80MODULE_AUTHOR("IBM Corporation");
81MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, "
82 "Copyright 2001, 2006 IBM Corporation");
83MODULE_LICENSE("GPL");
84#endif
85
86static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
87static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
88static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *,
89 struct ap_message *);
90
91static struct ap_driver zcrypt_pcixcc_driver = {
92 .probe = zcrypt_pcixcc_probe,
93 .remove = zcrypt_pcixcc_remove,
94 .receive = zcrypt_pcixcc_receive,
95 .ids = zcrypt_pcixcc_ids,
af512ed0 96 .request_timeout = PCIXCC_CLEANUP_TIME,
6684af1a
MS
97};
98
99/**
100 * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
101 * card in a type6 message. The 3 fields that must be filled in at execution
102 * time are req_parml, rpl_parml and usage_domain.
103 * Everything about this interface is ascii/big-endian, since the
104 * device does *not* have 'Intel inside'.
105 *
106 * The CPRBX is followed immediately by the parm block.
107 * The parm block contains:
108 * - function code ('PD' 0x5044 or 'PK' 0x504B)
109 * - rule block (one of:)
110 * + 0x000A 'PKCS-1.2' (MCL2 'PD')
111 * + 0x000A 'ZERO-PAD' (MCL2 'PK')
112 * + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
113 * + 0x000A 'MRP ' (MCL3 'PK' or CEX2C 'PK')
114 * - VUD block
115 */
116static struct CPRBX static_cprbx = {
117 .cprb_len = 0x00DC,
118 .cprb_ver_id = 0x02,
119 .func_id = {0x54,0x32},
120};
121
122/**
123 * Convert a ICAMEX message to a type6 MEX message.
124 *
125 * @zdev: crypto device pointer
126 * @ap_msg: pointer to AP message
127 * @mex: pointer to user input data
128 *
129 * Returns 0 on success or -EFAULT.
130 */
131static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev,
132 struct ap_message *ap_msg,
133 struct ica_rsa_modexpo *mex)
134{
135 static struct type6_hdr static_type6_hdrX = {
136 .type = 0x06,
137 .offset1 = 0x00000058,
138 .agent_id = {'C','A',},
139 .function_code = {'P','K'},
140 };
141 static struct function_and_rules_block static_pke_fnr = {
142 .function_code = {'P','K'},
143 .ulen = 10,
144 .only_rule = {'M','R','P',' ',' ',' ',' ',' '}
145 };
146 static struct function_and_rules_block static_pke_fnr_MCL2 = {
147 .function_code = {'P','K'},
148 .ulen = 10,
149 .only_rule = {'Z','E','R','O','-','P','A','D'}
150 };
151 struct {
152 struct type6_hdr hdr;
153 struct CPRBX cprbx;
154 struct function_and_rules_block fr;
155 unsigned short length;
156 char text[0];
157 } __attribute__((packed)) *msg = ap_msg->message;
158 int size;
159
160 /* VUD.ciphertext */
161 msg->length = mex->inputdatalength + 2;
162 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
163 return -EFAULT;
164
165 /* Set up key which is located after the variable length text. */
166 size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
167 if (size < 0)
168 return size;
169 size += sizeof(*msg) + mex->inputdatalength;
170
171 /* message header, cprbx and f&r */
172 msg->hdr = static_type6_hdrX;
173 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
174 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
175
176 msg->cprbx = static_cprbx;
177 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
178 msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
179
180 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
181 static_pke_fnr_MCL2 : static_pke_fnr;
182
183 msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
184
185 ap_msg->length = size;
186 return 0;
187}
188
189/**
190 * Convert a ICACRT message to a type6 CRT message.
191 *
192 * @zdev: crypto device pointer
193 * @ap_msg: pointer to AP message
194 * @crt: pointer to user input data
195 *
196 * Returns 0 on success or -EFAULT.
197 */
198static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
199 struct ap_message *ap_msg,
200 struct ica_rsa_modexpo_crt *crt)
201{
202 static struct type6_hdr static_type6_hdrX = {
203 .type = 0x06,
204 .offset1 = 0x00000058,
205 .agent_id = {'C','A',},
206 .function_code = {'P','D'},
207 };
208 static struct function_and_rules_block static_pkd_fnr = {
209 .function_code = {'P','D'},
210 .ulen = 10,
211 .only_rule = {'Z','E','R','O','-','P','A','D'}
212 };
213
214 static struct function_and_rules_block static_pkd_fnr_MCL2 = {
215 .function_code = {'P','D'},
216 .ulen = 10,
217 .only_rule = {'P','K','C','S','-','1','.','2'}
218 };
219 struct {
220 struct type6_hdr hdr;
221 struct CPRBX cprbx;
222 struct function_and_rules_block fr;
223 unsigned short length;
224 char text[0];
225 } __attribute__((packed)) *msg = ap_msg->message;
226 int size;
227
228 /* VUD.ciphertext */
229 msg->length = crt->inputdatalength + 2;
230 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
231 return -EFAULT;
232
233 /* Set up key which is located after the variable length text. */
234 size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
235 if (size < 0)
236 return size;
237 size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */
238
239 /* message header, cprbx and f&r */
240 msg->hdr = static_type6_hdrX;
241 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
242 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
243
244 msg->cprbx = static_cprbx;
245 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
246 msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
247 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
248
249 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
250 static_pkd_fnr_MCL2 : static_pkd_fnr;
251
252 ap_msg->length = size;
253 return 0;
254}
255
5432114b
RW
256/**
257 * Convert a XCRB message to a type6 CPRB message.
258 *
259 * @zdev: crypto device pointer
260 * @ap_msg: pointer to AP message
261 * @xcRB: pointer to user input data
262 *
263 * Returns 0 on success or -EFAULT.
264 */
265struct type86_fmt2_msg {
266 struct type86_hdr hdr;
267 struct type86_fmt2_ext fmt2;
268} __attribute__((packed));
269
270static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
271 struct ap_message *ap_msg,
272 struct ica_xcRB *xcRB)
273{
274 static struct type6_hdr static_type6_hdrX = {
275 .type = 0x06,
276 .offset1 = 0x00000058,
277 };
278 struct {
279 struct type6_hdr hdr;
280 struct ica_CPRBX cprbx;
281 } __attribute__((packed)) *msg = ap_msg->message;
282
283 int rcblen = CEIL4(xcRB->request_control_blk_length);
284 int replylen;
285 char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
286 char *function_code;
287
288 /* length checks */
289 ap_msg->length = sizeof(struct type6_hdr) +
290 CEIL4(xcRB->request_control_blk_length) +
291 xcRB->request_data_length;
292 if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE) {
293 PRINTK("Combined message is too large (%ld/%d/%d).\n",
294 sizeof(struct type6_hdr),
295 xcRB->request_control_blk_length,
296 xcRB->request_data_length);
297 return -EFAULT;
298 }
299 if (CEIL4(xcRB->reply_control_blk_length) >
300 PCIXCC_MAX_XCRB_REPLY_SIZE) {
301 PDEBUG("Reply CPRB length is too large (%d).\n",
302 xcRB->request_control_blk_length);
303 return -EFAULT;
304 }
305 if (CEIL4(xcRB->reply_data_length) > PCIXCC_MAX_XCRB_DATA_SIZE) {
306 PDEBUG("Reply data block length is too large (%d).\n",
307 xcRB->reply_data_length);
308 return -EFAULT;
309 }
310 replylen = CEIL4(xcRB->reply_control_blk_length) +
311 CEIL4(xcRB->reply_data_length) +
312 sizeof(struct type86_fmt2_msg);
313 if (replylen > PCIXCC_MAX_XCRB_RESPONSE_SIZE) {
314 PDEBUG("Reply CPRB + data block > PCIXCC_MAX_XCRB_RESPONSE_SIZE"
315 " (%d/%d/%d).\n",
316 sizeof(struct type86_fmt2_msg),
317 xcRB->reply_control_blk_length,
318 xcRB->reply_data_length);
319 xcRB->reply_control_blk_length = PCIXCC_MAX_XCRB_RESPONSE_SIZE -
320 (sizeof(struct type86_fmt2_msg) +
321 CEIL4(xcRB->reply_data_length));
322 PDEBUG("Capping Reply CPRB length at %d\n",
323 xcRB->reply_control_blk_length);
324 }
325
326 /* prepare type6 header */
327 msg->hdr = static_type6_hdrX;
328 memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
329 msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
330 if (xcRB->request_data_length) {
331 msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
332 msg->hdr.ToCardLen2 = xcRB->request_data_length;
333 }
334 msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length;
335 msg->hdr.FromCardLen2 = xcRB->reply_data_length;
336
337 /* prepare CPRB */
338 if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr,
339 xcRB->request_control_blk_length))
340 return -EFAULT;
341 if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
342 xcRB->request_control_blk_length) {
343 PDEBUG("cprb_len too large (%d/%d)\n", msg->cprbx.cprb_len,
344 xcRB->request_control_blk_length);
345 return -EFAULT;
346 }
347 function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
348 memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
349
350 /* copy data block */
351 if (xcRB->request_data_length &&
352 copy_from_user(req_data, xcRB->request_data_address,
353 xcRB->request_data_length))
354 return -EFAULT;
355 return 0;
356}
357
6684af1a
MS
358/**
359 * Copy results from a type 86 ICA reply message back to user space.
360 *
361 * @zdev: crypto device pointer
362 * @reply: reply AP message.
363 * @data: pointer to user output data
364 * @length: size of user output data
365 *
366 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
367 */
368struct type86x_reply {
369 struct type86_hdr hdr;
370 struct type86_fmt2_ext fmt2;
371 struct CPRBX cprbx;
372 unsigned char pad[4]; /* 4 byte function code/rules block ? */
373 unsigned short length;
374 char text[0];
375} __attribute__((packed));
376
377static int convert_type86_ica(struct zcrypt_device *zdev,
378 struct ap_message *reply,
379 char __user *outputdata,
380 unsigned int outputdatalength)
381{
382 static unsigned char static_pad[] = {
383 0x00,0x02,
384 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
385 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
386 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
387 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
388 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
389 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
390 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
391 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
392 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
393 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
394 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
395 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
396 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
397 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
398 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
399 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
400 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
401 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
402 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
403 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
404 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
405 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
406 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
407 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
408 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
409 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
410 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
411 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
412 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
413 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
414 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
415 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
416 };
417 struct type86x_reply *msg = reply->message;
418 unsigned short service_rc, service_rs;
419 unsigned int reply_len, pad_len;
420 char *data;
421
422 service_rc = msg->cprbx.ccp_rtcode;
423 if (unlikely(service_rc != 0)) {
424 service_rs = msg->cprbx.ccp_rscode;
425 if (service_rc == 8 && service_rs == 66) {
426 PDEBUG("Bad block format on PCIXCC/CEX2C\n");
427 return -EINVAL;
428 }
429 if (service_rc == 8 && service_rs == 65) {
430 PDEBUG("Probably an even modulus on PCIXCC/CEX2C\n");
431 return -EINVAL;
432 }
433 if (service_rc == 8 && service_rs == 770) {
434 PDEBUG("Invalid key length on PCIXCC/CEX2C\n");
435 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
436 return -EAGAIN;
437 }
438 if (service_rc == 8 && service_rs == 783) {
439 PDEBUG("Extended bitlengths not enabled on PCIXCC/CEX2C\n");
440 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
441 return -EAGAIN;
442 }
443 PRINTK("Unknown service rc/rs (PCIXCC/CEX2C): %d/%d\n",
444 service_rc, service_rs);
445 zdev->online = 0;
446 return -EAGAIN; /* repeat the request on a different device. */
447 }
448 data = msg->text;
449 reply_len = msg->length - 2;
450 if (reply_len > outputdatalength)
451 return -EINVAL;
452 /**
453 * For all encipher requests, the length of the ciphertext (reply_len)
454 * will always equal the modulus length. For MEX decipher requests
455 * the output needs to get padded. Minimum pad size is 10.
456 *
457 * Currently, the cases where padding will be added is for:
458 * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
459 * ZERO-PAD and CRT is only supported for PKD requests)
460 * - PCICC, always
461 */
462 pad_len = outputdatalength - reply_len;
463 if (pad_len > 0) {
464 if (pad_len < 10)
465 return -EINVAL;
466 /* 'restore' padding left in the PCICC/PCIXCC card. */
467 if (copy_to_user(outputdata, static_pad, pad_len - 1))
468 return -EFAULT;
469 if (put_user(0, outputdata + pad_len - 1))
470 return -EFAULT;
471 }
472 /* Copy the crypto response to user space. */
473 if (copy_to_user(outputdata + pad_len, data, reply_len))
474 return -EFAULT;
475 return 0;
476}
477
5432114b
RW
478/**
479 * Copy results from a type 86 XCRB reply message back to user space.
480 *
481 * @zdev: crypto device pointer
482 * @reply: reply AP message.
483 * @xcRB: pointer to XCRB
484 *
485 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
486 */
487static int convert_type86_xcrb(struct zcrypt_device *zdev,
488 struct ap_message *reply,
489 struct ica_xcRB *xcRB)
490{
491 struct type86_fmt2_msg *msg = reply->message;
492 char *data = reply->message;
493
494 /* Copy CPRB to user */
495 if (copy_to_user(xcRB->reply_control_blk_addr,
496 data + msg->fmt2.offset1, msg->fmt2.count1))
497 return -EFAULT;
498 xcRB->reply_control_blk_length = msg->fmt2.count1;
499
500 /* Copy data buffer to user */
501 if (msg->fmt2.count2)
502 if (copy_to_user(xcRB->reply_data_addr,
503 data + msg->fmt2.offset2, msg->fmt2.count2))
504 return -EFAULT;
505 xcRB->reply_data_length = msg->fmt2.count2;
506 return 0;
507}
508
6684af1a
MS
509static int convert_response_ica(struct zcrypt_device *zdev,
510 struct ap_message *reply,
511 char __user *outputdata,
512 unsigned int outputdatalength)
513{
514 struct type86x_reply *msg = reply->message;
515
516 /* Response type byte is the second byte in the response. */
517 switch (((unsigned char *) reply->message)[1]) {
518 case TYPE82_RSP_CODE:
519 case TYPE88_RSP_CODE:
520 return convert_error(zdev, reply);
521 case TYPE86_RSP_CODE:
522 if (msg->hdr.reply_code)
523 return convert_error(zdev, reply);
524 if (msg->cprbx.cprb_ver_id == 0x02)
525 return convert_type86_ica(zdev, reply,
526 outputdata, outputdatalength);
527 /* no break, incorrect cprb version is an unknown response */
528 default: /* Unknown response type, this should NEVER EVER happen */
529 PRINTK("Unrecognized Message Header: %08x%08x\n",
530 *(unsigned int *) reply->message,
531 *(unsigned int *) (reply->message+4));
532 zdev->online = 0;
533 return -EAGAIN; /* repeat the request on a different device. */
534 }
535}
536
5432114b
RW
537static int convert_response_xcrb(struct zcrypt_device *zdev,
538 struct ap_message *reply,
539 struct ica_xcRB *xcRB)
540{
541 struct type86x_reply *msg = reply->message;
542
543 /* Response type byte is the second byte in the response. */
544 switch (((unsigned char *) reply->message)[1]) {
545 case TYPE82_RSP_CODE:
546 case TYPE88_RSP_CODE:
547 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
548 return convert_error(zdev, reply);
549 case TYPE86_RSP_CODE:
550 if (msg->hdr.reply_code) {
551 memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
552 return convert_error(zdev, reply);
553 }
554 if (msg->cprbx.cprb_ver_id == 0x02)
555 return convert_type86_xcrb(zdev, reply, xcRB);
556 /* no break, incorrect cprb version is an unknown response */
557 default: /* Unknown response type, this should NEVER EVER happen */
558 PRINTK("Unrecognized Message Header: %08x%08x\n",
559 *(unsigned int *) reply->message,
560 *(unsigned int *) (reply->message+4));
561 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
562 zdev->online = 0;
563 return -EAGAIN; /* repeat the request on a different device. */
564 }
565}
566
6684af1a
MS
567/**
568 * This function is called from the AP bus code after a crypto request
569 * "msg" has finished with the reply message "reply".
570 * It is called from tasklet context.
571 * @ap_dev: pointer to the AP device
572 * @msg: pointer to the AP message
573 * @reply: pointer to the AP reply message
574 */
575static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
576 struct ap_message *msg,
577 struct ap_message *reply)
578{
579 static struct error_hdr error_reply = {
580 .type = TYPE82_RSP_CODE,
581 .reply_code = REP82_ERROR_MACHINE_FAILURE,
582 };
5432114b
RW
583 struct response_type *resp_type =
584 (struct response_type *) msg->private;
6684af1a
MS
585 struct type86x_reply *t86r = reply->message;
586 int length;
587
588 /* Copy the reply message to the request message buffer. */
589 if (IS_ERR(reply))
590 memcpy(msg->message, &error_reply, sizeof(error_reply));
591 else if (t86r->hdr.type == TYPE86_RSP_CODE &&
592 t86r->cprbx.cprb_ver_id == 0x02) {
5432114b
RW
593 switch (resp_type->type) {
594 case PCIXCC_RESPONSE_TYPE_ICA:
595 length = sizeof(struct type86x_reply)
596 + t86r->length - 2;
597 length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
598 memcpy(msg->message, reply->message, length);
599 break;
600 case PCIXCC_RESPONSE_TYPE_XCRB:
601 length = t86r->fmt2.offset2 + t86r->fmt2.count2;
602 length = min(PCIXCC_MAX_XCRB_RESPONSE_SIZE, length);
603 memcpy(msg->message, reply->message, length);
604 break;
605 default:
606 PRINTK("Invalid internal response type: %i\n",
607 resp_type->type);
608 memcpy(msg->message, &error_reply,
609 sizeof error_reply);
610 }
6684af1a
MS
611 } else
612 memcpy(msg->message, reply->message, sizeof error_reply);
5432114b 613 complete(&(resp_type->work));
6684af1a
MS
614}
615
616static atomic_t zcrypt_step = ATOMIC_INIT(0);
617
618/**
619 * The request distributor calls this function if it picked the PCIXCC/CEX2C
620 * device to handle a modexpo request.
621 * @zdev: pointer to zcrypt_device structure that identifies the
622 * PCIXCC/CEX2C device to the request distributor
623 * @mex: pointer to the modexpo request buffer
624 */
625static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
626 struct ica_rsa_modexpo *mex)
627{
628 struct ap_message ap_msg;
5432114b
RW
629 struct response_type resp_type = {
630 .type = PCIXCC_RESPONSE_TYPE_ICA,
631 };
6684af1a
MS
632 int rc;
633
634 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
635 if (!ap_msg.message)
636 return -ENOMEM;
637 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
638 atomic_inc_return(&zcrypt_step);
5432114b 639 ap_msg.private = &resp_type;
6684af1a
MS
640 rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
641 if (rc)
642 goto out_free;
5432114b 643 init_completion(&resp_type.work);
6684af1a 644 ap_queue_message(zdev->ap_dev, &ap_msg);
af512ed0
RW
645 rc = wait_for_completion_interruptible(&resp_type.work);
646 if (rc == 0)
6684af1a
MS
647 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
648 mex->outputdatalength);
af512ed0
RW
649 else
650 /* Signal pending. */
6684af1a 651 ap_cancel_message(zdev->ap_dev, &ap_msg);
6684af1a
MS
652out_free:
653 free_page((unsigned long) ap_msg.message);
654 return rc;
655}
656
657/**
658 * The request distributor calls this function if it picked the PCIXCC/CEX2C
659 * device to handle a modexpo_crt request.
660 * @zdev: pointer to zcrypt_device structure that identifies the
661 * PCIXCC/CEX2C device to the request distributor
662 * @crt: pointer to the modexpoc_crt request buffer
663 */
664static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
665 struct ica_rsa_modexpo_crt *crt)
666{
667 struct ap_message ap_msg;
5432114b
RW
668 struct response_type resp_type = {
669 .type = PCIXCC_RESPONSE_TYPE_ICA,
670 };
6684af1a
MS
671 int rc;
672
673 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
674 if (!ap_msg.message)
675 return -ENOMEM;
676 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
677 atomic_inc_return(&zcrypt_step);
5432114b 678 ap_msg.private = &resp_type;
6684af1a
MS
679 rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
680 if (rc)
681 goto out_free;
5432114b 682 init_completion(&resp_type.work);
6684af1a 683 ap_queue_message(zdev->ap_dev, &ap_msg);
af512ed0
RW
684 rc = wait_for_completion_interruptible(&resp_type.work);
685 if (rc == 0)
6684af1a
MS
686 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
687 crt->outputdatalength);
af512ed0
RW
688 else
689 /* Signal pending. */
6684af1a 690 ap_cancel_message(zdev->ap_dev, &ap_msg);
6684af1a
MS
691out_free:
692 free_page((unsigned long) ap_msg.message);
693 return rc;
694}
695
5432114b
RW
696/**
697 * The request distributor calls this function if it picked the PCIXCC/CEX2C
698 * device to handle a send_cprb request.
699 * @zdev: pointer to zcrypt_device structure that identifies the
700 * PCIXCC/CEX2C device to the request distributor
701 * @xcRB: pointer to the send_cprb request buffer
702 */
2b67fc46
HC
703static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
704 struct ica_xcRB *xcRB)
5432114b
RW
705{
706 struct ap_message ap_msg;
707 struct response_type resp_type = {
708 .type = PCIXCC_RESPONSE_TYPE_XCRB,
709 };
710 int rc;
711
5cbded58 712 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
5432114b
RW
713 if (!ap_msg.message)
714 return -ENOMEM;
715 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
716 atomic_inc_return(&zcrypt_step);
717 ap_msg.private = &resp_type;
718 rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
719 if (rc)
720 goto out_free;
721 init_completion(&resp_type.work);
722 ap_queue_message(zdev->ap_dev, &ap_msg);
af512ed0
RW
723 rc = wait_for_completion_interruptible(&resp_type.work);
724 if (rc == 0)
5432114b 725 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
af512ed0
RW
726 else
727 /* Signal pending. */
5432114b 728 ap_cancel_message(zdev->ap_dev, &ap_msg);
5432114b
RW
729out_free:
730 memset(ap_msg.message, 0x0, ap_msg.length);
731 kfree(ap_msg.message);
732 return rc;
733}
734
6684af1a
MS
735/**
736 * The crypto operations for a PCIXCC/CEX2C card.
737 */
738static struct zcrypt_ops zcrypt_pcixcc_ops = {
739 .rsa_modexpo = zcrypt_pcixcc_modexpo,
740 .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
5432114b 741 .send_cprb = zcrypt_pcixcc_send_cprb,
6684af1a
MS
742};
743
744/**
745 * Micro-code detection function. Its sends a message to a pcixcc card
746 * to find out the microcode level.
747 * @ap_dev: pointer to the AP device.
748 */
749static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
750{
751 static unsigned char msg[] = {
752 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
753 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
754 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
755 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
756 0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
757 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
758 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
759 0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
760 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
761 0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
762 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
763 0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
764 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
765 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
766 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
767 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
768 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
769 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
770 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
771 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
772 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
773 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
774 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
775 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
776 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
777 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
778 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
779 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
780 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
781 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
782 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
783 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
784 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,
785 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
786 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
787 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
788 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
789 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
790 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,
791 0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
792 0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
793 0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
794 0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
795 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
796 0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
797 0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
798 0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
799 0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
800 0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
801 0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
802 0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
803 0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
804 0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
805 0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
806 0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
807 0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
808 0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
809 0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
810 0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
811 0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
812 0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
813 0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
814 0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
815 0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
816 0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
817 0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
818 0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
819 0xF1,0x3D,0x93,0x53
820 };
821 unsigned long long psmid;
822 struct CPRBX *cprbx;
823 char *reply;
824 int rc, i;
825
826 reply = (void *) get_zeroed_page(GFP_KERNEL);
827 if (!reply)
828 return -ENOMEM;
829
830 rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
831 if (rc)
832 goto out_free;
833
834 /* Wait for the test message to complete. */
835 for (i = 0; i < 6; i++) {
836 mdelay(300);
837 rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
838 if (rc == 0 && psmid == 0x0102030405060708ULL)
839 break;
840 }
841
842 if (i >= 6) {
843 /* Got no answer. */
844 rc = -ENODEV;
845 goto out_free;
846 }
847
848 cprbx = (struct CPRBX *) (reply + 48);
849 if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
850 rc = ZCRYPT_PCIXCC_MCL2;
851 else
852 rc = ZCRYPT_PCIXCC_MCL3;
853out_free:
854 free_page((unsigned long) reply);
855 return rc;
856}
857
858/**
859 * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
860 * since the bus_match already checked the hardware type. The PCIXCC
861 * cards come in two flavours: micro code level 2 and micro code level 3.
862 * This is checked by sending a test message to the device.
863 * @ap_dev: pointer to the AP device.
864 */
865static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
866{
867 struct zcrypt_device *zdev;
868 int rc;
869
870 zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE);
871 if (!zdev)
872 return -ENOMEM;
873 zdev->ap_dev = ap_dev;
874 zdev->ops = &zcrypt_pcixcc_ops;
875 zdev->online = 1;
876 if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) {
877 rc = zcrypt_pcixcc_mcl(ap_dev);
878 if (rc < 0) {
879 zcrypt_device_free(zdev);
880 return rc;
881 }
882 zdev->user_space_type = rc;
883 if (rc == ZCRYPT_PCIXCC_MCL2) {
884 zdev->type_string = "PCIXCC_MCL2";
885 zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
886 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
887 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
888 } else {
889 zdev->type_string = "PCIXCC_MCL3";
890 zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
891 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
892 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
893 }
894 } else {
895 zdev->user_space_type = ZCRYPT_CEX2C;
896 zdev->type_string = "CEX2C";
897 zdev->speed_rating = CEX2C_SPEED_RATING;
898 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
899 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
900 }
901 ap_dev->reply = &zdev->reply;
902 ap_dev->private = zdev;
903 rc = zcrypt_device_register(zdev);
904 if (rc)
905 goto out_free;
906 return 0;
907
908 out_free:
909 ap_dev->private = NULL;
910 zcrypt_device_free(zdev);
911 return rc;
912}
913
914/**
915 * This is called to remove the extended PCIXCC/CEX2C driver information
916 * if an AP device is removed.
917 */
918static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
919{
920 struct zcrypt_device *zdev = ap_dev->private;
921
922 zcrypt_device_unregister(zdev);
923}
924
925int __init zcrypt_pcixcc_init(void)
926{
927 return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
928}
929
930void zcrypt_pcixcc_exit(void)
931{
932 ap_driver_unregister(&zcrypt_pcixcc_driver);
933}
934
935#ifndef CONFIG_ZCRYPT_MONOLITHIC
936module_init(zcrypt_pcixcc_init);
937module_exit(zcrypt_pcixcc_exit);
938#endif