s390/comments: unify copyright messages and remove file names
[linux-2.6-block.git] / drivers / s390 / crypto / zcrypt_pcixcc.c
CommitLineData
6684af1a 1/*
5432114b 2 * zcrypt 2.1.0
6684af1a 3 *
a53c8fab 4 * Copyright IBM Corp. 2001, 2006
6684af1a
MS
5 * Author(s): Robert Burroughs
6 * Eric Rossman (edrossma@us.ibm.com)
7 *
8 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
9 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
10 * Ralph Wuerthner <rwuerthn@de.ibm.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/err.h>
30#include <linux/delay.h>
5a0e3ad6 31#include <linux/slab.h>
60063497 32#include <linux/atomic.h>
6684af1a
MS
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_pcixcc.h"
40#include "zcrypt_cca_key.h"
41
42#define PCIXCC_MIN_MOD_SIZE 16 /* 128 bits */
43#define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */
44#define PCIXCC_MAX_MOD_SIZE 256 /* 2048 bits */
8e89b6be 45#define CEX3C_MIN_MOD_SIZE PCIXCC_MIN_MOD_SIZE
2ade1fab 46#define CEX3C_MAX_MOD_SIZE 512 /* 4096 bits */
6684af1a 47
18278dff 48#define PCIXCC_MCL2_SPEED_RATING 7870
6684af1a 49#define PCIXCC_MCL3_SPEED_RATING 7870
18278dff 50#define CEX2C_SPEED_RATING 7000
2ade1fab 51#define CEX3C_SPEED_RATING 6500
6684af1a
MS
52
53#define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c /* max size type6 v2 crt message */
54#define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */
55
56#define PCIXCC_MAX_XCRB_MESSAGE_SIZE (12*1024)
6684af1a
MS
57
58#define PCIXCC_CLEANUP_TIME (15*HZ)
59
5432114b
RW
60#define CEIL4(x) ((((x)+3)/4)*4)
61
62struct response_type {
63 struct completion work;
64 int type;
65};
66#define PCIXCC_RESPONSE_TYPE_ICA 0
67#define PCIXCC_RESPONSE_TYPE_XCRB 1
68
6684af1a
MS
69static struct ap_device_id zcrypt_pcixcc_ids[] = {
70 { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
71 { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
ffda4f71 72 { AP_DEVICE(AP_DEVICE_TYPE_CEX3C) },
6684af1a
MS
73 { /* end of list */ },
74};
75
6684af1a
MS
76MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
77MODULE_AUTHOR("IBM Corporation");
78MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, "
a53c8fab 79 "Copyright IBM Corp. 2001, 2006");
6684af1a 80MODULE_LICENSE("GPL");
6684af1a
MS
81
82static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
83static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
84static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *,
85 struct ap_message *);
86
87static struct ap_driver zcrypt_pcixcc_driver = {
88 .probe = zcrypt_pcixcc_probe,
89 .remove = zcrypt_pcixcc_remove,
6684af1a 90 .ids = zcrypt_pcixcc_ids,
af512ed0 91 .request_timeout = PCIXCC_CLEANUP_TIME,
6684af1a
MS
92};
93
94/**
95 * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
96 * card in a type6 message. The 3 fields that must be filled in at execution
97 * time are req_parml, rpl_parml and usage_domain.
98 * Everything about this interface is ascii/big-endian, since the
99 * device does *not* have 'Intel inside'.
100 *
101 * The CPRBX is followed immediately by the parm block.
102 * The parm block contains:
103 * - function code ('PD' 0x5044 or 'PK' 0x504B)
104 * - rule block (one of:)
105 * + 0x000A 'PKCS-1.2' (MCL2 'PD')
106 * + 0x000A 'ZERO-PAD' (MCL2 'PK')
107 * + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
108 * + 0x000A 'MRP ' (MCL3 'PK' or CEX2C 'PK')
109 * - VUD block
110 */
111static struct CPRBX static_cprbx = {
112 .cprb_len = 0x00DC,
113 .cprb_ver_id = 0x02,
114 .func_id = {0x54,0x32},
115};
116
117/**
118 * Convert a ICAMEX message to a type6 MEX message.
119 *
120 * @zdev: crypto device pointer
121 * @ap_msg: pointer to AP message
122 * @mex: pointer to user input data
123 *
124 * Returns 0 on success or -EFAULT.
125 */
126static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev,
127 struct ap_message *ap_msg,
128 struct ica_rsa_modexpo *mex)
129{
130 static struct type6_hdr static_type6_hdrX = {
131 .type = 0x06,
132 .offset1 = 0x00000058,
133 .agent_id = {'C','A',},
134 .function_code = {'P','K'},
135 };
136 static struct function_and_rules_block static_pke_fnr = {
137 .function_code = {'P','K'},
138 .ulen = 10,
139 .only_rule = {'M','R','P',' ',' ',' ',' ',' '}
140 };
141 static struct function_and_rules_block static_pke_fnr_MCL2 = {
142 .function_code = {'P','K'},
143 .ulen = 10,
144 .only_rule = {'Z','E','R','O','-','P','A','D'}
145 };
146 struct {
147 struct type6_hdr hdr;
148 struct CPRBX cprbx;
149 struct function_and_rules_block fr;
150 unsigned short length;
151 char text[0];
152 } __attribute__((packed)) *msg = ap_msg->message;
153 int size;
154
155 /* VUD.ciphertext */
156 msg->length = mex->inputdatalength + 2;
157 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
158 return -EFAULT;
159
160 /* Set up key which is located after the variable length text. */
161 size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
162 if (size < 0)
163 return size;
164 size += sizeof(*msg) + mex->inputdatalength;
165
166 /* message header, cprbx and f&r */
167 msg->hdr = static_type6_hdrX;
168 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
169 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
170
171 msg->cprbx = static_cprbx;
172 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
173 msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
174
175 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
176 static_pke_fnr_MCL2 : static_pke_fnr;
177
178 msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
179
180 ap_msg->length = size;
181 return 0;
182}
183
184/**
185 * Convert a ICACRT message to a type6 CRT message.
186 *
187 * @zdev: crypto device pointer
188 * @ap_msg: pointer to AP message
189 * @crt: pointer to user input data
190 *
191 * Returns 0 on success or -EFAULT.
192 */
193static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
194 struct ap_message *ap_msg,
195 struct ica_rsa_modexpo_crt *crt)
196{
197 static struct type6_hdr static_type6_hdrX = {
198 .type = 0x06,
199 .offset1 = 0x00000058,
200 .agent_id = {'C','A',},
201 .function_code = {'P','D'},
202 };
203 static struct function_and_rules_block static_pkd_fnr = {
204 .function_code = {'P','D'},
205 .ulen = 10,
206 .only_rule = {'Z','E','R','O','-','P','A','D'}
207 };
208
209 static struct function_and_rules_block static_pkd_fnr_MCL2 = {
210 .function_code = {'P','D'},
211 .ulen = 10,
212 .only_rule = {'P','K','C','S','-','1','.','2'}
213 };
214 struct {
215 struct type6_hdr hdr;
216 struct CPRBX cprbx;
217 struct function_and_rules_block fr;
218 unsigned short length;
219 char text[0];
220 } __attribute__((packed)) *msg = ap_msg->message;
221 int size;
222
223 /* VUD.ciphertext */
224 msg->length = crt->inputdatalength + 2;
225 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
226 return -EFAULT;
227
228 /* Set up key which is located after the variable length text. */
229 size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
230 if (size < 0)
231 return size;
232 size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */
233
234 /* message header, cprbx and f&r */
235 msg->hdr = static_type6_hdrX;
236 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
237 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
238
239 msg->cprbx = static_cprbx;
240 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
241 msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
242 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
243
244 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
245 static_pkd_fnr_MCL2 : static_pkd_fnr;
246
247 ap_msg->length = size;
248 return 0;
249}
250
5432114b
RW
251/**
252 * Convert a XCRB message to a type6 CPRB message.
253 *
254 * @zdev: crypto device pointer
255 * @ap_msg: pointer to AP message
256 * @xcRB: pointer to user input data
257 *
2389aef4 258 * Returns 0 on success or -EFAULT, -EINVAL.
5432114b
RW
259 */
260struct type86_fmt2_msg {
261 struct type86_hdr hdr;
262 struct type86_fmt2_ext fmt2;
263} __attribute__((packed));
264
265static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
266 struct ap_message *ap_msg,
267 struct ica_xcRB *xcRB)
268{
269 static struct type6_hdr static_type6_hdrX = {
270 .type = 0x06,
271 .offset1 = 0x00000058,
272 };
273 struct {
274 struct type6_hdr hdr;
16db63fd 275 struct CPRBX cprbx;
5432114b
RW
276 } __attribute__((packed)) *msg = ap_msg->message;
277
278 int rcblen = CEIL4(xcRB->request_control_blk_length);
279 int replylen;
280 char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
281 char *function_code;
282
283 /* length checks */
284 ap_msg->length = sizeof(struct type6_hdr) +
285 CEIL4(xcRB->request_control_blk_length) +
286 xcRB->request_data_length;
1a89dd8f 287 if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE)
2389aef4 288 return -EINVAL;
7fe6f097
HD
289 replylen = sizeof(struct type86_fmt2_msg) +
290 CEIL4(xcRB->reply_control_blk_length) +
291 xcRB->reply_data_length;
292 if (replylen > PCIXCC_MAX_XCRB_MESSAGE_SIZE)
2389aef4 293 return -EINVAL;
5432114b
RW
294
295 /* prepare type6 header */
296 msg->hdr = static_type6_hdrX;
297 memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
298 msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
299 if (xcRB->request_data_length) {
300 msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
301 msg->hdr.ToCardLen2 = xcRB->request_data_length;
302 }
303 msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length;
304 msg->hdr.FromCardLen2 = xcRB->reply_data_length;
305
306 /* prepare CPRB */
307 if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr,
308 xcRB->request_control_blk_length))
309 return -EFAULT;
310 if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
1a89dd8f 311 xcRB->request_control_blk_length)
2389aef4 312 return -EINVAL;
5432114b
RW
313 function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
314 memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
315
a6a5d73a
FB
316 if (memcmp(function_code, "US", 2) == 0)
317 ap_msg->special = 1;
318 else
319 ap_msg->special = 0;
320
5432114b
RW
321 /* copy data block */
322 if (xcRB->request_data_length &&
323 copy_from_user(req_data, xcRB->request_data_address,
324 xcRB->request_data_length))
325 return -EFAULT;
326 return 0;
327}
328
2f7c8bd6
RW
329/**
330 * Prepare a type6 CPRB message for random number generation
331 *
332 * @ap_dev: AP device pointer
333 * @ap_msg: pointer to AP message
334 */
335static void rng_type6CPRB_msgX(struct ap_device *ap_dev,
336 struct ap_message *ap_msg,
337 unsigned random_number_length)
338{
339 struct {
340 struct type6_hdr hdr;
341 struct CPRBX cprbx;
342 char function_code[2];
343 short int rule_length;
344 char rule[8];
345 short int verb_length;
346 short int key_length;
347 } __attribute__((packed)) *msg = ap_msg->message;
348 static struct type6_hdr static_type6_hdrX = {
349 .type = 0x06,
350 .offset1 = 0x00000058,
351 .agent_id = {'C', 'A'},
352 .function_code = {'R', 'L'},
353 .ToCardLen1 = sizeof *msg - sizeof(msg->hdr),
354 .FromCardLen1 = sizeof *msg - sizeof(msg->hdr),
355 };
6458abc9 356 static struct CPRBX local_cprbx = {
2f7c8bd6
RW
357 .cprb_len = 0x00dc,
358 .cprb_ver_id = 0x02,
359 .func_id = {0x54, 0x32},
360 .req_parml = sizeof *msg - sizeof(msg->hdr) -
361 sizeof(msg->cprbx),
362 .rpl_msgbl = sizeof *msg - sizeof(msg->hdr),
363 };
364
365 msg->hdr = static_type6_hdrX;
366 msg->hdr.FromCardLen2 = random_number_length,
6458abc9 367 msg->cprbx = local_cprbx;
2f7c8bd6
RW
368 msg->cprbx.rpl_datal = random_number_length,
369 msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid);
370 memcpy(msg->function_code, msg->hdr.function_code, 0x02);
371 msg->rule_length = 0x0a;
372 memcpy(msg->rule, "RANDOM ", 8);
373 msg->verb_length = 0x02;
374 msg->key_length = 0x02;
375 ap_msg->length = sizeof *msg;
376}
377
6684af1a
MS
378/**
379 * Copy results from a type 86 ICA reply message back to user space.
380 *
381 * @zdev: crypto device pointer
382 * @reply: reply AP message.
383 * @data: pointer to user output data
384 * @length: size of user output data
385 *
386 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
387 */
388struct type86x_reply {
389 struct type86_hdr hdr;
390 struct type86_fmt2_ext fmt2;
391 struct CPRBX cprbx;
392 unsigned char pad[4]; /* 4 byte function code/rules block ? */
393 unsigned short length;
394 char text[0];
395} __attribute__((packed));
396
397static int convert_type86_ica(struct zcrypt_device *zdev,
398 struct ap_message *reply,
399 char __user *outputdata,
400 unsigned int outputdatalength)
401{
402 static unsigned char static_pad[] = {
403 0x00,0x02,
404 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
405 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
406 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
407 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
408 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
409 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
410 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
411 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
412 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
413 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
414 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
415 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
416 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
417 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
418 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
419 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
420 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
421 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
422 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
423 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
424 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
425 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
426 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
427 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
428 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
429 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
430 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
431 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
432 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
433 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
434 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
435 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
436 };
437 struct type86x_reply *msg = reply->message;
438 unsigned short service_rc, service_rs;
439 unsigned int reply_len, pad_len;
440 char *data;
441
442 service_rc = msg->cprbx.ccp_rtcode;
443 if (unlikely(service_rc != 0)) {
444 service_rs = msg->cprbx.ccp_rscode;
1a89dd8f 445 if (service_rc == 8 && service_rs == 66)
6684af1a 446 return -EINVAL;
1a89dd8f 447 if (service_rc == 8 && service_rs == 65)
6684af1a 448 return -EINVAL;
1a89dd8f 449 if (service_rc == 8 && service_rs == 770)
2af48080 450 return -EINVAL;
6684af1a 451 if (service_rc == 8 && service_rs == 783) {
6684af1a
MS
452 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
453 return -EAGAIN;
454 }
1a89dd8f 455 if (service_rc == 12 && service_rs == 769)
2af48080 456 return -EINVAL;
19b123eb
FB
457 if (service_rc == 8 && service_rs == 72)
458 return -EINVAL;
6684af1a
MS
459 zdev->online = 0;
460 return -EAGAIN; /* repeat the request on a different device. */
461 }
462 data = msg->text;
463 reply_len = msg->length - 2;
464 if (reply_len > outputdatalength)
465 return -EINVAL;
1749a81d 466 /*
6684af1a
MS
467 * For all encipher requests, the length of the ciphertext (reply_len)
468 * will always equal the modulus length. For MEX decipher requests
469 * the output needs to get padded. Minimum pad size is 10.
470 *
471 * Currently, the cases where padding will be added is for:
472 * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
473 * ZERO-PAD and CRT is only supported for PKD requests)
474 * - PCICC, always
475 */
476 pad_len = outputdatalength - reply_len;
477 if (pad_len > 0) {
478 if (pad_len < 10)
479 return -EINVAL;
480 /* 'restore' padding left in the PCICC/PCIXCC card. */
481 if (copy_to_user(outputdata, static_pad, pad_len - 1))
482 return -EFAULT;
483 if (put_user(0, outputdata + pad_len - 1))
484 return -EFAULT;
485 }
486 /* Copy the crypto response to user space. */
487 if (copy_to_user(outputdata + pad_len, data, reply_len))
488 return -EFAULT;
489 return 0;
490}
491
5432114b
RW
492/**
493 * Copy results from a type 86 XCRB reply message back to user space.
494 *
495 * @zdev: crypto device pointer
496 * @reply: reply AP message.
497 * @xcRB: pointer to XCRB
498 *
499 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
500 */
501static int convert_type86_xcrb(struct zcrypt_device *zdev,
502 struct ap_message *reply,
503 struct ica_xcRB *xcRB)
504{
505 struct type86_fmt2_msg *msg = reply->message;
506 char *data = reply->message;
507
508 /* Copy CPRB to user */
509 if (copy_to_user(xcRB->reply_control_blk_addr,
510 data + msg->fmt2.offset1, msg->fmt2.count1))
511 return -EFAULT;
512 xcRB->reply_control_blk_length = msg->fmt2.count1;
513
514 /* Copy data buffer to user */
515 if (msg->fmt2.count2)
516 if (copy_to_user(xcRB->reply_data_addr,
517 data + msg->fmt2.offset2, msg->fmt2.count2))
518 return -EFAULT;
519 xcRB->reply_data_length = msg->fmt2.count2;
520 return 0;
521}
522
2f7c8bd6
RW
523static int convert_type86_rng(struct zcrypt_device *zdev,
524 struct ap_message *reply,
525 char *buffer)
526{
527 struct {
528 struct type86_hdr hdr;
529 struct type86_fmt2_ext fmt2;
530 struct CPRBX cprbx;
531 } __attribute__((packed)) *msg = reply->message;
532 char *data = reply->message;
533
1a89dd8f 534 if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
2f7c8bd6 535 return -EINVAL;
2f7c8bd6
RW
536 memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
537 return msg->fmt2.count2;
538}
539
6684af1a
MS
540static int convert_response_ica(struct zcrypt_device *zdev,
541 struct ap_message *reply,
542 char __user *outputdata,
543 unsigned int outputdatalength)
544{
545 struct type86x_reply *msg = reply->message;
546
547 /* Response type byte is the second byte in the response. */
548 switch (((unsigned char *) reply->message)[1]) {
549 case TYPE82_RSP_CODE:
550 case TYPE88_RSP_CODE:
551 return convert_error(zdev, reply);
552 case TYPE86_RSP_CODE:
c2567f8f
FB
553 if (msg->cprbx.ccp_rtcode &&
554 (msg->cprbx.ccp_rscode == 0x14f) &&
555 (outputdatalength > 256)) {
556 if (zdev->max_exp_bit_length <= 17) {
557 zdev->max_exp_bit_length = 17;
558 return -EAGAIN;
559 } else
560 return -EINVAL;
561 }
6684af1a
MS
562 if (msg->hdr.reply_code)
563 return convert_error(zdev, reply);
564 if (msg->cprbx.cprb_ver_id == 0x02)
565 return convert_type86_ica(zdev, reply,
566 outputdata, outputdatalength);
942b7e65
FB
567 /* Fall through, no break, incorrect cprb version is an unknown
568 * response */
6684af1a 569 default: /* Unknown response type, this should NEVER EVER happen */
6684af1a
MS
570 zdev->online = 0;
571 return -EAGAIN; /* repeat the request on a different device. */
572 }
573}
574
5432114b
RW
575static int convert_response_xcrb(struct zcrypt_device *zdev,
576 struct ap_message *reply,
577 struct ica_xcRB *xcRB)
578{
579 struct type86x_reply *msg = reply->message;
580
581 /* Response type byte is the second byte in the response. */
582 switch (((unsigned char *) reply->message)[1]) {
583 case TYPE82_RSP_CODE:
584 case TYPE88_RSP_CODE:
585 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
586 return convert_error(zdev, reply);
587 case TYPE86_RSP_CODE:
588 if (msg->hdr.reply_code) {
589 memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
590 return convert_error(zdev, reply);
591 }
592 if (msg->cprbx.cprb_ver_id == 0x02)
593 return convert_type86_xcrb(zdev, reply, xcRB);
942b7e65
FB
594 /* Fall through, no break, incorrect cprb version is an unknown
595 * response */
5432114b 596 default: /* Unknown response type, this should NEVER EVER happen */
5432114b
RW
597 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
598 zdev->online = 0;
599 return -EAGAIN; /* repeat the request on a different device. */
600 }
601}
602
2f7c8bd6
RW
603static int convert_response_rng(struct zcrypt_device *zdev,
604 struct ap_message *reply,
605 char *data)
606{
607 struct type86x_reply *msg = reply->message;
608
609 switch (msg->hdr.type) {
610 case TYPE82_RSP_CODE:
611 case TYPE88_RSP_CODE:
612 return -EINVAL;
613 case TYPE86_RSP_CODE:
614 if (msg->hdr.reply_code)
615 return -EINVAL;
616 if (msg->cprbx.cprb_ver_id == 0x02)
617 return convert_type86_rng(zdev, reply, data);
942b7e65
FB
618 /* Fall through, no break, incorrect cprb version is an unknown
619 * response */
2f7c8bd6 620 default: /* Unknown response type, this should NEVER EVER happen */
2f7c8bd6
RW
621 zdev->online = 0;
622 return -EAGAIN; /* repeat the request on a different device. */
623 }
624}
625
6684af1a
MS
626/**
627 * This function is called from the AP bus code after a crypto request
628 * "msg" has finished with the reply message "reply".
629 * It is called from tasklet context.
630 * @ap_dev: pointer to the AP device
631 * @msg: pointer to the AP message
632 * @reply: pointer to the AP reply message
633 */
634static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
635 struct ap_message *msg,
636 struct ap_message *reply)
637{
638 static struct error_hdr error_reply = {
639 .type = TYPE82_RSP_CODE,
640 .reply_code = REP82_ERROR_MACHINE_FAILURE,
641 };
5432114b
RW
642 struct response_type *resp_type =
643 (struct response_type *) msg->private;
21e7b2c4 644 struct type86x_reply *t86r;
6684af1a
MS
645 int length;
646
647 /* Copy the reply message to the request message buffer. */
21e7b2c4 648 if (IS_ERR(reply)) {
6684af1a 649 memcpy(msg->message, &error_reply, sizeof(error_reply));
21e7b2c4
JL
650 goto out;
651 }
652 t86r = reply->message;
653 if (t86r->hdr.type == TYPE86_RSP_CODE &&
6684af1a 654 t86r->cprbx.cprb_ver_id == 0x02) {
5432114b
RW
655 switch (resp_type->type) {
656 case PCIXCC_RESPONSE_TYPE_ICA:
657 length = sizeof(struct type86x_reply)
658 + t86r->length - 2;
659 length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
660 memcpy(msg->message, reply->message, length);
661 break;
662 case PCIXCC_RESPONSE_TYPE_XCRB:
663 length = t86r->fmt2.offset2 + t86r->fmt2.count2;
7fe6f097 664 length = min(PCIXCC_MAX_XCRB_MESSAGE_SIZE, length);
5432114b
RW
665 memcpy(msg->message, reply->message, length);
666 break;
667 default:
1a89dd8f 668 memcpy(msg->message, &error_reply, sizeof error_reply);
5432114b 669 }
6684af1a
MS
670 } else
671 memcpy(msg->message, reply->message, sizeof error_reply);
21e7b2c4 672out:
5432114b 673 complete(&(resp_type->work));
6684af1a
MS
674}
675
676static atomic_t zcrypt_step = ATOMIC_INIT(0);
677
678/**
679 * The request distributor calls this function if it picked the PCIXCC/CEX2C
680 * device to handle a modexpo request.
681 * @zdev: pointer to zcrypt_device structure that identifies the
682 * PCIXCC/CEX2C device to the request distributor
683 * @mex: pointer to the modexpo request buffer
684 */
685static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
686 struct ica_rsa_modexpo *mex)
687{
688 struct ap_message ap_msg;
5432114b
RW
689 struct response_type resp_type = {
690 .type = PCIXCC_RESPONSE_TYPE_ICA,
691 };
6684af1a
MS
692 int rc;
693
468ffddf 694 ap_init_message(&ap_msg);
6684af1a
MS
695 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
696 if (!ap_msg.message)
697 return -ENOMEM;
54a8f561 698 ap_msg.receive = zcrypt_pcixcc_receive;
6684af1a
MS
699 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
700 atomic_inc_return(&zcrypt_step);
5432114b 701 ap_msg.private = &resp_type;
6684af1a
MS
702 rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
703 if (rc)
704 goto out_free;
5432114b 705 init_completion(&resp_type.work);
6684af1a 706 ap_queue_message(zdev->ap_dev, &ap_msg);
af512ed0
RW
707 rc = wait_for_completion_interruptible(&resp_type.work);
708 if (rc == 0)
6684af1a
MS
709 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
710 mex->outputdatalength);
af512ed0
RW
711 else
712 /* Signal pending. */
6684af1a 713 ap_cancel_message(zdev->ap_dev, &ap_msg);
6684af1a
MS
714out_free:
715 free_page((unsigned long) ap_msg.message);
716 return rc;
717}
718
719/**
720 * The request distributor calls this function if it picked the PCIXCC/CEX2C
721 * device to handle a modexpo_crt request.
722 * @zdev: pointer to zcrypt_device structure that identifies the
723 * PCIXCC/CEX2C device to the request distributor
724 * @crt: pointer to the modexpoc_crt request buffer
725 */
726static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
727 struct ica_rsa_modexpo_crt *crt)
728{
729 struct ap_message ap_msg;
5432114b
RW
730 struct response_type resp_type = {
731 .type = PCIXCC_RESPONSE_TYPE_ICA,
732 };
6684af1a
MS
733 int rc;
734
468ffddf 735 ap_init_message(&ap_msg);
6684af1a
MS
736 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
737 if (!ap_msg.message)
738 return -ENOMEM;
54a8f561 739 ap_msg.receive = zcrypt_pcixcc_receive;
6684af1a
MS
740 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
741 atomic_inc_return(&zcrypt_step);
5432114b 742 ap_msg.private = &resp_type;
6684af1a
MS
743 rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
744 if (rc)
745 goto out_free;
5432114b 746 init_completion(&resp_type.work);
6684af1a 747 ap_queue_message(zdev->ap_dev, &ap_msg);
af512ed0
RW
748 rc = wait_for_completion_interruptible(&resp_type.work);
749 if (rc == 0)
6684af1a
MS
750 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
751 crt->outputdatalength);
af512ed0
RW
752 else
753 /* Signal pending. */
6684af1a 754 ap_cancel_message(zdev->ap_dev, &ap_msg);
6684af1a
MS
755out_free:
756 free_page((unsigned long) ap_msg.message);
757 return rc;
758}
759
5432114b
RW
760/**
761 * The request distributor calls this function if it picked the PCIXCC/CEX2C
762 * device to handle a send_cprb request.
763 * @zdev: pointer to zcrypt_device structure that identifies the
764 * PCIXCC/CEX2C device to the request distributor
765 * @xcRB: pointer to the send_cprb request buffer
766 */
2b67fc46
HC
767static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
768 struct ica_xcRB *xcRB)
5432114b
RW
769{
770 struct ap_message ap_msg;
771 struct response_type resp_type = {
772 .type = PCIXCC_RESPONSE_TYPE_XCRB,
773 };
774 int rc;
775
468ffddf 776 ap_init_message(&ap_msg);
5cbded58 777 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
5432114b
RW
778 if (!ap_msg.message)
779 return -ENOMEM;
54a8f561 780 ap_msg.receive = zcrypt_pcixcc_receive;
5432114b
RW
781 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
782 atomic_inc_return(&zcrypt_step);
783 ap_msg.private = &resp_type;
784 rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
785 if (rc)
786 goto out_free;
787 init_completion(&resp_type.work);
788 ap_queue_message(zdev->ap_dev, &ap_msg);
af512ed0
RW
789 rc = wait_for_completion_interruptible(&resp_type.work);
790 if (rc == 0)
5432114b 791 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
af512ed0
RW
792 else
793 /* Signal pending. */
5432114b 794 ap_cancel_message(zdev->ap_dev, &ap_msg);
5432114b 795out_free:
3e75a902 796 kzfree(ap_msg.message);
5432114b
RW
797 return rc;
798}
799
2f7c8bd6
RW
800/**
801 * The request distributor calls this function if it picked the PCIXCC/CEX2C
802 * device to generate random data.
803 * @zdev: pointer to zcrypt_device structure that identifies the
804 * PCIXCC/CEX2C device to the request distributor
805 * @buffer: pointer to a memory page to return random data
806 */
807
808static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev,
809 char *buffer)
810{
811 struct ap_message ap_msg;
812 struct response_type resp_type = {
813 .type = PCIXCC_RESPONSE_TYPE_XCRB,
814 };
815 int rc;
816
468ffddf 817 ap_init_message(&ap_msg);
2f7c8bd6
RW
818 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
819 if (!ap_msg.message)
820 return -ENOMEM;
54a8f561 821 ap_msg.receive = zcrypt_pcixcc_receive;
2f7c8bd6
RW
822 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
823 atomic_inc_return(&zcrypt_step);
824 ap_msg.private = &resp_type;
825 rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE);
826 init_completion(&resp_type.work);
827 ap_queue_message(zdev->ap_dev, &ap_msg);
828 rc = wait_for_completion_interruptible(&resp_type.work);
829 if (rc == 0)
830 rc = convert_response_rng(zdev, &ap_msg, buffer);
831 else
832 /* Signal pending. */
833 ap_cancel_message(zdev->ap_dev, &ap_msg);
834 kfree(ap_msg.message);
835 return rc;
836}
837
6684af1a
MS
838/**
839 * The crypto operations for a PCIXCC/CEX2C card.
840 */
841static struct zcrypt_ops zcrypt_pcixcc_ops = {
842 .rsa_modexpo = zcrypt_pcixcc_modexpo,
843 .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
5432114b 844 .send_cprb = zcrypt_pcixcc_send_cprb,
6684af1a
MS
845};
846
2f7c8bd6
RW
847static struct zcrypt_ops zcrypt_pcixcc_with_rng_ops = {
848 .rsa_modexpo = zcrypt_pcixcc_modexpo,
849 .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
850 .send_cprb = zcrypt_pcixcc_send_cprb,
851 .rng = zcrypt_pcixcc_rng,
852};
853
6684af1a
MS
854/**
855 * Micro-code detection function. Its sends a message to a pcixcc card
856 * to find out the microcode level.
857 * @ap_dev: pointer to the AP device.
858 */
859static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
860{
861 static unsigned char msg[] = {
862 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
863 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
864 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
865 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
866 0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
867 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
868 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
869 0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
870 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
871 0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
872 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
873 0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
874 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
875 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
876 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
877 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
878 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
879 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
880 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
881 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
882 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
883 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
884 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
885 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
886 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
887 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
888 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
889 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
890 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
891 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
892 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
893 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
894 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,
895 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
896 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
897 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
898 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
899 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
900 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,
901 0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
902 0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
903 0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
904 0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
905 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
906 0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
907 0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
908 0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
909 0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
910 0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
911 0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
912 0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
913 0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
914 0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
915 0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
916 0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
917 0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
918 0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
919 0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
920 0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
921 0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
922 0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
923 0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
924 0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
925 0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
926 0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
927 0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
928 0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
929 0xF1,0x3D,0x93,0x53
930 };
931 unsigned long long psmid;
932 struct CPRBX *cprbx;
933 char *reply;
934 int rc, i;
935
936 reply = (void *) get_zeroed_page(GFP_KERNEL);
937 if (!reply)
938 return -ENOMEM;
939
940 rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
941 if (rc)
942 goto out_free;
943
944 /* Wait for the test message to complete. */
945 for (i = 0; i < 6; i++) {
946 mdelay(300);
947 rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
948 if (rc == 0 && psmid == 0x0102030405060708ULL)
949 break;
950 }
951
952 if (i >= 6) {
953 /* Got no answer. */
954 rc = -ENODEV;
955 goto out_free;
956 }
957
958 cprbx = (struct CPRBX *) (reply + 48);
959 if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
960 rc = ZCRYPT_PCIXCC_MCL2;
961 else
962 rc = ZCRYPT_PCIXCC_MCL3;
963out_free:
964 free_page((unsigned long) reply);
965 return rc;
966}
967
2f7c8bd6
RW
968/**
969 * Large random number detection function. Its sends a message to a pcixcc
970 * card to find out if large random numbers are supported.
971 * @ap_dev: pointer to the AP device.
972 *
973 * Returns 1 if large random numbers are supported, 0 if not and < 0 on error.
974 */
975static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
976{
977 struct ap_message ap_msg;
978 unsigned long long psmid;
979 struct {
980 struct type86_hdr hdr;
981 struct type86_fmt2_ext fmt2;
982 struct CPRBX cprbx;
983 } __attribute__((packed)) *reply;
984 int rc, i;
985
468ffddf 986 ap_init_message(&ap_msg);
2f7c8bd6
RW
987 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
988 if (!ap_msg.message)
989 return -ENOMEM;
990
991 rng_type6CPRB_msgX(ap_dev, &ap_msg, 4);
992 rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, ap_msg.message,
993 ap_msg.length);
994 if (rc)
995 goto out_free;
996
997 /* Wait for the test message to complete. */
998 for (i = 0; i < 2 * HZ; i++) {
999 msleep(1000 / HZ);
1000 rc = ap_recv(ap_dev->qid, &psmid, ap_msg.message, 4096);
1001 if (rc == 0 && psmid == 0x0102030405060708ULL)
1002 break;
1003 }
1004
1005 if (i >= 2 * HZ) {
1006 /* Got no answer. */
1007 rc = -ENODEV;
1008 goto out_free;
1009 }
1010
1011 reply = ap_msg.message;
1012 if (reply->cprbx.ccp_rtcode == 0 && reply->cprbx.ccp_rscode == 0)
1013 rc = 1;
1014 else
1015 rc = 0;
1016out_free:
1017 free_page((unsigned long) ap_msg.message);
1018 return rc;
1019}
1020
6684af1a
MS
1021/**
1022 * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
1023 * since the bus_match already checked the hardware type. The PCIXCC
1024 * cards come in two flavours: micro code level 2 and micro code level 3.
1025 * This is checked by sending a test message to the device.
1026 * @ap_dev: pointer to the AP device.
1027 */
1028static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
1029{
1030 struct zcrypt_device *zdev;
8e89b6be 1031 int rc = 0;
6684af1a 1032
7fe6f097 1033 zdev = zcrypt_device_alloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE);
6684af1a
MS
1034 if (!zdev)
1035 return -ENOMEM;
1036 zdev->ap_dev = ap_dev;
6684af1a 1037 zdev->online = 1;
8e89b6be
FB
1038 switch (ap_dev->device_type) {
1039 case AP_DEVICE_TYPE_PCIXCC:
6684af1a
MS
1040 rc = zcrypt_pcixcc_mcl(ap_dev);
1041 if (rc < 0) {
1042 zcrypt_device_free(zdev);
1043 return rc;
1044 }
1045 zdev->user_space_type = rc;
1046 if (rc == ZCRYPT_PCIXCC_MCL2) {
1047 zdev->type_string = "PCIXCC_MCL2";
1048 zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
1049 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
1050 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
c2567f8f 1051 zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
6684af1a
MS
1052 } else {
1053 zdev->type_string = "PCIXCC_MCL3";
1054 zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
1055 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1056 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
c2567f8f 1057 zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
6684af1a 1058 }
8e89b6be
FB
1059 break;
1060 case AP_DEVICE_TYPE_CEX2C:
6684af1a
MS
1061 zdev->user_space_type = ZCRYPT_CEX2C;
1062 zdev->type_string = "CEX2C";
1063 zdev->speed_rating = CEX2C_SPEED_RATING;
1064 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1065 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
c2567f8f 1066 zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
8e89b6be
FB
1067 break;
1068 case AP_DEVICE_TYPE_CEX3C:
1069 zdev->user_space_type = ZCRYPT_CEX3C;
1070 zdev->type_string = "CEX3C";
1071 zdev->speed_rating = CEX3C_SPEED_RATING;
1072 zdev->min_mod_size = CEX3C_MIN_MOD_SIZE;
1073 zdev->max_mod_size = CEX3C_MAX_MOD_SIZE;
c2567f8f 1074 zdev->max_exp_bit_length = CEX3C_MAX_MOD_SIZE;
8e89b6be
FB
1075 break;
1076 default:
1077 goto out_free;
6684af1a 1078 }
8e89b6be 1079
2f7c8bd6
RW
1080 rc = zcrypt_pcixcc_rng_supported(ap_dev);
1081 if (rc < 0) {
1082 zcrypt_device_free(zdev);
1083 return rc;
1084 }
1085 if (rc)
1086 zdev->ops = &zcrypt_pcixcc_with_rng_ops;
1087 else
1088 zdev->ops = &zcrypt_pcixcc_ops;
6684af1a
MS
1089 ap_dev->reply = &zdev->reply;
1090 ap_dev->private = zdev;
1091 rc = zcrypt_device_register(zdev);
1092 if (rc)
1093 goto out_free;
1094 return 0;
1095
1096 out_free:
1097 ap_dev->private = NULL;
1098 zcrypt_device_free(zdev);
1099 return rc;
1100}
1101
1102/**
1103 * This is called to remove the extended PCIXCC/CEX2C driver information
1104 * if an AP device is removed.
1105 */
1106static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
1107{
1108 struct zcrypt_device *zdev = ap_dev->private;
1109
1110 zcrypt_device_unregister(zdev);
1111}
1112
1113int __init zcrypt_pcixcc_init(void)
1114{
1115 return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
1116}
1117
1118void zcrypt_pcixcc_exit(void)
1119{
1120 ap_driver_unregister(&zcrypt_pcixcc_driver);
1121}
1122
6684af1a
MS
1123module_init(zcrypt_pcixcc_init);
1124module_exit(zcrypt_pcixcc_exit);