Line data Source code
1 : /*
2 : * Copyright (C) 2017 sigma star gmbh
3 : *
4 : * This program is free software; you can redistribute it and/or modify it
5 : * under the terms of the GNU General Public License version 2 as published by
6 : * the Free Software Foundation.
7 : *
8 : * This program is distributed in the hope that it will be useful, but WITHOUT
9 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 : * more details.
12 : *
13 : * You should have received a copy of the GNU General Public License along with
14 : * this program; if not, write to the Free Software Foundation, Inc., 51
15 : * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 : *
17 : * Authors: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
18 : */
19 :
20 : #include <openssl/evp.h>
21 : #include <openssl/err.h>
22 : #include <openssl/rand.h>
23 : #include <string.h>
24 : #include <assert.h>
25 :
26 : #include "linux_types.h"
27 : #include "fscrypt.h"
28 : #include "defs.h"
29 : #include "ubifs.h"
30 :
31 640 : static int do_hash(const EVP_MD *md, const unsigned char *in, size_t len, unsigned char *out)
32 : {
33 : unsigned int out_len;
34 640 : EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
35 :
36 640 : if (!mdctx)
37 : return -1;
38 :
39 640 : if (EVP_DigestInit_ex(mdctx, md, NULL) != 1)
40 : return -1;
41 :
42 640 : if(EVP_DigestUpdate(mdctx, in, len) != 1)
43 : return -1;
44 :
45 640 : if(EVP_DigestFinal_ex(mdctx, out, &out_len) != 1)
46 : return -1;
47 :
48 640 : EVP_MD_CTX_destroy(mdctx);
49 :
50 640 : return 0;
51 : }
52 :
53 702720 : static int check_iv_key_size(const EVP_CIPHER *cipher, size_t key_len,
54 : size_t iv_len)
55 : {
56 702720 : if ((size_t)EVP_CIPHER_key_length(cipher) != key_len) {
57 0 : errmsg("Cipher key length mismatch. Expected %lu, got %d",
58 : (unsigned long)key_len, EVP_CIPHER_key_length(cipher));
59 0 : return -1;
60 : }
61 :
62 702720 : if (iv_len && (size_t)EVP_CIPHER_iv_length(cipher) != iv_len) {
63 0 : errmsg("Cipher IV length mismatch. Expected %lu, got %d",
64 : (unsigned long)iv_len, EVP_CIPHER_key_length(cipher));
65 0 : return -1;
66 : }
67 :
68 : return 0;
69 : }
70 :
71 702720 : static ssize_t do_encrypt(const EVP_CIPHER *cipher,
72 : const void *plaintext, size_t size,
73 : const void *key, size_t key_len,
74 : const void *iv, size_t iv_len,
75 : void *ciphertext)
76 : {
77 : int ciphertext_len, len;
78 : EVP_CIPHER_CTX *ctx;
79 :
80 702720 : if (check_iv_key_size(cipher, key_len, iv_len))
81 : return -1;
82 :
83 702720 : if (!(ctx = EVP_CIPHER_CTX_new()))
84 : goto fail;
85 :
86 702720 : EVP_CIPHER_CTX_set_padding(ctx, 0);
87 :
88 702720 : if (EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv) != 1)
89 : goto fail_ctx;
90 :
91 702720 : if (EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, size) != 1)
92 : goto fail_ctx;
93 :
94 702720 : ciphertext_len = len;
95 :
96 702720 : if (cipher == EVP_aes_256_xts()) {
97 301440 : if (EVP_EncryptFinal(ctx, ciphertext + ciphertext_len, &len) != 1)
98 : goto fail_ctx;
99 :
100 301440 : ciphertext_len += len;
101 : }
102 :
103 702720 : EVP_CIPHER_CTX_free(ctx);
104 702720 : return ciphertext_len;
105 0 : fail_ctx:
106 0 : ERR_print_errors_fp(stderr);
107 0 : EVP_CIPHER_CTX_free(ctx);
108 0 : return -1;
109 0 : fail:
110 0 : ERR_print_errors_fp(stderr);
111 0 : return -1;
112 : }
113 :
114 0 : static ssize_t gen_essiv_salt(const void *iv, size_t iv_len, const void *key, size_t key_len, void *salt)
115 : {
116 : size_t ret;
117 : const EVP_CIPHER *cipher;
118 0 : void *sha256 = xzalloc(EVP_MD_size(EVP_sha256()));
119 :
120 0 : cipher = EVP_aes_256_ecb();
121 0 : if (!cipher) {
122 0 : errmsg("OpenSSL: Cipher AES-256-ECB is not supported");
123 0 : goto fail;
124 : }
125 :
126 0 : if (do_hash(EVP_sha256(), key, key_len, sha256) != 0) {
127 0 : errmsg("sha256 failed");
128 0 : goto fail;
129 : }
130 :
131 0 : ret = do_encrypt(cipher, iv, iv_len, sha256, EVP_MD_size(EVP_sha256()), NULL, 0, salt);
132 0 : if (ret != iv_len) {
133 0 : errmsg("Unable to compute ESSIV salt, return value %zi instead of %zi", ret, iv_len);
134 0 : goto fail;
135 : }
136 :
137 0 : free(sha256);
138 :
139 0 : return ret;
140 0 : fail:
141 0 : free(sha256);
142 0 : return -1;
143 : }
144 :
145 301440 : static ssize_t encrypt_block(const void *plaintext, size_t size,
146 : const void *key, uint64_t block_index,
147 : void *ciphertext, const EVP_CIPHER *cipher)
148 : {
149 : size_t key_len, ivsize;
150 : void *tweak;
151 : struct {
152 : uint64_t index;
153 : uint8_t padding[FS_IV_SIZE - sizeof(uint64_t)];
154 : } iv;
155 :
156 301440 : ivsize = EVP_CIPHER_iv_length(cipher);
157 301440 : key_len = EVP_CIPHER_key_length(cipher);
158 :
159 301440 : iv.index = cpu_to_le64(block_index);
160 301440 : memset(iv.padding, 0, sizeof(iv.padding));
161 :
162 301440 : if (cipher == EVP_aes_128_cbc()) {
163 0 : tweak = alloca(ivsize);
164 0 : if (gen_essiv_salt(&iv, FS_IV_SIZE, key, key_len, tweak) < 0)
165 : return -1;
166 : } else {
167 : tweak = &iv;
168 : }
169 :
170 301440 : return do_encrypt(cipher, plaintext, size, key, key_len, tweak,
171 : ivsize, ciphertext);
172 : }
173 :
174 0 : static ssize_t encrypt_block_aes128_cbc(const void *plaintext, size_t size,
175 : const void *key, uint64_t block_index,
176 : void *ciphertext)
177 : {
178 0 : const EVP_CIPHER *cipher = EVP_aes_128_cbc();
179 :
180 0 : if (!cipher) {
181 0 : errmsg("OpenSSL: Cipher AES-128-CBC is not supported");
182 0 : return -1;
183 : }
184 0 : return encrypt_block(plaintext, size, key, block_index,
185 : ciphertext, cipher);
186 : }
187 :
188 301440 : static ssize_t encrypt_block_aes256_xts(const void *plaintext, size_t size,
189 : const void *key, uint64_t block_index,
190 : void *ciphertext)
191 : {
192 301440 : const EVP_CIPHER *cipher = EVP_aes_256_xts();
193 :
194 301440 : if (!cipher) {
195 0 : errmsg("OpenSSL: Cipher AES-256-XTS is not supported");
196 0 : return -1;
197 : }
198 301440 : return encrypt_block(plaintext, size, key, block_index,
199 : ciphertext, cipher);
200 : }
201 :
202 3840 : static void block_swap(uint8_t *ciphertext, size_t i0, size_t i1,
203 : size_t size)
204 3840 : {
205 3840 : uint8_t temp[size], *p0, *p1;
206 :
207 3840 : p0 = ciphertext + i0 * size;
208 3840 : p1 = ciphertext + i1 * size;
209 :
210 3840 : memcpy(temp, p0, size);
211 3840 : memcpy(p0, p1, size);
212 3840 : memcpy(p1, temp, size);
213 3840 : }
214 :
215 49920 : static ssize_t encrypt_cbc_cts(const void *plaintext, size_t size,
216 : const void *key, void *ciphertext,
217 : const EVP_CIPHER *cipher)
218 : {
219 : size_t diff, padded_size, count, ivsize;
220 : uint8_t iv[EVP_MAX_IV_LENGTH], *padded;
221 : ssize_t ret, key_len;
222 :
223 49920 : key_len = EVP_CIPHER_key_length(cipher);
224 49920 : ivsize = EVP_CIPHER_iv_length(cipher);
225 :
226 49920 : memset(iv, 0, ivsize);
227 :
228 49920 : diff = size % ivsize;
229 :
230 49920 : if (diff) {
231 3520 : padded_size = size - diff + ivsize;
232 3520 : padded = size > 256 ? malloc(padded_size) : alloca(padded_size);
233 :
234 3520 : memcpy(padded, plaintext, size);
235 3520 : memset(padded + size, 0, padded_size - size);
236 :
237 3520 : ret = do_encrypt(cipher, padded, padded_size, key, key_len,
238 : iv, ivsize, ciphertext);
239 :
240 3520 : if (size > 256)
241 2880 : free(padded);
242 : } else {
243 46400 : ret = do_encrypt(cipher, plaintext, size, key, key_len,
244 : iv, ivsize, ciphertext);
245 : }
246 :
247 49920 : if (ret < 0)
248 : return ret;
249 :
250 49920 : count = ret / ivsize;
251 :
252 49920 : if (count > 1)
253 3840 : block_swap(ciphertext, count - 2, count - 1, ivsize);
254 :
255 49920 : return size;
256 : }
257 :
258 0 : static ssize_t encrypt_aes128_cbc_cts(const void *plaintext, size_t size,
259 : const void *key, void *ciphertext)
260 : {
261 0 : const EVP_CIPHER *cipher = EVP_aes_128_cbc();
262 0 : if (!cipher) {
263 0 : errmsg("OpenSSL: Cipher AES-128-CBC is not supported");
264 0 : return -1;
265 : }
266 :
267 0 : return encrypt_cbc_cts(plaintext, size, key, ciphertext, cipher);
268 : }
269 :
270 49920 : static ssize_t encrypt_aes256_cbc_cts(const void *plaintext, size_t size,
271 : const void *key, void *ciphertext)
272 : {
273 49920 : const EVP_CIPHER *cipher = EVP_aes_256_cbc();
274 49920 : if (!cipher) {
275 0 : errmsg("OpenSSL: Cipher AES-256-CBC is not supported");
276 0 : return -1;
277 : }
278 :
279 49920 : return encrypt_cbc_cts(plaintext, size, key, ciphertext, cipher);
280 : }
281 :
282 351360 : ssize_t derive_key_aes(const void *deriving_key, const void *source_key,
283 : size_t source_key_len, void *derived_key)
284 : {
285 : const EVP_CIPHER *cipher;
286 : size_t aes_key_len;
287 :
288 351360 : cipher = EVP_aes_128_ecb();
289 351360 : if (!cipher) {
290 0 : errmsg("OpenSSL: Cipher AES-128-ECB is not supported");
291 0 : return -1;
292 : }
293 351360 : aes_key_len = EVP_CIPHER_key_length(cipher);
294 :
295 351360 : return do_encrypt(cipher, source_key, source_key_len, deriving_key,
296 : aes_key_len, NULL, 0, derived_key);
297 : }
298 :
299 320 : int derive_key_descriptor(const void *source_key, void *descriptor)
300 : {
301 320 : int ret = -1;
302 640 : void *hash1 = xzalloc(EVP_MD_size(EVP_sha512()));
303 640 : void *hash2 = xzalloc(EVP_MD_size(EVP_sha512()));
304 :
305 320 : if (do_hash(EVP_sha512(), source_key, FS_MAX_KEY_SIZE, hash1) != 0)
306 : goto out;
307 :
308 320 : if (do_hash(EVP_sha512(), hash1, EVP_MD_size(EVP_sha512()), hash2) != 0)
309 : goto out;
310 :
311 320 : memcpy(descriptor, hash2, FS_KEY_DESCRIPTOR_SIZE);
312 :
313 320 : ret = 0;
314 320 : out:
315 320 : free(hash1);
316 320 : free(hash2);
317 320 : return ret;
318 : }
319 :
320 : static struct cipher ciphers[] = {
321 : {
322 : .name = "AES-128-CBC",
323 : .key_length = 16,
324 : .encrypt_block = encrypt_block_aes128_cbc,
325 : .encrypt_fname = encrypt_aes128_cbc_cts,
326 : .fscrypt_block_mode = FS_ENCRYPTION_MODE_AES_128_CBC,
327 : .fscrypt_fname_mode = FS_ENCRYPTION_MODE_AES_128_CTS,
328 : }, {
329 : .name = "AES-256-XTS",
330 : .key_length = 64,
331 : .encrypt_block = encrypt_block_aes256_xts,
332 : .encrypt_fname = encrypt_aes256_cbc_cts,
333 : .fscrypt_block_mode = FS_ENCRYPTION_MODE_AES_256_XTS,
334 : .fscrypt_fname_mode = FS_ENCRYPTION_MODE_AES_256_CTS,
335 : }
336 : };
337 :
338 640 : int crypto_init(void)
339 : {
340 640 : ERR_load_crypto_strings();
341 640 : RAND_poll();
342 640 : return 0;
343 : }
344 :
345 640 : void crypto_cleanup(void)
346 : {
347 : EVP_cleanup();
348 : ERR_free_strings();
349 640 : }
350 :
351 320 : struct cipher *get_cipher(const char *name)
352 : {
353 : size_t i;
354 :
355 640 : for (i = 0; i < sizeof(ciphers) / sizeof(ciphers[0]); ++i) {
356 640 : if (!strcmp(ciphers[i].name, name))
357 320 : return ciphers + i;
358 : }
359 :
360 : return NULL;
361 : }
362 :
363 0 : void list_ciphers(FILE *fp)
364 : {
365 : size_t i;
366 :
367 0 : for (i = 0; i < sizeof(ciphers) / sizeof(ciphers[0]); ++i) {
368 0 : fprintf(fp, "\t%s\n", ciphers[i].name);
369 : }
370 0 : }
|