mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-08 06:00:53 -07:00
Remove reveng
(its license was not compatible with PM3 license, see issue #527)
This commit is contained in:
parent
3775e9e865
commit
757221f5d6
16 changed files with 2 additions and 4353 deletions
|
@ -169,14 +169,7 @@ CMDSRCS = crapto1/crapto1.c\
|
||||||
cmdscript.c\
|
cmdscript.c\
|
||||||
pm3_binlib.c\
|
pm3_binlib.c\
|
||||||
pm3_bitlib.c\
|
pm3_bitlib.c\
|
||||||
protocols.c\
|
protocols.c
|
||||||
cmdcrc.c\
|
|
||||||
reveng/reveng.c\
|
|
||||||
reveng/cli.c\
|
|
||||||
reveng/bmpbit.c\
|
|
||||||
reveng/model.c\
|
|
||||||
reveng/poly.c\
|
|
||||||
reveng/getopt.c\
|
|
||||||
|
|
||||||
cpu_arch = $(shell uname -m)
|
cpu_arch = $(shell uname -m)
|
||||||
ifneq ($(findstring 86, $(cpu_arch)), )
|
ifneq ($(findstring 86, $(cpu_arch)), )
|
||||||
|
|
547
client/cmdcrc.c
547
client/cmdcrc.c
|
@ -1,547 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2015 iceman <iceman at iuse.se>
|
|
||||||
//
|
|
||||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
|
||||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
|
||||||
// the license.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// CRC Calculations from the software reveng commands
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
# include <io.h>
|
|
||||||
# include <fcntl.h>
|
|
||||||
# ifndef STDIN_FILENO
|
|
||||||
# define STDIN_FILENO 0
|
|
||||||
# endif /* STDIN_FILENO */
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include "cmdmain.h"
|
|
||||||
#include "cmdcrc.h"
|
|
||||||
#include "reveng/reveng.h"
|
|
||||||
#include "ui.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#define MAX_ARGS 20
|
|
||||||
|
|
||||||
int uerr(char *msg){
|
|
||||||
PrintAndLog("%s",msg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int split(char *str, char *arr[MAX_ARGS]){
|
|
||||||
int beginIndex = 0;
|
|
||||||
int endIndex;
|
|
||||||
int maxWords = MAX_ARGS;
|
|
||||||
int wordCnt = 0;
|
|
||||||
|
|
||||||
while(1){
|
|
||||||
while(isspace((unsigned char)str[beginIndex])){
|
|
||||||
++beginIndex;
|
|
||||||
}
|
|
||||||
if(str[beginIndex] == '\0') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
endIndex = beginIndex;
|
|
||||||
while (str[endIndex] && !isspace((unsigned char)str[endIndex])){
|
|
||||||
++endIndex;
|
|
||||||
}
|
|
||||||
int len = endIndex - beginIndex;
|
|
||||||
char *tmp = calloc(len + 1, sizeof(char));
|
|
||||||
memcpy(tmp, &str[beginIndex], len);
|
|
||||||
arr[wordCnt++] = tmp;
|
|
||||||
//PrintAndLog("DEBUG cnt: %d, %s",wordCnt-1, arr[wordCnt-1]);
|
|
||||||
beginIndex = endIndex;
|
|
||||||
if (wordCnt == maxWords)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return wordCnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CmdCrc(const char *Cmd)
|
|
||||||
{
|
|
||||||
char name[] = {"reveng "};
|
|
||||||
char Cmd2[50 + 7];
|
|
||||||
memcpy(Cmd2, name, 7);
|
|
||||||
memcpy(Cmd2 + 7, Cmd, 50);
|
|
||||||
char *argv[MAX_ARGS];
|
|
||||||
int argc = split(Cmd2, argv);
|
|
||||||
|
|
||||||
if (argc == 3 && memcmp(argv[1],"-g",2)==0) {
|
|
||||||
CmdrevengSearch(argv[2]);
|
|
||||||
} else {
|
|
||||||
reveng_main(argc, argv);
|
|
||||||
}
|
|
||||||
//PrintAndLog("DEBUG argc: %d, %s %s Cmd: %s",argc, argv[0], Cmd2, Cmd);
|
|
||||||
for(int i = 0; i < argc; ++i){
|
|
||||||
free(argv[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//returns array of model names and the count of models returning
|
|
||||||
// as well as a width array for the width of each model
|
|
||||||
int GetModels(char *Models[], int *count, uint8_t *width){
|
|
||||||
/* default values */
|
|
||||||
static model_t model = {
|
|
||||||
PZERO, /* no CRC polynomial, user must specify */
|
|
||||||
PZERO, /* Init = 0 */
|
|
||||||
P_BE, /* RefIn = false, RefOut = false, plus P_RTJUST setting in reveng.h */
|
|
||||||
PZERO, /* XorOut = 0 */
|
|
||||||
PZERO, /* check value unused */
|
|
||||||
NULL /* no model name */
|
|
||||||
};
|
|
||||||
|
|
||||||
int ibperhx = 8;//, obperhx = 8;
|
|
||||||
int rflags = 0, uflags = 0; /* search and UI flags */
|
|
||||||
poly_t apoly, crc, qpoly = PZERO, *apolys = NULL, *pptr = NULL, *qptr = NULL;
|
|
||||||
model_t pset = model, *candmods, *mptr;
|
|
||||||
|
|
||||||
/* stdin must be binary */
|
|
||||||
#ifdef _WIN32
|
|
||||||
_setmode(STDIN_FILENO, _O_BINARY);
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
SETBMP();
|
|
||||||
|
|
||||||
int args = 0, psets, pass;
|
|
||||||
int Cnt = 0;
|
|
||||||
if (width[0] == 0) { //reveng -D
|
|
||||||
*count = mcount();
|
|
||||||
if(!*count)
|
|
||||||
return uerr("no preset models available");
|
|
||||||
|
|
||||||
for(int mode = 0; mode < *count; ++mode) {
|
|
||||||
mbynum(&model, mode);
|
|
||||||
mcanon(&model);
|
|
||||||
size_t size = (model.name && *model.name) ? strlen(model.name) : 6;
|
|
||||||
char *tmp = calloc(size+1, sizeof(char));
|
|
||||||
if (tmp==NULL)
|
|
||||||
return uerr("out of memory?");
|
|
||||||
|
|
||||||
memcpy(tmp, model.name, size);
|
|
||||||
Models[mode] = tmp;
|
|
||||||
width[mode] = plen(model.spoly);
|
|
||||||
}
|
|
||||||
mfree(&model);
|
|
||||||
} else { //reveng -s
|
|
||||||
|
|
||||||
if(~model.flags & P_MULXN)
|
|
||||||
return uerr("cannot search for non-Williams compliant models");
|
|
||||||
|
|
||||||
praloc(&model.spoly, (unsigned long)width[0]);
|
|
||||||
praloc(&model.init, (unsigned long)width[0]);
|
|
||||||
praloc(&model.xorout, (unsigned long)width[0]);
|
|
||||||
if(!plen(model.spoly))
|
|
||||||
palloc(&model.spoly, (unsigned long)width[0]);
|
|
||||||
else
|
|
||||||
width[0] = (uint8_t)plen(model.spoly);
|
|
||||||
|
|
||||||
/* special case if qpoly is zero, search to end of range */
|
|
||||||
if(!ptst(qpoly))
|
|
||||||
rflags &= ~R_HAVEQ;
|
|
||||||
|
|
||||||
|
|
||||||
/* not going to be sending additional args at this time (maybe future?)
|
|
||||||
|
|
||||||
// allocate argument array
|
|
||||||
args = argc - optind;
|
|
||||||
if(!(apolys = malloc(args * sizeof(poly_t))))
|
|
||||||
return uerr("cannot allocate memory for argument list");
|
|
||||||
|
|
||||||
for(pptr = apolys; optind < argc; ++optind) {
|
|
||||||
if(uflags & C_INFILE)
|
|
||||||
*pptr++ = rdpoly(argv[optind], model.flags, ibperhx);
|
|
||||||
else
|
|
||||||
*pptr++ = strtop(argv[optind], model.flags, ibperhx);
|
|
||||||
}
|
|
||||||
// exit value of pptr is used hereafter!
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* if endianness not specified, try
|
|
||||||
* little-endian then big-endian.
|
|
||||||
* NB: crossed-endian algorithms will not be
|
|
||||||
* searched.
|
|
||||||
*/
|
|
||||||
/* scan against preset models */
|
|
||||||
if(~uflags & C_FORCE) {
|
|
||||||
pass = 0;
|
|
||||||
Cnt = 0;
|
|
||||||
do {
|
|
||||||
psets = mcount();
|
|
||||||
//PrintAndLog("psets: %d",psets);
|
|
||||||
while(psets) {
|
|
||||||
mbynum(&pset, --psets);
|
|
||||||
|
|
||||||
/* skip if different width, or refin or refout don't match */
|
|
||||||
if(plen(pset.spoly) != width[0] || (model.flags ^ pset.flags) & (P_REFIN | P_REFOUT))
|
|
||||||
continue;
|
|
||||||
/* skip if the preset doesn't match specified parameters */
|
|
||||||
if(rflags & R_HAVEP && pcmp(&model.spoly, &pset.spoly))
|
|
||||||
continue;
|
|
||||||
if(rflags & R_HAVEI && psncmp(&model.init, &pset.init))
|
|
||||||
continue;
|
|
||||||
if(rflags & R_HAVEX && psncmp(&model.xorout, &pset.xorout))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//for additional args (not used yet, maybe future?)
|
|
||||||
apoly = pclone(pset.xorout);
|
|
||||||
if(pset.flags & P_REFOUT)
|
|
||||||
prev(&apoly);
|
|
||||||
|
|
||||||
for(qptr = apolys; qptr < pptr; ++qptr) {
|
|
||||||
crc = pcrc(*qptr, pset.spoly, pset.init, apoly, 0);
|
|
||||||
if(ptst(crc)) {
|
|
||||||
pfree(&crc);
|
|
||||||
break;
|
|
||||||
} else
|
|
||||||
pfree(&crc);
|
|
||||||
}
|
|
||||||
pfree(&apoly);
|
|
||||||
if(qptr == pptr) {
|
|
||||||
|
|
||||||
/* the selected model solved all arguments */
|
|
||||||
|
|
||||||
mcanon(&pset);
|
|
||||||
|
|
||||||
size_t size = (pset.name && *pset.name) ? strlen(pset.name) : 6;
|
|
||||||
//PrintAndLog("Size: %d, %s, count: %d",size,pset.name, Cnt);
|
|
||||||
char *tmp = calloc(size+1, sizeof(char));
|
|
||||||
if (tmp==NULL){
|
|
||||||
PrintAndLog("out of memory?");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
width[Cnt] = width[0];
|
|
||||||
memcpy(tmp, pset.name, size);
|
|
||||||
Models[Cnt++] = tmp;
|
|
||||||
*count = Cnt;
|
|
||||||
uflags |= C_RESULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mfree(&pset);
|
|
||||||
|
|
||||||
/* toggle refIn/refOut and reflect arguments */
|
|
||||||
if(~rflags & R_HAVERI) {
|
|
||||||
model.flags ^= P_REFIN | P_REFOUT;
|
|
||||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
|
||||||
prevch(qptr, ibperhx);
|
|
||||||
}
|
|
||||||
} while(~rflags & R_HAVERI && ++pass < 2);
|
|
||||||
}
|
|
||||||
//got everything now free the memory...
|
|
||||||
|
|
||||||
if(uflags & C_RESULT) {
|
|
||||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
|
||||||
pfree(qptr);
|
|
||||||
}
|
|
||||||
if(!(model.flags & P_REFIN) != !(model.flags & P_REFOUT))
|
|
||||||
return uerr("cannot search for crossed-endian models");
|
|
||||||
|
|
||||||
pass = 0;
|
|
||||||
do {
|
|
||||||
mptr = candmods = reveng(&model, qpoly, rflags, args, apolys);
|
|
||||||
if(mptr && plen(mptr->spoly))
|
|
||||||
uflags |= C_RESULT;
|
|
||||||
while(mptr && plen(mptr->spoly)) {
|
|
||||||
mfree(mptr++);
|
|
||||||
}
|
|
||||||
free(candmods);
|
|
||||||
if(~rflags & R_HAVERI) {
|
|
||||||
model.flags ^= P_REFIN | P_REFOUT;
|
|
||||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
|
||||||
prevch(qptr, ibperhx);
|
|
||||||
}
|
|
||||||
} while(~rflags & R_HAVERI && ++pass < 2);
|
|
||||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
|
||||||
pfree(qptr);
|
|
||||||
free(apolys);
|
|
||||||
if(~uflags & C_RESULT)
|
|
||||||
return uerr("no models found");
|
|
||||||
mfree(&model);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//test call to GetModels
|
|
||||||
int CmdrevengTest(const char *Cmd){
|
|
||||||
char *Models[80];
|
|
||||||
int count = 0;
|
|
||||||
uint8_t widtharr[80] = {0};
|
|
||||||
uint8_t width = 0;
|
|
||||||
width = param_get8(Cmd, 0);
|
|
||||||
//PrintAndLog("width: %d",width);
|
|
||||||
if (width > 89)
|
|
||||||
return uerr("Width cannot exceed 89");
|
|
||||||
|
|
||||||
widtharr[0] = width;
|
|
||||||
int ans = GetModels(Models, &count, widtharr);
|
|
||||||
if (!ans) return 0;
|
|
||||||
|
|
||||||
PrintAndLog("Count: %d",count);
|
|
||||||
for (int i = 0; i < count; i++){
|
|
||||||
PrintAndLog("Model %d: %s, width: %d",i,Models[i], widtharr[i]);
|
|
||||||
free(Models[i]);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-c || -v
|
|
||||||
//inModel = valid model name string - CRC-8
|
|
||||||
//inHexStr = input hex string to calculate crc on
|
|
||||||
//reverse = reverse calc option if true
|
|
||||||
//endian = {0 = calc default endian input and output, b = big endian input and output, B = big endian output, r = right justified
|
|
||||||
// l = little endian input and output, L = little endian output only, t = left justified}
|
|
||||||
//result = calculated crc hex string
|
|
||||||
int RunModel(char *inModel, char *inHexStr, bool reverse, char endian, char *result){
|
|
||||||
/* default values */
|
|
||||||
static model_t model = {
|
|
||||||
PZERO, // no CRC polynomial, user must specify
|
|
||||||
PZERO, // Init = 0
|
|
||||||
P_BE, // RefIn = false, RefOut = false, plus P_RTJUST setting in reveng.h
|
|
||||||
PZERO, // XorOut = 0
|
|
||||||
PZERO, // check value unused
|
|
||||||
NULL // no model name
|
|
||||||
};
|
|
||||||
int ibperhx = 8, obperhx = 8;
|
|
||||||
int rflags = 0; // search flags
|
|
||||||
int c;
|
|
||||||
//unsigned long width;
|
|
||||||
poly_t apoly, crc;
|
|
||||||
|
|
||||||
char *string;
|
|
||||||
|
|
||||||
// stdin must be binary
|
|
||||||
#ifdef _WIN32
|
|
||||||
_setmode(STDIN_FILENO, _O_BINARY);
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
SETBMP();
|
|
||||||
//set model
|
|
||||||
if(!(c = mbynam(&model, inModel))) {
|
|
||||||
fprintf(stderr,"error: preset model '%s' not found. Use reveng -D to list presets.\n", inModel);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(c < 0)
|
|
||||||
return uerr("no preset models available");
|
|
||||||
|
|
||||||
// must set width so that parameter to -ipx is not zeroed
|
|
||||||
//width = plen(model.spoly);
|
|
||||||
rflags |= R_HAVEP | R_HAVEI | R_HAVERI | R_HAVERO | R_HAVEX;
|
|
||||||
|
|
||||||
//set flags
|
|
||||||
switch (endian) {
|
|
||||||
case 'b': /* b big-endian (RefIn = false, RefOut = false ) */
|
|
||||||
model.flags &= ~P_REFIN;
|
|
||||||
rflags |= R_HAVERI;
|
|
||||||
/* fall through: */
|
|
||||||
case 'B': /* B big-endian output (RefOut = false) */
|
|
||||||
model.flags &= ~P_REFOUT;
|
|
||||||
rflags |= R_HAVERO;
|
|
||||||
mnovel(&model);
|
|
||||||
/* fall through: */
|
|
||||||
case 'r': /* r right-justified */
|
|
||||||
model.flags |= P_RTJUST;
|
|
||||||
break;
|
|
||||||
case 'l': /* l little-endian input and output */
|
|
||||||
model.flags |= P_REFIN;
|
|
||||||
rflags |= R_HAVERI;
|
|
||||||
/* fall through: */
|
|
||||||
case 'L': /* L little-endian output */
|
|
||||||
model.flags |= P_REFOUT;
|
|
||||||
rflags |= R_HAVERO;
|
|
||||||
mnovel(&model);
|
|
||||||
/* fall through: */
|
|
||||||
case 't': /* t left-justified */
|
|
||||||
model.flags &= ~P_RTJUST;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
mcanon(&model);
|
|
||||||
|
|
||||||
if (reverse) {
|
|
||||||
// v calculate reversed CRC
|
|
||||||
/* Distinct from the -V switch as this causes
|
|
||||||
* the arguments and output to be reversed as well.
|
|
||||||
*/
|
|
||||||
// reciprocate Poly
|
|
||||||
prcp(&model.spoly);
|
|
||||||
|
|
||||||
/* mrev() does:
|
|
||||||
* if(refout) prev(init); else prev(xorout);
|
|
||||||
* but here the entire argument polynomial is
|
|
||||||
* reflected, not just the characters, so RefIn
|
|
||||||
* and RefOut are not inverted as with -V.
|
|
||||||
* Consequently Init is the mirror image of the
|
|
||||||
* one resulting from -V, and so we have:
|
|
||||||
*/
|
|
||||||
if(~model.flags & P_REFOUT) {
|
|
||||||
prev(&model.init);
|
|
||||||
prev(&model.xorout);
|
|
||||||
}
|
|
||||||
|
|
||||||
// swap init and xorout
|
|
||||||
apoly = model.init;
|
|
||||||
model.init = model.xorout;
|
|
||||||
model.xorout = apoly;
|
|
||||||
}
|
|
||||||
// c calculate CRC
|
|
||||||
|
|
||||||
// validate inputs
|
|
||||||
/* if(plen(model.spoly) == 0) {
|
|
||||||
* fprintf(stderr,"%s: no polynomial specified for -%c (add -w WIDTH -p POLY)\n", myname, mode);
|
|
||||||
* exit(EXIT_FAILURE);
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* in the Williams model, xorout is applied after the refout stage.
|
|
||||||
* as refout is part of ptostr(), we reverse xorout here.
|
|
||||||
*/
|
|
||||||
if(model.flags & P_REFOUT)
|
|
||||||
prev(&model.xorout);
|
|
||||||
|
|
||||||
apoly = strtop(inHexStr, model.flags, ibperhx);
|
|
||||||
|
|
||||||
if(reverse)
|
|
||||||
prev(&apoly);
|
|
||||||
|
|
||||||
crc = pcrc(apoly, model.spoly, model.init, model.xorout, model.flags);
|
|
||||||
|
|
||||||
if(reverse)
|
|
||||||
prev(&crc);
|
|
||||||
|
|
||||||
string = ptostr(crc, model.flags, obperhx);
|
|
||||||
for (int i = 0; i < 50; i++){
|
|
||||||
result[i] = string[i];
|
|
||||||
if (result[i]==0) break;
|
|
||||||
}
|
|
||||||
free(string);
|
|
||||||
pfree(&crc);
|
|
||||||
pfree(&apoly);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//test call to RunModel
|
|
||||||
int CmdrevengTestC(const char *Cmd){
|
|
||||||
int cmdp = 0;
|
|
||||||
char inModel[30] = {0x00};
|
|
||||||
char inHexStr[30] = {0x00};
|
|
||||||
char result[30];
|
|
||||||
int dataLen;
|
|
||||||
char endian = 0;
|
|
||||||
dataLen = param_getstr(Cmd, cmdp++, inModel, sizeof(inModel));
|
|
||||||
if (dataLen < 4) return 0;
|
|
||||||
dataLen = param_getstr(Cmd, cmdp++, inHexStr, sizeof(inHexStr));
|
|
||||||
if (dataLen < 4) return 0;
|
|
||||||
bool reverse = (param_get8(Cmd, cmdp++)) ? true : false;
|
|
||||||
endian = param_getchar(Cmd, cmdp++);
|
|
||||||
|
|
||||||
//PrintAndLog("mod: %s, hex: %s, rev %d", inModel, inHexStr, reverse);
|
|
||||||
int ans = RunModel(inModel, inHexStr, reverse, endian, result);
|
|
||||||
if (!ans) return 0;
|
|
||||||
|
|
||||||
PrintAndLog("Result: %s",result);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//returns a calloced string (needs to be freed)
|
|
||||||
char *SwapEndianStr(const char *inStr, const size_t len, const uint8_t blockSize){
|
|
||||||
char *tmp = calloc(len+1, sizeof(char));
|
|
||||||
for (uint8_t block=0; block < (uint8_t)(len/blockSize); block++){
|
|
||||||
for (size_t i = 0; i < blockSize; i+=2){
|
|
||||||
tmp[i+(blockSize*block)] = inStr[(blockSize-1-i-1)+(blockSize*block)];
|
|
||||||
tmp[i+(blockSize*block)+1] = inStr[(blockSize-1-i)+(blockSize*block)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// takes hex string in and searches for a matching result (hex string must include checksum)
|
|
||||||
int CmdrevengSearch(const char *Cmd){
|
|
||||||
char inHexStr[50] = {0x00};
|
|
||||||
int dataLen = param_getstr(Cmd, 0, inHexStr, sizeof(inHexStr));
|
|
||||||
if (dataLen < 4) return 0;
|
|
||||||
|
|
||||||
char *Models[80];
|
|
||||||
int count = 0;
|
|
||||||
uint8_t width[80];
|
|
||||||
width[0] = 0;
|
|
||||||
uint8_t crcChars = 0;
|
|
||||||
char result[30];
|
|
||||||
char revResult[30];
|
|
||||||
int ans = GetModels(Models, &count, width);
|
|
||||||
bool found = false;
|
|
||||||
if (!ans) return 0;
|
|
||||||
|
|
||||||
// try each model and get result
|
|
||||||
for (int i = 0; i < count; i++){
|
|
||||||
/*if (found) {
|
|
||||||
free(Models[i]);
|
|
||||||
continue;
|
|
||||||
}*/
|
|
||||||
// round up to # of characters in this model's crc
|
|
||||||
crcChars = ((width[i]+7)/8)*2;
|
|
||||||
// can't test a model that has more crc digits than our data
|
|
||||||
if (crcChars >= dataLen)
|
|
||||||
continue;
|
|
||||||
memset(result, 0, 30);
|
|
||||||
char *inCRC = calloc(crcChars+1, sizeof(char));
|
|
||||||
memcpy(inCRC, inHexStr+(dataLen-crcChars), crcChars);
|
|
||||||
|
|
||||||
char *outHex = calloc(dataLen-crcChars+1, sizeof(char));
|
|
||||||
memcpy(outHex, inHexStr, dataLen-crcChars);
|
|
||||||
|
|
||||||
//PrintAndLog("DEBUG: dataLen: %d, crcChars: %d, Model: %s, CRC: %s, width: %d, outHex: %s",dataLen, crcChars, Models[i], inCRC, width[i], outHex);
|
|
||||||
ans = RunModel(Models[i], outHex, false, 0, result);
|
|
||||||
if (ans) {
|
|
||||||
//test for match
|
|
||||||
if (memcmp(result, inCRC, crcChars)==0){
|
|
||||||
PrintAndLog("\nFound a possible match!\nModel: %s\nValue: %s\n",Models[i], result);
|
|
||||||
//optional - stop searching if found...
|
|
||||||
found = true;
|
|
||||||
} else {
|
|
||||||
if (crcChars > 2){
|
|
||||||
char *swapEndian = SwapEndianStr(result, crcChars, crcChars);
|
|
||||||
if (memcmp(swapEndian, inCRC, crcChars)==0){
|
|
||||||
PrintAndLog("\nFound a possible match!\nModel: %s\nValue EndianSwapped: %s\n",Models[i], swapEndian);
|
|
||||||
//optional - stop searching if found...
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
free(swapEndian);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (!found){
|
|
||||||
ans = RunModel(Models[i], outHex, true, 0, revResult);
|
|
||||||
if (ans) {
|
|
||||||
//test for match
|
|
||||||
if (memcmp(revResult, inCRC, crcChars)==0){
|
|
||||||
PrintAndLog("\nFound a possible match!\nModel Reversed: %s\nValue: %s\n",Models[i], revResult);
|
|
||||||
//optional - stop searching if found...
|
|
||||||
found = true;
|
|
||||||
} else {
|
|
||||||
if (crcChars > 2){
|
|
||||||
char *swapEndian = SwapEndianStr(revResult, crcChars, crcChars);
|
|
||||||
if (memcmp(swapEndian, inCRC, crcChars)==0){
|
|
||||||
PrintAndLog("\nFound a possible match!\nModel Reversed: %s\nValue EndianSwapped: %s\n",Models[i], swapEndian);
|
|
||||||
//optional - stop searching if found...
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
free(swapEndian);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
free(inCRC);
|
|
||||||
free(outHex);
|
|
||||||
free(Models[i]);
|
|
||||||
}
|
|
||||||
if (!found) PrintAndLog("\nNo matches found\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2015 iceman <iceman at iuse.se>
|
|
||||||
//
|
|
||||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
|
||||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
|
||||||
// the license.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// CRC Calculations from the software reveng commands
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifndef CMDCRC_H__
|
|
||||||
#define CMDCRC_H__
|
|
||||||
|
|
||||||
int CmdCrc(const char *Cmd);
|
|
||||||
int CmdrevengTest(const char *Cmd);
|
|
||||||
int CmdrevengTestC(const char *Cmd);
|
|
||||||
int CmdrevengSearch(const char *Cmd);
|
|
||||||
int GetModels(char *Models[], int *count, uint8_t *width);
|
|
||||||
int RunModel(char *inModel, char *inHexStr, bool reverse, char endian, char *result);
|
|
||||||
#endif
|
|
|
@ -27,14 +27,12 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
#include "cmdscript.h"
|
#include "cmdscript.h"
|
||||||
#include "cmdcrc.h"
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int current_command = CMD_UNKNOWN;
|
unsigned int current_command = CMD_UNKNOWN;
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
static int CmdQuit(const char *Cmd);
|
static int CmdQuit(const char *Cmd);
|
||||||
static int CmdRev(const char *Cmd);
|
|
||||||
|
|
||||||
//For storing command that are received from the device
|
//For storing command that are received from the device
|
||||||
#define CMD_BUFFER_SIZE 50
|
#define CMD_BUFFER_SIZE 50
|
||||||
|
@ -53,7 +51,6 @@ static command_t CommandTable[] =
|
||||||
{"hf", CmdHF, 1, "{ High Frequency commands... }"},
|
{"hf", CmdHF, 1, "{ High Frequency commands... }"},
|
||||||
{"hw", CmdHW, 1, "{ Hardware commands... }"},
|
{"hw", CmdHW, 1, "{ Hardware commands... }"},
|
||||||
{"lf", CmdLF, 1, "{ Low Frequency commands... }"},
|
{"lf", CmdLF, 1, "{ Low Frequency commands... }"},
|
||||||
{"reveng",CmdRev, 1, "Crc calculations from the software reveng1-30"},
|
|
||||||
{"script",CmdScript,1, "{ Scripting commands }"},
|
{"script",CmdScript,1, "{ Scripting commands }"},
|
||||||
{"quit", CmdQuit, 1, "Exit program"},
|
{"quit", CmdQuit, 1, "Exit program"},
|
||||||
{"exit", CmdQuit, 1, "Exit program"},
|
{"exit", CmdQuit, 1, "Exit program"},
|
||||||
|
@ -75,12 +72,6 @@ int CmdQuit(const char *Cmd)
|
||||||
return 99;
|
return 99;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdRev(const char *Cmd)
|
|
||||||
{
|
|
||||||
CmdCrc(Cmd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This method should be called when sending a new command to the pm3. In case any old
|
* @brief This method should be called when sending a new command to the pm3. In case any old
|
||||||
* responses from previous commands are stored in the buffer, a call to this method should clear them.
|
* responses from previous commands are stored in the buffer, a call to this method should clear them.
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
/* bmpbit.c
|
|
||||||
* Greg Cook, 9/Apr/2015
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* CRC RevEng, an arbitrary-precision CRC calculator and algorithm finder
|
|
||||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Gregory Cook
|
|
||||||
*
|
|
||||||
* This file is part of CRC RevEng.
|
|
||||||
*
|
|
||||||
* CRC RevEng is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* CRC RevEng is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with CRC RevEng. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef BMPTST
|
|
||||||
# include <stdio.h>
|
|
||||||
# include <stdlib.h>
|
|
||||||
#else
|
|
||||||
# define FILE void
|
|
||||||
#endif
|
|
||||||
#include "reveng.h"
|
|
||||||
|
|
||||||
#if (defined BMPTST) || (BMP_BIT < 32)
|
|
||||||
/* Size in bits of a bmp_t. Not necessarily a power of two. */
|
|
||||||
int bmpbit;
|
|
||||||
|
|
||||||
/* The highest power of two that is strictly less than BMP_BIT.
|
|
||||||
* Initialises the index of a binary search for set bits in a bmp_t.
|
|
||||||
* (Computed correctly for BMP_BIT >= 2)
|
|
||||||
*/
|
|
||||||
int bmpsub;
|
|
||||||
|
|
||||||
void
|
|
||||||
setbmp(void) {
|
|
||||||
/* Initialise BMP_BIT and BMP_SUB for the local architecture. */
|
|
||||||
bmp_t bmpmax = ~(bmp_t) 0;
|
|
||||||
|
|
||||||
bmpbit = 0; bmpsub = 1;
|
|
||||||
|
|
||||||
while(bmpmax) {
|
|
||||||
bmpmax <<= 1;
|
|
||||||
++bmpbit;
|
|
||||||
}
|
|
||||||
|
|
||||||
while((bmpsub | (bmpsub - 1)) < bmpbit - 1)
|
|
||||||
bmpsub <<= 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BMPTST
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[]) {
|
|
||||||
/* check the compile-time bitmap width is correct, otherwise
|
|
||||||
* searches run forever. */
|
|
||||||
# if BMP_BIT > 0
|
|
||||||
setbmp();
|
|
||||||
if(BMP_BIT != bmpbit || BMP_SUB != bmpsub) {
|
|
||||||
fprintf(stderr,"reveng: configuration fault. Update "
|
|
||||||
"config.h with these definitions and "
|
|
||||||
"recompile:\n"
|
|
||||||
"\t#define BMP_BIT %d\n"
|
|
||||||
"\t#define BMP_SUB %d\n",
|
|
||||||
bmpbit, bmpsub);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
# endif /* BMP_BIT > 0 */
|
|
||||||
/* check the bitmap constant macro */
|
|
||||||
if(~(bmp_t) 0 != ~BMP_C(0)) {
|
|
||||||
fprintf(stderr, "reveng: configuration fault. Edit "
|
|
||||||
"the definition of BMP_C() in config.h to "
|
|
||||||
"match BMP_T and recompile.\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* BMPTST */
|
|
|
@ -1,628 +0,0 @@
|
||||||
/* cli.c
|
|
||||||
* Greg Cook, 9/Apr/2015
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* CRC RevEng, an arbitrary-precision CRC calculator and algorithm finder
|
|
||||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Gregory Cook
|
|
||||||
*
|
|
||||||
* This file is part of CRC RevEng.
|
|
||||||
*
|
|
||||||
* CRC RevEng is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* CRC RevEng is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with CRC RevEng. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* 2015-04-03: added -z
|
|
||||||
* 2013-09-16: do not search with -M
|
|
||||||
* 2013-06-11: uprog() suppresses first progress report
|
|
||||||
* 2013-04-22: uprog() prints poly same as mtostr()
|
|
||||||
* 2013-02-07: added -q, uprog(), removed -W, R_ODDLY
|
|
||||||
* 2012-05-24: -D dumps parameters of all models
|
|
||||||
* 2012-03-03: added code to test sort order of model table
|
|
||||||
* 2012-02-20: set stdin to binary (MinGW). offer -D if preset unknown.
|
|
||||||
* 2011-09-06: -s reads arguments once. stdin not closed.
|
|
||||||
* 2011-09-06: fixed bad argument-freeing loops.
|
|
||||||
* 2011-08-27: validates BMP_C()
|
|
||||||
* 2011-08-26: validates BMPBIT and BMPSUB
|
|
||||||
* 2011-08-25: fixed Init/Xorout reflection logic in -V and -v
|
|
||||||
* 2011-01-17: fixed ANSI C warnings
|
|
||||||
* 2011-01-15: added NOFORCE
|
|
||||||
* 2011-01-14: added -k, -P
|
|
||||||
* 2011-01-10: reorganised switches, added -V, -X
|
|
||||||
* 2010-12-26: renamed CRC RevEng
|
|
||||||
* 2010-12-18: implemented -c, -C
|
|
||||||
* 2010-12-14: added and implemented -d, -D, fixed -ipx entry
|
|
||||||
* 2010-12-11: implemented -e. first tests
|
|
||||||
* 2010-12-10: finalised option processing. started input validation
|
|
||||||
* 2010-12-07: started cli
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "getopt.h"
|
|
||||||
#ifdef _WIN32
|
|
||||||
# include <io.h>
|
|
||||||
# include <fcntl.h>
|
|
||||||
# ifndef STDIN_FILENO
|
|
||||||
# define STDIN_FILENO 0
|
|
||||||
# endif /* STDIN_FILENO */
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
#include "reveng.h"
|
|
||||||
|
|
||||||
static FILE *oread(const char *);
|
|
||||||
static poly_t rdpoly(const char *, int, int);
|
|
||||||
static void usage(void);
|
|
||||||
|
|
||||||
static const char *myname = "reveng"; /* name of our program */
|
|
||||||
|
|
||||||
int reveng_main(int argc, char *argv[]) {
|
|
||||||
/* Command-line interface for CRC RevEng.
|
|
||||||
* Process options and switches in the argument list and
|
|
||||||
* run the required function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* default values */
|
|
||||||
model_t model = {
|
|
||||||
PZERO, /* no CRC polynomial, user must specify */
|
|
||||||
PZERO, /* Init = 0 */
|
|
||||||
P_BE, /* RefIn = false, RefOut = false, plus P_RTJUST setting in reveng.h */
|
|
||||||
PZERO, /* XorOut = 0 */
|
|
||||||
PZERO, /* check value unused */
|
|
||||||
NULL /* no model name */
|
|
||||||
};
|
|
||||||
int ibperhx = 8, obperhx = 8;
|
|
||||||
int rflags = 0, uflags = 0; /* search and UI flags */
|
|
||||||
|
|
||||||
unsigned long width = 0UL;
|
|
||||||
int c, mode = 0, args, psets, pass;
|
|
||||||
poly_t apoly, crc, qpoly = PZERO, *apolys, *pptr = NULL, *qptr = NULL;
|
|
||||||
model_t pset = model, *candmods, *mptr;
|
|
||||||
char *string;
|
|
||||||
|
|
||||||
myname = argv[0];
|
|
||||||
|
|
||||||
/* stdin must be binary */
|
|
||||||
#ifdef _WIN32
|
|
||||||
_setmode(STDIN_FILENO, _O_BINARY);
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
SETBMP();
|
|
||||||
|
|
||||||
pos=0;
|
|
||||||
optind=1;
|
|
||||||
do {
|
|
||||||
c=getopt(argc, argv, "?A:BDFLMP:SVXa:bcdefhi:k:lm:p:q:rstuvw:x:yz");
|
|
||||||
switch(c) {
|
|
||||||
case 'A': /* A: bits per output character */
|
|
||||||
case 'a': /* a: bits per character */
|
|
||||||
if((obperhx = atoi(optarg)) > BMP_BIT) {
|
|
||||||
fprintf(stderr,"%s: argument to -%c must be between 1 and %d\n", myname, c, BMP_BIT);
|
|
||||||
return 0;
|
|
||||||
//exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
if(c == 'a') ibperhx = obperhx;
|
|
||||||
break;
|
|
||||||
case 'b': /* b big-endian (RefIn = false, RefOut = false ) */
|
|
||||||
model.flags &= ~P_REFIN;
|
|
||||||
rflags |= R_HAVERI;
|
|
||||||
/* fall through: */
|
|
||||||
case 'B': /* B big-endian output (RefOut = false) */
|
|
||||||
model.flags &= ~P_REFOUT;
|
|
||||||
rflags |= R_HAVERO;
|
|
||||||
mnovel(&model);
|
|
||||||
/* fall through: */
|
|
||||||
case 'r': /* r right-justified */
|
|
||||||
model.flags |= P_RTJUST;
|
|
||||||
break;
|
|
||||||
case 'c': /* c calculate CRC */
|
|
||||||
case 'D': /* D list primary model names */
|
|
||||||
case 'd': /* d dump CRC model */
|
|
||||||
case 'e': /* e echo arguments */
|
|
||||||
case 's': /* s search for algorithm */
|
|
||||||
case 'v': /* v calculate reversed CRC */
|
|
||||||
if(mode) {
|
|
||||||
fprintf(stderr,"%s: more than one mode switch specified. Use %s -h for help.\n", myname, myname);
|
|
||||||
return 0;
|
|
||||||
//exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
mode = c;
|
|
||||||
break;
|
|
||||||
case 'F': /* F force search */
|
|
||||||
#ifndef NOFORCE
|
|
||||||
uflags |= C_FORCE;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 'f': /* f arguments are filenames */
|
|
||||||
uflags |= C_INFILE;
|
|
||||||
break;
|
|
||||||
case 'h': /* h get help / usage */
|
|
||||||
case 'u': /* u get help / usage */
|
|
||||||
case '?': /* ? get help / usage */
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
return 0;
|
|
||||||
//exit(EXIT_FAILURE);
|
|
||||||
break;
|
|
||||||
case 'i': /* i: Init value */
|
|
||||||
pptr = &model.init;
|
|
||||||
rflags |= R_HAVEI;
|
|
||||||
goto ippx;
|
|
||||||
case 'k': /* k: polynomial in Koopman notation */
|
|
||||||
pfree(&model.spoly);
|
|
||||||
model.spoly = strtop(optarg, 0, 4);
|
|
||||||
pkchop(&model.spoly);
|
|
||||||
width = plen(model.spoly);
|
|
||||||
rflags |= R_HAVEP;
|
|
||||||
mnovel(&model);
|
|
||||||
break;
|
|
||||||
case 'l': /* l little-endian input and output */
|
|
||||||
model.flags |= P_REFIN;
|
|
||||||
rflags |= R_HAVERI;
|
|
||||||
/* fall through: */
|
|
||||||
case 'L': /* L little-endian output */
|
|
||||||
model.flags |= P_REFOUT;
|
|
||||||
rflags |= R_HAVERO;
|
|
||||||
mnovel(&model);
|
|
||||||
/* fall through: */
|
|
||||||
case 't': /* t left-justified */
|
|
||||||
model.flags &= ~P_RTJUST;
|
|
||||||
break;
|
|
||||||
case 'm': /* m: select preset CRC model */
|
|
||||||
if(!(c = mbynam(&model, optarg))) {
|
|
||||||
fprintf(stderr,"%s: preset model '%s' not found. Use %s -D to list presets.\n", myname, optarg, myname);
|
|
||||||
return 0;
|
|
||||||
//exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
if(c < 0){
|
|
||||||
uerror("no preset models available");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* must set width so that parameter to -ipx is not zeroed */
|
|
||||||
width = plen(model.spoly);
|
|
||||||
rflags |= R_HAVEP | R_HAVEI | R_HAVERI | R_HAVERO | R_HAVEX;
|
|
||||||
break;
|
|
||||||
case 'M': /* M non-augmenting algorithm */
|
|
||||||
model.flags &= ~P_MULXN;
|
|
||||||
break;
|
|
||||||
case 'P': /* P: reversed polynomial */
|
|
||||||
case 'p': /* p: polynomial */
|
|
||||||
pptr = &model.spoly;
|
|
||||||
rflags &= ~R_HAVEQ;
|
|
||||||
rflags |= R_HAVEP;
|
|
||||||
ippx:
|
|
||||||
pfree(pptr);
|
|
||||||
*pptr = strtop(optarg, 0, 4);
|
|
||||||
pright(pptr, width);
|
|
||||||
if(c == 'P')
|
|
||||||
prev(pptr);
|
|
||||||
mnovel(&model);
|
|
||||||
break;
|
|
||||||
case 'q': /* q: range end polynomial */
|
|
||||||
pptr = &qpoly;
|
|
||||||
rflags &= ~R_HAVEP;
|
|
||||||
rflags |= R_HAVEQ;
|
|
||||||
goto ippx;
|
|
||||||
case 'S': /* s space between output characters */
|
|
||||||
model.flags |= P_SPACE;
|
|
||||||
break;
|
|
||||||
case 'V': /* v reverse algorithm */
|
|
||||||
/* Distinct from the -v switch as the
|
|
||||||
* user will have to reverse his or her
|
|
||||||
* own arguments. The user cannot dump
|
|
||||||
* the model generated by -v either.
|
|
||||||
*/
|
|
||||||
mrev(&model);
|
|
||||||
break;
|
|
||||||
case 'w': /* w: CRC width = order - 1 */
|
|
||||||
width = (unsigned long) atol(optarg);
|
|
||||||
break;
|
|
||||||
case 'X': /* X print uppercase hex */
|
|
||||||
model.flags |= P_UPPER;
|
|
||||||
break;
|
|
||||||
case 'x': /* x: XorOut value */
|
|
||||||
pptr = &model.xorout;
|
|
||||||
rflags |= R_HAVEX;
|
|
||||||
goto ippx;
|
|
||||||
case 'y': /* y little-endian byte order in files */
|
|
||||||
model.flags |= P_LTLBYT;
|
|
||||||
break;
|
|
||||||
case 'z': /* z raw binary arguments */
|
|
||||||
model.flags |= P_DIRECT;
|
|
||||||
break;
|
|
||||||
case -1: /* no more options, continue */
|
|
||||||
;
|
|
||||||
}
|
|
||||||
} while(c != -1);
|
|
||||||
|
|
||||||
/* canonicalise the model, so the one we dump is the one we
|
|
||||||
* calculate with (not with -s, spoly may be blank which will
|
|
||||||
* normalise to zero and clear init and xorout.)
|
|
||||||
*/
|
|
||||||
if(mode != 's')
|
|
||||||
mcanon(&model);
|
|
||||||
|
|
||||||
switch(mode) {
|
|
||||||
case 'v': /* v calculate reversed CRC */
|
|
||||||
/* Distinct from the -V switch as this causes
|
|
||||||
* the arguments and output to be reversed as well.
|
|
||||||
*/
|
|
||||||
/* reciprocate Poly */
|
|
||||||
prcp(&model.spoly);
|
|
||||||
|
|
||||||
/* mrev() does:
|
|
||||||
* if(refout) prev(init); else prev(xorout);
|
|
||||||
* but here the entire argument polynomial is
|
|
||||||
* reflected, not just the characters, so RefIn
|
|
||||||
* and RefOut are not inverted as with -V.
|
|
||||||
* Consequently Init is the mirror image of the
|
|
||||||
* one resulting from -V, and so we have:
|
|
||||||
*/
|
|
||||||
if(~model.flags & P_REFOUT) {
|
|
||||||
prev(&model.init);
|
|
||||||
prev(&model.xorout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* swap init and xorout */
|
|
||||||
apoly = model.init;
|
|
||||||
model.init = model.xorout;
|
|
||||||
model.xorout = apoly;
|
|
||||||
|
|
||||||
/* fall through: */
|
|
||||||
case 'c': /* c calculate CRC */
|
|
||||||
|
|
||||||
/* validate inputs */
|
|
||||||
/* if(plen(model.spoly) == 0) {
|
|
||||||
* fprintf(stderr,"%s: no polynomial specified for -%c (add -w WIDTH -p POLY)\n", myname, mode);
|
|
||||||
* exit(EXIT_FAILURE);
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* in the Williams model, xorout is applied after the refout stage.
|
|
||||||
* as refout is part of ptostr(), we reverse xorout here.
|
|
||||||
*/
|
|
||||||
if(model.flags & P_REFOUT)
|
|
||||||
prev(&model.xorout);
|
|
||||||
|
|
||||||
for(; optind < argc; ++optind) {
|
|
||||||
if(uflags & C_INFILE)
|
|
||||||
apoly = rdpoly(argv[optind], model.flags, ibperhx);
|
|
||||||
else
|
|
||||||
apoly = strtop(argv[optind], model.flags, ibperhx);
|
|
||||||
|
|
||||||
if(mode == 'v')
|
|
||||||
prev(&apoly);
|
|
||||||
|
|
||||||
crc = pcrc(apoly, model.spoly, model.init, model.xorout, model.flags);
|
|
||||||
|
|
||||||
if(mode == 'v')
|
|
||||||
prev(&crc);
|
|
||||||
|
|
||||||
string = ptostr(crc, model.flags, obperhx);
|
|
||||||
puts(string);
|
|
||||||
free(string);
|
|
||||||
pfree(&crc);
|
|
||||||
pfree(&apoly);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'D': /* D dump all models */
|
|
||||||
args = mcount();
|
|
||||||
if(!args){
|
|
||||||
uerror("no preset models available");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
for(mode = 0; mode < args; ++mode) {
|
|
||||||
mbynum(&model, mode);
|
|
||||||
mcanon(&model);
|
|
||||||
ufound(&model);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'd': /* d dump CRC model */
|
|
||||||
/* maybe we don't want to do this:
|
|
||||||
* either attaching names to arbitrary models or forcing to a preset
|
|
||||||
* mmatch(&model, M_OVERWR);
|
|
||||||
*/
|
|
||||||
if(~model.flags & P_MULXN){
|
|
||||||
uerror("not a Williams model compliant algorithm");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
string = mtostr(&model);
|
|
||||||
puts(string);
|
|
||||||
free(string);
|
|
||||||
break;
|
|
||||||
case 'e': /* e echo arguments */
|
|
||||||
for(; optind < argc; ++optind) {
|
|
||||||
if(uflags & C_INFILE)
|
|
||||||
apoly = rdpoly(argv[optind], model.flags, ibperhx);
|
|
||||||
else
|
|
||||||
apoly = strtop(argv[optind], model.flags, ibperhx);
|
|
||||||
|
|
||||||
psum(&apoly, model.init, 0UL);
|
|
||||||
string = ptostr(apoly, model.flags, obperhx);
|
|
||||||
puts(string);
|
|
||||||
free(string);
|
|
||||||
pfree(&apoly);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 's': /* s search for algorithm */
|
|
||||||
if(!width){
|
|
||||||
uerror("must specify positive -k or -w before -s");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(~model.flags & P_MULXN){
|
|
||||||
uerror("cannot search for non-Williams compliant models");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
praloc(&model.spoly, width);
|
|
||||||
praloc(&model.init, width);
|
|
||||||
praloc(&model.xorout, width);
|
|
||||||
if(!plen(model.spoly))
|
|
||||||
palloc(&model.spoly, width);
|
|
||||||
else
|
|
||||||
width = plen(model.spoly);
|
|
||||||
|
|
||||||
/* special case if qpoly is zero, search to end of range */
|
|
||||||
if(!ptst(qpoly))
|
|
||||||
rflags &= ~R_HAVEQ;
|
|
||||||
|
|
||||||
/* allocate argument array */
|
|
||||||
args = argc - optind;
|
|
||||||
if(!(apolys = malloc(args * sizeof(poly_t)))){
|
|
||||||
uerror("cannot allocate memory for argument list");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(pptr = apolys; optind < argc; ++optind) {
|
|
||||||
if(uflags & C_INFILE)
|
|
||||||
*pptr++ = rdpoly(argv[optind], model.flags, ibperhx);
|
|
||||||
else
|
|
||||||
*pptr++ = strtop(argv[optind], model.flags, ibperhx);
|
|
||||||
}
|
|
||||||
/* exit value of pptr is used hereafter! */
|
|
||||||
|
|
||||||
/* if endianness not specified, try
|
|
||||||
* little-endian then big-endian.
|
|
||||||
* NB: crossed-endian algorithms will not be
|
|
||||||
* searched.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* scan against preset models */
|
|
||||||
if(~uflags & C_FORCE) {
|
|
||||||
pass = 0;
|
|
||||||
do {
|
|
||||||
psets = mcount();
|
|
||||||
while(psets) {
|
|
||||||
mbynum(&pset, --psets);
|
|
||||||
/* skip if different width, or refin or refout don't match */
|
|
||||||
if(plen(pset.spoly) != width || (model.flags ^ pset.flags) & (P_REFIN | P_REFOUT))
|
|
||||||
continue;
|
|
||||||
/* skip if the preset doesn't match specified parameters */
|
|
||||||
if(rflags & R_HAVEP && pcmp(&model.spoly, &pset.spoly))
|
|
||||||
continue;
|
|
||||||
if(rflags & R_HAVEI && psncmp(&model.init, &pset.init))
|
|
||||||
continue;
|
|
||||||
if(rflags & R_HAVEX && psncmp(&model.xorout, &pset.xorout))
|
|
||||||
continue;
|
|
||||||
apoly = pclone(pset.xorout);
|
|
||||||
if(pset.flags & P_REFOUT)
|
|
||||||
prev(&apoly);
|
|
||||||
for(qptr = apolys; qptr < pptr; ++qptr) {
|
|
||||||
crc = pcrc(*qptr, pset.spoly, pset.init, apoly, 0);
|
|
||||||
if(ptst(crc)) {
|
|
||||||
pfree(&crc);
|
|
||||||
break;
|
|
||||||
} else
|
|
||||||
pfree(&crc);
|
|
||||||
}
|
|
||||||
pfree(&apoly);
|
|
||||||
if(qptr == pptr) {
|
|
||||||
/* the selected model solved all arguments */
|
|
||||||
mcanon(&pset);
|
|
||||||
ufound(&pset);
|
|
||||||
uflags |= C_RESULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mfree(&pset);
|
|
||||||
|
|
||||||
/* toggle refIn/refOut and reflect arguments */
|
|
||||||
if(~rflags & R_HAVERI) {
|
|
||||||
model.flags ^= P_REFIN | P_REFOUT;
|
|
||||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
|
||||||
prevch(qptr, ibperhx);
|
|
||||||
}
|
|
||||||
} while(~rflags & R_HAVERI && ++pass < 2);
|
|
||||||
}
|
|
||||||
if(uflags & C_RESULT) {
|
|
||||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
|
||||||
pfree(qptr);
|
|
||||||
//return 1;
|
|
||||||
//exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
if(!(model.flags & P_REFIN) != !(model.flags & P_REFOUT)){
|
|
||||||
uerror("cannot search for crossed-endian models");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
pass = 0;
|
|
||||||
do {
|
|
||||||
mptr = candmods = reveng(&model, qpoly, rflags, args, apolys);
|
|
||||||
if(mptr && plen(mptr->spoly))
|
|
||||||
uflags |= C_RESULT;
|
|
||||||
while(mptr && plen(mptr->spoly)) {
|
|
||||||
/* results were printed by the callback
|
|
||||||
* string = mtostr(mptr);
|
|
||||||
* puts(string);
|
|
||||||
* free(string);
|
|
||||||
*/
|
|
||||||
mfree(mptr++);
|
|
||||||
}
|
|
||||||
free(candmods);
|
|
||||||
if(~rflags & R_HAVERI) {
|
|
||||||
model.flags ^= P_REFIN | P_REFOUT;
|
|
||||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
|
||||||
prevch(qptr, ibperhx);
|
|
||||||
}
|
|
||||||
} while(~rflags & R_HAVERI && ++pass < 2);
|
|
||||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
|
||||||
pfree(qptr);
|
|
||||||
free(apolys);
|
|
||||||
if(~uflags & C_RESULT)
|
|
||||||
uerror("no models found");
|
|
||||||
break;
|
|
||||||
default: /* no mode specified */
|
|
||||||
fprintf(stderr, "%s: no mode switch specified. Use %s -h for help.\n", myname, myname);
|
|
||||||
//exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
//exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ufound(const model_t *model) {
|
|
||||||
/* Callback function to report each model found */
|
|
||||||
char *string;
|
|
||||||
|
|
||||||
if(!model) return;
|
|
||||||
/* generated models will be canonical */
|
|
||||||
string = mtostr(model);
|
|
||||||
puts(string);
|
|
||||||
free(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
uerror(const char *msg) {
|
|
||||||
/* Callback function to report fatal errors */
|
|
||||||
fprintf(stderr, "%s: %s\n", myname, msg);
|
|
||||||
return;
|
|
||||||
//exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
uprog(const poly_t gpoly, int flags, unsigned long seq) {
|
|
||||||
/* Callback function to report search progress */
|
|
||||||
char *string;
|
|
||||||
|
|
||||||
/* Suppress first report in CLI */
|
|
||||||
if(!seq)
|
|
||||||
return;
|
|
||||||
string = ptostr(gpoly, P_RTJUST, 4);
|
|
||||||
fprintf(stderr, "%s: searching: width=%ld poly=0x%s refin=%s refout=%s\n",
|
|
||||||
myname, plen(gpoly), string,
|
|
||||||
(flags & P_REFIN ? "true" : "false"),
|
|
||||||
(flags & P_REFOUT ? "true" : "false")
|
|
||||||
);
|
|
||||||
free(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
static poly_t
|
|
||||||
rdpoly(const char *name, int flags, int bperhx) {
|
|
||||||
/* read poly from file in chunks and report errors */
|
|
||||||
|
|
||||||
poly_t apoly = PZERO, chunk = PZERO;
|
|
||||||
FILE *input;
|
|
||||||
|
|
||||||
input = oread(name);
|
|
||||||
while(!feof(input) && !ferror(input)) {
|
|
||||||
chunk = filtop(input, BUFFER, flags, bperhx);
|
|
||||||
psum(&apoly, chunk, plen(apoly));
|
|
||||||
pfree(&chunk);
|
|
||||||
}
|
|
||||||
if(ferror(input)) {
|
|
||||||
fprintf(stderr,"%s: error condition on file '%s'\n", myname, name);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
/* close file unless stdin */
|
|
||||||
if(input == stdin)
|
|
||||||
/* reset EOF condition */
|
|
||||||
clearerr(input);
|
|
||||||
else if(fclose(input)) {
|
|
||||||
fprintf(stderr,"%s: error closing file '%s'\n", myname, name);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
return(apoly);
|
|
||||||
}
|
|
||||||
|
|
||||||
static FILE *
|
|
||||||
oread(const char *name) {
|
|
||||||
/* open file for reading and report errors */
|
|
||||||
FILE *handle;
|
|
||||||
|
|
||||||
/* recognise special name '-' as standard input */
|
|
||||||
if(*name == '-' && name[1] == '\0')
|
|
||||||
return(stdin);
|
|
||||||
if(!(handle = fopen(name, "rb"))) {
|
|
||||||
fprintf(stderr, "%s: cannot open '%s' for reading\n", myname, name);
|
|
||||||
return 0;
|
|
||||||
//exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
return(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
usage(void) {
|
|
||||||
/* print usage if asked, or if syntax incorrect */
|
|
||||||
fprintf(stderr,
|
|
||||||
"CRC RevEng, an arbitrary-precision CRC calculator and algorithm finder\n"
|
|
||||||
"Usage:\t");
|
|
||||||
fputs(myname, stderr);
|
|
||||||
fprintf(stderr,
|
|
||||||
"\t-cdDesvhu? [-bBfFlLMrStVXyz]\n"
|
|
||||||
"\t\t[-a BITS] [-A OBITS] [-i INIT] [-k KPOLY] [-m MODEL]\n"
|
|
||||||
"\t\t[-p POLY] [-P RPOLY] [-q QPOLY] [-w WIDTH] [-x XOROUT]\n"
|
|
||||||
"\t\t[STRING...]\n"
|
|
||||||
"Options:\n"
|
|
||||||
"\t-a BITS\t\tbits per character (1 to %d)\n"
|
|
||||||
"\t-A OBITS\tbits per output character (1 to %d)\n"
|
|
||||||
"\t-i INIT\t\tinitial register value\n"
|
|
||||||
"\t-k KPOLY\tgenerator in Koopman notation (implies WIDTH)\n"
|
|
||||||
"\t-m MODEL\tpreset CRC algorithm\n"
|
|
||||||
"\t-p POLY\t\tgenerator or search range start polynomial\n"
|
|
||||||
"\t-P RPOLY\treversed generator polynomial\n",
|
|
||||||
BMP_BIT, BMP_BIT);
|
|
||||||
fprintf(stderr,
|
|
||||||
"\t-q QPOLY\tsearch range end polynomial\n"
|
|
||||||
"\t-w WIDTH\tregister size, in bits\n"
|
|
||||||
"\t-x XOROUT\tfinal register XOR value\n"
|
|
||||||
"Modifier switches:\n"
|
|
||||||
"\t-b big-endian CRC\t\t-B big-endian CRC output\n"
|
|
||||||
"\t-f read files named in STRINGs\t-F find presets less quickly\n"
|
|
||||||
"\t-l little-endian CRC\t\t-L little-endian CRC output\n"
|
|
||||||
"\t-M non-augmenting algorithm\t-r right-justified output\n"
|
|
||||||
"\t-S print spaces between chars\t-t left-justified output\n"
|
|
||||||
"\t-V reverse algorithm only\t-X print uppercase hex\n"
|
|
||||||
"\t-y low bytes first in files\t-z raw binary STRINGs\n");
|
|
||||||
fprintf(stderr,
|
|
||||||
"Mode switches:\n"
|
|
||||||
"\t-c calculate CRCs\t\t-d dump algorithm parameters\n"
|
|
||||||
"\t-D list preset algorithms\t-e echo (and reformat) input\n"
|
|
||||||
"\t-s search for algorithm\t\t-v calculate reversed CRCs\n"
|
|
||||||
"\t-g search for alg given hex+crc\t-h | -u | -? show this help\n"
|
|
||||||
"Common Use Examples:\n"
|
|
||||||
"\t reveng -g 01020304e3\n"
|
|
||||||
"\t Searches for a known/common crc preset that computes the crc\n"
|
|
||||||
"\t on the end of the given hex string\n"
|
|
||||||
"\t reveng -w 8 -s 01020304e3 010204039d\n"
|
|
||||||
"\t Searches for any possible 8 bit width crc calc that computes\n"
|
|
||||||
"\t the crc on the end of the given hex string(s)\n"
|
|
||||||
"\t reveng -m CRC-8 -c 01020304\n"
|
|
||||||
"\t Calculates the crc-8 of the given hex string\n"
|
|
||||||
"\t reveng -D\n"
|
|
||||||
"\t Outputs a list of all known/common crc models with their\n"
|
|
||||||
"\t preset values\n"
|
|
||||||
"\n"
|
|
||||||
"Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Gregory Cook\n"
|
|
||||||
"This is free software; see the source for copying conditions. There is NO\n"
|
|
||||||
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
|
|
||||||
"Version "
|
|
||||||
VERSION
|
|
||||||
"\t\t\t\t <http://reveng.sourceforge.net/>\n");
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
/* config.h
|
|
||||||
* Greg Cook, 9/Apr/2015
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* CRC RevEng, an arbitrary-precision CRC calculator and algorithm finder
|
|
||||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Gregory Cook
|
|
||||||
*
|
|
||||||
* This file is part of CRC RevEng.
|
|
||||||
*
|
|
||||||
* CRC RevEng is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* CRC RevEng is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with CRC RevEng. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CONFIG_H
|
|
||||||
#define CONFIG_H 1
|
|
||||||
|
|
||||||
/*****************************************
|
|
||||||
* *
|
|
||||||
* Start of user configuration options *
|
|
||||||
* *
|
|
||||||
*****************************************/
|
|
||||||
|
|
||||||
/* A type to contain polynomial coefficient bitmaps.
|
|
||||||
* Can be changed to 'unsigned long long' for some extended compilers.
|
|
||||||
* Adjust BMP_C(), BMP_BIT and BMP_SUB below if this is changed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BMP_T unsigned long
|
|
||||||
|
|
||||||
/* Creates an appropriate numeric constant for bmp_t.
|
|
||||||
* If the underlying type is 'unsigned long long', change UL to ULL.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BMP_C(n) (n##UL)
|
|
||||||
|
|
||||||
/* Define BMPMACRO to turn the definitions of the size of a bmp_t into
|
|
||||||
* compile-time constants. This improves efficiency but makes the code
|
|
||||||
* platform-specific.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* #define BMPMACRO 1 */
|
|
||||||
|
|
||||||
/* Some enterprise users may wish to disable the -F switch to minimise CPU
|
|
||||||
* usage. To do this, define the macro NOFORCE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* #define NOFORCE 1 */
|
|
||||||
|
|
||||||
/* Define PRESETS to compile CRC RevEng with the preset models from the
|
|
||||||
* CRC Catalogue. This implies BMPMACRO and so makes the code platform-
|
|
||||||
* specific.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// PM3 NOTES:
|
|
||||||
// only PRESETS tested on windows
|
|
||||||
// PRESETS was commented out of original code
|
|
||||||
// but to enable preset models it must be enabled
|
|
||||||
// (marshmellow)
|
|
||||||
#define PRESETS 1
|
|
||||||
|
|
||||||
|
|
||||||
/* Macros defining the size of a bmp_t.
|
|
||||||
* Their values only matter if PRESETS and/or BMPMACRO are defined, in
|
|
||||||
* which case edit the macros below to suit your architecture.
|
|
||||||
* Otherwise, BMP_BIT and BMP_SUB will be redefined as aliases of bmpbit
|
|
||||||
* and bmpsub, global objects initialised at run time.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Size in bits of a bmp_t. Not necessarily a power of two. */
|
|
||||||
|
|
||||||
#define BMP_BIT 32
|
|
||||||
|
|
||||||
/* The highest power of two that is strictly less than BMP_BIT.
|
|
||||||
* Initialises the index of a binary search for set bits in a bmp_t.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BMP_SUB 16
|
|
||||||
|
|
||||||
/*****************************************
|
|
||||||
* *
|
|
||||||
* End of user configuration options *
|
|
||||||
* *
|
|
||||||
*****************************************/
|
|
||||||
|
|
||||||
#endif /* CONFIG_H */
|
|
|
@ -1,81 +0,0 @@
|
||||||
/*----------------------------------------------------------------------
|
|
||||||
|
|
||||||
Replacement for Unix "getopt()", for DOS/Windows/etc.
|
|
||||||
|
|
||||||
getopt.c 1.3 2003/09/17 16:17:59
|
|
||||||
|
|
||||||
Copyright (C) 1998, 2003 by David A. Hinds -- All Rights Reserved
|
|
||||||
|
|
||||||
This file is part of ASPEX.
|
|
||||||
|
|
||||||
ASPEX is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
ASPEX is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with ASPEX; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "string.h"
|
|
||||||
#include "stdio.h"
|
|
||||||
#include "getopt.h"
|
|
||||||
|
|
||||||
char *optarg;
|
|
||||||
int optind = 1, opterr, optopt;
|
|
||||||
int pos = 0;
|
|
||||||
int getopt(int argc, char *argv[], const char *optstring)
|
|
||||||
{
|
|
||||||
//static int pos = 0;
|
|
||||||
char *str;
|
|
||||||
|
|
||||||
if (pos == 0) {
|
|
||||||
if ((optind >= argc) || (*argv[optind] != '-'))
|
|
||||||
return EOF;
|
|
||||||
pos = 1;
|
|
||||||
if (argv[optind][pos] == '\0')
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
str = strchr(optstring, argv[optind][pos]);
|
|
||||||
if (str == NULL) {
|
|
||||||
optopt = argv[optind][pos];
|
|
||||||
if (opterr)
|
|
||||||
fprintf(stderr, "%s: illegal option -- %c\n", argv[0],
|
|
||||||
optopt);
|
|
||||||
return '?';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (str[1] == ':') {
|
|
||||||
if (argv[optind][pos+1] != '\0') {
|
|
||||||
optarg = &argv[optind][pos+1];
|
|
||||||
return *str;
|
|
||||||
}
|
|
||||||
optind++;
|
|
||||||
if (optind >= argc) {
|
|
||||||
optopt = *str;
|
|
||||||
if (opterr)
|
|
||||||
fprintf(stderr, "%s: option requires an argument -- %c\n",
|
|
||||||
argv[0], optopt);
|
|
||||||
return '?';
|
|
||||||
}
|
|
||||||
optarg = argv[optind];
|
|
||||||
optind++; pos = 0;
|
|
||||||
return *str;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pos++;
|
|
||||||
if (argv[optind][pos] == '\0') {
|
|
||||||
optind++;
|
|
||||||
pos = 0;
|
|
||||||
}
|
|
||||||
return *str;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
getopt.h 1.2 2003/09/17 16:17:59
|
|
||||||
|
|
||||||
Copyright (C) 1998, 2003 by David A. Hinds -- All Rights Reserved
|
|
||||||
|
|
||||||
This file is part of ASPEX.
|
|
||||||
|
|
||||||
ASPEX is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
ASPEX is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with ASPEX; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern char *optarg;
|
|
||||||
extern int optind, opterr, optopt, pos;
|
|
||||||
int getopt(int argc, char *argv[], const char *optstring);
|
|
|
@ -1,823 +0,0 @@
|
||||||
/* model.c
|
|
||||||
* Greg Cook, 9/Apr/2015
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* CRC RevEng, an arbitrary-precision CRC calculator and algorithm finder
|
|
||||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Gregory Cook
|
|
||||||
*
|
|
||||||
* This file is part of CRC RevEng.
|
|
||||||
*
|
|
||||||
* CRC RevEng is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* CRC RevEng is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with CRC RevEng. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* 2014-01-14: added CRC-8/DVB-S2
|
|
||||||
* 2014-01-11: corrected CRC-40/GSM, added alias CRC-8/AES
|
|
||||||
* 2013-10-14: added CRC-13/BBC and six cdma2000 algorithms
|
|
||||||
* 2013-06-11: ensure BMP_BIT is an integer constant to compile presets
|
|
||||||
* 2013-01-20: big polynomials autogenerated, corrected CRC-82/DARC
|
|
||||||
* 2012-07-19: added CRC-8/EBU
|
|
||||||
* 2012-07-16: added CRC-15/MPT1327
|
|
||||||
* 2012-05-25: removed CRC-1/PARITY-EVEN, CRC-1/PARITY-ODD
|
|
||||||
* 2012-04-12: added model CRC-31/PHILIPS
|
|
||||||
* 2012-03-03: single-line Williams model string conversion
|
|
||||||
* 2012-02-20: corrected model CRC-6/DARC
|
|
||||||
* 2011-09-03: added mrev(), mnovel()
|
|
||||||
* 2011-08-28: added model CRC-64/XZ
|
|
||||||
* 2011-04-30: added models CRC-16/TMS37157 and CRC-A, and alias CRC-B
|
|
||||||
* 2011-02-10: made preset models ANSI C compliant
|
|
||||||
* 2011-01-17: fixed ANSI C warnings (except preset models)
|
|
||||||
* 2011-01-01: added mbynum(), mcount()
|
|
||||||
* 2010-12-26: renamed CRC RevEng
|
|
||||||
* 2010-12-18: minor change to mtostr() output format
|
|
||||||
* 2010-12-15: added mcmp(), mmatch()
|
|
||||||
* 2010-12-14: finished mbynam(), mnames(), mtostr()
|
|
||||||
* 2010-12-13: restarted with PCONST macros
|
|
||||||
* 2010-12-12: was having so much fun I didn't think to try compiling. :(
|
|
||||||
* 2010-12-12: started models.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "reveng.h"
|
|
||||||
|
|
||||||
/* Private declarations */
|
|
||||||
|
|
||||||
struct mpreset {
|
|
||||||
const unsigned long width; /* width of CRC algorithm */
|
|
||||||
const bmp_t *const bspoly; /* polynomial with highest-order term removed. length determines CRC width */
|
|
||||||
const bmp_t *const binit; /* initial register value. length == poly.length */
|
|
||||||
const int flags; /* P_REFIN and P_REFOUT indicate reflected input/output */
|
|
||||||
const bmp_t *const bxorout; /* final register XOR mask. length == poly.length */
|
|
||||||
const bmp_t *const bcheck; /* optional check value, the CRC of the UTF-8 string "123456789" */
|
|
||||||
const char *const name; /* optional canonical name of the model */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct malias {
|
|
||||||
const char *name;
|
|
||||||
const struct mpreset *model;
|
|
||||||
const int isprimry;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef PRESETS
|
|
||||||
# if BMP_BIT < 32
|
|
||||||
# error config.h: BMP_BIT must be an integer constant macro to compile presets
|
|
||||||
# else /* BMP_BIT */
|
|
||||||
|
|
||||||
/* Big polynomial constants. */
|
|
||||||
|
|
||||||
/* Directives for relink.pl */
|
|
||||||
/* CONSTANT b40 = (40, 0x0004820009) */
|
|
||||||
/* CONSTANT b40a = (40, 0xffffffffff) */
|
|
||||||
/* CONSTANT b40b = (40, 0xd4164fc646) */
|
|
||||||
/* CONSTANT b64 = (64, 0x42f0e1eba9ea3693) */
|
|
||||||
/* CONSTANT b64a = (64, 0x6c40df5f0b497347) */
|
|
||||||
/* CONSTANT b64b = (64, 0xffffffffffffffff) */
|
|
||||||
/* CONSTANT b64c = (64, 0x62ec59e3f1a4f00a) */
|
|
||||||
/* CONSTANT b64d = (64, 0x995dc9bbdf1939fa) */
|
|
||||||
/* CONSTANT b82 = (82, 0x0308c0111011401440411) */
|
|
||||||
/* CONSTANT b82a = (82, 0x09ea83f625023801fd612) */
|
|
||||||
|
|
||||||
/* The next section was generated by relink.pl from the directives above. */
|
|
||||||
|
|
||||||
/* DO NOT EDIT the section below, INCLUDING the next comment. */
|
|
||||||
/* BEGIN AUTO-GENERATED CONSTANTS */
|
|
||||||
# if BMP_BIT >= 40
|
|
||||||
static const bmp_t b40[] = {
|
|
||||||
BMP_C(0x0004820009) << (BMP_BIT - 40),
|
|
||||||
};
|
|
||||||
static const bmp_t b40a[] = {
|
|
||||||
BMP_C(0xffffffffff) << (BMP_BIT - 40),
|
|
||||||
};
|
|
||||||
static const bmp_t b40b[] = {
|
|
||||||
BMP_C(0xd4164fc646) << (BMP_BIT - 40),
|
|
||||||
};
|
|
||||||
# else /* BMP_BIT */
|
|
||||||
static const bmp_t b40[] = {
|
|
||||||
BMP_C(0x00048200) << (BMP_BIT - 32) | BMP_C(0x04) >> (39 - BMP_BIT),
|
|
||||||
BMP_C(0x09) << (BMP_BIT * 2 - 40),
|
|
||||||
};
|
|
||||||
static const bmp_t b40a[] = {
|
|
||||||
BMP_C(0xffffffff) << (BMP_BIT - 32) | BMP_C(0x7f) >> (39 - BMP_BIT),
|
|
||||||
BMP_C(0xff) << (BMP_BIT * 2 - 40),
|
|
||||||
};
|
|
||||||
static const bmp_t b40b[] = {
|
|
||||||
BMP_C(0xd4164fc6) << (BMP_BIT - 32) | BMP_C(0x23) >> (39 - BMP_BIT),
|
|
||||||
BMP_C(0x46) << (BMP_BIT * 2 - 40),
|
|
||||||
};
|
|
||||||
# endif /* BMP_BIT */
|
|
||||||
|
|
||||||
# if BMP_BIT >= 64
|
|
||||||
static const bmp_t b64[] = {
|
|
||||||
BMP_C(0x42f0e1eba9ea3693) << (BMP_BIT - 64),
|
|
||||||
};
|
|
||||||
static const bmp_t b64a[] = {
|
|
||||||
BMP_C(0x6c40df5f0b497347) << (BMP_BIT - 64),
|
|
||||||
};
|
|
||||||
static const bmp_t b64b[] = {
|
|
||||||
BMP_C(0xffffffffffffffff) << (BMP_BIT - 64),
|
|
||||||
};
|
|
||||||
static const bmp_t b64c[] = {
|
|
||||||
BMP_C(0x62ec59e3f1a4f00a) << (BMP_BIT - 64),
|
|
||||||
};
|
|
||||||
static const bmp_t b64d[] = {
|
|
||||||
BMP_C(0x995dc9bbdf1939fa) << (BMP_BIT - 64),
|
|
||||||
};
|
|
||||||
# else /* BMP_BIT */
|
|
||||||
static const bmp_t b64[] = {
|
|
||||||
BMP_C(0x42f0e1eb) << (BMP_BIT - 32) | BMP_C(0x54f51b49) >> (63 - BMP_BIT),
|
|
||||||
BMP_C(0xa9ea3693) << (BMP_BIT * 2 - 64),
|
|
||||||
};
|
|
||||||
static const bmp_t b64a[] = {
|
|
||||||
BMP_C(0x6c40df5f) << (BMP_BIT - 32) | BMP_C(0x05a4b9a3) >> (63 - BMP_BIT),
|
|
||||||
BMP_C(0x0b497347) << (BMP_BIT * 2 - 64),
|
|
||||||
};
|
|
||||||
static const bmp_t b64b[] = {
|
|
||||||
BMP_C(0xffffffff) << (BMP_BIT - 32) | BMP_C(0x7fffffff) >> (63 - BMP_BIT),
|
|
||||||
BMP_C(0xffffffff) << (BMP_BIT * 2 - 64),
|
|
||||||
};
|
|
||||||
static const bmp_t b64c[] = {
|
|
||||||
BMP_C(0x62ec59e3) << (BMP_BIT - 32) | BMP_C(0x78d27805) >> (63 - BMP_BIT),
|
|
||||||
BMP_C(0xf1a4f00a) << (BMP_BIT * 2 - 64),
|
|
||||||
};
|
|
||||||
static const bmp_t b64d[] = {
|
|
||||||
BMP_C(0x995dc9bb) << (BMP_BIT - 32) | BMP_C(0x6f8c9cfd) >> (63 - BMP_BIT),
|
|
||||||
BMP_C(0xdf1939fa) << (BMP_BIT * 2 - 64),
|
|
||||||
};
|
|
||||||
# endif /* BMP_BIT */
|
|
||||||
|
|
||||||
# if BMP_BIT >= 82
|
|
||||||
static const bmp_t b82[] = {
|
|
||||||
BMP_C(0x0308c0111011401440411) << (BMP_BIT - 82),
|
|
||||||
};
|
|
||||||
static const bmp_t b82a[] = {
|
|
||||||
BMP_C(0x09ea83f625023801fd612) << (BMP_BIT - 82),
|
|
||||||
};
|
|
||||||
# elif BMP_BIT >= 41
|
|
||||||
static const bmp_t b82[] = {
|
|
||||||
BMP_C(0x01846008880) << (BMP_BIT - 41) | BMP_C(0x08a00a20208) >> (81 - BMP_BIT),
|
|
||||||
BMP_C(0x11401440411) << (BMP_BIT * 2 - 82),
|
|
||||||
};
|
|
||||||
static const bmp_t b82a[] = {
|
|
||||||
BMP_C(0x04f541fb128) << (BMP_BIT - 41) | BMP_C(0x011c00feb09) >> (81 - BMP_BIT),
|
|
||||||
BMP_C(0x023801fd612) << (BMP_BIT * 2 - 82),
|
|
||||||
};
|
|
||||||
# else /* BMP_BIT */
|
|
||||||
static const bmp_t b82[] = {
|
|
||||||
BMP_C(0x0c230044) << (BMP_BIT - 32) | BMP_C(0x040) >> (40 - BMP_BIT),
|
|
||||||
BMP_C(0x40450051) << (BMP_BIT * 2 - 64) | BMP_C(0x00104) >> (80 - BMP_BIT * 2),
|
|
||||||
BMP_C(0x00411) << (BMP_BIT * 3 - 82),
|
|
||||||
};
|
|
||||||
static const bmp_t b82a[] = {
|
|
||||||
BMP_C(0x27aa0fd8) << (BMP_BIT - 32) | BMP_C(0x094) >> (40 - BMP_BIT),
|
|
||||||
BMP_C(0x9408e007) << (BMP_BIT * 2 - 64) | BMP_C(0x0f584) >> (80 - BMP_BIT * 2),
|
|
||||||
BMP_C(0x3d612) << (BMP_BIT * 3 - 82),
|
|
||||||
};
|
|
||||||
# endif /* BMP_BIT */
|
|
||||||
|
|
||||||
/* END AUTO-GENERATED CONSTANTS */
|
|
||||||
/* DO NOT EDIT the section above, INCLUDING the previous comment. */
|
|
||||||
|
|
||||||
/* Array of the polynomial bitmaps used in the model table. */
|
|
||||||
static const bmp_t b32[] = {
|
|
||||||
BMP_C(0x00000000) << (BMP_BIT - 32), /* 0 -- 5, 00 */
|
|
||||||
BMP_C(0x000000af) << (BMP_BIT - 32), /* 1 -- 32,000000af */
|
|
||||||
BMP_C(0x00010000) << (BMP_BIT - 32), /* 2 -- 16, 0001 */
|
|
||||||
BMP_C(0x00020000) << (BMP_BIT - 32), /* 3 -- 15, 0001 */
|
|
||||||
BMP_C(0x007e0000) << (BMP_BIT - 32), /* 4 -- 16, 007e */
|
|
||||||
BMP_C(0x007f0000) << (BMP_BIT - 32), /* 5 -- 16, 007f */
|
|
||||||
BMP_C(0x03400000) << (BMP_BIT - 32), /* 6 -- 11, 01a */
|
|
||||||
BMP_C(0x0376e6e7) << (BMP_BIT - 32), /* 7 -- 32,0376e6e7 */
|
|
||||||
BMP_C(0x04c11db7) << (BMP_BIT - 32), /* 8 -- 32,04c11db7 */
|
|
||||||
BMP_C(0x05890000) << (BMP_BIT - 32), /* 9 -- 16, 0589 */
|
|
||||||
BMP_C(0x07000000) << (BMP_BIT - 32), /* 10 -- 8, 07 */
|
|
||||||
BMP_C(0x09823b6e) << (BMP_BIT - 32), /* 11 -- 31,04c11db7 */
|
|
||||||
BMP_C(0x0b3c0000) << (BMP_BIT - 32), /* 12 -- 15, 059e */
|
|
||||||
BMP_C(0x0c000000) << (BMP_BIT - 32), /* 13 -- 6, 03 */
|
|
||||||
BMP_C(0x0fb30000) << (BMP_BIT - 32), /* 14 -- 16, 0fb3 */
|
|
||||||
BMP_C(0x10210000) << (BMP_BIT - 32), /* 15 -- 16, 1021 */
|
|
||||||
BMP_C(0x12000000) << (BMP_BIT - 32), /* 16 -- 7, 09 */
|
|
||||||
BMP_C(0x15000000) << (BMP_BIT - 32), /* 17 -- 8, 15 */
|
|
||||||
BMP_C(0x18000000) << (BMP_BIT - 32), /* 18 -- 6, 06 */
|
|
||||||
BMP_C(0x19d3c8d8) << (BMP_BIT - 32), /* 19 -- 31,0ce9e46c */
|
|
||||||
BMP_C(0x1c000000) << (BMP_BIT - 32), /* 20 -- 6, 07 */
|
|
||||||
BMP_C(0x1d000000) << (BMP_BIT - 32), /* 21 -- 8, 1d */
|
|
||||||
BMP_C(0x1d0f0000) << (BMP_BIT - 32), /* 22 -- 16, 1d0f */
|
|
||||||
BMP_C(0x1edc6f41) << (BMP_BIT - 32), /* 23 -- 32,1edc6f41 */
|
|
||||||
BMP_C(0x1f23b800) << (BMP_BIT - 32), /* 24 -- 24, 1f23b8 */
|
|
||||||
BMP_C(0x20140000) << (BMP_BIT - 32), /* 25 -- 14, 0805 */
|
|
||||||
BMP_C(0x20b40000) << (BMP_BIT - 32), /* 26 -- 14, 082d */
|
|
||||||
BMP_C(0x21890000) << (BMP_BIT - 32), /* 27 -- 16, 2189 */
|
|
||||||
BMP_C(0x21cf0200) << (BMP_BIT - 32), /* 28 -- 24, 21cf02 */
|
|
||||||
BMP_C(0x25000000) << (BMP_BIT - 32), /* 29 -- 8, 25 */
|
|
||||||
BMP_C(0x26b10000) << (BMP_BIT - 32), /* 30 -- 16, 26b1 */
|
|
||||||
BMP_C(0x27d00000) << (BMP_BIT - 32), /* 31 -- 13, 04fa */
|
|
||||||
BMP_C(0x28000000) << (BMP_BIT - 32), /* 32 -- 5, 05 */
|
|
||||||
BMP_C(0x29b10000) << (BMP_BIT - 32), /* 33 -- 16, 29b1 */
|
|
||||||
BMP_C(0x30000000) << (BMP_BIT - 32), /* 34 -- 4, 3 */
|
|
||||||
BMP_C(0x3010bf7f) << (BMP_BIT - 32), /* 35 -- 32,3010bf7f */
|
|
||||||
BMP_C(0x31000000) << (BMP_BIT - 32), /* 36 -- 8, 31 */
|
|
||||||
BMP_C(0x31c30000) << (BMP_BIT - 32), /* 37 -- 16, 31c3 */
|
|
||||||
BMP_C(0x34000000) << (BMP_BIT - 32), /* 38 -- 6, 0d */
|
|
||||||
BMP_C(0x340bc6d9) << (BMP_BIT - 32), /* 39 -- 32,340bc6d9 */
|
|
||||||
BMP_C(0x38000000) << (BMP_BIT - 32), /* 40 -- 5, 07 */
|
|
||||||
BMP_C(0x39000000) << (BMP_BIT - 32), /* 41 -- 8, 39 */
|
|
||||||
BMP_C(0x3d650000) << (BMP_BIT - 32), /* 42 -- 16, 3d65 */
|
|
||||||
BMP_C(0x44c20000) << (BMP_BIT - 32), /* 43 -- 16, 44c2 */
|
|
||||||
BMP_C(0x48000000) << (BMP_BIT - 32), /* 44 -- 5, 09 */
|
|
||||||
BMP_C(0x4acc0000) << (BMP_BIT - 32), /* 45 -- 15, 2566 */
|
|
||||||
BMP_C(0x4b370000) << (BMP_BIT - 32), /* 46 -- 16, 4b37 */
|
|
||||||
BMP_C(0x4c060000) << (BMP_BIT - 32), /* 47 -- 16, 4c06 */
|
|
||||||
BMP_C(0x55000000) << (BMP_BIT - 32), /* 48 -- 8, 55 */
|
|
||||||
BMP_C(0x5d6dcb00) << (BMP_BIT - 32), /* 49 -- 24, 5d6dcb */
|
|
||||||
BMP_C(0x60000000) << (BMP_BIT - 32), /* 50 -- 3, 3 */
|
|
||||||
BMP_C(0x63d00000) << (BMP_BIT - 32), /* 51 -- 16, 63d0 */
|
|
||||||
BMP_C(0x64000000) << (BMP_BIT - 32), /* 52 -- 6, 19 */
|
|
||||||
BMP_C(0x66400000) << (BMP_BIT - 32), /* 53 -- 10, 199 */
|
|
||||||
BMP_C(0x6f910000) << (BMP_BIT - 32), /* 54 -- 16, 6f91 */
|
|
||||||
BMP_C(0x70000000) << (BMP_BIT - 32), /* 55 -- 4, 7 */
|
|
||||||
BMP_C(0x70a00000) << (BMP_BIT - 32), /* 56 -- 11, 385 */
|
|
||||||
BMP_C(0x765e7680) << (BMP_BIT - 32), /* 57 -- 32,765e7680 */
|
|
||||||
BMP_C(0x7979bd00) << (BMP_BIT - 32), /* 58 -- 24, 7979bd */
|
|
||||||
BMP_C(0x7e000000) << (BMP_BIT - 32), /* 59 -- 8, 7e */
|
|
||||||
BMP_C(0x80050000) << (BMP_BIT - 32), /* 60 -- 16, 8005 */
|
|
||||||
BMP_C(0x800d0000) << (BMP_BIT - 32), /* 61 -- 16, 800d */
|
|
||||||
BMP_C(0x80f00000) << (BMP_BIT - 32), /* 62 -- 12, 80f */
|
|
||||||
BMP_C(0x814141ab) << (BMP_BIT - 32), /* 63 -- 32,814141ab */
|
|
||||||
BMP_C(0x864cfb00) << (BMP_BIT - 32), /* 64 -- 24, 864cfb */
|
|
||||||
BMP_C(0x87315576) << (BMP_BIT - 32), /* 65 -- 32,87315576 */
|
|
||||||
BMP_C(0x89ec0000) << (BMP_BIT - 32), /* 66 -- 16, 89ec */
|
|
||||||
BMP_C(0x8b320000) << (BMP_BIT - 32), /* 67 -- 15, 4599 */
|
|
||||||
BMP_C(0x8bb70000) << (BMP_BIT - 32), /* 68 -- 16, 8bb7 */
|
|
||||||
BMP_C(0x8cc00000) << (BMP_BIT - 32), /* 69 -- 10, 233 */
|
|
||||||
BMP_C(0x906e0000) << (BMP_BIT - 32), /* 70 -- 16, 906e */
|
|
||||||
BMP_C(0x97000000) << (BMP_BIT - 32), /* 71 -- 8, 97 */
|
|
||||||
BMP_C(0x98000000) << (BMP_BIT - 32), /* 72 -- 6, 26 */
|
|
||||||
BMP_C(0x9b000000) << (BMP_BIT - 32), /* 73 -- 8, 9b */
|
|
||||||
BMP_C(0x9c000000) << (BMP_BIT - 32), /* 74 -- 6, 27 */
|
|
||||||
BMP_C(0x9e000000) << (BMP_BIT - 32), /* 75 -- 7, 4f */
|
|
||||||
BMP_C(0x9ecf0000) << (BMP_BIT - 32), /* 76 -- 16, 9ecf */
|
|
||||||
BMP_C(0xa0970000) << (BMP_BIT - 32), /* 77 -- 16, a097 */
|
|
||||||
BMP_C(0xa1000000) << (BMP_BIT - 32), /* 78 -- 8, a1 */
|
|
||||||
BMP_C(0xa6000000) << (BMP_BIT - 32), /* 79 -- 7, 53 */
|
|
||||||
BMP_C(0xa8000000) << (BMP_BIT - 32), /* 80 -- 5, 15 */
|
|
||||||
BMP_C(0xa833982b) << (BMP_BIT - 32), /* 81 -- 32,a833982b */
|
|
||||||
BMP_C(0xabcdef00) << (BMP_BIT - 32), /* 82 -- 24, abcdef */
|
|
||||||
BMP_C(0xb2aa0000) << (BMP_BIT - 32), /* 83 -- 16, b2aa */
|
|
||||||
BMP_C(0xb4600000) << (BMP_BIT - 32), /* 84 -- 11, 5a3 */
|
|
||||||
BMP_C(0xb4c80000) << (BMP_BIT - 32), /* 85 -- 16, b4c8 */
|
|
||||||
BMP_C(0xb704ce00) << (BMP_BIT - 32), /* 86 -- 24, b704ce */
|
|
||||||
BMP_C(0xbb3d0000) << (BMP_BIT - 32), /* 87 -- 16, bb3d */
|
|
||||||
BMP_C(0xbc000000) << (BMP_BIT - 32), /* 88 -- 8, bc */
|
|
||||||
BMP_C(0xbd0be338) << (BMP_BIT - 32), /* 89 -- 32,bd0be338 */
|
|
||||||
BMP_C(0xbf050000) << (BMP_BIT - 32), /* 90 -- 16, bf05 */
|
|
||||||
BMP_C(0xc0000000) << (BMP_BIT - 32), /* 91 -- 3, 6 */
|
|
||||||
BMP_C(0xc2b70000) << (BMP_BIT - 32), /* 92 -- 16, c2b7 */
|
|
||||||
BMP_C(0xc6c60000) << (BMP_BIT - 32), /* 93 -- 16, c6c6 */
|
|
||||||
BMP_C(0xc8000000) << (BMP_BIT - 32), /* 94 -- 5, 19 */
|
|
||||||
BMP_C(0xc8670000) << (BMP_BIT - 32), /* 95 -- 16, c867 */
|
|
||||||
BMP_C(0xcbf43926) << (BMP_BIT - 32), /* 96 -- 32,cbf43926 */
|
|
||||||
BMP_C(0xd0000000) << (BMP_BIT - 32), /* 97 -- 8, d0 */
|
|
||||||
BMP_C(0xd02a0000) << (BMP_BIT - 32), /* 98 -- 15, 6815 */
|
|
||||||
BMP_C(0xd0db0000) << (BMP_BIT - 32), /* 99 -- 16, d0db */
|
|
||||||
BMP_C(0xd4d00000) << (BMP_BIT - 32), /* 100 -- 12, d4d */
|
|
||||||
BMP_C(0xd5000000) << (BMP_BIT - 32), /* 101 -- 8, d5 */
|
|
||||||
BMP_C(0xd64e0000) << (BMP_BIT - 32), /* 102 -- 16, d64e */
|
|
||||||
BMP_C(0xda000000) << (BMP_BIT - 32), /* 103 -- 8, da */
|
|
||||||
BMP_C(0xdaf00000) << (BMP_BIT - 32), /* 104 -- 12, daf */
|
|
||||||
BMP_C(0xe0000000) << (BMP_BIT - 32), /* 105 -- 3, 7 */
|
|
||||||
BMP_C(0xe3069283) << (BMP_BIT - 32), /* 106 -- 32,e3069283 */
|
|
||||||
BMP_C(0xe5cc0000) << (BMP_BIT - 32), /* 107 -- 16, e5cc */
|
|
||||||
BMP_C(0xe7a80000) << (BMP_BIT - 32), /* 108 -- 13, 1cf5 */
|
|
||||||
BMP_C(0xea000000) << (BMP_BIT - 32), /* 109 -- 7, 75 */
|
|
||||||
BMP_C(0xea820000) << (BMP_BIT - 32), /* 110 -- 16, ea82 */
|
|
||||||
BMP_C(0xec000000) << (BMP_BIT - 32), /* 111 -- 6, 3b */
|
|
||||||
BMP_C(0xf1300000) << (BMP_BIT - 32), /* 112 -- 12, f13 */
|
|
||||||
BMP_C(0xf4000000) << (BMP_BIT - 32), /* 113 -- 8, f4 */
|
|
||||||
BMP_C(0xf5b00000) << (BMP_BIT - 32), /* 114 -- 12, f5b */
|
|
||||||
BMP_C(0xf6400000) << (BMP_BIT - 32), /* 115 -- 10, 3d9 */
|
|
||||||
BMP_C(0xf8000000) << (BMP_BIT - 32), /* 116 -- 5, 1f */
|
|
||||||
BMP_C(0xfc000000) << (BMP_BIT - 32), /* 117 -- 6, 3f */
|
|
||||||
BMP_C(0xfc891918) << (BMP_BIT - 32), /* 118 -- 32,fc891918 */
|
|
||||||
BMP_C(0xfd000000) << (BMP_BIT - 32), /* 119 -- 8, fd */
|
|
||||||
BMP_C(0xfe000000) << (BMP_BIT - 32), /* 120 -- 7, 7f */
|
|
||||||
BMP_C(0xfedcba00) << (BMP_BIT - 32), /* 121 -- 24, fedcba */
|
|
||||||
BMP_C(0xfee80000) << (BMP_BIT - 32), /* 122 -- 16, fee8 */
|
|
||||||
BMP_C(0xff000000) << (BMP_BIT - 32), /* 123 -- 8, ff */
|
|
||||||
BMP_C(0xffc00000) << (BMP_BIT - 32), /* 124 -- 10, 3ff */
|
|
||||||
BMP_C(0xfff00000) << (BMP_BIT - 32), /* 125 -- 12, fff */
|
|
||||||
BMP_C(0xffff0000) << (BMP_BIT - 32), /* 126 -- 16, ffff */
|
|
||||||
BMP_C(0xfffffffe) << (BMP_BIT - 32), /* 127 -- 31,7fffffff */
|
|
||||||
BMP_C(0xffffffff) << (BMP_BIT - 32), /* 128 -- 32,ffffffff */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Table of preset CRC models.
|
|
||||||
* Sorted by left-justified polynomial for bsearch().
|
|
||||||
*/
|
|
||||||
static const struct mpreset models[] = {
|
|
||||||
{32UL, b32+ 1, 0, P_BE, 0, b32+ 89, "XFER" }, /* 0 */
|
|
||||||
{40UL, b40, 0, P_BE, b40a, b40b, "CRC-40/GSM" }, /* 1 */
|
|
||||||
{32UL, b32+ 8, 0, P_BE, b32+128, b32+ 57, "CRC-32/POSIX" }, /* 2 */
|
|
||||||
{32UL, b32+ 8, b32+128, P_BE, 0, b32+ 7, "CRC-32/MPEG-2" }, /* 3 */
|
|
||||||
{32UL, b32+ 8, b32+128, P_BE, b32+128, b32+118, "CRC-32/BZIP2" }, /* 4 */
|
|
||||||
{32UL, b32+ 8, b32+128, P_LE, 0, b32+ 39, "JAMCRC" }, /* 5 */
|
|
||||||
{32UL, b32+ 8, b32+128, P_LE, b32+128, b32+ 96, "CRC-32" }, /* 6 */
|
|
||||||
{16UL, b32+ 9, 0, P_BE, 0, b32+ 5, "CRC-16/DECT-X" }, /* 7 */
|
|
||||||
{16UL, b32+ 9, 0, P_BE, b32+ 2, b32+ 4, "CRC-16/DECT-R" }, /* 8 */
|
|
||||||
{ 8UL, b32+ 10, 0, P_BE, 0, b32+113, "CRC-8" }, /* 9 */
|
|
||||||
{ 8UL, b32+ 10, 0, P_BE, b32+ 48, b32+ 78, "CRC-8/ITU" }, /* 10 */
|
|
||||||
{ 8UL, b32+ 10, b32+123, P_LE, 0, b32+ 97, "CRC-8/ROHC" }, /* 11 */
|
|
||||||
{31UL, b32+ 11, b32+127, P_BE, b32+127, b32+ 19, "CRC-31/PHILIPS" }, /* 12 */
|
|
||||||
{ 6UL, b32+ 13, 0, P_LE, 0, b32+ 18, "CRC-6/ITU" }, /* 13 */
|
|
||||||
{82UL, b82, 0, P_LE, 0, b82a, "CRC-82/DARC" }, /* 14 */
|
|
||||||
{16UL, b32+ 15, 0, P_BE, 0, b32+ 37, "XMODEM" }, /* 15 */
|
|
||||||
{16UL, b32+ 15, 0, P_LE, 0, b32+ 27, "KERMIT" }, /* 16 */
|
|
||||||
{16UL, b32+ 15, b32+ 22, P_BE, 0, b32+107, "CRC-16/AUG-CCITT" }, /* 17 */
|
|
||||||
{16UL, b32+ 15, b32+ 66, P_LE, 0, b32+ 30, "CRC-16/TMS37157" }, /* 18 */
|
|
||||||
{16UL, b32+ 15, b32+ 83, P_LE, 0, b32+ 51, "CRC-16/RIELLO" }, /* 19 */
|
|
||||||
{16UL, b32+ 15, b32+ 93, P_LE, 0, b32+ 90, "CRC-A" }, /* 20 */
|
|
||||||
{16UL, b32+ 15, b32+126, P_BE, 0, b32+ 33, "CRC-16/CCITT-FALSE"}, /* 21 */
|
|
||||||
{16UL, b32+ 15, b32+126, P_BE, b32+126, b32+102, "CRC-16/GENIBUS" }, /* 22 */
|
|
||||||
{16UL, b32+ 15, b32+126, P_LE, 0, b32+ 54, "CRC-16/MCRF4XX" }, /* 23 */
|
|
||||||
{16UL, b32+ 15, b32+126, P_LE, b32+126, b32+ 70, "X-25" }, /* 24 */
|
|
||||||
{ 7UL, b32+ 16, 0, P_BE, 0, b32+109, "CRC-7" }, /* 25 */
|
|
||||||
{ 6UL, b32+ 20, b32+117, P_BE, 0, b32+111, "CRC-6/CDMA2000-B" }, /* 26 */
|
|
||||||
{ 8UL, b32+ 21, b32+119, P_BE, 0, b32+ 59, "CRC-8/I-CODE" }, /* 27 */
|
|
||||||
{ 8UL, b32+ 21, b32+123, P_LE, 0, b32+ 71, "CRC-8/EBU" }, /* 28 */
|
|
||||||
{32UL, b32+ 23, b32+128, P_LE, b32+128, b32+106, "CRC-32C" }, /* 29 */
|
|
||||||
{14UL, b32+ 25, 0, P_LE, 0, b32+ 26, "CRC-14/DARC" }, /* 30 */
|
|
||||||
{ 5UL, b32+ 32, b32+116, P_LE, b32+116, b32+ 94, "CRC-5/USB" }, /* 31 */
|
|
||||||
{ 4UL, b32+ 34, 0, P_LE, 0, b32+ 55, "CRC-4/ITU" }, /* 32 */
|
|
||||||
{ 8UL, b32+ 36, 0, P_LE, 0, b32+ 78, "CRC-8/MAXIM" }, /* 33 */
|
|
||||||
{ 8UL, b32+ 41, 0, P_LE, 0, b32+ 17, "CRC-8/DARC" }, /* 34 */
|
|
||||||
{16UL, b32+ 42, 0, P_BE, b32+126, b32+ 92, "CRC-16/EN-13757" }, /* 35 */
|
|
||||||
{16UL, b32+ 42, 0, P_LE, b32+126, b32+110, "CRC-16/DNP" }, /* 36 */
|
|
||||||
{64UL, b64, 0, P_BE, 0, b64a, "CRC-64" }, /* 37 */
|
|
||||||
{64UL, b64, b64b, P_BE, b64b, b64c, "CRC-64/WE" }, /* 38 */
|
|
||||||
{64UL, b64, b64b, P_LE, b64b, b64d, "CRC-64/XZ" }, /* 39 */
|
|
||||||
{ 5UL, b32+ 44, b32+ 44, P_BE, 0, b32+ 0, "CRC-5/EPC" }, /* 40 */
|
|
||||||
{24UL, b32+ 49, b32+ 82, P_BE, 0, b32+ 24, "CRC-24/FLEXRAY-B" }, /* 41 */
|
|
||||||
{24UL, b32+ 49, b32+121, P_BE, 0, b32+ 58, "CRC-24/FLEXRAY-A" }, /* 42 */
|
|
||||||
{ 3UL, b32+ 50, b32+105, P_LE, 0, b32+ 91, "CRC-3/ROHC" }, /* 43 */
|
|
||||||
{ 6UL, b32+ 52, 0, P_LE, 0, b32+ 72, "CRC-6/DARC" }, /* 44 */
|
|
||||||
{11UL, b32+ 56, b32+ 6, P_BE, 0, b32+ 84, "CRC-11" }, /* 45 */
|
|
||||||
{16UL, b32+ 60, 0, P_BE, 0, b32+122, "CRC-16/BUYPASS" }, /* 46 */
|
|
||||||
{16UL, b32+ 60, 0, P_LE, 0, b32+ 87, "ARC" }, /* 47 */
|
|
||||||
{16UL, b32+ 60, 0, P_LE, b32+126, b32+ 43, "CRC-16/MAXIM" }, /* 48 */
|
|
||||||
{16UL, b32+ 60, b32+ 61, P_BE, 0, b32+ 76, "CRC-16/DDS-110" }, /* 49 */
|
|
||||||
{16UL, b32+ 60, b32+126, P_LE, 0, b32+ 46, "MODBUS" }, /* 50 */
|
|
||||||
{16UL, b32+ 60, b32+126, P_LE, b32+126, b32+ 85, "CRC-16/USB" }, /* 51 */
|
|
||||||
{12UL, b32+ 62, 0, P_BE, 0, b32+114, "CRC-12/DECT" }, /* 52 */
|
|
||||||
{12UL, b32+ 62, 0, P_BELE, 0, b32+104, "CRC-12/3GPP" }, /* 53 */
|
|
||||||
{32UL, b32+ 63, 0, P_BE, 0, b32+ 35, "CRC-32Q" }, /* 54 */
|
|
||||||
{24UL, b32+ 64, b32+ 86, P_BE, 0, b32+ 28, "CRC-24" }, /* 55 */
|
|
||||||
{15UL, b32+ 67, 0, P_BE, 0, b32+ 12, "CRC-15" }, /* 56 */
|
|
||||||
{16UL, b32+ 68, 0, P_BE, 0, b32+ 99, "CRC-16/T10-DIF" }, /* 57 */
|
|
||||||
{10UL, b32+ 69, 0, P_BE, 0, b32+ 53, "CRC-10" }, /* 58 */
|
|
||||||
{ 8UL, b32+ 73, 0, P_LE, 0, b32+ 29, "CRC-8/WCDMA" }, /* 59 */
|
|
||||||
{ 8UL, b32+ 73, b32+123, P_BE, 0, b32+103, "CRC-8/CDMA2000" }, /* 60 */
|
|
||||||
{ 6UL, b32+ 74, b32+117, P_BE, 0, b32+ 38, "CRC-6/CDMA2000-A" }, /* 61 */
|
|
||||||
{ 7UL, b32+ 75, b32+120, P_LE, 0, b32+ 79, "CRC-7/ROHC" }, /* 62 */
|
|
||||||
{16UL, b32+ 77, 0, P_BE, 0, b32+ 14, "CRC-16/TELEDISK" }, /* 63 */
|
|
||||||
{ 5UL, b32+ 80, 0, P_LE, 0, b32+ 40, "CRC-5/ITU" }, /* 64 */
|
|
||||||
{32UL, b32+ 81, b32+128, P_LE, b32+128, b32+ 65, "CRC-32D" }, /* 65 */
|
|
||||||
{16UL, b32+ 95, b32+126, P_BE, 0, b32+ 47, "CRC-16/CDMA2000" }, /* 66 */
|
|
||||||
{15UL, b32+ 98, 0, P_BE, b32+ 3, b32+ 45, "CRC-15/MPT1327" }, /* 67 */
|
|
||||||
{ 8UL, b32+101, 0, P_BE, 0, b32+ 88, "CRC-8/DVB-S2" }, /* 68 */
|
|
||||||
{13UL, b32+108, 0, P_BE, 0, b32+ 31, "CRC-13/BBC" }, /* 69 */
|
|
||||||
{12UL, b32+112, b32+125, P_BE, 0, b32+100, "CRC-12/CDMA2000" }, /* 70 */
|
|
||||||
{10UL, b32+115, b32+124, P_BE, 0, b32+ 69, "CRC-10/CDMA2000" }, /* 71 */
|
|
||||||
};
|
|
||||||
# define NPRESETS 72
|
|
||||||
|
|
||||||
/* List of names with pointers to models, pre-sorted for use with bsearch() */
|
|
||||||
static const struct malias aliases[] = {
|
|
||||||
{"ARC", models+47, 1}, /* 0 */
|
|
||||||
{"B-CRC-32", models+ 4, 0}, /* 1 */
|
|
||||||
{"CKSUM", models+ 2, 0}, /* 2 */
|
|
||||||
{"CRC-10", models+58, 1}, /* 3 */
|
|
||||||
{"CRC-10/CDMA2000", models+71, 1}, /* 4 */
|
|
||||||
{"CRC-11", models+45, 1}, /* 5 */
|
|
||||||
{"CRC-12/3GPP", models+53, 1}, /* 6 */
|
|
||||||
{"CRC-12/CDMA2000", models+70, 1}, /* 7 */
|
|
||||||
{"CRC-12/DECT", models+52, 1}, /* 8 */
|
|
||||||
{"CRC-13/BBC", models+69, 1}, /* 9 */
|
|
||||||
{"CRC-14/DARC", models+30, 1}, /* 10 */
|
|
||||||
{"CRC-15", models+56, 1}, /* 11 */
|
|
||||||
{"CRC-15/MPT1327", models+67, 1}, /* 12 */
|
|
||||||
{"CRC-16", models+47, 0}, /* 13 */
|
|
||||||
{"CRC-16/ACORN", models+15, 0}, /* 14 */
|
|
||||||
{"CRC-16/ARC", models+47, 0}, /* 15 */
|
|
||||||
{"CRC-16/AUG-CCITT", models+17, 1}, /* 16 */
|
|
||||||
{"CRC-16/BUYPASS", models+46, 1}, /* 17 */
|
|
||||||
{"CRC-16/CCITT", models+16, 0}, /* 18 */
|
|
||||||
{"CRC-16/CCITT-FALSE", models+21, 1}, /* 19 */
|
|
||||||
{"CRC-16/CCITT-TRUE", models+16, 0}, /* 20 */
|
|
||||||
{"CRC-16/CDMA2000", models+66, 1}, /* 21 */
|
|
||||||
{"CRC-16/DARC", models+22, 0}, /* 22 */
|
|
||||||
{"CRC-16/DDS-110", models+49, 1}, /* 23 */
|
|
||||||
{"CRC-16/DECT-R", models+ 8, 1}, /* 24 */
|
|
||||||
{"CRC-16/DECT-X", models+ 7, 1}, /* 25 */
|
|
||||||
{"CRC-16/DNP", models+36, 1}, /* 26 */
|
|
||||||
{"CRC-16/EN-13757", models+35, 1}, /* 27 */
|
|
||||||
{"CRC-16/EPC", models+22, 0}, /* 28 */
|
|
||||||
{"CRC-16/GENIBUS", models+22, 1}, /* 29 */
|
|
||||||
{"CRC-16/I-CODE", models+22, 0}, /* 30 */
|
|
||||||
{"CRC-16/IBM-SDLC", models+24, 0}, /* 31 */
|
|
||||||
{"CRC-16/ISO-HDLC", models+24, 0}, /* 32 */
|
|
||||||
{"CRC-16/LHA", models+47, 0}, /* 33 */
|
|
||||||
{"CRC-16/MAXIM", models+48, 1}, /* 34 */
|
|
||||||
{"CRC-16/MCRF4XX", models+23, 1}, /* 35 */
|
|
||||||
{"CRC-16/RIELLO", models+19, 1}, /* 36 */
|
|
||||||
{"CRC-16/SPI-FUJITSU", models+17, 0}, /* 37 */
|
|
||||||
{"CRC-16/T10-DIF", models+57, 1}, /* 38 */
|
|
||||||
{"CRC-16/TELEDISK", models+63, 1}, /* 39 */
|
|
||||||
{"CRC-16/TMS37157", models+18, 1}, /* 40 */
|
|
||||||
{"CRC-16/USB", models+51, 1}, /* 41 */
|
|
||||||
{"CRC-16/VERIFONE", models+46, 0}, /* 42 */
|
|
||||||
{"CRC-24", models+55, 1}, /* 43 */
|
|
||||||
{"CRC-24/FLEXRAY-A", models+42, 1}, /* 44 */
|
|
||||||
{"CRC-24/FLEXRAY-B", models+41, 1}, /* 45 */
|
|
||||||
{"CRC-24/OPENPGP", models+55, 0}, /* 46 */
|
|
||||||
{"CRC-3/ROHC", models+43, 1}, /* 47 */
|
|
||||||
{"CRC-31/PHILIPS", models+12, 1}, /* 48 */
|
|
||||||
{"CRC-32", models+ 6, 1}, /* 49 */
|
|
||||||
{"CRC-32/AAL5", models+ 4, 0}, /* 50 */
|
|
||||||
{"CRC-32/ADCCP", models+ 6, 0}, /* 51 */
|
|
||||||
{"CRC-32/BZIP2", models+ 4, 1}, /* 52 */
|
|
||||||
{"CRC-32/CASTAGNOLI", models+29, 0}, /* 53 */
|
|
||||||
{"CRC-32/DECT-B", models+ 4, 0}, /* 54 */
|
|
||||||
{"CRC-32/ISCSI", models+29, 0}, /* 55 */
|
|
||||||
{"CRC-32/MPEG-2", models+ 3, 1}, /* 56 */
|
|
||||||
{"CRC-32/POSIX", models+ 2, 1}, /* 57 */
|
|
||||||
{"CRC-32C", models+29, 1}, /* 58 */
|
|
||||||
{"CRC-32D", models+65, 1}, /* 59 */
|
|
||||||
{"CRC-32Q", models+54, 1}, /* 60 */
|
|
||||||
{"CRC-4/ITU", models+32, 1}, /* 61 */
|
|
||||||
{"CRC-40/GSM", models+ 1, 1}, /* 62 */
|
|
||||||
{"CRC-5/EPC", models+40, 1}, /* 63 */
|
|
||||||
{"CRC-5/ITU", models+64, 1}, /* 64 */
|
|
||||||
{"CRC-5/USB", models+31, 1}, /* 65 */
|
|
||||||
{"CRC-6/CDMA2000-A", models+61, 1}, /* 66 */
|
|
||||||
{"CRC-6/CDMA2000-B", models+26, 1}, /* 67 */
|
|
||||||
{"CRC-6/DARC", models+44, 1}, /* 68 */
|
|
||||||
{"CRC-6/ITU", models+13, 1}, /* 69 */
|
|
||||||
{"CRC-64", models+37, 1}, /* 70 */
|
|
||||||
{"CRC-64/WE", models+38, 1}, /* 71 */
|
|
||||||
{"CRC-64/XZ", models+39, 1}, /* 72 */
|
|
||||||
{"CRC-7", models+25, 1}, /* 73 */
|
|
||||||
{"CRC-7/ROHC", models+62, 1}, /* 74 */
|
|
||||||
{"CRC-8", models+ 9, 1}, /* 75 */
|
|
||||||
{"CRC-8/AES", models+28, 0}, /* 76 */
|
|
||||||
{"CRC-8/CDMA2000", models+60, 1}, /* 77 */
|
|
||||||
{"CRC-8/DARC", models+34, 1}, /* 78 */
|
|
||||||
{"CRC-8/DVB-S2", models+68, 1}, /* 79 */
|
|
||||||
{"CRC-8/EBU", models+28, 1}, /* 80 */
|
|
||||||
{"CRC-8/I-CODE", models+27, 1}, /* 81 */
|
|
||||||
{"CRC-8/ITU", models+10, 1}, /* 82 */
|
|
||||||
{"CRC-8/MAXIM", models+33, 1}, /* 83 */
|
|
||||||
{"CRC-8/ROHC", models+11, 1}, /* 84 */
|
|
||||||
{"CRC-8/WCDMA", models+59, 1}, /* 85 */
|
|
||||||
{"CRC-82/DARC", models+14, 1}, /* 86 */
|
|
||||||
{"CRC-A", models+20, 1}, /* 87 */
|
|
||||||
{"CRC-B", models+24, 0}, /* 88 */
|
|
||||||
{"CRC-CCITT", models+16, 0}, /* 89 */
|
|
||||||
{"CRC-IBM", models+47, 0}, /* 90 */
|
|
||||||
{"DOW-CRC", models+33, 0}, /* 91 */
|
|
||||||
{"JAMCRC", models+ 5, 1}, /* 92 */
|
|
||||||
{"KERMIT", models+16, 1}, /* 93 */
|
|
||||||
{"MODBUS", models+50, 1}, /* 94 */
|
|
||||||
{"PKZIP", models+ 6, 0}, /* 95 */
|
|
||||||
{"R-CRC-16", models+ 8, 0}, /* 96 */
|
|
||||||
{"X-25", models+24, 1}, /* 97 */
|
|
||||||
{"X-CRC-12", models+52, 0}, /* 98 */
|
|
||||||
{"X-CRC-16", models+ 7, 0}, /* 99 */
|
|
||||||
{"XFER", models+ 0, 1}, /* 100 */
|
|
||||||
{"XMODEM", models+15, 1}, /* 101 */
|
|
||||||
{"ZMODEM", models+15, 0}, /* 102 */
|
|
||||||
{NULL, NULL, 0}, /* terminating entry */
|
|
||||||
};
|
|
||||||
# define NALIASES 103
|
|
||||||
|
|
||||||
# endif /* BMP_BIT */
|
|
||||||
#else /* PRESETS */
|
|
||||||
|
|
||||||
static const struct mpreset models[] = {
|
|
||||||
{ 0UL, 0, 0, P_BE, 0, 0, NULL }, /* terminating entry */
|
|
||||||
};
|
|
||||||
# define NPRESETS 0
|
|
||||||
|
|
||||||
static const struct malias aliases[] = {
|
|
||||||
{NULL, NULL, 0}, /* terminating entry */
|
|
||||||
};
|
|
||||||
# define NALIASES 0
|
|
||||||
|
|
||||||
#endif /* PRESETS */
|
|
||||||
|
|
||||||
static const poly_t pzero = PZERO;
|
|
||||||
|
|
||||||
static int acmp(const struct malias *, const struct malias *);
|
|
||||||
static void munpack(model_t *, const struct mpreset *);
|
|
||||||
|
|
||||||
/* copy a parameter of a preset into a model */
|
|
||||||
#define MUNPACK(parm) \
|
|
||||||
praloc(&dest->parm, (src->b##parm ? src->width : 0UL)); \
|
|
||||||
for(iter=0UL, idx=0UL; iter < dest->parm.length; iter += BMP_BIT, ++idx)\
|
|
||||||
dest->parm.bitmap[idx] = src->b##parm[idx];
|
|
||||||
|
|
||||||
/* Definitions */
|
|
||||||
|
|
||||||
void
|
|
||||||
mcpy(model_t *dest, const model_t *src) {
|
|
||||||
/* Copies the parameters of src to dest.
|
|
||||||
* dest must be an initialised model.
|
|
||||||
*/
|
|
||||||
if(!dest || !src) return;
|
|
||||||
pcpy(&dest->spoly, src->spoly);
|
|
||||||
pcpy(&dest->init, src->init);
|
|
||||||
pcpy(&dest->xorout, src->xorout);
|
|
||||||
pcpy(&dest->check, src->check);
|
|
||||||
dest->flags = src->flags;
|
|
||||||
/* link to the name as it is static */
|
|
||||||
dest->name = src->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
mfree(model_t *model) {
|
|
||||||
/* Frees the parameters of model. */
|
|
||||||
if(!model) return;
|
|
||||||
pfree(&model->spoly);
|
|
||||||
pfree(&model->init);
|
|
||||||
pfree(&model->xorout);
|
|
||||||
pfree(&model->check);
|
|
||||||
/* not name as it is static */
|
|
||||||
/* not model either, it might point to an array! */
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
mcmp(const model_t *a, const model_t *b) {
|
|
||||||
/* Compares a and b for identical effect, i.e. disregarding
|
|
||||||
* trailing zeroes in parameter polys.
|
|
||||||
* Intended for bsearch() to find a matching model in models[].
|
|
||||||
*/
|
|
||||||
int result;
|
|
||||||
if(!a || !b) return(!b - !a);
|
|
||||||
if((result = psncmp(&a->spoly, &b->spoly))) return(result);
|
|
||||||
if((result = psncmp(&a->init, &b->init))) return(result);
|
|
||||||
if((a->flags & P_REFIN) && (~b->flags & P_REFIN)) return(1);
|
|
||||||
if((~a->flags & P_REFIN) && (b->flags & P_REFIN)) return(-1);
|
|
||||||
if((a->flags & P_REFOUT) && (~b->flags & P_REFOUT)) return(1);
|
|
||||||
if((~a->flags & P_REFOUT) && (b->flags & P_REFOUT)) return(-1);
|
|
||||||
return(psncmp(&a->xorout, &b->xorout));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
mbynam(model_t *dest, const char *key) {
|
|
||||||
/* Sets parameters in dest according to the model named by key.
|
|
||||||
*/
|
|
||||||
struct malias akey = {NULL, NULL, 0}, *aptr;
|
|
||||||
char *ukey, *uptr;
|
|
||||||
|
|
||||||
if(!aliases->name)
|
|
||||||
return(-1);
|
|
||||||
if(!(ukey = malloc((size_t) 1 + strlen(key))))
|
|
||||||
uerror("cannot allocate memory for comparison string");
|
|
||||||
akey.name = uptr = ukey;
|
|
||||||
do
|
|
||||||
*uptr++ = toupper((unsigned char)*key);
|
|
||||||
while(*key++);
|
|
||||||
|
|
||||||
aptr = bsearch(&akey, aliases, NALIASES, sizeof(struct malias), (int (*)(const void *, const void *)) &acmp);
|
|
||||||
free(ukey);
|
|
||||||
|
|
||||||
if(aptr == NULL)
|
|
||||||
return(0);
|
|
||||||
munpack(dest, aptr->model);
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
mbynum(model_t *dest, int num) {
|
|
||||||
/* Sets parameters in dest according to the model indexed by num. */
|
|
||||||
if(num > NPRESETS)
|
|
||||||
num = NPRESETS;
|
|
||||||
munpack(dest, models+num);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
mcount(void) {
|
|
||||||
/* Returns the number of preset models. */
|
|
||||||
return(NPRESETS);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
mnames(void) {
|
|
||||||
/* Returns a malloc()-ed string of the names of all preset
|
|
||||||
* models, separated by newlines and terminated by NULL.
|
|
||||||
* Aliases are not listed.
|
|
||||||
*/
|
|
||||||
size_t size = 0;
|
|
||||||
char *string, *sptr;
|
|
||||||
const struct malias *aptr = aliases;
|
|
||||||
|
|
||||||
while(aptr->name) {
|
|
||||||
if(aptr->isprimry)
|
|
||||||
size += strlen(aptr->name) + 1;
|
|
||||||
++aptr;
|
|
||||||
}
|
|
||||||
if(!size) return(NULL);
|
|
||||||
if((string = malloc(size))) {
|
|
||||||
aptr = aliases;
|
|
||||||
sptr = string;
|
|
||||||
while(aptr->name) {
|
|
||||||
if(aptr->isprimry) {
|
|
||||||
strcpy(sptr, aptr->name);
|
|
||||||
sptr += strlen(aptr->name);
|
|
||||||
*sptr++ = '\n';
|
|
||||||
}
|
|
||||||
++aptr;
|
|
||||||
}
|
|
||||||
*--sptr = '\0';
|
|
||||||
} else
|
|
||||||
uerror("cannot allocate memory for list of models");
|
|
||||||
|
|
||||||
return(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
mtostr(const model_t *model) {
|
|
||||||
/* Returns a malloc()-ed string containing a Williams model
|
|
||||||
* record representing the input model.
|
|
||||||
* mcanon() should be called on the argument before printing.
|
|
||||||
*/
|
|
||||||
size_t size;
|
|
||||||
char *polystr, *initstr, *xorotstr, *checkstr, strbuf[512], *string = NULL;
|
|
||||||
|
|
||||||
if(!model) return(NULL);
|
|
||||||
polystr = ptostr(model->spoly, P_RTJUST, 4);
|
|
||||||
initstr = ptostr(model->init, P_RTJUST, 4);
|
|
||||||
xorotstr = ptostr(model->xorout, P_RTJUST, 4);
|
|
||||||
checkstr = ptostr(model->check, P_RTJUST, 4);
|
|
||||||
|
|
||||||
sprintf(strbuf, "%lu", plen(model->spoly));
|
|
||||||
size =
|
|
||||||
70
|
|
||||||
+ (model->name && *model->name ? 2 + strlen(model->name) : 6)
|
|
||||||
+ strlen(strbuf)
|
|
||||||
+ (polystr && *polystr ? strlen(polystr) : 6)
|
|
||||||
+ (initstr && *initstr ? strlen(initstr) : 6)
|
|
||||||
+ (model->flags & P_REFIN ? 4 : 5)
|
|
||||||
+ (model->flags & P_REFOUT ? 4 : 5)
|
|
||||||
+ (xorotstr && *xorotstr ? strlen(xorotstr) : 6)
|
|
||||||
+ (checkstr && *checkstr ? strlen(checkstr) : 6);
|
|
||||||
if((string = malloc(size))) {
|
|
||||||
sprintf(strbuf, "\"%s\"", model->name);
|
|
||||||
sprintf(string,
|
|
||||||
"width=%lu "
|
|
||||||
"poly=0x%s "
|
|
||||||
"init=0x%s "
|
|
||||||
"refin=%s "
|
|
||||||
"refout=%s "
|
|
||||||
"xorout=0x%s "
|
|
||||||
"check=0x%s "
|
|
||||||
"name=%s",
|
|
||||||
plen(model->spoly),
|
|
||||||
polystr && *polystr ? polystr : "(none)",
|
|
||||||
initstr && *initstr ? initstr : "(none)",
|
|
||||||
(model->flags & P_REFIN) ? "true" : "false",
|
|
||||||
(model->flags & P_REFOUT) ? "true" : "false",
|
|
||||||
xorotstr && *xorotstr ? xorotstr : "(none)",
|
|
||||||
checkstr && *checkstr ? checkstr : "(none)",
|
|
||||||
(model->name && *model->name) ? strbuf : "(none)");
|
|
||||||
}
|
|
||||||
free(polystr);
|
|
||||||
free(initstr);
|
|
||||||
free(xorotstr);
|
|
||||||
free(checkstr);
|
|
||||||
if(!string)
|
|
||||||
uerror("cannot allocate memory for model description");
|
|
||||||
return(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
mmatch(model_t *model, int flags) {
|
|
||||||
/* searches models[] for a model matching the argument, and links a name if found
|
|
||||||
* if flags & M_OVERWR, copies the found model onto the argument. */
|
|
||||||
model_t *mptr;
|
|
||||||
if(!model) return;
|
|
||||||
|
|
||||||
mptr = bsearch(model, models, NPRESETS, sizeof(model_t), (int (*)(const void *, const void *)) &mcmp);
|
|
||||||
if(mptr) {
|
|
||||||
model->name = mptr->name;
|
|
||||||
if(flags & M_OVERWR)
|
|
||||||
mcpy(model, mptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
mcanon(model_t *model) {
|
|
||||||
/* canonicalise a model */
|
|
||||||
unsigned long dlen;
|
|
||||||
|
|
||||||
if(!model) return;
|
|
||||||
|
|
||||||
/* extending on the right here. This preserves the functionality
|
|
||||||
* of a presumed working model.
|
|
||||||
*/
|
|
||||||
psnorm(&model->spoly);
|
|
||||||
dlen = plen(model->spoly);
|
|
||||||
praloc(&model->init, dlen);
|
|
||||||
praloc(&model->xorout, dlen);
|
|
||||||
|
|
||||||
if(!plen(model->check))
|
|
||||||
mcheck(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
mcheck(model_t *model) {
|
|
||||||
/* calculate a check for the model */
|
|
||||||
poly_t checkstr, check;
|
|
||||||
|
|
||||||
/* generate the check string with the correct bit order */
|
|
||||||
checkstr = strtop("313233343536373839", model->flags, 8);
|
|
||||||
check = pcrc(checkstr, model->spoly, model->init, pzero, model->flags);
|
|
||||||
if(model->flags & P_REFOUT)
|
|
||||||
prev(&check);
|
|
||||||
psum(&check, model->xorout, 0UL);
|
|
||||||
model->check = check;
|
|
||||||
pfree(&checkstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
mrev(model_t *model) {
|
|
||||||
/* reverse the model to calculate reversed CRCs */
|
|
||||||
/* Here we invert RefIn and RefOut so that the user need only
|
|
||||||
* reverse the order of characters in the arguments, not the
|
|
||||||
* characters themselves. If RefOut=True, the mirror image of
|
|
||||||
* Init seen through RefOut becomes XorOut, and as RefOut
|
|
||||||
* becomes false, the XorOut value moved to Init stays upright.
|
|
||||||
* If RefOut=False, Init transfers to XorOut without reflection
|
|
||||||
* but the new Init must be reflected to present the same image,
|
|
||||||
* as RefOut becomes true.
|
|
||||||
*/
|
|
||||||
poly_t temp;
|
|
||||||
|
|
||||||
prcp(&model->spoly);
|
|
||||||
if(model->flags & P_REFOUT)
|
|
||||||
prev(&model->init);
|
|
||||||
else
|
|
||||||
prev(&model->xorout);
|
|
||||||
|
|
||||||
/* exchange init and xorout */
|
|
||||||
temp = model->init;
|
|
||||||
model->init = model->xorout;
|
|
||||||
model->xorout = temp;
|
|
||||||
|
|
||||||
/* invert refin and refout */
|
|
||||||
model->flags ^= P_REFIN | P_REFOUT;
|
|
||||||
|
|
||||||
mnovel(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
mnovel(model_t *model) {
|
|
||||||
/* remove name and check string from modified model */
|
|
||||||
model->name = NULL;
|
|
||||||
pfree(&model->check);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
acmp(const struct malias *a, const struct malias *b) {
|
|
||||||
/* compares two aliases, for use in bsearch */
|
|
||||||
if(!a || !b) return(!b - !a);
|
|
||||||
if(!a->name || !b->name) return(!b->name - !a->name);
|
|
||||||
return(strcmp(a->name, b->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
munpack(model_t *dest, const struct mpreset *src) {
|
|
||||||
/* Copies the parameters of src to dest.
|
|
||||||
* dest must be an initialised model.
|
|
||||||
*/
|
|
||||||
unsigned long iter, idx;
|
|
||||||
if(!dest || !src) return;
|
|
||||||
MUNPACK(spoly);
|
|
||||||
MUNPACK(init);
|
|
||||||
MUNPACK(xorout);
|
|
||||||
MUNPACK(check);
|
|
||||||
dest->flags = src->flags;
|
|
||||||
/* link to the name as it is static */
|
|
||||||
dest->name = src->name;
|
|
||||||
}
|
|
1196
client/reveng/poly.c
1196
client/reveng/poly.c
File diff suppressed because it is too large
Load diff
|
@ -1,489 +0,0 @@
|
||||||
/* reveng.c
|
|
||||||
* Greg Cook, 9/Apr/2015
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* CRC RevEng, an arbitrary-precision CRC calculator and algorithm finder
|
|
||||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Gregory Cook
|
|
||||||
*
|
|
||||||
* This file is part of CRC RevEng.
|
|
||||||
*
|
|
||||||
* CRC RevEng is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* CRC RevEng is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with CRC RevEng. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* 2013-09-16: calini(), calout() work on shortest argument
|
|
||||||
* 2013-06-11: added sequence number to uprog() calls
|
|
||||||
* 2013-02-08: added polynomial range search
|
|
||||||
* 2013-01-18: refactored model checking to pshres(); renamed chkres()
|
|
||||||
* 2012-05-24: efficiently build Init contribution string
|
|
||||||
* 2012-05-24: removed broken search for crossed-endian algorithms
|
|
||||||
* 2012-05-23: rewrote engini() after Ewing; removed modini()
|
|
||||||
* 2011-01-17: fixed ANSI C warnings
|
|
||||||
* 2011-01-08: fixed calini(), modini() caters for crossed-endian algos
|
|
||||||
* 2011-01-04: renamed functions, added calini(), factored pshres();
|
|
||||||
* rewrote engini() and implemented quick Init search
|
|
||||||
* 2011-01-01: reveng() initialises terminating entry, addparms()
|
|
||||||
* initialises all fields
|
|
||||||
* 2010-12-26: renamed CRC RevEng. right results, rejects polys faster
|
|
||||||
* 2010-12-24: completed, first tests (unsuccessful)
|
|
||||||
* 2010-12-21: completed modulate(), partial sketch of reveng()
|
|
||||||
* 2010-12-19: started reveng
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* reveng() can in theory be modified to search for polynomials shorter
|
|
||||||
* than the full width as well, but this imposes a heavy time burden on
|
|
||||||
* the full width search, which is the primary use case, as well as
|
|
||||||
* complicating the search range function introduced in version 1.1.0.
|
|
||||||
* It is more effective to search for each shorter width directly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define FILE void
|
|
||||||
#include "reveng.h"
|
|
||||||
|
|
||||||
static poly_t *modpol(const poly_t init, int rflags, int args, const poly_t *argpolys);
|
|
||||||
static void engini(int *resc, model_t **result, const poly_t divisor, int flags, int args, const poly_t *argpolys);
|
|
||||||
static void calout(int *resc, model_t **result, const poly_t divisor, const poly_t init, int flags, int args, const poly_t *argpolys);
|
|
||||||
static void calini(int *resc, model_t **result, const poly_t divisor, int flags, const poly_t xorout, int args, const poly_t *argpolys);
|
|
||||||
static void chkres(int *resc, model_t **result, const poly_t divisor, const poly_t init, int flags, const poly_t xorout, int args, const poly_t *argpolys);
|
|
||||||
|
|
||||||
static const poly_t pzero = PZERO;
|
|
||||||
|
|
||||||
model_t *
|
|
||||||
reveng(const model_t *guess, const poly_t qpoly, int rflags, int args, const poly_t *argpolys) {
|
|
||||||
/* Complete the parameters of a model by calculation or brute search. */
|
|
||||||
poly_t *pworks, *wptr, rem, gpoly;
|
|
||||||
model_t *result = NULL, *rptr;
|
|
||||||
int resc = 0;
|
|
||||||
unsigned long spin = 0, seq = 0;
|
|
||||||
|
|
||||||
if(~rflags & R_HAVEP) {
|
|
||||||
/* The poly is not known.
|
|
||||||
* Produce a list of differences between the arguments.
|
|
||||||
*/
|
|
||||||
pworks = modpol(guess->init, rflags, args, argpolys);
|
|
||||||
if(!pworks || !plen(*pworks)) {
|
|
||||||
free(pworks);
|
|
||||||
goto requit;
|
|
||||||
}
|
|
||||||
/* Initialise the guessed poly to the starting value. */
|
|
||||||
gpoly = pclone(guess->spoly);
|
|
||||||
/* Clear the least significant term, to be set in the
|
|
||||||
* loop. qpoly does not need fixing as it is only
|
|
||||||
* compared with odd polys.
|
|
||||||
*/
|
|
||||||
if(plen(gpoly))
|
|
||||||
pshift(&gpoly, gpoly, 0UL, 0UL, plen(gpoly) - 1UL, 1UL);
|
|
||||||
|
|
||||||
while(piter(&gpoly) && (~rflags & R_HAVEQ || pcmp(&gpoly, &qpoly) < 0)) {
|
|
||||||
/* For each possible poly of this size, try
|
|
||||||
* dividing all the differences in the list.
|
|
||||||
*/
|
|
||||||
if(!(spin++ & R_SPMASK)) {
|
|
||||||
uprog(gpoly, guess->flags, seq++);
|
|
||||||
}
|
|
||||||
for(wptr = pworks; plen(*wptr); ++wptr) {
|
|
||||||
/* straight divide message by poly, don't multiply by x^n */
|
|
||||||
rem = pcrc(*wptr, gpoly, pzero, pzero, 0);
|
|
||||||
if(ptst(rem)) {
|
|
||||||
pfree(&rem);
|
|
||||||
break;
|
|
||||||
} else
|
|
||||||
pfree(&rem);
|
|
||||||
}
|
|
||||||
/* If gpoly divides all the differences, it is a
|
|
||||||
* candidate. Search for an Init value for this
|
|
||||||
* poly or if Init is known, log the result.
|
|
||||||
*/
|
|
||||||
if(!plen(*wptr)) {
|
|
||||||
/* gpoly is a candidate poly */
|
|
||||||
if(rflags & R_HAVEI && rflags & R_HAVEX)
|
|
||||||
chkres(&resc, &result, gpoly, guess->init, guess->flags, guess->xorout, args, argpolys);
|
|
||||||
else if(rflags & R_HAVEI)
|
|
||||||
calout(&resc, &result, gpoly, guess->init, guess->flags, args, argpolys);
|
|
||||||
else if(rflags & R_HAVEX)
|
|
||||||
calini(&resc, &result, gpoly, guess->flags, guess->xorout, args, argpolys);
|
|
||||||
else
|
|
||||||
engini(&resc, &result, gpoly, guess->flags, args, argpolys);
|
|
||||||
}
|
|
||||||
if(!piter(&gpoly))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Finished with gpoly and the differences list, free them.
|
|
||||||
*/
|
|
||||||
pfree(&gpoly);
|
|
||||||
for(wptr = pworks; plen(*wptr); ++wptr)
|
|
||||||
pfree(wptr);
|
|
||||||
free(pworks);
|
|
||||||
}
|
|
||||||
else if(rflags & R_HAVEI && rflags & R_HAVEX)
|
|
||||||
/* All parameters are known! Submit the result if we get here */
|
|
||||||
chkres(&resc, &result, guess->spoly, guess->init, guess->flags, guess->xorout, args, argpolys);
|
|
||||||
else if(rflags & R_HAVEI)
|
|
||||||
/* Poly and Init are known, calculate XorOut */
|
|
||||||
calout(&resc, &result, guess->spoly, guess->init, guess->flags, args, argpolys);
|
|
||||||
else if(rflags & R_HAVEX)
|
|
||||||
/* Poly and XorOut are known, calculate Init */
|
|
||||||
calini(&resc, &result, guess->spoly, guess->flags, guess->xorout, args, argpolys);
|
|
||||||
else
|
|
||||||
/* Poly is known but not Init; search for Init. */
|
|
||||||
engini(&resc, &result, guess->spoly, guess->flags, args, argpolys);
|
|
||||||
|
|
||||||
requit:
|
|
||||||
if(!(result = realloc(result, ++resc * sizeof(model_t))))
|
|
||||||
uerror("cannot reallocate result array");
|
|
||||||
rptr = result + resc - 1;
|
|
||||||
rptr->spoly = pzero;
|
|
||||||
rptr->init = pzero;
|
|
||||||
rptr->flags = 0;
|
|
||||||
rptr->xorout = pzero;
|
|
||||||
rptr->check = pzero;
|
|
||||||
rptr->name = NULL;
|
|
||||||
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static poly_t *
|
|
||||||
modpol(const poly_t init, int rflags, int args, const poly_t *argpolys) {
|
|
||||||
/* Produce, in ascending length order, a list of differences
|
|
||||||
* between the arguments in the list by summing pairs of arguments.
|
|
||||||
* If R_HAVEI is not set in rflags, only pairs of equal length are
|
|
||||||
* summed.
|
|
||||||
* Otherwise, sums of right-aligned pairs are also returned, with
|
|
||||||
* the supplied init poly added to the leftmost terms of each
|
|
||||||
* poly of the pair.
|
|
||||||
*/
|
|
||||||
poly_t work, swap, *result, *rptr, *iptr;
|
|
||||||
const poly_t *aptr, *bptr, *eptr = argpolys + args;
|
|
||||||
unsigned long alen, blen;
|
|
||||||
|
|
||||||
if(args < 2) return(NULL);
|
|
||||||
|
|
||||||
if(!(result = malloc(((((args - 1) * args) >> 1) + 1) * sizeof(poly_t))))
|
|
||||||
uerror("cannot allocate memory for codeword table");
|
|
||||||
|
|
||||||
rptr = result;
|
|
||||||
|
|
||||||
for(aptr = argpolys; aptr < eptr; ++aptr) {
|
|
||||||
alen = plen(*aptr);
|
|
||||||
for(bptr = aptr + 1; bptr < eptr; ++bptr) {
|
|
||||||
blen = plen(*bptr);
|
|
||||||
if(alen == blen) {
|
|
||||||
work = pclone(*aptr);
|
|
||||||
psum(&work, *bptr, 0UL);
|
|
||||||
} else if(rflags & R_HAVEI && alen < blen) {
|
|
||||||
work = pclone(*bptr);
|
|
||||||
psum(&work, *aptr, blen - alen);
|
|
||||||
psum(&work, init, 0UL);
|
|
||||||
psum(&work, init, blen - alen);
|
|
||||||
} else if(rflags & R_HAVEI /* && alen > blen */) {
|
|
||||||
work = pclone(*aptr);
|
|
||||||
psum(&work, *bptr, alen - blen);
|
|
||||||
psum(&work, init, 0UL);
|
|
||||||
psum(&work, init, alen - blen);
|
|
||||||
} else
|
|
||||||
work = pzero;
|
|
||||||
|
|
||||||
if(plen(work))
|
|
||||||
pnorm(&work);
|
|
||||||
if((blen = plen(work))) {
|
|
||||||
/* insert work into result[] in ascending order of length */
|
|
||||||
for(iptr = result; iptr < rptr; ++iptr) {
|
|
||||||
if(plen(work) < plen(*iptr)) {
|
|
||||||
swap = *iptr;
|
|
||||||
*iptr = work;
|
|
||||||
work = swap;
|
|
||||||
}
|
|
||||||
else if(plen(*iptr) == blen && !pcmp(&work, iptr)) {
|
|
||||||
pfree(&work);
|
|
||||||
work = *--rptr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*rptr++ = work;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*rptr = pzero;
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
engini(int *resc, model_t **result, const poly_t divisor, int flags, int args, const poly_t *argpolys) {
|
|
||||||
/* Search for init values implied by the arguments.
|
|
||||||
* Method from: Ewing, Gregory C. (March 2010).
|
|
||||||
* "Reverse-Engineering a CRC Algorithm". Christchurch:
|
|
||||||
* University of Canterbury.
|
|
||||||
* <http://www.cosc.canterbury.ac.nz/greg.ewing/essays/
|
|
||||||
* CRC-Reverse-Engineering.html>
|
|
||||||
*/
|
|
||||||
poly_t apoly = PZERO, bpoly, pone = PZERO, *mat, *jptr;
|
|
||||||
const poly_t *aptr, *bptr, *iptr;
|
|
||||||
unsigned long alen, blen, dlen, ilen, i, j;
|
|
||||||
int cy;
|
|
||||||
|
|
||||||
dlen = plen(divisor);
|
|
||||||
|
|
||||||
/* Allocate the CRC matrix */
|
|
||||||
if(!(mat = (poly_t *) malloc((dlen << 1) * sizeof(poly_t))))
|
|
||||||
uerror("cannot allocate memory for CRC matrix");
|
|
||||||
|
|
||||||
/* Find arguments of the two shortest lengths */
|
|
||||||
alen = blen = plen(*(aptr = bptr = iptr = argpolys));
|
|
||||||
for(++iptr; iptr < argpolys + args; ++iptr) {
|
|
||||||
ilen = plen(*iptr);
|
|
||||||
if(ilen < alen) {
|
|
||||||
bptr = aptr; blen = alen;
|
|
||||||
aptr = iptr; alen = ilen;
|
|
||||||
} else if(ilen > alen && (aptr == bptr || ilen < blen)) {
|
|
||||||
bptr = iptr; blen = ilen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(aptr == bptr) {
|
|
||||||
/* if no arguments are suitable, calculate Init with an
|
|
||||||
* assumed XorOut of 0. Create a padded XorOut
|
|
||||||
*/
|
|
||||||
palloc(&apoly, dlen);
|
|
||||||
calini(resc, result, divisor, flags, apoly, args, argpolys);
|
|
||||||
pfree(&apoly);
|
|
||||||
free(mat);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the potential contribution of the bottom bit of Init */
|
|
||||||
palloc(&pone, 1UL);
|
|
||||||
piter(&pone);
|
|
||||||
if(blen < (dlen << 1)) {
|
|
||||||
palloc(&apoly, dlen); /* >= 1 */
|
|
||||||
psum(&apoly, pone, (dlen << 1) - 1UL - blen); /* >= 0 */
|
|
||||||
psum(&apoly, pone, (dlen << 1) - 1UL - alen); /* >= 1 */
|
|
||||||
} else {
|
|
||||||
palloc(&apoly, blen - dlen + 1UL); /* > dlen */
|
|
||||||
psum(&apoly, pone, 0UL);
|
|
||||||
psum(&apoly, pone, blen - alen); /* >= 1 */
|
|
||||||
}
|
|
||||||
if(plen(apoly) > dlen) {
|
|
||||||
mat[dlen] = pcrc(apoly, divisor, pzero, pzero, 0);
|
|
||||||
pfree(&apoly);
|
|
||||||
} else {
|
|
||||||
mat[dlen] = apoly;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the actual contribution of Init */
|
|
||||||
apoly = pcrc(*aptr, divisor, pzero, pzero, 0);
|
|
||||||
bpoly = pcrc(*bptr, divisor, pzero, apoly, 0);
|
|
||||||
|
|
||||||
/* Populate the matrix */
|
|
||||||
palloc(&apoly, 1UL);
|
|
||||||
for(jptr=mat; jptr<mat+dlen; ++jptr)
|
|
||||||
*jptr = pzero;
|
|
||||||
for(iptr = jptr++; jptr < mat + (dlen << 1); iptr = jptr++)
|
|
||||||
*jptr = pcrc(apoly, divisor, *iptr, pzero, P_MULXN);
|
|
||||||
pfree(&apoly);
|
|
||||||
|
|
||||||
/* Transpose the matrix, augment with the Init contribution
|
|
||||||
* and convert to row echelon form
|
|
||||||
*/
|
|
||||||
for(i=0UL; i<dlen; ++i) {
|
|
||||||
apoly = pzero;
|
|
||||||
iptr = mat + (dlen << 1);
|
|
||||||
for(j=0UL; j<dlen; ++j)
|
|
||||||
ppaste(&apoly, *--iptr, i, j, j + 1UL, dlen + 1UL);
|
|
||||||
if(ptst(apoly))
|
|
||||||
ppaste(&apoly, bpoly, i, dlen, dlen + 1UL, dlen + 1UL);
|
|
||||||
j = pfirst(apoly);
|
|
||||||
while(j < dlen && !pident(mat[j], pzero)) {
|
|
||||||
psum(&apoly, mat[j], 0UL); /* pfirst(apoly) > j */
|
|
||||||
j = pfirst(apoly);
|
|
||||||
}
|
|
||||||
if(j < dlen)
|
|
||||||
mat[j] = apoly; /* pident(mat[j], pzero) || pfirst(mat[j]) == j */
|
|
||||||
else
|
|
||||||
pfree(&apoly);
|
|
||||||
}
|
|
||||||
palloc(&bpoly, dlen + 1UL);
|
|
||||||
psum(&bpoly, pone, dlen);
|
|
||||||
|
|
||||||
/* Iterate through all solutions */
|
|
||||||
do {
|
|
||||||
/* Solve the matrix by Gaussian elimination.
|
|
||||||
* The parity of the result, masked by each row, should be even.
|
|
||||||
*/
|
|
||||||
cy = 1;
|
|
||||||
apoly = pclone(bpoly);
|
|
||||||
jptr = mat + dlen;
|
|
||||||
for(i=0UL; i<dlen; ++i) {
|
|
||||||
/* Compute next bit of Init */
|
|
||||||
if(pmpar(apoly, *--jptr))
|
|
||||||
psum(&apoly, pone, dlen - 1UL - i);
|
|
||||||
/* Toggle each zero row with carry, for next iteration */
|
|
||||||
if(cy) {
|
|
||||||
if(pident(*jptr, pzero)) {
|
|
||||||
/* 0 to 1, no carry */
|
|
||||||
*jptr = bpoly;
|
|
||||||
cy = 0;
|
|
||||||
} else if(pident(*jptr, bpoly)) {
|
|
||||||
/* 1 to 0, carry forward */
|
|
||||||
*jptr = pzero;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Trim the augment mask bit */
|
|
||||||
praloc(&apoly, dlen);
|
|
||||||
|
|
||||||
/* Test the Init value and add to results if correct */
|
|
||||||
calout(resc, result, divisor, apoly, flags, args, argpolys);
|
|
||||||
pfree(&apoly);
|
|
||||||
} while(!cy);
|
|
||||||
pfree(&pone);
|
|
||||||
pfree(&bpoly);
|
|
||||||
|
|
||||||
/* Free the matrix. */
|
|
||||||
for(jptr=mat; jptr < mat + (dlen << 1); ++jptr)
|
|
||||||
pfree(jptr);
|
|
||||||
free(mat);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
calout(int *resc, model_t **result, const poly_t divisor, const poly_t init, int flags, int args, const poly_t *argpolys) {
|
|
||||||
/* Calculate Xorout, check it against all the arguments and
|
|
||||||
* add to results if consistent.
|
|
||||||
*/
|
|
||||||
poly_t xorout;
|
|
||||||
const poly_t *aptr, *iptr;
|
|
||||||
unsigned long alen, ilen;
|
|
||||||
|
|
||||||
if(args < 1) return;
|
|
||||||
|
|
||||||
/* find argument of the shortest length */
|
|
||||||
alen = plen(*(aptr = iptr = argpolys));
|
|
||||||
for(++iptr; iptr < argpolys + args; ++iptr) {
|
|
||||||
ilen = plen(*iptr);
|
|
||||||
if(ilen < alen) {
|
|
||||||
aptr = iptr; alen = ilen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xorout = pcrc(*aptr, divisor, init, pzero, 0);
|
|
||||||
/* On little-endian algorithms, the calculations yield
|
|
||||||
* the reverse of the actual xorout: in the Williams
|
|
||||||
* model, the refout stage intervenes between init and
|
|
||||||
* xorout.
|
|
||||||
*/
|
|
||||||
if(flags & P_REFOUT)
|
|
||||||
prev(&xorout);
|
|
||||||
|
|
||||||
/* Submit the model to the results table.
|
|
||||||
* Could skip the shortest argument but we wish to check our
|
|
||||||
* calculation.
|
|
||||||
*/
|
|
||||||
chkres(resc, result, divisor, init, flags, xorout, args, argpolys);
|
|
||||||
pfree(&xorout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
calini(int *resc, model_t **result, const poly_t divisor, int flags, const poly_t xorout, int args, const poly_t *argpolys) {
|
|
||||||
/* Calculate Init, check it against all the arguments and add to
|
|
||||||
* results if consistent.
|
|
||||||
*/
|
|
||||||
poly_t rcpdiv, rxor, arg, init;
|
|
||||||
const poly_t *aptr, *iptr;
|
|
||||||
unsigned long alen, ilen;
|
|
||||||
|
|
||||||
if(args < 1) return;
|
|
||||||
|
|
||||||
/* find argument of the shortest length */
|
|
||||||
alen = plen(*(aptr = iptr = argpolys));
|
|
||||||
for(++iptr; iptr < argpolys + args; ++iptr) {
|
|
||||||
ilen = plen(*iptr);
|
|
||||||
if(ilen < alen) {
|
|
||||||
aptr = iptr; alen = ilen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rcpdiv = pclone(divisor);
|
|
||||||
prcp(&rcpdiv);
|
|
||||||
/* If the algorithm is reflected, an ordinary CRC requires the
|
|
||||||
* model's XorOut to be reversed, as XorOut follows the RefOut
|
|
||||||
* stage. To reverse the CRC calculation we need rxor to be the
|
|
||||||
* mirror image of the forward XorOut.
|
|
||||||
*/
|
|
||||||
rxor = pclone(xorout);
|
|
||||||
if(~flags & P_REFOUT)
|
|
||||||
prev(&rxor);
|
|
||||||
arg = pclone(*aptr);
|
|
||||||
prev(&arg);
|
|
||||||
|
|
||||||
init = pcrc(arg, rcpdiv, rxor, pzero, 0);
|
|
||||||
pfree(&arg);
|
|
||||||
pfree(&rxor);
|
|
||||||
pfree(&rcpdiv);
|
|
||||||
prev(&init);
|
|
||||||
|
|
||||||
/* Submit the model to the results table.
|
|
||||||
* Could skip the shortest argument but we wish to check our
|
|
||||||
* calculation.
|
|
||||||
*/
|
|
||||||
chkres(resc, result, divisor, init, flags, xorout, args, argpolys);
|
|
||||||
pfree(&init);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
chkres(int *resc, model_t **result, const poly_t divisor, const poly_t init, int flags, const poly_t xorout, int args, const poly_t *argpolys) {
|
|
||||||
/* Checks a model against the argument list, and adds to the
|
|
||||||
* external results table if consistent.
|
|
||||||
* Extends the result array and update the external pointer if
|
|
||||||
* necessary.
|
|
||||||
*/
|
|
||||||
model_t *rptr;
|
|
||||||
poly_t xor, crc;
|
|
||||||
const poly_t *aptr = argpolys, *const eptr = argpolys + args;
|
|
||||||
|
|
||||||
/* If the algorithm is reflected, an ordinary CRC requires the
|
|
||||||
* model's XorOut to be reversed, as XorOut follows the RefOut
|
|
||||||
* stage.
|
|
||||||
*/
|
|
||||||
xor = pclone(xorout);
|
|
||||||
if(flags & P_REFOUT)
|
|
||||||
prev(&xor);
|
|
||||||
|
|
||||||
for(; aptr < eptr; ++aptr) {
|
|
||||||
crc = pcrc(*aptr, divisor, init, xor, 0);
|
|
||||||
if(ptst(crc)) {
|
|
||||||
pfree(&crc);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
pfree(&crc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pfree(&xor);
|
|
||||||
if(aptr != eptr) return;
|
|
||||||
|
|
||||||
if(!(*result = realloc(*result, ++*resc * sizeof(model_t))))
|
|
||||||
uerror("cannot reallocate result array");
|
|
||||||
|
|
||||||
rptr = *result + *resc - 1;
|
|
||||||
rptr->spoly = pclone(divisor);
|
|
||||||
rptr->init = pclone(init);
|
|
||||||
rptr->flags = flags;
|
|
||||||
rptr->xorout = pclone(xorout);
|
|
||||||
rptr->name = NULL;
|
|
||||||
|
|
||||||
/* compute check value for this model */
|
|
||||||
mcheck(rptr);
|
|
||||||
|
|
||||||
/* callback to notify new model */
|
|
||||||
ufound(rptr);
|
|
||||||
}
|
|
|
@ -1,214 +0,0 @@
|
||||||
/* reveng.h
|
|
||||||
* Greg Cook, 9/Apr/2015
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* CRC RevEng, an arbitrary-precision CRC calculator and algorithm finder
|
|
||||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Gregory Cook
|
|
||||||
*
|
|
||||||
* This file is part of CRC RevEng.
|
|
||||||
*
|
|
||||||
* CRC RevEng is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* CRC RevEng is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with CRC RevEng. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef REVENG_H
|
|
||||||
#define REVENG_H 1
|
|
||||||
|
|
||||||
/* Configuration options */
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#ifndef BMP_T
|
|
||||||
# error config.h: BMP_T must be defined as unsigned long or a longer unsigned type
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BMP_C
|
|
||||||
# error config.h: BMP_C() must define a BMP_T constant
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined PRESETS && !defined BMPMACRO
|
|
||||||
# undef BMP_BIT
|
|
||||||
# undef BMP_SUB
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef BMP_POF2
|
|
||||||
|
|
||||||
#ifdef BMP_BIT
|
|
||||||
# ifndef BMP_SUB
|
|
||||||
# error config.h: BMP_SUB must be defined as the highest power of two that is strictly less than BMP_BIT
|
|
||||||
# elif BMP_BIT < 32
|
|
||||||
# error config.h: BMP_BIT must be at least 32
|
|
||||||
# elif BMP_SUB < 16
|
|
||||||
# error config.h: BMP_SUB must be at least 16
|
|
||||||
# elif (BMP_SUB >= BMP_BIT || BMP_SUB << 1 < BMP_BIT || BMP_SUB & (BMP_SUB - 1))
|
|
||||||
# error config.h: BMP_SUB must be defined as the highest power of two that is strictly less than BMP_BIT
|
|
||||||
# else /* BMP_SUB */
|
|
||||||
# define SETBMP()
|
|
||||||
# endif /* BMP_SUB */
|
|
||||||
# if BMP_BIT == 32
|
|
||||||
# define BMP_POF2 5
|
|
||||||
# elif BMP_BIT == 64
|
|
||||||
# define BMP_POF2 6
|
|
||||||
# elif BMP_BIT == 128
|
|
||||||
# define BMP_POF2 7
|
|
||||||
# elif BMP_BIT == 256
|
|
||||||
# define BMP_POF2 8
|
|
||||||
# elif BMP_BIT == 512
|
|
||||||
# define BMP_POF2 9
|
|
||||||
# elif BMP_BIT == 1024
|
|
||||||
# define BMP_POF2 10
|
|
||||||
# elif BMP_BIT == 2048
|
|
||||||
# define BMP_POF2 11
|
|
||||||
# elif BMP_BIT == 4096
|
|
||||||
# define BMP_POF2 12
|
|
||||||
# elif BMP_BIT == 8192
|
|
||||||
# define BMP_POF2 13
|
|
||||||
# elif BMP_BIT == 16384
|
|
||||||
# define BMP_POF2 14
|
|
||||||
# elif BMP_BIT == 32768
|
|
||||||
# define BMP_POF2 15
|
|
||||||
# elif BMP_BIT == 65536
|
|
||||||
# define BMP_POF2 16
|
|
||||||
/* may extend list as required */
|
|
||||||
# elif (BMP_BIT & (BMP_BIT - 1)) == 0
|
|
||||||
# define BMP_POF2 1
|
|
||||||
# endif
|
|
||||||
#else /* BMP_BIT */
|
|
||||||
# define BMP_BIT bmpbit
|
|
||||||
# define BMP_SUB bmpsub
|
|
||||||
# define SETBMP() setbmp()
|
|
||||||
#endif /* BMP_BIT */
|
|
||||||
|
|
||||||
/* Global definitions */
|
|
||||||
|
|
||||||
/* CRC RevEng version string */
|
|
||||||
#define VERSION "1.3.0"
|
|
||||||
|
|
||||||
/* bmpbit.c */
|
|
||||||
typedef BMP_T bmp_t;
|
|
||||||
|
|
||||||
extern int bmpbit, bmpsub;
|
|
||||||
extern void setbmp(void);
|
|
||||||
|
|
||||||
/* poly.c */
|
|
||||||
#define P_REFIN 1
|
|
||||||
#define P_REFOUT 2
|
|
||||||
#define P_MULXN 4
|
|
||||||
#define P_RTJUST 8
|
|
||||||
#define P_UPPER 16
|
|
||||||
#define P_SPACE 32
|
|
||||||
#define P_LTLBYT 64
|
|
||||||
#define P_DIRECT 128
|
|
||||||
|
|
||||||
/* default flags */
|
|
||||||
#define P_BE (P_RTJUST | P_MULXN)
|
|
||||||
#define P_LE (P_REFIN | P_REFOUT | P_MULXN)
|
|
||||||
#define P_BELE (P_REFOUT | P_MULXN)
|
|
||||||
#define P_LEBE (P_REFIN | P_RTJUST | P_MULXN)
|
|
||||||
|
|
||||||
/* A poly_t constant representing the polynomial 0. */
|
|
||||||
#define PZERO {0UL, (bmp_t *) 0}
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned long length; /* number of significant bits */
|
|
||||||
bmp_t *bitmap; /* bitmap, MSB first, */
|
|
||||||
/* left-justified in each word */
|
|
||||||
} poly_t;
|
|
||||||
|
|
||||||
extern poly_t filtop(FILE *input, unsigned long length, int flags, int bperhx);
|
|
||||||
extern poly_t strtop(const char *string, int flags, int bperhx);
|
|
||||||
extern char *ptostr(const poly_t poly, int flags, int bperhx);
|
|
||||||
extern char *pxsubs(const poly_t poly, int flags, int bperhx, unsigned long start, unsigned long end);
|
|
||||||
extern poly_t pclone(const poly_t poly);
|
|
||||||
extern void pcpy(poly_t *dest, const poly_t src);
|
|
||||||
extern void pcanon(poly_t *poly);
|
|
||||||
extern void pnorm(poly_t *poly);
|
|
||||||
extern void psnorm(poly_t *poly);
|
|
||||||
extern void pchop(poly_t *poly);
|
|
||||||
extern void pkchop(poly_t *poly);
|
|
||||||
extern unsigned long plen(const poly_t poly);
|
|
||||||
extern int pcmp(const poly_t *a, const poly_t *b);
|
|
||||||
extern int psncmp(const poly_t *a, const poly_t *b);
|
|
||||||
extern int ptst(const poly_t poly);
|
|
||||||
extern unsigned long pfirst(const poly_t poly);
|
|
||||||
extern unsigned long plast(const poly_t poly);
|
|
||||||
extern poly_t psubs(const poly_t src, unsigned long head, unsigned long start, unsigned long end, unsigned long tail);
|
|
||||||
extern void pright(poly_t *poly, unsigned long length);
|
|
||||||
extern void pshift(poly_t *dest, const poly_t src, unsigned long head, unsigned long start, unsigned long end, unsigned long tail);
|
|
||||||
extern void ppaste(poly_t *dest, const poly_t src, unsigned long skip, unsigned long seek, unsigned long end, unsigned long fulllength);
|
|
||||||
extern void pdiff(poly_t *dest, const poly_t src, unsigned long ofs);
|
|
||||||
extern void psum(poly_t *dest, const poly_t src, unsigned long ofs);
|
|
||||||
extern void prev(poly_t *poly);
|
|
||||||
extern void prevch(poly_t *poly, int bperhx);
|
|
||||||
extern void prcp(poly_t *poly);
|
|
||||||
extern void pinv(poly_t *poly);
|
|
||||||
extern poly_t pmod(const poly_t dividend, const poly_t divisor);
|
|
||||||
extern poly_t pcrc(const poly_t message, const poly_t divisor, const poly_t init, const poly_t xorout, int flags);
|
|
||||||
extern int piter(poly_t *poly);
|
|
||||||
extern void palloc(poly_t *poly, unsigned long length);
|
|
||||||
extern void pfree(poly_t *poly);
|
|
||||||
extern void praloc(poly_t *poly, unsigned long length);
|
|
||||||
extern int pmpar(const poly_t poly, const poly_t mask);
|
|
||||||
extern int pident(const poly_t a, const poly_t b);
|
|
||||||
|
|
||||||
/* model.c */
|
|
||||||
#define M_OVERWR 256
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
poly_t spoly; /* polynomial with highest-order term removed. length determines CRC width */
|
|
||||||
poly_t init; /* initial register value. length == poly.length */
|
|
||||||
int flags; /* P_REFIN and P_REFOUT indicate reflected input/output */
|
|
||||||
poly_t xorout; /* final register XOR mask. length == poly.length */
|
|
||||||
poly_t check; /* optional check value, the CRC of the UTF-8 string "123456789" */
|
|
||||||
const char *name; /* optional canonical name of the model */
|
|
||||||
} model_t;
|
|
||||||
|
|
||||||
extern void mcpy(model_t *dest, const model_t *src);
|
|
||||||
extern void mfree(model_t *model);
|
|
||||||
extern int mcmp(const model_t *a, const model_t *b);
|
|
||||||
extern int mbynam(model_t *dest, const char *key);
|
|
||||||
extern void mbynum(model_t *dest, int num);
|
|
||||||
extern int mcount(void);
|
|
||||||
extern char *mnames(void);
|
|
||||||
extern char *mtostr(const model_t *model);
|
|
||||||
extern void mmatch(model_t *model, int flags);
|
|
||||||
extern void mcanon(model_t *model);
|
|
||||||
extern void mcheck(model_t *model);
|
|
||||||
extern void mrev(model_t *model);
|
|
||||||
extern void mnovel(model_t *model);
|
|
||||||
|
|
||||||
/* reveng.c */
|
|
||||||
#define R_HAVEP 512
|
|
||||||
#define R_HAVEI 1024
|
|
||||||
#define R_HAVERI 2048
|
|
||||||
#define R_HAVERO 4096
|
|
||||||
#define R_HAVEX 8192
|
|
||||||
#define R_HAVEQ 16384
|
|
||||||
|
|
||||||
#define R_SPMASK 0x7FFFFFFUL
|
|
||||||
|
|
||||||
extern model_t *reveng(const model_t *guess, const poly_t qpoly, int rflags, int args, const poly_t *argpolys);
|
|
||||||
|
|
||||||
/* cli.c */
|
|
||||||
#define C_INFILE 1
|
|
||||||
#define C_FORCE 2
|
|
||||||
#define C_RESULT 4
|
|
||||||
|
|
||||||
#define BUFFER 32768
|
|
||||||
|
|
||||||
extern int reveng_main(int argc, char *argv[]);
|
|
||||||
extern void ufound(const model_t *model);
|
|
||||||
extern void uerror(const char *msg);
|
|
||||||
extern void uprog(const poly_t gpoly, int flags, unsigned long seq);
|
|
||||||
|
|
||||||
#endif /* REVENG_H */
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "../common/crc64.h"
|
#include "../common/crc64.h"
|
||||||
#include "../common/polarssl/sha1.h"
|
#include "../common/polarssl/sha1.h"
|
||||||
#include "../common/polarssl/aes.h"
|
#include "../common/polarssl/aes.h"
|
||||||
#include "cmdcrc.h"
|
|
||||||
/**
|
/**
|
||||||
* The following params expected:
|
* The following params expected:
|
||||||
* UsbCommand c
|
* UsbCommand c
|
||||||
|
@ -391,62 +391,6 @@ static int l_sha1(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_reveng_models(lua_State *L){
|
|
||||||
|
|
||||||
char *models[80];
|
|
||||||
int count = 0;
|
|
||||||
int in_width = luaL_checkinteger(L, 1);
|
|
||||||
|
|
||||||
if( in_width > 89 ) return returnToLuaWithError(L,"Width cannot exceed 89, got %d", in_width);
|
|
||||||
|
|
||||||
uint8_t width[80];
|
|
||||||
width[0] = (uint8_t)in_width;
|
|
||||||
int ans = GetModels(models, &count, width);
|
|
||||||
if (!ans) return 0;
|
|
||||||
|
|
||||||
lua_newtable(L);
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++){
|
|
||||||
lua_pushstring(L, (const char*)models[i]);
|
|
||||||
lua_rawseti(L,-2,i+1);
|
|
||||||
free(models[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Called with 4 parameters.
|
|
||||||
// inModel ,string containing the crc model name: 'CRC-8'
|
|
||||||
// inHexStr ,string containing the hex representation of the data that will be used for CRC calculations.
|
|
||||||
// reverse ,int 0/1 (bool) if 1, calculate the reverse CRC
|
|
||||||
// endian ,char, 'B','b','L','l','t','r' describing if Big-Endian or Little-Endian should be used in different combinations.
|
|
||||||
//
|
|
||||||
// outputs: string with hex representation of the CRC result
|
|
||||||
static int l_reveng_RunModel(lua_State *L){
|
|
||||||
//-c || -v
|
|
||||||
//inModel = valid model name string - CRC-8
|
|
||||||
//inHexStr = input hex string to calculate crc on
|
|
||||||
//reverse = reverse calc option if true
|
|
||||||
//endian = {0 = calc default endian input and output, b = big endian input and output, B = big endian output, r = right justified
|
|
||||||
// l = little endian input and output, L = little endian output only, t = left justified}
|
|
||||||
//result = calculated crc hex string
|
|
||||||
char result[50];
|
|
||||||
|
|
||||||
const char *inModel = luaL_checkstring(L, 1);
|
|
||||||
const char *inHexStr = luaL_checkstring(L, 2);
|
|
||||||
bool reverse = lua_toboolean(L, 3);
|
|
||||||
const char endian = luaL_checkstring(L, 4)[0];
|
|
||||||
|
|
||||||
//PrintAndLog("mod: %s, hex: %s, rev %d", inModel, inHexStr, reverse);
|
|
||||||
//int RunModel(char *inModel, char *inHexStr, bool reverse, char endian, char *result)
|
|
||||||
int ans = RunModel( (char *)inModel, (char *)inHexStr, reverse, endian, result);
|
|
||||||
if (!ans)
|
|
||||||
return returnToLuaWithError(L,"Reveng failed");
|
|
||||||
|
|
||||||
lua_pushstring(L, (const char*)result);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
|
* @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
|
||||||
* able to do "require('foobar')" if foobar.lua is within lualibs folder.
|
* able to do "require('foobar')" if foobar.lua is within lualibs folder.
|
||||||
|
@ -493,8 +437,6 @@ int set_pm3_libraries(lua_State *L)
|
||||||
{"crc16", l_crc16},
|
{"crc16", l_crc16},
|
||||||
{"crc64", l_crc64},
|
{"crc64", l_crc64},
|
||||||
{"sha1", l_sha1},
|
{"sha1", l_sha1},
|
||||||
{"reveng_models", l_reveng_models},
|
|
||||||
{"reveng_runmodel", l_reveng_RunModel},
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
local getopt = require('getopt')
|
|
||||||
local utils = require('utils')
|
|
||||||
|
|
||||||
example = "script calculates many different checksums (CRC) over the provided hex input"
|
|
||||||
author = "Iceman"
|
|
||||||
desc =
|
|
||||||
[[
|
|
||||||
This script calculates many checksums (CRC) over the provided hex input.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
-b data in hex
|
|
||||||
-w bitwidth of the CRC family of algorithm. <optional> defaults to all known CRC presets.
|
|
||||||
Examples :
|
|
||||||
script run e -b 010203040506070809
|
|
||||||
script run e -b 010203040506070809 -w 16
|
|
||||||
]]
|
|
||||||
|
|
||||||
---
|
|
||||||
-- A debug printout-function
|
|
||||||
function dbg(args)
|
|
||||||
if DEBUG then
|
|
||||||
print("###", args)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
---
|
|
||||||
-- This is only meant to be used when errors occur
|
|
||||||
function oops(err)
|
|
||||||
print("ERROR: ",err)
|
|
||||||
return nil,err
|
|
||||||
end
|
|
||||||
---
|
|
||||||
-- Usage help
|
|
||||||
function help()
|
|
||||||
print(desc)
|
|
||||||
print("Example usage")
|
|
||||||
print(example)
|
|
||||||
end
|
|
||||||
---
|
|
||||||
-- The main entry point
|
|
||||||
function main(args)
|
|
||||||
|
|
||||||
local data
|
|
||||||
local width = 0
|
|
||||||
|
|
||||||
-- Read the parameters
|
|
||||||
for o, a in getopt.getopt(args, 'hb:w:') do
|
|
||||||
if o == "h" then return help() end
|
|
||||||
if o == "b" then data = a end
|
|
||||||
if o == "w" then width = a end
|
|
||||||
end
|
|
||||||
|
|
||||||
data = data or '01020304'
|
|
||||||
|
|
||||||
print( string.rep('-',60) )
|
|
||||||
print('Bit width of CRC | '..width)
|
|
||||||
print('Bytes | '..data)
|
|
||||||
print('')
|
|
||||||
print( ('%-20s| %-16s| %s'):format('Model','CRC', 'CRC reverse'))
|
|
||||||
print( string.rep('-',60) )
|
|
||||||
local lists = core.reveng_models(width)
|
|
||||||
for _,i in pairs(lists) do
|
|
||||||
local a1 = core.reveng_runmodel(i, data, false, '0')
|
|
||||||
local a2 = core.reveng_runmodel(i, data, true, '0')
|
|
||||||
local a3 = core.reveng_runmodel(i, data, false, 'b')
|
|
||||||
local a4 = core.reveng_runmodel(i, data, false, 'B')
|
|
||||||
local a5 = core.reveng_runmodel(i, data, false, 'l')
|
|
||||||
local a6 = core.reveng_runmodel(i, data, false, 'L')
|
|
||||||
print( ('%-20s| %-16s| %-16s| %-16s| %-16s| %-16s| %-16s'):format(i, a1:upper(), a2:upper(),a3:upper(),a4:upper(),a5:upper(),a6:upper() ) )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
main(args)
|
|
Loading…
Add table
Add a link
Reference in a new issue