Merge branch 'vendor/BYACC'
[dragonfly.git] / lib / libtcplay / hdr.c
1 /*
2  * Copyright (c) 2011 Alex Hornung <alex@alexhornung.com>.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in
13  *    the documentation and/or other materials provided with the
14  *    distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
20  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
22  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/types.h>
31
32 #if defined(__DragonFly__)
33 #include <sys/endian.h>
34 #elif defined(__linux__)
35 #include <endian.h>
36 #endif
37 #include <errno.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <inttypes.h>
41 #include <string.h>
42
43 #include "crc32.h"
44 #include "tcplay.h"
45
46 /* Endianess macros */
47 #define BE_TO_HOST(n, v) v = be ## n ## toh(v)
48 #define LE_TO_HOST(n, v) v = le ## n ## toh(v)
49 #define HOST_TO_BE(n, v) v = htobe ## n (v)
50 #define HOST_TO_LE(n, v) v = htole ## n (v)
51
52 struct tchdr_dec *
53 decrypt_hdr(struct tchdr_enc *ehdr, struct tc_cipher_chain *cipher_chain,
54     unsigned char *key)
55 {
56         struct tchdr_dec *dhdr;
57         unsigned char iv[128];
58         int error;
59
60         if ((dhdr = alloc_safe_mem(sizeof(struct tchdr_dec))) == NULL) {
61                 tc_log(1, "Error allocating safe tchdr_dec memory\n");
62                 return NULL;
63         }
64
65         memset(iv, 0, sizeof(iv));
66
67         error = tc_decrypt(cipher_chain, key, iv, ehdr->enc,
68             sizeof(struct tchdr_dec), (unsigned char *)dhdr);
69         if (error) {
70                 tc_log(1, "Header decryption failed\n");
71                 free_safe_mem(dhdr);
72                 return NULL;
73         }
74
75         BE_TO_HOST(16, dhdr->tc_ver);
76         LE_TO_HOST(16, dhdr->tc_min_ver);
77         BE_TO_HOST(32, dhdr->crc_keys);
78         BE_TO_HOST(64, dhdr->vol_ctime);
79         BE_TO_HOST(64, dhdr->hdr_ctime);
80         BE_TO_HOST(64, dhdr->sz_hidvol);
81         BE_TO_HOST(64, dhdr->sz_vol);
82         BE_TO_HOST(64, dhdr->off_mk_scope);
83         BE_TO_HOST(64, dhdr->sz_mk_scope);
84         BE_TO_HOST(32, dhdr->flags);
85         BE_TO_HOST(32, dhdr->sec_sz);
86         BE_TO_HOST(32, dhdr->crc_dhdr);
87
88         return dhdr;
89 }
90
91 int
92 verify_hdr(struct tchdr_dec *hdr)
93 {
94         uint32_t crc;
95
96         if (memcmp(hdr->tc_str, TC_SIG, sizeof(hdr->tc_str)) != 0) {
97 #ifdef DEBUG
98                 fprintf(stderr, "Signature mismatch\n");
99 #endif
100                 return 0;
101         }
102
103         crc = crc32((void *)&hdr->keys, 256);
104         if (crc != hdr->crc_keys) {
105 #ifdef DEBUG
106                 fprintf(stderr, "CRC32 mismatch (crc_keys)\n");
107 #endif
108                 return 0;
109         }
110
111         switch(hdr->tc_ver) {
112         case 1:
113         case 2:
114                 /* Unsupported header version */
115                 tc_log(1, "Header version %d unsupported\n", hdr->tc_ver);
116                 return 0;
117
118         case 3:
119         case 4:
120                 hdr->sec_sz = 512;
121                 break;
122         }
123
124         return 1;
125 }
126
127 struct tchdr_enc *
128 create_hdr(unsigned char *pass, int passlen, struct pbkdf_prf_algo *prf_algo,
129     struct tc_cipher_chain *cipher_chain, size_t sec_sz,
130     disksz_t total_blocks __unused,
131     off_t offset, disksz_t blocks, int hidden, int weak, struct tchdr_enc **backup_hdr)
132 {
133         struct tchdr_enc *ehdr, *ehdr_backup;
134         struct tchdr_dec *dhdr;
135         unsigned char *key, *key_backup;
136         unsigned char iv[128];
137         int error;
138
139         key = key_backup = NULL;
140         dhdr = NULL;
141         ehdr = ehdr_backup = NULL;
142
143         if (backup_hdr != NULL)
144                 *backup_hdr = NULL;
145
146         if ((dhdr = (struct tchdr_dec *)alloc_safe_mem(sizeof(*dhdr))) == NULL) {
147                 tc_log(1, "could not allocate safe dhdr memory\n");
148                 goto error;
149         }
150
151         if ((ehdr = (struct tchdr_enc *)alloc_safe_mem(sizeof(*ehdr))) == NULL) {
152                 tc_log(1, "could not allocate safe ehdr memory\n");
153                 goto error;
154         }
155
156         if ((ehdr_backup = (struct tchdr_enc *)alloc_safe_mem
157             (sizeof(*ehdr_backup))) == NULL) {
158                 tc_log(1, "could not allocate safe ehdr_backup memory\n");
159                 goto error;
160         }
161
162         if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
163                 tc_log(1, "could not allocate safe key memory\n");
164                 goto error;
165         }
166
167         if ((key_backup = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
168                 tc_log(1, "could not allocate safe backup key memory\n");
169                 goto error;
170         }
171
172         if ((error = get_random(ehdr->salt, sizeof(ehdr->salt), weak)) != 0) {
173                 tc_log(1, "could not get salt\n");
174                 goto error;
175         }
176
177         if ((error = get_random(ehdr_backup->salt, sizeof(ehdr_backup->salt), weak))
178             != 0) {
179                 tc_log(1, "could not get salt for backup header\n");
180                 goto error;
181         }
182
183         error = pbkdf2(prf_algo, (char *)pass, passlen,
184             ehdr->salt, sizeof(ehdr->salt),
185             MAX_KEYSZ, key);
186         if (error) {
187                 tc_log(1, "could not derive key\n");
188                 goto error;
189         }
190
191         error = pbkdf2(prf_algo, (char *)pass, passlen,
192             ehdr_backup->salt, sizeof(ehdr_backup->salt),
193             MAX_KEYSZ, key_backup);
194         if (error) {
195                 tc_log(1, "could not derive backup key\n");
196                 goto error;
197         }
198
199         memset(dhdr, 0, sizeof(*dhdr));
200
201         if ((error = get_random(dhdr->keys, sizeof(dhdr->keys), weak)) != 0) {
202                 tc_log(1, "could not get key random bits\n");
203                 goto error;
204         }
205
206         memcpy(dhdr->tc_str, "TRUE", 4);
207         dhdr->tc_ver = 5;
208         dhdr->tc_min_ver = 7;
209         dhdr->crc_keys = crc32((void *)&dhdr->keys, 256);
210         dhdr->sz_vol = blocks * sec_sz;
211         if (hidden)
212                 dhdr->sz_hidvol = dhdr->sz_vol;
213         dhdr->off_mk_scope = offset * sec_sz;
214         dhdr->sz_mk_scope = blocks * sec_sz;
215         dhdr->sec_sz = sec_sz;
216         dhdr->flags = 0;
217
218         HOST_TO_BE(16, dhdr->tc_ver);
219         HOST_TO_LE(16, dhdr->tc_min_ver);
220         HOST_TO_BE(32, dhdr->crc_keys);
221         HOST_TO_BE(64, dhdr->sz_vol);
222         HOST_TO_BE(64, dhdr->sz_hidvol);
223         HOST_TO_BE(64, dhdr->off_mk_scope);
224         HOST_TO_BE(64, dhdr->sz_mk_scope);
225         HOST_TO_BE(32, dhdr->sec_sz);
226         HOST_TO_BE(32, dhdr->flags);
227
228         dhdr->crc_dhdr = crc32((void *)dhdr, 188);
229         HOST_TO_BE(32, dhdr->crc_dhdr);
230
231         memset(iv, 0, sizeof(iv));
232         error = tc_encrypt(cipher_chain, key, iv, (unsigned char *)dhdr,
233             sizeof(struct tchdr_dec), ehdr->enc);
234         if (error) {
235                 tc_log(1, "Header encryption failed\n");
236                 goto error;
237         }
238
239         memset(iv, 0, sizeof(iv));
240         error = tc_encrypt(cipher_chain, key_backup, iv,
241             (unsigned char *)dhdr,
242             sizeof(struct tchdr_dec), ehdr_backup->enc);
243         if (error) {
244                 tc_log(1, "Backup header encryption failed\n");
245                 goto error;
246         }
247
248         free_safe_mem(key);
249         free_safe_mem(key_backup);
250         free_safe_mem(dhdr);
251
252         if (backup_hdr != NULL)
253                 *backup_hdr = ehdr_backup;
254         else
255                 free_safe_mem(ehdr_backup);
256
257         return ehdr;
258         /* NOT REACHED */
259
260 error:
261         if (key)
262                 free_safe_mem(key);
263         if (key_backup)
264                 free_safe_mem(key_backup);
265         if (dhdr)
266                 free_safe_mem(dhdr);
267         if (ehdr)
268                 free_safe_mem(ehdr);
269         if (ehdr_backup)
270                 free_safe_mem(ehdr_backup);
271
272         return NULL;
273 }
274
275 struct tchdr_enc *copy_reencrypt_hdr(unsigned char *pass, int passlen,
276     struct pbkdf_prf_algo *prf_algo, int weak, struct tcplay_info *info,
277     struct tchdr_enc **backup_hdr)
278 {
279         struct tchdr_enc *ehdr, *ehdr_backup;
280         unsigned char *key, *key_backup;
281         unsigned char iv[128];
282         int error;
283
284         key = key_backup = NULL;
285         ehdr = ehdr_backup = NULL;
286
287         /* By default stick to current PRF algo */
288         if (prf_algo == NULL)
289                 prf_algo = info->pbkdf_prf;
290
291         if ((ehdr = (struct tchdr_enc *)alloc_safe_mem(sizeof(*ehdr))) == NULL) {
292                 tc_log(1, "could not allocate safe ehdr memory\n");
293                 goto error;
294         }
295
296         if ((ehdr_backup = (struct tchdr_enc *)alloc_safe_mem
297             (sizeof(*ehdr_backup))) == NULL) {
298                 tc_log(1, "could not allocate safe ehdr_backup memory\n");
299                 goto error;
300         }
301
302         if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
303                 tc_log(1, "could not allocate safe key memory\n");
304                 goto error;
305         }
306
307         if ((key_backup = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
308                 tc_log(1, "could not allocate safe backup key memory\n");
309                 goto error;
310         }
311
312         if ((error = get_random(ehdr->salt, sizeof(ehdr->salt), weak)) != 0) {
313                 tc_log(1, "could not get salt\n");
314                 goto error;
315         }
316
317         if ((error = get_random(ehdr_backup->salt, sizeof(ehdr_backup->salt), weak))
318             != 0) {
319                 tc_log(1, "could not get salt for backup header\n");
320                 goto error;
321         }
322
323         error = pbkdf2(prf_algo, (char *)pass, passlen,
324             ehdr->salt, sizeof(ehdr->salt),
325             MAX_KEYSZ, key);
326         if (error) {
327                 tc_log(1, "could not derive key\n");
328                 goto error;
329         }
330
331         error = pbkdf2(prf_algo, (char *)pass, passlen,
332             ehdr_backup->salt, sizeof(ehdr_backup->salt),
333             MAX_KEYSZ, key_backup);
334         if (error) {
335                 tc_log(1, "could not derive backup key\n");
336                 goto error;
337         }
338
339         HOST_TO_BE(16, info->hdr->tc_ver);
340         HOST_TO_LE(16, info->hdr->tc_min_ver);
341         HOST_TO_BE(32, info->hdr->crc_keys);
342         HOST_TO_BE(64, info->hdr->vol_ctime);
343         HOST_TO_BE(64, info->hdr->hdr_ctime);
344         HOST_TO_BE(64, info->hdr->sz_vol);
345         HOST_TO_BE(64, info->hdr->sz_hidvol);
346         HOST_TO_BE(64, info->hdr->off_mk_scope);
347         HOST_TO_BE(64, info->hdr->sz_mk_scope);
348         HOST_TO_BE(32, info->hdr->sec_sz);
349         HOST_TO_BE(32, info->hdr->flags);
350         HOST_TO_BE(32, info->hdr->crc_dhdr);
351
352         memset(iv, 0, sizeof(iv));
353         error = tc_encrypt(info->cipher_chain, key, iv,
354             (unsigned char *)info->hdr, sizeof(struct tchdr_dec), ehdr->enc);
355         if (error) {
356                 tc_log(1, "Header encryption failed\n");
357                 goto error;
358         }
359
360         memset(iv, 0, sizeof(iv));
361         error = tc_encrypt(info->cipher_chain, key_backup, iv,
362             (unsigned char *)info->hdr,
363             sizeof(struct tchdr_dec), ehdr_backup->enc);
364         if (error) {
365                 tc_log(1, "Backup header encryption failed\n");
366                 goto error;
367         }
368
369         free_safe_mem(key);
370         free_safe_mem(key_backup);
371
372         if (backup_hdr != NULL)
373                 *backup_hdr = ehdr_backup;
374         else
375                 free_safe_mem(ehdr_backup);
376
377         return ehdr;
378         /* NOT REACHED */
379
380 error:
381         if (key)
382                 free_safe_mem(key);
383         if (key_backup)
384                 free_safe_mem(key_backup);
385         if (ehdr)
386                 free_safe_mem(ehdr);
387         if (ehdr_backup)
388                 free_safe_mem(ehdr_backup);
389
390         return NULL;
391 }