Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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