This is an unofficial patch to PGP 2.6ui. The original PGP 2.6ui used IDEA to generate random data to overwrite temp files. This was quite slow, and results in 2.6ui taking more than twice as long as 2.3A to perform many tasks. This patch substitutes the the MIT 2.6 code, which uses a polynomial pseudo-random generator. Wayne Chapeskie *** fileio.c 1.1 1994/06/28 06:39:21 --- fileio.c 1.2 1994/06/28 06:44:47 *************** *** 22,28 **** Modified 17 Nov 92 - HAJK Change to temp file stuff for VMS. - Modified 17 Nov 92 - apb Wipe file with random data. */ --- 22,27 ---- *************** *** 101,181 **** #endif } - static void init_buffrand(void) - { /* Initialise for future calls to buffrand(). - This random number generator is intended to be used - to provide data to overwrite a disk file. It does - not have to be cryptographically strong, but should - generate data that is unlikely to be easily compressible. - If a file is overwritten with compressible data, a - compressing file system is likely to leave some of the - original data intact. Overwriting a file with random - data does not guarantee that the original data will be - destroyed, but is better than overwriting the file - with zeros. - */ - - byte ideakey[24]; /* must be big enough for make_random_ideakey */ - - /* We don't want the ideakey itself here, we just want the side - effect of initialising lots of stuff so that buffrand() - can later call idearand(). */ - (void) make_random_ideakey(ideakey); - burn(ideakey); - } ! static void buffrand(char *buf, int n) ! { /* Fill a buffer with random data. See open_buffrand() ! and close_buffrand(). ! */ ! while (n-- > 0) { ! *buf++ = idearand(); ! } ! } ! static void close_buffrand(void) ! { /* Finish using buffrand(). ! */ ! close_idearand(); ! } ! static int wipeout(FILE *f) ! { /* Completely overwrite and erase file, so that no sensitive ! information is left on the disk. ! NOTE: File MUST be open for read/write. ! */ ! long flength; ! int count = 0; fseek(f, 0L, SEEK_END); ! flength = ftell(f); rewind(f); ! init_buffrand(); ! while (flength > 0L) ! { /* write random data to the whole file... */ ! buffrand(textbuf, DISKBUFSIZE); ! if (flength < (word32) DISKBUFSIZE) ! count = (int)flength; ! else ! count = DISKBUFSIZE; ! fwrite(textbuf,1,count,f); ! flength -= count; ! } ! close_buffrand(); ! burn(textbuf); ! rewind(f); /* maybe this isn't necessary */ ! return(0); /* normal return */ ! } /* wipeout */ int wipefile(char *filename) ! { /* Completely overwrite and erase file, so that no sensitive ! information is left on the disk. ! */ FILE *f; /* open file f for read/write, in binary (not text) mode...*/ if ((f = fopen(filename,FOPRWBIN)) == NULL) --- 100,224 ---- #endif } ! /* ! * This wipes a file with pseudo-random data. The purpose of this is to ! * make sure no sensitive information is left on the disk. The use ! * of pseudo-random data is to defeat disk compression drivers (such as ! * Stacker and dblspace) so that we are guaranteed that the entire file ! * has been overwritten. ! * ! * Note that the file MUST be open for read/write. ! * ! * It may not work to eliminate everything from non-volatile storage ! * if the OS you're using does its own paging or swapping. Then ! * it's an issue of how the OS's paging device is wiped, and you can ! * only hope that the space will be reused within a few seconds. ! * ! * Also, some file systems (in particular, the Logging File System ! * for Sprite) do not write new data in the same place as old data, ! * defeating this wiping entirely. Fortunately, such systems ! * usually don't need a swap file, and for small temp files, they ! * do write-behind, so if you create and delete a file fast enough, ! * it never gets written to disk at all. ! */ ! /* ! * The data is randomly generated with the size of the file as a seed. ! * The data should be random and not leak information. If someone is ! * examining deleted files, presumably they can reconstruct the file size, ! * so that's not a secret. H'm... this wiping algorithm makes it easy to, ! * given a block of data, find the size of the file it came from ! * and the offset of this block within it. That in turn reveals ! * something about the state of the disk's allocation tables when the ! * file was used, possibly making it easier to find other files created ! * at neaby times - such as plaintext files. Is this acceptable? ! */ ! /* ! * Theory of operation: We use the additive congruential RNG ! * r[i] = r[i-24] + r[i-55], from Knuth, Vol. 2. This is fast ! * and has a long enough period that there should be no repetitions ! * in even a huge file. It is seeded with r[-55] through r[-1] ! * using another polynomial-based RNG. We seed a linear feedback ! * shift register (CRC generator) with the size of the swap file, ! * and clock in 0 bits. Each 32 bits, the value of the generator is ! * taken as the next integer. This is just to ensure a reasonably ! * even mix of 1's and 0's in the initialization vector. ! */ ! /* ! * This is the CRC-32 polynomial, which should be okay for random ! * number generation. ! * x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 ! * = 1 0000 0100 1100 0001 0001 1101 1011 0111 ! * = 0x04c11db7 ! */ ! #define POLY 0x04c11db7 ! static int ! wipeout(FILE *f) ! { ! unsigned *p1, *p2, *p3; ! unsigned long len; ! unsigned long t; ! int i; ! /* Get the file size */ fseek(f, 0L, SEEK_END); ! len = ftell(f); rewind(f); ! /* Seed of first RNG. Inverted to get more 1 bits */ ! t = ~len; ! ! /* Initialize first 55 words of buf with pseudo-random stuff */ ! p1 = (unsigned *)textbuf2 + 55; ! do { ! for (i = 0; i < 32; i++) ! t = (t & 0x80000000) ? t<<1 ^ POLY : t<<1; ! *--p1 = (unsigned)t; ! } while (p1 > (unsigned *)textbuf2); ! ! while (len) { ! /* Fill buffer with pseudo-random integers */ ! ! p3 = (unsigned *)textbuf2 + 55; ! p2 = (unsigned *)textbuf2 + 24; ! p1 = (unsigned *)textbuf2 + sizeof(textbuf2)/sizeof(*p1); ! do { ! *--p1 = *--p2 + *--p3; ! } while (p2 > (unsigned *)textbuf2); ! ! p2 = (unsigned *)textbuf2 + sizeof(textbuf2)/sizeof(*p1); ! do { ! *--p1 = *--p2 + *--p3; ! } while (p3 > (unsigned *)textbuf2); ! ! p3 = (unsigned *)textbuf2 + sizeof(textbuf2)/sizeof(*p3); ! do { ! *--p1 = *--p2 + *--p3; ! } while (p1 > (unsigned *)textbuf2); ! ! /* Write it out - yes, we're ignoring errors */ ! if (len > sizeof(textbuf2)) { ! fwrite((char const *)textbuf2, sizeof(textbuf2), 1, f); ! len -= sizeof(textbuf2); ! } else { ! fwrite((char const *)textbuf2, len, 1, f); ! len = 0; ! } ! } ! } int wipefile(char *filename) ! /* ! * Completely overwrite and erase file, so that no sensitive ! * information is left on the disk. ! */ ! { FILE *f; /* open file f for read/write, in binary (not text) mode...*/ if ((f = fopen(filename,FOPRWBIN)) == NULL) *************** *** 1130,1132 **** --- 1173,1176 ---- if (tmpf[i].flags) rmtemp(tmpf[i].path); } /* cleanup_tmpf */ +