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