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