forked from Hay1tsme/segatools
iccard: aime authenticity
This commit is contained in:
parent
7051b849fa
commit
5becf8798c
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "iccard/aime.h"
|
#include "iccard/aime.h"
|
||||||
#include "iccard/mifare.h"
|
#include "iccard/mifare.h"
|
||||||
|
#include "iccard/solitaire.h"
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
@ -14,6 +15,9 @@ HRESULT aime_card_populate(
|
|||||||
{
|
{
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
char accessCode[21];
|
||||||
|
char hashed_id_wrk[9];
|
||||||
|
char id_wrk[9];
|
||||||
|
|
||||||
assert(mifare != NULL);
|
assert(mifare != NULL);
|
||||||
assert(luid != NULL);
|
assert(luid != NULL);
|
||||||
@ -37,11 +41,29 @@ HRESULT aime_card_populate(
|
|||||||
mifare->sectors[0].blocks[2].bytes[6 + i] = b;
|
mifare->sectors[0].blocks[2].bytes[6 + i] = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO An authentic Aime pass has a checksum of the LUID in the last few
|
// Set the card ID, nothing else matters in the first block
|
||||||
bytes of block 1. The output of this function fails authenticity check
|
mifare->sectors[0].blocks[0].bytes[0] = luid[0];
|
||||||
in its current form. */
|
mifare->sectors[0].blocks[0].bytes[1] = luid[1];
|
||||||
|
mifare->sectors[0].blocks[0].bytes[2] = luid[2];
|
||||||
|
mifare->sectors[0].blocks[0].bytes[3] = luid[3];
|
||||||
|
|
||||||
dprintf("AiMe IC: WARNING: Authenticity hash not yet implemented!\n");
|
sprintf_s(accessCode, sizeof accessCode, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||||
|
luid[0], luid[1], luid[2], luid[3], luid[4], luid[5], luid[6], luid[7], luid[8], luid[9]);
|
||||||
|
|
||||||
|
memcpy_s(hashed_id_wrk, sizeof(hashed_id_wrk), &accessCode[5],
|
||||||
|
8);
|
||||||
|
|
||||||
|
hashed_id_wrk[8] = '\0';
|
||||||
|
|
||||||
|
SolitaireCipherDecode(&accessCode[13], hashed_id_wrk, id_wrk);
|
||||||
|
|
||||||
|
|
||||||
|
DWORD nSerial = atoi(id_wrk);
|
||||||
|
|
||||||
|
mifare->sectors[0].blocks[1].bytes[12] = (nSerial >> 24) & 0xff;
|
||||||
|
mifare->sectors[0].blocks[1].bytes[13] = (nSerial >> 16) & 0xff;
|
||||||
|
mifare->sectors[0].blocks[1].bytes[14] = (nSerial >> 8) & 0xff;
|
||||||
|
mifare->sectors[0].blocks[1].bytes[15] = nSerial & 0xff;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -12,5 +12,7 @@ iccard_lib = static_library(
|
|||||||
'felica.c',
|
'felica.c',
|
||||||
'felica.h',
|
'felica.h',
|
||||||
'mifare.h',
|
'mifare.h',
|
||||||
|
'solitaire.c',
|
||||||
|
'solitaire.h',
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
143
iccard/solitaire.c
Normal file
143
iccard/solitaire.c
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#include "solitaire.h"
|
||||||
|
|
||||||
|
#include <memory.h>
|
||||||
|
|
||||||
|
#define DECK_SIZE 22
|
||||||
|
#define JOKER_A 21
|
||||||
|
#define JOKER_B 22
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char m_Deck[DECK_SIZE];
|
||||||
|
} DECK, *PDECK;
|
||||||
|
|
||||||
|
static DECK SOL_INIT_DECK = {
|
||||||
|
.m_Deck = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 },
|
||||||
|
};
|
||||||
|
|
||||||
|
#define char2num(c) ((c) - '0' + 1)
|
||||||
|
static inline char num2char(char num) {
|
||||||
|
while (num < 1) num = num + 10;
|
||||||
|
return (num - 1) % 10 + '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SolMoveCard(PDECK lpDeck, char card) {
|
||||||
|
int p = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < DECK_SIZE; i++) {
|
||||||
|
if (lpDeck->m_Deck[i] == card) {
|
||||||
|
p = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p < DECK_SIZE - 1) {
|
||||||
|
lpDeck->m_Deck[p] = lpDeck->m_Deck[p + 1];
|
||||||
|
lpDeck->m_Deck[p + 1] = card;
|
||||||
|
} else {
|
||||||
|
for (int i = DECK_SIZE - 1; i > 1; i--) lpDeck->m_Deck[i] = lpDeck->m_Deck[i - 1];
|
||||||
|
lpDeck->m_Deck[1] = card;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SolCutDeck(PDECK lpDeck, char point) {
|
||||||
|
DECK tmp;
|
||||||
|
|
||||||
|
memcpy(tmp.m_Deck, &lpDeck->m_Deck[(size_t)point], DECK_SIZE - point - 1);
|
||||||
|
memcpy(&tmp.m_Deck[DECK_SIZE - point - 1], lpDeck->m_Deck, point);
|
||||||
|
memcpy(lpDeck->m_Deck, tmp.m_Deck, DECK_SIZE - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SolSwapOutsideJoker(PDECK lpDeck) {
|
||||||
|
int j1 = -1;
|
||||||
|
int j2 = -1;
|
||||||
|
DECK tmp;
|
||||||
|
|
||||||
|
for (int i = 0; i < DECK_SIZE; i++) {
|
||||||
|
if (lpDeck->m_Deck[i] == JOKER_A || lpDeck->m_Deck[i] == JOKER_B) {
|
||||||
|
if (j1 == -1) {
|
||||||
|
j1 = i;
|
||||||
|
} else {
|
||||||
|
j2 = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 < DECK_SIZE - j2 - 1) memcpy(tmp.m_Deck, &lpDeck->m_Deck[j2 + 1], DECK_SIZE - j2 - 1);
|
||||||
|
tmp.m_Deck[DECK_SIZE - j2 - 1] = lpDeck->m_Deck[j1];
|
||||||
|
if (0 < j2 - j1 - 1) memcpy(&tmp.m_Deck[DECK_SIZE - j2], &lpDeck->m_Deck[j1 + 1], j2 - j1 - 1);
|
||||||
|
tmp.m_Deck[DECK_SIZE - j1 - 1] = lpDeck->m_Deck[j2];
|
||||||
|
if (0 < j1) memcpy(&tmp.m_Deck[DECK_SIZE - j1], lpDeck->m_Deck, j1);
|
||||||
|
memcpy(lpDeck->m_Deck, tmp.m_Deck, DECK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SolCutByBottomCard(PDECK lpDeck) {
|
||||||
|
char p = lpDeck->m_Deck[DECK_SIZE - 1];
|
||||||
|
if (p == JOKER_B) p = JOKER_A;
|
||||||
|
SolCutDeck(lpDeck, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char SolGetTopCardNum(PDECK lpDeck) {
|
||||||
|
char p = lpDeck->m_Deck[0];
|
||||||
|
if (p == JOKER_B) p = JOKER_A;
|
||||||
|
return lpDeck->m_Deck[(size_t)p];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SolDeckHash(PDECK lpDeck) {
|
||||||
|
char p;
|
||||||
|
|
||||||
|
do {
|
||||||
|
SolMoveCard(lpDeck, JOKER_A);
|
||||||
|
SolMoveCard(lpDeck, JOKER_B);
|
||||||
|
SolMoveCard(lpDeck, JOKER_B);
|
||||||
|
SolSwapOutsideJoker(lpDeck);
|
||||||
|
SolCutByBottomCard(lpDeck);
|
||||||
|
|
||||||
|
p = SolGetTopCardNum(lpDeck);
|
||||||
|
} while (p == JOKER_A || p == JOKER_B);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SolCreateDeck(PDECK lpDeck, const char *key) {
|
||||||
|
memcpy_s(lpDeck, sizeof *lpDeck, &SOL_INIT_DECK, sizeof SOL_INIT_DECK);
|
||||||
|
int p = 0;
|
||||||
|
while (key[p] != '\0') {
|
||||||
|
SolDeckHash(lpDeck);
|
||||||
|
char c = char2num(key[p]);
|
||||||
|
SolCutDeck(lpDeck, c);
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolitaireCipherEncode(const char *szKey, const char *szSrc, char *szDst) {
|
||||||
|
DECK deck;
|
||||||
|
SolCreateDeck(&deck, szKey);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (szSrc[i] != '\0') {
|
||||||
|
SolDeckHash(&deck);
|
||||||
|
char p = SolGetTopCardNum(&deck);
|
||||||
|
szDst[i] = num2char(char2num(szSrc[i]) + p);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
szDst[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolitaireCipherDecode(const char *szKey, const char *szSrc, char *szDst) {
|
||||||
|
DECK deck;
|
||||||
|
SolCreateDeck(&deck, szKey);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (szSrc[i] != '\0') {
|
||||||
|
SolDeckHash(&deck);
|
||||||
|
char p = SolGetTopCardNum(&deck);
|
||||||
|
szDst[i] = num2char(char2num(szSrc[i]) - p);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
szDst[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolitaireCipher(int nMode, const char *szKey, const char *szSrc, char *szDst) {
|
||||||
|
if (nMode == 0)
|
||||||
|
SolitaireCipherEncode(szKey, szSrc, szDst);
|
||||||
|
else if (nMode == 1)
|
||||||
|
SolitaireCipherDecode(szKey, szSrc, szDst);
|
||||||
|
}
|
3
iccard/solitaire.h
Normal file
3
iccard/solitaire.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
void SolitaireCipherDecode(const char *szKey, const char *szSrc, char *szDst);
|
||||||
|
void SolitaireCipherEncode(const char *szKey, const char *szSrc, char *szDst);
|
||||||
|
void SolitaireCipher(int mode, const char *key, const char *src_str, char *dest_str);
|
Loading…
Reference in New Issue
Block a user