📄 search.c
字号:
cp->board, cp->chip); if (FP_LOG) fprintf(FP_LOG, "Bad register on board 0x%02X, chip 0x%02X.%s", cp->board, cp->chip, " Chip disabled.\n"); } /* UPDATE THE CHIP CONTEXT */ cp->initialized = (j == 0) ? 1 : -1; /* initialized or defective */}/* * Service a chip by doing the following: * - Check if it has halted * - Check to see if it has finished its region * - Restart if it is idle */void ServiceChip(CHIP_CTX *cp, SEARCH_CTX *ctx, FILE *ctxFile) { int unit; long k; if (cp->initialized < 0) return; /* * READ KEYS & RESTART ANY HALTED UNITS */ for (unit = 0; unit < SEARCH_UNITS_PER_CHIP; unit++) { if (cp->region[unit] >= 0) { /* if currently running */ if (!(GetRegister(cp->board, cp->chip, REG_SEARCH_STATUS(unit)) & 1)) { CheckAndPrintKey(cp, ctx, unit); SetRegister(cp->board, cp->chip, REG_SEARCH_STATUS(unit), 1); } } } /* * See if any units have completed their search regions * Note: If I/O bandwidth was a problem and the clock rate of the * search system was fixed, we could predict when the keycounter * would flip and avoid this check. */ for (unit = 0; unit < SEARCH_UNITS_PER_CHIP; unit++) { if (cp->region[unit] < 0) continue; k = GetUnitKeyCounter(cp->board, cp->chip, unit); k -= cp->overFlow[unit]; if (k < 0) k += (1L << 24); if (VERBOSE && FP_LOG) fprintf(FP_LOG, "Board 0x%02X chip 0x%02X unit 0x%02X is at 0x%06lX " "(lastDone=0x%06lX, overFlow=%06lX)\n", cp->board, cp->chip, unit, k, cp->lastDone[unit], cp->overFlow[unit]); if (k < cp->lastDone[unit]) { if (!QUIET) printf("Board 0x%02X chip 0x%02X unit 0x%02X finished block " "0x%06lX (lastDone=0x%06lX, got 0x%06lX, overFlow=%06lX)\n", cp->board, cp->chip, unit, cp->region[unit], cp->lastDone[unit], k, cp->overFlow[unit]); if (FP_LOG) fprintf(FP_LOG, "Unit 0x%02X 0x%02X 0x%02X finished " "0x%06lX (last=%06lX, got %06lX, oFlow=%06lX)\n", cp->board, cp->chip, unit, cp->region[unit], cp->lastDone[unit], k, cp->overFlow[unit]); FinishKeyRegion(ctxFile, ctx, cp->region[unit]); /* region is done */ cp->region[unit] = -1; /* unit is now idle */ } else { cp->lastDone[unit] = k; } } /* * Start any units that are currently stalled */ for (unit = 0; unit < SEARCH_UNITS_PER_CHIP; unit++) { if (cp->region[unit] == -1) { k = ReserveKeyRegion(ctxFile, ctx); if (k < 0) break; /* no more regions... */ if (!QUIET) printf("Starting board 0x%02X, chip 0x%02X, unit 0x%02X... ", cp->board, cp->chip, unit); if (FP_LOG) fprintf(FP_LOG, "Starting unit 0x%02X 0x%02X 0x%02X... ", cp->board, cp->chip, unit); cp->region[unit] = k; /* LOAD UP THE KEY REGION AND LET 'ER RIP... */ SetRegister(cp->board, cp->chip, REG_SEARCH_KEY(unit)+6, (unsigned char)((k >> 16) & 0xFF)); SetRegister(cp->board, cp->chip, REG_SEARCH_KEY(unit)+5, (unsigned char)((k >> 8) & 0xFF)); SetRegister(cp->board, cp->chip, REG_SEARCH_KEY(unit)+4, (unsigned char)(k & 0xFF)); SetRegister(cp->board, cp->chip, REG_SEARCH_KEY(unit)+3, 0); SetRegister(cp->board, cp->chip, REG_SEARCH_KEY(unit)+2, 0); SetRegister(cp->board, cp->chip, REG_SEARCH_KEY(unit)+1, 0); SetRegister(cp->board, cp->chip, REG_SEARCH_KEY(unit)+0, 0); SetRegister(cp->board, cp->chip, REG_SEARCH_STATUS(unit), 1); /* GO! */ /* READ OUT THE KEY COUNTER (3 BYTES) FOR OVERFLOW SENSING */ k = GetUnitKeyCounter(cp->board, cp->chip, unit); cp->overFlow[unit] = k; cp->lastDone[unit] = k; if (!QUIET) printf("Region=0x%06lX, overFlow=0x%06lX\n", cp->region[unit], k); if (FP_LOG) fprintf(FP_LOG, "Region=0x%06lX, overFlow=0x%06lX\n", cp->region[unit], k); } }}/* * Read the value of a rapidly-incrementing key counter register. * The function reads the register twice, finds the most-significant * bit that changed during the operation, and returns the later * (higher) value with all bits to the right of the one that changed * set to zero. * The return value is the top 24 bits of the low 32 bits of the * key counter -- i.e., key bytes (MSB).. .. .. XX XX XX ..(LSB) */long GetUnitKeyCounter(int board, int chip, int unit) { long v1, v2, m; do { v1 = ((long)GetRegister(board, chip, REG_SEARCH_KEY(unit)+3)) << 16; v1 |= ((long)GetRegister(board, chip, REG_SEARCH_KEY(unit)+2)) << 8; v1 |= ((long)GetRegister(board, chip, REG_SEARCH_KEY(unit)+1)); v2 = ((long)GetRegister(board, chip, REG_SEARCH_KEY(unit)+3)) << 16; v2 |= ((long)GetRegister(board, chip, REG_SEARCH_KEY(unit)+2)) << 8; v2 |= ((long)GetRegister(board, chip, REG_SEARCH_KEY(unit)+1)); } while (v1 > v2); for (m = 0x800000L; m != 0; m >>= 1) { if ((v1 & m) != (v2 & m)) { v2 = (v2 & (0xFFFFFFL - m + 1)); break; } } return (v2);}/* * Get the key out of a halted unit and print it to the screen/logs */void CheckAndPrintKey(CHIP_CTX *cp, SEARCH_CTX *ctx, int unit) { unsigned char key[7]; unsigned char binKey[56]; char buf[128]; int i,j, goodKey; for (i = 0; i < 7; i++) key[i] = (unsigned char)GetRegister(cp->board, cp->chip, REG_SEARCH_KEY(unit)+i); if (--(key[0]) == 0xFF) /* Decrement key */ if (--(key[1]) == 0xFF) if (--(key[2]) == 0xFF) --key[3]; for (i = 0; i < 56; i++) binKey[i] = (key[i/8] >> (i&7)) & 1; for (i = 7; i >= 0; i--) { j = binKey[i*7]*2 + binKey[i*7+1]*4 + binKey[i*7+2]*8 + binKey[i*7+3]*16 + binKey[i*7+4]*32 + binKey[i*7+5]*64 + binKey[i*7+6]*128; sprintf(buf+14-2*i, "%02X", j); } if (QUIET) printf("Halt in %02X.%02X.%02X, K=%s P=", cp->board, cp->chip, unit, buf); else { printf("BOARD 0x%02X, CHIP 0x%02X, UNIT 0x%02X HALTED!\n K56 = ", cp->board, cp->chip, unit); for (i = 6; i >= 0; i--) printf("%02X", key[i]); printf("\n K64 = %s\n", buf); } if (FP_LOG) { fprintf(FP_LOG, "Halt@ %02X.%02X.%02X, K=", cp->board, cp->chip, unit); for (i = 6; i >= 0; i--) fprintf(FP_LOG, "%02X", key[i]); if (VERBOSE) fprintf(FP_LOG, ", K64=%s", buf); } goodKey = CheckKey(binKey, ctx); /* prints plaintexts */ if (QUIET) printf(goodKey ? " (OK!)\n" : " (BAD)\n"); else printf(" ***** KEY IS %s *****\n", goodKey ? " OKAY " : "BAD"); if (FP_LOG) fprintf(FP_LOG, goodKey ? " (=OK!)\n" : " (=BAD)\n"); fflush(stdout); if (FP_LOG) fflush(FP_LOG);}/* * Let the user see what's going on. */int ServiceKeyboard(SEARCH_CTX *ctx) { int k, i, board, chip, reg, val; char buffer[128]; while (kbhit()) { k = toupper(getch()); if (k == '?') { printf("Keystroke options:\n ESC=quit search\n"); printf(" R=read a chip\n SPACE=status\n P=pause\n"); printf(" S=set register\n"); printf("Press a command letter, ENTER to continue\n"); while (!kbhit()) {} continue; } if (k == 'P') { fprintf(stderr, " --- PAUSED ---\n(Press a command letter, "); fprintf(stderr, "ENTER to continue, or ? for help.)\n"); while (!kbhit()) {} continue; } if (k == 27) { fprintf(stderr, " -- ESC PRESSED! HIT 'Y' TO CONFIRM HALT --\n"); if (toupper(getch()) == 'Y') { fprintf(stderr, "Halting...\n"); return (-1); } fprintf(stderr, " (Not halting.)\n"); continue; } if (k == ' ') { fprintf(stderr, "There are %ld search units running\n", ctx->totalUnits); fprintf(stderr, "Of %ld blocks: %ld done, %ld unstarted, %ld pending\n", 1L<<24, ctx->totalFinishedKeyBlocks, ctx->totalUnstartedKeyBlocks, ctx->totalPendingKeyBlocks); fprintf(stderr, "The next key block to start is 0x%06lX.\n", ctx->nextUnstartedKeyBlock); fprintf(stderr, "Press a command letter or ENTER to continue\n"); while (!kbhit()) {} } if (k == 'R') { fprintf(stderr, "Enter board and chip (in hex): "); fgets(buffer, 127, stdin); board = chip = -1; sscanf(buffer, "%x %x", &board, &chip); if (board < 0 || board > 255 || chip < 0 || chip > 255) { fprintf(stderr, "Bad board (0x%02X) or chip (0x%02X)\n", board, chip); continue; } for (i = 0; i < 256; i++) { if ((i & 15) == 0) printf("\n0x%02X 0x%02X 0x%02X:", board, chip, i); printf(" %02X", GetRegister(board, chip, i)); } printf("\n"); fprintf(stderr, "Press a command letter or ENTER to continue\n"); while (!kbhit()) {} continue; } if (k == 'S') { fprintf(stderr, "Enter board chip reg value (all hex): "); fgets(buffer, 127, stdin); board = chip = reg = val = -1; sscanf(buffer, "%x %x %x %x", &board, &chip, ®, &val); if (board >= 0 && chip >= 0 && reg >= 0 && val >= 0) { fprintf(stderr, "Writing 0x%02X to 0x%02X.0x%02X reg 0x%02X\n", val, board, chip, reg); SetRegister(board, chip, reg, val); } fprintf(stderr, "Press a command letter or ENTER to continue.\n"); while (!kbhit()) {} continue; } } return (0);}/* * If needed, this function can be used to decide whether keys are * actually good or not to reject false positives. * Returns 1 if the key is not bad, zero if it is wrong. */int CheckKey(unsigned char key[56], SEARCH_CTX *ctx) { bool ctxt[64],ptxt0[64],ptxt1[64]; unsigned char p0[8],p1[8]; int i,c; /* Compute the plaintext and try to print it to the screen */ for (i = 0; i < 64; i++) ctxt[i] = (ctx->ciphertext0[i/8] >> (i&7)) & 1; DecryptDES((bool*)key, ptxt0, ctxt, 0); for (i = 0; i < 8; i++) { p0[i] = (unsigned char)(ptxt0[i*8+0]+ptxt0[i*8+1]*2+ptxt0[i*8+2]*4+ ptxt0[i*8+3]*8+ptxt0[i*8+4]*16+ptxt0[i*8+5]*32+ptxt0[i*8+6]*64+ ptxt0[i*8+7]*128); } for (i = 0; i < 8; i++) p0[i] ^= ctx->plaintextXorMask[i]; if (!QUIET) { printf(" Plaintext0 ="); for (i = 7; i>=0; i--) printf(" %02X", p0[i]); printf(" (\""); for (i = 7; i>=0; i--) printf("%c", (p0[i] < 32) ? '?' : p0[i]); printf("\")\n"); } if (QUIET) for (i = 7; i>=0; i--) printf("%02X", p0[i]); if (FP_LOG) fprintf(FP_LOG, ", ptxt="); if (FP_LOG) for (i = 7; i>=0; i--) fprintf(FP_LOG, "%02X", p0[i]); for (i = 0; i < 64; i++) ctxt[i] = (ctx->ciphertext1[i/8] >> (i&7)) & 1; DecryptDES((bool*)key, ptxt1, ctxt, 0); for (i = 0; i < 8; i++) { p1[i] = (unsigned char)(ptxt1[i*8+0]+ptxt1[i*8+1]*2+ptxt1[i*8+2]*4+ ptxt1[i*8+3]*8+ptxt1[i*8+4]*16+ptxt1[i*8+5]*32+ptxt1[i*8+6]*64+ ptxt1[i*8+7]*128); } if (ctx->searchInfo & 1) { /* if CBC mode, XOR w/ 1st ctxt */ for (i = 0; i < 8; i++) p1[i] ^= ctx->ciphertext0[i]; } if (!QUIET) printf(" Plaintext1 ="); if (QUIET) printf("/"); if (FP_LOG) fprintf(FP_LOG, "/"); if (!QUIET) for (i = 7; i>=0; i--) printf(" %02X", p1[i]); if (QUIET) for (i = 7; i>=0; i--) printf("%02X", p1[i]); if (FP_LOG) for (i = 7; i>=0; i--) fprintf(FP_LOG, "%02X", p1[i]); if (!QUIET) { printf(" (\""); for (i = 7; i>=0; i--) printf("%c", (p1[i] < 32) ? '?' : p1[i]); printf("\")\n"); } /* Reject key if doesn't contain good characters */ for(i = 0; i < 8;i++) { if (((ctx->plaintextByteMask) >> i) & 1) continue; c = p0[i]; if (((ctx->plaintextVector[c/8] >> (c & 7)) & 1) == 0) return (0); c = p1[i]; if (((ctx->plaintextVector[c/8] >> (c & 7)) & 1) == 0) return (0); } /* * INSERT ADDITIONAL CODE HERE TO REJECT FALSE POSITIVES */ return (1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -