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/gfp.h>
32#include <linux/err.h>
33#include <linux/atomic.h>
34#include <asm/uaccess.h>
35
36#include "ap_bus.h"
37#include "zcrypt_api.h"
38#include "zcrypt_error.h"
39#include "zcrypt_pcicc.h"
40#include "zcrypt_cca_key.h"
41
42#define PCICC_MIN_MOD_SIZE 64
43#define PCICC_MAX_MOD_SIZE_OLD 128
44#define PCICC_MAX_MOD_SIZE 256
45
46
47
48
49
50
51
52
53
54
55
56#define PCICC_SPEED_RATING 0
57
58#define PCICC_MAX_MESSAGE_SIZE 0x710
59#define PCICC_MAX_RESPONSE_SIZE 0x710
60
61#define PCICC_CLEANUP_TIME (15*HZ)
62
63static struct ap_device_id zcrypt_pcicc_ids[] = {
64 { AP_DEVICE(AP_DEVICE_TYPE_PCICC) },
65 { },
66};
67
68#ifndef CONFIG_ZCRYPT_MONOLITHIC
69MODULE_DEVICE_TABLE(ap, zcrypt_pcicc_ids);
70MODULE_AUTHOR("IBM Corporation");
71MODULE_DESCRIPTION("PCICC Cryptographic Coprocessor device driver, "
72 "Copyright 2001, 2006 IBM Corporation");
73MODULE_LICENSE("GPL");
74#endif
75
76static int zcrypt_pcicc_probe(struct ap_device *ap_dev);
77static void zcrypt_pcicc_remove(struct ap_device *ap_dev);
78static void zcrypt_pcicc_receive(struct ap_device *, struct ap_message *,
79 struct ap_message *);
80
81static struct ap_driver zcrypt_pcicc_driver = {
82 .probe = zcrypt_pcicc_probe,
83 .remove = zcrypt_pcicc_remove,
84 .receive = zcrypt_pcicc_receive,
85 .ids = zcrypt_pcicc_ids,
86 .request_timeout = PCICC_CLEANUP_TIME,
87};
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102static struct CPRB static_cprb = {
103 .cprb_len = __constant_cpu_to_le16(0x0070),
104 .cprb_ver_id = 0x41,
105 .func_id = {0x54,0x32},
106 .checkpoint_flag= 0x01,
107 .svr_namel = __constant_cpu_to_le16(0x0008),
108 .svr_name = {'I','C','S','F',' ',' ',' ',' '}
109};
110
111
112
113
114static inline int is_PKCS11_padded(unsigned char *buffer, int length)
115{
116 int i;
117 if ((buffer[0] != 0x00) || (buffer[1] != 0x01))
118 return 0;
119 for (i = 2; i < length; i++)
120 if (buffer[i] != 0xFF)
121 break;
122 if (i < 10 || i == length)
123 return 0;
124 if (buffer[i] != 0x00)
125 return 0;
126 return 1;
127}
128
129
130
131
132static inline int is_PKCS12_padded(unsigned char *buffer, int length)
133{
134 int i;
135 if ((buffer[0] != 0x00) || (buffer[1] != 0x02))
136 return 0;
137 for (i = 2; i < length; i++)
138 if (buffer[i] == 0x00)
139 break;
140 if ((i < 10) || (i == length))
141 return 0;
142 if (buffer[i] != 0x00)
143 return 0;
144 return 1;
145}
146
147
148
149
150
151
152
153
154
155
156static int ICAMEX_msg_to_type6MEX_msg(struct zcrypt_device *zdev,
157 struct ap_message *ap_msg,
158 struct ica_rsa_modexpo *mex)
159{
160 static struct type6_hdr static_type6_hdr = {
161 .type = 0x06,
162 .offset1 = 0x00000058,
163 .agent_id = {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
164 0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
165 .function_code = {'P','K'},
166 };
167 static struct function_and_rules_block static_pke_function_and_rules ={
168 .function_code = {'P','K'},
169 .ulen = __constant_cpu_to_le16(10),
170 .only_rule = {'P','K','C','S','-','1','.','2'}
171 };
172 struct {
173 struct type6_hdr hdr;
174 struct CPRB cprb;
175 struct function_and_rules_block fr;
176 unsigned short length;
177 char text[0];
178 } __attribute__((packed)) *msg = ap_msg->message;
179 int vud_len, pad_len, size;
180
181
182 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
183 return -EFAULT;
184
185 if (is_PKCS11_padded(msg->text, mex->inputdatalength))
186 return -EINVAL;
187
188
189 msg->hdr = static_type6_hdr;
190 msg->fr = static_pke_function_and_rules;
191
192 if (is_PKCS12_padded(msg->text, mex->inputdatalength)) {
193
194 pad_len = strnlen(msg->text + 2, mex->inputdatalength - 2) + 3;
195 if (pad_len <= 9 || pad_len >= mex->inputdatalength)
196 return -ENODEV;
197 vud_len = mex->inputdatalength - pad_len;
198 memmove(msg->text, msg->text + pad_len, vud_len);
199 msg->length = cpu_to_le16(vud_len + 2);
200
201
202 size = zcrypt_type6_mex_key_en(mex, msg->text + vud_len, 0);
203 if (size < 0)
204 return size;
205 size += sizeof(*msg) + vud_len;
206 } else {
207 vud_len = mex->inputdatalength;
208 msg->length = cpu_to_le16(2 + vud_len);
209
210 msg->hdr.function_code[1] = 'D';
211 msg->fr.function_code[1] = 'D';
212
213
214 size = zcrypt_type6_mex_key_de(mex, msg->text + vud_len, 0);
215 if (size < 0)
216 return size;
217 size += sizeof(*msg) + vud_len;
218 }
219
220
221 msg->hdr.ToCardLen1 = (size - sizeof(msg->hdr) + 3) & -4;
222 msg->hdr.FromCardLen1 = PCICC_MAX_RESPONSE_SIZE - sizeof(msg->hdr);
223
224 msg->cprb = static_cprb;
225 msg->cprb.usage_domain[0]= AP_QID_QUEUE(zdev->ap_dev->qid);
226 msg->cprb.req_parml = cpu_to_le16(size - sizeof(msg->hdr) -
227 sizeof(msg->cprb));
228 msg->cprb.rpl_parml = cpu_to_le16(msg->hdr.FromCardLen1);
229
230 ap_msg->length = (size + 3) & -4;
231 return 0;
232}
233
234
235
236
237
238
239
240
241
242
243static int ICACRT_msg_to_type6CRT_msg(struct zcrypt_device *zdev,
244 struct ap_message *ap_msg,
245 struct ica_rsa_modexpo_crt *crt)
246{
247 static struct type6_hdr static_type6_hdr = {
248 .type = 0x06,
249 .offset1 = 0x00000058,
250 .agent_id = {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
251 0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
252 .function_code = {'P','D'},
253 };
254 static struct function_and_rules_block static_pkd_function_and_rules ={
255 .function_code = {'P','D'},
256 .ulen = __constant_cpu_to_le16(10),
257 .only_rule = {'P','K','C','S','-','1','.','2'}
258 };
259 struct {
260 struct type6_hdr hdr;
261 struct CPRB cprb;
262 struct function_and_rules_block fr;
263 unsigned short length;
264 char text[0];
265 } __attribute__((packed)) *msg = ap_msg->message;
266 int size;
267
268
269 msg->length = cpu_to_le16(2 + crt->inputdatalength);
270 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
271 return -EFAULT;
272
273 if (is_PKCS11_padded(msg->text, crt->inputdatalength))
274 return -EINVAL;
275
276
277 size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 0);
278 if (size < 0)
279 return size;
280 size += sizeof(*msg) + crt->inputdatalength;
281
282
283 msg->hdr = static_type6_hdr;
284 msg->hdr.ToCardLen1 = (size - sizeof(msg->hdr) + 3) & -4;
285 msg->hdr.FromCardLen1 = PCICC_MAX_RESPONSE_SIZE - sizeof(msg->hdr);
286
287 msg->cprb = static_cprb;
288 msg->cprb.usage_domain[0] = AP_QID_QUEUE(zdev->ap_dev->qid);
289 msg->cprb.req_parml = msg->cprb.rpl_parml =
290 cpu_to_le16(size - sizeof(msg->hdr) - sizeof(msg->cprb));
291
292 msg->fr = static_pkd_function_and_rules;
293
294 ap_msg->length = (size + 3) & -4;
295 return 0;
296}
297
298
299
300
301
302
303
304
305
306
307
308struct type86_reply {
309 struct type86_hdr hdr;
310 struct type86_fmt2_ext fmt2;
311 struct CPRB cprb;
312 unsigned char pad[4];
313 unsigned short length;
314 char text[0];
315} __attribute__((packed));
316
317static int convert_type86(struct zcrypt_device *zdev,
318 struct ap_message *reply,
319 char __user *outputdata,
320 unsigned int outputdatalength)
321{
322 static unsigned char static_pad[] = {
323 0x00,0x02,
324 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
325 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
326 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
327 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
328 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
329 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
330 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
331 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
332 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
333 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
334 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
335 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
336 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
337 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
338 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
339 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
340 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
341 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
342 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
343 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
344 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
345 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
346 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
347 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
348 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
349 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
350 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
351 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
352 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
353 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
354 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
355 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
356 };
357 struct type86_reply *msg = reply->message;
358 unsigned short service_rc, service_rs;
359 unsigned int reply_len, pad_len;
360 char *data;
361
362 service_rc = le16_to_cpu(msg->cprb.ccp_rtcode);
363 if (unlikely(service_rc != 0)) {
364 service_rs = le16_to_cpu(msg->cprb.ccp_rscode);
365 if (service_rc == 8 && service_rs == 66)
366 return -EINVAL;
367 if (service_rc == 8 && service_rs == 65)
368 return -EINVAL;
369 if (service_rc == 8 && service_rs == 770) {
370 zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
371 return -EAGAIN;
372 }
373 if (service_rc == 8 && service_rs == 783) {
374 zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
375 return -EAGAIN;
376 }
377 if (service_rc == 8 && service_rs == 72)
378 return -EINVAL;
379 zdev->online = 0;
380 return -EAGAIN;
381 }
382 data = msg->text;
383 reply_len = le16_to_cpu(msg->length) - 2;
384 if (reply_len > outputdatalength)
385 return -EINVAL;
386
387
388
389
390
391
392
393
394
395
396 pad_len = outputdatalength - reply_len;
397 if (pad_len > 0) {
398 if (pad_len < 10)
399 return -EINVAL;
400
401 if (copy_to_user(outputdata, static_pad, pad_len - 1))
402 return -EFAULT;
403 if (put_user(0, outputdata + pad_len - 1))
404 return -EFAULT;
405 }
406
407 if (copy_to_user(outputdata + pad_len, data, reply_len))
408 return -EFAULT;
409 return 0;
410}
411
412static int convert_response(struct zcrypt_device *zdev,
413 struct ap_message *reply,
414 char __user *outputdata,
415 unsigned int outputdatalength)
416{
417 struct type86_reply *msg = reply->message;
418
419
420 switch (msg->hdr.type) {
421 case TYPE82_RSP_CODE:
422 case TYPE88_RSP_CODE:
423 return convert_error(zdev, reply);
424 case TYPE86_RSP_CODE:
425 if (msg->hdr.reply_code)
426 return convert_error(zdev, reply);
427 if (msg->cprb.cprb_ver_id == 0x01)
428 return convert_type86(zdev, reply,
429 outputdata, outputdatalength);
430
431 default:
432 zdev->online = 0;
433 return -EAGAIN;
434 }
435}
436
437
438
439
440
441
442
443
444
445static void zcrypt_pcicc_receive(struct ap_device *ap_dev,
446 struct ap_message *msg,
447 struct ap_message *reply)
448{
449 static struct error_hdr error_reply = {
450 .type = TYPE82_RSP_CODE,
451 .reply_code = REP82_ERROR_MACHINE_FAILURE,
452 };
453 struct type86_reply *t86r;
454 int length;
455
456
457 if (IS_ERR(reply)) {
458 memcpy(msg->message, &error_reply, sizeof(error_reply));
459 goto out;
460 }
461 t86r = reply->message;
462 if (t86r->hdr.type == TYPE86_RSP_CODE &&
463 t86r->cprb.cprb_ver_id == 0x01) {
464 length = sizeof(struct type86_reply) + t86r->length - 2;
465 length = min(PCICC_MAX_RESPONSE_SIZE, length);
466 memcpy(msg->message, reply->message, length);
467 } else
468 memcpy(msg->message, reply->message, sizeof error_reply);
469out:
470 complete((struct completion *) msg->private);
471}
472
473static atomic_t zcrypt_step = ATOMIC_INIT(0);
474
475
476
477
478
479
480
481
482static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev,
483 struct ica_rsa_modexpo *mex)
484{
485 struct ap_message ap_msg;
486 struct completion work;
487 int rc;
488
489 ap_init_message(&ap_msg);
490 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
491 if (!ap_msg.message)
492 return -ENOMEM;
493 ap_msg.length = PAGE_SIZE;
494 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
495 atomic_inc_return(&zcrypt_step);
496 ap_msg.private = &work;
497 rc = ICAMEX_msg_to_type6MEX_msg(zdev, &ap_msg, mex);
498 if (rc)
499 goto out_free;
500 init_completion(&work);
501 ap_queue_message(zdev->ap_dev, &ap_msg);
502 rc = wait_for_completion_interruptible(&work);
503 if (rc == 0)
504 rc = convert_response(zdev, &ap_msg, mex->outputdata,
505 mex->outputdatalength);
506 else
507
508 ap_cancel_message(zdev->ap_dev, &ap_msg);
509out_free:
510 free_page((unsigned long) ap_msg.message);
511 return rc;
512}
513
514
515
516
517
518
519
520
521static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev,
522 struct ica_rsa_modexpo_crt *crt)
523{
524 struct ap_message ap_msg;
525 struct completion work;
526 int rc;
527
528 ap_init_message(&ap_msg);
529 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
530 if (!ap_msg.message)
531 return -ENOMEM;
532 ap_msg.length = PAGE_SIZE;
533 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
534 atomic_inc_return(&zcrypt_step);
535 ap_msg.private = &work;
536 rc = ICACRT_msg_to_type6CRT_msg(zdev, &ap_msg, crt);
537 if (rc)
538 goto out_free;
539 init_completion(&work);
540 ap_queue_message(zdev->ap_dev, &ap_msg);
541 rc = wait_for_completion_interruptible(&work);
542 if (rc == 0)
543 rc = convert_response(zdev, &ap_msg, crt->outputdata,
544 crt->outputdatalength);
545 else
546
547 ap_cancel_message(zdev->ap_dev, &ap_msg);
548out_free:
549 free_page((unsigned long) ap_msg.message);
550 return rc;
551}
552
553
554
555
556static struct zcrypt_ops zcrypt_pcicc_ops = {
557 .rsa_modexpo = zcrypt_pcicc_modexpo,
558 .rsa_modexpo_crt = zcrypt_pcicc_modexpo_crt,
559};
560
561
562
563
564
565
566static int zcrypt_pcicc_probe(struct ap_device *ap_dev)
567{
568 struct zcrypt_device *zdev;
569 int rc;
570
571 zdev = zcrypt_device_alloc(PCICC_MAX_RESPONSE_SIZE);
572 if (!zdev)
573 return -ENOMEM;
574 zdev->ap_dev = ap_dev;
575 zdev->ops = &zcrypt_pcicc_ops;
576 zdev->online = 1;
577 zdev->user_space_type = ZCRYPT_PCICC;
578 zdev->type_string = "PCICC";
579 zdev->min_mod_size = PCICC_MIN_MOD_SIZE;
580 zdev->max_mod_size = PCICC_MAX_MOD_SIZE;
581 zdev->speed_rating = PCICC_SPEED_RATING;
582 zdev->max_exp_bit_length = PCICC_MAX_MOD_SIZE;
583 ap_dev->reply = &zdev->reply;
584 ap_dev->private = zdev;
585 rc = zcrypt_device_register(zdev);
586 if (rc)
587 goto out_free;
588 return 0;
589
590 out_free:
591 ap_dev->private = NULL;
592 zcrypt_device_free(zdev);
593 return rc;
594}
595
596
597
598
599
600static void zcrypt_pcicc_remove(struct ap_device *ap_dev)
601{
602 struct zcrypt_device *zdev = ap_dev->private;
603
604 zcrypt_device_unregister(zdev);
605}
606
607int __init zcrypt_pcicc_init(void)
608{
609 return ap_driver_register(&zcrypt_pcicc_driver, THIS_MODULE, "pcicc");
610}
611
612void zcrypt_pcicc_exit(void)
613{
614 ap_driver_unregister(&zcrypt_pcicc_driver);
615}
616
617#ifndef CONFIG_ZCRYPT_MONOLITHIC
618module_init(zcrypt_pcicc_init);
619module_exit(zcrypt_pcicc_exit);
620#endif
621