]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdcrc.c
cd6f217118a20f73486d22dc07f9ea86d586fc34
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2015 iceman <iceman at iuse.se>
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
8 // CRC Calculations from the software reveng commands
9 //-----------------------------------------------------------------------------
16 # define STDIN_FILENO 0
17 # endif /* STDIN_FILENO */
26 #include "reveng/reveng.h"
33 PrintAndLog("%s",msg
);
37 int split(char *str
, char *arr
[MAX_ARGS
]){
40 int maxWords
= MAX_ARGS
;
44 while(isspace(str
[beginIndex
])){
47 if(str
[beginIndex
] == '\0')
49 endIndex
= beginIndex
;
50 while (str
[endIndex
] && !isspace(str
[endIndex
])){
53 int len
= endIndex
- beginIndex
;
54 char *tmp
= calloc(len
+ 1, sizeof(char));
55 memcpy(tmp
, &str
[beginIndex
], len
);
57 //PrintAndLog("cnt: %d, %s",wordCnt-1, arr[wordCnt-1]);
58 beginIndex
= endIndex
;
59 if (wordCnt
== maxWords
)
65 int CmdCrc(const char *Cmd
)
67 char name
[] = {"reveng "};
69 memcpy(Cmd2
, name
, 7);
70 memcpy(Cmd2
+ 7, Cmd
, 50);
72 int argc
= split(Cmd2
, argv
);
73 //PrintAndLog("argc: %d, %s %s Cmd: %s",argc, argv[0], Cmd2, Cmd);
74 reveng_main(argc
, argv
);
75 for(int i
= 0; i
< argc
; ++i
){
83 int GetModels(char *Models
[], int *count
, uint32_t *width
){
85 static model_t model
= {
86 PZERO
, /* no CRC polynomial, user must specify */
88 P_BE
, /* RefIn = false, RefOut = false, plus P_RTJUST setting in reveng.h */
89 PZERO
, /* XorOut = 0 */
90 PZERO
, /* check value unused */
91 NULL
/* no model name */
93 int ibperhx
= 8;//, obperhx = 8;
94 int rflags
= 0, uflags
= 0; /* search and UI flags */
96 poly_t apoly
, crc
, qpoly
= PZERO
, *apolys
= NULL
, *pptr
= NULL
, *qptr
= NULL
;
97 model_t pset
= model
, *candmods
, *mptr
;
99 /* stdin must be binary */
101 _setmode(STDIN_FILENO
, _O_BINARY
);
106 int args
= 0, psets
, pass
;
108 if (*width
== 0) { //reveng -D
112 return uerr("no preset models available");
114 for(int mode
= 0; mode
< *count
; ++mode
) {
115 mbynum(&model
, mode
);
117 size_t size
= (model
.name
&& *model
.name
) ? strlen(model
.name
) : 6;
119 char *tmp
= calloc(size
+1, sizeof(char));
121 return uerr("out of memory?");
123 memcpy(tmp
, model
.name
, size
);
128 if(~model
.flags
& P_MULXN
)
129 return uerr("cannot search for non-Williams compliant models");
131 praloc(&model
.spoly
, *width
);
132 praloc(&model
.init
, *width
);
133 praloc(&model
.xorout
, *width
);
134 if(!plen(model
.spoly
))
135 palloc(&model
.spoly
, *width
);
137 *width
= plen(model
.spoly
);
139 /* special case if qpoly is zero, search to end of range */
143 /* if endianness not specified, try
144 * little-endian then big-endian.
145 * NB: crossed-endian algorithms will not be
148 /* scan against preset models */
149 if(~uflags
& C_FORCE
) {
156 mbynum(&pset
, --psets
);
158 /* skip if different width, or refin or refout don't match */
159 if(plen(pset
.spoly
) != *width
|| (model
.flags
^ pset
.flags
) & (P_REFIN
| P_REFOUT
))
161 /* skip if the preset doesn't match specified parameters */
162 if(rflags
& R_HAVEP
&& pcmp(&model
.spoly
, &pset
.spoly
))
164 if(rflags
& R_HAVEI
&& psncmp(&model
.init
, &pset
.init
))
166 if(rflags
& R_HAVEX
&& psncmp(&model
.xorout
, &pset
.xorout
))
169 apoly
= pclone(pset
.xorout
);
170 if(pset
.flags
& P_REFOUT
)
172 for(qptr
= apolys
; qptr
< pptr
; ++qptr
) {
173 crc
= pcrc(*qptr
, pset
.spoly
, pset
.init
, apoly
, 0);
182 /* the selected model solved all arguments */
185 size_t size
= (pset
.name
&& *pset
.name
) ? strlen(pset
.name
) : 6;
186 //PrintAndLog("Size: %d, %s, count: %d",size,pset.name, Cnt);
187 char *tmp
= calloc(size
+1, sizeof(char));
190 PrintAndLog("out of memory?");
193 memcpy(tmp
, pset
.name
, size
);
201 /* toggle refIn/refOut and reflect arguments */
202 if(~rflags
& R_HAVERI
) {
203 model
.flags
^= P_REFIN
| P_REFOUT
;
204 for(qptr
= apolys
; qptr
< pptr
; ++qptr
)
205 prevch(qptr
, ibperhx
);
207 } while(~rflags
& R_HAVERI
&& ++pass
< 2);
209 if(uflags
& C_RESULT
) {
210 for(qptr
= apolys
; qptr
< pptr
; ++qptr
)
214 if(!(model
.flags
& P_REFIN
) != !(model
.flags
& P_REFOUT
))
215 return uerr("cannot search for crossed-endian models");
218 mptr
= candmods
= reveng(&model
, qpoly
, rflags
, args
, apolys
);
219 if(mptr
&& plen(mptr
->spoly
))
221 while(mptr
&& plen(mptr
->spoly
)) {
222 /* results were printed by the callback
223 * string = mtostr(mptr);
230 if(~rflags
& R_HAVERI
) {
231 model
.flags
^= P_REFIN
| P_REFOUT
;
232 for(qptr
= apolys
; qptr
< pptr
; ++qptr
)
233 prevch(qptr
, ibperhx
);
235 } while(~rflags
& R_HAVERI
&& ++pass
< 2);
236 for(qptr
= apolys
; qptr
< pptr
; ++qptr
)
239 if(~uflags
& C_RESULT
)
240 return uerr("no models found");
247 //test call to GetModels
248 int CmdrevengTest(const char *Cmd
){
252 width
= param_get8(Cmd
, 0);
253 //PrintAndLog("width: %d",width);
255 return uerr("Width cannot exceed 89");
257 int ans
= GetModels(Models
, &count
, &width
);
260 PrintAndLog("Count: %d",count
);
261 for (int i
= 0; i
< count
; i
++){
262 PrintAndLog("Model %d: %s",i
,Models
[i
]);
269 //inModel = valid model name string - CRC-8
270 //inHexStr = input hex string to calculate crc on
271 //reverse = reverse calc option if true
272 //endian = {0 = calc default endian input and output, b = big endian input and output, B = big endian output, r = right justified
273 // l = little endian input and output, L = little endian output only, t = left justified}
274 //result = calculated crc hex string
275 int RunModel(char *inModel
, char *inHexStr
, bool reverse
, char endian
, char *result
){
277 static model_t model
= {
278 PZERO
, // no CRC polynomial, user must specify
280 P_BE
, // RefIn = false, RefOut = false, plus P_RTJUST setting in reveng.h
282 PZERO
, // check value unused
283 NULL
// no model name
285 int ibperhx
= 8, obperhx
= 8;
286 int rflags
= 0; // search flags
288 unsigned long width
= 0UL;
293 // stdin must be binary
295 _setmode(STDIN_FILENO
, _O_BINARY
);
300 if(!(c
= mbynam(&model
, inModel
))) {
301 fprintf(stderr
,"error: preset model '%s' not found. Use reveng -D to list presets.\n", inModel
);
305 return uerr("no preset models available");
307 // must set width so that parameter to -ipx is not zeroed
308 width
= plen(model
.spoly
);
309 rflags
|= R_HAVEP
| R_HAVEI
| R_HAVERI
| R_HAVERO
| R_HAVEX
;
313 case 'b': /* b big-endian (RefIn = false, RefOut = false ) */
314 model
.flags
&= ~P_REFIN
;
317 case 'B': /* B big-endian output (RefOut = false) */
318 model
.flags
&= ~P_REFOUT
;
322 case 'r': /* r right-justified */
323 model
.flags
|= P_RTJUST
;
325 case 'l': /* l little-endian input and output */
326 model
.flags
|= P_REFIN
;
329 case 'L': /* L little-endian output */
330 model
.flags
|= P_REFOUT
;
334 case 't': /* t left-justified */
335 model
.flags
&= ~P_RTJUST
;
342 // v calculate reversed CRC
343 /* Distinct from the -V switch as this causes
344 * the arguments and output to be reversed as well.
350 * if(refout) prev(init); else prev(xorout);
351 * but here the entire argument polynomial is
352 * reflected, not just the characters, so RefIn
353 * and RefOut are not inverted as with -V.
354 * Consequently Init is the mirror image of the
355 * one resulting from -V, and so we have:
357 if(~model
.flags
& P_REFOUT
) {
362 // swap init and xorout
364 model
.init
= model
.xorout
;
365 model
.xorout
= apoly
;
369 /* in the Williams model, xorout is applied after the refout stage.
370 * as refout is part of ptostr(), we reverse xorout here.
372 if(model
.flags
& P_REFOUT
)
375 apoly
= strtop(inHexStr
, model
.flags
, ibperhx
);
380 crc
= pcrc(apoly
, model
.spoly
, model
.init
, model
.xorout
, model
.flags
);
385 string
= ptostr(crc
, model
.flags
, obperhx
);
386 for (int i
= 0; i
< 50; i
++){
387 result
[i
] = string
[i
];
388 if (result
[i
]==0) break;