Add hashcat command lines
[pwdhash.git] / hmacmd5.c
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <time.h>
4 #include <string.h>
5 #include <stdbool.h>
6
7 #include "cencode.h"
8 #include "md5.h"
9
10 #include "hmacmd5.h"
11
12 #define SPH_kkPasswordPrefixLength (2)
13
14 void md5print(unsigned char digest[DIGEST_SIZE]) {
15 int pos;
16
17 for (pos = 0; pos < DIGEST_SIZE; pos++) {
18 printf ("%02x", digest[pos]);
19 }
20 }
21
22 void writeHexByte(unsigned char byte, unsigned char * hex) {
23 static char number[] = "0123456789abcdef";
24
25 hex[0] = number[(byte >> 4)];
26 hex[1] = number[(byte % 16)];
27 }
28
29 void md5hmac(unsigned char * key, unsigned char * inString, unsigned char digest[DIGEST_SIZE]) {
30 mbedtls_md5_context mdContext;
31 unsigned int keylen;
32 int pos;
33 unsigned char ipad[BLOCK_SIZE];
34 unsigned char opad[BLOCK_SIZE];
35 unsigned char hash[DIGEST_SIZE];
36
37 // Ensure key length is exaclty 16 bytes
38 keylen = strlen(key);
39 if (keylen > BLOCK_SIZE) {
40 mbedtls_md5(key, keylen, hash);
41 memcpy(ipad, hash, DIGEST_SIZE);
42 memcpy(opad, hash, DIGEST_SIZE);
43 keylen = DIGEST_SIZE;
44 }
45 else {
46 memcpy(ipad, key, keylen);
47 memcpy(opad, key, keylen);
48 }
49 for (pos = keylen; pos < BLOCK_SIZE; pos++) {
50 ipad[pos] = '\0';
51 opad[pos] = '\0';
52 }
53
54 for (pos = 0; pos < BLOCK_SIZE; pos++) {
55 ipad[pos] ^= 0x36;
56 opad[pos] ^= 0x5C;
57 }
58
59 mbedtls_md5_init(& mdContext);
60 mbedtls_md5_starts(& mdContext);
61 mbedtls_md5_update(& mdContext, ipad, BLOCK_SIZE);
62 mbedtls_md5_update(& mdContext, inString, strlen(inString));
63 mbedtls_md5_finish(& mdContext, hash);
64 mbedtls_md5_free(& mdContext);
65
66 mbedtls_md5_init(& mdContext);
67 mbedtls_md5_starts(& mdContext);
68 mbedtls_md5_update(& mdContext, opad, BLOCK_SIZE);
69 mbedtls_md5_update(& mdContext, hash, DIGEST_SIZE);
70 mbedtls_md5_finish(& mdContext, digest);
71 mbedtls_md5_free(& mdContext);
72 }
73
74 static void md5hmactest() {
75 unsigned char digest[DIGEST_SIZE];
76 //unsigned char output[DIGEST_SIZE];
77 //mbedtls_md5("Hello", 5, output);
78 //md5print(output);
79 //printf ("\n");
80
81 md5hmac("key", "The quick brown fox jumps over the lazy dog", digest);
82 md5print(digest);
83 printf ("\n");
84 }
85
86 bool containsnonalphanumeric(unsigned char * password, int length) {
87 bool nonalphanumeric;
88 unsigned int pos;
89 char check;
90 int startingSize;
91
92 nonalphanumeric = false;
93 for (pos = 0; (pos < length) && !nonalphanumeric; pos++) {
94 check = password[pos];
95 if (!((check >= 'a') && (check <= 'z'))
96 && !((check >= 'A') && (check <= 'Z'))
97 && !((check >= '0') && (check <= '9'))
98 && !(check == '_')) {
99 nonalphanumeric = true;
100 }
101 }
102
103 return nonalphanumeric;
104 }
105
106 bool contains(unsigned char * password, int length, char start, char end) {
107 bool doescontain = false;
108 unsigned int pos;
109
110 for (pos = 0; (pos < length) && (doescontain == false); pos++) {
111 if ((password[pos] >= start) && (password[pos] <= end)) {
112 doescontain = true;
113 }
114 }
115
116 return doescontain;
117 }
118
119 void rotate(unsigned char * torotate, int length, int steps) {
120 char scratch[RESULT_MAX];
121 unsigned int pos;
122
123 for (pos = 0; pos < length; pos++) {
124 scratch[pos] = torotate[(pos + steps) % length];
125 }
126
127 for (pos = 0; pos < length; pos++) {
128 torotate[pos] = scratch[pos];
129 }
130 }
131
132 void SPH_HashedPassowrd(unsigned char * password, unsigned char * realm, unsigned char result[RESULT_MAX]) {
133 unsigned char digest[DIGEST_SIZE];
134 base64_encodestate state_in;
135 size_t size;
136 unsigned char hash[25];
137 int extraSize = 0;
138 bool nonalphanumeric;
139 int startingSize;
140 int extraPos;
141 char next;
142 unsigned int pos;
143
144 md5hmac(password, realm, digest);
145
146 base64_init_encodestate(& state_in);
147 size = base64_encode_block(digest, DIGEST_SIZE, hash, & state_in);
148 size += base64_encode_blockend(hash + size, & state_in);
149 hash[24] = '\0';
150 hash[23] = '\0';
151 hash[22] = '\0';
152 extraSize = strlen(hash);
153
154 size = strlen(password) + SPH_kkPasswordPrefixLength;
155
156 nonalphanumeric = containsnonalphanumeric(password, strlen(password));
157 startingSize = size - 4;
158
159 startingSize = startingSize < extraSize ? startingSize : extraSize;
160 memcpy(result, hash, startingSize);
161 extraPos = startingSize;
162
163 // Add the extras
164 // Capital letter
165 next = (extraPos < extraSize) ? hash[extraPos] : 0;
166 extraPos++;
167 if (!contains(result, startingSize, 'A', 'Z')) {
168 next = 'A' + (next % ('Z' - 'A' + 1));
169 }
170 result[startingSize] = next;
171 startingSize++;
172
173 // Lower case letter
174 next = (extraPos < extraSize) ? hash[extraPos] : 0;
175 extraPos++;
176 if (!contains(result, startingSize, 'a', 'z')) {
177 next = 'a' + (next % ('z' - 'a' + 1));
178 }
179 result[startingSize] = next;
180 startingSize++;
181
182 // Number
183 next = (extraPos < extraSize) ? hash[extraPos] : 0;
184 extraPos++;
185 if (!contains(result, startingSize, '0', '9')) {
186 next = '0' + (next % ('9' - '0' + 1));
187 }
188 result[startingSize] = next;
189 startingSize++;
190
191 // Non alphanumeric
192 if (containsnonalphanumeric(result, startingSize) && nonalphanumeric) {
193 next = (extraPos < extraSize) ? hash[extraPos] : 0;
194 extraPos++;
195 }
196 else {
197 next = '+';
198 }
199 result[startingSize] = next;
200 startingSize++;
201
202 if (!nonalphanumeric) {
203 for (pos = 0; pos < startingSize; pos++) {
204 if (containsnonalphanumeric(result + pos, 1)) {
205 next = (extraPos < extraSize) ? hash[extraPos] : 0;
206 extraPos++;
207 next = 'A' + (next % ('Z' - 'A' + 1));
208 result[pos] = next;
209 }
210 }
211 }
212
213 next = (extraPos < extraSize) ? hash[extraPos] : 0;
214 rotate(result, startingSize, next);
215 result[startingSize] = '\0';
216 }
217
218 //int main(int argc, char * argv[]) {
219 // SPH_HashedPassowrd("lsksjfjsdfsjdflsksjfjsdfsjdflsksjfjsdfsjdflsksjfjsdfsjdf", "flypig.co.uk");
220 //
221 // return 0;
222 //}
223