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