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