xref: /dragonfly/lib/libtcplay/tcplay_api.c (revision 10f4bf95)
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 <stdlib.h>
31 #include <unistd.h>
32 #include <errno.h>
33 
34 #include "tcplay.h"
35 #include "tcplay_api.h"
36 
37 int
38 tc_api_init(int verbose)
39 {
40 	int error;
41 
42 	tc_internal_verbose = verbose;
43 
44 	if ((error = tc_play_init()) != 0)
45 		return TC_ERR;
46 	else
47 		return TC_OK;
48 }
49 
50 int
51 tc_api_uninit(void)
52 {
53 	check_and_purge_safe_mem();
54 	return TC_OK;
55 }
56 
57 const char *
58 tc_api_get_error_msg(void)
59 {
60 	return tc_internal_log_buffer;
61 }
62 
63 const char *
64 tc_api_get_summary(void)
65 {
66 	if (summary_fn != NULL) {
67 		summary_fn();
68 		return tc_internal_log_buffer;
69 	}
70 
71 	return NULL;
72 }
73 
74 int
75 tc_api_create_volume(tc_api_opts *api_opts)
76 {
77 	int nkeyfiles, n_hkeyfiles = 0;
78 	int create_hidden;
79 	int err;
80 
81 	if ((api_opts == NULL) ||
82 	    (api_opts->tc_device == NULL)) {
83 		errno = EFAULT;
84 		return TC_ERR;
85 	}
86 
87 	if ((err = tc_api_check_cipher(api_opts)) != TC_OK)
88 		return TC_ERR;
89 
90 	if ((err = tc_api_check_prf_hash(api_opts)) != TC_OK)
91 		return TC_ERR;
92 
93 	for (nkeyfiles = 0; (nkeyfiles < MAX_KEYFILES) &&
94 	    (api_opts->tc_keyfiles != NULL) &&
95 	    (api_opts->tc_keyfiles[nkeyfiles] != NULL); nkeyfiles++)
96 		;
97 
98 	create_hidden = 0;
99 
100 	if (api_opts->tc_size_hidden_in_bytes > 0) {
101 		create_hidden = 1;
102 		for (n_hkeyfiles = 0; (n_hkeyfiles < MAX_KEYFILES) &&
103 		    (api_opts->tc_keyfiles_hidden != NULL) &&
104 		    (api_opts->tc_keyfiles_hidden[n_hkeyfiles] != NULL);
105 		    n_hkeyfiles++)
106 			;
107 	}
108 
109 	err = create_volume(api_opts->tc_device, create_hidden,
110 	    api_opts->tc_keyfiles, nkeyfiles,
111 	    api_opts->tc_keyfiles_hidden, n_hkeyfiles,
112 	    check_prf_algo(api_opts->tc_prf_hash, 1),
113 	    check_cipher_chain(api_opts->tc_cipher, 1),
114 	    check_prf_algo(api_opts->tc_prf_hash_hidden, 1),
115 	    check_cipher_chain(api_opts->tc_cipher_hidden, 1),
116 	    api_opts->tc_passphrase, api_opts->tc_passphrase_hidden,
117 	    api_opts->tc_size_hidden_in_bytes, 0 /* non-interactive */);
118 
119 	return (err) ? TC_ERR : TC_OK;
120 }
121 
122 int
123 tc_api_map_volume(tc_api_opts *api_opts)
124 {
125 	int nkeyfiles;
126 	int err;
127 
128 	if ((api_opts == NULL) ||
129 	    (api_opts->tc_device == NULL)) {
130 		errno = EFAULT;
131 		return TC_ERR;
132 	}
133 
134 	for (nkeyfiles = 0; (nkeyfiles < MAX_KEYFILES) &&
135 	    (api_opts->tc_keyfiles != NULL) &&
136 	    (api_opts->tc_keyfiles[nkeyfiles] != NULL); nkeyfiles++)
137 		;
138 
139 	err = map_volume(api_opts->tc_map_name, api_opts->tc_device,
140 	    /* sflag */ 0, /* sys_dev */ NULL,
141 	    /* protect_hidden */ 0, api_opts->tc_keyfiles, nkeyfiles,
142 	    /* h_keyfiles[] */ NULL, /* n_hkeyfiles */ 0,
143 	    api_opts->tc_passphrase, /* passphrase_hidden */ NULL,
144 	    api_opts->tc_interactive_prompt, api_opts->tc_password_retries,
145 	    (time_t)api_opts->tc_prompt_timeout);
146 
147 	return (err) ? TC_ERR : TC_OK;
148 }
149 
150 int
151 tc_api_unmap_volume(tc_api_opts *api_opts)
152 {
153 	int err;
154 
155 	if ((api_opts == NULL) ||
156 	    (api_opts->tc_map_name == NULL)) {
157 		errno = EFAULT;
158 		return TC_ERR;
159 	}
160 
161 	err = dm_teardown(api_opts->tc_map_name, api_opts->tc_device);
162 	return (err) ? TC_ERR : TC_OK;
163 }
164 
165 int
166 tc_api_check_cipher(tc_api_opts *api_opts)
167 {
168 	struct tc_cipher_chain *chain;
169 
170 	if (api_opts == NULL || api_opts->tc_cipher == NULL) {
171 		errno = EFAULT;
172 		return TC_ERR;
173 	}
174 
175 	if ((chain = check_cipher_chain(api_opts->tc_cipher, 1)) != NULL)
176 		return TC_OK;
177 
178 	errno = ENOENT;
179 	return TC_ERR;
180 }
181 
182 int
183 tc_api_check_prf_hash(tc_api_opts *api_opts)
184 {
185 	struct pbkdf_prf_algo *prf_hash;
186 
187 	if (api_opts == NULL || api_opts->tc_prf_hash == NULL) {
188 		errno = EFAULT;
189 		return TC_ERR;
190 	}
191 
192 	if ((prf_hash = check_prf_algo(api_opts->tc_prf_hash, 1)) != NULL)
193 		return TC_OK;
194 
195 	errno = ENOENT;
196 	return TC_ERR;
197 }
198 
199