]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdcrc.c
3e68afb947ce470c01289d86e32014f002cd9877
   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 //inModel = valid model name string - CRC-8 
 299 //inHexStr = input hex string to calculate crc on 
 300 //reverse = reverse calc option if true 
 301 //endian = {0 = calc default endian input and output, b = big endian input and output, B = big endian output, r = right justified 
 302 //          l = little endian input and output, L = little endian output only, t = left justified} 
 303 //result = calculated crc hex string 
 304 int RunModel(char *inModel
, char *inHexStr
, bool reverse
, char endian
, char *result
){ 
 306         static model_t model 
= { 
 307                 PZERO
,          // no CRC polynomial, user must specify 
 309                 P_BE
,             // RefIn = false, RefOut = false, plus P_RTJUST setting in reveng.h 
 311                 PZERO
,          // check value unused  
 312                 NULL              
// no model name  
 314         int ibperhx 
= 8, obperhx 
= 8; 
 315         int rflags 
= 0; // search flags  
 317         unsigned long width 
= 0UL; 
 322         // stdin must be binary 
 324                 _setmode(STDIN_FILENO
, _O_BINARY
); 
 329         if(!(c 
= mbynam(&model
, inModel
))) { 
 330                 fprintf(stderr
,"error: preset model '%s' not found.  Use reveng -D to list presets.\n", inModel
); 
 334                 return uerr("no preset models available"); 
 336         // must set width so that parameter to -ipx is not zeroed  
 337         width 
= plen(model
.spoly
); 
 338         rflags 
|= R_HAVEP 
| R_HAVEI 
| R_HAVERI 
| R_HAVERO 
| R_HAVEX
; 
 342                 case 'b': /* b  big-endian (RefIn = false, RefOut = false ) */ 
 343                         model
.flags 
&= ~P_REFIN
; 
 346                 case 'B': /* B  big-endian output (RefOut = false) */ 
 347                         model
.flags 
&= ~P_REFOUT
; 
 351                 case 'r': /* r  right-justified */ 
 352                         model
.flags 
|= P_RTJUST
; 
 354                 case 'l': /* l  little-endian input and output */ 
 355                         model
.flags 
|= P_REFIN
; 
 358                 case 'L': /* L  little-endian output */ 
 359                         model
.flags 
|= P_REFOUT
; 
 363                 case 't': /* t  left-justified */ 
 364                         model
.flags 
&= ~P_RTJUST
; 
 371                 // v  calculate reversed CRC 
 372                 /* Distinct from the -V switch as this causes 
 373                  * the arguments and output to be reversed as well. 
 379                  *   if(refout) prev(init); else prev(xorout); 
 380                  * but here the entire argument polynomial is 
 381                  * reflected, not just the characters, so RefIn 
 382                  * and RefOut are not inverted as with -V. 
 383                  * Consequently Init is the mirror image of the 
 384                  * one resulting from -V, and so we have: 
 386                 if(~model
.flags 
& P_REFOUT
) { 
 391                 // swap init and xorout 
 393                 model
.init 
= model
.xorout
; 
 394                 model
.xorout 
= apoly
; 
 399         /* if(plen(model.spoly) == 0) { 
 400          *      fprintf(stderr,"%s: no polynomial specified for -%c (add -w WIDTH -p POLY)\n", myname, mode); 
 401          *      exit(EXIT_FAILURE); 
 405         /* in the Williams model, xorout is applied after the refout stage. 
 406          * as refout is part of ptostr(), we reverse xorout here. 
 408         if(model
.flags 
& P_REFOUT
) 
 411         apoly 
= strtop(inHexStr
, model
.flags
, ibperhx
); 
 416         crc 
= pcrc(apoly
, model
.spoly
, model
.init
, model
.xorout
, model
.flags
); 
 421         string 
= ptostr(crc
, model
.flags
, obperhx
); 
 422         for (int i 
= 0; i 
< 50; i
++){ 
 423                 result
[i
] = string
[i
]; 
 424                 if (result
[i
]==0) break; 
 432 //test call to RunModel 
 433 int CmdrevengTestC(const char *Cmd
){ 
 435         char inModel
[30] = {0x00}; 
 436         char inHexStr
[30] = {0x00}; 
 440         dataLen 
= param_getstr(Cmd
, cmdp
++, inModel
); 
 441         if (dataLen 
< 4) return 0; 
 442         dataLen 
= param_getstr(Cmd
, cmdp
++, inHexStr
); 
 443         if (dataLen 
< 4) return 0; 
 444         bool reverse 
= (param_get8(Cmd
, cmdp
++)) ? true : false; 
 445         endian 
= param_getchar(Cmd
, cmdp
++);  
 447         //PrintAndLog("mod: %s, hex: %s, rev %d", inModel, inHexStr, reverse); 
 448         int ans 
= RunModel(inModel
, inHexStr
, reverse
, endian
, result
); 
 451         PrintAndLog("Result: %s",result
);