]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdcrc.c
f93ab99d178eab9d0f61e470aed0ad094293e71d
   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         //unsigned long width = 0UL; 
  97         //int c, mode = 0, args, psets, pass; 
  98         poly_t apoly
, crc
, qpoly 
= PZERO
, *apolys 
= NULL
, *pptr 
= NULL
, *qptr 
= NULL
; 
  99         model_t pset 
= model
, *candmods
, *mptr
; 
 104         /* stdin must be binary */ 
 106                 _setmode(STDIN_FILENO
, _O_BINARY
); 
 114         int args 
= 0, psets
, pass
; 
 116         if (*width 
== 0) { //reveng -D 
 118                 //PrintAndLog("Count: %d",*count); 
 120                         return uerr("no preset models available"); 
 122                 for(int mode 
= 0; mode 
< *count
; ++mode
) { 
 123                         mbynum(&model
, mode
); 
 125                         size_t size 
= (model
.name 
&& *model
.name
) ? strlen(model
.name
) : 6; 
 126                         //PrintAndLog("Size: %d, %s",size,model.name); 
 127                         char *tmp 
= calloc(size
+1, sizeof(char)); 
 129                                 return uerr("out of memory?"); 
 131                         memcpy(tmp
, model
.name
, size
); 
 137                         if(~model
.flags 
& P_MULXN
) 
 138                                 return uerr("cannot search for non-Williams compliant models"); 
 140                         praloc(&model
.spoly
, *width
); 
 141                         praloc(&model
.init
, *width
); 
 142                         praloc(&model
.xorout
, *width
); 
 143                         if(!plen(model
.spoly
)) 
 144                                 palloc(&model
.spoly
, *width
); 
 146                                 *width 
= plen(model
.spoly
); 
 148                         /* special case if qpoly is zero, search to end of range */ 
 153                         /* not going to be sending additional args 
 155                         // allocate argument array  
 156                         args = argc - optind; 
 157                         if(!(apolys = malloc(args * sizeof(poly_t)))) 
 158                                 return uerr("cannot allocate memory for argument list"); 
 160                         for(pptr = apolys; optind < argc; ++optind) { 
 161                                 if(uflags & C_INFILE) 
 162                                         *pptr++ = rdpoly(argv[optind], model.flags, ibperhx); 
 164                                         *pptr++ = strtop(argv[optind], model.flags, ibperhx); 
 166                         // exit value of pptr is used hereafter!  
 170                         /* if endianness not specified, try 
 171                          * little-endian then big-endian. 
 172                          * NB: crossed-endian algorithms will not be 
 175                         /* scan against preset models */ 
 176                         if(~uflags 
& C_FORCE
) { 
 181                                         //PrintAndLog("psets: %d",psets); 
 183                                                 mbynum(&pset
, --psets
); 
 185                                                 /* skip if different width, or refin or refout don't match */ 
 186                                                 if(plen(pset
.spoly
) != *width 
|| (model
.flags 
^ pset
.flags
) & (P_REFIN 
| P_REFOUT
)) 
 188                                                 /* skip if the preset doesn't match specified parameters */ 
 189                                                 if(rflags 
& R_HAVEP 
&& pcmp(&model
.spoly
, &pset
.spoly
)) 
 191                                                 if(rflags 
& R_HAVEI 
&& psncmp(&model
.init
, &pset
.init
)) 
 193                                                 if(rflags 
& R_HAVEX 
&& psncmp(&model
.xorout
, &pset
.xorout
)) 
 196                                                 apoly 
= pclone(pset
.xorout
); 
 197                                                 if(pset
.flags 
& P_REFOUT
) 
 199                                                 for(qptr 
= apolys
; qptr 
< pptr
; ++qptr
) { 
 200                                                         crc 
= pcrc(*qptr
, pset
.spoly
, pset
.init
, apoly
, 0); 
 209                                                         /* the selected model solved all arguments */ 
 212                                                         size_t size 
= (pset
.name 
&& *pset
.name
) ? strlen(pset
.name
) : 6; 
 213                                                         //PrintAndLog("Size: %d, %s, count: %d",size,pset.name, Cnt); 
 214                                                         char *tmp 
= calloc(size
+1, sizeof(char)); 
 216                                                                 PrintAndLog("out of memory?"); 
 219                                                         memcpy(tmp
, pset
.name
, size
); 
 228                                         /* toggle refIn/refOut and reflect arguments */ 
 229                                         if(~rflags 
& R_HAVERI
) { 
 230                                                 model
.flags 
^= P_REFIN 
| P_REFOUT
; 
 231                                                 for(qptr 
= apolys
; qptr 
< pptr
; ++qptr
) 
 232                                                         prevch(qptr
, ibperhx
); 
 234                                 } while(~rflags 
& R_HAVERI 
&& ++pass 
< 2); 
 236                         if(uflags 
& C_RESULT
) { 
 237                                 for(qptr 
= apolys
; qptr 
< pptr
; ++qptr
) 
 240                                 //exit(EXIT_SUCCESS); 
 242                         if(!(model
.flags 
& P_REFIN
) != !(model
.flags 
& P_REFOUT
)) 
 243                                 return uerr("cannot search for crossed-endian models"); 
 246                                 mptr 
= candmods 
= reveng(&model
, qpoly
, rflags
, args
, apolys
); 
 247                                 if(mptr 
&& plen(mptr
->spoly
)) 
 249                                 while(mptr 
&& plen(mptr
->spoly
)) { 
 250                                         /* results were printed by the callback 
 251                                          * string = mtostr(mptr); 
 258                                 if(~rflags 
& R_HAVERI
) { 
 259                                         model
.flags 
^= P_REFIN 
| P_REFOUT
; 
 260                                         for(qptr 
= apolys
; qptr 
< pptr
; ++qptr
) 
 261                                                 prevch(qptr
, ibperhx
); 
 263                         } while(~rflags 
& R_HAVERI 
&& ++pass 
< 2); 
 264                         for(qptr 
= apolys
; qptr 
< pptr
; ++qptr
) 
 267                         if(~uflags 
& C_RESULT
) 
 268                                 return uerr("no models found"); 
 272         //PrintAndLog("DONE"); 
 276 //test call to GetModels 
 277 int CmdrevengTest(const char *Cmd
){ 
 281         width 
= param_get8(Cmd
, 0); 
 282         //PrintAndLog("width: %d",width); 
 284                 return uerr("Width cannot exceed 89"); 
 286         int ans 
= GetModels(Models
, &count
, &width
); 
 289         PrintAndLog("Count: %d",count
); 
 290         for (int i 
= 0; i 
< count
; i
++){ 
 291                 PrintAndLog("Model %d: %s",i
,Models
[i
]); 
 298 int RunModel(char *inModel
, char *inHexStr
, bool reverse
, char *result
){ 
 300         static model_t model 
= { 
 301                 PZERO
,          // no CRC polynomial, user must specify 
 303                 P_BE
,             // RefIn = false, RefOut = false, plus P_RTJUST setting in reveng.h 
 305                 PZERO
,          // check value unused  
 306                 NULL              
// no model name  
 308         int ibperhx 
= 8, obperhx 
= 8; 
 309         int rflags 
= 0; // search flags  
 311         unsigned long width 
= 0UL; 
 316         // stdin must be binary 
 318                 _setmode(STDIN_FILENO
, _O_BINARY
); 
 323         if(!(c 
= mbynam(&model
, inModel
))) { 
 324                 fprintf(stderr
,"error: preset model '%s' not found.  Use reveng -D to list presets.\n", inModel
); 
 328                 return uerr("no preset models available"); 
 330         // must set width so that parameter to -ipx is not zeroed  
 331         width 
= plen(model
.spoly
); 
 332         rflags 
|= R_HAVEP 
| R_HAVEI 
| R_HAVERI 
| R_HAVERO 
| R_HAVEX
; 
 337                 // v  calculate reversed CRC 
 338                 /* Distinct from the -V switch as this causes 
 339                  * the arguments and output to be reversed as well. 
 345                  *   if(refout) prev(init); else prev(xorout); 
 346                  * but here the entire argument polynomial is 
 347                  * reflected, not just the characters, so RefIn 
 348                  * and RefOut are not inverted as with -V. 
 349                  * Consequently Init is the mirror image of the 
 350                  * one resulting from -V, and so we have: 
 352                 if(~model
.flags 
& P_REFOUT
) { 
 357                 // swap init and xorout 
 359                 model
.init 
= model
.xorout
; 
 360                 model
.xorout 
= apoly
; 
 365         /* if(plen(model.spoly) == 0) { 
 366          *      fprintf(stderr,"%s: no polynomial specified for -%c (add -w WIDTH -p POLY)\n", myname, mode); 
 367          *      exit(EXIT_FAILURE); 
 371         /* in the Williams model, xorout is applied after the refout stage. 
 372          * as refout is part of ptostr(), we reverse xorout here. 
 374         if(model
.flags 
& P_REFOUT
) 
 377         apoly 
= strtop(inHexStr
, model
.flags
, ibperhx
); 
 382         crc 
= pcrc(apoly
, model
.spoly
, model
.init
, model
.xorout
, model
.flags
); 
 387         string 
= ptostr(crc
, model
.flags
, obperhx
); 
 388         for (int i 
= 0; i 
< 50; i
++){ 
 389                 result
[i
] = string
[i
]; 
 390                 if (result
[i
]==0) break; 
 398 //test call to RunModel 
 399 int CmdrevengTestC(const char *Cmd
){ 
 401         char inModel
[30] = {0x00}; 
 402         char inHexStr
[30] = {0x00}; 
 406         dataLen 
= param_getstr(Cmd
, cmdp
++, inModel
); 
 407         if (dataLen 
< 4) return 0; 
 408         dataLen 
= param_getstr(Cmd
, cmdp
++, inHexStr
); 
 409         if (dataLen 
< 4) return 0; 
 410         bool reverse 
= (param_get8(Cmd
, cmdp
)) ? true : false; 
 412         //PrintAndLog("mod: %s, hex: %s, rev %d", inModel, inHexStr, reverse); 
 413         int ans 
= RunModel(inModel
, inHexStr
, reverse
, result
); 
 416         PrintAndLog("Result: %s",result
);