int decrypt_root_fs(const char *crypt, const char *decrypt, char *key) { FILE *in, *out; cencrypted_v1_header v1header; cencrypted_v2_pwheader v2header; uint8_t hmacsha1_key[20], aes_key[16], inbuf[CHUNK_SIZE], outbuf[CHUNK_SIZE]; uint32_t chunk_no; int hdr_version, c,i, optError = 0; char inFile[512], outFile[512], passphrase[512]; int iflag = 0, oflag = 0, pflag = 0, kflag = 0, verbose = 0; extern char *optarg; extern int optind, optopt; memset(inFile, 0, 512); memset(outFile, 0, 512); memset(passphrase, 0, 512); verbose++; optarg=(char *)crypt; if(optarg) strncpy(inFile, optarg, sizeof(inFile)-1); iflag=1; optarg=(char *)decrypt; if (optarg) strncpy(outFile, optarg, sizeof(outFile)-1); oflag=1; optarg=key; convert_hex(optarg, aes_key, 16); convert_hex(optarg+32, hmacsha1_key, 20); kflag=1; if (strlen(inFile) == 0) { in = stdin; } else { if ((in = fopen(inFile, "rb")) == NULL) { fprintf(stderr, "Error: unable to open %s\n", inFile); exit(1); } } if (strlen(outFile) == 0) { out = stdout; } else { if ((out = fopen(outFile, "wb")) == NULL) { fprintf(stderr, "Error: unable to open %s\n", outFile); exit(1); } } hdr_version = determine_header_version(in); if (verbose >= 1) { if (hdr_version > 0) { fprintf(stderr, "v%d header detected.\n", hdr_version); } else { fprintf(stderr, "unknown format.\n"); exit(1); } } if (hdr_version == 1) { fseek(in, (long) -sizeof(cencrypted_v1_header), SEEK_END); if (fread(&v1header, sizeof(cencrypted_v1_header), 1, in) < 1) { fprintf(stderr, "header corrupted?\n"), exit(1); } adjust_v1_header_byteorder(&v1header); if(!kflag) unwrap_v1_header(passphrase, &v1header, aes_key, hmacsha1_key); } if (hdr_version == 2) { fseek(in, 0L, SEEK_SET); if (fread(&v2header, sizeof(cencrypted_v2_pwheader), 1, in) < 1) { fprintf(stderr, "header corrupted?\n"), exit(1); } adjust_v2_header_byteorder(&v2header); dump_v2_header(&v2header); if(!kflag) unwrap_v2_header(passphrase, &v2header, aes_key, hmacsha1_key); CHUNK_SIZE = v2header.blocksize; } HMAC_CTX_init(&hmacsha1_ctx); HMAC_Init_ex(&hmacsha1_ctx, hmacsha1_key, sizeof(hmacsha1_key), EVP_sha1(), NULL); AES_set_decrypt_key(aes_key, CIPHER_KEY_LENGTH * 8, &aes_decrypt_key); if (verbose >= 1) { fprintf(stderr, "AES Key: \n"); print_hex(aes_key, 16); fprintf(stderr, "SHA1 seed: \n"); print_hex(hmacsha1_key, 20); } if (hdr_version == 2) fseek(in, v2header.dataoffset, SEEK_SET); else fseek(in, 0L, SEEK_SET); chunk_no = 0; while(fread(inbuf, CHUNK_SIZE, 1, in) > 0) { decrypt_chunk(inbuf, outbuf, chunk_no); chunk_no++; if(hdr_version == 2 && (v2header.datasize-ftell(out)) < CHUNK_SIZE) { fwrite(outbuf, v2header.datasize - ftell(out), 1, out); break; } fwrite(outbuf, CHUNK_SIZE, 1, out); } if (verbose) fprintf(stderr, "%d chunks written\n", chunk_no); return 0; return 0; }
int main(int argc, char *argv[]) { FILE *in, *out; cencrypted_v1_header v1header; cencrypted_v2_pwheader v2header; uint8_t hmacsha1_key[20], aes_key[16], inbuf[CHUNK_SIZE], outbuf[CHUNK_SIZE]; uint32_t chunk_no; int hdr_version, c,i, optError = 0; char inFile[512], outFile[512], passphrase[512]; int iflag = 0, oflag = 0, pflag = 0, kflag = 0, verbose = 0; extern char *optarg; extern int optind, optopt; memset(inFile, 0, 512); memset(outFile, 0, 512); memset(passphrase, 0, 512); while((c = getopt(argc, argv, "hvi:o:p:k:")) != -1) { switch(c) { case 'h': usage("Help is on the way. Stay calm."); break; case 'v': verbose++; break; case 'i': if(optarg) strncpy(inFile, optarg, sizeof(inFile)-1); iflag = 1; break; case 'o': if (optarg) strncpy(outFile, optarg, sizeof(outFile)-1); oflag = 1; break; case 'p': if (optarg) strncpy(passphrase, optarg, sizeof(passphrase)-1); pflag = 1; break; case 'k': convert_hex(optarg, aes_key, 16); convert_hex(optarg+32, hmacsha1_key, 20); kflag=1; break; case '?': fprintf(stderr, "Unknown option: -%c\n", optopt); optError++; break; } } /* check to see if our user gave incorrect options */ if (optError) usage("Incorrect arguments."); if (strlen(inFile) == 0) { in = stdin; } else { if ((in = fopen(inFile, "rb")) == NULL) { fprintf(stderr, "Error: unable to open %s\n", inFile); exit(1); } } if (strlen(outFile) == 0) { out = stdout; } else { if ((out = fopen(outFile, "wb")) == NULL) { fprintf(stderr, "Error: unable to open %s\n", outFile); exit(1); } } if (!pflag && !kflag) { fprintf(stderr, "No Passphrase given.\n"); exit(1); } hdr_version = determine_header_version(in); if (verbose >= 1) { if (hdr_version > 0) { fprintf(stderr, "v%d header detected.\n", hdr_version); } else { fprintf(stderr, "unknown format.\n"); exit(1); } } if (hdr_version == 1) { fseek(in, (long) -sizeof(cencrypted_v1_header), SEEK_END); if (fread(&v1header, sizeof(cencrypted_v1_header), 1, in) < 1) { fprintf(stderr, "header corrupted?\n"), exit(1); } adjust_v1_header_byteorder(&v1header); if(!kflag) unwrap_v1_header(passphrase, &v1header, aes_key, hmacsha1_key); } if (hdr_version == 2) { fseek(in, 0L, SEEK_SET); if (fread(&v2header, sizeof(cencrypted_v2_pwheader), 1, in) < 1) { fprintf(stderr, "header corrupted?\n"), exit(1); } adjust_v2_header_byteorder(&v2header); dump_v2_header(&v2header); if(!kflag) unwrap_v2_header(passphrase, &v2header, aes_key, hmacsha1_key); CHUNK_SIZE = v2header.blocksize; } HMAC_CTX_init(&hmacsha1_ctx); HMAC_Init_ex(&hmacsha1_ctx, hmacsha1_key, sizeof(hmacsha1_key), EVP_sha1(), NULL); AES_set_decrypt_key(aes_key, CIPHER_KEY_LENGTH * 8, &aes_decrypt_key); if (verbose >= 1) { fprintf(stderr, "AES Key: \n"); print_hex(aes_key, 16); fprintf(stderr, "SHA1 seed: \n"); print_hex(hmacsha1_key, 20); } if (hdr_version == 2) fseek(in, v2header.dataoffset, SEEK_SET); else fseek(in, 0L, SEEK_SET); chunk_no = 0; while(fread(inbuf, CHUNK_SIZE, 1, in) > 0) { decrypt_chunk(inbuf, outbuf, chunk_no); chunk_no++; if(hdr_version == 2 && (v2header.datasize-ftell(out)) < CHUNK_SIZE) { fwrite(outbuf, v2header.datasize - ftell(out), 1, out); break; } fwrite(outbuf, CHUNK_SIZE, 1, out); } if (verbose) fprintf(stderr, "%d chunks written\n", chunk_no); return(0); }
int main(int argc, char *argv[]) { FILE *in, *out; cencrypted_v1_header v1header; cencrypted_v2_pwheader v2header; char hmacsha1_key_str[20*2+1]; char aes_key_str[16*2+1]; uint8_t hmacsha1_key[20]; uint8_t aes_key[16]; uint8_t inbuf[CHUNK_SIZE], outbuf[CHUNK_SIZE]; uint32_t chunk_no; int hdr_version; /* getopts */ int c; int optError; char inFile[512] = ""; char outFile[512] = ""; char passphrase[512]; int kflag = 0, iflag = 0, oflag = 0, pflag = 0, mflag = 0; int verbose = 0; extern char *optarg; extern int optind, optopt; memset(hmacsha1_key_str, '0', sizeof(hmacsha1_key_str)-1); hmacsha1_key_str[sizeof(hmacsha1_key_str)-1] = '\0'; optError = 0; while((c = getopt(argc, argv, "hvi:o::p::k:m:")) != -1){ switch(c) { case 'h': usage("Help is on the way. Stay calm."); break; case 'v': verbose = verbose + 1; break; case 'i': if(optarg) { strncpy(inFile, optarg, sizeof(inFile)-1); } iflag = 1; break; case 'o': if (optarg) { strncpy(outFile, optarg, sizeof(outFile)-1); } oflag = 1; break; case 'p': if (optarg) { strncpy(passphrase, optarg, sizeof(passphrase)-1); } pflag = 1; break; case 'k': if (optarg) { if (strlen(optarg) == 2*(16+20)) { strncpy(aes_key_str, optarg, sizeof(aes_key_str)); aes_key_str[sizeof(aes_key_str)-1] = '\0'; strncpy(hmacsha1_key_str, optarg+(2*16), sizeof(hmacsha1_key_str)); hmacsha1_key_str[sizeof(hmacsha1_key_str)-1] = '\0'; mflag = 1; } else if(strlen(optarg) == 2*16) { strncpy(aes_key_str, optarg, sizeof(aes_key_str)); aes_key_str[sizeof(aes_key_str)-1] = '\0'; } else { usage("you should either specify a aeskey||hmacsha1key or simply aeskey"); optError++; } } kflag = 1; break; case 'm': if (mflag) { usage("hmacsha1 key has already been specified!"); optError++; } if (optarg && strlen(optarg) == 2*20) { strncpy(hmacsha1_key_str, optarg, sizeof(hmacsha1_key_str)); hmacsha1_key_str[sizeof(hmacsha1_key_str)-1] = '\0'; } else { usage("Perhaps you'd like to give us 40 hex bytes of the HMACSHA1 key?"); optError++; } mflag = 1; break; case '?': fprintf(stderr, "Unknown option: -%c\n", optopt); optError++; break; } } /* check to see if our user gave incorrect options */ if (optError) { usage("Incorrect arguments."); } if (strlen(inFile) == 0) { in = stdin; } else { if ((in = fopen(inFile, "rb")) == NULL) { fprintf(stderr, "Error: unable to open %s\n", inFile); exit(1); } } if (strlen(outFile) == 0) { out = stdout; } else { if ((out = fopen(outFile, "wb")) == NULL) { fprintf(stderr, "Error: unable to open %s\n", outFile); exit(1); } } /* Obviously change this if we implement brute force methods inside vfdecrypt */ if (!kflag && !pflag) { fprintf(stderr, "Neither a passphrase nor a valid key/hmac combo were given.\n"); exit(1); } if (kflag && !mflag) { fprintf(stderr, "Setting HMAC-SHA1 key to all zeros!\n"); } hdr_version = determine_header_version(in); if (verbose >= 1) { if (hdr_version > 0) { fprintf(stderr, "v%d header detected.\n", hdr_version); } else { fprintf(stderr, "unknown format.\n"); exit(1); } } if (hdr_version == 1) { fseek(in, (long) -sizeof(cencrypted_v1_header), SEEK_END); if (fread(&v1header, sizeof(cencrypted_v1_header), 1, in) < 1) { fprintf(stderr, "header corrupted?\n"), exit(1); } adjust_v1_header_byteorder(&v1header); if(!kflag) unwrap_v1_header(passphrase, &v1header, aes_key, hmacsha1_key); } if (hdr_version == 2) { fseek(in, 0L, SEEK_SET); if (fread(&v2header, sizeof(cencrypted_v2_pwheader), 1, in) < 1) { fprintf(stderr, "header corrupted?\n"), exit(1); } adjust_v2_header_byteorder(&v2header); if (verbose >= 1) { dump_v2_header(&v2header); } if(!kflag) unwrap_v2_header(passphrase, &v2header, aes_key, hmacsha1_key); CHUNK_SIZE = v2header.blocksize; } if (kflag) { convert_hex(aes_key_str, aes_key, 16); convert_hex(hmacsha1_key_str, hmacsha1_key, 20); } HMAC_CTX_init(&hmacsha1_ctx); HMAC_Init_ex(&hmacsha1_ctx, hmacsha1_key, sizeof(hmacsha1_key), EVP_sha1(), NULL); AES_set_decrypt_key(aes_key, CIPHER_KEY_LENGTH * 8, &aes_decrypt_key); if (verbose >= 1) { fprintf(stderr, "aeskey:\n"); print_hex(stderr, aes_key, 16); } if (verbose >= 1) { fprintf(stderr, "hmacsha1key:\n"); print_hex(stderr, hmacsha1_key, 20); } if (hdr_version == 2) { if (verbose >= 1) { fprintf(stderr, "data offset : %llu\n", v2header.dataoffset); fprintf(stderr, "data size : %llu\n", v2header.datasize); } fseek(in, v2header.dataoffset, SEEK_SET); } else { fseek(in, 0L, SEEK_SET); } chunk_no = 0; while(fread(inbuf, CHUNK_SIZE, 1, in) > 0) { decrypt_chunk(inbuf, outbuf, chunk_no); chunk_no++; // fix for last chunk if(hdr_version == 2 && (v2header.datasize-ftell(out)) < CHUNK_SIZE) { fwrite(outbuf, v2header.datasize - ftell(out), 1, out); break; } fwrite(outbuf, CHUNK_SIZE, 1, out); } if (verbose >= 1) { fprintf(stderr, "%d chunks written\n", chunk_no); } fclose(in); fclose(out); return(0); }