]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libsec/port/aes_xts.c
libsec: generalize pbkdf2_hmac_sha1() to pbkdf2_x() passing the hmac as an argument
[plan9front.git] / sys / src / libsec / port / aes_xts.c
1 // Author Taru Karttunen <taruti@taruti.net>
2 // This file can be used as both Public Domain or Creative Commons CC0.
3 #include <u.h>
4 #include <libsec.h>
5
6 #define AesBlockSize 16
7
8 static void xor128(uchar* o,uchar* i1,uchar* i2) {
9         ((ulong*)o)[0] = ((ulong*)i1)[0] ^ ((ulong*)i2)[0];
10         ((ulong*)o)[1] = ((ulong*)i1)[1] ^ ((ulong*)i2)[1];
11         ((ulong*)o)[2] = ((ulong*)i1)[2] ^ ((ulong*)i2)[2];
12         ((ulong*)o)[3] = ((ulong*)i1)[3] ^ ((ulong*)i2)[3];
13 }
14
15 static void gf_mulx(uchar* x) {
16     ulong t = ((((ulong*)(x))[3] & 0x80000000u) ? 0x00000087u : 0);;
17     ((ulong*)(x))[3] = (((ulong*)(x))[3] << 1) | (((ulong*)(x))[2] & 0x80000000u ? 1 : 0);
18     ((ulong*)(x))[2] = (((ulong*)(x))[2] << 1) | (((ulong*)(x))[1] & 0x80000000u ? 1 : 0);
19     ((ulong*)(x))[1] = (((ulong*)(x))[1] << 1) | (((ulong*)(x))[0] & 0x80000000u ? 1 : 0);
20     ((ulong*)(x))[0] = (((ulong*)(x))[0] << 1) ^ t;
21
22 }
23
24 int aes_xts_encrypt(ulong tweak[], ulong ecb[],  vlong sectorNumber, uchar *input, uchar *output, ulong len) {
25         uchar T[16], x[16];
26         int i;
27         
28         if(len % 16 != 0)
29                 return -1;
30
31         for(i=0; i<AesBlockSize; i++) {
32                 T[i] = (uchar)(sectorNumber & 0xFF);
33                 sectorNumber = sectorNumber >> 8;
34         }
35         
36         aes_encrypt(tweak, 10, T, T);
37
38         for (i=0; i<len; i+=AesBlockSize) {
39                 xor128(&x[0], &input[i], &T[0]);
40                 aes_encrypt(ecb, 10, x, x);
41                 xor128(&output[i], &x[0], &T[0]);
42                 gf_mulx(&T[0]);
43         }
44         return 0;
45 }
46
47 int aes_xts_decrypt(ulong tweak[], ulong ecb[], vlong sectorNumber, uchar *input, uchar *output, ulong len) {
48         uchar T[16], x[16];
49         int i;
50         
51         if(len % 16 != 0)
52                 return -1;
53
54         for(i=0; i<AesBlockSize; i++) {
55                 T[i] = (uchar)(sectorNumber & 0xFF);
56                 sectorNumber = sectorNumber >> 8;
57         }
58         
59         aes_encrypt(tweak, 10, T, T);
60
61         for (i=0; i<len; i+=AesBlockSize) {
62                 xor128(&x[0], &input[i], &T[0]);
63                 aes_decrypt(ecb, 10, x, x);
64                 xor128(&output[i], &x[0], &T[0]);
65                 gf_mulx(&T[0]);
66         }
67         return 0;
68 }
69