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