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