unsigned long lSize;
FILE * inFile;
FILE * outFile;
size_t n,m;
char * pTemp;
char * buffer;
const AES_KEY *key;
inFile = fopen("SB2.bin", "rb");
outFile = fopen("finalPackResult", "wb+");
unsigned char uKey[]=
"3834373532303435333730323834383132373330393233343531323330383839";
unsigned char iv[] = "36363333383630393433313132323031";
int keyLength = sizeof(uKey);
int ivLength = sizeof(iv);
printf("key length:%d.\n",keyLength);
printf("Initialisation vector length:%d.\n",ivLength);
/* get file size and allocate memory to buffer */
fseek (inFile , 0,SEEK_END);
lSize = ftell (inFile);
rewind (inFile);
printf("File size is: %ld.\n",lSize);
unsigned char pInBuff[lSize];
unsigned char pOutBuff[lSize];
/* Allocate memory */
memset(pInBuff,0,lSize * sizeof(char));
memset(pOutBuff,0,lSize * sizeof(char));
buffer = (char *)malloc(sizeof(char)*lSize);
/* Read the input signature package which contains
* encrypted data. The AES encryption technique
* with CBC mode is followed
*/
if ((n = fread (pInBuff, 1, lSize, inFile)) == -1)
{
printf ("read error");
return -1;
}
printf("Data read from input binary is :%d\n", n);
if (n == 0)
{
printf ("Data read error from input file.\n");
return -1;
}
printf("LINE :%d.\n",__LINE__);
/* The AES_cbc_encrypt() function implements the Cipher Block Chaining
(CBC)
* mode of operation. It encrypts or decrypts B<in> using the key
schedule
* B<schedule> and places the result in B<out>. The value of B<length>
is
* the length of B<in> in bytes
*/
AES_set_decrypt_key(uKey, 256, &key);
printf("LINE :%d.\n",__LINE__);
AES_cbc_encrypt(pInBuff, pOutBuff, lSize, key, iv, AES_DECRYPT);---here
i'm getting segfault
printf("LINE :%d.\n",__LINE__);
pTemp = AES_options();
printf("AES function to which pointed:%s.\n", pTemp);
/* Write decrypted data into a file */
if((m=fwrite(pOutBuff, 1, lSize, outFile)) == -1)
{
printf ("Write error.\n");
}
if(m != n)
{
printf("Didn't write the data properly.%dbytes info missed",n-m);
}
printf("size of data written is:%d.\n",m);
return 0;
}
Thanks in Advance.
--
View this message in context: http://old.nabble.com/AES-cbc--How-to-Init-Openssl--tp12475822p26387613.html
Sent from the OpenSSL - User mailing list archive at Nabble.com.
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openss...@openssl.org
Automated List Manager majo...@openssl.org
> #include
> #inclide
> #incldue
I assume these were just a hint that the real code
has correct #include's.
> int main()
> {
>
> unsigned long lSize;
> FILE * inFile;
> FILE * outFile;
> size_t n,m;
> char * pTemp;
> char * buffer;
> const AES_KEY *key;
> inFile = fopen("SB2.bin", "rb");
> outFile = fopen("finalPackResult", "wb+");
You don't check for fopen() failure.
>
> unsigned char uKey[]=
> "3834373532303435333730323834383132373330393233343531323330383839";
> unsigned char iv[] = "36363333383630393433313132323031";
>
As already said, these are apparently the hex 'armoring' of the
key and iv, which is needed on a command line (because shell
etc. generally can't handle binary) but not used in code.
> int keyLength = sizeof(uKey);
> int ivLength = sizeof(iv);
Even after you change to the correct values, these lengths are one
too high. sizeof gives you the size of the whole array, which
includes the null terminator. strlen() gives you the length
of the valid content *before* the null terminator, and (thus)
only works on things that are null-terminated strings (which
ciphertext usually isn't, and keys and ivs often aren't).
But you don't really use them anyway.
> printf("key length:%d.\n",keyLength);
> printf("Initialisation vector length:%d.\n",ivLength);
>
> /* get file size and allocate memory to buffer */
> fseek (inFile , 0,SEEK_END);
> lSize = ftell (inFile);
> rewind (inFile);
It is a FGA on comp.lang.c that this isn't guaranteed to work
on all systems -- but *no* method is guaranteed to work on all
systems, so this is among the less bad alternatives.
> printf("File size is: %ld.\n",lSize);
Technically an unsigned long should use %lu not %ld.
In practice this will usually work except that values
greater than usually 2147483647 will display wrong.
> unsigned char pInBuff[lSize];
> unsigned char pOutBuff[lSize];
>
This (Variable Length Arrays, also mixed-code-decl) only
works in C99, or GNU89 which added it as an extension.
The portable way is malloc, as below.
> /* Allocate memory */
> memset(pInBuff,0,lSize * sizeof(char));
> memset(pOutBuff,0,lSize * sizeof(char));
> buffer = (char *)malloc(sizeof(char)*lSize);
>
sizeof(char) is *always* 1 per the standard.
There's no point in zeroing these buffers since
you proceed to (try to) fully overwrite them.
You don't check for malloc failure, but you don't
use buffer for anything anyway.
> /* Read the input signature package which contains
> * encrypted data. The AES encryption technique
> * with CBC mode is followed
> */
> if ((n = fread (pInBuff, 1, lSize, inFile)) == -1)
> {
> printf ("read error");
> return -1;
> }
fread doesn't return -1 for error; any value less than
the third (count) argument is error or EOF. (The Unix-level
read and write, and send and recv etc., do return -1.
Some *other* stdio routines return EOF which is defined by
the standard only as negative, but conventionally is -1.)
On some systems size_t is not large (wide) enough to
represent all possible file sizes; on such systems
this will process only a (small) part of the data.
Solutions are more complicated than you need now.
> printf("Data read from input binary is :%d\n", n);
> if (n == 0)
> {
> printf ("Data read error from input file.\n");
> return -1;
> }
> printf("LINE :%d.\n",__LINE__);
>
>
> /* The AES_cbc_encrypt() function implements the Cipher
> Block Chaining
> (CBC)
> * mode of operation. It encrypts or decrypts B<in> using the key
> schedule
> * B<schedule> and places the result in B<out>. The
> value of B<length>
> is
> * the length of B<in> in bytes
> */
> AES_set_decrypt_key(uKey, 256, &key);
> printf("LINE :%d.\n",__LINE__);
>
You need to give this routine, and the next, a pointer
to a AES_KEY object. Instead you give it a pointer to
a pointer. Your compiler should have warned you about
the type mismatch. Either set a pointer validly e.g.
/*not const!*/ AES_KEY * pkey = malloc (sizeof(AES_KEY));
if( pkey == NULL ) some_error_handling;
and pass pkey in both places, or just declare an object
/*not const!*/ AES_KEY key;
and pass &key to both set__key and _encrypt .
> AES_cbc_encrypt(pInBuff, pOutBuff, lSize, key, iv,
> AES_DECRYPT);---here
> i'm getting segfault
This is now trying to deref the totally garbage pointer
value in key created by the bad call above.
> printf("LINE :%d.\n",__LINE__);
> pTemp = AES_options();
> printf("AES function to which pointed:%s.\n", pTemp);
>
> /* Write decrypted data into a file */
> if((m=fwrite(pOutBuff, 1, lSize, outFile)) == -1)
> {
> printf ("Write error.\n");
> }
> if(m != n)
> {
> printf("Didn't write the data properly.%dbytes info
> missed",n-m);
> }
This one you got correct; fwrite also returns m < n not -1.
If size_t is wider than int, which is pretty rare, %d is
wrong and can screw up. The safest C89 way is to cast to
or just use unsigned long and %lu; GNU unsigned long long
and %llu; C99 uintmax_t and I forget I think %zu .
> printf("size of data written is:%d.\n",m);
> return 0;
> }
>
the shell command for decryption of my file is o
penssl enc -d -K
3834373532303435333730323834383132373330393233343531323330383839 -iv
36363333383630393433313132323031 -aes-256-cbc -in finalSigPackage.bin -out
x.zip
so what is the key I need to give in my code...??please help me!!
some error checking is removed as their file pointers are ready in the
code...and modification done to earlier is the file is read completely at
once not by chunks..
Here is my modified code :
INCLUDE FILES:
*/
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <openssl/aes.h>
#define AES_BLOCK_SIZE 16
int main()
{
unsigned long size;
FILE * inFile;
FILE * outFile;
char * pInBuff;
char * pOutBuff;
size_t n,m;
AES_KEY *key = malloc (sizeof(AES_KEY));
if (key == NULL)
{
printf ("Error in AES_KEY.\n");
return -1;
}
if((inFile = fopen("gout.bin", "rb")) == NULL)
{
printf ("Error in open input file.\n");
return -1;
}
if((outFile = fopen("finalPackResult", "wb")) == NULL)
{
printf ("Error in opening ouput file.\n");
return -1;
}
unsigned char uKey[] = "84752045370284812730923451230889";
unsigned char iv[] = "6633860943112201";
/* get file size */
struct stat st;
fstat(fileno(inFile), &st);
size = st.st_size;
printf("File size is:%lu.\n",size);
pInBuff = (char *)malloc(size * sizeof(char));
pOutBuff = (char *)malloc(size * sizeof(char));
/* Read the input signature package which contains
* encrypted data. The AES encryption technique
* with CBC mode is followed
*/
/* file is read in chunks
* and is written into file
* decrypt final uses the buffer which has decrypted data
*/
if(!AES_set_decrypt_key(uKey, 256, &key))
{
printf ("Error in set decrypt key.\n");
return -1;
}
if ((n = fread (pInBuff, 1, size, inFile)) < size)
{
printf ("read error\n");
return -1;
}
printf("Data read from input binary is :%d \n", n);
/* The AES_cbc_encrypt() function implements the Cipher Block Chaining
(CBC)
* mode of operation. It encrypts or decrypts B<in> using the key
schedule
* B<schedule> and places the result in B<out>. The value of B<length>
is
* the length of B<in> in bytes
*/
AES_cbc_encrypt((const unsigned char *)pInBuff,
(unsigned char *)pOutBuff,
size,
&key,
iv,
AES_DECRYPT);
/* Write decrypted data into a file */
fwrite(pOutBuff, 1, size, outFile);
printf("size of data written is:%lu.\n", m);
fclose (inFile);
fclose (outFile);
return 0;
}
--
View this message in context: http://old.nabble.com/AES-cbc--How-to-Init-Openssl--tp12475822p26421214.html
Sent from the OpenSSL - User mailing list archive at Nabble.com.
> #include <sys/types.h>
> #include <unistd.h>
> #include <stdlib.h>
> #include <string.h>
> #include <stdio.h>
> #include <openssl/aes.h>
> #define AES_BLOCK_SIZE 16
This is already in aes.h, you don't need to define it yourself.
>
> int main()
> {
>
> unsigned long size;
> FILE * inFile;
> FILE * outFile;
> char * pInBuff;
> char * pOutBuff;
I would make these pointer to unsigned char, since
that's how you want to use them; see below.
> size_t n,m;
> AES_KEY *key = malloc (sizeof(AES_KEY));
>
> if (key == NULL)
> {
> printf ("Error in AES_KEY.\n");
> return -1;
> }
Okay, key points to suitable memory for a key object.
<snip file opens and allocs>
> if(!AES_set_decrypt_key(uKey, 256, &key))
> {
> printf ("Error in set decrypt key.\n");
> return -1;
> }
>
key is a pointer, so pass its value, not &key.
&key here causes OpenSSL to clobber your stack frame.
key causes it to use the memory you correctly allocated.
As I said, the other approach is to declare an actual object
AES_KEY /*not pointer!*/ key;
and pass &key in both places. Experienced C programmers
(IMO) consider it better style to use this form for small
fixed-size objects (as opposed to things like your data
buffers, which apparently depend on the file you are given).
It's not illegal or unsafe to use malloc for such things,
just more work and clutter, less efficient and less common.
In general, whenever you get an error return from an OpenSSL
routine, you should look at OpenSSL's error info. Either
call ERR_get_error() to get the number, preferably decode it
with ERR_error_string assuming you have loaded error strings,
display, and repeat until you get 0; or if you have a suitable
outfile, which stderr usually is, just call ERR_print_errors.
But in this particular case, of an *invalid* pointer,
it appears to me OpenSSL won't detect it and thus can't
give you good error information here.
<snip read>
> AES_cbc_encrypt((const unsigned char *)pInBuff,
> (unsigned char *)pOutBuff,
> size,
> &key,
> iv,
> AES_DECRYPT);
>
Again key not &key, unless key is an actual object.
And if the pointers are to unsigned char, no casts.
<snip write>