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