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
/* little-endian data order */
5
#define	GET4(p)		((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24))
6
#define	PUT4(p,v)	(p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
7
 
8
static void
9
gf_mulx(uchar *x)
10
{
11
	ulong t0, t1, t2, t3, t4;
12
 
13
	t0 = GET4(x);
14
	t1 = GET4(x+4);
15
	t2 = GET4(x+8);
16
	t3 = GET4(x+12);
17
 
18
	t4 =             (t3 >> 31);
19
	t3 = (t3 << 1) | (t2 >> 31);
20
	t2 = (t2 << 1) | (t1 >> 31);
21
	t1 = (t1 << 1) | (t0 >> 31);
22
	t0 = (t0 << 1) ^ (t4*135);
23
 
24
	PUT4(x, t0);
25
	PUT4(x+4, t1);
26
	PUT4(x+8, t2);
27
	PUT4(x+12, t3);
28
}
29
 
30
static void
31
xor128(uchar *o, uchar *i1, uchar *i2)
32
{
33
	int i;
34
 
35
	for(i=0; i<16; i++)
36
		o[i] = i1[i] ^ i2[i];
37
}
38
 
39
static void
40
setupT(AESstate *tweak, uvlong sectorNumber, uchar T[AESbsize])
41
{
42
	PUT4(T+0, (ulong)sectorNumber), sectorNumber >>= 32;
43
	PUT4(T+4, (ulong)sectorNumber);
44
	PUT4(T+8, 0);
45
	PUT4(T+12, 0);
46
	aes_encrypt(tweak->ekey, tweak->rounds, T, T);
47
}
48
 
49
void
50
aes_xts_encrypt(AESstate *tweak, AESstate *ecb,
51
	uvlong sectorNumber, uchar *input, uchar *output, ulong len)
52
{
53
	uchar T[AESbsize], x[AESbsize];
54
 
55
	if(len % AESbsize)
56
		abort();
57
 
58
	setupT(tweak, sectorNumber, T);
59
	for (; len > 0; len -= AESbsize, input += AESbsize, output += AESbsize) {
60
		xor128(x, input, T);
61
		aes_encrypt(ecb->ekey, ecb->rounds, x, x);
62
		xor128(output, x, T);
63
		gf_mulx(T);
64
	}
65
}
66
 
67
void
68
aes_xts_decrypt(AESstate *tweak, AESstate *ecb,
69
	uvlong sectorNumber, uchar *input, uchar *output, ulong len)
70
{
71
	uchar T[AESbsize], x[AESbsize];
72
 
73
	if(len % AESbsize)
74
		abort();
75
 
76
	setupT(tweak, sectorNumber, T);
77
	for (; len > 0; len -= AESbsize, input += AESbsize, output += AESbsize) {
78
		xor128(x, input, T);
79
		aes_decrypt(ecb->dkey, ecb->rounds, x, x);
80
		xor128(output, x, T);
81
		gf_mulx(T);
82
	}
83
}