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