12 #define SPH_kkPasswordPrefixLength (2)
14 void md5print(unsigned char digest
[DIGEST_SIZE
]) {
17 for (pos
= 0; pos
< DIGEST_SIZE
; pos
++) {
18 printf ("%02x", digest
[pos
]);
22 void writeHexByte(unsigned char byte
, unsigned char * hex
) {
23 static char number
[] = "0123456789abcdef";
25 hex
[0] = number
[(byte
>> 4)];
26 hex
[1] = number
[(byte
% 16)];
29 void md5hmac(unsigned char * key
, unsigned char * inString
, unsigned char digest
[DIGEST_SIZE
]) {
30 mbedtls_md5_context mdContext
;
33 unsigned char ipad
[BLOCK_SIZE
];
34 unsigned char opad
[BLOCK_SIZE
];
35 unsigned char hash
[DIGEST_SIZE
];
37 // Ensure key length is exaclty 16 bytes
39 if (keylen
> BLOCK_SIZE
) {
40 mbedtls_md5(key
, keylen
, hash
);
41 memcpy(ipad
, hash
, DIGEST_SIZE
);
42 memcpy(opad
, hash
, DIGEST_SIZE
);
46 memcpy(ipad
, key
, keylen
);
47 memcpy(opad
, key
, keylen
);
49 for (pos
= keylen
; pos
< BLOCK_SIZE
; pos
++) {
54 for (pos
= 0; pos
< BLOCK_SIZE
; pos
++) {
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
);
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
);
74 static void md5hmactest() {
75 unsigned char digest
[DIGEST_SIZE
];
76 //unsigned char output[DIGEST_SIZE];
77 //mbedtls_md5("Hello", 5, output);
81 md5hmac("key", "The quick brown fox jumps over the lazy dog", digest
);
86 bool containsnonalphanumeric(unsigned char * password
, int length
) {
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'))
99 nonalphanumeric
= true;
103 return nonalphanumeric
;
106 bool contains(unsigned char * password
, int length
, char start
, char end
) {
107 bool doescontain
= false;
110 for (pos
= 0; (pos
< length
) && (doescontain
== false); pos
++) {
111 if ((password
[pos
] >= start
) && (password
[pos
] <= end
)) {
119 void rotate(unsigned char * torotate
, int length
, int steps
) {
120 char scratch
[RESULT_MAX
];
123 for (pos
= 0; pos
< length
; pos
++) {
124 scratch
[pos
] = torotate
[(pos
+ steps
) % length
];
127 for (pos
= 0; pos
< length
; pos
++) {
128 torotate
[pos
] = scratch
[pos
];
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
;
136 unsigned char hash
[25];
138 bool nonalphanumeric
;
144 md5hmac(password
, realm
, digest
);
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
);
152 extraSize
= strlen(hash
);
154 size
= strlen(password
) + SPH_kkPasswordPrefixLength
;
156 nonalphanumeric
= containsnonalphanumeric(password
, strlen(password
));
157 startingSize
= size
- 4;
159 startingSize
= startingSize
< extraSize
? startingSize
: extraSize
;
160 memcpy(result
, hash
, startingSize
);
161 extraPos
= startingSize
;
164 next
= (extraPos
< extraSize
) ? hash
[extraPos
] : 0;
166 if (!contains(result
, startingSize
, 'A', 'Z')) {
167 next
= 'A' + (next
% ('Z' - 'A' + 1));
169 result
[startingSize
] = next
;
172 next
= (extraPos
< extraSize
) ? hash
[extraPos
] : 0;
174 if (!contains(result
, startingSize
, 'a', 'z')) {
175 next
= 'a' + (next
% ('z' - 'a' + 1));
177 result
[startingSize
] = next
;
180 next
= (extraPos
< extraSize
) ? hash
[extraPos
] : 0;
182 if (!contains(result
, startingSize
, '0', '9')) {
183 next
= '0' + (next
% ('9' - '0' + 1));
185 result
[startingSize
] = next
;
188 if (containsnonalphanumeric(result
, startingSize
) && nonalphanumeric
) {
189 next
= (extraPos
< extraSize
) ? hash
[extraPos
] : 0;
195 result
[startingSize
] = next
;
198 if (!nonalphanumeric
) {
199 for (pos
= 0; pos
< startingSize
; pos
++) {
200 if (containsnonalphanumeric(result
+ pos
, 1)) {
201 next
= (extraPos
< extraSize
) ? hash
[extraPos
] : 0;
203 next
= 'A' + (next
% ('Z' - 'A' + 1));
209 next
= (extraPos
< extraSize
) ? hash
[extraPos
] : 0;
210 rotate(result
, startingSize
, next
);
211 result
[startingSize
] = '\0';
214 //int main(int argc, char * argv[]) {
215 // SPH_HashedPassowrd("lsksjfjsdfsjdflsksjfjsdfsjdflsksjfjsdfsjdflsksjfjsdfsjdf", "flypig.co.uk");