Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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