]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/s390/crypto/z90hardware.c
[PATCH] s390: cleanup Kconfig
[net-next-2.6.git] / drivers / s390 / crypto / z90hardware.c
CommitLineData
1da177e4
LT
1/*
2 * linux/drivers/s390/crypto/z90hardware.c
3 *
88fbf183 4 * z90crypt 1.3.3
1da177e4 5 *
88fbf183 6 * Copyright (C) 2001, 2005 IBM Corporation
1da177e4
LT
7 * Author(s): Robert Burroughs (burrough@us.ibm.com)
8 * Eric Rossman (edrossma@us.ibm.com)
9 *
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
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 <asm/uaccess.h>
28#include <linux/compiler.h>
29#include <linux/delay.h>
30#include <linux/init.h>
31#include <linux/module.h>
32#include "z90crypt.h"
33#include "z90common.h"
34
2dee702f 35#define VERSION_Z90HARDWARE_C "$Revision: 1.34 $"
1da177e4
LT
36
37char z90hardware_version[] __initdata =
38 "z90hardware.o (" VERSION_Z90HARDWARE_C "/"
39 VERSION_Z90COMMON_H "/" VERSION_Z90CRYPT_H ")";
40
41struct cca_token_hdr {
42 unsigned char token_identifier;
43 unsigned char version;
44 unsigned short token_length;
45 unsigned char reserved[4];
46};
47
48#define CCA_TKN_HDR_ID_EXT 0x1E
49
50struct cca_private_ext_ME_sec {
51 unsigned char section_identifier;
52 unsigned char version;
53 unsigned short section_length;
54 unsigned char private_key_hash[20];
55 unsigned char reserved1[4];
56 unsigned char key_format;
57 unsigned char reserved2;
58 unsigned char key_name_hash[20];
59 unsigned char key_use_flags[4];
60 unsigned char reserved3[6];
61 unsigned char reserved4[24];
62 unsigned char confounder[24];
63 unsigned char exponent[128];
64 unsigned char modulus[128];
65};
66
67#define CCA_PVT_USAGE_ALL 0x80
68
69struct cca_public_sec {
70 unsigned char section_identifier;
71 unsigned char version;
72 unsigned short section_length;
73 unsigned char reserved[2];
74 unsigned short exponent_len;
75 unsigned short modulus_bit_len;
76 unsigned short modulus_byte_len;
77 unsigned char exponent[3];
78};
79
80struct cca_private_ext_ME {
81 struct cca_token_hdr pvtMEHdr;
82 struct cca_private_ext_ME_sec pvtMESec;
83 struct cca_public_sec pubMESec;
84};
85
86struct cca_public_key {
87 struct cca_token_hdr pubHdr;
88 struct cca_public_sec pubSec;
89};
90
91struct cca_pvt_ext_CRT_sec {
92 unsigned char section_identifier;
93 unsigned char version;
94 unsigned short section_length;
95 unsigned char private_key_hash[20];
96 unsigned char reserved1[4];
97 unsigned char key_format;
98 unsigned char reserved2;
99 unsigned char key_name_hash[20];
100 unsigned char key_use_flags[4];
101 unsigned short p_len;
102 unsigned short q_len;
103 unsigned short dp_len;
104 unsigned short dq_len;
105 unsigned short u_len;
106 unsigned short mod_len;
107 unsigned char reserved3[4];
108 unsigned short pad_len;
109 unsigned char reserved4[52];
110 unsigned char confounder[8];
111};
112
113#define CCA_PVT_EXT_CRT_SEC_ID_PVT 0x08
114#define CCA_PVT_EXT_CRT_SEC_FMT_CL 0x40
115
116struct cca_private_ext_CRT {
117 struct cca_token_hdr pvtCrtHdr;
118 struct cca_pvt_ext_CRT_sec pvtCrtSec;
119 struct cca_public_sec pubCrtSec;
120};
121
122struct ap_status_word {
123 unsigned char q_stat_flags;
124 unsigned char response_code;
125 unsigned char reserved[2];
126};
127
128#define AP_Q_STATUS_EMPTY 0x80
129#define AP_Q_STATUS_REPLIES_WAITING 0x40
130#define AP_Q_STATUS_ARRAY_FULL 0x20
131
132#define AP_RESPONSE_NORMAL 0x00
133#define AP_RESPONSE_Q_NOT_AVAIL 0x01
134#define AP_RESPONSE_RESET_IN_PROGRESS 0x02
135#define AP_RESPONSE_DECONFIGURED 0x03
136#define AP_RESPONSE_CHECKSTOPPED 0x04
137#define AP_RESPONSE_BUSY 0x05
138#define AP_RESPONSE_Q_FULL 0x10
139#define AP_RESPONSE_NO_PENDING_REPLY 0x10
140#define AP_RESPONSE_INDEX_TOO_BIG 0x11
141#define AP_RESPONSE_NO_FIRST_PART 0x13
142#define AP_RESPONSE_MESSAGE_TOO_BIG 0x15
143
144#define AP_MAX_CDX_BITL 4
145#define AP_RQID_RESERVED_BITL 4
146#define SKIP_BITL (AP_MAX_CDX_BITL + AP_RQID_RESERVED_BITL)
147
148struct type4_hdr {
149 unsigned char reserved1;
150 unsigned char msg_type_code;
151 unsigned short msg_len;
152 unsigned char request_code;
153 unsigned char msg_fmt;
154 unsigned short reserved2;
155};
156
157#define TYPE4_TYPE_CODE 0x04
158#define TYPE4_REQU_CODE 0x40
159
160#define TYPE4_SME_LEN 0x0188
161#define TYPE4_LME_LEN 0x0308
162#define TYPE4_SCR_LEN 0x01E0
163#define TYPE4_LCR_LEN 0x03A0
164
165#define TYPE4_SME_FMT 0x00
166#define TYPE4_LME_FMT 0x10
167#define TYPE4_SCR_FMT 0x40
168#define TYPE4_LCR_FMT 0x50
169
170struct type4_sme {
171 struct type4_hdr header;
172 unsigned char message[128];
173 unsigned char exponent[128];
174 unsigned char modulus[128];
175};
176
177struct type4_lme {
178 struct type4_hdr header;
179 unsigned char message[256];
180 unsigned char exponent[256];
181 unsigned char modulus[256];
182};
183
184struct type4_scr {
185 struct type4_hdr header;
186 unsigned char message[128];
187 unsigned char dp[72];
188 unsigned char dq[64];
189 unsigned char p[72];
190 unsigned char q[64];
191 unsigned char u[72];
192};
193
194struct type4_lcr {
195 struct type4_hdr header;
196 unsigned char message[256];
197 unsigned char dp[136];
198 unsigned char dq[128];
199 unsigned char p[136];
200 unsigned char q[128];
201 unsigned char u[136];
202};
203
204union type4_msg {
205 struct type4_sme sme;
206 struct type4_lme lme;
207 struct type4_scr scr;
208 struct type4_lcr lcr;
209};
210
211struct type84_hdr {
212 unsigned char reserved1;
213 unsigned char code;
214 unsigned short len;
215 unsigned char reserved2[4];
216};
217
218#define TYPE84_RSP_CODE 0x84
219
220struct type6_hdr {
221 unsigned char reserved1;
222 unsigned char type;
223 unsigned char reserved2[2];
224 unsigned char right[4];
225 unsigned char reserved3[2];
226 unsigned char reserved4[2];
227 unsigned char apfs[4];
228 unsigned int offset1;
229 unsigned int offset2;
230 unsigned int offset3;
231 unsigned int offset4;
232 unsigned char agent_id[16];
233 unsigned char rqid[2];
234 unsigned char reserved5[2];
235 unsigned char function_code[2];
236 unsigned char reserved6[2];
237 unsigned int ToCardLen1;
238 unsigned int ToCardLen2;
239 unsigned int ToCardLen3;
240 unsigned int ToCardLen4;
241 unsigned int FromCardLen1;
242 unsigned int FromCardLen2;
243 unsigned int FromCardLen3;
244 unsigned int FromCardLen4;
245};
246
247struct CPRB {
248 unsigned char cprb_len[2];
249 unsigned char cprb_ver_id;
250 unsigned char pad_000;
251 unsigned char srpi_rtcode[4];
252 unsigned char srpi_verb;
253 unsigned char flags;
254 unsigned char func_id[2];
255 unsigned char checkpoint_flag;
256 unsigned char resv2;
257 unsigned char req_parml[2];
258 unsigned char req_parmp[4];
259 unsigned char req_datal[4];
260 unsigned char req_datap[4];
261 unsigned char rpl_parml[2];
262 unsigned char pad_001[2];
263 unsigned char rpl_parmp[4];
264 unsigned char rpl_datal[4];
265 unsigned char rpl_datap[4];
266 unsigned char ccp_rscode[2];
267 unsigned char ccp_rtcode[2];
268 unsigned char repd_parml[2];
269 unsigned char mac_data_len[2];
270 unsigned char repd_datal[4];
271 unsigned char req_pc[2];
272 unsigned char res_origin[8];
273 unsigned char mac_value[8];
274 unsigned char logon_id[8];
275 unsigned char usage_domain[2];
276 unsigned char resv3[18];
277 unsigned char svr_namel[2];
278 unsigned char svr_name[8];
279};
280
281struct type6_msg {
282 struct type6_hdr header;
283 struct CPRB CPRB;
284};
285
1da177e4
LT
286struct type86_hdr {
287 unsigned char reserved1;
288 unsigned char type;
289 unsigned char format;
290 unsigned char reserved2;
291 unsigned char reply_code;
292 unsigned char reserved3[3];
293};
294
295#define TYPE86_RSP_CODE 0x86
296#define TYPE86_FMT2 0x02
297
298struct type86_fmt2_msg {
2dee702f 299 struct type86_hdr header;
1da177e4
LT
300 unsigned char reserved[4];
301 unsigned char apfs[4];
302 unsigned int count1;
303 unsigned int offset1;
304 unsigned int count2;
305 unsigned int offset2;
306 unsigned int count3;
307 unsigned int offset3;
308 unsigned int count4;
309 unsigned int offset4;
310};
311
312static struct type6_hdr static_type6_hdr = {
313 0x00,
314 0x06,
315 {0x00,0x00},
316 {0x00,0x00,0x00,0x00},
317 {0x00,0x00},
318 {0x00,0x00},
319 {0x00,0x00,0x00,0x00},
320 0x00000058,
321 0x00000000,
322 0x00000000,
323 0x00000000,
324 {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
325 0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
326 {0x00,0x00},
327 {0x00,0x00},
328 {0x50,0x44},
329 {0x00,0x00},
330 0x00000000,
331 0x00000000,
332 0x00000000,
333 0x00000000,
334 0x00000000,
335 0x00000000,
336 0x00000000,
337 0x00000000
338};
339
340static struct type6_hdr static_type6_hdrX = {
341 0x00,
342 0x06,
343 {0x00,0x00},
344 {0x00,0x00,0x00,0x00},
345 {0x00,0x00},
346 {0x00,0x00},
347 {0x00,0x00,0x00,0x00},
348 0x00000058,
349 0x00000000,
350 0x00000000,
351 0x00000000,
352 {0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
353 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
354 {0x00,0x00},
355 {0x00,0x00},
356 {0x50,0x44},
357 {0x00,0x00},
358 0x00000000,
359 0x00000000,
360 0x00000000,
361 0x00000000,
362 0x00000000,
363 0x00000000,
364 0x00000000,
365 0x00000000
366};
367
368static struct CPRB static_cprb = {
369 {0x70,0x00},
370 0x41,
371 0x00,
372 {0x00,0x00,0x00,0x00},
373 0x00,
374 0x00,
375 {0x54,0x32},
376 0x01,
377 0x00,
378 {0x00,0x00},
379 {0x00,0x00,0x00,0x00},
380 {0x00,0x00,0x00,0x00},
381 {0x00,0x00,0x00,0x00},
382 {0x00,0x00},
383 {0x00,0x00},
384 {0x00,0x00,0x00,0x00},
385 {0x00,0x00,0x00,0x00},
386 {0x00,0x00,0x00,0x00},
387 {0x00,0x00},
388 {0x00,0x00},
389 {0x00,0x00},
390 {0x00,0x00},
391 {0x00,0x00,0x00,0x00},
392 {0x00,0x00},
393 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
394 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
395 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
396 {0x00,0x00},
397 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
398 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
399 0x00,0x00},
400 {0x08,0x00},
401 {0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20}
402};
403
404struct function_and_rules_block {
405 unsigned char function_code[2];
406 unsigned char ulen[2];
407 unsigned char only_rule[8];
408};
409
410static struct function_and_rules_block static_pkd_function_and_rules = {
411 {0x50,0x44},
412 {0x0A,0x00},
413 {'P','K','C','S','-','1','.','2'}
414};
415
416static struct function_and_rules_block static_pke_function_and_rules = {
417 {0x50,0x4B},
418 {0x0A,0x00},
419 {'P','K','C','S','-','1','.','2'}
420};
421
422struct T6_keyBlock_hdr {
423 unsigned char blen[2];
424 unsigned char ulen[2];
425 unsigned char flags[2];
426};
427
428static struct T6_keyBlock_hdr static_T6_keyBlock_hdr = {
429 {0x89,0x01},
430 {0x87,0x01},
431 {0x00}
432};
433
434static struct CPRBX static_cprbx = {
435 0x00DC,
436 0x02,
437 {0x00,0x00,0x00},
438 {0x54,0x32},
439 {0x00,0x00,0x00,0x00},
440 0x00000000,
441 0x00000000,
442 0x00000000,
443 0x00000000,
444 0x00000000,
445 0x00000000,
446 0x00000000,
447 {0x00,0x00,0x00,0x00},
448 0x00000000,
449 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
450 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
451 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
452 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
453 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
454 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
455 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
456 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
457 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
458 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
459 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
460 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
461 0x0000,
462 0x0000,
463 0x00000000,
464 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
465 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
466 0x00,
467 0x00,
468 0x0000,
469 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
470 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
471 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
472 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
473};
474
475static struct function_and_rules_block static_pkd_function_and_rulesX_MCL2 = {
476 {0x50,0x44},
477 {0x00,0x0A},
478 {'P','K','C','S','-','1','.','2'}
479};
480
481static struct function_and_rules_block static_pke_function_and_rulesX_MCL2 = {
482 {0x50,0x4B},
483 {0x00,0x0A},
484 {'Z','E','R','O','-','P','A','D'}
485};
486
487static struct function_and_rules_block static_pkd_function_and_rulesX = {
488 {0x50,0x44},
489 {0x00,0x0A},
490 {'Z','E','R','O','-','P','A','D'}
491};
492
493static struct function_and_rules_block static_pke_function_and_rulesX = {
494 {0x50,0x4B},
495 {0x00,0x0A},
496 {'M','R','P',' ',' ',' ',' ',' '}
497};
498
2dee702f
ER
499static unsigned char static_PKE_function_code[2] = {0x50, 0x4B};
500
1da177e4
LT
501struct T6_keyBlock_hdrX {
502 unsigned short blen;
503 unsigned short ulen;
504 unsigned char flags[2];
505};
506
507static unsigned char static_pad[256] = {
5080x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
5090x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
5100xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
5110x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
5120x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
5130x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
5140x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
5150xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
5160x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
5170x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
5180x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
5190x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
5200x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
5210x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
5220x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
5230x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
524};
525
526static struct cca_private_ext_ME static_pvt_me_key = {
527 {
528 0x1E,
529 0x00,
530 0x0183,
531 {0x00,0x00,0x00,0x00}
532 },
533
534 {
535 0x02,
536 0x00,
537 0x016C,
538 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
539 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
540 0x00,0x00,0x00,0x00},
541 {0x00,0x00,0x00,0x00},
542 0x00,
543 0x00,
544 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
545 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
546 0x00,0x00,0x00,0x00},
547 {0x80,0x00,0x00,0x00},
548 {0x00,0x00,0x00,0x00,0x00,0x00},
549 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
550 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
551 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
552 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
553 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
554 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
555 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
556 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
557 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
558 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
560 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
561 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
562 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
563 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
564 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
565 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
566 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
567 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
568 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
569 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
570 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
571 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
572 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
573 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
574 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
575 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
576 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
577 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
578 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
579 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
580 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
581 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
582 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
583 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
584 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
585 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
586 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
587 },
588
589 {
590 0x04,
591 0x00,
592 0x000F,
593 {0x00,0x00},
594 0x0003,
595 0x0000,
596 0x0000,
597 {0x01,0x00,0x01}
598 }
599};
600
601static struct cca_public_key static_public_key = {
602 {
603 0x1E,
604 0x00,
605 0x0000,
606 {0x00,0x00,0x00,0x00}
607 },
608
609 {
610 0x04,
611 0x00,
612 0x0000,
613 {0x00,0x00},
614 0x0000,
615 0x0000,
616 0x0000,
617 {0x01,0x00,0x01}
618 }
619};
620
621#define FIXED_TYPE6_ME_LEN 0x0000025F
622
623#define FIXED_TYPE6_ME_EN_LEN 0x000000F0
624
625#define FIXED_TYPE6_ME_LENX 0x000002CB
626
627#define FIXED_TYPE6_ME_EN_LENX 0x0000015C
628
629static struct cca_public_sec static_cca_pub_sec = {
630 0x04,
631 0x00,
632 0x000f,
633 {0x00,0x00},
634 0x0003,
635 0x0000,
636 0x0000,
637 {0x01,0x00,0x01}
638};
639
640#define FIXED_TYPE6_CR_LEN 0x00000177
641
642#define FIXED_TYPE6_CR_LENX 0x000001E3
643
644#define MAX_RESPONSE_SIZE 0x00000710
645
646#define MAX_RESPONSEX_SIZE 0x0000077C
647
648#define RESPONSE_CPRB_SIZE 0x000006B8
649#define RESPONSE_CPRBX_SIZE 0x00000724
650
88fbf183
ER
651struct type50_hdr {
652 u8 reserved1;
653 u8 msg_type_code;
654 u16 msg_len;
655 u8 reserved2;
656 u8 ignored;
657 u16 reserved3;
658};
659
660#define TYPE50_TYPE_CODE 0x50
661
662#define TYPE50_MEB1_LEN (sizeof(struct type50_meb1_msg))
663#define TYPE50_MEB2_LEN (sizeof(struct type50_meb2_msg))
664#define TYPE50_CRB1_LEN (sizeof(struct type50_crb1_msg))
665#define TYPE50_CRB2_LEN (sizeof(struct type50_crb2_msg))
666
667#define TYPE50_MEB1_FMT 0x0001
668#define TYPE50_MEB2_FMT 0x0002
669#define TYPE50_CRB1_FMT 0x0011
670#define TYPE50_CRB2_FMT 0x0012
671
672struct type50_meb1_msg {
673 struct type50_hdr header;
674 u16 keyblock_type;
675 u8 reserved[6];
676 u8 exponent[128];
677 u8 modulus[128];
678 u8 message[128];
679};
680
681struct type50_meb2_msg {
682 struct type50_hdr header;
683 u16 keyblock_type;
684 u8 reserved[6];
685 u8 exponent[256];
686 u8 modulus[256];
687 u8 message[256];
688};
689
690struct type50_crb1_msg {
691 struct type50_hdr header;
692 u16 keyblock_type;
693 u8 reserved[6];
694 u8 p[64];
695 u8 q[64];
696 u8 dp[64];
697 u8 dq[64];
698 u8 u[64];
699 u8 message[128];
700};
701
702struct type50_crb2_msg {
703 struct type50_hdr header;
704 u16 keyblock_type;
705 u8 reserved[6];
706 u8 p[128];
707 u8 q[128];
708 u8 dp[128];
709 u8 dq[128];
710 u8 u[128];
711 u8 message[256];
712};
713
714union type50_msg {
715 struct type50_meb1_msg meb1;
716 struct type50_meb2_msg meb2;
717 struct type50_crb1_msg crb1;
718 struct type50_crb2_msg crb2;
719};
720
721struct type80_hdr {
722 u8 reserved1;
723 u8 type;
724 u16 len;
725 u8 code;
726 u8 reserved2[3];
727 u8 reserved3[8];
728};
729
730#define TYPE80_RSP_CODE 0x80
731
2dee702f
ER
732struct error_hdr {
733 unsigned char reserved1;
734 unsigned char type;
735 unsigned char reserved2[2];
736 unsigned char reply_code;
737 unsigned char reserved3[3];
738};
1da177e4 739
2dee702f 740#define TYPE82_RSP_CODE 0x82
88fbf183 741#define TYPE88_RSP_CODE 0x88
2dee702f
ER
742
743#define REP82_ERROR_MACHINE_FAILURE 0x10
744#define REP82_ERROR_PREEMPT_FAILURE 0x12
745#define REP82_ERROR_CHECKPT_FAILURE 0x14
746#define REP82_ERROR_MESSAGE_TYPE 0x20
747#define REP82_ERROR_INVALID_COMM_CD 0x21
748#define REP82_ERROR_INVALID_MSG_LEN 0x23
749#define REP82_ERROR_RESERVD_FIELD 0x24
750#define REP82_ERROR_FORMAT_FIELD 0x29
751#define REP82_ERROR_INVALID_COMMAND 0x30
752#define REP82_ERROR_MALFORMED_MSG 0x40
753#define REP82_ERROR_RESERVED_FIELDO 0x50
754#define REP82_ERROR_WORD_ALIGNMENT 0x60
755#define REP82_ERROR_MESSAGE_LENGTH 0x80
756#define REP82_ERROR_OPERAND_INVALID 0x82
757#define REP82_ERROR_OPERAND_SIZE 0x84
758#define REP82_ERROR_EVEN_MOD_IN_OPND 0x85
759#define REP82_ERROR_RESERVED_FIELD 0x88
760#define REP82_ERROR_TRANSPORT_FAIL 0x90
761#define REP82_ERROR_PACKET_TRUNCATED 0xA0
762#define REP82_ERROR_ZERO_BUFFER_LEN 0xB0
763
88fbf183
ER
764#define REP88_ERROR_MODULE_FAILURE 0x10
765#define REP88_ERROR_MODULE_TIMEOUT 0x11
766#define REP88_ERROR_MODULE_NOTINIT 0x13
767#define REP88_ERROR_MODULE_NOTAVAIL 0x14
768#define REP88_ERROR_MODULE_DISABLED 0x15
769#define REP88_ERROR_MODULE_IN_DIAGN 0x17
770#define REP88_ERROR_FASTPATH_DISABLD 0x19
771#define REP88_ERROR_MESSAGE_TYPE 0x20
772#define REP88_ERROR_MESSAGE_MALFORMD 0x22
773#define REP88_ERROR_MESSAGE_LENGTH 0x23
774#define REP88_ERROR_RESERVED_FIELD 0x24
775#define REP88_ERROR_KEY_TYPE 0x34
776#define REP88_ERROR_INVALID_KEY 0x82
777#define REP88_ERROR_OPERAND 0x84
778#define REP88_ERROR_OPERAND_EVEN_MOD 0x85
779
2dee702f 780#define CALLER_HEADER 12
1da177e4
LT
781
782static inline int
783testq(int q_nr, int *q_depth, int *dev_type, struct ap_status_word *stat)
784{
785 int ccode;
786
787 asm volatile
347a8dc3 788#ifdef CONFIG_64BIT
1da177e4
LT
789 (" llgfr 0,%4 \n"
790 " slgr 1,1 \n"
791 " lgr 2,1 \n"
792 "0: .long 0xb2af0000 \n"
793 "1: ipm %0 \n"
794 " srl %0,28 \n"
795 " iihh %0,0 \n"
796 " iihl %0,0 \n"
797 " lgr %1,1 \n"
798 " lgr %3,2 \n"
799 " srl %3,24 \n"
800 " sll 2,24 \n"
801 " srl 2,24 \n"
802 " lgr %2,2 \n"
803 "2: \n"
804 ".section .fixup,\"ax\" \n"
805 "3: \n"
806 " lhi %0,%h5 \n"
807 " jg 2b \n"
808 ".previous \n"
809 ".section __ex_table,\"a\" \n"
810 " .align 8 \n"
811 " .quad 0b,3b \n"
812 " .quad 1b,3b \n"
813 ".previous"
814 :"=d" (ccode),"=d" (*stat),"=d" (*q_depth), "=d" (*dev_type)
815 :"d" (q_nr), "K" (DEV_TSQ_EXCEPTION)
816 :"cc","0","1","2","memory");
817#else
818 (" lr 0,%4 \n"
819 " slr 1,1 \n"
820 " lr 2,1 \n"
821 "0: .long 0xb2af0000 \n"
822 "1: ipm %0 \n"
823 " srl %0,28 \n"
824 " lr %1,1 \n"
825 " lr %3,2 \n"
826 " srl %3,24 \n"
827 " sll 2,24 \n"
828 " srl 2,24 \n"
829 " lr %2,2 \n"
830 "2: \n"
831 ".section .fixup,\"ax\" \n"
832 "3: \n"
833 " lhi %0,%h5 \n"
834 " bras 1,4f \n"
835 " .long 2b \n"
836 "4: \n"
837 " l 1,0(1) \n"
838 " br 1 \n"
839 ".previous \n"
840 ".section __ex_table,\"a\" \n"
841 " .align 4 \n"
842 " .long 0b,3b \n"
843 " .long 1b,3b \n"
844 ".previous"
845 :"=d" (ccode),"=d" (*stat),"=d" (*q_depth), "=d" (*dev_type)
846 :"d" (q_nr), "K" (DEV_TSQ_EXCEPTION)
847 :"cc","0","1","2","memory");
848#endif
849 return ccode;
850}
851
852static inline int
853resetq(int q_nr, struct ap_status_word *stat_p)
854{
855 int ccode;
856
857 asm volatile
347a8dc3 858#ifdef CONFIG_64BIT
1da177e4
LT
859 (" llgfr 0,%2 \n"
860 " lghi 1,1 \n"
861 " sll 1,24 \n"
862 " or 0,1 \n"
863 " slgr 1,1 \n"
864 " lgr 2,1 \n"
865 "0: .long 0xb2af0000 \n"
866 "1: ipm %0 \n"
867 " srl %0,28 \n"
868 " iihh %0,0 \n"
869 " iihl %0,0 \n"
870 " lgr %1,1 \n"
871 "2: \n"
872 ".section .fixup,\"ax\" \n"
873 "3: \n"
874 " lhi %0,%h3 \n"
875 " jg 2b \n"
876 ".previous \n"
877 ".section __ex_table,\"a\" \n"
878 " .align 8 \n"
879 " .quad 0b,3b \n"
880 " .quad 1b,3b \n"
881 ".previous"
882 :"=d" (ccode),"=d" (*stat_p)
883 :"d" (q_nr), "K" (DEV_RSQ_EXCEPTION)
884 :"cc","0","1","2","memory");
885#else
886 (" lr 0,%2 \n"
887 " lhi 1,1 \n"
888 " sll 1,24 \n"
889 " or 0,1 \n"
890 " slr 1,1 \n"
891 " lr 2,1 \n"
892 "0: .long 0xb2af0000 \n"
893 "1: ipm %0 \n"
894 " srl %0,28 \n"
895 " lr %1,1 \n"
896 "2: \n"
897 ".section .fixup,\"ax\" \n"
898 "3: \n"
899 " lhi %0,%h3 \n"
900 " bras 1,4f \n"
901 " .long 2b \n"
902 "4: \n"
903 " l 1,0(1) \n"
904 " br 1 \n"
905 ".previous \n"
906 ".section __ex_table,\"a\" \n"
907 " .align 4 \n"
908 " .long 0b,3b \n"
909 " .long 1b,3b \n"
910 ".previous"
911 :"=d" (ccode),"=d" (*stat_p)
912 :"d" (q_nr), "K" (DEV_RSQ_EXCEPTION)
913 :"cc","0","1","2","memory");
914#endif
915 return ccode;
916}
917
918static inline int
919sen(int msg_len, unsigned char *msg_ext, struct ap_status_word *stat)
920{
921 int ccode;
922
923 asm volatile
347a8dc3 924#ifdef CONFIG_64BIT
1da177e4
LT
925 (" lgr 6,%3 \n"
926 " llgfr 7,%2 \n"
927 " llgt 0,0(6) \n"
928 " lghi 1,64 \n"
929 " sll 1,24 \n"
930 " or 0,1 \n"
931 " la 6,4(6) \n"
932 " llgt 2,0(6) \n"
933 " llgt 3,4(6) \n"
934 " la 6,8(6) \n"
935 " slr 1,1 \n"
936 "0: .long 0xb2ad0026 \n"
937 "1: brc 2,0b \n"
938 " ipm %0 \n"
939 " srl %0,28 \n"
940 " iihh %0,0 \n"
941 " iihl %0,0 \n"
942 " lgr %1,1 \n"
943 "2: \n"
944 ".section .fixup,\"ax\" \n"
945 "3: \n"
946 " lhi %0,%h4 \n"
947 " jg 2b \n"
948 ".previous \n"
949 ".section __ex_table,\"a\" \n"
950 " .align 8 \n"
951 " .quad 0b,3b \n"
952 " .quad 1b,3b \n"
953 ".previous"
954 :"=d" (ccode),"=d" (*stat)
955 :"d" (msg_len),"a" (msg_ext), "K" (DEV_SEN_EXCEPTION)
956 :"cc","0","1","2","3","6","7","memory");
957#else
958 (" lr 6,%3 \n"
959 " lr 7,%2 \n"
960 " l 0,0(6) \n"
961 " lhi 1,64 \n"
962 " sll 1,24 \n"
963 " or 0,1 \n"
964 " la 6,4(6) \n"
965 " l 2,0(6) \n"
966 " l 3,4(6) \n"
967 " la 6,8(6) \n"
968 " slr 1,1 \n"
969 "0: .long 0xb2ad0026 \n"
970 "1: brc 2,0b \n"
971 " ipm %0 \n"
972 " srl %0,28 \n"
973 " lr %1,1 \n"
974 "2: \n"
975 ".section .fixup,\"ax\" \n"
976 "3: \n"
977 " lhi %0,%h4 \n"
978 " bras 1,4f \n"
979 " .long 2b \n"
980 "4: \n"
981 " l 1,0(1) \n"
982 " br 1 \n"
983 ".previous \n"
984 ".section __ex_table,\"a\" \n"
985 " .align 4 \n"
986 " .long 0b,3b \n"
987 " .long 1b,3b \n"
988 ".previous"
989 :"=d" (ccode),"=d" (*stat)
990 :"d" (msg_len),"a" (msg_ext), "K" (DEV_SEN_EXCEPTION)
991 :"cc","0","1","2","3","6","7","memory");
992#endif
993 return ccode;
994}
995
996static inline int
997rec(int q_nr, int buff_l, unsigned char *rsp, unsigned char *id,
998 struct ap_status_word *st)
999{
1000 int ccode;
1001
1002 asm volatile
347a8dc3 1003#ifdef CONFIG_64BIT
1da177e4
LT
1004 (" llgfr 0,%2 \n"
1005 " lgr 3,%4 \n"
1006 " lgr 6,%3 \n"
1007 " llgfr 7,%5 \n"
1008 " lghi 1,128 \n"
1009 " sll 1,24 \n"
1010 " or 0,1 \n"
1011 " slgr 1,1 \n"
1012 " lgr 2,1 \n"
1013 " lgr 4,1 \n"
1014 " lgr 5,1 \n"
1015 "0: .long 0xb2ae0046 \n"
1016 "1: brc 2,0b \n"
1017 " brc 4,0b \n"
1018 " ipm %0 \n"
1019 " srl %0,28 \n"
1020 " iihh %0,0 \n"
1021 " iihl %0,0 \n"
1022 " lgr %1,1 \n"
1023 " st 4,0(3) \n"
1024 " st 5,4(3) \n"
1025 "2: \n"
1026 ".section .fixup,\"ax\" \n"
1027 "3: \n"
1028 " lhi %0,%h6 \n"
1029 " jg 2b \n"
1030 ".previous \n"
1031 ".section __ex_table,\"a\" \n"
1032 " .align 8 \n"
1033 " .quad 0b,3b \n"
1034 " .quad 1b,3b \n"
1035 ".previous"
1036 :"=d"(ccode),"=d"(*st)
1037 :"d" (q_nr), "d" (rsp), "d" (id), "d" (buff_l), "K" (DEV_REC_EXCEPTION)
1038 :"cc","0","1","2","3","4","5","6","7","memory");
1039#else
1040 (" lr 0,%2 \n"
1041 " lr 3,%4 \n"
1042 " lr 6,%3 \n"
1043 " lr 7,%5 \n"
1044 " lhi 1,128 \n"
1045 " sll 1,24 \n"
1046 " or 0,1 \n"
1047 " slr 1,1 \n"
1048 " lr 2,1 \n"
1049 " lr 4,1 \n"
1050 " lr 5,1 \n"
1051 "0: .long 0xb2ae0046 \n"
1052 "1: brc 2,0b \n"
1053 " brc 4,0b \n"
1054 " ipm %0 \n"
1055 " srl %0,28 \n"
1056 " lr %1,1 \n"
1057 " st 4,0(3) \n"
1058 " st 5,4(3) \n"
1059 "2: \n"
1060 ".section .fixup,\"ax\" \n"
1061 "3: \n"
1062 " lhi %0,%h6 \n"
1063 " bras 1,4f \n"
1064 " .long 2b \n"
1065 "4: \n"
1066 " l 1,0(1) \n"
1067 " br 1 \n"
1068 ".previous \n"
1069 ".section __ex_table,\"a\" \n"
1070 " .align 4 \n"
1071 " .long 0b,3b \n"
1072 " .long 1b,3b \n"
1073 ".previous"
1074 :"=d"(ccode),"=d"(*st)
1075 :"d" (q_nr), "d" (rsp), "d" (id), "d" (buff_l), "K" (DEV_REC_EXCEPTION)
1076 :"cc","0","1","2","3","4","5","6","7","memory");
1077#endif
1078 return ccode;
1079}
1080
1081static inline void
1082itoLe2(int *i_p, unsigned char *lechars)
1083{
1084 *lechars = *((unsigned char *) i_p + sizeof(int) - 1);
1085 *(lechars + 1) = *((unsigned char *) i_p + sizeof(int) - 2);
1086}
1087
1088static inline void
1089le2toI(unsigned char *lechars, int *i_p)
1090{
1091 unsigned char *ic_p;
1092 *i_p = 0;
1093 ic_p = (unsigned char *) i_p;
1094 *(ic_p + 2) = *(lechars + 1);
1095 *(ic_p + 3) = *(lechars);
1096}
1097
1098static inline int
1099is_empty(unsigned char *ptr, int len)
1100{
1101 return !memcmp(ptr, (unsigned char *) &static_pvt_me_key+60, len);
1102}
1103
1104enum hdstat
1105query_online(int deviceNr, int cdx, int resetNr, int *q_depth, int *dev_type)
1106{
1107 int q_nr, i, t_depth, t_dev_type;
1108 enum devstat ccode;
1109 struct ap_status_word stat_word;
1110 enum hdstat stat;
1111 int break_out;
1112
1113 q_nr = (deviceNr << SKIP_BITL) + cdx;
1114 stat = HD_BUSY;
1115 ccode = testq(q_nr, &t_depth, &t_dev_type, &stat_word);
1116 PDEBUG("ccode %d response_code %02X\n", ccode, stat_word.response_code);
1117 break_out = 0;
1118 for (i = 0; i < resetNr; i++) {
1119 if (ccode > 3) {
1120 PRINTKC("Exception testing device %d\n", i);
1121 return HD_TSQ_EXCEPTION;
1122 }
1123 switch (ccode) {
1124 case 0:
1125 PDEBUG("t_dev_type %d\n", t_dev_type);
1126 break_out = 1;
1127 stat = HD_ONLINE;
1128 *q_depth = t_depth + 1;
1129 switch (t_dev_type) {
1da177e4
LT
1130 case PCICA_HW:
1131 *dev_type = PCICA;
1132 break;
1133 case PCICC_HW:
1134 *dev_type = PCICC;
1135 break;
1136 case PCIXCC_HW:
1137 *dev_type = PCIXCC_UNK;
1138 break;
1139 case CEX2C_HW:
1140 *dev_type = CEX2C;
1141 break;
88fbf183
ER
1142 case CEX2A_HW:
1143 *dev_type = CEX2A;
1144 break;
1da177e4
LT
1145 default:
1146 *dev_type = NILDEV;
1147 break;
1148 }
1149 PDEBUG("available device %d: Q depth = %d, dev "
1150 "type = %d, stat = %02X%02X%02X%02X\n",
1151 deviceNr, *q_depth, *dev_type,
1152 stat_word.q_stat_flags,
1153 stat_word.response_code,
1154 stat_word.reserved[0],
1155 stat_word.reserved[1]);
1156 break;
1157 case 3:
1158 switch (stat_word.response_code) {
1159 case AP_RESPONSE_NORMAL:
1160 stat = HD_ONLINE;
1161 break_out = 1;
1162 *q_depth = t_depth + 1;
1163 *dev_type = t_dev_type;
1164 PDEBUG("cc3, available device "
1165 "%d: Q depth = %d, dev "
1166 "type = %d, stat = "
1167 "%02X%02X%02X%02X\n",
1168 deviceNr, *q_depth,
1169 *dev_type,
1170 stat_word.q_stat_flags,
1171 stat_word.response_code,
1172 stat_word.reserved[0],
1173 stat_word.reserved[1]);
1174 break;
1175 case AP_RESPONSE_Q_NOT_AVAIL:
1176 stat = HD_NOT_THERE;
1177 break_out = 1;
1178 break;
1179 case AP_RESPONSE_RESET_IN_PROGRESS:
1180 PDEBUG("device %d in reset\n",
1181 deviceNr);
1182 break;
1183 case AP_RESPONSE_DECONFIGURED:
1184 stat = HD_DECONFIGURED;
1185 break_out = 1;
1186 break;
1187 case AP_RESPONSE_CHECKSTOPPED:
1188 stat = HD_CHECKSTOPPED;
1189 break_out = 1;
1190 break;
1191 case AP_RESPONSE_BUSY:
1192 PDEBUG("device %d busy\n",
1193 deviceNr);
1194 break;
1195 default:
1196 break;
1197 }
1198 break;
1199 default:
1200 stat = HD_NOT_THERE;
1201 break_out = 1;
1202 break;
1203 }
1204 if (break_out)
1205 break;
1206
1207 udelay(5);
1208
1209 ccode = testq(q_nr, &t_depth, &t_dev_type, &stat_word);
1210 }
1211 return stat;
1212}
1213
1214enum devstat
1215reset_device(int deviceNr, int cdx, int resetNr)
1216{
1217 int q_nr, ccode = 0, dummy_qdepth, dummy_devType, i;
1218 struct ap_status_word stat_word;
1219 enum devstat stat;
1220 int break_out;
1221
1222 q_nr = (deviceNr << SKIP_BITL) + cdx;
1223 stat = DEV_GONE;
1224 ccode = resetq(q_nr, &stat_word);
1225 if (ccode > 3)
1226 return DEV_RSQ_EXCEPTION;
1227
1228 break_out = 0;
1229 for (i = 0; i < resetNr; i++) {
1230 switch (ccode) {
1231 case 0:
1232 stat = DEV_ONLINE;
1233 if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY)
1234 break_out = 1;
1235 break;
1236 case 3:
1237 switch (stat_word.response_code) {
1238 case AP_RESPONSE_NORMAL:
1239 stat = DEV_ONLINE;
1240 if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY)
1241 break_out = 1;
1242 break;
1243 case AP_RESPONSE_Q_NOT_AVAIL:
1244 case AP_RESPONSE_DECONFIGURED:
1245 case AP_RESPONSE_CHECKSTOPPED:
1246 stat = DEV_GONE;
1247 break_out = 1;
1248 break;
1249 case AP_RESPONSE_RESET_IN_PROGRESS:
1250 case AP_RESPONSE_BUSY:
1251 default:
1252 break;
1253 }
1254 break;
1255 default:
1256 stat = DEV_GONE;
1257 break_out = 1;
1258 break;
1259 }
1260 if (break_out == 1)
1261 break;
1262 udelay(5);
1263
1264 ccode = testq(q_nr, &dummy_qdepth, &dummy_devType, &stat_word);
1265 if (ccode > 3) {
1266 stat = DEV_TSQ_EXCEPTION;
1267 break;
1268 }
1269 }
1270 PDEBUG("Number of testq's needed for reset: %d\n", i);
1271
1272 if (i >= resetNr) {
1273 stat = DEV_GONE;
1274 }
1275
1276 return stat;
1277}
1278
1279#ifdef DEBUG_HYDRA_MSGS
1280static inline void
1281print_buffer(unsigned char *buffer, int bufflen)
1282{
1283 int i;
1284 for (i = 0; i < bufflen; i += 16) {
1285 PRINTK("%04X: %02X%02X%02X%02X %02X%02X%02X%02X "
1286 "%02X%02X%02X%02X %02X%02X%02X%02X\n", i,
1287 buffer[i+0], buffer[i+1], buffer[i+2], buffer[i+3],
1288 buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7],
1289 buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11],
1290 buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
1291 }
1292}
1293#endif
1294
1295enum devstat
1296send_to_AP(int dev_nr, int cdx, int msg_len, unsigned char *msg_ext)
1297{
1298 struct ap_status_word stat_word;
1299 enum devstat stat;
1300 int ccode;
2dee702f 1301 u32 *q_nr_p = (u32 *)msg_ext;
1da177e4 1302
2dee702f 1303 *q_nr_p = (dev_nr << SKIP_BITL) + cdx;
1da177e4
LT
1304 PDEBUG("msg_len passed to sen: %d\n", msg_len);
1305 PDEBUG("q number passed to sen: %02x%02x%02x%02x\n",
1306 msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3]);
1307 stat = DEV_GONE;
1308
1309#ifdef DEBUG_HYDRA_MSGS
1310 PRINTK("Request header: %02X%02X%02X%02X %02X%02X%02X%02X "
1311 "%02X%02X%02X%02X\n",
1312 msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3],
1313 msg_ext[4], msg_ext[5], msg_ext[6], msg_ext[7],
1314 msg_ext[8], msg_ext[9], msg_ext[10], msg_ext[11]);
1315 print_buffer(msg_ext+CALLER_HEADER, msg_len);
1316#endif
1317
1318 ccode = sen(msg_len, msg_ext, &stat_word);
1319 if (ccode > 3)
1320 return DEV_SEN_EXCEPTION;
1321
1322 PDEBUG("nq cc: %u, st: %02x%02x%02x%02x\n",
1323 ccode, stat_word.q_stat_flags, stat_word.response_code,
1324 stat_word.reserved[0], stat_word.reserved[1]);
1325 switch (ccode) {
1326 case 0:
1327 stat = DEV_ONLINE;
1328 break;
1329 case 1:
1330 stat = DEV_GONE;
1331 break;
1332 case 3:
1333 switch (stat_word.response_code) {
1334 case AP_RESPONSE_NORMAL:
1335 stat = DEV_ONLINE;
1336 break;
1337 case AP_RESPONSE_Q_FULL:
1338 stat = DEV_QUEUE_FULL;
1339 break;
1340 default:
1341 stat = DEV_GONE;
1342 break;
1343 }
1344 break;
1345 default:
1346 stat = DEV_GONE;
1347 break;
1348 }
1349
1350 return stat;
1351}
1352
1353enum devstat
1354receive_from_AP(int dev_nr, int cdx, int resplen, unsigned char *resp,
1355 unsigned char *psmid)
1356{
1357 int ccode;
1358 struct ap_status_word stat_word;
1359 enum devstat stat;
1360
1361 memset(resp, 0x00, 8);
1362
1363 ccode = rec((dev_nr << SKIP_BITL) + cdx, resplen, resp, psmid,
1364 &stat_word);
1365 if (ccode > 3)
1366 return DEV_REC_EXCEPTION;
1367
1368 PDEBUG("dq cc: %u, st: %02x%02x%02x%02x\n",
1369 ccode, stat_word.q_stat_flags, stat_word.response_code,
1370 stat_word.reserved[0], stat_word.reserved[1]);
1371
1372 stat = DEV_GONE;
1373 switch (ccode) {
1374 case 0:
1375 stat = DEV_ONLINE;
1376#ifdef DEBUG_HYDRA_MSGS
1377 print_buffer(resp, resplen);
1378#endif
1379 break;
1380 case 3:
1381 switch (stat_word.response_code) {
1382 case AP_RESPONSE_NORMAL:
1383 stat = DEV_ONLINE;
1384 break;
1385 case AP_RESPONSE_NO_PENDING_REPLY:
1386 if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY)
1387 stat = DEV_EMPTY;
1388 else
1389 stat = DEV_NO_WORK;
1390 break;
1391 case AP_RESPONSE_INDEX_TOO_BIG:
1392 case AP_RESPONSE_NO_FIRST_PART:
1393 case AP_RESPONSE_MESSAGE_TOO_BIG:
1394 stat = DEV_BAD_MESSAGE;
1395 break;
1396 default:
1397 break;
1398 }
1399 break;
1400 default:
1401 break;
1402 }
1403
1404 return stat;
1405}
1406
1407static inline int
1408pad_msg(unsigned char *buffer, int totalLength, int msgLength)
1409{
1410 int pad_len;
1411
1412 for (pad_len = 0; pad_len < (totalLength - msgLength); pad_len++)
1413 if (buffer[pad_len] != 0x00)
1414 break;
1415 pad_len -= 3;
1416 if (pad_len < 8)
1417 return SEN_PAD_ERROR;
1418
1419 buffer[0] = 0x00;
1420 buffer[1] = 0x02;
1421
1422 memcpy(buffer+2, static_pad, pad_len);
1423
1424 buffer[pad_len + 2] = 0x00;
1425
1426 return 0;
1427}
1428
1429static inline int
1430is_common_public_key(unsigned char *key, int len)
1431{
1432 int i;
1433
1434 for (i = 0; i < len; i++)
1435 if (key[i])
1436 break;
1437 key += i;
1438 len -= i;
1439 if (((len == 1) && (key[0] == 3)) ||
1440 ((len == 3) && (key[0] == 1) && (key[1] == 0) && (key[2] == 1)))
1441 return 1;
1442
1443 return 0;
1444}
1445
1446static int
1447ICAMEX_msg_to_type4MEX_msg(struct ica_rsa_modexpo *icaMex_p, int *z90cMsg_l_p,
1448 union type4_msg *z90cMsg_p)
1449{
1450 int mod_len, msg_size, mod_tgt_len, exp_tgt_len, inp_tgt_len;
1451 unsigned char *mod_tgt, *exp_tgt, *inp_tgt;
1452 union type4_msg *tmp_type4_msg;
1453
1454 mod_len = icaMex_p->inputdatalength;
1455
1456 msg_size = ((mod_len <= 128) ? TYPE4_SME_LEN : TYPE4_LME_LEN) +
1457 CALLER_HEADER;
1458
1459 memset(z90cMsg_p, 0, msg_size);
1460
1461 tmp_type4_msg = (union type4_msg *)
1462 ((unsigned char *) z90cMsg_p + CALLER_HEADER);
1463
1464 tmp_type4_msg->sme.header.msg_type_code = TYPE4_TYPE_CODE;
1465 tmp_type4_msg->sme.header.request_code = TYPE4_REQU_CODE;
1466
1467 if (mod_len <= 128) {
1468 tmp_type4_msg->sme.header.msg_fmt = TYPE4_SME_FMT;
1469 tmp_type4_msg->sme.header.msg_len = TYPE4_SME_LEN;
1470 mod_tgt = tmp_type4_msg->sme.modulus;
1471 mod_tgt_len = sizeof(tmp_type4_msg->sme.modulus);
1472 exp_tgt = tmp_type4_msg->sme.exponent;
1473 exp_tgt_len = sizeof(tmp_type4_msg->sme.exponent);
1474 inp_tgt = tmp_type4_msg->sme.message;
1475 inp_tgt_len = sizeof(tmp_type4_msg->sme.message);
1476 } else {
1477 tmp_type4_msg->lme.header.msg_fmt = TYPE4_LME_FMT;
1478 tmp_type4_msg->lme.header.msg_len = TYPE4_LME_LEN;
1479 mod_tgt = tmp_type4_msg->lme.modulus;
1480 mod_tgt_len = sizeof(tmp_type4_msg->lme.modulus);
1481 exp_tgt = tmp_type4_msg->lme.exponent;
1482 exp_tgt_len = sizeof(tmp_type4_msg->lme.exponent);
1483 inp_tgt = tmp_type4_msg->lme.message;
1484 inp_tgt_len = sizeof(tmp_type4_msg->lme.message);
1485 }
1486
1487 mod_tgt += (mod_tgt_len - mod_len);
1488 if (copy_from_user(mod_tgt, icaMex_p->n_modulus, mod_len))
1489 return SEN_RELEASED;
1490 if (is_empty(mod_tgt, mod_len))
1491 return SEN_USER_ERROR;
1492 exp_tgt += (exp_tgt_len - mod_len);
1493 if (copy_from_user(exp_tgt, icaMex_p->b_key, mod_len))
1494 return SEN_RELEASED;
1495 if (is_empty(exp_tgt, mod_len))
1496 return SEN_USER_ERROR;
1497 inp_tgt += (inp_tgt_len - mod_len);
1498 if (copy_from_user(inp_tgt, icaMex_p->inputdata, mod_len))
1499 return SEN_RELEASED;
1500 if (is_empty(inp_tgt, mod_len))
1501 return SEN_USER_ERROR;
1502
1503 *z90cMsg_l_p = msg_size - CALLER_HEADER;
1504
1505 return 0;
1506}
1507
1508static int
1509ICACRT_msg_to_type4CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p,
1510 int *z90cMsg_l_p, union type4_msg *z90cMsg_p)
1511{
1512 int mod_len, short_len, long_len, tmp_size, p_tgt_len, q_tgt_len,
1513 dp_tgt_len, dq_tgt_len, u_tgt_len, inp_tgt_len;
1514 unsigned char *p_tgt, *q_tgt, *dp_tgt, *dq_tgt, *u_tgt, *inp_tgt;
1515 union type4_msg *tmp_type4_msg;
1516
1517 mod_len = icaMsg_p->inputdatalength;
1518 short_len = mod_len / 2;
1519 long_len = mod_len / 2 + 8;
1520
1521 tmp_size = ((mod_len <= 128) ? TYPE4_SCR_LEN : TYPE4_LCR_LEN) +
1522 CALLER_HEADER;
1523
1524 memset(z90cMsg_p, 0, tmp_size);
1525
1526 tmp_type4_msg = (union type4_msg *)
1527 ((unsigned char *) z90cMsg_p + CALLER_HEADER);
1528
1529 tmp_type4_msg->scr.header.msg_type_code = TYPE4_TYPE_CODE;
1530 tmp_type4_msg->scr.header.request_code = TYPE4_REQU_CODE;
1531 if (mod_len <= 128) {
1532 tmp_type4_msg->scr.header.msg_fmt = TYPE4_SCR_FMT;
1533 tmp_type4_msg->scr.header.msg_len = TYPE4_SCR_LEN;
1534 p_tgt = tmp_type4_msg->scr.p;
1535 p_tgt_len = sizeof(tmp_type4_msg->scr.p);
1536 q_tgt = tmp_type4_msg->scr.q;
1537 q_tgt_len = sizeof(tmp_type4_msg->scr.q);
1538 dp_tgt = tmp_type4_msg->scr.dp;
1539 dp_tgt_len = sizeof(tmp_type4_msg->scr.dp);
1540 dq_tgt = tmp_type4_msg->scr.dq;
1541 dq_tgt_len = sizeof(tmp_type4_msg->scr.dq);
1542 u_tgt = tmp_type4_msg->scr.u;
1543 u_tgt_len = sizeof(tmp_type4_msg->scr.u);
1544 inp_tgt = tmp_type4_msg->scr.message;
1545 inp_tgt_len = sizeof(tmp_type4_msg->scr.message);
1546 } else {
1547 tmp_type4_msg->lcr.header.msg_fmt = TYPE4_LCR_FMT;
1548 tmp_type4_msg->lcr.header.msg_len = TYPE4_LCR_LEN;
1549 p_tgt = tmp_type4_msg->lcr.p;
1550 p_tgt_len = sizeof(tmp_type4_msg->lcr.p);
1551 q_tgt = tmp_type4_msg->lcr.q;
1552 q_tgt_len = sizeof(tmp_type4_msg->lcr.q);
1553 dp_tgt = tmp_type4_msg->lcr.dp;
1554 dp_tgt_len = sizeof(tmp_type4_msg->lcr.dp);
1555 dq_tgt = tmp_type4_msg->lcr.dq;
1556 dq_tgt_len = sizeof(tmp_type4_msg->lcr.dq);
1557 u_tgt = tmp_type4_msg->lcr.u;
1558 u_tgt_len = sizeof(tmp_type4_msg->lcr.u);
1559 inp_tgt = tmp_type4_msg->lcr.message;
1560 inp_tgt_len = sizeof(tmp_type4_msg->lcr.message);
1561 }
1562
1563 p_tgt += (p_tgt_len - long_len);
1564 if (copy_from_user(p_tgt, icaMsg_p->np_prime, long_len))
1565 return SEN_RELEASED;
1566 if (is_empty(p_tgt, long_len))
1567 return SEN_USER_ERROR;
1568 q_tgt += (q_tgt_len - short_len);
1569 if (copy_from_user(q_tgt, icaMsg_p->nq_prime, short_len))
1570 return SEN_RELEASED;
1571 if (is_empty(q_tgt, short_len))
1572 return SEN_USER_ERROR;
1573 dp_tgt += (dp_tgt_len - long_len);
1574 if (copy_from_user(dp_tgt, icaMsg_p->bp_key, long_len))
1575 return SEN_RELEASED;
1576 if (is_empty(dp_tgt, long_len))
1577 return SEN_USER_ERROR;
1578 dq_tgt += (dq_tgt_len - short_len);
1579 if (copy_from_user(dq_tgt, icaMsg_p->bq_key, short_len))
1580 return SEN_RELEASED;
1581 if (is_empty(dq_tgt, short_len))
1582 return SEN_USER_ERROR;
1583 u_tgt += (u_tgt_len - long_len);
1584 if (copy_from_user(u_tgt, icaMsg_p->u_mult_inv, long_len))
1585 return SEN_RELEASED;
1586 if (is_empty(u_tgt, long_len))
1587 return SEN_USER_ERROR;
1588 inp_tgt += (inp_tgt_len - mod_len);
1589 if (copy_from_user(inp_tgt, icaMsg_p->inputdata, mod_len))
1590 return SEN_RELEASED;
1591 if (is_empty(inp_tgt, mod_len))
1592 return SEN_USER_ERROR;
1593
1594 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1595
1596 return 0;
1597}
1598
1599static int
1600ICAMEX_msg_to_type6MEX_de_msg(struct ica_rsa_modexpo *icaMsg_p, int cdx,
1601 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1602{
1603 int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l;
1604 unsigned char *temp;
1605 struct type6_hdr *tp6Hdr_p;
1606 struct CPRB *cprb_p;
1607 struct cca_private_ext_ME *key_p;
1608 static int deprecated_msg_count = 0;
1609
1610 mod_len = icaMsg_p->inputdatalength;
1611 tmp_size = FIXED_TYPE6_ME_LEN + mod_len;
1612 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1613 parmBlock_l = total_CPRB_len - sizeof(struct CPRB);
1614 tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER;
1615
1616 memset(z90cMsg_p, 0, tmp_size);
1617
1618 temp = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1619 memcpy(temp, &static_type6_hdr, sizeof(struct type6_hdr));
1620 tp6Hdr_p = (struct type6_hdr *)temp;
1621 tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4);
1622 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE;
1623
1624 temp += sizeof(struct type6_hdr);
1625 memcpy(temp, &static_cprb, sizeof(struct CPRB));
1626 cprb_p = (struct CPRB *) temp;
1627 cprb_p->usage_domain[0]= (unsigned char)cdx;
1628 itoLe2(&parmBlock_l, cprb_p->req_parml);
1629 itoLe2((int *)&(tp6Hdr_p->FromCardLen1), cprb_p->rpl_parml);
1630
1631 temp += sizeof(struct CPRB);
1632 memcpy(temp, &static_pkd_function_and_rules,
1633 sizeof(struct function_and_rules_block));
1634
1635 temp += sizeof(struct function_and_rules_block);
1636 vud_len = 2 + icaMsg_p->inputdatalength;
1637 itoLe2(&vud_len, temp);
1638
1639 temp += 2;
1640 if (copy_from_user(temp, icaMsg_p->inputdata, mod_len))
1641 return SEN_RELEASED;
1642 if (is_empty(temp, mod_len))
1643 return SEN_USER_ERROR;
1644
1645 temp += mod_len;
1646 memcpy(temp, &static_T6_keyBlock_hdr, sizeof(struct T6_keyBlock_hdr));
1647
1648 temp += sizeof(struct T6_keyBlock_hdr);
1649 memcpy(temp, &static_pvt_me_key, sizeof(struct cca_private_ext_ME));
1650 key_p = (struct cca_private_ext_ME *)temp;
1651 temp = key_p->pvtMESec.exponent + sizeof(key_p->pvtMESec.exponent)
1652 - mod_len;
1653 if (copy_from_user(temp, icaMsg_p->b_key, mod_len))
1654 return SEN_RELEASED;
1655 if (is_empty(temp, mod_len))
1656 return SEN_USER_ERROR;
1657
1658 if (is_common_public_key(temp, mod_len)) {
1659 if (deprecated_msg_count < 20) {
1660 PRINTK("Common public key used for modex decrypt\n");
1661 deprecated_msg_count++;
1662 if (deprecated_msg_count == 20)
1663 PRINTK("No longer issuing messages about common"
1664 " public key for modex decrypt.\n");
1665 }
1666 return SEN_NOT_AVAIL;
1667 }
1668
1669 temp = key_p->pvtMESec.modulus + sizeof(key_p->pvtMESec.modulus)
1670 - mod_len;
1671 if (copy_from_user(temp, icaMsg_p->n_modulus, mod_len))
1672 return SEN_RELEASED;
1673 if (is_empty(temp, mod_len))
1674 return SEN_USER_ERROR;
1675
1676 key_p->pubMESec.modulus_bit_len = 8 * mod_len;
1677
1678 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1679
1680 return 0;
1681}
1682
1683static int
1684ICAMEX_msg_to_type6MEX_en_msg(struct ica_rsa_modexpo *icaMsg_p, int cdx,
1685 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1686{
1687 int mod_len, vud_len, exp_len, key_len;
1688 int pad_len, tmp_size, total_CPRB_len, parmBlock_l, i;
1689 unsigned char *temp_exp, *exp_p, *temp;
1690 struct type6_hdr *tp6Hdr_p;
1691 struct CPRB *cprb_p;
1692 struct cca_public_key *key_p;
1693 struct T6_keyBlock_hdr *keyb_p;
1694
1695 temp_exp = kmalloc(256, GFP_KERNEL);
1696 if (!temp_exp)
1697 return EGETBUFF;
1698 mod_len = icaMsg_p->inputdatalength;
1699 if (copy_from_user(temp_exp, icaMsg_p->b_key, mod_len)) {
1700 kfree(temp_exp);
1701 return SEN_RELEASED;
1702 }
1703 if (is_empty(temp_exp, mod_len)) {
1704 kfree(temp_exp);
1705 return SEN_USER_ERROR;
1706 }
1707
1708 exp_p = temp_exp;
1709 for (i = 0; i < mod_len; i++)
1710 if (exp_p[i])
1711 break;
1712 if (i >= mod_len) {
1713 kfree(temp_exp);
1714 return SEN_USER_ERROR;
1715 }
1716
1717 exp_len = mod_len - i;
1718 exp_p += i;
1719
1720 PDEBUG("exp_len after computation: %08x\n", exp_len);
1721 tmp_size = FIXED_TYPE6_ME_EN_LEN + 2 * mod_len + exp_len;
1722 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1723 parmBlock_l = total_CPRB_len - sizeof(struct CPRB);
1724 tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER;
1725
1726 vud_len = 2 + mod_len;
1727 memset(z90cMsg_p, 0, tmp_size);
1728
1729 temp = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1730 memcpy(temp, &static_type6_hdr, sizeof(struct type6_hdr));
1731 tp6Hdr_p = (struct type6_hdr *)temp;
1732 tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4);
1733 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE;
1734 memcpy(tp6Hdr_p->function_code, static_PKE_function_code,
1735 sizeof(static_PKE_function_code));
1736 temp += sizeof(struct type6_hdr);
1737 memcpy(temp, &static_cprb, sizeof(struct CPRB));
1738 cprb_p = (struct CPRB *) temp;
1739 cprb_p->usage_domain[0]= (unsigned char)cdx;
1740 itoLe2((int *)&(tp6Hdr_p->FromCardLen1), cprb_p->rpl_parml);
1741 temp += sizeof(struct CPRB);
1742 memcpy(temp, &static_pke_function_and_rules,
1743 sizeof(struct function_and_rules_block));
1744 temp += sizeof(struct function_and_rules_block);
1745 temp += 2;
1746 if (copy_from_user(temp, icaMsg_p->inputdata, mod_len)) {
1747 kfree(temp_exp);
1748 return SEN_RELEASED;
1749 }
1750 if (is_empty(temp, mod_len)) {
1751 kfree(temp_exp);
1752 return SEN_USER_ERROR;
1753 }
1754 if ((temp[0] != 0x00) || (temp[1] != 0x02)) {
1755 kfree(temp_exp);
1756 return SEN_NOT_AVAIL;
1757 }
1758 for (i = 2; i < mod_len; i++)
1759 if (temp[i] == 0x00)
1760 break;
1761 if ((i < 9) || (i > (mod_len - 2))) {
1762 kfree(temp_exp);
1763 return SEN_NOT_AVAIL;
1764 }
1765 pad_len = i + 1;
1766 vud_len = mod_len - pad_len;
1767 memmove(temp, temp+pad_len, vud_len);
1768 temp -= 2;
1769 vud_len += 2;
1770 itoLe2(&vud_len, temp);
1771 temp += (vud_len);
1772 keyb_p = (struct T6_keyBlock_hdr *)temp;
1773 temp += sizeof(struct T6_keyBlock_hdr);
1774 memcpy(temp, &static_public_key, sizeof(static_public_key));
1775 key_p = (struct cca_public_key *)temp;
1776 temp = key_p->pubSec.exponent;
1777 memcpy(temp, exp_p, exp_len);
1778 kfree(temp_exp);
1779 temp += exp_len;
1780 if (copy_from_user(temp, icaMsg_p->n_modulus, mod_len))
1781 return SEN_RELEASED;
1782 if (is_empty(temp, mod_len))
1783 return SEN_USER_ERROR;
1784 key_p->pubSec.modulus_bit_len = 8 * mod_len;
1785 key_p->pubSec.modulus_byte_len = mod_len;
1786 key_p->pubSec.exponent_len = exp_len;
1787 key_p->pubSec.section_length = CALLER_HEADER + mod_len + exp_len;
1788 key_len = key_p->pubSec.section_length + sizeof(struct cca_token_hdr);
1789 key_p->pubHdr.token_length = key_len;
1790 key_len += 4;
1791 itoLe2(&key_len, keyb_p->ulen);
1792 key_len += 2;
1793 itoLe2(&key_len, keyb_p->blen);
1794 parmBlock_l -= pad_len;
1795 itoLe2(&parmBlock_l, cprb_p->req_parml);
1796 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1797
1798 return 0;
1799}
1800
1801static int
1802ICACRT_msg_to_type6CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p, int cdx,
1803 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1804{
1805 int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l, short_len;
1806 int long_len, pad_len, keyPartsLen, tmp_l;
1807 unsigned char *tgt_p, *temp;
1808 struct type6_hdr *tp6Hdr_p;
1809 struct CPRB *cprb_p;
1810 struct cca_token_hdr *keyHdr_p;
1811 struct cca_pvt_ext_CRT_sec *pvtSec_p;
1812 struct cca_public_sec *pubSec_p;
1813
1814 mod_len = icaMsg_p->inputdatalength;
1815 short_len = mod_len / 2;
1816 long_len = 8 + short_len;
1817 keyPartsLen = 3 * long_len + 2 * short_len;
1818 pad_len = (8 - (keyPartsLen % 8)) % 8;
1819 keyPartsLen += pad_len + mod_len;
1820 tmp_size = FIXED_TYPE6_CR_LEN + keyPartsLen + mod_len;
1821 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1822 parmBlock_l = total_CPRB_len - sizeof(struct CPRB);
1823 vud_len = 2 + mod_len;
1824 tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER;
1825
1826 memset(z90cMsg_p, 0, tmp_size);
1827 tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1828 memcpy(tgt_p, &static_type6_hdr, sizeof(struct type6_hdr));
1829 tp6Hdr_p = (struct type6_hdr *)tgt_p;
1830 tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4);
1831 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE;
1832 tgt_p += sizeof(struct type6_hdr);
1833 cprb_p = (struct CPRB *) tgt_p;
1834 memcpy(tgt_p, &static_cprb, sizeof(struct CPRB));
1835 cprb_p->usage_domain[0]= *((unsigned char *)(&(cdx))+3);
1836 itoLe2(&parmBlock_l, cprb_p->req_parml);
1837 memcpy(cprb_p->rpl_parml, cprb_p->req_parml,
1838 sizeof(cprb_p->req_parml));
1839 tgt_p += sizeof(struct CPRB);
1840 memcpy(tgt_p, &static_pkd_function_and_rules,
1841 sizeof(struct function_and_rules_block));
1842 tgt_p += sizeof(struct function_and_rules_block);
1843 itoLe2(&vud_len, tgt_p);
1844 tgt_p += 2;
1845 if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len))
1846 return SEN_RELEASED;
1847 if (is_empty(tgt_p, mod_len))
1848 return SEN_USER_ERROR;
1849 tgt_p += mod_len;
1850 tmp_l = sizeof(struct T6_keyBlock_hdr) + sizeof(struct cca_token_hdr) +
1851 sizeof(struct cca_pvt_ext_CRT_sec) + 0x0F + keyPartsLen;
1852 itoLe2(&tmp_l, tgt_p);
1853 temp = tgt_p + 2;
1854 tmp_l -= 2;
1855 itoLe2(&tmp_l, temp);
1856 tgt_p += sizeof(struct T6_keyBlock_hdr);
1857 keyHdr_p = (struct cca_token_hdr *)tgt_p;
1858 keyHdr_p->token_identifier = CCA_TKN_HDR_ID_EXT;
1859 tmp_l -= 4;
1860 keyHdr_p->token_length = tmp_l;
1861 tgt_p += sizeof(struct cca_token_hdr);
1862 pvtSec_p = (struct cca_pvt_ext_CRT_sec *)tgt_p;
1863 pvtSec_p->section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT;
1864 pvtSec_p->section_length =
1865 sizeof(struct cca_pvt_ext_CRT_sec) + keyPartsLen;
1866 pvtSec_p->key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL;
1867 pvtSec_p->key_use_flags[0] = CCA_PVT_USAGE_ALL;
1868 pvtSec_p->p_len = long_len;
1869 pvtSec_p->q_len = short_len;
1870 pvtSec_p->dp_len = long_len;
1871 pvtSec_p->dq_len = short_len;
1872 pvtSec_p->u_len = long_len;
1873 pvtSec_p->mod_len = mod_len;
1874 pvtSec_p->pad_len = pad_len;
1875 tgt_p += sizeof(struct cca_pvt_ext_CRT_sec);
1876 if (copy_from_user(tgt_p, icaMsg_p->np_prime, long_len))
1877 return SEN_RELEASED;
1878 if (is_empty(tgt_p, long_len))
1879 return SEN_USER_ERROR;
1880 tgt_p += long_len;
1881 if (copy_from_user(tgt_p, icaMsg_p->nq_prime, short_len))
1882 return SEN_RELEASED;
1883 if (is_empty(tgt_p, short_len))
1884 return SEN_USER_ERROR;
1885 tgt_p += short_len;
1886 if (copy_from_user(tgt_p, icaMsg_p->bp_key, long_len))
1887 return SEN_RELEASED;
1888 if (is_empty(tgt_p, long_len))
1889 return SEN_USER_ERROR;
1890 tgt_p += long_len;
1891 if (copy_from_user(tgt_p, icaMsg_p->bq_key, short_len))
1892 return SEN_RELEASED;
1893 if (is_empty(tgt_p, short_len))
1894 return SEN_USER_ERROR;
1895 tgt_p += short_len;
1896 if (copy_from_user(tgt_p, icaMsg_p->u_mult_inv, long_len))
1897 return SEN_RELEASED;
1898 if (is_empty(tgt_p, long_len))
1899 return SEN_USER_ERROR;
1900 tgt_p += long_len;
1901 tgt_p += pad_len;
1902 memset(tgt_p, 0xFF, mod_len);
1903 tgt_p += mod_len;
1904 memcpy(tgt_p, &static_cca_pub_sec, sizeof(struct cca_public_sec));
1905 pubSec_p = (struct cca_public_sec *) tgt_p;
1906 pubSec_p->modulus_bit_len = 8 * mod_len;
1907 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1908
1909 return 0;
1910}
1911
1912static int
1913ICAMEX_msg_to_type6MEX_msgX(struct ica_rsa_modexpo *icaMsg_p, int cdx,
1914 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p,
1915 int dev_type)
1916{
1917 int mod_len, exp_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l;
1918 int key_len, i;
1919 unsigned char *temp_exp, *tgt_p, *temp, *exp_p;
1920 struct type6_hdr *tp6Hdr_p;
1921 struct CPRBX *cprbx_p;
1922 struct cca_public_key *key_p;
1923 struct T6_keyBlock_hdrX *keyb_p;
1924
1925 temp_exp = kmalloc(256, GFP_KERNEL);
1926 if (!temp_exp)
1927 return EGETBUFF;
1928 mod_len = icaMsg_p->inputdatalength;
1929 if (copy_from_user(temp_exp, icaMsg_p->b_key, mod_len)) {
1930 kfree(temp_exp);
1931 return SEN_RELEASED;
1932 }
1933 if (is_empty(temp_exp, mod_len)) {
1934 kfree(temp_exp);
1935 return SEN_USER_ERROR;
1936 }
1937 exp_p = temp_exp;
1938 for (i = 0; i < mod_len; i++)
1939 if (exp_p[i])
1940 break;
1941 if (i >= mod_len) {
1942 kfree(temp_exp);
1943 return SEN_USER_ERROR;
1944 }
1945 exp_len = mod_len - i;
1946 exp_p += i;
1947 PDEBUG("exp_len after computation: %08x\n", exp_len);
1948 tmp_size = FIXED_TYPE6_ME_EN_LENX + 2 * mod_len + exp_len;
1949 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1950 parmBlock_l = total_CPRB_len - sizeof(struct CPRBX);
1951 tmp_size = tmp_size + CALLER_HEADER;
1952 vud_len = 2 + mod_len;
1953 memset(z90cMsg_p, 0, tmp_size);
1954 tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1955 memcpy(tgt_p, &static_type6_hdrX, sizeof(struct type6_hdr));
1956 tp6Hdr_p = (struct type6_hdr *)tgt_p;
1957 tp6Hdr_p->ToCardLen1 = total_CPRB_len;
1958 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRBX_SIZE;
1959 memcpy(tp6Hdr_p->function_code, static_PKE_function_code,
1960 sizeof(static_PKE_function_code));
1961 tgt_p += sizeof(struct type6_hdr);
1962 memcpy(tgt_p, &static_cprbx, sizeof(struct CPRBX));
1963 cprbx_p = (struct CPRBX *) tgt_p;
1964 cprbx_p->domain = (unsigned short)cdx;
1965 cprbx_p->rpl_msgbl = RESPONSE_CPRBX_SIZE;
1966 tgt_p += sizeof(struct CPRBX);
1967 if (dev_type == PCIXCC_MCL2)
1968 memcpy(tgt_p, &static_pke_function_and_rulesX_MCL2,
1969 sizeof(struct function_and_rules_block));
1970 else
1971 memcpy(tgt_p, &static_pke_function_and_rulesX,
1972 sizeof(struct function_and_rules_block));
1973 tgt_p += sizeof(struct function_and_rules_block);
1974
1975 tgt_p += 2;
1976 if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len)) {
1977 kfree(temp_exp);
1978 return SEN_RELEASED;
1979 }
1980 if (is_empty(tgt_p, mod_len)) {
1981 kfree(temp_exp);
1982 return SEN_USER_ERROR;
1983 }
1984 tgt_p -= 2;
1985 *((short *)tgt_p) = (short) vud_len;
1986 tgt_p += vud_len;
1987 keyb_p = (struct T6_keyBlock_hdrX *)tgt_p;
1988 tgt_p += sizeof(struct T6_keyBlock_hdrX);
1989 memcpy(tgt_p, &static_public_key, sizeof(static_public_key));
1990 key_p = (struct cca_public_key *)tgt_p;
1991 temp = key_p->pubSec.exponent;
1992 memcpy(temp, exp_p, exp_len);
1993 kfree(temp_exp);
1994 temp += exp_len;
1995 if (copy_from_user(temp, icaMsg_p->n_modulus, mod_len))
1996 return SEN_RELEASED;
1997 if (is_empty(temp, mod_len))
1998 return SEN_USER_ERROR;
1999 key_p->pubSec.modulus_bit_len = 8 * mod_len;
2000 key_p->pubSec.modulus_byte_len = mod_len;
2001 key_p->pubSec.exponent_len = exp_len;
2002 key_p->pubSec.section_length = CALLER_HEADER + mod_len + exp_len;
2003 key_len = key_p->pubSec.section_length + sizeof(struct cca_token_hdr);
2004 key_p->pubHdr.token_length = key_len;
2005 key_len += 4;
2006 keyb_p->ulen = (unsigned short)key_len;
2007 key_len += 2;
2008 keyb_p->blen = (unsigned short)key_len;
2009 cprbx_p->req_parml = parmBlock_l;
2010 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
2011
2012 return 0;
2013}
2014
2015static int
2016ICACRT_msg_to_type6CRT_msgX(struct ica_rsa_modexpo_crt *icaMsg_p, int cdx,
2017 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p,
2018 int dev_type)
2019{
2020 int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l, short_len;
2021 int long_len, pad_len, keyPartsLen, tmp_l;
2022 unsigned char *tgt_p, *temp;
2023 struct type6_hdr *tp6Hdr_p;
2024 struct CPRBX *cprbx_p;
2025 struct cca_token_hdr *keyHdr_p;
2026 struct cca_pvt_ext_CRT_sec *pvtSec_p;
2027 struct cca_public_sec *pubSec_p;
2028
2029 mod_len = icaMsg_p->inputdatalength;
2030 short_len = mod_len / 2;
2031 long_len = 8 + short_len;
2032 keyPartsLen = 3 * long_len + 2 * short_len;
2033 pad_len = (8 - (keyPartsLen % 8)) % 8;
2034 keyPartsLen += pad_len + mod_len;
2035 tmp_size = FIXED_TYPE6_CR_LENX + keyPartsLen + mod_len;
2036 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
2037 parmBlock_l = total_CPRB_len - sizeof(struct CPRBX);
2038 vud_len = 2 + mod_len;
2039 tmp_size = tmp_size + CALLER_HEADER;
2040 memset(z90cMsg_p, 0, tmp_size);
2041 tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER;
2042 memcpy(tgt_p, &static_type6_hdrX, sizeof(struct type6_hdr));
2043 tp6Hdr_p = (struct type6_hdr *)tgt_p;
2044 tp6Hdr_p->ToCardLen1 = total_CPRB_len;
2045 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRBX_SIZE;
2046 tgt_p += sizeof(struct type6_hdr);
2047 cprbx_p = (struct CPRBX *) tgt_p;
2048 memcpy(tgt_p, &static_cprbx, sizeof(struct CPRBX));
2049 cprbx_p->domain = (unsigned short)cdx;
2050 cprbx_p->req_parml = parmBlock_l;
2051 cprbx_p->rpl_msgbl = parmBlock_l;
2052 tgt_p += sizeof(struct CPRBX);
2053 if (dev_type == PCIXCC_MCL2)
2054 memcpy(tgt_p, &static_pkd_function_and_rulesX_MCL2,
2055 sizeof(struct function_and_rules_block));
2056 else
2057 memcpy(tgt_p, &static_pkd_function_and_rulesX,
2058 sizeof(struct function_and_rules_block));
2059 tgt_p += sizeof(struct function_and_rules_block);
2060 *((short *)tgt_p) = (short) vud_len;
2061 tgt_p += 2;
2062 if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len))
2063 return SEN_RELEASED;
2064 if (is_empty(tgt_p, mod_len))
2065 return SEN_USER_ERROR;
2066 tgt_p += mod_len;
2067 tmp_l = sizeof(struct T6_keyBlock_hdr) + sizeof(struct cca_token_hdr) +
2068 sizeof(struct cca_pvt_ext_CRT_sec) + 0x0F + keyPartsLen;
2069 *((short *)tgt_p) = (short) tmp_l;
2070 temp = tgt_p + 2;
2071 tmp_l -= 2;
2072 *((short *)temp) = (short) tmp_l;
2073 tgt_p += sizeof(struct T6_keyBlock_hdr);
2074 keyHdr_p = (struct cca_token_hdr *)tgt_p;
2075 keyHdr_p->token_identifier = CCA_TKN_HDR_ID_EXT;
2076 tmp_l -= 4;
2077 keyHdr_p->token_length = tmp_l;
2078 tgt_p += sizeof(struct cca_token_hdr);
2079 pvtSec_p = (struct cca_pvt_ext_CRT_sec *)tgt_p;
2080 pvtSec_p->section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT;
2081 pvtSec_p->section_length =
2082 sizeof(struct cca_pvt_ext_CRT_sec) + keyPartsLen;
2083 pvtSec_p->key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL;
2084 pvtSec_p->key_use_flags[0] = CCA_PVT_USAGE_ALL;
2085 pvtSec_p->p_len = long_len;
2086 pvtSec_p->q_len = short_len;
2087 pvtSec_p->dp_len = long_len;
2088 pvtSec_p->dq_len = short_len;
2089 pvtSec_p->u_len = long_len;
2090 pvtSec_p->mod_len = mod_len;
2091 pvtSec_p->pad_len = pad_len;
2092 tgt_p += sizeof(struct cca_pvt_ext_CRT_sec);
2093 if (copy_from_user(tgt_p, icaMsg_p->np_prime, long_len))
2094 return SEN_RELEASED;
2095 if (is_empty(tgt_p, long_len))
2096 return SEN_USER_ERROR;
2097 tgt_p += long_len;
2098 if (copy_from_user(tgt_p, icaMsg_p->nq_prime, short_len))
2099 return SEN_RELEASED;
2100 if (is_empty(tgt_p, short_len))
2101 return SEN_USER_ERROR;
2102 tgt_p += short_len;
2103 if (copy_from_user(tgt_p, icaMsg_p->bp_key, long_len))
2104 return SEN_RELEASED;
2105 if (is_empty(tgt_p, long_len))
2106 return SEN_USER_ERROR;
2107 tgt_p += long_len;
2108 if (copy_from_user(tgt_p, icaMsg_p->bq_key, short_len))
2109 return SEN_RELEASED;
2110 if (is_empty(tgt_p, short_len))
2111 return SEN_USER_ERROR;
2112 tgt_p += short_len;
2113 if (copy_from_user(tgt_p, icaMsg_p->u_mult_inv, long_len))
2114 return SEN_RELEASED;
2115 if (is_empty(tgt_p, long_len))
2116 return SEN_USER_ERROR;
2117 tgt_p += long_len;
2118 tgt_p += pad_len;
2119 memset(tgt_p, 0xFF, mod_len);
2120 tgt_p += mod_len;
2121 memcpy(tgt_p, &static_cca_pub_sec, sizeof(struct cca_public_sec));
2122 pubSec_p = (struct cca_public_sec *) tgt_p;
2123 pubSec_p->modulus_bit_len = 8 * mod_len;
2124 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
2125
2126 return 0;
2127}
2128
88fbf183
ER
2129static int
2130ICAMEX_msg_to_type50MEX_msg(struct ica_rsa_modexpo *icaMex_p, int *z90cMsg_l_p,
2131 union type50_msg *z90cMsg_p)
2132{
2133 int mod_len, msg_size, mod_tgt_len, exp_tgt_len, inp_tgt_len;
2134 unsigned char *mod_tgt, *exp_tgt, *inp_tgt;
2135 union type50_msg *tmp_type50_msg;
2136
2137 mod_len = icaMex_p->inputdatalength;
2138
2139 msg_size = ((mod_len <= 128) ? TYPE50_MEB1_LEN : TYPE50_MEB2_LEN) +
2140 CALLER_HEADER;
2141
2142 memset(z90cMsg_p, 0, msg_size);
2143
2144 tmp_type50_msg = (union type50_msg *)
2145 ((unsigned char *) z90cMsg_p + CALLER_HEADER);
2146
2147 tmp_type50_msg->meb1.header.msg_type_code = TYPE50_TYPE_CODE;
2148
2149 if (mod_len <= 128) {
2150 tmp_type50_msg->meb1.header.msg_len = TYPE50_MEB1_LEN;
2151 tmp_type50_msg->meb1.keyblock_type = TYPE50_MEB1_FMT;
2152 mod_tgt = tmp_type50_msg->meb1.modulus;
2153 mod_tgt_len = sizeof(tmp_type50_msg->meb1.modulus);
2154 exp_tgt = tmp_type50_msg->meb1.exponent;
2155 exp_tgt_len = sizeof(tmp_type50_msg->meb1.exponent);
2156 inp_tgt = tmp_type50_msg->meb1.message;
2157 inp_tgt_len = sizeof(tmp_type50_msg->meb1.message);
2158 } else {
2159 tmp_type50_msg->meb2.header.msg_len = TYPE50_MEB2_LEN;
2160 tmp_type50_msg->meb2.keyblock_type = TYPE50_MEB2_FMT;
2161 mod_tgt = tmp_type50_msg->meb2.modulus;
2162 mod_tgt_len = sizeof(tmp_type50_msg->meb2.modulus);
2163 exp_tgt = tmp_type50_msg->meb2.exponent;
2164 exp_tgt_len = sizeof(tmp_type50_msg->meb2.exponent);
2165 inp_tgt = tmp_type50_msg->meb2.message;
2166 inp_tgt_len = sizeof(tmp_type50_msg->meb2.message);
2167 }
2168
2169 mod_tgt += (mod_tgt_len - mod_len);
2170 if (copy_from_user(mod_tgt, icaMex_p->n_modulus, mod_len))
2171 return SEN_RELEASED;
2172 if (is_empty(mod_tgt, mod_len))
2173 return SEN_USER_ERROR;
2174 exp_tgt += (exp_tgt_len - mod_len);
2175 if (copy_from_user(exp_tgt, icaMex_p->b_key, mod_len))
2176 return SEN_RELEASED;
2177 if (is_empty(exp_tgt, mod_len))
2178 return SEN_USER_ERROR;
2179 inp_tgt += (inp_tgt_len - mod_len);
2180 if (copy_from_user(inp_tgt, icaMex_p->inputdata, mod_len))
2181 return SEN_RELEASED;
2182 if (is_empty(inp_tgt, mod_len))
2183 return SEN_USER_ERROR;
2184
2185 *z90cMsg_l_p = msg_size - CALLER_HEADER;
2186
2187 return 0;
2188}
2189
2190static int
2191ICACRT_msg_to_type50CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p,
2192 int *z90cMsg_l_p, union type50_msg *z90cMsg_p)
2193{
2194 int mod_len, short_len, long_len, tmp_size, p_tgt_len, q_tgt_len,
2195 dp_tgt_len, dq_tgt_len, u_tgt_len, inp_tgt_len, long_offset;
2196 unsigned char *p_tgt, *q_tgt, *dp_tgt, *dq_tgt, *u_tgt, *inp_tgt,
2197 temp[8];
2198 union type50_msg *tmp_type50_msg;
2199
2200 mod_len = icaMsg_p->inputdatalength;
2201 short_len = mod_len / 2;
2202 long_len = mod_len / 2 + 8;
2203 long_offset = 0;
2204
2205 if (long_len > 128) {
2206 memset(temp, 0x00, sizeof(temp));
2207 if (copy_from_user(temp, icaMsg_p->np_prime, long_len-128))
2208 return SEN_RELEASED;
2209 if (!is_empty(temp, 8))
2210 return SEN_NOT_AVAIL;
2211 if (copy_from_user(temp, icaMsg_p->bp_key, long_len-128))
2212 return SEN_RELEASED;
2213 if (!is_empty(temp, 8))
2214 return SEN_NOT_AVAIL;
2215 if (copy_from_user(temp, icaMsg_p->u_mult_inv, long_len-128))
2216 return SEN_RELEASED;
2217 if (!is_empty(temp, 8))
2218 return SEN_NOT_AVAIL;
2219 long_offset = long_len - 128;
2220 long_len = 128;
2221 }
2222
2223 tmp_size = ((mod_len <= 128) ? TYPE50_CRB1_LEN : TYPE50_CRB2_LEN) +
2224 CALLER_HEADER;
2225
2226 memset(z90cMsg_p, 0, tmp_size);
2227
2228 tmp_type50_msg = (union type50_msg *)
2229 ((unsigned char *) z90cMsg_p + CALLER_HEADER);
2230
2231 tmp_type50_msg->crb1.header.msg_type_code = TYPE50_TYPE_CODE;
2232 if (long_len <= 64) {
2233 tmp_type50_msg->crb1.header.msg_len = TYPE50_CRB1_LEN;
2234 tmp_type50_msg->crb1.keyblock_type = TYPE50_CRB1_FMT;
2235 p_tgt = tmp_type50_msg->crb1.p;
2236 p_tgt_len = sizeof(tmp_type50_msg->crb1.p);
2237 q_tgt = tmp_type50_msg->crb1.q;
2238 q_tgt_len = sizeof(tmp_type50_msg->crb1.q);
2239 dp_tgt = tmp_type50_msg->crb1.dp;
2240 dp_tgt_len = sizeof(tmp_type50_msg->crb1.dp);
2241 dq_tgt = tmp_type50_msg->crb1.dq;
2242 dq_tgt_len = sizeof(tmp_type50_msg->crb1.dq);
2243 u_tgt = tmp_type50_msg->crb1.u;
2244 u_tgt_len = sizeof(tmp_type50_msg->crb1.u);
2245 inp_tgt = tmp_type50_msg->crb1.message;
2246 inp_tgt_len = sizeof(tmp_type50_msg->crb1.message);
2247 } else {
2248 tmp_type50_msg->crb2.header.msg_len = TYPE50_CRB2_LEN;
2249 tmp_type50_msg->crb2.keyblock_type = TYPE50_CRB2_FMT;
2250 p_tgt = tmp_type50_msg->crb2.p;
2251 p_tgt_len = sizeof(tmp_type50_msg->crb2.p);
2252 q_tgt = tmp_type50_msg->crb2.q;
2253 q_tgt_len = sizeof(tmp_type50_msg->crb2.q);
2254 dp_tgt = tmp_type50_msg->crb2.dp;
2255 dp_tgt_len = sizeof(tmp_type50_msg->crb2.dp);
2256 dq_tgt = tmp_type50_msg->crb2.dq;
2257 dq_tgt_len = sizeof(tmp_type50_msg->crb2.dq);
2258 u_tgt = tmp_type50_msg->crb2.u;
2259 u_tgt_len = sizeof(tmp_type50_msg->crb2.u);
2260 inp_tgt = tmp_type50_msg->crb2.message;
2261 inp_tgt_len = sizeof(tmp_type50_msg->crb2.message);
2262 }
2263
2264 p_tgt += (p_tgt_len - long_len);
2265 if (copy_from_user(p_tgt, icaMsg_p->np_prime + long_offset, long_len))
2266 return SEN_RELEASED;
2267 if (is_empty(p_tgt, long_len))
2268 return SEN_USER_ERROR;
2269 q_tgt += (q_tgt_len - short_len);
2270 if (copy_from_user(q_tgt, icaMsg_p->nq_prime, short_len))
2271 return SEN_RELEASED;
2272 if (is_empty(q_tgt, short_len))
2273 return SEN_USER_ERROR;
2274 dp_tgt += (dp_tgt_len - long_len);
2275 if (copy_from_user(dp_tgt, icaMsg_p->bp_key + long_offset, long_len))
2276 return SEN_RELEASED;
2277 if (is_empty(dp_tgt, long_len))
2278 return SEN_USER_ERROR;
2279 dq_tgt += (dq_tgt_len - short_len);
2280 if (copy_from_user(dq_tgt, icaMsg_p->bq_key, short_len))
2281 return SEN_RELEASED;
2282 if (is_empty(dq_tgt, short_len))
2283 return SEN_USER_ERROR;
2284 u_tgt += (u_tgt_len - long_len);
2285 if (copy_from_user(u_tgt, icaMsg_p->u_mult_inv + long_offset, long_len))
2286 return SEN_RELEASED;
2287 if (is_empty(u_tgt, long_len))
2288 return SEN_USER_ERROR;
2289 inp_tgt += (inp_tgt_len - mod_len);
2290 if (copy_from_user(inp_tgt, icaMsg_p->inputdata, mod_len))
2291 return SEN_RELEASED;
2292 if (is_empty(inp_tgt, mod_len))
2293 return SEN_USER_ERROR;
2294
2295 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
2296
2297 return 0;
2298}
2299
1da177e4
LT
2300int
2301convert_request(unsigned char *buffer, int func, unsigned short function,
2302 int cdx, int dev_type, int *msg_l_p, unsigned char *msg_p)
2303{
2304 if (dev_type == PCICA) {
2305 if (func == ICARSACRT)
2306 return ICACRT_msg_to_type4CRT_msg(
2307 (struct ica_rsa_modexpo_crt *) buffer,
2308 msg_l_p, (union type4_msg *) msg_p);
2309 else
2310 return ICAMEX_msg_to_type4MEX_msg(
2311 (struct ica_rsa_modexpo *) buffer,
2312 msg_l_p, (union type4_msg *) msg_p);
2313 }
2314 if (dev_type == PCICC) {
2315 if (func == ICARSACRT)
2316 return ICACRT_msg_to_type6CRT_msg(
2317 (struct ica_rsa_modexpo_crt *) buffer,
2318 cdx, msg_l_p, (struct type6_msg *)msg_p);
2319 if (function == PCI_FUNC_KEY_ENCRYPT)
2320 return ICAMEX_msg_to_type6MEX_en_msg(
2321 (struct ica_rsa_modexpo *) buffer,
2322 cdx, msg_l_p, (struct type6_msg *) msg_p);
2323 else
2324 return ICAMEX_msg_to_type6MEX_de_msg(
2325 (struct ica_rsa_modexpo *) buffer,
2326 cdx, msg_l_p, (struct type6_msg *) msg_p);
2327 }
2328 if ((dev_type == PCIXCC_MCL2) ||
2329 (dev_type == PCIXCC_MCL3) ||
2330 (dev_type == CEX2C)) {
2331 if (func == ICARSACRT)
2332 return ICACRT_msg_to_type6CRT_msgX(
2333 (struct ica_rsa_modexpo_crt *) buffer,
2334 cdx, msg_l_p, (struct type6_msg *) msg_p,
2335 dev_type);
2336 else
2337 return ICAMEX_msg_to_type6MEX_msgX(
2338 (struct ica_rsa_modexpo *) buffer,
2339 cdx, msg_l_p, (struct type6_msg *) msg_p,
2340 dev_type);
2341 }
88fbf183
ER
2342 if (dev_type == CEX2A) {
2343 if (func == ICARSACRT)
2344 return ICACRT_msg_to_type50CRT_msg(
2345 (struct ica_rsa_modexpo_crt *) buffer,
2346 msg_l_p, (union type50_msg *) msg_p);
2347 else
2348 return ICAMEX_msg_to_type50MEX_msg(
2349 (struct ica_rsa_modexpo *) buffer,
2350 msg_l_p, (union type50_msg *) msg_p);
2351 }
1da177e4
LT
2352
2353 return 0;
2354}
2355
2356int ext_bitlens_msg_count = 0;
2357static inline void
2358unset_ext_bitlens(void)
2359{
2360 if (!ext_bitlens_msg_count) {
2361 PRINTK("Unable to use coprocessors for extended bitlengths. "
88fbf183
ER
2362 "Using PCICAs/CEX2As (if present) for extended "
2363 "bitlengths. This is not an error.\n");
1da177e4
LT
2364 ext_bitlens_msg_count++;
2365 }
2366 ext_bitlens = 0;
2367}
2368
2369int
2370convert_response(unsigned char *response, unsigned char *buffer,
2371 int *respbufflen_p, unsigned char *resp_buff)
2372{
2373 struct ica_rsa_modexpo *icaMsg_p = (struct ica_rsa_modexpo *) buffer;
2dee702f 2374 struct error_hdr *errh_p = (struct error_hdr *) response;
88fbf183 2375 struct type80_hdr *t80h_p = (struct type80_hdr *) response;
1da177e4
LT
2376 struct type84_hdr *t84h_p = (struct type84_hdr *) response;
2377 struct type86_fmt2_msg *t86m_p = (struct type86_fmt2_msg *) response;
2378 int reply_code, service_rc, service_rs, src_l;
2379 unsigned char *src_p, *tgt_p;
2380 struct CPRB *cprb_p;
2381 struct CPRBX *cprbx_p;
2382
2383 src_p = 0;
2384 reply_code = 0;
2385 service_rc = 0;
2386 service_rs = 0;
2387 src_l = 0;
2dee702f 2388 switch (errh_p->type) {
1da177e4 2389 case TYPE82_RSP_CODE:
88fbf183 2390 case TYPE88_RSP_CODE:
2dee702f
ER
2391 reply_code = errh_p->reply_code;
2392 src_p = (unsigned char *)errh_p;
2393 PRINTK("Hardware error: Type %02X Message Header: "
1da177e4 2394 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
2dee702f 2395 errh_p->type,
1da177e4
LT
2396 src_p[0], src_p[1], src_p[2], src_p[3],
2397 src_p[4], src_p[5], src_p[6], src_p[7]);
2398 break;
88fbf183
ER
2399 case TYPE80_RSP_CODE:
2400 src_l = icaMsg_p->outputdatalength;
2401 src_p = response + (int)t80h_p->len - src_l;
2402 break;
1da177e4
LT
2403 case TYPE84_RSP_CODE:
2404 src_l = icaMsg_p->outputdatalength;
2405 src_p = response + (int)t84h_p->len - src_l;
2406 break;
2407 case TYPE86_RSP_CODE:
2dee702f 2408 reply_code = t86m_p->header.reply_code;
1da177e4
LT
2409 if (reply_code != 0)
2410 break;
2411 cprb_p = (struct CPRB *)
2412 (response + sizeof(struct type86_fmt2_msg));
2413 cprbx_p = (struct CPRBX *) cprb_p;
2414 if (cprb_p->cprb_ver_id != 0x02) {
2415 le2toI(cprb_p->ccp_rtcode, &service_rc);
2416 if (service_rc != 0) {
2417 le2toI(cprb_p->ccp_rscode, &service_rs);
2418 if ((service_rc == 8) && (service_rs == 66))
2419 PDEBUG("Bad block format on PCICC\n");
2dee702f
ER
2420 else if ((service_rc == 8) && (service_rs == 65))
2421 PDEBUG("Probably an even modulus on "
2422 "PCICC\n");
1da177e4
LT
2423 else if ((service_rc == 8) && (service_rs == 770)) {
2424 PDEBUG("Invalid key length on PCICC\n");
2425 unset_ext_bitlens();
2426 return REC_USE_PCICA;
2427 }
2428 else if ((service_rc == 8) && (service_rs == 783)) {
2429 PDEBUG("Extended bitlengths not enabled"
2430 "on PCICC\n");
2431 unset_ext_bitlens();
2432 return REC_USE_PCICA;
2433 }
2434 else
2dee702f 2435 PRINTK("service rc/rs (PCICC): %d/%d\n",
1da177e4
LT
2436 service_rc, service_rs);
2437 return REC_OPERAND_INV;
2438 }
2439 src_p = (unsigned char *)cprb_p + sizeof(struct CPRB);
2440 src_p += 4;
2441 le2toI(src_p, &src_l);
2442 src_l -= 2;
2443 src_p += 2;
2444 } else {
2445 service_rc = (int)cprbx_p->ccp_rtcode;
2446 if (service_rc != 0) {
2447 service_rs = (int) cprbx_p->ccp_rscode;
2448 if ((service_rc == 8) && (service_rs == 66))
2dee702f
ER
2449 PDEBUG("Bad block format on PCIXCC\n");
2450 else if ((service_rc == 8) && (service_rs == 65))
2451 PDEBUG("Probably an even modulus on "
2452 "PCIXCC\n");
1da177e4
LT
2453 else if ((service_rc == 8) && (service_rs == 770)) {
2454 PDEBUG("Invalid key length on PCIXCC\n");
2455 unset_ext_bitlens();
2456 return REC_USE_PCICA;
2457 }
2458 else if ((service_rc == 8) && (service_rs == 783)) {
2459 PDEBUG("Extended bitlengths not enabled"
2460 "on PCIXCC\n");
2461 unset_ext_bitlens();
2462 return REC_USE_PCICA;
2463 }
2464 else
2dee702f 2465 PRINTK("service rc/rs (PCIXCC): %d/%d\n",
1da177e4
LT
2466 service_rc, service_rs);
2467 return REC_OPERAND_INV;
2468 }
2469 src_p = (unsigned char *)
2470 cprbx_p + sizeof(struct CPRBX);
2471 src_p += 4;
2472 src_l = (int)(*((short *) src_p));
2473 src_l -= 2;
2474 src_p += 2;
2475 }
2476 break;
2477 default:
2dee702f
ER
2478 src_p = (unsigned char *)errh_p;
2479 PRINTK("Unrecognized Message Header: "
2480 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
2481 src_p[0], src_p[1], src_p[2], src_p[3],
2482 src_p[4], src_p[5], src_p[6], src_p[7]);
1da177e4
LT
2483 return REC_BAD_MESSAGE;
2484 }
2485
2486 if (reply_code)
2487 switch (reply_code) {
2dee702f 2488 case REP82_ERROR_OPERAND_INVALID:
88fbf183 2489 case REP88_ERROR_MESSAGE_MALFORMD:
1da177e4 2490 return REC_OPERAND_INV;
2dee702f 2491 case REP82_ERROR_OPERAND_SIZE:
1da177e4 2492 return REC_OPERAND_SIZE;
2dee702f 2493 case REP82_ERROR_EVEN_MOD_IN_OPND:
1da177e4 2494 return REC_EVEN_MOD;
2dee702f 2495 case REP82_ERROR_MESSAGE_TYPE:
1da177e4 2496 return WRONG_DEVICE_TYPE;
2dee702f 2497 case REP82_ERROR_TRANSPORT_FAIL:
1da177e4
LT
2498 PRINTKW("Transport failed (APFS = %02X%02X%02X%02X)\n",
2499 t86m_p->apfs[0], t86m_p->apfs[1],
2500 t86m_p->apfs[2], t86m_p->apfs[3]);
2501 return REC_HARDWAR_ERR;
2502 default:
2503 PRINTKW("reply code = %d\n", reply_code);
2504 return REC_HARDWAR_ERR;
2505 }
2506
2507 if (service_rc != 0)
2508 return REC_OPERAND_INV;
2509
2510 if ((src_l > icaMsg_p->outputdatalength) ||
2511 (src_l > RESPBUFFSIZE) ||
2512 (src_l <= 0))
2513 return REC_OPERAND_SIZE;
2514
2515 PDEBUG("Length returned = %d\n", src_l);
2516 tgt_p = resp_buff + icaMsg_p->outputdatalength - src_l;
2517 memcpy(tgt_p, src_p, src_l);
2dee702f 2518 if ((errh_p->type == TYPE86_RSP_CODE) && (resp_buff < tgt_p)) {
1da177e4
LT
2519 memset(resp_buff, 0, icaMsg_p->outputdatalength - src_l);
2520 if (pad_msg(resp_buff, icaMsg_p->outputdatalength, src_l))
2521 return REC_INVALID_PAD;
2522 }
2523 *respbufflen_p = icaMsg_p->outputdatalength;
2524 if (*respbufflen_p == 0)
2525 PRINTK("Zero *respbufflen_p\n");
2526
2527 return 0;
2528}
2529