2 * linux/drivers/s390/crypto/z90hardware.c
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)
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>
33 #include "z90common.h"
35 #define VERSION_Z90HARDWARE_C "$Revision: 1.33 $"
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)
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
171 struct type4_hdr header
;
172 unsigned char message
[128];
173 unsigned char exponent
[128];
174 unsigned char modulus
[128];
178 struct type4_hdr header
;
179 unsigned char message
[256];
180 unsigned char exponent
[256];
181 unsigned char modulus
[256];
185 struct type4_hdr header
;
186 unsigned char message
[128];
187 unsigned char dp
[72];
188 unsigned char dq
[64];
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];
205 struct type4_sme sme
;
206 struct type4_lme lme
;
207 struct type4_scr scr
;
208 struct type4_lcr lcr
;
212 unsigned char reserved1
;
215 unsigned char reserved2
[4];
218 #define TYPE84_RSP_CODE 0x84
221 unsigned char reserved1
;
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
;
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
;
254 unsigned char func_id
[2];
255 unsigned char checkpoint_flag
;
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];
282 struct type6_hdr header
;
287 union type4_msg t4msg
;
288 struct type6_msg t6msg
;
291 struct request_msg_ext
{
293 unsigned char *psmid
;
294 union request_msg reqMsg
;
298 unsigned char reserved1
;
300 unsigned char reserved2
[2];
301 unsigned char reply_code
;
302 unsigned char reserved3
[3];
305 #define TYPE82_RSP_CODE 0x82
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
329 unsigned char reserved1
;
331 unsigned char format
;
332 unsigned char reserved2
;
333 unsigned char reply_code
;
334 unsigned char reserved3
[3];
337 #define TYPE86_RSP_CODE 0x86
338 #define TYPE86_FMT2 0x02
340 struct type86_fmt2_msg
{
341 struct type86_hdr hdr
;
342 unsigned char reserved
[4];
343 unsigned char apfs
[4];
345 unsigned int offset1
;
347 unsigned int offset2
;
349 unsigned int offset3
;
351 unsigned int offset4
;
354 static struct type6_hdr static_type6_hdr
= {
358 {0x00,0x00,0x00,0x00},
361 {0x00,0x00,0x00,0x00},
366 {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
367 0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
382 static struct type6_hdr static_type6_hdrX
= {
386 {0x00,0x00,0x00,0x00},
389 {0x00,0x00,0x00,0x00},
394 {0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
395 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
410 static struct CPRB static_cprb
= {
414 {0x00,0x00,0x00,0x00},
421 {0x00,0x00,0x00,0x00},
422 {0x00,0x00,0x00,0x00},
423 {0x00,0x00,0x00,0x00},
426 {0x00,0x00,0x00,0x00},
427 {0x00,0x00,0x00,0x00},
428 {0x00,0x00,0x00,0x00},
433 {0x00,0x00,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},
439 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
440 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
443 {0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20}
446 struct function_and_rules_block
{
447 unsigned char function_code
[2];
448 unsigned char ulen
[2];
449 unsigned char only_rule
[8];
452 static struct function_and_rules_block static_pkd_function_and_rules
= {
455 {'P','K','C','S','-','1','.','2'}
458 static struct function_and_rules_block static_pke_function_and_rules
= {
461 {'P','K','C','S','-','1','.','2'}
464 struct T6_keyBlock_hdr
{
465 unsigned char blen
[2];
466 unsigned char ulen
[2];
467 unsigned char flags
[2];
470 static struct T6_keyBlock_hdr static_T6_keyBlock_hdr
= {
476 static struct CPRBX static_cprbx
= {
481 {0x00,0x00,0x00,0x00},
489 {0x00,0x00,0x00,0x00},
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},
506 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
507 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
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}
517 static struct function_and_rules_block static_pkd_function_and_rulesX_MCL2
= {
520 {'P','K','C','S','-','1','.','2'}
523 static struct function_and_rules_block static_pke_function_and_rulesX_MCL2
= {
526 {'Z','E','R','O','-','P','A','D'}
529 static struct function_and_rules_block static_pkd_function_and_rulesX
= {
532 {'Z','E','R','O','-','P','A','D'}
535 static struct function_and_rules_block static_pke_function_and_rulesX
= {
538 {'M','R','P',' ',' ',' ',' ',' '}
541 struct T6_keyBlock_hdrX
{
544 unsigned char flags
[2];
547 static unsigned char static_pad
[256] = {
548 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
549 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
550 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
551 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
552 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
553 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
554 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
555 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
556 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
557 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
558 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
559 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
560 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
561 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
562 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
563 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
566 static struct cca_private_ext_ME static_pvt_me_key
= {
571 {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},
581 {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},
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}
641 static struct cca_public_key static_public_key
= {
646 {0x00,0x00,0x00,0x00}
661 #define FIXED_TYPE6_ME_LEN 0x0000025F
663 #define FIXED_TYPE6_ME_EN_LEN 0x000000F0
665 #define FIXED_TYPE6_ME_LENX 0x000002CB
667 #define FIXED_TYPE6_ME_EN_LENX 0x0000015C
669 static struct cca_public_sec static_cca_pub_sec
= {
680 #define FIXED_TYPE6_CR_LEN 0x00000177
682 #define FIXED_TYPE6_CR_LENX 0x000001E3
684 #define MAX_RESPONSE_SIZE 0x00000710
686 #define MAX_RESPONSEX_SIZE 0x0000077C
688 #define RESPONSE_CPRB_SIZE 0x000006B8
689 #define RESPONSE_CPRBX_SIZE 0x00000724
691 #define CALLER_HEADER 12
693 static unsigned char static_PKE_function_code
[2] = {0x50, 0x4B};
696 testq(int q_nr
, int *q_depth
, int *dev_type
, struct ap_status_word
*stat
)
705 "0: .long 0xb2af0000 \n"
717 ".section .fixup,\"ax\" \n"
722 ".section __ex_table,\"a\" \n"
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");
734 "0: .long 0xb2af0000 \n"
744 ".section .fixup,\"ax\" \n"
753 ".section __ex_table,\"a\" \n"
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");
766 resetq(int q_nr
, struct ap_status_word
*stat_p
)
778 "0: .long 0xb2af0000 \n"
785 ".section .fixup,\"ax\" \n"
790 ".section __ex_table,\"a\" \n"
795 :"=d" (ccode
),"=d" (*stat_p
)
796 :"d" (q_nr
), "K" (DEV_RSQ_EXCEPTION
)
797 :"cc","0","1","2","memory");
805 "0: .long 0xb2af0000 \n"
810 ".section .fixup,\"ax\" \n"
819 ".section __ex_table,\"a\" \n"
824 :"=d" (ccode
),"=d" (*stat_p
)
825 :"d" (q_nr
), "K" (DEV_RSQ_EXCEPTION
)
826 :"cc","0","1","2","memory");
832 sen(int msg_len
, unsigned char *msg_ext
, struct ap_status_word
*stat
)
849 "0: .long 0xb2ad0026 \n"
857 ".section .fixup,\"ax\" \n"
862 ".section __ex_table,\"a\" \n"
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");
882 "0: .long 0xb2ad0026 \n"
888 ".section .fixup,\"ax\" \n"
897 ".section __ex_table,\"a\" \n"
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");
910 rec(int q_nr
, int buff_l
, unsigned char *rsp
, unsigned char *id
,
911 struct ap_status_word
*st
)
928 "0: .long 0xb2ae0046 \n"
939 ".section .fixup,\"ax\" \n"
944 ".section __ex_table,\"a\" \n"
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");
964 "0: .long 0xb2ae0046 \n"
973 ".section .fixup,\"ax\" \n"
982 ".section __ex_table,\"a\" \n"
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");
995 itoLe2(int *i_p
, unsigned char *lechars
)
997 *lechars
= *((unsigned char *) i_p
+ sizeof(int) - 1);
998 *(lechars
+ 1) = *((unsigned char *) i_p
+ sizeof(int) - 2);
1002 le2toI(unsigned char *lechars
, int *i_p
)
1004 unsigned char *ic_p
;
1006 ic_p
= (unsigned char *) i_p
;
1007 *(ic_p
+ 2) = *(lechars
+ 1);
1008 *(ic_p
+ 3) = *(lechars
);
1012 is_empty(unsigned char *ptr
, int len
)
1014 return !memcmp(ptr
, (unsigned char *) &static_pvt_me_key
+60, len
);
1018 query_online(int deviceNr
, int cdx
, int resetNr
, int *q_depth
, int *dev_type
)
1020 int q_nr
, i
, t_depth
, t_dev_type
;
1022 struct ap_status_word stat_word
;
1026 q_nr
= (deviceNr
<< SKIP_BITL
) + cdx
;
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
);
1031 for (i
= 0; i
< resetNr
; i
++) {
1033 PRINTKC("Exception testing device %d\n", i
);
1034 return HD_TSQ_EXCEPTION
;
1038 PDEBUG("t_dev_type %d\n", t_dev_type
);
1041 *q_depth
= t_depth
+ 1;
1042 switch (t_dev_type
) {
1044 stat
= HD_NOT_THERE
;
1054 *dev_type
= PCIXCC_UNK
;
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]);
1072 switch (stat_word
.response_code
) {
1073 case AP_RESPONSE_NORMAL
:
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",
1084 stat_word
.q_stat_flags
,
1085 stat_word
.response_code
,
1086 stat_word
.reserved
[0],
1087 stat_word
.reserved
[1]);
1089 case AP_RESPONSE_Q_NOT_AVAIL
:
1090 stat
= HD_NOT_THERE
;
1093 case AP_RESPONSE_RESET_IN_PROGRESS
:
1094 PDEBUG("device %d in reset\n",
1097 case AP_RESPONSE_DECONFIGURED
:
1098 stat
= HD_DECONFIGURED
;
1101 case AP_RESPONSE_CHECKSTOPPED
:
1102 stat
= HD_CHECKSTOPPED
;
1105 case AP_RESPONSE_BUSY
:
1106 PDEBUG("device %d busy\n",
1114 stat
= HD_NOT_THERE
;
1123 ccode
= testq(q_nr
, &t_depth
, &t_dev_type
, &stat_word
);
1129 reset_device(int deviceNr
, int cdx
, int resetNr
)
1131 int q_nr
, ccode
= 0, dummy_qdepth
, dummy_devType
, i
;
1132 struct ap_status_word stat_word
;
1136 q_nr
= (deviceNr
<< SKIP_BITL
) + cdx
;
1138 ccode
= resetq(q_nr
, &stat_word
);
1140 return DEV_RSQ_EXCEPTION
;
1143 for (i
= 0; i
< resetNr
; i
++) {
1147 if (stat_word
.q_stat_flags
& AP_Q_STATUS_EMPTY
)
1151 switch (stat_word
.response_code
) {
1152 case AP_RESPONSE_NORMAL
:
1154 if (stat_word
.q_stat_flags
& AP_Q_STATUS_EMPTY
)
1157 case AP_RESPONSE_Q_NOT_AVAIL
:
1158 case AP_RESPONSE_DECONFIGURED
:
1159 case AP_RESPONSE_CHECKSTOPPED
:
1163 case AP_RESPONSE_RESET_IN_PROGRESS
:
1164 case AP_RESPONSE_BUSY
:
1178 ccode
= testq(q_nr
, &dummy_qdepth
, &dummy_devType
, &stat_word
);
1180 stat
= DEV_TSQ_EXCEPTION
;
1184 PDEBUG("Number of testq's needed for reset: %d\n", i
);
1193 #ifdef DEBUG_HYDRA_MSGS
1195 print_buffer(unsigned char *buffer
, int bufflen
)
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]);
1210 send_to_AP(int dev_nr
, int cdx
, int msg_len
, unsigned char *msg_ext
)
1212 struct ap_status_word stat_word
;
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]);
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
);
1232 ccode
= sen(msg_len
, msg_ext
, &stat_word
);
1234 return DEV_SEN_EXCEPTION
;
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]);
1247 switch (stat_word
.response_code
) {
1248 case AP_RESPONSE_NORMAL
:
1251 case AP_RESPONSE_Q_FULL
:
1252 stat
= DEV_QUEUE_FULL
;
1268 receive_from_AP(int dev_nr
, int cdx
, int resplen
, unsigned char *resp
,
1269 unsigned char *psmid
)
1272 struct ap_status_word stat_word
;
1275 memset(resp
, 0x00, 8);
1277 ccode
= rec((dev_nr
<< SKIP_BITL
) + cdx
, resplen
, resp
, psmid
,
1280 return DEV_REC_EXCEPTION
;
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]);
1290 #ifdef DEBUG_HYDRA_MSGS
1291 print_buffer(resp
, resplen
);
1295 switch (stat_word
.response_code
) {
1296 case AP_RESPONSE_NORMAL
:
1299 case AP_RESPONSE_NO_PENDING_REPLY
:
1300 if (stat_word
.q_stat_flags
& AP_Q_STATUS_EMPTY
)
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
;
1322 pad_msg(unsigned char *buffer
, int totalLength
, int msgLength
)
1326 for (pad_len
= 0; pad_len
< (totalLength
- msgLength
); pad_len
++)
1327 if (buffer
[pad_len
] != 0x00)
1331 return SEN_PAD_ERROR
;
1336 memcpy(buffer
+2, static_pad
, pad_len
);
1338 buffer
[pad_len
+ 2] = 0x00;
1344 is_common_public_key(unsigned char *key
, int len
)
1348 for (i
= 0; i
< len
; i
++)
1353 if (((len
== 1) && (key
[0] == 3)) ||
1354 ((len
== 3) && (key
[0] == 1) && (key
[1] == 0) && (key
[2] == 1)))
1361 ICAMEX_msg_to_type4MEX_msg(struct ica_rsa_modexpo
*icaMex_p
, int *z90cMsg_l_p
,
1362 union type4_msg
*z90cMsg_p
)
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
;
1368 mod_len
= icaMex_p
->inputdatalength
;
1370 msg_size
= ((mod_len
<= 128) ? TYPE4_SME_LEN
: TYPE4_LME_LEN
) +
1373 memset(z90cMsg_p
, 0, msg_size
);
1375 tmp_type4_msg
= (union type4_msg
*)
1376 ((unsigned char *) z90cMsg_p
+ CALLER_HEADER
);
1378 tmp_type4_msg
->sme
.header
.msg_type_code
= TYPE4_TYPE_CODE
;
1379 tmp_type4_msg
->sme
.header
.request_code
= TYPE4_REQU_CODE
;
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
);
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
);
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
;
1417 *z90cMsg_l_p
= msg_size
- CALLER_HEADER
;
1423 ICACRT_msg_to_type4CRT_msg(struct ica_rsa_modexpo_crt
*icaMsg_p
,
1424 int *z90cMsg_l_p
, union type4_msg
*z90cMsg_p
)
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
;
1431 mod_len
= icaMsg_p
->inputdatalength
;
1432 short_len
= mod_len
/ 2;
1433 long_len
= mod_len
/ 2 + 8;
1435 tmp_size
= ((mod_len
<= 128) ? TYPE4_SCR_LEN
: TYPE4_LCR_LEN
) +
1438 memset(z90cMsg_p
, 0, tmp_size
);
1440 tmp_type4_msg
= (union type4_msg
*)
1441 ((unsigned char *) z90cMsg_p
+ CALLER_HEADER
);
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
);
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
);
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
;
1508 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
1514 ICAMEX_msg_to_type6MEX_de_msg(struct ica_rsa_modexpo
*icaMsg_p
, int cdx
,
1515 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
)
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;
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
;
1530 memset(z90cMsg_p
, 0, tmp_size
);
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
;
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
);
1545 temp
+= sizeof(struct CPRB
);
1546 memcpy(temp
, &static_pkd_function_and_rules
,
1547 sizeof(struct function_and_rules_block
));
1549 temp
+= sizeof(struct function_and_rules_block
);
1550 vud_len
= 2 + icaMsg_p
->inputdatalength
;
1551 itoLe2(&vud_len
, temp
);
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
;
1560 memcpy(temp
, &static_T6_keyBlock_hdr
, sizeof(struct T6_keyBlock_hdr
));
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
)
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
;
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");
1580 return SEN_NOT_AVAIL
;
1583 temp
= key_p
->pvtMESec
.modulus
+ sizeof(key_p
->pvtMESec
.modulus
)
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
;
1590 key_p
->pubMESec
.modulus_bit_len
= 8 * mod_len
;
1592 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
1598 ICAMEX_msg_to_type6MEX_en_msg(struct ica_rsa_modexpo
*icaMsg_p
, int cdx
,
1599 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
)
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
;
1609 temp_exp
= kmalloc(256, GFP_KERNEL
);
1612 mod_len
= icaMsg_p
->inputdatalength
;
1613 if (copy_from_user(temp_exp
, icaMsg_p
->b_key
, mod_len
)) {
1615 return SEN_RELEASED
;
1617 if (is_empty(temp_exp
, mod_len
)) {
1619 return SEN_USER_ERROR
;
1623 for (i
= 0; i
< mod_len
; i
++)
1628 return SEN_USER_ERROR
;
1631 exp_len
= mod_len
- i
;
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
;
1640 vud_len
= 2 + mod_len
;
1641 memset(z90cMsg_p
, 0, tmp_size
);
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
);
1660 if (copy_from_user(temp
, icaMsg_p
->inputdata
, mod_len
)) {
1662 return SEN_RELEASED
;
1664 if (is_empty(temp
, mod_len
)) {
1666 return SEN_USER_ERROR
;
1668 if ((temp
[0] != 0x00) || (temp
[1] != 0x02)) {
1670 return SEN_NOT_AVAIL
;
1672 for (i
= 2; i
< mod_len
; i
++)
1673 if (temp
[i
] == 0x00)
1675 if ((i
< 9) || (i
> (mod_len
- 2))) {
1677 return SEN_NOT_AVAIL
;
1680 vud_len
= mod_len
- pad_len
;
1681 memmove(temp
, temp
+pad_len
, vud_len
);
1684 itoLe2(&vud_len
, temp
);
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
);
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
;
1705 itoLe2(&key_len
, keyb_p
->ulen
);
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
;
1716 ICACRT_msg_to_type6CRT_msg(struct ica_rsa_modexpo_crt
*icaMsg_p
, int cdx
,
1717 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
)
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
;
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
;
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
);
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
;
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
);
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
;
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
;
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
;
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
;
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
;
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
;
1816 memset(tgt_p
, 0xFF, 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
;
1827 ICAMEX_msg_to_type6MEX_msgX(struct ica_rsa_modexpo
*icaMsg_p
, int cdx
,
1828 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
,
1831 int mod_len
, exp_len
, vud_len
, tmp_size
, total_CPRB_len
, parmBlock_l
;
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
;
1839 temp_exp
= kmalloc(256, GFP_KERNEL
);
1842 mod_len
= icaMsg_p
->inputdatalength
;
1843 if (copy_from_user(temp_exp
, icaMsg_p
->b_key
, mod_len
)) {
1845 return SEN_RELEASED
;
1847 if (is_empty(temp_exp
, mod_len
)) {
1849 return SEN_USER_ERROR
;
1852 for (i
= 0; i
< mod_len
; i
++)
1857 return SEN_USER_ERROR
;
1859 exp_len
= mod_len
- 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
));
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
);
1890 if (copy_from_user(tgt_p
, icaMsg_p
->inputdata
, mod_len
)) {
1892 return SEN_RELEASED
;
1894 if (is_empty(tgt_p
, mod_len
)) {
1896 return SEN_USER_ERROR
;
1899 *((short *)tgt_p
) = (short) 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
);
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
;
1920 keyb_p
->ulen
= (unsigned short)key_len
;
1922 keyb_p
->blen
= (unsigned short)key_len
;
1923 cprbx_p
->req_parml
= parmBlock_l
;
1924 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
1930 ICACRT_msg_to_type6CRT_msgX(struct ica_rsa_modexpo_crt
*icaMsg_p
, int cdx
,
1931 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
,
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
;
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
));
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
2033 memset(tgt_p
, 0xFF, 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
;
2044 convert_request(unsigned char *buffer
, int func
, unsigned short function
,
2045 int cdx
, int dev_type
, int *msg_l_p
, unsigned char *msg_p
)
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
);
2053 return ICAMEX_msg_to_type4MEX_msg(
2054 (struct ica_rsa_modexpo
*) buffer
,
2055 msg_l_p
, (union type4_msg
*) msg_p
);
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
);
2067 return ICAMEX_msg_to_type6MEX_de_msg(
2068 (struct ica_rsa_modexpo
*) buffer
,
2069 cdx
, msg_l_p
, (struct type6_msg
*) msg_p
);
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
,
2080 return ICAMEX_msg_to_type6MEX_msgX(
2081 (struct ica_rsa_modexpo
*) buffer
,
2082 cdx
, msg_l_p
, (struct type6_msg
*) msg_p
,
2089 int ext_bitlens_msg_count
= 0;
2091 unset_ext_bitlens(void)
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
++;
2103 convert_response(unsigned char *response
, unsigned char *buffer
,
2104 int *respbufflen_p
, unsigned char *resp_buff
)
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
;
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]);
2129 case TYPE84_RSP_CODE
:
2130 src_l
= icaMsg_p
->outputdatalength
;
2131 src_p
= response
+ (int)t84h_p
->len
- src_l
;
2133 case TYPE86_RSP_CODE
:
2134 reply_code
= t86m_p
->hdr
.reply_code
;
2135 if (reply_code
!= 0)
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
;
2151 else if ((service_rc
== 8) && (service_rs
== 783)) {
2152 PDEBUG("Extended bitlengths not enabled"
2154 unset_ext_bitlens();
2155 return REC_USE_PCICA
;
2158 PRINTK("service rc/rs: %d/%d\n",
2159 service_rc
, service_rs
);
2160 return REC_OPERAND_INV
;
2162 src_p
= (unsigned char *)cprb_p
+ sizeof(struct CPRB
);
2164 le2toI(src_p
, &src_l
);
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
;
2178 else if ((service_rc
== 8) && (service_rs
== 783)) {
2179 PDEBUG("Extended bitlengths not enabled"
2181 unset_ext_bitlens();
2182 return REC_USE_PCICA
;
2185 PRINTK("service rc/rs: %d/%d\n",
2186 service_rc
, service_rs
);
2187 return REC_OPERAND_INV
;
2189 src_p
= (unsigned char *)
2190 cprbx_p
+ sizeof(struct CPRBX
);
2192 src_l
= (int)(*((short *) src_p
));
2198 return REC_BAD_MESSAGE
;
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
;
2217 PRINTKW("reply code = %d\n", reply_code
);
2218 return REC_HARDWAR_ERR
;
2221 if (service_rc
!= 0)
2222 return REC_OPERAND_INV
;
2224 if ((src_l
> icaMsg_p
->outputdatalength
) ||
2225 (src_l
> RESPBUFFSIZE
) ||
2227 return REC_OPERAND_SIZE
;
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
;
2237 *respbufflen_p
= icaMsg_p
->outputdatalength
;
2238 if (*respbufflen_p
== 0)
2239 PRINTK("Zero *respbufflen_p\n");