📄 z90hardware.c
字号:
q_nr = (deviceNr << SKIP_BITL) + cdx; stat = DEV_GONE; ccode = resetq(q_nr, &stat_word); if (ccode > 3) return DEV_RSQ_EXCEPTION; break_out = 0; for (i = 0; i < resetNr; i++) { switch (ccode) { case 0: stat = DEV_ONLINE; if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY) break_out = 1; break; case 3: switch (stat_word.response_code) { case AP_RESPONSE_NORMAL: stat = DEV_ONLINE; if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY) break_out = 1; break; case AP_RESPONSE_Q_NOT_AVAIL: case AP_RESPONSE_DECONFIGURED: case AP_RESPONSE_CHECKSTOPPED: stat = DEV_GONE; break_out = 1; break; case AP_RESPONSE_RESET_IN_PROGRESS: case AP_RESPONSE_BUSY: default: break; } break; default: stat = DEV_GONE; break_out = 1; break; } if (break_out == 1) break; udelay(5); ccode = testq(q_nr, &dummy_qdepth, &dummy_devType, &stat_word); if (ccode > 3) { stat = DEV_TSQ_EXCEPTION; break; } } PDEBUG("Number of testq's needed for reset: %d\n", i); if (i >= resetNr) { stat = DEV_GONE; } return stat;}#ifdef DEBUG_HYDRA_MSGSstatic inline voidprint_buffer(unsigned char *buffer, int bufflen){ int i; for (i = 0; i < bufflen; i += 16) { PRINTK("%04X: %02X%02X%02X%02X %02X%02X%02X%02X " "%02X%02X%02X%02X %02X%02X%02X%02X\n", i, buffer[i+0], buffer[i+1], buffer[i+2], buffer[i+3], buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7], buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11], buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]); }}#endifenum devstatsend_to_AP(int dev_nr, int cdx, int msg_len, unsigned char *msg_ext){ struct ap_status_word stat_word; enum devstat stat; int ccode; u32 *q_nr_p = (u32 *)msg_ext; *q_nr_p = (dev_nr << SKIP_BITL) + cdx; PDEBUG("msg_len passed to sen: %d\n", msg_len); PDEBUG("q number passed to sen: %02x%02x%02x%02x\n", msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3]); stat = DEV_GONE;#ifdef DEBUG_HYDRA_MSGS PRINTK("Request header: %02X%02X%02X%02X %02X%02X%02X%02X " "%02X%02X%02X%02X\n", msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3], msg_ext[4], msg_ext[5], msg_ext[6], msg_ext[7], msg_ext[8], msg_ext[9], msg_ext[10], msg_ext[11]); print_buffer(msg_ext+CALLER_HEADER, msg_len);#endif ccode = sen(msg_len, msg_ext, &stat_word); if (ccode > 3) return DEV_SEN_EXCEPTION; PDEBUG("nq cc: %u, st: %02x%02x%02x%02x\n", ccode, stat_word.q_stat_flags, stat_word.response_code, stat_word.reserved[0], stat_word.reserved[1]); switch (ccode) { case 0: stat = DEV_ONLINE; break; case 1: stat = DEV_GONE; break; case 3: switch (stat_word.response_code) { case AP_RESPONSE_NORMAL: stat = DEV_ONLINE; break; case AP_RESPONSE_Q_FULL: stat = DEV_QUEUE_FULL; break; default: stat = DEV_GONE; break; } break; default: stat = DEV_GONE; break; } return stat;}enum devstatreceive_from_AP(int dev_nr, int cdx, int resplen, unsigned char *resp, unsigned char *psmid){ int ccode; struct ap_status_word stat_word; enum devstat stat; memset(resp, 0x00, 8); ccode = rec((dev_nr << SKIP_BITL) + cdx, resplen, resp, psmid, &stat_word); if (ccode > 3) return DEV_REC_EXCEPTION; PDEBUG("dq cc: %u, st: %02x%02x%02x%02x\n", ccode, stat_word.q_stat_flags, stat_word.response_code, stat_word.reserved[0], stat_word.reserved[1]); stat = DEV_GONE; switch (ccode) { case 0: stat = DEV_ONLINE;#ifdef DEBUG_HYDRA_MSGS print_buffer(resp, resplen);#endif break; case 3: switch (stat_word.response_code) { case AP_RESPONSE_NORMAL: stat = DEV_ONLINE; break; case AP_RESPONSE_NO_PENDING_REPLY: if (stat_word.q_stat_flags & AP_Q_STATUS_EMPTY) stat = DEV_EMPTY; else stat = DEV_NO_WORK; break; case AP_RESPONSE_INDEX_TOO_BIG: case AP_RESPONSE_NO_FIRST_PART: case AP_RESPONSE_MESSAGE_TOO_BIG: stat = DEV_BAD_MESSAGE; break; default: break; } break; default: break; } return stat;}static inline intpad_msg(unsigned char *buffer, int totalLength, int msgLength){ int pad_len; for (pad_len = 0; pad_len < (totalLength - msgLength); pad_len++) if (buffer[pad_len] != 0x00) break; pad_len -= 3; if (pad_len < 8) return SEN_PAD_ERROR; buffer[0] = 0x00; buffer[1] = 0x02; memcpy(buffer+2, static_pad, pad_len); buffer[pad_len + 2] = 0x00; return 0;}static inline intis_common_public_key(unsigned char *key, int len){ int i; for (i = 0; i < len; i++) if (key[i]) break; key += i; len -= i; if (((len == 1) && (key[0] == 3)) || ((len == 3) && (key[0] == 1) && (key[1] == 0) && (key[2] == 1))) return 1; return 0;}static intICAMEX_msg_to_type4MEX_msg(struct ica_rsa_modexpo *icaMex_p, int *z90cMsg_l_p, union type4_msg *z90cMsg_p){ int mod_len, msg_size, mod_tgt_len, exp_tgt_len, inp_tgt_len; unsigned char *mod_tgt, *exp_tgt, *inp_tgt; union type4_msg *tmp_type4_msg; mod_len = icaMex_p->inputdatalength; msg_size = ((mod_len <= 128) ? TYPE4_SME_LEN : TYPE4_LME_LEN) + CALLER_HEADER; memset(z90cMsg_p, 0, msg_size); tmp_type4_msg = (union type4_msg *) ((unsigned char *) z90cMsg_p + CALLER_HEADER); tmp_type4_msg->sme.header.msg_type_code = TYPE4_TYPE_CODE; tmp_type4_msg->sme.header.request_code = TYPE4_REQU_CODE; if (mod_len <= 128) { tmp_type4_msg->sme.header.msg_fmt = TYPE4_SME_FMT; tmp_type4_msg->sme.header.msg_len = TYPE4_SME_LEN; mod_tgt = tmp_type4_msg->sme.modulus; mod_tgt_len = sizeof(tmp_type4_msg->sme.modulus); exp_tgt = tmp_type4_msg->sme.exponent; exp_tgt_len = sizeof(tmp_type4_msg->sme.exponent); inp_tgt = tmp_type4_msg->sme.message; inp_tgt_len = sizeof(tmp_type4_msg->sme.message); } else { tmp_type4_msg->lme.header.msg_fmt = TYPE4_LME_FMT; tmp_type4_msg->lme.header.msg_len = TYPE4_LME_LEN; mod_tgt = tmp_type4_msg->lme.modulus; mod_tgt_len = sizeof(tmp_type4_msg->lme.modulus); exp_tgt = tmp_type4_msg->lme.exponent; exp_tgt_len = sizeof(tmp_type4_msg->lme.exponent); inp_tgt = tmp_type4_msg->lme.message; inp_tgt_len = sizeof(tmp_type4_msg->lme.message); } mod_tgt += (mod_tgt_len - mod_len); if (copy_from_user(mod_tgt, icaMex_p->n_modulus, mod_len)) return SEN_RELEASED; if (is_empty(mod_tgt, mod_len)) return SEN_USER_ERROR; exp_tgt += (exp_tgt_len - mod_len); if (copy_from_user(exp_tgt, icaMex_p->b_key, mod_len)) return SEN_RELEASED; if (is_empty(exp_tgt, mod_len)) return SEN_USER_ERROR; inp_tgt += (inp_tgt_len - mod_len); if (copy_from_user(inp_tgt, icaMex_p->inputdata, mod_len)) return SEN_RELEASED; if (is_empty(inp_tgt, mod_len)) return SEN_USER_ERROR; *z90cMsg_l_p = msg_size - CALLER_HEADER; return 0;}static intICACRT_msg_to_type4CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p, int *z90cMsg_l_p, union type4_msg *z90cMsg_p){ int mod_len, short_len, long_len, tmp_size, p_tgt_len, q_tgt_len, dp_tgt_len, dq_tgt_len, u_tgt_len, inp_tgt_len; unsigned char *p_tgt, *q_tgt, *dp_tgt, *dq_tgt, *u_tgt, *inp_tgt; union type4_msg *tmp_type4_msg; mod_len = icaMsg_p->inputdatalength; short_len = mod_len / 2; long_len = mod_len / 2 + 8; tmp_size = ((mod_len <= 128) ? TYPE4_SCR_LEN : TYPE4_LCR_LEN) + CALLER_HEADER; memset(z90cMsg_p, 0, tmp_size); tmp_type4_msg = (union type4_msg *) ((unsigned char *) z90cMsg_p + CALLER_HEADER); tmp_type4_msg->scr.header.msg_type_code = TYPE4_TYPE_CODE; tmp_type4_msg->scr.header.request_code = TYPE4_REQU_CODE; if (mod_len <= 128) { tmp_type4_msg->scr.header.msg_fmt = TYPE4_SCR_FMT; tmp_type4_msg->scr.header.msg_len = TYPE4_SCR_LEN; p_tgt = tmp_type4_msg->scr.p; p_tgt_len = sizeof(tmp_type4_msg->scr.p); q_tgt = tmp_type4_msg->scr.q; q_tgt_len = sizeof(tmp_type4_msg->scr.q); dp_tgt = tmp_type4_msg->scr.dp; dp_tgt_len = sizeof(tmp_type4_msg->scr.dp); dq_tgt = tmp_type4_msg->scr.dq; dq_tgt_len = sizeof(tmp_type4_msg->scr.dq); u_tgt = tmp_type4_msg->scr.u; u_tgt_len = sizeof(tmp_type4_msg->scr.u); inp_tgt = tmp_type4_msg->scr.message; inp_tgt_len = sizeof(tmp_type4_msg->scr.message); } else { tmp_type4_msg->lcr.header.msg_fmt = TYPE4_LCR_FMT; tmp_type4_msg->lcr.header.msg_len = TYPE4_LCR_LEN; p_tgt = tmp_type4_msg->lcr.p; p_tgt_len = sizeof(tmp_type4_msg->lcr.p); q_tgt = tmp_type4_msg->lcr.q; q_tgt_len = sizeof(tmp_type4_msg->lcr.q); dp_tgt = tmp_type4_msg->lcr.dp; dp_tgt_len = sizeof(tmp_type4_msg->lcr.dp); dq_tgt = tmp_type4_msg->lcr.dq; dq_tgt_len = sizeof(tmp_type4_msg->lcr.dq); u_tgt = tmp_type4_msg->lcr.u; u_tgt_len = sizeof(tmp_type4_msg->lcr.u); inp_tgt = tmp_type4_msg->lcr.message; inp_tgt_len = sizeof(tmp_type4_msg->lcr.message); } p_tgt += (p_tgt_len - long_len); if (copy_from_user(p_tgt, icaMsg_p->np_prime, long_len)) return SEN_RELEASED; if (is_empty(p_tgt, long_len)) return SEN_USER_ERROR; q_tgt += (q_tgt_len - short_len); if (copy_from_user(q_tgt, icaMsg_p->nq_prime, short_len)) return SEN_RELEASED; if (is_empty(q_tgt, short_len)) return SEN_USER_ERROR; dp_tgt += (dp_tgt_len - long_len); if (copy_from_user(dp_tgt, icaMsg_p->bp_key, long_len)) return SEN_RELEASED; if (is_empty(dp_tgt, long_len)) return SEN_USER_ERROR; dq_tgt += (dq_tgt_len - short_len); if (copy_from_user(dq_tgt, icaMsg_p->bq_key, short_len)) return SEN_RELEASED; if (is_empty(dq_tgt, short_len)) return SEN_USER_ERROR; u_tgt += (u_tgt_len - long_len); if (copy_from_user(u_tgt, icaMsg_p->u_mult_inv, long_len)) return SEN_RELEASED; if (is_empty(u_tgt, long_len)) return SEN_USER_ERROR; inp_tgt += (inp_tgt_len - mod_len); if (copy_from_user(inp_tgt, icaMsg_p->inputdata, mod_len)) return SEN_RELEASED; if (is_empty(inp_tgt, mod_len)) return SEN_USER_ERROR; *z90cMsg_l_p = tmp_size - CALLER_HEADER; return 0;}static intICAMEX_msg_to_type6MEX_de_msg(struct ica_rsa_modexpo *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; unsigned char *temp; struct type6_hdr *tp6Hdr_p; struct CPRB *cprb_p; struct cca_private_ext_ME *key_p; static int deprecated_msg_count = 0; mod_len = icaMsg_p->inputdatalength; tmp_size = FIXED_TYPE6_ME_LEN + mod_len; total_CPRB_len = tmp_size - sizeof(struct type6_hdr); parmBlock_l = total_CPRB_len - sizeof(struct CPRB); tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER; memset(z90cMsg_p, 0, tmp_size); temp = (unsigned char *)z90cMsg_p + CALLER_HEADER; memcpy(temp, &static_type6_hdr, sizeof(struct type6_hdr)); tp6Hdr_p = (struct type6_hdr *)temp; tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4); tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE; temp += sizeof(struct type6_hdr); memcpy(temp, &static_cprb, sizeof(struct CPRB)); cprb_p = (struct CPRB *) temp; cprb_p->usage_domain[0]= (unsigned char)cdx; itoLe2(&parmBlock_l, cprb_p->req_parml); itoLe2((int *)&(tp6Hdr_p->FromCardLen1), cprb_p->rpl_parml); temp += sizeof(struct CPRB); memcpy(temp, &static_pkd_function_and_rules, sizeof(struct function_and_rules_block)); temp += sizeof(struct function_and_rules_block); vud_len = 2 + icaMsg_p->inputdatalength; itoLe2(&vud_len, temp); temp += 2; if (copy_from_user(temp, icaMsg_p->inputdata, mod_len)) return SEN_RELEASED; if (is_empty(temp, mod_len)) return SEN_USER_ERROR; temp += mod_len; memcpy(temp, &static_T6_keyBlock_hdr, sizeof(struct T6_keyBlock_hdr)); temp += sizeof(struct T6_keyBlock_hdr); memcpy(temp, &static_pvt_me_key, sizeof(struct cca_private_ext_ME)); key_p = (struct cca_private_ext_ME *)temp; temp = key_p->pvtMESec.exponent + sizeof(key_p->pvtMESec.exponent) - mod_len; if (copy_from_user(temp, icaMsg_p->b_key, mod_len)) return SEN_RELEASED; if (is_empty(temp, mod_len)) return SEN_USER_ERROR; if (is_common_public_key(temp, mod_len)) { if (deprecated_msg_count < 20) { PRINTK("Common public key used for modex decrypt\n"); deprecated_msg_count++; if (deprecated_msg_count == 20) PRINTK("No longer issuing messages about common" " public key for modex decrypt.\n"); } return SEN_NOT_AVAIL; } temp = key_p->pvtMESec.modulus + sizeof(key_p->pvtMESec.modulus) - mod_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->pubMESec.modulus_bit_len = 8 * mod_len; *z90cMsg_l_p = tmp_size - CALLER_HEADER; return 0;}static intICAMEX_msg_to_type6MEX_en_msg(struct ica_rsa_modexpo *icaMsg_p, int cdx, int *z90cMsg_l_p, struct type6_msg *z90cMsg_p){ int mod_len, vud_len, exp_len, key_len; int pad_len, tmp_size, total_CPRB_len, parmBlock_l, i; unsigned char *temp_exp, *exp_p, *temp; struct type6_hdr *tp6Hdr_p; struct CPRB *cprb_p; struct cca_public_key *key_p; struct T6_keyBlock_hdr *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_LEN + 2 * mod_len + exp_len; total_CPRB_len = tmp_size - sizeof(struct type6_hdr); parmBlock_l = total_CPRB_len - sizeof(struct CPRB); tmp_size = 4*((tmp_size + 3)/4) + CALLER_HEADER; vud_len = 2 + mod_len; memset(z90cMsg_p, 0, tmp_size); temp = (unsigned char *)z90cMsg_p + CALLER_HEADER; memcpy(temp, &static_type6_hdr, sizeof(struct type6_hdr)); tp6Hdr_p = (struct type6_hdr *)temp; tp6Hdr_p->ToCardLen1 = 4*((total_CPRB_len+3)/4); tp6Hdr_p->FromCardLen1 = RESPONSE_CPRB_SIZE; memcpy(tp6Hdr_p->function_code, static_PKE_function_code, sizeof(static_PKE_function_code)); temp += sizeof(struct type6_hdr); memcpy(temp, &static_cprb, sizeof(struct CPRB)); cprb_p = (struct CPRB *) temp; cprb_p->usage_domain[0]= (unsigned char)cdx; itoLe2((int *)&(tp6Hdr_p->FromCardLen1), cprb_p->rpl_parml); temp += sizeof(struct CPRB); memcpy(temp, &static_pke_function_and_rules, sizeof(struct function_and_rules_block)); temp += sizeof(struct function_and_rules_block); temp += 2; if (copy_from_user(temp, icaMsg_p->inputdata, mod_len)) { kfree(temp_exp); return SEN_RELEASED; } if (is_empty(temp, mod_len)) { kfree(temp_exp); return SEN_USER_ERROR; } if ((temp[0] != 0x00) || (temp[1] != 0x02)) { kfree(temp_exp); return SEN_NOT_AVAIL; } for (i = 2; i < mod_len; i++) if (temp[i] == 0x00) break; if ((i < 9) || (i > (mod_len - 2))) { kfree(temp_exp); return SEN_NOT_AVAIL; } pad_len = i + 1; vud_len = mod_len - pad_len; memmove(temp, temp+pad_len, vud_len); temp -= 2; vud_len += 2; itoLe2(&vud_len, temp); temp += (vud_len); keyb_p = (struct T6_keyBlock_hdr *)temp; temp += sizeof(struct T6_keyBlock_hdr); memcpy(temp, &static_public_key, sizeof(static_public_key)); key_p = (struct cca_public_key *)temp; 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -