#include "quakedef.h"
#include "hmac.h"
-void hmac(
+qboolean hmac(
hashfunc_t hfunc, int hlen, int hblock,
unsigned char *out,
- unsigned char *in, int n,
- unsigned char *key, int k
+ const unsigned char *in, int n,
+ const unsigned char *key, int k
)
{
unsigned char hashbuf[32];
unsigned char k_xor_ipad[128];
unsigned char k_xor_opad[128];
- unsigned char catbuf[256];
+ unsigned char *catbuf;
int i;
if(sizeof(hashbuf) < (size_t) hlen)
- Host_Error("Invalid hash function used for HMAC - too long hash length");
+ return false;
if(sizeof(k_xor_ipad) < (size_t) hblock)
- Host_Error("Invalid hash function used for HMAC - too long hash block length");
- if(sizeof(catbuf) < (size_t) hblock + (size_t) hlen)
- Host_Error("Invalid hash function used for HMAC - too long hash block length");
- if(sizeof(catbuf) < (size_t) hblock + (size_t) n)
- Host_Error("Invalid hash function used for HMAC - too long message length");
+ return false;
+ if(sizeof(k_xor_ipad) < (size_t) hlen)
+ return false;
+
+ catbuf = (unsigned char *)Mem_Alloc(tempmempool, (size_t) hblock + max((size_t) hlen, (size_t) n));
if(k > hblock)
{
// hash the key if it is too long
- // NO! that makes it too short if hblock != hlen
- // just shorten it, then
- // hfunc(hashbuf, key, k);
- // key = hashbuf;
- k = hblock;
+ hfunc(k_xor_opad, key, k);
+ key = k_xor_opad;
+ k = hlen;
}
- else if(k < hblock)
+
+ if(k < hblock)
{
// zero pad the key if it is too short
- memcpy(k_xor_opad, key, k);
+ if(key != k_xor_opad)
+ memcpy(k_xor_opad, key, k);
for(i = k; i < hblock; ++i)
k_xor_opad[i] = 0;
key = k_xor_opad;
memcpy(catbuf, k_xor_opad, hblock);
memcpy(catbuf + hblock, hashbuf, hlen);
hfunc(out, catbuf, hblock + hlen);
+
+ Mem_Free(catbuf);
+
+ return true;
}