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