2 * Generic wrapper for storage encryption modes and Initial Vectors
3 * (reimplementation of some functions from Linux dm-crypt kernel)
5 * Copyright (C) 2014-2023 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.
26 #include "crypto_backend.h"
28 #define SECTOR_SHIFT 9
32 * IV documentation: https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt
34 struct crypt_sector_iv {
35 enum { IV_NONE, IV_NULL, IV_PLAIN, IV_PLAIN64, IV_ESSIV, IV_BENBI, IV_PLAIN64BE, IV_EBOIV } type;
38 struct crypt_cipher *cipher;
42 /* Block encryption storage context */
43 struct crypt_storage {
46 struct crypt_cipher *cipher;
47 struct crypt_sector_iv cipher_iv;
50 static int int_log2(unsigned int x)
53 for (x >>= 1; x > 0; x >>= 1)
58 static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
59 const char *cipher_name, const char *mode_name,
60 const char *iv_name, const void *key, size_t key_length,
65 memset(ctx, 0, sizeof(*ctx));
67 ctx->iv_size = crypt_cipher_ivsize(cipher_name, mode_name);
68 if (ctx->iv_size < 0 || (strcmp(mode_name, "ecb") && ctx->iv_size < 8))
71 if (!strcmp(cipher_name, "cipher_null") ||
72 !strcmp(mode_name, "ecb")) {
78 } else if (!iv_name) {
80 } else if (!strcasecmp(iv_name, "null")) {
82 } else if (!strcasecmp(iv_name, "plain64")) {
83 ctx->type = IV_PLAIN64;
84 } else if (!strcasecmp(iv_name, "plain64be")) {
85 ctx->type = IV_PLAIN64BE;
86 } else if (!strcasecmp(iv_name, "plain")) {
88 } else if (!strncasecmp(iv_name, "essiv:", 6)) {
89 struct crypt_hash *h = NULL;
90 char *hash_name = strchr(iv_name, ':');
97 hash_size = crypt_hash_size(++hash_name);
101 if ((unsigned)hash_size > sizeof(tmp))
104 if (crypt_hash_init(&h, hash_name))
107 r = crypt_hash_write(h, key, key_length);
109 crypt_hash_destroy(h);
113 r = crypt_hash_final(h, tmp, hash_size);
114 crypt_hash_destroy(h);
116 crypt_backend_memzero(tmp, sizeof(tmp));
120 r = crypt_cipher_init(&ctx->cipher, cipher_name, "ecb",
122 crypt_backend_memzero(tmp, sizeof(tmp));
126 ctx->type = IV_ESSIV;
127 } else if (!strncasecmp(iv_name, "benbi", 5)) {
128 int log = int_log2(ctx->iv_size);
129 if (log > SECTOR_SHIFT)
132 ctx->type = IV_BENBI;
133 ctx->shift = SECTOR_SHIFT - log;
134 } else if (!strncasecmp(iv_name, "eboiv", 5)) {
135 r = crypt_cipher_init(&ctx->cipher, cipher_name, "ecb",
140 ctx->type = IV_EBOIV;
141 ctx->shift = int_log2(sector_size);
145 ctx->iv = malloc(ctx->iv_size);
152 static int crypt_sector_iv_generate(struct crypt_sector_iv *ctx, uint64_t sector)
154 uint64_t val, *u64_iv;
161 memset(ctx->iv, 0, ctx->iv_size);
164 memset(ctx->iv, 0, ctx->iv_size);
165 u32_iv = (void *)ctx->iv;
166 *u32_iv = cpu_to_le32(sector & 0xffffffff);
169 memset(ctx->iv, 0, ctx->iv_size);
170 u64_iv = (void *)ctx->iv;
171 *u64_iv = cpu_to_le64(sector);
174 memset(ctx->iv, 0, ctx->iv_size);
175 /* iv_size is at least of size u64; usually it is 16 bytes */
176 u64_iv = (void *)&ctx->iv[ctx->iv_size - sizeof(uint64_t)];
177 *u64_iv = cpu_to_be64(sector);
180 memset(ctx->iv, 0, ctx->iv_size);
181 u64_iv = (void *)ctx->iv;
182 *u64_iv = cpu_to_le64(sector);
183 return crypt_cipher_encrypt(ctx->cipher,
184 ctx->iv, ctx->iv, ctx->iv_size, NULL, 0);
187 memset(ctx->iv, 0, ctx->iv_size);
188 val = cpu_to_be64((sector << ctx->shift) + 1);
189 memcpy(ctx->iv + ctx->iv_size - sizeof(val), &val, sizeof(val));
192 memset(ctx->iv, 0, ctx->iv_size);
193 u64_iv = (void *)ctx->iv;
194 *u64_iv = cpu_to_le64(sector << ctx->shift);
195 return crypt_cipher_encrypt(ctx->cipher,
196 ctx->iv, ctx->iv, ctx->iv_size, NULL, 0);
205 static void crypt_sector_iv_destroy(struct crypt_sector_iv *ctx)
207 if (ctx->type == IV_ESSIV || ctx->type == IV_EBOIV)
208 crypt_cipher_destroy(ctx->cipher);
211 memset(ctx->iv, 0, ctx->iv_size);
215 memset(ctx, 0, sizeof(*ctx));
218 /* Block encryption storage wrappers */
220 int crypt_storage_init(struct crypt_storage **ctx,
223 const char *cipher_mode,
224 const void *key, size_t key_length,
227 struct crypt_storage *s;
229 char *cipher_iv = NULL;
232 if (sector_size < (1 << SECTOR_SHIFT) ||
233 sector_size > (1 << (SECTOR_SHIFT + 3)) ||
234 sector_size & (sector_size - 1))
237 s = malloc(sizeof(*s));
240 memset(s, 0, sizeof(*s));
242 /* Remove IV if present */
243 strncpy(mode_name, cipher_mode, sizeof(mode_name));
244 mode_name[sizeof(mode_name) - 1] = 0;
245 cipher_iv = strchr(mode_name, '-');
251 r = crypt_cipher_init(&s->cipher, cipher, mode_name, key, key_length);
253 crypt_storage_destroy(s);
257 r = crypt_sector_iv_init(&s->cipher_iv, cipher, mode_name, cipher_iv, key, key_length, sector_size);
259 crypt_storage_destroy(s);
263 s->sector_size = sector_size;
264 s->iv_shift = large_iv ? int_log2(sector_size) - SECTOR_SHIFT : 0;
270 int crypt_storage_decrypt(struct crypt_storage *ctx,
272 uint64_t length, char *buffer)
277 if (length & (ctx->sector_size - 1))
280 if (iv_offset & ((ctx->sector_size >> SECTOR_SHIFT) - 1))
283 for (i = 0; i < length; i += ctx->sector_size) {
284 r = crypt_sector_iv_generate(&ctx->cipher_iv, (iv_offset + (i >> SECTOR_SHIFT)) >> ctx->iv_shift);
287 r = crypt_cipher_decrypt(ctx->cipher,
292 ctx->cipher_iv.iv_size);
300 int crypt_storage_encrypt(struct crypt_storage *ctx,
302 uint64_t length, char *buffer)
307 if (length & (ctx->sector_size - 1))
310 if (iv_offset & ((ctx->sector_size >> SECTOR_SHIFT) - 1))
313 for (i = 0; i < length; i += ctx->sector_size) {
314 r = crypt_sector_iv_generate(&ctx->cipher_iv, (iv_offset + (i >> SECTOR_SHIFT)) >> ctx->iv_shift);
317 r = crypt_cipher_encrypt(ctx->cipher,
322 ctx->cipher_iv.iv_size);
330 void crypt_storage_destroy(struct crypt_storage *ctx)
335 crypt_sector_iv_destroy(&ctx->cipher_iv);
338 crypt_cipher_destroy(ctx->cipher);
340 memset(ctx, 0, sizeof(*ctx));
344 bool crypt_storage_kernel_only(struct crypt_storage *ctx)
346 return crypt_cipher_kernel_only(ctx->cipher);