When giving away or selling a PC, one should be careful not to send personal data with it. I'm in such a situation and was using dd if=/dev/urandom of=/dev/sdb bs=8M, but it was only averaging 22MB/s. Way too slow since I have to drop it at the post office next morning. So I decided to write my own and see what kinds of results I would get.First I dropped /dev/urandom in favor of hashing a secret key and feeding back the output as state. The second thing I did was to use O_DIRECT to avoid buffering.My program reports an average of 48MiB/s, much better than what I got with plain old dd unless it has a bug.#define _GNU_SOURCE 1#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <time.h>#include <stdint.h>#include <string.h>#include <unistd.h>#include <openssl/sha.h>#define BLOCK_SIZE (1024 * 1024 * 8)#define ALIGNMENT 512typedef struct {  unsigned char state[64];  unsigned char key[32];  __uint128_t counter;} RandomCtx;static void _xor64(uint64_t* a, uint64_t* b){  for(int i = 0; i < 8; ++i)    *a++ ^= *b++;}static void _cipher(RandomCtx* ctx, unsigned char* data, unsigned int len){  unsigned int runs = len >> 6;  while(runs){    // get value to XOR    unsigned char x[64];    SHA512((unsigned char const*)ctx, sizeof(RandomCtx), x);    // XOR with data    _xor64((uint64_t*)data, (uint64_t*)x);    // feed the XORed result back as state and update counter    memcpy(ctx->state, data, 64);    ++ctx->counter;    // move on    data += 64;    --runs;  }}int main(int argc, char* argv[]){  if(2 != argc){    fprintf(stderr, Usage: %s /dev/sdb\n, argv[0]);    return EXIT_FAILURE;  }  // open disk  int disk = open(argv[1], O_WRONLY|O_DIRECT);  if(-1 == disk){    perror(open());    return EXIT_FAILURE;  }  // allocate memory enough  char* raw = malloc(BLOCK_SIZE + ALIGNMENT - 1);  if(!raw){    perror(malloc());    return EXIT_FAILURE;  }  // align  unsigned char* aligned = (unsigned char*)                           ((size_t)(raw + (ALIGNMENT-1)) & ~(ALIGNMENT-1));  // open random source  int urandom = open(/dev/urandom, O_RDONLY);  if(-1 == urandom){    perror(open());    return EXIT_FAILURE;  }  // init random ctx  RandomCtx ctx;  if(sizeof ctx != read(urandom, &ctx, sizeof ctx)){    perror(read());    return EXIT_FAILURE;  }  // init buffer  if(BLOCK_SIZE != read(urandom, aligned, BLOCK_SIZE)){    perror(read());    return EXIT_FAILURE;  }  // we are done with urandom  close(urandom);  // now run until there's no more space  time_t ti0 = time(NULL);  size_t to0 = 0;  size_t to1 = 0;  int gib = 0;  while(BLOCK_SIZE == write(disk, aligned, BLOCK_SIZE)){    to1 += BLOCK_SIZE;    if((to1 - to0) >= (1024*1024*1024)){      to0 = to1;      ++gib;      size_t secs = time(NULL) - ti0;            printf(Total: %d GiB in %zu secs. %.2f MiB/s\n, gib, secs,             (double)gib*1024/secs);    }    _cipher(&ctx, aligned, BLOCK_SIZE);  }}
Securely Delete All Drive Data
c;security;file system