📄 sccom.c
字号:
/*----------------------------------------------------------*/ /* Statements */ /*----------------------------------------------------------*/ out_apdu->nbytes = 0; out_apdu->bytes = NULL;#ifdef STREAM fprintf(sc_trfp, "TRACE in sc_checkmac\n"); fprintf(sc_trfp, " in_apdu->nbytes = %d\n", in_apdu->nbytes); fprintf(sc_trfp, " in_apdu->bytes = \n"); aux_fxdump(sc_trfp, in_apdu->bytes, in_apdu->nbytes, 0); fprintf(sc_trfp, " sec_key->nbits = %d\n", sec_key->nbits / 8); fprintf(sc_trfp, " sec_key->bits = \n"); aux_fxdump(sc_trfp, sec_key->bits, sec_key->nbits / 8, 0);#endif if (in_apdu->nbytes == 3) { /* only L,SW1,SW2 received */ out_apdu->nbytes = in_apdu->nbytes;#ifdef MALLOC out_apdu->bytes = malloc(out_apdu->nbytes); /* if no error => return */ if (out_apdu->bytes == NULL) { sc_errno = EMEMAVAIL; sc_errmsg = sct_error[sc_errno].msg; return (-1); }#endif /* copy L,SW1,SW2 into out_apdu->bytes */ ptr = out_apdu->bytes; for (i = 0; i < 3; i++) *ptr++ = *(in_apdu->bytes + i);#ifdef STREAM fprintf(sc_trfp, " out_apdu->nbytes = %d\n", out_apdu->nbytes); fprintf(sc_trfp, " out_apdu->bytes = \n"); aux_fxdump(sc_trfp, out_apdu->bytes, out_apdu->nbytes, 0); fprintf(sc_trfp, "TRACE-END in sc_checkmac\n");#endif return (0); } in_octets.noctets = *in_apdu->bytes + 4; /* 4 = * L,SSC,DATA,SW1,SW2 */ mac_field = in_apdu->bytes + (*in_apdu->bytes + 2); mac_len = in_apdu->nbytes - in_octets.noctets;#ifdef MALLOC in_octets.octets = malloc(in_octets.noctets); /* will be set free in * this proc. */ if (in_octets.octets == NULL) { sc_errno = EMEMAVAIL; sc_errmsg = sct_error[sc_errno].msg; return (-1); }#endif /* copy L,SSC,DATA,SW1,SW2 from in_apdu->bytes into in_octets.octets */ ptr = in_octets.octets; apdu_ptr = in_apdu->bytes; *ptr = *apdu_ptr++; /* Length-field */ data_len = *ptr; ptr++; *ptr = *apdu_ptr++; /* SSC */ rec_ssc = *ptr & 0xFF; ptr++; for (i = 0; i < data_len; i++) { /* Data */ *ptr = *apdu_ptr++; ptr++; } apdu_ptr = in_apdu->bytes + (in_apdu->nbytes - 2); *ptr++ = *apdu_ptr++; /* SW1 */ *ptr = *apdu_ptr; /* SW2 */ /*---------------------------------------------------------*/ /* encrypt data (L,SSC,DATA,SW1,SW2) */ /* with Secure Messaging Key */ /*---------------------------------------------------------*/#ifdef STREAM fprintf(sc_trfp, " in_octets.noctets = %d\n", in_octets.noctets); fprintf(sc_trfp, " in_octets.octets = \n"); aux_fxdump(sc_trfp, in_octets.octets, in_octets.noctets, 0); fprintf(sc_trfp, " rec_ssc = %x\n", rec_ssc); fprintf(sc_trfp, " akt_ssc = %x\n", (ssc & 0xFF) % 256); fprintf(sc_trfp, " mac_len = %d\n", mac_len); fprintf(sc_trfp, " mac_field = \n"); aux_fxdump(sc_trfp, mac_field, mac_len, 0);#endif key_info.subjectkey.nbits = sec_key->nbits; key_info.subjectkey.bits = sec_key->bits; switch (algenc) { case DES: key_info.subjectAI = desCBC; break; default: aux_free2_OctetString(&in_octets); sc_errno = EALGO; sc_errmsg = sct_error[sc_errno].msg; return (-1); break; } more = END; /* allocate memory for out_bits */ /* the memory must be a multiple of 8 Bytes */ if ((in_octets.noctets % 8) != 0) memolen = (in_octets.noctets - (in_octets.noctets % 8)) + 8; else memolen = in_octets.noctets; out_bits.nbits = 0;#ifdef STREAM fprintf(sc_trfp, " allocate out_bits = %d\n", memolen);#endif#ifdef MALLOC out_bits.bits = malloc(memolen); /* will be set free in this * proc. */ if (out_bits.bits == NULL) { sc_errno = EMEMAVAIL; sc_errmsg = sct_error[sc_errno].msg; aux_free2_OctetString(&in_octets); return (-1); }#endif memolen = des_encrypt(&in_octets, &out_bits, more, &key_info); if (memolen == -1) { sc_errno = EDESENC; sc_errmsg = sct_error[sc_errno].msg; aux_free2_OctetString(&in_octets); aux_free2_BitString(&out_bits); return (-1); }#ifdef STREAM fprintf(sc_trfp, " out_bits.nbits = %d\n", out_bits.nbits); fprintf(sc_trfp, " out_bits.bits = \n"); aux_fxdump(sc_trfp, out_bits.bits, out_bits.nbits / 8, 0);#endif /* check SSC */ if (rec_ssc != ((ssc & 0xFF) % 256)) { sc_errno = ESSC; sc_errmsg = sct_error[sc_errno].msg; aux_free2_OctetString(&in_octets); aux_free2_BitString(&out_bits); return (-1); } /* check MAC */ if (mac_len != maclen) { sc_errno = EMAC; sc_errmsg = sct_error[sc_errno].msg; aux_free2_OctetString(&in_octets); aux_free2_BitString(&out_bits); return (-1); } /* if only 1 block encrypted => take the first 4 Bytes for MAC */ /* else take the last 4 bytes of the last block */ if ((out_bits.nbits / 8) > 8) mac_ptr = out_bits.bits + ((out_bits.nbits / 8) - 8); else mac_ptr = out_bits.bits;#ifdef STREAM fprintf(sc_trfp, " mac_ptr = \n"); aux_fxdump(sc_trfp, mac_ptr, mac_len, 0);#endif for (i = 0; i < mac_len; i++) { if (mac_field[i] != *(mac_ptr + i)) { sc_errno = EMAC; sc_errmsg = sct_error[sc_errno].msg; aux_free2_OctetString(&in_octets); aux_free2_BitString(&out_bits); return (-1); } } memolen = in_octets.noctets - 1; /* - SSC-Byte */#ifdef MALLOC out_apdu->bytes = malloc(memolen); /* if no error => return */ /* else will be set free in this proc. */ if (out_apdu->bytes == NULL) { sc_errno = EMEMAVAIL; sc_errmsg = sct_error[sc_errno].msg; aux_free2_OctetString(&in_octets); aux_free2_BitString(&out_bits); return (-1); }#endif out_apdu->nbytes = memolen; ptr = out_apdu->bytes; *ptr++ = *in_octets.octets; for (i = 2; i < in_octets.noctets; i++) { *ptr = *(in_octets.octets + i); ptr++; } aux_free2_OctetString(&in_octets); aux_free2_BitString(&out_bits);#ifdef STREAM fprintf(sc_trfp, " out_apdu->nbytes = %d\n", out_apdu->nbytes); fprintf(sc_trfp, " out_apdu->bytes = \n"); aux_fxdump(sc_trfp, out_apdu->bytes, out_apdu->nbytes, 0); fprintf(sc_trfp, "TRACE-END in sc_checkmac\n");#endif return (0);}/*-------------------------------------------------------------*//* E N D O F P R O C E D U R E sc_checkmac *//*-------------------------------------------------------------*//*--------------------------------------------------------*//* | GMD *//* +-----*//* PROC sc_dec VERSION 2.0 *//* DATE November 1991 *//* BY L.Eckstein,GMD *//* *//* DESCRIPTION *//* Decrypt SEC-RESPONSE-APDU *//* This procedure can be called in case of *//* secure messaging = CONCEALED or in case of *//* secure messaging = COMBINED before calling the *//* procedure sc_checkmac. *//* In case of seucre messaging = CONCEALED this procedure*//* also checks the SSC. *//* In case of secure messaging = COMBINED the calling *//* procedure must set the parameter maclen. *//* This parameter will be need to allocate the *//* buffer out_apdu->bytes correctly. *//* *//* *//* *//* IN DESCRIPTION *//* sec_key Secure Messaging key *//* *//* sec_mode security mode *//* *//* ssc Send Sequence Counter *//* only used in case of *//* sec_mode = CONCEALED *//* *//* in_apdu Pointer of SEC-APDU *//* The SEC-APDU have the */ /* * structure *//* _______________ __ *//* | ENCRYPTED DATA | *//* _________________ *//* or *//* _________________ *//* | L = 0,SW1,SW2 | *//* _________________ *//* algenc Encryption method *//* *//* maclen Length of MAC *//* Only used in case of *//* sec_mode = COMBINED; *//* (COMBINED-Mode) *//* *//* OUT *//* out_apdu Pointer of SC-APDU *//* out_apdu->bytes will be *//* allocated by the called *//* program *//* and must be set free by the*//* calling program *//* The APDU has the structure:*//* _________________ *//* | L,DATA,SW1,SW2 | *//* _________________ *//* or *//* ________________________ *//* | L,SSC,DATA,MAC,SW1,SW2 | *//* ________________________ *//* *//* *//* RETURN DESCRIPTION *//* 0 o.k *//* -1 Error *//* EMEMAVAIL *//* EDESDEC *//* ESSC *//* EALGO *//* *//* CALLED FUNCTIONS *//* des_decrypt *//* aux_fxdump *//* sta_aux_bytestr_free *//* aux_free2_OctetString *//* Bemerkung: *//* Derzeit wird nur der DES-CBC-Mode unterstuetzt. *//* Der DES-3-CBC-Mode noch nicht. *//*--------------------------------------------------------*/intsc_dec(sec_key, sec_mode, ssc, in_apdu, out_apdu, algenc, maclen) BitString *sec_key;/* secure messaging key */ SecMessMode sec_mode; /* security mode */ int ssc; /* Send sequence Counter */ Bytestring *in_apdu;/* SEC-APDU */ Bytestring *out_apdu; /* SC-APDU */ AlgEnc algenc; /* encryption method */ int maclen; /* MAC-Length */{ /*----------------------------------------------------------*/ /* Definitions */ /*----------------------------------------------------------*/ OctetString out_octets; char *ptr, *apdu_ptr; int i; int memolen; BitString in_bits; KeyInfo key_info; More more; int rec_ssc, data_len; /*----------------------------------------------------------*/ /* Statements */ /*----------------------------------------------------------*/#ifdef STREAM fprintf(sc_trfp, "TRACE in sc_dec\n"); fprintf(sc_trfp, " in_apdu->nbytes = %d\n", in_apdu->nbytes); fprintf(sc_trfp, " in_apdu->bytes = \n"); aux_fxdump(sc_trfp, in_apdu->bytes, in_apdu->nbytes, 0);#endif if (in_apdu->nbytes == 3) { /* only L,SW1,SW2 received */ out_apdu->nbytes = in_apdu->nbytes;#ifdef MALLOC out_apdu->bytes = malloc(out_apdu->nbytes); /* if no error => return */ /* else will be set free in this proc. */ if (out_apdu->bytes == NULL) { sc_errno = EMEMAVAIL; sc_errmsg = sct_error[sc_errno].msg; return (-1); }#endif /* copy L,SW1,SW2 into out_apdu->bytes */ ptr = out_apdu->bytes; for (i = 0; i < 3; i++) { *ptr = *(in_apdu->bytes + i); ptr++; }#ifdef STREAM fprintf(sc_trfp, " out_apdu->nbytes = %d\n", out_apdu->nbytes); fprintf(sc_trfp, " out_apdu->bytes = \n"); aux_fxdump(sc_trfp, out_apdu->bytes, out_apdu->nbytes, 0); fprintf(sc_trfp, "TRACE-END in sc_dec\n");#endif return (0); } /*---------------------------------------------------------*/ /* decrypt data */ /* with Secure Messaging Key */ /*---------------------------------------------------------*/ /* allocate memory for out_octets */ out_octets.noctets = 0;#ifdef MALLOC out_octets.octets = malloc(in_apdu->nbytes); /* will be set free in * this proc. */ if (out_octets.octets == NULL) { sc_errno = EMEMAVAIL; sc_errmsg = sct_error[sc_errno].msg; return (-1); }#endif key_info.subjectkey.nbits =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -