If you have a good example of simply encrypting a file using openssl that is better than this one that I am having issues with I would be very grateful.
Update: Myabe the author was correct. Using memset on something I did not allocate reminds me of strtok choking on non-stack variables.
Update2: Got the core dump to stop by using malloc. Updated the code. The control Hs are still appearing. Updating the code to reflect this.
Update3: The looping structure does not appear correct in the example. I am unsure how subsequent reads are occuring greater than the size of the initial read.
Update4: I think I found it. decrypt loop has a olen += tlen and the buffer should discard that set of bits. :( not it.
Update99988: I have given up all hope here. I think I need to throw away this example and start with something from the Openssl book instead. Upon decrypting the middle layer buffers are preappended with ^H's but since a pointer is passed in I am beginning to suspect alignment issues.
I think I may be in the boat of starting with a bad example is worse than starting from scratch. i had to make some corrections (the original is annotated in the code below). The original author had some issues with passing addresses incorrectly. My mind is being kicked around by the different sized buffers the author is using 1024 and 1032 but I think it is related to the 8 bit seed and chained encryption calls.
I am getting garbage characters in (control Hs) and a core dump like the decryption is corrupting the stack. I am fairly new to encryption, openssl, and I am not all that familiar with gdb.
I have made every attempt to simplify this down
- 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
BAD CODE WARNING BAD CODE USE CODE FROM SELECTED ANSWER blowfish.c
/*
This code is a modificaiton of work cieted below. It
was modified by ojblass June 16, 2009.
The original can be found at http://tldp.org/LDP/LG/issue87/vinayak.html
TERMS OF THE Open Publication License (OPL)
Copyright © 2003, Vinayak Hegde. Copying license
http://www.linuxgazette.com/copying.html
Published in Issue 87 of Linux Gazette, February 2003
1. The modified version must be labeled as such.
2. The person making the modifications must be identified and the modifications
dated.
3. Acknowledgement of the original author and publisher if applicable must be
retained according to normal academic citation practices.
4. The location of the original unmodified document must be identified.
5. The original author's (or authors') name(s) may not be used to assert or
imply endorsement of the resulting document without the original author's (or
authors') permission.
*/
#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;
}