Skip to content

Commit

Permalink
s390/zcrypt: CEX7S exploitation support
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Ingo Franzki <[email protected]>
Signed-off-by: Vasily Gorbik <[email protected]>
  • Loading branch information
hfreude authored and Vasily Gorbik committed Sep 19, 2019
1 parent b91d9e6 commit cf2957f
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 29 deletions.
4 changes: 2 additions & 2 deletions arch/s390/include/uapi/asm/zcrypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 ([email protected])
*
Expand Down Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions drivers/s390/crypto/ap_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion drivers/s390/crypto/ap_bus.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright IBM Corp. 2006, 2012
* Copyright IBM Corp. 2006, 2019
* Author(s): Cornelia Huck <[email protected]>
* Martin Schwidefsky <[email protected]>
* Ralph Wuerthner <[email protected]>
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions drivers/s390/crypto/vfio_ap_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */ },
};

Expand Down
3 changes: 2 additions & 1 deletion drivers/s390/crypto/zcrypt_api.h
Original file line number Diff line number Diff line change
@@ -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 ([email protected])
* Cornelia Huck <[email protected]>
Expand Down Expand Up @@ -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
Expand Down
72 changes: 53 additions & 19 deletions drivers/s390/crypto/zcrypt_cex4.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright IBM Corp. 2012
* Copyright IBM Corp. 2012, 2019
* Author(s): Holger Dengler <[email protected]>
*/

Expand Down Expand Up @@ -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[] = {
Expand All @@ -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 */ },
};

Expand All @@ -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 */ },
};

Expand Down Expand Up @@ -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.
Expand All @@ -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;
Expand All @@ -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) &&
Expand Down Expand Up @@ -232,14 +250,22 @@ 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
*/
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;
Expand All @@ -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;
Expand Down Expand Up @@ -289,8 +323,8 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)
}

/**
* 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)
{
Expand All @@ -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.
Expand Down Expand Up @@ -369,7 +403,7 @@ static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev)
}

/**
* 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)
Expand Down

0 comments on commit cf2957f

Please sign in to comment.