mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-02-24 08:05:13 +08:00
authentication works
This commit is contained in:
parent
1a937b33c4
commit
1ba9606011
3 changed files with 21 additions and 35 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue