1 /* radare2 - LGPL - Copyright 2007-2019 pancake */
2
3 #include <r_hash.h>
4 #include "r_util.h"
5 #if USE_LIB_XXHASH
6 #include <xxhash.h>
7 #else
8 #include "xxhash.h"
9 #endif
10
11 R_LIB_VERSION (r_hash);
12
13 static const struct {
14 const char *name;
15 ut64 bit;
16 } hash_name_bytes[] = {
17 { "all", UT64_MAX },
18 { "xor", R_HASH_XOR },
19 { "xorpair", R_HASH_XORPAIR },
20 { "md4", R_HASH_MD4 },
21 { "md5", R_HASH_MD5 },
22 { "sha1", R_HASH_SHA1 },
23 { "sha256", R_HASH_SHA256 },
24 { "sha384", R_HASH_SHA384 },
25 { "sha512", R_HASH_SHA512 },
26 { "adler32", R_HASH_ADLER32 },
27 { "xxhash", R_HASH_XXHASH },
28 { "parity", R_HASH_PARITY },
29 { "entropy", R_HASH_ENTROPY },
30 { "hamdist", R_HASH_HAMDIST },
31 { "pcprint", R_HASH_PCPRINT },
32 { "mod255", R_HASH_MOD255 },
33 // {"base64", R_HASH_BASE64},
34 // {"base91", R_HASH_BASE91},
35 // {"punycode", R_HASH_PUNYCODE},
36 { "luhn", R_HASH_LUHN },
37
38 { "fletcher8", R_HASH_FLETCHER8 },
39 { "fletcher16", R_HASH_FLETCHER16 },
40 { "fletcher32", R_HASH_FLETCHER32 },
41 { "fletcher64", R_HASH_FLETCHER64 },
42
43 { "crc8smbus", R_HASH_CRC8_SMBUS },
44 #if R_HAVE_CRC8_EXTRA
45 { /* CRC-8/CDMA2000 */ "crc8cdma2000", R_HASH_CRC8_CDMA2000 },
46 { /* CRC-8/DARC */ "crc8darc", R_HASH_CRC8_DARC },
47 { /* CRC-8/DVB-S2 */ "crc8dvbs2", R_HASH_CRC8_DVB_S2 },
48 { /* CRC-8/EBU */ "crc8ebu", R_HASH_CRC8_EBU },
49 { /* CRC-8/I-CODE */ "crc8icode", R_HASH_CRC8_ICODE },
50 { /* CRC-8/ITU */ "crc8itu", R_HASH_CRC8_ITU },
51 { /* CRC-8/MAXIM */ "crc8maxim", R_HASH_CRC8_MAXIM },
52 { /* CRC-8/ROHC */ "crc8rohc", R_HASH_CRC8_ROHC },
53 { /* CRC-8/WCDMA */ "crc8wcdma", R_HASH_CRC8_WCDMA },
54 #endif /* #if R_HAVE_CRC8_EXTRA */
55
56 #if R_HAVE_CRC15_EXTRA
57 { "crc15can", R_HASH_CRC15_CAN },
58 #endif /* #if R_HAVE_CRC15_EXTRA */
59
60 { "crc16", R_HASH_CRC16 },
61 { "crc16hdlc", R_HASH_CRC16_HDLC },
62 { /* CRC-16/USB */ "crc16usb", R_HASH_CRC16_USB },
63 { /* CRC-16/CCITT-FALSE */ "crc16citt", R_HASH_CRC16_CITT },
64 #if R_HAVE_CRC16_EXTRA
65 { /* CRC-16/AUG-CCITT */ "crc16augccitt", R_HASH_CRC16_AUG_CCITT },
66 { /* CRC-16/BUYPASS */ "crc16buypass", R_HASH_CRC16_BUYPASS },
67 { /* CRC-16/CDMA2000 */ "crc16cdma2000", R_HASH_CRC16_CDMA2000 },
68 { /* CRC-16/DDS-110 */ "crc16dds110", R_HASH_CRC16_DDS110 },
69 { /* CRC-16/RECT-R */ "crc16dectr", R_HASH_CRC16_DECT_R },
70 { /* CRC-16/RECT-X */ "crc16dectx", R_HASH_CRC16_DECT_X },
71 { /* CRC-16/DNP */ "crc16dnp", R_HASH_CRC16_DNP },
72 { /* CRC-16/EN-13757 */ "crc16en13757", R_HASH_CRC16_EN13757 },
73 { /* CRC-16/GENIBUS */ "crc16genibus", R_HASH_CRC16_GENIBUS },
74 { /* CRC-16/MAXIM */ "crc16maxim", R_HASH_CRC16_MAXIM },
75 { /* CRC-16/MCRF4XX */ "crc16mcrf4xx", R_HASH_CRC16_MCRF4XX },
76 { /* CRC-16/RIELLO */ "crc16riello", R_HASH_CRC16_RIELLO },
77 { /* CRC-16/T10-DIF */ "crc16t10dif", R_HASH_CRC16_T10_DIF },
78 { /* CRC-16/TELEDISK */ "crc16teledisk", R_HASH_CRC16_TELEDISK },
79 { /* CRC-16/TMS37157 */ "crc16tms37157", R_HASH_CRC16_TMS37157 },
80 { /* CRC-A */ "crca", R_HASH_CRCA },
81 { /* CRC-16/KERMIT */ "crc16kermit", R_HASH_CRC16_KERMIT },
82 { /* CRC-16/MODBUS */ "crc16modbus", R_HASH_CRC16_MODBUS },
83 { /* CRC-16/X-25 */ "crc16x25", R_HASH_CRC16_X25 },
84 { /* CRC-16/XMODEM */ "crc16xmodem", R_HASH_CRC16_XMODEM },
85 #endif /* #if R_HAVE_CRC16_EXTRA */
86
87 #if R_HAVE_CRC24
88 { "crc24", R_HASH_CRC24 },
89 #endif /* #if R_HAVE_CRC24 */
90
91 { "crc32", R_HASH_CRC32 },
92 { "crc32c", R_HASH_CRC32C },
93 { "crc32ecma267", R_HASH_CRC32_ECMA_267 },
94 #if R_HAVE_CRC32_EXTRA
95 { /* CRC-32/BZIP2 */ "crc32bzip2", R_HASH_CRC32_BZIP2 },
96 { /* CRC-32D */ "crc32d", R_HASH_CRC32D },
97 { /* CRC-32/MPEG2 */ "crc32mpeg2", R_HASH_CRC32_MPEG2 },
98 { /* CRC-32/POSIX */ "crc32posix", R_HASH_CRC32_POSIX },
99 { /* CRC-32Q */ "crc32q", R_HASH_CRC32Q },
100 { /* CRC-32/JAMCRC */ "crc32jamcrc", R_HASH_CRC32_JAMCRC },
101 { /* CRC-32/XFER */ "crc32xfer", R_HASH_CRC32_XFER },
102 #endif /* #if R_HAVE_CRC32_EXTRA */
103
104 #if R_HAVE_CRC64
105 { /* CRC-64 */ "crc64", R_HASH_CRC64 },
106 #endif /* #if R_HAVE_CRC64 */
107
108 #if R_HAVE_CRC64_EXTRA
109 { /* CRC-64/ECMA-182 */ "crc64ecma", R_HASH_CRC64_ECMA182 },
110 { /* CRC-64/WE */ "crc64we", R_HASH_CRC64_WE },
111 { /* CRC-64/XZ */ "crc64xz", R_HASH_CRC64_XZ },
112 { /* CRC-64/ISO */ "crc64iso", R_HASH_CRC64_ISO },
113 #endif /* #if R_HAVE_CRC64_EXTRA */
114 { NULL, 0 }
115 };
116
117 /* returns 0-100 */
r_hash_pcprint(const ut8 * buffer,ut64 len)118 R_API int r_hash_pcprint(const ut8 *buffer, ut64 len) {
119 const ut8 *end = buffer + len;
120 int n;
121 if (len < 1) {
122 return 0;
123 }
124 for (n = 0; buffer < end; buffer++) {
125 if (IS_PRINTABLE (*buffer)) {
126 n++;
127 }
128 }
129 return ((100 * n) / len);
130 }
131
r_hash_parity(const ut8 * buf,ut64 len)132 R_API int r_hash_parity(const ut8 *buf, ut64 len) {
133 const ut8 *end = buf + len;
134 ut32 ones = 0;
135 for (; buf < end; buf++) {
136 ut8 x = buf[0];
137 ones += ((x & 128) ? 1 : 0) + ((x & 64) ? 1 : 0) + ((x & 32) ? 1 : 0) + ((x & 16) ? 1 : 0) +
138 ((x & 8) ? 1 : 0) + ((x & 4) ? 1 : 0) + ((x & 2) ? 1 : 0) + ((x & 1) ? 1 : 0);
139 }
140 return ones % 2;
141 }
142
143 /* These functions comes from 0xFFFF */
144 /* fmi: nopcode.org/0xFFFF */
r_hash_xorpair(const ut8 * a,ut64 len)145 R_API ut16 r_hash_xorpair(const ut8 *a, ut64 len) {
146 ut16 result = 0, *b = (ut16 *)a;
147 for (len >>= 1; len--; b++) {
148 result ^= *b;
149 }
150 return result;
151 }
152
r_hash_xor(const ut8 * b,ut64 len)153 R_API ut8 r_hash_xor(const ut8 *b, ut64 len) {
154 ut8 res = 0;
155 for (; len--; b++) {
156 res ^= *b;
157 }
158 return res;
159 }
160
r_hash_mod255(const ut8 * b,ut64 len)161 R_API ut8 r_hash_mod255(const ut8 *b, ut64 len) {
162 int i, c = 0;
163 /* from gdb */
164 for (i = 0; i < len; i++) {
165 c += b[i];
166 }
167 return c % 255;
168 }
169
r_hash_xxhash(const ut8 * buf,ut64 len)170 R_API ut32 r_hash_xxhash(const ut8 *buf, ut64 len) {
171 return XXH32 (buf, (size_t)len, 0);
172 }
173
r_hash_deviation(const ut8 * b,ut64 len)174 R_API ut8 r_hash_deviation(const ut8 *b, ut64 len) {
175 int i, c;
176 for (c = i = 0, len--; i < len; i++) {
177 c += R_ABS (b[i + 1] - b[i]);
178 }
179 return c;
180 }
181
r_hash_name(ut64 bit)182 R_API const char *r_hash_name(ut64 bit) {
183 int i;
184 for (i = 1; hash_name_bytes[i].bit; i++) {
185 if (bit & hash_name_bytes[i].bit) {
186 return hash_name_bytes[i].name;
187 }
188 }
189 return "";
190 }
191
r_hash_size(ut64 algo)192 R_API int r_hash_size(ut64 algo) {
193 #define ALGOBIT(x)\
194 if (algo & R_HASH_##x) {\
195 return R_HASH_SIZE_##x;\
196 }
197 ALGOBIT (FLETCHER8);
198 ALGOBIT (FLETCHER16);
199 ALGOBIT (FLETCHER32);
200 ALGOBIT (FLETCHER64);
201 ALGOBIT (MD4);
202 ALGOBIT (MD5);
203 ALGOBIT (SHA1);
204 ALGOBIT (SHA256);
205 ALGOBIT (SHA384);
206 ALGOBIT (SHA512);
207 ALGOBIT (XXHASH);
208 ALGOBIT (ADLER32);
209 ALGOBIT (PARITY);
210 ALGOBIT (ENTROPY);
211 ALGOBIT (HAMDIST);
212 ALGOBIT (XOR);
213 ALGOBIT (XORPAIR);
214 ALGOBIT (MOD255);
215 ALGOBIT (PCPRINT);
216 ALGOBIT (LUHN);
217
218 ALGOBIT (CRC8_SMBUS);
219 #if R_HAVE_CRC8_EXTRA
220 ALGOBIT (CRC8_CDMA2000);
221 ALGOBIT (CRC8_DARC);
222 ALGOBIT (CRC8_DVB_S2);
223 ALGOBIT (CRC8_EBU);
224 ALGOBIT (CRC8_ICODE);
225 ALGOBIT (CRC8_ITU);
226 ALGOBIT (CRC8_MAXIM);
227 ALGOBIT (CRC8_ROHC);
228 ALGOBIT (CRC8_WCDMA);
229 #endif /* #if R_HAVE_CRC8_EXTRA */
230
231 #if R_HAVE_CRC15_EXTRA
232 ALGOBIT (CRC15_CAN);
233 #endif /* #if R_HAVE_CRC15_EXTRA */
234
235 ALGOBIT (CRC16);
236 ALGOBIT (CRC16_HDLC);
237 ALGOBIT (CRC16_USB);
238 ALGOBIT (CRC16_CITT);
239 #if R_HAVE_CRC16_EXTRA
240 ALGOBIT (CRC16_AUG_CCITT);
241 ALGOBIT (CRC16_BUYPASS)
242 ALGOBIT (CRC16_CDMA2000);
243 ALGOBIT (CRC16_DDS110);
244 ALGOBIT (CRC16_DECT_R);
245 ALGOBIT (CRC16_DECT_X);
246 ALGOBIT (CRC16_DNP);
247 ALGOBIT (CRC16_EN13757);
248 ALGOBIT (CRC16_GENIBUS);
249 ALGOBIT (CRC16_MAXIM);
250 ALGOBIT (CRC16_MCRF4XX);
251 ALGOBIT (CRC16_RIELLO);
252 ALGOBIT (CRC16_T10_DIF);
253 ALGOBIT (CRC16_TELEDISK);
254 ALGOBIT (CRC16_TMS37157);
255 ALGOBIT (CRCA);
256 ALGOBIT (CRC16_KERMIT);
257 ALGOBIT (CRC16_MODBUS);
258 ALGOBIT (CRC16_X25);
259 ALGOBIT (CRC16_XMODEM);
260 #endif /* #if R_HAVE_CRC16_EXTRA */
261
262 #if R_HAVE_CRC24
263 ALGOBIT (CRC24);
264 #endif /* #if R_HAVE_CRC24 */
265
266 ALGOBIT (CRC32);
267 ALGOBIT (CRC32C);
268 ALGOBIT (CRC32_ECMA_267);
269 #if R_HAVE_CRC32_EXTRA
270 ALGOBIT (CRC32_BZIP2);
271 ALGOBIT (CRC32D);
272 ALGOBIT (CRC32_MPEG2);
273 ALGOBIT (CRC32_POSIX);
274 ALGOBIT (CRC32Q);
275 ALGOBIT (CRC32_JAMCRC);
276 ALGOBIT (CRC32_XFER);
277 #endif /* #if R_HAVE_CRC32_EXTRA */
278
279 #if R_HAVE_CRC64
280 ALGOBIT (CRC64);
281 #endif /* #if R_HAVE_CRC64 */
282
283 #if R_HAVE_CRC64_EXTRA
284 ALGOBIT (CRC64_ECMA182);
285 ALGOBIT (CRC64_WE);
286 ALGOBIT (CRC64_XZ);
287 ALGOBIT (CRC64_ISO);
288 #endif /* #if R_HAVE_CRC64_EXTRA */
289 return 0;
290 }
291
292 /* Converts a comma separated list of names to the respective bit combination */
r_hash_name_to_bits(const char * name)293 R_API ut64 r_hash_name_to_bits(const char *name) {
294 char tmp[128];
295 int i;
296 const char *ptr = name;
297 ut64 ret = 0;
298
299 if (!ptr) {
300 return ret;
301 }
302
303 do {
304 /* Eat everything up to the comma */
305 for (i = 0; *ptr && *ptr != ',' && i < sizeof (tmp) - 1; i++) {
306 tmp[i] = tolower ((ut8)*ptr++);
307 }
308
309 /* Safety net */
310 tmp[i] = '\0';
311
312 for (i = 0; hash_name_bytes[i].name; i++) {
313 if (!strcmp (tmp, hash_name_bytes[i].name)) {
314 ret |= hash_name_bytes[i].bit;
315 break;
316 }
317 }
318
319 /* Skip the trailing comma, if any */
320 if (*ptr) {
321 ptr++;
322 }
323 } while (*ptr);
324
325 return ret;
326 }
327
r_hash_do_spice(RHash * ctx,ut64 algo,int loops,RHashSeed * seed)328 R_API void r_hash_do_spice(RHash *ctx, ut64 algo, int loops, RHashSeed *seed) {
329 ut8 buf[1024];
330 int i, len, hlen = r_hash_size (algo);
331 for (i = 0; i < loops; i++) {
332 if (seed) {
333 if (seed->prefix) {
334 memcpy (buf, seed->buf, seed->len);
335 memcpy (buf + seed->len, ctx->digest, hlen);
336 } else {
337 memcpy (buf, ctx->digest, hlen);
338 memcpy (buf + hlen, seed->buf, seed->len);
339 }
340 len = hlen + seed->len;
341 } else {
342 memcpy (buf, ctx->digest, hlen);
343 len = hlen;
344 }
345 (void)r_hash_calculate (ctx, algo, buf, len);
346 }
347 }
348
r_hash_to_string(RHash * ctx,const char * name,const ut8 * data,int len)349 R_API char *r_hash_to_string(RHash *ctx, const char *name, const ut8 *data, int len) {
350 ut64 algo = r_hash_name_to_bits (name);
351 char *digest_hex = NULL;
352 RHash *myctx = NULL;
353 int i, digest_size;
354 if (!algo || !data) {
355 return NULL;
356 }
357 if (!ctx) {
358 myctx = ctx = r_hash_new (true, algo);
359 }
360 r_hash_do_begin (ctx, algo);
361 digest_size = r_hash_calculate (ctx, algo, data, len);
362 r_hash_do_end (ctx, algo);
363 if (digest_size == 0) {
364 digest_hex = calloc (16, 1);
365 snprintf (digest_hex, 15, "%02.8f", ctx->entropy);
366 } else if (digest_size > 0) {
367 if (digest_size * 2 < digest_size) {
368 digest_hex = NULL;
369 } else {
370 digest_hex = malloc ((digest_size * 2) + 1);
371 if (digest_hex) {
372 for (i = 0; i < digest_size; i++) {
373 sprintf (digest_hex + (i * 2), "%02x", ctx->digest[i]);
374 }
375 digest_hex[digest_size * 2] = 0;
376 }
377 }
378 }
379 r_hash_free (myctx);
380 return digest_hex;
381 }
382