]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
s390/zcrypt: CEX7S exploitation support
authorHarald Freudenberger <freude@linux.ibm.com>
Fri, 16 Aug 2019 09:05:58 +0000 (11:05 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Thu, 19 Sep 2019 10:56:06 +0000 (12:56 +0200)
This patch adds CEX7 exploitation support for the AP bus code,
the zcrypt device driver zoo and the vfio device driver.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/include/uapi/asm/zcrypt.h
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/ap_bus.h
drivers/s390/crypto/vfio_ap_drv.c
drivers/s390/crypto/zcrypt_api.h
drivers/s390/crypto/zcrypt_cex4.c

index 8c5755f41ddeeef538f2d8452020cc1afd25e84f..f9e5e1f0821d4503fd4fedd137f969267b9abbe0 100644 (file)
@@ -4,7 +4,7 @@
  *
  *  zcrypt 2.2.1 (user-visible header)
  *
- *  Copyright IBM Corp. 2001, 2018
+ *  Copyright IBM Corp. 2001, 2019
  *  Author(s): Robert Burroughs
  *            Eric Rossman (edrossma@us.ibm.com)
  *
@@ -286,7 +286,7 @@ struct zcrypt_device_matrix_ext {
  *      0x08: CEX3A
  *      0x0a: CEX4
  *      0x0b: CEX5
- *      0x0c: CEX6
+ *      0x0c: CEX6 and CEX7
  *      0x0d: device is disabled
  *
  *   ZCRYPT_QDEPTH_MASK
index a76b8a8bcbbb6c27e18bcb69d8ee6bdcbe668d4b..a1915061932eb0325d95a644c6e8d6249bd09d47 100644 (file)
@@ -1322,24 +1322,24 @@ static int ap_get_compatible_type(ap_qid_t qid, int rawtype, unsigned int func)
        /* < CEX2A is not supported */
        if (rawtype < AP_DEVICE_TYPE_CEX2A)
                return 0;
-       /* up to CEX6 known and fully supported */
-       if (rawtype <= AP_DEVICE_TYPE_CEX6)
+       /* up to CEX7 known and fully supported */
+       if (rawtype <= AP_DEVICE_TYPE_CEX7)
                return rawtype;
        /*
-        * unknown new type > CEX6, check for compatibility
+        * unknown new type > CEX7, check for compatibility
         * to the highest known and supported type which is
-        * currently CEX6 with the help of the QACT function.
+        * currently CEX7 with the help of the QACT function.
         */
        if (ap_qact_available()) {
                struct ap_queue_status status;
                union ap_qact_ap_info apinfo = {0};
 
                apinfo.mode = (func >> 26) & 0x07;
-               apinfo.cat = AP_DEVICE_TYPE_CEX6;
+               apinfo.cat = AP_DEVICE_TYPE_CEX7;
                status = ap_qact(qid, 0, &apinfo);
                if (status.response_code == AP_RESPONSE_NORMAL
                    && apinfo.cat >= AP_DEVICE_TYPE_CEX2A
-                   && apinfo.cat <= AP_DEVICE_TYPE_CEX6)
+                   && apinfo.cat <= AP_DEVICE_TYPE_CEX7)
                        comp_type = apinfo.cat;
        }
        if (!comp_type)
index 6f3cf37776cae5b038f647b9e056c94412bf71c6..433b7b64368d6710523c468eaac5f3270cc5701f 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
- * Copyright IBM Corp. 2006, 2012
+ * Copyright IBM Corp. 2006, 2019
  * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
  *           Martin Schwidefsky <schwidefsky@de.ibm.com>
  *           Ralph Wuerthner <rwuerthn@de.ibm.com>
@@ -63,6 +63,7 @@ static inline int ap_test_bit(unsigned int *ptr, unsigned int nr)
 #define AP_DEVICE_TYPE_CEX4    10
 #define AP_DEVICE_TYPE_CEX5    11
 #define AP_DEVICE_TYPE_CEX6    12
+#define AP_DEVICE_TYPE_CEX7    13
 
 /*
  * Known function facilities
index 003662aa8060520304c05ada1436a01cac8ebfe6..be2520cc010bef249509eca4505e114026507331 100644 (file)
@@ -36,6 +36,8 @@ static struct ap_device_id ap_queue_ids[] = {
          .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
        { .dev_type = AP_DEVICE_TYPE_CEX6,
          .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
+       { .dev_type = AP_DEVICE_TYPE_CEX7,
+         .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
        { /* end of sibling */ },
 };
 
