+ PrintAndLog("\n--> Mastercard M/Chip transaction.");
+
+ PrintAndLog("* * Generate challenge");
+ res = EMVGenerateChallenge(true, buf, sizeof(buf), &len, &sw, tlvRoot);
+ if (res) {
+ PrintAndLog("ERROR GetChallenge. APDU error %4x", sw);
+ dreturn(6);
+ }
+ if (len < 4) {
+ PrintAndLog("ERROR GetChallenge. Wrong challenge length %d", len);
+ dreturn(6);
+ }
+
+ // ICC Dynamic Number
+ struct tlvdb * ICCDynN = tlvdb_fixed(0x9f4c, len, buf);
+ tlvdb_add(tlvRoot, ICCDynN);
+ if (decodeTLV){
+ PrintAndLog("\n* * ICC Dynamic Number:");
+ TLVPrintFromTLV(ICCDynN);
+ }
+
+ PrintAndLog("* * Calc CDOL1");
+ struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag
+ if (!cdol_data_tlv){
+ PrintAndLog("ERROR: can't create CDOL1 TLV.");
+ dreturn(6);
+ }
+ PrintAndLog("CDOL1 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len));
+
+ PrintAndLog("* * AC1");
+ // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD
+ res = EMVAC(true, (TrType == TT_CDA) ? EMVAC_TC + EMVAC_CDAREQ : EMVAC_TC, (uint8_t *)cdol_data_tlv->value, cdol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
+
+ if (res) {
+ PrintAndLog("AC1 error(%d): %4x. Exit...", res, sw);
+ dreturn(7);
+ }
+
+ if (decodeTLV)
+ TLVPrintFromBuffer(buf, len);
+
+ // CDA
+ PrintAndLog("\n* CDA:");
+ struct tlvdb *ac_tlv = tlvdb_parse_multi(buf, len);
+ res = trCDA(tlvRoot, ac_tlv, pdol_data_tlv, cdol_data_tlv);
+ if (res) {
+ PrintAndLog("CDA error (%d)", res);
+ }
+ free(ac_tlv);
+ free(cdol_data_tlv);
+
+ PrintAndLog("\n* M/Chip transaction result:");
+ // 9F27: Cryptogram Information Data (CID)
+ const struct tlv *CID = tlvdb_get(tlvRoot, 0x9F27, NULL);
+ if (CID) {
+ emv_tag_dump(CID, stdout, 0);
+ PrintAndLog("------------------------------");
+ if (CID->len > 0) {
+ switch(CID->value[0] & EMVAC_AC_MASK){
+ case EMVAC_AAC:
+ PrintAndLog("Transaction DECLINED.");
+ break;
+ case EMVAC_TC:
+ PrintAndLog("Transaction approved OFFLINE.");
+ break;
+ case EMVAC_ARQC:
+ PrintAndLog("Transaction approved ONLINE.");
+ break;
+ default:
+ PrintAndLog("ERROR: CID transaction code error %2x", CID->value[0] & EMVAC_AC_MASK);
+ break;
+ }
+ } else {
+ PrintAndLog("ERROR: Wrong CID length %d", CID->len);
+ }
+ } else {
+ PrintAndLog("ERROR: CID(9F27) not found.");
+ }