summaryrefslogtreecommitdiff
path: root/drivers/s390/crypto/zcrypt_pcixcc.c
diff options
context:
space:
mode:
authorFelix Beck <felix.beck@de.ibm.com>2011-01-05 12:47:47 +0100
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2011-01-05 12:47:27 +0100
commitc2567f8ffa2704f6f2f81013e9a590deca5a865f (patch)
tree83c71b7139d21b51166f085f08bcefcaaa808b93 /drivers/s390/crypto/zcrypt_pcixcc.c
parent2ade1fab026b4a103f0105ec4b47654fc2f729c7 (diff)
[S390] zcrypt: cope with cca restriction of cex3
The cca on the crypto adapter has a restriction in the size of the exponent if a key with a modulus bigger than 2048 bit is used. Thus in that case we have to avoid that the crypto device driver thinks the adapter is defect and sets it offline. Therfore a new member for the zcrypt_device struct called max_exp_bit_length is introduced. This will be set the first time the cca returns the error code function not implemented. If this is done with an adapter twice it will return -EINVAL. Signed-off-by: Felix Beck <felix.beck@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/crypto/zcrypt_pcixcc.c')
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index fc8eb9dce841..4f85eb725f4f 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -567,6 +567,15 @@ static int convert_response_ica(struct zcrypt_device *zdev,
case TYPE88_RSP_CODE:
return convert_error(zdev, reply);
case TYPE86_RSP_CODE:
+ if (msg->cprbx.ccp_rtcode &&
+ (msg->cprbx.ccp_rscode == 0x14f) &&
+ (outputdatalength > 256)) {
+ if (zdev->max_exp_bit_length <= 17) {
+ zdev->max_exp_bit_length = 17;
+ return -EAGAIN;
+ } else
+ return -EINVAL;
+ }
if (msg->hdr.reply_code)
return convert_error(zdev, reply);
if (msg->cprbx.cprb_ver_id == 0x02)
@@ -1052,11 +1061,13 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
+ zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
} else {
zdev->type_string = "PCIXCC_MCL3";
zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
+ zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
}
break;
case AP_DEVICE_TYPE_CEX2C:
@@ -1065,6 +1076,7 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
zdev->speed_rating = CEX2C_SPEED_RATING;
zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
+ zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
break;
case AP_DEVICE_TYPE_CEX3C:
zdev->user_space_type = ZCRYPT_CEX3C;
@@ -1072,6 +1084,7 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
zdev->speed_rating = CEX3C_SPEED_RATING;
zdev->min_mod_size = CEX3C_MIN_MOD_SIZE;
zdev->max_mod_size = CEX3C_MAX_MOD_SIZE;
+ zdev->max_exp_bit_length = CEX3C_MAX_MOD_SIZE;
break;
default:
goto out_free;