📄 sim.c
字号:
/***************************************************************************** * sim.c * * Software Simulator for DES keysearch ASIC * * * * Written 1998 by Cryptography Research (http://www.cryptography.com) * * and Paul Kocher for the Electronic Frontier Foundation (EFF). * * Placed in the public domain by Cryptography Research and EFF. * * THIS IS UNSUPPORTED FREE SOFTWARE. USE AND DISTRIBUTE AT YOUR OWN RISK. * * * * IMPORTANT: U.S. LAW MAY REGULATE THE USE AND/OR EXPORT OF THIS PROGRAM. * * * ***************************************************************************** * * * REVISION HISTORY: * * * * Version 1.0: Initial version. * * Version 1.1: Initial release by Cryptography Research to EFF. * * (Fixed byte/bit ordering notation to match VHDL.) * * * *****************************************************************************/#include <stdio.h>#include <stdlib.h>#include <memory.h>#include <string.h>#include "des.h"#include "sim.h"#define DEBUGlong getClockCounter(void);int peekState(int addr);int RunChip(char *input, FILE *outfile, int useRaw);static void EXIT_ERR(char *s) { fprintf(stderr, s); exit(1); }static void parseInput(char *input, int *reset, int *boardEn, int *ale, int *adrsel1, int *web, int *rdb, int *adrsel2, int *allactIn, int *addr, int *chipId, int *data);static int unhex(char c);static void RunClock(void);static void desDecrypt(unsigned char m[8], unsigned char c[8], unsigned char k[7]);static void increment32(unsigned char *num);static void decrement32(unsigned char *num);static void printKeyInfo(FILE *outDev, char *preamble, int searchUnit);static unsigned char ALLACTIVE_IN = 1; /* not held between calls */unsigned char ALLACTIVE_OUT = 0;unsigned char STATE[256];unsigned char SELECTED_CHIP; long CLOCK_COUNTER = 1; int DES_POSITION;unsigned char WORKING_CTXT[24*8]; /* last DES input */unsigned char WORKING_PTXT[24*8]; /* last DES out (for ptxt check) */unsigned char RAW_DES_OUT[24*8]; /* raw DES outputs */int WORKING_KDELTA[24]; /* key delta (-1, 0, or +1) */unsigned char WORKING_LAST_SELECTOR[24]; /* last ciphertext selector */unsigned char WORKING_NEXT_SELECTOR[24]; /* next ciphertext selector */ int STARTUP_DELAY[24]; /* startup delay */unsigned char THIS_KEY[24*7]; /* current DES key */unsigned char NEXT_KEY[24*7]; /* next DES key */ int PENDING_UPDATE_ADDR1 = -1, PENDING_UPDATE_DATA1 = -1; int PENDING_UPDATE_ADDR2 = -1, PENDING_UPDATE_DATA2 = -1; int PENDING_UPDATE_ADDR3 = -1, PENDING_UPDATE_DATA3 = -1;unsigned char MATCH[24];static void resetChip(void) { memset(STATE, 0, sizeof(STATE)); /* RESET */ SELECTED_CHIP = 0; DES_POSITION = 13; memset(WORKING_CTXT, 0, sizeof(WORKING_CTXT)); memset(WORKING_PTXT, 0, sizeof(WORKING_PTXT)); memset(RAW_DES_OUT, 0, sizeof(RAW_DES_OUT)); memset(WORKING_KDELTA, 0, sizeof(WORKING_KDELTA)); memset(WORKING_LAST_SELECTOR, 1, sizeof(WORKING_LAST_SELECTOR)); memset(WORKING_NEXT_SELECTOR, 1, sizeof(WORKING_NEXT_SELECTOR)); memset(STARTUP_DELAY, 0, sizeof(STARTUP_DELAY)); memset(THIS_KEY, 0, sizeof(THIS_KEY)); memset(NEXT_KEY, 0, sizeof(NEXT_KEY)); PENDING_UPDATE_ADDR1 = -1; PENDING_UPDATE_ADDR2 = -1; PENDING_UPDATE_ADDR3 = -1; memset(MATCH, 0, sizeof(MATCH));}long getClockCounter(void) { return (CLOCK_COUNTER);}int peekState(int addr) { return (STATE[addr]);}int RunChip(char *input, FILE *outfile, int useRaw) { int reset,boardEn,ale,adrsel1,web,rdb,adrsel2,allactiveIn,addr,chipId,data; int dataOut; int i,j; parseInput(input, &reset, &boardEn, &ale, &adrsel1, &web, &rdb, &adrsel2, &allactiveIn, &addr, &chipId, &data); ALLACTIVE_IN = (unsigned char)allactiveIn; dataOut = data; /* default */ if (reset == 0) { /* reset? */ resetChip(); RunClock(); } else if (boardEn == 0) { /* board disabled? */ RunClock(); } else if (ale == 1) { /* select chip/board */ RunClock(); if (adrsel1 == 1) SELECTED_CHIP = (unsigned char)addr; else { /* board select done off-chip */ } } else if (chipId != SELECTED_CHIP) { /* chipId not ours? */ RunClock(); } else if (web == 0) { /* writing register? */ RunClock(); if (addr >= REG_SEARCH_KEY(0)) { PENDING_UPDATE_ADDR2 = addr; /* key */ PENDING_UPDATE_DATA2 = data; if (((addr & 7) == 7) && (data & 1) && ((STATE[addr] & 1) == 0)) { if (CLOCK_COUNTER < 750) STARTUP_DELAY[(addr - 0x47) / 8] = 21; /* adjust? */ else { STARTUP_DELAY[(addr - 0x47) / 8] = 2*CLOCKS_PER_DES - DES_POSITION; if (DES_POSITION >= 15) STARTUP_DELAY[(addr - 0x47) / 8] += CLOCKS_PER_DES;#if 0 /* uncomment for debugging message on halts */ fprintf(stderr,"Startup with DES_POSITION=%d in unit %d, delay=%d\n", DES_POSITION, (addr-0x47)/8, STARTUP_DELAY[(addr - 0x47) / 8]);#endif } } } else { PENDING_UPDATE_ADDR2 = addr; /* other reg */ PENDING_UPDATE_DATA2 = data; } } else if (rdb == 0) { /* read a register */ dataOut = STATE[addr]; RunClock(); } else { RunClock(); } if (CLOCK_COUNTER >= 2) { if (useRaw) { fprintf(outfile, "%02X %d\n", dataOut, ALLACTIVE_OUT); } else { fprintf(outfile, " (Addr: %02X) (Exp: 00) (Get: %02X) at Cycle:%ld\n", addr, dataOut, CLOCK_COUNTER); for (i = 0; i < 24; i++) { for (j = 6; j >= 0; j--) fprintf(outfile, "%02X", STATE[REG_SEARCH_KEY(i)+j]); fprintf(outfile, " "); if (CLOCK_COUNTER < 22) fprintf(outfile, "0000000000000000"); else if (CLOCK_COUNTER <= 37) fprintf(outfile, "094CCE83D677160F"); else { for (j = 7; j >= 0; j--) fprintf(outfile, "%02X", RAW_DES_OUT[8*i+j]); }#if 0 /* uncomment to print information about the MATCH */ { static int latch[24]={0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0}; if (DES_POSITION==10) latch[i] = MATCH[i]; fprintf(outfile, " %d", latch[i]); }#endif#if 0 /* uncomment to print information about NEXT_SELECTOR */ { static int latch[24]={1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1}; if (DES_POSITION==15) latch[i] = WORKING_NEXT_SELECTOR[i]; fprintf(outfile, "%d", latch[i]); }#endif fprintf(outfile, " : Unit%d\n", i); } fprintf(outfile, "\n"); } } CLOCK_COUNTER++; return (dataOut);}static void parseInput(char *input, int *reset, int *boardEn, int *ale, int *adrsel1, int *web, int *rdb, int *adrsel2, int *allactIn, int *addr, int *chipId, int *data) { int i; if (strlen(input) < 17 || input[8]!=' ' || input[11]!=' ' || input[14]!=' ') EXIT_ERR("Bad input.\n"); for (i = 0; i < 8; i++) { if (input[i] != '0' && input[i] != '1') EXIT_ERR("Bad input (first 8 digits must be binary.)\n"); } if (unhex(input[9]) < 0 || unhex(input[10]) < 0 || unhex(input[12]) < 0 || unhex(input[13]) < 0 || unhex(input[15]) < 0 || unhex(input[16]) < 0) { EXIT_ERR("Bad input (addr, chipId, data must be hex)"); } *reset = input[0]-'0'; *boardEn = input[1]-'0'; *ale = input[2]-'0'; *adrsel1 = input[3]-'0'; *web = input[4]-'0'; *rdb = input[5]-'0'; *adrsel2 = input[6]-'0'; *allactIn = input[7]-'0'; *addr = 16*unhex(input[9]) + unhex(input[10]); *chipId = 16*unhex(input[12]) + unhex(input[13]); *data = 16*unhex(input[15]) + unhex(input[16]);}/* Decodes a hex char or returns -1 if bad. */static int unhex(char c) { if (c >= '0' && c <= '9') return (c - '0'); if (c >= 'a' && c <= 'f') return (c - 'a' + 10); if (c >= 'A' && c <= 'F') return (c - 'A' + 10); return (-1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -