]> Pileus Git - ~andy/linux/blob - drivers/s390/crypto/zcrypt_pcicc.c
s390/ap: move receive callback to message struct
[~andy/linux] / drivers / s390 / crypto / zcrypt_pcicc.c
1 /*
2  *  linux/drivers/s390/crypto/zcrypt_pcicc.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/gfp.h>
32 #include <linux/err.h>
33 #include <linux/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_cca_key.h"
41
42 #define PCICC_MIN_MOD_SIZE       64     /*  512 bits */
43 #define PCICC_MAX_MOD_SIZE_OLD  128     /* 1024 bits */
44 #define PCICC_MAX_MOD_SIZE      256     /* 2048 bits */
45
46 /*
47  * PCICC cards need a speed rating of 0. This keeps them at the end of
48  * the zcrypt device list (see zcrypt_api.c). PCICC cards are only
49  * used if no other cards are present because they are slow and can only
50  * cope with PKCS12 padded requests. The logic is queer. PKCS11 padded
51  * requests are rejected. The modexpo function encrypts PKCS12 padded data
52  * and decrypts any non-PKCS12 padded data (except PKCS11) in the assumption
53  * that it's encrypted PKCS12 data. The modexpo_crt function always decrypts
54  * the data in the assumption that its PKCS12 encrypted data.
55  */
56 #define PCICC_SPEED_RATING      0
57
58 #define PCICC_MAX_MESSAGE_SIZE 0x710    /* max size type6 v1 crt message */
59 #define PCICC_MAX_RESPONSE_SIZE 0x710   /* max size type86 v1 reply      */
60
61 #define PCICC_CLEANUP_TIME      (15*HZ)
62
63 static struct ap_device_id zcrypt_pcicc_ids[] = {
64         { AP_DEVICE(AP_DEVICE_TYPE_PCICC) },
65         { /* end of list */ },
66 };
67
68 MODULE_DEVICE_TABLE(ap, zcrypt_pcicc_ids);
69 MODULE_AUTHOR("IBM Corporation");
70 MODULE_DESCRIPTION("PCICC Cryptographic Coprocessor device driver, "
71                    "Copyright 2001, 2006 IBM Corporation");
72 MODULE_LICENSE("GPL");
73
74 static int zcrypt_pcicc_probe(struct ap_device *ap_dev);
75 static void zcrypt_pcicc_remove(struct ap_device *ap_dev);
76 static void zcrypt_pcicc_receive(struct ap_device *, struct ap_message *,
77                                  struct ap_message *);
78
79 static struct ap_driver zcrypt_pcicc_driver = {
80         .probe = zcrypt_pcicc_probe,
81         .remove = zcrypt_pcicc_remove,
82         .ids = zcrypt_pcicc_ids,
83         .request_timeout = PCICC_CLEANUP_TIME,
84 };
85
86 /**
87  * The following is used to initialize the CPRB passed to the PCICC card
88  * in a type6 message. The 3 fields that must be filled in at execution
89  * time are  req_parml, rpl_parml and usage_domain. Note that all three
90  * fields are *little*-endian. Actually, everything about this interface
91  * is ascii/little-endian, since the device has 'Intel inside'.
92  *
93  * The CPRB is followed immediately by the parm block.
94  * The parm block contains:
95  * - function code ('PD' 0x5044 or 'PK' 0x504B)
96  * - rule block (0x0A00 'PKCS-1.2' or 0x0A00 'ZERO-PAD')
97  * - VUD block
98  */
99 static struct CPRB static_cprb = {
100         .cprb_len       = __constant_cpu_to_le16(0x0070),
101         .cprb_ver_id    =  0x41,
102         .func_id        = {0x54,0x32},
103         .checkpoint_flag=  0x01,
104         .svr_namel      = __constant_cpu_to_le16(0x0008),
105         .svr_name       = {'I','C','S','F',' ',' ',' ',' '}
106 };
107
108 /**
109  * Check the message for PKCS11 padding.
110  */
111 static inline int is_PKCS11_padded(unsigned char *buffer, int length)
112 {
113         int i;
114         if ((buffer[0] != 0x00) || (buffer[1] != 0x01))
115                 return 0;
116         for (i = 2; i < length; i++)
117                 if (buffer[i] != 0xFF)
118                         break;
119         if (i < 10 || i == length)
120                 return 0;
121         if (buffer[i] != 0x00)
122                 return 0;
123         return 1;
124 }
125
126 /**
127  * Check the message for PKCS12 padding.
128  */
129 static inline int is_PKCS12_padded(unsigned char *buffer, int length)
130 {
131         int i;
132         if ((buffer[0] != 0x00) || (buffer[1] != 0x02))
133                 return 0;
134         for (i = 2; i < length; i++)
135                 if (buffer[i] == 0x00)
136                         break;
137         if ((i < 10) || (i == length))
138                 return 0;
139         if (buffer[i] != 0x00)
140                 return 0;
141         return 1;
142 }
143
144 /**
145  * Convert a ICAMEX message to a type6 MEX message.
146  *
147  * @zdev: crypto device pointer
148  * @zreq: crypto request pointer
149  * @mex: pointer to user input data
150  *
151  * Returns 0 on success or -EFAULT.
152  */
153 static int ICAMEX_msg_to_type6MEX_msg(struct zcrypt_device *zdev,
154                                       struct ap_message *ap_msg,
155                                       struct ica_rsa_modexpo *mex)
156 {
157         static struct type6_hdr static_type6_hdr = {
158                 .type           =  0x06,
159                 .offset1        =  0x00000058,
160                 .agent_id       = {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
161                                    0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
162                 .function_code  = {'P','K'},
163         };
164         static struct function_and_rules_block static_pke_function_and_rules ={
165                 .function_code  = {'P','K'},
166                 .ulen           = __constant_cpu_to_le16(10),
167                 .only_rule      = {'P','K','C','S','-','1','.','2'}
168         };
169         struct {
170                 struct type6_hdr hdr;
171                 struct CPRB cprb;
172                 struct function_and_rules_block fr;
173                 unsigned short length;
174                 char text[0];
175         } __attribute__((packed)) *msg = ap_msg->message;
176         int vud_len, pad_len, size;
177
178         /* VUD.ciphertext */
179         if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
180                 return -EFAULT;
181
182         if (is_PKCS11_padded(msg->text, mex->inputdatalength))
183                 return -EINVAL;
184
185         /* static message header and f&r */
186         msg->hdr = static_type6_hdr;
187         msg->fr = static_pke_function_and_rules;
188
189         if (is_PKCS12_padded(msg->text, mex->inputdatalength)) {
190                 /* strip the padding and adjust the data length */
191                 pad_len = strnlen(msg->text + 2, mex->inputdatalength - 2) + 3;
192                 if (pad_len <= 9 || pad_len >= mex->inputdatalength)
193                         return -ENODEV;
194                 vud_len = mex->inputdatalength - pad_len;
195                 memmove(msg->text, msg->text + pad_len, vud_len);
196                 msg->length = cpu_to_le16(vud_len + 2);
197
198                 /* Set up key after the variable length text. */
199                 size = zcrypt_type6_mex_key_en(mex, msg->text + vud_len, 0);
200                 if (size < 0)
201                         return size;
202                 size += sizeof(*msg) + vud_len; /* total size of msg */
203         } else {
204                 vud_len = mex->inputdatalength;
205                 msg->length = cpu_to_le16(2 + vud_len);
206
207                 msg->hdr.function_code[1] = 'D';
208                 msg->fr.function_code[1] = 'D';
209
210                 /* Set up key after the variable length text. */
211                 size = zcrypt_type6_mex_key_de(mex, msg->text + vud_len, 0);
212                 if (size < 0)
213                         return size;
214                 size += sizeof(*msg) + vud_len; /* total size of msg */
215         }
216
217         /* message header, cprb and f&r */
218         msg->hdr.ToCardLen1 = (size - sizeof(msg->hdr) + 3) & -4;
219         msg->hdr.FromCardLen1 = PCICC_MAX_RESPONSE_SIZE - sizeof(msg->hdr);
220
221         msg->cprb = static_cprb;
222         msg->cprb.usage_domain[0]= AP_QID_QUEUE(zdev->ap_dev->qid);
223         msg->cprb.req_parml = cpu_to_le16(size - sizeof(msg->hdr) -
224                                            sizeof(msg->cprb));
225         msg->cprb.rpl_parml = cpu_to_le16(msg->hdr.FromCardLen1);
226
227         ap_msg->length = (size + 3) & -4;
228         return 0;
229 }
230
231 /**
232  * Convert a ICACRT message to a type6 CRT message.
233  *
234  * @zdev: crypto device pointer
235  * @zreq: crypto request pointer
236  * @crt: pointer to user input data
237  *
238  * Returns 0 on success or -EFAULT.
239  */
240 static int ICACRT_msg_to_type6CRT_msg(struct zcrypt_device *zdev,
241                                       struct ap_message *ap_msg,
242                                       struct ica_rsa_modexpo_crt *crt)
243 {
244         static struct type6_hdr static_type6_hdr = {
245                 .type           =  0x06,
246                 .offset1        =  0x00000058,
247                 .agent_id       = {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
248                                    0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
249                 .function_code  = {'P','D'},
250         };
251         static struct function_and_rules_block static_pkd_function_and_rules ={
252                 .function_code  = {'P','D'},
253                 .ulen           = __constant_cpu_to_le16(10),
254                 .only_rule      = {'P','K','C','S','-','1','.','2'}
255         };
256         struct {
257                 struct type6_hdr hdr;
258                 struct CPRB cprb;
259                 struct function_and_rules_block fr;
260                 unsigned short length;
261                 char text[0];
262         } __attribute__((packed)) *msg = ap_msg->message;
263         int size;
264
265         /* VUD.ciphertext */
266         msg->length = cpu_to_le16(2 + crt->inputdatalength);
267         if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
268                 return -EFAULT;
269
270         if (is_PKCS11_padded(msg->text, crt->inputdatalength))
271                 return -EINVAL;
272
273         /* Set up key after the variable length text. */
274         size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 0);
275         if (size < 0)
276                 return size;
277         size += sizeof(*msg) + crt->inputdatalength;    /* total size of msg */
278
279         /* message header, cprb and f&r */
280         msg->hdr = static_type6_hdr;
281         msg->hdr.ToCardLen1 = (size -  sizeof(msg->hdr) + 3) & -4;
282         msg->hdr.FromCardLen1 = PCICC_MAX_RESPONSE_SIZE - sizeof(msg->hdr);
283
284         msg->cprb = static_cprb;
285         msg->cprb.usage_domain[0] = AP_QID_QUEUE(zdev->ap_dev->qid);
286         msg->cprb.req_parml = msg->cprb.rpl_parml =
287                 cpu_to_le16(size - sizeof(msg->hdr) - sizeof(msg->cprb));
288
289         msg->fr = static_pkd_function_and_rules;
290
291         ap_msg->length = (size + 3) & -4;
292         return 0;
293 }
294
295 /**
296  * Copy results from a type 86 reply message back to user space.
297  *
298  * @zdev: crypto device pointer
299  * @reply: reply AP message.
300  * @data: pointer to user output data
301  * @length: size of user output data
302  *
303  * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
304  */
305 struct type86_reply {
306         struct type86_hdr hdr;
307         struct type86_fmt2_ext fmt2;
308         struct CPRB cprb;
309         unsigned char pad[4];   /* 4 byte function code/rules block ? */
310         unsigned short length;
311         char text[0];
312 } __attribute__((packed));
313
314 static int convert_type86(struct zcrypt_device *zdev,
315                           struct ap_message *reply,
316                           char __user *outputdata,
317                           unsigned int outputdatalength)
318 {
319         static unsigned char static_pad[] = {
320                 0x00,0x02,
321                 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
322                 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
323                 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
324                 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
325                 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
326                 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
327                 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
328                 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
329                 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
330                 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
331                 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
332                 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
333                 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
334                 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
335                 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
336                 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
337                 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
338                 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
339                 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
340                 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
341                 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
342                 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
343                 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
344                 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
345                 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
346                 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
347                 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
348                 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
349                 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
350                 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
351                 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
352                 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
353         };
354         struct type86_reply *msg = reply->message;
355         unsigned short service_rc, service_rs;
356         unsigned int reply_len, pad_len;
357         char *data;
358
359         service_rc = le16_to_cpu(msg->cprb.ccp_rtcode);
360         if (unlikely(service_rc != 0)) {
361                 service_rs = le16_to_cpu(msg->cprb.ccp_rscode);
362                 if (service_rc == 8 && service_rs == 66)
363                         return -EINVAL;
364                 if (service_rc == 8 && service_rs == 65)
365                         return -EINVAL;
366                 if (service_rc == 8 && service_rs == 770) {
367                         zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
368                         return -EAGAIN;
369                 }
370                 if (service_rc == 8 && service_rs == 783) {
371                         zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
372                         return -EAGAIN;
373                 }
374                 if (service_rc == 8 && service_rs == 72)
375                         return -EINVAL;
376                 zdev->online = 0;
377                 return -EAGAIN; /* repeat the request on a different device. */
378         }
379         data = msg->text;
380         reply_len = le16_to_cpu(msg->length) - 2;
381         if (reply_len > outputdatalength)
382                 return -EINVAL;
383         /*
384          * For all encipher requests, the length of the ciphertext (reply_len)
385          * will always equal the modulus length. For MEX decipher requests
386          * the output needs to get padded. Minimum pad size is 10.
387          *
388          * Currently, the cases where padding will be added is for:
389          * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
390          *   ZERO-PAD and CRT is only supported for PKD requests)
391          * - PCICC, always
392          */
393         pad_len = outputdatalength - reply_len;
394         if (pad_len > 0) {
395                 if (pad_len < 10)
396                         return -EINVAL;
397                 /* 'restore' padding left in the PCICC/PCIXCC card. */
398                 if (copy_to_user(outputdata, static_pad, pad_len - 1))
399                         return -EFAULT;
400                 if (put_user(0, outputdata + pad_len - 1))
401                         return -EFAULT;
402         }
403         /* Copy the crypto response to user space. */
404         if (copy_to_user(outputdata + pad_len, data, reply_len))
405                 return -EFAULT;
406         return 0;
407 }
408
409 static int convert_response(struct zcrypt_device *zdev,
410                             struct ap_message *reply,
411                             char __user *outputdata,
412                             unsigned int outputdatalength)
413 {
414         struct type86_reply *msg = reply->message;
415
416         /* Response type byte is the second byte in the response. */
417         switch (msg->hdr.type) {
418         case TYPE82_RSP_CODE:
419         case TYPE88_RSP_CODE:
420                 return convert_error(zdev, reply);
421         case TYPE86_RSP_CODE:
422                 if (msg->hdr.reply_code)
423                         return convert_error(zdev, reply);
424                 if (msg->cprb.cprb_ver_id == 0x01)
425                         return convert_type86(zdev, reply,
426                                               outputdata, outputdatalength);
427                 /* no break, incorrect cprb version is an unknown response */
428         default: /* Unknown response type, this should NEVER EVER happen */
429                 zdev->online = 0;
430                 return -EAGAIN; /* repeat the request on a different device. */
431         }
432 }
433
434 /**
435  * This function is called from the AP bus code after a crypto request
436  * "msg" has finished with the reply message "reply".
437  * It is called from tasklet context.
438  * @ap_dev: pointer to the AP device
439  * @msg: pointer to the AP message
440  * @reply: pointer to the AP reply message
441  */
442 static void zcrypt_pcicc_receive(struct ap_device *ap_dev,
443                                  struct ap_message *msg,
444                                  struct ap_message *reply)
445 {
446         static struct error_hdr error_reply = {
447                 .type = TYPE82_RSP_CODE,
448                 .reply_code = REP82_ERROR_MACHINE_FAILURE,
449         };
450         struct type86_reply *t86r;
451         int length;
452
453         /* Copy the reply message to the request message buffer. */
454         if (IS_ERR(reply)) {
455                 memcpy(msg->message, &error_reply, sizeof(error_reply));
456                 goto out;
457         }
458         t86r = reply->message;
459         if (t86r->hdr.type == TYPE86_RSP_CODE &&
460                  t86r->cprb.cprb_ver_id == 0x01) {
461                 length = sizeof(struct type86_reply) + t86r->length - 2;
462                 length = min(PCICC_MAX_RESPONSE_SIZE, length);
463                 memcpy(msg->message, reply->message, length);
464         } else
465                 memcpy(msg->message, reply->message, sizeof error_reply);
466 out:
467         complete((struct completion *) msg->private);
468 }
469
470 static atomic_t zcrypt_step = ATOMIC_INIT(0);
471
472 /**
473  * The request distributor calls this function if it picked the PCICC
474  * device to handle a modexpo request.
475  * @zdev: pointer to zcrypt_device structure that identifies the
476  *        PCICC device to the request distributor
477  * @mex: pointer to the modexpo request buffer
478  */
479 static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev,
480                                  struct ica_rsa_modexpo *mex)
481 {
482         struct ap_message ap_msg;
483         struct completion work;
484         int rc;
485
486         ap_init_message(&ap_msg);
487         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
488         if (!ap_msg.message)
489                 return -ENOMEM;
490         ap_msg.receive = zcrypt_pcicc_receive;
491         ap_msg.length = PAGE_SIZE;
492         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
493                                 atomic_inc_return(&zcrypt_step);
494         ap_msg.private = &work;
495         rc = ICAMEX_msg_to_type6MEX_msg(zdev, &ap_msg, mex);
496         if (rc)
497                 goto out_free;
498         init_completion(&work);
499         ap_queue_message(zdev->ap_dev, &ap_msg);
500         rc = wait_for_completion_interruptible(&work);
501         if (rc == 0)
502                 rc = convert_response(zdev, &ap_msg, mex->outputdata,
503                                       mex->outputdatalength);
504         else
505                 /* Signal pending. */
506                 ap_cancel_message(zdev->ap_dev, &ap_msg);
507 out_free:
508         free_page((unsigned long) ap_msg.message);
509         return rc;
510 }
511
512 /**
513  * The request distributor calls this function if it picked the PCICC
514  * device to handle a modexpo_crt request.
515  * @zdev: pointer to zcrypt_device structure that identifies the
516  *        PCICC device to the request distributor
517  * @crt: pointer to the modexpoc_crt request buffer
518  */
519 static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev,
520                                      struct ica_rsa_modexpo_crt *crt)
521 {
522         struct ap_message ap_msg;
523         struct completion work;
524         int rc;
525
526         ap_init_message(&ap_msg);
527         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
528         if (!ap_msg.message)
529                 return -ENOMEM;
530         ap_msg.receive = zcrypt_pcicc_receive;
531         ap_msg.length = PAGE_SIZE;
532         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
533                                 atomic_inc_return(&zcrypt_step);
534         ap_msg.private = &work;
535         rc = ICACRT_msg_to_type6CRT_msg(zdev, &ap_msg, crt);
536         if (rc)
537                 goto out_free;
538         init_completion(&work);
539         ap_queue_message(zdev->ap_dev, &ap_msg);
540         rc = wait_for_completion_interruptible(&work);
541         if (rc == 0)
542                 rc = convert_response(zdev, &ap_msg, crt->outputdata,
543                                       crt->outputdatalength);
544         else
545                 /* Signal pending. */
546                 ap_cancel_message(zdev->ap_dev, &ap_msg);
547 out_free:
548         free_page((unsigned long) ap_msg.message);
549         return rc;
550 }
551
552 /**
553  * The crypto operations for a PCICC card.
554  */
555 static struct zcrypt_ops zcrypt_pcicc_ops = {
556         .rsa_modexpo = zcrypt_pcicc_modexpo,
557         .rsa_modexpo_crt = zcrypt_pcicc_modexpo_crt,
558 };
559
560 /**
561  * Probe function for PCICC cards. It always accepts the AP device
562  * since the bus_match already checked the hardware type.
563  * @ap_dev: pointer to the AP device.
564  */
565 static int zcrypt_pcicc_probe(struct ap_device *ap_dev)
566 {
567         struct zcrypt_device *zdev;
568         int rc;
569
570         zdev = zcrypt_device_alloc(PCICC_MAX_RESPONSE_SIZE);
571         if (!zdev)
572                 return -ENOMEM;
573         zdev->ap_dev = ap_dev;
574         zdev->ops = &zcrypt_pcicc_ops;
575         zdev->online = 1;
576         zdev->user_space_type = ZCRYPT_PCICC;
577         zdev->type_string = "PCICC";
578         zdev->min_mod_size = PCICC_MIN_MOD_SIZE;
579         zdev->max_mod_size = PCICC_MAX_MOD_SIZE;
580         zdev->speed_rating = PCICC_SPEED_RATING;
581         zdev->max_exp_bit_length = PCICC_MAX_MOD_SIZE;
582         ap_dev->reply = &zdev->reply;
583         ap_dev->private = zdev;
584         rc = zcrypt_device_register(zdev);
585         if (rc)
586                 goto out_free;
587         return 0;
588
589  out_free:
590         ap_dev->private = NULL;
591         zcrypt_device_free(zdev);
592         return rc;
593 }
594
595 /**
596  * This is called to remove the extended PCICC driver information
597  * if an AP device is removed.
598  */
599 static void zcrypt_pcicc_remove(struct ap_device *ap_dev)
600 {
601         struct zcrypt_device *zdev = ap_dev->private;
602
603         zcrypt_device_unregister(zdev);
604 }
605
606 int __init zcrypt_pcicc_init(void)
607 {
608         return ap_driver_register(&zcrypt_pcicc_driver, THIS_MODULE, "pcicc");
609 }
610
611 void zcrypt_pcicc_exit(void)
612 {
613         ap_driver_unregister(&zcrypt_pcicc_driver);
614 }
615
616 module_init(zcrypt_pcicc_init);
617 module_exit(zcrypt_pcicc_exit);