usched: Allow process to change self cpu affinity
[dragonfly.git] / lib / libtcplay / hdr.c
blobee32c04938ea3f0b3e0539880872fa30ecd8b660
1 /*
2 * Copyright (c) 2011 Alex Hornung <alex@alexhornung.com>.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
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.
30 #include <sys/types.h>
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>
43 #include "crc32.h"
44 #include "tcplay.h"
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)
52 struct tchdr_dec *
53 decrypt_hdr(struct tchdr_enc *ehdr, struct tc_cipher_chain *cipher_chain,
54 unsigned char *key)
56 struct tchdr_dec *dhdr;
57 unsigned char iv[128];
58 int error;
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;
65 memset(iv, 0, sizeof(iv));
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;
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);
88 return dhdr;
91 int
92 verify_hdr(struct tchdr_dec *hdr)
94 uint32_t crc;
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;
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;
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;
118 case 3:
119 case 4:
120 hdr->sec_sz = 512;
121 break;
124 return 1;
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)
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;
139 key = key_backup = NULL;
140 dhdr = NULL;
141 ehdr = ehdr_backup = NULL;
143 if (backup_hdr != NULL)
144 *backup_hdr = NULL;
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;
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;
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;
162 if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
163 tc_log(1, "could not allocate safe key memory\n");
164 goto error;
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;
172 if ((error = get_random(ehdr->salt, sizeof(ehdr->salt), weak)) != 0) {
173 tc_log(1, "could not get salt\n");
174 goto error;
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;
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;
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;
199 memset(dhdr, 0, sizeof(*dhdr));
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;
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;
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);
228 dhdr->crc_dhdr = crc32((void *)dhdr, 188);
229 HOST_TO_BE(32, dhdr->crc_dhdr);
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;
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;
248 free_safe_mem(key);
249 free_safe_mem(key_backup);
250 free_safe_mem(dhdr);
252 if (backup_hdr != NULL)
253 *backup_hdr = ehdr_backup;
254 else
255 free_safe_mem(ehdr_backup);
257 return ehdr;
258 /* NOT REACHED */
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);
272 return NULL;
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)
279 struct tchdr_enc *ehdr, *ehdr_backup;
280 unsigned char *key, *key_backup;
281 unsigned char iv[128];
282 int error;
284 key = key_backup = NULL;
285 ehdr = ehdr_backup = NULL;
287 /* By default stick to current PRF algo */
288 if (prf_algo == NULL)
289 prf_algo = info->pbkdf_prf;
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;
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;
302 if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
303 tc_log(1, "could not allocate safe key memory\n");
304 goto error;
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;
312 if ((error = get_random(ehdr->salt, sizeof(ehdr->salt), weak)) != 0) {
313 tc_log(1, "could not get salt\n");
314 goto error;
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;
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;
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;
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);
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;
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;
369 free_safe_mem(key);
370 free_safe_mem(key_backup);
372 if (backup_hdr != NULL)
373 *backup_hdr = ehdr_backup;
374 else
375 free_safe_mem(ehdr_backup);
377 return ehdr;
378 /* NOT REACHED */
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);
390 return NULL;