]> icculus.org git repositories - divverent/darkplaces.git/blob - hmac.c
better error handling for overlong srcon commands
[divverent/darkplaces.git] / hmac.c
1 #include "quakedef.h"
2 #include "hmac.h"
3
4 qboolean hmac(
5         hashfunc_t hfunc, int hlen, int hblock,
6         unsigned char *out,
7         unsigned char *in, int n,
8         unsigned char *key, int k
9 )
10 {
11         static unsigned char hashbuf[32];
12         static unsigned char k_xor_ipad[128];
13         static unsigned char k_xor_opad[128];
14         static unsigned char catbuf[4096];
15         int i;
16
17         if(sizeof(hashbuf) < (size_t) hlen)
18                 return false;
19         if(sizeof(k_xor_ipad) < (size_t) hblock)
20                 return false;
21         if(sizeof(k_xor_ipad) < (size_t) hlen)
22                 return false;
23         if(sizeof(catbuf) < (size_t) hblock + (size_t) hlen)
24                 return false;
25         if(sizeof(catbuf) < (size_t) hblock + (size_t) n)
26                 return false;
27
28         if(k > hblock)
29         {
30                 // hash the key if it is too long
31                 hfunc(k_xor_opad, key, k);
32                 key = k_xor_opad;
33                 k = hlen;
34         }
35
36         if(k < hblock)
37         {
38                 // zero pad the key if it is too short
39                 if(key != k_xor_opad)
40                         memcpy(k_xor_opad, key, k);
41                 for(i = k; i < hblock; ++i)
42                         k_xor_opad[i] = 0;
43                 key = k_xor_opad;
44                 k = hblock;
45         }
46
47         for(i = 0; i < hblock; ++i)
48         {
49                 k_xor_ipad[i] = key[i] ^ 0x36;
50                 k_xor_opad[i] = key[i] ^ 0x5c;
51         }
52
53         memcpy(catbuf, k_xor_ipad, hblock);
54         memcpy(catbuf + hblock, in, n);
55         hfunc(hashbuf, catbuf, hblock + n);
56         memcpy(catbuf, k_xor_opad, hblock);
57         memcpy(catbuf + hblock, hashbuf, hlen);
58         hfunc(out, catbuf, hblock + hlen);
59         return true;
60 }