Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ingo Tuchscherer and committed by
Martin Schwidefsky
1e466fcf a4f32bdb

+29 -41
+27 -41
drivers/s390/crypto/zcrypt_msgtype50.c
··· 241 241 struct ap_message *ap_msg, 242 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 245 unsigned char *p, *q, *dp, *dq, *u, *inp; 246 246 247 247 mod_len = crt->inputdatalength; 248 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. 253 - * If we have one of these, we need to do extra checking. 254 - * For CEX3A the limit is 256 bytes. 251 + * CEX2A and CEX3A w/o FW update can handle requests up to 252 + * 256 byte modulus (2k keys). 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) 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) { 256 + if (mod_len <= 128) { /* up to 1024 bit key size */ 276 257 struct type50_crb1_msg *crb1 = ap_msg->message; 277 258 memset(crb1, 0, sizeof(*crb1)); 278 259 ap_msg->length = sizeof(*crb1); 279 260 crb1->header.msg_type_code = TYPE50_TYPE_CODE; 280 261 crb1->header.msg_len = sizeof(*crb1); 281 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 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 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 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 270 struct type50_crb2_msg *crb2 = ap_msg->message; 290 271 memset(crb2, 0, sizeof(*crb2)); 291 272 ap_msg->length = sizeof(*crb2); 292 273 crb2->header.msg_type_code = TYPE50_TYPE_CODE; 293 274 crb2->header.msg_len = sizeof(*crb2); 294 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 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 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 281 inp = crb2->message + sizeof(crb2->message) - mod_len; 301 - } else { 302 - /* long_len >= 256 */ 282 + } else if ((mod_len <= 512) && /* up to 4096 bit key size */ 283 + (zdev->max_mod_size == CEX3A_MAX_MOD_SIZE)) { /* >= CEX3A */ 303 284 struct type50_crb3_msg *crb3 = ap_msg->message; 304 285 memset(crb3, 0, sizeof(*crb3)); 305 286 ap_msg->length = sizeof(*crb3); 306 287 crb3->header.msg_type_code = TYPE50_TYPE_CODE; 307 288 crb3->header.msg_len = sizeof(*crb3); 308 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 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 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 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 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 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 308 copy_from_user(inp, crt->inputdata, mod_len)) 323 309 return -EFAULT; 324 310
+2
drivers/s390/crypto/zcrypt_msgtype50.h
··· 33 33 #define MSGTYPE50_CRB2_MAX_MSG_SIZE 0x390 /*sizeof(struct type50_crb2_msg)*/ 34 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 38 int zcrypt_msgtype50_init(void); 37 39 void zcrypt_msgtype50_exit(void); 38 40