]> Pileus Git - ~andy/linux/blob - drivers/s390/crypto/zcrypt_pcixcc.c
Merge branch 'next' of git://git.infradead.org/users/vkoul/slave-dma
[~andy/linux] / drivers / s390 / crypto / zcrypt_pcixcc.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 <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 #include "zcrypt_msgtype6.h"
43
44 #define PCIXCC_MIN_MOD_SIZE      16     /*  128 bits    */
45 #define PCIXCC_MIN_MOD_SIZE_OLD  64     /*  512 bits    */
46 #define PCIXCC_MAX_MOD_SIZE     256     /* 2048 bits    */
47 #define CEX3C_MIN_MOD_SIZE      PCIXCC_MIN_MOD_SIZE
48 #define CEX3C_MAX_MOD_SIZE      512     /* 4096 bits    */
49
50 #define PCIXCC_MCL2_SPEED_RATING        7870
51 #define PCIXCC_MCL3_SPEED_RATING        7870
52 #define CEX2C_SPEED_RATING              7000
53 #define CEX3C_SPEED_RATING              6500
54
55 #define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c  /* max size type6 v2 crt message */
56 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply      */
57
58 #define PCIXCC_MAX_XCRB_MESSAGE_SIZE (12*1024)
59
60 #define PCIXCC_CLEANUP_TIME     (15*HZ)
61
62 #define CEIL4(x) ((((x)+3)/4)*4)
63
64 struct response_type {
65         struct completion work;
66         int type;
67 };
68 #define PCIXCC_RESPONSE_TYPE_ICA  0
69 #define PCIXCC_RESPONSE_TYPE_XCRB 1
70
71 static struct ap_device_id zcrypt_pcixcc_ids[] = {
72         { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
73         { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
74         { AP_DEVICE(AP_DEVICE_TYPE_CEX3C) },
75         { /* end of list */ },
76 };
77
78 MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
79 MODULE_AUTHOR("IBM Corporation");
80 MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, " \
81                    "Copyright IBM Corp. 2001, 2012");
82 MODULE_LICENSE("GPL");
83
84 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
85 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
86
87 static struct ap_driver zcrypt_pcixcc_driver = {
88         .probe = zcrypt_pcixcc_probe,
89         .remove = zcrypt_pcixcc_remove,
90         .ids = zcrypt_pcixcc_ids,
91         .request_timeout = PCIXCC_CLEANUP_TIME,
92 };
93
94 /**
95  * Micro-code detection function. Its sends a message to a pcixcc card
96  * to find out the microcode level.
97  * @ap_dev: pointer to the AP device.
98  */
99 static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
100 {
101         static unsigned char msg[] = {
102                 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
103                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
104                 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
105                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
106                 0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
107                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
108                 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
109                 0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
110                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
111                 0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
112                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
113                 0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
114                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
115                 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
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,0x00,0x00,0x00,0x00,0x00,
134                 0x00,0x00,0x00,0x04,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,0x00,0x00,0x00,0x00,
140                 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,
141                 0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
142                 0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
143                 0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
144                 0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
145                 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
146                 0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
147                 0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
148                 0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
149                 0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
150                 0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
151                 0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
152                 0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
153                 0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
154                 0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
155                 0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
156                 0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
157                 0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
158                 0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
159                 0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
160                 0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
161                 0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
162                 0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
163                 0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
164                 0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
165                 0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
166                 0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
167                 0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
168                 0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
169                 0xF1,0x3D,0x93,0x53
170         };
171         unsigned long long psmid;
172         struct CPRBX *cprbx;
173         char *reply;
174         int rc, i;
175
176         reply = (void *) get_zeroed_page(GFP_KERNEL);
177         if (!reply)
178                 return -ENOMEM;
179
180         rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
181         if (rc)
182                 goto out_free;
183
184         /* Wait for the test message to complete. */
185         for (i = 0; i < 6; i++) {
186                 mdelay(300);
187                 rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
188                 if (rc == 0 && psmid == 0x0102030405060708ULL)
189                         break;
190         }
191
192         if (i >= 6) {
193                 /* Got no answer. */
194                 rc = -ENODEV;
195                 goto out_free;
196         }
197
198         cprbx = (struct CPRBX *) (reply + 48);
199         if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
200                 rc = ZCRYPT_PCIXCC_MCL2;
201         else
202                 rc = ZCRYPT_PCIXCC_MCL3;
203 out_free:
204         free_page((unsigned long) reply);
205         return rc;
206 }
207
208 /**
209  * Large random number detection function. Its sends a message to a pcixcc
210  * card to find out if large random numbers are supported.
211  * @ap_dev: pointer to the AP device.
212  *
213  * Returns 1 if large random numbers are supported, 0 if not and < 0 on error.
214  */
215 static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
216 {
217         struct ap_message ap_msg;
218         unsigned long long psmid;
219         struct {
220                 struct type86_hdr hdr;
221                 struct type86_fmt2_ext fmt2;
222                 struct CPRBX cprbx;
223         } __attribute__((packed)) *reply;
224         int rc, i;
225
226         ap_init_message(&ap_msg);
227         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
228         if (!ap_msg.message)
229                 return -ENOMEM;
230
231         rng_type6CPRB_msgX(ap_dev, &ap_msg, 4);
232         rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, ap_msg.message,
233                      ap_msg.length);
234         if (rc)
235                 goto out_free;
236
237         /* Wait for the test message to complete. */
238         for (i = 0; i < 2 * HZ; i++) {
239                 msleep(1000 / HZ);
240                 rc = ap_recv(ap_dev->qid, &psmid, ap_msg.message, 4096);
241                 if (rc == 0 && psmid == 0x0102030405060708ULL)
242                         break;
243         }
244
245         if (i >= 2 * HZ) {
246                 /* Got no answer. */
247                 rc = -ENODEV;
248                 goto out_free;
249         }
250
251         reply = ap_msg.message;
252         if (reply->cprbx.ccp_rtcode == 0 && reply->cprbx.ccp_rscode == 0)
253                 rc = 1;
254         else
255                 rc = 0;
256 out_free:
257         free_page((unsigned long) ap_msg.message);
258         return rc;
259 }
260
261 /**
262  * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
263  * since the bus_match already checked the hardware type. The PCIXCC
264  * cards come in two flavours: micro code level 2 and micro code level 3.
265  * This is checked by sending a test message to the device.
266  * @ap_dev: pointer to the AP device.
267  */
268 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
269 {
270         struct zcrypt_device *zdev;
271         int rc = 0;
272
273         zdev = zcrypt_device_alloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE);
274         if (!zdev)
275                 return -ENOMEM;
276         zdev->ap_dev = ap_dev;
277         zdev->online = 1;
278         switch (ap_dev->device_type) {
279         case AP_DEVICE_TYPE_PCIXCC:
280                 rc = zcrypt_pcixcc_mcl(ap_dev);
281                 if (rc < 0) {
282                         zcrypt_device_free(zdev);
283                         return rc;
284                 }
285                 zdev->user_space_type = rc;
286                 if (rc == ZCRYPT_PCIXCC_MCL2) {
287                         zdev->type_string = "PCIXCC_MCL2";
288                         zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
289                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
290                         zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
291                         zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
292                 } else {
293                         zdev->type_string = "PCIXCC_MCL3";
294                         zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
295                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
296                         zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
297                         zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
298                 }
299                 break;
300         case AP_DEVICE_TYPE_CEX2C:
301                 zdev->user_space_type = ZCRYPT_CEX2C;
302                 zdev->type_string = "CEX2C";
303                 zdev->speed_rating = CEX2C_SPEED_RATING;
304                 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
305                 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
306                 zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
307                 break;
308         case AP_DEVICE_TYPE_CEX3C:
309                 zdev->user_space_type = ZCRYPT_CEX3C;
310                 zdev->type_string = "CEX3C";
311                 zdev->speed_rating = CEX3C_SPEED_RATING;
312                 zdev->min_mod_size = CEX3C_MIN_MOD_SIZE;
313                 zdev->max_mod_size = CEX3C_MAX_MOD_SIZE;
314                 zdev->max_exp_bit_length = CEX3C_MAX_MOD_SIZE;
315                 break;
316         default:
317                 goto out_free;
318         }
319
320         rc = zcrypt_pcixcc_rng_supported(ap_dev);
321         if (rc < 0) {
322                 zcrypt_device_free(zdev);
323                 return rc;
324         }
325         if (rc)
326                 zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME,
327                                                    MSGTYPE06_VARIANT_DEFAULT);
328         else
329                 zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME,
330                                                    MSGTYPE06_VARIANT_NORNG);
331         ap_dev->reply = &zdev->reply;
332         ap_dev->private = zdev;
333         rc = zcrypt_device_register(zdev);
334         if (rc)
335                 goto out_free;
336         return 0;
337
338  out_free:
339         ap_dev->private = NULL;
340         zcrypt_msgtype_release(zdev->ops);
341         zcrypt_device_free(zdev);
342         return rc;
343 }
344
345 /**
346  * This is called to remove the extended PCIXCC/CEX2C driver information
347  * if an AP device is removed.
348  */
349 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
350 {
351         struct zcrypt_device *zdev = ap_dev->private;
352         struct zcrypt_ops *zops = zdev->ops;
353
354         zcrypt_device_unregister(zdev);
355         zcrypt_msgtype_release(zops);
356 }
357
358 int __init zcrypt_pcixcc_init(void)
359 {
360         return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
361 }
362
363 void zcrypt_pcixcc_exit(void)
364 {
365         ap_driver_unregister(&zcrypt_pcixcc_driver);
366 }
367
368 module_init(zcrypt_pcixcc_init);
369 module_exit(zcrypt_pcixcc_exit);