📄 z90hardware.c
字号:
key_p->pubSec.modulus_bit_len = 8 * mod_len; key_p->pubSec.modulus_byte_len = mod_len; key_p->pubSec.exponent_len = exp_len; key_p->pubSec.section_length = CALLER_HEADER + mod_len + exp_len; key_len = key_p->pubSec.section_length + sizeof(struct cca_token_hdr); key_p->pubHdr.token_length = key_len; key_len += 4; itoLe2(&key_len, keyb_p->ulen); key_len += 2; itoLe2(&key_len, keyb_p->blen); parmBlock_l -= pad_len; itoLe2(&parmBlock_l, cprb_p->req_parml); *z90cMsg_l_p = tmp_size - CALLER_HEADER; return 0;}static intICACRT_msg_to_type6CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p, int cdx, int *z90cMsg_l_p, struct type6_msg *z90cMsg_p){ int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l, short_len; int long_len, pad_len, keyPartsLen, tmp_l; unsigned char *tgt_p, *temp; struct type6_hdr *tp6Hdr_p; struct CPRB *cprb_p; struct cca_token_hdr *keyHdr_p; struct cca_pvt_ext_CRT_sec *pvtSec_p; struct cca_public_sec *pubSec_p; mod_len = icaMsg_p->inputdatalength; short_len = mod_len / 2; long_len = 8 + short_len; keyPartsLen = 3 * long_len + 2 * short_len; pad_len = (8 - (keyPartsLen % 8)) % 8; keyPartsLen += pad_len + mod_len; tmp_size = FIXED_TYPE6_CR_LEN + keyPartsLen + mod_len; total_CPRB_len = tmp_size - sizeof(struct type6_hdr); parmBlock_l = total_CPRB_len - sizeof(struct CPRB); vud_len = 2 + mod_len; tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER; memset(z90cMsg_p, 0, tmp_size); tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER; memcpy(tgt_p, &static_type6_hdr, sizeof(struct type6_hdr)); tp6Hdr_p = (struct type6_hdr *)tgt_p; tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4); tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE; tgt_p += sizeof(struct type6_hdr); cprb_p = (struct CPRB *) tgt_p; memcpy(tgt_p, &static_cprb, sizeof(struct CPRB)); cprb_p->usage_domain[0]= *((unsigned char *)(&(cdx))+3); itoLe2(&parmBlock_l, cprb_p->req_parml); memcpy(cprb_p->rpl_parml, cprb_p->req_parml, sizeof(cprb_p->req_parml)); tgt_p += sizeof(struct CPRB); memcpy(tgt_p, &static_pkd_function_and_rules, sizeof(struct function_and_rules_block)); tgt_p += sizeof(struct function_and_rules_block); itoLe2(&vud_len, tgt_p); tgt_p += 2; if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len)) return SEN_RELEASED; if (is_empty(tgt_p, mod_len)) return SEN_USER_ERROR; tgt_p += mod_len; tmp_l = sizeof(struct T6_keyBlock_hdr) + sizeof(struct cca_token_hdr) + sizeof(struct cca_pvt_ext_CRT_sec) + 0x0F + keyPartsLen; itoLe2(&tmp_l, tgt_p); temp = tgt_p + 2; tmp_l -= 2; itoLe2(&tmp_l, temp); tgt_p += sizeof(struct T6_keyBlock_hdr); keyHdr_p = (struct cca_token_hdr *)tgt_p; keyHdr_p->token_identifier = CCA_TKN_HDR_ID_EXT; tmp_l -= 4; keyHdr_p->token_length = tmp_l; tgt_p += sizeof(struct cca_token_hdr); pvtSec_p = (struct cca_pvt_ext_CRT_sec *)tgt_p; pvtSec_p->section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT; pvtSec_p->section_length = sizeof(struct cca_pvt_ext_CRT_sec) + keyPartsLen; pvtSec_p->key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL; pvtSec_p->key_use_flags[0] = CCA_PVT_USAGE_ALL; pvtSec_p->p_len = long_len; pvtSec_p->q_len = short_len; pvtSec_p->dp_len = long_len; pvtSec_p->dq_len = short_len; pvtSec_p->u_len = long_len; pvtSec_p->mod_len = mod_len; pvtSec_p->pad_len = pad_len; tgt_p += sizeof(struct cca_pvt_ext_CRT_sec); if (copy_from_user(tgt_p, icaMsg_p->np_prime, long_len)) return SEN_RELEASED; if (is_empty(tgt_p, long_len)) return SEN_USER_ERROR; tgt_p += long_len; if (copy_from_user(tgt_p, icaMsg_p->nq_prime, short_len)) return SEN_RELEASED; if (is_empty(tgt_p, short_len)) return SEN_USER_ERROR; tgt_p += short_len; if (copy_from_user(tgt_p, icaMsg_p->bp_key, long_len)) return SEN_RELEASED; if (is_empty(tgt_p, long_len)) return SEN_USER_ERROR; tgt_p += long_len; if (copy_from_user(tgt_p, icaMsg_p->bq_key, short_len)) return SEN_RELEASED; if (is_empty(tgt_p, short_len)) return SEN_USER_ERROR; tgt_p += short_len; if (copy_from_user(tgt_p, icaMsg_p->u_mult_inv, long_len)) return SEN_RELEASED; if (is_empty(tgt_p, long_len)) return SEN_USER_ERROR; tgt_p += long_len; tgt_p += pad_len; memset(tgt_p, 0xFF, mod_len); tgt_p += mod_len; memcpy(tgt_p, &static_cca_pub_sec, sizeof(struct cca_public_sec)); pubSec_p = (struct cca_public_sec *) tgt_p; pubSec_p->modulus_bit_len = 8 * mod_len; *z90cMsg_l_p = tmp_size - CALLER_HEADER; return 0;}static intICAMEX_msg_to_type6MEX_msgX(struct ica_rsa_modexpo *icaMsg_p, int cdx, int *z90cMsg_l_p, struct type6_msg *z90cMsg_p, int dev_type){ int mod_len, exp_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l; int key_len, i; unsigned char *temp_exp, *tgt_p, *temp, *exp_p; struct type6_hdr *tp6Hdr_p; struct CPRBX *cprbx_p; struct cca_public_key *key_p; struct T6_keyBlock_hdrX *keyb_p; temp_exp = kmalloc(256, GFP_KERNEL); if (!temp_exp) return EGETBUFF; mod_len = icaMsg_p->inputdatalength; if (copy_from_user(temp_exp, icaMsg_p->b_key, mod_len)) { kfree(temp_exp); return SEN_RELEASED; } if (is_empty(temp_exp, mod_len)) { kfree(temp_exp); return SEN_USER_ERROR; } exp_p = temp_exp; for (i = 0; i < mod_len; i++) if (exp_p[i]) break; if (i >= mod_len) { kfree(temp_exp); return SEN_USER_ERROR; } exp_len = mod_len - i; exp_p += i; PDEBUG("exp_len after computation: %08x\n", exp_len); tmp_size = FIXED_TYPE6_ME_EN_LENX + 2 * mod_len + exp_len; total_CPRB_len = tmp_size - sizeof(struct type6_hdr); parmBlock_l = total_CPRB_len - sizeof(struct CPRBX); tmp_size = tmp_size + CALLER_HEADER; vud_len = 2 + mod_len; memset(z90cMsg_p, 0, tmp_size); tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER; memcpy(tgt_p, &static_type6_hdrX, sizeof(struct type6_hdr)); tp6Hdr_p = (struct type6_hdr *)tgt_p; tp6Hdr_p->ToCardLen1 = total_CPRB_len; tp6Hdr_p->FromCardLen1 = RESPONSE_CPRBX_SIZE; memcpy(tp6Hdr_p->function_code, static_PKE_function_code, sizeof(static_PKE_function_code)); tgt_p += sizeof(struct type6_hdr); memcpy(tgt_p, &static_cprbx, sizeof(struct CPRBX)); cprbx_p = (struct CPRBX *) tgt_p; cprbx_p->domain = (unsigned short)cdx; cprbx_p->rpl_msgbl = RESPONSE_CPRBX_SIZE; tgt_p += sizeof(struct CPRBX); if (dev_type == PCIXCC_MCL2) memcpy(tgt_p, &static_pke_function_and_rulesX_MCL2, sizeof(struct function_and_rules_block)); else memcpy(tgt_p, &static_pke_function_and_rulesX, sizeof(struct function_and_rules_block)); tgt_p += sizeof(struct function_and_rules_block); tgt_p += 2; if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len)) { kfree(temp_exp); return SEN_RELEASED; } if (is_empty(tgt_p, mod_len)) { kfree(temp_exp); return SEN_USER_ERROR; } tgt_p -= 2; *((short *)tgt_p) = (short) vud_len; tgt_p += vud_len; keyb_p = (struct T6_keyBlock_hdrX *)tgt_p; tgt_p += sizeof(struct T6_keyBlock_hdrX); memcpy(tgt_p, &static_public_key, sizeof(static_public_key)); key_p = (struct cca_public_key *)tgt_p; temp = key_p->pubSec.exponent; memcpy(temp, exp_p, exp_len); kfree(temp_exp); temp += exp_len; if (copy_from_user(temp, icaMsg_p->n_modulus, mod_len)) return SEN_RELEASED; if (is_empty(temp, mod_len)) return SEN_USER_ERROR; key_p->pubSec.modulus_bit_len = 8 * mod_len; key_p->pubSec.modulus_byte_len = mod_len; key_p->pubSec.exponent_len = exp_len; key_p->pubSec.section_length = CALLER_HEADER + mod_len + exp_len; key_len = key_p->pubSec.section_length + sizeof(struct cca_token_hdr); key_p->pubHdr.token_length = key_len; key_len += 4; keyb_p->ulen = (unsigned short)key_len; key_len += 2; keyb_p->blen = (unsigned short)key_len; cprbx_p->req_parml = parmBlock_l; *z90cMsg_l_p = tmp_size - CALLER_HEADER; return 0;}static intICACRT_msg_to_type6CRT_msgX(struct ica_rsa_modexpo_crt *icaMsg_p, int cdx, int *z90cMsg_l_p, struct type6_msg *z90cMsg_p, int dev_type){ int mod_len, vud_len, tmp_size, total_CPRB_len, parmBlock_l, short_len; int long_len, pad_len, keyPartsLen, tmp_l; unsigned char *tgt_p, *temp; struct type6_hdr *tp6Hdr_p; struct CPRBX *cprbx_p; struct cca_token_hdr *keyHdr_p; struct cca_pvt_ext_CRT_sec *pvtSec_p; struct cca_public_sec *pubSec_p; mod_len = icaMsg_p->inputdatalength; short_len = mod_len / 2; long_len = 8 + short_len; keyPartsLen = 3 * long_len + 2 * short_len; pad_len = (8 - (keyPartsLen % 8)) % 8; keyPartsLen += pad_len + mod_len; tmp_size = FIXED_TYPE6_CR_LENX + keyPartsLen + mod_len; total_CPRB_len = tmp_size - sizeof(struct type6_hdr); parmBlock_l = total_CPRB_len - sizeof(struct CPRBX); vud_len = 2 + mod_len; tmp_size = tmp_size + CALLER_HEADER; memset(z90cMsg_p, 0, tmp_size); tgt_p = (unsigned char *)z90cMsg_p + CALLER_HEADER; memcpy(tgt_p, &static_type6_hdrX, sizeof(struct type6_hdr)); tp6Hdr_p = (struct type6_hdr *)tgt_p; tp6Hdr_p->ToCardLen1 = total_CPRB_len; tp6Hdr_p->FromCardLen1 = RESPONSE_CPRBX_SIZE; tgt_p += sizeof(struct type6_hdr); cprbx_p = (struct CPRBX *) tgt_p; memcpy(tgt_p, &static_cprbx, sizeof(struct CPRBX)); cprbx_p->domain = (unsigned short)cdx; cprbx_p->req_parml = parmBlock_l; cprbx_p->rpl_msgbl = parmBlock_l; tgt_p += sizeof(struct CPRBX); if (dev_type == PCIXCC_MCL2) memcpy(tgt_p, &static_pkd_function_and_rulesX_MCL2, sizeof(struct function_and_rules_block)); else memcpy(tgt_p, &static_pkd_function_and_rulesX, sizeof(struct function_and_rules_block)); tgt_p += sizeof(struct function_and_rules_block); *((short *)tgt_p) = (short) vud_len; tgt_p += 2; if (copy_from_user(tgt_p, icaMsg_p->inputdata, mod_len)) return SEN_RELEASED; if (is_empty(tgt_p, mod_len)) return SEN_USER_ERROR; tgt_p += mod_len; tmp_l = sizeof(struct T6_keyBlock_hdr) + sizeof(struct cca_token_hdr) + sizeof(struct cca_pvt_ext_CRT_sec) + 0x0F + keyPartsLen; *((short *)tgt_p) = (short) tmp_l; temp = tgt_p + 2; tmp_l -= 2; *((short *)temp) = (short) tmp_l; tgt_p += sizeof(struct T6_keyBlock_hdr); keyHdr_p = (struct cca_token_hdr *)tgt_p; keyHdr_p->token_identifier = CCA_TKN_HDR_ID_EXT; tmp_l -= 4; keyHdr_p->token_length = tmp_l; tgt_p += sizeof(struct cca_token_hdr); pvtSec_p = (struct cca_pvt_ext_CRT_sec *)tgt_p; pvtSec_p->section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT; pvtSec_p->section_length = sizeof(struct cca_pvt_ext_CRT_sec) + keyPartsLen; pvtSec_p->key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL; pvtSec_p->key_use_flags[0] = CCA_PVT_USAGE_ALL; pvtSec_p->p_len = long_len; pvtSec_p->q_len = short_len; pvtSec_p->dp_len = long_len; pvtSec_p->dq_len = short_len; pvtSec_p->u_len = long_len; pvtSec_p->mod_len = mod_len; pvtSec_p->pad_len = pad_len; tgt_p += sizeof(struct cca_pvt_ext_CRT_sec); if (copy_from_user(tgt_p, icaMsg_p->np_prime, long_len)) return SEN_RELEASED; if (is_empty(tgt_p, long_len)) return SEN_USER_ERROR; tgt_p += long_len; if (copy_from_user(tgt_p, icaMsg_p->nq_prime, short_len)) return SEN_RELEASED; if (is_empty(tgt_p, short_len)) return SEN_USER_ERROR; tgt_p += short_len; if (copy_from_user(tgt_p, icaMsg_p->bp_key, long_len)) return SEN_RELEASED; if (is_empty(tgt_p, long_len)) return SEN_USER_ERROR; tgt_p += long_len; if (copy_from_user(tgt_p, icaMsg_p->bq_key, short_len)) return SEN_RELEASED; if (is_empty(tgt_p, short_len)) return SEN_USER_ERROR; tgt_p += short_len; if (copy_from_user(tgt_p, icaMsg_p->u_mult_inv, long_len)) return SEN_RELEASED; if (is_empty(tgt_p, long_len)) return SEN_USER_ERROR; tgt_p += long_len; tgt_p += pad_len; memset(tgt_p, 0xFF, mod_len); tgt_p += mod_len; memcpy(tgt_p, &static_cca_pub_sec, sizeof(struct cca_public_sec)); pubSec_p = (struct cca_public_sec *) tgt_p; pubSec_p->modulus_bit_len = 8 * mod_len; *z90cMsg_l_p = tmp_size - CALLER_HEADER; return 0;}intconvert_request(unsigned char *buffer, int func, unsigned short function, int cdx, int dev_type, int *msg_l_p, unsigned char *msg_p){ if (dev_type == PCICA) { if (func == ICARSACRT) return ICACRT_msg_to_type4CRT_msg( (struct ica_rsa_modexpo_crt *) buffer, msg_l_p, (union type4_msg *) msg_p); else return ICAMEX_msg_to_type4MEX_msg( (struct ica_rsa_modexpo *) buffer, msg_l_p, (union type4_msg *) msg_p); } if (dev_type == PCICC) { if (func == ICARSACRT) return ICACRT_msg_to_type6CRT_msg( (struct ica_rsa_modexpo_crt *) buffer, cdx, msg_l_p, (struct type6_msg *)msg_p); if (function == PCI_FUNC_KEY_ENCRYPT) return ICAMEX_msg_to_type6MEX_en_msg( (struct ica_rsa_modexpo *) buffer, cdx, msg_l_p, (struct type6_msg *) msg_p); else return ICAMEX_msg_to_type6MEX_de_msg( (struct ica_rsa_modexpo *) buffer, cdx, msg_l_p, (struct type6_msg *) msg_p); } if ((dev_type == PCIXCC_MCL2) || (dev_type == PCIXCC_MCL3) || (dev_type == CEX2C)) { if (func == ICARSACRT) return ICACRT_msg_to_type6CRT_msgX( (struct ica_rsa_modexpo_crt *) buffer, cdx, msg_l_p, (struct type6_msg *) msg_p, dev_type); else return ICAMEX_msg_to_type6MEX_msgX( (struct ica_rsa_modexpo *) buffer, cdx, msg_l_p, (struct type6_msg *) msg_p, dev_type); } return 0;}int ext_bitlens_msg_count = 0;static inline voidunset_ext_bitlens(void){ if (!ext_bitlens_msg_count) { PRINTK("Unable to use coprocessors for extended bitlengths. " "Using PCICAs (if present) for extended bitlengths. " "This is not an error.\n"); ext_bitlens_msg_count++; } ext_bitlens = 0;}intconvert_response(unsigned char *response, unsigned char *buffer, int *respbufflen_p, unsigned char *resp_buff){ struct ica_rsa_modexpo *icaMsg_p = (struct ica_rsa_modexpo *) buffer; struct error_hdr *errh_p = (struct error_hdr *) response; struct type84_hdr *t84h_p = (struct type84_hdr *) response; struct type86_fmt2_msg *t86m_p = (struct type86_fmt2_msg *) response; int reply_code, service_rc, service_rs, src_l; unsigned char *src_p, *tgt_p; struct CPRB *cprb_p; struct CPRBX *cprbx_p; src_p = 0; reply_code = 0; service_rc = 0; service_rs = 0; src_l = 0; switch (errh_p->type) { case TYPE82_RSP_CODE: reply_code = errh_p->reply_code; src_p = (unsigned char *)errh_p; PRINTK("Hardware error: Type %02X Message Header: " "%02x%02x%02x%02x%02x%02x%02x%02x\n", errh_p->type, src_p[0], src_p[1], src_p[2], src_p[3], src_p[4], src_p[5], src_p[6], src_p[7]); break; case TYPE84_RSP_CODE: src_l = icaMsg_p->outputdatalength; src_p = response + (int)t84h_p->len - src_l; break; case TYPE86_RSP_CODE: reply_code = t86m_p->header.reply_code; if (reply_code != 0) break; cprb_p = (struct CPRB *) (response + sizeof(struct type86_fmt2_msg)); cprbx_p = (struct CPRBX *) cprb_p; if (cprb_p->cprb_ver_id != 0x02) { le2toI(cprb_p->ccp_rtcode, &service_rc); if (service_rc != 0) { le2toI(cprb_p->ccp_rscode, &service_rs); if ((service_rc == 8) && (service_rs == 66)) PDEBUG("Bad block format on PCICC\n"); else if ((service_rc == 8) && (service_rs == 65)) PDEBUG("Probably an even modulus on " "PCICC\n"); else if ((service_rc == 8) && (service_rs == 770)) { PDEBUG("Invalid key length on PCICC\n"); unset_ext_bitlens(); return REC_USE_PCICA; } else if ((service_rc == 8) && (service_rs == 783)) { PDEBUG("Extended bitlengths not enabled" "on PCICC\n"); unset_ext_bitlens(); return REC_USE_PCICA; } else PRINTK("service rc/rs (PCICC): %d/%d\n", service_rc, service_rs); return REC_OPERAND_INV; } src_p = (unsigned char *)cprb_p + sizeof(struct CPRB); src_p += 4; le2toI(src_p, &src_l); src_l -= 2; src_p += 2; } else { service_rc = (int)cprbx_p->ccp_rtcode; if (service_rc != 0) { service_rs = (int) cprbx_p->ccp_rscode; if ((service_rc == 8) && (service_rs == 66)) PDEBUG("Bad block format on PCIXCC\n"); else if ((service_rc == 8) && (service_rs == 65)) PDEBUG("Probably an even modulus on " "PCIXCC\n"); else if ((service_rc == 8) && (service_rs == 770)) { PDEBUG("Invalid key length on PCIXCC\n"); unset_ext_bitlens(); return REC_USE_PCICA; } else if ((service_rc == 8) && (service_rs == 783)) { PDEBUG("Extended bitlengths not enabled" "on PCIXCC\n"); unset_ext_bitlens(); return REC_USE_PCICA; } else PRINTK("service rc/rs (PCIXCC): %d/%d\n", service_rc, service_rs); return REC_OPERAND_INV; } src_p = (unsigned char *) cprbx_p + sizeof(struct CPRBX); src_p += 4; src_l = (int)(*((short *) src_p)); src_l -= 2; src_p += 2; } break; default: src_p = (unsigned char *)errh_p; PRINTK("Unrecognized Message Header: " "%02x%02x%02x%02x%02x%02x%02x%02x\n", src_p[0], src_p[1], src_p[2], src_p[3], src_p[4], src_p[5], src_p[6], src_p[7]); return REC_BAD_MESSAGE; } if (reply_code) switch (reply_code) { case REP82_ERROR_OPERAND_INVALID: return REC_OPERAND_INV; case REP82_ERROR_OPERAND_SIZE: return REC_OPERAND_SIZE; case REP82_ERROR_EVEN_MOD_IN_OPND: return REC_EVEN_MOD; case REP82_ERROR_MESSAGE_TYPE: return WRONG_DEVICE_TYPE; case REP82_ERROR_TRANSPORT_FAIL: PRINTKW("Transport failed (APFS = %02X%02X%02X%02X)\n", t86m_p->apfs[0], t86m_p->apfs[1], t86m_p->apfs[2], t86m_p->apfs[3]); return REC_HARDWAR_ERR; default: PRINTKW("reply code = %d\n", reply_code); return REC_HARDWAR_ERR; } if (service_rc != 0) return REC_OPERAND_INV; if ((src_l > icaMsg_p->outputdatalength) || (src_l > RESPBUFFSIZE) || (src_l <= 0)) return REC_OPERAND_SIZE; PDEBUG("Length returned = %d\n", src_l); tgt_p = resp_buff + icaMsg_p->outputdatalength - src_l; memcpy(tgt_p, src_p, src_l); if ((errh_p->type == TYPE86_RSP_CODE) && (resp_buff < tgt_p)) { memset(resp_buff, 0, icaMsg_p->outputdatalength - src_l); if (pad_msg(resp_buff, icaMsg_p->outputdatalength, src_l)) return REC_INVALID_PAD; } *respbufflen_p = icaMsg_p->outputdatalength; if (*respbufflen_p == 0) PRINTK("Zero *respbufflen_p\n"); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -