/*** * ENCRYPTION * * Makes files unreadable, kinda. */ #include "encryption.h" #include #include #include #include #include #include #include #include #include #include // Encrypt a file (OVERWRITES FILE!) using a passphrase size_t passenc(int fd, const char *passphrase) { struct stat sb; void *filebuf = NULL; ssize_t cur_len = 0; ssize_t bytesread = 0; int esave; // Set up file buffer if(fstat(fd, &sb) < 0) { error(0, errno, "[passenc] Could not stat file descriptor \"%d\"", fd); return -1; } filebuf = calloc(sb.st_size, 1); if(filebuf == NULL) { error(0, errno, "[passenc] Could not allocate buffer for reading file"); return -1; } while((bytesread = read(fd, ((uint8_t*)filebuf) + cur_len, sb.st_size - cur_len)) > 0) { esave = errno; cur_len += bytesread; if(cur_len > sb.st_size) { error(0, ERANGE, "[passenc] Reading overran the proper file size somehow"); free(filebuf); return -1; } } if(bytesread < 0) { error(0, esave, "[passenc] Ran into a read error"); free(filebuf); return -1; } // Do the "encryption" size_t phraselen = strlen(passphrase); for(off_t i = 0; i < sb.st_size; i++) { ((uint8_t*)filebuf)[i] ^= passphrase[i % phraselen]; } // Write "encrypted" data to file if(lseek(fd, 0, SEEK_SET) < 0) { error(0, errno, "[passenc] Could not seek to beginning of file"); free(filebuf); return -1; } bytesread = 0; cur_len = 0; while((bytesread = write(fd, ((uint8_t*)filebuf) + cur_len, sb.st_size - cur_len)) > 0) { esave = errno; cur_len += bytesread; if(cur_len > sb.st_size) { error(0, ERANGE, "[passenc] writing overran the proper file size somehow"); free(filebuf); return -1; } } if(bytesread < 0) { error(0, esave, "[passenc] Ran into a write error"); free(filebuf); return -1; } free(filebuf); return cur_len; } // Encrypt a file one block at a time (Overwrites file) size_t passencblock(int fd, const char *passphrase) { struct stat sb; void *filebuf = NULL; ssize_t cur_len = 0, totalwritten = 0; ssize_t bytesread = 0, usebytes = 0; int esave; off_t offset = 0; // Set up file buffer if(fstat(fd, &sb) < 0) { error(0, errno, "[passenc] Could not stat file descriptor \"%d\"", fd); return -1; } filebuf = calloc(sb.st_blksize, 1); if(filebuf == NULL) { error(0, errno, "[passenc] Could not allocate buffer for reading file"); return -1; } // Read 1 block // Do the encryption // Overwrite the block with the encryption // Repeat until EOF while(offset < sb.st_size) { // Read a block bytesread = 0; cur_len = 0; while((bytesread = read(fd, ((char*)filebuf) + cur_len, sb.st_blksize - cur_len)) > 0) { esave = errno; cur_len += bytesread; if(cur_len > sb.st_blksize) { error(0, ERANGE, "[passenc] Read too many bytes somehow"); free(filebuf); return -1; } } if(bytesread < 0) { error(0, esave, "[passenc] Ran into a read error"); free(filebuf); return -1; } usebytes = cur_len; // Do the encryption size_t phraselen = strlen(passphrase); for(off_t i = 0; i < usebytes; i++) { ((char*)filebuf)[i] ^= passphrase[i % phraselen]; } // Seek to the right spot if(lseek(fd, offset, SEEK_SET) < 0) { error(0, errno, "[passenc] Could not seek to proper offset"); free(filebuf); return -1; } offset += sb.st_blksize; // Write to the file bytesread = 0; cur_len = 0; while((bytesread = write(fd, ((char*)filebuf) + cur_len, usebytes - cur_len)) > 0) { esave = errno; cur_len += bytesread; if(cur_len > sb.st_blksize) { error(0, ERANGE, "[passenc] writing overran the block size somehow"); free(filebuf); return -1; } } if(bytesread < 0) { error(0, esave, "[passenc] Ran into a write error"); free(filebuf); return -1; } totalwritten += cur_len; } free(filebuf); return totalwritten; } int main() { int fd = open("test.txt", O_RDWR); passencblock(fd, "we do a little trolling"); return 0; }