mirror of
https://gitea.tendokyu.moe/Hay1tsme/segatools.git
synced 2024-11-11 20:37:09 +01:00
iccard: aime authenticity
This commit is contained in:
parent
7051b849fa
commit
5becf8798c
@ -4,6 +4,7 @@
|
||||
|
||||
#include "iccard/aime.h"
|
||||
#include "iccard/mifare.h"
|
||||
#include "iccard/solitaire.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
@ -14,6 +15,9 @@ HRESULT aime_card_populate(
|
||||
{
|
||||
uint8_t b;
|
||||
size_t i;
|
||||
char accessCode[21];
|
||||
char hashed_id_wrk[9];
|
||||
char id_wrk[9];
|
||||
|
||||
assert(mifare != NULL);
|
||||
assert(luid != NULL);
|
||||
@ -37,11 +41,29 @@ HRESULT aime_card_populate(
|
||||
mifare->sectors[0].blocks[2].bytes[6 + i] = b;
|
||||
}
|
||||
|
||||
/* TODO An authentic Aime pass has a checksum of the LUID in the last few
|
||||
bytes of block 1. The output of this function fails authenticity check
|
||||
in its current form. */
|
||||
// Set the card ID, nothing else matters in the first block
|
||||
mifare->sectors[0].blocks[0].bytes[0] = luid[0];
|
||||
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;
|
||||
}
|
||||
|
@ -12,5 +12,7 @@ iccard_lib = static_library(
|
||||
'felica.c',
|
||||
'felica.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