]>
Commit | Line | Data |
---|---|---|
5e55a488 HD |
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 | ||
91f3e3ea IT |
28 | #define KMSG_COMPONENT "zcrypt" |
29 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | |
30 | ||
5e55a488 HD |
31 | #include <linux/module.h> |
32 | #include <linux/slab.h> | |
33 | #include <linux/init.h> | |
34 | #include <linux/err.h> | |
35 | #include <linux/atomic.h> | |
36 | #include <linux/uaccess.h> | |
37 | ||
38 | #include "ap_bus.h" | |
39 | #include "zcrypt_api.h" | |
40 | #include "zcrypt_error.h" | |
41 | #include "zcrypt_msgtype50.h" | |
42 | ||
43 | #define CEX3A_MAX_MOD_SIZE 512 /* 4096 bits */ | |
44 | ||
45 | #define CEX2A_MAX_RESPONSE_SIZE 0x110 /* max outputdatalength + type80_hdr */ | |
46 | ||
47 | #define CEX3A_MAX_RESPONSE_SIZE 0x210 /* 512 bit modulus | |
48 | * (max outputdatalength) + | |
49 | * type80_hdr*/ | |
50 | ||
51 | MODULE_AUTHOR("IBM Corporation"); | |
52 | MODULE_DESCRIPTION("Cryptographic Accelerator (message type 50), " \ | |
53 | "Copyright IBM Corp. 2001, 2012"); | |
54 | MODULE_LICENSE("GPL"); | |
55 | ||
56 | static void zcrypt_cex2a_receive(struct ap_device *, struct ap_message *, | |
57 | struct ap_message *); | |
58 | ||
59 | /** | |
60 | * The type 50 message family is associated with a CEX2A card. | |
61 | * | |
62 | * The four members of the family are described below. | |
63 | * | |
64 | * Note that all unsigned char arrays are right-justified and left-padded | |
65 | * with zeroes. | |
66 | * | |
67 | * Note that all reserved fields must be zeroes. | |
68 | */ | |
69 | struct type50_hdr { | |
70 | unsigned char reserved1; | |
71 | unsigned char msg_type_code; /* 0x50 */ | |
72 | unsigned short msg_len; | |
73 | unsigned char reserved2; | |
74 | unsigned char ignored; | |
75 | unsigned short reserved3; | |
76 | } __packed; | |
77 | ||
78 | #define TYPE50_TYPE_CODE 0x50 | |
79 | ||
80 | #define TYPE50_MEB1_FMT 0x0001 | |
81 | #define TYPE50_MEB2_FMT 0x0002 | |
82 | #define TYPE50_MEB3_FMT 0x0003 | |
83 | #define TYPE50_CRB1_FMT 0x0011 | |
84 | #define TYPE50_CRB2_FMT 0x0012 | |
85 | #define TYPE50_CRB3_FMT 0x0013 | |
86 | ||
87 | /* Mod-Exp, with a small modulus */ | |
88 | struct type50_meb1_msg { | |
89 | struct type50_hdr header; | |
90 | unsigned short keyblock_type; /* 0x0001 */ | |
91 | unsigned char reserved[6]; | |
92 | unsigned char exponent[128]; | |
93 | unsigned char modulus[128]; | |
94 | unsigned char message[128]; | |
95 | } __packed; | |
96 | ||
97 | /* Mod-Exp, with a large modulus */ | |
98 | struct type50_meb2_msg { | |
99 | struct type50_hdr header; | |
100 | unsigned short keyblock_type; /* 0x0002 */ | |
101 | unsigned char reserved[6]; | |
102 | unsigned char exponent[256]; | |
103 | unsigned char modulus[256]; | |
104 | unsigned char message[256]; | |
105 | } __packed; | |
106 | ||
107 | /* Mod-Exp, with a larger modulus */ | |
108 | struct type50_meb3_msg { | |
109 | struct type50_hdr header; | |
110 | unsigned short keyblock_type; /* 0x0003 */ | |
111 | unsigned char reserved[6]; | |
112 | unsigned char exponent[512]; | |
113 | unsigned char modulus[512]; | |
114 | unsigned char message[512]; | |
115 | } __packed; | |
116 | ||
117 | /* CRT, with a small modulus */ | |
118 | struct type50_crb1_msg { | |
119 | struct type50_hdr header; | |
120 | unsigned short keyblock_type; /* 0x0011 */ | |
121 | unsigned char reserved[6]; | |
122 | unsigned char p[64]; | |
123 | unsigned char q[64]; | |
124 | unsigned char dp[64]; | |
125 | unsigned char dq[64]; | |
126 | unsigned char u[64]; | |
127 | unsigned char message[128]; | |
128 | } __packed; | |
129 | ||
130 | /* CRT, with a large modulus */ | |
131 | struct type50_crb2_msg { | |
132 | struct type50_hdr header; | |
133 | unsigned short keyblock_type; /* 0x0012 */ | |
134 | unsigned char reserved[6]; | |
135 | unsigned char p[128]; | |
136 | unsigned char q[128]; | |
137 | unsigned char dp[128]; | |
138 | unsigned char dq[128]; | |
139 | unsigned char u[128]; | |
140 | unsigned char message[256]; | |
141 | } __packed; | |
142 | ||
143 | /* CRT, with a larger modulus */ | |
144 | struct type50_crb3_msg { | |
145 | struct type50_hdr header; | |
146 | unsigned short keyblock_type; /* 0x0013 */ | |
147 | unsigned char reserved[6]; | |
148 | unsigned char p[256]; | |
149 | unsigned char q[256]; | |
150 | unsigned char dp[256]; | |
151 | unsigned char dq[256]; | |
152 | unsigned char u[256]; | |
153 | unsigned char message[512]; | |
154 | } __packed; | |
155 | ||
156 | /** | |
157 | * The type 80 response family is associated with a CEX2A card. | |
158 | * | |
159 | * Note that all unsigned char arrays are right-justified and left-padded | |
160 | * with zeroes. | |
161 | * | |
162 | * Note that all reserved fields must be zeroes. | |
163 | */ | |
164 | ||
165 | #define TYPE80_RSP_CODE 0x80 | |
166 | ||
167 | struct type80_hdr { | |
168 | unsigned char reserved1; | |
169 | unsigned char type; /* 0x80 */ | |
170 | unsigned short len; | |
171 | unsigned char code; /* 0x00 */ | |
172 | unsigned char reserved2[3]; | |
173 | unsigned char reserved3[8]; | |
174 | } __packed; | |
175 | ||
176 | /** | |
177 | * Convert a ICAMEX message to a type50 MEX message. | |
178 | * | |
179 | * @zdev: crypto device pointer | |
180 | * @zreq: crypto request pointer | |
181 | * @mex: pointer to user input data | |
182 | * | |
183 | * Returns 0 on success or -EFAULT. | |
184 | */ | |
185 | static int ICAMEX_msg_to_type50MEX_msg(struct zcrypt_device *zdev, | |
186 | struct ap_message *ap_msg, | |
187 | struct ica_rsa_modexpo *mex) | |
188 | { | |
189 | unsigned char *mod, *exp, *inp; | |
190 | int mod_len; | |
191 | ||
192 | mod_len = mex->inputdatalength; | |
193 | ||
194 | if (mod_len <= 128) { | |
195 | struct type50_meb1_msg *meb1 = ap_msg->message; | |
196 | memset(meb1, 0, sizeof(*meb1)); | |
197 | ap_msg->length = sizeof(*meb1); | |
198 | meb1->header.msg_type_code = TYPE50_TYPE_CODE; | |
199 | meb1->header.msg_len = sizeof(*meb1); | |
200 | meb1->keyblock_type = TYPE50_MEB1_FMT; | |
201 | mod = meb1->modulus + sizeof(meb1->modulus) - mod_len; | |
202 | exp = meb1->exponent + sizeof(meb1->exponent) - mod_len; | |
203 | inp = meb1->message + sizeof(meb1->message) - mod_len; | |
204 | } else if (mod_len <= 256) { | |
205 | struct type50_meb2_msg *meb2 = ap_msg->message; | |
206 | memset(meb2, 0, sizeof(*meb2)); | |
207 | ap_msg->length = sizeof(*meb2); | |
208 | meb2->header.msg_type_code = TYPE50_TYPE_CODE; | |
209 | meb2->header.msg_len = sizeof(*meb2); | |
210 | meb2->keyblock_type = TYPE50_MEB2_FMT; | |
211 | mod = meb2->modulus + sizeof(meb2->modulus) - mod_len; | |
212 | exp = meb2->exponent + sizeof(meb2->exponent) - mod_len; | |
213 | inp = meb2->message + sizeof(meb2->message) - mod_len; | |
214 | } else { | |
215 | /* mod_len > 256 = 4096 bit RSA Key */ | |
216 | struct type50_meb3_msg *meb3 = ap_msg->message; | |
217 | memset(meb3, 0, sizeof(*meb3)); | |
218 | ap_msg->length = sizeof(*meb3); | |
219 | meb3->header.msg_type_code = TYPE50_TYPE_CODE; | |
220 | meb3->header.msg_len = sizeof(*meb3); | |
221 | meb3->keyblock_type = TYPE50_MEB3_FMT; | |
222 | mod = meb3->modulus + sizeof(meb3->modulus) - mod_len; | |
223 | exp = meb3->exponent + sizeof(meb3->exponent) - mod_len; | |
224 | inp = meb3->message + sizeof(meb3->message) - mod_len; | |
225 | } | |
226 | ||
227 | if (copy_from_user(mod, mex->n_modulus, mod_len) || | |
228 | copy_from_user(exp, mex->b_key, mod_len) || | |
229 | copy_from_user(inp, mex->inputdata, mod_len)) | |
230 | return -EFAULT; | |
231 | return 0; | |
232 | } | |
233 | ||
234 | /** | |
235 | * Convert a ICACRT message to a type50 CRT message. | |
236 | * | |
237 | * @zdev: crypto device pointer | |
238 | * @zreq: crypto request pointer | |
239 | * @crt: pointer to user input data | |
240 | * | |
241 | * Returns 0 on success or -EFAULT. | |
242 | */ | |
243 | static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_device *zdev, | |
244 | struct ap_message *ap_msg, | |
245 | struct ica_rsa_modexpo_crt *crt) | |
246 | { | |
1e466fcf | 247 | int mod_len, short_len; |
5e55a488 HD |
248 | unsigned char *p, *q, *dp, *dq, *u, *inp; |
249 | ||
250 | mod_len = crt->inputdatalength; | |
1330a125 | 251 | short_len = (mod_len + 1) / 2; |
5e55a488 HD |
252 | |
253 | /* | |
1e466fcf IT |
254 | * CEX2A and CEX3A w/o FW update can handle requests up to |
255 | * 256 byte modulus (2k keys). | |
256 | * CEX3A with FW update and CEX4A cards are able to handle | |
257 | * 512 byte modulus (4k keys). | |
5e55a488 | 258 | */ |
1e466fcf | 259 | if (mod_len <= 128) { /* up to 1024 bit key size */ |
5e55a488 HD |
260 | struct type50_crb1_msg *crb1 = ap_msg->message; |
261 | memset(crb1, 0, sizeof(*crb1)); | |
262 | ap_msg->length = sizeof(*crb1); | |
263 | crb1->header.msg_type_code = TYPE50_TYPE_CODE; | |
264 | crb1->header.msg_len = sizeof(*crb1); | |
265 | crb1->keyblock_type = TYPE50_CRB1_FMT; | |
1e466fcf | 266 | p = crb1->p + sizeof(crb1->p) - short_len; |
5e55a488 | 267 | q = crb1->q + sizeof(crb1->q) - short_len; |
1e466fcf | 268 | dp = crb1->dp + sizeof(crb1->dp) - short_len; |
5e55a488 | 269 | dq = crb1->dq + sizeof(crb1->dq) - short_len; |
1e466fcf | 270 | u = crb1->u + sizeof(crb1->u) - short_len; |
5e55a488 | 271 | inp = crb1->message + sizeof(crb1->message) - mod_len; |
1e466fcf | 272 | } else if (mod_len <= 256) { /* up to 2048 bit key size */ |
5e55a488 HD |
273 | struct type50_crb2_msg *crb2 = ap_msg->message; |
274 | memset(crb2, 0, sizeof(*crb2)); | |
275 | ap_msg->length = sizeof(*crb2); | |
276 | crb2->header.msg_type_code = TYPE50_TYPE_CODE; | |
277 | crb2->header.msg_len = sizeof(*crb2); | |
278 | crb2->keyblock_type = TYPE50_CRB2_FMT; | |
1e466fcf | 279 | p = crb2->p + sizeof(crb2->p) - short_len; |
5e55a488 | 280 | q = crb2->q + sizeof(crb2->q) - short_len; |
1e466fcf | 281 | dp = crb2->dp + sizeof(crb2->dp) - short_len; |
5e55a488 | 282 | dq = crb2->dq + sizeof(crb2->dq) - short_len; |
1e466fcf | 283 | u = crb2->u + sizeof(crb2->u) - short_len; |
5e55a488 | 284 | inp = crb2->message + sizeof(crb2->message) - mod_len; |
1e466fcf IT |
285 | } else if ((mod_len <= 512) && /* up to 4096 bit key size */ |
286 | (zdev->max_mod_size == CEX3A_MAX_MOD_SIZE)) { /* >= CEX3A */ | |
5e55a488 HD |
287 | struct type50_crb3_msg *crb3 = ap_msg->message; |
288 | memset(crb3, 0, sizeof(*crb3)); | |
289 | ap_msg->length = sizeof(*crb3); | |
290 | crb3->header.msg_type_code = TYPE50_TYPE_CODE; | |
291 | crb3->header.msg_len = sizeof(*crb3); | |
292 | crb3->keyblock_type = TYPE50_CRB3_FMT; | |
1e466fcf | 293 | p = crb3->p + sizeof(crb3->p) - short_len; |
5e55a488 | 294 | q = crb3->q + sizeof(crb3->q) - short_len; |
1e466fcf | 295 | dp = crb3->dp + sizeof(crb3->dp) - short_len; |
5e55a488 | 296 | dq = crb3->dq + sizeof(crb3->dq) - short_len; |
1e466fcf | 297 | u = crb3->u + sizeof(crb3->u) - short_len; |
5e55a488 | 298 | inp = crb3->message + sizeof(crb3->message) - mod_len; |
1e466fcf IT |
299 | } else |
300 | return -EINVAL; | |
5e55a488 | 301 | |
1e466fcf IT |
302 | /* |
303 | * correct the offset of p, bp and mult_inv according zcrypt.h | |
304 | * block size right aligned (skip the first byte) | |
305 | */ | |
306 | if (copy_from_user(p, crt->np_prime + MSGTYPE_ADJUSTMENT, short_len) || | |
5e55a488 | 307 | copy_from_user(q, crt->nq_prime, short_len) || |
1e466fcf | 308 | copy_from_user(dp, crt->bp_key + MSGTYPE_ADJUSTMENT, short_len) || |
5e55a488 | 309 | copy_from_user(dq, crt->bq_key, short_len) || |
1e466fcf | 310 | copy_from_user(u, crt->u_mult_inv + MSGTYPE_ADJUSTMENT, short_len) || |
5e55a488 HD |
311 | copy_from_user(inp, crt->inputdata, mod_len)) |
312 | return -EFAULT; | |
313 | ||
314 | return 0; | |
315 | } | |
316 | ||
317 | /** | |
318 | * Copy results from a type 80 reply message back to user space. | |
319 | * | |
320 | * @zdev: crypto device pointer | |
321 | * @reply: reply AP message. | |
322 | * @data: pointer to user output data | |
323 | * @length: size of user output data | |
324 | * | |
325 | * Returns 0 on success or -EFAULT. | |
326 | */ | |
327 | static int convert_type80(struct zcrypt_device *zdev, | |
328 | struct ap_message *reply, | |
329 | char __user *outputdata, | |
330 | unsigned int outputdatalength) | |
331 | { | |
332 | struct type80_hdr *t80h = reply->message; | |
333 | unsigned char *data; | |
334 | ||
335 | if (t80h->len < sizeof(*t80h) + outputdatalength) { | |
336 | /* The result is too short, the CEX2A card may not do that.. */ | |
337 | zdev->online = 0; | |
91f3e3ea | 338 | pr_err("Cryptographic device %x failed and was set offline\n", |
d8f51227 | 339 | AP_QID_DEVICE(zdev->ap_dev->qid)); |
91f3e3ea | 340 | ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%drc%d", |
d8f51227 IT |
341 | AP_QID_DEVICE(zdev->ap_dev->qid), |
342 | zdev->online, t80h->code); | |
91f3e3ea | 343 | |
5e55a488 HD |
344 | return -EAGAIN; /* repeat the request on a different device. */ |
345 | } | |
346 | if (zdev->user_space_type == ZCRYPT_CEX2A) | |
347 | BUG_ON(t80h->len > CEX2A_MAX_RESPONSE_SIZE); | |
348 | else | |
349 | BUG_ON(t80h->len > CEX3A_MAX_RESPONSE_SIZE); | |
350 | data = reply->message + t80h->len - outputdatalength; | |
351 | if (copy_to_user(outputdata, data, outputdatalength)) | |
352 | return -EFAULT; | |
353 | return 0; | |
354 | } | |
355 | ||
356 | static int convert_response(struct zcrypt_device *zdev, | |
357 | struct ap_message *reply, | |
358 | char __user *outputdata, | |
359 | unsigned int outputdatalength) | |
360 | { | |
361 | /* Response type byte is the second byte in the response. */ | |
362 | switch (((unsigned char *) reply->message)[1]) { | |
363 | case TYPE82_RSP_CODE: | |
364 | case TYPE88_RSP_CODE: | |
365 | return convert_error(zdev, reply); | |
366 | case TYPE80_RSP_CODE: | |
367 | return convert_type80(zdev, reply, | |
368 | outputdata, outputdatalength); | |
369 | default: /* Unknown response type, this should NEVER EVER happen */ | |
370 | zdev->online = 0; | |
91f3e3ea | 371 | pr_err("Cryptographic device %x failed and was set offline\n", |
d8f51227 | 372 | AP_QID_DEVICE(zdev->ap_dev->qid)); |
91f3e3ea | 373 | ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail", |
d8f51227 | 374 | AP_QID_DEVICE(zdev->ap_dev->qid), zdev->online); |
5e55a488 HD |
375 | return -EAGAIN; /* repeat the request on a different device. */ |
376 | } | |
377 | } | |
378 | ||
379 | /** | |
380 | * This function is called from the AP bus code after a crypto request | |
381 | * "msg" has finished with the reply message "reply". | |
382 | * It is called from tasklet context. | |
383 | * @ap_dev: pointer to the AP device | |
384 | * @msg: pointer to the AP message | |
385 | * @reply: pointer to the AP reply message | |
386 | */ | |
387 | static void zcrypt_cex2a_receive(struct ap_device *ap_dev, | |
388 | struct ap_message *msg, | |
389 | struct ap_message *reply) | |
390 | { | |
391 | static struct error_hdr error_reply = { | |
392 | .type = TYPE82_RSP_CODE, | |
393 | .reply_code = REP82_ERROR_MACHINE_FAILURE, | |
394 | }; | |
395 | struct type80_hdr *t80h; | |
396 | int length; | |
397 | ||
398 | /* Copy the reply message to the request message buffer. */ | |
f58fe336 MS |
399 | if (!reply) |
400 | goto out; /* ap_msg->rc indicates the error */ | |
5e55a488 HD |
401 | t80h = reply->message; |
402 | if (t80h->type == TYPE80_RSP_CODE) { | |
403 | if (ap_dev->device_type == AP_DEVICE_TYPE_CEX2A) | |
404 | length = min_t(int, | |
405 | CEX2A_MAX_RESPONSE_SIZE, t80h->len); | |
406 | else | |
407 | length = min_t(int, | |
408 | CEX3A_MAX_RESPONSE_SIZE, t80h->len); | |
409 | memcpy(msg->message, reply->message, length); | |
410 | } else | |
411 | memcpy(msg->message, reply->message, sizeof(error_reply)); | |
412 | out: | |
413 | complete((struct completion *) msg->private); | |
414 | } | |
415 | ||
416 | static atomic_t zcrypt_step = ATOMIC_INIT(0); | |
417 | ||
418 | /** | |
419 | * The request distributor calls this function if it picked the CEX2A | |
420 | * device to handle a modexpo request. | |
421 | * @zdev: pointer to zcrypt_device structure that identifies the | |
422 | * CEX2A device to the request distributor | |
423 | * @mex: pointer to the modexpo request buffer | |
424 | */ | |
425 | static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev, | |
426 | struct ica_rsa_modexpo *mex) | |
427 | { | |
428 | struct ap_message ap_msg; | |
429 | struct completion work; | |
430 | int rc; | |
431 | ||
432 | ap_init_message(&ap_msg); | |
433 | if (zdev->user_space_type == ZCRYPT_CEX2A) | |
434 | ap_msg.message = kmalloc(MSGTYPE50_CRB2_MAX_MSG_SIZE, | |
435 | GFP_KERNEL); | |
436 | else | |
437 | ap_msg.message = kmalloc(MSGTYPE50_CRB3_MAX_MSG_SIZE, | |
438 | GFP_KERNEL); | |
439 | if (!ap_msg.message) | |
440 | return -ENOMEM; | |
441 | ap_msg.receive = zcrypt_cex2a_receive; | |
442 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + | |
443 | atomic_inc_return(&zcrypt_step); | |
444 | ap_msg.private = &work; | |
445 | rc = ICAMEX_msg_to_type50MEX_msg(zdev, &ap_msg, mex); | |
446 | if (rc) | |
447 | goto out_free; | |
448 | init_completion(&work); | |
449 | ap_queue_message(zdev->ap_dev, &ap_msg); | |
450 | rc = wait_for_completion_interruptible(&work); | |
f58fe336 MS |
451 | if (rc == 0) { |
452 | rc = ap_msg.rc; | |
453 | if (rc == 0) | |
454 | rc = convert_response(zdev, &ap_msg, mex->outputdata, | |
455 | mex->outputdatalength); | |
456 | } else | |
5e55a488 HD |
457 | /* Signal pending. */ |
458 | ap_cancel_message(zdev->ap_dev, &ap_msg); | |
459 | out_free: | |
460 | kfree(ap_msg.message); | |
461 | return rc; | |
462 | } | |
463 | ||
464 | /** | |
465 | * The request distributor calls this function if it picked the CEX2A | |
466 | * device to handle a modexpo_crt request. | |
467 | * @zdev: pointer to zcrypt_device structure that identifies the | |
468 | * CEX2A device to the request distributor | |
469 | * @crt: pointer to the modexpoc_crt request buffer | |
470 | */ | |
471 | static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev, | |
472 | struct ica_rsa_modexpo_crt *crt) | |
473 | { | |
474 | struct ap_message ap_msg; | |
475 | struct completion work; | |
476 | int rc; | |
477 | ||
478 | ap_init_message(&ap_msg); | |
479 | if (zdev->user_space_type == ZCRYPT_CEX2A) | |
480 | ap_msg.message = kmalloc(MSGTYPE50_CRB2_MAX_MSG_SIZE, | |
481 | GFP_KERNEL); | |
482 | else | |
483 | ap_msg.message = kmalloc(MSGTYPE50_CRB3_MAX_MSG_SIZE, | |
484 | GFP_KERNEL); | |
485 | if (!ap_msg.message) | |
486 | return -ENOMEM; | |
487 | ap_msg.receive = zcrypt_cex2a_receive; | |
488 | ap_msg.psmid = (((unsigned long long) current->pid) << 32) + | |
489 | atomic_inc_return(&zcrypt_step); | |
490 | ap_msg.private = &work; | |
491 | rc = ICACRT_msg_to_type50CRT_msg(zdev, &ap_msg, crt); | |
492 | if (rc) | |
493 | goto out_free; | |
494 | init_completion(&work); | |
495 | ap_queue_message(zdev->ap_dev, &ap_msg); | |
496 | rc = wait_for_completion_interruptible(&work); | |
f58fe336 MS |
497 | if (rc == 0) { |
498 | rc = ap_msg.rc; | |
499 | if (rc == 0) | |
500 | rc = convert_response(zdev, &ap_msg, crt->outputdata, | |
501 | crt->outputdatalength); | |
502 | } else | |
5e55a488 HD |
503 | /* Signal pending. */ |
504 | ap_cancel_message(zdev->ap_dev, &ap_msg); | |
505 | out_free: | |
506 | kfree(ap_msg.message); | |
507 | return rc; | |
508 | } | |
509 | ||
510 | /** | |
511 | * The crypto operations for message type 50. | |
512 | */ | |
513 | static struct zcrypt_ops zcrypt_msgtype50_ops = { | |
514 | .rsa_modexpo = zcrypt_cex2a_modexpo, | |
515 | .rsa_modexpo_crt = zcrypt_cex2a_modexpo_crt, | |
516 | .owner = THIS_MODULE, | |
121a868d | 517 | .name = MSGTYPE50_NAME, |
5e55a488 HD |
518 | .variant = MSGTYPE50_VARIANT_DEFAULT, |
519 | }; | |
520 | ||
521 | int __init zcrypt_msgtype50_init(void) | |
522 | { | |
523 | zcrypt_msgtype_register(&zcrypt_msgtype50_ops); | |
524 | return 0; | |
525 | } | |
526 | ||
527 | void __exit zcrypt_msgtype50_exit(void) | |
528 | { | |
529 | zcrypt_msgtype_unregister(&zcrypt_msgtype50_ops); | |
530 | } | |
531 | ||
532 | module_init(zcrypt_msgtype50_init); | |
533 | module_exit(zcrypt_msgtype50_exit); |