2 * linux/drivers/s390/crypto/z90hardware.c
6 * Copyright (C) 2001, 2005 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
660 #define TYPE50_TYPE_CODE 0x50
662 #define TYPE50_MEB1_LEN (sizeof(struct type50_meb1_msg))
663 #define TYPE50_MEB2_LEN (sizeof(struct type50_meb2_msg))
664 #define TYPE50_CRB1_LEN (sizeof(struct type50_crb1_msg))
665 #define TYPE50_CRB2_LEN (sizeof(struct type50_crb2_msg))
667 #define TYPE50_MEB1_FMT 0x0001
668 #define TYPE50_MEB2_FMT 0x0002
669 #define TYPE50_CRB1_FMT 0x0011
670 #define TYPE50_CRB2_FMT 0x0012
672 struct type50_meb1_msg
{
673 struct type50_hdr header
;
681 struct type50_meb2_msg
{
682 struct type50_hdr header
;
690 struct type50_crb1_msg
{
691 struct type50_hdr header
;
702 struct type50_crb2_msg
{
703 struct type50_hdr header
;
715 struct type50_meb1_msg meb1
;
716 struct type50_meb2_msg meb2
;
717 struct type50_crb1_msg crb1
;
718 struct type50_crb2_msg crb2
;
730 #define TYPE80_RSP_CODE 0x80
733 unsigned char reserved1
;
735 unsigned char reserved2
[2];
736 unsigned char reply_code
;
737 unsigned char reserved3
[3];
740 #define TYPE82_RSP_CODE 0x82
741 #define TYPE88_RSP_CODE 0x88
743 #define REP82_ERROR_MACHINE_FAILURE 0x10
744 #define REP82_ERROR_PREEMPT_FAILURE 0x12
745 #define REP82_ERROR_CHECKPT_FAILURE 0x14
746 #define REP82_ERROR_MESSAGE_TYPE 0x20
747 #define REP82_ERROR_INVALID_COMM_CD 0x21
748 #define REP82_ERROR_INVALID_MSG_LEN 0x23
749 #define REP82_ERROR_RESERVD_FIELD 0x24
750 #define REP82_ERROR_FORMAT_FIELD 0x29
751 #define REP82_ERROR_INVALID_COMMAND 0x30
752 #define REP82_ERROR_MALFORMED_MSG 0x40
753 #define REP82_ERROR_RESERVED_FIELDO 0x50
754 #define REP82_ERROR_WORD_ALIGNMENT 0x60
755 #define REP82_ERROR_MESSAGE_LENGTH 0x80
756 #define REP82_ERROR_OPERAND_INVALID 0x82
757 #define REP82_ERROR_OPERAND_SIZE 0x84
758 #define REP82_ERROR_EVEN_MOD_IN_OPND 0x85
759 #define REP82_ERROR_RESERVED_FIELD 0x88
760 #define REP82_ERROR_TRANSPORT_FAIL 0x90
761 #define REP82_ERROR_PACKET_TRUNCATED 0xA0
762 #define REP82_ERROR_ZERO_BUFFER_LEN 0xB0
764 #define REP88_ERROR_MODULE_FAILURE 0x10
765 #define REP88_ERROR_MODULE_TIMEOUT 0x11
766 #define REP88_ERROR_MODULE_NOTINIT 0x13
767 #define REP88_ERROR_MODULE_NOTAVAIL 0x14
768 #define REP88_ERROR_MODULE_DISABLED 0x15
769 #define REP88_ERROR_MODULE_IN_DIAGN 0x17
770 #define REP88_ERROR_FASTPATH_DISABLD 0x19
771 #define REP88_ERROR_MESSAGE_TYPE 0x20
772 #define REP88_ERROR_MESSAGE_MALFORMD 0x22
773 #define REP88_ERROR_MESSAGE_LENGTH 0x23
774 #define REP88_ERROR_RESERVED_FIELD 0x24
775 #define REP88_ERROR_KEY_TYPE 0x34
776 #define REP88_ERROR_INVALID_KEY 0x82
777 #define REP88_ERROR_OPERAND 0x84
778 #define REP88_ERROR_OPERAND_EVEN_MOD 0x85
780 #define CALLER_HEADER 12
783 testq(int q_nr
, int *q_depth
, int *dev_type
, struct ap_status_word
*stat
)
792 "0: .long 0xb2af0000 \n"
804 ".section .fixup,\"ax\" \n"
809 ".section __ex_table,\"a\" \n"
814 :"=d" (ccode
),"=d" (*stat
),"=d" (*q_depth
), "=d" (*dev_type
)
815 :"d" (q_nr
), "K" (DEV_TSQ_EXCEPTION
)
816 :"cc","0","1","2","memory");
821 "0: .long 0xb2af0000 \n"
831 ".section .fixup,\"ax\" \n"
840 ".section __ex_table,\"a\" \n"
845 :"=d" (ccode
),"=d" (*stat
),"=d" (*q_depth
), "=d" (*dev_type
)
846 :"d" (q_nr
), "K" (DEV_TSQ_EXCEPTION
)
847 :"cc","0","1","2","memory");
853 resetq(int q_nr
, struct ap_status_word
*stat_p
)
865 "0: .long 0xb2af0000 \n"
872 ".section .fixup,\"ax\" \n"
877 ".section __ex_table,\"a\" \n"
882 :"=d" (ccode
),"=d" (*stat_p
)
883 :"d" (q_nr
), "K" (DEV_RSQ_EXCEPTION
)
884 :"cc","0","1","2","memory");
892 "0: .long 0xb2af0000 \n"
897 ".section .fixup,\"ax\" \n"
906 ".section __ex_table,\"a\" \n"
911 :"=d" (ccode
),"=d" (*stat_p
)
912 :"d" (q_nr
), "K" (DEV_RSQ_EXCEPTION
)
913 :"cc","0","1","2","memory");
919 sen(int msg_len
, unsigned char *msg_ext
, struct ap_status_word
*stat
)
936 "0: .long 0xb2ad0026 \n"
944 ".section .fixup,\"ax\" \n"
949 ".section __ex_table,\"a\" \n"
954 :"=d" (ccode
),"=d" (*stat
)
955 :"d" (msg_len
),"a" (msg_ext
), "K" (DEV_SEN_EXCEPTION
)
956 :"cc","0","1","2","3","6","7","memory");
969 "0: .long 0xb2ad0026 \n"
975 ".section .fixup,\"ax\" \n"
984 ".section __ex_table,\"a\" \n"
989 :"=d" (ccode
),"=d" (*stat
)
990 :"d" (msg_len
),"a" (msg_ext
), "K" (DEV_SEN_EXCEPTION
)
991 :"cc","0","1","2","3","6","7","memory");
997 rec(int q_nr
, int buff_l
, unsigned char *rsp
, unsigned char *id
,
998 struct ap_status_word
*st
)
1015 "0: .long 0xb2ae0046 \n"
1026 ".section .fixup,\"ax\" \n"
1031 ".section __ex_table,\"a\" \n"
1036 :"=d"(ccode
),"=d"(*st
)
1037 :"d" (q_nr
), "d" (rsp
), "d" (id
), "d" (buff_l
), "K" (DEV_REC_EXCEPTION
)
1038 :"cc","0","1","2","3","4","5","6","7","memory");
1051 "0: .long 0xb2ae0046 \n"
1060 ".section .fixup,\"ax\" \n"
1069 ".section __ex_table,\"a\" \n"
1074 :"=d"(ccode
),"=d"(*st
)
1075 :"d" (q_nr
), "d" (rsp
), "d" (id
), "d" (buff_l
), "K" (DEV_REC_EXCEPTION
)
1076 :"cc","0","1","2","3","4","5","6","7","memory");
1082 itoLe2(int *i_p
, unsigned char *lechars
)
1084 *lechars
= *((unsigned char *) i_p
+ sizeof(int) - 1);
1085 *(lechars
+ 1) = *((unsigned char *) i_p
+ sizeof(int) - 2);
1089 le2toI(unsigned char *lechars
, int *i_p
)
1091 unsigned char *ic_p
;
1093 ic_p
= (unsigned char *) i_p
;
1094 *(ic_p
+ 2) = *(lechars
+ 1);
1095 *(ic_p
+ 3) = *(lechars
);
1099 is_empty(unsigned char *ptr
, int len
)
1101 return !memcmp(ptr
, (unsigned char *) &static_pvt_me_key
+60, len
);
1105 query_online(int deviceNr
, int cdx
, int resetNr
, int *q_depth
, int *dev_type
)
1107 int q_nr
, i
, t_depth
, t_dev_type
;
1109 struct ap_status_word stat_word
;
1113 q_nr
= (deviceNr
<< SKIP_BITL
) + cdx
;
1115 ccode
= testq(q_nr
, &t_depth
, &t_dev_type
, &stat_word
);
1116 PDEBUG("ccode %d response_code %02X\n", ccode
, stat_word
.response_code
);
1118 for (i
= 0; i
< resetNr
; i
++) {
1120 PRINTKC("Exception testing device %d\n", i
);
1121 return HD_TSQ_EXCEPTION
;
1125 PDEBUG("t_dev_type %d\n", t_dev_type
);
1128 *q_depth
= t_depth
+ 1;
1129 switch (t_dev_type
) {
1137 *dev_type
= PCIXCC_UNK
;
1149 PDEBUG("available device %d: Q depth = %d, dev "
1150 "type = %d, stat = %02X%02X%02X%02X\n",
1151 deviceNr
, *q_depth
, *dev_type
,
1152 stat_word
.q_stat_flags
,
1153 stat_word
.response_code
,
1154 stat_word
.reserved
[0],
1155 stat_word
.reserved
[1]);
1158 switch (stat_word
.response_code
) {
1159 case AP_RESPONSE_NORMAL
:
1162 *q_depth
= t_depth
+ 1;
1163 *dev_type
= t_dev_type
;
1164 PDEBUG("cc3, available device "
1165 "%d: Q depth = %d, dev "
1166 "type = %d, stat = "
1167 "%02X%02X%02X%02X\n",
1170 stat_word
.q_stat_flags
,
1171 stat_word
.response_code
,
1172 stat_word
.reserved
[0],
1173 stat_word
.reserved
[1]);
1175 case AP_RESPONSE_Q_NOT_AVAIL
:
1176 stat
= HD_NOT_THERE
;
1179 case AP_RESPONSE_RESET_IN_PROGRESS
:
1180 PDEBUG("device %d in reset\n",
1183 case AP_RESPONSE_DECONFIGURED
:
1184 stat
= HD_DECONFIGURED
;
1187 case AP_RESPONSE_CHECKSTOPPED
:
1188 stat
= HD_CHECKSTOPPED
;
1191 case AP_RESPONSE_BUSY
:
1192 PDEBUG("device %d busy\n",
1200 stat
= HD_NOT_THERE
;
1209 ccode
= testq(q_nr
, &t_depth
, &t_dev_type
, &stat_word
);
1215 reset_device(int deviceNr
, int cdx
, int resetNr
)
1217 int q_nr
, ccode
= 0, dummy_qdepth
, dummy_devType
, i
;
1218 struct ap_status_word stat_word
;
1222 q_nr
= (deviceNr
<< SKIP_BITL
) + cdx
;
1224 ccode
= resetq(q_nr
, &stat_word
);
1226 return DEV_RSQ_EXCEPTION
;
1229 for (i
= 0; i
< resetNr
; i
++) {
1233 if (stat_word
.q_stat_flags
& AP_Q_STATUS_EMPTY
)
1237 switch (stat_word
.response_code
) {
1238 case AP_RESPONSE_NORMAL
:
1240 if (stat_word
.q_stat_flags
& AP_Q_STATUS_EMPTY
)
1243 case AP_RESPONSE_Q_NOT_AVAIL
:
1244 case AP_RESPONSE_DECONFIGURED
:
1245 case AP_RESPONSE_CHECKSTOPPED
:
1249 case AP_RESPONSE_RESET_IN_PROGRESS
:
1250 case AP_RESPONSE_BUSY
:
1264 ccode
= testq(q_nr
, &dummy_qdepth
, &dummy_devType
, &stat_word
);
1266 stat
= DEV_TSQ_EXCEPTION
;
1270 PDEBUG("Number of testq's needed for reset: %d\n", i
);
1279 #ifdef DEBUG_HYDRA_MSGS
1281 print_buffer(unsigned char *buffer
, int bufflen
)
1284 for (i
= 0; i
< bufflen
; i
+= 16) {
1285 PRINTK("%04X: %02X%02X%02X%02X %02X%02X%02X%02X "
1286 "%02X%02X%02X%02X %02X%02X%02X%02X\n", i
,
1287 buffer
[i
+0], buffer
[i
+1], buffer
[i
+2], buffer
[i
+3],
1288 buffer
[i
+4], buffer
[i
+5], buffer
[i
+6], buffer
[i
+7],
1289 buffer
[i
+8], buffer
[i
+9], buffer
[i
+10], buffer
[i
+11],
1290 buffer
[i
+12], buffer
[i
+13], buffer
[i
+14], buffer
[i
+15]);
1296 send_to_AP(int dev_nr
, int cdx
, int msg_len
, unsigned char *msg_ext
)
1298 struct ap_status_word stat_word
;
1301 u32
*q_nr_p
= (u32
*)msg_ext
;
1303 *q_nr_p
= (dev_nr
<< SKIP_BITL
) + cdx
;
1304 PDEBUG("msg_len passed to sen: %d\n", msg_len
);
1305 PDEBUG("q number passed to sen: %02x%02x%02x%02x\n",
1306 msg_ext
[0], msg_ext
[1], msg_ext
[2], msg_ext
[3]);
1309 #ifdef DEBUG_HYDRA_MSGS
1310 PRINTK("Request header: %02X%02X%02X%02X %02X%02X%02X%02X "
1311 "%02X%02X%02X%02X\n",
1312 msg_ext
[0], msg_ext
[1], msg_ext
[2], msg_ext
[3],
1313 msg_ext
[4], msg_ext
[5], msg_ext
[6], msg_ext
[7],
1314 msg_ext
[8], msg_ext
[9], msg_ext
[10], msg_ext
[11]);
1315 print_buffer(msg_ext
+CALLER_HEADER
, msg_len
);
1318 ccode
= sen(msg_len
, msg_ext
, &stat_word
);
1320 return DEV_SEN_EXCEPTION
;
1322 PDEBUG("nq cc: %u, st: %02x%02x%02x%02x\n",
1323 ccode
, stat_word
.q_stat_flags
, stat_word
.response_code
,
1324 stat_word
.reserved
[0], stat_word
.reserved
[1]);
1333 switch (stat_word
.response_code
) {
1334 case AP_RESPONSE_NORMAL
:
1337 case AP_RESPONSE_Q_FULL
:
1338 stat
= DEV_QUEUE_FULL
;
1354 receive_from_AP(int dev_nr
, int cdx
, int resplen
, unsigned char *resp
,
1355 unsigned char *psmid
)
1358 struct ap_status_word stat_word
;
1361 memset(resp
, 0x00, 8);
1363 ccode
= rec((dev_nr
<< SKIP_BITL
) + cdx
, resplen
, resp
, psmid
,
1366 return DEV_REC_EXCEPTION
;
1368 PDEBUG("dq cc: %u, st: %02x%02x%02x%02x\n",
1369 ccode
, stat_word
.q_stat_flags
, stat_word
.response_code
,
1370 stat_word
.reserved
[0], stat_word
.reserved
[1]);
1376 #ifdef DEBUG_HYDRA_MSGS
1377 print_buffer(resp
, resplen
);
1381 switch (stat_word
.response_code
) {
1382 case AP_RESPONSE_NORMAL
:
1385 case AP_RESPONSE_NO_PENDING_REPLY
:
1386 if (stat_word
.q_stat_flags
& AP_Q_STATUS_EMPTY
)
1391 case AP_RESPONSE_INDEX_TOO_BIG
:
1392 case AP_RESPONSE_NO_FIRST_PART
:
1393 case AP_RESPONSE_MESSAGE_TOO_BIG
:
1394 stat
= DEV_BAD_MESSAGE
;
1408 pad_msg(unsigned char *buffer
, int totalLength
, int msgLength
)
1412 for (pad_len
= 0; pad_len
< (totalLength
- msgLength
); pad_len
++)
1413 if (buffer
[pad_len
] != 0x00)
1417 return SEN_PAD_ERROR
;
1422 memcpy(buffer
+2, static_pad
, pad_len
);
1424 buffer
[pad_len
+ 2] = 0x00;
1430 is_common_public_key(unsigned char *key
, int len
)
1434 for (i
= 0; i
< len
; i
++)
1439 if (((len
== 1) && (key
[0] == 3)) ||
1440 ((len
== 3) && (key
[0] == 1) && (key
[1] == 0) && (key
[2] == 1)))
1447 ICAMEX_msg_to_type4MEX_msg(struct ica_rsa_modexpo
*icaMex_p
, int *z90cMsg_l_p
,
1448 union type4_msg
*z90cMsg_p
)
1450 int mod_len
, msg_size
, mod_tgt_len
, exp_tgt_len
, inp_tgt_len
;
1451 unsigned char *mod_tgt
, *exp_tgt
, *inp_tgt
;
1452 union type4_msg
*tmp_type4_msg
;
1454 mod_len
= icaMex_p
->inputdatalength
;
1456 msg_size
= ((mod_len
<= 128) ? TYPE4_SME_LEN
: TYPE4_LME_LEN
) +
1459 memset(z90cMsg_p
, 0, msg_size
);
1461 tmp_type4_msg
= (union type4_msg
*)
1462 ((unsigned char *) z90cMsg_p
+ CALLER_HEADER
);
1464 tmp_type4_msg
->sme
.header
.msg_type_code
= TYPE4_TYPE_CODE
;
1465 tmp_type4_msg
->sme
.header
.request_code
= TYPE4_REQU_CODE
;
1467 if (mod_len
<= 128) {
1468 tmp_type4_msg
->sme
.header
.msg_fmt
= TYPE4_SME_FMT
;
1469 tmp_type4_msg
->sme
.header
.msg_len
= TYPE4_SME_LEN
;
1470 mod_tgt
= tmp_type4_msg
->sme
.modulus
;
1471 mod_tgt_len
= sizeof(tmp_type4_msg
->sme
.modulus
);
1472 exp_tgt
= tmp_type4_msg
->sme
.exponent
;
1473 exp_tgt_len
= sizeof(tmp_type4_msg
->sme
.exponent
);
1474 inp_tgt
= tmp_type4_msg
->sme
.message
;
1475 inp_tgt_len
= sizeof(tmp_type4_msg
->sme
.message
);
1477 tmp_type4_msg
->lme
.header
.msg_fmt
= TYPE4_LME_FMT
;
1478 tmp_type4_msg
->lme
.header
.msg_len
= TYPE4_LME_LEN
;
1479 mod_tgt
= tmp_type4_msg
->lme
.modulus
;
1480 mod_tgt_len
= sizeof(tmp_type4_msg
->lme
.modulus
);
1481 exp_tgt
= tmp_type4_msg
->lme
.exponent
;
1482 exp_tgt_len
= sizeof(tmp_type4_msg
->lme
.exponent
);
1483 inp_tgt
= tmp_type4_msg
->lme
.message
;
1484 inp_tgt_len
= sizeof(tmp_type4_msg
->lme
.message
);
1487 mod_tgt
+= (mod_tgt_len
- mod_len
);
1488 if (copy_from_user(mod_tgt
, icaMex_p
->n_modulus
, mod_len
))
1489 return SEN_RELEASED
;
1490 if (is_empty(mod_tgt
, mod_len
))
1491 return SEN_USER_ERROR
;
1492 exp_tgt
+= (exp_tgt_len
- mod_len
);
1493 if (copy_from_user(exp_tgt
, icaMex_p
->b_key
, mod_len
))
1494 return SEN_RELEASED
;
1495 if (is_empty(exp_tgt
, mod_len
))
1496 return SEN_USER_ERROR
;
1497 inp_tgt
+= (inp_tgt_len
- mod_len
);
1498 if (copy_from_user(inp_tgt
, icaMex_p
->inputdata
, mod_len
))
1499 return SEN_RELEASED
;
1500 if (is_empty(inp_tgt
, mod_len
))
1501 return SEN_USER_ERROR
;
1503 *z90cMsg_l_p
= msg_size
- CALLER_HEADER
;
1509 ICACRT_msg_to_type4CRT_msg(struct ica_rsa_modexpo_crt
*icaMsg_p
,
1510 int *z90cMsg_l_p
, union type4_msg
*z90cMsg_p
)
1512 int mod_len
, short_len
, long_len
, tmp_size
, p_tgt_len
, q_tgt_len
,
1513 dp_tgt_len
, dq_tgt_len
, u_tgt_len
, inp_tgt_len
;
1514 unsigned char *p_tgt
, *q_tgt
, *dp_tgt
, *dq_tgt
, *u_tgt
, *inp_tgt
;
1515 union type4_msg
*tmp_type4_msg
;
1517 mod_len
= icaMsg_p
->inputdatalength
;
1518 short_len
= mod_len
/ 2;
1519 long_len
= mod_len
/ 2 + 8;
1521 tmp_size
= ((mod_len
<= 128) ? TYPE4_SCR_LEN
: TYPE4_LCR_LEN
) +
1524 memset(z90cMsg_p
, 0, tmp_size
);
1526 tmp_type4_msg
= (union type4_msg
*)
1527 ((unsigned char *) z90cMsg_p
+ CALLER_HEADER
);
1529 tmp_type4_msg
->scr
.header
.msg_type_code
= TYPE4_TYPE_CODE
;
1530 tmp_type4_msg
->scr
.header
.request_code
= TYPE4_REQU_CODE
;
1531 if (mod_len
<= 128) {
1532 tmp_type4_msg
->scr
.header
.msg_fmt
= TYPE4_SCR_FMT
;
1533 tmp_type4_msg
->scr
.header
.msg_len
= TYPE4_SCR_LEN
;
1534 p_tgt
= tmp_type4_msg
->scr
.p
;
1535 p_tgt_len
= sizeof(tmp_type4_msg
->scr
.p
);
1536 q_tgt
= tmp_type4_msg
->scr
.q
;
1537 q_tgt_len
= sizeof(tmp_type4_msg
->scr
.q
);
1538 dp_tgt
= tmp_type4_msg
->scr
.dp
;
1539 dp_tgt_len
= sizeof(tmp_type4_msg
->scr
.dp
);
1540 dq_tgt
= tmp_type4_msg
->scr
.dq
;
1541 dq_tgt_len
= sizeof(tmp_type4_msg
->scr
.dq
);
1542 u_tgt
= tmp_type4_msg
->scr
.u
;
1543 u_tgt_len
= sizeof(tmp_type4_msg
->scr
.u
);
1544 inp_tgt
= tmp_type4_msg
->scr
.message
;
1545 inp_tgt_len
= sizeof(tmp_type4_msg
->scr
.message
);
1547 tmp_type4_msg
->lcr
.header
.msg_fmt
= TYPE4_LCR_FMT
;
1548 tmp_type4_msg
->lcr
.header
.msg_len
= TYPE4_LCR_LEN
;
1549 p_tgt
= tmp_type4_msg
->lcr
.p
;
1550 p_tgt_len
= sizeof(tmp_type4_msg
->lcr
.p
);
1551 q_tgt
= tmp_type4_msg
->lcr
.q
;
1552 q_tgt_len
= sizeof(tmp_type4_msg
->lcr
.q
);
1553 dp_tgt
= tmp_type4_msg
->lcr
.dp
;
1554 dp_tgt_len
= sizeof(tmp_type4_msg
->lcr
.dp
);
1555 dq_tgt
= tmp_type4_msg
->lcr
.dq
;
1556 dq_tgt_len
= sizeof(tmp_type4_msg
->lcr
.dq
);
1557 u_tgt
= tmp_type4_msg
->lcr
.u
;
1558 u_tgt_len
= sizeof(tmp_type4_msg
->lcr
.u
);
1559 inp_tgt
= tmp_type4_msg
->lcr
.message
;
1560 inp_tgt_len
= sizeof(tmp_type4_msg
->lcr
.message
);
1563 p_tgt
+= (p_tgt_len
- long_len
);
1564 if (copy_from_user(p_tgt
, icaMsg_p
->np_prime
, long_len
))
1565 return SEN_RELEASED
;
1566 if (is_empty(p_tgt
, long_len
))
1567 return SEN_USER_ERROR
;
1568 q_tgt
+= (q_tgt_len
- short_len
);
1569 if (copy_from_user(q_tgt
, icaMsg_p
->nq_prime
, short_len
))
1570 return SEN_RELEASED
;
1571 if (is_empty(q_tgt
, short_len
))
1572 return SEN_USER_ERROR
;
1573 dp_tgt
+= (dp_tgt_len
- long_len
);
1574 if (copy_from_user(dp_tgt
, icaMsg_p
->bp_key
, long_len
))
1575 return SEN_RELEASED
;
1576 if (is_empty(dp_tgt
, long_len
))
1577 return SEN_USER_ERROR
;
1578 dq_tgt
+= (dq_tgt_len
- short_len
);
1579 if (copy_from_user(dq_tgt
, icaMsg_p
->bq_key
, short_len
))
1580 return SEN_RELEASED
;
1581 if (is_empty(dq_tgt
, short_len
))
1582 return SEN_USER_ERROR
;
1583 u_tgt
+= (u_tgt_len
- long_len
);
1584 if (copy_from_user(u_tgt
, icaMsg_p
->u_mult_inv
, long_len
))
1585 return SEN_RELEASED
;
1586 if (is_empty(u_tgt
, long_len
))
1587 return SEN_USER_ERROR
;
1588 inp_tgt
+= (inp_tgt_len
- mod_len
);
1589 if (copy_from_user(inp_tgt
, icaMsg_p
->inputdata
, mod_len
))
1590 return SEN_RELEASED
;
1591 if (is_empty(inp_tgt
, mod_len
))
1592 return SEN_USER_ERROR
;
1594 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
1600 ICAMEX_msg_to_type6MEX_de_msg(struct ica_rsa_modexpo
*icaMsg_p
, int cdx
,
1601 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
)
1603 int mod_len
, vud_len
, tmp_size
, total_CPRB_len
, parmBlock_l
;
1604 unsigned char *temp
;
1605 struct type6_hdr
*tp6Hdr_p
;
1606 struct CPRB
*cprb_p
;
1607 struct cca_private_ext_ME
*key_p
;
1608 static int deprecated_msg_count
= 0;
1610 mod_len
= icaMsg_p
->inputdatalength
;
1611 tmp_size
= FIXED_TYPE6_ME_LEN
+ mod_len
;
1612 total_CPRB_len
= tmp_size
- sizeof(struct type6_hdr
);
1613 parmBlock_l
= total_CPRB_len
- sizeof(struct CPRB
);
1614 tmp_size
= 4*((tmp_size
+ 3)/4) + CALLER_HEADER
;
1616 memset(z90cMsg_p
, 0, tmp_size
);
1618 temp
= (unsigned char *)z90cMsg_p
+ CALLER_HEADER
;
1619 memcpy(temp
, &static_type6_hdr
, sizeof(struct type6_hdr
));
1620 tp6Hdr_p
= (struct type6_hdr
*)temp
;
1621 tp6Hdr_p
->ToCardLen1
= 4*((total_CPRB_len
+3)/4);
1622 tp6Hdr_p
->FromCardLen1
= RESPONSE_CPRB_SIZE
;
1624 temp
+= sizeof(struct type6_hdr
);
1625 memcpy(temp
, &static_cprb
, sizeof(struct CPRB
));
1626 cprb_p
= (struct CPRB
*) temp
;
1627 cprb_p
->usage_domain
[0]= (unsigned char)cdx
;
1628 itoLe2(&parmBlock_l
, cprb_p
->req_parml
);
1629 itoLe2((int *)&(tp6Hdr_p
->FromCardLen1
), cprb_p
->rpl_parml
);
1631 temp
+= sizeof(struct CPRB
);
1632 memcpy(temp
, &static_pkd_function_and_rules
,
1633 sizeof(struct function_and_rules_block
));
1635 temp
+= sizeof(struct function_and_rules_block
);
1636 vud_len
= 2 + icaMsg_p
->inputdatalength
;
1637 itoLe2(&vud_len
, temp
);
1640 if (copy_from_user(temp
, icaMsg_p
->inputdata
, mod_len
))
1641 return SEN_RELEASED
;
1642 if (is_empty(temp
, mod_len
))
1643 return SEN_USER_ERROR
;
1646 memcpy(temp
, &static_T6_keyBlock_hdr
, sizeof(struct T6_keyBlock_hdr
));
1648 temp
+= sizeof(struct T6_keyBlock_hdr
);
1649 memcpy(temp
, &static_pvt_me_key
, sizeof(struct cca_private_ext_ME
));
1650 key_p
= (struct cca_private_ext_ME
*)temp
;
1651 temp
= key_p
->pvtMESec
.exponent
+ sizeof(key_p
->pvtMESec
.exponent
)
1653 if (copy_from_user(temp
, icaMsg_p
->b_key
, mod_len
))
1654 return SEN_RELEASED
;
1655 if (is_empty(temp
, mod_len
))
1656 return SEN_USER_ERROR
;
1658 if (is_common_public_key(temp
, mod_len
)) {
1659 if (deprecated_msg_count
< 20) {
1660 PRINTK("Common public key used for modex decrypt\n");
1661 deprecated_msg_count
++;
1662 if (deprecated_msg_count
== 20)
1663 PRINTK("No longer issuing messages about common"
1664 " public key for modex decrypt.\n");
1666 return SEN_NOT_AVAIL
;
1669 temp
= key_p
->pvtMESec
.modulus
+ sizeof(key_p
->pvtMESec
.modulus
)
1671 if (copy_from_user(temp
, icaMsg_p
->n_modulus
, mod_len
))
1672 return SEN_RELEASED
;
1673 if (is_empty(temp
, mod_len
))
1674 return SEN_USER_ERROR
;
1676 key_p
->pubMESec
.modulus_bit_len
= 8 * mod_len
;
1678 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
1684 ICAMEX_msg_to_type6MEX_en_msg(struct ica_rsa_modexpo
*icaMsg_p
, int cdx
,
1685 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
)
1687 int mod_len
, vud_len
, exp_len
, key_len
;
1688 int pad_len
, tmp_size
, total_CPRB_len
, parmBlock_l
, i
;
1689 unsigned char *temp_exp
, *exp_p
, *temp
;
1690 struct type6_hdr
*tp6Hdr_p
;
1691 struct CPRB
*cprb_p
;
1692 struct cca_public_key
*key_p
;
1693 struct T6_keyBlock_hdr
*keyb_p
;
1695 temp_exp
= kmalloc(256, GFP_KERNEL
);
1698 mod_len
= icaMsg_p
->inputdatalength
;
1699 if (copy_from_user(temp_exp
, icaMsg_p
->b_key
, mod_len
)) {
1701 return SEN_RELEASED
;
1703 if (is_empty(temp_exp
, mod_len
)) {
1705 return SEN_USER_ERROR
;
1709 for (i
= 0; i
< mod_len
; i
++)
1714 return SEN_USER_ERROR
;
1717 exp_len
= mod_len
- i
;
1720 PDEBUG("exp_len after computation: %08x\n", exp_len
);
1721 tmp_size
= FIXED_TYPE6_ME_EN_LEN
+ 2 * mod_len
+ exp_len
;
1722 total_CPRB_len
= tmp_size
- sizeof(struct type6_hdr
);
1723 parmBlock_l
= total_CPRB_len
- sizeof(struct CPRB
);
1724 tmp_size
= 4*((tmp_size
+ 3)/4) + CALLER_HEADER
;
1726 vud_len
= 2 + mod_len
;
1727 memset(z90cMsg_p
, 0, tmp_size
);
1729 temp
= (unsigned char *)z90cMsg_p
+ CALLER_HEADER
;
1730 memcpy(temp
, &static_type6_hdr
, sizeof(struct type6_hdr
));
1731 tp6Hdr_p
= (struct type6_hdr
*)temp
;
1732 tp6Hdr_p
->ToCardLen1
= 4*((total_CPRB_len
+3)/4);
1733 tp6Hdr_p
->FromCardLen1
= RESPONSE_CPRB_SIZE
;
1734 memcpy(tp6Hdr_p
->function_code
, static_PKE_function_code
,
1735 sizeof(static_PKE_function_code
));
1736 temp
+= sizeof(struct type6_hdr
);
1737 memcpy(temp
, &static_cprb
, sizeof(struct CPRB
));
1738 cprb_p
= (struct CPRB
*) temp
;
1739 cprb_p
->usage_domain
[0]= (unsigned char)cdx
;
1740 itoLe2((int *)&(tp6Hdr_p
->FromCardLen1
), cprb_p
->rpl_parml
);
1741 temp
+= sizeof(struct CPRB
);
1742 memcpy(temp
, &static_pke_function_and_rules
,
1743 sizeof(struct function_and_rules_block
));
1744 temp
+= sizeof(struct function_and_rules_block
);
1746 if (copy_from_user(temp
, icaMsg_p
->inputdata
, mod_len
)) {
1748 return SEN_RELEASED
;
1750 if (is_empty(temp
, mod_len
)) {
1752 return SEN_USER_ERROR
;
1754 if ((temp
[0] != 0x00) || (temp
[1] != 0x02)) {
1756 return SEN_NOT_AVAIL
;
1758 for (i
= 2; i
< mod_len
; i
++)
1759 if (temp
[i
] == 0x00)
1761 if ((i
< 9) || (i
> (mod_len
- 2))) {
1763 return SEN_NOT_AVAIL
;
1766 vud_len
= mod_len
- pad_len
;
1767 memmove(temp
, temp
+pad_len
, vud_len
);
1770 itoLe2(&vud_len
, temp
);
1772 keyb_p
= (struct T6_keyBlock_hdr
*)temp
;
1773 temp
+= sizeof(struct T6_keyBlock_hdr
);
1774 memcpy(temp
, &static_public_key
, sizeof(static_public_key
));
1775 key_p
= (struct cca_public_key
*)temp
;
1776 temp
= key_p
->pubSec
.exponent
;
1777 memcpy(temp
, exp_p
, exp_len
);
1780 if (copy_from_user(temp
, icaMsg_p
->n_modulus
, mod_len
))
1781 return SEN_RELEASED
;
1782 if (is_empty(temp
, mod_len
))
1783 return SEN_USER_ERROR
;
1784 key_p
->pubSec
.modulus_bit_len
= 8 * mod_len
;
1785 key_p
->pubSec
.modulus_byte_len
= mod_len
;
1786 key_p
->pubSec
.exponent_len
= exp_len
;
1787 key_p
->pubSec
.section_length
= CALLER_HEADER
+ mod_len
+ exp_len
;
1788 key_len
= key_p
->pubSec
.section_length
+ sizeof(struct cca_token_hdr
);
1789 key_p
->pubHdr
.token_length
= key_len
;
1791 itoLe2(&key_len
, keyb_p
->ulen
);
1793 itoLe2(&key_len
, keyb_p
->blen
);
1794 parmBlock_l
-= pad_len
;
1795 itoLe2(&parmBlock_l
, cprb_p
->req_parml
);
1796 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
1802 ICACRT_msg_to_type6CRT_msg(struct ica_rsa_modexpo_crt
*icaMsg_p
, int cdx
,
1803 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
)
1805 int mod_len
, vud_len
, tmp_size
, total_CPRB_len
, parmBlock_l
, short_len
;
1806 int long_len
, pad_len
, keyPartsLen
, tmp_l
;
1807 unsigned char *tgt_p
, *temp
;
1808 struct type6_hdr
*tp6Hdr_p
;
1809 struct CPRB
*cprb_p
;
1810 struct cca_token_hdr
*keyHdr_p
;
1811 struct cca_pvt_ext_CRT_sec
*pvtSec_p
;
1812 struct cca_public_sec
*pubSec_p
;
1814 mod_len
= icaMsg_p
->inputdatalength
;
1815 short_len
= mod_len
/ 2;
1816 long_len
= 8 + short_len
;
1817 keyPartsLen
= 3 * long_len
+ 2 * short_len
;
1818 pad_len
= (8 - (keyPartsLen
% 8)) % 8;
1819 keyPartsLen
+= pad_len
+ mod_len
;
1820 tmp_size
= FIXED_TYPE6_CR_LEN
+ keyPartsLen
+ mod_len
;
1821 total_CPRB_len
= tmp_size
- sizeof(struct type6_hdr
);
1822 parmBlock_l
= total_CPRB_len
- sizeof(struct CPRB
);
1823 vud_len
= 2 + mod_len
;
1824 tmp_size
= 4*((tmp_size
+ 3)/4) + CALLER_HEADER
;
1826 memset(z90cMsg_p
, 0, tmp_size
);
1827 tgt_p
= (unsigned char *)z90cMsg_p
+ CALLER_HEADER
;
1828 memcpy(tgt_p
, &static_type6_hdr
, sizeof(struct type6_hdr
));
1829 tp6Hdr_p
= (struct type6_hdr
*)tgt_p
;
1830 tp6Hdr_p
->ToCardLen1
= 4*((total_CPRB_len
+3)/4);
1831 tp6Hdr_p
->FromCardLen1
= RESPONSE_CPRB_SIZE
;
1832 tgt_p
+= sizeof(struct type6_hdr
);
1833 cprb_p
= (struct CPRB
*) tgt_p
;
1834 memcpy(tgt_p
, &static_cprb
, sizeof(struct CPRB
));
1835 cprb_p
->usage_domain
[0]= *((unsigned char *)(&(cdx
))+3);
1836 itoLe2(&parmBlock_l
, cprb_p
->req_parml
);
1837 memcpy(cprb_p
->rpl_parml
, cprb_p
->req_parml
,
1838 sizeof(cprb_p
->req_parml
));
1839 tgt_p
+= sizeof(struct CPRB
);
1840 memcpy(tgt_p
, &static_pkd_function_and_rules
,
1841 sizeof(struct function_and_rules_block
));
1842 tgt_p
+= sizeof(struct function_and_rules_block
);
1843 itoLe2(&vud_len
, tgt_p
);
1845 if (copy_from_user(tgt_p
, icaMsg_p
->inputdata
, mod_len
))
1846 return SEN_RELEASED
;
1847 if (is_empty(tgt_p
, mod_len
))
1848 return SEN_USER_ERROR
;
1850 tmp_l
= sizeof(struct T6_keyBlock_hdr
) + sizeof(struct cca_token_hdr
) +
1851 sizeof(struct cca_pvt_ext_CRT_sec
) + 0x0F + keyPartsLen
;
1852 itoLe2(&tmp_l
, tgt_p
);
1855 itoLe2(&tmp_l
, temp
);
1856 tgt_p
+= sizeof(struct T6_keyBlock_hdr
);
1857 keyHdr_p
= (struct cca_token_hdr
*)tgt_p
;
1858 keyHdr_p
->token_identifier
= CCA_TKN_HDR_ID_EXT
;
1860 keyHdr_p
->token_length
= tmp_l
;
1861 tgt_p
+= sizeof(struct cca_token_hdr
);
1862 pvtSec_p
= (struct cca_pvt_ext_CRT_sec
*)tgt_p
;
1863 pvtSec_p
->section_identifier
= CCA_PVT_EXT_CRT_SEC_ID_PVT
;
1864 pvtSec_p
->section_length
=
1865 sizeof(struct cca_pvt_ext_CRT_sec
) + keyPartsLen
;
1866 pvtSec_p
->key_format
= CCA_PVT_EXT_CRT_SEC_FMT_CL
;
1867 pvtSec_p
->key_use_flags
[0] = CCA_PVT_USAGE_ALL
;
1868 pvtSec_p
->p_len
= long_len
;
1869 pvtSec_p
->q_len
= short_len
;
1870 pvtSec_p
->dp_len
= long_len
;
1871 pvtSec_p
->dq_len
= short_len
;
1872 pvtSec_p
->u_len
= long_len
;
1873 pvtSec_p
->mod_len
= mod_len
;
1874 pvtSec_p
->pad_len
= pad_len
;
1875 tgt_p
+= sizeof(struct cca_pvt_ext_CRT_sec
);
1876 if (copy_from_user(tgt_p
, icaMsg_p
->np_prime
, long_len
))
1877 return SEN_RELEASED
;
1878 if (is_empty(tgt_p
, long_len
))
1879 return SEN_USER_ERROR
;
1881 if (copy_from_user(tgt_p
, icaMsg_p
->nq_prime
, short_len
))
1882 return SEN_RELEASED
;
1883 if (is_empty(tgt_p
, short_len
))
1884 return SEN_USER_ERROR
;
1886 if (copy_from_user(tgt_p
, icaMsg_p
->bp_key
, long_len
))
1887 return SEN_RELEASED
;
1888 if (is_empty(tgt_p
, long_len
))
1889 return SEN_USER_ERROR
;
1891 if (copy_from_user(tgt_p
, icaMsg_p
->bq_key
, short_len
))
1892 return SEN_RELEASED
;
1893 if (is_empty(tgt_p
, short_len
))
1894 return SEN_USER_ERROR
;
1896 if (copy_from_user(tgt_p
, icaMsg_p
->u_mult_inv
, long_len
))
1897 return SEN_RELEASED
;
1898 if (is_empty(tgt_p
, long_len
))
1899 return SEN_USER_ERROR
;
1902 memset(tgt_p
, 0xFF, mod_len
);
1904 memcpy(tgt_p
, &static_cca_pub_sec
, sizeof(struct cca_public_sec
));
1905 pubSec_p
= (struct cca_public_sec
*) tgt_p
;
1906 pubSec_p
->modulus_bit_len
= 8 * mod_len
;
1907 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
1913 ICAMEX_msg_to_type6MEX_msgX(struct ica_rsa_modexpo
*icaMsg_p
, int cdx
,
1914 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
,
1917 int mod_len
, exp_len
, vud_len
, tmp_size
, total_CPRB_len
, parmBlock_l
;
1919 unsigned char *temp_exp
, *tgt_p
, *temp
, *exp_p
;
1920 struct type6_hdr
*tp6Hdr_p
;
1921 struct CPRBX
*cprbx_p
;
1922 struct cca_public_key
*key_p
;
1923 struct T6_keyBlock_hdrX
*keyb_p
;
1925 temp_exp
= kmalloc(256, GFP_KERNEL
);
1928 mod_len
= icaMsg_p
->inputdatalength
;
1929 if (copy_from_user(temp_exp
, icaMsg_p
->b_key
, mod_len
)) {
1931 return SEN_RELEASED
;
1933 if (is_empty(temp_exp
, mod_len
)) {
1935 return SEN_USER_ERROR
;
1938 for (i
= 0; i
< mod_len
; i
++)
1943 return SEN_USER_ERROR
;
1945 exp_len
= mod_len
- i
;
1947 PDEBUG("exp_len after computation: %08x\n", exp_len
);
1948 tmp_size
= FIXED_TYPE6_ME_EN_LENX
+ 2 * mod_len
+ exp_len
;
1949 total_CPRB_len
= tmp_size
- sizeof(struct type6_hdr
);
1950 parmBlock_l
= total_CPRB_len
- sizeof(struct CPRBX
);
1951 tmp_size
= tmp_size
+ CALLER_HEADER
;
1952 vud_len
= 2 + mod_len
;
1953 memset(z90cMsg_p
, 0, tmp_size
);
1954 tgt_p
= (unsigned char *)z90cMsg_p
+ CALLER_HEADER
;
1955 memcpy(tgt_p
, &static_type6_hdrX
, sizeof(struct type6_hdr
));
1956 tp6Hdr_p
= (struct type6_hdr
*)tgt_p
;
1957 tp6Hdr_p
->ToCardLen1
= total_CPRB_len
;
1958 tp6Hdr_p
->FromCardLen1
= RESPONSE_CPRBX_SIZE
;
1959 memcpy(tp6Hdr_p
->function_code
, static_PKE_function_code
,
1960 sizeof(static_PKE_function_code
));
1961 tgt_p
+= sizeof(struct type6_hdr
);
1962 memcpy(tgt_p
, &static_cprbx
, sizeof(struct CPRBX
));
1963 cprbx_p
= (struct CPRBX
*) tgt_p
;
1964 cprbx_p
->domain
= (unsigned short)cdx
;
1965 cprbx_p
->rpl_msgbl
= RESPONSE_CPRBX_SIZE
;
1966 tgt_p
+= sizeof(struct CPRBX
);
1967 if (dev_type
== PCIXCC_MCL2
)
1968 memcpy(tgt_p
, &static_pke_function_and_rulesX_MCL2
,
1969 sizeof(struct function_and_rules_block
));
1971 memcpy(tgt_p
, &static_pke_function_and_rulesX
,
1972 sizeof(struct function_and_rules_block
));
1973 tgt_p
+= sizeof(struct function_and_rules_block
);
1976 if (copy_from_user(tgt_p
, icaMsg_p
->inputdata
, mod_len
)) {
1978 return SEN_RELEASED
;
1980 if (is_empty(tgt_p
, mod_len
)) {
1982 return SEN_USER_ERROR
;
1985 *((short *)tgt_p
) = (short) vud_len
;
1987 keyb_p
= (struct T6_keyBlock_hdrX
*)tgt_p
;
1988 tgt_p
+= sizeof(struct T6_keyBlock_hdrX
);
1989 memcpy(tgt_p
, &static_public_key
, sizeof(static_public_key
));
1990 key_p
= (struct cca_public_key
*)tgt_p
;
1991 temp
= key_p
->pubSec
.exponent
;
1992 memcpy(temp
, exp_p
, exp_len
);
1995 if (copy_from_user(temp
, icaMsg_p
->n_modulus
, mod_len
))
1996 return SEN_RELEASED
;
1997 if (is_empty(temp
, mod_len
))
1998 return SEN_USER_ERROR
;
1999 key_p
->pubSec
.modulus_bit_len
= 8 * mod_len
;
2000 key_p
->pubSec
.modulus_byte_len
= mod_len
;
2001 key_p
->pubSec
.exponent_len
= exp_len
;
2002 key_p
->pubSec
.section_length
= CALLER_HEADER
+ mod_len
+ exp_len
;
2003 key_len
= key_p
->pubSec
.section_length
+ sizeof(struct cca_token_hdr
);
2004 key_p
->pubHdr
.token_length
= key_len
;
2006 keyb_p
->ulen
= (unsigned short)key_len
;
2008 keyb_p
->blen
= (unsigned short)key_len
;
2009 cprbx_p
->req_parml
= parmBlock_l
;
2010 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
2016 ICACRT_msg_to_type6CRT_msgX(struct ica_rsa_modexpo_crt
*icaMsg_p
, int cdx
,
2017 int *z90cMsg_l_p
, struct type6_msg
*z90cMsg_p
,
2020 int mod_len
, vud_len
, tmp_size
, total_CPRB_len
, parmBlock_l
, short_len
;
2021 int long_len
, pad_len
, keyPartsLen
, tmp_l
;
2022 unsigned char *tgt_p
, *temp
;
2023 struct type6_hdr
*tp6Hdr_p
;
2024 struct CPRBX
*cprbx_p
;
2025 struct cca_token_hdr
*keyHdr_p
;
2026 struct cca_pvt_ext_CRT_sec
*pvtSec_p
;
2027 struct cca_public_sec
*pubSec_p
;
2029 mod_len
= icaMsg_p
->inputdatalength
;
2030 short_len
= mod_len
/ 2;
2031 long_len
= 8 + short_len
;
2032 keyPartsLen
= 3 * long_len
+ 2 * short_len
;
2033 pad_len
= (8 - (keyPartsLen
% 8)) % 8;
2034 keyPartsLen
+= pad_len
+ mod_len
;
2035 tmp_size
= FIXED_TYPE6_CR_LENX
+ keyPartsLen
+ mod_len
;
2036 total_CPRB_len
= tmp_size
- sizeof(struct type6_hdr
);
2037 parmBlock_l
= total_CPRB_len
- sizeof(struct CPRBX
);
2038 vud_len
= 2 + mod_len
;
2039 tmp_size
= tmp_size
+ CALLER_HEADER
;
2040 memset(z90cMsg_p
, 0, tmp_size
);
2041 tgt_p
= (unsigned char *)z90cMsg_p
+ CALLER_HEADER
;
2042 memcpy(tgt_p
, &static_type6_hdrX
, sizeof(struct type6_hdr
));
2043 tp6Hdr_p
= (struct type6_hdr
*)tgt_p
;
2044 tp6Hdr_p
->ToCardLen1
= total_CPRB_len
;
2045 tp6Hdr_p
->FromCardLen1
= RESPONSE_CPRBX_SIZE
;
2046 tgt_p
+= sizeof(struct type6_hdr
);
2047 cprbx_p
= (struct CPRBX
*) tgt_p
;
2048 memcpy(tgt_p
, &static_cprbx
, sizeof(struct CPRBX
));
2049 cprbx_p
->domain
= (unsigned short)cdx
;
2050 cprbx_p
->req_parml
= parmBlock_l
;
2051 cprbx_p
->rpl_msgbl
= parmBlock_l
;
2052 tgt_p
+= sizeof(struct CPRBX
);
2053 if (dev_type
== PCIXCC_MCL2
)
2054 memcpy(tgt_p
, &static_pkd_function_and_rulesX_MCL2
,
2055 sizeof(struct function_and_rules_block
));
2057 memcpy(tgt_p
, &static_pkd_function_and_rulesX
,
2058 sizeof(struct function_and_rules_block
));
2059 tgt_p
+= sizeof(struct function_and_rules_block
);
2060 *((short *)tgt_p
) = (short) vud_len
;
2062 if (copy_from_user(tgt_p
, icaMsg_p
->inputdata
, mod_len
))
2063 return SEN_RELEASED
;
2064 if (is_empty(tgt_p
, mod_len
))
2065 return SEN_USER_ERROR
;
2067 tmp_l
= sizeof(struct T6_keyBlock_hdr
) + sizeof(struct cca_token_hdr
) +
2068 sizeof(struct cca_pvt_ext_CRT_sec
) + 0x0F + keyPartsLen
;
2069 *((short *)tgt_p
) = (short) tmp_l
;
2072 *((short *)temp
) = (short) tmp_l
;
2073 tgt_p
+= sizeof(struct T6_keyBlock_hdr
);
2074 keyHdr_p
= (struct cca_token_hdr
*)tgt_p
;
2075 keyHdr_p
->token_identifier
= CCA_TKN_HDR_ID_EXT
;
2077 keyHdr_p
->token_length
= tmp_l
;
2078 tgt_p
+= sizeof(struct cca_token_hdr
);
2079 pvtSec_p
= (struct cca_pvt_ext_CRT_sec
*)tgt_p
;
2080 pvtSec_p
->section_identifier
= CCA_PVT_EXT_CRT_SEC_ID_PVT
;
2081 pvtSec_p
->section_length
=
2082 sizeof(struct cca_pvt_ext_CRT_sec
) + keyPartsLen
;
2083 pvtSec_p
->key_format
= CCA_PVT_EXT_CRT_SEC_FMT_CL
;
2084 pvtSec_p
->key_use_flags
[0] = CCA_PVT_USAGE_ALL
;
2085 pvtSec_p
->p_len
= long_len
;
2086 pvtSec_p
->q_len
= short_len
;
2087 pvtSec_p
->dp_len
= long_len
;
2088 pvtSec_p
->dq_len
= short_len
;
2089 pvtSec_p
->u_len
= long_len
;
2090 pvtSec_p
->mod_len
= mod_len
;
2091 pvtSec_p
->pad_len
= pad_len
;
2092 tgt_p
+= sizeof(struct cca_pvt_ext_CRT_sec
);
2093 if (copy_from_user(tgt_p
, icaMsg_p
->np_prime
, long_len
))
2094 return SEN_RELEASED
;
2095 if (is_empty(tgt_p
, long_len
))
2096 return SEN_USER_ERROR
;
2098 if (copy_from_user(tgt_p
, icaMsg_p
->nq_prime
, short_len
))
2099 return SEN_RELEASED
;
2100 if (is_empty(tgt_p
, short_len
))
2101 return SEN_USER_ERROR
;
2103 if (copy_from_user(tgt_p
, icaMsg_p
->bp_key
, long_len
))
2104 return SEN_RELEASED
;
2105 if (is_empty(tgt_p
, long_len
))
2106 return SEN_USER_ERROR
;
2108 if (copy_from_user(tgt_p
, icaMsg_p
->bq_key
, short_len
))
2109 return SEN_RELEASED
;
2110 if (is_empty(tgt_p
, short_len
))
2111 return SEN_USER_ERROR
;
2113 if (copy_from_user(tgt_p
, icaMsg_p
->u_mult_inv
, long_len
))
2114 return SEN_RELEASED
;
2115 if (is_empty(tgt_p
, long_len
))
2116 return SEN_USER_ERROR
;
2119 memset(tgt_p
, 0xFF, mod_len
);
2121 memcpy(tgt_p
, &static_cca_pub_sec
, sizeof(struct cca_public_sec
));
2122 pubSec_p
= (struct cca_public_sec
*) tgt_p
;
2123 pubSec_p
->modulus_bit_len
= 8 * mod_len
;
2124 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
2130 ICAMEX_msg_to_type50MEX_msg(struct ica_rsa_modexpo
*icaMex_p
, int *z90cMsg_l_p
,
2131 union type50_msg
*z90cMsg_p
)
2133 int mod_len
, msg_size
, mod_tgt_len
, exp_tgt_len
, inp_tgt_len
;
2134 unsigned char *mod_tgt
, *exp_tgt
, *inp_tgt
;
2135 union type50_msg
*tmp_type50_msg
;
2137 mod_len
= icaMex_p
->inputdatalength
;
2139 msg_size
= ((mod_len
<= 128) ? TYPE50_MEB1_LEN
: TYPE50_MEB2_LEN
) +
2142 memset(z90cMsg_p
, 0, msg_size
);
2144 tmp_type50_msg
= (union type50_msg
*)
2145 ((unsigned char *) z90cMsg_p
+ CALLER_HEADER
);
2147 tmp_type50_msg
->meb1
.header
.msg_type_code
= TYPE50_TYPE_CODE
;
2149 if (mod_len
<= 128) {
2150 tmp_type50_msg
->meb1
.header
.msg_len
= TYPE50_MEB1_LEN
;
2151 tmp_type50_msg
->meb1
.keyblock_type
= TYPE50_MEB1_FMT
;
2152 mod_tgt
= tmp_type50_msg
->meb1
.modulus
;
2153 mod_tgt_len
= sizeof(tmp_type50_msg
->meb1
.modulus
);
2154 exp_tgt
= tmp_type50_msg
->meb1
.exponent
;
2155 exp_tgt_len
= sizeof(tmp_type50_msg
->meb1
.exponent
);
2156 inp_tgt
= tmp_type50_msg
->meb1
.message
;
2157 inp_tgt_len
= sizeof(tmp_type50_msg
->meb1
.message
);
2159 tmp_type50_msg
->meb2
.header
.msg_len
= TYPE50_MEB2_LEN
;
2160 tmp_type50_msg
->meb2
.keyblock_type
= TYPE50_MEB2_FMT
;
2161 mod_tgt
= tmp_type50_msg
->meb2
.modulus
;
2162 mod_tgt_len
= sizeof(tmp_type50_msg
->meb2
.modulus
);
2163 exp_tgt
= tmp_type50_msg
->meb2
.exponent
;
2164 exp_tgt_len
= sizeof(tmp_type50_msg
->meb2
.exponent
);
2165 inp_tgt
= tmp_type50_msg
->meb2
.message
;
2166 inp_tgt_len
= sizeof(tmp_type50_msg
->meb2
.message
);
2169 mod_tgt
+= (mod_tgt_len
- mod_len
);
2170 if (copy_from_user(mod_tgt
, icaMex_p
->n_modulus
, mod_len
))
2171 return SEN_RELEASED
;
2172 if (is_empty(mod_tgt
, mod_len
))
2173 return SEN_USER_ERROR
;
2174 exp_tgt
+= (exp_tgt_len
- mod_len
);
2175 if (copy_from_user(exp_tgt
, icaMex_p
->b_key
, mod_len
))
2176 return SEN_RELEASED
;
2177 if (is_empty(exp_tgt
, mod_len
))
2178 return SEN_USER_ERROR
;
2179 inp_tgt
+= (inp_tgt_len
- mod_len
);
2180 if (copy_from_user(inp_tgt
, icaMex_p
->inputdata
, mod_len
))
2181 return SEN_RELEASED
;
2182 if (is_empty(inp_tgt
, mod_len
))
2183 return SEN_USER_ERROR
;
2185 *z90cMsg_l_p
= msg_size
- CALLER_HEADER
;
2191 ICACRT_msg_to_type50CRT_msg(struct ica_rsa_modexpo_crt
*icaMsg_p
,
2192 int *z90cMsg_l_p
, union type50_msg
*z90cMsg_p
)
2194 int mod_len
, short_len
, long_len
, tmp_size
, p_tgt_len
, q_tgt_len
,
2195 dp_tgt_len
, dq_tgt_len
, u_tgt_len
, inp_tgt_len
, long_offset
;
2196 unsigned char *p_tgt
, *q_tgt
, *dp_tgt
, *dq_tgt
, *u_tgt
, *inp_tgt
,
2198 union type50_msg
*tmp_type50_msg
;
2200 mod_len
= icaMsg_p
->inputdatalength
;
2201 short_len
= mod_len
/ 2;
2202 long_len
= mod_len
/ 2 + 8;
2205 if (long_len
> 128) {
2206 memset(temp
, 0x00, sizeof(temp
));
2207 if (copy_from_user(temp
, icaMsg_p
->np_prime
, long_len
-128))
2208 return SEN_RELEASED
;
2209 if (!is_empty(temp
, 8))
2210 return SEN_NOT_AVAIL
;
2211 if (copy_from_user(temp
, icaMsg_p
->bp_key
, long_len
-128))
2212 return SEN_RELEASED
;
2213 if (!is_empty(temp
, 8))
2214 return SEN_NOT_AVAIL
;
2215 if (copy_from_user(temp
, icaMsg_p
->u_mult_inv
, long_len
-128))
2216 return SEN_RELEASED
;
2217 if (!is_empty(temp
, 8))
2218 return SEN_NOT_AVAIL
;
2219 long_offset
= long_len
- 128;
2223 tmp_size
= ((mod_len
<= 128) ? TYPE50_CRB1_LEN
: TYPE50_CRB2_LEN
) +
2226 memset(z90cMsg_p
, 0, tmp_size
);
2228 tmp_type50_msg
= (union type50_msg
*)
2229 ((unsigned char *) z90cMsg_p
+ CALLER_HEADER
);
2231 tmp_type50_msg
->crb1
.header
.msg_type_code
= TYPE50_TYPE_CODE
;
2232 if (long_len
<= 64) {
2233 tmp_type50_msg
->crb1
.header
.msg_len
= TYPE50_CRB1_LEN
;
2234 tmp_type50_msg
->crb1
.keyblock_type
= TYPE50_CRB1_FMT
;
2235 p_tgt
= tmp_type50_msg
->crb1
.p
;
2236 p_tgt_len
= sizeof(tmp_type50_msg
->crb1
.p
);
2237 q_tgt
= tmp_type50_msg
->crb1
.q
;
2238 q_tgt_len
= sizeof(tmp_type50_msg
->crb1
.q
);
2239 dp_tgt
= tmp_type50_msg
->crb1
.dp
;
2240 dp_tgt_len
= sizeof(tmp_type50_msg
->crb1
.dp
);
2241 dq_tgt
= tmp_type50_msg
->crb1
.dq
;
2242 dq_tgt_len
= sizeof(tmp_type50_msg
->crb1
.dq
);
2243 u_tgt
= tmp_type50_msg
->crb1
.u
;
2244 u_tgt_len
= sizeof(tmp_type50_msg
->crb1
.u
);
2245 inp_tgt
= tmp_type50_msg
->crb1
.message
;
2246 inp_tgt_len
= sizeof(tmp_type50_msg
->crb1
.message
);
2248 tmp_type50_msg
->crb2
.header
.msg_len
= TYPE50_CRB2_LEN
;
2249 tmp_type50_msg
->crb2
.keyblock_type
= TYPE50_CRB2_FMT
;
2250 p_tgt
= tmp_type50_msg
->crb2
.p
;
2251 p_tgt_len
= sizeof(tmp_type50_msg
->crb2
.p
);
2252 q_tgt
= tmp_type50_msg
->crb2
.q
;
2253 q_tgt_len
= sizeof(tmp_type50_msg
->crb2
.q
);
2254 dp_tgt
= tmp_type50_msg
->crb2
.dp
;
2255 dp_tgt_len
= sizeof(tmp_type50_msg
->crb2
.dp
);
2256 dq_tgt
= tmp_type50_msg
->crb2
.dq
;
2257 dq_tgt_len
= sizeof(tmp_type50_msg
->crb2
.dq
);
2258 u_tgt
= tmp_type50_msg
->crb2
.u
;
2259 u_tgt_len
= sizeof(tmp_type50_msg
->crb2
.u
);
2260 inp_tgt
= tmp_type50_msg
->crb2
.message
;
2261 inp_tgt_len
= sizeof(tmp_type50_msg
->crb2
.message
);
2264 p_tgt
+= (p_tgt_len
- long_len
);
2265 if (copy_from_user(p_tgt
, icaMsg_p
->np_prime
+ long_offset
, long_len
))
2266 return SEN_RELEASED
;
2267 if (is_empty(p_tgt
, long_len
))
2268 return SEN_USER_ERROR
;
2269 q_tgt
+= (q_tgt_len
- short_len
);
2270 if (copy_from_user(q_tgt
, icaMsg_p
->nq_prime
, short_len
))
2271 return SEN_RELEASED
;
2272 if (is_empty(q_tgt
, short_len
))
2273 return SEN_USER_ERROR
;
2274 dp_tgt
+= (dp_tgt_len
- long_len
);
2275 if (copy_from_user(dp_tgt
, icaMsg_p
->bp_key
+ long_offset
, long_len
))
2276 return SEN_RELEASED
;
2277 if (is_empty(dp_tgt
, long_len
))
2278 return SEN_USER_ERROR
;
2279 dq_tgt
+= (dq_tgt_len
- short_len
);
2280 if (copy_from_user(dq_tgt
, icaMsg_p
->bq_key
, short_len
))
2281 return SEN_RELEASED
;
2282 if (is_empty(dq_tgt
, short_len
))
2283 return SEN_USER_ERROR
;
2284 u_tgt
+= (u_tgt_len
- long_len
);
2285 if (copy_from_user(u_tgt
, icaMsg_p
->u_mult_inv
+ long_offset
, long_len
))
2286 return SEN_RELEASED
;
2287 if (is_empty(u_tgt
, long_len
))
2288 return SEN_USER_ERROR
;
2289 inp_tgt
+= (inp_tgt_len
- mod_len
);
2290 if (copy_from_user(inp_tgt
, icaMsg_p
->inputdata
, mod_len
))
2291 return SEN_RELEASED
;
2292 if (is_empty(inp_tgt
, mod_len
))
2293 return SEN_USER_ERROR
;
2295 *z90cMsg_l_p
= tmp_size
- CALLER_HEADER
;
2301 convert_request(unsigned char *buffer
, int func
, unsigned short function
,
2302 int cdx
, int dev_type
, int *msg_l_p
, unsigned char *msg_p
)
2304 if (dev_type
== PCICA
) {
2305 if (func
== ICARSACRT
)
2306 return ICACRT_msg_to_type4CRT_msg(
2307 (struct ica_rsa_modexpo_crt
*) buffer
,
2308 msg_l_p
, (union type4_msg
*) msg_p
);
2310 return ICAMEX_msg_to_type4MEX_msg(
2311 (struct ica_rsa_modexpo
*) buffer
,
2312 msg_l_p
, (union type4_msg
*) msg_p
);
2314 if (dev_type
== PCICC
) {
2315 if (func
== ICARSACRT
)
2316 return ICACRT_msg_to_type6CRT_msg(
2317 (struct ica_rsa_modexpo_crt
*) buffer
,
2318 cdx
, msg_l_p
, (struct type6_msg
*)msg_p
);
2319 if (function
== PCI_FUNC_KEY_ENCRYPT
)
2320 return ICAMEX_msg_to_type6MEX_en_msg(
2321 (struct ica_rsa_modexpo
*) buffer
,
2322 cdx
, msg_l_p
, (struct type6_msg
*) msg_p
);
2324 return ICAMEX_msg_to_type6MEX_de_msg(
2325 (struct ica_rsa_modexpo
*) buffer
,
2326 cdx
, msg_l_p
, (struct type6_msg
*) msg_p
);
2328 if ((dev_type
== PCIXCC_MCL2
) ||
2329 (dev_type
== PCIXCC_MCL3
) ||
2330 (dev_type
== CEX2C
)) {
2331 if (func
== ICARSACRT
)
2332 return ICACRT_msg_to_type6CRT_msgX(
2333 (struct ica_rsa_modexpo_crt
*) buffer
,
2334 cdx
, msg_l_p
, (struct type6_msg
*) msg_p
,
2337 return ICAMEX_msg_to_type6MEX_msgX(
2338 (struct ica_rsa_modexpo
*) buffer
,
2339 cdx
, msg_l_p
, (struct type6_msg
*) msg_p
,
2342 if (dev_type
== CEX2A
) {
2343 if (func
== ICARSACRT
)
2344 return ICACRT_msg_to_type50CRT_msg(
2345 (struct ica_rsa_modexpo_crt
*) buffer
,
2346 msg_l_p
, (union type50_msg
*) msg_p
);
2348 return ICAMEX_msg_to_type50MEX_msg(
2349 (struct ica_rsa_modexpo
*) buffer
,
2350 msg_l_p
, (union type50_msg
*) msg_p
);
2356 int ext_bitlens_msg_count
= 0;
2358 unset_ext_bitlens(void)
2360 if (!ext_bitlens_msg_count
) {
2361 PRINTK("Unable to use coprocessors for extended bitlengths. "
2362 "Using PCICAs/CEX2As (if present) for extended "
2363 "bitlengths. This is not an error.\n");
2364 ext_bitlens_msg_count
++;
2370 convert_response(unsigned char *response
, unsigned char *buffer
,
2371 int *respbufflen_p
, unsigned char *resp_buff
)
2373 struct ica_rsa_modexpo
*icaMsg_p
= (struct ica_rsa_modexpo
*) buffer
;
2374 struct error_hdr
*errh_p
= (struct error_hdr
*) response
;
2375 struct type80_hdr
*t80h_p
= (struct type80_hdr
*) response
;
2376 struct type84_hdr
*t84h_p
= (struct type84_hdr
*) response
;
2377 struct type86_fmt2_msg
*t86m_p
= (struct type86_fmt2_msg
*) response
;
2378 int reply_code
, service_rc
, service_rs
, src_l
;
2379 unsigned char *src_p
, *tgt_p
;
2380 struct CPRB
*cprb_p
;
2381 struct CPRBX
*cprbx_p
;
2388 switch (errh_p
->type
) {
2389 case TYPE82_RSP_CODE
:
2390 case TYPE88_RSP_CODE
:
2391 reply_code
= errh_p
->reply_code
;
2392 src_p
= (unsigned char *)errh_p
;
2393 PRINTK("Hardware error: Type %02X Message Header: "
2394 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
2396 src_p
[0], src_p
[1], src_p
[2], src_p
[3],
2397 src_p
[4], src_p
[5], src_p
[6], src_p
[7]);
2399 case TYPE80_RSP_CODE
:
2400 src_l
= icaMsg_p
->outputdatalength
;
2401 src_p
= response
+ (int)t80h_p
->len
- src_l
;
2403 case TYPE84_RSP_CODE
:
2404 src_l
= icaMsg_p
->outputdatalength
;
2405 src_p
= response
+ (int)t84h_p
->len
- src_l
;
2407 case TYPE86_RSP_CODE
:
2408 reply_code
= t86m_p
->header
.reply_code
;
2409 if (reply_code
!= 0)
2411 cprb_p
= (struct CPRB
*)
2412 (response
+ sizeof(struct type86_fmt2_msg
));
2413 cprbx_p
= (struct CPRBX
*) cprb_p
;
2414 if (cprb_p
->cprb_ver_id
!= 0x02) {
2415 le2toI(cprb_p
->ccp_rtcode
, &service_rc
);
2416 if (service_rc
!= 0) {
2417 le2toI(cprb_p
->ccp_rscode
, &service_rs
);
2418 if ((service_rc
== 8) && (service_rs
== 66))
2419 PDEBUG("Bad block format on PCICC\n");
2420 else if ((service_rc
== 8) && (service_rs
== 65))
2421 PDEBUG("Probably an even modulus on "
2423 else if ((service_rc
== 8) && (service_rs
== 770)) {
2424 PDEBUG("Invalid key length on PCICC\n");
2425 unset_ext_bitlens();
2426 return REC_USE_PCICA
;
2428 else if ((service_rc
== 8) && (service_rs
== 783)) {
2429 PDEBUG("Extended bitlengths not enabled"
2431 unset_ext_bitlens();
2432 return REC_USE_PCICA
;
2435 PRINTK("service rc/rs (PCICC): %d/%d\n",
2436 service_rc
, service_rs
);
2437 return REC_OPERAND_INV
;
2439 src_p
= (unsigned char *)cprb_p
+ sizeof(struct CPRB
);
2441 le2toI(src_p
, &src_l
);
2445 service_rc
= (int)cprbx_p
->ccp_rtcode
;
2446 if (service_rc
!= 0) {
2447 service_rs
= (int) cprbx_p
->ccp_rscode
;
2448 if ((service_rc
== 8) && (service_rs
== 66))
2449 PDEBUG("Bad block format on PCIXCC\n");
2450 else if ((service_rc
== 8) && (service_rs
== 65))
2451 PDEBUG("Probably an even modulus on "
2453 else if ((service_rc
== 8) && (service_rs
== 770)) {
2454 PDEBUG("Invalid key length on PCIXCC\n");
2455 unset_ext_bitlens();
2456 return REC_USE_PCICA
;
2458 else if ((service_rc
== 8) && (service_rs
== 783)) {
2459 PDEBUG("Extended bitlengths not enabled"
2461 unset_ext_bitlens();
2462 return REC_USE_PCICA
;
2465 PRINTK("service rc/rs (PCIXCC): %d/%d\n",
2466 service_rc
, service_rs
);
2467 return REC_OPERAND_INV
;
2469 src_p
= (unsigned char *)
2470 cprbx_p
+ sizeof(struct CPRBX
);
2472 src_l
= (int)(*((short *) src_p
));
2478 src_p
= (unsigned char *)errh_p
;
2479 PRINTK("Unrecognized Message Header: "
2480 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
2481 src_p
[0], src_p
[1], src_p
[2], src_p
[3],
2482 src_p
[4], src_p
[5], src_p
[6], src_p
[7]);
2483 return REC_BAD_MESSAGE
;
2487 switch (reply_code
) {
2488 case REP82_ERROR_OPERAND_INVALID
:
2489 case REP88_ERROR_MESSAGE_MALFORMD
:
2490 return REC_OPERAND_INV
;
2491 case REP82_ERROR_OPERAND_SIZE
:
2492 return REC_OPERAND_SIZE
;
2493 case REP82_ERROR_EVEN_MOD_IN_OPND
:
2494 return REC_EVEN_MOD
;
2495 case REP82_ERROR_MESSAGE_TYPE
:
2496 return WRONG_DEVICE_TYPE
;
2497 case REP82_ERROR_TRANSPORT_FAIL
:
2498 PRINTKW("Transport failed (APFS = %02X%02X%02X%02X)\n",
2499 t86m_p
->apfs
[0], t86m_p
->apfs
[1],
2500 t86m_p
->apfs
[2], t86m_p
->apfs
[3]);
2501 return REC_HARDWAR_ERR
;
2503 PRINTKW("reply code = %d\n", reply_code
);
2504 return REC_HARDWAR_ERR
;
2507 if (service_rc
!= 0)
2508 return REC_OPERAND_INV
;
2510 if ((src_l
> icaMsg_p
->outputdatalength
) ||
2511 (src_l
> RESPBUFFSIZE
) ||
2513 return REC_OPERAND_SIZE
;
2515 PDEBUG("Length returned = %d\n", src_l
);
2516 tgt_p
= resp_buff
+ icaMsg_p
->outputdatalength
- src_l
;
2517 memcpy(tgt_p
, src_p
, src_l
);
2518 if ((errh_p
->type
== TYPE86_RSP_CODE
) && (resp_buff
< tgt_p
)) {
2519 memset(resp_buff
, 0, icaMsg_p
->outputdatalength
- src_l
);
2520 if (pad_msg(resp_buff
, icaMsg_p
->outputdatalength
, src_l
))
2521 return REC_INVALID_PAD
;
2523 *respbufflen_p
= icaMsg_p
->outputdatalength
;
2524 if (*respbufflen_p
== 0)
2525 PRINTK("Zero *respbufflen_p\n");