Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 295 lines (243 sloc) 6.152 kb
dedd95c @bwalex major refactoring, bugfixes
authored
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 #include <sys/types.h>
30 #include <sys/diskslice.h>
31 #include <sys/uio.h>
46f7fdb @bwalex add prompt timeout support
authored
32 #include <sys/select.h>
dedd95c @bwalex major refactoring, bugfixes
authored
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <termios.h>
39 #include <unistd.h>
40
1af29c1 @bwalex rename tc-play => tcplay
authored
41 #include "tcplay.h"
dedd95c @bwalex major refactoring, bugfixes
authored
42
43 void *
44 read_to_safe_mem(const char *file, off_t offset, size_t *sz)
45 {
46 void *mem = NULL;
345e21f @bwalex minor fixes
authored
47 ssize_t r = 0;
dedd95c @bwalex major refactoring, bugfixes
authored
48 int fd;
49
50 if ((fd = open(file, O_RDONLY)) < 0) {
05bf0a1 @bwalex Start C API work
authored
51 tc_log(1, "Error opening file %s\n", file);
dedd95c @bwalex major refactoring, bugfixes
authored
52 return NULL;
53 }
54
55 if ((mem = alloc_safe_mem(*sz)) == NULL) {
05bf0a1 @bwalex Start C API work
authored
56 tc_log(1, "Error allocating memory\n");
dedd95c @bwalex major refactoring, bugfixes
authored
57 goto out;
58 }
59
60 if ((lseek(fd, offset, SEEK_SET) < 0)) {
05bf0a1 @bwalex Start C API work
authored
61 tc_log(1, "Error seeking on file %s\n", file);
dedd95c @bwalex major refactoring, bugfixes
authored
62 goto m_err;
63 }
64
65 if ((r = read(fd, mem, *sz)) <= 0) {
05bf0a1 @bwalex Start C API work
authored
66 tc_log(1, "Error reading from file %s\n", file);
dedd95c @bwalex major refactoring, bugfixes
authored
67 goto m_err;
68 }
69
70 out:
71 *sz = r;
72 close(fd);
73 return mem;
74 /* NOT REACHED */
75
76 m_err:
77 free_safe_mem(mem);
78 close(fd);
79 return NULL;
80 }
81
82 int
83 get_random(unsigned char *buf, size_t len)
84 {
85 int fd;
86 ssize_t r;
87 size_t rd = 0;
88 struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; /* 10 ms */
89
90
91 if ((fd = open("/dev/random", O_RDONLY)) < 0) {
05bf0a1 @bwalex Start C API work
authored
92 tc_log(1, "Error opening /dev/random\n");
dedd95c @bwalex major refactoring, bugfixes
authored
93 return -1;
94 }
95
96 while (rd < len) {
97 if ((r = read(fd, buf+rd, len-rd)) < 0) {
05bf0a1 @bwalex Start C API work
authored
98 tc_log(1, "Error reading from /dev/random\n");
dedd95c @bwalex major refactoring, bugfixes
authored
99 close(fd);
100 return -1;
101 }
102 rd += r;
103 nanosleep(&ts, NULL);
104 }
105
106 close(fd);
107 return 0;
108 }
109
69686eb @bwalex improve secure_erase speed; add SIGINFO support
authored
110 static size_t secure_erase_total_bytes = 0;
111 static size_t secure_erase_erased_bytes = 0;
112
113 static
114 void
115 secure_erase_summary(void)
116 {
117 float pct_done;
118
119 pct_done = (1.0 * secure_erase_erased_bytes) /
120 (1.0 * secure_erase_total_bytes) * 100.0;
121 tc_log(0, "Securely erasing, %.0f%% done.\n", pct_done);
122 }
123
dedd95c @bwalex major refactoring, bugfixes
authored
124 int
125 secure_erase(const char *dev, size_t bytes, size_t blksz)
126 {
127 size_t erased = 0;
128 int fd_rand, fd;
69686eb @bwalex improve secure_erase speed; add SIGINFO support
authored
129 char buf[ERASE_BUFFER_SIZE];
dedd95c @bwalex major refactoring, bugfixes
authored
130 ssize_t r, w;
69686eb @bwalex improve secure_erase speed; add SIGINFO support
authored
131 size_t sz;
dedd95c @bwalex major refactoring, bugfixes
authored
132
133 if (blksz > MAX_BLKSZ) {
05bf0a1 @bwalex Start C API work
authored
134 tc_log(1, "blksz > MAX_BLKSZ\n");
dedd95c @bwalex major refactoring, bugfixes
authored
135 return -1;
136 }
137
138 if ((fd_rand = open("/dev/urandom", O_RDONLY)) < 0) {
05bf0a1 @bwalex Start C API work
authored
139 tc_log(1, "Error opening /dev/urandom\n");
dedd95c @bwalex major refactoring, bugfixes
authored
140 return -1;
141 }
142
143 if ((fd = open(dev, O_WRONLY)) < 0) {
144 close(fd_rand);
05bf0a1 @bwalex Start C API work
authored
145 tc_log(1, "Error opening %s\n", dev);
dedd95c @bwalex major refactoring, bugfixes
authored
146 return -1;
147 }
148
69686eb @bwalex improve secure_erase speed; add SIGINFO support
authored
149 summary_fn = secure_erase_summary;
150 secure_erase_total_bytes = bytes;
151
152 sz = ERASE_BUFFER_SIZE;
dedd95c @bwalex major refactoring, bugfixes
authored
153 while (erased < bytes) {
69686eb @bwalex improve secure_erase speed; add SIGINFO support
authored
154 secure_erase_erased_bytes = erased;
155 /* Switch to block size when not much is remaining */
156 if ((bytes - erased) <= ERASE_BUFFER_SIZE)
157 sz = blksz;
158
159 if ((r = read(fd_rand, buf, sz)) < 0) {
05bf0a1 @bwalex Start C API work
authored
160 tc_log(1, "Error reading from /dev/urandom\n");
dedd95c @bwalex major refactoring, bugfixes
authored
161 close(fd);
162 close(fd_rand);
69686eb @bwalex improve secure_erase speed; add SIGINFO support
authored
163 summary_fn = NULL;
dedd95c @bwalex major refactoring, bugfixes
authored
164 return -1;
165 }
166
0c6d6a0 @bwalex big warning cleanup
authored
167 if (r < (ssize_t)blksz)
dedd95c @bwalex major refactoring, bugfixes
authored
168 continue;
169
69686eb @bwalex improve secure_erase speed; add SIGINFO support
authored
170 if ((w = write(fd, buf, r)) < 0) {
05bf0a1 @bwalex Start C API work
authored
171 tc_log(1, "Error writing to %s\n", dev);
dedd95c @bwalex major refactoring, bugfixes
authored
172 close(fd);
173 close(fd_rand);
69686eb @bwalex improve secure_erase speed; add SIGINFO support
authored
174 summary_fn = NULL;
dedd95c @bwalex major refactoring, bugfixes
authored
175 return -1;
176 }
177
178 erased += (size_t)w;
179 }
180
181 close(fd);
182 close(fd_rand);
183
69686eb @bwalex improve secure_erase speed; add SIGINFO support
authored
184 summary_fn = NULL;
185
dedd95c @bwalex major refactoring, bugfixes
authored
186 return 0;
187 }
188
189 int
190 get_disk_info(const char *dev, size_t *blocks, size_t *bsize)
191 {
192 struct partinfo pinfo;
193 int fd;
194
195 if ((fd = open(dev, O_RDONLY)) < 0) {
05bf0a1 @bwalex Start C API work
authored
196 tc_log(1, "Error opening %s\n", dev);
dedd95c @bwalex major refactoring, bugfixes
authored
197 return -1;
198 }
199
200 memset(&pinfo, 0, sizeof(struct partinfo));
201
202 if (ioctl(fd, DIOCGPART, &pinfo) < 0) {
203 close(fd);
204 return -1;
205 }
206
207 *blocks = pinfo.media_blocks;
208 *bsize = pinfo.media_blksize;
209
210 close(fd);
211 return 0;
212 }
213
214 int
0c6d6a0 @bwalex big warning cleanup
authored
215 write_mem(const char *dev, off_t offset, size_t blksz __unused, void *mem,
216 size_t bytes)
dedd95c @bwalex major refactoring, bugfixes
authored
217 {
218 ssize_t w;
219 int fd;
220
221 if ((fd = open(dev, O_WRONLY)) < 0) {
05bf0a1 @bwalex Start C API work
authored
222 tc_log(1, "Error opening device %s\n", dev);
dedd95c @bwalex major refactoring, bugfixes
authored
223 return -1;
224 }
225
226 if ((lseek(fd, offset, SEEK_SET) < 0)) {
05bf0a1 @bwalex Start C API work
authored
227 tc_log(1, "Error seeking on device %s\n", dev);
dedd95c @bwalex major refactoring, bugfixes
authored
228 close(fd);
229 return -1;
230 }
231
232 if ((w = write(fd, mem, bytes)) <= 0) {
05bf0a1 @bwalex Start C API work
authored
233 tc_log(1, "Error writing to device %s\n", dev);
dedd95c @bwalex major refactoring, bugfixes
authored
234 close(fd);
235 return -1;
236 }
237
238 close(fd);
239 return 0;
240 }
241
242 int
46f7fdb @bwalex add prompt timeout support
authored
243 read_passphrase(const char *prompt, char *pass, size_t passlen, time_t timeout)
dedd95c @bwalex major refactoring, bugfixes
authored
244 {
245 struct termios termios_old, termios_new;
46f7fdb @bwalex add prompt timeout support
authored
246 struct timeval to;
247 fd_set fds;
dedd95c @bwalex major refactoring, bugfixes
authored
248 ssize_t n;
46f7fdb @bwalex add prompt timeout support
authored
249 int fd, r = 0, cfd = 0, nready;
dedd95c @bwalex major refactoring, bugfixes
authored
250
251 if ((fd = open("/dev/tty", O_RDONLY)) == -1) {
252 fd = STDIN_FILENO;
253 cfd = 1;
254 }
255
256 printf(prompt);
257 fflush(stdout);
258
259 memset(pass, 0, passlen);
260
261 tcgetattr(fd, &termios_old);
262 memcpy(&termios_new, &termios_old, sizeof(termios_new));
263 termios_new.c_lflag &= ~ECHO;
264 tcsetattr(fd, TCSAFLUSH, &termios_new);
265
46f7fdb @bwalex add prompt timeout support
authored
266 if (timeout > 0) {
267 memset(&to, 0, sizeof(to));
268 to.tv_sec = timeout;
269
270 FD_ZERO(&fds);
271 FD_SET(fd, &fds);
272 nready = select(fd + 1, &fds, NULL, NULL, &to);
273 if (nready <= 0) {
274 r = EINTR;
275 goto out;
276 }
277 }
278
dedd95c @bwalex major refactoring, bugfixes
authored
279 n = read(fd, pass, passlen-1);
280 if (n > 0) {
281 pass[n-1] = '\0'; /* Strip trailing \n */
282 } else {
283 r = EIO;
284 }
285
46f7fdb @bwalex add prompt timeout support
authored
286 out:
dedd95c @bwalex major refactoring, bugfixes
authored
287 if (cfd)
288 close(fd);
289
290 tcsetattr(fd, TCSAFLUSH, &termios_old);
291 putchar('\n');
292
293 return r;
294 }
Something went wrong with that request. Please try again.