> From: owner-openssl-us...@openssl.org 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 openssl-users@openssl.org Automated List Manager majord...@openssl.org