1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
45#define PCIXCC_MIN_MOD_SIZE_OLD 64
46#define PCIXCC_MAX_MOD_SIZE 256
47#define CEX3C_MIN_MOD_SIZE PCIXCC_MIN_MOD_SIZE
48#define CEX3C_MAX_MOD_SIZE 512
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
56#define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c
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 { },
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121static struct CPRBX static_cprbx = {
122 .cprb_len = 0x00DC,
123 .cprb_ver_id = 0x02,
124 .func_id = {0x54,0x32},
125};
126
127
128
129
130
131
132
133
134
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
166 msg->length = mex->inputdatalength + 2;
167 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
168 return -EFAULT;
169
170
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
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
196
197
198
199
200
201
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
234 msg->length = crt->inputdatalength + 2;
235 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
236 return -EFAULT;
237
238
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;
243
244
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
263
264
265
266
267
268
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
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
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
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
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
348
349
350
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
397
398
399
400
401
402
403
404
405struct type86x_reply {
406 struct type86_hdr hdr;
407 struct type86_fmt2_ext fmt2;
408 struct CPRBX cprbx;
409 unsigned char pad[4];
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;
478 }
479 data = msg->text;
480 reply_len = msg->length - 2;
481 if (reply_len > outputdatalength)
482 return -EINVAL;
483
484
485
486
487
488
489
490
491
492
493 pad_len = outputdatalength - reply_len;
494 if (pad_len > 0) {
495 if (pad_len < 10)
496 return -EINVAL;
497
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
504 if (copy_to_user(outputdata + pad_len, data, reply_len))
505 return -EFAULT;
506 return 0;
507}
508
509
510
511
512
513
514
515
516
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
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
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
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
585
586 default:
587 zdev->online = 0;
588 return -EAGAIN;
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
599 switch (((unsigned char *) reply->message)[1]) {
600 case TYPE82_RSP_CODE:
601 case TYPE88_RSP_CODE:
602 xcRB->status = 0x0008044DL;
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
612
613 default:
614 xcRB->status = 0x0008044DL;
615 zdev->online = 0;
616 return -EAGAIN;
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
636
637 default:
638 zdev->online = 0;
639 return -EAGAIN;
640 }
641}
642
643
644
645
646
647
648
649
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
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
697
698
699
700
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
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
737
738
739
740
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
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
777
778
779
780
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
808 ap_cancel_message(zdev->ap_dev, &ap_msg);
809out_free:
810 kzfree(ap_msg.message);
811 return rc;
812}
813
814
815
816
817
818
819
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
846 ap_cancel_message(zdev->ap_dev, &ap_msg);
847 kfree(ap_msg.message);
848 return rc;
849}
850
851
852
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
869
870
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
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
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
983
984
985
986
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
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
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
1036
1037
1038
1039
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
1117
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