]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdcrc.c
@marshmellows memory fix
[proxmark3-svn] / client / cmdcrc.c
CommitLineData
9962091e 1//-----------------------------------------------------------------------------
2// Copyright (C) 2015 iceman <iceman at iuse.se>
3//
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
6// the license.
7//-----------------------------------------------------------------------------
8// CRC Calculations from the software reveng commands
9//-----------------------------------------------------------------------------
10
60e86577 11#include <stdlib.h>
12#ifdef _WIN32
13# include <io.h>
14# include <fcntl.h>
15# ifndef STDIN_FILENO
16# define STDIN_FILENO 0
17# endif /* STDIN_FILENO */
18#endif /* _WIN32 */
19
9962091e 20#include <stdio.h>
21#include <string.h>
a71ece51 22//#include <stdlib.h>
23//#include <ctype.h>
24#include "cmdmain.h"
9962091e 25#include "cmdcrc.h"
a71ece51 26#include "reveng/reveng.h"
27#include "ui.h"
28#include "util.h"
9962091e 29
a71ece51 30#define MAX_ARGS 20
9962091e 31
60e86577 32int uerr(char *msg){
33 PrintAndLog("%s",msg);
34 return 0;
35}
36
a71ece51 37int split(char *str, char *arr[MAX_ARGS]){
38 int beginIndex = 0;
39 int endIndex;
40 int maxWords = MAX_ARGS;
41 int wordCnt = 0;
42
43 while(1){
44 while(isspace(str[beginIndex])){
45 ++beginIndex;
46 }
47 if(str[beginIndex] == '\0')
48 break;
49 endIndex = beginIndex;
50 while (str[endIndex] && !isspace(str[endIndex])){
51 ++endIndex;
52 }
53 int len = endIndex - beginIndex;
54 char *tmp = calloc(len + 1, sizeof(char));
55 memcpy(tmp, &str[beginIndex], len);
56 arr[wordCnt++] = tmp;
57 //PrintAndLog("cnt: %d, %s",wordCnt-1, arr[wordCnt-1]);
58 beginIndex = endIndex;
59 if (wordCnt == maxWords)
60 break;
61 }
62 return wordCnt;
63}
9962091e 64
65int CmdCrc(const char *Cmd)
66{
a71ece51 67 char name[] = {"reveng "};
68 char Cmd2[50 + 7];
69 memcpy(Cmd2, name, 7);
70 memcpy(Cmd2 + 7, Cmd, 50);
71 char *argv[MAX_ARGS];
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){
76 //puts(arr[i]);
77 free(argv[i]);
78 }
79
9962091e 80 return 0;
81}
82
60e86577 83int GetModels(char *Models[], int *count, uint32_t *width){
84 /* default values */
85 static model_t model = {
86 PZERO, /* no CRC polynomial, user must specify */
87 PZERO, /* Init = 0 */
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 */
92 };
93 int ibperhx = 8;//, obperhx = 8;
94 int rflags = 0, uflags = 0; /* search and UI flags */
95
96 poly_t apoly, crc, qpoly = PZERO, *apolys = NULL, *pptr = NULL, *qptr = NULL;
97 model_t pset = model, *candmods, *mptr;
98
99 /* stdin must be binary */
100 #ifdef _WIN32
101 _setmode(STDIN_FILENO, _O_BINARY);
102 #endif /* _WIN32 */
103
104 SETBMP();
105
106 int args = 0, psets, pass;
107 int Cnt = 0;
108 if (*width == 0) { //reveng -D
109 *count = mcount();
110
111 if(!*count)
112 return uerr("no preset models available");
113
114 for(int mode = 0; mode < *count; ++mode) {
115 mbynum(&model, mode);
116 mcanon(&model);
117 size_t size = (model.name && *model.name) ? strlen(model.name) : 6;
118
119 char *tmp = calloc(size+1, sizeof(char));
120 if (tmp==NULL)
121 return uerr("out of memory?");
122
123 memcpy(tmp, model.name, size);
124 Models[mode] = tmp;
125 }
126 } else { //reveng -s
127
128 if(~model.flags & P_MULXN)
129 return uerr("cannot search for non-Williams compliant models");
130
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);
136 else
137 *width = plen(model.spoly);
138
139 /* special case if qpoly is zero, search to end of range */
140 if(!ptst(qpoly))
141 rflags &= ~R_HAVEQ;
142
143 /* if endianness not specified, try
144 * little-endian then big-endian.
145 * NB: crossed-endian algorithms will not be
146 * searched.
147 */
148 /* scan against preset models */
149 if(~uflags & C_FORCE) {
150 pass = 0;
151 Cnt = 0;
152 do {
153 psets = mcount();
154
155 while(psets) {
156 mbynum(&pset, --psets);
157
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))
160 continue;
161 /* skip if the preset doesn't match specified parameters */
162 if(rflags & R_HAVEP && pcmp(&model.spoly, &pset.spoly))
163 continue;
164 if(rflags & R_HAVEI && psncmp(&model.init, &pset.init))
165 continue;
166 if(rflags & R_HAVEX && psncmp(&model.xorout, &pset.xorout))
167 continue;
168
169 apoly = pclone(pset.xorout);
170 if(pset.flags & P_REFOUT)
171 prev(&apoly);
172 for(qptr = apolys; qptr < pptr; ++qptr) {
173 crc = pcrc(*qptr, pset.spoly, pset.init, apoly, 0);
174 if(ptst(crc)) {
175 pfree(&crc);
176 break;
177 } else
178 pfree(&crc);
179 }
180 pfree(&apoly);
181 if(qptr == pptr) {
182 /* the selected model solved all arguments */
183 mcanon(&pset);
184
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));
188
189 if (tmp == NULL){
190 PrintAndLog("out of memory?");
191 return 0;
192 }
193 memcpy(tmp, pset.name, size);
194 Models[Cnt++] = tmp;
195 *count = Cnt;
196 uflags |= C_RESULT;
197 }
198 }
199 mfree(&pset);
200
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);
206 }
207 } while(~rflags & R_HAVERI && ++pass < 2);
208 }
209 if(uflags & C_RESULT) {
210 for(qptr = apolys; qptr < pptr; ++qptr)
211 pfree(qptr);
212 return 1;
213 }
214 if(!(model.flags & P_REFIN) != !(model.flags & P_REFOUT))
215 return uerr("cannot search for crossed-endian models");
216 pass = 0;
217 do {
218 mptr = candmods = reveng(&model, qpoly, rflags, args, apolys);
219 if(mptr && plen(mptr->spoly))
220 uflags |= C_RESULT;
221 while(mptr && plen(mptr->spoly)) {
222 /* results were printed by the callback
223 * string = mtostr(mptr);
224 * puts(string);
225 * free(string);
226 */
227 mfree(mptr++);
228 }
229 free(candmods);
230 if(~rflags & R_HAVERI) {
231 model.flags ^= P_REFIN | P_REFOUT;
232 for(qptr = apolys; qptr < pptr; ++qptr)
233 prevch(qptr, ibperhx);
234 }
235 } while(~rflags & R_HAVERI && ++pass < 2);
236 for(qptr = apolys; qptr < pptr; ++qptr)
237 pfree(qptr);
238 free(apolys);
239 if(~uflags & C_RESULT)
240 return uerr("no models found");
241
242
243 }
244 return 1;
245}
246
247//test call to GetModels
248int CmdrevengTest(const char *Cmd){
249 char *Models[80];
250 int count = 0;
251 uint32_t width = 0;
252 width = param_get8(Cmd, 0);
253 //PrintAndLog("width: %d",width);
254 if (width > 89)
255 return uerr("Width cannot exceed 89");
256
257 int ans = GetModels(Models, &count, &width);
258 if (!ans) return 0;
259
260 PrintAndLog("Count: %d",count);
261 for (int i = 0; i < count; i++){
262 PrintAndLog("Model %d: %s",i,Models[i]);
263 free(Models[i]);
264 }
265 return 1;
266}
267
268//-c || -v
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
275int RunModel(char *inModel, char *inHexStr, bool reverse, char endian, char *result){
276 /* default values */
277 static model_t model = {
278 PZERO, // no CRC polynomial, user must specify
279 PZERO, // Init = 0
280 P_BE, // RefIn = false, RefOut = false, plus P_RTJUST setting in reveng.h
281 PZERO, // XorOut = 0
282 PZERO, // check value unused
283 NULL // no model name
284 };
285 int ibperhx = 8, obperhx = 8;
286 int rflags = 0; // search flags
287 int c;
288 unsigned long width = 0UL;
289 poly_t apoly, crc;
290
291 char *string;
292
293 // stdin must be binary
294 #ifdef _WIN32
295 _setmode(STDIN_FILENO, _O_BINARY);
296 #endif /* _WIN32 */
297
298 SETBMP();
299 //set model
300 if(!(c = mbynam(&model, inModel))) {
301 fprintf(stderr,"error: preset model '%s' not found. Use reveng -D to list presets.\n", inModel);
302 return 0;
303 }
304 if(c < 0)
305 return uerr("no preset models available");
306
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;
310
311 //set flags
312 switch (endian) {
313 case 'b': /* b big-endian (RefIn = false, RefOut = false ) */
314 model.flags &= ~P_REFIN;
315 rflags |= R_HAVERI;
316 /* fall through: */
317 case 'B': /* B big-endian output (RefOut = false) */
318 model.flags &= ~P_REFOUT;
319 rflags |= R_HAVERO;
320 mnovel(&model);
321 /* fall through: */
322 case 'r': /* r right-justified */
323 model.flags |= P_RTJUST;
324 break;
325 case 'l': /* l little-endian input and output */
326 model.flags |= P_REFIN;
327 rflags |= R_HAVERI;
328 /* fall through: */
329 case 'L': /* L little-endian output */
330 model.flags |= P_REFOUT;
331 rflags |= R_HAVERO;
332 mnovel(&model);
333 /* fall through: */
334 case 't': /* t left-justified */
335 model.flags &= ~P_RTJUST;
336 break;
337 }
338
339 mcanon(&model);
340
341 if (reverse) {
342 // v calculate reversed CRC
343 /* Distinct from the -V switch as this causes
344 * the arguments and output to be reversed as well.
345 */
346 // reciprocate Poly
347 prcp(&model.spoly);
348
349 /* mrev() does:
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:
356 */
357 if(~model.flags & P_REFOUT) {
358 prev(&model.init);
359 prev(&model.xorout);
360 }
361
362 // swap init and xorout
363 apoly = model.init;
364 model.init = model.xorout;
365 model.xorout = apoly;
366 }
367 // c calculate CRC
368
369 /* in the Williams model, xorout is applied after the refout stage.
370 * as refout is part of ptostr(), we reverse xorout here.
371 */
372 if(model.flags & P_REFOUT)
373 prev(&model.xorout);
374
375 apoly = strtop(inHexStr, model.flags, ibperhx);
376
377 if(reverse)
378 prev(&apoly);
379
380 crc = pcrc(apoly, model.spoly, model.init, model.xorout, model.flags);
381
382 if(reverse)
383 prev(&crc);
384
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;
389 }
390 free(string);
391 pfree(&crc);
392 pfree(&apoly);
393 return 1;
394}
Impressum, Datenschutz