Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
zcrypt_pcica.c
Go to the documentation of this file.
1 /*
2  * zcrypt 2.1.0
3  *
4  * Copyright IBM Corp. 2001, 2006
5  * Author(s): Robert Burroughs
6  * Eric Rossman ([email protected])
7  *
8  * Hotplug & misc device support: Jochen Roehrig ([email protected])
9  * Major cleanup & driver split: Martin Schwidefsky <[email protected]>
10  * Ralph Wuerthner <[email protected]>
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 #include <linux/module.h>
28 #include <linux/slab.h>
29 #include <linux/init.h>
30 #include <linux/err.h>
31 #include <linux/atomic.h>
32 #include <asm/uaccess.h>
33 
34 #include "ap_bus.h"
35 #include "zcrypt_api.h"
36 #include "zcrypt_error.h"
37 #include "zcrypt_pcica.h"
38 
39 #define PCICA_MIN_MOD_SIZE 1 /* 8 bits */
40 #define PCICA_MAX_MOD_SIZE 256 /* 2048 bits */
41 
42 #define PCICA_SPEED_RATING 2800
43 
44 #define PCICA_MAX_MESSAGE_SIZE 0x3a0 /* sizeof(struct type4_lcr) */
45 #define PCICA_MAX_RESPONSE_SIZE 0x110 /* max outputdatalength + type80_hdr */
46 
47 #define PCICA_CLEANUP_TIME (15*HZ)
48 
49 static struct ap_device_id zcrypt_pcica_ids[] = {
51  { /* end of list */ },
52 };
53 
54 MODULE_DEVICE_TABLE(ap, zcrypt_pcica_ids);
55 MODULE_AUTHOR("IBM Corporation");
56 MODULE_DESCRIPTION("PCICA Cryptographic Coprocessor device driver, "
57  "Copyright IBM Corp. 2001, 2006");
58 MODULE_LICENSE("GPL");
59 
60 static int zcrypt_pcica_probe(struct ap_device *ap_dev);
61 static void zcrypt_pcica_remove(struct ap_device *ap_dev);
62 static void zcrypt_pcica_receive(struct ap_device *, struct ap_message *,
63  struct ap_message *);
64 
65 static struct ap_driver zcrypt_pcica_driver = {
66  .probe = zcrypt_pcica_probe,
67  .remove = zcrypt_pcica_remove,
68  .ids = zcrypt_pcica_ids,
69  .request_timeout = PCICA_CLEANUP_TIME,
70 };
71 
81 static int ICAMEX_msg_to_type4MEX_msg(struct zcrypt_device *zdev,
82  struct ap_message *ap_msg,
83  struct ica_rsa_modexpo *mex)
84 {
85  unsigned char *modulus, *exponent, *message;
86  int mod_len;
87 
88  mod_len = mex->inputdatalength;
89 
90  if (mod_len <= 128) {
91  struct type4_sme *sme = ap_msg->message;
92  memset(sme, 0, sizeof(*sme));
93  ap_msg->length = sizeof(*sme);
94  sme->header.msg_fmt = TYPE4_SME_FMT;
95  sme->header.msg_len = sizeof(*sme);
96  sme->header.msg_type_code = TYPE4_TYPE_CODE;
97  sme->header.request_code = TYPE4_REQU_CODE;
98  modulus = sme->modulus + sizeof(sme->modulus) - mod_len;
99  exponent = sme->exponent + sizeof(sme->exponent) - mod_len;
100  message = sme->message + sizeof(sme->message) - mod_len;
101  } else {
102  struct type4_lme *lme = ap_msg->message;
103  memset(lme, 0, sizeof(*lme));
104  ap_msg->length = sizeof(*lme);
105  lme->header.msg_fmt = TYPE4_LME_FMT;
106  lme->header.msg_len = sizeof(*lme);
107  lme->header.msg_type_code = TYPE4_TYPE_CODE;
108  lme->header.request_code = TYPE4_REQU_CODE;
109  modulus = lme->modulus + sizeof(lme->modulus) - mod_len;
110  exponent = lme->exponent + sizeof(lme->exponent) - mod_len;
111  message = lme->message + sizeof(lme->message) - mod_len;
112  }
113 
114  if (copy_from_user(modulus, mex->n_modulus, mod_len) ||
115  copy_from_user(exponent, mex->b_key, mod_len) ||
116  copy_from_user(message, mex->inputdata, mod_len))
117  return -EFAULT;
118  return 0;
119 }
120 
130 static int ICACRT_msg_to_type4CRT_msg(struct zcrypt_device *zdev,
131  struct ap_message *ap_msg,
132  struct ica_rsa_modexpo_crt *crt)
133 {
134  unsigned char *p, *q, *dp, *dq, *u, *inp;
135  int mod_len, short_len, long_len;
136 
137  mod_len = crt->inputdatalength;
138  short_len = mod_len / 2;
139  long_len = mod_len / 2 + 8;
140 
141  if (mod_len <= 128) {
142  struct type4_scr *scr = ap_msg->message;
143  memset(scr, 0, sizeof(*scr));
144  ap_msg->length = sizeof(*scr);
145  scr->header.msg_type_code = TYPE4_TYPE_CODE;
146  scr->header.request_code = TYPE4_REQU_CODE;
147  scr->header.msg_fmt = TYPE4_SCR_FMT;
148  scr->header.msg_len = sizeof(*scr);
149  p = scr->p + sizeof(scr->p) - long_len;
150  q = scr->q + sizeof(scr->q) - short_len;
151  dp = scr->dp + sizeof(scr->dp) - long_len;
152  dq = scr->dq + sizeof(scr->dq) - short_len;
153  u = scr->u + sizeof(scr->u) - long_len;
154  inp = scr->message + sizeof(scr->message) - mod_len;
155  } else {
156  struct type4_lcr *lcr = ap_msg->message;
157  memset(lcr, 0, sizeof(*lcr));
158  ap_msg->length = sizeof(*lcr);
159  lcr->header.msg_type_code = TYPE4_TYPE_CODE;
160  lcr->header.request_code = TYPE4_REQU_CODE;
161  lcr->header.msg_fmt = TYPE4_LCR_FMT;
162  lcr->header.msg_len = sizeof(*lcr);
163  p = lcr->p + sizeof(lcr->p) - long_len;
164  q = lcr->q + sizeof(lcr->q) - short_len;
165  dp = lcr->dp + sizeof(lcr->dp) - long_len;
166  dq = lcr->dq + sizeof(lcr->dq) - short_len;
167  u = lcr->u + sizeof(lcr->u) - long_len;
168  inp = lcr->message + sizeof(lcr->message) - mod_len;
169  }
170 
171  if (copy_from_user(p, crt->np_prime, long_len) ||
172  copy_from_user(q, crt->nq_prime, short_len) ||
173  copy_from_user(dp, crt->bp_key, long_len) ||
174  copy_from_user(dq, crt->bq_key, short_len) ||
175  copy_from_user(u, crt->u_mult_inv, long_len) ||
176  copy_from_user(inp, crt->inputdata, mod_len))
177  return -EFAULT;
178  return 0;
179 }
180 
191 static int convert_type84(struct zcrypt_device *zdev,
192  struct ap_message *reply,
193  char __user *outputdata,
194  unsigned int outputdatalength)
195 {
196  struct type84_hdr *t84h = reply->message;
197  char *data;
198 
199  if (t84h->len < sizeof(*t84h) + outputdatalength) {
200  /* The result is too short, the PCICA card may not do that.. */
201  zdev->online = 0;
202  return -EAGAIN; /* repeat the request on a different device. */
203  }
205  data = reply->message + t84h->len - outputdatalength;
206  if (copy_to_user(outputdata, data, outputdatalength))
207  return -EFAULT;
208  return 0;
209 }
210 
211 static int convert_response(struct zcrypt_device *zdev,
212  struct ap_message *reply,
213  char __user *outputdata,
214  unsigned int outputdatalength)
215 {
216  /* Response type byte is the second byte in the response. */
217  switch (((unsigned char *) reply->message)[1]) {
218  case TYPE82_RSP_CODE:
219  case TYPE88_RSP_CODE:
220  return convert_error(zdev, reply);
221  case TYPE84_RSP_CODE:
222  return convert_type84(zdev, reply,
223  outputdata, outputdatalength);
224  default: /* Unknown response type, this should NEVER EVER happen */
225  zdev->online = 0;
226  return -EAGAIN; /* repeat the request on a different device. */
227  }
228 }
229 
238 static void zcrypt_pcica_receive(struct ap_device *ap_dev,
239  struct ap_message *msg,
240  struct ap_message *reply)
241 {
242  static struct error_hdr error_reply = {
244  .reply_code = REP82_ERROR_MACHINE_FAILURE,
245  };
246  struct type84_hdr *t84h;
247  int length;
248 
249  /* Copy the reply message to the request message buffer. */
250  if (IS_ERR(reply)) {
251  memcpy(msg->message, &error_reply, sizeof(error_reply));
252  goto out;
253  }
254  t84h = reply->message;
255  if (t84h->code == TYPE84_RSP_CODE) {
256  length = min(PCICA_MAX_RESPONSE_SIZE, (int) t84h->len);
257  memcpy(msg->message, reply->message, length);
258  } else
259  memcpy(msg->message, reply->message, sizeof error_reply);
260 out:
261  complete((struct completion *) msg->private);
262 }
263 
264 static atomic_t zcrypt_step = ATOMIC_INIT(0);
265 
273 static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev,
274  struct ica_rsa_modexpo *mex)
275 {
276  struct ap_message ap_msg;
277  struct completion work;
278  int rc;
279 
280  ap_init_message(&ap_msg);
282  if (!ap_msg.message)
283  return -ENOMEM;
284  ap_msg.receive = zcrypt_pcica_receive;
285  ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
286  atomic_inc_return(&zcrypt_step);
287  ap_msg.private = &work;
288  rc = ICAMEX_msg_to_type4MEX_msg(zdev, &ap_msg, mex);
289  if (rc)
290  goto out_free;
291  init_completion(&work);
292  ap_queue_message(zdev->ap_dev, &ap_msg);
294  if (rc == 0)
295  rc = convert_response(zdev, &ap_msg, mex->outputdata,
296  mex->outputdatalength);
297  else
298  /* Signal pending. */
299  ap_cancel_message(zdev->ap_dev, &ap_msg);
300 out_free:
301  kfree(ap_msg.message);
302  return rc;
303 }
304 
312 static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev,
313  struct ica_rsa_modexpo_crt *crt)
314 {
315  struct ap_message ap_msg;
316  struct completion work;
317  int rc;
318 
319  ap_init_message(&ap_msg);
321  if (!ap_msg.message)
322  return -ENOMEM;
323  ap_msg.receive = zcrypt_pcica_receive;
324  ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
325  atomic_inc_return(&zcrypt_step);
326  ap_msg.private = &work;
327  rc = ICACRT_msg_to_type4CRT_msg(zdev, &ap_msg, crt);
328  if (rc)
329  goto out_free;
330  init_completion(&work);
331  ap_queue_message(zdev->ap_dev, &ap_msg);
333  if (rc == 0)
334  rc = convert_response(zdev, &ap_msg, crt->outputdata,
335  crt->outputdatalength);
336  else
337  /* Signal pending. */
338  ap_cancel_message(zdev->ap_dev, &ap_msg);
339 out_free:
340  kfree(ap_msg.message);
341  return rc;
342 }
343 
347 static struct zcrypt_ops zcrypt_pcica_ops = {
348  .rsa_modexpo = zcrypt_pcica_modexpo,
349  .rsa_modexpo_crt = zcrypt_pcica_modexpo_crt,
350 };
351 
357 static int zcrypt_pcica_probe(struct ap_device *ap_dev)
358 {
359  struct zcrypt_device *zdev;
360  int rc;
361 
363  if (!zdev)
364  return -ENOMEM;
365  zdev->ap_dev = ap_dev;
366  zdev->ops = &zcrypt_pcica_ops;
367  zdev->online = 1;
369  zdev->type_string = "PCICA";
374  ap_dev->reply = &zdev->reply;
375  ap_dev->private = zdev;
376  rc = zcrypt_device_register(zdev);
377  if (rc)
378  goto out_free;
379  return 0;
380 
381 out_free:
382  ap_dev->private = NULL;
383  zcrypt_device_free(zdev);
384  return rc;
385 }
386 
391 static void zcrypt_pcica_remove(struct ap_device *ap_dev)
392 {
393  struct zcrypt_device *zdev = ap_dev->private;
394 
396 }
397 
399 {
400  return ap_driver_register(&zcrypt_pcica_driver, THIS_MODULE, "pcica");
401 }
402 
404 {
405  ap_driver_unregister(&zcrypt_pcica_driver);
406 }
407