blob: 7d97fa5a26d0cca4e6f318e5d57d392728f3c5f9 [file] [log] [blame]
Holger Dengler5e55a482012-08-28 16:45:36 +02001/*
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#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/err.h>
31#include <linux/delay.h>
32#include <linux/slab.h>
33#include <linux/atomic.h>
34#include <linux/uaccess.h>
35
36#include "ap_bus.h"
37#include "zcrypt_api.h"
38#include "zcrypt_error.h"
39#include "zcrypt_msgtype6.h"
40#include "zcrypt_cca_key.h"
41
42#define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */
43#define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */
44
45#define CEIL4(x) ((((x)+3)/4)*4)
46
47struct response_type {
48 struct completion work;
49 int type;
50};
51#define PCIXCC_RESPONSE_TYPE_ICA 0
52#define PCIXCC_RESPONSE_TYPE_XCRB 1
53
54MODULE_AUTHOR("IBM Corporation");
55MODULE_DESCRIPTION("Cryptographic Coprocessor (message type 6), " \
56 "Copyright IBM Corp. 2001, 2012");
57MODULE_LICENSE("GPL");
58
59static void zcrypt_msgtype6_receive(struct ap_device *, struct ap_message *,
60 struct ap_message *);
61
62/**
63 * CPRB
64 * Note that all shorts, ints and longs are little-endian.
65 * All pointer fields are 32-bits long, and mean nothing
66 *
67 * A request CPRB is followed by a request_parameter_block.
68 *
69 * The request (or reply) parameter block is organized thus:
70 * function code
71 * VUD block
72 * key block
73 */
74struct CPRB {
75 unsigned short cprb_len; /* CPRB length */
76 unsigned char cprb_ver_id; /* CPRB version id. */
77 unsigned char pad_000; /* Alignment pad byte. */
78 unsigned char srpi_rtcode[4]; /* SRPI return code LELONG */
79 unsigned char srpi_verb; /* SRPI verb type */
80 unsigned char flags; /* flags */
81 unsigned char func_id[2]; /* function id */
82 unsigned char checkpoint_flag; /* */
83 unsigned char resv2; /* reserved */
84 unsigned short req_parml; /* request parameter buffer */
85 /* length 16-bit little endian */
86 unsigned char req_parmp[4]; /* request parameter buffer *
87 * pointer (means nothing: the *
88 * parameter buffer follows *
89 * the CPRB). */
90 unsigned char req_datal[4]; /* request data buffer */
91 /* length ULELONG */
92 unsigned char req_datap[4]; /* request data buffer */
93 /* pointer */
94 unsigned short rpl_parml; /* reply parameter buffer */
95 /* length 16-bit little endian */
96 unsigned char pad_001[2]; /* Alignment pad bytes. ULESHORT */
97 unsigned char rpl_parmp[4]; /* reply parameter buffer *
98 * pointer (means nothing: the *
99 * parameter buffer follows *
100 * the CPRB). */
101 unsigned char rpl_datal[4]; /* reply data buffer len ULELONG */
102 unsigned char rpl_datap[4]; /* reply data buffer */
103 /* pointer */
104 unsigned short ccp_rscode; /* server reason code ULESHORT */
105 unsigned short ccp_rtcode; /* server return code ULESHORT */
106 unsigned char repd_parml[2]; /* replied parameter len ULESHORT*/
107 unsigned char mac_data_len[2]; /* Mac Data Length ULESHORT */
108 unsigned char repd_datal[4]; /* replied data length ULELONG */
109 unsigned char req_pc[2]; /* PC identifier */
110 unsigned char res_origin[8]; /* resource origin */
111 unsigned char mac_value[8]; /* Mac Value */
112 unsigned char logon_id[8]; /* Logon Identifier */
113 unsigned char usage_domain[2]; /* cdx */
114 unsigned char resv3[18]; /* reserved for requestor */
115 unsigned short svr_namel; /* server name length ULESHORT */
116 unsigned char svr_name[8]; /* server name */
117} __packed;
118
119struct function_and_rules_block {
120 unsigned char function_code[2];
121 unsigned short ulen;
122 unsigned char only_rule[8];
123} __packed;
124
125/**
126 * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
127 * card in a type6 message. The 3 fields that must be filled in at execution
128 * time are req_parml, rpl_parml and usage_domain.
129 * Everything about this interface is ascii/big-endian, since the
130 * device does *not* have 'Intel inside'.
131 *
132 * The CPRBX is followed immediately by the parm block.
133 * The parm block contains:
134 * - function code ('PD' 0x5044 or 'PK' 0x504B)
135 * - rule block (one of:)
136 * + 0x000A 'PKCS-1.2' (MCL2 'PD')
137 * + 0x000A 'ZERO-PAD' (MCL2 'PK')
138 * + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
139 * + 0x000A 'MRP ' (MCL3 'PK' or CEX2C 'PK')
140 * - VUD block
141 */
142static struct CPRBX static_cprbx = {
143 .cprb_len = 0x00DC,
144 .cprb_ver_id = 0x02,
145 .func_id = {0x54, 0x32},
146};
147
148/**
149 * Convert a ICAMEX message to a type6 MEX message.
150 *
151 * @zdev: crypto device pointer
152 * @ap_msg: pointer to AP message
153 * @mex: pointer to user input data
154 *
155 * Returns 0 on success or -EFAULT.
156 */
157static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev,
158 struct ap_message *ap_msg,
159 struct ica_rsa_modexpo *mex)
160{
161 static struct type6_hdr static_type6_hdrX = {
162 .type = 0x06,
163 .offset1 = 0x00000058,
164 .agent_id = {'C', 'A',},
165 .function_code = {'P', 'K'},
166 };
167 static struct function_and_rules_block static_pke_fnr = {
168 .function_code = {'P', 'K'},
169 .ulen = 10,
170 .only_rule = {'M', 'R', 'P', ' ', ' ', ' ', ' ', ' '}
171 };
172 static struct function_and_rules_block static_pke_fnr_MCL2 = {
173 .function_code = {'P', 'K'},
174 .ulen = 10,
175 .only_rule = {'Z', 'E', 'R', 'O', '-', 'P', 'A', 'D'}
176 };
177 struct {
178 struct type6_hdr hdr;
179 struct CPRBX cprbx;
180 struct function_and_rules_block fr;
181 unsigned short length;
182 char text[0];
183 } __packed * msg = ap_msg->message;
184 int size;
185
186 /* VUD.ciphertext */
187 msg->length = mex->inputdatalength + 2;
188 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
189 return -EFAULT;
190
191 /* Set up key which is located after the variable length text. */
192 size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
193 if (size < 0)
194 return size;
195 size += sizeof(*msg) + mex->inputdatalength;
196
197 /* message header, cprbx and f&r */
198 msg->hdr = static_type6_hdrX;
199 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
200 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
201
202 msg->cprbx = static_cprbx;
203 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
204 msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
205
206 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
207 static_pke_fnr_MCL2 : static_pke_fnr;
208
209 msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
210
211 ap_msg->length = size;
212 return 0;
213}
214
215/**
216 * Convert a ICACRT message to a type6 CRT message.
217 *
218 * @zdev: crypto device pointer
219 * @ap_msg: pointer to AP message
220 * @crt: pointer to user input data
221 *
222 * Returns 0 on success or -EFAULT.
223 */
224static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
225 struct ap_message *ap_msg,
226 struct ica_rsa_modexpo_crt *crt)
227{
228 static struct type6_hdr static_type6_hdrX = {
229 .type = 0x06,
230 .offset1 = 0x00000058,
231 .agent_id = {'C', 'A',},
232 .function_code = {'P', 'D'},
233 };
234 static struct function_and_rules_block static_pkd_fnr = {
235 .function_code = {'P', 'D'},
236 .ulen = 10,
237 .only_rule = {'Z', 'E', 'R', 'O', '-', 'P', 'A', 'D'}
238 };
239
240 static struct function_and_rules_block static_pkd_fnr_MCL2 = {
241 .function_code = {'P', 'D'},
242 .ulen = 10,
243 .only_rule = {'P', 'K', 'C', 'S', '-', '1', '.', '2'}
244 };
245 struct {
246 struct type6_hdr hdr;
247 struct CPRBX cprbx;
248 struct function_and_rules_block fr;
249 unsigned short length;
250 char text[0];
251 } __packed * msg = ap_msg->message;
252 int size;
253
254 /* VUD.ciphertext */
255 msg->length = crt->inputdatalength + 2;
256 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
257 return -EFAULT;
258
259 /* Set up key which is located after the variable length text. */
260 size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
261 if (size < 0)
262 return size;
263 size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */
264
265 /* message header, cprbx and f&r */
266 msg->hdr = static_type6_hdrX;
267 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
268 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
269
270 msg->cprbx = static_cprbx;
271 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
272 msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
273 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
274
275 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
276 static_pkd_fnr_MCL2 : static_pkd_fnr;
277
278 ap_msg->length = size;
279 return 0;
280}
281
282/**
283 * Convert a XCRB message to a type6 CPRB message.
284 *
285 * @zdev: crypto device pointer
286 * @ap_msg: pointer to AP message
287 * @xcRB: pointer to user input data
288 *
289 * Returns 0 on success or -EFAULT, -EINVAL.
290 */
291struct type86_fmt2_msg {
292 struct type86_hdr hdr;
293 struct type86_fmt2_ext fmt2;
294} __packed;
295
296static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
297 struct ap_message *ap_msg,
298 struct ica_xcRB *xcRB)
299{
300 static struct type6_hdr static_type6_hdrX = {
301 .type = 0x06,
302 .offset1 = 0x00000058,
303 };
304 struct {
305 struct type6_hdr hdr;
306 struct CPRBX cprbx;
307 } __packed * msg = ap_msg->message;
308
309 int rcblen = CEIL4(xcRB->request_control_blk_length);
310 int replylen;
311 char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
312 char *function_code;
313
314 /* length checks */
315 ap_msg->length = sizeof(struct type6_hdr) +
316 CEIL4(xcRB->request_control_blk_length) +
317 xcRB->request_data_length;
318 if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE)
319 return -EINVAL;
320 replylen = sizeof(struct type86_fmt2_msg) +
321 CEIL4(xcRB->reply_control_blk_length) +
322 xcRB->reply_data_length;
323 if (replylen > MSGTYPE06_MAX_MSG_SIZE)
324 return -EINVAL;
325
326 /* prepare type6 header */
327 msg->hdr = static_type6_hdrX;
328 memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
329 msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
330 if (xcRB->request_data_length) {
331 msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
332 msg->hdr.ToCardLen2 = xcRB->request_data_length;
333 }
334 msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length;
335 msg->hdr.FromCardLen2 = xcRB->reply_data_length;
336
337 /* prepare CPRB */
338 if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr,
339 xcRB->request_control_blk_length))
340 return -EFAULT;
341 if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
342 xcRB->request_control_blk_length)
343 return -EINVAL;
344 function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
345 memcpy(msg->hdr.function_code, function_code,
346 sizeof(msg->hdr.function_code));
347
348 if (memcmp(function_code, "US", 2) == 0)
349 ap_msg->special = 1;
350 else
351 ap_msg->special = 0;
352
353 /* copy data block */
354 if (xcRB->request_data_length &&
355 copy_from_user(req_data, xcRB->request_data_address,
356 xcRB->request_data_length))
357 return -EFAULT;
358 return 0;
359}
360
361/**
362 * Copy results from a type 86 ICA reply message back to user space.
363 *
364 * @zdev: crypto device pointer
365 * @reply: reply AP message.
366 * @data: pointer to user output data
367 * @length: size of user output data
368 *
369 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
370 */
371struct type86x_reply {
372 struct type86_hdr hdr;
373 struct type86_fmt2_ext fmt2;
374 struct CPRBX cprbx;
375 unsigned char pad[4]; /* 4 byte function code/rules block ? */
376 unsigned short length;
377 char text[0];
378} __packed;
379
380static int convert_type86_ica(struct zcrypt_device *zdev,
381 struct ap_message *reply,
382 char __user *outputdata,
383 unsigned int outputdatalength)
384{
385 static unsigned char static_pad[] = {
386 0x00, 0x02,
387 0x1B, 0x7B, 0x5D, 0xB5, 0x75, 0x01, 0x3D, 0xFD,
388 0x8D, 0xD1, 0xC7, 0x03, 0x2D, 0x09, 0x23, 0x57,
389 0x89, 0x49, 0xB9, 0x3F, 0xBB, 0x99, 0x41, 0x5B,
390 0x75, 0x21, 0x7B, 0x9D, 0x3B, 0x6B, 0x51, 0x39,
391 0xBB, 0x0D, 0x35, 0xB9, 0x89, 0x0F, 0x93, 0xA5,
392 0x0B, 0x47, 0xF1, 0xD3, 0xBB, 0xCB, 0xF1, 0x9D,
393 0x23, 0x73, 0x71, 0xFF, 0xF3, 0xF5, 0x45, 0xFB,
394 0x61, 0x29, 0x23, 0xFD, 0xF1, 0x29, 0x3F, 0x7F,
395 0x17, 0xB7, 0x1B, 0xA9, 0x19, 0xBD, 0x57, 0xA9,
396 0xD7, 0x95, 0xA3, 0xCB, 0xED, 0x1D, 0xDB, 0x45,
397 0x7D, 0x11, 0xD1, 0x51, 0x1B, 0xED, 0x71, 0xE9,
398 0xB1, 0xD1, 0xAB, 0xAB, 0x21, 0x2B, 0x1B, 0x9F,
399 0x3B, 0x9F, 0xF7, 0xF7, 0xBD, 0x63, 0xEB, 0xAD,
400 0xDF, 0xB3, 0x6F, 0x5B, 0xDB, 0x8D, 0xA9, 0x5D,
401 0xE3, 0x7D, 0x77, 0x49, 0x47, 0xF5, 0xA7, 0xFD,
402 0xAB, 0x2F, 0x27, 0x35, 0x77, 0xD3, 0x49, 0xC9,
403 0x09, 0xEB, 0xB1, 0xF9, 0xBF, 0x4B, 0xCB, 0x2B,
404 0xEB, 0xEB, 0x05, 0xFF, 0x7D, 0xC7, 0x91, 0x8B,
405 0x09, 0x83, 0xB9, 0xB9, 0x69, 0x33, 0x39, 0x6B,
406 0x79, 0x75, 0x19, 0xBF, 0xBB, 0x07, 0x1D, 0xBD,
407 0x29, 0xBF, 0x39, 0x95, 0x93, 0x1D, 0x35, 0xC7,
408 0xC9, 0x4D, 0xE5, 0x97, 0x0B, 0x43, 0x9B, 0xF1,
409 0x16, 0x93, 0x03, 0x1F, 0xA5, 0xFB, 0xDB, 0xF3,
410 0x27, 0x4F, 0x27, 0x61, 0x05, 0x1F, 0xB9, 0x23,
411 0x2F, 0xC3, 0x81, 0xA9, 0x23, 0x71, 0x55, 0x55,
412 0xEB, 0xED, 0x41, 0xE5, 0xF3, 0x11, 0xF1, 0x43,
413 0x69, 0x03, 0xBD, 0x0B, 0x37, 0x0F, 0x51, 0x8F,
414 0x0B, 0xB5, 0x89, 0x5B, 0x67, 0xA9, 0xD9, 0x4F,
415 0x01, 0xF9, 0x21, 0x77, 0x37, 0x73, 0x79, 0xC5,
416 0x7F, 0x51, 0xC1, 0xCF, 0x97, 0xA1, 0x75, 0xAD,
417 0x35, 0x9D, 0xD3, 0xD3, 0xA7, 0x9D, 0x5D, 0x41,
418 0x6F, 0x65, 0x1B, 0xCF, 0xA9, 0x87, 0x91, 0x09
419 };
420 struct type86x_reply *msg = reply->message;
421 unsigned short service_rc, service_rs;
422 unsigned int reply_len, pad_len;
423 char *data;
424
425 service_rc = msg->cprbx.ccp_rtcode;
426 if (unlikely(service_rc != 0)) {
427 service_rs = msg->cprbx.ccp_rscode;
428 if (service_rc == 8 && service_rs == 66)
429 return -EINVAL;
430 if (service_rc == 8 && service_rs == 65)
431 return -EINVAL;
432 if (service_rc == 8 && service_rs == 770)
433 return -EINVAL;
434 if (service_rc == 8 && service_rs == 783) {
435 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
436 return -EAGAIN;
437 }
438 if (service_rc == 12 && service_rs == 769)
439 return -EINVAL;
440 if (service_rc == 8 && service_rs == 72)
441 return -EINVAL;
442 zdev->online = 0;
443 return -EAGAIN; /* repeat the request on a different device. */
444 }
445 data = msg->text;
446 reply_len = msg->length - 2;
447 if (reply_len > outputdatalength)
448 return -EINVAL;
449 /*
450 * For all encipher requests, the length of the ciphertext (reply_len)
451 * will always equal the modulus length. For MEX decipher requests
452 * the output needs to get padded. Minimum pad size is 10.
453 *
454 * Currently, the cases where padding will be added is for:
455 * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
456 * ZERO-PAD and CRT is only supported for PKD requests)
457 * - PCICC, always
458 */
459 pad_len = outputdatalength - reply_len;
460 if (pad_len > 0) {
461 if (pad_len < 10)
462 return -EINVAL;
463 /* 'restore' padding left in the PCICC/PCIXCC card. */
464 if (copy_to_user(outputdata, static_pad, pad_len - 1))
465 return -EFAULT;
466 if (put_user(0, outputdata + pad_len - 1))
467 return -EFAULT;
468 }
469 /* Copy the crypto response to user space. */
470 if (copy_to_user(outputdata + pad_len, data, reply_len))
471 return -EFAULT;
472 return 0;
473}
474
475/**
476 * Copy results from a type 86 XCRB reply message back to user space.
477 *
478 * @zdev: crypto device pointer
479 * @reply: reply AP message.
480 * @xcRB: pointer to XCRB
481 *
482 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
483 */
484static int convert_type86_xcrb(struct zcrypt_device *zdev,
485 struct ap_message *reply,
486 struct ica_xcRB *xcRB)
487{
488 struct type86_fmt2_msg *msg = reply->message;
489 char *data = reply->message;
490
491 /* Copy CPRB to user */
492 if (copy_to_user(xcRB->reply_control_blk_addr,
493 data + msg->fmt2.offset1, msg->fmt2.count1))
494 return -EFAULT;
495 xcRB->reply_control_blk_length = msg->fmt2.count1;
496
497 /* Copy data buffer to user */
498 if (msg->fmt2.count2)
499 if (copy_to_user(xcRB->reply_data_addr,
500 data + msg->fmt2.offset2, msg->fmt2.count2))
501 return -EFAULT;
502 xcRB->reply_data_length = msg->fmt2.count2;
503 return 0;
504}
505
506static int convert_type86_rng(struct zcrypt_device *zdev,
507 struct ap_message *reply,
508 char *buffer)
509{
510 struct {
511 struct type86_hdr hdr;
512 struct type86_fmt2_ext fmt2;
513 struct CPRBX cprbx;
514 } __packed * msg = reply->message;
515 char *data = reply->message;
516
517 if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
518 return -EINVAL;
519 memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
520 return msg->fmt2.count2;
521}
522
523static int convert_response_ica(struct zcrypt_device *zdev,
524 struct ap_message *reply,
525 char __user *outputdata,
526 unsigned int outputdatalength)
527{
528 struct type86x_reply *msg = reply->message;
529
530 /* Response type byte is the second byte in the response. */
531 switch (((unsigned char *) reply->message)[1]) {
532 case TYPE82_RSP_CODE:
533 case TYPE88_RSP_CODE:
534 return convert_error(zdev, reply);
535 case TYPE86_RSP_CODE:
536 if (msg->cprbx.ccp_rtcode &&
537 (msg->cprbx.ccp_rscode == 0x14f) &&
538 (outputdatalength > 256)) {
539 if (zdev->max_exp_bit_length <= 17) {
540 zdev->max_exp_bit_length = 17;
541 return -EAGAIN;
542 } else
543 return -EINVAL;
544 }
545 if (msg->hdr.reply_code)
546 return convert_error(zdev, reply);
547 if (msg->cprbx.cprb_ver_id == 0x02)
548 return convert_type86_ica(zdev, reply,
549 outputdata, outputdatalength);
550 /* Fall through, no break, incorrect cprb version is an unknown
551 * response */
552 default: /* Unknown response type, this should NEVER EVER happen */
553 zdev->online = 0;
554 return -EAGAIN; /* repeat the request on a different device. */
555 }
556}
557
558static int convert_response_xcrb(struct zcrypt_device *zdev,
559 struct ap_message *reply,
560 struct ica_xcRB *xcRB)
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 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
569 return convert_error(zdev, reply);
570 case TYPE86_RSP_CODE:
571 if (msg->hdr.reply_code) {
572 memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
573 return convert_error(zdev, reply);
574 }
575 if (msg->cprbx.cprb_ver_id == 0x02)
576 return convert_type86_xcrb(zdev, reply, xcRB);
577 /* Fall through, no break, incorrect cprb version is an unknown
578 * response */
579 default: /* Unknown response type, this should NEVER EVER happen */
580 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
581 zdev->online = 0;
582 return -EAGAIN; /* repeat the request on a different device. */
583 }
584}
585
586static int convert_response_rng(struct zcrypt_device *zdev,
587 struct ap_message *reply,
588 char *data)
589{
590 struct type86x_reply *msg = reply->message;
591
592 switch (msg->hdr.type) {
593 case TYPE82_RSP_CODE:
594 case TYPE88_RSP_CODE:
595 return -EINVAL;
596 case TYPE86_RSP_CODE:
597 if (msg->hdr.reply_code)
598 return -EINVAL;
599 if (msg->cprbx.cprb_ver_id == 0x02)
600 return convert_type86_rng(zdev, reply, data);
601 /* Fall through, no break, incorrect cprb version is an unknown
602 * response */
603 default: /* Unknown response type, this should NEVER EVER happen */
604 zdev->online = 0;
605 return -EAGAIN; /* repeat the request on a different device. */
606 }
607}
608
609/**
610 * This function is called from the AP bus code after a crypto request
611 * "msg" has finished with the reply message "reply".
612 * It is called from tasklet context.
613 * @ap_dev: pointer to the AP device
614 * @msg: pointer to the AP message
615 * @reply: pointer to the AP reply message
616 */
617static void zcrypt_msgtype6_receive(struct ap_device *ap_dev,
618 struct ap_message *msg,
619 struct ap_message *reply)
620{
621 static struct error_hdr error_reply = {
622 .type = TYPE82_RSP_CODE,
623 .reply_code = REP82_ERROR_MACHINE_FAILURE,
624 };
625 struct response_type *resp_type =
626 (struct response_type *) msg->private;
627 struct type86x_reply *t86r;
628 int length;
629
630 /* Copy the reply message to the request message buffer. */
631 if (IS_ERR(reply)) {
632 memcpy(msg->message, &error_reply, sizeof(error_reply));
633 goto out;
634 }
635 t86r = reply->message;
636 if (t86r->hdr.type == TYPE86_RSP_CODE &&
637 t86r->cprbx.cprb_ver_id == 0x02) {
638 switch (resp_type->type) {
639 case PCIXCC_RESPONSE_TYPE_ICA:
640 length = sizeof(struct type86x_reply)
641 + t86r->length - 2;
642 length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
643 memcpy(msg->message, reply->message, length);
644 break;
645 case PCIXCC_RESPONSE_TYPE_XCRB:
646 length = t86r->fmt2.offset2 + t86r->fmt2.count2;
647 length = min(MSGTYPE06_MAX_MSG_SIZE, length);
648 memcpy(msg->message, reply->message, length);
649 break;
650 default:
651 memcpy(msg->message, &error_reply,
652 sizeof(error_reply));
653 }
654 } else
655 memcpy(msg->message, reply->message, sizeof(error_reply));
656out:
657 complete(&(resp_type->work));
658}
659
660static atomic_t zcrypt_step = ATOMIC_INIT(0);
661
662/**
663 * The request distributor calls this function if it picked the PCIXCC/CEX2C
664 * device to handle a modexpo request.
665 * @zdev: pointer to zcrypt_device structure that identifies the
666 * PCIXCC/CEX2C device to the request distributor
667 * @mex: pointer to the modexpo request buffer
668 */
669static long zcrypt_msgtype6_modexpo(struct zcrypt_device *zdev,
670 struct ica_rsa_modexpo *mex)
671{
672 struct ap_message ap_msg;
673 struct response_type resp_type = {
674 .type = PCIXCC_RESPONSE_TYPE_ICA,
675 };
676 int rc;
677
678 ap_init_message(&ap_msg);
679 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
680 if (!ap_msg.message)
681 return -ENOMEM;
682 ap_msg.receive = zcrypt_msgtype6_receive;
683 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
684 atomic_inc_return(&zcrypt_step);
685 ap_msg.private = &resp_type;
686 rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
687 if (rc)
688 goto out_free;
689 init_completion(&resp_type.work);
690 ap_queue_message(zdev->ap_dev, &ap_msg);
691 rc = wait_for_completion_interruptible(&resp_type.work);
692 if (rc == 0)
693 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
694 mex->outputdatalength);
695 else
696 /* Signal pending. */
697 ap_cancel_message(zdev->ap_dev, &ap_msg);
698out_free:
699 free_page((unsigned long) ap_msg.message);
700 return rc;
701}
702
703/**
704 * The request distributor calls this function if it picked the PCIXCC/CEX2C
705 * device to handle a modexpo_crt request.
706 * @zdev: pointer to zcrypt_device structure that identifies the
707 * PCIXCC/CEX2C device to the request distributor
708 * @crt: pointer to the modexpoc_crt request buffer
709 */
710static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_device *zdev,
711 struct ica_rsa_modexpo_crt *crt)
712{
713 struct ap_message ap_msg;
714 struct response_type resp_type = {
715 .type = PCIXCC_RESPONSE_TYPE_ICA,
716 };
717 int rc;
718
719 ap_init_message(&ap_msg);
720 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
721 if (!ap_msg.message)
722 return -ENOMEM;
723 ap_msg.receive = zcrypt_msgtype6_receive;
724 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
725 atomic_inc_return(&zcrypt_step);
726 ap_msg.private = &resp_type;
727 rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
728 if (rc)
729 goto out_free;
730 init_completion(&resp_type.work);
731 ap_queue_message(zdev->ap_dev, &ap_msg);
732 rc = wait_for_completion_interruptible(&resp_type.work);
733 if (rc == 0)
734 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
735 crt->outputdatalength);
736 else
737 /* Signal pending. */
738 ap_cancel_message(zdev->ap_dev, &ap_msg);
739out_free:
740 free_page((unsigned long) ap_msg.message);
741 return rc;
742}
743
744/**
745 * The request distributor calls this function if it picked the PCIXCC/CEX2C
746 * device to handle a send_cprb request.
747 * @zdev: pointer to zcrypt_device structure that identifies the
748 * PCIXCC/CEX2C device to the request distributor
749 * @xcRB: pointer to the send_cprb request buffer
750 */
751static long zcrypt_msgtype6_send_cprb(struct zcrypt_device *zdev,
752 struct ica_xcRB *xcRB)
753{
754 struct ap_message ap_msg;
755 struct response_type resp_type = {
756 .type = PCIXCC_RESPONSE_TYPE_XCRB,
757 };
758 int rc;
759
760 ap_init_message(&ap_msg);
761 ap_msg.message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
762 if (!ap_msg.message)
763 return -ENOMEM;
764 ap_msg.receive = zcrypt_msgtype6_receive;
765 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
766 atomic_inc_return(&zcrypt_step);
767 ap_msg.private = &resp_type;
768 rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
769 if (rc)
770 goto out_free;
771 init_completion(&resp_type.work);
772 ap_queue_message(zdev->ap_dev, &ap_msg);
773 rc = wait_for_completion_interruptible(&resp_type.work);
774 if (rc == 0)
775 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
776 else
777 /* Signal pending. */
778 ap_cancel_message(zdev->ap_dev, &ap_msg);
779out_free:
780 kzfree(ap_msg.message);
781 return rc;
782}
783
784/**
785 * The request distributor calls this function if it picked the PCIXCC/CEX2C
786 * device to generate random data.
787 * @zdev: pointer to zcrypt_device structure that identifies the
788 * PCIXCC/CEX2C device to the request distributor
789 * @buffer: pointer to a memory page to return random data
790 */
791
792static long zcrypt_msgtype6_rng(struct zcrypt_device *zdev,
793 char *buffer)
794{
795 struct ap_message ap_msg;
796 struct response_type resp_type = {
797 .type = PCIXCC_RESPONSE_TYPE_XCRB,
798 };
799 int rc;
800
801 ap_init_message(&ap_msg);
802 ap_msg.message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
803 if (!ap_msg.message)
804 return -ENOMEM;
805 ap_msg.receive = zcrypt_msgtype6_receive;
806 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
807 atomic_inc_return(&zcrypt_step);
808 ap_msg.private = &resp_type;
809 rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE);
810 init_completion(&resp_type.work);
811 ap_queue_message(zdev->ap_dev, &ap_msg);
812 rc = wait_for_completion_interruptible(&resp_type.work);
813 if (rc == 0)
814 rc = convert_response_rng(zdev, &ap_msg, buffer);
815 else
816 /* Signal pending. */
817 ap_cancel_message(zdev->ap_dev, &ap_msg);
818 kfree(ap_msg.message);
819 return rc;
820}
821
822/**
823 * The crypto operations for a PCIXCC/CEX2C card.
824 */
825static struct zcrypt_ops zcrypt_msgtype6_norng_ops = {
826 .owner = THIS_MODULE,
827 .variant = MSGTYPE06_VARIANT_NORNG,
828 .rsa_modexpo = zcrypt_msgtype6_modexpo,
829 .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
830 .send_cprb = zcrypt_msgtype6_send_cprb,
831};
832
833static struct zcrypt_ops zcrypt_msgtype6_ops = {
834 .owner = THIS_MODULE,
835 .variant = MSGTYPE06_VARIANT_DEFAULT,
836 .rsa_modexpo = zcrypt_msgtype6_modexpo,
837 .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
838 .send_cprb = zcrypt_msgtype6_send_cprb,
839 .rng = zcrypt_msgtype6_rng,
840};
841
842int __init zcrypt_msgtype6_init(void)
843{
844 zcrypt_msgtype_register(&zcrypt_msgtype6_norng_ops);
845 zcrypt_msgtype_register(&zcrypt_msgtype6_ops);
846 return 0;
847}
848
849void __exit zcrypt_msgtype6_exit(void)
850{
851 zcrypt_msgtype_unregister(&zcrypt_msgtype6_norng_ops);
852 zcrypt_msgtype_unregister(&zcrypt_msgtype6_ops);
853}
854
855module_init(zcrypt_msgtype6_init);
856module_exit(zcrypt_msgtype6_exit);