Subversion Repositories planix.SVN

Rev

Rev 33 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
26 7u83 1
#include "os.h"
2
#include <libsec.h>
3
 
4
/*
5
 * AES-XCBC-MAC-96 message authentication, per rfc3566.
6
 */
7
static uchar basekey[3][16] = {
8
	{
9
	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
10
	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
11
	},
12
	{
13
	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
14
	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
15
	},
16
	{
17
	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
18
	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
19
	},
20
};
21
 
22
void
23
setupAESXCBCstate(AESstate *s)		/* was setupmac96 */
24
{
25
	int i, j;
26
	uint q[16 / sizeof(uint)];
27
	uchar *p;
28
 
29
	assert(s->keybytes == 16);
30
	for(i = 0; i < 3; i++)
31
		aes_encrypt(s->ekey, s->rounds, basekey[i],
32
			s->mackey + AESbsize*i);
33
 
34
	p = s->mackey;
35
	memset(q, 0, AESbsize);
36
 
37
	/*
38
	 * put the in the right endian.  once figured, probably better
39
	 * to use some fcall macros.
40
	 * keys for encryption in local endianness for the algorithm...
41
	 * only key1 is used for encryption;
42
	 * BUG!!: I think this is what I got wrong.
43
	 */
44
	for(i = 0; i < 16 / sizeof(uint); i ++){
45
		for(j = 0; j < sizeof(uint); j++)
46
			q[i] |= p[sizeof(uint)-j-1] << 8*j;
47
		p += sizeof(uint);
48
	}
49
	memmove(s->mackey, q, 16);
50
}
51
 
52
/*
53
 * Not dealing with > 128-bit keys, not dealing with strange corner cases like
54
 * empty message.  Should be fine for AES-XCBC-MAC-96.
55
 */
56
uchar*
57
aesXCBCmac(uchar *p, int len, AESstate *s)
58
{
59
	uchar *p2, *ip, *eip, *mackey;
60
	uchar q[AESbsize];
61
 
62
	assert(s->keybytes == 16);	/* more complicated for bigger */
63
	memset(s->ivec, 0, AESbsize);	/* E[0] is 0+ */
64
 
65
	for(; len > AESbsize; len -= AESbsize){
66
		memmove(q, p, AESbsize);
67
		p2 = q;
68
		ip = s->ivec;
69
		for(eip = ip + AESbsize; ip < eip; )
70
			*p2++ ^= *ip++;
71
		aes_encrypt((ulong *)s->mackey, s->rounds, q, s->ivec);
72
		p += AESbsize;
73
	}
74
	/* the last one */
75
 
76
	memmove(q, p, len);
77
	p2 = q+len;
78
	if(len == AESbsize)
79
		mackey = s->mackey + AESbsize;	/* k2 */
80
	else{
81
		mackey = s->mackey+2*AESbsize;	/* k3 */
82
		*p2++ = 1 << 7;			/* padding */
83
		len = AESbsize - len - 1;
84
		memset(p2, 0, len);
85
	}
86
 
87
	ip = s->ivec;
88
	p2 = q;
89
	for(eip = ip + AESbsize; ip < eip; )
90
		*p2++ ^= *ip++ ^ *mackey++;
91
	aes_encrypt((ulong *)s->mackey, s->rounds, q, s->ivec);
92
	return s->ivec;			/* only the 12 bytes leftmost */
93
}