File: hmac.c

package info (click to toggle)
darkplaces 0~20180412~beta1-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 18,200 kB
  • sloc: ansic: 176,886; makefile: 485; pascal: 455; perl: 372; objc: 245; sh: 102
file content (61 lines) | stat: -rw-r--r-- 1,268 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "quakedef.h"
#include "hmac.h"

qboolean hmac(
	hashfunc_t hfunc, int hlen, int hblock,
	unsigned char *out,
	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;
	int i;

	if(sizeof(hashbuf) < (size_t) hlen)
		return false;
	if(sizeof(k_xor_ipad) < (size_t) hblock)
		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
		hfunc(k_xor_opad, key, k);
		key = k_xor_opad;
		k = hlen;
	}

	if(k < hblock)
	{
		// zero pad the key if it is too short
		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;
		k = hblock;
	}

	for(i = 0; i < hblock; ++i)
	{
		k_xor_ipad[i] = key[i] ^ 0x36;
		k_xor_opad[i] = key[i] ^ 0x5c;
	}

	memcpy(catbuf, k_xor_ipad, hblock);
	memcpy(catbuf + hblock, in, n);
	hfunc(hashbuf, catbuf, hblock + n);
	memcpy(catbuf, k_xor_opad, hblock);
	memcpy(catbuf + hblock, hashbuf, hlen);
	hfunc(out, catbuf, hblock + hlen);

	Mem_Free(catbuf);

	return true;
}