index 2d3f2732344f2d831854ce1608a7c1abf69883d7..d464618cd84f50274dfdc5eed3f69498dfc29448 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
- *  Copyright IBM Corp. 2001, 2018
+ *  Copyright IBM Corp. 2001, 2019
  *  Author(s): Robert Burroughs
  *            Eric Rossman (edrossma@us.ibm.com)
  *            Cornelia Huck <cornelia.huck@de.ibm.com>
@@ -29,6 +29,7 @@
 #define ZCRYPT_CEX4           10
 #define ZCRYPT_CEX5           11
 #define ZCRYPT_CEX6           12
+#define ZCRYPT_CEX7           13
 
 /**
  * Large random numbers are pulled in 4096 byte chunks from the crypto cards
index f58d8dec19dceee1fefa837e53f03a37fc24a186..442e3d6162f761645d5f1df2849d28c3b486c855 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- *  Copyright IBM Corp. 2012
+ *  Copyright IBM Corp. 2012, 2019
  *  Author(s): Holger Dengler <hd@linux.vnet.ibm.com>
  */
 
@@ -38,8 +38,8 @@
 #define CEX4_CLEANUP_TIME      (900*HZ)
 
 MODULE_AUTHOR("IBM Corporation");
-MODULE_DESCRIPTION("CEX4/CEX5/CEX6 Cryptographic Card device driver, " \
-                  "Copyright IBM Corp. 2018");
+MODULE_DESCRIPTION("CEX4/CEX5/CEX6/CEX7 Cryptographic Card device driver, " \
+                  "Copyright IBM Corp. 2019");
 MODULE_LICENSE("GPL");
 
 static struct ap_device_id zcrypt_cex4_card_ids[] = {
@@ -49,6 +49,8 @@ static struct ap_device_id zcrypt_cex4_card_ids[] = {
          .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
        { .dev_type = AP_DEVICE_TYPE_CEX6,
          .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
+       { .dev_type = AP_DEVICE_TYPE_CEX7,
+         .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
        { /* end of list */ },
 };
 
@@ -61,6 +63,8 @@ static struct ap_device_id zcrypt_cex4_queue_ids[] = {
          .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
        { .dev_type = AP_DEVICE_TYPE_CEX6,
          .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
+       { .dev_type = AP_DEVICE_TYPE_CEX7,
+         .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
        { /* end of list */ },
 };
 
@@ -146,7 +150,7 @@ static const struct attribute_group cca_queue_attr_group = {
 };
 
 /**
- * Probe function for CEX4/CEX5/CEX6 card device. It always
+ * Probe function for CEX4/CEX5/CEX6/CEX7 card device. It always
  * accepts the AP device since the bus_match already checked
  * the hardware type.
  * @ap_dev: pointer to the AP device.
@@ -158,25 +162,31 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)
         * MEX_1k, MEX_2k, MEX_4k, CRT_1k, CRT_2k, CRT_4k, RNG, SECKEY
         */
        static const int CEX4A_SPEED_IDX[] = {
-                14, 19, 249, 42, 228, 1458, 0, 0};
+                14,  19, 249, 42, 228, 1458, 0, 0};
        static const int CEX5A_SPEED_IDX[] = {
-                 8,  9,  20, 18,  66,  458, 0, 0};
+                 8,   9,  20, 18,  66,  458, 0, 0};
        static const int CEX6A_SPEED_IDX[] = {
-                 6,  9,  20, 17,  65,  438, 0, 0};
+                 6,   9,  20, 17,  65,  438, 0, 0};
+       static const int CEX7A_SPEED_IDX[] = {
+                 6,   8,  17, 15,  54,  362, 0, 0};
 
        static const int CEX4C_SPEED_IDX[] = {
                 59,  69, 308, 83, 278, 2204, 209, 40};
        static const int CEX5C_SPEED_IDX[] = {
-                24,  31,  50, 37,  90,  479,  27, 10};
+                24,  31,  50, 37,  90,  479,  27, 10};
        static const int CEX6C_SPEED_IDX[] = {
-                16,  20,  32, 27,  77,  455,  23,  9};
+                16,  20,  32, 27,  77,  455,  24,  9};
+       static const int CEX7C_SPEED_IDX[] = {
+                14,  16,  26, 23,  64,  376,  23,  8};
 
        static const int CEX4P_SPEED_IDX[] = {
-               224, 313, 3560, 359, 605, 2827, 0, 50};
+                 0,   0,   0,   0,   0,   0,   0,  50};
        static const int CEX5P_SPEED_IDX[] = {
-                63,  84,  156,  83, 142,  533, 0, 10};
+                 0,   0,   0,   0,   0,   0,   0,  10};
        static const int CEX6P_SPEED_IDX[] = {
-                55,  70,  121,  73, 129,  522, 0,  9};
+                 0,   0,   0,   0,   0,   0,   0,   9};
+       static const int CEX7P_SPEED_IDX[] = {
+                 0,   0,   0,   0,   0,   0,   0,   8};
 
        struct ap_card *ac = to_ap_card(&ap_dev->device);
        struct zcrypt_card *zc;
