2  *  linux/drivers/s390/crypto/zcrypt_pcixcc.c
 
   6  *  Copyright (C)  2001, 2006 IBM Corporation
 
   7  *  Author(s): Robert Burroughs
 
   8  *             Eric Rossman (edrossma@us.ibm.com)
 
  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>
 
  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)
 
  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.
 
  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.
 
  29 #include <linux/module.h>
 
  30 #include <linux/init.h>
 
  31 #include <linux/err.h>
 
  32 #include <linux/delay.h>
 
  33 #include <asm/atomic.h>
 
  34 #include <asm/uaccess.h>
 
  37 #include "zcrypt_api.h"
 
  38 #include "zcrypt_error.h"
 
  39 #include "zcrypt_pcicc.h"
 
  40 #include "zcrypt_pcixcc.h"
 
  41 #include "zcrypt_cca_key.h"
 
  43 #define PCIXCC_MIN_MOD_SIZE      16     /*  128 bits    */
 
  44 #define PCIXCC_MIN_MOD_SIZE_OLD  64     /*  512 bits    */
 
  45 #define PCIXCC_MAX_MOD_SIZE     256     /* 2048 bits    */
 
  47 #define PCIXCC_MCL2_SPEED_RATING        7870    /* FIXME: needs finetuning */
 
  48 #define PCIXCC_MCL3_SPEED_RATING        7870
 
  49 #define CEX2C_SPEED_RATING              8540
 
  51 #define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c  /* max size type6 v2 crt message */
 
  52 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply      */
 
  54 #define PCIXCC_MAX_XCRB_MESSAGE_SIZE (12*1024)
 
  55 #define PCIXCC_MAX_XCRB_RESPONSE_SIZE PCIXCC_MAX_XCRB_MESSAGE_SIZE
 
  56 #define PCIXCC_MAX_XCRB_DATA_SIZE (11*1024)
 
  57 #define PCIXCC_MAX_XCRB_REPLY_SIZE (5*1024)
 
  59 #define PCIXCC_MAX_RESPONSE_SIZE PCIXCC_MAX_XCRB_RESPONSE_SIZE
 
  61 #define PCIXCC_CLEANUP_TIME     (15*HZ)
 
  63 #define CEIL4(x) ((((x)+3)/4)*4)
 
  65 struct response_type {
 
  66         struct completion work;
 
  69 #define PCIXCC_RESPONSE_TYPE_ICA  0
 
  70 #define PCIXCC_RESPONSE_TYPE_XCRB 1
 
  72 static struct ap_device_id zcrypt_pcixcc_ids[] = {
 
  73         { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
 
  74         { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
 
  75         { AP_DEVICE(AP_DEVICE_TYPE_CEX2C2) },
 
  76         { /* end of list */ },
 
  79 #ifndef CONFIG_ZCRYPT_MONOLITHIC
 
  80 MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
 
  81 MODULE_AUTHOR("IBM Corporation");
 
  82 MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, "
 
  83                    "Copyright 2001, 2006 IBM Corporation");
 
  84 MODULE_LICENSE("GPL");
 
  87 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
 
  88 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
 
  89 static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *,
 
  92 static struct ap_driver zcrypt_pcixcc_driver = {
 
  93         .probe = zcrypt_pcixcc_probe,
 
  94         .remove = zcrypt_pcixcc_remove,
 
  95         .receive = zcrypt_pcixcc_receive,
 
  96         .ids = zcrypt_pcixcc_ids,
 
  97         .request_timeout = PCIXCC_CLEANUP_TIME,
 
 101  * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
 
 102  * card in a type6 message. The 3 fields that must be filled in at execution
 
 103  * time are  req_parml, rpl_parml and usage_domain.
 
 104  * Everything about this interface is ascii/big-endian, since the
 
 105  * device does *not* have 'Intel inside'.
 
 107  * The CPRBX is followed immediately by the parm block.
 
 108  * The parm block contains:
 
 109  * - function code ('PD' 0x5044 or 'PK' 0x504B)
 
 110  * - rule block (one of:)
 
 111  *   + 0x000A 'PKCS-1.2' (MCL2 'PD')
 
 112  *   + 0x000A 'ZERO-PAD' (MCL2 'PK')
 
 113  *   + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
 
 114  *   + 0x000A 'MRP     ' (MCL3 'PK' or CEX2C 'PK')
 
 117 static struct CPRBX static_cprbx = {
 
 120         .func_id        = {0x54,0x32},
 
 124  * Convert a ICAMEX message to a type6 MEX message.
 
 126  * @zdev: crypto device pointer
 
 127  * @ap_msg: pointer to AP message
 
 128  * @mex: pointer to user input data
 
 130  * Returns 0 on success or -EFAULT.
 
 132 static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev,
 
 133                                        struct ap_message *ap_msg,
 
 134                                        struct ica_rsa_modexpo *mex)
 
 136         static struct type6_hdr static_type6_hdrX = {
 
 138                 .offset1        =  0x00000058,
 
 139                 .agent_id       = {'C','A',},
 
 140                 .function_code  = {'P','K'},
 
 142         static struct function_and_rules_block static_pke_fnr = {
 
 143                 .function_code  = {'P','K'},
 
 145                 .only_rule      = {'M','R','P',' ',' ',' ',' ',' '}
 
 147         static struct function_and_rules_block static_pke_fnr_MCL2 = {
 
 148                 .function_code  = {'P','K'},
 
 150                 .only_rule      = {'Z','E','R','O','-','P','A','D'}
 
 153                 struct type6_hdr hdr;
 
 155                 struct function_and_rules_block fr;
 
 156                 unsigned short length;
 
 158         } __attribute__((packed)) *msg = ap_msg->message;
 
 162         msg->length = mex->inputdatalength + 2;
 
 163         if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
 
 166         /* Set up key which is located after the variable length text. */
 
 167         size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
 
 170         size += sizeof(*msg) + mex->inputdatalength;
 
 172         /* message header, cprbx and f&r */
 
 173         msg->hdr = static_type6_hdrX;
 
 174         msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
 
 175         msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
 
 177         msg->cprbx = static_cprbx;
 
 178         msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
 
 179         msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
 
 181         msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
 
 182                 static_pke_fnr_MCL2 : static_pke_fnr;
 
 184         msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
 
 186         ap_msg->length = size;
 
 191  * Convert a ICACRT message to a type6 CRT message.
 
 193  * @zdev: crypto device pointer
 
 194  * @ap_msg: pointer to AP message
 
 195  * @crt: pointer to user input data
 
 197  * Returns 0 on success or -EFAULT.
 
 199 static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
 
 200                                        struct ap_message *ap_msg,
 
 201                                        struct ica_rsa_modexpo_crt *crt)
 
 203         static struct type6_hdr static_type6_hdrX = {
 
 205                 .offset1        =  0x00000058,
 
 206                 .agent_id       = {'C','A',},
 
 207                 .function_code  = {'P','D'},
 
 209         static struct function_and_rules_block static_pkd_fnr = {
 
 210                 .function_code  = {'P','D'},
 
 212                 .only_rule      = {'Z','E','R','O','-','P','A','D'}
 
 215         static struct function_and_rules_block static_pkd_fnr_MCL2 = {
 
 216                 .function_code  = {'P','D'},
 
 218                 .only_rule      = {'P','K','C','S','-','1','.','2'}
 
 221                 struct type6_hdr hdr;
 
 223                 struct function_and_rules_block fr;
 
 224                 unsigned short length;
 
 226         } __attribute__((packed)) *msg = ap_msg->message;
 
 230         msg->length = crt->inputdatalength + 2;
 
 231         if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
 
 234         /* Set up key which is located after the variable length text. */
 
 235         size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
 
 238         size += sizeof(*msg) + crt->inputdatalength;    /* total size of msg */
 
 240         /* message header, cprbx and f&r */
 
 241         msg->hdr = static_type6_hdrX;
 
 242         msg->hdr.ToCardLen1 = size -  sizeof(msg->hdr);
 
 243         msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
 
 245         msg->cprbx = static_cprbx;
 
 246         msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
 
 247         msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
 
 248                 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
 
 250         msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
 
 251                 static_pkd_fnr_MCL2 : static_pkd_fnr;
 
 253         ap_msg->length = size;
 
 258  * Convert a XCRB message to a type6 CPRB message.
 
 260  * @zdev: crypto device pointer
 
 261  * @ap_msg: pointer to AP message
 
 262  * @xcRB: pointer to user input data
 
 264  * Returns 0 on success or -EFAULT.
 
 266 struct type86_fmt2_msg {
 
 267         struct type86_hdr hdr;
 
 268         struct type86_fmt2_ext fmt2;
 
 269 } __attribute__((packed));
 
 271 static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
 
 272                                        struct ap_message *ap_msg,
 
 273                                        struct ica_xcRB *xcRB)
 
 275         static struct type6_hdr static_type6_hdrX = {
 
 277                 .offset1        =  0x00000058,
 
 280                 struct type6_hdr hdr;
 
 282         } __attribute__((packed)) *msg = ap_msg->message;
 
 284         int rcblen = CEIL4(xcRB->request_control_blk_length);
 
 286         char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
 
 290         ap_msg->length = sizeof(struct type6_hdr) +
 
 291                 CEIL4(xcRB->request_control_blk_length) +
 
 292                 xcRB->request_data_length;
 
 293         if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE)
 
 295         if (CEIL4(xcRB->reply_control_blk_length) > PCIXCC_MAX_XCRB_REPLY_SIZE)
 
 297         if (CEIL4(xcRB->reply_data_length) > PCIXCC_MAX_XCRB_DATA_SIZE)
 
 299         replylen = CEIL4(xcRB->reply_control_blk_length) +
 
 300                 CEIL4(xcRB->reply_data_length) +
 
 301                 sizeof(struct type86_fmt2_msg);
 
 302         if (replylen > PCIXCC_MAX_XCRB_RESPONSE_SIZE) {
 
 303                 xcRB->reply_control_blk_length = PCIXCC_MAX_XCRB_RESPONSE_SIZE -
 
 304                         (sizeof(struct type86_fmt2_msg) +
 
 305                             CEIL4(xcRB->reply_data_length));
 
 308         /* prepare type6 header */
 
 309         msg->hdr = static_type6_hdrX;
 
 310         memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
 
 311         msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
 
 312         if (xcRB->request_data_length) {
 
 313                 msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
 
 314                 msg->hdr.ToCardLen2 = xcRB->request_data_length;
 
 316         msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length;
 
 317         msg->hdr.FromCardLen2 = xcRB->reply_data_length;
 
 320         if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr,
 
 321                     xcRB->request_control_blk_length))
 
 323         if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
 
 324             xcRB->request_control_blk_length)
 
 326         function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
 
 327         memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
 
 329         /* copy data block */
 
 330         if (xcRB->request_data_length &&
 
 331             copy_from_user(req_data, xcRB->request_data_address,
 
 332                 xcRB->request_data_length))
 
 338  * Prepare a type6 CPRB message for random number generation
 
 340  * @ap_dev: AP device pointer
 
 341  * @ap_msg: pointer to AP message
 
 343 static void rng_type6CPRB_msgX(struct ap_device *ap_dev,
 
 344                                struct ap_message *ap_msg,
 
 345                                unsigned random_number_length)
 
 348                 struct type6_hdr hdr;
 
 350                 char function_code[2];
 
 351                 short int rule_length;
 
 353                 short int verb_length;
 
 354                 short int key_length;
 
 355         } __attribute__((packed)) *msg = ap_msg->message;
 
 356         static struct type6_hdr static_type6_hdrX = {
 
 358                 .offset1        = 0x00000058,
 
 359                 .agent_id       = {'C', 'A'},
 
 360                 .function_code  = {'R', 'L'},
 
 361                 .ToCardLen1     = sizeof *msg - sizeof(msg->hdr),
 
 362                 .FromCardLen1   = sizeof *msg - sizeof(msg->hdr),
 
 364         static struct CPRBX static_cprbx = {
 
 367                 .func_id        = {0x54, 0x32},
 
 368                 .req_parml      = sizeof *msg - sizeof(msg->hdr) -
 
 370                 .rpl_msgbl      = sizeof *msg - sizeof(msg->hdr),
 
 373         msg->hdr = static_type6_hdrX;
 
 374         msg->hdr.FromCardLen2 = random_number_length,
 
 375         msg->cprbx = static_cprbx;
 
 376         msg->cprbx.rpl_datal = random_number_length,
 
 377         msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid);
 
 378         memcpy(msg->function_code, msg->hdr.function_code, 0x02);
 
 379         msg->rule_length = 0x0a;
 
 380         memcpy(msg->rule, "RANDOM  ", 8);
 
 381         msg->verb_length = 0x02;
 
 382         msg->key_length = 0x02;
 
 383         ap_msg->length = sizeof *msg;
 
 387  * Copy results from a type 86 ICA reply message back to user space.
 
 389  * @zdev: crypto device pointer
 
 390  * @reply: reply AP message.
 
 391  * @data: pointer to user output data
 
 392  * @length: size of user output data
 
 394  * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
 
 396 struct type86x_reply {
 
 397         struct type86_hdr hdr;
 
 398         struct type86_fmt2_ext fmt2;
 
 400         unsigned char pad[4];   /* 4 byte function code/rules block ? */
 
 401         unsigned short length;
 
 403 } __attribute__((packed));
 
 405 static int convert_type86_ica(struct zcrypt_device *zdev,
 
 406                           struct ap_message *reply,
 
 407                           char __user *outputdata,
 
 408                           unsigned int outputdatalength)
 
 410         static unsigned char static_pad[] = {
 
 412                 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
 
 413                 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
 
 414                 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
 
 415                 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
 
 416                 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
 
 417                 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
 
 418                 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
 
 419                 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
 
 420                 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
 
 421                 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
 
 422                 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
 
 423                 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
 
 424                 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
 
 425                 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
 
 426                 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
 
 427                 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
 
 428                 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
 
 429                 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
 
 430                 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
 
 431                 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
 
 432                 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
 
 433                 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
 
 434                 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
 
 435                 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
 
 436                 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
 
 437                 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
 
 438                 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
 
 439                 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
 
 440                 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
 
 441                 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
 
 442                 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
 
 443                 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
 
 445         struct type86x_reply *msg = reply->message;
 
 446         unsigned short service_rc, service_rs;
 
 447         unsigned int reply_len, pad_len;
 
 450         service_rc = msg->cprbx.ccp_rtcode;
 
 451         if (unlikely(service_rc != 0)) {
 
 452                 service_rs = msg->cprbx.ccp_rscode;
 
 453                 if (service_rc == 8 && service_rs == 66)
 
 455                 if (service_rc == 8 && service_rs == 65)
 
 457                 if (service_rc == 8 && service_rs == 770)
 
 459                 if (service_rc == 8 && service_rs == 783) {
 
 460                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
 
 463                 if (service_rc == 12 && service_rs == 769)
 
 466                 return -EAGAIN; /* repeat the request on a different device. */
 
 469         reply_len = msg->length - 2;
 
 470         if (reply_len > outputdatalength)
 
 473          * For all encipher requests, the length of the ciphertext (reply_len)
 
 474          * will always equal the modulus length. For MEX decipher requests
 
 475          * the output needs to get padded. Minimum pad size is 10.
 
 477          * Currently, the cases where padding will be added is for:
 
 478          * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
 
 479          *   ZERO-PAD and CRT is only supported for PKD requests)
 
 482         pad_len = outputdatalength - reply_len;
 
 486                 /* 'restore' padding left in the PCICC/PCIXCC card. */
 
 487                 if (copy_to_user(outputdata, static_pad, pad_len - 1))
 
 489                 if (put_user(0, outputdata + pad_len - 1))
 
 492         /* Copy the crypto response to user space. */
 
 493         if (copy_to_user(outputdata + pad_len, data, reply_len))
 
 499  * Copy results from a type 86 XCRB reply message back to user space.
 
 501  * @zdev: crypto device pointer
 
 502  * @reply: reply AP message.
 
 503  * @xcRB: pointer to XCRB
 
 505  * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
 
 507 static int convert_type86_xcrb(struct zcrypt_device *zdev,
 
 508                                struct ap_message *reply,
 
 509                                struct ica_xcRB *xcRB)
 
 511         struct type86_fmt2_msg *msg = reply->message;
 
 512         char *data = reply->message;
 
 514         /* Copy CPRB to user */
 
 515         if (copy_to_user(xcRB->reply_control_blk_addr,
 
 516                 data + msg->fmt2.offset1, msg->fmt2.count1))
 
 518         xcRB->reply_control_blk_length = msg->fmt2.count1;
 
 520         /* Copy data buffer to user */
 
 521         if (msg->fmt2.count2)
 
 522                 if (copy_to_user(xcRB->reply_data_addr,
 
 523                         data + msg->fmt2.offset2, msg->fmt2.count2))
 
 525         xcRB->reply_data_length = msg->fmt2.count2;
 
 529 static int convert_type86_rng(struct zcrypt_device *zdev,
 
 530                           struct ap_message *reply,
 
 534                 struct type86_hdr hdr;
 
 535                 struct type86_fmt2_ext fmt2;
 
 537         } __attribute__((packed)) *msg = reply->message;
 
 538         char *data = reply->message;
 
 540         if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
 
 542         memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
 
 543         return msg->fmt2.count2;
 
 546 static int convert_response_ica(struct zcrypt_device *zdev,
 
 547                             struct ap_message *reply,
 
 548                             char __user *outputdata,
 
 549                             unsigned int outputdatalength)
 
 551         struct type86x_reply *msg = reply->message;
 
 553         /* Response type byte is the second byte in the response. */
 
 554         switch (((unsigned char *) reply->message)[1]) {
 
 555         case TYPE82_RSP_CODE:
 
 556         case TYPE88_RSP_CODE:
 
 557                 return convert_error(zdev, reply);
 
 558         case TYPE86_RSP_CODE:
 
 559                 if (msg->hdr.reply_code)
 
 560                         return convert_error(zdev, reply);
 
 561                 if (msg->cprbx.cprb_ver_id == 0x02)
 
 562                         return convert_type86_ica(zdev, reply,
 
 563                                                   outputdata, outputdatalength);
 
 564                 /* no break, incorrect cprb version is an unknown response */
 
 565         default: /* Unknown response type, this should NEVER EVER happen */
 
 567                 return -EAGAIN; /* repeat the request on a different device. */
 
 571 static int convert_response_xcrb(struct zcrypt_device *zdev,
 
 572                             struct ap_message *reply,
 
 573                             struct ica_xcRB *xcRB)
 
 575         struct type86x_reply *msg = reply->message;
 
 577         /* Response type byte is the second byte in the response. */
 
 578         switch (((unsigned char *) reply->message)[1]) {
 
 579         case TYPE82_RSP_CODE:
 
 580         case TYPE88_RSP_CODE:
 
 581                 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
 
 582                 return convert_error(zdev, reply);
 
 583         case TYPE86_RSP_CODE:
 
 584                 if (msg->hdr.reply_code) {
 
 585                         memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
 
 586                         return convert_error(zdev, reply);
 
 588                 if (msg->cprbx.cprb_ver_id == 0x02)
 
 589                         return convert_type86_xcrb(zdev, reply, xcRB);
 
 590                 /* no break, incorrect cprb version is an unknown response */
 
 591         default: /* Unknown response type, this should NEVER EVER happen */
 
 592                 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
 
 594                 return -EAGAIN; /* repeat the request on a different device. */
 
 598 static int convert_response_rng(struct zcrypt_device *zdev,
 
 599                                  struct ap_message *reply,
 
 602         struct type86x_reply *msg = reply->message;
 
 604         switch (msg->hdr.type) {
 
 605         case TYPE82_RSP_CODE:
 
 606         case TYPE88_RSP_CODE:
 
 608         case TYPE86_RSP_CODE:
 
 609                 if (msg->hdr.reply_code)
 
 611                 if (msg->cprbx.cprb_ver_id == 0x02)
 
 612                         return convert_type86_rng(zdev, reply, data);
 
 613                 /* no break, incorrect cprb version is an unknown response */
 
 614         default: /* Unknown response type, this should NEVER EVER happen */
 
 616                 return -EAGAIN; /* repeat the request on a different device. */
 
 621  * This function is called from the AP bus code after a crypto request
 
 622  * "msg" has finished with the reply message "reply".
 
 623  * It is called from tasklet context.
 
 624  * @ap_dev: pointer to the AP device
 
 625  * @msg: pointer to the AP message
 
 626  * @reply: pointer to the AP reply message
 
 628 static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
 
 629                                   struct ap_message *msg,
 
 630                                   struct ap_message *reply)
 
 632         static struct error_hdr error_reply = {
 
 633                 .type = TYPE82_RSP_CODE,
 
 634                 .reply_code = REP82_ERROR_MACHINE_FAILURE,
 
 636         struct response_type *resp_type =
 
 637                 (struct response_type *) msg->private;
 
 638         struct type86x_reply *t86r = reply->message;
 
 641         /* Copy the reply message to the request message buffer. */
 
 643                 memcpy(msg->message, &error_reply, sizeof(error_reply));
 
 644         else if (t86r->hdr.type == TYPE86_RSP_CODE &&
 
 645                  t86r->cprbx.cprb_ver_id == 0x02) {
 
 646                 switch (resp_type->type) {
 
 647                 case PCIXCC_RESPONSE_TYPE_ICA:
 
 648                         length = sizeof(struct type86x_reply)
 
 650                         length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
 
 651                         memcpy(msg->message, reply->message, length);
 
 653                 case PCIXCC_RESPONSE_TYPE_XCRB:
 
 654                         length = t86r->fmt2.offset2 + t86r->fmt2.count2;
 
 655                         length = min(PCIXCC_MAX_XCRB_RESPONSE_SIZE, length);
 
 656                         memcpy(msg->message, reply->message, length);
 
 659                         memcpy(msg->message, &error_reply, sizeof error_reply);
 
 662                 memcpy(msg->message, reply->message, sizeof error_reply);
 
 663         complete(&(resp_type->work));
 
 666 static atomic_t zcrypt_step = ATOMIC_INIT(0);
 
 669  * The request distributor calls this function if it picked the PCIXCC/CEX2C
 
 670  * device to handle a modexpo request.
 
 671  * @zdev: pointer to zcrypt_device structure that identifies the
 
 672  *        PCIXCC/CEX2C device to the request distributor
 
 673  * @mex: pointer to the modexpo request buffer
 
 675 static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
 
 676                                   struct ica_rsa_modexpo *mex)
 
 678         struct ap_message ap_msg;
 
 679         struct response_type resp_type = {
 
 680                 .type = PCIXCC_RESPONSE_TYPE_ICA,
 
 684         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
 
 687         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
 
 688                                 atomic_inc_return(&zcrypt_step);
 
 689         ap_msg.private = &resp_type;
 
 690         rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
 
 693         init_completion(&resp_type.work);
 
 694         ap_queue_message(zdev->ap_dev, &ap_msg);
 
 695         rc = wait_for_completion_interruptible(&resp_type.work);
 
 697                 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
 
 698                                           mex->outputdatalength);
 
 700                 /* Signal pending. */
 
 701                 ap_cancel_message(zdev->ap_dev, &ap_msg);
 
 703         free_page((unsigned long) ap_msg.message);
 
 708  * The request distributor calls this function if it picked the PCIXCC/CEX2C
 
 709  * device to handle a modexpo_crt request.
 
 710  * @zdev: pointer to zcrypt_device structure that identifies the
 
 711  *        PCIXCC/CEX2C device to the request distributor
 
 712  * @crt: pointer to the modexpoc_crt request buffer
 
 714 static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
 
 715                                       struct ica_rsa_modexpo_crt *crt)
 
 717         struct ap_message ap_msg;
 
 718         struct response_type resp_type = {
 
 719                 .type = PCIXCC_RESPONSE_TYPE_ICA,
 
 723         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
 
 726         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
 
 727                                 atomic_inc_return(&zcrypt_step);
 
 728         ap_msg.private = &resp_type;
 
 729         rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
 
 732         init_completion(&resp_type.work);
 
 733         ap_queue_message(zdev->ap_dev, &ap_msg);
 
 734         rc = wait_for_completion_interruptible(&resp_type.work);
 
 736                 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
 
 737                                           crt->outputdatalength);
 
 739                 /* Signal pending. */
 
 740                 ap_cancel_message(zdev->ap_dev, &ap_msg);
 
 742         free_page((unsigned long) ap_msg.message);
 
 747  * The request distributor calls this function if it picked the PCIXCC/CEX2C
 
 748  * device to handle a send_cprb request.
 
 749  * @zdev: pointer to zcrypt_device structure that identifies the
 
 750  *        PCIXCC/CEX2C device to the request distributor
 
 751  * @xcRB: pointer to the send_cprb request buffer
 
 753 static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
 
 754                                     struct ica_xcRB *xcRB)
 
 756         struct ap_message ap_msg;
 
 757         struct response_type resp_type = {
 
 758                 .type = PCIXCC_RESPONSE_TYPE_XCRB,
 
 762         ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
 
 765         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
 
 766                                 atomic_inc_return(&zcrypt_step);
 
 767         ap_msg.private = &resp_type;
 
 768         rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
 
 771         init_completion(&resp_type.work);
 
 772         ap_queue_message(zdev->ap_dev, &ap_msg);
 
 773         rc = wait_for_completion_interruptible(&resp_type.work);
 
 775                 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
 
 777                 /* Signal pending. */
 
 778                 ap_cancel_message(zdev->ap_dev, &ap_msg);
 
 780         memset(ap_msg.message, 0x0, ap_msg.length);
 
 781         kfree(ap_msg.message);
 
 786  * The request distributor calls this function if it picked the PCIXCC/CEX2C
 
 787  * device to generate random data.
 
 788  * @zdev: pointer to zcrypt_device structure that identifies the
 
 789  *        PCIXCC/CEX2C device to the request distributor
 
 790  * @buffer: pointer to a memory page to return random data
 
 793 static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev,
 
 796         struct ap_message ap_msg;
 
 797         struct response_type resp_type = {
 
 798                 .type = PCIXCC_RESPONSE_TYPE_XCRB,
 
 802         ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
 
 805         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
 
 806                                 atomic_inc_return(&zcrypt_step);
 
 807         ap_msg.private = &resp_type;
 
 808         rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE);
 
 809         init_completion(&resp_type.work);
 
 810         ap_queue_message(zdev->ap_dev, &ap_msg);
 
 811         rc = wait_for_completion_interruptible(&resp_type.work);
 
 813                 rc = convert_response_rng(zdev, &ap_msg, buffer);
 
 815                 /* Signal pending. */
 
 816                 ap_cancel_message(zdev->ap_dev, &ap_msg);
 
 817         kfree(ap_msg.message);
 
 822  * The crypto operations for a PCIXCC/CEX2C card.
 
 824 static struct zcrypt_ops zcrypt_pcixcc_ops = {
 
 825         .rsa_modexpo = zcrypt_pcixcc_modexpo,
 
 826         .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
 
 827         .send_cprb = zcrypt_pcixcc_send_cprb,
 
 830 static struct zcrypt_ops zcrypt_pcixcc_with_rng_ops = {
 
 831         .rsa_modexpo = zcrypt_pcixcc_modexpo,
 
 832         .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
 
 833         .send_cprb = zcrypt_pcixcc_send_cprb,
 
 834         .rng = zcrypt_pcixcc_rng,
 
 838  * Micro-code detection function. Its sends a message to a pcixcc card
 
 839  * to find out the microcode level.
 
 840  * @ap_dev: pointer to the AP device.
 
 842 static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
 
 844         static unsigned char msg[] = {
 
 845                 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
 
 846                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 847                 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
 
 848                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 849                 0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
 
 850                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 851                 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
 
 852                 0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
 
 853                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 854                 0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
 
 855                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 856                 0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
 
 857                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
 
 858                 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
 
 859                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 860                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 861                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 862                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 863                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 864                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 865                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 866                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 867                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 868                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 869                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 870                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 871                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 872                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 873                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 874                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 875                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 876                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 
 877                 0x00,0x00,0x00,0x04,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,0x50,0x4B,0x00,0x0A,
 
 884                 0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
 
 885                 0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
 
 886                 0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
 
 887                 0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
 
 888                 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
 
 889                 0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
 
 890                 0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
 
 891                 0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
 
 892                 0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
 
 893                 0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
 
 894                 0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
 
 895                 0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
 
 896                 0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
 
 897                 0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
 
 898                 0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
 
 899                 0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
 
 900                 0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
 
 901                 0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
 
 902                 0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
 
 903                 0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
 
 904                 0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
 
 905                 0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
 
 906                 0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
 
 907                 0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
 
 908                 0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
 
 909                 0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
 
 910                 0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
 
 911                 0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
 
 914         unsigned long long psmid;
 
 919         reply = (void *) get_zeroed_page(GFP_KERNEL);
 
 923         rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
 
 927         /* Wait for the test message to complete. */
 
 928         for (i = 0; i < 6; i++) {
 
 930                 rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
 
 931                 if (rc == 0 && psmid == 0x0102030405060708ULL)
 
 941         cprbx = (struct CPRBX *) (reply + 48);
 
 942         if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
 
 943                 rc = ZCRYPT_PCIXCC_MCL2;
 
 945                 rc = ZCRYPT_PCIXCC_MCL3;
 
 947         free_page((unsigned long) reply);
 
 952  * Large random number detection function. Its sends a message to a pcixcc
 
 953  * card to find out if large random numbers are supported.
 
 954  * @ap_dev: pointer to the AP device.
 
 956  * Returns 1 if large random numbers are supported, 0 if not and < 0 on error.
 
 958 static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
 
 960         struct ap_message ap_msg;
 
 961         unsigned long long psmid;
 
 963                 struct type86_hdr hdr;
 
 964                 struct type86_fmt2_ext fmt2;
 
 966         } __attribute__((packed)) *reply;
 
 969         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
 
 973         rng_type6CPRB_msgX(ap_dev, &ap_msg, 4);
 
 974         rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, ap_msg.message,
 
 979         /* Wait for the test message to complete. */
 
 980         for (i = 0; i < 2 * HZ; i++) {
 
 982                 rc = ap_recv(ap_dev->qid, &psmid, ap_msg.message, 4096);
 
 983                 if (rc == 0 && psmid == 0x0102030405060708ULL)
 
 993         reply = ap_msg.message;
 
 994         if (reply->cprbx.ccp_rtcode == 0 && reply->cprbx.ccp_rscode == 0)
 
 999         free_page((unsigned long) ap_msg.message);
 
1004  * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
 
1005  * since the bus_match already checked the hardware type. The PCIXCC
 
1006  * cards come in two flavours: micro code level 2 and micro code level 3.
 
1007  * This is checked by sending a test message to the device.
 
1008  * @ap_dev: pointer to the AP device.
 
1010 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
 
1012         struct zcrypt_device *zdev;
 
1015         zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE);
 
1018         zdev->ap_dev = ap_dev;
 
1020         if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) {
 
1021                 rc = zcrypt_pcixcc_mcl(ap_dev);
 
1023                         zcrypt_device_free(zdev);
 
1026                 zdev->user_space_type = rc;
 
1027                 if (rc == ZCRYPT_PCIXCC_MCL2) {
 
1028                         zdev->type_string = "PCIXCC_MCL2";
 
1029                         zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
 
1030                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
 
1031                         zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
 
1033                         zdev->type_string = "PCIXCC_MCL3";
 
1034                         zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
 
1035                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
 
1036                         zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
 
1039                 zdev->user_space_type = ZCRYPT_CEX2C;
 
1040                 zdev->type_string = "CEX2C";
 
1041                 zdev->speed_rating = CEX2C_SPEED_RATING;
 
1042                 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
 
1043                 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
 
1045         rc = zcrypt_pcixcc_rng_supported(ap_dev);
 
1047                 zcrypt_device_free(zdev);
 
1051                 zdev->ops = &zcrypt_pcixcc_with_rng_ops;
 
1053                 zdev->ops = &zcrypt_pcixcc_ops;
 
1054         ap_dev->reply = &zdev->reply;
 
1055         ap_dev->private = zdev;
 
1056         rc = zcrypt_device_register(zdev);
 
1062         ap_dev->private = NULL;
 
1063         zcrypt_device_free(zdev);
 
1068  * This is called to remove the extended PCIXCC/CEX2C driver information
 
1069  * if an AP device is removed.
 
1071 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
 
1073         struct zcrypt_device *zdev = ap_dev->private;
 
1075         zcrypt_device_unregister(zdev);
 
1078 int __init zcrypt_pcixcc_init(void)
 
1080         return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
 
1083 void zcrypt_pcixcc_exit(void)
 
1085         ap_driver_unregister(&zcrypt_pcixcc_driver);
 
1088 #ifndef CONFIG_ZCRYPT_MONOLITHIC
 
1089 module_init(zcrypt_pcixcc_init);
 
1090 module_exit(zcrypt_pcixcc_exit);