nrelease - fix/improve livecd
[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 sig_hdr_cfg {
53         const char      *sig;
54         uint16_t        min_ver;
55 };
56
57 struct sig_hdr_cfg sig_hdr_cfgs[] = {
58         { TC_SIG,       0x0007 },
59         { VC_SIG,       0x0b01 },
60         { NULL,         0x0000 }
61 };
62
63 static
64 const
65 struct sig_hdr_cfg *hdr_cfg_from_sig(const char *sig)
66 {
67         const struct sig_hdr_cfg *cfg;
68
69         for (cfg = &sig_hdr_cfgs[0]; cfg->sig != NULL; cfg++) {
70                 if (strcmp(cfg->sig, sig) == 0)
71                         return cfg;
72         }
73
74         return NULL;
75 }
76
77 struct tchdr_dec *
78 decrypt_hdr(struct tchdr_enc *ehdr, struct tc_cipher_chain *cipher_chain,
79     unsigned char *key)
80 {
81         struct tchdr_dec *dhdr;
82         unsigned char iv[128];
83         int error;
84
85         if ((dhdr = alloc_safe_mem(sizeof(struct tchdr_dec))) == NULL) {
86                 tc_log(1, "Error allocating safe tchdr_dec memory\n");
87                 return NULL;
88         }
89
90         memset(iv, 0, sizeof(iv));
91
92         error = tc_decrypt(cipher_chain, key, iv, ehdr->enc,
93             sizeof(struct tchdr_dec), (unsigned char *)dhdr);
94         if (error) {
95                 tc_log(1, "Header decryption failed\n");
96                 free_safe_mem(dhdr);
97                 return NULL;
98         }
99
100         BE_TO_HOST(16, dhdr->tc_ver);
101         LE_TO_HOST(16, dhdr->tc_min_ver);
102         BE_TO_HOST(32, dhdr->crc_keys);
103         BE_TO_HOST(64, dhdr->vol_ctime);
104         BE_TO_HOST(64, dhdr->hdr_ctime);
105         BE_TO_HOST(64, dhdr->sz_hidvol);
106         BE_TO_HOST(64, dhdr->sz_vol);
107         BE_TO_HOST(64, dhdr->off_mk_scope);
108         BE_TO_HOST(64, dhdr->sz_mk_scope);
109         BE_TO_HOST(32, dhdr->flags);
110         BE_TO_HOST(32, dhdr->sec_sz);
111         BE_TO_HOST(32, dhdr->crc_dhdr);
112
113         return dhdr;
114 }
115
116 int
117 verify_hdr(struct tchdr_dec *hdr, struct pbkdf_prf_algo *prf_algo)
118 {
119         uint32_t crc;
120
121         if (memcmp(hdr->tc_str, prf_algo->sig, sizeof(hdr->tc_str)) != 0) {
122 #ifdef DEBUG
123                 fprintf(stderr, "Signature mismatch\n");
124 #endif
125                 return 0;
126         }
127
128         crc = crc32((void *)&hdr->keys, 256);
129         if (crc != hdr->crc_keys) {
130 #ifdef DEBUG
131                 fprintf(stderr, "CRC32 mismatch (crc_keys)\n");
132 #endif
133                 return 0;
134         }
135
136         switch(hdr->tc_ver) {
137         case 1:
138         case 2:
139                 /* Unsupported header version */
140                 tc_log(1, "Header version %d unsupported\n", hdr->tc_ver);
141                 return 0;
142
143         case 3:
144         case 4:
145                 hdr->sec_sz = 512;
146                 break;
147         }
148
149         return 1;
150 }
151
152 struct tchdr_enc *
153 create_hdr(unsigned char *pass, int passlen, struct pbkdf_prf_algo *prf_algo,
154     struct tc_cipher_chain *cipher_chain, size_t sec_sz,
155     disksz_t total_blocks __unused,
156     off_t offset, disksz_t blocks, int hidden, int weak, struct tchdr_enc **backup_hdr)
157 {
158         struct tchdr_enc *ehdr, *ehdr_backup;
159         struct tchdr_dec *dhdr;
160         unsigned char *key, *key_backup;
161         unsigned char iv[128];
162         const struct sig_hdr_cfg *hdr_cfg;
163         int error;
164
165         key = key_backup = NULL;
166         dhdr = NULL;
167         ehdr = ehdr_backup = NULL;
168
169         if (backup_hdr != NULL)
170                 *backup_hdr = NULL;
171
172         if ((dhdr = (struct tchdr_dec *)alloc_safe_mem(sizeof(*dhdr))) == NULL) {
173                 tc_log(1, "could not allocate safe dhdr memory\n");
174                 goto error;
175         }
176
177         if ((ehdr = (struct tchdr_enc *)alloc_safe_mem(sizeof(*ehdr))) == NULL) {
178                 tc_log(1, "could not allocate safe ehdr memory\n");
179                 goto error;
180         }
181
182         if ((ehdr_backup = (struct tchdr_enc *)alloc_safe_mem
183             (sizeof(*ehdr_backup))) == NULL) {
184                 tc_log(1, "could not allocate safe ehdr_backup memory\n");
185                 goto error;
186         }
187
188         if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
189                 tc_log(1, "could not allocate safe key memory\n");
190                 goto error;
191         }
192
193         if ((key_backup = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
194                 tc_log(1, "could not allocate safe backup key memory\n");
195                 goto error;
196         }
197
198         if ((error = get_random(ehdr->salt, sizeof(ehdr->salt), weak)) != 0) {
199                 tc_log(1, "could not get salt\n");
200                 goto error;
201         }
202
203         if ((error = get_random(ehdr_backup->salt, sizeof(ehdr_backup->salt), weak))
204             != 0) {
205                 tc_log(1, "could not get salt for backup header\n");
206                 goto error;
207         }
208
209         error = pbkdf2(prf_algo, (char *)pass, passlen,
210             ehdr->salt, sizeof(ehdr->salt),
211             MAX_KEYSZ, key);
212         if (error) {
213                 tc_log(1, "could not derive key\n");
214                 goto error;
215         }
216
217         error = pbkdf2(prf_algo, (char *)pass, passlen,
218             ehdr_backup->salt, sizeof(ehdr_backup->salt),
219             MAX_KEYSZ, key_backup);
220         if (error) {
221                 tc_log(1, "could not derive backup key\n");
222                 goto error;
223         }
224
225         memset(dhdr, 0, sizeof(*dhdr));
226
227         if ((error = get_random(dhdr->keys, sizeof(dhdr->keys), weak)) != 0) {
228                 tc_log(1, "could not get key random bits\n");
229                 goto error;
230         }
231
232         if ((hdr_cfg = hdr_cfg_from_sig(prf_algo->sig)) == NULL) {
233                 tc_log(1, "could not find internal header configuration\n");
234                 goto error;
235         }
236
237         memcpy(dhdr->tc_str, prf_algo->sig, 4);
238         dhdr->tc_ver = 5;
239         dhdr->tc_min_ver = hdr_cfg->min_ver;
240         dhdr->crc_keys = crc32((void *)&dhdr->keys, 256);
241         dhdr->sz_vol = blocks * sec_sz;
242         if (hidden)
243                 dhdr->sz_hidvol = dhdr->sz_vol;
244         dhdr->off_mk_scope = offset * sec_sz;
245         dhdr->sz_mk_scope = blocks * sec_sz;
246         dhdr->sec_sz = sec_sz;
247         dhdr->flags = 0;
248
249         HOST_TO_BE(16, dhdr->tc_ver);
250         HOST_TO_LE(16, dhdr->tc_min_ver);
251         HOST_TO_BE(32, dhdr->crc_keys);
252         HOST_TO_BE(64, dhdr->sz_vol);
253         HOST_TO_BE(64, dhdr->sz_hidvol);
254         HOST_TO_BE(64, dhdr->off_mk_scope);
255         HOST_TO_BE(64, dhdr->sz_mk_scope);
256         HOST_TO_BE(32, dhdr->sec_sz);
257         HOST_TO_BE(32, dhdr->flags);
258
259         dhdr->crc_dhdr = crc32((void *)dhdr, 188);
260         HOST_TO_BE(32, dhdr->crc_dhdr);
261
262         memset(iv, 0, sizeof(iv));
263         error = tc_encrypt(cipher_chain, key, iv, (unsigned char *)dhdr,
264             sizeof(struct tchdr_dec), ehdr->enc);
265         if (error) {
266                 tc_log(1, "Header encryption failed\n");
267                 goto error;
268         }
269
270         memset(iv, 0, sizeof(iv));
271         error = tc_encrypt(cipher_chain, key_backup, iv,
272             (unsigned char *)dhdr,
273             sizeof(struct tchdr_dec), ehdr_backup->enc);
274         if (error) {
275                 tc_log(1, "Backup header encryption failed\n");
276                 goto error;
277         }
278
279         free_safe_mem(key);
280         free_safe_mem(key_backup);
281         free_safe_mem(dhdr);
282
283         if (backup_hdr != NULL)
284                 *backup_hdr = ehdr_backup;
285         else
286                 free_safe_mem(ehdr_backup);
287
288         return ehdr;
289         /* NOT REACHED */
290
291 error:
292         if (key)
293                 free_safe_mem(key);
294         if (key_backup)
295                 free_safe_mem(key_backup);
296         if (dhdr)
297                 free_safe_mem(dhdr);
298         if (ehdr)
299                 free_safe_mem(ehdr);
300         if (ehdr_backup)
301                 free_safe_mem(ehdr_backup);
302
303         return NULL;
304 }
305
306 struct tchdr_enc *copy_reencrypt_hdr(unsigned char *pass, int passlen,
307     struct pbkdf_prf_algo *prf_algo, int weak, struct tcplay_info *info,
308     struct tchdr_enc **backup_hdr)
309 {
310         struct tchdr_enc *ehdr, *ehdr_backup;
311         unsigned char *key, *key_backup;
312         unsigned char iv[128];
313         const struct sig_hdr_cfg *hdr_cfg;
314         int error;
315
316         key = key_backup = NULL;
317         ehdr = ehdr_backup = NULL;
318
319         /* By default stick to current PRF algo */
320         if (prf_algo == NULL)
321                 prf_algo = info->pbkdf_prf;
322
323         if ((ehdr = (struct tchdr_enc *)alloc_safe_mem(sizeof(*ehdr))) == NULL) {
324                 tc_log(1, "could not allocate safe ehdr memory\n");
325                 goto error;
326         }
327
328         if ((ehdr_backup = (struct tchdr_enc *)alloc_safe_mem
329             (sizeof(*ehdr_backup))) == NULL) {
330                 tc_log(1, "could not allocate safe ehdr_backup memory\n");
331                 goto error;
332         }
333
334         if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
335                 tc_log(1, "could not allocate safe key memory\n");
336                 goto error;
337         }
338
339         if ((key_backup = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
340                 tc_log(1, "could not allocate safe backup key memory\n");
341                 goto error;
342         }
343
344         if ((error = get_random(ehdr->salt, sizeof(ehdr->salt), weak)) != 0) {
345                 tc_log(1, "could not get salt\n");
346                 goto error;
347         }
348
349         if ((error = get_random(ehdr_backup->salt, sizeof(ehdr_backup->salt), weak))
350             != 0) {
351                 tc_log(1, "could not get salt for backup header\n");
352                 goto error;
353         }
354
355         error = pbkdf2(prf_algo, (char *)pass, passlen,
356             ehdr->salt, sizeof(ehdr->salt),
357             MAX_KEYSZ, key);
358         if (error) {
359                 tc_log(1, "could not derive key\n");
360                 goto error;
361         }
362
363         error = pbkdf2(prf_algo, (char *)pass, passlen,
364             ehdr_backup->salt, sizeof(ehdr_backup->salt),
365             MAX_KEYSZ, key_backup);
366         if (error) {
367                 tc_log(1, "could not derive backup key\n");
368                 goto error;
369         }
370
371         if ((hdr_cfg = hdr_cfg_from_sig(prf_algo->sig)) == NULL) {
372                 tc_log(1, "could not find internal header configuration\n");
373                 goto error;
374         }
375
376         /* Update signature and min_ver depending on selected PBKDF2 PRF algo */
377         memcpy(info->hdr->tc_str, prf_algo->sig, 4);
378         info->hdr->tc_min_ver = hdr_cfg->min_ver;
379
380         HOST_TO_BE(16, info->hdr->tc_ver);
381         HOST_TO_LE(16, info->hdr->tc_min_ver);
382         HOST_TO_BE(32, info->hdr->crc_keys);
383         HOST_TO_BE(64, info->hdr->vol_ctime);
384         HOST_TO_BE(64, info->hdr->hdr_ctime);
385         HOST_TO_BE(64, info->hdr->sz_vol);
386         HOST_TO_BE(64, info->hdr->sz_hidvol);
387         HOST_TO_BE(64, info->hdr->off_mk_scope);
388         HOST_TO_BE(64, info->hdr->sz_mk_scope);
389         HOST_TO_BE(32, info->hdr->sec_sz);
390         HOST_TO_BE(32, info->hdr->flags);
391         HOST_TO_BE(32, info->hdr->crc_dhdr);
392
393         memset(iv, 0, sizeof(iv));
394         error = tc_encrypt(info->cipher_chain, key, iv,
395             (unsigned char *)info->hdr, sizeof(struct tchdr_dec), ehdr->enc);
396         if (error) {
397                 tc_log(1, "Header encryption failed\n");
398                 goto error;
399         }
400
401         memset(iv, 0, sizeof(iv));
402         error = tc_encrypt(info->cipher_chain, key_backup, iv,
403             (unsigned char *)info->hdr,
404             sizeof(struct tchdr_dec), ehdr_backup->enc);
405         if (error) {
406                 tc_log(1, "Backup header encryption failed\n");
407                 goto error;
408         }
409
410         free_safe_mem(key);
411         free_safe_mem(key_backup);
412
413         if (backup_hdr != NULL)
414                 *backup_hdr = ehdr_backup;
415         else
416                 free_safe_mem(ehdr_backup);
417
418         return ehdr;
419         /* NOT REACHED */
420
421 error:
422         if (key)
423                 free_safe_mem(key);
424         if (key_backup)
425                 free_safe_mem(key_backup);
426         if (ehdr)
427                 free_safe_mem(ehdr);
428         if (ehdr_backup)
429                 free_safe_mem(ehdr_backup);
430
431         return NULL;
432 }