mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
rename typedef structs
This commit is contained in:
parent
dd3b63ae32
commit
bae5362656
24 changed files with 196 additions and 196 deletions
|
@ -23,9 +23,9 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
// context for secure channel
|
// context for secure channel
|
||||||
CipurseContext cipurseContext;
|
CipurseContext_t cipurseContext;
|
||||||
|
|
||||||
static int CIPURSEExchangeEx(bool activate_field, bool leave_field_on, sAPDU apdu, bool include_le,
|
static int CIPURSEExchangeEx(bool activate_field, bool leave_field_on, sAPDU_t apdu, bool include_le,
|
||||||
uint16_t le, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
uint16_t le, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||||
|
|
||||||
if (result_len == NULL) {
|
if (result_len == NULL) {
|
||||||
|
@ -57,7 +57,7 @@ static int CIPURSEExchangeEx(bool activate_field, bool leave_field_on, sAPDU apd
|
||||||
xle = le;
|
xle = le;
|
||||||
}
|
}
|
||||||
|
|
||||||
sAPDU secapdu;
|
sAPDU_t secapdu;
|
||||||
uint8_t securedata[APDU_RES_LEN] = {0};
|
uint8_t securedata[APDU_RES_LEN] = {0};
|
||||||
CipurseCAPDUReqEncode(&cipurseContext, &apdu, &secapdu, securedata, include_le, le);
|
CipurseCAPDUReqEncode(&cipurseContext, &apdu, &secapdu, securedata, include_le, le);
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ static int CIPURSEExchangeEx(bool activate_field, bool leave_field_on, sAPDU apd
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CIPURSEExchange(sAPDU apdu, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
static int CIPURSEExchange(sAPDU_t apdu, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||||
return CIPURSEExchangeEx(false, true, apdu, true, 0, result, max_result_len, result_len, sw);
|
return CIPURSEExchangeEx(false, true, apdu, true, 0, result, max_result_len, result_len, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,41 +131,41 @@ int CIPURSESelect(bool activate_field, bool leave_field_on, uint8_t *result, siz
|
||||||
}
|
}
|
||||||
|
|
||||||
int CIPURSEChallenge(uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
int CIPURSEChallenge(uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||||
return CIPURSEExchangeEx(false, true, (sAPDU) {0x00, 0x84, 0x00, 0x00, 0x00, NULL}, true, 0x16, result, max_result_len, result_len, sw);
|
return CIPURSEExchangeEx(false, true, (sAPDU_t) {0x00, 0x84, 0x00, 0x00, 0x00, NULL}, true, 0x16, result, max_result_len, result_len, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CIPURSEMutalAuthenticate(uint8_t keyindex, uint8_t *params, uint8_t paramslen, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
int CIPURSEMutalAuthenticate(uint8_t keyindex, uint8_t *params, uint8_t paramslen, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||||
return CIPURSEExchangeEx(false, true, (sAPDU) {0x00, 0x82, 0x00, keyindex, paramslen, params}, true, 0x10, result, max_result_len, result_len, sw);
|
return CIPURSEExchangeEx(false, true, (sAPDU_t) {0x00, 0x82, 0x00, keyindex, paramslen, params}, true, 0x10, result, max_result_len, result_len, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CIPURSECreateFile(uint8_t *attr, uint16_t attrlen, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
int CIPURSECreateFile(uint8_t *attr, uint16_t attrlen, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||||
return CIPURSEExchangeEx(false, true, (sAPDU) {0x00, 0xe4, 0x00, 0x00, attrlen, attr}, false, 0, result, max_result_len, result_len, sw);
|
return CIPURSEExchangeEx(false, true, (sAPDU_t) {0x00, 0xe4, 0x00, 0x00, attrlen, attr}, false, 0, result, max_result_len, result_len, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CIPURSEDeleteFile(uint16_t fileid, uint8_t *Result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
int CIPURSEDeleteFile(uint16_t fileid, uint8_t *Result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||||
uint8_t fileIdBin[] = {fileid >> 8, fileid & 0xff};
|
uint8_t fileIdBin[] = {fileid >> 8, fileid & 0xff};
|
||||||
return CIPURSEExchangeEx(false, true, (sAPDU) {0x00, 0xe4, 0x00, 0x00, 02, fileIdBin}, false, 0, Result, max_result_len, result_len, sw);
|
return CIPURSEExchangeEx(false, true, (sAPDU_t) {0x00, 0xe4, 0x00, 0x00, 02, fileIdBin}, false, 0, Result, max_result_len, result_len, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CIPURSESelectFile(uint16_t fileid, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
int CIPURSESelectFile(uint16_t fileid, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||||
uint8_t fileIdBin[] = {fileid >> 8, fileid & 0xff};
|
uint8_t fileIdBin[] = {fileid >> 8, fileid & 0xff};
|
||||||
return CIPURSEExchange((sAPDU) {0x00, 0xa4, 0x00, 0x00, 02, fileIdBin}, result, max_result_len, result_len, sw);
|
return CIPURSEExchange((sAPDU_t) {0x00, 0xa4, 0x00, 0x00, 02, fileIdBin}, result, max_result_len, result_len, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CIPURSESelectMFFile(uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
int CIPURSESelectMFFile(uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||||
return CIPURSEExchange((sAPDU) {0x00, 0xa4, 0x00, 0x00, 0, NULL}, result, max_result_len, result_len, sw);
|
return CIPURSEExchange((sAPDU_t) {0x00, 0xa4, 0x00, 0x00, 0, NULL}, result, max_result_len, result_len, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CIPURSEReadFileAttributes(uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
int CIPURSEReadFileAttributes(uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||||
return CIPURSEExchange((sAPDU) {0x80, 0xce, 0x00, 0x00, 0, NULL}, result, max_result_len, result_len, sw);
|
return CIPURSEExchange((sAPDU_t) {0x80, 0xce, 0x00, 0x00, 0, NULL}, result, max_result_len, result_len, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CIPURSEReadBinary(uint16_t offset, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
int CIPURSEReadBinary(uint16_t offset, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||||
return CIPURSEExchange((sAPDU) {0x00, 0xb0, (offset >> 8) & 0x7f, offset & 0xff, 0, NULL}, result, max_result_len, result_len, sw);
|
return CIPURSEExchange((sAPDU_t) {0x00, 0xb0, (offset >> 8) & 0x7f, offset & 0xff, 0, NULL}, result, max_result_len, result_len, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CIPURSEUpdateBinary(uint16_t offset, uint8_t *data, uint16_t datalen, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
int CIPURSEUpdateBinary(uint16_t offset, uint8_t *data, uint16_t datalen, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||||
return CIPURSEExchange((sAPDU) {0x00, 0xd6, (offset >> 8) & 0x7f, offset & 0xff, datalen, data}, result, max_result_len, result_len, sw);
|
return CIPURSEExchange((sAPDU_t) {0x00, 0xd6, (offset >> 8) & 0x7f, offset & 0xff, datalen, data}, result, max_result_len, result_len, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CIPURSEChannelAuthenticate(uint8_t keyindex, uint8_t *key, bool verbose) {
|
bool CIPURSEChannelAuthenticate(uint8_t keyindex, uint8_t *key, bool verbose) {
|
||||||
|
@ -173,7 +173,7 @@ bool CIPURSEChannelAuthenticate(uint8_t keyindex, uint8_t *key, bool verbose) {
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
uint16_t sw = 0;
|
uint16_t sw = 0;
|
||||||
|
|
||||||
CipurseContext cpc = {0};
|
CipurseContext_t cpc = {0};
|
||||||
CipurseCSetKey(&cpc, keyindex, key);
|
CipurseCSetKey(&cpc, keyindex, key);
|
||||||
|
|
||||||
// get RP, rP
|
// get RP, rP
|
||||||
|
@ -217,7 +217,7 @@ bool CIPURSEChannelAuthenticate(uint8_t keyindex, uint8_t *key, bool verbose) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CipurseCChannelSetSecurityLevels(&cpc, CPSMACed, CPSMACed);
|
CipurseCChannelSetSecurityLevels(&cpc, CPSMACed, CPSMACed);
|
||||||
memcpy(&cipurseContext, &cpc, sizeof(CipurseContext));
|
memcpy(&cipurseContext, &cpc, sizeof(CipurseContext_t));
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "iso7816/apduinfo.h" // sAPDU
|
#include "iso7816/apduinfo.h" // sAPDU_t
|
||||||
#include "cipurse/cipursecrypto.h"
|
#include "cipurse/cipursecrypto.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ static void computeNLM(uint8_t *res, uint8_t *x, uint8_t *y) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CipurseCGenerateK0AndCp(CipurseContext *ctx) {
|
static void CipurseCGenerateK0AndCp(CipurseContext_t *ctx) {
|
||||||
uint8_t temp1[CIPURSE_AES_KEY_LENGTH] = {0};
|
uint8_t temp1[CIPURSE_AES_KEY_LENGTH] = {0};
|
||||||
uint8_t temp2[CIPURSE_AES_KEY_LENGTH] = {0};
|
uint8_t temp2[CIPURSE_AES_KEY_LENGTH] = {0};
|
||||||
uint8_t kp[CIPURSE_SECURITY_PARAM_N] = {0};
|
uint8_t kp[CIPURSE_SECURITY_PARAM_N] = {0};
|
||||||
|
@ -145,59 +145,59 @@ void CipurseCGetKVV(uint8_t *key, uint8_t *kvv) {
|
||||||
memcpy(kvv, res, CIPURSE_KVV_LENGTH);
|
memcpy(kvv, res, CIPURSE_KVV_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CipurseCClearContext(CipurseContext *ctx) {
|
void CipurseCClearContext(CipurseContext_t *ctx) {
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memset(ctx, 0, sizeof(CipurseContext));
|
memset(ctx, 0, sizeof(CipurseContext_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CipurseCSetKey(CipurseContext *ctx, uint8_t keyId, uint8_t *key) {
|
void CipurseCSetKey(CipurseContext_t *ctx, uint8_t keyId, uint8_t *key) {
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CipurseCClearContext(ctx);
|
CipurseCClearContext(ctx);
|
||||||
|
|
||||||
ctx->keyId = keyId;
|
ctx->keyId = keyId;
|
||||||
memcpy(ctx->key, key, member_size(CipurseContext, key));
|
memcpy(ctx->key, key, member_size(CipurseContext_t, key));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CipurseCChannelSetSecurityLevels(CipurseContext *ctx, CipurseChannelSecurityLevel req, CipurseChannelSecurityLevel resp) {
|
void CipurseCChannelSetSecurityLevels(CipurseContext_t *ctx, CipurseChannelSecurityLevel req, CipurseChannelSecurityLevel resp) {
|
||||||
ctx->RequestSecurity = req;
|
ctx->RequestSecurity = req;
|
||||||
ctx->ResponseSecurity = resp;
|
ctx->ResponseSecurity = resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isCipurseCChannelSecuritySet(CipurseContext *ctx) {
|
bool isCipurseCChannelSecuritySet(CipurseContext_t *ctx) {
|
||||||
return ((ctx->RequestSecurity != CPSNone) && (ctx->ResponseSecurity != CPSNone));
|
return ((ctx->RequestSecurity != CPSNone) && (ctx->ResponseSecurity != CPSNone));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CipurseCSetRandomFromPICC(CipurseContext *ctx, uint8_t *random) {
|
void CipurseCSetRandomFromPICC(CipurseContext_t *ctx, uint8_t *random) {
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memcpy(ctx->RP, random, member_size(CipurseContext, RP));
|
memcpy(ctx->RP, random, member_size(CipurseContext_t, RP));
|
||||||
memcpy(ctx->rP, random + member_size(CipurseContext, RP), member_size(CipurseContext, rP));
|
memcpy(ctx->rP, random + member_size(CipurseContext_t, RP), member_size(CipurseContext_t, rP));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CipurseCSetRandomHost(CipurseContext *ctx) {
|
void CipurseCSetRandomHost(CipurseContext_t *ctx) {
|
||||||
memset(ctx->RT, 0x10, member_size(CipurseContext, RT));
|
memset(ctx->RT, 0x10, member_size(CipurseContext_t, RT));
|
||||||
memset(ctx->rT, 0x20, member_size(CipurseContext, rT));
|
memset(ctx->rT, 0x20, member_size(CipurseContext_t, rT));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t CipurseCGetSMI(CipurseContext *ctx, bool LePresent) {
|
uint8_t CipurseCGetSMI(CipurseContext_t *ctx, bool LePresent) {
|
||||||
uint8_t res = LePresent ? 1 : 0;
|
uint8_t res = LePresent ? 1 : 0;
|
||||||
res = res | (CipurseCSecurityLevelEnc(ctx->ResponseSecurity) << 2);
|
res = res | (CipurseCSecurityLevelEnc(ctx->ResponseSecurity) << 2);
|
||||||
res = res | (CipurseCSecurityLevelEnc(ctx->RequestSecurity) << 6);
|
res = res | (CipurseCSecurityLevelEnc(ctx->RequestSecurity) << 6);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CipurseCFillAuthData(CipurseContext *ctx, uint8_t *authdata) {
|
static void CipurseCFillAuthData(CipurseContext_t *ctx, uint8_t *authdata) {
|
||||||
memcpy(authdata, ctx->cP, member_size(CipurseContext, cP));
|
memcpy(authdata, ctx->cP, member_size(CipurseContext_t, cP));
|
||||||
memcpy(&authdata[member_size(CipurseContext, cP)], ctx->RT, member_size(CipurseContext, RT));
|
memcpy(&authdata[member_size(CipurseContext_t, cP)], ctx->RT, member_size(CipurseContext_t, RT));
|
||||||
memcpy(&authdata[member_size(CipurseContext, cP) + member_size(CipurseContext, RT)], ctx->rT, member_size(CipurseContext, rT));
|
memcpy(&authdata[member_size(CipurseContext_t, cP) + member_size(CipurseContext_t, RT)], ctx->rT, member_size(CipurseContext_t, rT));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CipurseCAuthenticateHost(CipurseContext *ctx, uint8_t *authdata) {
|
void CipurseCAuthenticateHost(CipurseContext_t *ctx, uint8_t *authdata) {
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ void CipurseCAuthenticateHost(CipurseContext *ctx, uint8_t *authdata) {
|
||||||
CipurseCFillAuthData(ctx, authdata);
|
CipurseCFillAuthData(ctx, authdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CipurseCCheckCT(CipurseContext *ctx, uint8_t *CT) {
|
bool CipurseCCheckCT(CipurseContext_t *ctx, uint8_t *CT) {
|
||||||
return (memcmp(CT, ctx->CT, CIPURSE_AES_KEY_LENGTH) == 0);
|
return (memcmp(CT, ctx->CT, CIPURSE_AES_KEY_LENGTH) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ bool CipurseCCheckMIC(uint8_t *data, size_t datalen, uint8_t *mic) {
|
||||||
* Dx+1 ), ... hy := AES( key = hy-1 ; q ) XOR q, Cy := AES( key = hy ;
|
* Dx+1 ), ... hy := AES( key = hy-1 ; q ) XOR q, Cy := AES( key = hy ;
|
||||||
* Dy ), ki+1 := hy
|
* Dy ), ki+1 := hy
|
||||||
*/
|
*/
|
||||||
void CipurseCEncryptDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *dstdata, bool isEncrypt) {
|
void CipurseCEncryptDecrypt(CipurseContext_t *ctx, uint8_t *data, size_t datalen, uint8_t *dstdata, bool isEncrypt) {
|
||||||
uint8_t hx[CIPURSE_AES_KEY_LENGTH] = {0};
|
uint8_t hx[CIPURSE_AES_KEY_LENGTH] = {0};
|
||||||
|
|
||||||
if (datalen == 0 || datalen % CIPURSE_AES_KEY_LENGTH != 0)
|
if (datalen == 0 || datalen % CIPURSE_AES_KEY_LENGTH != 0)
|
||||||
|
@ -295,7 +295,7 @@ void CipurseCEncryptDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen,
|
||||||
memcpy(ctx->frameKey, ctx->frameKeyNext, CIPURSE_AES_KEY_LENGTH);
|
memcpy(ctx->frameKey, ctx->frameKeyNext, CIPURSE_AES_KEY_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CipurseCChannelEncrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *encdata, size_t *encdatalen) {
|
void CipurseCChannelEncrypt(CipurseContext_t *ctx, uint8_t *data, size_t datalen, uint8_t *encdata, size_t *encdatalen) {
|
||||||
uint8_t pdata[datalen + CIPURSE_AES_KEY_LENGTH];
|
uint8_t pdata[datalen + CIPURSE_AES_KEY_LENGTH];
|
||||||
size_t pdatalen = 0;
|
size_t pdatalen = 0;
|
||||||
AddISO9797M2Padding(pdata, &pdatalen, data, datalen, CIPURSE_AES_KEY_LENGTH);
|
AddISO9797M2Padding(pdata, &pdatalen, data, datalen, CIPURSE_AES_KEY_LENGTH);
|
||||||
|
@ -304,7 +304,7 @@ void CipurseCChannelEncrypt(CipurseContext *ctx, uint8_t *data, size_t datalen,
|
||||||
*encdatalen = pdatalen;
|
*encdatalen = pdatalen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CipurseCChannelDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *plaindata, size_t *plaindatalen) {
|
void CipurseCChannelDecrypt(CipurseContext_t *ctx, uint8_t *data, size_t datalen, uint8_t *plaindata, size_t *plaindatalen) {
|
||||||
CipurseCEncryptDecrypt(ctx, data, datalen, plaindata, false);
|
CipurseCEncryptDecrypt(ctx, data, datalen, plaindata, false);
|
||||||
*plaindatalen = FindISO9797M2PaddingDataLen(plaindata, datalen);
|
*plaindatalen = FindISO9797M2PaddingDataLen(plaindata, datalen);
|
||||||
}
|
}
|
||||||
|
@ -320,7 +320,7 @@ void CipurseCChannelDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen,
|
||||||
* hy+1 M'i := AES( key = ki ; ki+1 ) XOR ki+1, Mi := m LS bits of M'i = (
|
* hy+1 M'i := AES( key = ki ; ki+1 ) XOR ki+1, Mi := m LS bits of M'i = (
|
||||||
* (M'i )0, (M'i )1, ..., (M'i )m-1)
|
* (M'i )0, (M'i )1, ..., (M'i )m-1)
|
||||||
*/
|
*/
|
||||||
void CipurseCGenerateMAC(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac) {
|
void CipurseCGenerateMAC(CipurseContext_t *ctx, uint8_t *data, size_t datalen, uint8_t *mac) {
|
||||||
uint8_t temp[CIPURSE_AES_KEY_LENGTH] = {0};
|
uint8_t temp[CIPURSE_AES_KEY_LENGTH] = {0};
|
||||||
|
|
||||||
memcpy(ctx->frameKeyNext, ctx->frameKey, CIPURSE_AES_KEY_LENGTH);
|
memcpy(ctx->frameKeyNext, ctx->frameKey, CIPURSE_AES_KEY_LENGTH);
|
||||||
|
@ -339,20 +339,20 @@ void CipurseCGenerateMAC(CipurseContext *ctx, uint8_t *data, size_t datalen, uin
|
||||||
memcpy(mac, temp, CIPURSE_MAC_LENGTH);
|
memcpy(mac, temp, CIPURSE_MAC_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CipurseCCalcMACPadded(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac) {
|
void CipurseCCalcMACPadded(CipurseContext_t *ctx, uint8_t *data, size_t datalen, uint8_t *mac) {
|
||||||
uint8_t pdata[datalen + CIPURSE_AES_KEY_LENGTH];
|
uint8_t pdata[datalen + CIPURSE_AES_KEY_LENGTH];
|
||||||
size_t pdatalen = 0;
|
size_t pdatalen = 0;
|
||||||
AddISO9797M2Padding(pdata, &pdatalen, data, datalen, CIPURSE_AES_KEY_LENGTH);
|
AddISO9797M2Padding(pdata, &pdatalen, data, datalen, CIPURSE_AES_KEY_LENGTH);
|
||||||
CipurseCGenerateMAC(ctx, pdata, pdatalen, mac);
|
CipurseCGenerateMAC(ctx, pdata, pdatalen, mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CipurseCCheckMACPadded(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac) {
|
bool CipurseCCheckMACPadded(CipurseContext_t *ctx, uint8_t *data, size_t datalen, uint8_t *mac) {
|
||||||
uint8_t xmac[CIPURSE_MAC_LENGTH] = {0};
|
uint8_t xmac[CIPURSE_MAC_LENGTH] = {0};
|
||||||
CipurseCCalcMACPadded(ctx, data, datalen, xmac);
|
CipurseCCalcMACPadded(ctx, data, datalen, xmac);
|
||||||
return (memcmp(mac, xmac, CIPURSE_MAC_LENGTH) == 0);
|
return (memcmp(mac, xmac, CIPURSE_MAC_LENGTH) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CipurseCAPDUMACEncode(CipurseContext *ctx, sAPDU *apdu, uint8_t originalLc, uint8_t *data, size_t *datalen) {
|
static void CipurseCAPDUMACEncode(CipurseContext_t *ctx, sAPDU_t *apdu, uint8_t originalLc, uint8_t *data, size_t *datalen) {
|
||||||
data[0] = apdu->CLA;
|
data[0] = apdu->CLA;
|
||||||
data[1] = apdu->INS;
|
data[1] = apdu->INS;
|
||||||
data[2] = apdu->P1;
|
data[2] = apdu->P1;
|
||||||
|
@ -365,12 +365,12 @@ static void CipurseCAPDUMACEncode(CipurseContext *ctx, sAPDU *apdu, uint8_t orig
|
||||||
memcpy(&data[5], apdu->data, *datalen);
|
memcpy(&data[5], apdu->data, *datalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CipurseCAPDUReqEncode(CipurseContext *ctx, sAPDU *srcapdu, sAPDU *dstapdu, uint8_t *dstdatabuf, bool includeLe, uint8_t Le) {
|
void CipurseCAPDUReqEncode(CipurseContext_t *ctx, sAPDU_t *srcapdu, sAPDU_t *dstapdu, uint8_t *dstdatabuf, bool includeLe, uint8_t Le) {
|
||||||
uint8_t mac[CIPURSE_MAC_LENGTH] = {0};
|
uint8_t mac[CIPURSE_MAC_LENGTH] = {0};
|
||||||
uint8_t buf[260] = {0};
|
uint8_t buf[260] = {0};
|
||||||
size_t buflen = 0;
|
size_t buflen = 0;
|
||||||
|
|
||||||
memcpy(dstapdu, srcapdu, sizeof(sAPDU));
|
memcpy(dstapdu, srcapdu, sizeof(sAPDU_t));
|
||||||
|
|
||||||
if (isCipurseCChannelSecuritySet(ctx) == false)
|
if (isCipurseCChannelSecuritySet(ctx) == false)
|
||||||
return;
|
return;
|
||||||
|
@ -422,7 +422,7 @@ void CipurseCAPDUReqEncode(CipurseContext *ctx, sAPDU *srcapdu, sAPDU *dstapdu,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CipurseCAPDURespDecode(CipurseContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen, uint16_t *sw) {
|
void CipurseCAPDURespDecode(CipurseContext_t *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen, uint16_t *sw) {
|
||||||
uint8_t buf[260] = {0};
|
uint8_t buf[260] = {0};
|
||||||
size_t buflen = 0;
|
size_t buflen = 0;
|
||||||
uint8_t micdata[260] = {0};
|
uint8_t micdata[260] = {0};
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#define __CIPURSECRYPTO_H__
|
#define __CIPURSECRYPTO_H__
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "iso7816/apduinfo.h" // sAPDU
|
#include "iso7816/apduinfo.h" // sAPDU_t
|
||||||
|
|
||||||
#define CIPURSE_KVV_LENGTH 4
|
#define CIPURSE_KVV_LENGTH 4
|
||||||
#define CIPURSE_AES_KEY_LENGTH 16
|
#define CIPURSE_AES_KEY_LENGTH 16
|
||||||
|
@ -31,7 +31,7 @@ typedef enum {
|
||||||
CPSEncrypted
|
CPSEncrypted
|
||||||
} CipurseChannelSecurityLevel;
|
} CipurseChannelSecurityLevel;
|
||||||
|
|
||||||
typedef struct CipurseContextS {
|
typedef struct CipurseContext_tS {
|
||||||
uint8_t keyId;
|
uint8_t keyId;
|
||||||
uint8_t key[CIPURSE_AES_KEY_LENGTH];
|
uint8_t key[CIPURSE_AES_KEY_LENGTH];
|
||||||
|
|
||||||
|
@ -49,34 +49,34 @@ typedef struct CipurseContextS {
|
||||||
|
|
||||||
CipurseChannelSecurityLevel RequestSecurity;
|
CipurseChannelSecurityLevel RequestSecurity;
|
||||||
CipurseChannelSecurityLevel ResponseSecurity;
|
CipurseChannelSecurityLevel ResponseSecurity;
|
||||||
} CipurseContext;
|
} CipurseContext_t;
|
||||||
|
|
||||||
uint8_t CipurseCSecurityLevelEnc(CipurseChannelSecurityLevel lvl);
|
uint8_t CipurseCSecurityLevelEnc(CipurseChannelSecurityLevel lvl);
|
||||||
|
|
||||||
void CipurseCClearContext(CipurseContext *ctx);
|
void CipurseCClearContext(CipurseContext_t *ctx);
|
||||||
void CipurseCSetKey(CipurseContext *ctx, uint8_t keyId, uint8_t *key);
|
void CipurseCSetKey(CipurseContext_t *ctx, uint8_t keyId, uint8_t *key);
|
||||||
void CipurseCSetRandomFromPICC(CipurseContext *ctx, uint8_t *random);
|
void CipurseCSetRandomFromPICC(CipurseContext_t *ctx, uint8_t *random);
|
||||||
void CipurseCSetRandomHost(CipurseContext *ctx);
|
void CipurseCSetRandomHost(CipurseContext_t *ctx);
|
||||||
uint8_t CipurseCGetSMI(CipurseContext *ctx, bool LePresent);
|
uint8_t CipurseCGetSMI(CipurseContext_t *ctx, bool LePresent);
|
||||||
|
|
||||||
void CipurseCAuthenticateHost(CipurseContext *ctx, uint8_t *authdata);
|
void CipurseCAuthenticateHost(CipurseContext_t *ctx, uint8_t *authdata);
|
||||||
bool CipurseCCheckCT(CipurseContext *ctx, uint8_t *CT);
|
bool CipurseCCheckCT(CipurseContext_t *ctx, uint8_t *CT);
|
||||||
|
|
||||||
void CipurseCChannelSetSecurityLevels(CipurseContext *ctx, CipurseChannelSecurityLevel req, CipurseChannelSecurityLevel resp);
|
void CipurseCChannelSetSecurityLevels(CipurseContext_t *ctx, CipurseChannelSecurityLevel req, CipurseChannelSecurityLevel resp);
|
||||||
bool isCipurseCChannelSecuritySet(CipurseContext *ctx);
|
bool isCipurseCChannelSecuritySet(CipurseContext_t *ctx);
|
||||||
|
|
||||||
void CipurseCGenerateMAC(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac);
|
void CipurseCGenerateMAC(CipurseContext_t *ctx, uint8_t *data, size_t datalen, uint8_t *mac);
|
||||||
void CipurseCCalcMACPadded(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac);
|
void CipurseCCalcMACPadded(CipurseContext_t *ctx, uint8_t *data, size_t datalen, uint8_t *mac);
|
||||||
bool CipurseCCheckMACPadded(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac);
|
bool CipurseCCheckMACPadded(CipurseContext_t *ctx, uint8_t *data, size_t datalen, uint8_t *mac);
|
||||||
void CipurseCGenerateMIC(uint8_t *data, size_t datalen, uint8_t *mic);
|
void CipurseCGenerateMIC(uint8_t *data, size_t datalen, uint8_t *mic);
|
||||||
bool CipurseCCheckMIC(uint8_t *data, size_t datalen, uint8_t *mic);
|
bool CipurseCCheckMIC(uint8_t *data, size_t datalen, uint8_t *mic);
|
||||||
void CipurseCEncryptDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *dstdata, bool isEncrypt);
|
void CipurseCEncryptDecrypt(CipurseContext_t *ctx, uint8_t *data, size_t datalen, uint8_t *dstdata, bool isEncrypt);
|
||||||
void CipurseCChannelEncrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *encdata, size_t *encdatalen);
|
void CipurseCChannelEncrypt(CipurseContext_t *ctx, uint8_t *data, size_t datalen, uint8_t *encdata, size_t *encdatalen);
|
||||||
void CipurseCChannelDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *plaindata, size_t *plaindatalen);
|
void CipurseCChannelDecrypt(CipurseContext_t *ctx, uint8_t *data, size_t datalen, uint8_t *plaindata, size_t *plaindatalen);
|
||||||
void CipurseCGetKVV(uint8_t *key, uint8_t *kvv);
|
void CipurseCGetKVV(uint8_t *key, uint8_t *kvv);
|
||||||
|
|
||||||
void CipurseCAPDUReqEncode(CipurseContext *ctx, sAPDU *srcapdu, sAPDU *dstapdu, uint8_t *dstdatabuf, bool includeLe, uint8_t Le);
|
void CipurseCAPDUReqEncode(CipurseContext_t *ctx, sAPDU_t *srcapdu, sAPDU_t *dstapdu, uint8_t *dstdatabuf, bool includeLe, uint8_t Le);
|
||||||
void CipurseCAPDURespDecode(CipurseContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen, uint16_t *sw);
|
void CipurseCAPDURespDecode(CipurseContext_t *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen, uint16_t *sw);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __CIPURSECRYPTO_H__ */
|
#endif /* __CIPURSECRYPTO_H__ */
|
||||||
|
|
|
@ -59,7 +59,7 @@ static bool TestISO9797M2(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool TestSMI(void) {
|
static bool TestSMI(void) {
|
||||||
CipurseContext ctx = {0};
|
CipurseContext_t ctx = {0};
|
||||||
CipurseCClearContext(&ctx);
|
CipurseCClearContext(&ctx);
|
||||||
|
|
||||||
bool res = (isCipurseCChannelSecuritySet(&ctx) == false);
|
bool res = (isCipurseCChannelSecuritySet(&ctx) == false);
|
||||||
|
@ -117,7 +117,7 @@ static bool TestMIC(void) {
|
||||||
|
|
||||||
|
|
||||||
static bool TestAuth(void) {
|
static bool TestAuth(void) {
|
||||||
CipurseContext ctx = {0};
|
CipurseContext_t ctx = {0};
|
||||||
CipurseCClearContext(&ctx);
|
CipurseCClearContext(&ctx);
|
||||||
|
|
||||||
bool res = (isCipurseCChannelSecuritySet(&ctx) == false);
|
bool res = (isCipurseCChannelSecuritySet(&ctx) == false);
|
||||||
|
@ -160,7 +160,7 @@ static bool TestAuth(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool TestMAC(void) {
|
static bool TestMAC(void) {
|
||||||
CipurseContext ctx = {0};
|
CipurseContext_t ctx = {0};
|
||||||
|
|
||||||
// authentication
|
// authentication
|
||||||
CipurseCClearContext(&ctx);
|
CipurseCClearContext(&ctx);
|
||||||
|
@ -212,7 +212,7 @@ static bool TestMAC(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool TestEncDec(void) {
|
static bool TestEncDec(void) {
|
||||||
CipurseContext ctx = {0};
|
CipurseContext_t ctx = {0};
|
||||||
|
|
||||||
// authentication
|
// authentication
|
||||||
CipurseCClearContext(&ctx);
|
CipurseCClearContext(&ctx);
|
||||||
|
@ -259,10 +259,10 @@ static bool TestEncDec(void) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
//void CipurseCAPDUReqEncode(CipurseContext *ctx, sAPDU *srcapdu, sAPDU *dstapdu, uint8_t *dstdatabuf, bool includeLe, uint8_t Le);
|
//void CipurseCAPDUReqEncode(CipurseContext_t *ctx, sAPDU_t *srcapdu, sAPDU_t *dstapdu, uint8_t *dstdatabuf, bool includeLe, uint8_t Le);
|
||||||
//void CipurseCAPDURespDecode(CipurseContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen, uint16_t *sw);
|
//void CipurseCAPDURespDecode(CipurseContext_t *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen, uint16_t *sw);
|
||||||
static bool TestAPDU(void) {
|
static bool TestAPDU(void) {
|
||||||
CipurseContext ctx = {0};
|
CipurseContext_t ctx = {0};
|
||||||
|
|
||||||
// authentication
|
// authentication
|
||||||
CipurseCClearContext(&ctx);
|
CipurseCClearContext(&ctx);
|
||||||
|
@ -276,8 +276,8 @@ static bool TestAPDU(void) {
|
||||||
res = res && (isCipurseCChannelSecuritySet(&ctx) == true);
|
res = res && (isCipurseCChannelSecuritySet(&ctx) == true);
|
||||||
|
|
||||||
// check APDU formatting
|
// check APDU formatting
|
||||||
sAPDU srcAPDU = {0};
|
sAPDU_t srcAPDU = {0};
|
||||||
sAPDU dstAPDU = {0};
|
sAPDU_t dstAPDU = {0};
|
||||||
uint8_t dstdata[256] = {0};
|
uint8_t dstdata[256] = {0};
|
||||||
size_t dstdatalen = 0;
|
size_t dstdatalen = 0;
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ static bool APDUInFramingEnable = true;
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
static int waitCmd(bool i_select, uint32_t timeout, bool verbose);
|
static int waitCmd(bool i_select, uint32_t timeout, bool verbose);
|
||||||
|
|
||||||
static const manufactureName manufactureMapping[] = {
|
static const manufactureName_t manufactureMapping[] = {
|
||||||
// ID, "Vendor Country"
|
// ID, "Vendor Country"
|
||||||
{ 0x01, "Motorola UK" },
|
{ 0x01, "Motorola UK" },
|
||||||
{ 0x02, "ST Microelectronics SA France" },
|
{ 0x02, "ST Microelectronics SA France" },
|
||||||
|
@ -169,7 +169,7 @@ const char *getTagInfo(uint8_t uid) {
|
||||||
return manufactureMapping[ARRAYLEN(manufactureMapping) - 1].desc;
|
return manufactureMapping[ARRAYLEN(manufactureMapping) - 1].desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const hintAIDListT hintAIDList[] = {
|
static const hintAIDList_t hintAIDList[] = {
|
||||||
// AID, AID len, name, hint - how to use
|
// AID, AID len, name, hint - how to use
|
||||||
{ "\xA0\x00\x00\x06\x47\x2F\x00\x01", 8, "FIDO", "hf fido" },
|
{ "\xA0\x00\x00\x06\x47\x2F\x00\x01", 8, "FIDO", "hf fido" },
|
||||||
{ "\xA0\x00\x00\x03\x08\x00\x00\x10\x00\x01\x00", 11, "PIV", "" },
|
{ "\xA0\x00\x00\x03\x08\x00\x00\x10\x00\x01\x00", 11, "PIV", "" },
|
||||||
|
@ -1125,7 +1125,7 @@ static int CmdHF14AAPDU(const char *Cmd) {
|
||||||
|
|
||||||
CLIGetHexBLessWithReturn(ctx, 8, apdudata, &apdudatalen, 1 + 2);
|
CLIGetHexBLessWithReturn(ctx, 8, apdudata, &apdudatalen, 1 + 2);
|
||||||
|
|
||||||
APDUStruct apdu;
|
APDU_t apdu;
|
||||||
apdu.cla = header[0];
|
apdu.cla = header[0];
|
||||||
apdu.ins = header[1];
|
apdu.ins = header[1];
|
||||||
apdu.p1 = header[2];
|
apdu.p1 = header[2];
|
||||||
|
@ -1168,7 +1168,7 @@ static int CmdHF14AAPDU(const char *Cmd) {
|
||||||
PrintAndLogEx(SUCCESS, ">>> %s", sprint_hex_inrow(data, datalen));
|
PrintAndLogEx(SUCCESS, ">>> %s", sprint_hex_inrow(data, datalen));
|
||||||
|
|
||||||
if (decodeAPDU) {
|
if (decodeAPDU) {
|
||||||
APDUStruct apdu;
|
APDU_t apdu;
|
||||||
|
|
||||||
if (APDUDecode(data, datalen, &apdu) == 0)
|
if (APDUDecode(data, datalen, &apdu) == 0)
|
||||||
APDUPrint(apdu);
|
APDUPrint(apdu);
|
||||||
|
@ -1571,9 +1571,9 @@ typedef struct {
|
||||||
uint8_t uid0;
|
uint8_t uid0;
|
||||||
uint8_t uid1;
|
uint8_t uid1;
|
||||||
const char *desc;
|
const char *desc;
|
||||||
} uid_label_name;
|
} uid_label_name_t;
|
||||||
|
|
||||||
static const uid_label_name uid_label_map[] = {
|
static const uid_label_name_t uid_label_map[] = {
|
||||||
// UID0, UID1, TEXT
|
// UID0, UID1, TEXT
|
||||||
{0x02, 0x84, "M24SR64-Y"},
|
{0x02, 0x84, "M24SR64-Y"},
|
||||||
{0x02, 0xA3, "25TA02KB-P"},
|
{0x02, 0xA3, "25TA02KB-P"},
|
||||||
|
|
|
@ -20,14 +20,14 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t uid;
|
uint8_t uid;
|
||||||
const char *desc;
|
const char *desc;
|
||||||
} manufactureName;
|
} manufactureName_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *aid;
|
const char *aid;
|
||||||
const uint8_t aid_length;
|
const uint8_t aid_length;
|
||||||
const char *desc;
|
const char *desc;
|
||||||
const char *hint;
|
const char *hint;
|
||||||
} hintAIDListT;
|
} hintAIDList_t;
|
||||||
|
|
||||||
int CmdHF14A(const char *Cmd);
|
int CmdHF14A(const char *Cmd);
|
||||||
int CmdHF14ASniff(const char *Cmd); // used by hf topaz sniff
|
int CmdHF14ASniff(const char *Cmd); // used by hf topaz sniff
|
||||||
|
|
|
@ -90,7 +90,7 @@ static void hf14b_aid_search(bool verbose) {
|
||||||
// COMPUTE APDU
|
// COMPUTE APDU
|
||||||
uint8_t apdu_data[PM3_CMD_DATA_SIZE] = {0};
|
uint8_t apdu_data[PM3_CMD_DATA_SIZE] = {0};
|
||||||
int apdu_len = 0;
|
int apdu_len = 0;
|
||||||
sAPDU apdu = (sAPDU) {0x00, 0xa4, 0x04, 0x00, vaidlen, vaid};
|
sAPDU_t apdu = (sAPDU_t) {0x00, 0xa4, 0x04, 0x00, vaidlen, vaid};
|
||||||
|
|
||||||
if (APDUEncodeS(&apdu, false, 0x00, apdu_data, &apdu_len)) {
|
if (APDUEncodeS(&apdu, false, 0x00, apdu_data, &apdu_len)) {
|
||||||
PrintAndLogEx(ERR, "APDU encoding error.");
|
PrintAndLogEx(ERR, "APDU encoding error.");
|
||||||
|
@ -1849,7 +1849,7 @@ static int CmdHF14BAPDU(const char *Cmd) {
|
||||||
|
|
||||||
CLIGetHexBLessWithReturn(ctx, 8, apdudata, &apdudatalen, 1 + 2);
|
CLIGetHexBLessWithReturn(ctx, 8, apdudata, &apdudatalen, 1 + 2);
|
||||||
|
|
||||||
APDUStruct apdu;
|
APDU_t apdu;
|
||||||
apdu.cla = header[0];
|
apdu.cla = header[0];
|
||||||
apdu.ins = header[1];
|
apdu.ins = header[1];
|
||||||
apdu.p1 = header[2];
|
apdu.p1 = header[2];
|
||||||
|
@ -1893,7 +1893,7 @@ static int CmdHF14BAPDU(const char *Cmd) {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (decode_APDU) {
|
if (decode_APDU) {
|
||||||
APDUStruct apdu;
|
APDU_t apdu;
|
||||||
if (APDUDecode(data, datalen, &apdu) == 0)
|
if (APDUDecode(data, datalen, &apdu) == 0)
|
||||||
APDUPrint(apdu);
|
APDUPrint(apdu);
|
||||||
else
|
else
|
||||||
|
|
|
@ -178,7 +178,7 @@ static emrtd_dg_t *emrtd_fileid_to_dg(uint16_t file_id) {
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static bool emrtd_exchange_commands(sAPDU apdu, bool include_le, uint16_t le, uint8_t *dataout, size_t maxdataoutlen, size_t *dataoutlen, bool activate_field, bool keep_field_on) {
|
static bool emrtd_exchange_commands(sAPDU_t apdu, bool include_le, uint16_t le, uint8_t *dataout, size_t maxdataoutlen, size_t *dataoutlen, bool activate_field, bool keep_field_on) {
|
||||||
uint16_t sw;
|
uint16_t sw;
|
||||||
int res = Iso7816ExchangeEx(CC_CONTACTLESS, activate_field, keep_field_on, apdu, include_le, le, dataout, maxdataoutlen, dataoutlen, &sw);
|
int res = Iso7816ExchangeEx(CC_CONTACTLESS, activate_field, keep_field_on, apdu, include_le, le, dataout, maxdataoutlen, dataoutlen, &sw);
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ static bool emrtd_exchange_commands(sAPDU apdu, bool include_le, uint16_t le, ui
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int emrtd_exchange_commands_noout(sAPDU apdu, bool activate_field, bool keep_field_on) {
|
static int emrtd_exchange_commands_noout(sAPDU_t apdu, bool activate_field, bool keep_field_on) {
|
||||||
uint8_t response[PM3_CMD_DATA_SIZE];
|
uint8_t response[PM3_CMD_DATA_SIZE];
|
||||||
size_t resplen = 0;
|
size_t resplen = 0;
|
||||||
|
|
||||||
|
@ -375,25 +375,25 @@ static void _emrtd_convert_fileid(uint16_t file, uint8_t *dataout) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int emrtd_select_file_by_name(uint8_t namelen, uint8_t *name) {
|
static int emrtd_select_file_by_name(uint8_t namelen, uint8_t *name) {
|
||||||
return emrtd_exchange_commands_noout((sAPDU) {0, EMRTD_SELECT, EMRTD_P1_SELECT_BY_NAME, 0x0C, namelen, name}, false, true);
|
return emrtd_exchange_commands_noout((sAPDU_t) {0, EMRTD_SELECT, EMRTD_P1_SELECT_BY_NAME, 0x0C, namelen, name}, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int emrtd_select_file_by_ef(uint16_t file_id) {
|
static int emrtd_select_file_by_ef(uint16_t file_id) {
|
||||||
uint8_t data[2];
|
uint8_t data[2];
|
||||||
_emrtd_convert_fileid(file_id, data);
|
_emrtd_convert_fileid(file_id, data);
|
||||||
return emrtd_exchange_commands_noout((sAPDU) {0, EMRTD_SELECT, EMRTD_P1_SELECT_BY_EF, 0x0C, sizeof(data), data}, false, true);
|
return emrtd_exchange_commands_noout((sAPDU_t) {0, EMRTD_SELECT, EMRTD_P1_SELECT_BY_EF, 0x0C, sizeof(data), data}, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int emrtd_get_challenge(int length, uint8_t *dataout, size_t maxdataoutlen, size_t *dataoutlen) {
|
static int emrtd_get_challenge(int length, uint8_t *dataout, size_t maxdataoutlen, size_t *dataoutlen) {
|
||||||
return emrtd_exchange_commands((sAPDU) {0, EMRTD_GET_CHALLENGE, 0, 0, 0, NULL}, true, length, dataout, maxdataoutlen, dataoutlen, false, true);
|
return emrtd_exchange_commands((sAPDU_t) {0, EMRTD_GET_CHALLENGE, 0, 0, 0, NULL}, true, length, dataout, maxdataoutlen, dataoutlen, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int emrtd_external_authenticate(uint8_t *data, int length, uint8_t *dataout, size_t maxdataoutlen, size_t *dataoutlen) {
|
static int emrtd_external_authenticate(uint8_t *data, int length, uint8_t *dataout, size_t maxdataoutlen, size_t *dataoutlen) {
|
||||||
return emrtd_exchange_commands((sAPDU) {0, EMRTD_EXTERNAL_AUTHENTICATE, 0, 0, length, data}, true, length, dataout, maxdataoutlen, dataoutlen, false, true);
|
return emrtd_exchange_commands((sAPDU_t) {0, EMRTD_EXTERNAL_AUTHENTICATE, 0, 0, length, data}, true, length, dataout, maxdataoutlen, dataoutlen, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _emrtd_read_binary(int offset, int bytes_to_read, uint8_t *dataout, size_t maxdataoutlen, size_t *dataoutlen) {
|
static int _emrtd_read_binary(int offset, int bytes_to_read, uint8_t *dataout, size_t maxdataoutlen, size_t *dataoutlen) {
|
||||||
return emrtd_exchange_commands((sAPDU) {0, EMRTD_READ_BINARY, offset >> 8, offset & 0xFF, 0, NULL}, true, bytes_to_read, dataout, maxdataoutlen, dataoutlen, false, true);
|
return emrtd_exchange_commands((sAPDU_t) {0, EMRTD_READ_BINARY, offset >> 8, offset & 0xFF, 0, NULL}, true, bytes_to_read, dataout, maxdataoutlen, dataoutlen, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emrtd_bump_ssc(uint8_t *ssc) {
|
static void emrtd_bump_ssc(uint8_t *ssc) {
|
||||||
|
@ -495,7 +495,7 @@ static bool emrtd_secure_select_file_by_ef(uint8_t *kenc, uint8_t *kmac, uint8_t
|
||||||
memcpy(data + (datalen + 3), do8e, 10);
|
memcpy(data + (datalen + 3), do8e, 10);
|
||||||
PrintAndLogEx(DEBUG, "data: %s", sprint_hex_inrow(data, lc));
|
PrintAndLogEx(DEBUG, "data: %s", sprint_hex_inrow(data, lc));
|
||||||
|
|
||||||
if (emrtd_exchange_commands((sAPDU) {0x0C, EMRTD_SELECT, EMRTD_P1_SELECT_BY_EF, 0x0C, lc, data}, true, 0, response, sizeof(response), &resplen, false, true) == false) {
|
if (emrtd_exchange_commands((sAPDU_t) {0x0C, EMRTD_SELECT, EMRTD_P1_SELECT_BY_EF, 0x0C, lc, data}, true, 0, response, sizeof(response), &resplen, false, true) == false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,7 +544,7 @@ static bool _emrtd_secure_read_binary(uint8_t *kmac, uint8_t *ssc, int offset, i
|
||||||
memcpy(data + 3, do8e, 10);
|
memcpy(data + 3, do8e, 10);
|
||||||
PrintAndLogEx(DEBUG, "data: %s", sprint_hex_inrow(data, lc));
|
PrintAndLogEx(DEBUG, "data: %s", sprint_hex_inrow(data, lc));
|
||||||
|
|
||||||
if (emrtd_exchange_commands((sAPDU) {0x0C, EMRTD_READ_BINARY, offset >> 8, offset & 0xFF, lc, data}, true, 0, dataout, maxdataoutlen, dataoutlen, false, true) == false) {
|
if (emrtd_exchange_commands((sAPDU_t) {0x0C, EMRTD_READ_BINARY, offset >> 8, offset & 0xFF, lc, data}, true, 0, dataout, maxdataoutlen, dataoutlen, false, true) == false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ enum MifareAuthSeq {
|
||||||
masError,
|
masError,
|
||||||
};
|
};
|
||||||
static enum MifareAuthSeq MifareAuthState;
|
static enum MifareAuthSeq MifareAuthState;
|
||||||
static TAuthData AuthData;
|
static AuthData_t AuthData;
|
||||||
|
|
||||||
void ClearAuthData(void) {
|
void ClearAuthData(void) {
|
||||||
AuthData.uid = 0;
|
AuthData.uid = 0;
|
||||||
|
@ -1551,7 +1551,7 @@ bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isRes
|
||||||
return *mfDataLen > 0;
|
return *mfDataLen > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NTParityChk(TAuthData *ad, uint32_t ntx) {
|
bool NTParityChk(AuthData_t *ad, uint32_t ntx) {
|
||||||
if (
|
if (
|
||||||
(oddparity8(ntx >> 8 & 0xff) ^ (ntx & 0x01) ^ ((ad->nt_enc_par >> 5) & 0x01) ^ (ad->nt_enc & 0x01)) ||
|
(oddparity8(ntx >> 8 & 0xff) ^ (ntx & 0x01) ^ ((ad->nt_enc_par >> 5) & 0x01) ^ (ad->nt_enc & 0x01)) ||
|
||||||
(oddparity8(ntx >> 16 & 0xff) ^ (ntx >> 8 & 0x01) ^ ((ad->nt_enc_par >> 6) & 0x01) ^ (ad->nt_enc >> 8 & 0x01)) ||
|
(oddparity8(ntx >> 16 & 0xff) ^ (ntx >> 8 & 0x01) ^ ((ad->nt_enc_par >> 6) & 0x01) ^ (ad->nt_enc >> 8 & 0x01)) ||
|
||||||
|
@ -1579,7 +1579,7 @@ bool NTParityChk(TAuthData *ad, uint32_t ntx) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NestedCheckKey(uint64_t key, TAuthData *ad, uint8_t *cmd, uint8_t cmdsize, uint8_t *parity) {
|
bool NestedCheckKey(uint64_t key, AuthData_t *ad, uint8_t *cmd, uint8_t cmdsize, uint8_t *parity) {
|
||||||
uint8_t buf[32] = {0};
|
uint8_t buf[32] = {0};
|
||||||
struct Crypto1State *pcs;
|
struct Crypto1State *pcs;
|
||||||
|
|
||||||
|
@ -1627,7 +1627,7 @@ bool CheckCrypto1Parity(uint8_t *cmd_enc, uint8_t cmdsize, uint8_t *cmd, uint8_t
|
||||||
|
|
||||||
// Another implementation of mfkey64 attack, more "valid" than "probable"
|
// Another implementation of mfkey64 attack, more "valid" than "probable"
|
||||||
//
|
//
|
||||||
uint64_t GetCrypto1ProbableKey(TAuthData *ad) {
|
uint64_t GetCrypto1ProbableKey(AuthData_t *ad) {
|
||||||
struct Crypto1State *revstate = lfsr_recovery64(ad->ks2, ad->ks3);
|
struct Crypto1State *revstate = lfsr_recovery64(ad->ks2, ad->ks3);
|
||||||
lfsr_rollback_word(revstate, 0, 0);
|
lfsr_rollback_word(revstate, 0, 0);
|
||||||
lfsr_rollback_word(revstate, 0, 0);
|
lfsr_rollback_word(revstate, 0, 0);
|
||||||
|
|
|
@ -26,7 +26,7 @@ typedef struct {
|
||||||
bool first_auth; // is first authentication
|
bool first_auth; // is first authentication
|
||||||
uint32_t ks2; // ar ^ ar_enc
|
uint32_t ks2; // ar ^ ar_enc
|
||||||
uint32_t ks3; // at ^ at_enc
|
uint32_t ks3; // at ^ at_enc
|
||||||
} TAuthData;
|
} AuthData_t;
|
||||||
|
|
||||||
void ClearAuthData(void);
|
void ClearAuthData(void);
|
||||||
|
|
||||||
|
@ -53,9 +53,9 @@ void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
||||||
void annotateCryptoRF(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
void annotateCryptoRF(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
||||||
|
|
||||||
bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isResponse, uint8_t *mfData, size_t *mfDataLen, const uint64_t *dicKeys, uint32_t dicKeysCount);
|
bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isResponse, uint8_t *mfData, size_t *mfDataLen, const uint64_t *dicKeys, uint32_t dicKeysCount);
|
||||||
bool NTParityChk(TAuthData *ad, uint32_t ntx);
|
bool NTParityChk(AuthData_t *ad, uint32_t ntx);
|
||||||
bool NestedCheckKey(uint64_t key, TAuthData *ad, uint8_t *cmd, uint8_t cmdsize, uint8_t *parity);
|
bool NestedCheckKey(uint64_t key, AuthData_t *ad, uint8_t *cmd, uint8_t cmdsize, uint8_t *parity);
|
||||||
bool CheckCrypto1Parity(uint8_t *cmd_enc, uint8_t cmdsize, uint8_t *cmd, uint8_t *parity_enc);
|
bool CheckCrypto1Parity(uint8_t *cmd_enc, uint8_t cmdsize, uint8_t *cmd, uint8_t *parity_enc);
|
||||||
uint64_t GetCrypto1ProbableKey(TAuthData *ad);
|
uint64_t GetCrypto1ProbableKey(AuthData_t *ad);
|
||||||
|
|
||||||
#endif // CMDHFLIST
|
#endif // CMDHFLIST
|
||||||
|
|
|
@ -20,7 +20,7 @@ typedef struct {
|
||||||
uint32_t p_memsz;
|
uint32_t p_memsz;
|
||||||
uint32_t p_flags;
|
uint32_t p_flags;
|
||||||
uint32_t p_align;
|
uint32_t p_align;
|
||||||
} PACKED Elf32_Phdr;
|
} PACKED Elf32_Phdr_t;
|
||||||
|
|
||||||
#define EI_NIDENT 16
|
#define EI_NIDENT 16
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ typedef struct {
|
||||||
uint16_t e_shentsize;
|
uint16_t e_shentsize;
|
||||||
uint16_t e_shnum;
|
uint16_t e_shnum;
|
||||||
uint16_t e_shtrndx;
|
uint16_t e_shtrndx;
|
||||||
} PACKED Elf32_Ehdr;
|
} PACKED Elf32_Ehdr_t;
|
||||||
|
|
||||||
#define PT_NULL 0
|
#define PT_NULL 0
|
||||||
#define PT_LOAD 1
|
#define PT_LOAD 1
|
||||||
|
|
|
@ -265,7 +265,7 @@ struct tlvdb *GetdCVVRawFromTrack2(const struct tlv *track2) {
|
||||||
return tlvdb_fixed(0x02, dCVVlen, dCVV);
|
return tlvdb_fixed(0x02, dCVVlen, dCVV);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int EMVExchangeEx(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, sAPDU apdu, bool IncludeLe, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
static int EMVExchangeEx(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, sAPDU_t apdu, bool IncludeLe, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
||||||
int res = Iso7816ExchangeEx(channel, ActivateField, LeaveFieldON, apdu, IncludeLe, 0, Result, MaxResultLen, ResultLen, sw);
|
int res = Iso7816ExchangeEx(channel, ActivateField, LeaveFieldON, apdu, IncludeLe, 0, Result, MaxResultLen, ResultLen, sw);
|
||||||
// add to tlv tree
|
// add to tlv tree
|
||||||
if ((res == PM3_SUCCESS) && tlv) {
|
if ((res == PM3_SUCCESS) && tlv) {
|
||||||
|
@ -275,7 +275,7 @@ static int EMVExchangeEx(Iso7816CommandChannel channel, bool ActivateField, bool
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EMVExchange(Iso7816CommandChannel channel, bool LeaveFieldON, sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
int EMVExchange(Iso7816CommandChannel channel, bool LeaveFieldON, sAPDU_t apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
||||||
int res = Iso7816Exchange(channel, LeaveFieldON, apdu, Result, MaxResultLen, ResultLen, sw);
|
int res = Iso7816Exchange(channel, LeaveFieldON, apdu, Result, MaxResultLen, ResultLen, sw);
|
||||||
// add to tlv tree
|
// add to tlv tree
|
||||||
if ((res == PM3_SUCCESS) && tlv) {
|
if ((res == PM3_SUCCESS) && tlv) {
|
||||||
|
@ -563,40 +563,40 @@ int EMVSelectApplication(struct tlvdb *tlv, uint8_t *AID, size_t *AIDlen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int EMVGPO(Iso7816CommandChannel channel, bool LeaveFieldON, uint8_t *PDOL, size_t PDOLLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
int EMVGPO(Iso7816CommandChannel channel, bool LeaveFieldON, uint8_t *PDOL, size_t PDOLLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
||||||
return EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU) {0x80, 0xa8, 0x00, 0x00, PDOLLen, PDOL}, true, Result, MaxResultLen, ResultLen, sw, tlv);
|
return EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU_t) {0x80, 0xa8, 0x00, 0x00, PDOLLen, PDOL}, true, Result, MaxResultLen, ResultLen, sw, tlv);
|
||||||
}
|
}
|
||||||
|
|
||||||
int EMVReadRecord(Iso7816CommandChannel channel, bool LeaveFieldON, uint8_t SFI, uint8_t SFIrec, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
int EMVReadRecord(Iso7816CommandChannel channel, bool LeaveFieldON, uint8_t SFI, uint8_t SFIrec, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
||||||
int res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU) {0x00, 0xb2, SFIrec, (SFI << 3) | 0x04, 0, NULL}, true, Result, MaxResultLen, ResultLen, sw, tlv);
|
int res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU_t) {0x00, 0xb2, SFIrec, (SFI << 3) | 0x04, 0, NULL}, true, Result, MaxResultLen, ResultLen, sw, tlv);
|
||||||
if (*sw == 0x6700 || *sw == 0x6f00) {
|
if (*sw == 0x6700 || *sw == 0x6f00) {
|
||||||
PrintAndLogEx(INFO, ">>> trying to reissue command without Le...");
|
PrintAndLogEx(INFO, ">>> trying to reissue command without Le...");
|
||||||
res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU) {0x00, 0xb2, SFIrec, (SFI << 3) | 0x04, 0, NULL}, false, Result, MaxResultLen, ResultLen, sw, tlv);
|
res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU_t) {0x00, 0xb2, SFIrec, (SFI << 3) | 0x04, 0, NULL}, false, Result, MaxResultLen, ResultLen, sw, tlv);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EMVAC(Iso7816CommandChannel channel, bool LeaveFieldON, uint8_t RefControl, uint8_t *CDOL, size_t CDOLLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
int EMVAC(Iso7816CommandChannel channel, bool LeaveFieldON, uint8_t RefControl, uint8_t *CDOL, size_t CDOLLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
||||||
return EMVExchange(channel, LeaveFieldON, (sAPDU) {0x80, 0xae, RefControl, 0x00, CDOLLen, CDOL}, Result, MaxResultLen, ResultLen, sw, tlv);
|
return EMVExchange(channel, LeaveFieldON, (sAPDU_t) {0x80, 0xae, RefControl, 0x00, CDOLLen, CDOL}, Result, MaxResultLen, ResultLen, sw, tlv);
|
||||||
}
|
}
|
||||||
|
|
||||||
int EMVGenerateChallenge(Iso7816CommandChannel channel, bool LeaveFieldON, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
int EMVGenerateChallenge(Iso7816CommandChannel channel, bool LeaveFieldON, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
||||||
int res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU) {0x00, 0x84, 0x00, 0x00, 0x00, NULL}, true, Result, MaxResultLen, ResultLen, sw, tlv);
|
int res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU_t) {0x00, 0x84, 0x00, 0x00, 0x00, NULL}, true, Result, MaxResultLen, ResultLen, sw, tlv);
|
||||||
if (*sw == 0x6700 || *sw == 0x6f00) {
|
if (*sw == 0x6700 || *sw == 0x6f00) {
|
||||||
PrintAndLogEx(INFO, ">>> trying to reissue command without Le...");
|
PrintAndLogEx(INFO, ">>> trying to reissue command without Le...");
|
||||||
res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU) {0x00, 0x84, 0x00, 0x00, 0x00, NULL}, false, Result, MaxResultLen, ResultLen, sw, tlv);
|
res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU_t) {0x00, 0x84, 0x00, 0x00, 0x00, NULL}, false, Result, MaxResultLen, ResultLen, sw, tlv);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EMVInternalAuthenticate(Iso7816CommandChannel channel, bool LeaveFieldON, uint8_t *DDOL, size_t DDOLLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
int EMVInternalAuthenticate(Iso7816CommandChannel channel, bool LeaveFieldON, uint8_t *DDOL, size_t DDOLLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
||||||
return EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU) {0x00, 0x88, 0x00, 0x00, DDOLLen, DDOL}, true, Result, MaxResultLen, ResultLen, sw, tlv);
|
return EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU_t) {0x00, 0x88, 0x00, 0x00, DDOLLen, DDOL}, true, Result, MaxResultLen, ResultLen, sw, tlv);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MSCComputeCryptoChecksum(Iso7816CommandChannel channel, bool LeaveFieldON, uint8_t *UDOL, uint8_t UDOLlen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
int MSCComputeCryptoChecksum(Iso7816CommandChannel channel, bool LeaveFieldON, uint8_t *UDOL, uint8_t UDOLlen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
|
||||||
int res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU) {0x80, 0x2a, 0x8e, 0x80, UDOLlen, UDOL}, true, Result, MaxResultLen, ResultLen, sw, tlv);
|
int res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU_t) {0x80, 0x2a, 0x8e, 0x80, UDOLlen, UDOL}, true, Result, MaxResultLen, ResultLen, sw, tlv);
|
||||||
if (*sw == 0x6700 || *sw == 0x6f00) {
|
if (*sw == 0x6700 || *sw == 0x6f00) {
|
||||||
PrintAndLogEx(INFO, ">>> trying to reissue command without Le...");
|
PrintAndLogEx(INFO, ">>> trying to reissue command without Le...");
|
||||||
res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU) {0x80, 0x2a, 0x8e, 0x80, UDOLlen, UDOL}, false, Result, MaxResultLen, ResultLen, sw, tlv);
|
res = EMVExchangeEx(channel, false, LeaveFieldON, (sAPDU_t) {0x80, 0x2a, 0x8e, 0x80, UDOLlen, UDOL}, false, Result, MaxResultLen, ResultLen, sw, tlv);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ struct tlvdb *GetPANFromTrack2(const struct tlv *track2);
|
||||||
struct tlvdb *GetdCVVRawFromTrack2(const struct tlv *track2);
|
struct tlvdb *GetdCVVRawFromTrack2(const struct tlv *track2);
|
||||||
|
|
||||||
// exchange
|
// exchange
|
||||||
int EMVExchange(Iso7816CommandChannel channel, bool LeaveFieldON, sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv);
|
int EMVExchange(Iso7816CommandChannel channel, bool LeaveFieldON, sAPDU_t apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv);
|
||||||
|
|
||||||
// search application
|
// search application
|
||||||
int EMVSearchPSE(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t PSENum, bool decodeTLV, struct tlvdb *tlv);
|
int EMVSearchPSE(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t PSENum, bool decodeTLV, struct tlvdb *tlv);
|
||||||
|
|
|
@ -175,14 +175,14 @@ int FIDOSelect(bool ActivateField, bool LeaveFieldON, uint8_t *Result, size_t Ma
|
||||||
return Iso7816Select(CC_CONTACTLESS, ActivateField, LeaveFieldON, data, sizeof(data), Result, MaxResultLen, ResultLen, sw);
|
return Iso7816Select(CC_CONTACTLESS, ActivateField, LeaveFieldON, data, sizeof(data), Result, MaxResultLen, ResultLen, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FIDOExchange(sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
int FIDOExchange(sAPDU_t apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
||||||
int res = Iso7816Exchange(CC_CONTACTLESS, true, apdu, Result, MaxResultLen, ResultLen, sw);
|
int res = Iso7816Exchange(CC_CONTACTLESS, true, apdu, Result, MaxResultLen, ResultLen, sw);
|
||||||
if (res == 5) // apdu result (sw) not a 0x9000
|
if (res == 5) // apdu result (sw) not a 0x9000
|
||||||
res = 0;
|
res = 0;
|
||||||
// software chaining
|
// software chaining
|
||||||
while (!res && (*sw >> 8) == 0x61) {
|
while (!res && (*sw >> 8) == 0x61) {
|
||||||
size_t oldlen = *ResultLen;
|
size_t oldlen = *ResultLen;
|
||||||
res = Iso7816Exchange(CC_CONTACTLESS, true, (sAPDU) {0x00, 0xC0, 0x00, 0x00, 0x00, NULL}, &Result[oldlen], MaxResultLen - oldlen, ResultLen, sw);
|
res = Iso7816Exchange(CC_CONTACTLESS, true, (sAPDU_t) {0x00, 0xC0, 0x00, 0x00, 0x00, NULL}, &Result[oldlen], MaxResultLen - oldlen, ResultLen, sw);
|
||||||
if (res == 5) // apdu result (sw) not a 0x9000
|
if (res == 5) // apdu result (sw) not a 0x9000
|
||||||
res = 0;
|
res = 0;
|
||||||
|
|
||||||
|
@ -194,30 +194,30 @@ int FIDOExchange(sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *Resul
|
||||||
}
|
}
|
||||||
|
|
||||||
int FIDORegister(uint8_t *params, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
int FIDORegister(uint8_t *params, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
||||||
return FIDOExchange((sAPDU) {0x00, 0x01, 0x03, 0x00, 64, params}, Result, MaxResultLen, ResultLen, sw);
|
return FIDOExchange((sAPDU_t) {0x00, 0x01, 0x03, 0x00, 64, params}, Result, MaxResultLen, ResultLen, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FIDOAuthentication(uint8_t *params, uint8_t paramslen, uint8_t controlb, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
int FIDOAuthentication(uint8_t *params, uint8_t paramslen, uint8_t controlb, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
||||||
return FIDOExchange((sAPDU) {0x00, 0x02, controlb, 0x00, paramslen, params}, Result, MaxResultLen, ResultLen, sw);
|
return FIDOExchange((sAPDU_t) {0x00, 0x02, controlb, 0x00, paramslen, params}, Result, MaxResultLen, ResultLen, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FIDO2GetInfo(uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
int FIDO2GetInfo(uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
||||||
uint8_t data[] = {fido2CmdGetInfo};
|
uint8_t data[] = {fido2CmdGetInfo};
|
||||||
return FIDOExchange((sAPDU) {0x80, 0x10, 0x00, 0x00, sizeof(data), data}, Result, MaxResultLen, ResultLen, sw);
|
return FIDOExchange((sAPDU_t) {0x80, 0x10, 0x00, 0x00, sizeof(data), data}, Result, MaxResultLen, ResultLen, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FIDO2MakeCredential(uint8_t *params, uint8_t paramslen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
int FIDO2MakeCredential(uint8_t *params, uint8_t paramslen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
||||||
uint8_t data[paramslen + 1];
|
uint8_t data[paramslen + 1];
|
||||||
data[0] = fido2CmdMakeCredential;
|
data[0] = fido2CmdMakeCredential;
|
||||||
memcpy(&data[1], params, paramslen);
|
memcpy(&data[1], params, paramslen);
|
||||||
return FIDOExchange((sAPDU) {0x80, 0x10, 0x00, 0x00, sizeof(data), data}, Result, MaxResultLen, ResultLen, sw);
|
return FIDOExchange((sAPDU_t) {0x80, 0x10, 0x00, 0x00, sizeof(data), data}, Result, MaxResultLen, ResultLen, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FIDO2GetAssertion(uint8_t *params, uint8_t paramslen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
int FIDO2GetAssertion(uint8_t *params, uint8_t paramslen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
|
||||||
uint8_t data[paramslen + 1];
|
uint8_t data[paramslen + 1];
|
||||||
data[0] = fido2CmdGetAssertion;
|
data[0] = fido2CmdGetAssertion;
|
||||||
memcpy(&data[1], params, paramslen);
|
memcpy(&data[1], params, paramslen);
|
||||||
return FIDOExchange((sAPDU) {0x80, 0x10, 0x00, 0x00, sizeof(data), data}, Result, MaxResultLen, ResultLen, sw);
|
return FIDOExchange((sAPDU_t) {0x80, 0x10, 0x00, 0x00, sizeof(data), data}, Result, MaxResultLen, ResultLen, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FIDOCheckDERAndGetKey(uint8_t *der, size_t derLen, bool verbose, uint8_t *publicKey, size_t publicKeyMaxLen) {
|
int FIDOCheckDERAndGetKey(uint8_t *der, size_t derLen, bool verbose, uint8_t *publicKey, size_t publicKeyMaxLen) {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include "iso7816/apduinfo.h" // sAPDU
|
#include "iso7816/apduinfo.h" // sAPDU_t
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
fido2CmdMakeCredential = 0x01,
|
fido2CmdMakeCredential = 0x01,
|
||||||
|
@ -36,7 +36,7 @@ typedef enum {
|
||||||
} fido2PacketType;
|
} fido2PacketType;
|
||||||
|
|
||||||
int FIDOSelect(bool ActivateField, bool LeaveFieldON, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
int FIDOSelect(bool ActivateField, bool LeaveFieldON, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
||||||
int FIDOExchange(sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
int FIDOExchange(sAPDU_t apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
||||||
int FIDORegister(uint8_t *params, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
int FIDORegister(uint8_t *params, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
||||||
int FIDOAuthentication(uint8_t *params, uint8_t paramslen, uint8_t controlb, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
int FIDOAuthentication(uint8_t *params, uint8_t paramslen, uint8_t controlb, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
||||||
int FIDO2GetInfo(uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
int FIDO2GetInfo(uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
||||||
|
|
|
@ -76,8 +76,8 @@ static int chipid_to_mem_avail(uint32_t iChipID) {
|
||||||
|
|
||||||
// Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent
|
// Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent
|
||||||
// unaligned segments if needed
|
// unaligned segments if needed
|
||||||
static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint16_t num_phdrs, uint32_t flash_end) {
|
static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr_t *phdrs, uint16_t num_phdrs, uint32_t flash_end) {
|
||||||
Elf32_Phdr *phdr = phdrs;
|
Elf32_Phdr_t *phdr = phdrs;
|
||||||
flash_seg_t *seg;
|
flash_seg_t *seg;
|
||||||
uint32_t last_end = 0;
|
uint32_t last_end = 0;
|
||||||
|
|
||||||
|
@ -231,8 +231,8 @@ static int check_segs(flash_file_t *ctx, int can_write_bl, uint32_t flash_end) {
|
||||||
// Load an ELF file and prepare it for flashing
|
// Load an ELF file and prepare it for flashing
|
||||||
int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_size) {
|
int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_size) {
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
Elf32_Ehdr ehdr;
|
Elf32_Ehdr_t ehdr;
|
||||||
Elf32_Phdr *phdrs = NULL;
|
Elf32_Phdr_t *phdrs = NULL;
|
||||||
uint16_t num_phdrs;
|
uint16_t num_phdrs;
|
||||||
uint32_t flash_end = FLASH_START + flash_size;
|
uint32_t flash_end = FLASH_START + flash_size;
|
||||||
int res = PM3_EUNDEF;
|
int res = PM3_EUNDEF;
|
||||||
|
@ -272,7 +272,7 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
|
||||||
res = PM3_EFILE;
|
res = PM3_EFILE;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (le16(ehdr.e_phentsize) != sizeof(Elf32_Phdr)) {
|
if (le16(ehdr.e_phentsize) != sizeof(Elf32_Phdr_t)) {
|
||||||
// could be a structure padding issue...
|
// could be a structure padding issue...
|
||||||
PrintAndLogEx(ERR, "Either the ELF file or this code is made of fail");
|
PrintAndLogEx(ERR, "Either the ELF file or this code is made of fail");
|
||||||
res = PM3_EFILE;
|
res = PM3_EFILE;
|
||||||
|
@ -280,7 +280,7 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
|
||||||
}
|
}
|
||||||
num_phdrs = le16(ehdr.e_phnum);
|
num_phdrs = le16(ehdr.e_phnum);
|
||||||
|
|
||||||
phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr), sizeof(uint8_t));
|
phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr_t), sizeof(uint8_t));
|
||||||
if (!phdrs) {
|
if (!phdrs) {
|
||||||
PrintAndLogEx(ERR, "Out of memory");
|
PrintAndLogEx(ERR, "Out of memory");
|
||||||
res = PM3_EMALLOC;
|
res = PM3_EMALLOC;
|
||||||
|
@ -291,7 +291,7 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
|
||||||
res = PM3_EFILE;
|
res = PM3_EFILE;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (fread(phdrs, sizeof(Elf32_Phdr), num_phdrs, fd) != num_phdrs) {
|
if (fread(phdrs, sizeof(Elf32_Phdr_t), num_phdrs, fd) != num_phdrs) {
|
||||||
res = PM3_EFILE;
|
res = PM3_EFILE;
|
||||||
PrintAndLogEx(ERR, "Error while reading ELF PHDRs");
|
PrintAndLogEx(ERR, "Error while reading ELF PHDRs");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "commonutil.h" // ARRAYLEN
|
#include "commonutil.h" // ARRAYLEN
|
||||||
|
|
||||||
const APDUCode APDUCodeTable[] = {
|
const APDUCode_t APDUCodeTable[] = {
|
||||||
// ID Type Description
|
// ID Type Description
|
||||||
{"XXXX", APDUCODE_TYPE_NONE, ""}, // blank string
|
{"XXXX", APDUCODE_TYPE_NONE, ""}, // blank string
|
||||||
{"6---", APDUCODE_TYPE_ERROR, "Class not supported."},
|
{"6---", APDUCODE_TYPE_ERROR, "Class not supported."},
|
||||||
|
@ -283,7 +283,7 @@ static int CodeCmp(const char *code1, const char *code2) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const APDUCode *GetAPDUCode(uint8_t sw1, uint8_t sw2) {
|
const APDUCode_t *GetAPDUCode(uint8_t sw1, uint8_t sw2) {
|
||||||
char buf[6] = {0};
|
char buf[6] = {0};
|
||||||
int mineq = ARRAYLEN(APDUCodeTable);
|
int mineq = ARRAYLEN(APDUCodeTable);
|
||||||
int mineqindx = 0;
|
int mineqindx = 0;
|
||||||
|
@ -314,15 +314,15 @@ const APDUCode *GetAPDUCode(uint8_t sw1, uint8_t sw2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2) {
|
const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2) {
|
||||||
const APDUCode *cd = GetAPDUCode(sw1, sw2);
|
const APDUCode_t *cd = GetAPDUCode(sw1, sw2);
|
||||||
if (cd)
|
if (cd)
|
||||||
return cd->Description;
|
return cd->Description;
|
||||||
else
|
else
|
||||||
return APDUCodeTable[0].Description; //empty string
|
return APDUCodeTable[0].Description; //empty string
|
||||||
}
|
}
|
||||||
|
|
||||||
int APDUDecode(uint8_t *data, int len, APDUStruct *apdu) {
|
int APDUDecode(uint8_t *data, int len, APDU_t *apdu) {
|
||||||
ExtAPDUHeader *hapdu = (ExtAPDUHeader *)data;
|
ExtAPDUHeader_t *hapdu = (ExtAPDUHeader_t *)data;
|
||||||
|
|
||||||
apdu->cla = hapdu->cla;
|
apdu->cla = hapdu->cla;
|
||||||
apdu->ins = hapdu->ins;
|
apdu->ins = hapdu->ins;
|
||||||
|
@ -421,7 +421,7 @@ int APDUDecode(uint8_t *data, int len, APDUStruct *apdu) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len) {
|
int APDUEncode(APDU_t *apdu, uint8_t *data, int *len) {
|
||||||
if (len)
|
if (len)
|
||||||
*len = 0;
|
*len = 0;
|
||||||
|
|
||||||
|
@ -473,11 +473,11 @@ int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int APDUEncodeS(sAPDU *sapdu, bool extended, uint16_t le, uint8_t *data, int *len) {
|
int APDUEncodeS(sAPDU_t *sapdu, bool extended, uint16_t le, uint8_t *data, int *len) {
|
||||||
if (extended && le > 0x100)
|
if (extended && le > 0x100)
|
||||||
return 10;
|
return 10;
|
||||||
|
|
||||||
APDUStruct apdu;
|
APDU_t apdu;
|
||||||
|
|
||||||
apdu.cla = sapdu->CLA;
|
apdu.cla = sapdu->CLA;
|
||||||
apdu.ins = sapdu->INS;
|
apdu.ins = sapdu->INS;
|
||||||
|
@ -497,11 +497,11 @@ int APDUEncodeS(sAPDU *sapdu, bool extended, uint16_t le, uint8_t *data, int *le
|
||||||
return APDUEncode(&apdu, data, len);
|
return APDUEncode(&apdu, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void APDUPrint(APDUStruct apdu) {
|
void APDUPrint(APDU_t apdu) {
|
||||||
APDUPrintEx(apdu, 0);
|
APDUPrintEx(apdu, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void APDUPrintEx(APDUStruct apdu, size_t maxdatalen) {
|
void APDUPrintEx(APDU_t apdu, size_t maxdatalen) {
|
||||||
PrintAndLogEx(INFO, "APDU: %scase=0x%02x cla=0x%02x ins=0x%02x p1=0x%02x p2=0x%02x Lc=0x%02x(%d) Le=0x%02x(%d)",
|
PrintAndLogEx(INFO, "APDU: %scase=0x%02x cla=0x%02x ins=0x%02x p1=0x%02x p2=0x%02x Lc=0x%02x(%d) Le=0x%02x(%d)",
|
||||||
apdu.extended_apdu ? "[e]" : "",
|
apdu.extended_apdu ? "[e]" : "",
|
||||||
apdu.case_type,
|
apdu.case_type,
|
||||||
|
@ -518,7 +518,7 @@ void APDUPrintEx(APDUStruct apdu, size_t maxdatalen) {
|
||||||
PrintAndLogEx(INFO, "data: %s%s", sprint_hex(apdu.data, MIN(apdu.lc, maxdatalen)), apdu.lc > maxdatalen ? "..." : "");
|
PrintAndLogEx(INFO, "data: %s%s", sprint_hex(apdu.data, MIN(apdu.lc, maxdatalen)), apdu.lc > maxdatalen ? "..." : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SAPDUPrint(sAPDU apdu, size_t maxdatalen) {
|
void SAPDUPrint(sAPDU_t apdu, size_t maxdatalen) {
|
||||||
PrintAndLogEx(INFO, "APDU: CLA 0x%02x, INS 0x%02x, P1 0x%02x, P2 0x%02x, Lc 0x%02x(%d)",
|
PrintAndLogEx(INFO, "APDU: CLA 0x%02x, INS 0x%02x, P1 0x%02x, P2 0x%02x, Lc 0x%02x(%d)",
|
||||||
apdu.CLA,
|
apdu.CLA,
|
||||||
apdu.INS,
|
apdu.INS,
|
||||||
|
|
|
@ -25,9 +25,9 @@ typedef struct {
|
||||||
const char *ID;
|
const char *ID;
|
||||||
const uint8_t Type;
|
const uint8_t Type;
|
||||||
const char *Description;
|
const char *Description;
|
||||||
} APDUCode;
|
} APDUCode_t;
|
||||||
|
|
||||||
const APDUCode *GetAPDUCode(uint8_t sw1, uint8_t sw2);
|
const APDUCode_t *GetAPDUCode(uint8_t sw1, uint8_t sw2);
|
||||||
const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2);
|
const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -37,7 +37,7 @@ typedef struct {
|
||||||
uint8_t P2;
|
uint8_t P2;
|
||||||
uint8_t Lc;
|
uint8_t Lc;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
} PACKED sAPDU;
|
} PACKED sAPDU_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t cla;
|
uint8_t cla;
|
||||||
|
@ -45,7 +45,7 @@ typedef struct {
|
||||||
uint8_t p1;
|
uint8_t p1;
|
||||||
uint8_t p2;
|
uint8_t p2;
|
||||||
uint8_t lc[3];
|
uint8_t lc[3];
|
||||||
} PACKED ExtAPDUHeader;
|
} PACKED ExtAPDUHeader_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t cla;
|
uint8_t cla;
|
||||||
|
@ -57,13 +57,13 @@ typedef struct {
|
||||||
uint32_t le;
|
uint32_t le;
|
||||||
bool extended_apdu;
|
bool extended_apdu;
|
||||||
uint8_t case_type;
|
uint8_t case_type;
|
||||||
} PACKED APDUStruct;
|
} PACKED APDU_t;
|
||||||
|
|
||||||
extern int APDUDecode(uint8_t *data, int len, APDUStruct *apdu);
|
extern int APDUDecode(uint8_t *data, int len, APDU_t *apdu);
|
||||||
extern int APDUEncode(APDUStruct *apdu, uint8_t *data, int *len);
|
extern int APDUEncode(APDU_t *apdu, uint8_t *data, int *len);
|
||||||
extern int APDUEncodeS(sAPDU *sapdu, bool extended, uint16_t le, uint8_t *data, int *len);
|
extern int APDUEncodeS(sAPDU_t *sapdu, bool extended, uint16_t le, uint8_t *data, int *len);
|
||||||
extern void APDUPrint(APDUStruct apdu);
|
extern void APDUPrint(APDU_t apdu);
|
||||||
extern void APDUPrintEx(APDUStruct apdu, size_t maxdatalen);
|
extern void APDUPrintEx(APDU_t apdu, size_t maxdatalen);
|
||||||
|
|
||||||
void SAPDUPrint(sAPDU apdu, size_t maxdatalen);
|
void SAPDUPrint(sAPDU_t apdu, size_t maxdatalen);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -74,7 +74,7 @@ int Iso7816Connect(Iso7816CommandChannel channel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool activate_field, bool leave_field_on,
|
int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool activate_field, bool leave_field_on,
|
||||||
sAPDU apdu, bool include_le, uint16_t le, uint8_t *result,
|
sAPDU_t apdu, bool include_le, uint16_t le, uint8_t *result,
|
||||||
size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||||
|
|
||||||
*result_len = 0;
|
*result_len = 0;
|
||||||
|
@ -175,7 +175,7 @@ int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool activate_field, bool l
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Iso7816Exchange(Iso7816CommandChannel channel, bool leave_field_on, sAPDU apdu, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
int Iso7816Exchange(Iso7816CommandChannel channel, bool leave_field_on, sAPDU_t apdu, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
|
||||||
return Iso7816ExchangeEx(channel
|
return Iso7816ExchangeEx(channel
|
||||||
, false
|
, false
|
||||||
, leave_field_on
|
, leave_field_on
|
||||||
|
@ -195,7 +195,7 @@ int Iso7816Select(Iso7816CommandChannel channel, bool activate_field, bool leave
|
||||||
return Iso7816ExchangeEx(channel
|
return Iso7816ExchangeEx(channel
|
||||||
, activate_field
|
, activate_field
|
||||||
, leave_field_on
|
, leave_field_on
|
||||||
, (sAPDU) {0x00, 0xa4, 0x04, 0x00, aid_len, aid}
|
, (sAPDU_t) {0x00, 0xa4, 0x04, 0x00, aid_len, aid}
|
||||||
, (channel == CC_CONTACTLESS)
|
, (channel == CC_CONTACTLESS)
|
||||||
, 0
|
, 0
|
||||||
, result
|
, result
|
||||||
|
|
|
@ -39,10 +39,10 @@ isodep_state_t GetISODEPState(void);
|
||||||
int Iso7816Connect(Iso7816CommandChannel channel);
|
int Iso7816Connect(Iso7816CommandChannel channel);
|
||||||
|
|
||||||
// exchange
|
// exchange
|
||||||
int Iso7816Exchange(Iso7816CommandChannel channel, bool leave_field_on, sAPDU apdu, uint8_t *result, size_t max_result_len,
|
int Iso7816Exchange(Iso7816CommandChannel channel, bool leave_field_on, sAPDU_t apdu, uint8_t *result, size_t max_result_len,
|
||||||
size_t *result_len, uint16_t *sw);
|
size_t *result_len, uint16_t *sw);
|
||||||
|
|
||||||
int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool activate_field, bool leave_field_on, sAPDU apdu, bool include_le,
|
int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool activate_field, bool leave_field_on, sAPDU_t apdu, bool include_le,
|
||||||
uint16_t le, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw);
|
uint16_t le, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw);
|
||||||
|
|
||||||
// search application
|
// search application
|
||||||
|
|
|
@ -421,7 +421,7 @@ void DesfirePrintContext(DesfireContext *ctx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DESFIRESendApduEx(bool activate_field, sAPDU apdu, uint16_t le, uint8_t *result, uint32_t max_result_len, uint32_t *result_len, uint16_t *sw) {
|
static int DESFIRESendApduEx(bool activate_field, sAPDU_t apdu, uint16_t le, uint8_t *result, uint32_t max_result_len, uint32_t *result_len, uint16_t *sw) {
|
||||||
if (result_len) *result_len = 0;
|
if (result_len) *result_len = 0;
|
||||||
if (sw) *sw = 0;
|
if (sw) *sw = 0;
|
||||||
|
|
||||||
|
@ -480,7 +480,7 @@ static int DESFIRESendApduEx(bool activate_field, sAPDU apdu, uint16_t le, uint8
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DESFIRESendApdu(bool activate_field, sAPDU apdu, uint8_t *result, uint32_t max_result_len, uint32_t *result_len, uint16_t *sw) {
|
static int DESFIRESendApdu(bool activate_field, sAPDU_t apdu, uint8_t *result, uint32_t max_result_len, uint32_t *result_len, uint16_t *sw) {
|
||||||
return DESFIRESendApduEx(activate_field, apdu, APDU_INCLUDE_LE_00, result, max_result_len, result_len, sw);
|
return DESFIRESendApduEx(activate_field, apdu, APDU_INCLUDE_LE_00, result, max_result_len, result_len, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,7 +642,7 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext *ctx, ui
|
||||||
uint32_t pos = 0;
|
uint32_t pos = 0;
|
||||||
uint32_t i = 1;
|
uint32_t i = 1;
|
||||||
|
|
||||||
sAPDU apdu = {0};
|
sAPDU_t apdu = {0};
|
||||||
apdu.CLA = MFDES_NATIVE_ISO7816_WRAP_CLA; //0x90
|
apdu.CLA = MFDES_NATIVE_ISO7816_WRAP_CLA; //0x90
|
||||||
apdu.INS = cmd;
|
apdu.INS = cmd;
|
||||||
apdu.Lc = datalen;
|
apdu.Lc = datalen;
|
||||||
|
@ -736,7 +736,7 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext *ctx, ui
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DesfireExchangeISO(bool activate_field, DesfireContext *ctx, sAPDU apdu, uint16_t le, uint8_t *resp, size_t *resplen, uint16_t *sw) {
|
static int DesfireExchangeISO(bool activate_field, DesfireContext *ctx, sAPDU_t apdu, uint16_t le, uint8_t *resp, size_t *resplen, uint16_t *sw) {
|
||||||
uint8_t data[1050] = {0};
|
uint8_t data[1050] = {0};
|
||||||
uint32_t datalen = 0;
|
uint32_t datalen = 0;
|
||||||
int res = DESFIRESendApduEx(activate_field, apdu, le, data, sizeof(data), &datalen, sw);
|
int res = DESFIRESendApduEx(activate_field, apdu, le, data, sizeof(data), &datalen, sw);
|
||||||
|
@ -1632,7 +1632,7 @@ static bool DesfireCheckISOAuthCmd(uint32_t appAID, char *dfname, uint8_t keyNum
|
||||||
uint16_t sw = 0;
|
uint16_t sw = 0;
|
||||||
uint8_t p1 = DesfireKeyToISOKey(keytype);
|
uint8_t p1 = DesfireKeyToISOKey(keytype);
|
||||||
uint8_t p2 = ((app_level) ? 0x80 : 0x00) | keyNum;
|
uint8_t p2 = ((app_level) ? 0x80 : 0x00) | keyNum;
|
||||||
res = DesfireExchangeISO(false, &dctx, (sAPDU) {0x00, ISO7816_EXTERNAL_AUTHENTICATION, p1, p2, rndlen * 2, piccrnd}, 0, resp, &resplen, &sw);
|
res = DesfireExchangeISO(false, &dctx, (sAPDU_t) {0x00, ISO7816_EXTERNAL_AUTHENTICATION, p1, p2, rndlen * 2, piccrnd}, 0, resp, &resplen, &sw);
|
||||||
DropField();
|
DropField();
|
||||||
return (sw == 0x9000 || sw == 0x6982);
|
return (sw == 0x9000 || sw == 0x6982);
|
||||||
}
|
}
|
||||||
|
@ -2805,7 +2805,7 @@ int DesfireISOSelectEx(DesfireContext *dctx, bool fieldon, DesfireISOSelectContr
|
||||||
uint8_t xresp[250] = {0};
|
uint8_t xresp[250] = {0};
|
||||||
size_t xresplen = 0;
|
size_t xresplen = 0;
|
||||||
uint16_t sw = 0;
|
uint16_t sw = 0;
|
||||||
int res = DesfireExchangeISO(fieldon, dctx, (sAPDU) {0x00, ISO7816_SELECT_FILE, cntr, ((resp == NULL) ? 0x0C : 0x00), datalen, data}, APDU_INCLUDE_LE_00, xresp, &xresplen, &sw);
|
int res = DesfireExchangeISO(fieldon, dctx, (sAPDU_t) {0x00, ISO7816_SELECT_FILE, cntr, ((resp == NULL) ? 0x0C : 0x00), datalen, data}, APDU_INCLUDE_LE_00, xresp, &xresplen, &sw);
|
||||||
if (res == PM3_SUCCESS && sw != 0x9000)
|
if (res == PM3_SUCCESS && sw != 0x9000)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
|
@ -2831,7 +2831,7 @@ int DesfireISOSelectDF(DesfireContext *dctx, char *dfname, uint8_t *resp, size_t
|
||||||
|
|
||||||
int DesfireISOGetChallenge(DesfireContext *dctx, DesfireCryptoAlgorythm keytype, uint8_t *resp, size_t *resplen) {
|
int DesfireISOGetChallenge(DesfireContext *dctx, DesfireCryptoAlgorythm keytype, uint8_t *resp, size_t *resplen) {
|
||||||
uint16_t sw = 0;
|
uint16_t sw = 0;
|
||||||
int res = DesfireExchangeISO(false, dctx, (sAPDU) {0x00, ISO7816_GET_CHALLENGE, 0x00, 0x00, 0x00, NULL}, DesfireGetRndLenForKey(keytype), resp, resplen, &sw);
|
int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_GET_CHALLENGE, 0x00, 0x00, 0x00, NULL}, DesfireGetRndLenForKey(keytype), resp, resplen, &sw);
|
||||||
if (res == PM3_SUCCESS && sw != 0x9000)
|
if (res == PM3_SUCCESS && sw != 0x9000)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
|
@ -2846,7 +2846,7 @@ int DesfireISOExternalAuth(DesfireContext *dctx, bool app_level, uint8_t keynum,
|
||||||
size_t resplen = 0;
|
size_t resplen = 0;
|
||||||
|
|
||||||
uint16_t sw = 0;
|
uint16_t sw = 0;
|
||||||
int res = DesfireExchangeISO(false, dctx, (sAPDU) {0x00, ISO7816_EXTERNAL_AUTHENTICATION, p1, p2, DesfireGetRndLenForKey(keytype) * 2, data}, 0, resp, &resplen, &sw);
|
int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_EXTERNAL_AUTHENTICATION, p1, p2, DesfireGetRndLenForKey(keytype) * 2, data}, 0, resp, &resplen, &sw);
|
||||||
if (res == PM3_SUCCESS && sw != 0x9000)
|
if (res == PM3_SUCCESS && sw != 0x9000)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
|
@ -2859,7 +2859,7 @@ int DesfireISOInternalAuth(DesfireContext *dctx, bool app_level, uint8_t keynum,
|
||||||
uint8_t p2 = ((app_level) ? 0x80 : 0x00) | keynum;
|
uint8_t p2 = ((app_level) ? 0x80 : 0x00) | keynum;
|
||||||
|
|
||||||
uint16_t sw = 0;
|
uint16_t sw = 0;
|
||||||
int res = DesfireExchangeISO(false, dctx, (sAPDU) {0x00, ISO7816_INTERNAL_AUTHENTICATION, p1, p2, keylen, data}, keylen * 2, resp, resplen, &sw);
|
int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_INTERNAL_AUTHENTICATION, p1, p2, keylen, data}, keylen * 2, resp, resplen, &sw);
|
||||||
if (res == PM3_SUCCESS && sw != 0x9000)
|
if (res == PM3_SUCCESS && sw != 0x9000)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
|
@ -2875,7 +2875,7 @@ int DesfireISOReadBinary(DesfireContext *dctx, bool use_file_id, uint8_t fileid,
|
||||||
uint8_t p2 = offset & 0xff;
|
uint8_t p2 = offset & 0xff;
|
||||||
|
|
||||||
uint16_t sw = 0;
|
uint16_t sw = 0;
|
||||||
int res = DesfireExchangeISO(false, dctx, (sAPDU) {0x00, ISO7816_READ_BINARY, p1, p2, 0, NULL}, (length == 0) ? APDU_INCLUDE_LE_00 : length, resp, resplen, &sw);
|
int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_READ_BINARY, p1, p2, 0, NULL}, (length == 0) ? APDU_INCLUDE_LE_00 : length, resp, resplen, &sw);
|
||||||
if (res == PM3_SUCCESS && sw != 0x9000)
|
if (res == PM3_SUCCESS && sw != 0x9000)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
|
@ -2894,7 +2894,7 @@ int DesfireISOUpdateBinary(DesfireContext *dctx, bool use_file_id, uint8_t filei
|
||||||
size_t resplen = 0;
|
size_t resplen = 0;
|
||||||
|
|
||||||
uint16_t sw = 0;
|
uint16_t sw = 0;
|
||||||
int res = DesfireExchangeISO(false, dctx, (sAPDU) {0x00, ISO7816_UPDATE_BINARY, p1, p2, datalen, data}, 0, resp, &resplen, &sw);
|
int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_UPDATE_BINARY, p1, p2, datalen, data}, 0, resp, &resplen, &sw);
|
||||||
if (res == PM3_SUCCESS && sw != 0x9000)
|
if (res == PM3_SUCCESS && sw != 0x9000)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
|
@ -2905,7 +2905,7 @@ int DesfireISOReadRecords(DesfireContext *dctx, uint8_t recordnum, bool read_all
|
||||||
uint8_t p2 = ((fileid & 0x1f) << 3) | ((read_all_records) ? 0x05 : 0x04);
|
uint8_t p2 = ((fileid & 0x1f) << 3) | ((read_all_records) ? 0x05 : 0x04);
|
||||||
|
|
||||||
uint16_t sw = 0;
|
uint16_t sw = 0;
|
||||||
int res = DesfireExchangeISO(false, dctx, (sAPDU) {0x00, ISO7816_READ_RECORDS, recordnum, p2, 0, NULL}, (length == 0) ? APDU_INCLUDE_LE_00 : length, resp, resplen, &sw);
|
int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_READ_RECORDS, recordnum, p2, 0, NULL}, (length == 0) ? APDU_INCLUDE_LE_00 : length, resp, resplen, &sw);
|
||||||
if (res == PM3_SUCCESS && sw != 0x9000)
|
if (res == PM3_SUCCESS && sw != 0x9000)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
|
@ -2919,7 +2919,7 @@ int DesfireISOAppendRecord(DesfireContext *dctx, uint8_t fileid, uint8_t *data,
|
||||||
size_t resplen = 0;
|
size_t resplen = 0;
|
||||||
|
|
||||||
uint16_t sw = 0;
|
uint16_t sw = 0;
|
||||||
int res = DesfireExchangeISO(false, dctx, (sAPDU) {0x00, ISO7816_APPEND_RECORD, 0x00, p2, datalen, data}, 0, resp, &resplen, &sw);
|
int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_APPEND_RECORD, 0x00, p2, datalen, data}, 0, resp, &resplen, &sw);
|
||||||
if (res == PM3_SUCCESS && sw != 0x9000)
|
if (res == PM3_SUCCESS && sw != 0x9000)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ typedef struct {
|
||||||
int fd; // Serial port file descriptor
|
int fd; // Serial port file descriptor
|
||||||
term_info tiOld; // Terminal info before using the port
|
term_info tiOld; // Terminal info before using the port
|
||||||
term_info tiNew; // Terminal info during the transaction
|
term_info tiNew; // Terminal info during the transaction
|
||||||
} serial_port_unix;
|
} serial_port_unix_t_t;
|
||||||
|
|
||||||
// see pm3_cmd.h
|
// see pm3_cmd.h
|
||||||
struct timeval timeout = {
|
struct timeval timeout = {
|
||||||
|
@ -87,7 +87,7 @@ int uart_reconfigure_timeouts(uint32_t value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
serial_port uart_open(const char *pcPortName, uint32_t speed) {
|
serial_port uart_open(const char *pcPortName, uint32_t speed) {
|
||||||
serial_port_unix *sp = calloc(sizeof(serial_port_unix), sizeof(uint8_t));
|
serial_port_unix_t_t *sp = calloc(sizeof(serial_port_unix_t_t), sizeof(uint8_t));
|
||||||
|
|
||||||
if (sp == 0) {
|
if (sp == 0) {
|
||||||
PrintAndLogEx(ERR, "UART failed to allocate memory");
|
PrintAndLogEx(ERR, "UART failed to allocate memory");
|
||||||
|
@ -345,7 +345,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_close(const serial_port sp) {
|
void uart_close(const serial_port sp) {
|
||||||
serial_port_unix *spu = (serial_port_unix *)sp;
|
serial_port_unix_t_t *spu = (serial_port_unix_t_t *)sp;
|
||||||
tcflush(spu->fd, TCIOFLUSH);
|
tcflush(spu->fd, TCIOFLUSH);
|
||||||
tcsetattr(spu->fd, TCSANOW, &(spu->tiOld));
|
tcsetattr(spu->fd, TCSANOW, &(spu->tiOld));
|
||||||
struct flock fl;
|
struct flock fl;
|
||||||
|
@ -379,9 +379,9 @@ int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uin
|
||||||
do {
|
do {
|
||||||
// Reset file descriptor
|
// Reset file descriptor
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(((serial_port_unix *)sp)->fd, &rfds);
|
FD_SET(((serial_port_unix_t_t *)sp)->fd, &rfds);
|
||||||
tv = timeout;
|
tv = timeout;
|
||||||
int res = select(((serial_port_unix *)sp)->fd + 1, &rfds, NULL, NULL, &tv);
|
int res = select(((serial_port_unix_t_t *)sp)->fd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
|
||||||
// Read error
|
// Read error
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
@ -400,7 +400,7 @@ int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the count of the incoming bytes
|
// Retrieve the count of the incoming bytes
|
||||||
res = ioctl(((serial_port_unix *)sp)->fd, FIONREAD, &byteCount);
|
res = ioctl(((serial_port_unix_t_t *)sp)->fd, FIONREAD, &byteCount);
|
||||||
// PrintAndLogEx(ERR, "UART:: RX ioctl res %d byteCount %u", res, byteCount);
|
// PrintAndLogEx(ERR, "UART:: RX ioctl res %d byteCount %u", res, byteCount);
|
||||||
if (res < 0) return PM3_ENOTTY;
|
if (res < 0) return PM3_ENOTTY;
|
||||||
|
|
||||||
|
@ -411,7 +411,7 @@ int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uin
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is something available, read the data
|
// There is something available, read the data
|
||||||
res = read(((serial_port_unix *)sp)->fd, pbtRx + (*pszRxLen), byteCount);
|
res = read(((serial_port_unix_t_t *)sp)->fd, pbtRx + (*pszRxLen), byteCount);
|
||||||
|
|
||||||
// Stop if the OS has some troubles reading the data
|
// Stop if the OS has some troubles reading the data
|
||||||
if (res <= 0) {
|
if (res <= 0) {
|
||||||
|
@ -437,9 +437,9 @@ int uart_send(const serial_port sp, const uint8_t *pbtTx, const uint32_t len) {
|
||||||
while (pos < len) {
|
while (pos < len) {
|
||||||
// Reset file descriptor
|
// Reset file descriptor
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(((serial_port_unix *)sp)->fd, &rfds);
|
FD_SET(((serial_port_unix_t_t *)sp)->fd, &rfds);
|
||||||
tv = timeout;
|
tv = timeout;
|
||||||
int res = select(((serial_port_unix *)sp)->fd + 1, NULL, &rfds, NULL, &tv);
|
int res = select(((serial_port_unix_t_t *)sp)->fd + 1, NULL, &rfds, NULL, &tv);
|
||||||
|
|
||||||
// Write error
|
// Write error
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
@ -454,7 +454,7 @@ int uart_send(const serial_port sp, const uint8_t *pbtTx, const uint32_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send away the bytes
|
// Send away the bytes
|
||||||
res = write(((serial_port_unix *)sp)->fd, pbtTx + pos, len - pos);
|
res = write(((serial_port_unix_t_t *)sp)->fd, pbtTx + pos, len - pos);
|
||||||
|
|
||||||
// Stop if the OS has some troubles sending the data
|
// Stop if the OS has some troubles sending the data
|
||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
|
@ -466,7 +466,7 @@ int uart_send(const serial_port sp, const uint8_t *pbtTx, const uint32_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
|
bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
|
||||||
const serial_port_unix *spu = (serial_port_unix *)sp;
|
const serial_port_unix_t_t *spu = (serial_port_unix_t_t *)sp;
|
||||||
speed_t stPortSpeed;
|
speed_t stPortSpeed;
|
||||||
switch (uiPortSpeed) {
|
switch (uiPortSpeed) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -565,7 +565,7 @@ bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
|
||||||
uint32_t uart_get_speed(const serial_port sp) {
|
uint32_t uart_get_speed(const serial_port sp) {
|
||||||
struct termios ti;
|
struct termios ti;
|
||||||
uint32_t uiPortSpeed;
|
uint32_t uiPortSpeed;
|
||||||
const serial_port_unix *spu = (serial_port_unix *)sp;
|
const serial_port_unix_t_t *spu = (serial_port_unix_t_t *)sp;
|
||||||
|
|
||||||
if (tcgetattr(spu->fd, &ti) == -1)
|
if (tcgetattr(spu->fd, &ti) == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -53,7 +53,7 @@ typedef struct {
|
||||||
HANDLE hPort; // Serial port handle
|
HANDLE hPort; // Serial port handle
|
||||||
DCB dcb; // Device control settings
|
DCB dcb; // Device control settings
|
||||||
COMMTIMEOUTS ct; // Serial port time-out configuration
|
COMMTIMEOUTS ct; // Serial port time-out configuration
|
||||||
} serial_port_windows;
|
} serial_port_windows_t;
|
||||||
|
|
||||||
uint32_t newtimeout_value = 0;
|
uint32_t newtimeout_value = 0;
|
||||||
bool newtimeout_pending = false;
|
bool newtimeout_pending = false;
|
||||||
|
@ -69,8 +69,8 @@ static int uart_reconfigure_timeouts_polling(serial_port sp) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
newtimeout_pending = false;
|
newtimeout_pending = false;
|
||||||
|
|
||||||
serial_port_windows *spw;
|
serial_port_windows_t *spw;
|
||||||
spw = (serial_port_windows *)sp;
|
spw = (serial_port_windows_t *)sp;
|
||||||
spw->ct.ReadIntervalTimeout = newtimeout_value;
|
spw->ct.ReadIntervalTimeout = newtimeout_value;
|
||||||
spw->ct.ReadTotalTimeoutMultiplier = 0;
|
spw->ct.ReadTotalTimeoutMultiplier = 0;
|
||||||
spw->ct.ReadTotalTimeoutConstant = newtimeout_value;
|
spw->ct.ReadTotalTimeoutConstant = newtimeout_value;
|
||||||
|
@ -88,7 +88,7 @@ static int uart_reconfigure_timeouts_polling(serial_port sp) {
|
||||||
|
|
||||||
serial_port uart_open(const char *pcPortName, uint32_t speed) {
|
serial_port uart_open(const char *pcPortName, uint32_t speed) {
|
||||||
char acPortName[255] = {0};
|
char acPortName[255] = {0};
|
||||||
serial_port_windows *sp = calloc(sizeof(serial_port_windows), sizeof(uint8_t));
|
serial_port_windows_t *sp = calloc(sizeof(serial_port_windows_t), sizeof(uint8_t));
|
||||||
|
|
||||||
if (sp == 0) {
|
if (sp == 0) {
|
||||||
PrintAndLogEx(WARNING, "UART failed to allocate memory\n");
|
PrintAndLogEx(WARNING, "UART failed to allocate memory\n");
|
||||||
|
@ -140,13 +140,13 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_close(const serial_port sp) {
|
void uart_close(const serial_port sp) {
|
||||||
if (((serial_port_windows *)sp)->hPort != INVALID_HANDLE_VALUE)
|
if (((serial_port_windows_t *)sp)->hPort != INVALID_HANDLE_VALUE)
|
||||||
CloseHandle(((serial_port_windows *)sp)->hPort);
|
CloseHandle(((serial_port_windows_t *)sp)->hPort);
|
||||||
free(sp);
|
free(sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
|
bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
|
||||||
serial_port_windows *spw;
|
serial_port_windows_t *spw;
|
||||||
|
|
||||||
// Set port speed (Input and Output)
|
// Set port speed (Input and Output)
|
||||||
switch (uiPortSpeed) {
|
switch (uiPortSpeed) {
|
||||||
|
@ -164,7 +164,7 @@ bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
spw = (serial_port_windows *)sp;
|
spw = (serial_port_windows_t *)sp;
|
||||||
spw->dcb.BaudRate = uiPortSpeed;
|
spw->dcb.BaudRate = uiPortSpeed;
|
||||||
bool result = SetCommState(spw->hPort, &spw->dcb);
|
bool result = SetCommState(spw->hPort, &spw->dcb);
|
||||||
PurgeComm(spw->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
|
PurgeComm(spw->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
|
||||||
|
@ -175,7 +175,7 @@ bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t uart_get_speed(const serial_port sp) {
|
uint32_t uart_get_speed(const serial_port sp) {
|
||||||
const serial_port_windows *spw = (serial_port_windows *)sp;
|
const serial_port_windows_t *spw = (serial_port_windows_t *)sp;
|
||||||
if (!GetCommState(spw->hPort, (serial_port) & spw->dcb))
|
if (!GetCommState(spw->hPort, (serial_port) & spw->dcb))
|
||||||
return spw->dcb.BaudRate;
|
return spw->dcb.BaudRate;
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ uint32_t uart_get_speed(const serial_port sp) {
|
||||||
|
|
||||||
int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen) {
|
int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen) {
|
||||||
uart_reconfigure_timeouts_polling(sp);
|
uart_reconfigure_timeouts_polling(sp);
|
||||||
int res = ReadFile(((serial_port_windows *)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL);
|
int res = ReadFile(((serial_port_windows_t *)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL);
|
||||||
if (res)
|
if (res)
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uin
|
||||||
|
|
||||||
int uart_send(const serial_port sp, const uint8_t *p_tx, const uint32_t len) {
|
int uart_send(const serial_port sp, const uint8_t *p_tx, const uint32_t len) {
|
||||||
DWORD txlen = 0;
|
DWORD txlen = 0;
|
||||||
int res = WriteFile(((serial_port_windows *)sp)->hPort, p_tx, len, &txlen, NULL);
|
int res = WriteFile(((serial_port_windows_t *)sp)->hPort, p_tx, len, &txlen, NULL);
|
||||||
if (res)
|
if (res)
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue