Auto-update from upstream
[pandora-kernel.git] / drivers / s390 / crypto / z90hardware.c
1 /*
2  *  linux/drivers/s390/crypto/z90hardware.c
3  *
4  *  z90crypt 1.3.3
5  *
6  *  Copyright (C)  2001, 2005 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.34 $"
36
37 char z90hardware_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 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
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 type6_msg {
282         struct type6_hdr header;
283         struct CPRB      CPRB;
284 };
285
286 struct 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
298 struct type86_fmt2_msg {
299         struct type86_hdr header;
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
312 static 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
340 static 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
368 static 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
404 struct function_and_rules_block {
405         unsigned char function_code[2];
406         unsigned char ulen[2];
407         unsigned char only_rule[8];
408 };
409
410 static 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
416 static 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
422 struct T6_keyBlock_hdr {
423         unsigned char blen[2];
424         unsigned char ulen[2];
425         unsigned char flags[2];
426 };
427
428 static struct T6_keyBlock_hdr static_T6_keyBlock_hdr = {
429         {0x89,0x01},
430         {0x87,0x01},
431         {0x00}
432 };
433
434 static 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
475 static 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
481 static 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
487 static 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
493 static struct function_and_rules_block static_pke_function_and_rulesX = {
494         {0x50,0x4B},
495         {0x00,0x0A},
496         {'M','R','P',' ',' ',' ',' ',' '}
497 };
498
499 static unsigned char static_PKE_function_code[2] = {0x50, 0x4B};
500
501 struct T6_keyBlock_hdrX {
502         unsigned short blen;
503         unsigned short ulen;
504         unsigned char flags[2];
505 };
506
507 static unsigned char static_pad[256] = {
508 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
509 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
510 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
511 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
512 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
513 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
514 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
515 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
516 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
517 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
518 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
519 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
520 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
521 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
522 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
523 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
524 };
525
526 static 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
601 static 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
629 static 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
651 struct 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
672 struct 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
681 struct 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
690 struct 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
702 struct 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
714 union 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
721 struct 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
732 struct 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 };
739
740 #define TYPE82_RSP_CODE 0x82
741 #define TYPE88_RSP_CODE 0x88
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
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
780 #define CALLER_HEADER 12
781
782 static inline int
783 testq(int q_nr, int *q_depth, int *dev_type, struct ap_status_word *stat)
784 {
785         int ccode;
786
787         asm volatile
788 #ifdef CONFIG_64BIT
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
852 static inline int
853 resetq(int q_nr, struct ap_status_word *stat_p)
854 {
855         int ccode;
856
857         asm volatile
858 #ifdef CONFIG_64BIT
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
918 static inline int
919 sen(int msg_len, unsigned char *msg_ext, struct ap_status_word *stat)
920 {
921         int ccode;
922
923         asm volatile
924 #ifdef CONFIG_64BIT
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
996 static inline int
997 rec(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
1003 #ifdef CONFIG_64BIT
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
1081 static inline void
1082 itoLe2(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
1088 static inline void
1089 le2toI(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
1098 static inline int
1099 is_empty(unsigned char *ptr, int len)
1100 {
1101         return !memcmp(ptr, (unsigned char *) &static_pvt_me_key+60, len);
1102 }
1103
1104 enum hdstat
1105 query_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) {
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;
1142                         case CEX2A_HW:
1143                                 *dev_type = CEX2A;
1144                                 break;
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
1214 enum devstat
1215 reset_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
1280 static inline void
1281 print_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
1295 enum devstat
1296 send_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;
1301         u32 *q_nr_p = (u32 *)msg_ext;
1302
1303         *q_nr_p = (dev_nr << SKIP_BITL) + cdx;
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
1353 enum devstat
1354 receive_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
1407 static inline int
1408 pad_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
1429 static inline int
1430 is_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
1446 static int
1447 ICAMEX_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
1508 static int
1509 ICACRT_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
1599 static int
1600 ICAMEX_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
1683 static int
1684 ICAMEX_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
1801 static int
1802 ICACRT_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
1912 static int
1913 ICAMEX_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
2015 static int
2016 ICACRT_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
2129 static int
2130 ICAMEX_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
2190 static int
2191 ICACRT_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
2300 int
2301 convert_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         }
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         }
2352
2353         return 0;
2354 }
2355
2356 int ext_bitlens_msg_count = 0;
2357 static inline void
2358 unset_ext_bitlens(void)
2359 {
2360         if (!ext_bitlens_msg_count) {
2361                 PRINTK("Unable to use coprocessors for extended bitlengths. "
2362                        "Using PCICAs/CEX2As (if present) for extended "
2363                        "bitlengths. This is not an error.\n");
2364                 ext_bitlens_msg_count++;
2365         }
2366         ext_bitlens = 0;
2367 }
2368
2369 int
2370 convert_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;
2374         struct error_hdr *errh_p = (struct error_hdr *) response;
2375         struct type80_hdr *t80h_p = (struct type80_hdr *) response;
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;
2388         switch (errh_p->type) {
2389         case TYPE82_RSP_CODE:
2390         case TYPE88_RSP_CODE:
2391                 reply_code = errh_p->reply_code;
2392                 src_p = (unsigned char *)errh_p;
2393                 PRINTK("Hardware error: Type %02X Message Header: "
2394                        "%02x%02x%02x%02x%02x%02x%02x%02x\n",
2395                        errh_p->type,
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;
2399         case TYPE80_RSP_CODE:
2400                 src_l = icaMsg_p->outputdatalength;
2401                 src_p = response + (int)t80h_p->len - src_l;
2402                 break;
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:
2408                 reply_code = t86m_p->header.reply_code;
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");
2420                                 else if ((service_rc == 8) && (service_rs == 65))
2421                                         PDEBUG("Probably an even modulus on "
2422                                                "PCICC\n");
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
2435                                         PRINTK("service rc/rs (PCICC): %d/%d\n",
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))
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");
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
2465                                         PRINTK("service rc/rs (PCIXCC): %d/%d\n",
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:
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]);
2483                 return REC_BAD_MESSAGE;
2484         }
2485
2486         if (reply_code)
2487                 switch (reply_code) {
2488                 case REP82_ERROR_OPERAND_INVALID:
2489                 case REP88_ERROR_MESSAGE_MALFORMD:
2490                         return REC_OPERAND_INV;
2491                 case REP82_ERROR_OPERAND_SIZE:
2492                         return REC_OPERAND_SIZE;
2493                 case REP82_ERROR_EVEN_MOD_IN_OPND:
2494                         return REC_EVEN_MOD;
2495                 case REP82_ERROR_MESSAGE_TYPE:
2496                         return WRONG_DEVICE_TYPE;
2497                 case REP82_ERROR_TRANSPORT_FAIL:
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);
2518         if ((errh_p->type == TYPE86_RSP_CODE) && (resp_buff < tgt_p)) {
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