If you have a good example of simple file encryption using openssl, which is better than the one I'm having problems with, I would really appreciate it.
Update: Myabe author was right. Using memset for something that I didn't allocate reminds me of strtok, choking on unsteady variables.
Update2:. Reset the main dump using malloc. Updated code. Hs management still appears. Code update to reflect this.
Update3: The loop structure in the example does not look correct. I'm not sure how subsequent reads exceed the size of the initial read.
Update4: I think I found. the decryption loop has olen + = tlen, and the buffer should discard this set of bits. :( not it.
Update99988: I left all hope here. I think I need to drop this example and start with something from the Openssl book. When decrypting, the mid-level buffers are pre-populated with ^ H, but as the pointer is passed, I begin to suspect alignment problems.
I think I can be in a boat, starting with a bad example, worse than starting from scratch. I had to make some corrections (the original is annotated in the code below). The original author had some problems with the wrong address flow. My mind is pushed by buffers of various sizes, which the author uses 1024 and 1032, but I think this is due to 8-bit semantic and encoded encryption calls.
I get garbage characters in (control Hs), and a kernel dump, such as decryption, distorts the stack. I'm new to encryption, openssl, and I'm not so familiar with gdb.
I made all attempts to simplify this.
- gcc --version reports 4.3.2
- Open SUSE 11
compile.sh
gcc -g -o blowfish blowfish.c -lcrypto
run.sh
ulimit -c unlimited ./blowfish example.txt encrypted_example decrypted_example echo diff example.txt decrypted_example diff example.txt decrypted_example
clean.sh
rm -rf blowfish encrypted_example decrypted_example core
example.txt
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Hydrogen H Helium H Lithium L Beryllium B Boron B Carbon C Nitrogen N Oxygen O Fluorine F Neon N Sodium N Magnesium M Aluminium A Silicon S Phosphorus P Sulfur S Chlorine C Argon A Potassium K Calcium C Scandium S Titanium T Vanadium V Chromium C Manganese M Iron F Cobalt C Nickel N Copper C Zinc Z Gallium G Germanium G Arsenic A Selenium S Bromine B Krypton K Rubidium R Strontium S Yttrium Y Zirconium Z Niobium N Molybdenum M Technetium T Ruthenium R Rhodium R Palladium P Silver A Cadmium C Indium I Tin S Antimony S Tellurium T Iodine I Xenon X Caesium C Barium B Lanthanum L Cerium C Praseodymium P Neodymium N Promethium P Samarium S Europium E Gadolinium G Terbium T Dysprosium D Holmium H Erbium E Thulium T Ytterbium Y Lutetium L Hafnium H Tantalum T Tungsten W Rhenium R Osmium O Iridium I Platinum P Gold A Mercury H Thallium T Lead P Bismuth B Polonium P Astatine A Radon R Francium F Radium R Actinium A Thorium T Protactinium P Uranium U Neptunium N Plutonium P Americium A Curium C Berkelium B Californium C Einsteinium E Fermium F Mendelevium M Nobelium N Lawrencium L Rutherfordium R Dubnium D Seaborgium S Bohrium B Hassium H Meitnerium M Darmstadtium D Roentgenium R Ununbium U Ununtrium U Ununquadium U Ununpentium U Ununhexium U Ununseptium U Ununoctium U
WARNING BAD CODE BAD CODE USE CODE FROM A SEPARATE RESPONSE blowfish.c
#include <openssl/blowfish.h> #include <openssl/evp.h> #include <fcntl.h> #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <string.h> #define IP_SIZE 1024 #define OP_SIZE 1032 unsigned char key[16]; unsigned char iv[8]; int generate_key () { int i, j, fd; if ((fd = open ("/dev/random", O_RDONLY)) == -1) perror ("open error"); if ((read (fd, key, 16)) == -1) perror ("read key error"); if ((read (fd, iv, 8)) == -1) perror ("read iv error"); printf ("128 bit key:\n"); for (i = 0; i < 16; i++) printf ("%4d ", key[i]); printf ("\nInitialization vector\n"); for (i = 0; i < 8; i++) printf ("%4d ", iv[i]); printf ("\n"); close (fd); return 0; } int decrypt (int infd, int outfd) { char *inbuff, *outbuf; int olen, tlen, n; EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init (&ctx); EVP_DecryptInit (&ctx, EVP_bf_cbc (), key, iv); outbuf = (unsigned char *) malloc ( sizeof(unsigned char) * IP_SIZE ); inbuff = (unsigned char *) malloc ( sizeof(unsigned char) * OP_SIZE ); /* keep reading until a break */ for (;;) { memset(inbuff,'\0', OP_SIZE); if ((n = read (infd, inbuff, OP_SIZE)) == -1) { perror ("read error"); break; } else if (n == 0) break; memset(outbuf,'\0', IP_SIZE); if (EVP_DecryptUpdate (&ctx, outbuf, &olen, inbuff, n) != 1) { printf ("error in decrypt update\n"); return 0; } if (EVP_DecryptFinal (&ctx, outbuf + olen, &tlen) != 1) { printf ("error in decrypt final\n"); return 0; } olen += tlen; if ((n = write (outfd, outbuf, olen)) == -1) perror ("write error"); } EVP_CIPHER_CTX_cleanup (&ctx); return 1; } int encrypt (int infd, int outfd) { char *inbuff, *outbuf; int olen, tlen, n; EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init (&ctx); EVP_EncryptInit (&ctx, EVP_bf_cbc (), key, iv); outbuf = (unsigned char *) malloc ( sizeof(unsigned char) * OP_SIZE ); inbuff = (unsigned char *) malloc ( sizeof(unsigned char) * IP_SIZE ); for (;;) { memset(inbuff,'\0', IP_SIZE); if ((n = read (infd, inbuff, IP_SIZE)) == -1) { perror ("read error"); break; } else if (n == 0) break; if (EVP_EncryptUpdate (&ctx, outbuf, &olen, inbuff, n) != 1) { printf ("error in encrypt update\n"); return 0; } if (EVP_EncryptFinal (&ctx, outbuf + olen, &tlen) != 1) { printf ("error in encrypt final\n"); return 0; } olen += tlen; if ((n = write (outfd, outbuf, olen)) == -1) perror ("write error"); } EVP_CIPHER_CTX_cleanup (&ctx); return 1; } int main (int argc, char *argv[]) { int flags1 = 0, flags2 = 0, outfd, infd, decfd; mode_t mode; char choice, temp; int done = 0, n, olen; memset(key,'\0', 16); memset(iv,'\0', 8); memset(&mode, '\0', sizeof(mode)); flags1 = flags1 | O_RDONLY; flags2 = flags2 | O_RDONLY; flags2 = flags2 | O_WRONLY; flags2 = flags2 | O_CREAT; mode = mode | S_IRUSR; mode = mode | S_IWUSR; generate_key (); if ((infd = open (argv[1], flags1, mode)) == -1) perror ("open input file error"); if ((outfd = open (argv[2], flags2, mode)) == -1) perror ("open output file error"); encrypt (infd, outfd); close (infd); close (outfd); if ((outfd = open (argv[2], flags1, mode)) == -1) perror ("open output file error"); if ((decfd = open (argv[3], flags2, mode)) == -1) perror ("open output file error"); /* After much head scratching reusing the out as an in is correct here */ decrypt (outfd, decfd); close (outfd); fsync (decfd); close (decfd); return 0; }