+//by marshmellow
+//attempts to demodulate and identify a G_Prox_II verex/chubb card
+//WARNING: if it fails during some points it will destroy the DemodBuffer data
+// but will leave the GraphBuffer intact.
+//if successful it will push askraw data back to demod buffer ready for emulation
+int CmdG_Prox_II_Demod(const char *Cmd)
+{
+ int ans = ASKrawDemod(Cmd, FALSE);
+ if (ans <= 0) {
+ if (g_debugMode) PrintAndLog("Error AskrawDemod: %d",ans);
+ return ans;
+ }
+ size_t size = DemodBufferLen;
+ ans = BiphaseRawDecode(DemodBuffer, &size, 0, 0);
+ if (ans !=0) {
+ if (g_debugMode) PrintAndLog("Error BiphaseRawDecode: %d",ans);
+ return ans;
+ }
+ //call lfdemod.c demod for gProxII
+ ans = gProxII_Demod(DemodBuffer, &size);
+ if (ans < 0){
+ if (g_debugMode) PrintAndLog("Error gProxII_Demod 1st Try: %d",ans);
+ //try biphase again
+ ans = BiphaseRawDecode(DemodBuffer, &size, 1, 0);
+ if (ans != 0) {
+ if (g_debugMode) PrintAndLog("Error BiphaseRawDecode: %d",ans);
+ return ans;
+ }
+ ans = gProxII_Demod(DemodBuffer, &size);
+ if (ans < 0) {
+ if (g_debugMode) PrintAndLog("Error gProxII_Demod 1st Try: %d",ans);
+ return ans;
+ }
+ }
+ //got a good demod
+ uint32_t ByteStream[65] = {0x00};
+ uint8_t xorKey=0;
+ uint8_t keyCnt=0;
+ uint8_t bitCnt=0;
+ uint8_t ByteCnt=0;
+ size_t startIdx = ans + 6; //start after preamble
+ for (size_t idx = 0; idx<size-6; idx++){
+ if ((idx+1) % 5 == 0){
+ //spacer bit - should be 0
+ if (DemodBuffer[startIdx+idx] != 0) {
+ if (g_debugMode) PrintAndLog("Error spacer not 0: %d, pos: %d",DemodBuffer[startIdx+idx],startIdx+idx);
+ return -1;
+ }
+ continue;
+ }
+ if (keyCnt<8){ //lsb first
+ xorKey = xorKey | (DemodBuffer[startIdx+idx]<<keyCnt);
+ keyCnt++;
+ if (keyCnt==8 && g_debugMode) PrintAndLog("xorKey Found: %02x", xorKey);
+ continue;
+ }
+ //lsb first
+ ByteStream[ByteCnt] = ByteStream[ByteCnt] | (DemodBuffer[startIdx+idx]<<bitCnt);
+ bitCnt++;
+ if (bitCnt % 8 == 0){
+ if (g_debugMode) PrintAndLog("byte %d: %02x",ByteCnt,ByteStream[ByteCnt]);
+ bitCnt=0;
+ ByteCnt++;
+ }
+ }
+ for (uint8_t i = 0; i < ByteCnt; i++){
+ ByteStream[i] ^= xorKey; //xor
+ if (g_debugMode) PrintAndLog("byte %d after xor: %02x", i, ByteStream[i]);
+ }
+ //now ByteStream contains 64 bytes of decrypted raw tag data
+ //
+ uint8_t fmtLen = ByteStream[0]>>2;
+ uint32_t FC = 0;
+ uint32_t Card = 0;
+ uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans,32);
+ uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32);
+ uint32_t raw3 = bytebits_to_byte(DemodBuffer+ans+64, 32);
+
+ if (fmtLen==36){
+ FC = ((ByteStream[3] & 0x7F)<<7) | (ByteStream[4]>>1);
+ Card = ((ByteStream[4]&1)<<19) | (ByteStream[5]<<11) | (ByteStream[6]<<3) | (ByteStream[7]>>5);
+ PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d",fmtLen,FC,Card);
+ } else if(fmtLen==26){
+ FC = ((ByteStream[3] & 0x7F)<<1) | (ByteStream[4]>>7);
+ Card = ((ByteStream[4]&0x7F)<<9) | (ByteStream[5]<<1) | (ByteStream[6]>>7);
+ PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d",fmtLen,FC,Card);
+ } else {
+ PrintAndLog("Unknown G-Prox-II Fmt Found: FmtLen %d",fmtLen);
+ }
+ PrintAndLog("Raw: %08x%08x%08x", raw1,raw2,raw3);
+ setBiphaseDemodBuf(DemodBuffer+ans, 96);