mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-24 23:25:40 -07:00
security level logic
This commit is contained in:
parent
54e7713a9a
commit
9857094274
3 changed files with 38 additions and 2 deletions
|
@ -13,6 +13,7 @@
|
||||||
#include "commonutil.h" // ARRAYLEN
|
#include "commonutil.h" // ARRAYLEN
|
||||||
#include "comms.h" // DropField
|
#include "comms.h" // DropField
|
||||||
#include "util_posix.h" // msleep
|
#include "util_posix.h" // msleep
|
||||||
|
#include <string.h> // memcpy memset
|
||||||
|
|
||||||
#include "cmdhf14a.h"
|
#include "cmdhf14a.h"
|
||||||
#include "emv/emvcore.h"
|
#include "emv/emvcore.h"
|
||||||
|
@ -37,6 +38,10 @@ static int CIPURSEExchangeEx(bool ActivateField, bool LeaveFieldON, sAPDU apdu,
|
||||||
msleep(50);
|
msleep(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// long messages is not allowed
|
||||||
|
if (apdu.Lc > 228)
|
||||||
|
return 20;
|
||||||
|
|
||||||
// COMPUTE APDU
|
// COMPUTE APDU
|
||||||
int datalen = 0;
|
int datalen = 0;
|
||||||
uint16_t xle = IncludeLe ? 0x100 : 0x00;
|
uint16_t xle = IncludeLe ? 0x100 : 0x00;
|
||||||
|
@ -144,6 +149,7 @@ bool CIPURSEChannelAuthenticate(uint8_t keyIndex, uint8_t *key, bool verbose) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
PrintAndLogEx(INFO, "Authentication " _GREEN_("OK"));
|
PrintAndLogEx(INFO, "Authentication " _GREEN_("OK"));
|
||||||
|
|
||||||
|
CipurseCChannelSetSecurityLevels(&cpc, CPSMACed, CPSMACed);
|
||||||
memcpy(&cipurseContext, &cpc, sizeof(CipurseContext));
|
memcpy(&cipurseContext, &cpc, sizeof(CipurseContext));
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -25,6 +25,16 @@
|
||||||
uint8_t AESData0[CIPURSE_AES_KEY_LENGTH] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
uint8_t AESData0[CIPURSE_AES_KEY_LENGTH] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
uint8_t QConstant[CIPURSE_AES_KEY_LENGTH] = {0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73};
|
uint8_t QConstant[CIPURSE_AES_KEY_LENGTH] = {0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73};
|
||||||
|
|
||||||
|
uint8_t CipurseCSecurityLevelEnc(CipurseChannelSecurityLevel lvl) {
|
||||||
|
switch (lvl) {
|
||||||
|
case CPSNone: return 0x00;
|
||||||
|
case CPSPlain: return 0x00;
|
||||||
|
case CPSMACed: return 0x01;
|
||||||
|
case CPSEncrypted: return 0x02;
|
||||||
|
default: return 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void bin_xor(uint8_t *d1, uint8_t *d2, size_t len) {
|
static void bin_xor(uint8_t *d1, uint8_t *d2, size_t len) {
|
||||||
for(size_t i = 0; i < len; i++)
|
for(size_t i = 0; i < len; i++)
|
||||||
d1[i] = d1[i] ^ d2[i];
|
d1[i] = d1[i] ^ d2[i];
|
||||||
|
@ -152,6 +162,11 @@ void CipurseCSetKey(CipurseContext *ctx, uint8_t keyId, uint8_t *key) {
|
||||||
memcpy(ctx->key, key, member_size(CipurseContext, key));
|
memcpy(ctx->key, key, member_size(CipurseContext, key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CipurseCChannelSetSecurityLevels(CipurseContext *ctx, CipurseChannelSecurityLevel req, CipurseChannelSecurityLevel resp) {
|
||||||
|
ctx->RequestSecurity = req;
|
||||||
|
ctx->ResponseSecurity = resp;
|
||||||
|
}
|
||||||
|
|
||||||
void CipurseCSetRandomFromPICC(CipurseContext *ctx, uint8_t *random) {
|
void CipurseCSetRandomFromPICC(CipurseContext *ctx, uint8_t *random) {
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -165,6 +180,13 @@ void CipurseCSetRandomHost(CipurseContext *ctx) {
|
||||||
memset(ctx->rT, 0x20, member_size(CipurseContext, rT));
|
memset(ctx->rT, 0x20, member_size(CipurseContext, rT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t CipurseCGetSMI(CipurseContext *ctx, bool LePresent) {
|
||||||
|
uint8_t res = LePresent ? 1 : 0;
|
||||||
|
res = res | (CipurseCSecurityLevelEnc(ctx->RequestSecurity) << 2);
|
||||||
|
res = res | (CipurseCSecurityLevelEnc(ctx->ResponseSecurity) << 6);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static void CipurseCFillAuthData(CipurseContext *ctx, uint8_t *authdata) {
|
static void CipurseCFillAuthData(CipurseContext *ctx, uint8_t *authdata) {
|
||||||
memcpy(authdata, ctx->cP, member_size(CipurseContext, cP));
|
memcpy(authdata, ctx->cP, member_size(CipurseContext, cP));
|
||||||
memcpy(&authdata[member_size(CipurseContext, cP)], ctx->RT, member_size(CipurseContext, RT));
|
memcpy(&authdata[member_size(CipurseContext, cP)], ctx->RT, member_size(CipurseContext, RT));
|
||||||
|
|
|
@ -22,12 +22,12 @@
|
||||||
|
|
||||||
#define member_size(type, member) sizeof(((type *)0)->member)
|
#define member_size(type, member) sizeof(((type *)0)->member)
|
||||||
|
|
||||||
enum CipurseChannelSecurityLevel {
|
typedef enum {
|
||||||
CPSNone,
|
CPSNone,
|
||||||
CPSPlain,
|
CPSPlain,
|
||||||
CPSMACed,
|
CPSMACed,
|
||||||
CPSEncrypted
|
CPSEncrypted
|
||||||
};
|
} CipurseChannelSecurityLevel;
|
||||||
|
|
||||||
typedef struct CipurseContextS {
|
typedef struct CipurseContextS {
|
||||||
uint8_t keyId;
|
uint8_t keyId;
|
||||||
|
@ -44,16 +44,24 @@ typedef struct CipurseContextS {
|
||||||
|
|
||||||
uint8_t frameKey[CIPURSE_AES_KEY_LENGTH];
|
uint8_t frameKey[CIPURSE_AES_KEY_LENGTH];
|
||||||
uint8_t frameKeyNext[CIPURSE_AES_KEY_LENGTH];
|
uint8_t frameKeyNext[CIPURSE_AES_KEY_LENGTH];
|
||||||
|
|
||||||
|
CipurseChannelSecurityLevel RequestSecurity;
|
||||||
|
CipurseChannelSecurityLevel ResponseSecurity;
|
||||||
} CipurseContext;
|
} CipurseContext;
|
||||||
|
|
||||||
|
uint8_t CipurseCSecurityLevelEnc(CipurseChannelSecurityLevel lvl);
|
||||||
|
|
||||||
void CipurseCClearContext(CipurseContext *ctx);
|
void CipurseCClearContext(CipurseContext *ctx);
|
||||||
void CipurseCSetKey(CipurseContext *ctx, uint8_t keyId, uint8_t *key);
|
void CipurseCSetKey(CipurseContext *ctx, uint8_t keyId, uint8_t *key);
|
||||||
void CipurseCSetRandomFromPICC(CipurseContext *ctx, uint8_t *random);
|
void CipurseCSetRandomFromPICC(CipurseContext *ctx, uint8_t *random);
|
||||||
void CipurseCSetRandomHost(CipurseContext *ctx);
|
void CipurseCSetRandomHost(CipurseContext *ctx);
|
||||||
|
uint8_t CipurseCGetSMI(CipurseContext *ctx, bool LePresent);
|
||||||
|
|
||||||
void CipurseCAuthenticateHost(CipurseContext *ctx, uint8_t *authdata);
|
void CipurseCAuthenticateHost(CipurseContext *ctx, uint8_t *authdata);
|
||||||
bool CipurseCCheckCT(CipurseContext *ctx, uint8_t *CT);
|
bool CipurseCCheckCT(CipurseContext *ctx, uint8_t *CT);
|
||||||
|
|
||||||
|
void CipurseCChannelSetSecurityLevels(CipurseContext *ctx, CipurseChannelSecurityLevel req, CipurseChannelSecurityLevel resp);
|
||||||
|
|
||||||
void AddISO9797M2Padding(uint8_t *ddata, size_t *ddatalen, uint8_t *sdata, size_t sdatalen, size_t blocklen);
|
void AddISO9797M2Padding(uint8_t *ddata, size_t *ddatalen, uint8_t *sdata, size_t sdatalen, size_t blocklen);
|
||||||
size_t FindISO9797M2PaddingDataLen(uint8_t *data, size_t datalen);
|
size_t FindISO9797M2PaddingDataLen(uint8_t *data, size_t datalen);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue