aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto/zcrypt_pcixcc.c
diff options
context:
space:
mode:
authorRalph Wuerthner <rwuerthn@de.ibm.com>2008-04-17 01:46:15 -0400
committerHeiko Carstens <heiko.carstens@de.ibm.com>2008-04-17 01:47:02 -0400
commit2f7c8bd6dc6540aa3275c0ad9f657401985c00e9 (patch)
tree12cb12d661424d332ad960113c8849b3579e7e6a /drivers/s390/crypto/zcrypt_pcixcc.c
parent893f11286644780fc7d6d415e537644da7bdaaf8 (diff)
[S390] zcrypt: add support for large random numbers
This patch allows user space applications to access large amounts of truly random data. The random data source is the build-in hardware random number generator on the CEX2C cards. Signed-off-by: Ralph Wuerthner <rwuerthn@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'drivers/s390/crypto/zcrypt_pcixcc.c')
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c199
1 files changed, 198 insertions, 1 deletions
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index 70b9ddc8cf9d..3674bfa82b65 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -356,6 +356,55 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
356} 356}
357 357
358/** 358/**
359 * Prepare a type6 CPRB message for random number generation
360 *
361 * @ap_dev: AP device pointer
362 * @ap_msg: pointer to AP message
363 */
364static void rng_type6CPRB_msgX(struct ap_device *ap_dev,
365 struct ap_message *ap_msg,
366 unsigned random_number_length)
367{
368 struct {
369 struct type6_hdr hdr;
370 struct CPRBX cprbx;
371 char function_code[2];
372 short int rule_length;
373 char rule[8];
374 short int verb_length;
375 short int key_length;
376 } __attribute__((packed)) *msg = ap_msg->message;
377 static struct type6_hdr static_type6_hdrX = {
378 .type = 0x06,
379 .offset1 = 0x00000058,
380 .agent_id = {'C', 'A'},
381 .function_code = {'R', 'L'},
382 .ToCardLen1 = sizeof *msg - sizeof(msg->hdr),
383 .FromCardLen1 = sizeof *msg - sizeof(msg->hdr),
384 };
385 static struct CPRBX static_cprbx = {
386 .cprb_len = 0x00dc,
387 .cprb_ver_id = 0x02,
388 .func_id = {0x54, 0x32},
389 .req_parml = sizeof *msg - sizeof(msg->hdr) -
390 sizeof(msg->cprbx),
391 .rpl_msgbl = sizeof *msg - sizeof(msg->hdr),
392 };
393
394 msg->hdr = static_type6_hdrX;
395 msg->hdr.FromCardLen2 = random_number_length,
396 msg->cprbx = static_cprbx;
397 msg->cprbx.rpl_datal = random_number_length,
398 msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid);
399 memcpy(msg->function_code, msg->hdr.function_code, 0x02);
400 msg->rule_length = 0x0a;
401 memcpy(msg->rule, "RANDOM ", 8);
402 msg->verb_length = 0x02;
403 msg->key_length = 0x02;
404 ap_msg->length = sizeof *msg;
405}
406
407/**
359 * Copy results from a type 86 ICA reply message back to user space. 408 * Copy results from a type 86 ICA reply message back to user space.
360 * 409 *
361 * @zdev: crypto device pointer 410 * @zdev: crypto device pointer
@@ -509,6 +558,26 @@ static int convert_type86_xcrb(struct zcrypt_device *zdev,
509 return 0; 558 return 0;
510} 559}
511 560
561static int convert_type86_rng(struct zcrypt_device *zdev,
562 struct ap_message *reply,
563 char *buffer)
564{
565 struct {
566 struct type86_hdr hdr;
567 struct type86_fmt2_ext fmt2;
568 struct CPRBX cprbx;
569 } __attribute__((packed)) *msg = reply->message;
570 char *data = reply->message;
571
572 if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0) {
573 PDEBUG("RNG response error on PCIXCC/CEX2C rc=%hu/rs=%hu\n",
574 rc, rs);
575 return -EINVAL;
576 }
577 memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
578 return msg->fmt2.count2;
579}
580
512static int convert_response_ica(struct zcrypt_device *zdev, 581static int convert_response_ica(struct zcrypt_device *zdev,
513 struct ap_message *reply, 582 struct ap_message *reply,
514 char __user *outputdata, 583 char __user *outputdata,
@@ -567,6 +636,31 @@ static int convert_response_xcrb(struct zcrypt_device *zdev,
567 } 636 }
568} 637}
569 638
639static int convert_response_rng(struct zcrypt_device *zdev,
640 struct ap_message *reply,
641 char *data)
642{
643 struct type86x_reply *msg = reply->message;
644
645 switch (msg->hdr.type) {
646 case TYPE82_RSP_CODE:
647 case TYPE88_RSP_CODE:
648 return -EINVAL;
649 case TYPE86_RSP_CODE:
650 if (msg->hdr.reply_code)
651 return -EINVAL;
652 if (msg->cprbx.cprb_ver_id == 0x02)
653 return convert_type86_rng(zdev, reply, data);
654 /* no break, incorrect cprb version is an unknown response */
655 default: /* Unknown response type, this should NEVER EVER happen */
656 PRINTK("Unrecognized Message Header: %08x%08x\n",
657 *(unsigned int *) reply->message,
658 *(unsigned int *) (reply->message+4));
659 zdev->online = 0;
660 return -EAGAIN; /* repeat the request on a different device. */
661 }
662}
663
570/** 664/**
571 * This function is called from the AP bus code after a crypto request 665 * This function is called from the AP bus code after a crypto request
572 * "msg" has finished with the reply message "reply". 666 * "msg" has finished with the reply message "reply".
@@ -736,6 +830,42 @@ out_free:
736} 830}
737 831
738/** 832/**
833 * The request distributor calls this function if it picked the PCIXCC/CEX2C
834 * device to generate random data.
835 * @zdev: pointer to zcrypt_device structure that identifies the
836 * PCIXCC/CEX2C device to the request distributor
837 * @buffer: pointer to a memory page to return random data
838 */
839
840static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev,
841 char *buffer)
842{
843 struct ap_message ap_msg;
844 struct response_type resp_type = {
845 .type = PCIXCC_RESPONSE_TYPE_XCRB,
846 };
847 int rc;
848
849 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
850 if (!ap_msg.message)
851 return -ENOMEM;
852 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
853 atomic_inc_return(&zcrypt_step);
854 ap_msg.private = &resp_type;
855 rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE);
856 init_completion(&resp_type.work);
857 ap_queue_message(zdev->ap_dev, &ap_msg);
858 rc = wait_for_completion_interruptible(&resp_type.work);
859 if (rc == 0)
860 rc = convert_response_rng(zdev, &ap_msg, buffer);
861 else
862 /* Signal pending. */
863 ap_cancel_message(zdev->ap_dev, &ap_msg);
864 kfree(ap_msg.message);
865 return rc;
866}
867
868/**
739 * The crypto operations for a PCIXCC/CEX2C card. 869 * The crypto operations for a PCIXCC/CEX2C card.
740 */ 870 */
741static struct zcrypt_ops zcrypt_pcixcc_ops = { 871static struct zcrypt_ops zcrypt_pcixcc_ops = {
@@ -744,6 +874,13 @@ static struct zcrypt_ops zcrypt_pcixcc_ops = {
744 .send_cprb = zcrypt_pcixcc_send_cprb, 874 .send_cprb = zcrypt_pcixcc_send_cprb,
745}; 875};
746 876
877static struct zcrypt_ops zcrypt_pcixcc_with_rng_ops = {
878 .rsa_modexpo = zcrypt_pcixcc_modexpo,
879 .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
880 .send_cprb = zcrypt_pcixcc_send_cprb,
881 .rng = zcrypt_pcixcc_rng,
882};
883
747/** 884/**
748 * Micro-code detection function. Its sends a message to a pcixcc card 885 * Micro-code detection function. Its sends a message to a pcixcc card
749 * to find out the microcode level. 886 * to find out the microcode level.
@@ -859,6 +996,58 @@ out_free:
859} 996}
860 997
861/** 998/**
999 * Large random number detection function. Its sends a message to a pcixcc
1000 * card to find out if large random numbers are supported.
1001 * @ap_dev: pointer to the AP device.
1002 *
1003 * Returns 1 if large random numbers are supported, 0 if not and < 0 on error.
1004 */
1005static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
1006{
1007 struct ap_message ap_msg;
1008 unsigned long long psmid;
1009 struct {
1010 struct type86_hdr hdr;
1011 struct type86_fmt2_ext fmt2;
1012 struct CPRBX cprbx;
1013 } __attribute__((packed)) *reply;
1014 int rc, i;
1015
1016 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
1017 if (!ap_msg.message)
1018 return -ENOMEM;
1019
1020 rng_type6CPRB_msgX(ap_dev, &ap_msg, 4);
1021 rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, ap_msg.message,
1022 ap_msg.length);
1023 if (rc)
1024 goto out_free;
1025
1026 /* Wait for the test message to complete. */
1027 for (i = 0; i < 2 * HZ; i++) {
1028 msleep(1000 / HZ);
1029 rc = ap_recv(ap_dev->qid, &psmid, ap_msg.message, 4096);
1030 if (rc == 0 && psmid == 0x0102030405060708ULL)
1031 break;
1032 }
1033
1034 if (i >= 2 * HZ) {
1035 /* Got no answer. */
1036 rc = -ENODEV;
1037 goto out_free;
1038 }
1039
1040 reply = ap_msg.message;
1041 if (reply->cprbx.ccp_rtcode == 0 && reply->cprbx.ccp_rscode == 0)
1042 rc = 1;
1043 else
1044 rc = 0;
1045out_free:
1046 free_page((unsigned long) ap_msg.message);
1047 return rc;
1048}
1049
1050/**
862 * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device 1051 * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
863 * since the bus_match already checked the hardware type. The PCIXCC 1052 * since the bus_match already checked the hardware type. The PCIXCC
864 * cards come in two flavours: micro code level 2 and micro code level 3. 1053 * cards come in two flavours: micro code level 2 and micro code level 3.
@@ -874,7 +1063,6 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
874 if (!zdev) 1063 if (!zdev)
875 return -ENOMEM; 1064 return -ENOMEM;
876 zdev->ap_dev = ap_dev; 1065 zdev->ap_dev = ap_dev;
877 zdev->ops = &zcrypt_pcixcc_ops;
878 zdev->online = 1; 1066 zdev->online = 1;
879 if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) { 1067 if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) {
880 rc = zcrypt_pcixcc_mcl(ap_dev); 1068 rc = zcrypt_pcixcc_mcl(ap_dev);
@@ -901,6 +1089,15 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
901 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE; 1089 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
902 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE; 1090 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
903 } 1091 }
1092 rc = zcrypt_pcixcc_rng_supported(ap_dev);
1093 if (rc < 0) {
1094 zcrypt_device_free(zdev);
1095 return rc;
1096 }
1097 if (rc)
1098 zdev->ops = &zcrypt_pcixcc_with_rng_ops;
1099 else
1100 zdev->ops = &zcrypt_pcixcc_ops;
904 ap_dev->reply = &zdev->reply; 1101 ap_dev->reply = &zdev->reply;
905 ap_dev->private = zdev; 1102 ap_dev->private = zdev;
906 rc = zcrypt_device_register(zdev); 1103 rc = zcrypt_device_register(zdev);