2
* Generic wrapper for storage encryption modes and Initial Vectors
3
* (reimplementation of some functions from Linux dm-crypt kernel)
5
* Copyright (C) 2014, Milan Broz
7
* This file is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
12
* This file is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this file; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25
#include "crypto_backend.h"
27
#define SECTOR_SHIFT 9
28
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
32
* IV documentation: https://code.google.com/p/cryptsetup/wiki/DMCrypt
34
struct crypt_sector_iv {
35
enum { IV_NONE, IV_NULL, IV_PLAIN, IV_PLAIN64, IV_ESSIV, IV_BENBI } type;
38
struct crypt_cipher *essiv_cipher;
42
/* Block encryption storage context */
43
struct crypt_storage {
44
uint64_t sector_start;
45
struct crypt_cipher *cipher;
46
struct crypt_sector_iv cipher_iv;
49
static int int_log2(unsigned int x)
52
for (x >>= 1; x > 0; x >>= 1)
57
static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
58
const char *cipher_name, const char *iv_name,
59
char *key, size_t key_length)
61
memset(ctx, 0, sizeof(*ctx));
63
ctx->iv_size = crypt_cipher_blocksize(cipher_name);
67
if (!iv_name || !strcmp(cipher_name, "cipher_null")) {
71
} else if (!strcasecmp(iv_name, "null")) {
73
} else if (!strcasecmp(iv_name, "plain64")) {
74
ctx->type = IV_PLAIN64;
75
} else if (!strcasecmp(iv_name, "plain")) {
77
} else if (!strncasecmp(iv_name, "essiv:", 6)) {
78
struct crypt_hash *h = NULL;
79
char *hash_name = strchr(iv_name, ':');
87
hash_size = crypt_hash_size(++hash_name);
91
if ((unsigned)hash_size > sizeof(tmp))
94
if (crypt_hash_init(&h, hash_name))
97
r = crypt_hash_write(h, key, key_length);
99
crypt_hash_destroy(h);
103
r = crypt_hash_final(h, tmp, hash_size);
104
crypt_hash_destroy(h);
106
memset(tmp, 0, sizeof(tmp));
110
r = crypt_cipher_init(&ctx->essiv_cipher, cipher_name, "ecb",
112
memset(tmp, 0, sizeof(tmp));
116
ctx->type = IV_ESSIV;
117
} else if (!strncasecmp(iv_name, "benbi", 5)) {
118
int log = int_log2(ctx->iv_size);
119
if (log > SECTOR_SHIFT)
122
ctx->type = IV_BENBI;
123
ctx->benbi_shift = SECTOR_SHIFT - log;
127
ctx->iv = malloc(ctx->iv_size);
134
static int crypt_sector_iv_generate(struct crypt_sector_iv *ctx, uint64_t sector)
142
memset(ctx->iv, 0, ctx->iv_size);
145
memset(ctx->iv, 0, ctx->iv_size);
146
*(uint32_t *)ctx->iv = cpu_to_le32(sector & 0xffffffff);
149
memset(ctx->iv, 0, ctx->iv_size);
150
*(uint64_t *)ctx->iv = cpu_to_le64(sector);
153
memset(ctx->iv, 0, ctx->iv_size);
154
*(uint64_t *)ctx->iv = cpu_to_le64(sector);
155
return crypt_cipher_encrypt(ctx->essiv_cipher,
156
ctx->iv, ctx->iv, ctx->iv_size, NULL, 0);
159
memset(ctx->iv, 0, ctx->iv_size);
160
val = cpu_to_be64((sector << ctx->benbi_shift) + 1);
161
memcpy(ctx->iv + ctx->iv_size - sizeof(val), &val, sizeof(val));
170
static int crypt_sector_iv_destroy(struct crypt_sector_iv *ctx)
172
if (ctx->type == IV_ESSIV)
173
crypt_cipher_destroy(ctx->essiv_cipher);
176
memset(ctx->iv, 0, ctx->iv_size);
180
memset(ctx, 0, sizeof(*ctx));
184
/* Block encryption storage wrappers */
186
int crypt_storage_init(struct crypt_storage **ctx,
187
uint64_t sector_start,
189
const char *cipher_mode,
190
char *key, size_t key_length)
192
struct crypt_storage *s;
194
char *cipher_iv = NULL;
197
s = malloc(sizeof(*s));
200
memset(s, 0, sizeof(*s));
202
/* Remove IV if present */
203
strncpy(mode_name, cipher_mode, sizeof(mode_name));
204
mode_name[sizeof(mode_name) - 1] = 0;
205
cipher_iv = strchr(mode_name, '-');
211
r = crypt_cipher_init(&s->cipher, cipher, mode_name, key, key_length);
213
crypt_storage_destroy(s);
217
r = crypt_sector_iv_init(&s->cipher_iv, cipher, cipher_iv, key, key_length);
219
crypt_storage_destroy(s);
223
s->sector_start = sector_start;
229
int crypt_storage_decrypt(struct crypt_storage *ctx,
230
uint64_t sector, size_t count,
236
for (i = 0; i < count; i++) {
237
r = crypt_sector_iv_generate(&ctx->cipher_iv, sector + i);
240
r = crypt_cipher_decrypt(ctx->cipher,
241
&buffer[i * SECTOR_SIZE],
242
&buffer[i * SECTOR_SIZE],
245
ctx->cipher_iv.iv_size);
253
int crypt_storage_encrypt(struct crypt_storage *ctx,
254
uint64_t sector, size_t count,
260
for (i = 0; i < count; i++) {
261
r = crypt_sector_iv_generate(&ctx->cipher_iv, sector + i);
264
r = crypt_cipher_encrypt(ctx->cipher,
265
&buffer[i * SECTOR_SIZE],
266
&buffer[i * SECTOR_SIZE],
269
ctx->cipher_iv.iv_size);
277
int crypt_storage_destroy(struct crypt_storage *ctx)
282
crypt_sector_iv_destroy(&ctx->cipher_iv);
285
crypt_cipher_destroy(ctx->cipher);
287
memset(ctx, 0, sizeof(*ctx));