authentication works

This commit is contained in:
merlokk 2021-05-29 19:46:51 +03:00
parent 1a937b33c4
commit 1ba9606011
3 changed files with 21 additions and 35 deletions

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
}