2 * xts.c: AES-XTS implementation
4 * Copyright (C) 2008 Jan Krueger <jk@jk.gs>
6 * This file is part of dmsetup-tc.
8 * dmsetup-tc is free software: you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation, either version 3 of the
11 * License, or (at your option) any later version.
13 * dmsetup-tc is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with dmsetup-tc. If not, see <http://www.gnu.org/licenses/>.
29 * This is a partial implementation of AES-XTS (using libgcrypt for
30 * AES-256). Care was taken to keep the code readable. The algorithm is
31 * explained in various comments.
37 * "Chain-encrypted" blocks of data inside a _data unit_.
40 * Separately encrypted units of data, e.g. disk sectors. Each data unit
41 * uses a different _tweak_ for decryption to prevent a variety of
45 * Usually something like a sector number. More generally, a series of
46 * positive numbers starting at a certain point and increasing by one
47 * for each new data unit.
52 * This code only works on little-endian systems. Fix xts_shift if you care.
54 * Ciphertext stealing is not supported, i.e. the data unit size better be
55 * divisible by the block size.
57 * For simplicity, we limit the tweak to 32 bit values. This is sufficient
58 * for disk encryption for disk sectors below 2 terabytes.
60 * We always assume we're starting to decrypt at the first block, i.e. block
64 #define XTS_BLOCKSIZE 16
66 typedef unsigned int *xts_block32
;
68 const char *aes_xts_err
;
69 const char *aes_xts_errsrc
;
72 * Performs one left shift of the encrypted tweak. We call this after each
73 * round of block decryption so that the value gets shifted further each
76 static void xts_shift(xts_block32 b
)
78 unsigned int x
= (b
[3] & 0x80000000) ? 135 : 0;
79 b
[3] <<= 1; if (b
[2] & 0x80000000) b
[3] |= 1;
80 b
[2] <<= 1; if (b
[1] & 0x80000000) b
[2] |= 1;
81 b
[1] <<= 1; if (b
[0] & 0x80000000) b
[1] |= 1;
82 b
[0] <<= 1; b
[0] ^= x
;
84 static void xts_xor(xts_block32 dst
, xts_block32 src
)
93 * Decrypts a series of blocks. Works in-place if so desired by setting
94 * cipher to NULL (in which case existing ciphertext will be taken from
95 * plain). Of course, overlapping buffers are evil scary verboten). Be sure
96 * to initialize libgcrypt beforehand, too (and have it init secure memory).
98 int aes_xts_decrypt(unsigned char *key
, unsigned char *cipher
, int numblocks
,
99 unsigned int tweak
, unsigned char *plain
)
108 * XTS actually uses twice the key size of the underlying cipher.
109 * The second half of the key is used to encrypt the tweak.
111 char *key2
= (char *) &key
[32];
113 etweak
= (xts_block32
) buf
;
114 memset(etweak
, 0, 16);
117 #define _xts_checkerr(c, x) {err = c;\
118 if (0 != gcry_err_code(err)) {\
119 errno = gcry_err_code_to_errno(err);\
120 aes_xts_err = gcry_strerror(err);\
121 aes_xts_errsrc = gcry_strsource(err);\
122 if (x) gcry_cipher_close(x);\
126 _xts_checkerr(gcry_cipher_open(&hd
, GCRY_CIPHER_AES256
,
127 GCRY_CIPHER_MODE_ECB
, GCRY_CIPHER_SECURE
), 0);
128 _xts_checkerr(gcry_cipher_setkey(hd
, key2
, 32), hd
);
129 _xts_checkerr(gcry_cipher_encrypt(hd
, etweak
, XTS_BLOCKSIZE
, NULL
,
132 /* For the rest we use the main key, i.e. the first half. */
133 _xts_checkerr(gcry_cipher_setkey(hd
, key
, 32), hd
);
135 for (i
= 0; i
< numblocks
; i
++) {
137 xts_xor((xts_block32
) cipher
, etweak
);
138 _xts_checkerr(gcry_cipher_decrypt(hd
, plain
,
139 XTS_BLOCKSIZE
, cipher
, XTS_BLOCKSIZE
), hd
);
140 cipher
+= XTS_BLOCKSIZE
;
142 xts_xor((xts_block32
) plain
, etweak
);
143 _xts_checkerr(gcry_cipher_decrypt(hd
, plain
,
144 XTS_BLOCKSIZE
, NULL
, 0), hd
);
146 xts_xor((xts_block32
) plain
, etweak
);
147 plain
+= XTS_BLOCKSIZE
;
151 gcry_cipher_close(hd
);