1 /* radare - LGPL - Copyright 2009-2017 pancake */
2 
3 #include <r_hash.h>
4 
5 #if HAVE_LIB_SSL
6 #include <openssl/md4.h>
7 #include <openssl/md5.h>
8 #include <openssl/sha.h>
9 #else
10 #include "md4.h"
11 #include "md5.h"
12 #include "sha1.h"
13 #include "sha2.h"
14 #endif
15 
16 #define CHKFLAG(x) if (!flags || flags & (x))
17 
r_hash_new(bool rst,ut64 flags)18 R_API RHash *r_hash_new(bool rst, ut64 flags) {
19 	RHash *ctx = R_NEW0 (RHash);
20 	if (ctx) {
21 		r_hash_do_begin (ctx, flags);
22 		ctx->rst = rst;
23 	}
24 	return ctx;
25 }
26 
r_hash_do_begin(RHash * ctx,ut64 flags)27 R_API void r_hash_do_begin(RHash *ctx, ut64 flags) {
28 	CHKFLAG (R_HASH_MD5) r_hash_do_md5 (ctx, NULL, -1);
29 	CHKFLAG (R_HASH_SHA1) SHA1_Init (&ctx->sha1);
30 	CHKFLAG (R_HASH_SHA256) SHA256_Init (&ctx->sha256);
31 	CHKFLAG (R_HASH_SHA384) SHA384_Init (&ctx->sha384);
32 	CHKFLAG (R_HASH_SHA512) SHA512_Init (&ctx->sha512);
33 	ctx->rst = false;
34 }
35 
r_hash_do_end(RHash * ctx,ut64 flags)36 R_API void r_hash_do_end(RHash *ctx, ut64 flags) {
37 	CHKFLAG (R_HASH_MD5) r_hash_do_md5 (ctx, NULL, -2);
38 	CHKFLAG (R_HASH_SHA1) SHA1_Final (ctx->digest, &ctx->sha1);
39 	CHKFLAG (R_HASH_SHA256) SHA256_Final (ctx->digest, &ctx->sha256);
40 	CHKFLAG (R_HASH_SHA384) SHA384_Final (ctx->digest, &ctx->sha384);
41 	CHKFLAG (R_HASH_SHA512) SHA512_Final (ctx->digest, &ctx->sha512);
42 	ctx->rst = true;
43 }
44 
r_hash_free(RHash * ctx)45 R_API void r_hash_free(RHash *ctx) {
46 	free (ctx);
47 }
48 
r_hash_do_sha1(RHash * ctx,const ut8 * input,int len)49 R_API ut8 *r_hash_do_sha1(RHash *ctx, const ut8 *input, int len) {
50 	if (len < 0) {
51 		return NULL;
52 	}
53 	if (ctx->rst) {
54 		SHA1_Init (&ctx->sha1);
55 	}
56 	SHA1_Update (&ctx->sha1, input, len);
57 	if (ctx->rst || len == 0) {
58 		SHA1_Final (ctx->digest, &ctx->sha1);
59 	}
60 	return ctx->digest;
61 }
62 
r_hash_do_sha256(RHash * ctx,const ut8 * input,int len)63 R_API ut8 *r_hash_do_sha256(RHash *ctx, const ut8 *input, int len) {
64 	if (len < 0) {
65 		return NULL;
66 	}
67 	if (ctx->rst) {
68 		SHA256_Init (&ctx->sha256);
69 	}
70 	SHA256_Update (&ctx->sha256, input, len);
71 	if (ctx->rst || len == 0) {
72 		SHA256_Final (ctx->digest, &ctx->sha256);
73 	}
74 	return ctx->digest;
75 }
76 
r_hash_do_sha384(RHash * ctx,const ut8 * input,int len)77 R_API ut8 *r_hash_do_sha384(RHash *ctx, const ut8 *input, int len) {
78 	if (len < 0) {
79 		return NULL;
80 	}
81 	if (ctx->rst) {
82 		SHA384_Init (&ctx->sha384);
83 	}
84 	SHA384_Update (&ctx->sha384, input, len);
85 	if (ctx->rst || len == 0) {
86 		SHA384_Final (ctx->digest, &ctx->sha384);
87 	}
88 	return ctx->digest;
89 }
90 
r_hash_do_sha512(RHash * ctx,const ut8 * input,int len)91 R_API ut8 *r_hash_do_sha512(RHash *ctx, const ut8 *input, int len) {
92 	if (len < 0) {
93 		return NULL;
94 	}
95 	if (ctx->rst) {
96 		SHA512_Init (&ctx->sha512);
97 	}
98 	SHA512_Update (&ctx->sha512, input, len);
99 	if (ctx->rst || len == 0) {
100 		SHA512_Final (ctx->digest, &ctx->sha512);
101 	}
102 	return ctx->digest;
103 }
104 
r_hash_do_md5(RHash * ctx,const ut8 * input,int len)105 R_API ut8 *r_hash_do_md5(RHash *ctx, const ut8 *input, int len) {
106 	if (len < 0) {
107 		if (len == -1) {
108 			MD5_Init (&ctx->md5);
109 		} else if (len == -2) {
110 			MD5_Final (ctx->digest, &ctx->md5);
111 		}
112 		return NULL;
113 	}
114 	if (ctx->rst) {
115 		MD5_Init (&ctx->md5);
116 	}
117 	if (len > 0) {
118 		MD5_Update (&ctx->md5, input, len);
119 	} else {
120 		MD5_Update (&ctx->md5, (const ut8 *) "", 0);
121 	}
122 	if (ctx->rst) {
123 		MD5_Final (ctx->digest, &ctx->md5);
124 	}
125 	return ctx->digest;
126 }
127 
r_hash_do_md4(RHash * ctx,const ut8 * input,int len)128 R_API ut8 *r_hash_do_md4(RHash *ctx, const ut8 *input, int len) {
129 	if (len >= 0) {
130 		MD4 (input, len, ctx->digest);
131 		return ctx->digest;
132 	}
133 	return NULL;
134 }
135 
r_hash_do_hmac_sha256(RHash * ctx,const ut8 * input,int len,const ut8 * key,int klen)136 R_API ut8 *r_hash_do_hmac_sha256(RHash *ctx, const ut8 *input, int len, const ut8 *key, int klen) {
137 	if (len < 0 || klen < 0) {
138 		return NULL;
139 	}
140 
141 	size_t i;
142 	ut8 bskey[SHA256_BLOCK_LENGTH]; // block-sized key
143 	ut8 kpad[SHA256_BLOCK_LENGTH]; // keypad for opad, ipad
144 
145 	// If klen > block-size, bskey = Hash(key)
146 	memset (bskey, 0, SHA256_BLOCK_LENGTH);
147 	if (klen > SHA256_BLOCK_LENGTH) {
148 		SHA256_Init (&ctx->sha256);
149 		SHA256_Update (&ctx->sha256, key, klen);
150 		SHA256_Final (ctx->digest, &ctx->sha256);
151 		memcpy (bskey, ctx->digest, R_HASH_SIZE_SHA256);
152 	} else {
153 		memcpy (bskey, key, klen);
154 	}
155 
156 	// XOR block-sized key with ipad 0x36
157 	memset (kpad, 0, SHA256_BLOCK_LENGTH);
158 	memcpy (kpad, bskey, SHA256_BLOCK_LENGTH);
159 	for (i = 0; i < SHA256_BLOCK_LENGTH; i++) {
160 		kpad[i] ^= 0x36;
161 	}
162 
163 	// Inner hash (key ^ ipad || input)
164 	SHA256_Init (&ctx->sha256);
165 	SHA256_Update (&ctx->sha256, kpad, SHA256_BLOCK_LENGTH);
166 	SHA256_Update (&ctx->sha256, input, len);
167 	SHA256_Final (ctx->digest, &ctx->sha256);
168 
169 	// XOR block-sized key with opad 0x5c
170 	memset (kpad, 0, SHA256_BLOCK_LENGTH);
171 	memcpy (kpad, bskey, SHA256_BLOCK_LENGTH);
172 	for (i = 0; i < SHA256_BLOCK_LENGTH; i++) {
173 		kpad[i] ^= 0x5c;
174 	}
175 
176 	// Outer hash (key ^ opad || Inner hash)
177 	SHA256_Init (&ctx->sha256);
178 	SHA256_Update (&ctx->sha256, kpad, SHA256_BLOCK_LENGTH);
179 	SHA256_Update (&ctx->sha256, ctx->digest, R_HASH_SIZE_SHA256);
180 	SHA256_Final (ctx->digest, &ctx->sha256);
181 
182 	return ctx->digest;
183 }
184