ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / s390 / crypto / z90hardware.c
1 /*
2  *  linux/drivers/s390/misc/z90hardware.c
3  *
4  *  z90crypt 1.3.1
5  *
6  *  Copyright (C)  2001, 2004 IBM Corporation
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
35 #define VERSION_Z90HARDWARE_C "$Revision: 1.19 $"
36
37 char z90chardware_version[] __initdata =
38         "z90hardware.o (" VERSION_Z90HARDWARE_C "/"
39                           VERSION_Z90COMMON_H "/" VERSION_Z90CRYPT_H ")";
40
41 struct 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
50 struct 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
69 struct 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
80 struct 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
86 struct cca_public_key {
87         struct cca_token_hdr  pubHdr;
88         struct cca_public_sec pubSec;
89 };
90
91 struct 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
116 struct 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
122 struct 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
148 struct 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
170 struct type4_sme {
171         struct type4_hdr header;
172         unsigned char    message[128];
173         unsigned char    exponent[128];
174         unsigned char    modulus[128];
175 };
176
177 struct type4_lme {
178         struct type4_hdr header;
179         unsigned char    message[256];
180         unsigned char    exponent[256];
181         unsigned char    modulus[256];
182 };
183
184 struct 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
194 struct 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
204 union type4_msg {
205         struct type4_sme sme;
206         struct type4_lme lme;
207         struct type4_scr scr;
208         struct type4_lcr lcr;
209 };
210
211 struct 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
220 struct 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 pfs[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
247 struct 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
281 struct CPRBX {
282         unsigned short cprb_len;
283         unsigned char  cprb_ver_id;
284         unsigned char  pad_000[3];
285         unsigned char  func_id[2];
286         unsigned char  cprb_flags[4];
287         unsigned int   req_parml;
288         unsigned int   req_datal;
289         unsigned int   rpl_msgbl;
290         unsigned int   rpld_parml;
291         unsigned int   rpl_datal;
292         unsigned int   rpld_datal;
293         unsigned int   req_extbl;
294         unsigned char  pad_001[4];
295         unsigned int   rpld_extbl;
296         unsigned char  req_parmb[16];
297         unsigned char  req_datab[16];
298         unsigned char  rpl_parmb[16];
299         unsigned char  rpl_datab[16];
300         unsigned char  req_extb[16];
301         unsigned char  rpl_extb[16];
302         unsigned short ccp_rtcode;
303         unsigned short ccp_rscode;
304         unsigned int   mac_data_len;
305         unsigned char  logon_id[8];
306         unsigned char  mac_value[8];
307         unsigned char  mac_content_flgs;
308         unsigned char  pad_002;
309         unsigned short domain;
310         unsigned char  pad_003[12];
311         unsigned char  pad_004[36];
312 };
313
314 struct type6_msg {
315         struct type6_hdr header;
316         struct CPRB      CPRB;
317 };
318
319 union request_msg {
320         union  type4_msg t4msg;
321         struct type6_msg t6msg;
322 };
323
324 struct request_msg_ext {
325         int               q_nr;
326         unsigned char     *psmid;
327         union request_msg reqMsg;
328 };
329
330 struct type82_hdr {
331         unsigned char reserved1;
332         unsigned char type;
333         unsigned char reserved2[2];
334         unsigned char reply_code;
335         unsigned char reserved3[3];
336 };
337
338 #define TYPE82_RSP_CODE 0x82
339
340 #define REPLY_ERROR_MACHINE_FAILURE  0x10
341 #define REPLY_ERROR_PREEMPT_FAILURE  0x12
342 #define REPLY_ERROR_CHECKPT_FAILURE  0x14
343 #define REPLY_ERROR_MESSAGE_TYPE     0x20
344 #define REPLY_ERROR_INVALID_COMM_CD  0x21
345 #define REPLY_ERROR_INVALID_MSG_LEN  0x23
346 #define REPLY_ERROR_RESERVD_FIELD    0x24
347 #define REPLY_ERROR_FORMAT_FIELD     0x29
348 #define REPLY_ERROR_INVALID_COMMAND  0x30
349 #define REPLY_ERROR_MALFORMED_MSG    0x40
350 #define REPLY_ERROR_RESERVED_FIELD   0x50
351 #define REPLY_ERROR_WORD_ALIGNMENT   0x60
352 #define REPLY_ERROR_MESSAGE_LENGTH   0x80
353 #define REPLY_ERROR_OPERAND_INVALID  0x82
354 #define REPLY_ERROR_OPERAND_SIZE     0x84
355 #define REPLY_ERROR_EVEN_MOD_IN_OPND 0x85
356 #define REPLY_ERROR_TRANSPORT_FAIL   0x90
357 #define REPLY_ERROR_PACKET_TRUNCATED 0xA0
358 #define REPLY_ERROR_ZERO_BUFFER_LEN  0xB0
359
360 struct type86_hdr {
361         unsigned char reserved1;
362         unsigned char type;
363         unsigned char format;
364         unsigned char reserved2;
365         unsigned char reply_code;
366         unsigned char reserved3[3];
367 };
368
369 #define TYPE86_RSP_CODE 0x86
370 #define TYPE86_FMT2     0x02
371
372 struct type86_fmt2_msg {
373         struct type86_hdr hdr;
374         unsigned char     reserved[4];
375         unsigned char     apfs[4];
376         unsigned int      count1;
377         unsigned int      offset1;
378         unsigned int      count2;
379         unsigned int      offset2;
380         unsigned int      count3;
381         unsigned int      offset3;
382         unsigned int      ount4;
383         unsigned int      offset4;
384 };
385
386 static struct type6_hdr static_type6_hdr = {
387         0x00,
388         0x06,
389         {0x00,0x00},
390         {0x00,0x00,0x00,0x00},
391         {0x00,0x00},
392         {0x00,0x00},
393         {0x00,0x00,0x00,0x00},
394         0x00000058,
395         0x00000000,
396         0x00000000,
397         0x00000000,
398         {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
399          0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
400         {0x00,0x00},
401         {0x00,0x00},
402         {0x50,0x44},
403         {0x00,0x00},
404         0x00000000,
405         0x00000000,
406         0x00000000,
407         0x00000000,
408         0x00000000,
409         0x00000000,
410         0x00000000,
411         0x00000000
412 };
413
414 static struct type6_hdr static_type6_hdrX = {
415         0x00,
416         0x06,
417         {0x00,0x00},
418         {0x00,0x00,0x00,0x00},
419         {0x00,0x00},
420         {0x00,0x00},
421         {0x00,0x00,0x00,0x00},
422         0x00000058,
423         0x00000000,
424         0x00000000,
425         0x00000000,
426         {0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
427          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
428         {0x00,0x00},
429         {0x00,0x00},
430         {0x50,0x44},
431         {0x00,0x00},
432         0x00000000,
433         0x00000000,
434         0x00000000,
435         0x00000000,
436         0x00000000,
437         0x00000000,
438         0x00000000,
439         0x00000000
440 };
441
442 static struct CPRB static_cprb = {
443         {0x70,0x00},
444         0x41,
445         0x00,
446         {0x00,0x00,0x00,0x00},
447         0x00,
448         0x00,
449         {0x54,0x32},
450         0x01,
451         0x00,
452         {0x00,0x00},
453         {0x00,0x00,0x00,0x00},
454         {0x00,0x00,0x00,0x00},
455         {0x00,0x00,0x00,0x00},
456         {0x00,0x00},
457         {0x00,0x00},
458         {0x00,0x00,0x00,0x00},
459         {0x00,0x00,0x00,0x00},
460         {0x00,0x00,0x00,0x00},
461         {0x00,0x00},
462         {0x00,0x00},
463         {0x00,0x00},
464         {0x00,0x00},
465         {0x00,0x00,0x00,0x00},
466         {0x00,0x00},
467         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
468         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
469         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
470         {0x00,0x00},
471         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
472          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
473          0x00,0x00},
474         {0x08,0x00},
475         {0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20}
476 };
477
478 struct function_and_rules_block {
479         unsigned char function_code[2];
480         unsigned char ulen[2];
481         unsigned char only_rule[8];
482 };
483
484 static struct function_and_rules_block static_pkd_function_and_rules = {
485         {0x50,0x44},
486         {0x0A,0x00},
487         {'P','K','C','S','-','1','.','2'}
488 };
489
490 static struct function_and_rules_block static_pke_function_and_rules = {
491         {0x50,0x4B},
492         {0x0A,0x00},
493         {'P','K','C','S','-','1','.','2'}
494 };
495
496 struct T6_keyBlock_hdr {
497         unsigned char blen[2];
498         unsigned char ulen[2];
499         unsigned char flags[2];
500 };
501
502 static struct T6_keyBlock_hdr static_T6_keyBlock_hdr = {
503         {0x89,0x01},
504         {0x87,0x01},
505         {0x00}
506 };
507
508 static struct CPRBX static_cprbx = {
509         0x00DC,
510         0x02,
511         {0x00,0x00,0x00},
512         {0x54,0x32},
513         {0x00,0x00,0x00,0x00},
514         0x00000000,
515         0x00000000,
516         0x00000000,
517         0x00000000,
518         0x00000000,
519         0x00000000,
520         0x00000000,
521         {0x00,0x00,0x00,0x00},
522         0x00000000,
523         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
524          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
525         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
526          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
527         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
528          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
529         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
530          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
531         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
532          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
533         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
534          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
535         0x0000,
536         0x0000,
537         0x00000000,
538         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
539         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
540         0x00,
541         0x00,
542         0x0000,
543         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
544         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
545          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
546          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
547 };
548
549 static struct function_and_rules_block static_pkd_function_and_rulesX = {
550         {0x50,0x44},
551         {0x00,0x0A},
552         {'P','K','C','S','-','1','.','2'}
553 };
554
555 static struct function_and_rules_block static_pke_function_and_rulesX = {
556         {0x50,0x4B},
557         {0x00,0x0A},
558         {'Z','E','R','O','-','P','A','D'}
559 };
560
561 struct T6_keyBlock_hdrX {
562         unsigned short blen;
563         unsigned short ulen;
564         unsigned char flags[2];
565 };
566
567 static unsigned char static_pad[256] = {
568 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
569 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
570 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
571 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
572 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
573 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
574 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
575 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
576 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
577 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
578 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
579 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
580 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
581 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
582 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
583 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
584 };
585
586 static struct cca_private_ext_ME static_pvt_me_key = {
587         {
588                 0x1E,
589                 0x00,
590                 0x0183,
591                 {0x00,0x00,0x00,0x00}
592         },
593
594         {
595                 0x02,
596                 0x00,
597                 0x016C,
598                 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
599                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
600                  0x00,0x00,0x00,0x00},
601                 {0x00,0x00,0x00,0x00},
602                 0x00,
603                 0x00,
604                 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
605                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
606                  0x00,0x00,0x00,0x00},
607                 {0x80,0x00,0x00,0x00},
608                 {0x00,0x00,0x00,0x00,0x00,0x00},
609                 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
610                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
611                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
612                 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
613                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
614                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
615                 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
616                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
617                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
618                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
619                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
620                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
621                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
622                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
623                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
624                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
625                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
626                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
627                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
628                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
629                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
630                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
631                 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
632                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
633                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
634                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
635                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
636                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
637                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
638                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
639                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
640                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
641                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
642                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
643                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
644                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
645                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
646                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
647         },
648
649         {
650                 0x04,
651                 0x00,
652                 0x000F,
653                 {0x00,0x00},
654                 0x0003,
655                 0x0000,
656                 0x0000,
657                 {0x01,0x00,0x01}
658         }
659 };
660
661 static struct cca_public_key static_public_key = {
662         {
663                 0x1E,
664                 0x00,
665                 0x0000,
666                 {0x00,0x00,0x00,0x00}
667         },
668
669         {
670                 0x04,
671                 0x00,
672                 0x0000,
673                 {0x00,0x00},
674                 0x0000,
675                 0x0000,
676                 0x0000,
677                 {0x01,0x00,0x01}
678         }
679 };
680
681 #define FIXED_TYPE6_ME_LEN 0x0000025F
682
683 #define FIXED_TYPE6_ME_EN_LEN 0x000000F0
684
685 #define FIXED_TYPE6_ME_LENX 0x000002CB
686
687 #define FIXED_TYPE6_ME_EN_LENX 0x0000015C
688
689 static struct cca_public_sec static_cca_pub_sec = {
690         0x04,
691         0x00,
692         0x000f,
693         {0x00,0x00},
694         0x0003,
695         0x0000,
696         0x0000,
697         {0x01,0x00,0x01}
698 };
699
700 #define FIXED_TYPE6_CR_LEN 0x00000177
701
702 #define FIXED_TYPE6_CR_LENX 0x000001E3
703
704 #ifndef MAX_RESPONSE_SIZE
705 #define MAX_RESPONSE_SIZE 0x00000710
706
707 #define MAX_RESPONSEX_SIZE 0x0000077C
708 #endif
709
710 #define RESPONSE_CPRB_SIZE  0x000006B8
711 #define RESPONSE_CPRBX_SIZE 0x00000724
712
713 #define CALLER_HEADER 12
714
715 static unsigned char static_PKE_function_code[2] = {0x50, 0x4B};
716
717 static inline int
718 testq(int q_nr, int *q_depth, int *dev_type, struct ap_status_word *stat)
719 {
720         int ccode;
721
722         asm volatile
723 #ifdef __s390x__
724         ("      llgfr   0,%4            \n"
725          "      slgr    1,1             \n"
726          "      lgr     2,1             \n"
727          "0:    .long   0xb2af0000      \n"
728          "1:    ipm     %0              \n"
729          "      srl     %0,28           \n"
730          "      iihh    %0,0            \n"
731          "      iihl    %0,0            \n"
732          "      lgr     %1,1            \n"
733          "      lgr     %3,2            \n"
734          "      srl     %3,24           \n"
735          "      sll     2,24            \n"
736          "      srl     2,24            \n"
737          "      lgr     %2,2            \n"
738          "2:                            \n"
739          ".section .fixup,\"ax\"        \n"
740          "3:                            \n"
741          "      lhi     %0,%h5          \n"
742          "      jg      2b              \n"
743          ".previous                     \n"
744          ".section __ex_table,\"a\"     \n"
745          "      .align  8               \n"
746          "      .quad   0b,3b           \n"
747          "      .quad   1b,3b           \n"
748          ".previous"
749          :"=d" (ccode),"=d" (*stat),"=d" (*q_depth), "=d" (*dev_type)
750          :"d" (q_nr), "K" (DEV_TSQ_EXCEPTION)
751          :"cc","0","1","2","memory");
752 #else
753         ("      lr      0,%4            \n"
754          "      slr     1,1             \n"
755          "      lr      2,1             \n"
756          "0:    .long   0xb2af0000      \n"
757          "1:    ipm     %0              \n"
758          "      srl     %0,28           \n"
759          "      lr      %1,1            \n"
760          "      lr      %3,2            \n"
761          "      srl     %3,24           \n"
762          "      sll     2,24            \n"
763          "      srl     2,24            \n"
764          "      lr      %2,2            \n"
765          "2:                            \n"
766          ".section .fixup,\"ax\"        \n"
767          "3:                            \n"
768          "      lhi     %0,%h5          \n"
769          "      bras    1,4f            \n"
770          "      .long   2b              \n"
771          "4:                            \n"
772          "      l       1,0(1)          \n"
773          "      br      1               \n"
774          ".previous                     \n"
775          ".section __ex_table,\"a\"     \n"
776          "      .align  4               \n"
777          "      .long   0b,3b           \n"
778          "      .long   1b,3b           \n"
779          ".previous"
780          :"=d" (ccode),"=d" (*stat),"=d" (*q_depth), "=d" (*dev_type)
781          :"d" (q_nr), "K" (DEV_TSQ_EXCEPTION)
782          :"cc","0","1","2","memory");
783 #endif
784         return ccode;
785 }
786
787 static inline int
788 resetq(int q_nr, struct ap_status_word *stat_p)
789 {
790         int ccode;
791
792         asm volatile
793 #ifdef __s390x__
794         ("      llgfr   0,%2            \n"
795          "      lghi    1,1             \n"
796          "      sll     1,24            \n"
797          "      or      0,1             \n"
798          "      slgr    1,1             \n"
799          "      lgr     2,1             \n"
800          "0:    .long   0xb2af0000      \n"
801          "1:    ipm     %0              \n"
802          "      srl     %0,28           \n"
803          "      iihh    %0,0            \n"
804          "      iihl    %0,0            \n"
805          "      lgr     %1,1            \n"
806          "2:                            \n"
807          ".section .fixup,\"ax\"        \n"
808          "3:                            \n"
809          "      lhi     %0,%h3          \n"
810          "      jg      2b              \n"
811          ".previous                     \n"
812          ".section __ex_table,\"a\"     \n"
813          "      .align  8               \n"
814          "      .quad   0b,3b           \n"
815          "      .quad   1b,3b           \n"
816          ".previous"
817          :"=d" (ccode),"=d" (*stat_p)
818          :"d" (q_nr), "K" (DEV_RSQ_EXCEPTION)
819          :"cc","0","1","2","memory");
820 #else
821         ("      lr      0,%2            \n"
822          "      lhi     1,1             \n"
823          "      sll     1,24            \n"
824          "      or      0,1             \n"
825          "      slr     1,1             \n"
826          "      lr      2,1             \n"
827          "0:    .long   0xb2af0000      \n"
828          "1:    ipm     %0              \n"
829          "      srl     %0,28           \n"
830          "      lr      %1,1            \n"
831          "2:                            \n"
832          ".section .fixup,\"ax\"        \n"
833          "3:                            \n"
834          "      lhi     %0,%h3          \n"
835          "      bras    1,4f            \n"
836          "      .long   2b              \n"
837          "4:                            \n"
838          "      l       1,0(1)          \n"
839          "      br      1               \n"
840          ".previous                     \n"
841          ".section __ex_table,\"a\"     \n"
842          "      .align  4               \n"
843          "      .long   0b,3b           \n"
844          "      .long   1b,3b           \n"
845          ".previous"
846          :"=d" (ccode),"=d" (*stat_p)
847          :"d" (q_nr), "K" (DEV_RSQ_EXCEPTION)
848          :"cc","0","1","2","memory");
849 #endif
850         return ccode;
851 }
852
853 static inline int
854 sen(int msg_len, unsigned char *msg_ext, struct ap_status_word *stat)
855 {
856         int ccode;
857
858         asm volatile
859 #ifdef __s390x__
860         ("      lgr     6,%3            \n"
861          "      llgfr   7,%2            \n"
862          "      llgt    0,0(6)          \n"
863          "      lghi    1,64            \n"
864          "      sll     1,24            \n"
865          "      or      0,1             \n"
866          "      la      6,4(6)          \n"
867          "      llgt    2,0(6)          \n"
868          "      llgt    3,4(6)          \n"
869          "      la      6,8(6)          \n"
870          "      slr     1,1             \n"
871          "0:    .long   0xb2ad0026      \n"
872          "1:    brc     2,0b            \n"
873          "      ipm     %0              \n"
874          "      srl     %0,28           \n"
875          "      iihh    %0,0            \n"
876          "      iihl    %0,0            \n"
877          "      lgr     %1,1            \n"
878          "2:                            \n"
879          ".section .fixup,\"ax\"        \n"
880          "3:                            \n"
881          "      lhi     %0,%h4          \n"
882          "      jg      2b              \n"
883          ".previous                     \n"
884          ".section __ex_table,\"a\"     \n"
885          "      .align  8               \n"
886          "      .quad   0b,3b           \n"
887          "      .quad   1b,3b           \n"
888          ".previous"
889          :"=d" (ccode),"=d" (*stat)
890          :"d" (msg_len),"a" (msg_ext), "K" (DEV_SEN_EXCEPTION)
891          :"cc","0","1","2","3","6","7","memory");
892 #else
893         ("      lr      6,%3            \n"
894          "      lr      7,%2            \n"
895          "      l       0,0(6)          \n"
896          "      lhi     1,64            \n"
897          "      sll     1,24            \n"
898          "      or      0,1             \n"
899          "      la      6,4(6)          \n"
900          "      l       2,0(6)          \n"
901          "      l       3,4(6)          \n"
902          "      la      6,8(6)          \n"
903          "      slr     1,1             \n"
904          "0:    .long   0xb2ad0026      \n"
905          "1:    brc     2,0b            \n"
906          "      ipm     %0              \n"
907          "      srl     %0,28           \n"
908          "      lr      %1,1            \n"
909          "2:                            \n"
910          ".section .fixup,\"ax\"        \n"
911          "3:                            \n"
912          "      lhi     %0,%h4          \n"
913          "      bras    1,4f            \n"
914          "      .long   2b              \n"
915          "4:                            \n"
916          "      l       1,0(1)          \n"
917          "      br      1               \n"
918          ".previous                     \n"
919          ".section __ex_table,\"a\"     \n"
920          "      .align  4               \n"
921          "      .long   0b,3b           \n"
922          "      .long   1b,3b           \n"
923          ".previous"
924          :"=d" (ccode),"=d" (*stat)
925          :"d" (msg_len),"a" (msg_ext), "K" (DEV_SEN_EXCEPTION)
926          :"cc","0","1","2","3","6","7","memory");
927 #endif
928         return ccode;
929 }
930
931 static inline int
932 rec(int q_nr, int buff_l, unsigned char *rsp, unsigned char *id,
933     struct ap_status_word *st)
934 {
935         int ccode;
936
937         asm volatile
938 #ifdef __s390x__
939         ("      llgfr   0,%2            \n"
940          "      lgr     3,%4            \n"
941          "      lgr     6,%3            \n"
942          "      llgfr   7,%5            \n"
943          "      lghi    1,128           \n"
944          "      sll     1,24            \n"
945          "      or      0,1             \n"
946          "      slgr    1,1             \n"
947          "      lgr     2,1             \n"
948          "      lgr     4,1             \n"
949          "      lgr     5,1             \n"
950          "0:    .long   0xb2ae0046      \n"
951          "1:    brc     2,0b            \n"
952          "      brc     4,0b            \n"
953          "      ipm     %0              \n"
954          "      srl     %0,28           \n"
955          "      iihh    %0,0            \n"
956          "      iihl    %0,0            \n"
957          "      lgr     %1,1            \n"
958          "      st      4,0(3)          \n"
959          "      st      5,4(3)          \n"
960          "2:                            \n"
961          ".section .fixup,\"ax\"        \n"
962          "3:                            \n"
963          "      lhi   %0,%h6            \n"
964          "      jg    2b                \n"
965          ".previous                     \n"
966          ".section __ex_table,\"a\"     \n"
967          "   .align     8               \n"
968          "   .quad      0b,3b           \n"
969          "   .quad      1b,3b           \n"
970          ".previous"
971          :"=d"(ccode),"=d"(*st)
972          :"d" (q_nr), "d" (rsp), "d" (id), "d" (buff_l), "K" (DEV_REC_EXCEPTION)
973          :"cc","0","1","2","3","4","5","6","7","memory");
974 #else
975         ("      lr      0,%2            \n"
976          "      lr      3,%4            \n"
977          "      lr      6,%3            \n"
978          "      lr      7,%5            \n"
979          "      lhi     1,128           \n"
980          "      sll     1,24            \n"
981          "      or      0,1             \n"
982          "      slr     1,1             \n"
983          "      lr      2,1             \n"
984          "      lr      4,1             \n"
985          "      lr      5,1             \n"
986          "0:    .long   0xb2ae0046      \n"
987          "1:    brc     2,0b            \n"
988          "      brc     4,0b            \n"
989          "      ipm     %0              \n"
990          "      srl     %0,28           \n"
991          "      lr      %1,1            \n"
992          "      st      4,0(3)          \n"
993          "      st      5,4(3)          \n"
994          "2:                            \n"
995          ".section .fixup,\"ax\"        \n"
996          "3:                            \n"
997          "      lhi   %0,%h6            \n"
998          "      bras  1,4f              \n"
999          "      .long 2b                \n"
1000          "4:                            \n"
1001          "      l     1,0(1)            \n"
1002          "      br    1                 \n"
1003          ".previous                     \n"
1004          ".section __ex_table,\"a\"     \n"
1005          "   .align     4               \n"
1006          "   .long      0b,3b           \n"
1007          "   .long      1b,3b           \n"
1008          ".previous"
1009          :"=d"(ccode),"=d"(*st)
1010          :"d" (q_nr), "d" (rsp), "d" (id), "d" (buff_l), "K" (DEV_REC_EXCEPTION)
1011          :"cc","0","1","2","3","4","5","6","7","memory");
1012 #endif
1013         return ccode;
1014 }
1015
1016 static inline void
1017 itoLe2(int *i_p, unsigned char *lechars)
1018 {
1019         *lechars       = *((unsigned char *) i_p + sizeof(int) - 1);
1020         *(lechars + 1) = *((unsigned char *) i_p + sizeof(int) - 2);
1021 }
1022
1023 static inline void
1024 le2toI(unsigned char *lechars, int *i_p)
1025 {
1026         unsigned char *ic_p;
1027         *i_p = 0;
1028         ic_p = (unsigned char *) i_p;
1029         *(ic_p + 2) = *(lechars + 1);
1030         *(ic_p + 3) = *(lechars);
1031 }
1032
1033 static inline int
1034 is_empty(unsigned char *ptr, int len)
1035 {
1036         return !memcmp(ptr, (unsigned char *) &static_pvt_me_key+60, len);
1037 }
1038
1039 enum hdstat
1040 query_online(int deviceNr, int cdx, int resetNr, int *q_depth, int *dev_type)
1041 {
1042         int q_nr, i, t_depth, t_dev_type;
1043         enum devstat ccode;
1044         struct ap_status_word stat_word;
1045         enum hdstat stat;
1046         int break_out;
1047
1048         q_nr = (deviceNr << SKIP_BITL) + cdx;
1049         stat = HD_BUSY;
1050         ccode = testq(q_nr, &t_depth, &t_dev_type, &stat_word);
1051         PDEBUG("ccode %d response_code %02X\n", ccode, stat_word.response_code);
1052         break_out = 0;
1053         for (i = 0; i < resetNr; i++) {
1054                 if (ccode > 3) {
1055                         PRINTKC("Exception testing device %d\n", i);
1056                         return HD_TSQ_EXCEPTION;
1057                 }
1058                 switch (ccode) {
1059                 case 0:
1060                         PDEBUG("t_dev_type %d\n", t_dev_type);
1061                         break_out = 1;
1062                         stat = HD_ONLINE;
1063                         *q_depth = t_depth + 1;
1064                         switch (t_dev_type) {
1065                         case OTHER_HW:
1066                         case OTHER2_HW:
1067                                 stat = HD_NOT_THERE;
1068                                 *dev_type = NILDEV;
1069                                 break;
1070                         case PCICA_HW:
1071                                 *dev_type = PCICA;
1072                                 break;
1073                         case PCICC_HW:
1074                                 *dev_type = PCICC;
1075                                 break;
1076                         case PCIXCC_HW:
1077                                 *dev_type = PCIXCC;
1078                                 break;
1079                         default:
1080                                 *dev_type = NILDEV;
1081                                 break;
1082                         }
1083                         PDEBUG("available device %d: Q depth = %d, dev "
1084                                "type = %d, stat = %02X%02X%02X%02X\n",
1085                                deviceNr, *q_depth, *dev_type,
1086                                stat_word.q_stat_flags,
1087                                stat_word.response_code,
1088                                stat_word.reserved[0],
1089                                stat_word.reserved[1]);
1090                         break;
1091                 case 3:
1092                         switch (stat_word.response_code) {
1093                         case AP_RESPONSE_NORMAL:
1094                                 stat = HD_ONLINE;
1095                                 break_out = 1;
1096                                 *q_depth = t_depth + 1;
1097                                 *dev_type = t_dev_type;
1098                                 PDEBUG("cc3, available device "
1099                                        "%d: Q depth = %d, dev "
1100                                        "type = %d, stat = "
1101                                        "%02X%02X%02X%02X\n",
1102                                        deviceNr, *q_depth,
1103                                        *dev_type,
1104                                        stat_word.q_stat_flags,
1105                                        stat_word.response_code,
1106                                        stat_word.reserved[0],
1107                                        stat_word.reserved[1]);
1108                                 break;
1109                         case AP_RESPONSE_Q_NOT_AVAIL:
1110                                 stat = HD_NOT_THERE;
1111                                 break_out = 1;
1112                                 break;
1113                         case AP_RESPONSE_RESET_IN_PROGRESS:
1114                                 PDEBUG("device %d in reset\n",
1115                                        deviceNr);
1116                                 break;
1117                         case AP_RESPONSE_DECONFIGURED:
1118                                 stat = HD_DECONFIGURED;
1119                                 break_out = 1;
1120                                 break;
1121                         case AP_RESPONSE_CHECKSTOPPED:
1122                                 stat = HD_CHECKSTOPPED;
1123                                 break_out = 1;
1124                                 break;
1125                         case AP_RESPONSE_BUSY:
1126                                 PDEBUG("device %d busy\n",
1127                                        deviceNr);
1128                                 break;
1129                         default:
1130                                 break;
1131                         }
1132                         break;
1133                 default:
1134                         stat = HD_NOT_THERE;
1135                         break_out = 1;
1136                 }
1137                 if (break_out)
1138                         break;
1139
1140                 udelay(5);
1141
1142                 ccode = testq(q_nr, &t_depth, &t_dev_type, &stat_word);
1143         }
1144         return stat;
1145 }
1146
1147 enum devstat
1148 reset_device(int deviceNr, int cdx, int resetNr)
1149 {
1150         int q_nr, ccode = 0, dummy_qdepth, dummy_devType, i;
1151         struct ap_status_word stat_word;
1152         enum devstat stat;
1153         int break_out;
1154
1155         q_nr = (deviceNr << SKIP_BITL) + cdx;
1156         stat = DEV_GONE;
1157         ccode = resetq(q_nr, &stat_word);
1158         if (ccode > 3)
1159                 return DEV_RSQ_EXCEPTION;
1160
1161         break_out = 0;
1162         for (i = 0; i < resetNr; i++) {
1163                 switch (ccode) {
1164                 case 0:
1165                         stat = DEV_ONLINE;
1166                         if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY)
1167                                 break_out = 1;
1168                         break;
1169                 case 3:
1170                         switch (stat_word.response_code) {
1171                         case AP_RESPONSE_NORMAL:
1172                                 stat = DEV_ONLINE;
1173                                 if (stat_word.q_stat_flags &
1174                                     AP_Q_STATUS_EMPTY)
1175                                         break_out = 1;
1176                                 break;
1177                         case AP_RESPONSE_Q_NOT_AVAIL:
1178                                 stat = DEV_GONE;
1179                                 break_out = 1;
1180                                 break;
1181                         case AP_RESPONSE_DECONFIGURED:
1182                                 stat = DEV_GONE;
1183                                 break_out = 1;
1184                                 break;
1185                         case AP_RESPONSE_CHECKSTOPPED:
1186                                 stat = DEV_GONE;
1187                                 break_out = 1;
1188                                 break;
1189                         case AP_RESPONSE_RESET_IN_PROGRESS:
1190                         case AP_RESPONSE_BUSY:
1191                         default:
1192                                 break;
1193                         }
1194                         break;
1195                 default:
1196                         stat = DEV_GONE;
1197                         break_out = 1;
1198                 }
1199                 if (break_out == 1)
1200                         break;
1201                 udelay(5);
1202
1203                 ccode = testq(q_nr, &dummy_qdepth, &dummy_devType, &stat_word);
1204                 if (ccode > 3) {
1205                         stat = DEV_TSQ_EXCEPTION;
1206                         break;
1207                 }
1208         }
1209         PDEBUG("Number of testq's needed for reset: %d\n", i);
1210
1211         if (i >= resetNr) {
1212           stat = DEV_GONE;
1213         }
1214
1215         return stat;
1216 }
1217
1218 #ifdef DEBUG_HYDRA_MSGS
1219 static inline void
1220 print_buffer(unsigned char *buffer, int bufflen)
1221 {
1222         int i;
1223         for (i = 0; i < bufflen; i += 16) {
1224                 PRINTK("%04X: %02X%02X%02X%02X %02X%02X%02X%02X "
1225                        "%02X%02X%02X%02X %02X%02X%02X%02X\n", i,
1226                        buffer[i+0], buffer[i+1], buffer[i+2], buffer[i+3],
1227                        buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7],
1228                        buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11],
1229                        buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
1230         }
1231 }
1232 #endif
1233
1234 enum devstat
1235 send_to_AP(int dev_nr, int cdx, int msg_len, unsigned char *msg_ext)
1236 {
1237         struct ap_status_word stat_word;
1238         enum devstat stat;
1239         int ccode;
1240
1241         ((struct request_msg_ext *) msg_ext)->q_nr =
1242                 (dev_nr << SKIP_BITL) + cdx;
1243         PDEBUG("msg_len passed to sen: %d\n", msg_len);
1244         PDEBUG("q number passed to sen: %02x%02x%02x%02x\n",
1245                msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3]);
1246         stat = DEV_GONE;
1247
1248 #ifdef DEBUG_HYDRA_MSGS
1249         PRINTK("Request header: %02X%02X%02X%02X %02X%02X%02X%02X "
1250                "%02X%02X%02X%02X\n",
1251                msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3],
1252                msg_ext[4], msg_ext[5], msg_ext[6], msg_ext[7],
1253                msg_ext[8], msg_ext[9], msg_ext[10], msg_ext[11]);
1254         print_buffer(msg_ext+12, msg_len);
1255 #endif
1256
1257         ccode = sen(msg_len, msg_ext, &stat_word);
1258         if (ccode > 3)
1259                 return DEV_SEN_EXCEPTION;
1260
1261         PDEBUG("nq cc: %u, st: %02x%02x%02x%02x\n",
1262                ccode, stat_word.q_stat_flags, stat_word.response_code,
1263                stat_word.reserved[0], stat_word.reserved[1]);
1264         switch (ccode) {
1265         case 0:
1266                 stat = DEV_ONLINE;
1267                 break;
1268         case 1:
1269                 stat = DEV_GONE;
1270                 break;
1271         case 3:
1272                 switch (stat_word.response_code) {
1273                 case AP_RESPONSE_NORMAL:
1274                         stat = DEV_ONLINE;
1275                         break;
1276                 case AP_RESPONSE_Q_FULL:
1277                         stat = DEV_QUEUE_FULL;
1278                         break;
1279                 default:
1280                         stat = DEV_GONE;
1281                         break;
1282                 }
1283                 break;
1284         default:
1285                 stat = DEV_GONE;
1286         }
1287
1288         return stat;
1289 }
1290
1291 enum devstat
1292 receive_from_AP(int dev_nr, int cdx, int resplen,
1293                 unsigned char *resp, unsigned char *psmid)
1294 {
1295         int ccode;
1296         struct ap_status_word stat_word;
1297         enum devstat stat;
1298
1299         memset(resp, 0x00, 8);
1300
1301         ccode = rec((dev_nr << SKIP_BITL) + cdx, resplen, resp, psmid,
1302                     &stat_word);
1303         if (ccode > 3)
1304                 return DEV_REC_EXCEPTION;
1305
1306         PDEBUG("dq cc: %u, st: %02x%02x%02x%02x\n",
1307                ccode, stat_word.q_stat_flags, stat_word.response_code,
1308                stat_word.reserved[0], stat_word.reserved[1]);
1309
1310         stat = DEV_GONE;
1311         switch (ccode) {
1312         case 0:
1313                 stat = DEV_ONLINE;
1314 #ifdef DEBUG_HYDRA_MSGS
1315                 print_buffer(resp, resplen);
1316 #endif
1317                 break;
1318         case 3:
1319                 switch (stat_word.response_code) {
1320                 case AP_RESPONSE_NORMAL:
1321                         stat = DEV_ONLINE;
1322                         break;
1323                 case AP_RESPONSE_NO_PENDING_REPLY:
1324                         if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY)
1325                                 stat = DEV_EMPTY;
1326                         else
1327                                 stat = DEV_NO_WORK;
1328                         break;
1329                 case AP_RESPONSE_INDEX_TOO_BIG:
1330                 case AP_RESPONSE_NO_FIRST_PART:
1331                 case AP_RESPONSE_MESSAGE_TOO_BIG:
1332                         stat = DEV_BAD_MESSAGE;
1333                         break;
1334                 default:
1335                         break;
1336                 }
1337                 break;
1338         default:
1339                 break;
1340         }
1341
1342         return stat;
1343 }
1344
1345 static inline int
1346 pad_msg(unsigned char *buffer, int  totalLength, int msgLength)
1347 {
1348         int pad_len;
1349
1350         for (pad_len = 0; pad_len < (totalLength - msgLength); pad_len++)
1351                 if (buffer[pad_len] != 0x00)
1352                         break;
1353         pad_len -= 3;
1354         if (pad_len < 8)
1355                 return SEN_PAD_ERROR;
1356
1357         buffer[0] = 0x00;
1358         buffer[1] = 0x02;
1359
1360         memcpy(buffer+2, static_pad, pad_len);
1361
1362         buffer[pad_len + 2] = 0x00;
1363
1364         return 0;
1365 }
1366
1367 static inline int
1368 is_common_public_key(unsigned char *key, int len)
1369 {
1370         int i;
1371
1372         for (i = 0; i < len; i++)
1373                 if (key[i])
1374                         break;
1375         key += i;
1376         len -= i;
1377         if (((len == 1) && (key[0] == 3)) ||
1378             ((len == 3) && (key[0] == 1) && (key[1] == 0) && (key[2] == 1)))
1379                 return 1;
1380
1381         return 0;
1382 }
1383
1384 static int
1385 ICAMEX_msg_to_type4MEX_msg(struct ica_rsa_modexpo *icaMex_p, int *z90cMsg_l_p,
1386                            union type4_msg *z90cMsg_p)
1387 {
1388         int mod_len, msg_size, mod_tgt_len, exp_tgt_len, inp_tgt_len;
1389         unsigned char *mod_tgt, *exp_tgt, *inp_tgt;
1390         union type4_msg *tmp_type4_msg;
1391
1392         mod_len = icaMex_p->inputdatalength;
1393
1394         msg_size = ((mod_len <= 128) ? TYPE4_SME_LEN : TYPE4_LME_LEN) +
1395                     CALLER_HEADER;
1396
1397         memset(z90cMsg_p, 0, msg_size);
1398
1399         tmp_type4_msg = (union type4_msg *)
1400                 ((unsigned char *) z90cMsg_p + CALLER_HEADER);
1401
1402         tmp_type4_msg->sme.header.msg_type_code = TYPE4_TYPE_CODE;
1403         tmp_type4_msg->sme.header.request_code = TYPE4_REQU_CODE;
1404
1405         if (mod_len <= 128) {
1406                 tmp_type4_msg->sme.header.msg_fmt = TYPE4_SME_FMT;
1407                 tmp_type4_msg->sme.header.msg_len = TYPE4_SME_LEN;
1408                 mod_tgt = tmp_type4_msg->sme.modulus;
1409                 mod_tgt_len = sizeof(tmp_type4_msg->sme.modulus);
1410                 exp_tgt = tmp_type4_msg->sme.exponent;
1411                 exp_tgt_len = sizeof(tmp_type4_msg->sme.exponent);
1412                 inp_tgt = tmp_type4_msg->sme.message;
1413                 inp_tgt_len = sizeof(tmp_type4_msg->sme.message);
1414         } else {
1415                 tmp_type4_msg->lme.header.msg_fmt = TYPE4_LME_FMT;
1416                 tmp_type4_msg->lme.header.msg_len = TYPE4_LME_LEN;
1417                 mod_tgt = tmp_type4_msg->lme.modulus;
1418                 mod_tgt_len = sizeof(tmp_type4_msg->lme.modulus);
1419                 exp_tgt = tmp_type4_msg->lme.exponent;
1420                 exp_tgt_len = sizeof(tmp_type4_msg->lme.exponent);
1421                 inp_tgt = tmp_type4_msg->lme.message;
1422                 inp_tgt_len = sizeof(tmp_type4_msg->lme.message);
1423         }
1424
1425         mod_tgt += (mod_tgt_len - mod_len);
1426         if (copy_from_user(mod_tgt, icaMex_p->n_modulus, mod_len))
1427                 return SEN_RELEASED;
1428         if (is_empty(mod_tgt, mod_len))
1429                 return SEN_USER_ERROR;
1430         exp_tgt += (exp_tgt_len - mod_len);
1431         if (copy_from_user(exp_tgt, icaMex_p->b_key, mod_len))
1432                 return SEN_RELEASED;
1433         if (is_empty(exp_tgt, mod_len))
1434                 return SEN_USER_ERROR;
1435         inp_tgt += (inp_tgt_len - mod_len);
1436         if (copy_from_user(inp_tgt, icaMex_p->inputdata, mod_len))
1437                 return SEN_RELEASED;
1438         if (is_empty(inp_tgt, mod_len))
1439                 return SEN_USER_ERROR;
1440
1441         *z90cMsg_l_p = msg_size - CALLER_HEADER;
1442
1443         return 0;
1444 }
1445
1446 static int
1447 ICACRT_msg_to_type4CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p,
1448                            int *z90cMsg_l_p, union type4_msg *z90cMsg_p)
1449 {
1450         int mod_len, short_len, long_len, tmp_size, p_tgt_len, q_tgt_len,
1451             dp_tgt_len, dq_tgt_len, u_tgt_len, inp_tgt_len;
1452         unsigned char *p_tgt, *q_tgt, *dp_tgt, *dq_tgt, *u_tgt, *inp_tgt;
1453         union type4_msg *tmp_type4_msg;
1454
1455         mod_len = icaMsg_p->inputdatalength;
1456         short_len = mod_len / 2;
1457         long_len = mod_len / 2 + 8;
1458
1459         tmp_size = ((mod_len <= 128) ? TYPE4_SCR_LEN : TYPE4_LCR_LEN) +
1460                     CALLER_HEADER;
1461
1462         memset(z90cMsg_p, 0, tmp_size);
1463
1464         tmp_type4_msg = (union type4_msg *)
1465                 ((unsigned char *) z90cMsg_p + CALLER_HEADER);
1466
1467         tmp_type4_msg->scr.header.msg_type_code = TYPE4_TYPE_CODE;
1468         tmp_type4_msg->scr.header.request_code = TYPE4_REQU_CODE;
1469         if (mod_len <= 128) {
1470                 tmp_type4_msg->scr.header.msg_fmt = TYPE4_SCR_FMT;
1471                 tmp_type4_msg->scr.header.msg_len = TYPE4_SCR_LEN;
1472                 p_tgt = tmp_type4_msg->scr.p;
1473                 p_tgt_len = sizeof(tmp_type4_msg->scr.p);
1474                 q_tgt = tmp_type4_msg->scr.q;
1475                 q_tgt_len = sizeof(tmp_type4_msg->scr.q);
1476                 dp_tgt = tmp_type4_msg->scr.dp;
1477                 dp_tgt_len = sizeof(tmp_type4_msg->scr.dp);
1478                 dq_tgt = tmp_type4_msg->scr.dq;
1479                 dq_tgt_len = sizeof(tmp_type4_msg->scr.dq);
1480                 u_tgt = tmp_type4_msg->scr.u;
1481                 u_tgt_len = sizeof(tmp_type4_msg->scr.u);
1482                 inp_tgt = tmp_type4_msg->scr.message;
1483                 inp_tgt_len = sizeof(tmp_type4_msg->scr.message);
1484         } else {
1485                 tmp_type4_msg->lcr.header.msg_fmt = TYPE4_LCR_FMT;
1486                 tmp_type4_msg->lcr.header.msg_len = TYPE4_LCR_LEN;
1487                 p_tgt = tmp_type4_msg->lcr.p;
1488                 p_tgt_len = sizeof(tmp_type4_msg->lcr.p);
1489                 q_tgt = tmp_type4_msg->lcr.q;
1490                 q_tgt_len = sizeof(tmp_type4_msg->lcr.q);
1491                 dp_tgt = tmp_type4_msg->lcr.dp;
1492                 dp_tgt_len = sizeof(tmp_type4_msg->lcr.dp);
1493                 dq_tgt = tmp_type4_msg->lcr.dq;
1494                 dq_tgt_len = sizeof(tmp_type4_msg->lcr.dq);
1495                 u_tgt = tmp_type4_msg->lcr.u;
1496                 u_tgt_len = sizeof(tmp_type4_msg->lcr.u);
1497                 inp_tgt = tmp_type4_msg->lcr.message;
1498                 inp_tgt_len = sizeof(tmp_type4_msg->lcr.message);
1499         }
1500
1501         p_tgt += (p_tgt_len - long_len);
1502         if (copy_from_user(p_tgt, icaMsg_p->np_prime, long_len))
1503                 return SEN_RELEASED;
1504         if (is_empty(p_tgt, long_len))
1505                 return SEN_USER_ERROR;
1506         q_tgt += (q_tgt_len - short_len);
1507         if (copy_from_user(q_tgt, icaMsg_p->nq_prime, short_len))
1508                 return SEN_RELEASED;
1509         if (is_empty(q_tgt, short_len))
1510                 return SEN_USER_ERROR;
1511         dp_tgt += (dp_tgt_len - long_len);
1512         if (copy_from_user(dp_tgt, icaMsg_p->bp_key, long_len))
1513                 return SEN_RELEASED;
1514         if (is_empty(dp_tgt, long_len))
1515                 return SEN_USER_ERROR;
1516         dq_tgt += (dq_tgt_len - short_len);
1517         if (copy_from_user(dq_tgt, icaMsg_p->bq_key, short_len))
1518                 return SEN_RELEASED;
1519         if (is_empty(dq_tgt, short_len))
1520                 return SEN_USER_ERROR;
1521         u_tgt += (u_tgt_len - long_len);
1522         if (copy_from_user(u_tgt, icaMsg_p->u_mult_inv, long_len))
1523                 return SEN_RELEASED;
1524         if (is_empty(u_tgt, long_len))
1525                 return SEN_USER_ERROR;
1526         inp_tgt += (inp_tgt_len - mod_len);
1527         if (copy_from_user(inp_tgt, icaMsg_p->inputdata, mod_len))
1528                 return SEN_RELEASED;
1529         if (is_empty(inp_tgt, mod_len))
1530                 return SEN_USER_ERROR;
1531
1532         *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1533
1534         return 0;
1535 }
1536
1537 static int
1538 ICAMEX_msg_to_type6MEX_de_msg(struct ica_rsa_modexpo *icaMsg_p, int cdx,
1539                               int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1540 {
1541         int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l;
1542         unsigned char *temp;
1543         struct type6_hdr *tp6Hdr_p;
1544         struct CPRB *cprb_p;
1545         struct cca_private_ext_ME *key_p;
1546
1547         mod_len = icaMsg_p->inputdatalength;
1548         tmp_size = FIXED_TYPE6_ME_LEN + mod_len;
1549         total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1550         parmBlock_l = total_CPRB_len - sizeof(struct CPRB);
1551         tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER;
1552
1553         memset(z90cMsg_p, 0, tmp_size);
1554
1555         temp = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1556         memcpy(temp, &static_type6_hdr, sizeof(struct type6_hdr));
1557         tp6Hdr_p = (struct type6_hdr *)temp;
1558         tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4);
1559         tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE;
1560
1561         temp += sizeof(struct type6_hdr);
1562         memcpy(temp, &static_cprb, sizeof(struct CPRB));
1563         cprb_p = (struct CPRB *) temp;
1564         cprb_p->usage_domain[0]= (unsigned char)cdx;
1565         itoLe2(&parmBlock_l, cprb_p->req_parml);
1566         itoLe2((int *)&(tp6Hdr_p->FromCardLen1), cprb_p->rpl_parml);
1567
1568         temp += sizeof(struct CPRB);
1569         memcpy(temp, &static_pkd_function_and_rules,
1570                sizeof(struct function_and_rules_block));
1571
1572         temp += sizeof(struct function_and_rules_block);
1573         vud_len = 2 + icaMsg_p->inputdatalength;
1574         itoLe2(&vud_len, temp);
1575
1576         temp += 2;
1577         if (copy_from_user(temp, icaMsg_p->inputdata, mod_len))
1578                 return SEN_RELEASED;
1579         if (is_empty(temp, mod_len))
1580                 return SEN_USER_ERROR;
1581
1582         temp += mod_len;
1583         memcpy(temp, &static_T6_keyBlock_hdr, sizeof(struct T6_keyBlock_hdr));
1584
1585         temp += sizeof(struct T6_keyBlock_hdr);
1586         memcpy(temp, &static_pvt_me_key, sizeof(struct cca_private_ext_ME));
1587         key_p = (struct cca_private_ext_ME *)temp;
1588         temp = key_p->pvtMESec.exponent + sizeof(key_p->pvtMESec.exponent)
1589                - mod_len;
1590         if (copy_from_user(temp, icaMsg_p->b_key, mod_len))
1591                 return SEN_RELEASED;
1592         if (is_empty(temp, mod_len))
1593                 return SEN_USER_ERROR;
1594
1595         if (is_common_public_key(temp, mod_len)) {
1596                 PRINTK("Common public key used for modex decrypt\n");
1597                 return SEN_NOT_AVAIL;
1598         }
1599
1600         temp = key_p->pvtMESec.modulus + sizeof(key_p->pvtMESec.modulus)
1601                - mod_len;
1602         if (copy_from_user(temp, icaMsg_p->n_modulus, mod_len) != 0)
1603                 return SEN_RELEASED;
1604         if (is_empty(temp, mod_len))
1605                 return SEN_USER_ERROR;
1606
1607         key_p->pubMESec.modulus_bit_len = 8 * mod_len;
1608
1609         *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1610
1611         return 0;
1612 }
1613
1614 static int
1615 ICAMEX_msg_to_type6MEX_en_msg(struct ica_rsa_modexpo *icaMsg_p, int cdx,
1616                               int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1617 {
1618         int mod_len, vud_len, exp_len, key_len;
1619         int pad_len, tmp_size, total_CPRB_len, parmBlock_l, i;
1620         unsigned char temp_exp[256], *exp_p, *temp;
1621         struct type6_hdr *tp6Hdr_p;
1622         struct CPRB *cprb_p;
1623         struct cca_public_key *key_p;
1624         struct T6_keyBlock_hdr *keyb_p;
1625
1626         mod_len = icaMsg_p->inputdatalength;
1627         if (copy_from_user(temp_exp, icaMsg_p->b_key, mod_len))
1628                 return SEN_RELEASED;
1629         if (is_empty(temp_exp, mod_len))
1630                 return SEN_USER_ERROR;
1631
1632         exp_p = temp_exp;
1633         for (i = 0; i < mod_len; i++)
1634                 if (exp_p[i])
1635                         break;
1636         if (i >= mod_len)
1637                 return SEN_USER_ERROR;
1638
1639         exp_len = mod_len - i;
1640         exp_p += i;
1641
1642         PDEBUG("exp_len after computation: %08x\n", exp_len);
1643         tmp_size = FIXED_TYPE6_ME_EN_LEN + 2 * mod_len + exp_len;
1644         total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1645         parmBlock_l = total_CPRB_len - sizeof(struct CPRB);
1646         tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER;
1647
1648         vud_len = 2 + mod_len;
1649         memset(z90cMsg_p, 0, tmp_size);
1650
1651         temp = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1652         memcpy(temp, &static_type6_hdr, sizeof(struct type6_hdr));
1653         tp6Hdr_p = (struct type6_hdr *)temp;
1654         tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4);
1655         tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE;
1656         memcpy(tp6Hdr_p->function_code, static_PKE_function_code,
1657                sizeof(static_PKE_function_code));
1658         temp += sizeof(struct type6_hdr);
1659         memcpy(temp, &static_cprb, sizeof(struct CPRB));
1660         cprb_p = (struct CPRB *) temp;
1661         cprb_p->usage_domain[0]= (unsigned char)cdx;
1662         itoLe2((int *)&(tp6Hdr_p->FromCardLen1), cprb_p->rpl_parml);
1663         temp += sizeof(struct CPRB);
1664         memcpy(temp, &static_pke_function_and_rules,
1665                  sizeof(struct function_and_rules_block));
1666         temp += sizeof(struct function_and_rules_block);
1667         temp += 2;
1668         if (copy_from_user(temp, icaMsg_p->inputdata, mod_len))
1669                 return SEN_RELEASED;
1670         if (is_empty(temp, mod_len))
1671                 return SEN_USER_ERROR;
1672         if (temp[0] != 0x00 || temp[1] != 0x02)
1673                 return SEN_NOT_AVAIL;
1674         for (i = 2; i < mod_len; i++)
1675                 if (temp[i] == 0x00)
1676                         break;
1677         if ((i < 9) || (i > (mod_len - 2)))
1678                 return SEN_NOT_AVAIL;
1679         pad_len = i + 1;
1680         vud_len = mod_len - pad_len;
1681         memmove(temp, temp+pad_len, vud_len);
1682         temp -= 2;
1683         vud_len += 2;
1684         itoLe2(&vud_len, temp);
1685         temp += (vud_len);
1686         keyb_p = (struct T6_keyBlock_hdr *)temp;
1687         temp += sizeof(struct T6_keyBlock_hdr);
1688         memcpy(temp, &static_public_key, sizeof(static_public_key));
1689         key_p = (struct cca_public_key *)temp;
1690         temp = key_p->pubSec.exponent;
1691         memcpy(temp, exp_p, exp_len);
1692         temp += exp_len;
1693         if (copy_from_user(temp, icaMsg_p->n_modulus, mod_len))
1694                 return SEN_RELEASED;
1695         if (is_empty(temp, mod_len))
1696                 return SEN_USER_ERROR;
1697         key_p->pubSec.modulus_bit_len = 8 * mod_len;
1698         key_p->pubSec.modulus_byte_len = mod_len;
1699         key_p->pubSec.exponent_len = exp_len;
1700         key_p->pubSec.section_length = 12 + mod_len + exp_len;
1701         key_len = key_p->pubSec.section_length + sizeof(struct cca_token_hdr);
1702         key_p->pubHdr.token_length = key_len;
1703         key_len += 4;
1704         itoLe2(&key_len, keyb_p->ulen);
1705         key_len += 2;
1706         itoLe2(&key_len, keyb_p->blen);
1707         parmBlock_l -= pad_len;
1708         itoLe2(&parmBlock_l, cprb_p->req_parml);
1709         *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1710
1711         return 0;
1712 }
1713
1714 static int
1715 ICACRT_msg_to_type6CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p, int cdx,
1716                            int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1717 {
1718         int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l, short_len;
1719         int long_len, pad_len, keyPartsLen, tmp_l;
1720         unsigned char *tgt_p, *temp;
1721         struct type6_hdr *tp6Hdr_p;
1722         struct CPRB *cprb_p;
1723         struct cca_token_hdr *keyHdr_p;
1724         struct cca_pvt_ext_CRT_sec *pvtSec_p;
1725         struct cca_public_sec *pubSec_p;
1726
1727         mod_len = icaMsg_p->inputdatalength;
1728         short_len = mod_len / 2;
1729         long_len = 8 + short_len;
1730         keyPartsLen = 3 * long_len + 2 * short_len;
1731         pad_len = (8 - (keyPartsLen % 8)) % 8;
1732         keyPartsLen += pad_len + mod_len;
1733         tmp_size = FIXED_TYPE6_CR_LEN + keyPartsLen + mod_len;
1734         total_CPRB_len = tmp_size -  sizeof(struct type6_hdr);
1735         parmBlock_l = total_CPRB_len - sizeof(struct CPRB);
1736         vud_len = 2 + mod_len;
1737         tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER;
1738
1739         memset(z90cMsg_p, 0, tmp_size);
1740         tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1741         memcpy(tgt_p, &static_type6_hdr, sizeof(struct type6_hdr));
1742         tp6Hdr_p = (struct type6_hdr *)tgt_p;
1743         tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4);
1744         tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE;
1745         tgt_p += sizeof(struct type6_hdr);
1746         cprb_p = (struct CPRB *) tgt_p;
1747         memcpy(tgt_p, &static_cprb, sizeof(struct CPRB));
1748         cprb_p->usage_domain[0]= *((unsigned char *)(&(cdx))+3);
1749         itoLe2(&parmBlock_l, cprb_p->req_parml);
1750         memcpy(cprb_p->rpl_parml, cprb_p->req_parml,
1751                sizeof(cprb_p->req_parml));
1752         tgt_p += sizeof(struct CPRB);
1753         memcpy(tgt_p, &static_pkd_function_and_rules,
1754                sizeof(struct function_and_rules_block));
1755         tgt_p += sizeof(struct function_and_rules_block);
1756         itoLe2(&vud_len, tgt_p);
1757         tgt_p += 2;
1758         if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len))
1759                 return SEN_RELEASED;
1760         if (is_empty(tgt_p, mod_len))
1761                 return SEN_USER_ERROR;
1762         tgt_p += mod_len;
1763         tmp_l = sizeof(struct T6_keyBlock_hdr) + sizeof(struct cca_token_hdr) +
1764                 sizeof(struct cca_pvt_ext_CRT_sec) + 0x0F + keyPartsLen;
1765         itoLe2(&tmp_l, tgt_p);
1766         temp = tgt_p + 2;
1767         tmp_l -= 2;
1768         itoLe2(&tmp_l, temp);
1769         tgt_p += sizeof(struct T6_keyBlock_hdr);
1770         keyHdr_p = (struct cca_token_hdr *)tgt_p;
1771         keyHdr_p->token_identifier = CCA_TKN_HDR_ID_EXT;
1772         tmp_l -= 4;
1773         keyHdr_p->token_length = tmp_l;
1774         tgt_p += sizeof(struct cca_token_hdr);
1775         pvtSec_p = (struct cca_pvt_ext_CRT_sec *)tgt_p;
1776         pvtSec_p->section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT;
1777         pvtSec_p->section_length =
1778                 sizeof(struct cca_pvt_ext_CRT_sec) + keyPartsLen;
1779         pvtSec_p->key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL;
1780         pvtSec_p->key_use_flags[0] = CCA_PVT_USAGE_ALL;
1781         pvtSec_p->p_len = long_len;
1782         pvtSec_p->q_len = short_len;
1783         pvtSec_p->dp_len = long_len;
1784         pvtSec_p->dq_len = short_len;
1785         pvtSec_p->u_len = long_len;
1786         pvtSec_p->mod_len = mod_len;
1787         pvtSec_p->pad_len = pad_len;
1788         tgt_p += sizeof(struct cca_pvt_ext_CRT_sec);
1789         if (copy_from_user(tgt_p, icaMsg_p->np_prime, long_len))
1790                 return SEN_RELEASED;
1791         if (is_empty(tgt_p, long_len))
1792                 return SEN_USER_ERROR;
1793         tgt_p += long_len;
1794         if (copy_from_user(tgt_p, icaMsg_p->nq_prime, short_len))
1795                 return SEN_RELEASED;
1796         if (is_empty(tgt_p, short_len))
1797                 return SEN_USER_ERROR;
1798         tgt_p += short_len;
1799         if (copy_from_user(tgt_p, icaMsg_p->bp_key, long_len))
1800                 return SEN_RELEASED;
1801         if (is_empty(tgt_p, long_len))
1802                 return SEN_USER_ERROR;
1803         tgt_p += long_len;
1804         if (copy_from_user(tgt_p, icaMsg_p->bq_key, short_len))
1805                 return SEN_RELEASED;
1806         if (is_empty(tgt_p, short_len))
1807                 return SEN_USER_ERROR;
1808         tgt_p += short_len;
1809         if (copy_from_user(tgt_p, icaMsg_p->u_mult_inv, long_len))
1810                 return SEN_RELEASED;
1811         if (is_empty(tgt_p, long_len))
1812                 return SEN_USER_ERROR;
1813         tgt_p += long_len;
1814         tgt_p += pad_len;
1815         memset(tgt_p, 0xFF, mod_len);
1816         tgt_p += mod_len;
1817         memcpy(tgt_p, &static_cca_pub_sec, sizeof(struct cca_public_sec));
1818         pubSec_p = (struct cca_public_sec *) tgt_p;
1819         pubSec_p->modulus_bit_len = 8 * mod_len;
1820         *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1821
1822         return 0;
1823 }
1824
1825 static int
1826 ICAMEX_msg_to_type6MEX_msgX(struct ica_rsa_modexpo *icaMsg_p, int cdx,
1827                             int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1828 {
1829         int mod_len, exp_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l;
1830         int key_len, i;
1831         unsigned char temp_exp[256], *tgt_p, *temp, *exp_p;
1832         struct type6_hdr *tp6Hdr_p;
1833         struct CPRBX *cprbx_p;
1834         struct cca_public_key *key_p;
1835         struct T6_keyBlock_hdrX *keyb_p;
1836
1837         mod_len = icaMsg_p->inputdatalength;
1838         if (copy_from_user(temp_exp, icaMsg_p->b_key, mod_len))
1839                 return SEN_RELEASED;
1840         if (is_empty(temp_exp, mod_len))
1841                 return SEN_USER_ERROR;
1842         exp_p = temp_exp;
1843         for (i = 0; i < mod_len; i++)
1844                 if (exp_p[i])
1845                         break;
1846         if (i >= mod_len)
1847                 return SEN_USER_ERROR;
1848         exp_len = mod_len - i;
1849         exp_p += i;
1850         PDEBUG("exp_len after computation: %08x\n", exp_len);
1851         tmp_size = FIXED_TYPE6_ME_EN_LENX + 2 * mod_len + exp_len;
1852         total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1853         parmBlock_l = total_CPRB_len - sizeof(struct CPRBX);
1854         tmp_size = tmp_size + CALLER_HEADER;
1855         vud_len = 2 + mod_len;
1856         memset(z90cMsg_p, 0, tmp_size);
1857         tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1858         memcpy(tgt_p, &static_type6_hdrX, sizeof(struct type6_hdr));
1859         tp6Hdr_p = (struct type6_hdr *)tgt_p;
1860         tp6Hdr_p->ToCardLen1 = total_CPRB_len;
1861         tp6Hdr_p->FromCardLen1 = RESPONSE_CPRBX_SIZE;
1862         memcpy(tp6Hdr_p->function_code, static_PKE_function_code,
1863                sizeof(static_PKE_function_code));
1864         tgt_p += sizeof(struct type6_hdr);
1865         memcpy(tgt_p, &static_cprbx, sizeof(struct CPRBX));
1866         cprbx_p = (struct CPRBX *) tgt_p;
1867         cprbx_p->domain = (unsigned short)cdx;
1868         cprbx_p->rpl_msgbl = RESPONSE_CPRBX_SIZE;
1869         tgt_p += sizeof(struct CPRBX);
1870         memcpy(tgt_p, &static_pke_function_and_rulesX,
1871                sizeof(struct function_and_rules_block));
1872         tgt_p += sizeof(struct function_and_rules_block);
1873
1874         tgt_p += 2;
1875         if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len))
1876               return SEN_RELEASED;
1877         if (is_empty(tgt_p, mod_len))
1878               return SEN_USER_ERROR;
1879         tgt_p -= 2;
1880         *((short *)tgt_p) = (short) vud_len;
1881         tgt_p += vud_len;
1882         keyb_p = (struct T6_keyBlock_hdrX *)tgt_p;
1883         tgt_p += sizeof(struct T6_keyBlock_hdrX);
1884         memcpy(tgt_p, &static_public_key, sizeof(static_public_key));
1885         key_p = (struct cca_public_key *)tgt_p;
1886         temp = key_p->pubSec.exponent;
1887         memcpy(temp, exp_p, exp_len);
1888         temp += exp_len;
1889         if (copy_from_user(temp, icaMsg_p->n_modulus, mod_len))
1890               return SEN_RELEASED;
1891         if (is_empty(temp, mod_len))
1892               return SEN_USER_ERROR;
1893         key_p->pubSec.modulus_bit_len = 8 * mod_len;
1894         key_p->pubSec.modulus_byte_len = mod_len;
1895         key_p->pubSec.exponent_len = exp_len;
1896         key_p->pubSec.section_length = 12 + mod_len + exp_len;
1897         key_len = key_p->pubSec.section_length + sizeof(struct cca_token_hdr);
1898         key_p->pubHdr.token_length = key_len;
1899         key_len += 4;
1900         keyb_p->ulen = (unsigned short)key_len;
1901         key_len += 2;
1902         keyb_p->blen = (unsigned short)key_len;
1903         cprbx_p->req_parml = parmBlock_l;
1904         *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1905
1906         return 0;
1907 }
1908
1909 static int
1910 ICACRT_msg_to_type6CRT_msgX(struct ica_rsa_modexpo_crt *icaMsg_p, int cdx,
1911                             int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1912 {
1913         int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l, short_len;
1914         int long_len, pad_len, keyPartsLen, tmp_l;
1915         unsigned char *tgt_p, *temp;
1916         struct type6_hdr *tp6Hdr_p;
1917         struct CPRBX *cprbx_p;
1918         struct cca_token_hdr *keyHdr_p;
1919         struct cca_pvt_ext_CRT_sec *pvtSec_p;
1920         struct cca_public_sec *pubSec_p;
1921
1922         mod_len = icaMsg_p->inputdatalength;
1923         short_len = mod_len / 2;
1924         long_len = 8 + short_len;
1925         keyPartsLen = 3 * long_len + 2 * short_len;
1926         pad_len = (8 - (keyPartsLen % 8)) % 8;
1927         keyPartsLen += pad_len + mod_len;
1928         tmp_size = FIXED_TYPE6_CR_LENX + keyPartsLen + mod_len;
1929         total_CPRB_len = tmp_size -  sizeof(struct type6_hdr);
1930         parmBlock_l = total_CPRB_len - sizeof(struct CPRBX);
1931         vud_len = 2 + mod_len;
1932         tmp_size = tmp_size + CALLER_HEADER;
1933         memset(z90cMsg_p, 0, tmp_size);
1934         tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1935         memcpy(tgt_p, &static_type6_hdrX, sizeof(struct type6_hdr));
1936         tp6Hdr_p = (struct type6_hdr *)tgt_p;
1937         tp6Hdr_p->ToCardLen1 = total_CPRB_len;
1938         tp6Hdr_p->FromCardLen1 = RESPONSE_CPRBX_SIZE;
1939         tgt_p += sizeof(struct type6_hdr);
1940         cprbx_p = (struct CPRBX *) tgt_p;
1941         memcpy(tgt_p, &static_cprbx, sizeof(struct CPRBX));
1942         cprbx_p->domain = (unsigned short)cdx;
1943         cprbx_p->req_parml = parmBlock_l;
1944         cprbx_p->rpl_msgbl = parmBlock_l;
1945         tgt_p += sizeof(struct CPRBX);
1946         memcpy(tgt_p, &static_pkd_function_and_rulesX,
1947                sizeof(struct function_and_rules_block));
1948         tgt_p += sizeof(struct function_and_rules_block);
1949         *((short *)tgt_p) = (short) vud_len;
1950         tgt_p += 2;
1951         if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len))
1952                 return SEN_RELEASED;
1953         if (is_empty(tgt_p, mod_len))
1954                 return SEN_USER_ERROR;
1955         tgt_p += mod_len;
1956         tmp_l = sizeof(struct T6_keyBlock_hdr) + sizeof(struct cca_token_hdr) +
1957                 sizeof(struct cca_pvt_ext_CRT_sec) + 0x0F + keyPartsLen;
1958         *((short *)tgt_p) = (short) tmp_l;
1959         temp = tgt_p + 2;
1960         tmp_l -= 2;
1961         *((short *)temp) = (short) tmp_l;
1962         tgt_p += sizeof(struct T6_keyBlock_hdr);
1963         keyHdr_p = (struct cca_token_hdr *)tgt_p;
1964         keyHdr_p->token_identifier = CCA_TKN_HDR_ID_EXT;
1965         tmp_l -= 4;
1966         keyHdr_p->token_length = tmp_l;
1967         tgt_p += sizeof(struct cca_token_hdr);
1968         pvtSec_p = (struct cca_pvt_ext_CRT_sec *)tgt_p;
1969         pvtSec_p->section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT;
1970         pvtSec_p->section_length =
1971                 sizeof(struct cca_pvt_ext_CRT_sec) + keyPartsLen;
1972         pvtSec_p->key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL;
1973         pvtSec_p->key_use_flags[0] = CCA_PVT_USAGE_ALL;
1974         pvtSec_p->p_len = long_len;
1975         pvtSec_p->q_len = short_len;
1976         pvtSec_p->dp_len = long_len;
1977         pvtSec_p->dq_len = short_len;
1978         pvtSec_p->u_len = long_len;
1979         pvtSec_p->mod_len = mod_len;
1980         pvtSec_p->pad_len = pad_len;
1981         tgt_p += sizeof(struct cca_pvt_ext_CRT_sec);
1982         if (copy_from_user(tgt_p, icaMsg_p->np_prime, long_len))
1983                 return SEN_RELEASED;
1984         if (is_empty(tgt_p, long_len))
1985                 return SEN_USER_ERROR;
1986         tgt_p += long_len;
1987         if (copy_from_user(tgt_p, icaMsg_p->nq_prime, short_len))
1988                 return SEN_RELEASED;
1989         if (is_empty(tgt_p, short_len))
1990                 return SEN_USER_ERROR;
1991         tgt_p += short_len;
1992         if (copy_from_user(tgt_p, icaMsg_p->bp_key, long_len))
1993                 return SEN_RELEASED;
1994         if (is_empty(tgt_p, long_len))
1995                 return SEN_USER_ERROR;
1996         tgt_p += long_len;
1997         if (copy_from_user(tgt_p, icaMsg_p->bq_key, short_len))
1998                 return SEN_RELEASED;
1999         if (is_empty(tgt_p, short_len))
2000                 return SEN_USER_ERROR;
2001         tgt_p += short_len;
2002         if (copy_from_user(tgt_p, icaMsg_p->u_mult_inv, long_len))
2003                 return SEN_RELEASED;
2004         if (is_empty(tgt_p, long_len))
2005                 return SEN_USER_ERROR;
2006         tgt_p += long_len;
2007         tgt_p += pad_len;
2008         memset(tgt_p, 0xFF, mod_len);
2009         tgt_p += mod_len;
2010         memcpy(tgt_p, &static_cca_pub_sec, sizeof(struct cca_public_sec));
2011         pubSec_p = (struct cca_public_sec *) tgt_p;
2012         pubSec_p->modulus_bit_len = 8 * mod_len;
2013         *z90cMsg_l_p = tmp_size - CALLER_HEADER;
2014
2015         return 0;
2016 }
2017
2018 int
2019 convert_request(unsigned char *buffer, int func, unsigned short function,
2020                 int cdx, int dev_type, int *msg_l_p, unsigned char *msg_p)
2021 {
2022         if (dev_type == PCICA) {
2023                 if (func == ICARSACRT)
2024                         return ICACRT_msg_to_type4CRT_msg(
2025                                 (struct ica_rsa_modexpo_crt *) buffer,
2026                                 msg_l_p, (union type4_msg *) msg_p);
2027                 else
2028                         return ICAMEX_msg_to_type4MEX_msg(
2029                                 (struct ica_rsa_modexpo *) buffer,
2030                                 msg_l_p, (union type4_msg *) msg_p);
2031         }
2032         if (dev_type == PCICC) {
2033                 if (func == ICARSACRT)
2034                         return ICACRT_msg_to_type6CRT_msg(
2035                                 (struct ica_rsa_modexpo_crt *) buffer,
2036                                 cdx, msg_l_p, (struct type6_msg *)msg_p);
2037                 if (function == PCI_FUNC_KEY_ENCRYPT)
2038                         return ICAMEX_msg_to_type6MEX_en_msg(
2039                                 (struct ica_rsa_modexpo *) buffer,
2040                                 cdx, msg_l_p, (struct type6_msg *) msg_p);
2041                 else
2042                         return ICAMEX_msg_to_type6MEX_de_msg(
2043                                 (struct ica_rsa_modexpo *) buffer,
2044                                 cdx, msg_l_p, (struct type6_msg *) msg_p);
2045         }
2046         if (dev_type == PCIXCC) {
2047                 if (func == ICARSACRT)
2048                         return ICACRT_msg_to_type6CRT_msgX(
2049                                 (struct ica_rsa_modexpo_crt *) buffer,
2050                                 cdx, msg_l_p, (struct type6_msg *) msg_p);
2051                 else
2052                         return ICAMEX_msg_to_type6MEX_msgX(
2053                                 (struct ica_rsa_modexpo *) buffer,
2054                                 cdx, msg_l_p, (struct type6_msg *) msg_p);
2055         }
2056
2057         return 0;
2058 }
2059
2060 int
2061 convert_response(unsigned char *response, unsigned char *buffer,
2062                  int *respbufflen_p, unsigned char *resp_buff)
2063 {
2064         struct ica_rsa_modexpo *icaMsg_p = (struct ica_rsa_modexpo *) buffer;
2065         struct type82_hdr *t82h_p = (struct type82_hdr *) response;
2066         struct type84_hdr *t84h_p = (struct type84_hdr *) response;
2067         struct type86_hdr *t86h_p = (struct type86_hdr *) response;
2068         int rv, reply_code, service_rc, service_rs, src_l;
2069         unsigned char *src_p, *tgt_p;
2070         struct CPRB *cprb_p;
2071         struct CPRBX *cprbx_p;
2072
2073         src_p = 0;
2074         reply_code = 0;
2075         service_rc = 0;
2076         service_rs = 0;
2077         src_l = 0;
2078         rv = 0;
2079         switch (t82h_p->type) {
2080         case TYPE82_RSP_CODE:
2081                 reply_code = t82h_p->reply_code;
2082                 rv = 4;
2083                 src_p = (unsigned char *)t82h_p;
2084                 PRINTK("Hardware error: Type 82 Message Header: "
2085                        "%02x%02x%02x%02x%02x%02x%02x%02x\n",
2086                        src_p[0], src_p[1], src_p[2], src_p[3],
2087                        src_p[4], src_p[5], src_p[6], src_p[7]);
2088                 break;
2089         case TYPE84_RSP_CODE:
2090                 src_l = icaMsg_p->outputdatalength;
2091                 src_p = response + (int)t84h_p->len - src_l;
2092                 break;
2093         case TYPE86_RSP_CODE:
2094                 reply_code = t86h_p->reply_code;
2095                 if (t86h_p->format != TYPE86_FMT2) {
2096                         rv = 4;
2097                         break;
2098                 }
2099                 if (reply_code != 0) {
2100                         rv = 4;
2101                         break;
2102                 }
2103                 cprb_p = (struct CPRB *)
2104                         (response + sizeof(struct type86_fmt2_msg));
2105                 cprbx_p = (struct CPRBX *) cprb_p;
2106                 if (cprb_p->cprb_ver_id != 0x02) {
2107                         le2toI(cprb_p->ccp_rtcode, &service_rc);
2108                         if (service_rc != 0) {
2109                                 le2toI(cprb_p->ccp_rscode, &service_rs);
2110                                 if ((service_rc == 8) && (service_rs == 66))
2111                                         PDEBUG("8/66 on PCICC\n");
2112                                 else
2113                                         PRINTK("service rc/rs: %d/%d\n",
2114                                                service_rc, service_rs);
2115                                 rv = 8;
2116                         }
2117                         src_p = (unsigned char *)cprb_p + sizeof(struct CPRB);
2118                         src_p += 4;
2119                         le2toI(src_p, &src_l);
2120                         src_l -= 2;
2121                         src_p += 2;
2122                 } else {
2123                         service_rc = (int)cprbx_p->ccp_rtcode;
2124                         if (service_rc != 0) {
2125                                 service_rs = (int) cprbx_p->ccp_rscode;
2126                                 if ((service_rc == 8) && (service_rs == 66))
2127                                         PDEBUG("8/66 on PCIXCC\n");
2128                                 else
2129                                         PRINTK("service rc/rs: %d/%d\n",
2130                                                service_rc, service_rs);
2131                                 rv = 8;
2132                         }
2133                         src_p = (unsigned char *)
2134                                 cprbx_p + sizeof(struct CPRBX);
2135                         src_p += 4;
2136                         src_l = (int)(*((short *) src_p));
2137                         src_l -= 2;
2138                         src_p += 2;
2139                 }
2140                 break;
2141         default:
2142                 break;
2143         }
2144
2145         if (rv == 8)
2146                 return 8;
2147         if (rv == 4)
2148                 switch (reply_code) {
2149                 case REPLY_ERROR_OPERAND_INVALID:
2150                         return REC_OPERAND_INV;
2151                 case REPLY_ERROR_OPERAND_SIZE:
2152                         return REC_OPERAND_SIZE;
2153                 case REPLY_ERROR_EVEN_MOD_IN_OPND:
2154                         return REC_EVEN_MOD;
2155                 case REPLY_ERROR_MESSAGE_TYPE:
2156                         return WRONG_DEVICE_TYPE;
2157                 default:
2158                         return 12;
2159                 }
2160
2161         if (service_rc != 0)
2162                 return REC_OPERAND_INV;
2163
2164         if ((src_l > icaMsg_p->outputdatalength) ||
2165             (src_l > RESPBUFFSIZE) ||
2166             (src_l <= 0))
2167                 return REC_OPERAND_SIZE;
2168
2169         PDEBUG("Length returned = %d\n", src_l);
2170         tgt_p = resp_buff + icaMsg_p->outputdatalength - src_l;
2171         memcpy(tgt_p, src_p, src_l);
2172         if ((t82h_p->type == TYPE86_RSP_CODE) && (resp_buff < tgt_p)) {
2173                 memset(resp_buff, 0, icaMsg_p->outputdatalength - src_l);
2174                 rv = pad_msg(resp_buff, icaMsg_p->outputdatalength, src_l);
2175                 if (rv != 0)
2176                         return rv;
2177         }
2178         *respbufflen_p = icaMsg_p->outputdatalength;
2179         if (*respbufflen_p == 0)
2180                 PRINTK("Zero *respbufflen_p\n");
2181
2182         return rv;
2183 }
2184