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.34 $"
37 char z90hardware_version
[] __initdata
=
38 "z90hardware.o (" VERSION_Z90HARDWARE_C
"/"
39 VERSION_Z90COMMON_H
"/" VERSION_Z90CRYPT_H
")";
41 struct cca_token_hdr
{
42 unsigned char token_identifier
;
43 unsigned char version
;
44 unsigned short token_length
;
45 unsigned char reserved
[4];
48 #define CCA_TKN_HDR_ID_EXT 0x1E
50 struct cca_private_ext_ME_sec
{
51 unsigned char section_identifier
;
52 unsigned char version
;
53 unsigned short section_length
;
54 unsigned char private_key_hash
[20];
55 unsigned char reserved1
[4];
56 unsigned char key_format
;
57 unsigned char reserved2
;
58 unsigned char key_name_hash
[20];
59 unsigned char key_use_flags
[4];
60 unsigned char reserved3
[6];
61 unsigned char reserved4
[24];
62 unsigned char confounder
[24];
63 unsigned char exponent
[128];
64 unsigned char modulus
[128];
67 #define CCA_PVT_USAGE_ALL 0x80
69 struct cca_public_sec
{
70 unsigned char section_identifier
;
71 unsigned char version
;
72 unsigned short section_length
;
73 unsigned char reserved
[2];
74 unsigned short exponent_len
;
75 unsigned short modulus_bit_len
;
76 unsigned short modulus_byte_len
;
77 unsigned char exponent
[3];
80 struct cca_private_ext_ME
{
81 struct cca_token_hdr pvtMEHdr
;
82 struct cca_private_ext_ME_sec pvtMESec
;
83 struct cca_public_sec pubMESec
;
86 struct cca_public_key
{
87 struct cca_token_hdr pubHdr
;
88 struct cca_public_sec pubSec
;
91 struct cca_pvt_ext_CRT_sec
{
92 unsigned char section_identifier
;
93 unsigned char version
;
94 unsigned short section_length
;
95 unsigned char private_key_hash
[20];
96 unsigned char reserved1
[4];
97 unsigned char key_format
;
98 unsigned char reserved2
;
99 unsigned char key_name_hash
[20];
100 unsigned char key_use_flags
[4];
101 unsigned short p_len
;
102 unsigned short q_len
;
103 unsigned short dp_len
;
104 unsigned short dq_len
;
105 unsigned short u_len
;
106 unsigned short mod_len
;
107 unsigned char reserved3
[4];
108 unsigned short pad_len
;
109 unsigned char reserved4
[52];
110 unsigned char confounder
[8];
113 #define CCA_PVT_EXT_CRT_SEC_ID_PVT 0x08
114 #define CCA_PVT_EXT_CRT_SEC_FMT_CL 0x40
116 struct cca_private_ext_CRT
{
117 struct cca_token_hdr pvtCrtHdr
;
118 struct cca_pvt_ext_CRT_sec pvtCrtSec
;
119 struct cca_public_sec pubCrtSec
;
122 struct ap_status_word
{
123 unsigned char q_stat_flags
;
124 unsigned char response_code
;
125 unsigned char reserved
[2];
128 #define AP_Q_STATUS_EMPTY 0x80
129 #define AP_Q_STATUS_REPLIES_WAITING 0x40
130 #define AP_Q_STATUS_ARRAY_FULL 0x20
132 #define AP_RESPONSE_NORMAL 0x00
133 #define AP_RESPONSE_Q_NOT_AVAIL 0x01
134 #define AP_RESPONSE_RESET_IN_PROGRESS 0x02
135 #define AP_RESPONSE_DECONFIGURED 0x03
136 #define AP_RESPONSE_CHECKSTOPPED 0x04
137 #define AP_RESPONSE_BUSY 0x05
138 #define AP_RESPONSE_Q_FULL 0x10
139 #define AP_RESPONSE_NO_PENDING_REPLY 0x10
140 #define AP_RESPONSE_INDEX_TOO_BIG 0x11
141 #define AP_RESPONSE_NO_FIRST_PART 0x13
142 #define AP_RESPONSE_MESSAGE_TOO_BIG 0x15
144 #define AP_MAX_CDX_BITL 4
145 #define AP_RQID_RESERVED_BITL 4
146 #define SKIP_BITL (AP_MAX_CDX_BITL + AP_RQID_RESERVED_BITL)
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 unsigned char reserved1
;
289 unsigned char format
;
290 unsigned char reserved2
;
291 unsigned char reply_code
;
292 unsigned char reserved3
[3];
295 #define TYPE86_RSP_CODE 0x86
296 #define TYPE86_FMT2 0x02
298 struct type86_fmt2_msg
{
299 struct type86_hdr header
;
300 unsigned char reserved
[4];
301 unsigned char apfs
[4];
303 unsigned int offset1
;
305 unsigned int offset2
;
307 unsigned int offset3
;
309 unsigned int offset4
;
312 static struct type6_hdr static_type6_hdr
= {
316 {0x00,0x00,0x00,0x00},
319 {0x00,0x00,0x00,0x00},
324 {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
325 0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
340 static struct type6_hdr static_type6_hdrX
= {
344 {0x00,0x00,0x00,0x00},
347 {0x00,0x00,0x00,0x00},
352 {0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
353 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
368 static struct CPRB static_cprb
= {
372 {0x00,0x00,0x00,0x00},
379 {0x00,0x00,0x00,0x00},
380 {0x00,0x00,0x00,0x00},
381 {0x00,0x00,0x00,0x00},
384 {0x00,0x00,0x00,0x00},
385 {0x00,0x00,0x00,0x00},
386 {0x00,0x00,0x00,0x00},
391 {0x00,0x00,0x00,0x00},
393 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
394 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
395 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
397 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
398 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
401 {0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20}
404 struct function_and_rules_block
{
405 unsigned char function_code
[2];
406 unsigned char ulen
[2];
407 unsigned char only_rule
[8];
410 static struct function_and_rules_block static_pkd_function_and_rules
= {
413 {'P','K','C','S','-','1','.','2'}
416 static struct function_and_rules_block static_pke_function_and_rules
= {
419 {'P','K','C','S','-','1','.','2'}
422 struct T6_keyBlock_hdr
{
423 unsigned char blen
[2];
424 unsigned char ulen
[2];
425 unsigned char flags
[2];
428 static struct T6_keyBlock_hdr static_T6_keyBlock_hdr
= {
434 static struct CPRBX static_cprbx
= {
439 {0x00,0x00,0x00,0x00},
447 {0x00,0x00,0x00,0x00},
449 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
450 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
451 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
452 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
453 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
454 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
455 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
456 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
457 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
458 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
459 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
460 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
464 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
465 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
469 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
470 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
471 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
472 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
475 static struct function_and_rules_block static_pkd_function_and_rulesX_MCL2
= {
478 {'P','K','C','S','-','1','.','2'}
481 static struct function_and_rules_block static_pke_function_and_rulesX_MCL2
= {
484 {'Z','E','R','O','-','P','A','D'}
487 static struct function_and_rules_block static_pkd_function_and_rulesX
= {
490 {'Z','E','R','O','-','P','A','D'}
493 static struct function_and_rules_block static_pke_function_and_rulesX
= {
496 {'M','R','P',' ',' ',' ',' ',' '}
499 static unsigned char static_PKE_function_code
[2] = {0x50, 0x4B};
501 struct T6_keyBlock_hdrX
{
504 unsigned char flags
[2];
507 static unsigned char static_pad
[256] = {
508 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
509 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
510 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
511 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
512 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
513 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
514 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
515 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
516 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
517 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
518 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
519 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
520 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
521 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
522 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
523 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
526 static struct cca_private_ext_ME static_pvt_me_key
= {
531 {0x00,0x00,0x00,0x00}
538 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
539 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
540 0x00,0x00,0x00,0x00},
541 {0x00,0x00,0x00,0x00},
544 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
545 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
546 0x00,0x00,0x00,0x00},
547 {0x80,0x00,0x00,0x00},
548 {0x00,0x00,0x00,0x00,0x00,0x00},
549 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
550 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
551 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
552 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
553 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
554 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
555 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
556 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
557 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
558 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
559 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
560 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
561 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
562 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
563 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
564 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
565 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
566 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
567 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
568 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
569 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
570 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
571 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
572 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
573 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
574 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
575 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
576 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
577 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
578 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
579 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
580 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
581 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
582 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
583 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
584 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
585 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
586 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
601 static struct cca_public_key static_public_key
= {
606 {0x00,0x00,0x00,0x00}
621 #define FIXED_TYPE6_ME_LEN 0x0000025F
623 #define FIXED_TYPE6_ME_EN_LEN 0x000000F0
625 #define FIXED_TYPE6_ME_LENX 0x000002CB
627 #define FIXED_TYPE6_ME_EN_LENX 0x0000015C
629 static struct cca_public_sec static_cca_pub_sec
= {
640 #define FIXED_TYPE6_CR_LEN 0x00000177
642 #define FIXED_TYPE6_CR_LENX 0x000001E3
644 #define MAX_RESPONSE_SIZE 0x00000710
646 #define MAX_RESPONSEX_SIZE 0x0000077C
648 #define RESPONSE_CPRB_SIZE 0x000006B8
649 #define RESPONSE_CPRBX_SIZE 0x00000724
652 unsigned char reserved1
;
654 unsigned char reserved2
[2];
655 unsigned char reply_code
;
656 unsigned char reserved3
[3];
659 #define TYPE82_RSP_CODE 0x82
661 #define REP82_ERROR_MACHINE_FAILURE 0x10
662 #define REP82_ERROR_PREEMPT_FAILURE 0x12
663 #define REP82_ERROR_CHECKPT_FAILURE 0x14
664 #define REP82_ERROR_MESSAGE_TYPE 0x20
665 #define REP82_ERROR_INVALID_COMM_CD 0x21
666 #define REP82_ERROR_INVALID_MSG_LEN 0x23
667 #define REP82_ERROR_RESERVD_FIELD 0x24
668 #define REP82_ERROR_FORMAT_FIELD 0x29
669 #define REP82_ERROR_INVALID_COMMAND 0x30
670 #define REP82_ERROR_MALFORMED_MSG 0x40
671 #define REP82_ERROR_RESERVED_FIELDO 0x50
672 #define REP82_ERROR_WORD_ALIGNMENT 0x60
673 #define REP82_ERROR_MESSAGE_LENGTH 0x80
674 #define REP82_ERROR_OPERAND_INVALID 0x82
675 #define REP82_ERROR_OPERAND_SIZE 0x84
676 #define REP82_ERROR_EVEN_MOD_IN_OPND 0x85
677 #define REP82_ERROR_RESERVED_FIELD 0x88
678 #define REP82_ERROR_TRANSPORT_FAIL 0x90
679 #define REP82_ERROR_PACKET_TRUNCATED 0xA0
680 #define REP82_ERROR_ZERO_BUFFER_LEN 0xB0
682 #define CALLER_HEADER 12
685 testq(int q_nr
, int *q_depth
, int *dev_type
, struct ap_status_word
*stat
)
694 "0: .long 0xb2af0000 \n"
706 ".section .fixup,\"ax\" \n"
711 ".section __ex_table,\"a\" \n"
716 :"=d" (ccode
),"=d" (*stat
),"=d" (*q_depth
), "=d" (*dev_type
)
717 :"d" (q_nr
), "K" (DEV_TSQ_EXCEPTION
)
718 :"cc","0","1","2","memory");
723 "0: .long 0xb2af0000 \n"
733 ".section .fixup,\"ax\" \n"
742 ".section __ex_table,\"a\" \n"
747 :"=d" (ccode
),"=d" (*stat
),"=d" (*q_depth
), "=d" (*dev_type
)
748 :"d" (q_nr
), "K" (DEV_TSQ_EXCEPTION
)
749 :"cc","0","1","2","memory");
755 resetq(int q_nr
, struct ap_status_word
*stat_p
)
767 "0: .long 0xb2af0000 \n"
774 ".section .fixup,\"ax\" \n"
779 ".section __ex_table,\"a\" \n"
784 :"=d" (ccode
),"=d" (*stat_p
)
785 :"d" (q_nr
), "K" (DEV_RSQ_EXCEPTION
)
786 :"cc","0","1","2","memory");
794 "0: .long 0xb2af0000 \n"
799 ".section .fixup,\"ax\" \n"
808 ".section __ex_table,\"a\" \n"
813 :"=d" (ccode
),"=d" (*stat_p
)
814 :"d" (q_nr
), "K" (DEV_RSQ_EXCEPTION
)
815 :"cc","0","1","2","memory");
821 sen(int msg_len
, unsigned char *msg_ext
, struct ap_status_word
*stat
)
838 "0: .long 0xb2ad0026 \n"
846 ".section .fixup,\"ax\" \n"
851 ".section __ex_table,\"a\" \n"
856 :"=d" (ccode
),"=d" (*stat
)
857 :"d" (msg_len
),"a" (msg_ext
), "K" (DEV_SEN_EXCEPTION
)
858 :"cc","0","1","2","3","6","7","memory");
871 "0: .long 0xb2ad0026 \n"
877 ".section .fixup,\"ax\" \n"
886 ".section __ex_table,\"a\" \n"
891 :"=d" (ccode
),"=d" (*stat
)
892 :"d" (msg_len
),"a" (msg_ext
), "K" (DEV_SEN_EXCEPTION
)
893 :"cc","0","1","2","3","6","7","memory");
899 rec(int q_nr
, int buff_l
, unsigned char *rsp
, unsigned char *id
,
900 struct ap_status_word
*st
)
917 "0: .long 0xb2ae0046 \n"
928 ".section .fixup,\"ax\" \n"
933 ".section __ex_table,\"a\" \n"
938 :"=d"(ccode
),"=d"(*st
)
939 :"d" (q_nr
), "d" (rsp
), "d" (id
), "d" (buff_l
), "K" (DEV_REC_EXCEPTION
)
940 :"cc","0","1","2","3","4","5","6","7","memory");
953 "0: .long 0xb2ae0046 \n"
962 ".section .fixup,\"ax\" \n"
971 ".section __ex_table,\"a\" \n"
976 :"=d"(ccode
),"=d"(*st
)
977 :"d" (q_nr
), "d" (rsp
), "d" (id
), "d" (buff_l
), "K" (DEV_REC_EXCEPTION
)
978 :"cc","0","1","2","3","4","5","6","7","memory");
984 itoLe2(int *i_p
, unsigned char *lechars
)
986 *lechars
= *((unsigned char *) i_p
+ sizeof(int) - 1);
987 *(lechars
+ 1) = *((unsigned char *) i_p
+ sizeof(int) - 2);
991 le2toI(unsigned char *lechars
, int *i_p
)
995 ic_p
= (unsigned char *) i_p
;
996 *(ic_p
+ 2) = *(lechars
+ 1);
997 *(ic_p
+ 3) = *(lechars
);
1001 is_empty(unsigned char *ptr
, int len
)
1003 return !memcmp(ptr
, (unsigned char *) &static_pvt_me_key
+60, len
);
1007 query_online(int deviceNr
, int cdx
, int resetNr
, int *q_depth
, int *dev_type
)
1009 int q_nr
, i
, t_depth
, t_dev_type
;
1011 struct ap_status_word stat_word
;
1015 q_nr
= (deviceNr
<< SKIP_BITL
) + cdx
;
1017 ccode
= testq(q_nr
, &t_depth
, &t_dev_type
, &stat_word
);
1018 PDEBUG("ccode %d response_code %02X\n", ccode
, stat_word
.response_code
);
1020 for (i
= 0; i
< resetNr
; i
++) {
1022 PRINTKC("Exception testing device %d\n", i
);
1023 return HD_TSQ_EXCEPTION
;
1027 PDEBUG("t_dev_type %d\n", t_dev_type
);
1030 *q_depth
= t_depth
+ 1;
1031 switch (t_dev_type
) {
1033 stat
= HD_NOT_THERE
;
1043 *dev_type
= PCIXCC_UNK
;
1052 PDEBUG("available device %d: Q depth = %d, dev "
1053 "type = %d, stat = %02X%02X%02X%02X\n",
1054 deviceNr
, *q_depth
, *dev_type
,
1055 stat_word
.q_stat_flags
,
1056 stat_word
.response_code
,
1057 stat_word
.reserved
[0],
1058 stat_word
.reserved
[1]);
1061 switch (stat_word
.response_code
) {
1062 case AP_RESPONSE_NORMAL
:
1065 *q_depth
= t_depth
+ 1;
1066 *dev_type
= t_dev_type
;
1067 PDEBUG("cc3, available device "
1068 "%d: Q depth = %d, dev "
1069 "type = %d, stat = "
1070 "%02X%02X%02X%02X\n",
1073 stat_word
.q_stat_flags
,
1074 stat_word
.response_code
,
1075 stat_word
.reserved
[0],
1076 stat_word
.reserved
[1]);
1078 case AP_RESPONSE_Q_NOT_AVAIL
:
1079 stat
= HD_NOT_THERE
;
1082 case AP_RESPONSE_RESET_IN_PROGRESS
:
1083 PDEBUG("device %d in reset\n",
1086 case AP_RESPONSE_DECONFIGURED
:
1087 stat
= HD_DECONFIGURED
;
1090 case AP_RESPONSE_CHECKSTOPPED
:
1091 stat
= HD_CHECKSTOPPED
;
1094 case AP_RESPONSE_BUSY
:
1095 PDEBUG("device %d busy\n",
1103 stat
= HD_NOT_THERE
;
1112 ccode
= testq(q_nr
, &t_depth
, &t_dev_type
, &stat_word
);
1118 reset_device(int deviceNr
, int cdx
, int resetNr
)
1120 int q_nr
, ccode
= 0, dummy_qdepth
, dummy_devType
, i
;
1121 struct ap_status_word stat_word
;
1125 q_nr
= (deviceNr
<< SKIP_BITL
) + cdx
;
1127 ccode
= resetq(q_nr
, &stat_word
);
1129 return DEV_RSQ_EXCEPTION
;
1132 for (i
= 0; i
< resetNr
; i
++) {
1136 if (stat_word
.q_stat_flags
& AP_Q_STATUS_EMPTY
)
1140 switch (stat_word
.response_code
) {
1141 case AP_RESPONSE_NORMAL
:
1143 if (stat_word
.q_stat_flags
& AP_Q_STATUS_EMPTY
)
1146 case AP_RESPONSE_Q_NOT_AVAIL
:
1147 case AP_RESPONSE_DECONFIGURED
:
1148 case AP_RESPONSE_CHECKSTOPPED
:
1152 case AP_RESPONSE_RESET_IN_PROGRESS
:
1153 case AP_RESPONSE_BUSY
:
1167 ccode
= testq(q_nr
, &dummy_qdepth
, &dummy_devType
, &stat_word
);
1169 stat
= DEV_TSQ_EXCEPTION
;
1173 PDEBUG("Number of testq's needed for reset: %d\n", i
);
1182 #ifdef DEBUG_HYDRA_MSGS
1184 print_buffer(unsigned char *buffer
, int bufflen
)
1187 for (i
= 0; i
< bufflen
; i
+= 16) {
1188 PRINTK("%04X: %02X%02X%02X%02X %02X%02X%02X%02X "
1189 "%02X%02X%02X%02X %02X%02X%02X%02X\n", i
,
1190 buffer
[i
+0], buffer
[i
+1], buffer
[i
+2], buffer
[i
+3],
1191 buffer
[i
+4], buffer
[i
+5], buffer
[i
+6], buffer
[i
+7],
1192 buffer
[i
+8], buffer
[i
+9], buffer
[i
+10], buffer
[i
+11],
1193 buffer
[i
+12], buffer
[i
+13], buffer
[i
+14], buffer
[i
+15]);
1199 send_to_AP(int dev_nr
, int cdx
, int msg_len
, unsigned char *msg_ext
)
1201 struct ap_status_word stat_word
;
1204 u32
*q_nr_p
= (u32
*)msg_ext
;
1206 *q_nr_p
= (dev_nr
<< SKIP_BITL
) + cdx
;
1207 PDEBUG("msg_len passed to sen: %d\n", msg_len
);
1208 PDEBUG("q number passed to sen: %02x%02x%02x%02x\n",
1209 msg_ext
[0], msg_ext
[1], msg_ext
[2], msg_ext
[3]);
1212 #ifdef DEBUG_HYDRA_MSGS
1213 PRINTK("Request header: %02X%02X%02X%02X %02X%02X%02X%02X "
1214 "%02X%02X%02X%02X\n",
1215 msg_ext
[0], msg_ext
[1], msg_ext
[2], msg_ext
[3],
1216 msg_ext
[4], msg_ext
[5], msg_ext
[6], msg_ext
[7],
1217 msg_ext
[8], msg_ext
[9], msg_ext
[10], msg_ext
[11]);
1218 print_buffer(msg_ext
+CALLER_HEADER
, msg_len
);
1221 ccode
= sen(msg_len
, msg_ext
, &stat_word
);
1223 return DEV_SEN_EXCEPTION
;
1225 PDEBUG("nq cc: %u, st: %02x%02x%02x%02x\n",
1226 ccode
, stat_word
.q_stat_flags
, stat_word
.response_code
,
1227 stat_word
.reserved
[0], stat_word
.reserved
[1]);
1236 switch (stat_word
.response_code
) {
1237 case AP_RESPONSE_NORMAL
:
1240 case AP_RESPONSE_Q_FULL
:
1241 stat
= DEV_QUEUE_FULL
;
1257 receive_from_AP(int dev_nr
, int cdx
, int resplen
, unsigned char *resp
,
1258 unsigned char *psmid
)
1261 struct ap_status_word stat_word
;
1264 memset(resp
, 0x00, 8);
1266 ccode
= rec((dev_nr
<< SKIP_BITL
) + cdx
, resplen
, resp
, psmid
,
1269 return DEV_REC_EXCEPTION
;
1271 PDEBUG("dq cc: %u, st: %02x%02x%02x%02x\n",
1272 ccode
, stat_word
.q_stat_flags
, stat_word
.response_code
,
1273 stat_word
.reserved
[0], stat_word
.reserved
[1]);
1279 #ifdef DEBUG_HYDRA_MSGS
1280 print_buffer(resp
, resplen
);
1284 switch (stat_word
.response_code
) {
1285 case AP_RESPONSE_NORMAL
:
1288 case AP_RESPONSE_NO_PENDING_REPLY
:
1289 if (stat_word
.q_stat_flags
& AP_Q_STATUS_EMPTY
)
1294 case AP_RESPONSE_INDEX_TOO_BIG
:
1295 case AP_RESPONSE_NO_FIRST_PART
:
1296 case AP_RESPONSE_MESSAGE_TOO_BIG
:
1297 stat
= DEV_BAD_MESSAGE
;
1311 pad_msg(unsigned char *buffer
, int totalLength
, int msgLength
)
1315 for (pad_len
= 0; pad_len
< (totalLength
- msgLength
); pad_len
++)
1316 if (buffer
[pad_len
] != 0x00)
1320 return SEN_PAD_ERROR
;
1325 memcpy(buffer
+2, static_pad
, pad_len
);
1327 buffer
[pad_len
+ 2] = 0x00;
1333 is_common_public_key(unsigned char *key
, int len
)
1337 for (i
= 0; i
< len
; i
++)
1342 if (((len
== 1) && (key
[0] == 3)) ||
1343 ((len
== 3) && (key
[0] == 1) && (key
[1] == 0) && (key
[2] == 1)))
1350 ICAMEX_msg_to_type4MEX_msg(struct ica_rsa_modexpo
*icaMex_p
, int *z90cMsg_l_p
,
1351 union type4_msg
*z90cMsg_p
)
1353 int mod_len
, msg_size
, mod_tgt_len
, exp_tgt_len
, inp_tgt_len
;
1354 unsigned char *mod_tgt
, *exp_tgt
, *inp_tgt
;
1355 union type4_msg
*tmp_type4_msg
;
1357 mod_len
= icaMex_p
->inputdatalength
;
1359 msg_size
= ((mod_len
<= 128) ? TYPE4_SME_LEN
: TYPE4_LME_LEN
) +
1362 memset(z90cMsg_p
, 0, msg_size
);
1364 tmp_type4_msg
= (union type4_msg
*)
1365 ((unsigned char *) z90cMsg_p
+ CALLER_HEADER
);
1367 tmp_type4_msg
->sme
.header
.msg_type_code
= TYPE4_TYPE_CODE
;
1368 tmp_type4_msg
->sme
.header
.request_code
= TYPE4_REQU_CODE
;
1370 if (mod_len
<= 128) {
1371 tmp_type4_msg
->sme
.header
.msg_fmt
= TYPE4_SME_FMT
;
1372 tmp_type4_msg
->sme
.header
.msg_len
= TYPE4_SME_LEN
;
1373 mod_tgt
= tmp_type4_msg
->sme
.modulus
;
1374 mod_tgt_len
= sizeof(tmp_type4_msg
->sme
.modulus
);
1375 exp_tgt
= tmp_type4_msg
->sme
.exponent
;
1376 exp_tgt_len
= sizeof(tmp_type4_msg
->sme
.exponent
);
1377 inp_tgt
= tmp_type4_msg
->sme
.message
;
1378 inp_tgt_len
= sizeof(tmp_type4_msg
->sme
.message
);
1380 tmp_type4_msg
->lme
.header
.msg_fmt
= TYPE4_LME_FMT
;
1381 tmp_type4_msg
->lme
.header
.msg_len
= TYPE4_LME_LEN
;
1382 mod_tgt
= tmp_type4_msg
->lme
.modulus
;
1383 mod_tgt_len
= sizeof(tmp_type4_msg
->lme
.modulus
);
1384 exp_tgt
= tmp_type4_msg
->lme
.exponent
;
1385 exp_tgt_len
= sizeof(tmp_type4_msg
->lme
.exponent
);
1386 inp_tgt
= tmp_type4_msg
->lme
.message
;
1387 inp_tgt_len
= sizeof(tmp_type4_msg
->lme
.message
);
1390 mod_tgt
+= (mod_tgt_len
- mod_len
);
1391 if (copy_from_user(mod_tgt
, icaMex_p
->n_modulus
, mod_len
))
1392 return SEN_RELEASED
;
1393 if (is_empty(mod_tgt
, mod_len
))
1394 return SEN_USER_ERROR
;
1395 exp_tgt
+= (exp_tgt_len
- mod_len
);
1396 if (copy_from_user(exp_tgt
, icaMex_p
->b_key
, mod_len
))
1397 return SEN_RELEASED
;
1398 if (is_empty(exp_tgt
, mod_len
))
1399 return SEN_USER_ERROR
;
1400 inp_tgt
+= (inp_tgt_len
- mod_len
);
1401 if (copy_from_user(inp_tgt
, icaMex_p
->inputdata
, mod_len
))
1402 return SEN_RELEASED
;
1403 if (is_empty(inp_tgt
, mod_len
))
1404 return SEN_USER_ERROR
;
1406 *z90cMsg_l_p
= msg_size
- CALLER_HEADER
;
1412 ICACRT_msg_to_type4CRT_msg(struct ica_rsa_modexpo_crt
*icaMsg_p
,
1413 int *z90cMsg_l_p
, union type4_msg
*z90cMsg_p
)
1415 int mod_len
, short_len
, long_len
, tmp_size
, p_tgt_len
, q_tgt_len
,
1416 dp_tgt_len
, dq_tgt_len
, u_tgt_len
, inp_tgt_len
;
1417 unsigned char *p_tgt
, *q_tgt
, *dp_tgt
, *dq_tgt
, *u_tgt
, *inp_tgt
;
1418 union type4_msg
*tmp_type4_msg
;
1420 mod_len
= icaMsg_p
->inputdatalength
;
1421 short_len
= mod_len
/ 2;
1422 long_len
= mod_len
/ 2 + 8;
1424 tmp_size
= ((mod_len
<= 128) ? TYPE4_SCR_LEN
: TYPE4_LCR_LEN
) +
1427 memset(z90cMsg_p
, 0, tmp_size
);
1429 tmp_type4_msg
= (union type4_msg
*)
1430 ((unsigned char *) z90cMsg_p
+ CALLER_HEADER
);
1432 tmp_type4_msg
->scr
.header
.msg_type_code
= TYPE4_TYPE_CODE
;
1433 tmp_type4_msg
->scr
.header
.request_code
= TYPE4_REQU_CODE
;
1434 if (mod_len
<= 128) {
1435 tmp_type4_msg
->scr
.header
.msg_fmt
= TYPE4_SCR_FMT
;
1436 tmp_type4_msg
->scr
.header
.msg_len
= TYPE4_SCR_LEN
;
1437 p_tgt
= tmp_type4_msg
->scr
.p
;
1438 p_tgt_len
= sizeof(tmp_type4_msg
->scr
.p
);
1439 q_tgt
= tmp_type4_msg
->scr
.q
;
1440 q_tgt_len
= sizeof(tmp_type4_msg
->scr
.q
);
1441 dp_tgt
= tmp_type4_msg
->scr
.dp
;
1442 dp_tgt_len
= sizeof(tmp_type4_msg
->scr
.dp
);
1443 dq_tgt
= tmp_type4_msg
->scr
.dq
;
1444 dq_tgt_len
= sizeof(tmp_type4_msg
->scr
.dq
);
1445 u_tgt
= tmp_type4_msg
->scr
.u
;
1446 u_tgt_len
= sizeof(tmp_type4_msg
->scr
.u
);
1447 inp_tgt
= tmp_type4_msg
->scr
.message
;
1448 inp_tgt_len
= sizeof(tmp_type4_msg
->scr
.message
);
1450 tmp_type4_msg
->lcr
.header
.msg_fmt
= TYPE4_LCR_FMT
;
1451 tmp_type4_msg
->lcr
.header
.msg_len
= TYPE4_LCR_LEN
;
1452 p_tgt
= tmp_type4_msg
->lcr
.p
;
1453 p_tgt_len
= sizeof(tmp_type4_msg
->lcr
.p
);
1454 q_tgt
= tmp_type4_msg
->lcr
.q
;
1455 q_tgt_len
= sizeof(tmp_type4_msg
->lcr
.q
);
1456 dp_tgt
= tmp_type4_msg
->lcr
.dp
;
1457 dp_tgt_len
= sizeof(tmp_type4_msg
->lcr
.dp
);
1458 dq_tgt
= tmp_type4_msg
->lcr
.dq
;
1459 dq_tgt_len
= sizeof(tmp_type4_msg
->lcr
.dq
);
1460 u_tgt
= tmp_type4_msg
->lcr
.u
;
1461 u_tgt_len
= sizeof(tmp_type4_msg
->lcr
.u
);
1462 inp_tgt
= tmp_type4_msg
->lcr
.message
;
1463 inp_tgt_len
= sizeof(tmp_type4_msg
->lcr
.message
);
1466 p_tgt
+= (p_tgt_len
- long_len
);
1467 if (copy_from_user(p_tgt
, icaMsg_p
->np_prime
, long_len
))
1468 return SEN_RELEASED
;
1469 if (is_empty(p_tgt
, long_len
))
1470 return SEN_USER_ERROR
;
1471 q_tgt
+= (q_tgt_len
- short_len
);
1472 if (copy_from_user(q_tgt
, icaMsg_p
->nq_prime
, short_len
))
1473 return SEN_RELEASED
;
1474 if (is_empty(q_tgt
, short_len
))
1475 return SEN_USER_ERROR
;
1476 dp_tgt
+= (dp_tgt_len
- long_len
);
1477 if (copy_from_user(dp_tgt
, icaMsg_p
->bp_key
, long_len
))
1478 return SEN_RELEASED
;
1479 if (is_empty(dp_tgt
, long_len
))
1480 return SEN_USER_ERROR
;
1481 dq_tgt
+= (dq_tgt_len
- short_len
);
1482 if (copy_from_user(dq_tgt
, icaMsg_p
->bq_key
, short_len
))
1483 return SEN_RELEASED
;
1484 if (is_empty(dq_tgt
, short_len
))
1485 return SEN_USER_ERROR
;
1486 u_tgt
+= (u_tgt_len
- long_len
);
1487 if (copy_from_user(u_tgt
, icaMsg_p
->u_mult_inv
, long_len
))
1488 return SEN_RELEASED
;
1489 if (is_empty(u_tgt
, long_len
))
1490 return SEN_USER_ERROR
;
1491 inp_tgt
+= (inp_tgt_len
- mod_len
);
1492 if (copy_from_user(inp_tgt
, icaMsg_p
->inputdata
, mod_len
))
1493 return SEN_RELEASED
;
1494 if (is_empty(inp_tgt
, mod_len
))
1495 return SEN_USER_ERROR
;
1497 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
1503 ICAMEX_msg_to_type6MEX_de_msg(struct ica_rsa_modexpo
*icaMsg_p
, int cdx
,
1504 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
)
1506 int mod_len
, vud_len
, tmp_size
, total_CPRB_len
, parmBlock_l
;
1507 unsigned char *temp
;
1508 struct type6_hdr
*tp6Hdr_p
;
1509 struct CPRB
*cprb_p
;
1510 struct cca_private_ext_ME
*key_p
;
1511 static int deprecated_msg_count
= 0;
1513 mod_len
= icaMsg_p
->inputdatalength
;
1514 tmp_size
= FIXED_TYPE6_ME_LEN
+ mod_len
;
1515 total_CPRB_len
= tmp_size
- sizeof(struct type6_hdr
);
1516 parmBlock_l
= total_CPRB_len
- sizeof(struct CPRB
);
1517 tmp_size
= 4*((tmp_size
+ 3)/4) + CALLER_HEADER
;
1519 memset(z90cMsg_p
, 0, tmp_size
);
1521 temp
= (unsigned char *)z90cMsg_p
+ CALLER_HEADER
;
1522 memcpy(temp
, &static_type6_hdr
, sizeof(struct type6_hdr
));
1523 tp6Hdr_p
= (struct type6_hdr
*)temp
;
1524 tp6Hdr_p
->ToCardLen1
= 4*((total_CPRB_len
+3)/4);
1525 tp6Hdr_p
->FromCardLen1
= RESPONSE_CPRB_SIZE
;
1527 temp
+= sizeof(struct type6_hdr
);
1528 memcpy(temp
, &static_cprb
, sizeof(struct CPRB
));
1529 cprb_p
= (struct CPRB
*) temp
;
1530 cprb_p
->usage_domain
[0]= (unsigned char)cdx
;
1531 itoLe2(&parmBlock_l
, cprb_p
->req_parml
);
1532 itoLe2((int *)&(tp6Hdr_p
->FromCardLen1
), cprb_p
->rpl_parml
);
1534 temp
+= sizeof(struct CPRB
);
1535 memcpy(temp
, &static_pkd_function_and_rules
,
1536 sizeof(struct function_and_rules_block
));
1538 temp
+= sizeof(struct function_and_rules_block
);
1539 vud_len
= 2 + icaMsg_p
->inputdatalength
;
1540 itoLe2(&vud_len
, temp
);
1543 if (copy_from_user(temp
, icaMsg_p
->inputdata
, mod_len
))
1544 return SEN_RELEASED
;
1545 if (is_empty(temp
, mod_len
))
1546 return SEN_USER_ERROR
;
1549 memcpy(temp
, &static_T6_keyBlock_hdr
, sizeof(struct T6_keyBlock_hdr
));
1551 temp
+= sizeof(struct T6_keyBlock_hdr
);
1552 memcpy(temp
, &static_pvt_me_key
, sizeof(struct cca_private_ext_ME
));
1553 key_p
= (struct cca_private_ext_ME
*)temp
;
1554 temp
= key_p
->pvtMESec
.exponent
+ sizeof(key_p
->pvtMESec
.exponent
)
1556 if (copy_from_user(temp
, icaMsg_p
->b_key
, mod_len
))
1557 return SEN_RELEASED
;
1558 if (is_empty(temp
, mod_len
))
1559 return SEN_USER_ERROR
;
1561 if (is_common_public_key(temp
, mod_len
)) {
1562 if (deprecated_msg_count
< 20) {
1563 PRINTK("Common public key used for modex decrypt\n");
1564 deprecated_msg_count
++;
1565 if (deprecated_msg_count
== 20)
1566 PRINTK("No longer issuing messages about common"
1567 " public key for modex decrypt.\n");
1569 return SEN_NOT_AVAIL
;
1572 temp
= key_p
->pvtMESec
.modulus
+ sizeof(key_p
->pvtMESec
.modulus
)
1574 if (copy_from_user(temp
, icaMsg_p
->n_modulus
, mod_len
))
1575 return SEN_RELEASED
;
1576 if (is_empty(temp
, mod_len
))
1577 return SEN_USER_ERROR
;
1579 key_p
->pubMESec
.modulus_bit_len
= 8 * mod_len
;
1581 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
1587 ICAMEX_msg_to_type6MEX_en_msg(struct ica_rsa_modexpo
*icaMsg_p
, int cdx
,
1588 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
)
1590 int mod_len
, vud_len
, exp_len
, key_len
;
1591 int pad_len
, tmp_size
, total_CPRB_len
, parmBlock_l
, i
;
1592 unsigned char *temp_exp
, *exp_p
, *temp
;
1593 struct type6_hdr
*tp6Hdr_p
;
1594 struct CPRB
*cprb_p
;
1595 struct cca_public_key
*key_p
;
1596 struct T6_keyBlock_hdr
*keyb_p
;
1598 temp_exp
= kmalloc(256, GFP_KERNEL
);
1601 mod_len
= icaMsg_p
->inputdatalength
;
1602 if (copy_from_user(temp_exp
, icaMsg_p
->b_key
, mod_len
)) {
1604 return SEN_RELEASED
;
1606 if (is_empty(temp_exp
, mod_len
)) {
1608 return SEN_USER_ERROR
;
1612 for (i
= 0; i
< mod_len
; i
++)
1617 return SEN_USER_ERROR
;
1620 exp_len
= mod_len
- i
;
1623 PDEBUG("exp_len after computation: %08x\n", exp_len
);
1624 tmp_size
= FIXED_TYPE6_ME_EN_LEN
+ 2 * mod_len
+ exp_len
;
1625 total_CPRB_len
= tmp_size
- sizeof(struct type6_hdr
);
1626 parmBlock_l
= total_CPRB_len
- sizeof(struct CPRB
);
1627 tmp_size
= 4*((tmp_size
+ 3)/4) + CALLER_HEADER
;
1629 vud_len
= 2 + mod_len
;
1630 memset(z90cMsg_p
, 0, tmp_size
);
1632 temp
= (unsigned char *)z90cMsg_p
+ CALLER_HEADER
;
1633 memcpy(temp
, &static_type6_hdr
, sizeof(struct type6_hdr
));
1634 tp6Hdr_p
= (struct type6_hdr
*)temp
;
1635 tp6Hdr_p
->ToCardLen1
= 4*((total_CPRB_len
+3)/4);
1636 tp6Hdr_p
->FromCardLen1
= RESPONSE_CPRB_SIZE
;
1637 memcpy(tp6Hdr_p
->function_code
, static_PKE_function_code
,
1638 sizeof(static_PKE_function_code
));
1639 temp
+= sizeof(struct type6_hdr
);
1640 memcpy(temp
, &static_cprb
, sizeof(struct CPRB
));
1641 cprb_p
= (struct CPRB
*) temp
;
1642 cprb_p
->usage_domain
[0]= (unsigned char)cdx
;
1643 itoLe2((int *)&(tp6Hdr_p
->FromCardLen1
), cprb_p
->rpl_parml
);
1644 temp
+= sizeof(struct CPRB
);
1645 memcpy(temp
, &static_pke_function_and_rules
,
1646 sizeof(struct function_and_rules_block
));
1647 temp
+= sizeof(struct function_and_rules_block
);
1649 if (copy_from_user(temp
, icaMsg_p
->inputdata
, mod_len
)) {
1651 return SEN_RELEASED
;
1653 if (is_empty(temp
, mod_len
)) {
1655 return SEN_USER_ERROR
;
1657 if ((temp
[0] != 0x00) || (temp
[1] != 0x02)) {
1659 return SEN_NOT_AVAIL
;
1661 for (i
= 2; i
< mod_len
; i
++)
1662 if (temp
[i
] == 0x00)
1664 if ((i
< 9) || (i
> (mod_len
- 2))) {
1666 return SEN_NOT_AVAIL
;
1669 vud_len
= mod_len
- pad_len
;
1670 memmove(temp
, temp
+pad_len
, vud_len
);
1673 itoLe2(&vud_len
, temp
);
1675 keyb_p
= (struct T6_keyBlock_hdr
*)temp
;
1676 temp
+= sizeof(struct T6_keyBlock_hdr
);
1677 memcpy(temp
, &static_public_key
, sizeof(static_public_key
));
1678 key_p
= (struct cca_public_key
*)temp
;
1679 temp
= key_p
->pubSec
.exponent
;
1680 memcpy(temp
, exp_p
, exp_len
);
1683 if (copy_from_user(temp
, icaMsg_p
->n_modulus
, mod_len
))
1684 return SEN_RELEASED
;
1685 if (is_empty(temp
, mod_len
))
1686 return SEN_USER_ERROR
;
1687 key_p
->pubSec
.modulus_bit_len
= 8 * mod_len
;
1688 key_p
->pubSec
.modulus_byte_len
= mod_len
;
1689 key_p
->pubSec
.exponent_len
= exp_len
;
1690 key_p
->pubSec
.section_length
= CALLER_HEADER
+ mod_len
+ exp_len
;
1691 key_len
= key_p
->pubSec
.section_length
+ sizeof(struct cca_token_hdr
);
1692 key_p
->pubHdr
.token_length
= key_len
;
1694 itoLe2(&key_len
, keyb_p
->ulen
);
1696 itoLe2(&key_len
, keyb_p
->blen
);
1697 parmBlock_l
-= pad_len
;
1698 itoLe2(&parmBlock_l
, cprb_p
->req_parml
);
1699 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
1705 ICACRT_msg_to_type6CRT_msg(struct ica_rsa_modexpo_crt
*icaMsg_p
, int cdx
,
1706 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
)
1708 int mod_len
, vud_len
, tmp_size
, total_CPRB_len
, parmBlock_l
, short_len
;
1709 int long_len
, pad_len
, keyPartsLen
, tmp_l
;
1710 unsigned char *tgt_p
, *temp
;
1711 struct type6_hdr
*tp6Hdr_p
;
1712 struct CPRB
*cprb_p
;
1713 struct cca_token_hdr
*keyHdr_p
;
1714 struct cca_pvt_ext_CRT_sec
*pvtSec_p
;
1715 struct cca_public_sec
*pubSec_p
;
1717 mod_len
= icaMsg_p
->inputdatalength
;
1718 short_len
= mod_len
/ 2;
1719 long_len
= 8 + short_len
;
1720 keyPartsLen
= 3 * long_len
+ 2 * short_len
;
1721 pad_len
= (8 - (keyPartsLen
% 8)) % 8;
1722 keyPartsLen
+= pad_len
+ mod_len
;
1723 tmp_size
= FIXED_TYPE6_CR_LEN
+ keyPartsLen
+ mod_len
;
1724 total_CPRB_len
= tmp_size
- sizeof(struct type6_hdr
);
1725 parmBlock_l
= total_CPRB_len
- sizeof(struct CPRB
);
1726 vud_len
= 2 + mod_len
;
1727 tmp_size
= 4*((tmp_size
+ 3)/4) + CALLER_HEADER
;
1729 memset(z90cMsg_p
, 0, tmp_size
);
1730 tgt_p
= (unsigned char *)z90cMsg_p
+ CALLER_HEADER
;
1731 memcpy(tgt_p
, &static_type6_hdr
, sizeof(struct type6_hdr
));
1732 tp6Hdr_p
= (struct type6_hdr
*)tgt_p
;
1733 tp6Hdr_p
->ToCardLen1
= 4*((total_CPRB_len
+3)/4);
1734 tp6Hdr_p
->FromCardLen1
= RESPONSE_CPRB_SIZE
;
1735 tgt_p
+= sizeof(struct type6_hdr
);
1736 cprb_p
= (struct CPRB
*) tgt_p
;
1737 memcpy(tgt_p
, &static_cprb
, sizeof(struct CPRB
));
1738 cprb_p
->usage_domain
[0]= *((unsigned char *)(&(cdx
))+3);
1739 itoLe2(&parmBlock_l
, cprb_p
->req_parml
);
1740 memcpy(cprb_p
->rpl_parml
, cprb_p
->req_parml
,
1741 sizeof(cprb_p
->req_parml
));
1742 tgt_p
+= sizeof(struct CPRB
);
1743 memcpy(tgt_p
, &static_pkd_function_and_rules
,
1744 sizeof(struct function_and_rules_block
));
1745 tgt_p
+= sizeof(struct function_and_rules_block
);
1746 itoLe2(&vud_len
, tgt_p
);
1748 if (copy_from_user(tgt_p
, icaMsg_p
->inputdata
, mod_len
))
1749 return SEN_RELEASED
;
1750 if (is_empty(tgt_p
, mod_len
))
1751 return SEN_USER_ERROR
;
1753 tmp_l
= sizeof(struct T6_keyBlock_hdr
) + sizeof(struct cca_token_hdr
) +
1754 sizeof(struct cca_pvt_ext_CRT_sec
) + 0x0F + keyPartsLen
;
1755 itoLe2(&tmp_l
, tgt_p
);
1758 itoLe2(&tmp_l
, temp
);
1759 tgt_p
+= sizeof(struct T6_keyBlock_hdr
);
1760 keyHdr_p
= (struct cca_token_hdr
*)tgt_p
;
1761 keyHdr_p
->token_identifier
= CCA_TKN_HDR_ID_EXT
;
1763 keyHdr_p
->token_length
= tmp_l
;
1764 tgt_p
+= sizeof(struct cca_token_hdr
);
1765 pvtSec_p
= (struct cca_pvt_ext_CRT_sec
*)tgt_p
;
1766 pvtSec_p
->section_identifier
= CCA_PVT_EXT_CRT_SEC_ID_PVT
;
1767 pvtSec_p
->section_length
=
1768 sizeof(struct cca_pvt_ext_CRT_sec
) + keyPartsLen
;
1769 pvtSec_p
->key_format
= CCA_PVT_EXT_CRT_SEC_FMT_CL
;
1770 pvtSec_p
->key_use_flags
[0] = CCA_PVT_USAGE_ALL
;
1771 pvtSec_p
->p_len
= long_len
;
1772 pvtSec_p
->q_len
= short_len
;
1773 pvtSec_p
->dp_len
= long_len
;
1774 pvtSec_p
->dq_len
= short_len
;
1775 pvtSec_p
->u_len
= long_len
;
1776 pvtSec_p
->mod_len
= mod_len
;
1777 pvtSec_p
->pad_len
= pad_len
;
1778 tgt_p
+= sizeof(struct cca_pvt_ext_CRT_sec
);
1779 if (copy_from_user(tgt_p
, icaMsg_p
->np_prime
, long_len
))
1780 return SEN_RELEASED
;
1781 if (is_empty(tgt_p
, long_len
))
1782 return SEN_USER_ERROR
;
1784 if (copy_from_user(tgt_p
, icaMsg_p
->nq_prime
, short_len
))
1785 return SEN_RELEASED
;
1786 if (is_empty(tgt_p
, short_len
))
1787 return SEN_USER_ERROR
;
1789 if (copy_from_user(tgt_p
, icaMsg_p
->bp_key
, long_len
))
1790 return SEN_RELEASED
;
1791 if (is_empty(tgt_p
, long_len
))
1792 return SEN_USER_ERROR
;
1794 if (copy_from_user(tgt_p
, icaMsg_p
->bq_key
, short_len
))
1795 return SEN_RELEASED
;
1796 if (is_empty(tgt_p
, short_len
))
1797 return SEN_USER_ERROR
;
1799 if (copy_from_user(tgt_p
, icaMsg_p
->u_mult_inv
, long_len
))
1800 return SEN_RELEASED
;
1801 if (is_empty(tgt_p
, long_len
))
1802 return SEN_USER_ERROR
;
1805 memset(tgt_p
, 0xFF, mod_len
);
1807 memcpy(tgt_p
, &static_cca_pub_sec
, sizeof(struct cca_public_sec
));
1808 pubSec_p
= (struct cca_public_sec
*) tgt_p
;
1809 pubSec_p
->modulus_bit_len
= 8 * mod_len
;
1810 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
1816 ICAMEX_msg_to_type6MEX_msgX(struct ica_rsa_modexpo
*icaMsg_p
, int cdx
,
1817 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
,
1820 int mod_len
, exp_len
, vud_len
, tmp_size
, total_CPRB_len
, parmBlock_l
;
1822 unsigned char *temp_exp
, *tgt_p
, *temp
, *exp_p
;
1823 struct type6_hdr
*tp6Hdr_p
;
1824 struct CPRBX
*cprbx_p
;
1825 struct cca_public_key
*key_p
;
1826 struct T6_keyBlock_hdrX
*keyb_p
;
1828 temp_exp
= kmalloc(256, GFP_KERNEL
);
1831 mod_len
= icaMsg_p
->inputdatalength
;
1832 if (copy_from_user(temp_exp
, icaMsg_p
->b_key
, mod_len
)) {
1834 return SEN_RELEASED
;
1836 if (is_empty(temp_exp
, mod_len
)) {
1838 return SEN_USER_ERROR
;
1841 for (i
= 0; i
< mod_len
; i
++)
1846 return SEN_USER_ERROR
;
1848 exp_len
= mod_len
- i
;
1850 PDEBUG("exp_len after computation: %08x\n", exp_len
);
1851 tmp_size
= FIXED_TYPE6_ME_EN_LENX
+ 2 * mod_len
+ exp_len
;
1852 total_CPRB_len
= tmp_size
- sizeof(struct type6_hdr
);
1853 parmBlock_l
= total_CPRB_len
- sizeof(struct CPRBX
);
1854 tmp_size
= tmp_size
+ CALLER_HEADER
;
1855 vud_len
= 2 + mod_len
;
1856 memset(z90cMsg_p
, 0, tmp_size
);
1857 tgt_p
= (unsigned char *)z90cMsg_p
+ CALLER_HEADER
;
1858 memcpy(tgt_p
, &static_type6_hdrX
, sizeof(struct type6_hdr
));
1859 tp6Hdr_p
= (struct type6_hdr
*)tgt_p
;
1860 tp6Hdr_p
->ToCardLen1
= total_CPRB_len
;
1861 tp6Hdr_p
->FromCardLen1
= RESPONSE_CPRBX_SIZE
;
1862 memcpy(tp6Hdr_p
->function_code
, static_PKE_function_code
,
1863 sizeof(static_PKE_function_code
));
1864 tgt_p
+= sizeof(struct type6_hdr
);
1865 memcpy(tgt_p
, &static_cprbx
, sizeof(struct CPRBX
));
1866 cprbx_p
= (struct CPRBX
*) tgt_p
;
1867 cprbx_p
->domain
= (unsigned short)cdx
;
1868 cprbx_p
->rpl_msgbl
= RESPONSE_CPRBX_SIZE
;
1869 tgt_p
+= sizeof(struct CPRBX
);
1870 if (dev_type
== PCIXCC_MCL2
)
1871 memcpy(tgt_p
, &static_pke_function_and_rulesX_MCL2
,
1872 sizeof(struct function_and_rules_block
));
1874 memcpy(tgt_p
, &static_pke_function_and_rulesX
,
1875 sizeof(struct function_and_rules_block
));
1876 tgt_p
+= sizeof(struct function_and_rules_block
);
1879 if (copy_from_user(tgt_p
, icaMsg_p
->inputdata
, mod_len
)) {
1881 return SEN_RELEASED
;
1883 if (is_empty(tgt_p
, mod_len
)) {
1885 return SEN_USER_ERROR
;
1888 *((short *)tgt_p
) = (short) vud_len
;
1890 keyb_p
= (struct T6_keyBlock_hdrX
*)tgt_p
;
1891 tgt_p
+= sizeof(struct T6_keyBlock_hdrX
);
1892 memcpy(tgt_p
, &static_public_key
, sizeof(static_public_key
));
1893 key_p
= (struct cca_public_key
*)tgt_p
;
1894 temp
= key_p
->pubSec
.exponent
;
1895 memcpy(temp
, exp_p
, exp_len
);
1898 if (copy_from_user(temp
, icaMsg_p
->n_modulus
, mod_len
))
1899 return SEN_RELEASED
;
1900 if (is_empty(temp
, mod_len
))
1901 return SEN_USER_ERROR
;
1902 key_p
->pubSec
.modulus_bit_len
= 8 * mod_len
;
1903 key_p
->pubSec
.modulus_byte_len
= mod_len
;
1904 key_p
->pubSec
.exponent_len
= exp_len
;
1905 key_p
->pubSec
.section_length
= CALLER_HEADER
+ mod_len
+ exp_len
;
1906 key_len
= key_p
->pubSec
.section_length
+ sizeof(struct cca_token_hdr
);
1907 key_p
->pubHdr
.token_length
= key_len
;
1909 keyb_p
->ulen
= (unsigned short)key_len
;
1911 keyb_p
->blen
= (unsigned short)key_len
;
1912 cprbx_p
->req_parml
= parmBlock_l
;
1913 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
1919 ICACRT_msg_to_type6CRT_msgX(struct ica_rsa_modexpo_crt
*icaMsg_p
, int cdx
,
1920 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
,
1923 int mod_len
, vud_len
, tmp_size
, total_CPRB_len
, parmBlock_l
, short_len
;
1924 int long_len
, pad_len
, keyPartsLen
, tmp_l
;
1925 unsigned char *tgt_p
, *temp
;
1926 struct type6_hdr
*tp6Hdr_p
;
1927 struct CPRBX
*cprbx_p
;
1928 struct cca_token_hdr
*keyHdr_p
;
1929 struct cca_pvt_ext_CRT_sec
*pvtSec_p
;
1930 struct cca_public_sec
*pubSec_p
;
1932 mod_len
= icaMsg_p
->inputdatalength
;
1933 short_len
= mod_len
/ 2;
1934 long_len
= 8 + short_len
;
1935 keyPartsLen
= 3 * long_len
+ 2 * short_len
;
1936 pad_len
= (8 - (keyPartsLen
% 8)) % 8;
1937 keyPartsLen
+= pad_len
+ mod_len
;
1938 tmp_size
= FIXED_TYPE6_CR_LENX
+ keyPartsLen
+ mod_len
;
1939 total_CPRB_len
= tmp_size
- sizeof(struct type6_hdr
);
1940 parmBlock_l
= total_CPRB_len
- sizeof(struct CPRBX
);
1941 vud_len
= 2 + mod_len
;
1942 tmp_size
= tmp_size
+ CALLER_HEADER
;
1943 memset(z90cMsg_p
, 0, tmp_size
);
1944 tgt_p
= (unsigned char *)z90cMsg_p
+ CALLER_HEADER
;
1945 memcpy(tgt_p
, &static_type6_hdrX
, sizeof(struct type6_hdr
));
1946 tp6Hdr_p
= (struct type6_hdr
*)tgt_p
;
1947 tp6Hdr_p
->ToCardLen1
= total_CPRB_len
;
1948 tp6Hdr_p
->FromCardLen1
= RESPONSE_CPRBX_SIZE
;
1949 tgt_p
+= sizeof(struct type6_hdr
);
1950 cprbx_p
= (struct CPRBX
*) tgt_p
;
1951 memcpy(tgt_p
, &static_cprbx
, sizeof(struct CPRBX
));
1952 cprbx_p
->domain
= (unsigned short)cdx
;
1953 cprbx_p
->req_parml
= parmBlock_l
;
1954 cprbx_p
->rpl_msgbl
= parmBlock_l
;
1955 tgt_p
+= sizeof(struct CPRBX
);
1956 if (dev_type
== PCIXCC_MCL2
)
1957 memcpy(tgt_p
, &static_pkd_function_and_rulesX_MCL2
,
1958 sizeof(struct function_and_rules_block
));
1960 memcpy(tgt_p
, &static_pkd_function_and_rulesX
,
1961 sizeof(struct function_and_rules_block
));
1962 tgt_p
+= sizeof(struct function_and_rules_block
);
1963 *((short *)tgt_p
) = (short) vud_len
;
1965 if (copy_from_user(tgt_p
, icaMsg_p
->inputdata
, mod_len
))
1966 return SEN_RELEASED
;
1967 if (is_empty(tgt_p
, mod_len
))
1968 return SEN_USER_ERROR
;
1970 tmp_l
= sizeof(struct T6_keyBlock_hdr
) + sizeof(struct cca_token_hdr
) +
1971 sizeof(struct cca_pvt_ext_CRT_sec
) + 0x0F + keyPartsLen
;
1972 *((short *)tgt_p
) = (short) tmp_l
;
1975 *((short *)temp
) = (short) tmp_l
;
1976 tgt_p
+= sizeof(struct T6_keyBlock_hdr
);
1977 keyHdr_p
= (struct cca_token_hdr
*)tgt_p
;
1978 keyHdr_p
->token_identifier
= CCA_TKN_HDR_ID_EXT
;
1980 keyHdr_p
->token_length
= tmp_l
;
1981 tgt_p
+= sizeof(struct cca_token_hdr
);
1982 pvtSec_p
= (struct cca_pvt_ext_CRT_sec
*)tgt_p
;
1983 pvtSec_p
->section_identifier
= CCA_PVT_EXT_CRT_SEC_ID_PVT
;
1984 pvtSec_p
->section_length
=
1985 sizeof(struct cca_pvt_ext_CRT_sec
) + keyPartsLen
;
1986 pvtSec_p
->key_format
= CCA_PVT_EXT_CRT_SEC_FMT_CL
;
1987 pvtSec_p
->key_use_flags
[0] = CCA_PVT_USAGE_ALL
;
1988 pvtSec_p
->p_len
= long_len
;
1989 pvtSec_p
->q_len
= short_len
;
1990 pvtSec_p
->dp_len
= long_len
;
1991 pvtSec_p
->dq_len
= short_len
;
1992 pvtSec_p
->u_len
= long_len
;
1993 pvtSec_p
->mod_len
= mod_len
;
1994 pvtSec_p
->pad_len
= pad_len
;
1995 tgt_p
+= sizeof(struct cca_pvt_ext_CRT_sec
);
1996 if (copy_from_user(tgt_p
, icaMsg_p
->np_prime
, long_len
))
1997 return SEN_RELEASED
;
1998 if (is_empty(tgt_p
, long_len
))
1999 return SEN_USER_ERROR
;
2001 if (copy_from_user(tgt_p
, icaMsg_p
->nq_prime
, short_len
))
2002 return SEN_RELEASED
;
2003 if (is_empty(tgt_p
, short_len
))
2004 return SEN_USER_ERROR
;
2006 if (copy_from_user(tgt_p
, icaMsg_p
->bp_key
, long_len
))
2007 return SEN_RELEASED
;
2008 if (is_empty(tgt_p
, long_len
))
2009 return SEN_USER_ERROR
;
2011 if (copy_from_user(tgt_p
, icaMsg_p
->bq_key
, short_len
))
2012 return SEN_RELEASED
;
2013 if (is_empty(tgt_p
, short_len
))
2014 return SEN_USER_ERROR
;
2016 if (copy_from_user(tgt_p
, icaMsg_p
->u_mult_inv
, long_len
))
2017 return SEN_RELEASED
;
2018 if (is_empty(tgt_p
, long_len
))
2019 return SEN_USER_ERROR
;
2022 memset(tgt_p
, 0xFF, mod_len
);
2024 memcpy(tgt_p
, &static_cca_pub_sec
, sizeof(struct cca_public_sec
));
2025 pubSec_p
= (struct cca_public_sec
*) tgt_p
;
2026 pubSec_p
->modulus_bit_len
= 8 * mod_len
;
2027 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
2033 convert_request(unsigned char *buffer
, int func
, unsigned short function
,
2034 int cdx
, int dev_type
, int *msg_l_p
, unsigned char *msg_p
)
2036 if (dev_type
== PCICA
) {
2037 if (func
== ICARSACRT
)
2038 return ICACRT_msg_to_type4CRT_msg(
2039 (struct ica_rsa_modexpo_crt
*) buffer
,
2040 msg_l_p
, (union type4_msg
*) msg_p
);
2042 return ICAMEX_msg_to_type4MEX_msg(
2043 (struct ica_rsa_modexpo
*) buffer
,
2044 msg_l_p
, (union type4_msg
*) msg_p
);
2046 if (dev_type
== PCICC
) {
2047 if (func
== ICARSACRT
)
2048 return ICACRT_msg_to_type6CRT_msg(
2049 (struct ica_rsa_modexpo_crt
*) buffer
,
2050 cdx
, msg_l_p
, (struct type6_msg
*)msg_p
);
2051 if (function
== PCI_FUNC_KEY_ENCRYPT
)
2052 return ICAMEX_msg_to_type6MEX_en_msg(
2053 (struct ica_rsa_modexpo
*) buffer
,
2054 cdx
, msg_l_p
, (struct type6_msg
*) msg_p
);
2056 return ICAMEX_msg_to_type6MEX_de_msg(
2057 (struct ica_rsa_modexpo
*) buffer
,
2058 cdx
, msg_l_p
, (struct type6_msg
*) msg_p
);
2060 if ((dev_type
== PCIXCC_MCL2
) ||
2061 (dev_type
== PCIXCC_MCL3
) ||
2062 (dev_type
== CEX2C
)) {
2063 if (func
== ICARSACRT
)
2064 return ICACRT_msg_to_type6CRT_msgX(
2065 (struct ica_rsa_modexpo_crt
*) buffer
,
2066 cdx
, msg_l_p
, (struct type6_msg
*) msg_p
,
2069 return ICAMEX_msg_to_type6MEX_msgX(
2070 (struct ica_rsa_modexpo
*) buffer
,
2071 cdx
, msg_l_p
, (struct type6_msg
*) msg_p
,
2078 int ext_bitlens_msg_count
= 0;
2080 unset_ext_bitlens(void)
2082 if (!ext_bitlens_msg_count
) {
2083 PRINTK("Unable to use coprocessors for extended bitlengths. "
2084 "Using PCICAs (if present) for extended bitlengths. "
2085 "This is not an error.\n");
2086 ext_bitlens_msg_count
++;
2092 convert_response(unsigned char *response
, unsigned char *buffer
,
2093 int *respbufflen_p
, unsigned char *resp_buff
)
2095 struct ica_rsa_modexpo
*icaMsg_p
= (struct ica_rsa_modexpo
*) buffer
;
2096 struct error_hdr
*errh_p
= (struct error_hdr
*) response
;
2097 struct type84_hdr
*t84h_p
= (struct type84_hdr
*) response
;
2098 struct type86_fmt2_msg
*t86m_p
= (struct type86_fmt2_msg
*) response
;
2099 int reply_code
, service_rc
, service_rs
, src_l
;
2100 unsigned char *src_p
, *tgt_p
;
2101 struct CPRB
*cprb_p
;
2102 struct CPRBX
*cprbx_p
;
2109 switch (errh_p
->type
) {
2110 case TYPE82_RSP_CODE
:
2111 reply_code
= errh_p
->reply_code
;
2112 src_p
= (unsigned char *)errh_p
;
2113 PRINTK("Hardware error: Type %02X Message Header: "
2114 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
2116 src_p
[0], src_p
[1], src_p
[2], src_p
[3],
2117 src_p
[4], src_p
[5], src_p
[6], src_p
[7]);
2119 case TYPE84_RSP_CODE
:
2120 src_l
= icaMsg_p
->outputdatalength
;
2121 src_p
= response
+ (int)t84h_p
->len
- src_l
;
2123 case TYPE86_RSP_CODE
:
2124 reply_code
= t86m_p
->header
.reply_code
;
2125 if (reply_code
!= 0)
2127 cprb_p
= (struct CPRB
*)
2128 (response
+ sizeof(struct type86_fmt2_msg
));
2129 cprbx_p
= (struct CPRBX
*) cprb_p
;
2130 if (cprb_p
->cprb_ver_id
!= 0x02) {
2131 le2toI(cprb_p
->ccp_rtcode
, &service_rc
);
2132 if (service_rc
!= 0) {
2133 le2toI(cprb_p
->ccp_rscode
, &service_rs
);
2134 if ((service_rc
== 8) && (service_rs
== 66))
2135 PDEBUG("Bad block format on PCICC\n");
2136 else if ((service_rc
== 8) && (service_rs
== 65))
2137 PDEBUG("Probably an even modulus on "
2139 else if ((service_rc
== 8) && (service_rs
== 770)) {
2140 PDEBUG("Invalid key length on PCICC\n");
2141 unset_ext_bitlens();
2142 return REC_USE_PCICA
;
2144 else if ((service_rc
== 8) && (service_rs
== 783)) {
2145 PDEBUG("Extended bitlengths not enabled"
2147 unset_ext_bitlens();
2148 return REC_USE_PCICA
;
2151 PRINTK("service rc/rs (PCICC): %d/%d\n",
2152 service_rc
, service_rs
);
2153 return REC_OPERAND_INV
;
2155 src_p
= (unsigned char *)cprb_p
+ sizeof(struct CPRB
);
2157 le2toI(src_p
, &src_l
);
2161 service_rc
= (int)cprbx_p
->ccp_rtcode
;
2162 if (service_rc
!= 0) {
2163 service_rs
= (int) cprbx_p
->ccp_rscode
;
2164 if ((service_rc
== 8) && (service_rs
== 66))
2165 PDEBUG("Bad block format on PCIXCC\n");
2166 else if ((service_rc
== 8) && (service_rs
== 65))
2167 PDEBUG("Probably an even modulus on "
2169 else if ((service_rc
== 8) && (service_rs
== 770)) {
2170 PDEBUG("Invalid key length on PCIXCC\n");
2171 unset_ext_bitlens();
2172 return REC_USE_PCICA
;
2174 else if ((service_rc
== 8) && (service_rs
== 783)) {
2175 PDEBUG("Extended bitlengths not enabled"
2177 unset_ext_bitlens();
2178 return REC_USE_PCICA
;
2181 PRINTK("service rc/rs (PCIXCC): %d/%d\n",
2182 service_rc
, service_rs
);
2183 return REC_OPERAND_INV
;
2185 src_p
= (unsigned char *)
2186 cprbx_p
+ sizeof(struct CPRBX
);
2188 src_l
= (int)(*((short *) src_p
));
2194 src_p
= (unsigned char *)errh_p
;
2195 PRINTK("Unrecognized Message Header: "
2196 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
2197 src_p
[0], src_p
[1], src_p
[2], src_p
[3],
2198 src_p
[4], src_p
[5], src_p
[6], src_p
[7]);
2199 return REC_BAD_MESSAGE
;
2203 switch (reply_code
) {
2204 case REP82_ERROR_OPERAND_INVALID
:
2205 return REC_OPERAND_INV
;
2206 case REP82_ERROR_OPERAND_SIZE
:
2207 return REC_OPERAND_SIZE
;
2208 case REP82_ERROR_EVEN_MOD_IN_OPND
:
2209 return REC_EVEN_MOD
;
2210 case REP82_ERROR_MESSAGE_TYPE
:
2211 return WRONG_DEVICE_TYPE
;
2212 case REP82_ERROR_TRANSPORT_FAIL
:
2213 PRINTKW("Transport failed (APFS = %02X%02X%02X%02X)\n",
2214 t86m_p
->apfs
[0], t86m_p
->apfs
[1],
2215 t86m_p
->apfs
[2], t86m_p
->apfs
[3]);
2216 return REC_HARDWAR_ERR
;
2218 PRINTKW("reply code = %d\n", reply_code
);
2219 return REC_HARDWAR_ERR
;
2222 if (service_rc
!= 0)
2223 return REC_OPERAND_INV
;
2225 if ((src_l
> icaMsg_p
->outputdatalength
) ||
2226 (src_l
> RESPBUFFSIZE
) ||
2228 return REC_OPERAND_SIZE
;
2230 PDEBUG("Length returned = %d\n", src_l
);
2231 tgt_p
= resp_buff
+ icaMsg_p
->outputdatalength
- src_l
;
2232 memcpy(tgt_p
, src_p
, src_l
);
2233 if ((errh_p
->type
== TYPE86_RSP_CODE
) && (resp_buff
< tgt_p
)) {
2234 memset(resp_buff
, 0, icaMsg_p
->outputdatalength
- src_l
);
2235 if (pad_msg(resp_buff
, icaMsg_p
->outputdatalength
, src_l
))
2236 return REC_INVALID_PAD
;
2238 *respbufflen_p
= icaMsg_p
->outputdatalength
;
2239 if (*respbufflen_p
== 0)
2240 PRINTK("Zero *respbufflen_p\n");