* utils_wipe - wipe a device
*
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
- * Copyright (C) 2011, Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2011-2012, Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
return write_lseek_blockwise(fd, buffer, size, offset);
}
+static ssize_t _crypt_wipe_random(int fd, char *buffer, uint64_t offset, uint64_t size)
+{
+ if (crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL) < 0)
+ return -EINVAL;
+
+ return write_lseek_blockwise(fd, buffer, size, offset);
+}
+
/*
* Wipe using Peter Gutmann method described in
* http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html
static ssize_t _crypt_wipe_disk(int fd, char *buffer, uint64_t offset, uint64_t size)
{
+ int r;
unsigned int i;
ssize_t written;
for(i = 0; i < 39; ++i) {
- if (i < 5) crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL);
- else if(i >= 5 && i < 32) wipeSpecial(buffer, size, i - 5);
- else if(i >= 32 && i < 38) crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL);
- else if(i >= 38 && i < 39) memset(buffer, 0xFF, size);
+ if (i < 5) {
+ r = crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL);
+ } else if(i >= 5 && i < 32) {
+ wipeSpecial(buffer, size, i - 5);
+ r = 0;
+ } else if(i >= 32 && i < 38) {
+ r = crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL);
+ } else if(i >= 38 && i < 39) {
+ memset(buffer, 0xFF, size);
+ r = 0;
+ }
+ if (r < 0)
+ return r;
written = write_lseek_blockwise(fd, buffer, size, offset);
- if (written < 0 || written != size)
+ if (written < 0 || written != (ssize_t)size)
return written;
}
- return written;
-}
-
-static ssize_t _crypt_wipe_random(int fd, char *buffer, uint64_t offset, uint64_t size)
-{
- crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL);
- return write_lseek_blockwise(fd, buffer, size, offset);
+ /* Rewrite it finally with random */
+ return _crypt_wipe_random(fd, buffer, offset, size);
}
static ssize_t _crypt_wipe_ssd(int fd, char *buffer, uint64_t offset, uint64_t size)
if (!buffer)
return -ENOMEM;
- flags = O_WRONLY | O_DIRECT | O_SYNC;
+ flags = O_RDWR | O_DIRECT | O_SYNC;
/* use O_EXCL only for block devices */
if (exclusive && S_ISBLK(st.st_mode))
break;
case CRYPT_WIPE_DISK:
written = _crypt_wipe_disk(devfd, buffer, offset, size);
+ break;
case CRYPT_WIPE_SSD:
written = _crypt_wipe_ssd(devfd, buffer, offset, size);
break;
case CRYPT_WIPE_RANDOM:
written = _crypt_wipe_random(devfd, buffer, offset, size);
+ break;
default:
log_dbg("Unsuported wipe type requested: (%d)", type);
written = -1;
close(devfd);
free(buffer);
- if (written != size || written < 0)
+ if (written != (ssize_t)size || written < 0)
return -EIO;
return 0;