@@ -198,11 +208,19 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)
                        zc->user_space_type = ZCRYPT_CEX5;
                        memcpy(zc->speed_rating, CEX5A_SPEED_IDX,
                               sizeof(CEX5A_SPEED_IDX));
-               } else {
+               } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {
                        zc->type_string = "CEX6A";
                        zc->user_space_type = ZCRYPT_CEX6;
                        memcpy(zc->speed_rating, CEX6A_SPEED_IDX,
                               sizeof(CEX6A_SPEED_IDX));
+               } else {
+                       zc->type_string = "CEX7A";
+                       /* wrong user space type, just for compatibility
+                        * with the ZCRYPT_STATUS_MASK ioctl.
+                        */
+                       zc->user_space_type = ZCRYPT_CEX6;
+                       memcpy(zc->speed_rating, CEX7A_SPEED_IDX,
+                              sizeof(CEX7A_SPEED_IDX));
                }
                zc->min_mod_size = CEX4A_MIN_MOD_SIZE;
                if (ap_test_bit(&ac->functions, AP_FUNC_MEX4K) &&
@@ -232,7 +250,7 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)
                        zc->user_space_type = ZCRYPT_CEX3C;
                        memcpy(zc->speed_rating, CEX5C_SPEED_IDX,
                               sizeof(CEX5C_SPEED_IDX));
-               } else {
+               } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {
                        zc->type_string = "CEX6C";
                        /* wrong user space type, must be CEX6
                         * just keep it for cca compatibility
@@ -240,6 +258,14 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)
                        zc->user_space_type = ZCRYPT_CEX3C;
                        memcpy(zc->speed_rating, CEX6C_SPEED_IDX,
                               sizeof(CEX6C_SPEED_IDX));
+               } else {
+                       zc->type_string = "CEX7C";
+                       /* wrong user space type, must be CEX7
+                        * just keep it for cca compatibility
+                        */
+                       zc->user_space_type = ZCRYPT_CEX3C;
+                       memcpy(zc->speed_rating, CEX7C_SPEED_IDX,
+                              sizeof(CEX7C_SPEED_IDX));
                }
                zc->min_mod_size = CEX4C_MIN_MOD_SIZE;
                zc->max_mod_size = CEX4C_MAX_MOD_SIZE;
@@ -255,11 +281,19 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)
                        zc->user_space_type = ZCRYPT_CEX5;
                        memcpy(zc->speed_rating, CEX5P_SPEED_IDX,
                               sizeof(CEX5P_SPEED_IDX));
-               } else {
+               } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {
                        zc->type_string = "CEX6P";
                        zc->user_space_type = ZCRYPT_CEX6;
                        memcpy(zc->speed_rating, CEX6P_SPEED_IDX,
                               sizeof(CEX6P_SPEED_IDX));
+               } else {
+                       zc->type_string = "CEX7P";
+                       /* wrong user space type, just for compatibility
+                        * with the ZCRYPT_STATUS_MASK ioctl.
+                        */
+                       zc->user_space_type = ZCRYPT_CEX6;
+                       memcpy(zc->speed_rating, CEX7P_SPEED_IDX,
+                              sizeof(CEX7P_SPEED_IDX));
                }
                zc->min_mod_size = CEX4C_MIN_MOD_SIZE;
                zc->max_mod_size = CEX4C_MAX_MOD_SIZE;
@@ -289,8 +323,8 @@ out:
 }
 
 /**
- * This is called to remove the CEX4/CEX5/CEX6 card driver information
- * if an AP card device is removed.
+ * This is called to remove the CEX4/CEX5/CEX6/CEX7 card driver
+ * information if an AP card device is removed.
  */
 static void zcrypt_cex4_card_remove(struct ap_device *ap_dev)
 {
@@ -311,7 +345,7 @@ static struct ap_driver zcrypt_cex4_card_driver = {
 };
 
 /**
- * Probe function for CEX4/CEX5/CEX6 queue device. It always
+ * Probe function for CEX4/CEX5/CEX6/CEX7 queue device. It always
  * accepts the AP device since the bus_match already checked
  * the hardware type.
  * @ap_dev: pointer to the AP device.
@@ -369,7 +403,7 @@ out:
 }
 
 /**
- * This is called to remove the CEX4/CEX5/CEX6 queue driver
+ * This is called to remove the CEX4/CEX5/CEX6/CEX7 queue driver
  * information if an AP queue device is removed.
  */
 static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev)