aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorIngo Tuchscherer <ingo.tuchscherer@de.ibm.com>2012-10-31 05:38:15 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-11-23 05:14:30 -0500
commit1e466fcf3882e4c17c7df918185d0069cc334811 (patch)
treea39e5c19c051a47f904ff3920e9aa38683239d7d /drivers/s390
parenta4f32bdbd9c5807af1e80e2ba91ef52845a236a8 (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.c68
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype50.h2
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
36int zcrypt_msgtype50_init(void); 38int zcrypt_msgtype50_init(void);
37void zcrypt_msgtype50_exit(void); 39void zcrypt_msgtype50_exit(void);
38 40