]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/reveng/model.c
2 * Greg Cook, 26/Jul/2016
5 /* CRC RevEng: arbitrary-precision CRC calculator and algorithm finder
6 * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016 Gregory Cook
8 * This file is part of CRC RevEng.
10 * CRC RevEng is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
15 * CRC RevEng is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with CRC RevEng. If not, see <https://www.gnu.org/licenses/>.
24 /* 2016-02-22: split off preset.c
25 * 2012-03-03: single-line Williams model string conversion
26 * 2011-09-03: added mrev(), mnovel()
27 * 2011-01-17: fixed ANSI C warnings (except preset models)
28 * 2010-12-26: renamed CRC RevEng
29 * 2010-12-18: minor change to mtostr() output format
30 * 2010-12-15: added mcmp()
31 * 2010-12-14: finished mtostr()
32 * 2010-12-12: started models.c
41 /* Private declarations */
43 static const poly_t pzero
= PZERO
;
48 mcpy(model_t
*dest
, const model_t
*src
) {
49 /* Copies the parameters of src to dest.
50 * dest must be an initialised model.
52 if(!dest
|| !src
) return;
53 pcpy(&dest
->spoly
, src
->spoly
);
54 pcpy(&dest
->init
, src
->init
);
55 pcpy(&dest
->xorout
, src
->xorout
);
56 pcpy(&dest
->check
, src
->check
);
57 dest
->flags
= src
->flags
;
58 /* link to the name as it is static */
59 dest
->name
= src
->name
;
63 mfree(model_t
*model
) {
64 /* Frees the parameters of model. */
68 pfree(&model
->xorout
);
70 /* not name as it is static */
71 /* not model either, it might point to an array! */
75 mcmp(const model_t
*a
, const model_t
*b
) {
76 /* Compares a and b for identical effect, i.e. disregarding
77 * trailing zeroes in parameter polys.
78 * Intended for bsearch().
81 if(!a
|| !b
) return(!b
- !a
);
82 if((result
= psncmp(&a
->spoly
, &b
->spoly
))) return(result
);
83 if((result
= psncmp(&a
->init
, &b
->init
))) return(result
);
84 if((a
->flags
& P_REFIN
) && (~b
->flags
& P_REFIN
)) return(1);
85 if((~a
->flags
& P_REFIN
) && (b
->flags
& P_REFIN
)) return(-1);
86 if((a
->flags
& P_REFOUT
) && (~b
->flags
& P_REFOUT
)) return(1);
87 if((~a
->flags
& P_REFOUT
) && (b
->flags
& P_REFOUT
)) return(-1);
88 return(psncmp(&a
->xorout
, &b
->xorout
));
92 mtostr(const model_t
*model
) {
93 /* Returns a malloc()-ed string containing a Williams model
94 * record representing the input model.
95 * mcanon() should be called on the argument before printing.
98 char *polystr
, *initstr
, *xorotstr
, *checkstr
, strbuf
[512], *string
= NULL
;
100 if(!model
) return(NULL
);
101 polystr
= ptostr(model
->spoly
, P_RTJUST
, 4);
102 initstr
= ptostr(model
->init
, P_RTJUST
, 4);
103 xorotstr
= ptostr(model
->xorout
, P_RTJUST
, 4);
104 checkstr
= ptostr(model
->check
, P_RTJUST
, 4);
106 sprintf(strbuf
, "%lu", plen(model
->spoly
));
109 + (model
->name
&& *model
->name
? 2 + strlen(model
->name
) : 6)
111 + (polystr
&& *polystr
? strlen(polystr
) : 6)
112 + (initstr
&& *initstr
? strlen(initstr
) : 6)
113 + (model
->flags
& P_REFIN
? 4 : 5)
114 + (model
->flags
& P_REFOUT
? 4 : 5)
115 + (xorotstr
&& *xorotstr
? strlen(xorotstr
) : 6)
116 + (checkstr
&& *checkstr
? strlen(checkstr
) : 6);
117 if((string
= malloc(size
))) {
118 sprintf(strbuf
, "\"%s\"", model
->name
);
129 polystr
&& *polystr
? polystr
: "(none)",
130 initstr
&& *initstr
? initstr
: "(none)",
131 (model
->flags
& P_REFIN
) ? "true" : "false",
132 (model
->flags
& P_REFOUT
) ? "true" : "false",
133 xorotstr
&& *xorotstr
? xorotstr
: "(none)",
134 checkstr
&& *checkstr
? checkstr
: "(none)",
135 (model
->name
&& *model
->name
) ? strbuf
: "(none)");
142 uerror("cannot allocate memory for model description");
147 mcanon(model_t
*model
) {
148 /* canonicalise a model */
153 /* extending on the right here. This preserves the functionality
154 * of a presumed working model.
156 psnorm(&model
->spoly
);
157 dlen
= plen(model
->spoly
);
158 praloc(&model
->init
, dlen
);
159 praloc(&model
->xorout
, dlen
);
161 /* only calculate Check if missing. Relying on all functions
162 * changing parameters to call mnovel(). This is to ensure that
163 * the Check value stored in the preset table is printed when
164 * the model is dumped. If something goes wrong with the
165 * calculator then the discrepancy with the stored Check value
166 * might be noticed. Storing the Check value with each preset
167 * is highly preferred.
169 if(!plen(model
->check
))
174 mcheck(model_t
*model
) {
175 /* calculate a check for the model */
176 poly_t checkstr
, check
;
178 /* generate the check string with the correct bit order */
179 checkstr
= strtop("313233343536373839", model
->flags
, 8);
180 check
= pcrc(checkstr
, model
->spoly
, model
->init
, pzero
, model
->flags
);
181 if(model
->flags
& P_REFOUT
)
183 psum(&check
, model
->xorout
, 0UL);
184 model
->check
= check
;
189 mrev(model_t
*model
) {
190 /* reverse the model to calculate reversed CRCs */
191 /* Here we invert RefIn and RefOut so that the user need only
192 * reverse the order of characters in the arguments, not the
193 * characters themselves. If RefOut=True, the mirror image of
194 * Init seen through RefOut becomes XorOut, and as RefOut
195 * becomes false, the XorOut value moved to Init stays upright.
196 * If RefOut=False, Init transfers to XorOut without reflection
197 * but the new Init must be reflected to present the same image,
198 * as RefOut becomes true.
203 if(model
->flags
& P_REFOUT
)
206 prev(&model
->xorout
);
208 /* exchange init and xorout */
210 model
->init
= model
->xorout
;
211 model
->xorout
= temp
;
213 /* invert refin and refout */
214 model
->flags
^= P_REFIN
| P_REFOUT
;
220 mnovel(model_t
*model
) {
221 /* remove name and check string from modified model */
223 pfree(&model
->check
);