diff --git a/client/src/cipurse/cipursecrypto.c b/client/src/cipurse/cipursecrypto.c index 9da227d58..14dd8c3a5 100644 --- a/client/src/cipurse/cipursecrypto.c +++ b/client/src/cipurse/cipursecrypto.c @@ -53,7 +53,7 @@ static void bin_pad2(uint8_t *dst, size_t dstlen, uint8_t *src, size_t srclen) { static uint64_t rotateLeft48(uint64_t src) { uint64_t dst = src << 1; - if (dst && 0x0001000000000000UL != 0) { + if (dst & 0x0001000000000000UL) { dst = dst | 1; dst = dst & 0x0000ffffffffffffUL; } @@ -70,7 +70,7 @@ static uint64_t computeNLM48(uint64_t x, uint64_t y) { y = rotateLeft48(y); if (y & 1) res = res ^ x; - } + } return res; } @@ -91,31 +91,7 @@ static void computeNLM(uint8_t *res, uint8_t *x, uint8_t *y) { } } -static void CipurseCGenerateK0AndCp(CipurseContext *ctx) { - /* // session key derivation function - // kP := NLM(EXT(kID), rP) - // k0 := AES(key=PAD2(kP) XOR PAD(rT),kID) XOR kID - var temp1 = CryptoUtils.extFunction(kid, CIPURSE_SECURITY_PARAM_N) ?: return null - val kp = CryptoUtils.computeNLM(rP, temp1) ?: return null - temp1 = CryptoUtils.pad2(kp) ?: return null - val temp2 = CryptoUtils.pad(rT) ?: return null - temp1 = temp1 xor temp2 - - // session key K0 - k0 = AesECB.aesEncrypt(temp1, kid) ?: return null - k0 = k0 xor kid - - // first frame key k1, function to calculate k1, - // k1 := AES(key = RP; k0 XOR RT) XOR (k0 XOR RT) - temp1 = k0 xor RT - val temp3: ByteArray = AesECB.aesEncrypt(RP, temp1) ?: return null - frameKeyi = temp3 xor temp1 - Log.d(TAG, "frame key=${Utils.toHex(frameKeyi)}") - - // function to caluclate cP := AES(key=k0, RP). - // terminal response - return AesECB.aesEncrypt(k0, RP)*/ - +static void CipurseCGenerateK0AndCp(CipurseContext *ctx) { uint8_t temp1[CIPURSE_AES_KEY_LENGTH] = {0}; uint8_t temp2[CIPURSE_AES_KEY_LENGTH] = {0}; uint8_t kp[CIPURSE_SECURITY_PARAM_N] = {0}; @@ -204,3 +180,7 @@ void CipurseCAuthenticateHost(CipurseContext *ctx, uint8_t *authdata) { if (authdata != NULL) CipurseCFillAuthData(ctx, authdata); } + +bool CipurseCCheckCT(CipurseContext *ctx, uint8_t *CT) { + return (memcmp(CT, ctx->CT, CIPURSE_AES_KEY_LENGTH) == 0); +} diff --git a/client/src/cipurse/cipursecrypto.h b/client/src/cipurse/cipursecrypto.h index 53c171a0c..ca1ed29f3 100644 --- a/client/src/cipurse/cipursecrypto.h +++ b/client/src/cipurse/cipursecrypto.h @@ -51,6 +51,7 @@ void CipurseCSetRandomFromPICC(CipurseContext *ctx, uint8_t *random); void CipurseCSetRandomHost(CipurseContext *ctx); void CipurseCAuthenticateHost(CipurseContext *ctx, uint8_t *authdata); +bool CipurseCCheckCT(CipurseContext *ctx, uint8_t *CT); void CipurseCGetKVV(uint8_t *key, uint8_t *kvv); diff --git a/client/src/cmdhfcipurse.c b/client/src/cmdhfcipurse.c index 1bb3e83d5..cea5755f4 100644 --- a/client/src/cmdhfcipurse.c +++ b/client/src/cmdhfcipurse.c @@ -87,7 +87,7 @@ static int CmdHFCipurseAuth(const char *Cmd) { uint16_t sw = 0; uint8_t keyId = 1; uint8_t key[] = {0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73}; - + CLIParserContext *ctx; CLIParserInit(&ctx, "hf 14a sim", "Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID", @@ -130,12 +130,12 @@ static int CmdHFCipurseAuth(const char *Cmd) { } CipurseContext cpc = {0}; - CipurseCSetKey(&cpc, 1, key); + CipurseCSetKey(&cpc, keyId, key); uint8_t kvv[CIPURSE_KVV_LENGTH] = {0}; CipurseCGetKVV(key, kvv); if (verbose) - PrintAndLogEx(INFO, "Key: %s KVV: %s", sprint_hex(key, CIPURSE_AES_KEY_LENGTH), sprint_hex_inrow(kvv, CIPURSE_KVV_LENGTH)); + PrintAndLogEx(INFO, "Key id: %d key: %s KVV: %s", keyId, sprint_hex(key, CIPURSE_AES_KEY_LENGTH), sprint_hex_inrow(kvv, CIPURSE_KVV_LENGTH)); // get RP, rP res = CIPURSEChallenge(buf, sizeof(buf), &len, &sw); @@ -145,24 +145,29 @@ static int CmdHFCipurseAuth(const char *Cmd) { return PM3_ESOFT; } CipurseCSetRandomFromPICC(&cpc, buf); - + // make auth data uint8_t authparams[16 + 16 + 6] = {0}; CipurseCAuthenticateHost(&cpc, authparams); // authenticate res = CIPURSEMutalAuthenticate(keyId, authparams, sizeof(authparams), buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000 || len != 0x16) { + if (res != 0 || sw != 0x9000 || len != 16) { if (sw == 0x6988) - PrintAndLogEx(ERR, "Cipurse authentication error. Wrong key."); + PrintAndLogEx(ERR, "Cipurse authentication " _RED_("error") ". Wrong key."); else if ((sw == 0x6A88)) - PrintAndLogEx(ERR, "Cipurse authentication error. Wrong key number."); - else PrintAndLogEx(ERR, "Cipurse authentication error. Card returns 0x%04x.", sw); + PrintAndLogEx(ERR, "Cipurse authentication " _RED_("error") ". Wrong key number."); + else PrintAndLogEx(ERR, "Cipurse authentication " _RED_("error") ". Card returns 0x%04x.", sw); DropField(); return PM3_ESOFT; } + if (CipurseCCheckCT(&cpc, buf)) + PrintAndLogEx(INFO, "Authentication " _GREEN_("OK")); + else + PrintAndLogEx(ERR, "Authentication " _RED_("ERROR") " card returned wrong CT"); + DropField(); return PM3_SUCCESS; }