14ab7fe2866be9d6b6885b2aa2543213d59ddbc6
[platform/upstream/cryptsetup.git] / lib / crypto_backend / crypto_storage.c
1 /*
2  * Generic wrapper for storage encryption modes and Initial Vectors
3  * (reimplementation of some functions from Linux dm-crypt kernel)
4  *
5  * Copyright (C) 2014-2021 Milan Broz
6  *
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.
11  *
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.
16  *
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.
20  */
21
22 #include <stdlib.h>
23 #include <errno.h>
24 #include "bitops.h"
25 #include "crypto_backend.h"
26
27 #define SECTOR_SHIFT    9
28
29 /*
30  * Internal IV helper
31  * IV documentation: https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt
32  */
33 struct crypt_sector_iv {
34         enum { IV_NONE, IV_NULL, IV_PLAIN, IV_PLAIN64, IV_ESSIV, IV_BENBI, IV_PLAIN64BE, IV_EBOIV } type;
35         int iv_size;
36         char *iv;
37         struct crypt_cipher *cipher;
38         int shift;
39 };
40
41 /* Block encryption storage context */
42 struct crypt_storage {
43         size_t sector_size;
44         unsigned iv_shift;
45         struct crypt_cipher *cipher;
46         struct crypt_sector_iv cipher_iv;
47 };
48
49 static int int_log2(unsigned int x)
50 {
51         int r = 0;
52         for (x >>= 1; x > 0; x >>= 1)
53                 r++;
54         return r;
55 }
56
57 static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
58                          const char *cipher_name, const char *mode_name,
59                          const char *iv_name, const void *key, size_t key_length,
60                          size_t sector_size)
61 {
62         int r;
63
64         memset(ctx, 0, sizeof(*ctx));
65
66         ctx->iv_size = crypt_cipher_ivsize(cipher_name, mode_name);
67         if (ctx->iv_size < 0 || (strcmp(mode_name, "ecb") && ctx->iv_size < 8))
68                 return -ENOENT;
69
70         if (!strcmp(cipher_name, "cipher_null") ||
71             !strcmp(mode_name, "ecb")) {
72                 if (iv_name)
73                         return -EINVAL;
74                 ctx->type = IV_NONE;
75                 ctx->iv_size = 0;
76                 return 0;
77         } else if (!iv_name) {
78                 return -EINVAL;
79         } else if (!strcasecmp(iv_name, "null")) {
80                 ctx->type = IV_NULL;
81         } else if (!strcasecmp(iv_name, "plain64")) {
82                 ctx->type = IV_PLAIN64;
83         } else if (!strcasecmp(iv_name, "plain64be")) {
84                 ctx->type = IV_PLAIN64BE;
85         } else if (!strcasecmp(iv_name, "plain")) {
86                 ctx->type = IV_PLAIN;
87         } else if (!strncasecmp(iv_name, "essiv:", 6)) {
88                 struct crypt_hash *h = NULL;
89                 char *hash_name = strchr(iv_name, ':');
90                 int hash_size;
91                 char tmp[256];
92
93                 if (!hash_name)
94                         return -EINVAL;
95
96                 hash_size = crypt_hash_size(++hash_name);
97                 if (hash_size < 0)
98                         return -ENOENT;
99
100                 if ((unsigned)hash_size > sizeof(tmp))
101                         return -EINVAL;
102
103                 if (crypt_hash_init(&h, hash_name))
104                         return -EINVAL;
105
106                 r = crypt_hash_write(h, key, key_length);
107                 if (r) {
108                         crypt_hash_destroy(h);
109                         return r;
110                 }
111
112                 r = crypt_hash_final(h, tmp, hash_size);
113                 crypt_hash_destroy(h);
114                 if (r) {
115                         crypt_backend_memzero(tmp, sizeof(tmp));
116                         return r;
117                 }
118
119                 r = crypt_cipher_init(&ctx->cipher, cipher_name, "ecb",
120                                       tmp, hash_size);
121                 crypt_backend_memzero(tmp, sizeof(tmp));
122                 if (r)
123                         return r;
124
125                 ctx->type = IV_ESSIV;
126         } else if (!strncasecmp(iv_name, "benbi", 5)) {
127                 int log = int_log2(ctx->iv_size);
128                 if (log > SECTOR_SHIFT)
129                         return -EINVAL;
130
131                 ctx->type = IV_BENBI;
132                 ctx->shift = SECTOR_SHIFT - log;
133         } else if (!strncasecmp(iv_name, "eboiv", 5)) {
134                 r = crypt_cipher_init(&ctx->cipher, cipher_name, "ecb",
135                                       key, key_length);
136                 if (r)
137                         return r;
138
139                 ctx->type = IV_EBOIV;
140                 ctx->shift = int_log2(sector_size);
141         } else
142                 return -ENOENT;
143
144         ctx->iv = malloc(ctx->iv_size);
145         if (!ctx->iv)
146                 return -ENOMEM;
147
148         return 0;
149 }
150
151 static int crypt_sector_iv_generate(struct crypt_sector_iv *ctx, uint64_t sector)
152 {
153         uint64_t val;
154
155         switch (ctx->type) {
156         case IV_NONE:
157                 break;
158         case IV_NULL:
159                 memset(ctx->iv, 0, ctx->iv_size);
160                 break;
161         case IV_PLAIN:
162                 memset(ctx->iv, 0, ctx->iv_size);
163                 *(uint32_t *)ctx->iv = cpu_to_le32(sector & 0xffffffff);
164                 break;
165         case IV_PLAIN64:
166                 memset(ctx->iv, 0, ctx->iv_size);
167                 *(uint64_t *)ctx->iv = cpu_to_le64(sector);
168                 break;
169         case IV_PLAIN64BE:
170                 memset(ctx->iv, 0, ctx->iv_size);
171                 *(uint64_t *)&ctx->iv[ctx->iv_size - sizeof(uint64_t)] = cpu_to_be64(sector);
172                 break;
173         case IV_ESSIV:
174                 memset(ctx->iv, 0, ctx->iv_size);
175                 *(uint64_t *)ctx->iv = cpu_to_le64(sector);
176                 return crypt_cipher_encrypt(ctx->cipher,
177                         ctx->iv, ctx->iv, ctx->iv_size, NULL, 0);
178                 break;
179         case IV_BENBI:
180                 memset(ctx->iv, 0, ctx->iv_size);
181                 val = cpu_to_be64((sector << ctx->shift) + 1);
182                 memcpy(ctx->iv + ctx->iv_size - sizeof(val), &val, sizeof(val));
183                 break;
184         case IV_EBOIV:
185                 memset(ctx->iv, 0, ctx->iv_size);
186                 *(uint64_t *)ctx->iv = cpu_to_le64(sector << ctx->shift);
187                 return crypt_cipher_encrypt(ctx->cipher,
188                         ctx->iv, ctx->iv, ctx->iv_size, NULL, 0);
189                 break;
190         default:
191                 return -EINVAL;
192         }
193
194         return 0;
195 }
196
197 static void crypt_sector_iv_destroy(struct crypt_sector_iv *ctx)
198 {
199         if (ctx->type == IV_ESSIV || ctx->type == IV_EBOIV)
200                 crypt_cipher_destroy(ctx->cipher);
201
202         if (ctx->iv) {
203                 memset(ctx->iv, 0, ctx->iv_size);
204                 free(ctx->iv);
205         }
206
207         memset(ctx, 0, sizeof(*ctx));
208 }
209
210 /* Block encryption storage wrappers */
211
212 int crypt_storage_init(struct crypt_storage **ctx,
213                        size_t sector_size,
214                        const char *cipher,
215                        const char *cipher_mode,
216                        const void *key, size_t key_length,
217                        bool large_iv)
218 {
219         struct crypt_storage *s;
220         char mode_name[64];
221         char *cipher_iv = NULL;
222         int r = -EIO;
223
224         if (sector_size < (1 << SECTOR_SHIFT) ||
225             sector_size > (1 << (SECTOR_SHIFT + 3)) ||
226             sector_size & (sector_size - 1))
227                 return -EINVAL;
228
229         s = malloc(sizeof(*s));
230         if (!s)
231                 return -ENOMEM;
232         memset(s, 0, sizeof(*s));
233
234         /* Remove IV if present */
235         strncpy(mode_name, cipher_mode, sizeof(mode_name));
236         mode_name[sizeof(mode_name) - 1] = 0;
237         cipher_iv = strchr(mode_name, '-');
238         if (cipher_iv) {
239                 *cipher_iv = '\0';
240                 cipher_iv++;
241         }
242
243         r = crypt_cipher_init(&s->cipher, cipher, mode_name, key, key_length);
244         if (r) {
245                 crypt_storage_destroy(s);
246                 return r;
247         }
248
249         r = crypt_sector_iv_init(&s->cipher_iv, cipher, mode_name, cipher_iv, key, key_length, sector_size);
250         if (r) {
251                 crypt_storage_destroy(s);
252                 return r;
253         }
254
255         s->sector_size = sector_size;
256         s->iv_shift = large_iv ? int_log2(sector_size) - SECTOR_SHIFT : 0;
257
258         *ctx = s;
259         return 0;
260 }
261
262 int crypt_storage_decrypt(struct crypt_storage *ctx,
263                        uint64_t iv_offset,
264                        uint64_t length, char *buffer)
265 {
266         uint64_t i;
267         int r = 0;
268
269         if (length & (ctx->sector_size - 1))
270                 return -EINVAL;
271
272         if (iv_offset & ((ctx->sector_size >> SECTOR_SHIFT) - 1))
273                 return -EINVAL;
274
275         for (i = 0; i < length; i += ctx->sector_size) {
276                 r = crypt_sector_iv_generate(&ctx->cipher_iv, (iv_offset + (i >> SECTOR_SHIFT)) >> ctx->iv_shift);
277                 if (r)
278                         break;
279                 r = crypt_cipher_decrypt(ctx->cipher,
280                                          &buffer[i],
281                                          &buffer[i],
282                                          ctx->sector_size,
283                                          ctx->cipher_iv.iv,
284                                          ctx->cipher_iv.iv_size);
285                 if (r)
286                         break;
287         }
288
289         return r;
290 }
291
292 int crypt_storage_encrypt(struct crypt_storage *ctx,
293                        uint64_t iv_offset,
294                        uint64_t length, char *buffer)
295 {
296         uint64_t i;
297         int r = 0;
298
299         if (length & (ctx->sector_size - 1))
300                 return -EINVAL;
301
302         if (iv_offset & ((ctx->sector_size >> SECTOR_SHIFT) - 1))
303                 return -EINVAL;
304
305         for (i = 0; i < length; i += ctx->sector_size) {
306                 r = crypt_sector_iv_generate(&ctx->cipher_iv, (iv_offset + (i >> SECTOR_SHIFT)) >> ctx->iv_shift);
307                 if (r)
308                         break;
309                 r = crypt_cipher_encrypt(ctx->cipher,
310                                          &buffer[i],
311                                          &buffer[i],
312                                          ctx->sector_size,
313                                          ctx->cipher_iv.iv,
314                                          ctx->cipher_iv.iv_size);
315                 if (r)
316                         break;
317         }
318
319         return r;
320 }
321
322 void crypt_storage_destroy(struct crypt_storage *ctx)
323 {
324         if (!ctx)
325                 return;
326
327         crypt_sector_iv_destroy(&ctx->cipher_iv);
328
329         if (ctx->cipher)
330                 crypt_cipher_destroy(ctx->cipher);
331
332         memset(ctx, 0, sizeof(*ctx));
333         free(ctx);
334 }
335
336 bool crypt_storage_kernel_only(struct crypt_storage *ctx)
337 {
338         return crypt_cipher_kernel_only(ctx->cipher);
339 }