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

s390/zcrypt: Separate msgtype implementation from card modules.

Msgtype implementations are now separated from card specific modules
and can be dynamically registered. Existing msgtype implementations
are restructured in modules.

Signed-off-by: Holger Dengler <hd@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Holger Dengler and committed by
Martin Schwidefsky
5e55a488 b26bd941

+1707 -1124
+1
drivers/s390/crypto/Makefile
··· 5 5 ap-objs := ap_bus.o 6 6 obj-$(CONFIG_ZCRYPT) += ap.o zcrypt_api.o zcrypt_pcicc.o zcrypt_pcixcc.o 7 7 obj-$(CONFIG_ZCRYPT) += zcrypt_pcica.o zcrypt_cex2a.o 8 + obj-$(CONFIG_ZCRYPT) += zcrypt_msgtype6.o zcrypt_msgtype50.o
+70 -3
drivers/s390/crypto/zcrypt_api.c
··· 1 1 /* 2 2 * zcrypt 2.1.0 3 3 * 4 - * Copyright IBM Corp. 2001, 2006 4 + * Copyright IBM Corp. 2001, 2012 5 5 * Author(s): Robert Burroughs 6 6 * Eric Rossman (edrossma@us.ibm.com) 7 7 * Cornelia Huck <cornelia.huck@de.ibm.com> ··· 9 9 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) 10 10 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com> 11 11 * Ralph Wuerthner <rwuerthn@de.ibm.com> 12 + * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> 12 13 * 13 14 * This program is free software; you can redistribute it and/or modify 14 15 * it under the terms of the GNU General Public License as published by ··· 45 44 * Module description. 46 45 */ 47 46 MODULE_AUTHOR("IBM Corporation"); 48 - MODULE_DESCRIPTION("Cryptographic Coprocessor interface, " 49 - "Copyright IBM Corp. 2001, 2006"); 47 + MODULE_DESCRIPTION("Cryptographic Coprocessor interface, " \ 48 + "Copyright IBM Corp. 2001, 2012"); 50 49 MODULE_LICENSE("GPL"); 51 50 52 51 static DEFINE_SPINLOCK(zcrypt_device_lock); ··· 56 55 57 56 static int zcrypt_rng_device_add(void); 58 57 static void zcrypt_rng_device_remove(void); 58 + 59 + static DEFINE_SPINLOCK(zcrypt_ops_list_lock); 60 + static LIST_HEAD(zcrypt_ops_list); 59 61 60 62 /* 61 63 * Device attributes common for all crypto devices. ··· 219 215 { 220 216 int rc; 221 217 218 + if (!zdev->ops) 219 + return -ENODEV; 222 220 rc = sysfs_create_group(&zdev->ap_dev->device.kobj, 223 221 &zcrypt_device_attr_group); 224 222 if (rc) ··· 274 268 zcrypt_device_put(zdev); 275 269 } 276 270 EXPORT_SYMBOL(zcrypt_device_unregister); 271 + 272 + void zcrypt_msgtype_register(struct zcrypt_ops *zops) 273 + { 274 + if (zops->owner) { 275 + spin_lock_bh(&zcrypt_ops_list_lock); 276 + list_add_tail(&zops->list, &zcrypt_ops_list); 277 + spin_unlock_bh(&zcrypt_ops_list_lock); 278 + } 279 + } 280 + EXPORT_SYMBOL(zcrypt_msgtype_register); 281 + 282 + void zcrypt_msgtype_unregister(struct zcrypt_ops *zops) 283 + { 284 + spin_lock_bh(&zcrypt_ops_list_lock); 285 + list_del_init(&zops->list); 286 + spin_unlock_bh(&zcrypt_ops_list_lock); 287 + } 288 + EXPORT_SYMBOL(zcrypt_msgtype_unregister); 289 + 290 + static inline 291 + struct zcrypt_ops *__ops_lookup(unsigned char *name, int variant) 292 + { 293 + struct zcrypt_ops *zops; 294 + int found = 0; 295 + 296 + spin_lock_bh(&zcrypt_ops_list_lock); 297 + list_for_each_entry(zops, &zcrypt_ops_list, list) { 298 + if ((zops->variant == variant) && 299 + (!strncmp(zops->owner->name, name, MODULE_NAME_LEN))) { 300 + found = 1; 301 + break; 302 + } 303 + } 304 + spin_unlock_bh(&zcrypt_ops_list_lock); 305 + 306 + if (!found) 307 + return NULL; 308 + return zops; 309 + } 310 + 311 + struct zcrypt_ops *zcrypt_msgtype_request(unsigned char *name, int variant) 312 + { 313 + struct zcrypt_ops *zops = NULL; 314 + 315 + zops = __ops_lookup(name, variant); 316 + if (!zops) { 317 + request_module(name); 318 + zops = __ops_lookup(name, variant); 319 + } 320 + if ((!zops) || (!try_module_get(zops->owner))) 321 + return NULL; 322 + return zops; 323 + } 324 + EXPORT_SYMBOL(zcrypt_msgtype_request); 325 + 326 + void zcrypt_msgtype_release(struct zcrypt_ops *zops) 327 + { 328 + if (zops) 329 + module_put(zops->owner); 330 + } 331 + EXPORT_SYMBOL(zcrypt_msgtype_release); 277 332 278 333 /** 279 334 * zcrypt_read (): Not supported beyond zcrypt 1.3.1.
+9 -1
drivers/s390/crypto/zcrypt_api.h
··· 1 1 /* 2 2 * zcrypt 2.1.0 3 3 * 4 - * Copyright IBM Corp. 2001, 2006 4 + * Copyright IBM Corp. 2001, 2012 5 5 * Author(s): Robert Burroughs 6 6 * Eric Rossman (edrossma@us.ibm.com) 7 7 * Cornelia Huck <cornelia.huck@de.ibm.com> ··· 9 9 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) 10 10 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com> 11 11 * Ralph Wuerthner <rwuerthn@de.ibm.com> 12 + * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> 12 13 * 13 14 * This program is free software; you can redistribute it and/or modify 14 15 * it under the terms of the GNU General Public License as published by ··· 88 87 struct ica_rsa_modexpo_crt *); 89 88 long (*send_cprb)(struct zcrypt_device *, struct ica_xcRB *); 90 89 long (*rng)(struct zcrypt_device *, char *); 90 + struct list_head list; /* zcrypt ops list. */ 91 + struct module *owner; 92 + int variant; 91 93 }; 92 94 93 95 struct zcrypt_device { ··· 120 116 int zcrypt_device_put(struct zcrypt_device *); 121 117 int zcrypt_device_register(struct zcrypt_device *); 122 118 void zcrypt_device_unregister(struct zcrypt_device *); 119 + void zcrypt_msgtype_register(struct zcrypt_ops *); 120 + void zcrypt_msgtype_unregister(struct zcrypt_ops *); 121 + struct zcrypt_ops *zcrypt_msgtype_request(unsigned char *, int); 122 + void zcrypt_msgtype_release(struct zcrypt_ops *); 123 123 int zcrypt_api_init(void); 124 124 void zcrypt_api_exit(void); 125 125
+17 -351
drivers/s390/crypto/zcrypt_cex2a.c
··· 1 1 /* 2 2 * zcrypt 2.1.0 3 3 * 4 - * Copyright IBM Corp. 2001, 2006 4 + * Copyright IBM Corp. 2001, 2012 5 5 * Author(s): Robert Burroughs 6 6 * Eric Rossman (edrossma@us.ibm.com) 7 7 * 8 8 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) 9 9 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com> 10 10 * Ralph Wuerthner <rwuerthn@de.ibm.com> 11 + * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> 11 12 * 12 13 * This program is free software; you can redistribute it and/or modify 13 14 * it under the terms of the GNU General Public License as published by ··· 36 35 #include "zcrypt_api.h" 37 36 #include "zcrypt_error.h" 38 37 #include "zcrypt_cex2a.h" 38 + #include "zcrypt_msgtype50.h" 39 39 40 40 #define CEX2A_MIN_MOD_SIZE 1 /* 8 bits */ 41 41 #define CEX2A_MAX_MOD_SIZE 256 /* 2048 bits */ ··· 65 63 66 64 MODULE_DEVICE_TABLE(ap, zcrypt_cex2a_ids); 67 65 MODULE_AUTHOR("IBM Corporation"); 68 - MODULE_DESCRIPTION("CEX2A Cryptographic Coprocessor device driver, " 69 - "Copyright IBM Corp. 2001, 2006"); 66 + MODULE_DESCRIPTION("CEX2A Cryptographic Coprocessor device driver, " \ 67 + "Copyright IBM Corp. 2001, 2012"); 70 68 MODULE_LICENSE("GPL"); 71 69 72 70 static int zcrypt_cex2a_probe(struct ap_device *ap_dev); 73 71 static void zcrypt_cex2a_remove(struct ap_device *ap_dev); 74 - static void zcrypt_cex2a_receive(struct ap_device *, struct ap_message *, 75 - struct ap_message *); 76 72 77 73 static struct ap_driver zcrypt_cex2a_driver = { 78 74 .probe = zcrypt_cex2a_probe, 79 75 .remove = zcrypt_cex2a_remove, 80 76 .ids = zcrypt_cex2a_ids, 81 77 .request_timeout = CEX2A_CLEANUP_TIME, 82 - }; 83 - 84 - /** 85 - * Convert a ICAMEX message to a type50 MEX message. 86 - * 87 - * @zdev: crypto device pointer 88 - * @zreq: crypto request pointer 89 - * @mex: pointer to user input data 90 - * 91 - * Returns 0 on success or -EFAULT. 92 - */ 93 - static int ICAMEX_msg_to_type50MEX_msg(struct zcrypt_device *zdev, 94 - struct ap_message *ap_msg, 95 - struct ica_rsa_modexpo *mex) 96 - { 97 - unsigned char *mod, *exp, *inp; 98 - int mod_len; 99 - 100 - mod_len = mex->inputdatalength; 101 - 102 - if (mod_len <= 128) { 103 - struct type50_meb1_msg *meb1 = ap_msg->message; 104 - memset(meb1, 0, sizeof(*meb1)); 105 - ap_msg->length = sizeof(*meb1); 106 - meb1->header.msg_type_code = TYPE50_TYPE_CODE; 107 - meb1->header.msg_len = sizeof(*meb1); 108 - meb1->keyblock_type = TYPE50_MEB1_FMT; 109 - mod = meb1->modulus + sizeof(meb1->modulus) - mod_len; 110 - exp = meb1->exponent + sizeof(meb1->exponent) - mod_len; 111 - inp = meb1->message + sizeof(meb1->message) - mod_len; 112 - } else if (mod_len <= 256) { 113 - struct type50_meb2_msg *meb2 = ap_msg->message; 114 - memset(meb2, 0, sizeof(*meb2)); 115 - ap_msg->length = sizeof(*meb2); 116 - meb2->header.msg_type_code = TYPE50_TYPE_CODE; 117 - meb2->header.msg_len = sizeof(*meb2); 118 - meb2->keyblock_type = TYPE50_MEB2_FMT; 119 - mod = meb2->modulus + sizeof(meb2->modulus) - mod_len; 120 - exp = meb2->exponent + sizeof(meb2->exponent) - mod_len; 121 - inp = meb2->message + sizeof(meb2->message) - mod_len; 122 - } else { 123 - /* mod_len > 256 = 4096 bit RSA Key */ 124 - struct type50_meb3_msg *meb3 = ap_msg->message; 125 - memset(meb3, 0, sizeof(*meb3)); 126 - ap_msg->length = sizeof(*meb3); 127 - meb3->header.msg_type_code = TYPE50_TYPE_CODE; 128 - meb3->header.msg_len = sizeof(*meb3); 129 - meb3->keyblock_type = TYPE50_MEB3_FMT; 130 - mod = meb3->modulus + sizeof(meb3->modulus) - mod_len; 131 - exp = meb3->exponent + sizeof(meb3->exponent) - mod_len; 132 - inp = meb3->message + sizeof(meb3->message) - mod_len; 133 - } 134 - 135 - if (copy_from_user(mod, mex->n_modulus, mod_len) || 136 - copy_from_user(exp, mex->b_key, mod_len) || 137 - copy_from_user(inp, mex->inputdata, mod_len)) 138 - return -EFAULT; 139 - return 0; 140 - } 141 - 142 - /** 143 - * Convert a ICACRT message to a type50 CRT message. 144 - * 145 - * @zdev: crypto device pointer 146 - * @zreq: crypto request pointer 147 - * @crt: pointer to user input data 148 - * 149 - * Returns 0 on success or -EFAULT. 150 - */ 151 - static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_device *zdev, 152 - struct ap_message *ap_msg, 153 - struct ica_rsa_modexpo_crt *crt) 154 - { 155 - int mod_len, short_len, long_len, long_offset, limit; 156 - unsigned char *p, *q, *dp, *dq, *u, *inp; 157 - 158 - mod_len = crt->inputdatalength; 159 - short_len = mod_len / 2; 160 - long_len = mod_len / 2 + 8; 161 - 162 - /* 163 - * CEX2A cannot handle p, dp, or U > 128 bytes. 164 - * If we have one of these, we need to do extra checking. 165 - * For CEX3A the limit is 256 bytes. 166 - */ 167 - if (zdev->max_mod_size == CEX3A_MAX_MOD_SIZE) 168 - limit = 256; 169 - else 170 - limit = 128; 171 - 172 - if (long_len > limit) { 173 - /* 174 - * zcrypt_rsa_crt already checked for the leading 175 - * zeroes of np_prime, bp_key and u_mult_inc. 176 - */ 177 - long_offset = long_len - limit; 178 - long_len = limit; 179 - } else 180 - long_offset = 0; 181 - 182 - /* 183 - * Instead of doing extra work for p, dp, U > 64 bytes, we'll just use 184 - * the larger message structure. 185 - */ 186 - if (long_len <= 64) { 187 - struct type50_crb1_msg *crb1 = ap_msg->message; 188 - memset(crb1, 0, sizeof(*crb1)); 189 - ap_msg->length = sizeof(*crb1); 190 - crb1->header.msg_type_code = TYPE50_TYPE_CODE; 191 - crb1->header.msg_len = sizeof(*crb1); 192 - crb1->keyblock_type = TYPE50_CRB1_FMT; 193 - p = crb1->p + sizeof(crb1->p) - long_len; 194 - q = crb1->q + sizeof(crb1->q) - short_len; 195 - dp = crb1->dp + sizeof(crb1->dp) - long_len; 196 - dq = crb1->dq + sizeof(crb1->dq) - short_len; 197 - u = crb1->u + sizeof(crb1->u) - long_len; 198 - inp = crb1->message + sizeof(crb1->message) - mod_len; 199 - } else if (long_len <= 128) { 200 - struct type50_crb2_msg *crb2 = ap_msg->message; 201 - memset(crb2, 0, sizeof(*crb2)); 202 - ap_msg->length = sizeof(*crb2); 203 - crb2->header.msg_type_code = TYPE50_TYPE_CODE; 204 - crb2->header.msg_len = sizeof(*crb2); 205 - crb2->keyblock_type = TYPE50_CRB2_FMT; 206 - p = crb2->p + sizeof(crb2->p) - long_len; 207 - q = crb2->q + sizeof(crb2->q) - short_len; 208 - dp = crb2->dp + sizeof(crb2->dp) - long_len; 209 - dq = crb2->dq + sizeof(crb2->dq) - short_len; 210 - u = crb2->u + sizeof(crb2->u) - long_len; 211 - inp = crb2->message + sizeof(crb2->message) - mod_len; 212 - } else { 213 - /* long_len >= 256 */ 214 - struct type50_crb3_msg *crb3 = ap_msg->message; 215 - memset(crb3, 0, sizeof(*crb3)); 216 - ap_msg->length = sizeof(*crb3); 217 - crb3->header.msg_type_code = TYPE50_TYPE_CODE; 218 - crb3->header.msg_len = sizeof(*crb3); 219 - crb3->keyblock_type = TYPE50_CRB3_FMT; 220 - p = crb3->p + sizeof(crb3->p) - long_len; 221 - q = crb3->q + sizeof(crb3->q) - short_len; 222 - dp = crb3->dp + sizeof(crb3->dp) - long_len; 223 - dq = crb3->dq + sizeof(crb3->dq) - short_len; 224 - u = crb3->u + sizeof(crb3->u) - long_len; 225 - inp = crb3->message + sizeof(crb3->message) - mod_len; 226 - } 227 - 228 - if (copy_from_user(p, crt->np_prime + long_offset, long_len) || 229 - copy_from_user(q, crt->nq_prime, short_len) || 230 - copy_from_user(dp, crt->bp_key + long_offset, long_len) || 231 - copy_from_user(dq, crt->bq_key, short_len) || 232 - copy_from_user(u, crt->u_mult_inv + long_offset, long_len) || 233 - copy_from_user(inp, crt->inputdata, mod_len)) 234 - return -EFAULT; 235 - 236 - return 0; 237 - } 238 - 239 - /** 240 - * Copy results from a type 80 reply message back to user space. 241 - * 242 - * @zdev: crypto device pointer 243 - * @reply: reply AP message. 244 - * @data: pointer to user output data 245 - * @length: size of user output data 246 - * 247 - * Returns 0 on success or -EFAULT. 248 - */ 249 - static int convert_type80(struct zcrypt_device *zdev, 250 - struct ap_message *reply, 251 - char __user *outputdata, 252 - unsigned int outputdatalength) 253 - { 254 - struct type80_hdr *t80h = reply->message; 255 - unsigned char *data; 256 - 257 - if (t80h->len < sizeof(*t80h) + outputdatalength) { 258 - /* The result is too short, the CEX2A card may not do that.. */ 259 - zdev->online = 0; 260 - return -EAGAIN; /* repeat the request on a different device. */ 261 - } 262 - if (zdev->user_space_type == ZCRYPT_CEX2A) 263 - BUG_ON(t80h->len > CEX2A_MAX_RESPONSE_SIZE); 264 - else 265 - BUG_ON(t80h->len > CEX3A_MAX_RESPONSE_SIZE); 266 - data = reply->message + t80h->len - outputdatalength; 267 - if (copy_to_user(outputdata, data, outputdatalength)) 268 - return -EFAULT; 269 - return 0; 270 - } 271 - 272 - static int convert_response(struct zcrypt_device *zdev, 273 - struct ap_message *reply, 274 - char __user *outputdata, 275 - unsigned int outputdatalength) 276 - { 277 - /* Response type byte is the second byte in the response. */ 278 - switch (((unsigned char *) reply->message)[1]) { 279 - case TYPE82_RSP_CODE: 280 - case TYPE88_RSP_CODE: 281 - return convert_error(zdev, reply); 282 - case TYPE80_RSP_CODE: 283 - return convert_type80(zdev, reply, 284 - outputdata, outputdatalength); 285 - default: /* Unknown response type, this should NEVER EVER happen */ 286 - zdev->online = 0; 287 - return -EAGAIN; /* repeat the request on a different device. */ 288 - } 289 - } 290 - 291 - /** 292 - * This function is called from the AP bus code after a crypto request 293 - * "msg" has finished with the reply message "reply". 294 - * It is called from tasklet context. 295 - * @ap_dev: pointer to the AP device 296 - * @msg: pointer to the AP message 297 - * @reply: pointer to the AP reply message 298 - */ 299 - static void zcrypt_cex2a_receive(struct ap_device *ap_dev, 300 - struct ap_message *msg, 301 - struct ap_message *reply) 302 - { 303 - static struct error_hdr error_reply = { 304 - .type = TYPE82_RSP_CODE, 305 - .reply_code = REP82_ERROR_MACHINE_FAILURE, 306 - }; 307 - struct type80_hdr *t80h; 308 - int length; 309 - 310 - /* Copy the reply message to the request message buffer. */ 311 - if (IS_ERR(reply)) { 312 - memcpy(msg->message, &error_reply, sizeof(error_reply)); 313 - goto out; 314 - } 315 - t80h = reply->message; 316 - if (t80h->type == TYPE80_RSP_CODE) { 317 - if (ap_dev->device_type == AP_DEVICE_TYPE_CEX2A) 318 - length = min(CEX2A_MAX_RESPONSE_SIZE, (int) t80h->len); 319 - else 320 - length = min(CEX3A_MAX_RESPONSE_SIZE, (int) t80h->len); 321 - memcpy(msg->message, reply->message, length); 322 - } else 323 - memcpy(msg->message, reply->message, sizeof error_reply); 324 - out: 325 - complete((struct completion *) msg->private); 326 - } 327 - 328 - static atomic_t zcrypt_step = ATOMIC_INIT(0); 329 - 330 - /** 331 - * The request distributor calls this function if it picked the CEX2A 332 - * device to handle a modexpo request. 333 - * @zdev: pointer to zcrypt_device structure that identifies the 334 - * CEX2A device to the request distributor 335 - * @mex: pointer to the modexpo request buffer 336 - */ 337 - static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev, 338 - struct ica_rsa_modexpo *mex) 339 - { 340 - struct ap_message ap_msg; 341 - struct completion work; 342 - int rc; 343 - 344 - ap_init_message(&ap_msg); 345 - if (zdev->user_space_type == ZCRYPT_CEX2A) 346 - ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL); 347 - else 348 - ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL); 349 - if (!ap_msg.message) 350 - return -ENOMEM; 351 - ap_msg.receive = zcrypt_cex2a_receive; 352 - ap_msg.psmid = (((unsigned long long) current->pid) << 32) + 353 - atomic_inc_return(&zcrypt_step); 354 - ap_msg.private = &work; 355 - rc = ICAMEX_msg_to_type50MEX_msg(zdev, &ap_msg, mex); 356 - if (rc) 357 - goto out_free; 358 - init_completion(&work); 359 - ap_queue_message(zdev->ap_dev, &ap_msg); 360 - rc = wait_for_completion_interruptible(&work); 361 - if (rc == 0) 362 - rc = convert_response(zdev, &ap_msg, mex->outputdata, 363 - mex->outputdatalength); 364 - else 365 - /* Signal pending. */ 366 - ap_cancel_message(zdev->ap_dev, &ap_msg); 367 - out_free: 368 - kfree(ap_msg.message); 369 - return rc; 370 - } 371 - 372 - /** 373 - * The request distributor calls this function if it picked the CEX2A 374 - * device to handle a modexpo_crt request. 375 - * @zdev: pointer to zcrypt_device structure that identifies the 376 - * CEX2A device to the request distributor 377 - * @crt: pointer to the modexpoc_crt request buffer 378 - */ 379 - static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev, 380 - struct ica_rsa_modexpo_crt *crt) 381 - { 382 - struct ap_message ap_msg; 383 - struct completion work; 384 - int rc; 385 - 386 - ap_init_message(&ap_msg); 387 - if (zdev->user_space_type == ZCRYPT_CEX2A) 388 - ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL); 389 - else 390 - ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL); 391 - if (!ap_msg.message) 392 - return -ENOMEM; 393 - ap_msg.receive = zcrypt_cex2a_receive; 394 - ap_msg.psmid = (((unsigned long long) current->pid) << 32) + 395 - atomic_inc_return(&zcrypt_step); 396 - ap_msg.private = &work; 397 - rc = ICACRT_msg_to_type50CRT_msg(zdev, &ap_msg, crt); 398 - if (rc) 399 - goto out_free; 400 - init_completion(&work); 401 - ap_queue_message(zdev->ap_dev, &ap_msg); 402 - rc = wait_for_completion_interruptible(&work); 403 - if (rc == 0) 404 - rc = convert_response(zdev, &ap_msg, crt->outputdata, 405 - crt->outputdatalength); 406 - else 407 - /* Signal pending. */ 408 - ap_cancel_message(zdev->ap_dev, &ap_msg); 409 - out_free: 410 - kfree(ap_msg.message); 411 - return rc; 412 - } 413 - 414 - /** 415 - * The crypto operations for a CEX2A card. 416 - */ 417 - static struct zcrypt_ops zcrypt_cex2a_ops = { 418 - .rsa_modexpo = zcrypt_cex2a_modexpo, 419 - .rsa_modexpo_crt = zcrypt_cex2a_modexpo_crt, 420 78 }; 421 79 422 80 /** ··· 120 458 zdev->speed_rating = CEX3A_SPEED_RATING; 121 459 break; 122 460 } 123 - if (zdev != NULL) { 124 - zdev->ap_dev = ap_dev; 125 - zdev->ops = &zcrypt_cex2a_ops; 126 - zdev->online = 1; 127 - ap_dev->reply = &zdev->reply; 128 - ap_dev->private = zdev; 129 - rc = zcrypt_device_register(zdev); 130 - } 461 + if (!zdev) 462 + return -ENODEV; 463 + zdev->ops = zcrypt_msgtype_request(MSGTYPE50_NAME, 464 + MSGTYPE50_VARIANT_DEFAULT); 465 + zdev->ap_dev = ap_dev; 466 + zdev->online = 1; 467 + ap_dev->reply = &zdev->reply; 468 + ap_dev->private = zdev; 469 + rc = zcrypt_device_register(zdev); 131 470 if (rc) { 132 471 ap_dev->private = NULL; 472 + zcrypt_msgtype_release(zdev->ops); 133 473 zcrypt_device_free(zdev); 134 474 } 135 475 return rc; ··· 144 480 static void zcrypt_cex2a_remove(struct ap_device *ap_dev) 145 481 { 146 482 struct zcrypt_device *zdev = ap_dev->private; 483 + struct zcrypt_ops *zops = zdev->ops; 147 484 148 485 zcrypt_device_unregister(zdev); 486 + zcrypt_msgtype_release(zops); 149 487 } 150 488 151 489 int __init zcrypt_cex2a_init(void)
+531
drivers/s390/crypto/zcrypt_msgtype50.c
··· 1 + /* 2 + * zcrypt 2.1.0 3 + * 4 + * Copyright IBM Corp. 2001, 2012 5 + * Author(s): Robert Burroughs 6 + * Eric Rossman (edrossma@us.ibm.com) 7 + * 8 + * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) 9 + * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com> 10 + * Ralph Wuerthner <rwuerthn@de.ibm.com> 11 + * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> 12 + * 13 + * This program is free software; you can redistribute it and/or modify 14 + * it under the terms of the GNU General Public License as published by 15 + * the Free Software Foundation; either version 2, or (at your option) 16 + * any later version. 17 + * 18 + * This program is distributed in the hope that it will be useful, 19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 + * GNU General Public License for more details. 22 + * 23 + * You should have received a copy of the GNU General Public License 24 + * along with this program; if not, write to the Free Software 25 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 + */ 27 + 28 + #include <linux/module.h> 29 + #include <linux/slab.h> 30 + #include <linux/init.h> 31 + #include <linux/err.h> 32 + #include <linux/atomic.h> 33 + #include <linux/uaccess.h> 34 + 35 + #include "ap_bus.h" 36 + #include "zcrypt_api.h" 37 + #include "zcrypt_error.h" 38 + #include "zcrypt_msgtype50.h" 39 + 40 + #define CEX3A_MAX_MOD_SIZE 512 /* 4096 bits */ 41 + 42 + #define CEX2A_MAX_RESPONSE_SIZE 0x110 /* max outputdatalength + type80_hdr */ 43 + 44 + #define CEX3A_MAX_RESPONSE_SIZE 0x210 /* 512 bit modulus 45 + * (max outputdatalength) + 46 + * type80_hdr*/ 47 + 48 + MODULE_AUTHOR("IBM Corporation"); 49 + MODULE_DESCRIPTION("Cryptographic Accelerator (message type 50), " \ 50 + "Copyright IBM Corp. 2001, 2012"); 51 + MODULE_LICENSE("GPL"); 52 + 53 + static void zcrypt_cex2a_receive(struct ap_device *, struct ap_message *, 54 + struct ap_message *); 55 + 56 + /** 57 + * The type 50 message family is associated with a CEX2A card. 58 + * 59 + * The four members of the family are described below. 60 + * 61 + * Note that all unsigned char arrays are right-justified and left-padded 62 + * with zeroes. 63 + * 64 + * Note that all reserved fields must be zeroes. 65 + */ 66 + struct type50_hdr { 67 + unsigned char reserved1; 68 + unsigned char msg_type_code; /* 0x50 */ 69 + unsigned short msg_len; 70 + unsigned char reserved2; 71 + unsigned char ignored; 72 + unsigned short reserved3; 73 + } __packed; 74 + 75 + #define TYPE50_TYPE_CODE 0x50 76 + 77 + #define TYPE50_MEB1_FMT 0x0001 78 + #define TYPE50_MEB2_FMT 0x0002 79 + #define TYPE50_MEB3_FMT 0x0003 80 + #define TYPE50_CRB1_FMT 0x0011 81 + #define TYPE50_CRB2_FMT 0x0012 82 + #define TYPE50_CRB3_FMT 0x0013 83 + 84 + /* Mod-Exp, with a small modulus */ 85 + struct type50_meb1_msg { 86 + struct type50_hdr header; 87 + unsigned short keyblock_type; /* 0x0001 */ 88 + unsigned char reserved[6]; 89 + unsigned char exponent[128]; 90 + unsigned char modulus[128]; 91 + unsigned char message[128]; 92 + } __packed; 93 + 94 + /* Mod-Exp, with a large modulus */ 95 + struct type50_meb2_msg { 96 + struct type50_hdr header; 97 + unsigned short keyblock_type; /* 0x0002 */ 98 + unsigned char reserved[6]; 99 + unsigned char exponent[256]; 100 + unsigned char modulus[256]; 101 + unsigned char message[256]; 102 + } __packed; 103 + 104 + /* Mod-Exp, with a larger modulus */ 105 + struct type50_meb3_msg { 106 + struct type50_hdr header; 107 + unsigned short keyblock_type; /* 0x0003 */ 108 + unsigned char reserved[6]; 109 + unsigned char exponent[512]; 110 + unsigned char modulus[512]; 111 + unsigned char message[512]; 112 + } __packed; 113 + 114 + /* CRT, with a small modulus */ 115 + struct type50_crb1_msg { 116 + struct type50_hdr header; 117 + unsigned short keyblock_type; /* 0x0011 */ 118 + unsigned char reserved[6]; 119 + unsigned char p[64]; 120 + unsigned char q[64]; 121 + unsigned char dp[64]; 122 + unsigned char dq[64]; 123 + unsigned char u[64]; 124 + unsigned char message[128]; 125 + } __packed; 126 + 127 + /* CRT, with a large modulus */ 128 + struct type50_crb2_msg { 129 + struct type50_hdr header; 130 + unsigned short keyblock_type; /* 0x0012 */ 131 + unsigned char reserved[6]; 132 + unsigned char p[128]; 133 + unsigned char q[128]; 134 + unsigned char dp[128]; 135 + unsigned char dq[128]; 136 + unsigned char u[128]; 137 + unsigned char message[256]; 138 + } __packed; 139 + 140 + /* CRT, with a larger modulus */ 141 + struct type50_crb3_msg { 142 + struct type50_hdr header; 143 + unsigned short keyblock_type; /* 0x0013 */ 144 + unsigned char reserved[6]; 145 + unsigned char p[256]; 146 + unsigned char q[256]; 147 + unsigned char dp[256]; 148 + unsigned char dq[256]; 149 + unsigned char u[256]; 150 + unsigned char message[512]; 151 + } __packed; 152 + 153 + /** 154 + * The type 80 response family is associated with a CEX2A card. 155 + * 156 + * Note that all unsigned char arrays are right-justified and left-padded 157 + * with zeroes. 158 + * 159 + * Note that all reserved fields must be zeroes. 160 + */ 161 + 162 + #define TYPE80_RSP_CODE 0x80 163 + 164 + struct type80_hdr { 165 + unsigned char reserved1; 166 + unsigned char type; /* 0x80 */ 167 + unsigned short len; 168 + unsigned char code; /* 0x00 */ 169 + unsigned char reserved2[3]; 170 + unsigned char reserved3[8]; 171 + } __packed; 172 + 173 + /** 174 + * Convert a ICAMEX message to a type50 MEX message. 175 + * 176 + * @zdev: crypto device pointer 177 + * @zreq: crypto request pointer 178 + * @mex: pointer to user input data 179 + * 180 + * Returns 0 on success or -EFAULT. 181 + */ 182 + static int ICAMEX_msg_to_type50MEX_msg(struct zcrypt_device *zdev, 183 + struct ap_message *ap_msg, 184 + struct ica_rsa_modexpo *mex) 185 + { 186 + unsigned char *mod, *exp, *inp; 187 + int mod_len; 188 + 189 + mod_len = mex->inputdatalength; 190 + 191 + if (mod_len <= 128) { 192 + struct type50_meb1_msg *meb1 = ap_msg->message; 193 + memset(meb1, 0, sizeof(*meb1)); 194 + ap_msg->length = sizeof(*meb1); 195 + meb1->header.msg_type_code = TYPE50_TYPE_CODE; 196 + meb1->header.msg_len = sizeof(*meb1); 197 + meb1->keyblock_type = TYPE50_MEB1_FMT; 198 + mod = meb1->modulus + sizeof(meb1->modulus) - mod_len; 199 + exp = meb1->exponent + sizeof(meb1->exponent) - mod_len; 200 + inp = meb1->message + sizeof(meb1->message) - mod_len; 201 + } else if (mod_len <= 256) { 202 + struct type50_meb2_msg *meb2 = ap_msg->message; 203 + memset(meb2, 0, sizeof(*meb2)); 204 + ap_msg->length = sizeof(*meb2); 205 + meb2->header.msg_type_code = TYPE50_TYPE_CODE; 206 + meb2->header.msg_len = sizeof(*meb2); 207 + meb2->keyblock_type = TYPE50_MEB2_FMT; 208 + mod = meb2->modulus + sizeof(meb2->modulus) - mod_len; 209 + exp = meb2->exponent + sizeof(meb2->exponent) - mod_len; 210 + inp = meb2->message + sizeof(meb2->message) - mod_len; 211 + } else { 212 + /* mod_len > 256 = 4096 bit RSA Key */ 213 + struct type50_meb3_msg *meb3 = ap_msg->message; 214 + memset(meb3, 0, sizeof(*meb3)); 215 + ap_msg->length = sizeof(*meb3); 216 + meb3->header.msg_type_code = TYPE50_TYPE_CODE; 217 + meb3->header.msg_len = sizeof(*meb3); 218 + meb3->keyblock_type = TYPE50_MEB3_FMT; 219 + mod = meb3->modulus + sizeof(meb3->modulus) - mod_len; 220 + exp = meb3->exponent + sizeof(meb3->exponent) - mod_len; 221 + inp = meb3->message + sizeof(meb3->message) - mod_len; 222 + } 223 + 224 + if (copy_from_user(mod, mex->n_modulus, mod_len) || 225 + copy_from_user(exp, mex->b_key, mod_len) || 226 + copy_from_user(inp, mex->inputdata, mod_len)) 227 + return -EFAULT; 228 + return 0; 229 + } 230 + 231 + /** 232 + * Convert a ICACRT message to a type50 CRT message. 233 + * 234 + * @zdev: crypto device pointer 235 + * @zreq: crypto request pointer 236 + * @crt: pointer to user input data 237 + * 238 + * Returns 0 on success or -EFAULT. 239 + */ 240 + static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_device *zdev, 241 + struct ap_message *ap_msg, 242 + struct ica_rsa_modexpo_crt *crt) 243 + { 244 + int mod_len, short_len, long_len, long_offset, limit; 245 + unsigned char *p, *q, *dp, *dq, *u, *inp; 246 + 247 + mod_len = crt->inputdatalength; 248 + short_len = mod_len / 2; 249 + long_len = mod_len / 2 + 8; 250 + 251 + /* 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. 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) { 276 + struct type50_crb1_msg *crb1 = ap_msg->message; 277 + memset(crb1, 0, sizeof(*crb1)); 278 + ap_msg->length = sizeof(*crb1); 279 + crb1->header.msg_type_code = TYPE50_TYPE_CODE; 280 + crb1->header.msg_len = sizeof(*crb1); 281 + crb1->keyblock_type = TYPE50_CRB1_FMT; 282 + p = crb1->p + sizeof(crb1->p) - long_len; 283 + q = crb1->q + sizeof(crb1->q) - short_len; 284 + dp = crb1->dp + sizeof(crb1->dp) - long_len; 285 + dq = crb1->dq + sizeof(crb1->dq) - short_len; 286 + u = crb1->u + sizeof(crb1->u) - long_len; 287 + inp = crb1->message + sizeof(crb1->message) - mod_len; 288 + } else if (long_len <= 128) { 289 + struct type50_crb2_msg *crb2 = ap_msg->message; 290 + memset(crb2, 0, sizeof(*crb2)); 291 + ap_msg->length = sizeof(*crb2); 292 + crb2->header.msg_type_code = TYPE50_TYPE_CODE; 293 + crb2->header.msg_len = sizeof(*crb2); 294 + crb2->keyblock_type = TYPE50_CRB2_FMT; 295 + p = crb2->p + sizeof(crb2->p) - long_len; 296 + q = crb2->q + sizeof(crb2->q) - short_len; 297 + dp = crb2->dp + sizeof(crb2->dp) - long_len; 298 + dq = crb2->dq + sizeof(crb2->dq) - short_len; 299 + u = crb2->u + sizeof(crb2->u) - long_len; 300 + inp = crb2->message + sizeof(crb2->message) - mod_len; 301 + } else { 302 + /* long_len >= 256 */ 303 + struct type50_crb3_msg *crb3 = ap_msg->message; 304 + memset(crb3, 0, sizeof(*crb3)); 305 + ap_msg->length = sizeof(*crb3); 306 + crb3->header.msg_type_code = TYPE50_TYPE_CODE; 307 + crb3->header.msg_len = sizeof(*crb3); 308 + crb3->keyblock_type = TYPE50_CRB3_FMT; 309 + p = crb3->p + sizeof(crb3->p) - long_len; 310 + q = crb3->q + sizeof(crb3->q) - short_len; 311 + dp = crb3->dp + sizeof(crb3->dp) - long_len; 312 + dq = crb3->dq + sizeof(crb3->dq) - short_len; 313 + u = crb3->u + sizeof(crb3->u) - long_len; 314 + inp = crb3->message + sizeof(crb3->message) - mod_len; 315 + } 316 + 317 + if (copy_from_user(p, crt->np_prime + long_offset, long_len) || 318 + copy_from_user(q, crt->nq_prime, short_len) || 319 + copy_from_user(dp, crt->bp_key + long_offset, long_len) || 320 + copy_from_user(dq, crt->bq_key, short_len) || 321 + copy_from_user(u, crt->u_mult_inv + long_offset, long_len) || 322 + copy_from_user(inp, crt->inputdata, mod_len)) 323 + return -EFAULT; 324 + 325 + return 0; 326 + } 327 + 328 + /** 329 + * Copy results from a type 80 reply message back to user space. 330 + * 331 + * @zdev: crypto device pointer 332 + * @reply: reply AP message. 333 + * @data: pointer to user output data 334 + * @length: size of user output data 335 + * 336 + * Returns 0 on success or -EFAULT. 337 + */ 338 + static int convert_type80(struct zcrypt_device *zdev, 339 + struct ap_message *reply, 340 + char __user *outputdata, 341 + unsigned int outputdatalength) 342 + { 343 + struct type80_hdr *t80h = reply->message; 344 + unsigned char *data; 345 + 346 + if (t80h->len < sizeof(*t80h) + outputdatalength) { 347 + /* The result is too short, the CEX2A card may not do that.. */ 348 + zdev->online = 0; 349 + return -EAGAIN; /* repeat the request on a different device. */ 350 + } 351 + if (zdev->user_space_type == ZCRYPT_CEX2A) 352 + BUG_ON(t80h->len > CEX2A_MAX_RESPONSE_SIZE); 353 + else 354 + BUG_ON(t80h->len > CEX3A_MAX_RESPONSE_SIZE); 355 + data = reply->message + t80h->len - outputdatalength; 356 + if (copy_to_user(outputdata, data, outputdatalength)) 357 + return -EFAULT; 358 + return 0; 359 + } 360 + 361 + static int convert_response(struct zcrypt_device *zdev, 362 + struct ap_message *reply, 363 + char __user *outputdata, 364 + unsigned int outputdatalength) 365 + { 366 + /* Response type byte is the second byte in the response. */ 367 + switch (((unsigned char *) reply->message)[1]) { 368 + case TYPE82_RSP_CODE: 369 + case TYPE88_RSP_CODE: 370 + return convert_error(zdev, reply); 371 + case TYPE80_RSP_CODE: 372 + return convert_type80(zdev, reply, 373 + outputdata, outputdatalength); 374 + default: /* Unknown response type, this should NEVER EVER happen */ 375 + zdev->online = 0; 376 + return -EAGAIN; /* repeat the request on a different device. */ 377 + } 378 + } 379 + 380 + /** 381 + * This function is called from the AP bus code after a crypto request 382 + * "msg" has finished with the reply message "reply". 383 + * It is called from tasklet context. 384 + * @ap_dev: pointer to the AP device 385 + * @msg: pointer to the AP message 386 + * @reply: pointer to the AP reply message 387 + */ 388 + static void zcrypt_cex2a_receive(struct ap_device *ap_dev, 389 + struct ap_message *msg, 390 + struct ap_message *reply) 391 + { 392 + static struct error_hdr error_reply = { 393 + .type = TYPE82_RSP_CODE, 394 + .reply_code = REP82_ERROR_MACHINE_FAILURE, 395 + }; 396 + struct type80_hdr *t80h; 397 + int length; 398 + 399 + /* Copy the reply message to the request message buffer. */ 400 + if (IS_ERR(reply)) { 401 + memcpy(msg->message, &error_reply, sizeof(error_reply)); 402 + goto out; 403 + } 404 + t80h = reply->message; 405 + if (t80h->type == TYPE80_RSP_CODE) { 406 + if (ap_dev->device_type == AP_DEVICE_TYPE_CEX2A) 407 + length = min_t(int, 408 + CEX2A_MAX_RESPONSE_SIZE, t80h->len); 409 + else 410 + length = min_t(int, 411 + CEX3A_MAX_RESPONSE_SIZE, t80h->len); 412 + memcpy(msg->message, reply->message, length); 413 + } else 414 + memcpy(msg->message, reply->message, sizeof(error_reply)); 415 + out: 416 + complete((struct completion *) msg->private); 417 + } 418 + 419 + static atomic_t zcrypt_step = ATOMIC_INIT(0); 420 + 421 + /** 422 + * The request distributor calls this function if it picked the CEX2A 423 + * device to handle a modexpo request. 424 + * @zdev: pointer to zcrypt_device structure that identifies the 425 + * CEX2A device to the request distributor 426 + * @mex: pointer to the modexpo request buffer 427 + */ 428 + static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev, 429 + struct ica_rsa_modexpo *mex) 430 + { 431 + struct ap_message ap_msg; 432 + struct completion work; 433 + int rc; 434 + 435 + ap_init_message(&ap_msg); 436 + if (zdev->user_space_type == ZCRYPT_CEX2A) 437 + ap_msg.message = kmalloc(MSGTYPE50_CRB2_MAX_MSG_SIZE, 438 + GFP_KERNEL); 439 + else 440 + ap_msg.message = kmalloc(MSGTYPE50_CRB3_MAX_MSG_SIZE, 441 + GFP_KERNEL); 442 + if (!ap_msg.message) 443 + return -ENOMEM; 444 + ap_msg.receive = zcrypt_cex2a_receive; 445 + ap_msg.psmid = (((unsigned long long) current->pid) << 32) + 446 + atomic_inc_return(&zcrypt_step); 447 + ap_msg.private = &work; 448 + rc = ICAMEX_msg_to_type50MEX_msg(zdev, &ap_msg, mex); 449 + if (rc) 450 + goto out_free; 451 + init_completion(&work); 452 + ap_queue_message(zdev->ap_dev, &ap_msg); 453 + rc = wait_for_completion_interruptible(&work); 454 + if (rc == 0) 455 + rc = convert_response(zdev, &ap_msg, mex->outputdata, 456 + mex->outputdatalength); 457 + else 458 + /* Signal pending. */ 459 + ap_cancel_message(zdev->ap_dev, &ap_msg); 460 + out_free: 461 + kfree(ap_msg.message); 462 + return rc; 463 + } 464 + 465 + /** 466 + * The request distributor calls this function if it picked the CEX2A 467 + * device to handle a modexpo_crt request. 468 + * @zdev: pointer to zcrypt_device structure that identifies the 469 + * CEX2A device to the request distributor 470 + * @crt: pointer to the modexpoc_crt request buffer 471 + */ 472 + static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev, 473 + struct ica_rsa_modexpo_crt *crt) 474 + { 475 + struct ap_message ap_msg; 476 + struct completion work; 477 + int rc; 478 + 479 + ap_init_message(&ap_msg); 480 + if (zdev->user_space_type == ZCRYPT_CEX2A) 481 + ap_msg.message = kmalloc(MSGTYPE50_CRB2_MAX_MSG_SIZE, 482 + GFP_KERNEL); 483 + else 484 + ap_msg.message = kmalloc(MSGTYPE50_CRB3_MAX_MSG_SIZE, 485 + GFP_KERNEL); 486 + if (!ap_msg.message) 487 + return -ENOMEM; 488 + ap_msg.receive = zcrypt_cex2a_receive; 489 + ap_msg.psmid = (((unsigned long long) current->pid) << 32) + 490 + atomic_inc_return(&zcrypt_step); 491 + ap_msg.private = &work; 492 + rc = ICACRT_msg_to_type50CRT_msg(zdev, &ap_msg, crt); 493 + if (rc) 494 + goto out_free; 495 + init_completion(&work); 496 + ap_queue_message(zdev->ap_dev, &ap_msg); 497 + rc = wait_for_completion_interruptible(&work); 498 + if (rc == 0) 499 + rc = convert_response(zdev, &ap_msg, crt->outputdata, 500 + crt->outputdatalength); 501 + else 502 + /* Signal pending. */ 503 + ap_cancel_message(zdev->ap_dev, &ap_msg); 504 + out_free: 505 + kfree(ap_msg.message); 506 + return rc; 507 + } 508 + 509 + /** 510 + * The crypto operations for message type 50. 511 + */ 512 + static struct zcrypt_ops zcrypt_msgtype50_ops = { 513 + .rsa_modexpo = zcrypt_cex2a_modexpo, 514 + .rsa_modexpo_crt = zcrypt_cex2a_modexpo_crt, 515 + .owner = THIS_MODULE, 516 + .variant = MSGTYPE50_VARIANT_DEFAULT, 517 + }; 518 + 519 + int __init zcrypt_msgtype50_init(void) 520 + { 521 + zcrypt_msgtype_register(&zcrypt_msgtype50_ops); 522 + return 0; 523 + } 524 + 525 + void __exit zcrypt_msgtype50_exit(void) 526 + { 527 + zcrypt_msgtype_unregister(&zcrypt_msgtype50_ops); 528 + } 529 + 530 + module_init(zcrypt_msgtype50_init); 531 + module_exit(zcrypt_msgtype50_exit);
+39
drivers/s390/crypto/zcrypt_msgtype50.h
··· 1 + /* 2 + * zcrypt 2.1.0 3 + * 4 + * Copyright IBM Corp. 2001, 2012 5 + * Author(s): Robert Burroughs 6 + * Eric Rossman (edrossma@us.ibm.com) 7 + * 8 + * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) 9 + * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com> 10 + * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> 11 + * 12 + * This program is free software; you can redistribute it and/or modify 13 + * it under the terms of the GNU General Public License as published by 14 + * the Free Software Foundation; either version 2, or (at your option) 15 + * any later version. 16 + * 17 + * This program is distributed in the hope that it will be useful, 18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 + * GNU General Public License for more details. 21 + * 22 + * You should have received a copy of the GNU General Public License 23 + * along with this program; if not, write to the Free Software 24 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 + */ 26 + 27 + #ifndef _ZCRYPT_MSGTYPE50_H_ 28 + #define _ZCRYPT_MSGTYPE50_H_ 29 + 30 + #define MSGTYPE50_NAME "zcrypt_msgtype50" 31 + #define MSGTYPE50_VARIANT_DEFAULT 0 32 + 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)*/ 35 + 36 + int zcrypt_msgtype50_init(void); 37 + void zcrypt_msgtype50_exit(void); 38 + 39 + #endif /* _ZCRYPT_MSGTYPE50_H_ */
+856
drivers/s390/crypto/zcrypt_msgtype6.c
··· 1 + /* 2 + * zcrypt 2.1.0 3 + * 4 + * Copyright IBM Corp. 2001, 2012 5 + * Author(s): Robert Burroughs 6 + * Eric Rossman (edrossma@us.ibm.com) 7 + * 8 + * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) 9 + * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com> 10 + * Ralph Wuerthner <rwuerthn@de.ibm.com> 11 + * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> 12 + * 13 + * This program is free software; you can redistribute it and/or modify 14 + * it under the terms of the GNU General Public License as published by 15 + * the Free Software Foundation; either version 2, or (at your option) 16 + * any later version. 17 + * 18 + * This program is distributed in the hope that it will be useful, 19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 + * GNU General Public License for more details. 22 + * 23 + * You should have received a copy of the GNU General Public License 24 + * along with this program; if not, write to the Free Software 25 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 + */ 27 + 28 + #include <linux/module.h> 29 + #include <linux/init.h> 30 + #include <linux/err.h> 31 + #include <linux/delay.h> 32 + #include <linux/slab.h> 33 + #include <linux/atomic.h> 34 + #include <linux/uaccess.h> 35 + 36 + #include "ap_bus.h" 37 + #include "zcrypt_api.h" 38 + #include "zcrypt_error.h" 39 + #include "zcrypt_msgtype6.h" 40 + #include "zcrypt_cca_key.h" 41 + 42 + #define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */ 43 + #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */ 44 + 45 + #define CEIL4(x) ((((x)+3)/4)*4) 46 + 47 + struct response_type { 48 + struct completion work; 49 + int type; 50 + }; 51 + #define PCIXCC_RESPONSE_TYPE_ICA 0 52 + #define PCIXCC_RESPONSE_TYPE_XCRB 1 53 + 54 + MODULE_AUTHOR("IBM Corporation"); 55 + MODULE_DESCRIPTION("Cryptographic Coprocessor (message type 6), " \ 56 + "Copyright IBM Corp. 2001, 2012"); 57 + MODULE_LICENSE("GPL"); 58 + 59 + static void zcrypt_msgtype6_receive(struct ap_device *, struct ap_message *, 60 + struct ap_message *); 61 + 62 + /** 63 + * CPRB 64 + * Note that all shorts, ints and longs are little-endian. 65 + * All pointer fields are 32-bits long, and mean nothing 66 + * 67 + * A request CPRB is followed by a request_parameter_block. 68 + * 69 + * The request (or reply) parameter block is organized thus: 70 + * function code 71 + * VUD block 72 + * key block 73 + */ 74 + struct CPRB { 75 + unsigned short cprb_len; /* CPRB length */ 76 + unsigned char cprb_ver_id; /* CPRB version id. */ 77 + unsigned char pad_000; /* Alignment pad byte. */ 78 + unsigned char srpi_rtcode[4]; /* SRPI return code LELONG */ 79 + unsigned char srpi_verb; /* SRPI verb type */ 80 + unsigned char flags; /* flags */ 81 + unsigned char func_id[2]; /* function id */ 82 + unsigned char checkpoint_flag; /* */ 83 + unsigned char resv2; /* reserved */ 84 + unsigned short req_parml; /* request parameter buffer */ 85 + /* length 16-bit little endian */ 86 + unsigned char req_parmp[4]; /* request parameter buffer * 87 + * pointer (means nothing: the * 88 + * parameter buffer follows * 89 + * the CPRB). */ 90 + unsigned char req_datal[4]; /* request data buffer */ 91 + /* length ULELONG */ 92 + unsigned char req_datap[4]; /* request data buffer */ 93 + /* pointer */ 94 + unsigned short rpl_parml; /* reply parameter buffer */ 95 + /* length 16-bit little endian */ 96 + unsigned char pad_001[2]; /* Alignment pad bytes. ULESHORT */ 97 + unsigned char rpl_parmp[4]; /* reply parameter buffer * 98 + * pointer (means nothing: the * 99 + * parameter buffer follows * 100 + * the CPRB). */ 101 + unsigned char rpl_datal[4]; /* reply data buffer len ULELONG */ 102 + unsigned char rpl_datap[4]; /* reply data buffer */ 103 + /* pointer */ 104 + unsigned short ccp_rscode; /* server reason code ULESHORT */ 105 + unsigned short ccp_rtcode; /* server return code ULESHORT */ 106 + unsigned char repd_parml[2]; /* replied parameter len ULESHORT*/ 107 + unsigned char mac_data_len[2]; /* Mac Data Length ULESHORT */ 108 + unsigned char repd_datal[4]; /* replied data length ULELONG */ 109 + unsigned char req_pc[2]; /* PC identifier */ 110 + unsigned char res_origin[8]; /* resource origin */ 111 + unsigned char mac_value[8]; /* Mac Value */ 112 + unsigned char logon_id[8]; /* Logon Identifier */ 113 + unsigned char usage_domain[2]; /* cdx */ 114 + unsigned char resv3[18]; /* reserved for requestor */ 115 + unsigned short svr_namel; /* server name length ULESHORT */ 116 + unsigned char svr_name[8]; /* server name */ 117 + } __packed; 118 + 119 + struct function_and_rules_block { 120 + unsigned char function_code[2]; 121 + unsigned short ulen; 122 + unsigned char only_rule[8]; 123 + } __packed; 124 + 125 + /** 126 + * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C 127 + * card in a type6 message. The 3 fields that must be filled in at execution 128 + * time are req_parml, rpl_parml and usage_domain. 129 + * Everything about this interface is ascii/big-endian, since the 130 + * device does *not* have 'Intel inside'. 131 + * 132 + * The CPRBX is followed immediately by the parm block. 133 + * The parm block contains: 134 + * - function code ('PD' 0x5044 or 'PK' 0x504B) 135 + * - rule block (one of:) 136 + * + 0x000A 'PKCS-1.2' (MCL2 'PD') 137 + * + 0x000A 'ZERO-PAD' (MCL2 'PK') 138 + * + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD') 139 + * + 0x000A 'MRP ' (MCL3 'PK' or CEX2C 'PK') 140 + * - VUD block 141 + */ 142 + static struct CPRBX static_cprbx = { 143 + .cprb_len = 0x00DC, 144 + .cprb_ver_id = 0x02, 145 + .func_id = {0x54, 0x32}, 146 + }; 147 + 148 + /** 149 + * Convert a ICAMEX message to a type6 MEX message. 150 + * 151 + * @zdev: crypto device pointer 152 + * @ap_msg: pointer to AP message 153 + * @mex: pointer to user input data 154 + * 155 + * Returns 0 on success or -EFAULT. 156 + */ 157 + static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev, 158 + struct ap_message *ap_msg, 159 + struct ica_rsa_modexpo *mex) 160 + { 161 + static struct type6_hdr static_type6_hdrX = { 162 + .type = 0x06, 163 + .offset1 = 0x00000058, 164 + .agent_id = {'C', 'A',}, 165 + .function_code = {'P', 'K'}, 166 + }; 167 + static struct function_and_rules_block static_pke_fnr = { 168 + .function_code = {'P', 'K'}, 169 + .ulen = 10, 170 + .only_rule = {'M', 'R', 'P', ' ', ' ', ' ', ' ', ' '} 171 + }; 172 + static struct function_and_rules_block static_pke_fnr_MCL2 = { 173 + .function_code = {'P', 'K'}, 174 + .ulen = 10, 175 + .only_rule = {'Z', 'E', 'R', 'O', '-', 'P', 'A', 'D'} 176 + }; 177 + struct { 178 + struct type6_hdr hdr; 179 + struct CPRBX cprbx; 180 + struct function_and_rules_block fr; 181 + unsigned short length; 182 + char text[0]; 183 + } __packed * msg = ap_msg->message; 184 + int size; 185 + 186 + /* VUD.ciphertext */ 187 + msg->length = mex->inputdatalength + 2; 188 + if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength)) 189 + return -EFAULT; 190 + 191 + /* Set up key which is located after the variable length text. */ 192 + size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1); 193 + if (size < 0) 194 + return size; 195 + size += sizeof(*msg) + mex->inputdatalength; 196 + 197 + /* message header, cprbx and f&r */ 198 + msg->hdr = static_type6_hdrX; 199 + msg->hdr.ToCardLen1 = size - sizeof(msg->hdr); 200 + msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr); 201 + 202 + msg->cprbx = static_cprbx; 203 + msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid); 204 + msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1; 205 + 206 + msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ? 207 + static_pke_fnr_MCL2 : static_pke_fnr; 208 + 209 + msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx); 210 + 211 + ap_msg->length = size; 212 + return 0; 213 + } 214 + 215 + /** 216 + * Convert a ICACRT message to a type6 CRT message. 217 + * 218 + * @zdev: crypto device pointer 219 + * @ap_msg: pointer to AP message 220 + * @crt: pointer to user input data 221 + * 222 + * Returns 0 on success or -EFAULT. 223 + */ 224 + static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev, 225 + struct ap_message *ap_msg, 226 + struct ica_rsa_modexpo_crt *crt) 227 + { 228 + static struct type6_hdr static_type6_hdrX = { 229 + .type = 0x06, 230 + .offset1 = 0x00000058, 231 + .agent_id = {'C', 'A',}, 232 + .function_code = {'P', 'D'}, 233 + }; 234 + static struct function_and_rules_block static_pkd_fnr = { 235 + .function_code = {'P', 'D'}, 236 + .ulen = 10, 237 + .only_rule = {'Z', 'E', 'R', 'O', '-', 'P', 'A', 'D'} 238 + }; 239 + 240 + static struct function_and_rules_block static_pkd_fnr_MCL2 = { 241 + .function_code = {'P', 'D'}, 242 + .ulen = 10, 243 + .only_rule = {'P', 'K', 'C', 'S', '-', '1', '.', '2'} 244 + }; 245 + struct { 246 + struct type6_hdr hdr; 247 + struct CPRBX cprbx; 248 + struct function_and_rules_block fr; 249 + unsigned short length; 250 + char text[0]; 251 + } __packed * msg = ap_msg->message; 252 + int size; 253 + 254 + /* VUD.ciphertext */ 255 + msg->length = crt->inputdatalength + 2; 256 + if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength)) 257 + return -EFAULT; 258 + 259 + /* Set up key which is located after the variable length text. */ 260 + size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1); 261 + if (size < 0) 262 + return size; 263 + size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */ 264 + 265 + /* message header, cprbx and f&r */ 266 + msg->hdr = static_type6_hdrX; 267 + msg->hdr.ToCardLen1 = size - sizeof(msg->hdr); 268 + msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr); 269 + 270 + msg->cprbx = static_cprbx; 271 + msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid); 272 + msg->cprbx.req_parml = msg->cprbx.rpl_msgbl = 273 + size - sizeof(msg->hdr) - sizeof(msg->cprbx); 274 + 275 + msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ? 276 + static_pkd_fnr_MCL2 : static_pkd_fnr; 277 + 278 + ap_msg->length = size; 279 + return 0; 280 + } 281 + 282 + /** 283 + * Convert a XCRB message to a type6 CPRB message. 284 + * 285 + * @zdev: crypto device pointer 286 + * @ap_msg: pointer to AP message 287 + * @xcRB: pointer to user input data 288 + * 289 + * Returns 0 on success or -EFAULT, -EINVAL. 290 + */ 291 + struct type86_fmt2_msg { 292 + struct type86_hdr hdr; 293 + struct type86_fmt2_ext fmt2; 294 + } __packed; 295 + 296 + static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, 297 + struct ap_message *ap_msg, 298 + struct ica_xcRB *xcRB) 299 + { 300 + static struct type6_hdr static_type6_hdrX = { 301 + .type = 0x06, 302 + .offset1 = 0x00000058, 303 + }; 304 + struct { 305 + struct type6_hdr hdr; 306 + struct CPRBX cprbx; 307 + } __packed * msg = ap_msg->message; 308 + 309 + int rcblen = CEIL4(xcRB->request_control_blk_length); 310 + int replylen; 311 + char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen; 312 + char *function_code; 313 + 314 + /* length checks */ 315 + ap_msg->length = sizeof(struct type6_hdr) + 316 + CEIL4(xcRB->request_control_blk_length) + 317 + xcRB->request_data_length; 318 + if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE) 319 + return -EINVAL; 320 + replylen = sizeof(struct type86_fmt2_msg) + 321 + CEIL4(xcRB->reply_control_blk_length) + 322 + xcRB->reply_data_length; 323 + if (replylen > MSGTYPE06_MAX_MSG_SIZE) 324 + return -EINVAL; 325 + 326 + /* prepare type6 header */ 327 + msg->hdr = static_type6_hdrX; 328 + memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID)); 329 + msg->hdr.ToCardLen1 = xcRB->request_control_blk_length; 330 + if (xcRB->request_data_length) { 331 + msg->hdr.offset2 = msg->hdr.offset1 + rcblen; 332 + msg->hdr.ToCardLen2 = xcRB->request_data_length; 333 + } 334 + msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length; 335 + msg->hdr.FromCardLen2 = xcRB->reply_data_length; 336 + 337 + /* prepare CPRB */ 338 + if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr, 339 + xcRB->request_control_blk_length)) 340 + return -EFAULT; 341 + if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) > 342 + xcRB->request_control_blk_length) 343 + return -EINVAL; 344 + function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len; 345 + memcpy(msg->hdr.function_code, function_code, 346 + sizeof(msg->hdr.function_code)); 347 + 348 + if (memcmp(function_code, "US", 2) == 0) 349 + ap_msg->special = 1; 350 + else 351 + ap_msg->special = 0; 352 + 353 + /* copy data block */ 354 + if (xcRB->request_data_length && 355 + copy_from_user(req_data, xcRB->request_data_address, 356 + xcRB->request_data_length)) 357 + return -EFAULT; 358 + return 0; 359 + } 360 + 361 + /** 362 + * Copy results from a type 86 ICA reply message back to user space. 363 + * 364 + * @zdev: crypto device pointer 365 + * @reply: reply AP message. 366 + * @data: pointer to user output data 367 + * @length: size of user output data 368 + * 369 + * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error. 370 + */ 371 + struct type86x_reply { 372 + struct type86_hdr hdr; 373 + struct type86_fmt2_ext fmt2; 374 + struct CPRBX cprbx; 375 + unsigned char pad[4]; /* 4 byte function code/rules block ? */ 376 + unsigned short length; 377 + char text[0]; 378 + } __packed; 379 + 380 + static int convert_type86_ica(struct zcrypt_device *zdev, 381 + struct ap_message *reply, 382 + char __user *outputdata, 383 + unsigned int outputdatalength) 384 + { 385 + static unsigned char static_pad[] = { 386 + 0x00, 0x02, 387 + 0x1B, 0x7B, 0x5D, 0xB5, 0x75, 0x01, 0x3D, 0xFD, 388 + 0x8D, 0xD1, 0xC7, 0x03, 0x2D, 0x09, 0x23, 0x57, 389 + 0x89, 0x49, 0xB9, 0x3F, 0xBB, 0x99, 0x41, 0x5B, 390 + 0x75, 0x21, 0x7B, 0x9D, 0x3B, 0x6B, 0x51, 0x39, 391 + 0xBB, 0x0D, 0x35, 0xB9, 0x89, 0x0F, 0x93, 0xA5, 392 + 0x0B, 0x47, 0xF1, 0xD3, 0xBB, 0xCB, 0xF1, 0x9D, 393 + 0x23, 0x73, 0x71, 0xFF, 0xF3, 0xF5, 0x45, 0xFB, 394 + 0x61, 0x29, 0x23, 0xFD, 0xF1, 0x29, 0x3F, 0x7F, 395 + 0x17, 0xB7, 0x1B, 0xA9, 0x19, 0xBD, 0x57, 0xA9, 396 + 0xD7, 0x95, 0xA3, 0xCB, 0xED, 0x1D, 0xDB, 0x45, 397 + 0x7D, 0x11, 0xD1, 0x51, 0x1B, 0xED, 0x71, 0xE9, 398 + 0xB1, 0xD1, 0xAB, 0xAB, 0x21, 0x2B, 0x1B, 0x9F, 399 + 0x3B, 0x9F, 0xF7, 0xF7, 0xBD, 0x63, 0xEB, 0xAD, 400 + 0xDF, 0xB3, 0x6F, 0x5B, 0xDB, 0x8D, 0xA9, 0x5D, 401 + 0xE3, 0x7D, 0x77, 0x49, 0x47, 0xF5, 0xA7, 0xFD, 402 + 0xAB, 0x2F, 0x27, 0x35, 0x77, 0xD3, 0x49, 0xC9, 403 + 0x09, 0xEB, 0xB1, 0xF9, 0xBF, 0x4B, 0xCB, 0x2B, 404 + 0xEB, 0xEB, 0x05, 0xFF, 0x7D, 0xC7, 0x91, 0x8B, 405 + 0x09, 0x83, 0xB9, 0xB9, 0x69, 0x33, 0x39, 0x6B, 406 + 0x79, 0x75, 0x19, 0xBF, 0xBB, 0x07, 0x1D, 0xBD, 407 + 0x29, 0xBF, 0x39, 0x95, 0x93, 0x1D, 0x35, 0xC7, 408 + 0xC9, 0x4D, 0xE5, 0x97, 0x0B, 0x43, 0x9B, 0xF1, 409 + 0x16, 0x93, 0x03, 0x1F, 0xA5, 0xFB, 0xDB, 0xF3, 410 + 0x27, 0x4F, 0x27, 0x61, 0x05, 0x1F, 0xB9, 0x23, 411 + 0x2F, 0xC3, 0x81, 0xA9, 0x23, 0x71, 0x55, 0x55, 412 + 0xEB, 0xED, 0x41, 0xE5, 0xF3, 0x11, 0xF1, 0x43, 413 + 0x69, 0x03, 0xBD, 0x0B, 0x37, 0x0F, 0x51, 0x8F, 414 + 0x0B, 0xB5, 0x89, 0x5B, 0x67, 0xA9, 0xD9, 0x4F, 415 + 0x01, 0xF9, 0x21, 0x77, 0x37, 0x73, 0x79, 0xC5, 416 + 0x7F, 0x51, 0xC1, 0xCF, 0x97, 0xA1, 0x75, 0xAD, 417 + 0x35, 0x9D, 0xD3, 0xD3, 0xA7, 0x9D, 0x5D, 0x41, 418 + 0x6F, 0x65, 0x1B, 0xCF, 0xA9, 0x87, 0x91, 0x09 419 + }; 420 + struct type86x_reply *msg = reply->message; 421 + unsigned short service_rc, service_rs; 422 + unsigned int reply_len, pad_len; 423 + char *data; 424 + 425 + service_rc = msg->cprbx.ccp_rtcode; 426 + if (unlikely(service_rc != 0)) { 427 + service_rs = msg->cprbx.ccp_rscode; 428 + if (service_rc == 8 && service_rs == 66) 429 + return -EINVAL; 430 + if (service_rc == 8 && service_rs == 65) 431 + return -EINVAL; 432 + if (service_rc == 8 && service_rs == 770) 433 + return -EINVAL; 434 + if (service_rc == 8 && service_rs == 783) { 435 + zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD; 436 + return -EAGAIN; 437 + } 438 + if (service_rc == 12 && service_rs == 769) 439 + return -EINVAL; 440 + if (service_rc == 8 && service_rs == 72) 441 + return -EINVAL; 442 + zdev->online = 0; 443 + return -EAGAIN; /* repeat the request on a different device. */ 444 + } 445 + data = msg->text; 446 + reply_len = msg->length - 2; 447 + if (reply_len > outputdatalength) 448 + return -EINVAL; 449 + /* 450 + * For all encipher requests, the length of the ciphertext (reply_len) 451 + * will always equal the modulus length. For MEX decipher requests 452 + * the output needs to get padded. Minimum pad size is 10. 453 + * 454 + * Currently, the cases where padding will be added is for: 455 + * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support 456 + * ZERO-PAD and CRT is only supported for PKD requests) 457 + * - PCICC, always 458 + */ 459 + pad_len = outputdatalength - reply_len; 460 + if (pad_len > 0) { 461 + if (pad_len < 10) 462 + return -EINVAL; 463 + /* 'restore' padding left in the PCICC/PCIXCC card. */ 464 + if (copy_to_user(outputdata, static_pad, pad_len - 1)) 465 + return -EFAULT; 466 + if (put_user(0, outputdata + pad_len - 1)) 467 + return -EFAULT; 468 + } 469 + /* Copy the crypto response to user space. */ 470 + if (copy_to_user(outputdata + pad_len, data, reply_len)) 471 + return -EFAULT; 472 + return 0; 473 + } 474 + 475 + /** 476 + * Copy results from a type 86 XCRB reply message back to user space. 477 + * 478 + * @zdev: crypto device pointer 479 + * @reply: reply AP message. 480 + * @xcRB: pointer to XCRB 481 + * 482 + * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error. 483 + */ 484 + static int convert_type86_xcrb(struct zcrypt_device *zdev, 485 + struct ap_message *reply, 486 + struct ica_xcRB *xcRB) 487 + { 488 + struct type86_fmt2_msg *msg = reply->message; 489 + char *data = reply->message; 490 + 491 + /* Copy CPRB to user */ 492 + if (copy_to_user(xcRB->reply_control_blk_addr, 493 + data + msg->fmt2.offset1, msg->fmt2.count1)) 494 + return -EFAULT; 495 + xcRB->reply_control_blk_length = msg->fmt2.count1; 496 + 497 + /* Copy data buffer to user */ 498 + if (msg->fmt2.count2) 499 + if (copy_to_user(xcRB->reply_data_addr, 500 + data + msg->fmt2.offset2, msg->fmt2.count2)) 501 + return -EFAULT; 502 + xcRB->reply_data_length = msg->fmt2.count2; 503 + return 0; 504 + } 505 + 506 + static int convert_type86_rng(struct zcrypt_device *zdev, 507 + struct ap_message *reply, 508 + char *buffer) 509 + { 510 + struct { 511 + struct type86_hdr hdr; 512 + struct type86_fmt2_ext fmt2; 513 + struct CPRBX cprbx; 514 + } __packed * msg = reply->message; 515 + char *data = reply->message; 516 + 517 + if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0) 518 + return -EINVAL; 519 + memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2); 520 + return msg->fmt2.count2; 521 + } 522 + 523 + static int convert_response_ica(struct zcrypt_device *zdev, 524 + struct ap_message *reply, 525 + char __user *outputdata, 526 + unsigned int outputdatalength) 527 + { 528 + struct type86x_reply *msg = reply->message; 529 + 530 + /* Response type byte is the second byte in the response. */ 531 + switch (((unsigned char *) reply->message)[1]) { 532 + case TYPE82_RSP_CODE: 533 + case TYPE88_RSP_CODE: 534 + return convert_error(zdev, reply); 535 + case TYPE86_RSP_CODE: 536 + if (msg->cprbx.ccp_rtcode && 537 + (msg->cprbx.ccp_rscode == 0x14f) && 538 + (outputdatalength > 256)) { 539 + if (zdev->max_exp_bit_length <= 17) { 540 + zdev->max_exp_bit_length = 17; 541 + return -EAGAIN; 542 + } else 543 + return -EINVAL; 544 + } 545 + if (msg->hdr.reply_code) 546 + return convert_error(zdev, reply); 547 + if (msg->cprbx.cprb_ver_id == 0x02) 548 + return convert_type86_ica(zdev, reply, 549 + outputdata, outputdatalength); 550 + /* Fall through, no break, incorrect cprb version is an unknown 551 + * response */ 552 + default: /* Unknown response type, this should NEVER EVER happen */ 553 + zdev->online = 0; 554 + return -EAGAIN; /* repeat the request on a different device. */ 555 + } 556 + } 557 + 558 + static int convert_response_xcrb(struct zcrypt_device *zdev, 559 + struct ap_message *reply, 560 + struct ica_xcRB *xcRB) 561 + { 562 + struct type86x_reply *msg = reply->message; 563 + 564 + /* Response type byte is the second byte in the response. */ 565 + switch (((unsigned char *) reply->message)[1]) { 566 + case TYPE82_RSP_CODE: 567 + case TYPE88_RSP_CODE: 568 + xcRB->status = 0x0008044DL; /* HDD_InvalidParm */ 569 + return convert_error(zdev, reply); 570 + case TYPE86_RSP_CODE: 571 + if (msg->hdr.reply_code) { 572 + memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32)); 573 + return convert_error(zdev, reply); 574 + } 575 + if (msg->cprbx.cprb_ver_id == 0x02) 576 + return convert_type86_xcrb(zdev, reply, xcRB); 577 + /* Fall through, no break, incorrect cprb version is an unknown 578 + * response */ 579 + default: /* Unknown response type, this should NEVER EVER happen */ 580 + xcRB->status = 0x0008044DL; /* HDD_InvalidParm */ 581 + zdev->online = 0; 582 + return -EAGAIN; /* repeat the request on a different device. */ 583 + } 584 + } 585 + 586 + static int convert_response_rng(struct zcrypt_device *zdev, 587 + struct ap_message *reply, 588 + char *data) 589 + { 590 + struct type86x_reply *msg = reply->message; 591 + 592 + switch (msg->hdr.type) { 593 + case TYPE82_RSP_CODE: 594 + case TYPE88_RSP_CODE: 595 + return -EINVAL; 596 + case TYPE86_RSP_CODE: 597 + if (msg->hdr.reply_code) 598 + return -EINVAL; 599 + if (msg->cprbx.cprb_ver_id == 0x02) 600 + return convert_type86_rng(zdev, reply, data); 601 + /* Fall through, no break, incorrect cprb version is an unknown 602 + * response */ 603 + default: /* Unknown response type, this should NEVER EVER happen */ 604 + zdev->online = 0; 605 + return -EAGAIN; /* repeat the request on a different device. */ 606 + } 607 + } 608 + 609 + /** 610 + * This function is called from the AP bus code after a crypto request 611 + * "msg" has finished with the reply message "reply". 612 + * It is called from tasklet context. 613 + * @ap_dev: pointer to the AP device 614 + * @msg: pointer to the AP message 615 + * @reply: pointer to the AP reply message 616 + */ 617 + static void zcrypt_msgtype6_receive(struct ap_device *ap_dev, 618 + struct ap_message *msg, 619 + struct ap_message *reply) 620 + { 621 + static struct error_hdr error_reply = { 622 + .type = TYPE82_RSP_CODE, 623 + .reply_code = REP82_ERROR_MACHINE_FAILURE, 624 + }; 625 + struct response_type *resp_type = 626 + (struct response_type *) msg->private; 627 + struct type86x_reply *t86r; 628 + int length; 629 + 630 + /* Copy the reply message to the request message buffer. */ 631 + if (IS_ERR(reply)) { 632 + memcpy(msg->message, &error_reply, sizeof(error_reply)); 633 + goto out; 634 + } 635 + t86r = reply->message; 636 + if (t86r->hdr.type == TYPE86_RSP_CODE && 637 + t86r->cprbx.cprb_ver_id == 0x02) { 638 + switch (resp_type->type) { 639 + case PCIXCC_RESPONSE_TYPE_ICA: 640 + length = sizeof(struct type86x_reply) 641 + + t86r->length - 2; 642 + length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length); 643 + memcpy(msg->message, reply->message, length); 644 + break; 645 + case PCIXCC_RESPONSE_TYPE_XCRB: 646 + length = t86r->fmt2.offset2 + t86r->fmt2.count2; 647 + length = min(MSGTYPE06_MAX_MSG_SIZE, length); 648 + memcpy(msg->message, reply->message, length); 649 + break; 650 + default: 651 + memcpy(msg->message, &error_reply, 652 + sizeof(error_reply)); 653 + } 654 + } else 655 + memcpy(msg->message, reply->message, sizeof(error_reply)); 656 + out: 657 + complete(&(resp_type->work)); 658 + } 659 + 660 + static atomic_t zcrypt_step = ATOMIC_INIT(0); 661 + 662 + /** 663 + * The request distributor calls this function if it picked the PCIXCC/CEX2C 664 + * device to handle a modexpo request. 665 + * @zdev: pointer to zcrypt_device structure that identifies the 666 + * PCIXCC/CEX2C device to the request distributor 667 + * @mex: pointer to the modexpo request buffer 668 + */ 669 + static long zcrypt_msgtype6_modexpo(struct zcrypt_device *zdev, 670 + struct ica_rsa_modexpo *mex) 671 + { 672 + struct ap_message ap_msg; 673 + struct response_type resp_type = { 674 + .type = PCIXCC_RESPONSE_TYPE_ICA, 675 + }; 676 + int rc; 677 + 678 + ap_init_message(&ap_msg); 679 + ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); 680 + if (!ap_msg.message) 681 + return -ENOMEM; 682 + ap_msg.receive = zcrypt_msgtype6_receive; 683 + ap_msg.psmid = (((unsigned long long) current->pid) << 32) + 684 + atomic_inc_return(&zcrypt_step); 685 + ap_msg.private = &resp_type; 686 + rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex); 687 + if (rc) 688 + goto out_free; 689 + init_completion(&resp_type.work); 690 + ap_queue_message(zdev->ap_dev, &ap_msg); 691 + rc = wait_for_completion_interruptible(&resp_type.work); 692 + if (rc == 0) 693 + rc = convert_response_ica(zdev, &ap_msg, mex->outputdata, 694 + mex->outputdatalength); 695 + else 696 + /* Signal pending. */ 697 + ap_cancel_message(zdev->ap_dev, &ap_msg); 698 + out_free: 699 + free_page((unsigned long) ap_msg.message); 700 + return rc; 701 + } 702 + 703 + /** 704 + * The request distributor calls this function if it picked the PCIXCC/CEX2C 705 + * device to handle a modexpo_crt request. 706 + * @zdev: pointer to zcrypt_device structure that identifies the 707 + * PCIXCC/CEX2C device to the request distributor 708 + * @crt: pointer to the modexpoc_crt request buffer 709 + */ 710 + static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_device *zdev, 711 + struct ica_rsa_modexpo_crt *crt) 712 + { 713 + struct ap_message ap_msg; 714 + struct response_type resp_type = { 715 + .type = PCIXCC_RESPONSE_TYPE_ICA, 716 + }; 717 + int rc; 718 + 719 + ap_init_message(&ap_msg); 720 + ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); 721 + if (!ap_msg.message) 722 + return -ENOMEM; 723 + ap_msg.receive = zcrypt_msgtype6_receive; 724 + ap_msg.psmid = (((unsigned long long) current->pid) << 32) + 725 + atomic_inc_return(&zcrypt_step); 726 + ap_msg.private = &resp_type; 727 + rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt); 728 + if (rc) 729 + goto out_free; 730 + init_completion(&resp_type.work); 731 + ap_queue_message(zdev->ap_dev, &ap_msg); 732 + rc = wait_for_completion_interruptible(&resp_type.work); 733 + if (rc == 0) 734 + rc = convert_response_ica(zdev, &ap_msg, crt->outputdata, 735 + crt->outputdatalength); 736 + else 737 + /* Signal pending. */ 738 + ap_cancel_message(zdev->ap_dev, &ap_msg); 739 + out_free: 740 + free_page((unsigned long) ap_msg.message); 741 + return rc; 742 + } 743 + 744 + /** 745 + * The request distributor calls this function if it picked the PCIXCC/CEX2C 746 + * device to handle a send_cprb request. 747 + * @zdev: pointer to zcrypt_device structure that identifies the 748 + * PCIXCC/CEX2C device to the request distributor 749 + * @xcRB: pointer to the send_cprb request buffer 750 + */ 751 + static long zcrypt_msgtype6_send_cprb(struct zcrypt_device *zdev, 752 + struct ica_xcRB *xcRB) 753 + { 754 + struct ap_message ap_msg; 755 + struct response_type resp_type = { 756 + .type = PCIXCC_RESPONSE_TYPE_XCRB, 757 + }; 758 + int rc; 759 + 760 + ap_init_message(&ap_msg); 761 + ap_msg.message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL); 762 + if (!ap_msg.message) 763 + return -ENOMEM; 764 + ap_msg.receive = zcrypt_msgtype6_receive; 765 + ap_msg.psmid = (((unsigned long long) current->pid) << 32) + 766 + atomic_inc_return(&zcrypt_step); 767 + ap_msg.private = &resp_type; 768 + rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB); 769 + if (rc) 770 + goto out_free; 771 + init_completion(&resp_type.work); 772 + ap_queue_message(zdev->ap_dev, &ap_msg); 773 + rc = wait_for_completion_interruptible(&resp_type.work); 774 + if (rc == 0) 775 + rc = convert_response_xcrb(zdev, &ap_msg, xcRB); 776 + else 777 + /* Signal pending. */ 778 + ap_cancel_message(zdev->ap_dev, &ap_msg); 779 + out_free: 780 + kzfree(ap_msg.message); 781 + return rc; 782 + } 783 + 784 + /** 785 + * The request distributor calls this function if it picked the PCIXCC/CEX2C 786 + * device to generate random data. 787 + * @zdev: pointer to zcrypt_device structure that identifies the 788 + * PCIXCC/CEX2C device to the request distributor 789 + * @buffer: pointer to a memory page to return random data 790 + */ 791 + 792 + static long zcrypt_msgtype6_rng(struct zcrypt_device *zdev, 793 + char *buffer) 794 + { 795 + struct ap_message ap_msg; 796 + struct response_type resp_type = { 797 + .type = PCIXCC_RESPONSE_TYPE_XCRB, 798 + }; 799 + int rc; 800 + 801 + ap_init_message(&ap_msg); 802 + ap_msg.message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL); 803 + if (!ap_msg.message) 804 + return -ENOMEM; 805 + ap_msg.receive = zcrypt_msgtype6_receive; 806 + ap_msg.psmid = (((unsigned long long) current->pid) << 32) + 807 + atomic_inc_return(&zcrypt_step); 808 + ap_msg.private = &resp_type; 809 + rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE); 810 + init_completion(&resp_type.work); 811 + ap_queue_message(zdev->ap_dev, &ap_msg); 812 + rc = wait_for_completion_interruptible(&resp_type.work); 813 + if (rc == 0) 814 + rc = convert_response_rng(zdev, &ap_msg, buffer); 815 + else 816 + /* Signal pending. */ 817 + ap_cancel_message(zdev->ap_dev, &ap_msg); 818 + kfree(ap_msg.message); 819 + return rc; 820 + } 821 + 822 + /** 823 + * The crypto operations for a PCIXCC/CEX2C card. 824 + */ 825 + static struct zcrypt_ops zcrypt_msgtype6_norng_ops = { 826 + .owner = THIS_MODULE, 827 + .variant = MSGTYPE06_VARIANT_NORNG, 828 + .rsa_modexpo = zcrypt_msgtype6_modexpo, 829 + .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt, 830 + .send_cprb = zcrypt_msgtype6_send_cprb, 831 + }; 832 + 833 + static struct zcrypt_ops zcrypt_msgtype6_ops = { 834 + .owner = THIS_MODULE, 835 + .variant = MSGTYPE06_VARIANT_DEFAULT, 836 + .rsa_modexpo = zcrypt_msgtype6_modexpo, 837 + .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt, 838 + .send_cprb = zcrypt_msgtype6_send_cprb, 839 + .rng = zcrypt_msgtype6_rng, 840 + }; 841 + 842 + int __init zcrypt_msgtype6_init(void) 843 + { 844 + zcrypt_msgtype_register(&zcrypt_msgtype6_norng_ops); 845 + zcrypt_msgtype_register(&zcrypt_msgtype6_ops); 846 + return 0; 847 + } 848 + 849 + void __exit zcrypt_msgtype6_exit(void) 850 + { 851 + zcrypt_msgtype_unregister(&zcrypt_msgtype6_norng_ops); 852 + zcrypt_msgtype_unregister(&zcrypt_msgtype6_ops); 853 + } 854 + 855 + module_init(zcrypt_msgtype6_init); 856 + module_exit(zcrypt_msgtype6_exit);
+169
drivers/s390/crypto/zcrypt_msgtype6.h
··· 1 + /* 2 + * zcrypt 2.1.0 3 + * 4 + * Copyright IBM Corp. 2001, 2012 5 + * Author(s): Robert Burroughs 6 + * Eric Rossman (edrossma@us.ibm.com) 7 + * 8 + * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) 9 + * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com> 10 + * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> 11 + * 12 + * This program is free software; you can redistribute it and/or modify 13 + * it under the terms of the GNU General Public License as published by 14 + * the Free Software Foundation; either version 2, or (at your option) 15 + * any later version. 16 + * 17 + * This program is distributed in the hope that it will be useful, 18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 + * GNU General Public License for more details. 21 + * 22 + * You should have received a copy of the GNU General Public License 23 + * along with this program; if not, write to the Free Software 24 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 + */ 26 + 27 + #ifndef _ZCRYPT_MSGTYPE6_H_ 28 + #define _ZCRYPT_MSGTYPE6_H_ 29 + 30 + #include <asm/zcrypt.h> 31 + 32 + #define MSGTYPE06_NAME "zcrypt_msgtype6" 33 + #define MSGTYPE06_VARIANT_DEFAULT 0 34 + #define MSGTYPE06_VARIANT_NORNG 1 35 + 36 + #define MSGTYPE06_MAX_MSG_SIZE (12*1024) 37 + 38 + /** 39 + * The type 6 message family is associated with PCICC or PCIXCC cards. 40 + * 41 + * It contains a message header followed by a CPRB, both of which 42 + * are described below. 43 + * 44 + * Note that all reserved fields must be zeroes. 45 + */ 46 + struct type6_hdr { 47 + unsigned char reserved1; /* 0x00 */ 48 + unsigned char type; /* 0x06 */ 49 + unsigned char reserved2[2]; /* 0x0000 */ 50 + unsigned char right[4]; /* 0x00000000 */ 51 + unsigned char reserved3[2]; /* 0x0000 */ 52 + unsigned char reserved4[2]; /* 0x0000 */ 53 + unsigned char apfs[4]; /* 0x00000000 */ 54 + unsigned int offset1; /* 0x00000058 (offset to CPRB) */ 55 + unsigned int offset2; /* 0x00000000 */ 56 + unsigned int offset3; /* 0x00000000 */ 57 + unsigned int offset4; /* 0x00000000 */ 58 + unsigned char agent_id[16]; /* PCICC: */ 59 + /* 0x0100 */ 60 + /* 0x4343412d4150504c202020 */ 61 + /* 0x010101 */ 62 + /* PCIXCC: */ 63 + /* 0x4341000000000000 */ 64 + /* 0x0000000000000000 */ 65 + unsigned char rqid[2]; /* rqid. internal to 603 */ 66 + unsigned char reserved5[2]; /* 0x0000 */ 67 + unsigned char function_code[2]; /* for PKD, 0x5044 (ascii 'PD') */ 68 + unsigned char reserved6[2]; /* 0x0000 */ 69 + unsigned int ToCardLen1; /* (request CPRB len + 3) & -4 */ 70 + unsigned int ToCardLen2; /* db len 0x00000000 for PKD */ 71 + unsigned int ToCardLen3; /* 0x00000000 */ 72 + unsigned int ToCardLen4; /* 0x00000000 */ 73 + unsigned int FromCardLen1; /* response buffer length */ 74 + unsigned int FromCardLen2; /* db len 0x00000000 for PKD */ 75 + unsigned int FromCardLen3; /* 0x00000000 */ 76 + unsigned int FromCardLen4; /* 0x00000000 */ 77 + } __packed; 78 + 79 + /** 80 + * The type 86 message family is associated with PCICC and PCIXCC cards. 81 + * 82 + * It contains a message header followed by a CPRB. The CPRB is 83 + * the same as the request CPRB, which is described above. 84 + * 85 + * If format is 1, an error condition exists and no data beyond 86 + * the 8-byte message header is of interest. 87 + * 88 + * The non-error message is shown below. 89 + * 90 + * Note that all reserved fields must be zeroes. 91 + */ 92 + struct type86_hdr { 93 + unsigned char reserved1; /* 0x00 */ 94 + unsigned char type; /* 0x86 */ 95 + unsigned char format; /* 0x01 (error) or 0x02 (ok) */ 96 + unsigned char reserved2; /* 0x00 */ 97 + unsigned char reply_code; /* reply code (see above) */ 98 + unsigned char reserved3[3]; /* 0x000000 */ 99 + } __packed; 100 + 101 + #define TYPE86_RSP_CODE 0x86 102 + #define TYPE86_FMT2 0x02 103 + 104 + struct type86_fmt2_ext { 105 + unsigned char reserved[4]; /* 0x00000000 */ 106 + unsigned char apfs[4]; /* final status */ 107 + unsigned int count1; /* length of CPRB + parameters */ 108 + unsigned int offset1; /* offset to CPRB */ 109 + unsigned int count2; /* 0x00000000 */ 110 + unsigned int offset2; /* db offset 0x00000000 for PKD */ 111 + unsigned int count3; /* 0x00000000 */ 112 + unsigned int offset3; /* 0x00000000 */ 113 + unsigned int count4; /* 0x00000000 */ 114 + unsigned int offset4; /* 0x00000000 */ 115 + } __packed; 116 + 117 + /** 118 + * Prepare a type6 CPRB message for random number generation 119 + * 120 + * @ap_dev: AP device pointer 121 + * @ap_msg: pointer to AP message 122 + */ 123 + static inline void rng_type6CPRB_msgX(struct ap_device *ap_dev, 124 + struct ap_message *ap_msg, 125 + unsigned random_number_length) 126 + { 127 + struct { 128 + struct type6_hdr hdr; 129 + struct CPRBX cprbx; 130 + char function_code[2]; 131 + short int rule_length; 132 + char rule[8]; 133 + short int verb_length; 134 + short int key_length; 135 + } __packed * msg = ap_msg->message; 136 + static struct type6_hdr static_type6_hdrX = { 137 + .type = 0x06, 138 + .offset1 = 0x00000058, 139 + .agent_id = {'C', 'A'}, 140 + .function_code = {'R', 'L'}, 141 + .ToCardLen1 = sizeof(*msg) - sizeof(msg->hdr), 142 + .FromCardLen1 = sizeof(*msg) - sizeof(msg->hdr), 143 + }; 144 + static struct CPRBX local_cprbx = { 145 + .cprb_len = 0x00dc, 146 + .cprb_ver_id = 0x02, 147 + .func_id = {0x54, 0x32}, 148 + .req_parml = sizeof(*msg) - sizeof(msg->hdr) - 149 + sizeof(msg->cprbx), 150 + .rpl_msgbl = sizeof(*msg) - sizeof(msg->hdr), 151 + }; 152 + 153 + msg->hdr = static_type6_hdrX; 154 + msg->hdr.FromCardLen2 = random_number_length, 155 + msg->cprbx = local_cprbx; 156 + msg->cprbx.rpl_datal = random_number_length, 157 + msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid); 158 + memcpy(msg->function_code, msg->hdr.function_code, 0x02); 159 + msg->rule_length = 0x0a; 160 + memcpy(msg->rule, "RANDOM ", 8); 161 + msg->verb_length = 0x02; 162 + msg->key_length = 0x02; 163 + ap_msg->length = sizeof(*msg); 164 + } 165 + 166 + int zcrypt_msgtype6_init(void); 167 + void zcrypt_msgtype6_exit(void); 168 + 169 + #endif /* _ZCRYPT_MSGTYPE6_H_ */
+13 -768
drivers/s390/crypto/zcrypt_pcixcc.c
··· 1 1 /* 2 2 * zcrypt 2.1.0 3 3 * 4 - * Copyright IBM Corp. 2001, 2006 4 + * Copyright IBM Corp. 2001, 2012 5 5 * Author(s): Robert Burroughs 6 6 * Eric Rossman (edrossma@us.ibm.com) 7 7 * 8 8 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) 9 9 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com> 10 10 * Ralph Wuerthner <rwuerthn@de.ibm.com> 11 + * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> 11 12 * 12 13 * This program is free software; you can redistribute it and/or modify 13 14 * it under the terms of the GNU General Public License as published by ··· 36 35 #include "ap_bus.h" 37 36 #include "zcrypt_api.h" 38 37 #include "zcrypt_error.h" 39 - #include "zcrypt_pcicc.h" 38 + #include "zcrypt_msgtype6.h" 40 39 #include "zcrypt_pcixcc.h" 41 40 #include "zcrypt_cca_key.h" 41 + #include "zcrypt_msgtype6.h" 42 42 43 43 #define PCIXCC_MIN_MOD_SIZE 16 /* 128 bits */ 44 44 #define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */ ··· 77 75 78 76 MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids); 79 77 MODULE_AUTHOR("IBM Corporation"); 80 - MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, " 81 - "Copyright IBM Corp. 2001, 2006"); 78 + MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, " \ 79 + "Copyright IBM Corp. 2001, 2012"); 82 80 MODULE_LICENSE("GPL"); 83 81 84 82 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev); 85 83 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev); 86 - static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *, 87 - struct ap_message *); 88 84 89 85 static struct ap_driver zcrypt_pcixcc_driver = { 90 86 .probe = zcrypt_pcixcc_probe, 91 87 .remove = zcrypt_pcixcc_remove, 92 88 .ids = zcrypt_pcixcc_ids, 93 89 .request_timeout = PCIXCC_CLEANUP_TIME, 94 - }; 95 - 96 - /** 97 - * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C 98 - * card in a type6 message. The 3 fields that must be filled in at execution 99 - * time are req_parml, rpl_parml and usage_domain. 100 - * Everything about this interface is ascii/big-endian, since the 101 - * device does *not* have 'Intel inside'. 102 - * 103 - * The CPRBX is followed immediately by the parm block. 104 - * The parm block contains: 105 - * - function code ('PD' 0x5044 or 'PK' 0x504B) 106 - * - rule block (one of:) 107 - * + 0x000A 'PKCS-1.2' (MCL2 'PD') 108 - * + 0x000A 'ZERO-PAD' (MCL2 'PK') 109 - * + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD') 110 - * + 0x000A 'MRP ' (MCL3 'PK' or CEX2C 'PK') 111 - * - VUD block 112 - */ 113 - static struct CPRBX static_cprbx = { 114 - .cprb_len = 0x00DC, 115 - .cprb_ver_id = 0x02, 116 - .func_id = {0x54,0x32}, 117 - }; 118 - 119 - /** 120 - * Convert a ICAMEX message to a type6 MEX message. 121 - * 122 - * @zdev: crypto device pointer 123 - * @ap_msg: pointer to AP message 124 - * @mex: pointer to user input data 125 - * 126 - * Returns 0 on success or -EFAULT. 127 - */ 128 - static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev, 129 - struct ap_message *ap_msg, 130 - struct ica_rsa_modexpo *mex) 131 - { 132 - static struct type6_hdr static_type6_hdrX = { 133 - .type = 0x06, 134 - .offset1 = 0x00000058, 135 - .agent_id = {'C','A',}, 136 - .function_code = {'P','K'}, 137 - }; 138 - static struct function_and_rules_block static_pke_fnr = { 139 - .function_code = {'P','K'}, 140 - .ulen = 10, 141 - .only_rule = {'M','R','P',' ',' ',' ',' ',' '} 142 - }; 143 - static struct function_and_rules_block static_pke_fnr_MCL2 = { 144 - .function_code = {'P','K'}, 145 - .ulen = 10, 146 - .only_rule = {'Z','E','R','O','-','P','A','D'} 147 - }; 148 - struct { 149 - struct type6_hdr hdr; 150 - struct CPRBX cprbx; 151 - struct function_and_rules_block fr; 152 - unsigned short length; 153 - char text[0]; 154 - } __attribute__((packed)) *msg = ap_msg->message; 155 - int size; 156 - 157 - /* VUD.ciphertext */ 158 - msg->length = mex->inputdatalength + 2; 159 - if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength)) 160 - return -EFAULT; 161 - 162 - /* Set up key which is located after the variable length text. */ 163 - size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1); 164 - if (size < 0) 165 - return size; 166 - size += sizeof(*msg) + mex->inputdatalength; 167 - 168 - /* message header, cprbx and f&r */ 169 - msg->hdr = static_type6_hdrX; 170 - msg->hdr.ToCardLen1 = size - sizeof(msg->hdr); 171 - msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr); 172 - 173 - msg->cprbx = static_cprbx; 174 - msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid); 175 - msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1; 176 - 177 - msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ? 178 - static_pke_fnr_MCL2 : static_pke_fnr; 179 - 180 - msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx); 181 - 182 - ap_msg->length = size; 183 - return 0; 184 - } 185 - 186 - /** 187 - * Convert a ICACRT message to a type6 CRT message. 188 - * 189 - * @zdev: crypto device pointer 190 - * @ap_msg: pointer to AP message 191 - * @crt: pointer to user input data 192 - * 193 - * Returns 0 on success or -EFAULT. 194 - */ 195 - static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev, 196 - struct ap_message *ap_msg, 197 - struct ica_rsa_modexpo_crt *crt) 198 - { 199 - static struct type6_hdr static_type6_hdrX = { 200 - .type = 0x06, 201 - .offset1 = 0x00000058, 202 - .agent_id = {'C','A',}, 203 - .function_code = {'P','D'}, 204 - }; 205 - static struct function_and_rules_block static_pkd_fnr = { 206 - .function_code = {'P','D'}, 207 - .ulen = 10, 208 - .only_rule = {'Z','E','R','O','-','P','A','D'} 209 - }; 210 - 211 - static struct function_and_rules_block static_pkd_fnr_MCL2 = { 212 - .function_code = {'P','D'}, 213 - .ulen = 10, 214 - .only_rule = {'P','K','C','S','-','1','.','2'} 215 - }; 216 - struct { 217 - struct type6_hdr hdr; 218 - struct CPRBX cprbx; 219 - struct function_and_rules_block fr; 220 - unsigned short length; 221 - char text[0]; 222 - } __attribute__((packed)) *msg = ap_msg->message; 223 - int size; 224 - 225 - /* VUD.ciphertext */ 226 - msg->length = crt->inputdatalength + 2; 227 - if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength)) 228 - return -EFAULT; 229 - 230 - /* Set up key which is located after the variable length text. */ 231 - size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1); 232 - if (size < 0) 233 - return size; 234 - size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */ 235 - 236 - /* message header, cprbx and f&r */ 237 - msg->hdr = static_type6_hdrX; 238 - msg->hdr.ToCardLen1 = size - sizeof(msg->hdr); 239 - msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr); 240 - 241 - msg->cprbx = static_cprbx; 242 - msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid); 243 - msg->cprbx.req_parml = msg->cprbx.rpl_msgbl = 244 - size - sizeof(msg->hdr) - sizeof(msg->cprbx); 245 - 246 - msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ? 247 - static_pkd_fnr_MCL2 : static_pkd_fnr; 248 - 249 - ap_msg->length = size; 250 - return 0; 251 - } 252 - 253 - /** 254 - * Convert a XCRB message to a type6 CPRB message. 255 - * 256 - * @zdev: crypto device pointer 257 - * @ap_msg: pointer to AP message 258 - * @xcRB: pointer to user input data 259 - * 260 - * Returns 0 on success or -EFAULT, -EINVAL. 261 - */ 262 - struct type86_fmt2_msg { 263 - struct type86_hdr hdr; 264 - struct type86_fmt2_ext fmt2; 265 - } __attribute__((packed)); 266 - 267 - static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, 268 - struct ap_message *ap_msg, 269 - struct ica_xcRB *xcRB) 270 - { 271 - static struct type6_hdr static_type6_hdrX = { 272 - .type = 0x06, 273 - .offset1 = 0x00000058, 274 - }; 275 - struct { 276 - struct type6_hdr hdr; 277 - struct CPRBX cprbx; 278 - } __attribute__((packed)) *msg = ap_msg->message; 279 - 280 - int rcblen = CEIL4(xcRB->request_control_blk_length); 281 - int replylen; 282 - char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen; 283 - char *function_code; 284 - 285 - /* length checks */ 286 - ap_msg->length = sizeof(struct type6_hdr) + 287 - CEIL4(xcRB->request_control_blk_length) + 288 - xcRB->request_data_length; 289 - if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE) 290 - return -EINVAL; 291 - replylen = sizeof(struct type86_fmt2_msg) + 292 - CEIL4(xcRB->reply_control_blk_length) + 293 - xcRB->reply_data_length; 294 - if (replylen > PCIXCC_MAX_XCRB_MESSAGE_SIZE) 295 - return -EINVAL; 296 - 297 - /* prepare type6 header */ 298 - msg->hdr = static_type6_hdrX; 299 - memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID)); 300 - msg->hdr.ToCardLen1 = xcRB->request_control_blk_length; 301 - if (xcRB->request_data_length) { 302 - msg->hdr.offset2 = msg->hdr.offset1 + rcblen; 303 - msg->hdr.ToCardLen2 = xcRB->request_data_length; 304 - } 305 - msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length; 306 - msg->hdr.FromCardLen2 = xcRB->reply_data_length; 307 - 308 - /* prepare CPRB */ 309 - if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr, 310 - xcRB->request_control_blk_length)) 311 - return -EFAULT; 312 - if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) > 313 - xcRB->request_control_blk_length) 314 - return -EINVAL; 315 - function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len; 316 - memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code)); 317 - 318 - if (memcmp(function_code, "US", 2) == 0) 319 - ap_msg->special = 1; 320 - else 321 - ap_msg->special = 0; 322 - 323 - /* copy data block */ 324 - if (xcRB->request_data_length && 325 - copy_from_user(req_data, xcRB->request_data_address, 326 - xcRB->request_data_length)) 327 - return -EFAULT; 328 - return 0; 329 - } 330 - 331 - /** 332 - * Prepare a type6 CPRB message for random number generation 333 - * 334 - * @ap_dev: AP device pointer 335 - * @ap_msg: pointer to AP message 336 - */ 337 - static void rng_type6CPRB_msgX(struct ap_device *ap_dev, 338 - struct ap_message *ap_msg, 339 - unsigned random_number_length) 340 - { 341 - struct { 342 - struct type6_hdr hdr; 343 - struct CPRBX cprbx; 344 - char function_code[2]; 345 - short int rule_length; 346 - char rule[8]; 347 - short int verb_length; 348 - short int key_length; 349 - } __attribute__((packed)) *msg = ap_msg->message; 350 - static struct type6_hdr static_type6_hdrX = { 351 - .type = 0x06, 352 - .offset1 = 0x00000058, 353 - .agent_id = {'C', 'A'}, 354 - .function_code = {'R', 'L'}, 355 - .ToCardLen1 = sizeof *msg - sizeof(msg->hdr), 356 - .FromCardLen1 = sizeof *msg - sizeof(msg->hdr), 357 - }; 358 - static struct CPRBX local_cprbx = { 359 - .cprb_len = 0x00dc, 360 - .cprb_ver_id = 0x02, 361 - .func_id = {0x54, 0x32}, 362 - .req_parml = sizeof *msg - sizeof(msg->hdr) - 363 - sizeof(msg->cprbx), 364 - .rpl_msgbl = sizeof *msg - sizeof(msg->hdr), 365 - }; 366 - 367 - msg->hdr = static_type6_hdrX; 368 - msg->hdr.FromCardLen2 = random_number_length, 369 - msg->cprbx = local_cprbx; 370 - msg->cprbx.rpl_datal = random_number_length, 371 - msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid); 372 - memcpy(msg->function_code, msg->hdr.function_code, 0x02); 373 - msg->rule_length = 0x0a; 374 - memcpy(msg->rule, "RANDOM ", 8); 375 - msg->verb_length = 0x02; 376 - msg->key_length = 0x02; 377 - ap_msg->length = sizeof *msg; 378 - } 379 - 380 - /** 381 - * Copy results from a type 86 ICA reply message back to user space. 382 - * 383 - * @zdev: crypto device pointer 384 - * @reply: reply AP message. 385 - * @data: pointer to user output data 386 - * @length: size of user output data 387 - * 388 - * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error. 389 - */ 390 - struct type86x_reply { 391 - struct type86_hdr hdr; 392 - struct type86_fmt2_ext fmt2; 393 - struct CPRBX cprbx; 394 - unsigned char pad[4]; /* 4 byte function code/rules block ? */ 395 - unsigned short length; 396 - char text[0]; 397 - } __attribute__((packed)); 398 - 399 - static int convert_type86_ica(struct zcrypt_device *zdev, 400 - struct ap_message *reply, 401 - char __user *outputdata, 402 - unsigned int outputdatalength) 403 - { 404 - static unsigned char static_pad[] = { 405 - 0x00,0x02, 406 - 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD, 407 - 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57, 408 - 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B, 409 - 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39, 410 - 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5, 411 - 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D, 412 - 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB, 413 - 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F, 414 - 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9, 415 - 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45, 416 - 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9, 417 - 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F, 418 - 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD, 419 - 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D, 420 - 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD, 421 - 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9, 422 - 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B, 423 - 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B, 424 - 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B, 425 - 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD, 426 - 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7, 427 - 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1, 428 - 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3, 429 - 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23, 430 - 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55, 431 - 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43, 432 - 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F, 433 - 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F, 434 - 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5, 435 - 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD, 436 - 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41, 437 - 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09 438 - }; 439 - struct type86x_reply *msg = reply->message; 440 - unsigned short service_rc, service_rs; 441 - unsigned int reply_len, pad_len; 442 - char *data; 443 - 444 - service_rc = msg->cprbx.ccp_rtcode; 445 - if (unlikely(service_rc != 0)) { 446 - service_rs = msg->cprbx.ccp_rscode; 447 - if (service_rc == 8 && service_rs == 66) 448 - return -EINVAL; 449 - if (service_rc == 8 && service_rs == 65) 450 - return -EINVAL; 451 - if (service_rc == 8 && service_rs == 770) 452 - return -EINVAL; 453 - if (service_rc == 8 && service_rs == 783) { 454 - zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD; 455 - return -EAGAIN; 456 - } 457 - if (service_rc == 12 && service_rs == 769) 458 - return -EINVAL; 459 - if (service_rc == 8 && service_rs == 72) 460 - return -EINVAL; 461 - zdev->online = 0; 462 - return -EAGAIN; /* repeat the request on a different device. */ 463 - } 464 - data = msg->text; 465 - reply_len = msg->length - 2; 466 - if (reply_len > outputdatalength) 467 - return -EINVAL; 468 - /* 469 - * For all encipher requests, the length of the ciphertext (reply_len) 470 - * will always equal the modulus length. For MEX decipher requests 471 - * the output needs to get padded. Minimum pad size is 10. 472 - * 473 - * Currently, the cases where padding will be added is for: 474 - * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support 475 - * ZERO-PAD and CRT is only supported for PKD requests) 476 - * - PCICC, always 477 - */ 478 - pad_len = outputdatalength - reply_len; 479 - if (pad_len > 0) { 480 - if (pad_len < 10) 481 - return -EINVAL; 482 - /* 'restore' padding left in the PCICC/PCIXCC card. */ 483 - if (copy_to_user(outputdata, static_pad, pad_len - 1)) 484 - return -EFAULT; 485 - if (put_user(0, outputdata + pad_len - 1)) 486 - return -EFAULT; 487 - } 488 - /* Copy the crypto response to user space. */ 489 - if (copy_to_user(outputdata + pad_len, data, reply_len)) 490 - return -EFAULT; 491 - return 0; 492 - } 493 - 494 - /** 495 - * Copy results from a type 86 XCRB reply message back to user space. 496 - * 497 - * @zdev: crypto device pointer 498 - * @reply: reply AP message. 499 - * @xcRB: pointer to XCRB 500 - * 501 - * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error. 502 - */ 503 - static int convert_type86_xcrb(struct zcrypt_device *zdev, 504 - struct ap_message *reply, 505 - struct ica_xcRB *xcRB) 506 - { 507 - struct type86_fmt2_msg *msg = reply->message; 508 - char *data = reply->message; 509 - 510 - /* Copy CPRB to user */ 511 - if (copy_to_user(xcRB->reply_control_blk_addr, 512 - data + msg->fmt2.offset1, msg->fmt2.count1)) 513 - return -EFAULT; 514 - xcRB->reply_control_blk_length = msg->fmt2.count1; 515 - 516 - /* Copy data buffer to user */ 517 - if (msg->fmt2.count2) 518 - if (copy_to_user(xcRB->reply_data_addr, 519 - data + msg->fmt2.offset2, msg->fmt2.count2)) 520 - return -EFAULT; 521 - xcRB->reply_data_length = msg->fmt2.count2; 522 - return 0; 523 - } 524 - 525 - static int convert_type86_rng(struct zcrypt_device *zdev, 526 - struct ap_message *reply, 527 - char *buffer) 528 - { 529 - struct { 530 - struct type86_hdr hdr; 531 - struct type86_fmt2_ext fmt2; 532 - struct CPRBX cprbx; 533 - } __attribute__((packed)) *msg = reply->message; 534 - char *data = reply->message; 535 - 536 - if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0) 537 - return -EINVAL; 538 - memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2); 539 - return msg->fmt2.count2; 540 - } 541 - 542 - static int convert_response_ica(struct zcrypt_device *zdev, 543 - struct ap_message *reply, 544 - char __user *outputdata, 545 - unsigned int outputdatalength) 546 - { 547 - struct type86x_reply *msg = reply->message; 548 - 549 - /* Response type byte is the second byte in the response. */ 550 - switch (((unsigned char *) reply->message)[1]) { 551 - case TYPE82_RSP_CODE: 552 - case TYPE88_RSP_CODE: 553 - return convert_error(zdev, reply); 554 - case TYPE86_RSP_CODE: 555 - if (msg->cprbx.ccp_rtcode && 556 - (msg->cprbx.ccp_rscode == 0x14f) && 557 - (outputdatalength > 256)) { 558 - if (zdev->max_exp_bit_length <= 17) { 559 - zdev->max_exp_bit_length = 17; 560 - return -EAGAIN; 561 - } else 562 - return -EINVAL; 563 - } 564 - if (msg->hdr.reply_code) 565 - return convert_error(zdev, reply); 566 - if (msg->cprbx.cprb_ver_id == 0x02) 567 - return convert_type86_ica(zdev, reply, 568 - outputdata, outputdatalength); 569 - /* Fall through, no break, incorrect cprb version is an unknown 570 - * response */ 571 - default: /* Unknown response type, this should NEVER EVER happen */ 572 - zdev->online = 0; 573 - return -EAGAIN; /* repeat the request on a different device. */ 574 - } 575 - } 576 - 577 - static int convert_response_xcrb(struct zcrypt_device *zdev, 578 - struct ap_message *reply, 579 - struct ica_xcRB *xcRB) 580 - { 581 - struct type86x_reply *msg = reply->message; 582 - 583 - /* Response type byte is the second byte in the response. */ 584 - switch (((unsigned char *) reply->message)[1]) { 585 - case TYPE82_RSP_CODE: 586 - case TYPE88_RSP_CODE: 587 - xcRB->status = 0x0008044DL; /* HDD_InvalidParm */ 588 - return convert_error(zdev, reply); 589 - case TYPE86_RSP_CODE: 590 - if (msg->hdr.reply_code) { 591 - memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32)); 592 - return convert_error(zdev, reply); 593 - } 594 - if (msg->cprbx.cprb_ver_id == 0x02) 595 - return convert_type86_xcrb(zdev, reply, xcRB); 596 - /* Fall through, no break, incorrect cprb version is an unknown 597 - * response */ 598 - default: /* Unknown response type, this should NEVER EVER happen */ 599 - xcRB->status = 0x0008044DL; /* HDD_InvalidParm */ 600 - zdev->online = 0; 601 - return -EAGAIN; /* repeat the request on a different device. */ 602 - } 603 - } 604 - 605 - static int convert_response_rng(struct zcrypt_device *zdev, 606 - struct ap_message *reply, 607 - char *data) 608 - { 609 - struct type86x_reply *msg = reply->message; 610 - 611 - switch (msg->hdr.type) { 612 - case TYPE82_RSP_CODE: 613 - case TYPE88_RSP_CODE: 614 - return -EINVAL; 615 - case TYPE86_RSP_CODE: 616 - if (msg->hdr.reply_code) 617 - return -EINVAL; 618 - if (msg->cprbx.cprb_ver_id == 0x02) 619 - return convert_type86_rng(zdev, reply, data); 620 - /* Fall through, no break, incorrect cprb version is an unknown 621 - * response */ 622 - default: /* Unknown response type, this should NEVER EVER happen */ 623 - zdev->online = 0; 624 - return -EAGAIN; /* repeat the request on a different device. */ 625 - } 626 - } 627 - 628 - /** 629 - * This function is called from the AP bus code after a crypto request 630 - * "msg" has finished with the reply message "reply". 631 - * It is called from tasklet context. 632 - * @ap_dev: pointer to the AP device 633 - * @msg: pointer to the AP message 634 - * @reply: pointer to the AP reply message 635 - */ 636 - static void zcrypt_pcixcc_receive(struct ap_device *ap_dev, 637 - struct ap_message *msg, 638 - struct ap_message *reply) 639 - { 640 - static struct error_hdr error_reply = { 641 - .type = TYPE82_RSP_CODE, 642 - .reply_code = REP82_ERROR_MACHINE_FAILURE, 643 - }; 644 - struct response_type *resp_type = 645 - (struct response_type *) msg->private; 646 - struct type86x_reply *t86r; 647 - int length; 648 - 649 - /* Copy the reply message to the request message buffer. */ 650 - if (IS_ERR(reply)) { 651 - memcpy(msg->message, &error_reply, sizeof(error_reply)); 652 - goto out; 653 - } 654 - t86r = reply->message; 655 - if (t86r->hdr.type == TYPE86_RSP_CODE && 656 - t86r->cprbx.cprb_ver_id == 0x02) { 657 - switch (resp_type->type) { 658 - case PCIXCC_RESPONSE_TYPE_ICA: 659 - length = sizeof(struct type86x_reply) 660 - + t86r->length - 2; 661 - length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length); 662 - memcpy(msg->message, reply->message, length); 663 - break; 664 - case PCIXCC_RESPONSE_TYPE_XCRB: 665 - length = t86r->fmt2.offset2 + t86r->fmt2.count2; 666 - length = min(PCIXCC_MAX_XCRB_MESSAGE_SIZE, length); 667 - memcpy(msg->message, reply->message, length); 668 - break; 669 - default: 670 - memcpy(msg->message, &error_reply, sizeof error_reply); 671 - } 672 - } else 673 - memcpy(msg->message, reply->message, sizeof error_reply); 674 - out: 675 - complete(&(resp_type->work)); 676 - } 677 - 678 - static atomic_t zcrypt_step = ATOMIC_INIT(0); 679 - 680 - /** 681 - * The request distributor calls this function if it picked the PCIXCC/CEX2C 682 - * device to handle a modexpo request. 683 - * @zdev: pointer to zcrypt_device structure that identifies the 684 - * PCIXCC/CEX2C device to the request distributor 685 - * @mex: pointer to the modexpo request buffer 686 - */ 687 - static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev, 688 - struct ica_rsa_modexpo *mex) 689 - { 690 - struct ap_message ap_msg; 691 - struct response_type resp_type = { 692 - .type = PCIXCC_RESPONSE_TYPE_ICA, 693 - }; 694 - int rc; 695 - 696 - ap_init_message(&ap_msg); 697 - ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); 698 - if (!ap_msg.message) 699 - return -ENOMEM; 700 - ap_msg.receive = zcrypt_pcixcc_receive; 701 - ap_msg.psmid = (((unsigned long long) current->pid) << 32) + 702 - atomic_inc_return(&zcrypt_step); 703 - ap_msg.private = &resp_type; 704 - rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex); 705 - if (rc) 706 - goto out_free; 707 - init_completion(&resp_type.work); 708 - ap_queue_message(zdev->ap_dev, &ap_msg); 709 - rc = wait_for_completion_interruptible(&resp_type.work); 710 - if (rc == 0) 711 - rc = convert_response_ica(zdev, &ap_msg, mex->outputdata, 712 - mex->outputdatalength); 713 - else 714 - /* Signal pending. */ 715 - ap_cancel_message(zdev->ap_dev, &ap_msg); 716 - out_free: 717 - free_page((unsigned long) ap_msg.message); 718 - return rc; 719 - } 720 - 721 - /** 722 - * The request distributor calls this function if it picked the PCIXCC/CEX2C 723 - * device to handle a modexpo_crt request. 724 - * @zdev: pointer to zcrypt_device structure that identifies the 725 - * PCIXCC/CEX2C device to the request distributor 726 - * @crt: pointer to the modexpoc_crt request buffer 727 - */ 728 - static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev, 729 - struct ica_rsa_modexpo_crt *crt) 730 - { 731 - struct ap_message ap_msg; 732 - struct response_type resp_type = { 733 - .type = PCIXCC_RESPONSE_TYPE_ICA, 734 - }; 735 - int rc; 736 - 737 - ap_init_message(&ap_msg); 738 - ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); 739 - if (!ap_msg.message) 740 - return -ENOMEM; 741 - ap_msg.receive = zcrypt_pcixcc_receive; 742 - ap_msg.psmid = (((unsigned long long) current->pid) << 32) + 743 - atomic_inc_return(&zcrypt_step); 744 - ap_msg.private = &resp_type; 745 - rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt); 746 - if (rc) 747 - goto out_free; 748 - init_completion(&resp_type.work); 749 - ap_queue_message(zdev->ap_dev, &ap_msg); 750 - rc = wait_for_completion_interruptible(&resp_type.work); 751 - if (rc == 0) 752 - rc = convert_response_ica(zdev, &ap_msg, crt->outputdata, 753 - crt->outputdatalength); 754 - else 755 - /* Signal pending. */ 756 - ap_cancel_message(zdev->ap_dev, &ap_msg); 757 - out_free: 758 - free_page((unsigned long) ap_msg.message); 759 - return rc; 760 - } 761 - 762 - /** 763 - * The request distributor calls this function if it picked the PCIXCC/CEX2C 764 - * device to handle a send_cprb request. 765 - * @zdev: pointer to zcrypt_device structure that identifies the 766 - * PCIXCC/CEX2C device to the request distributor 767 - * @xcRB: pointer to the send_cprb request buffer 768 - */ 769 - static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev, 770 - struct ica_xcRB *xcRB) 771 - { 772 - struct ap_message ap_msg; 773 - struct response_type resp_type = { 774 - .type = PCIXCC_RESPONSE_TYPE_XCRB, 775 - }; 776 - int rc; 777 - 778 - ap_init_message(&ap_msg); 779 - ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); 780 - if (!ap_msg.message) 781 - return -ENOMEM; 782 - ap_msg.receive = zcrypt_pcixcc_receive; 783 - ap_msg.psmid = (((unsigned long long) current->pid) << 32) + 784 - atomic_inc_return(&zcrypt_step); 785 - ap_msg.private = &resp_type; 786 - rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB); 787 - if (rc) 788 - goto out_free; 789 - init_completion(&resp_type.work); 790 - ap_queue_message(zdev->ap_dev, &ap_msg); 791 - rc = wait_for_completion_interruptible(&resp_type.work); 792 - if (rc == 0) 793 - rc = convert_response_xcrb(zdev, &ap_msg, xcRB); 794 - else 795 - /* Signal pending. */ 796 - ap_cancel_message(zdev->ap_dev, &ap_msg); 797 - out_free: 798 - kzfree(ap_msg.message); 799 - return rc; 800 - } 801 - 802 - /** 803 - * The request distributor calls this function if it picked the PCIXCC/CEX2C 804 - * device to generate random data. 805 - * @zdev: pointer to zcrypt_device structure that identifies the 806 - * PCIXCC/CEX2C device to the request distributor 807 - * @buffer: pointer to a memory page to return random data 808 - */ 809 - 810 - static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev, 811 - char *buffer) 812 - { 813 - struct ap_message ap_msg; 814 - struct response_type resp_type = { 815 - .type = PCIXCC_RESPONSE_TYPE_XCRB, 816 - }; 817 - int rc; 818 - 819 - ap_init_message(&ap_msg); 820 - ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); 821 - if (!ap_msg.message) 822 - return -ENOMEM; 823 - ap_msg.receive = zcrypt_pcixcc_receive; 824 - ap_msg.psmid = (((unsigned long long) current->pid) << 32) + 825 - atomic_inc_return(&zcrypt_step); 826 - ap_msg.private = &resp_type; 827 - rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE); 828 - init_completion(&resp_type.work); 829 - ap_queue_message(zdev->ap_dev, &ap_msg); 830 - rc = wait_for_completion_interruptible(&resp_type.work); 831 - if (rc == 0) 832 - rc = convert_response_rng(zdev, &ap_msg, buffer); 833 - else 834 - /* Signal pending. */ 835 - ap_cancel_message(zdev->ap_dev, &ap_msg); 836 - kfree(ap_msg.message); 837 - return rc; 838 - } 839 - 840 - /** 841 - * The crypto operations for a PCIXCC/CEX2C card. 842 - */ 843 - static struct zcrypt_ops zcrypt_pcixcc_ops = { 844 - .rsa_modexpo = zcrypt_pcixcc_modexpo, 845 - .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt, 846 - .send_cprb = zcrypt_pcixcc_send_cprb, 847 - }; 848 - 849 - static struct zcrypt_ops zcrypt_pcixcc_with_rng_ops = { 850 - .rsa_modexpo = zcrypt_pcixcc_modexpo, 851 - .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt, 852 - .send_cprb = zcrypt_pcixcc_send_cprb, 853 - .rng = zcrypt_pcixcc_rng, 854 90 }; 855 91 856 92 /** ··· 323 1083 return rc; 324 1084 } 325 1085 if (rc) 326 - zdev->ops = &zcrypt_pcixcc_with_rng_ops; 1086 + zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME, 1087 + MSGTYPE06_VARIANT_DEFAULT); 327 1088 else 328 - zdev->ops = &zcrypt_pcixcc_ops; 1089 + zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME, 1090 + MSGTYPE06_VARIANT_NORNG); 329 1091 ap_dev->reply = &zdev->reply; 330 1092 ap_dev->private = zdev; 331 1093 rc = zcrypt_device_register(zdev); ··· 337 1095 338 1096 out_free: 339 1097 ap_dev->private = NULL; 1098 + zcrypt_msgtype_release(zdev->ops); 340 1099 zcrypt_device_free(zdev); 341 1100 return rc; 342 1101 } ··· 349 1106 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev) 350 1107 { 351 1108 struct zcrypt_device *zdev = ap_dev->private; 1109 + struct zcrypt_ops *zops = zdev->ops; 352 1110 353 1111 zcrypt_device_unregister(zdev); 1112 + zcrypt_msgtype_release(zops); 354 1113 } 355 1114 356 1115 int __init zcrypt_pcixcc_init(void)
+2 -1
drivers/s390/crypto/zcrypt_pcixcc.h
··· 1 1 /* 2 2 * zcrypt 2.1.0 3 3 * 4 - * Copyright IBM Corp. 2001, 2006 4 + * Copyright IBM Corp. 2001, 2012 5 5 * Author(s): Robert Burroughs 6 6 * Eric Rossman (edrossma@us.ibm.com) 7 7 * 8 8 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) 9 9 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com> 10 + * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> 10 11 * 11 12 * This program is free software; you can redistribute it and/or modify 12 13 * it under the terms of the GNU General Public License as published by