> From: [email protected] On Behalf Of NaGaGo
> Sent: Tuesday, 17 November, 2009 05:35
> #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;
> }
>
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [email protected]
Automated List Manager [email protected]