blob: c7275e303a0d95074eefab828142c97406417c2b [file] [log] [blame]
Martin Schwidefsky6684af12006-09-20 15:58:32 +02001/*
Ralph Wuerthner54321142006-09-20 15:58:36 +02002 * zcrypt 2.1.0
Martin Schwidefsky6684af12006-09-20 15:58:32 +02003 *
Holger Dengler5e55a482012-08-28 16:45:36 +02004 * Copyright IBM Corp. 2001, 2012
Martin Schwidefsky6684af12006-09-20 15:58:32 +02005 * 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>
Holger Dengler5e55a482012-08-28 16:45:36 +020011 * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com>
Martin Schwidefsky6684af12006-09-20 15:58:32 +020012 *
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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090032#include <linux/slab.h>
Arun Sharma600634972011-07-26 16:09:06 -070033#include <linux/atomic.h>
Martin Schwidefsky6684af12006-09-20 15:58:32 +020034#include <asm/uaccess.h>
35
36#include "ap_bus.h"
37#include "zcrypt_api.h"
38#include "zcrypt_error.h"
Holger Dengler5e55a482012-08-28 16:45:36 +020039#include "zcrypt_msgtype6.h"
Martin Schwidefsky6684af12006-09-20 15:58:32 +020040#include "zcrypt_pcixcc.h"
41#include "zcrypt_cca_key.h"
Holger Dengler5e55a482012-08-28 16:45:36 +020042#include "zcrypt_msgtype6.h"
Martin Schwidefsky6684af12006-09-20 15:58:32 +020043
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 */
Felix Beck8e89b6b2009-12-07 12:51:57 +010047#define CEX3C_MIN_MOD_SIZE PCIXCC_MIN_MOD_SIZE
Felix Beck2ade1fa2011-01-05 12:47:46 +010048#define CEX3C_MAX_MOD_SIZE 512 /* 4096 bits */
Martin Schwidefsky6684af12006-09-20 15:58:32 +020049
Felix Beck18278df2009-12-07 12:51:58 +010050#define PCIXCC_MCL2_SPEED_RATING 7870
Martin Schwidefsky6684af12006-09-20 15:58:32 +020051#define PCIXCC_MCL3_SPEED_RATING 7870
Felix Beck18278df2009-12-07 12:51:58 +010052#define CEX2C_SPEED_RATING 7000
Felix Beck2ade1fa2011-01-05 12:47:46 +010053#define CEX3C_SPEED_RATING 6500
Martin Schwidefsky6684af12006-09-20 15:58:32 +020054
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)
Martin Schwidefsky6684af12006-09-20 15:58:32 +020059
60#define PCIXCC_CLEANUP_TIME (15*HZ)
61
Ralph Wuerthner54321142006-09-20 15:58:36 +020062#define CEIL4(x) ((((x)+3)/4)*4)
63
64struct 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
Martin Schwidefsky6684af12006-09-20 15:58:32 +020071static struct ap_device_id zcrypt_pcixcc_ids[] = {
72 { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
73 { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
Felix Beckffda4f72009-12-07 12:51:56 +010074 { AP_DEVICE(AP_DEVICE_TYPE_CEX3C) },
Martin Schwidefsky6684af12006-09-20 15:58:32 +020075 { /* end of list */ },
76};
77
Martin Schwidefsky6684af12006-09-20 15:58:32 +020078MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
79MODULE_AUTHOR("IBM Corporation");
Holger Dengler5e55a482012-08-28 16:45:36 +020080MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, " \
81 "Copyright IBM Corp. 2001, 2012");
Martin Schwidefsky6684af12006-09-20 15:58:32 +020082MODULE_LICENSE("GPL");
Martin Schwidefsky6684af12006-09-20 15:58:32 +020083
84static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
85static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
Martin Schwidefsky6684af12006-09-20 15:58:32 +020086
87static struct ap_driver zcrypt_pcixcc_driver = {
88 .probe = zcrypt_pcixcc_probe,
89 .remove = zcrypt_pcixcc_remove,
Martin Schwidefsky6684af12006-09-20 15:58:32 +020090 .ids = zcrypt_pcixcc_ids,
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +020091 .request_timeout = PCIXCC_CLEANUP_TIME,
Martin Schwidefsky6684af12006-09-20 15:58:32 +020092};
93
94/**
Martin Schwidefsky6684af12006-09-20 15:58:32 +020095 * 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 */
99static 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;
203out_free:
204 free_page((unsigned long) reply);
205 return rc;
206}
207
208/**
Ralph Wuerthner2f7c8bd2008-04-17 07:46:15 +0200209 * 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 */
215static 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
Felix Beck468ffdd2009-12-07 12:51:54 +0100226 ap_init_message(&ap_msg);
Ralph Wuerthner2f7c8bd2008-04-17 07:46:15 +0200227 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;
256out_free:
257 free_page((unsigned long) ap_msg.message);
258 return rc;
259}
260
261/**
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200262 * 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 */
268static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
269{
270 struct zcrypt_device *zdev;
Felix Beck8e89b6b2009-12-07 12:51:57 +0100271 int rc = 0;
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200272
Holger Dengler7fe6f092011-12-27 11:27:19 +0100273 zdev = zcrypt_device_alloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE);
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200274 if (!zdev)
275 return -ENOMEM;
276 zdev->ap_dev = ap_dev;
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200277 zdev->online = 1;
Felix Beck8e89b6b2009-12-07 12:51:57 +0100278 switch (ap_dev->device_type) {
279 case AP_DEVICE_TYPE_PCIXCC:
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200280 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;
Felix Beckc2567f82011-01-05 12:47:47 +0100291 zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200292 } 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;
Felix Beckc2567f82011-01-05 12:47:47 +0100297 zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200298 }
Felix Beck8e89b6b2009-12-07 12:51:57 +0100299 break;
300 case AP_DEVICE_TYPE_CEX2C:
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200301 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;
Felix Beckc2567f82011-01-05 12:47:47 +0100306 zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
Felix Beck8e89b6b2009-12-07 12:51:57 +0100307 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;
Felix Beckc2567f82011-01-05 12:47:47 +0100314 zdev->max_exp_bit_length = CEX3C_MAX_MOD_SIZE;
Felix Beck8e89b6b2009-12-07 12:51:57 +0100315 break;
316 default:
317 goto out_free;
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200318 }
Felix Beck8e89b6b2009-12-07 12:51:57 +0100319
Ralph Wuerthner2f7c8bd2008-04-17 07:46:15 +0200320 rc = zcrypt_pcixcc_rng_supported(ap_dev);
321 if (rc < 0) {
322 zcrypt_device_free(zdev);
323 return rc;
324 }
325 if (rc)
Holger Dengler5e55a482012-08-28 16:45:36 +0200326 zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME,
327 MSGTYPE06_VARIANT_DEFAULT);
Ralph Wuerthner2f7c8bd2008-04-17 07:46:15 +0200328 else
Holger Dengler5e55a482012-08-28 16:45:36 +0200329 zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME,
330 MSGTYPE06_VARIANT_NORNG);
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200331 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;
Holger Dengler5e55a482012-08-28 16:45:36 +0200340 zcrypt_msgtype_release(zdev->ops);
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200341 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 */
349static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
350{
351 struct zcrypt_device *zdev = ap_dev->private;
Holger Dengler5e55a482012-08-28 16:45:36 +0200352 struct zcrypt_ops *zops = zdev->ops;
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200353
354 zcrypt_device_unregister(zdev);
Holger Dengler5e55a482012-08-28 16:45:36 +0200355 zcrypt_msgtype_release(zops);
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200356}
357
358int __init zcrypt_pcixcc_init(void)
359{
360 return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
361}
362
363void zcrypt_pcixcc_exit(void)
364{
365 ap_driver_unregister(&zcrypt_pcixcc_driver);
366}
367
Martin Schwidefsky6684af12006-09-20 15:58:32 +0200368module_init(zcrypt_pcixcc_init);
369module_exit(zcrypt_pcixcc_exit);