[PATCH] W1: w1_netlink: New init/fini netlink callbacks.
[linux-2.6/verdex.git] / drivers / s390 / crypto / z90hardware.c
blobc215e088973625087daf5985afd5cb97e0794976
1 /*
2 * linux/drivers/s390/crypto/z90hardware.c
4 * z90crypt 1.3.2
6 * Copyright (C) 2001, 2004 IBM Corporation
7 * Author(s): Robert Burroughs (burrough@us.ibm.com)
8 * Eric Rossman (edrossma@us.ibm.com)
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
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.
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.
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.
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"
35 #define VERSION_Z90HARDWARE_C "$Revision: 1.34 $"
37 char z90hardware_version[] __initdata =
38 "z90hardware.o (" VERSION_Z90HARDWARE_C "/"
39 VERSION_Z90COMMON_H "/" VERSION_Z90CRYPT_H ")";
41 struct cca_token_hdr {
42 unsigned char token_identifier;
43 unsigned char version;
44 unsigned short token_length;
45 unsigned char reserved[4];
48 #define CCA_TKN_HDR_ID_EXT 0x1E
50 struct cca_private_ext_ME_sec {
51 unsigned char section_identifier;
52 unsigned char version;
53 unsigned short section_length;
54 unsigned char private_key_hash[20];
55 unsigned char reserved1[4];
56 unsigned char key_format;
57 unsigned char reserved2;
58 unsigned char key_name_hash[20];
59 unsigned char key_use_flags[4];
60 unsigned char reserved3[6];
61 unsigned char reserved4[24];
62 unsigned char confounder[24];
63 unsigned char exponent[128];
64 unsigned char modulus[128];
67 #define CCA_PVT_USAGE_ALL 0x80
69 struct cca_public_sec {
70 unsigned char section_identifier;
71 unsigned char version;
72 unsigned short section_length;
73 unsigned char reserved[2];
74 unsigned short exponent_len;
75 unsigned short modulus_bit_len;
76 unsigned short modulus_byte_len;
77 unsigned char exponent[3];
80 struct cca_private_ext_ME {
81 struct cca_token_hdr pvtMEHdr;
82 struct cca_private_ext_ME_sec pvtMESec;
83 struct cca_public_sec pubMESec;
86 struct cca_public_key {
87 struct cca_token_hdr pubHdr;
88 struct cca_public_sec pubSec;
91 struct cca_pvt_ext_CRT_sec {
92 unsigned char section_identifier;
93 unsigned char version;
94 unsigned short section_length;
95 unsigned char private_key_hash[20];
96 unsigned char reserved1[4];
97 unsigned char key_format;
98 unsigned char reserved2;
99 unsigned char key_name_hash[20];
100 unsigned char key_use_flags[4];
101 unsigned short p_len;
102 unsigned short q_len;
103 unsigned short dp_len;
104 unsigned short dq_len;
105 unsigned short u_len;
106 unsigned short mod_len;
107 unsigned char reserved3[4];
108 unsigned short pad_len;
109 unsigned char reserved4[52];
110 unsigned char confounder[8];
113 #define CCA_PVT_EXT_CRT_SEC_ID_PVT 0x08
114 #define CCA_PVT_EXT_CRT_SEC_FMT_CL 0x40
116 struct cca_private_ext_CRT {
117 struct cca_token_hdr pvtCrtHdr;
118 struct cca_pvt_ext_CRT_sec pvtCrtSec;
119 struct cca_public_sec pubCrtSec;
122 struct ap_status_word {
123 unsigned char q_stat_flags;
124 unsigned char response_code;
125 unsigned char reserved[2];
128 #define AP_Q_STATUS_EMPTY 0x80
129 #define AP_Q_STATUS_REPLIES_WAITING 0x40
130 #define AP_Q_STATUS_ARRAY_FULL 0x20
132 #define AP_RESPONSE_NORMAL 0x00
133 #define AP_RESPONSE_Q_NOT_AVAIL 0x01
134 #define AP_RESPONSE_RESET_IN_PROGRESS 0x02
135 #define AP_RESPONSE_DECONFIGURED 0x03
136 #define AP_RESPONSE_CHECKSTOPPED 0x04
137 #define AP_RESPONSE_BUSY 0x05
138 #define AP_RESPONSE_Q_FULL 0x10
139 #define AP_RESPONSE_NO_PENDING_REPLY 0x10
140 #define AP_RESPONSE_INDEX_TOO_BIG 0x11
141 #define AP_RESPONSE_NO_FIRST_PART 0x13
142 #define AP_RESPONSE_MESSAGE_TOO_BIG 0x15
144 #define AP_MAX_CDX_BITL 4
145 #define AP_RQID_RESERVED_BITL 4
146 #define SKIP_BITL (AP_MAX_CDX_BITL + AP_RQID_RESERVED_BITL)
148 struct type4_hdr {
149 unsigned char reserved1;
150 unsigned char msg_type_code;
151 unsigned short msg_len;
152 unsigned char request_code;
153 unsigned char msg_fmt;
154 unsigned short reserved2;
157 #define TYPE4_TYPE_CODE 0x04
158 #define TYPE4_REQU_CODE 0x40
160 #define TYPE4_SME_LEN 0x0188
161 #define TYPE4_LME_LEN 0x0308
162 #define TYPE4_SCR_LEN 0x01E0
163 #define TYPE4_LCR_LEN 0x03A0
165 #define TYPE4_SME_FMT 0x00
166 #define TYPE4_LME_FMT 0x10
167 #define TYPE4_SCR_FMT 0x40
168 #define TYPE4_LCR_FMT 0x50
170 struct type4_sme {
171 struct type4_hdr header;
172 unsigned char message[128];
173 unsigned char exponent[128];
174 unsigned char modulus[128];
177 struct type4_lme {
178 struct type4_hdr header;
179 unsigned char message[256];
180 unsigned char exponent[256];
181 unsigned char modulus[256];
184 struct type4_scr {
185 struct type4_hdr header;
186 unsigned char message[128];
187 unsigned char dp[72];
188 unsigned char dq[64];
189 unsigned char p[72];
190 unsigned char q[64];
191 unsigned char u[72];
194 struct type4_lcr {
195 struct type4_hdr header;
196 unsigned char message[256];
197 unsigned char dp[136];
198 unsigned char dq[128];
199 unsigned char p[136];
200 unsigned char q[128];
201 unsigned char u[136];
204 union type4_msg {
205 struct type4_sme sme;
206 struct type4_lme lme;
207 struct type4_scr scr;
208 struct type4_lcr lcr;
211 struct type84_hdr {
212 unsigned char reserved1;
213 unsigned char code;
214 unsigned short len;
215 unsigned char reserved2[4];
218 #define TYPE84_RSP_CODE 0x84
220 struct type6_hdr {
221 unsigned char reserved1;
222 unsigned char type;
223 unsigned char reserved2[2];
224 unsigned char right[4];
225 unsigned char reserved3[2];
226 unsigned char reserved4[2];
227 unsigned char apfs[4];
228 unsigned int offset1;
229 unsigned int offset2;
230 unsigned int offset3;
231 unsigned int offset4;
232 unsigned char agent_id[16];
233 unsigned char rqid[2];
234 unsigned char reserved5[2];
235 unsigned char function_code[2];
236 unsigned char reserved6[2];
237 unsigned int ToCardLen1;
238 unsigned int ToCardLen2;
239 unsigned int ToCardLen3;
240 unsigned int ToCardLen4;
241 unsigned int FromCardLen1;
242 unsigned int FromCardLen2;
243 unsigned int FromCardLen3;
244 unsigned int FromCardLen4;
247 struct CPRB {
248 unsigned char cprb_len[2];
249 unsigned char cprb_ver_id;
250 unsigned char pad_000;
251 unsigned char srpi_rtcode[4];
252 unsigned char srpi_verb;
253 unsigned char flags;
254 unsigned char func_id[2];
255 unsigned char checkpoint_flag;
256 unsigned char resv2;
257 unsigned char req_parml[2];
258 unsigned char req_parmp[4];
259 unsigned char req_datal[4];
260 unsigned char req_datap[4];
261 unsigned char rpl_parml[2];
262 unsigned char pad_001[2];
263 unsigned char rpl_parmp[4];
264 unsigned char rpl_datal[4];
265 unsigned char rpl_datap[4];
266 unsigned char ccp_rscode[2];
267 unsigned char ccp_rtcode[2];
268 unsigned char repd_parml[2];
269 unsigned char mac_data_len[2];
270 unsigned char repd_datal[4];
271 unsigned char req_pc[2];
272 unsigned char res_origin[8];
273 unsigned char mac_value[8];
274 unsigned char logon_id[8];
275 unsigned char usage_domain[2];
276 unsigned char resv3[18];
277 unsigned char svr_namel[2];
278 unsigned char svr_name[8];
281 struct type6_msg {
282 struct type6_hdr header;
283 struct CPRB CPRB;
286 struct type86_hdr {
287 unsigned char reserved1;
288 unsigned char type;
289 unsigned char format;
290 unsigned char reserved2;
291 unsigned char reply_code;
292 unsigned char reserved3[3];
295 #define TYPE86_RSP_CODE 0x86
296 #define TYPE86_FMT2 0x02
298 struct type86_fmt2_msg {
299 struct type86_hdr header;
300 unsigned char reserved[4];
301 unsigned char apfs[4];
302 unsigned int count1;
303 unsigned int offset1;
304 unsigned int count2;
305 unsigned int offset2;
306 unsigned int count3;
307 unsigned int offset3;
308 unsigned int count4;
309 unsigned int offset4;
312 static struct type6_hdr static_type6_hdr = {
313 0x00,
314 0x06,
315 {0x00,0x00},
316 {0x00,0x00,0x00,0x00},
317 {0x00,0x00},
318 {0x00,0x00},
319 {0x00,0x00,0x00,0x00},
320 0x00000058,
321 0x00000000,
322 0x00000000,
323 0x00000000,
324 {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
325 0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
326 {0x00,0x00},
327 {0x00,0x00},
328 {0x50,0x44},
329 {0x00,0x00},
330 0x00000000,
331 0x00000000,
332 0x00000000,
333 0x00000000,
334 0x00000000,
335 0x00000000,
336 0x00000000,
337 0x00000000
340 static struct type6_hdr static_type6_hdrX = {
341 0x00,
342 0x06,
343 {0x00,0x00},
344 {0x00,0x00,0x00,0x00},
345 {0x00,0x00},
346 {0x00,0x00},
347 {0x00,0x00,0x00,0x00},
348 0x00000058,
349 0x00000000,
350 0x00000000,
351 0x00000000,
352 {0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
353 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
354 {0x00,0x00},
355 {0x00,0x00},
356 {0x50,0x44},
357 {0x00,0x00},
358 0x00000000,
359 0x00000000,
360 0x00000000,
361 0x00000000,
362 0x00000000,
363 0x00000000,
364 0x00000000,
365 0x00000000
368 static struct CPRB static_cprb = {
369 {0x70,0x00},
370 0x41,
371 0x00,
372 {0x00,0x00,0x00,0x00},
373 0x00,
374 0x00,
375 {0x54,0x32},
376 0x01,
377 0x00,
378 {0x00,0x00},
379 {0x00,0x00,0x00,0x00},
380 {0x00,0x00,0x00,0x00},
381 {0x00,0x00,0x00,0x00},
382 {0x00,0x00},
383 {0x00,0x00},
384 {0x00,0x00,0x00,0x00},
385 {0x00,0x00,0x00,0x00},
386 {0x00,0x00,0x00,0x00},
387 {0x00,0x00},
388 {0x00,0x00},
389 {0x00,0x00},
390 {0x00,0x00},
391 {0x00,0x00,0x00,0x00},
392 {0x00,0x00},
393 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
394 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
395 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
396 {0x00,0x00},
397 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
398 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
399 0x00,0x00},
400 {0x08,0x00},
401 {0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20}
404 struct function_and_rules_block {
405 unsigned char function_code[2];
406 unsigned char ulen[2];
407 unsigned char only_rule[8];
410 static struct function_and_rules_block static_pkd_function_and_rules = {
411 {0x50,0x44},
412 {0x0A,0x00},
413 {'P','K','C','S','-','1','.','2'}
416 static struct function_and_rules_block static_pke_function_and_rules = {
417 {0x50,0x4B},
418 {0x0A,0x00},
419 {'P','K','C','S','-','1','.','2'}
422 struct T6_keyBlock_hdr {
423 unsigned char blen[2];
424 unsigned char ulen[2];
425 unsigned char flags[2];
428 static struct T6_keyBlock_hdr static_T6_keyBlock_hdr = {
429 {0x89,0x01},
430 {0x87,0x01},
431 {0x00}
434 static struct CPRBX static_cprbx = {
435 0x00DC,
436 0x02,
437 {0x00,0x00,0x00},
438 {0x54,0x32},
439 {0x00,0x00,0x00,0x00},
440 0x00000000,
441 0x00000000,
442 0x00000000,
443 0x00000000,
444 0x00000000,
445 0x00000000,
446 0x00000000,
447 {0x00,0x00,0x00,0x00},
448 0x00000000,
449 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
450 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
451 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
452 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
453 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
454 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
455 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
456 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
457 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
458 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
459 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
460 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
461 0x0000,
462 0x0000,
463 0x00000000,
464 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
465 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
466 0x00,
467 0x00,
468 0x0000,
469 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
470 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
471 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
472 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
475 static struct function_and_rules_block static_pkd_function_and_rulesX_MCL2 = {
476 {0x50,0x44},
477 {0x00,0x0A},
478 {'P','K','C','S','-','1','.','2'}
481 static struct function_and_rules_block static_pke_function_and_rulesX_MCL2 = {
482 {0x50,0x4B},
483 {0x00,0x0A},
484 {'Z','E','R','O','-','P','A','D'}
487 static struct function_and_rules_block static_pkd_function_and_rulesX = {
488 {0x50,0x44},
489 {0x00,0x0A},
490 {'Z','E','R','O','-','P','A','D'}
493 static struct function_and_rules_block static_pke_function_and_rulesX = {
494 {0x50,0x4B},
495 {0x00,0x0A},
496 {'M','R','P',' ',' ',' ',' ',' '}
499 static unsigned char static_PKE_function_code[2] = {0x50, 0x4B};
501 struct T6_keyBlock_hdrX {
502 unsigned short blen;
503 unsigned short ulen;
504 unsigned char flags[2];
507 static unsigned char static_pad[256] = {
508 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
509 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
510 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
511 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
512 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
513 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
514 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
515 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
516 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
517 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
518 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
519 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
520 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
521 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
522 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
523 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
526 static struct cca_private_ext_ME static_pvt_me_key = {
528 0x1E,
529 0x00,
530 0x0183,
531 {0x00,0x00,0x00,0x00}
535 0x02,
536 0x00,
537 0x016C,
538 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
539 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
540 0x00,0x00,0x00,0x00},
541 {0x00,0x00,0x00,0x00},
542 0x00,
543 0x00,
544 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
545 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
546 0x00,0x00,0x00,0x00},
547 {0x80,0x00,0x00,0x00},
548 {0x00,0x00,0x00,0x00,0x00,0x00},
549 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
550 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
551 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
552 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
553 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
554 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
555 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
556 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
557 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
558 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
560 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
561 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
562 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
563 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
564 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
565 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
566 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
567 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
568 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
569 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
570 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
571 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
572 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
573 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
574 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
575 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
576 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
577 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
578 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
579 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
580 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
581 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
582 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
583 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
584 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
585 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
586 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
590 0x04,
591 0x00,
592 0x000F,
593 {0x00,0x00},
594 0x0003,
595 0x0000,
596 0x0000,
597 {0x01,0x00,0x01}
601 static struct cca_public_key static_public_key = {
603 0x1E,
604 0x00,
605 0x0000,
606 {0x00,0x00,0x00,0x00}
610 0x04,
611 0x00,
612 0x0000,
613 {0x00,0x00},
614 0x0000,
615 0x0000,
616 0x0000,
617 {0x01,0x00,0x01}
621 #define FIXED_TYPE6_ME_LEN 0x0000025F
623 #define FIXED_TYPE6_ME_EN_LEN 0x000000F0
625 #define FIXED_TYPE6_ME_LENX 0x000002CB
627 #define FIXED_TYPE6_ME_EN_LENX 0x0000015C
629 static struct cca_public_sec static_cca_pub_sec = {
630 0x04,
631 0x00,
632 0x000f,
633 {0x00,0x00},
634 0x0003,
635 0x0000,
636 0x0000,
637 {0x01,0x00,0x01}
640 #define FIXED_TYPE6_CR_LEN 0x00000177
642 #define FIXED_TYPE6_CR_LENX 0x000001E3
644 #define MAX_RESPONSE_SIZE 0x00000710
646 #define MAX_RESPONSEX_SIZE 0x0000077C
648 #define RESPONSE_CPRB_SIZE 0x000006B8
649 #define RESPONSE_CPRBX_SIZE 0x00000724
651 struct error_hdr {
652 unsigned char reserved1;
653 unsigned char type;
654 unsigned char reserved2[2];
655 unsigned char reply_code;
656 unsigned char reserved3[3];
659 #define TYPE82_RSP_CODE 0x82
661 #define REP82_ERROR_MACHINE_FAILURE 0x10
662 #define REP82_ERROR_PREEMPT_FAILURE 0x12
663 #define REP82_ERROR_CHECKPT_FAILURE 0x14
664 #define REP82_ERROR_MESSAGE_TYPE 0x20
665 #define REP82_ERROR_INVALID_COMM_CD 0x21
666 #define REP82_ERROR_INVALID_MSG_LEN 0x23
667 #define REP82_ERROR_RESERVD_FIELD 0x24
668 #define REP82_ERROR_FORMAT_FIELD 0x29
669 #define REP82_ERROR_INVALID_COMMAND 0x30
670 #define REP82_ERROR_MALFORMED_MSG 0x40
671 #define REP82_ERROR_RESERVED_FIELDO 0x50
672 #define REP82_ERROR_WORD_ALIGNMENT 0x60
673 #define REP82_ERROR_MESSAGE_LENGTH 0x80
674 #define REP82_ERROR_OPERAND_INVALID 0x82
675 #define REP82_ERROR_OPERAND_SIZE 0x84
676 #define REP82_ERROR_EVEN_MOD_IN_OPND 0x85
677 #define REP82_ERROR_RESERVED_FIELD 0x88
678 #define REP82_ERROR_TRANSPORT_FAIL 0x90
679 #define REP82_ERROR_PACKET_TRUNCATED 0xA0
680 #define REP82_ERROR_ZERO_BUFFER_LEN 0xB0
682 #define CALLER_HEADER 12
684 static inline int
685 testq(int q_nr, int *q_depth, int *dev_type, struct ap_status_word *stat)
687 int ccode;
689 asm volatile
690 #ifdef __s390x__
691 (" llgfr 0,%4 \n"
692 " slgr 1,1 \n"
693 " lgr 2,1 \n"
694 "0: .long 0xb2af0000 \n"
695 "1: ipm %0 \n"
696 " srl %0,28 \n"
697 " iihh %0,0 \n"
698 " iihl %0,0 \n"
699 " lgr %1,1 \n"
700 " lgr %3,2 \n"
701 " srl %3,24 \n"
702 " sll 2,24 \n"
703 " srl 2,24 \n"
704 " lgr %2,2 \n"
705 "2: \n"
706 ".section .fixup,\"ax\" \n"
707 "3: \n"
708 " lhi %0,%h5 \n"
709 " jg 2b \n"
710 ".previous \n"
711 ".section __ex_table,\"a\" \n"
712 " .align 8 \n"
713 " .quad 0b,3b \n"
714 " .quad 1b,3b \n"
715 ".previous"
716 :"=d" (ccode),"=d" (*stat),"=d" (*q_depth), "=d" (*dev_type)
717 :"d" (q_nr), "K" (DEV_TSQ_EXCEPTION)
718 :"cc","0","1","2","memory");
719 #else
720 (" lr 0,%4 \n"
721 " slr 1,1 \n"
722 " lr 2,1 \n"
723 "0: .long 0xb2af0000 \n"
724 "1: ipm %0 \n"
725 " srl %0,28 \n"
726 " lr %1,1 \n"
727 " lr %3,2 \n"
728 " srl %3,24 \n"
729 " sll 2,24 \n"
730 " srl 2,24 \n"
731 " lr %2,2 \n"
732 "2: \n"
733 ".section .fixup,\"ax\" \n"
734 "3: \n"
735 " lhi %0,%h5 \n"
736 " bras 1,4f \n"
737 " .long 2b \n"
738 "4: \n"
739 " l 1,0(1) \n"
740 " br 1 \n"
741 ".previous \n"
742 ".section __ex_table,\"a\" \n"
743 " .align 4 \n"
744 " .long 0b,3b \n"
745 " .long 1b,3b \n"
746 ".previous"
747 :"=d" (ccode),"=d" (*stat),"=d" (*q_depth), "=d" (*dev_type)
748 :"d" (q_nr), "K" (DEV_TSQ_EXCEPTION)
749 :"cc","0","1","2","memory");
750 #endif
751 return ccode;
754 static inline int
755 resetq(int q_nr, struct ap_status_word *stat_p)
757 int ccode;
759 asm volatile
760 #ifdef __s390x__
761 (" llgfr 0,%2 \n"
762 " lghi 1,1 \n"
763 " sll 1,24 \n"
764 " or 0,1 \n"
765 " slgr 1,1 \n"
766 " lgr 2,1 \n"
767 "0: .long 0xb2af0000 \n"
768 "1: ipm %0 \n"
769 " srl %0,28 \n"
770 " iihh %0,0 \n"
771 " iihl %0,0 \n"
772 " lgr %1,1 \n"
773 "2: \n"
774 ".section .fixup,\"ax\" \n"
775 "3: \n"
776 " lhi %0,%h3 \n"
777 " jg 2b \n"
778 ".previous \n"
779 ".section __ex_table,\"a\" \n"
780 " .align 8 \n"
781 " .quad 0b,3b \n"
782 " .quad 1b,3b \n"
783 ".previous"
784 :"=d" (ccode),"=d" (*stat_p)
785 :"d" (q_nr), "K" (DEV_RSQ_EXCEPTION)
786 :"cc","0","1","2","memory");
787 #else
788 (" lr 0,%2 \n"
789 " lhi 1,1 \n"
790 " sll 1,24 \n"
791 " or 0,1 \n"
792 " slr 1,1 \n"
793 " lr 2,1 \n"
794 "0: .long 0xb2af0000 \n"
795 "1: ipm %0 \n"
796 " srl %0,28 \n"
797 " lr %1,1 \n"
798 "2: \n"
799 ".section .fixup,\"ax\" \n"
800 "3: \n"
801 " lhi %0,%h3 \n"
802 " bras 1,4f \n"
803 " .long 2b \n"
804 "4: \n"
805 " l 1,0(1) \n"
806 " br 1 \n"
807 ".previous \n"
808 ".section __ex_table,\"a\" \n"
809 " .align 4 \n"
810 " .long 0b,3b \n"
811 " .long 1b,3b \n"
812 ".previous"
813 :"=d" (ccode),"=d" (*stat_p)
814 :"d" (q_nr), "K" (DEV_RSQ_EXCEPTION)
815 :"cc","0","1","2","memory");
816 #endif
817 return ccode;
820 static inline int
821 sen(int msg_len, unsigned char *msg_ext, struct ap_status_word *stat)
823 int ccode;
825 asm volatile
826 #ifdef __s390x__
827 (" lgr 6,%3 \n"
828 " llgfr 7,%2 \n"
829 " llgt 0,0(6) \n"
830 " lghi 1,64 \n"
831 " sll 1,24 \n"
832 " or 0,1 \n"
833 " la 6,4(6) \n"
834 " llgt 2,0(6) \n"
835 " llgt 3,4(6) \n"
836 " la 6,8(6) \n"
837 " slr 1,1 \n"
838 "0: .long 0xb2ad0026 \n"
839 "1: brc 2,0b \n"
840 " ipm %0 \n"
841 " srl %0,28 \n"
842 " iihh %0,0 \n"
843 " iihl %0,0 \n"
844 " lgr %1,1 \n"
845 "2: \n"
846 ".section .fixup,\"ax\" \n"
847 "3: \n"
848 " lhi %0,%h4 \n"
849 " jg 2b \n"
850 ".previous \n"
851 ".section __ex_table,\"a\" \n"
852 " .align 8 \n"
853 " .quad 0b,3b \n"
854 " .quad 1b,3b \n"
855 ".previous"
856 :"=d" (ccode),"=d" (*stat)
857 :"d" (msg_len),"a" (msg_ext), "K" (DEV_SEN_EXCEPTION)
858 :"cc","0","1","2","3","6","7","memory");
859 #else
860 (" lr 6,%3 \n"
861 " lr 7,%2 \n"
862 " l 0,0(6) \n"
863 " lhi 1,64 \n"
864 " sll 1,24 \n"
865 " or 0,1 \n"
866 " la 6,4(6) \n"
867 " l 2,0(6) \n"
868 " l 3,4(6) \n"
869 " la 6,8(6) \n"
870 " slr 1,1 \n"
871 "0: .long 0xb2ad0026 \n"
872 "1: brc 2,0b \n"
873 " ipm %0 \n"
874 " srl %0,28 \n"
875 " lr %1,1 \n"
876 "2: \n"
877 ".section .fixup,\"ax\" \n"
878 "3: \n"
879 " lhi %0,%h4 \n"
880 " bras 1,4f \n"
881 " .long 2b \n"
882 "4: \n"
883 " l 1,0(1) \n"
884 " br 1 \n"
885 ".previous \n"
886 ".section __ex_table,\"a\" \n"
887 " .align 4 \n"
888 " .long 0b,3b \n"
889 " .long 1b,3b \n"
890 ".previous"
891 :"=d" (ccode),"=d" (*stat)
892 :"d" (msg_len),"a" (msg_ext), "K" (DEV_SEN_EXCEPTION)
893 :"cc","0","1","2","3","6","7","memory");
894 #endif
895 return ccode;
898 static inline int
899 rec(int q_nr, int buff_l, unsigned char *rsp, unsigned char *id,
900 struct ap_status_word *st)
902 int ccode;
904 asm volatile
905 #ifdef __s390x__
906 (" llgfr 0,%2 \n"
907 " lgr 3,%4 \n"
908 " lgr 6,%3 \n"
909 " llgfr 7,%5 \n"
910 " lghi 1,128 \n"
911 " sll 1,24 \n"
912 " or 0,1 \n"
913 " slgr 1,1 \n"
914 " lgr 2,1 \n"
915 " lgr 4,1 \n"
916 " lgr 5,1 \n"
917 "0: .long 0xb2ae0046 \n"
918 "1: brc 2,0b \n"
919 " brc 4,0b \n"
920 " ipm %0 \n"
921 " srl %0,28 \n"
922 " iihh %0,0 \n"
923 " iihl %0,0 \n"
924 " lgr %1,1 \n"
925 " st 4,0(3) \n"
926 " st 5,4(3) \n"
927 "2: \n"
928 ".section .fixup,\"ax\" \n"
929 "3: \n"
930 " lhi %0,%h6 \n"
931 " jg 2b \n"
932 ".previous \n"
933 ".section __ex_table,\"a\" \n"
934 " .align 8 \n"
935 " .quad 0b,3b \n"
936 " .quad 1b,3b \n"
937 ".previous"
938 :"=d"(ccode),"=d"(*st)
939 :"d" (q_nr), "d" (rsp), "d" (id), "d" (buff_l), "K" (DEV_REC_EXCEPTION)
940 :"cc","0","1","2","3","4","5","6","7","memory");
941 #else
942 (" lr 0,%2 \n"
943 " lr 3,%4 \n"
944 " lr 6,%3 \n"
945 " lr 7,%5 \n"
946 " lhi 1,128 \n"
947 " sll 1,24 \n"
948 " or 0,1 \n"
949 " slr 1,1 \n"
950 " lr 2,1 \n"
951 " lr 4,1 \n"
952 " lr 5,1 \n"
953 "0: .long 0xb2ae0046 \n"
954 "1: brc 2,0b \n"
955 " brc 4,0b \n"
956 " ipm %0 \n"
957 " srl %0,28 \n"
958 " lr %1,1 \n"
959 " st 4,0(3) \n"
960 " st 5,4(3) \n"
961 "2: \n"
962 ".section .fixup,\"ax\" \n"
963 "3: \n"
964 " lhi %0,%h6 \n"
965 " bras 1,4f \n"
966 " .long 2b \n"
967 "4: \n"
968 " l 1,0(1) \n"
969 " br 1 \n"
970 ".previous \n"
971 ".section __ex_table,\"a\" \n"
972 " .align 4 \n"
973 " .long 0b,3b \n"
974 " .long 1b,3b \n"
975 ".previous"
976 :"=d"(ccode),"=d"(*st)
977 :"d" (q_nr), "d" (rsp), "d" (id), "d" (buff_l), "K" (DEV_REC_EXCEPTION)
978 :"cc","0","1","2","3","4","5","6","7","memory");
979 #endif
980 return ccode;
983 static inline void
984 itoLe2(int *i_p, unsigned char *lechars)
986 *lechars = *((unsigned char *) i_p + sizeof(int) - 1);
987 *(lechars + 1) = *((unsigned char *) i_p + sizeof(int) - 2);
990 static inline void
991 le2toI(unsigned char *lechars, int *i_p)
993 unsigned char *ic_p;
994 *i_p = 0;
995 ic_p = (unsigned char *) i_p;
996 *(ic_p + 2) = *(lechars + 1);
997 *(ic_p + 3) = *(lechars);
1000 static inline int
1001 is_empty(unsigned char *ptr, int len)
1003 return !memcmp(ptr, (unsigned char *) &static_pvt_me_key+60, len);
1006 enum hdstat
1007 query_online(int deviceNr, int cdx, int resetNr, int *q_depth, int *dev_type)
1009 int q_nr, i, t_depth, t_dev_type;
1010 enum devstat ccode;
1011 struct ap_status_word stat_word;
1012 enum hdstat stat;
1013 int break_out;
1015 q_nr = (deviceNr << SKIP_BITL) + cdx;
1016 stat = HD_BUSY;
1017 ccode = testq(q_nr, &t_depth, &t_dev_type, &stat_word);
1018 PDEBUG("ccode %d response_code %02X\n", ccode, stat_word.response_code);
1019 break_out = 0;
1020 for (i = 0; i < resetNr; i++) {
1021 if (ccode > 3) {
1022 PRINTKC("Exception testing device %d\n", i);
1023 return HD_TSQ_EXCEPTION;
1025 switch (ccode) {
1026 case 0:
1027 PDEBUG("t_dev_type %d\n", t_dev_type);
1028 break_out = 1;
1029 stat = HD_ONLINE;
1030 *q_depth = t_depth + 1;
1031 switch (t_dev_type) {
1032 case OTHER_HW:
1033 stat = HD_NOT_THERE;
1034 *dev_type = NILDEV;
1035 break;
1036 case PCICA_HW:
1037 *dev_type = PCICA;
1038 break;
1039 case PCICC_HW:
1040 *dev_type = PCICC;
1041 break;
1042 case PCIXCC_HW:
1043 *dev_type = PCIXCC_UNK;
1044 break;
1045 case CEX2C_HW:
1046 *dev_type = CEX2C;
1047 break;
1048 default:
1049 *dev_type = NILDEV;
1050 break;
1052 PDEBUG("available device %d: Q depth = %d, dev "
1053 "type = %d, stat = %02X%02X%02X%02X\n",
1054 deviceNr, *q_depth, *dev_type,
1055 stat_word.q_stat_flags,
1056 stat_word.response_code,
1057 stat_word.reserved[0],
1058 stat_word.reserved[1]);
1059 break;
1060 case 3:
1061 switch (stat_word.response_code) {
1062 case AP_RESPONSE_NORMAL:
1063 stat = HD_ONLINE;
1064 break_out = 1;
1065 *q_depth = t_depth + 1;
1066 *dev_type = t_dev_type;
1067 PDEBUG("cc3, available device "
1068 "%d: Q depth = %d, dev "
1069 "type = %d, stat = "
1070 "%02X%02X%02X%02X\n",
1071 deviceNr, *q_depth,
1072 *dev_type,
1073 stat_word.q_stat_flags,
1074 stat_word.response_code,
1075 stat_word.reserved[0],
1076 stat_word.reserved[1]);
1077 break;
1078 case AP_RESPONSE_Q_NOT_AVAIL:
1079 stat = HD_NOT_THERE;
1080 break_out = 1;
1081 break;
1082 case AP_RESPONSE_RESET_IN_PROGRESS:
1083 PDEBUG("device %d in reset\n",
1084 deviceNr);
1085 break;
1086 case AP_RESPONSE_DECONFIGURED:
1087 stat = HD_DECONFIGURED;
1088 break_out = 1;
1089 break;
1090 case AP_RESPONSE_CHECKSTOPPED:
1091 stat = HD_CHECKSTOPPED;
1092 break_out = 1;
1093 break;
1094 case AP_RESPONSE_BUSY:
1095 PDEBUG("device %d busy\n",
1096 deviceNr);
1097 break;
1098 default:
1099 break;
1101 break;
1102 default:
1103 stat = HD_NOT_THERE;
1104 break_out = 1;
1105 break;
1107 if (break_out)
1108 break;
1110 udelay(5);
1112 ccode = testq(q_nr, &t_depth, &t_dev_type, &stat_word);
1114 return stat;
1117 enum devstat
1118 reset_device(int deviceNr, int cdx, int resetNr)
1120 int q_nr, ccode = 0, dummy_qdepth, dummy_devType, i;
1121 struct ap_status_word stat_word;
1122 enum devstat stat;
1123 int break_out;
1125 q_nr = (deviceNr << SKIP_BITL) + cdx;
1126 stat = DEV_GONE;
1127 ccode = resetq(q_nr, &stat_word);
1128 if (ccode > 3)
1129 return DEV_RSQ_EXCEPTION;
1131 break_out = 0;
1132 for (i = 0; i < resetNr; i++) {
1133 switch (ccode) {
1134 case 0:
1135 stat = DEV_ONLINE;
1136 if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY)
1137 break_out = 1;
1138 break;
1139 case 3:
1140 switch (stat_word.response_code) {
1141 case AP_RESPONSE_NORMAL:
1142 stat = DEV_ONLINE;
1143 if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY)
1144 break_out = 1;
1145 break;
1146 case AP_RESPONSE_Q_NOT_AVAIL:
1147 case AP_RESPONSE_DECONFIGURED:
1148 case AP_RESPONSE_CHECKSTOPPED:
1149 stat = DEV_GONE;
1150 break_out = 1;
1151 break;
1152 case AP_RESPONSE_RESET_IN_PROGRESS:
1153 case AP_RESPONSE_BUSY:
1154 default:
1155 break;
1157 break;
1158 default:
1159 stat = DEV_GONE;
1160 break_out = 1;
1161 break;
1163 if (break_out == 1)
1164 break;
1165 udelay(5);
1167 ccode = testq(q_nr, &dummy_qdepth, &dummy_devType, &stat_word);
1168 if (ccode > 3) {
1169 stat = DEV_TSQ_EXCEPTION;
1170 break;
1173 PDEBUG("Number of testq's needed for reset: %d\n", i);
1175 if (i >= resetNr) {
1176 stat = DEV_GONE;
1179 return stat;
1182 #ifdef DEBUG_HYDRA_MSGS
1183 static inline void
1184 print_buffer(unsigned char *buffer, int bufflen)
1186 int i;
1187 for (i = 0; i < bufflen; i += 16) {
1188 PRINTK("%04X: %02X%02X%02X%02X %02X%02X%02X%02X "
1189 "%02X%02X%02X%02X %02X%02X%02X%02X\n", i,
1190 buffer[i+0], buffer[i+1], buffer[i+2], buffer[i+3],
1191 buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7],
1192 buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11],
1193 buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
1196 #endif
1198 enum devstat
1199 send_to_AP(int dev_nr, int cdx, int msg_len, unsigned char *msg_ext)
1201 struct ap_status_word stat_word;
1202 enum devstat stat;
1203 int ccode;
1204 u32 *q_nr_p = (u32 *)msg_ext;
1206 *q_nr_p = (dev_nr << SKIP_BITL) + cdx;
1207 PDEBUG("msg_len passed to sen: %d\n", msg_len);
1208 PDEBUG("q number passed to sen: %02x%02x%02x%02x\n",
1209 msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3]);
1210 stat = DEV_GONE;
1212 #ifdef DEBUG_HYDRA_MSGS
1213 PRINTK("Request header: %02X%02X%02X%02X %02X%02X%02X%02X "
1214 "%02X%02X%02X%02X\n",
1215 msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3],
1216 msg_ext[4], msg_ext[5], msg_ext[6], msg_ext[7],
1217 msg_ext[8], msg_ext[9], msg_ext[10], msg_ext[11]);
1218 print_buffer(msg_ext+CALLER_HEADER, msg_len);
1219 #endif
1221 ccode = sen(msg_len, msg_ext, &stat_word);
1222 if (ccode > 3)
1223 return DEV_SEN_EXCEPTION;
1225 PDEBUG("nq cc: %u, st: %02x%02x%02x%02x\n",
1226 ccode, stat_word.q_stat_flags, stat_word.response_code,
1227 stat_word.reserved[0], stat_word.reserved[1]);
1228 switch (ccode) {
1229 case 0:
1230 stat = DEV_ONLINE;
1231 break;
1232 case 1:
1233 stat = DEV_GONE;
1234 break;
1235 case 3:
1236 switch (stat_word.response_code) {
1237 case AP_RESPONSE_NORMAL:
1238 stat = DEV_ONLINE;
1239 break;
1240 case AP_RESPONSE_Q_FULL:
1241 stat = DEV_QUEUE_FULL;
1242 break;
1243 default:
1244 stat = DEV_GONE;
1245 break;
1247 break;
1248 default:
1249 stat = DEV_GONE;
1250 break;
1253 return stat;
1256 enum devstat
1257 receive_from_AP(int dev_nr, int cdx, int resplen, unsigned char *resp,
1258 unsigned char *psmid)
1260 int ccode;
1261 struct ap_status_word stat_word;
1262 enum devstat stat;
1264 memset(resp, 0x00, 8);
1266 ccode = rec((dev_nr << SKIP_BITL) + cdx, resplen, resp, psmid,
1267 &stat_word);
1268 if (ccode > 3)
1269 return DEV_REC_EXCEPTION;
1271 PDEBUG("dq cc: %u, st: %02x%02x%02x%02x\n",
1272 ccode, stat_word.q_stat_flags, stat_word.response_code,
1273 stat_word.reserved[0], stat_word.reserved[1]);
1275 stat = DEV_GONE;
1276 switch (ccode) {
1277 case 0:
1278 stat = DEV_ONLINE;
1279 #ifdef DEBUG_HYDRA_MSGS
1280 print_buffer(resp, resplen);
1281 #endif
1282 break;
1283 case 3:
1284 switch (stat_word.response_code) {
1285 case AP_RESPONSE_NORMAL:
1286 stat = DEV_ONLINE;
1287 break;
1288 case AP_RESPONSE_NO_PENDING_REPLY:
1289 if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY)
1290 stat = DEV_EMPTY;
1291 else
1292 stat = DEV_NO_WORK;
1293 break;
1294 case AP_RESPONSE_INDEX_TOO_BIG:
1295 case AP_RESPONSE_NO_FIRST_PART:
1296 case AP_RESPONSE_MESSAGE_TOO_BIG:
1297 stat = DEV_BAD_MESSAGE;
1298 break;
1299 default:
1300 break;
1302 break;
1303 default:
1304 break;
1307 return stat;
1310 static inline int
1311 pad_msg(unsigned char *buffer, int totalLength, int msgLength)
1313 int pad_len;
1315 for (pad_len = 0; pad_len < (totalLength - msgLength); pad_len++)
1316 if (buffer[pad_len] != 0x00)
1317 break;
1318 pad_len -= 3;
1319 if (pad_len < 8)
1320 return SEN_PAD_ERROR;
1322 buffer[0] = 0x00;
1323 buffer[1] = 0x02;
1325 memcpy(buffer+2, static_pad, pad_len);
1327 buffer[pad_len + 2] = 0x00;
1329 return 0;
1332 static inline int
1333 is_common_public_key(unsigned char *key, int len)
1335 int i;
1337 for (i = 0; i < len; i++)
1338 if (key[i])
1339 break;
1340 key += i;
1341 len -= i;
1342 if (((len == 1) && (key[0] == 3)) ||
1343 ((len == 3) && (key[0] == 1) && (key[1] == 0) && (key[2] == 1)))
1344 return 1;
1346 return 0;
1349 static int
1350 ICAMEX_msg_to_type4MEX_msg(struct ica_rsa_modexpo *icaMex_p, int *z90cMsg_l_p,
1351 union type4_msg *z90cMsg_p)
1353 int mod_len, msg_size, mod_tgt_len, exp_tgt_len, inp_tgt_len;
1354 unsigned char *mod_tgt, *exp_tgt, *inp_tgt;
1355 union type4_msg *tmp_type4_msg;
1357 mod_len = icaMex_p->inputdatalength;
1359 msg_size = ((mod_len <= 128) ? TYPE4_SME_LEN : TYPE4_LME_LEN) +
1360 CALLER_HEADER;
1362 memset(z90cMsg_p, 0, msg_size);
1364 tmp_type4_msg = (union type4_msg *)
1365 ((unsigned char *) z90cMsg_p + CALLER_HEADER);
1367 tmp_type4_msg->sme.header.msg_type_code = TYPE4_TYPE_CODE;
1368 tmp_type4_msg->sme.header.request_code = TYPE4_REQU_CODE;
1370 if (mod_len <= 128) {
1371 tmp_type4_msg->sme.header.msg_fmt = TYPE4_SME_FMT;
1372 tmp_type4_msg->sme.header.msg_len = TYPE4_SME_LEN;
1373 mod_tgt = tmp_type4_msg->sme.modulus;
1374 mod_tgt_len = sizeof(tmp_type4_msg->sme.modulus);
1375 exp_tgt = tmp_type4_msg->sme.exponent;
1376 exp_tgt_len = sizeof(tmp_type4_msg->sme.exponent);
1377 inp_tgt = tmp_type4_msg->sme.message;
1378 inp_tgt_len = sizeof(tmp_type4_msg->sme.message);
1379 } else {
1380 tmp_type4_msg->lme.header.msg_fmt = TYPE4_LME_FMT;
1381 tmp_type4_msg->lme.header.msg_len = TYPE4_LME_LEN;
1382 mod_tgt = tmp_type4_msg->lme.modulus;
1383 mod_tgt_len = sizeof(tmp_type4_msg->lme.modulus);
1384 exp_tgt = tmp_type4_msg->lme.exponent;
1385 exp_tgt_len = sizeof(tmp_type4_msg->lme.exponent);
1386 inp_tgt = tmp_type4_msg->lme.message;
1387 inp_tgt_len = sizeof(tmp_type4_msg->lme.message);
1390 mod_tgt += (mod_tgt_len - mod_len);
1391 if (copy_from_user(mod_tgt, icaMex_p->n_modulus, mod_len))
1392 return SEN_RELEASED;
1393 if (is_empty(mod_tgt, mod_len))
1394 return SEN_USER_ERROR;
1395 exp_tgt += (exp_tgt_len - mod_len);
1396 if (copy_from_user(exp_tgt, icaMex_p->b_key, mod_len))
1397 return SEN_RELEASED;
1398 if (is_empty(exp_tgt, mod_len))
1399 return SEN_USER_ERROR;
1400 inp_tgt += (inp_tgt_len - mod_len);
1401 if (copy_from_user(inp_tgt, icaMex_p->inputdata, mod_len))
1402 return SEN_RELEASED;
1403 if (is_empty(inp_tgt, mod_len))
1404 return SEN_USER_ERROR;
1406 *z90cMsg_l_p = msg_size - CALLER_HEADER;
1408 return 0;
1411 static int
1412 ICACRT_msg_to_type4CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p,
1413 int *z90cMsg_l_p, union type4_msg *z90cMsg_p)
1415 int mod_len, short_len, long_len, tmp_size, p_tgt_len, q_tgt_len,
1416 dp_tgt_len, dq_tgt_len, u_tgt_len, inp_tgt_len;
1417 unsigned char *p_tgt, *q_tgt, *dp_tgt, *dq_tgt, *u_tgt, *inp_tgt;
1418 union type4_msg *tmp_type4_msg;
1420 mod_len = icaMsg_p->inputdatalength;
1421 short_len = mod_len / 2;
1422 long_len = mod_len / 2 + 8;
1424 tmp_size = ((mod_len <= 128) ? TYPE4_SCR_LEN : TYPE4_LCR_LEN) +
1425 CALLER_HEADER;
1427 memset(z90cMsg_p, 0, tmp_size);
1429 tmp_type4_msg = (union type4_msg *)
1430 ((unsigned char *) z90cMsg_p + CALLER_HEADER);
1432 tmp_type4_msg->scr.header.msg_type_code = TYPE4_TYPE_CODE;
1433 tmp_type4_msg->scr.header.request_code = TYPE4_REQU_CODE;
1434 if (mod_len <= 128) {
1435 tmp_type4_msg->scr.header.msg_fmt = TYPE4_SCR_FMT;
1436 tmp_type4_msg->scr.header.msg_len = TYPE4_SCR_LEN;
1437 p_tgt = tmp_type4_msg->scr.p;
1438 p_tgt_len = sizeof(tmp_type4_msg->scr.p);
1439 q_tgt = tmp_type4_msg->scr.q;
1440 q_tgt_len = sizeof(tmp_type4_msg->scr.q);
1441 dp_tgt = tmp_type4_msg->scr.dp;
1442 dp_tgt_len = sizeof(tmp_type4_msg->scr.dp);
1443 dq_tgt = tmp_type4_msg->scr.dq;
1444 dq_tgt_len = sizeof(tmp_type4_msg->scr.dq);
1445 u_tgt = tmp_type4_msg->scr.u;
1446 u_tgt_len = sizeof(tmp_type4_msg->scr.u);
1447 inp_tgt = tmp_type4_msg->scr.message;
1448 inp_tgt_len = sizeof(tmp_type4_msg->scr.message);
1449 } else {
1450 tmp_type4_msg->lcr.header.msg_fmt = TYPE4_LCR_FMT;
1451 tmp_type4_msg->lcr.header.msg_len = TYPE4_LCR_LEN;
1452 p_tgt = tmp_type4_msg->lcr.p;
1453 p_tgt_len = sizeof(tmp_type4_msg->lcr.p);
1454 q_tgt = tmp_type4_msg->lcr.q;
1455 q_tgt_len = sizeof(tmp_type4_msg->lcr.q);
1456 dp_tgt = tmp_type4_msg->lcr.dp;
1457 dp_tgt_len = sizeof(tmp_type4_msg->lcr.dp);
1458 dq_tgt = tmp_type4_msg->lcr.dq;
1459 dq_tgt_len = sizeof(tmp_type4_msg->lcr.dq);
1460 u_tgt = tmp_type4_msg->lcr.u;
1461 u_tgt_len = sizeof(tmp_type4_msg->lcr.u);
1462 inp_tgt = tmp_type4_msg->lcr.message;
1463 inp_tgt_len = sizeof(tmp_type4_msg->lcr.message);
1466 p_tgt += (p_tgt_len - long_len);
1467 if (copy_from_user(p_tgt, icaMsg_p->np_prime, long_len))
1468 return SEN_RELEASED;
1469 if (is_empty(p_tgt, long_len))
1470 return SEN_USER_ERROR;
1471 q_tgt += (q_tgt_len - short_len);
1472 if (copy_from_user(q_tgt, icaMsg_p->nq_prime, short_len))
1473 return SEN_RELEASED;
1474 if (is_empty(q_tgt, short_len))
1475 return SEN_USER_ERROR;
1476 dp_tgt += (dp_tgt_len - long_len);
1477 if (copy_from_user(dp_tgt, icaMsg_p->bp_key, long_len))
1478 return SEN_RELEASED;
1479 if (is_empty(dp_tgt, long_len))
1480 return SEN_USER_ERROR;
1481 dq_tgt += (dq_tgt_len - short_len);
1482 if (copy_from_user(dq_tgt, icaMsg_p->bq_key, short_len))
1483 return SEN_RELEASED;
1484 if (is_empty(dq_tgt, short_len))
1485 return SEN_USER_ERROR;
1486 u_tgt += (u_tgt_len - long_len);
1487 if (copy_from_user(u_tgt, icaMsg_p->u_mult_inv, long_len))
1488 return SEN_RELEASED;
1489 if (is_empty(u_tgt, long_len))
1490 return SEN_USER_ERROR;
1491 inp_tgt += (inp_tgt_len - mod_len);
1492 if (copy_from_user(inp_tgt, icaMsg_p->inputdata, mod_len))
1493 return SEN_RELEASED;
1494 if (is_empty(inp_tgt, mod_len))
1495 return SEN_USER_ERROR;
1497 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1499 return 0;
1502 static int
1503 ICAMEX_msg_to_type6MEX_de_msg(struct ica_rsa_modexpo *icaMsg_p, int cdx,
1504 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1506 int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l;
1507 unsigned char *temp;
1508 struct type6_hdr *tp6Hdr_p;
1509 struct CPRB *cprb_p;
1510 struct cca_private_ext_ME *key_p;
1511 static int deprecated_msg_count = 0;
1513 mod_len = icaMsg_p->inputdatalength;
1514 tmp_size = FIXED_TYPE6_ME_LEN + mod_len;
1515 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1516 parmBlock_l = total_CPRB_len - sizeof(struct CPRB);
1517 tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER;
1519 memset(z90cMsg_p, 0, tmp_size);
1521 temp = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1522 memcpy(temp, &static_type6_hdr, sizeof(struct type6_hdr));
1523 tp6Hdr_p = (struct type6_hdr *)temp;
1524 tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4);
1525 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE;
1527 temp += sizeof(struct type6_hdr);
1528 memcpy(temp, &static_cprb, sizeof(struct CPRB));
1529 cprb_p = (struct CPRB *) temp;
1530 cprb_p->usage_domain[0]= (unsigned char)cdx;
1531 itoLe2(&parmBlock_l, cprb_p->req_parml);
1532 itoLe2((int *)&(tp6Hdr_p->FromCardLen1), cprb_p->rpl_parml);
1534 temp += sizeof(struct CPRB);
1535 memcpy(temp, &static_pkd_function_and_rules,
1536 sizeof(struct function_and_rules_block));
1538 temp += sizeof(struct function_and_rules_block);
1539 vud_len = 2 + icaMsg_p->inputdatalength;
1540 itoLe2(&vud_len, temp);
1542 temp += 2;
1543 if (copy_from_user(temp, icaMsg_p->inputdata, mod_len))
1544 return SEN_RELEASED;
1545 if (is_empty(temp, mod_len))
1546 return SEN_USER_ERROR;
1548 temp += mod_len;
1549 memcpy(temp, &static_T6_keyBlock_hdr, sizeof(struct T6_keyBlock_hdr));
1551 temp += sizeof(struct T6_keyBlock_hdr);
1552 memcpy(temp, &static_pvt_me_key, sizeof(struct cca_private_ext_ME));
1553 key_p = (struct cca_private_ext_ME *)temp;
1554 temp = key_p->pvtMESec.exponent + sizeof(key_p->pvtMESec.exponent)
1555 - mod_len;
1556 if (copy_from_user(temp, icaMsg_p->b_key, mod_len))
1557 return SEN_RELEASED;
1558 if (is_empty(temp, mod_len))
1559 return SEN_USER_ERROR;
1561 if (is_common_public_key(temp, mod_len)) {
1562 if (deprecated_msg_count < 20) {
1563 PRINTK("Common public key used for modex decrypt\n");
1564 deprecated_msg_count++;
1565 if (deprecated_msg_count == 20)
1566 PRINTK("No longer issuing messages about common"
1567 " public key for modex decrypt.\n");
1569 return SEN_NOT_AVAIL;
1572 temp = key_p->pvtMESec.modulus + sizeof(key_p->pvtMESec.modulus)
1573 - mod_len;
1574 if (copy_from_user(temp, icaMsg_p->n_modulus, mod_len))
1575 return SEN_RELEASED;
1576 if (is_empty(temp, mod_len))
1577 return SEN_USER_ERROR;
1579 key_p->pubMESec.modulus_bit_len = 8 * mod_len;
1581 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1583 return 0;
1586 static int
1587 ICAMEX_msg_to_type6MEX_en_msg(struct ica_rsa_modexpo *icaMsg_p, int cdx,
1588 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1590 int mod_len, vud_len, exp_len, key_len;
1591 int pad_len, tmp_size, total_CPRB_len, parmBlock_l, i;
1592 unsigned char *temp_exp, *exp_p, *temp;
1593 struct type6_hdr *tp6Hdr_p;
1594 struct CPRB *cprb_p;
1595 struct cca_public_key *key_p;
1596 struct T6_keyBlock_hdr *keyb_p;
1598 temp_exp = kmalloc(256, GFP_KERNEL);
1599 if (!temp_exp)
1600 return EGETBUFF;
1601 mod_len = icaMsg_p->inputdatalength;
1602 if (copy_from_user(temp_exp, icaMsg_p->b_key, mod_len)) {
1603 kfree(temp_exp);
1604 return SEN_RELEASED;
1606 if (is_empty(temp_exp, mod_len)) {
1607 kfree(temp_exp);
1608 return SEN_USER_ERROR;
1611 exp_p = temp_exp;
1612 for (i = 0; i < mod_len; i++)
1613 if (exp_p[i])
1614 break;
1615 if (i >= mod_len) {
1616 kfree(temp_exp);
1617 return SEN_USER_ERROR;
1620 exp_len = mod_len - i;
1621 exp_p += i;
1623 PDEBUG("exp_len after computation: %08x\n", exp_len);
1624 tmp_size = FIXED_TYPE6_ME_EN_LEN + 2 * mod_len + exp_len;
1625 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1626 parmBlock_l = total_CPRB_len - sizeof(struct CPRB);
1627 tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER;
1629 vud_len = 2 + mod_len;
1630 memset(z90cMsg_p, 0, tmp_size);
1632 temp = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1633 memcpy(temp, &static_type6_hdr, sizeof(struct type6_hdr));
1634 tp6Hdr_p = (struct type6_hdr *)temp;
1635 tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4);
1636 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE;
1637 memcpy(tp6Hdr_p->function_code, static_PKE_function_code,
1638 sizeof(static_PKE_function_code));
1639 temp += sizeof(struct type6_hdr);
1640 memcpy(temp, &static_cprb, sizeof(struct CPRB));
1641 cprb_p = (struct CPRB *) temp;
1642 cprb_p->usage_domain[0]= (unsigned char)cdx;
1643 itoLe2((int *)&(tp6Hdr_p->FromCardLen1), cprb_p->rpl_parml);
1644 temp += sizeof(struct CPRB);
1645 memcpy(temp, &static_pke_function_and_rules,
1646 sizeof(struct function_and_rules_block));
1647 temp += sizeof(struct function_and_rules_block);
1648 temp += 2;
1649 if (copy_from_user(temp, icaMsg_p->inputdata, mod_len)) {
1650 kfree(temp_exp);
1651 return SEN_RELEASED;
1653 if (is_empty(temp, mod_len)) {
1654 kfree(temp_exp);
1655 return SEN_USER_ERROR;
1657 if ((temp[0] != 0x00) || (temp[1] != 0x02)) {
1658 kfree(temp_exp);
1659 return SEN_NOT_AVAIL;
1661 for (i = 2; i < mod_len; i++)
1662 if (temp[i] == 0x00)
1663 break;
1664 if ((i < 9) || (i > (mod_len - 2))) {
1665 kfree(temp_exp);
1666 return SEN_NOT_AVAIL;
1668 pad_len = i + 1;
1669 vud_len = mod_len - pad_len;
1670 memmove(temp, temp+pad_len, vud_len);
1671 temp -= 2;
1672 vud_len += 2;
1673 itoLe2(&vud_len, temp);
1674 temp += (vud_len);
1675 keyb_p = (struct T6_keyBlock_hdr *)temp;
1676 temp += sizeof(struct T6_keyBlock_hdr);
1677 memcpy(temp, &static_public_key, sizeof(static_public_key));
1678 key_p = (struct cca_public_key *)temp;
1679 temp = key_p->pubSec.exponent;
1680 memcpy(temp, exp_p, exp_len);
1681 kfree(temp_exp);
1682 temp += exp_len;
1683 if (copy_from_user(temp, icaMsg_p->n_modulus, mod_len))
1684 return SEN_RELEASED;
1685 if (is_empty(temp, mod_len))
1686 return SEN_USER_ERROR;
1687 key_p->pubSec.modulus_bit_len = 8 * mod_len;
1688 key_p->pubSec.modulus_byte_len = mod_len;
1689 key_p->pubSec.exponent_len = exp_len;
1690 key_p->pubSec.section_length = CALLER_HEADER + mod_len + exp_len;
1691 key_len = key_p->pubSec.section_length + sizeof(struct cca_token_hdr);
1692 key_p->pubHdr.token_length = key_len;
1693 key_len += 4;
1694 itoLe2(&key_len, keyb_p->ulen);
1695 key_len += 2;
1696 itoLe2(&key_len, keyb_p->blen);
1697 parmBlock_l -= pad_len;
1698 itoLe2(&parmBlock_l, cprb_p->req_parml);
1699 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1701 return 0;
1704 static int
1705 ICACRT_msg_to_type6CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p, int cdx,
1706 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p)
1708 int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l, short_len;
1709 int long_len, pad_len, keyPartsLen, tmp_l;
1710 unsigned char *tgt_p, *temp;
1711 struct type6_hdr *tp6Hdr_p;
1712 struct CPRB *cprb_p;
1713 struct cca_token_hdr *keyHdr_p;
1714 struct cca_pvt_ext_CRT_sec *pvtSec_p;
1715 struct cca_public_sec *pubSec_p;
1717 mod_len = icaMsg_p->inputdatalength;
1718 short_len = mod_len / 2;
1719 long_len = 8 + short_len;
1720 keyPartsLen = 3 * long_len + 2 * short_len;
1721 pad_len = (8 - (keyPartsLen % 8)) % 8;
1722 keyPartsLen += pad_len + mod_len;
1723 tmp_size = FIXED_TYPE6_CR_LEN + keyPartsLen + mod_len;
1724 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1725 parmBlock_l = total_CPRB_len - sizeof(struct CPRB);
1726 vud_len = 2 + mod_len;
1727 tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER;
1729 memset(z90cMsg_p, 0, tmp_size);
1730 tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1731 memcpy(tgt_p, &static_type6_hdr, sizeof(struct type6_hdr));
1732 tp6Hdr_p = (struct type6_hdr *)tgt_p;
1733 tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4);
1734 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE;
1735 tgt_p += sizeof(struct type6_hdr);
1736 cprb_p = (struct CPRB *) tgt_p;
1737 memcpy(tgt_p, &static_cprb, sizeof(struct CPRB));
1738 cprb_p->usage_domain[0]= *((unsigned char *)(&(cdx))+3);
1739 itoLe2(&parmBlock_l, cprb_p->req_parml);
1740 memcpy(cprb_p->rpl_parml, cprb_p->req_parml,
1741 sizeof(cprb_p->req_parml));
1742 tgt_p += sizeof(struct CPRB);
1743 memcpy(tgt_p, &static_pkd_function_and_rules,
1744 sizeof(struct function_and_rules_block));
1745 tgt_p += sizeof(struct function_and_rules_block);
1746 itoLe2(&vud_len, tgt_p);
1747 tgt_p += 2;
1748 if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len))
1749 return SEN_RELEASED;
1750 if (is_empty(tgt_p, mod_len))
1751 return SEN_USER_ERROR;
1752 tgt_p += mod_len;
1753 tmp_l = sizeof(struct T6_keyBlock_hdr) + sizeof(struct cca_token_hdr) +
1754 sizeof(struct cca_pvt_ext_CRT_sec) + 0x0F + keyPartsLen;
1755 itoLe2(&tmp_l, tgt_p);
1756 temp = tgt_p + 2;
1757 tmp_l -= 2;
1758 itoLe2(&tmp_l, temp);
1759 tgt_p += sizeof(struct T6_keyBlock_hdr);
1760 keyHdr_p = (struct cca_token_hdr *)tgt_p;
1761 keyHdr_p->token_identifier = CCA_TKN_HDR_ID_EXT;
1762 tmp_l -= 4;
1763 keyHdr_p->token_length = tmp_l;
1764 tgt_p += sizeof(struct cca_token_hdr);
1765 pvtSec_p = (struct cca_pvt_ext_CRT_sec *)tgt_p;
1766 pvtSec_p->section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT;
1767 pvtSec_p->section_length =
1768 sizeof(struct cca_pvt_ext_CRT_sec) + keyPartsLen;
1769 pvtSec_p->key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL;
1770 pvtSec_p->key_use_flags[0] = CCA_PVT_USAGE_ALL;
1771 pvtSec_p->p_len = long_len;
1772 pvtSec_p->q_len = short_len;
1773 pvtSec_p->dp_len = long_len;
1774 pvtSec_p->dq_len = short_len;
1775 pvtSec_p->u_len = long_len;
1776 pvtSec_p->mod_len = mod_len;
1777 pvtSec_p->pad_len = pad_len;
1778 tgt_p += sizeof(struct cca_pvt_ext_CRT_sec);
1779 if (copy_from_user(tgt_p, icaMsg_p->np_prime, long_len))
1780 return SEN_RELEASED;
1781 if (is_empty(tgt_p, long_len))
1782 return SEN_USER_ERROR;
1783 tgt_p += long_len;
1784 if (copy_from_user(tgt_p, icaMsg_p->nq_prime, short_len))
1785 return SEN_RELEASED;
1786 if (is_empty(tgt_p, short_len))
1787 return SEN_USER_ERROR;
1788 tgt_p += short_len;
1789 if (copy_from_user(tgt_p, icaMsg_p->bp_key, long_len))
1790 return SEN_RELEASED;
1791 if (is_empty(tgt_p, long_len))
1792 return SEN_USER_ERROR;
1793 tgt_p += long_len;
1794 if (copy_from_user(tgt_p, icaMsg_p->bq_key, short_len))
1795 return SEN_RELEASED;
1796 if (is_empty(tgt_p, short_len))
1797 return SEN_USER_ERROR;
1798 tgt_p += short_len;
1799 if (copy_from_user(tgt_p, icaMsg_p->u_mult_inv, long_len))
1800 return SEN_RELEASED;
1801 if (is_empty(tgt_p, long_len))
1802 return SEN_USER_ERROR;
1803 tgt_p += long_len;
1804 tgt_p += pad_len;
1805 memset(tgt_p, 0xFF, mod_len);
1806 tgt_p += mod_len;
1807 memcpy(tgt_p, &static_cca_pub_sec, sizeof(struct cca_public_sec));
1808 pubSec_p = (struct cca_public_sec *) tgt_p;
1809 pubSec_p->modulus_bit_len = 8 * mod_len;
1810 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1812 return 0;
1815 static int
1816 ICAMEX_msg_to_type6MEX_msgX(struct ica_rsa_modexpo *icaMsg_p, int cdx,
1817 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p,
1818 int dev_type)
1820 int mod_len, exp_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l;
1821 int key_len, i;
1822 unsigned char *temp_exp, *tgt_p, *temp, *exp_p;
1823 struct type6_hdr *tp6Hdr_p;
1824 struct CPRBX *cprbx_p;
1825 struct cca_public_key *key_p;
1826 struct T6_keyBlock_hdrX *keyb_p;
1828 temp_exp = kmalloc(256, GFP_KERNEL);
1829 if (!temp_exp)
1830 return EGETBUFF;
1831 mod_len = icaMsg_p->inputdatalength;
1832 if (copy_from_user(temp_exp, icaMsg_p->b_key, mod_len)) {
1833 kfree(temp_exp);
1834 return SEN_RELEASED;
1836 if (is_empty(temp_exp, mod_len)) {
1837 kfree(temp_exp);
1838 return SEN_USER_ERROR;
1840 exp_p = temp_exp;
1841 for (i = 0; i < mod_len; i++)
1842 if (exp_p[i])
1843 break;
1844 if (i >= mod_len) {
1845 kfree(temp_exp);
1846 return SEN_USER_ERROR;
1848 exp_len = mod_len - i;
1849 exp_p += i;
1850 PDEBUG("exp_len after computation: %08x\n", exp_len);
1851 tmp_size = FIXED_TYPE6_ME_EN_LENX + 2 * mod_len + exp_len;
1852 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1853 parmBlock_l = total_CPRB_len - sizeof(struct CPRBX);
1854 tmp_size = tmp_size + CALLER_HEADER;
1855 vud_len = 2 + mod_len;
1856 memset(z90cMsg_p, 0, tmp_size);
1857 tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1858 memcpy(tgt_p, &static_type6_hdrX, sizeof(struct type6_hdr));
1859 tp6Hdr_p = (struct type6_hdr *)tgt_p;
1860 tp6Hdr_p->ToCardLen1 = total_CPRB_len;
1861 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRBX_SIZE;
1862 memcpy(tp6Hdr_p->function_code, static_PKE_function_code,
1863 sizeof(static_PKE_function_code));
1864 tgt_p += sizeof(struct type6_hdr);
1865 memcpy(tgt_p, &static_cprbx, sizeof(struct CPRBX));
1866 cprbx_p = (struct CPRBX *) tgt_p;
1867 cprbx_p->domain = (unsigned short)cdx;
1868 cprbx_p->rpl_msgbl = RESPONSE_CPRBX_SIZE;
1869 tgt_p += sizeof(struct CPRBX);
1870 if (dev_type == PCIXCC_MCL2)
1871 memcpy(tgt_p, &static_pke_function_and_rulesX_MCL2,
1872 sizeof(struct function_and_rules_block));
1873 else
1874 memcpy(tgt_p, &static_pke_function_and_rulesX,
1875 sizeof(struct function_and_rules_block));
1876 tgt_p += sizeof(struct function_and_rules_block);
1878 tgt_p += 2;
1879 if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len)) {
1880 kfree(temp_exp);
1881 return SEN_RELEASED;
1883 if (is_empty(tgt_p, mod_len)) {
1884 kfree(temp_exp);
1885 return SEN_USER_ERROR;
1887 tgt_p -= 2;
1888 *((short *)tgt_p) = (short) vud_len;
1889 tgt_p += vud_len;
1890 keyb_p = (struct T6_keyBlock_hdrX *)tgt_p;
1891 tgt_p += sizeof(struct T6_keyBlock_hdrX);
1892 memcpy(tgt_p, &static_public_key, sizeof(static_public_key));
1893 key_p = (struct cca_public_key *)tgt_p;
1894 temp = key_p->pubSec.exponent;
1895 memcpy(temp, exp_p, exp_len);
1896 kfree(temp_exp);
1897 temp += exp_len;
1898 if (copy_from_user(temp, icaMsg_p->n_modulus, mod_len))
1899 return SEN_RELEASED;
1900 if (is_empty(temp, mod_len))
1901 return SEN_USER_ERROR;
1902 key_p->pubSec.modulus_bit_len = 8 * mod_len;
1903 key_p->pubSec.modulus_byte_len = mod_len;
1904 key_p->pubSec.exponent_len = exp_len;
1905 key_p->pubSec.section_length = CALLER_HEADER + mod_len + exp_len;
1906 key_len = key_p->pubSec.section_length + sizeof(struct cca_token_hdr);
1907 key_p->pubHdr.token_length = key_len;
1908 key_len += 4;
1909 keyb_p->ulen = (unsigned short)key_len;
1910 key_len += 2;
1911 keyb_p->blen = (unsigned short)key_len;
1912 cprbx_p->req_parml = parmBlock_l;
1913 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
1915 return 0;
1918 static int
1919 ICACRT_msg_to_type6CRT_msgX(struct ica_rsa_modexpo_crt *icaMsg_p, int cdx,
1920 int *z90cMsg_l_p, struct type6_msg *z90cMsg_p,
1921 int dev_type)
1923 int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l, short_len;
1924 int long_len, pad_len, keyPartsLen, tmp_l;
1925 unsigned char *tgt_p, *temp;
1926 struct type6_hdr *tp6Hdr_p;
1927 struct CPRBX *cprbx_p;
1928 struct cca_token_hdr *keyHdr_p;
1929 struct cca_pvt_ext_CRT_sec *pvtSec_p;
1930 struct cca_public_sec *pubSec_p;
1932 mod_len = icaMsg_p->inputdatalength;
1933 short_len = mod_len / 2;
1934 long_len = 8 + short_len;
1935 keyPartsLen = 3 * long_len + 2 * short_len;
1936 pad_len = (8 - (keyPartsLen % 8)) % 8;
1937 keyPartsLen += pad_len + mod_len;
1938 tmp_size = FIXED_TYPE6_CR_LENX + keyPartsLen + mod_len;
1939 total_CPRB_len = tmp_size - sizeof(struct type6_hdr);
1940 parmBlock_l = total_CPRB_len - sizeof(struct CPRBX);
1941 vud_len = 2 + mod_len;
1942 tmp_size = tmp_size + CALLER_HEADER;
1943 memset(z90cMsg_p, 0, tmp_size);
1944 tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER;
1945 memcpy(tgt_p, &static_type6_hdrX, sizeof(struct type6_hdr));
1946 tp6Hdr_p = (struct type6_hdr *)tgt_p;
1947 tp6Hdr_p->ToCardLen1 = total_CPRB_len;
1948 tp6Hdr_p->FromCardLen1 = RESPONSE_CPRBX_SIZE;
1949 tgt_p += sizeof(struct type6_hdr);
1950 cprbx_p = (struct CPRBX *) tgt_p;
1951 memcpy(tgt_p, &static_cprbx, sizeof(struct CPRBX));
1952 cprbx_p->domain = (unsigned short)cdx;
1953 cprbx_p->req_parml = parmBlock_l;
1954 cprbx_p->rpl_msgbl = parmBlock_l;
1955 tgt_p += sizeof(struct CPRBX);
1956 if (dev_type == PCIXCC_MCL2)
1957 memcpy(tgt_p, &static_pkd_function_and_rulesX_MCL2,
1958 sizeof(struct function_and_rules_block));
1959 else
1960 memcpy(tgt_p, &static_pkd_function_and_rulesX,
1961 sizeof(struct function_and_rules_block));
1962 tgt_p += sizeof(struct function_and_rules_block);
1963 *((short *)tgt_p) = (short) vud_len;
1964 tgt_p += 2;
1965 if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len))
1966 return SEN_RELEASED;
1967 if (is_empty(tgt_p, mod_len))
1968 return SEN_USER_ERROR;
1969 tgt_p += mod_len;
1970 tmp_l = sizeof(struct T6_keyBlock_hdr) + sizeof(struct cca_token_hdr) +
1971 sizeof(struct cca_pvt_ext_CRT_sec) + 0x0F + keyPartsLen;
1972 *((short *)tgt_p) = (short) tmp_l;
1973 temp = tgt_p + 2;
1974 tmp_l -= 2;
1975 *((short *)temp) = (short) tmp_l;
1976 tgt_p += sizeof(struct T6_keyBlock_hdr);
1977 keyHdr_p = (struct cca_token_hdr *)tgt_p;
1978 keyHdr_p->token_identifier = CCA_TKN_HDR_ID_EXT;
1979 tmp_l -= 4;
1980 keyHdr_p->token_length = tmp_l;
1981 tgt_p += sizeof(struct cca_token_hdr);
1982 pvtSec_p = (struct cca_pvt_ext_CRT_sec *)tgt_p;
1983 pvtSec_p->section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT;
1984 pvtSec_p->section_length =
1985 sizeof(struct cca_pvt_ext_CRT_sec) + keyPartsLen;
1986 pvtSec_p->key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL;
1987 pvtSec_p->key_use_flags[0] = CCA_PVT_USAGE_ALL;
1988 pvtSec_p->p_len = long_len;
1989 pvtSec_p->q_len = short_len;
1990 pvtSec_p->dp_len = long_len;
1991 pvtSec_p->dq_len = short_len;
1992 pvtSec_p->u_len = long_len;
1993 pvtSec_p->mod_len = mod_len;
1994 pvtSec_p->pad_len = pad_len;
1995 tgt_p += sizeof(struct cca_pvt_ext_CRT_sec);
1996 if (copy_from_user(tgt_p, icaMsg_p->np_prime, long_len))
1997 return SEN_RELEASED;
1998 if (is_empty(tgt_p, long_len))
1999 return SEN_USER_ERROR;
2000 tgt_p += long_len;
2001 if (copy_from_user(tgt_p, icaMsg_p->nq_prime, short_len))
2002 return SEN_RELEASED;
2003 if (is_empty(tgt_p, short_len))
2004 return SEN_USER_ERROR;
2005 tgt_p += short_len;
2006 if (copy_from_user(tgt_p, icaMsg_p->bp_key, long_len))
2007 return SEN_RELEASED;
2008 if (is_empty(tgt_p, long_len))
2009 return SEN_USER_ERROR;
2010 tgt_p += long_len;
2011 if (copy_from_user(tgt_p, icaMsg_p->bq_key, short_len))
2012 return SEN_RELEASED;
2013 if (is_empty(tgt_p, short_len))
2014 return SEN_USER_ERROR;
2015 tgt_p += short_len;
2016 if (copy_from_user(tgt_p, icaMsg_p->u_mult_inv, long_len))
2017 return SEN_RELEASED;
2018 if (is_empty(tgt_p, long_len))
2019 return SEN_USER_ERROR;
2020 tgt_p += long_len;
2021 tgt_p += pad_len;
2022 memset(tgt_p, 0xFF, mod_len);
2023 tgt_p += mod_len;
2024 memcpy(tgt_p, &static_cca_pub_sec, sizeof(struct cca_public_sec));
2025 pubSec_p = (struct cca_public_sec *) tgt_p;
2026 pubSec_p->modulus_bit_len = 8 * mod_len;
2027 *z90cMsg_l_p = tmp_size - CALLER_HEADER;
2029 return 0;
2033 convert_request(unsigned char *buffer, int func, unsigned short function,
2034 int cdx, int dev_type, int *msg_l_p, unsigned char *msg_p)
2036 if (dev_type == PCICA) {
2037 if (func == ICARSACRT)
2038 return ICACRT_msg_to_type4CRT_msg(
2039 (struct ica_rsa_modexpo_crt *) buffer,
2040 msg_l_p, (union type4_msg *) msg_p);
2041 else
2042 return ICAMEX_msg_to_type4MEX_msg(
2043 (struct ica_rsa_modexpo *) buffer,
2044 msg_l_p, (union type4_msg *) msg_p);
2046 if (dev_type == PCICC) {
2047 if (func == ICARSACRT)
2048 return ICACRT_msg_to_type6CRT_msg(
2049 (struct ica_rsa_modexpo_crt *) buffer,
2050 cdx, msg_l_p, (struct type6_msg *)msg_p);
2051 if (function == PCI_FUNC_KEY_ENCRYPT)
2052 return ICAMEX_msg_to_type6MEX_en_msg(
2053 (struct ica_rsa_modexpo *) buffer,
2054 cdx, msg_l_p, (struct type6_msg *) msg_p);
2055 else
2056 return ICAMEX_msg_to_type6MEX_de_msg(
2057 (struct ica_rsa_modexpo *) buffer,
2058 cdx, msg_l_p, (struct type6_msg *) msg_p);
2060 if ((dev_type == PCIXCC_MCL2) ||
2061 (dev_type == PCIXCC_MCL3) ||
2062 (dev_type == CEX2C)) {
2063 if (func == ICARSACRT)
2064 return ICACRT_msg_to_type6CRT_msgX(
2065 (struct ica_rsa_modexpo_crt *) buffer,
2066 cdx, msg_l_p, (struct type6_msg *) msg_p,
2067 dev_type);
2068 else
2069 return ICAMEX_msg_to_type6MEX_msgX(
2070 (struct ica_rsa_modexpo *) buffer,
2071 cdx, msg_l_p, (struct type6_msg *) msg_p,
2072 dev_type);
2075 return 0;
2078 int ext_bitlens_msg_count = 0;
2079 static inline void
2080 unset_ext_bitlens(void)
2082 if (!ext_bitlens_msg_count) {
2083 PRINTK("Unable to use coprocessors for extended bitlengths. "
2084 "Using PCICAs (if present) for extended bitlengths. "
2085 "This is not an error.\n");
2086 ext_bitlens_msg_count++;
2088 ext_bitlens = 0;
2092 convert_response(unsigned char *response, unsigned char *buffer,
2093 int *respbufflen_p, unsigned char *resp_buff)
2095 struct ica_rsa_modexpo *icaMsg_p = (struct ica_rsa_modexpo *) buffer;
2096 struct error_hdr *errh_p = (struct error_hdr *) response;
2097 struct type84_hdr *t84h_p = (struct type84_hdr *) response;
2098 struct type86_fmt2_msg *t86m_p = (struct type86_fmt2_msg *) response;
2099 int reply_code, service_rc, service_rs, src_l;
2100 unsigned char *src_p, *tgt_p;
2101 struct CPRB *cprb_p;
2102 struct CPRBX *cprbx_p;
2104 src_p = 0;
2105 reply_code = 0;
2106 service_rc = 0;
2107 service_rs = 0;
2108 src_l = 0;
2109 switch (errh_p->type) {
2110 case TYPE82_RSP_CODE:
2111 reply_code = errh_p->reply_code;
2112 src_p = (unsigned char *)errh_p;
2113 PRINTK("Hardware error: Type %02X Message Header: "
2114 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
2115 errh_p->type,
2116 src_p[0], src_p[1], src_p[2], src_p[3],
2117 src_p[4], src_p[5], src_p[6], src_p[7]);
2118 break;
2119 case TYPE84_RSP_CODE:
2120 src_l = icaMsg_p->outputdatalength;
2121 src_p = response + (int)t84h_p->len - src_l;
2122 break;
2123 case TYPE86_RSP_CODE:
2124 reply_code = t86m_p->header.reply_code;
2125 if (reply_code != 0)
2126 break;
2127 cprb_p = (struct CPRB *)
2128 (response + sizeof(struct type86_fmt2_msg));
2129 cprbx_p = (struct CPRBX *) cprb_p;
2130 if (cprb_p->cprb_ver_id != 0x02) {
2131 le2toI(cprb_p->ccp_rtcode, &service_rc);
2132 if (service_rc != 0) {
2133 le2toI(cprb_p->ccp_rscode, &service_rs);
2134 if ((service_rc == 8) && (service_rs == 66))
2135 PDEBUG("Bad block format on PCICC\n");
2136 else if ((service_rc == 8) && (service_rs == 65))
2137 PDEBUG("Probably an even modulus on "
2138 "PCICC\n");
2139 else if ((service_rc == 8) && (service_rs == 770)) {
2140 PDEBUG("Invalid key length on PCICC\n");
2141 unset_ext_bitlens();
2142 return REC_USE_PCICA;
2144 else if ((service_rc == 8) && (service_rs == 783)) {
2145 PDEBUG("Extended bitlengths not enabled"
2146 "on PCICC\n");
2147 unset_ext_bitlens();
2148 return REC_USE_PCICA;
2150 else
2151 PRINTK("service rc/rs (PCICC): %d/%d\n",
2152 service_rc, service_rs);
2153 return REC_OPERAND_INV;
2155 src_p = (unsigned char *)cprb_p + sizeof(struct CPRB);
2156 src_p += 4;
2157 le2toI(src_p, &src_l);
2158 src_l -= 2;
2159 src_p += 2;
2160 } else {
2161 service_rc = (int)cprbx_p->ccp_rtcode;
2162 if (service_rc != 0) {
2163 service_rs = (int) cprbx_p->ccp_rscode;
2164 if ((service_rc == 8) && (service_rs == 66))
2165 PDEBUG("Bad block format on PCIXCC\n");
2166 else if ((service_rc == 8) && (service_rs == 65))
2167 PDEBUG("Probably an even modulus on "
2168 "PCIXCC\n");
2169 else if ((service_rc == 8) && (service_rs == 770)) {
2170 PDEBUG("Invalid key length on PCIXCC\n");
2171 unset_ext_bitlens();
2172 return REC_USE_PCICA;
2174 else if ((service_rc == 8) && (service_rs == 783)) {
2175 PDEBUG("Extended bitlengths not enabled"
2176 "on PCIXCC\n");
2177 unset_ext_bitlens();
2178 return REC_USE_PCICA;
2180 else
2181 PRINTK("service rc/rs (PCIXCC): %d/%d\n",
2182 service_rc, service_rs);
2183 return REC_OPERAND_INV;
2185 src_p = (unsigned char *)
2186 cprbx_p + sizeof(struct CPRBX);
2187 src_p += 4;
2188 src_l = (int)(*((short *) src_p));
2189 src_l -= 2;
2190 src_p += 2;
2192 break;
2193 default:
2194 src_p = (unsigned char *)errh_p;
2195 PRINTK("Unrecognized Message Header: "
2196 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
2197 src_p[0], src_p[1], src_p[2], src_p[3],
2198 src_p[4], src_p[5], src_p[6], src_p[7]);
2199 return REC_BAD_MESSAGE;
2202 if (reply_code)
2203 switch (reply_code) {
2204 case REP82_ERROR_OPERAND_INVALID:
2205 return REC_OPERAND_INV;
2206 case REP82_ERROR_OPERAND_SIZE:
2207 return REC_OPERAND_SIZE;
2208 case REP82_ERROR_EVEN_MOD_IN_OPND:
2209 return REC_EVEN_MOD;
2210 case REP82_ERROR_MESSAGE_TYPE:
2211 return WRONG_DEVICE_TYPE;
2212 case REP82_ERROR_TRANSPORT_FAIL:
2213 PRINTKW("Transport failed (APFS = %02X%02X%02X%02X)\n",
2214 t86m_p->apfs[0], t86m_p->apfs[1],
2215 t86m_p->apfs[2], t86m_p->apfs[3]);
2216 return REC_HARDWAR_ERR;
2217 default:
2218 PRINTKW("reply code = %d\n", reply_code);
2219 return REC_HARDWAR_ERR;
2222 if (service_rc != 0)
2223 return REC_OPERAND_INV;
2225 if ((src_l > icaMsg_p->outputdatalength) ||
2226 (src_l > RESPBUFFSIZE) ||
2227 (src_l <= 0))
2228 return REC_OPERAND_SIZE;
2230 PDEBUG("Length returned = %d\n", src_l);
2231 tgt_p = resp_buff + icaMsg_p->outputdatalength - src_l;
2232 memcpy(tgt_p, src_p, src_l);
2233 if ((errh_p->type == TYPE86_RSP_CODE) && (resp_buff < tgt_p)) {
2234 memset(resp_buff, 0, icaMsg_p->outputdatalength - src_l);
2235 if (pad_msg(resp_buff, icaMsg_p->outputdatalength, src_l))
2236 return REC_INVALID_PAD;
2238 *respbufflen_p = icaMsg_p->outputdatalength;
2239 if (*respbufflen_p == 0)
2240 PRINTK("Zero *respbufflen_p\n");
2242 return 0;