]>
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
40 /* Private declarations */
42 static const poly_t pzero
= PZERO
;
47 mcpy(model_t
*dest
, const model_t
*src
) {
48 /* Copies the parameters of src to dest.
49 * dest must be an initialised model.
51 if(!dest
|| !src
) return;
52 pcpy(&dest
->spoly
, src
->spoly
);
53 pcpy(&dest
->init
, src
->init
);
54 pcpy(&dest
->xorout
, src
->xorout
);
55 pcpy(&dest
->check
, src
->check
);
56 dest
->flags
= src
->flags
;
57 /* link to the name as it is static */
58 dest
->name
= src
->name
;
62 mfree(model_t
*model
) {
63 /* Frees the parameters of model. */
67 pfree(&model
->xorout
);
69 /* not name as it is static */
70 /* not model either, it might point to an array! */
74 mcmp(const model_t
*a
, const model_t
*b
) {
75 /* Compares a and b for identical effect, i.e. disregarding
76 * trailing zeroes in parameter polys.
77 * Intended for bsearch().
80 if(!a
|| !b
) return(!b
- !a
);
81 if((result
= psncmp(&a
->spoly
, &b
->spoly
))) return(result
);
82 if((result
= psncmp(&a
->init
, &b
->init
))) return(result
);
83 if((a
->flags
& P_REFIN
) && (~b
->flags
& P_REFIN
)) return(1);
84 if((~a
->flags
& P_REFIN
) && (b
->flags
& P_REFIN
)) return(-1);
85 if((a
->flags
& P_REFOUT
) && (~b
->flags
& P_REFOUT
)) return(1);
86 if((~a
->flags
& P_REFOUT
) && (b
->flags
& P_REFOUT
)) return(-1);
87 return(psncmp(&a
->xorout
, &b
->xorout
));
91 mtostr(const model_t
*model
) {
92 /* Returns a malloc()-ed string containing a Williams model
93 * record representing the input model.
94 * mcanon() should be called on the argument before printing.
97 char *polystr
, *initstr
, *xorotstr
, *checkstr
, strbuf
[512], *string
= NULL
;
99 if(!model
) return(NULL
);
100 polystr
= ptostr(model
->spoly
, P_RTJUST
, 4);
101 initstr
= ptostr(model
->init
, P_RTJUST
, 4);
102 xorotstr
= ptostr(model
->xorout
, P_RTJUST
, 4);
103 checkstr
= ptostr(model
->check
, P_RTJUST
, 4);
105 sprintf(strbuf
, "%lu", plen(model
->spoly
));
108 + (model
->name
&& *model
->name
? 2 + strlen(model
->name
) : 6)
110 + (polystr
&& *polystr
? strlen(polystr
) : 6)
111 + (initstr
&& *initstr
? strlen(initstr
) : 6)
112 + (model
->flags
& P_REFIN
? 4 : 5)
113 + (model
->flags
& P_REFOUT
? 4 : 5)
114 + (xorotstr
&& *xorotstr
? strlen(xorotstr
) : 6)
115 + (checkstr
&& *checkstr
? strlen(checkstr
) : 6);
116 if((string
= malloc(size
))) {
117 sprintf(strbuf
, "\"%s\"", model
->name
);
128 polystr
&& *polystr
? polystr
: "(none)",
129 initstr
&& *initstr
? initstr
: "(none)",
130 (model
->flags
& P_REFIN
) ? "true" : "false",
131 (model
->flags
& P_REFOUT
) ? "true" : "false",
132 xorotstr
&& *xorotstr
? xorotstr
: "(none)",
133 checkstr
&& *checkstr
? checkstr
: "(none)",
134 (model
->name
&& *model
->name
) ? strbuf
: "(none)");
141 uerror("cannot allocate memory for model description");
146 mcanon(model_t
*model
) {
147 /* canonicalise a model */
152 /* extending on the right here. This preserves the functionality
153 * of a presumed working model.
155 psnorm(&model
->spoly
);
156 dlen
= plen(model
->spoly
);
157 praloc(&model
->init
, dlen
);
158 praloc(&model
->xorout
, dlen
);
160 /* only calculate Check if missing. Relying on all functions
161 * changing parameters to call mnovel(). This is to ensure that
162 * the Check value stored in the preset table is printed when
163 * the model is dumped. If something goes wrong with the
164 * calculator then the discrepancy with the stored Check value
165 * might be noticed. Storing the Check value with each preset
166 * is highly preferred.
168 if(!plen(model
->check
))
173 mcheck(model_t
*model
) {
174 /* calculate a check for the model */
175 poly_t checkstr
, check
;
177 /* generate the check string with the correct bit order */
178 checkstr
= strtop("313233343536373839", model
->flags
, 8);
179 check
= pcrc(checkstr
, model
->spoly
, model
->init
, pzero
, model
->flags
);
180 if(model
->flags
& P_REFOUT
)
182 psum(&check
, model
->xorout
, 0UL);
183 model
->check
= check
;
188 mrev(model_t
*model
) {
189 /* reverse the model to calculate reversed CRCs */
190 /* Here we invert RefIn and RefOut so that the user need only
191 * reverse the order of characters in the arguments, not the
192 * characters themselves. If RefOut=True, the mirror image of
193 * Init seen through RefOut becomes XorOut, and as RefOut
194 * becomes false, the XorOut value moved to Init stays upright.
195 * If RefOut=False, Init transfers to XorOut without reflection
196 * but the new Init must be reflected to present the same image,
197 * as RefOut becomes true.
202 if(model
->flags
& P_REFOUT
)
205 prev(&model
->xorout
);
207 /* exchange init and xorout */
209 model
->init
= model
->xorout
;
210 model
->xorout
= temp
;
212 /* invert refin and refout */
213 model
->flags
^= P_REFIN
| P_REFOUT
;
219 mnovel(model_t
*model
) {
220 /* remove name and check string from modified model */
222 pfree(&model
->check
);