diff options
author | Ingo Tuchscherer <ingo.tuchscherer@de.ibm.com> | 2012-10-31 05:38:15 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-11-23 05:14:30 -0500 |
commit | 1e466fcf3882e4c17c7df918185d0069cc334811 (patch) | |
tree | a39e5c19c051a47f904ff3920e9aa38683239d7d /drivers/s390 | |
parent | a4f32bdbd9c5807af1e80e2ba91ef52845a236a8 (diff) |
s390/zcrypt: msgType50 (RSA-CRT) fix
The message request handling (type50 - clear key) for RSA operations
(in CRT format) are now handled correctly with respect to the crb
format container.
Signed-off-by: Ingo Tuchscherer <ingo.tuchscherer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/crypto/zcrypt_msgtype50.c | 68 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_msgtype50.h | 2 |
2 files changed, 29 insertions, 41 deletions
diff --git a/drivers/s390/crypto/zcrypt_msgtype50.c b/drivers/s390/crypto/zcrypt_msgtype50.c index 035b6dc31b71..7c522f338bda 100644 --- a/drivers/s390/crypto/zcrypt_msgtype50.c +++ b/drivers/s390/crypto/zcrypt_msgtype50.c | |||
@@ -241,84 +241,70 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_device *zdev, | |||
241 | struct ap_message *ap_msg, | 241 | struct ap_message *ap_msg, |
242 | struct ica_rsa_modexpo_crt *crt) | 242 | struct ica_rsa_modexpo_crt *crt) |
243 | { | 243 | { |
244 | int mod_len, short_len, long_len, long_offset, limit; | 244 | int mod_len, short_len; |
245 | unsigned char *p, *q, *dp, *dq, *u, *inp; | 245 | unsigned char *p, *q, *dp, *dq, *u, *inp; |
246 | 246 | ||
247 | mod_len = crt->inputdatalength; | 247 | mod_len = crt->inputdatalength; |
248 | short_len = mod_len / 2; | 248 | short_len = mod_len / 2; |
249 | long_len = mod_len / 2 + 8; | ||
250 | 249 | ||
251 | /* | 250 | /* |
252 | * CEX2A cannot handle p, dp, or U > 128 bytes. | 251 | * CEX2A and CEX3A w/o FW update can handle requests up to |
253 | * If we have one of these, we need to do extra checking. | 252 | * 256 byte modulus (2k keys). |
254 | * For CEX3A the limit is 256 bytes. | 253 | * CEX3A with FW update and CEX4A cards are able to handle |
254 | * 512 byte modulus (4k keys). | ||
255 | */ | 255 | */ |
256 | if (zdev->max_mod_size == CEX3A_MAX_MOD_SIZE) | 256 | if (mod_len <= 128) { /* up to 1024 bit key size */ |
257 | limit = 256; | ||
258 | else | ||
259 | limit = 128; | ||
260 | |||
261 | if (long_len > limit) { | ||
262 | /* | ||
263 | * zcrypt_rsa_crt already checked for the leading | ||
264 | * zeroes of np_prime, bp_key and u_mult_inc. | ||
265 | */ | ||
266 | long_offset = long_len - limit; | ||
267 | long_len = limit; | ||
268 | } else | ||
269 | long_offset = 0; | ||
270 | |||
271 | /* | ||
272 | * Instead of doing extra work for p, dp, U > 64 bytes, we'll just use | ||
273 | * the larger message structure. | ||
274 | */ | ||
275 | if (long_len <= 64) { | ||
276 | struct type50_crb1_msg *crb1 = ap_msg->message; | 257 | struct type50_crb1_msg *crb1 = ap_msg->message; |
277 | memset(crb1, 0, sizeof(*crb1)); | 258 | memset(crb1, 0, sizeof(*crb1)); |
278 | ap_msg->length = sizeof(*crb1); | 259 | ap_msg->length = sizeof(*crb1); |
279 | crb1->header.msg_type_code = TYPE50_TYPE_CODE; | 260 | crb1->header.msg_type_code = TYPE50_TYPE_CODE; |
280 | crb1->header.msg_len = sizeof(*crb1); | 261 | crb1->header.msg_len = sizeof(*crb1); |
281 | crb1->keyblock_type = TYPE50_CRB1_FMT; | 262 | crb1->keyblock_type = TYPE50_CRB1_FMT; |
282 | p = crb1->p + sizeof(crb1->p) - long_len; | 263 | p = crb1->p + sizeof(crb1->p) - short_len; |
283 | q = crb1->q + sizeof(crb1->q) - short_len; | 264 | q = crb1->q + sizeof(crb1->q) - short_len; |
284 | dp = crb1->dp + sizeof(crb1->dp) - long_len; | 265 | dp = crb1->dp + sizeof(crb1->dp) - short_len; |
285 | dq = crb1->dq + sizeof(crb1->dq) - short_len; | 266 | dq = crb1->dq + sizeof(crb1->dq) - short_len; |
286 | u = crb1->u + sizeof(crb1->u) - long_len; | 267 | u = crb1->u + sizeof(crb1->u) - short_len; |
287 | inp = crb1->message + sizeof(crb1->message) - mod_len; | 268 | inp = crb1->message + sizeof(crb1->message) - mod_len; |
288 | } else if (long_len <= 128) { | 269 | } else if (mod_len <= 256) { /* up to 2048 bit key size */ |
289 | struct type50_crb2_msg *crb2 = ap_msg->message; | 270 | struct type50_crb2_msg *crb2 = ap_msg->message; |
290 | memset(crb2, 0, sizeof(*crb2)); | 271 | memset(crb2, 0, sizeof(*crb2)); |
291 | ap_msg->length = sizeof(*crb2); | 272 | ap_msg->length = sizeof(*crb2); |
292 | crb2->header.msg_type_code = TYPE50_TYPE_CODE; | 273 | crb2->header.msg_type_code = TYPE50_TYPE_CODE; |
293 | crb2->header.msg_len = sizeof(*crb2); | 274 | crb2->header.msg_len = sizeof(*crb2); |
294 | crb2->keyblock_type = TYPE50_CRB2_FMT; | 275 | crb2->keyblock_type = TYPE50_CRB2_FMT; |
295 | p = crb2->p + sizeof(crb2->p) - long_len; | 276 | p = crb2->p + sizeof(crb2->p) - short_len; |
296 | q = crb2->q + sizeof(crb2->q) - short_len; | 277 | q = crb2->q + sizeof(crb2->q) - short_len; |
297 | dp = crb2->dp + sizeof(crb2->dp) - long_len; | 278 | dp = crb2->dp + sizeof(crb2->dp) - short_len; |
298 | dq = crb2->dq + sizeof(crb2->dq) - short_len; | 279 | dq = crb2->dq + sizeof(crb2->dq) - short_len; |
299 | u = crb2->u + sizeof(crb2->u) - long_len; | 280 | u = crb2->u + sizeof(crb2->u) - short_len; |
300 | inp = crb2->message + sizeof(crb2->message) - mod_len; | 281 | inp = crb2->message + sizeof(crb2->message) - mod_len; |
301 | } else { | 282 | } else if ((mod_len <= 512) && /* up to 4096 bit key size */ |
302 | /* long_len >= 256 */ | 283 | (zdev->max_mod_size == CEX3A_MAX_MOD_SIZE)) { /* >= CEX3A */ |
303 | struct type50_crb3_msg *crb3 = ap_msg->message; | 284 | struct type50_crb3_msg *crb3 = ap_msg->message; |
304 | memset(crb3, 0, sizeof(*crb3)); | 285 | memset(crb3, 0, sizeof(*crb3)); |
305 | ap_msg->length = sizeof(*crb3); | 286 | ap_msg->length = sizeof(*crb3); |
306 | crb3->header.msg_type_code = TYPE50_TYPE_CODE; | 287 | crb3->header.msg_type_code = TYPE50_TYPE_CODE; |
307 | crb3->header.msg_len = sizeof(*crb3); | 288 | crb3->header.msg_len = sizeof(*crb3); |
308 | crb3->keyblock_type = TYPE50_CRB3_FMT; | 289 | crb3->keyblock_type = TYPE50_CRB3_FMT; |
309 | p = crb3->p + sizeof(crb3->p) - long_len; | 290 | p = crb3->p + sizeof(crb3->p) - short_len; |
310 | q = crb3->q + sizeof(crb3->q) - short_len; | 291 | q = crb3->q + sizeof(crb3->q) - short_len; |
311 | dp = crb3->dp + sizeof(crb3->dp) - long_len; | 292 | dp = crb3->dp + sizeof(crb3->dp) - short_len; |
312 | dq = crb3->dq + sizeof(crb3->dq) - short_len; | 293 | dq = crb3->dq + sizeof(crb3->dq) - short_len; |
313 | u = crb3->u + sizeof(crb3->u) - long_len; | 294 | u = crb3->u + sizeof(crb3->u) - short_len; |
314 | inp = crb3->message + sizeof(crb3->message) - mod_len; | 295 | inp = crb3->message + sizeof(crb3->message) - mod_len; |
315 | } | 296 | } else |
297 | return -EINVAL; | ||
316 | 298 | ||
317 | if (copy_from_user(p, crt->np_prime + long_offset, long_len) || | 299 | /* |
300 | * correct the offset of p, bp and mult_inv according zcrypt.h | ||
301 | * block size right aligned (skip the first byte) | ||
302 | */ | ||
303 | if (copy_from_user(p, crt->np_prime + MSGTYPE_ADJUSTMENT, short_len) || | ||
318 | copy_from_user(q, crt->nq_prime, short_len) || | 304 | copy_from_user(q, crt->nq_prime, short_len) || |
319 | copy_from_user(dp, crt->bp_key + long_offset, long_len) || | 305 | copy_from_user(dp, crt->bp_key + MSGTYPE_ADJUSTMENT, short_len) || |
320 | copy_from_user(dq, crt->bq_key, short_len) || | 306 | copy_from_user(dq, crt->bq_key, short_len) || |
321 | copy_from_user(u, crt->u_mult_inv + long_offset, long_len) || | 307 | copy_from_user(u, crt->u_mult_inv + MSGTYPE_ADJUSTMENT, short_len) || |
322 | copy_from_user(inp, crt->inputdata, mod_len)) | 308 | copy_from_user(inp, crt->inputdata, mod_len)) |
323 | return -EFAULT; | 309 | return -EFAULT; |
324 | 310 | ||
diff --git a/drivers/s390/crypto/zcrypt_msgtype50.h b/drivers/s390/crypto/zcrypt_msgtype50.h index e56dc72c7733..0a66e4aeeb50 100644 --- a/drivers/s390/crypto/zcrypt_msgtype50.h +++ b/drivers/s390/crypto/zcrypt_msgtype50.h | |||
@@ -33,6 +33,8 @@ | |||
33 | #define MSGTYPE50_CRB2_MAX_MSG_SIZE 0x390 /*sizeof(struct type50_crb2_msg)*/ | 33 | #define MSGTYPE50_CRB2_MAX_MSG_SIZE 0x390 /*sizeof(struct type50_crb2_msg)*/ |
34 | #define MSGTYPE50_CRB3_MAX_MSG_SIZE 0x710 /*sizeof(struct type50_crb3_msg)*/ | 34 | #define MSGTYPE50_CRB3_MAX_MSG_SIZE 0x710 /*sizeof(struct type50_crb3_msg)*/ |
35 | 35 | ||
36 | #define MSGTYPE_ADJUSTMENT 0x08 /*type04 extension (not needed in type50)*/ | ||
37 | |||
36 | int zcrypt_msgtype50_init(void); | 38 | int zcrypt_msgtype50_init(void); |
37 | void zcrypt_msgtype50_exit(void); | 39 | void zcrypt_msgtype50_exit(void); |
38 | 40 | ||