Commit c2567f8f authored by Felix Beck's avatar Felix Beck Committed by Martin Schwidefsky

[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: default avatarFelix Beck <felix.beck@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 2ade1fab
...@@ -109,6 +109,7 @@ struct zcrypt_device { ...@@ -109,6 +109,7 @@ struct zcrypt_device {
int request_count; /* # current requests. */ int request_count; /* # current requests. */
struct ap_message reply; /* Per-device reply structure. */ struct ap_message reply; /* Per-device reply structure. */
int max_exp_bit_length;
}; };
struct zcrypt_device *zcrypt_device_alloc(size_t); struct zcrypt_device *zcrypt_device_alloc(size_t);
......
...@@ -441,6 +441,7 @@ static int zcrypt_cex2a_probe(struct ap_device *ap_dev) ...@@ -441,6 +441,7 @@ static int zcrypt_cex2a_probe(struct ap_device *ap_dev)
zdev->max_mod_size = CEX2A_MAX_MOD_SIZE; zdev->max_mod_size = CEX2A_MAX_MOD_SIZE;
zdev->short_crt = 1; zdev->short_crt = 1;
zdev->speed_rating = CEX2A_SPEED_RATING; zdev->speed_rating = CEX2A_SPEED_RATING;
zdev->max_exp_bit_length = CEX2A_MAX_MOD_SIZE;
break; break;
case AP_DEVICE_TYPE_CEX3A: case AP_DEVICE_TYPE_CEX3A:
zdev = zcrypt_device_alloc(CEX3A_MAX_RESPONSE_SIZE); zdev = zcrypt_device_alloc(CEX3A_MAX_RESPONSE_SIZE);
...@@ -450,8 +451,11 @@ static int zcrypt_cex2a_probe(struct ap_device *ap_dev) ...@@ -450,8 +451,11 @@ static int zcrypt_cex2a_probe(struct ap_device *ap_dev)
zdev->type_string = "CEX3A"; zdev->type_string = "CEX3A";
zdev->min_mod_size = CEX2A_MIN_MOD_SIZE; zdev->min_mod_size = CEX2A_MIN_MOD_SIZE;
zdev->max_mod_size = CEX2A_MAX_MOD_SIZE; zdev->max_mod_size = CEX2A_MAX_MOD_SIZE;
if (ap_4096_commands_available(ap_dev->qid)) zdev->max_exp_bit_length = CEX2A_MAX_MOD_SIZE;
if (ap_4096_commands_available(ap_dev->qid)) {
zdev->max_mod_size = CEX3A_MAX_MOD_SIZE; zdev->max_mod_size = CEX3A_MAX_MOD_SIZE;
zdev->max_exp_bit_length = CEX3A_MAX_MOD_SIZE;
}
zdev->short_crt = 1; zdev->short_crt = 1;
zdev->speed_rating = CEX3A_SPEED_RATING; zdev->speed_rating = CEX3A_SPEED_RATING;
break; break;
......
...@@ -373,6 +373,7 @@ static int zcrypt_pcica_probe(struct ap_device *ap_dev) ...@@ -373,6 +373,7 @@ static int zcrypt_pcica_probe(struct ap_device *ap_dev)
zdev->min_mod_size = PCICA_MIN_MOD_SIZE; zdev->min_mod_size = PCICA_MIN_MOD_SIZE;
zdev->max_mod_size = PCICA_MAX_MOD_SIZE; zdev->max_mod_size = PCICA_MAX_MOD_SIZE;
zdev->speed_rating = PCICA_SPEED_RATING; zdev->speed_rating = PCICA_SPEED_RATING;
zdev->max_exp_bit_length = PCICA_MAX_MOD_SIZE;
ap_dev->reply = &zdev->reply; ap_dev->reply = &zdev->reply;
ap_dev->private = zdev; ap_dev->private = zdev;
rc = zcrypt_device_register(zdev); rc = zcrypt_device_register(zdev);
......
...@@ -579,6 +579,7 @@ static int zcrypt_pcicc_probe(struct ap_device *ap_dev) ...@@ -579,6 +579,7 @@ static int zcrypt_pcicc_probe(struct ap_device *ap_dev)
zdev->min_mod_size = PCICC_MIN_MOD_SIZE; zdev->min_mod_size = PCICC_MIN_MOD_SIZE;
zdev->max_mod_size = PCICC_MAX_MOD_SIZE; zdev->max_mod_size = PCICC_MAX_MOD_SIZE;
zdev->speed_rating = PCICC_SPEED_RATING; zdev->speed_rating = PCICC_SPEED_RATING;
zdev->max_exp_bit_length = PCICC_MAX_MOD_SIZE;
ap_dev->reply = &zdev->reply; ap_dev->reply = &zdev->reply;
ap_dev->private = zdev; ap_dev->private = zdev;
rc = zcrypt_device_register(zdev); rc = zcrypt_device_register(zdev);
......
...@@ -567,6 +567,15 @@ static int convert_response_ica(struct zcrypt_device *zdev, ...@@ -567,6 +567,15 @@ static int convert_response_ica(struct zcrypt_device *zdev,
case TYPE88_RSP_CODE: case TYPE88_RSP_CODE:
return convert_error(zdev, reply); return convert_error(zdev, reply);
case TYPE86_RSP_CODE: 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) if (msg->hdr.reply_code)
return convert_error(zdev, reply); return convert_error(zdev, reply);
if (msg->cprbx.cprb_ver_id == 0x02) if (msg->cprbx.cprb_ver_id == 0x02)
...@@ -1052,11 +1061,13 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev) ...@@ -1052,11 +1061,13 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING; zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD; zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE; zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
} else { } else {
zdev->type_string = "PCIXCC_MCL3"; zdev->type_string = "PCIXCC_MCL3";
zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING; zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE; zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE; zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
} }
break; break;
case AP_DEVICE_TYPE_CEX2C: case AP_DEVICE_TYPE_CEX2C:
...@@ -1065,6 +1076,7 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev) ...@@ -1065,6 +1076,7 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
zdev->speed_rating = CEX2C_SPEED_RATING; zdev->speed_rating = CEX2C_SPEED_RATING;
zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE; zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE; zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
break; break;
case AP_DEVICE_TYPE_CEX3C: case AP_DEVICE_TYPE_CEX3C:
zdev->user_space_type = ZCRYPT_CEX3C; zdev->user_space_type = ZCRYPT_CEX3C;
...@@ -1072,6 +1084,7 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev) ...@@ -1072,6 +1084,7 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
zdev->speed_rating = CEX3C_SPEED_RATING; zdev->speed_rating = CEX3C_SPEED_RATING;
zdev->min_mod_size = CEX3C_MIN_MOD_SIZE; zdev->min_mod_size = CEX3C_MIN_MOD_SIZE;
zdev->max_mod_size = CEX3C_MAX_MOD_SIZE; zdev->max_mod_size = CEX3C_MAX_MOD_SIZE;
zdev->max_exp_bit_length = CEX3C_MAX_MOD_SIZE;
break; break;
default: default:
goto out_free; goto out_free;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment