summaryrefslogtreecommitdiff
path: root/drivers/s390/crypto/zcrypt_msgtype6.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/crypto/zcrypt_msgtype6.c')
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype6.c49
1 files changed, 26 insertions, 23 deletions
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
index 67fd2ec9c5a1..3c53abbdc342 100644
--- a/drivers/s390/crypto/zcrypt_msgtype6.c
+++ b/drivers/s390/crypto/zcrypt_msgtype6.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright IBM Corp. 2001, 2022
+ * Copyright IBM Corp. 2001, 2023
* Author(s): Robert Burroughs
* Eric Rossman (edrossma@us.ibm.com)
*
@@ -42,7 +42,7 @@ struct response_type {
MODULE_AUTHOR("IBM Corporation");
MODULE_DESCRIPTION("Cryptographic Coprocessor (message type 6), " \
- "Copyright IBM Corp. 2001, 2012");
+ "Copyright IBM Corp. 2001, 2023");
MODULE_LICENSE("GPL");
struct function_and_rules_block {
@@ -1101,23 +1101,36 @@ static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq,
struct ica_xcRB *xcrb,
struct ap_message *ap_msg)
{
- int rc;
struct response_type *rtype = ap_msg->private;
struct {
struct type6_hdr hdr;
struct CPRBX cprbx;
/* ... more data blocks ... */
} __packed * msg = ap_msg->msg;
-
- /*
- * Set the queue's reply buffer length minus 128 byte padding
- * as reply limit for the card firmware.
- */
- msg->hdr.fromcardlen1 = min_t(unsigned int, msg->hdr.fromcardlen1,
- zq->reply.bufsize - 128);
- if (msg->hdr.fromcardlen2)
- msg->hdr.fromcardlen2 =
- zq->reply.bufsize - msg->hdr.fromcardlen1 - 128;
+ unsigned int max_payload_size;
+ int rc, delta;
+
+ /* calculate maximum payload for this card and msg type */
+ max_payload_size = zq->reply.bufsize - sizeof(struct type86_fmt2_msg);
+
+ /* limit each of the two from fields to the maximum payload size */
+ msg->hdr.fromcardlen1 = min(msg->hdr.fromcardlen1, max_payload_size);
+ msg->hdr.fromcardlen2 = min(msg->hdr.fromcardlen2, max_payload_size);
+
+ /* calculate delta if the sum of both exceeds max payload size */
+ delta = msg->hdr.fromcardlen1 + msg->hdr.fromcardlen2
+ - max_payload_size;
+ if (delta > 0) {
+ /*
+ * Sum exceeds maximum payload size, prune fromcardlen1
+ * (always trust fromcardlen2)
+ */
+ if (delta > msg->hdr.fromcardlen1) {
+ rc = -EINVAL;
+ goto out;
+ }
+ msg->hdr.fromcardlen1 -= delta;
+ }
init_completion(&rtype->work);
rc = ap_queue_message(zq->queue, ap_msg);
@@ -1335,14 +1348,6 @@ out:
/*
* The crypto operations for a CEXxC card.
*/
-static struct zcrypt_ops zcrypt_msgtype6_norng_ops = {
- .owner = THIS_MODULE,
- .name = MSGTYPE06_NAME,
- .variant = MSGTYPE06_VARIANT_NORNG,
- .rsa_modexpo = zcrypt_msgtype6_modexpo,
- .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
- .send_cprb = zcrypt_msgtype6_send_cprb,
-};
static struct zcrypt_ops zcrypt_msgtype6_ops = {
.owner = THIS_MODULE,
@@ -1365,14 +1370,12 @@ static struct zcrypt_ops zcrypt_msgtype6_ep11_ops = {
void __init zcrypt_msgtype6_init(void)
{
- zcrypt_msgtype_register(&zcrypt_msgtype6_norng_ops);
zcrypt_msgtype_register(&zcrypt_msgtype6_ops);
zcrypt_msgtype_register(&zcrypt_msgtype6_ep11_ops);
}
void __exit zcrypt_msgtype6_exit(void)
{
- zcrypt_msgtype_unregister(&zcrypt_msgtype6_norng_ops);
zcrypt_msgtype_unregister(&zcrypt_msgtype6_ops);
zcrypt_msgtype_unregister(&zcrypt_msgtype6_ep11_ops);
}