Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
zcrypt_pcixcc.c
Go to the documentation of this file.
1 /*
2  * zcrypt 2.1.0
3  *
4  * Copyright IBM Corp. 2001, 2012
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  * MSGTYPE restruct: Holger Dengler <[email protected]>
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 <asm/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_pcixcc.h"
41 #include "zcrypt_cca_key.h"
42 
43 #define PCIXCC_MIN_MOD_SIZE 16 /* 128 bits */
44 #define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */
45 #define PCIXCC_MAX_MOD_SIZE 256 /* 2048 bits */
46 #define CEX3C_MIN_MOD_SIZE PCIXCC_MIN_MOD_SIZE
47 #define CEX3C_MAX_MOD_SIZE 512 /* 4096 bits */
48 
49 #define PCIXCC_MCL2_SPEED_RATING 7870
50 #define PCIXCC_MCL3_SPEED_RATING 7870
51 #define CEX2C_SPEED_RATING 7000
52 #define CEX3C_SPEED_RATING 6500
53 
54 #define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c /* max size type6 v2 crt message */
55 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */
56 
57 #define PCIXCC_MAX_XCRB_MESSAGE_SIZE (12*1024)
58 
59 #define PCIXCC_CLEANUP_TIME (15*HZ)
60 
61 #define CEIL4(x) ((((x)+3)/4)*4)
62 
63 struct response_type {
64  struct completion work;
65  int type;
66 };
67 #define PCIXCC_RESPONSE_TYPE_ICA 0
68 #define PCIXCC_RESPONSE_TYPE_XCRB 1
69 
70 static struct ap_device_id zcrypt_pcixcc_ids[] = {
74  { /* end of list */ },
75 };
76 
77 MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
78 MODULE_AUTHOR("IBM Corporation");
79 MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, " \
80  "Copyright IBM Corp. 2001, 2012");
81 MODULE_LICENSE("GPL");
82 
83 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
84 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
85 
86 static struct ap_driver zcrypt_pcixcc_driver = {
87  .probe = zcrypt_pcixcc_probe,
88  .remove = zcrypt_pcixcc_remove,
89  .ids = zcrypt_pcixcc_ids,
90  .request_timeout = PCIXCC_CLEANUP_TIME,
91 };
92 
98 static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
99 {
100  static unsigned char msg[] = {
101  0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
102  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
103  0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
104  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
105  0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
106  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
107  0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
108  0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
109  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
110  0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
111  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
112  0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
113  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
114  0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
115  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
116  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
117  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
118  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
119  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
120  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
121  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
122  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
123  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
124  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
125  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
126  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
127  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
128  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
129  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
130  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
131  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
132  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
133  0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,
134  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
136  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
137  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
138  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
139  0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,
140  0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
141  0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
142  0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
143  0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
144  0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
145  0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
146  0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
147  0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
148  0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
149  0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
150  0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
151  0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
152  0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
153  0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
154  0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
155  0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
156  0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
157  0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
158  0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
159  0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
160  0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
161  0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
162  0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
163  0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
164  0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
165  0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
166  0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
167  0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
168  0xF1,0x3D,0x93,0x53
169  };
170  unsigned long long psmid;
171  struct CPRBX *cprbx;
172  char *reply;
173  int rc, i;
174 
175  reply = (void *) get_zeroed_page(GFP_KERNEL);
176  if (!reply)
177  return -ENOMEM;
178 
179  rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
180  if (rc)
181  goto out_free;
182 
183  /* Wait for the test message to complete. */
184  for (i = 0; i < 6; i++) {
185  mdelay(300);
186  rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
187  if (rc == 0 && psmid == 0x0102030405060708ULL)
188  break;
189  }
190 
191  if (i >= 6) {
192  /* Got no answer. */
193  rc = -ENODEV;
194  goto out_free;
195  }
196 
197  cprbx = (struct CPRBX *) (reply + 48);
198  if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
199  rc = ZCRYPT_PCIXCC_MCL2;
200  else
201  rc = ZCRYPT_PCIXCC_MCL3;
202 out_free:
203  free_page((unsigned long) reply);
204  return rc;
205 }
206 
214 static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
215 {
216  struct ap_message ap_msg;
217  unsigned long long psmid;
218  struct {
219  struct type86_hdr hdr;
220  struct type86_fmt2_ext fmt2;
221  struct CPRBX cprbx;
222  } __attribute__((packed)) *reply;
223  int rc, i;
224 
225  ap_init_message(&ap_msg);
226  ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
227  if (!ap_msg.message)
228  return -ENOMEM;
229 
230  rng_type6CPRB_msgX(ap_dev, &ap_msg, 4);
231  rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, ap_msg.message,
232  ap_msg.length);
233  if (rc)
234  goto out_free;
235 
236  /* Wait for the test message to complete. */
237  for (i = 0; i < 2 * HZ; i++) {
238  msleep(1000 / HZ);
239  rc = ap_recv(ap_dev->qid, &psmid, ap_msg.message, 4096);
240  if (rc == 0 && psmid == 0x0102030405060708ULL)
241  break;
242  }
243 
244  if (i >= 2 * HZ) {
245  /* Got no answer. */
246  rc = -ENODEV;
247  goto out_free;
248  }
249 
250  reply = ap_msg.message;
251  if (reply->cprbx.ccp_rtcode == 0 && reply->cprbx.ccp_rscode == 0)
252  rc = 1;
253  else
254  rc = 0;
255 out_free:
256  free_page((unsigned long) ap_msg.message);
257  return rc;
258 }
259 
267 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
268 {
269  struct zcrypt_device *zdev;
270  int rc = 0;
271 
273  if (!zdev)
274  return -ENOMEM;
275  zdev->ap_dev = ap_dev;
276  zdev->online = 1;
277  switch (ap_dev->device_type) {
279  rc = zcrypt_pcixcc_mcl(ap_dev);
280  if (rc < 0) {
281  zcrypt_device_free(zdev);
282  return rc;
283  }
284  zdev->user_space_type = rc;
285  if (rc == ZCRYPT_PCIXCC_MCL2) {
286  zdev->type_string = "PCIXCC_MCL2";
291  } else {
292  zdev->type_string = "PCIXCC_MCL3";
297  }
298  break;
301  zdev->type_string = "CEX2C";
306  break;
309  zdev->type_string = "CEX3C";
314  break;
315  default:
316  goto out_free;
317  }
318 
319  rc = zcrypt_pcixcc_rng_supported(ap_dev);
320  if (rc < 0) {
321  zcrypt_device_free(zdev);
322  return rc;
323  }
324  if (rc)
327  else
330  ap_dev->reply = &zdev->reply;
331  ap_dev->private = zdev;
332  rc = zcrypt_device_register(zdev);
333  if (rc)
334  goto out_free;
335  return 0;
336 
337  out_free:
338  ap_dev->private = NULL;
340  zcrypt_device_free(zdev);
341  return rc;
342 }
343 
348 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
349 {
350  struct zcrypt_device *zdev = ap_dev->private;
351  struct zcrypt_ops *zops = zdev->ops;
352 
355 }
356 
358 {
359  return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
360 }
361 
363 {
364  ap_driver_unregister(&zcrypt_pcixcc_driver);
365 }
366