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

[S390] zcrypt: support for 4096 bit keys for cex3a

Definitions for CEX3 card types are changed to support 4096 bit RSA
keys. Also new structs for the accelerator mode are needed.
Additionaly when checking the length of key parts, the case for bigger
(4096 bit) keys is needed.

Signed-off-by: Felix Beck <felix.beck@de.ibm.com>
Signed-off-by: Ralph Wuerthner <ralph.wuerthner@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Felix Beck and committed by
Martin Schwidefsky
3e309a66 b1f933da

+87 -16
+62 -16
drivers/s390/crypto/zcrypt_cex2a.c
··· 41 41 #define CEX2A_MIN_MOD_SIZE 1 /* 8 bits */ 42 42 #define CEX2A_MAX_MOD_SIZE 256 /* 2048 bits */ 43 43 #define CEX3A_MIN_MOD_SIZE CEX2A_MIN_MOD_SIZE 44 - #define CEX3A_MAX_MOD_SIZE CEX2A_MAX_MOD_SIZE 44 + #define CEX3A_MAX_MOD_SIZE 512 /* 4096 bits */ 45 45 46 46 #define CEX2A_SPEED_RATING 970 47 47 #define CEX3A_SPEED_RATING 900 /* Fixme: Needs finetuning */ ··· 49 49 #define CEX2A_MAX_MESSAGE_SIZE 0x390 /* sizeof(struct type50_crb2_msg) */ 50 50 #define CEX2A_MAX_RESPONSE_SIZE 0x110 /* max outputdatalength + type80_hdr */ 51 51 52 - #define CEX3A_MAX_MESSAGE_SIZE CEX2A_MAX_MESSAGE_SIZE 53 - #define CEX3A_MAX_RESPONSE_SIZE CEX2A_MAX_RESPONSE_SIZE 52 + #define CEX3A_MAX_RESPONSE_SIZE 0x210 /* 512 bit modulus 53 + * (max outputdatalength) + 54 + * type80_hdr*/ 55 + #define CEX3A_MAX_MESSAGE_SIZE sizeof(struct type50_crb3_msg) 54 56 55 57 #define CEX2A_CLEANUP_TIME (15*HZ) 56 58 #define CEX3A_CLEANUP_TIME CEX2A_CLEANUP_TIME ··· 112 110 mod = meb1->modulus + sizeof(meb1->modulus) - mod_len; 113 111 exp = meb1->exponent + sizeof(meb1->exponent) - mod_len; 114 112 inp = meb1->message + sizeof(meb1->message) - mod_len; 115 - } else { 113 + } else if (mod_len <= 256) { 116 114 struct type50_meb2_msg *meb2 = ap_msg->message; 117 115 memset(meb2, 0, sizeof(*meb2)); 118 116 ap_msg->length = sizeof(*meb2); ··· 122 120 mod = meb2->modulus + sizeof(meb2->modulus) - mod_len; 123 121 exp = meb2->exponent + sizeof(meb2->exponent) - mod_len; 124 122 inp = meb2->message + sizeof(meb2->message) - mod_len; 123 + } else { 124 + /* mod_len > 256 = 4096 bit RSA Key */ 125 + struct type50_meb3_msg *meb3 = ap_msg->message; 126 + memset(meb3, 0, sizeof(*meb3)); 127 + ap_msg->length = sizeof(*meb3); 128 + meb3->header.msg_type_code = TYPE50_TYPE_CODE; 129 + meb3->header.msg_len = sizeof(*meb3); 130 + meb3->keyblock_type = TYPE50_MEB3_FMT; 131 + mod = meb3->modulus + sizeof(meb3->modulus) - mod_len; 132 + exp = meb3->exponent + sizeof(meb3->exponent) - mod_len; 133 + inp = meb3->message + sizeof(meb3->message) - mod_len; 125 134 } 126 135 127 136 if (copy_from_user(mod, mex->n_modulus, mod_len) || ··· 155 142 struct ap_message *ap_msg, 156 143 struct ica_rsa_modexpo_crt *crt) 157 144 { 158 - int mod_len, short_len, long_len, long_offset; 145 + int mod_len, short_len, long_len, long_offset, limit; 159 146 unsigned char *p, *q, *dp, *dq, *u, *inp; 160 147 161 148 mod_len = crt->inputdatalength; ··· 165 152 /* 166 153 * CEX2A cannot handle p, dp, or U > 128 bytes. 167 154 * If we have one of these, we need to do extra checking. 155 + * For CEX3A the limit is 256 bytes. 168 156 */ 169 - if (long_len > 128) { 157 + if (zdev->max_mod_size == CEX3A_MAX_MOD_SIZE) 158 + limit = 256; 159 + else 160 + limit = 128; 161 + 162 + if (long_len > limit) { 170 163 /* 171 164 * zcrypt_rsa_crt already checked for the leading 172 165 * zeroes of np_prime, bp_key and u_mult_inc. 173 166 */ 174 - long_offset = long_len - 128; 175 - long_len = 128; 167 + long_offset = long_len - limit; 168 + long_len = limit; 176 169 } else 177 170 long_offset = 0; 178 171 ··· 199 180 dq = crb1->dq + sizeof(crb1->dq) - short_len; 200 181 u = crb1->u + sizeof(crb1->u) - long_len; 201 182 inp = crb1->message + sizeof(crb1->message) - mod_len; 202 - } else { 183 + } else if (long_len <= 128) { 203 184 struct type50_crb2_msg *crb2 = ap_msg->message; 204 185 memset(crb2, 0, sizeof(*crb2)); 205 186 ap_msg->length = sizeof(*crb2); ··· 212 193 dq = crb2->dq + sizeof(crb2->dq) - short_len; 213 194 u = crb2->u + sizeof(crb2->u) - long_len; 214 195 inp = crb2->message + sizeof(crb2->message) - mod_len; 196 + } else { 197 + /* long_len >= 256 */ 198 + struct type50_crb3_msg *crb3 = ap_msg->message; 199 + memset(crb3, 0, sizeof(*crb3)); 200 + ap_msg->length = sizeof(*crb3); 201 + crb3->header.msg_type_code = TYPE50_TYPE_CODE; 202 + crb3->header.msg_len = sizeof(*crb3); 203 + crb3->keyblock_type = TYPE50_CRB3_FMT; 204 + p = crb3->p + sizeof(crb3->p) - long_len; 205 + q = crb3->q + sizeof(crb3->q) - short_len; 206 + dp = crb3->dp + sizeof(crb3->dp) - long_len; 207 + dq = crb3->dq + sizeof(crb3->dq) - short_len; 208 + u = crb3->u + sizeof(crb3->u) - long_len; 209 + inp = crb3->message + sizeof(crb3->message) - mod_len; 215 210 } 216 211 217 212 if (copy_from_user(p, crt->np_prime + long_offset, long_len) || ··· 235 202 copy_from_user(u, crt->u_mult_inv + long_offset, long_len) || 236 203 copy_from_user(inp, crt->inputdata, mod_len)) 237 204 return -EFAULT; 238 - 239 205 240 206 return 0; 241 207 } ··· 262 230 zdev->online = 0; 263 231 return -EAGAIN; /* repeat the request on a different device. */ 264 232 } 265 - BUG_ON(t80h->len > CEX2A_MAX_RESPONSE_SIZE); 233 + if (zdev->user_space_type == ZCRYPT_CEX2A) 234 + BUG_ON(t80h->len > CEX2A_MAX_RESPONSE_SIZE); 235 + else 236 + BUG_ON(t80h->len > CEX3A_MAX_RESPONSE_SIZE); 266 237 data = reply->message + t80h->len - outputdatalength; 267 238 if (copy_to_user(outputdata, data, outputdatalength)) 268 239 return -EFAULT; ··· 317 282 } 318 283 t80h = reply->message; 319 284 if (t80h->type == TYPE80_RSP_CODE) { 320 - length = min(CEX2A_MAX_RESPONSE_SIZE, (int) t80h->len); 285 + if (ap_dev->device_type == AP_DEVICE_TYPE_CEX2A) 286 + length = min(CEX2A_MAX_RESPONSE_SIZE, (int) t80h->len); 287 + else 288 + length = min(CEX3A_MAX_RESPONSE_SIZE, (int) t80h->len); 321 289 memcpy(msg->message, reply->message, length); 322 290 } else 323 291 memcpy(msg->message, reply->message, sizeof error_reply); ··· 345 307 int rc; 346 308 347 309 ap_init_message(&ap_msg); 348 - ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL); 310 + if (zdev->user_space_type == ZCRYPT_CEX2A) 311 + ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL); 312 + else 313 + ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL); 349 314 if (!ap_msg.message) 350 315 return -ENOMEM; 351 316 ap_msg.psmid = (((unsigned long long) current->pid) << 32) + ··· 386 345 int rc; 387 346 388 347 ap_init_message(&ap_msg); 389 - ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL); 348 + if (zdev->user_space_type == ZCRYPT_CEX2A) 349 + ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL); 350 + else 351 + ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL); 390 352 if (!ap_msg.message) 391 353 return -ENOMEM; 392 354 ap_msg.psmid = (((unsigned long long) current->pid) << 32) + ··· 448 404 return -ENOMEM; 449 405 zdev->user_space_type = ZCRYPT_CEX3A; 450 406 zdev->type_string = "CEX3A"; 451 - zdev->min_mod_size = CEX3A_MIN_MOD_SIZE; 452 - zdev->max_mod_size = CEX3A_MAX_MOD_SIZE; 407 + zdev->min_mod_size = CEX2A_MIN_MOD_SIZE; 408 + zdev->max_mod_size = CEX2A_MAX_MOD_SIZE; 409 + if (ap_4096_commands_available(ap_dev->qid)) 410 + zdev->max_mod_size = CEX3A_MAX_MOD_SIZE; 453 411 zdev->short_crt = 1; 454 412 zdev->speed_rating = CEX3A_SPEED_RATING; 455 413 break;
+25
drivers/s390/crypto/zcrypt_cex2a.h
··· 51 51 52 52 #define TYPE50_MEB1_FMT 0x0001 53 53 #define TYPE50_MEB2_FMT 0x0002 54 + #define TYPE50_MEB3_FMT 0x0003 54 55 #define TYPE50_CRB1_FMT 0x0011 55 56 #define TYPE50_CRB2_FMT 0x0012 57 + #define TYPE50_CRB3_FMT 0x0013 56 58 57 59 /* Mod-Exp, with a small modulus */ 58 60 struct type50_meb1_msg { ··· 74 72 unsigned char exponent[256]; 75 73 unsigned char modulus[256]; 76 74 unsigned char message[256]; 75 + } __attribute__((packed)); 76 + 77 + /* Mod-Exp, with a larger modulus */ 78 + struct type50_meb3_msg { 79 + struct type50_hdr header; 80 + unsigned short keyblock_type; /* 0x0003 */ 81 + unsigned char reserved[6]; 82 + unsigned char exponent[512]; 83 + unsigned char modulus[512]; 84 + unsigned char message[512]; 77 85 } __attribute__((packed)); 78 86 79 87 /* CRT, with a small modulus */ ··· 110 98 unsigned char dq[128]; 111 99 unsigned char u[128]; 112 100 unsigned char message[256]; 101 + } __attribute__((packed)); 102 + 103 + /* CRT, with a larger modulus */ 104 + struct type50_crb3_msg { 105 + struct type50_hdr header; 106 + unsigned short keyblock_type; /* 0x0013 */ 107 + unsigned char reserved[6]; 108 + unsigned char p[256]; 109 + unsigned char q[256]; 110 + unsigned char dp[256]; 111 + unsigned char dq[256]; 112 + unsigned char u[256]; 113 + unsigned char message[512]; 113 114 } __attribute__((packed)); 114 115 115 116 /**