'Aes-128-cbc encryption in C and decryption in openssl

I have written a code that reads a file and encrypts it using Aes-cbc-128

# include <stdio.h>
//# include <ctype.h>
# include <string.h>
# include <stdio.h>
# include <stdlib.h>
# include <openssl/aes.h>

# define BLOCK_LEN  16
# define MAXBUF     256
# define MAXHEX     (MAXBUF * 2) + 1
# define KEY        "0123456789abcdef"
# define IV     "RandomIVRandomIV"
unsigned int bin2hex (unsigned char *in, unsigned char *out, unsigned int len);
unsigned int hex2bin (unsigned char *in, unsigned char *out, unsigned int len);
unsigned int PadData (unsigned char *ibuf, unsigned int ilen, int blksize);
unsigned int NoPadLen (unsigned char *ibuf, unsigned int ilen);


 void print_hex(char *iv)
     {int i=0;


        for (i =0; i < 16; ++i)
            printf("%02x", iv[i]);

        printf("\n"); 

     }

void callkey (unsigned char *keyFileName)
{
   unsigned char key[] = KEY;

FILE *keyFile = fopen(keyFileName, "wb");
 fwrite(key, 1, 16, keyFile);
        fclose(keyFile);
printf("Key Hex : "); 
    print_hex(key);
}


int
main(int argc, char *argv[])
{
  unsigned long ilen;
  unsigned char data[MAXBUF];   // command line input
  unsigned char ibuf[MAXBUF + BLOCK_LEN];   // padded input to encrypt
  unsigned char obuf[MAXHEX];   // encrypt output
  unsigned char xbuf[MAXHEX];   // hex encrypt output
  unsigned char ybuf[MAXBUF];   // hex decrypt output
  unsigned char dbuf[MAXBUF];   // decrypt output
  unsigned char key[] = KEY;
  unsigned char iv[]  = IV;
  AES_KEY aeskeyEnc, aeskeyDec;

  unsigned int len =0;

  FILE *inFile = fopen(argv[1], "rb");

  FILE *outFile = fopen(argv[2], "wb");
    unsigned char *k1ey = "static.key";
    callkey(k1ey);


    while((len = fread(data, 1, sizeof(data), inFile)) > 0) 
    { 
     // prepare the input data with padding
     printf("len = %d \n", len);
     memset (ibuf, 0x00, MAXBUF);
     memcpy (ibuf, data, len); 


    // pad and calc length of block to encode
     ilen = PadData (ibuf, len, BLOCK_LEN);
    printf("ilength = %ld \n", ilen);

    // init cipher keys 
    AES_set_encrypt_key (key, 128, &aeskeyEnc);
    AES_set_decrypt_key (key, 128, &aeskeyDec);



    // encrypt string
    memcpy (iv,IV, sizeof (IV));
    memset(obuf, 0x00, MAXHEX);
    AES_cbc_encrypt (ibuf, obuf, ilen, &aeskeyEnc, iv, AES_ENCRYPT);
    len = fwrite(obuf,1, ilen, outFile);
    printf("writtenLen: %d\n", len);

    memset(data, 0x00, MAXBUF);

  } // while (1)


  fclose(inFile);

  fclose(outFile);




  return (0);
}


/*
 * The PadData() function is used to pad input data for cipher block
 * chaining using standard padding as specified in PKCS#5.  Input data
 * is padded in place.  The ilen value is the length of the data before
 * padding.  The blksize parameter is the block size to use (16 for AES
CBC).
 * The function returns the new length of ibuf after padding.
 *
 * NOTE: The ibuf must be large enough to hold at least blksize additional
 * bytes of data to accommodate padding.
 */

unsigned int
PadData (unsigned char *ibuf, unsigned int ilen, int blksize)
{
  unsigned int   i;         // loop counter
  unsigned char  pad;           // pad character (calculated)
  unsigned char *p;         // pointer to end of data



 //if(ilen % blksize == 0)
//   return ilen; 


  // calculate pad character
  pad = (unsigned char) (blksize - (ilen % blksize));


  // append pad to end of string
  p = ibuf + ilen;
  for (i = 0; i < (int) pad; i++) {
    *p = pad;
    ++p;
  }

  return (ilen + pad);
}

In openssl I decrypt the file i have encoded,

gcc aescodefile -o aes -lcrypto -lssl -ldl    #this is to to complile code
./aes filetobeencrypted.txt    encryptedfile  #execute file

openssl enc -aes-128-cbc -d -in filetobeencrypted.txt -out aes-decrypted.c  -p -nosalt -K 30313233343536373839616263646566 -iv 52616e646f6d495652616e646f6d4956

This code gives some junk values in between after decrypting. I cannot increase the buffer size. Please suggest what could be done to correct this.



Solution 1:[1]

The problem is that the C code performs padding for each 256 byte buffer. Instead it should encrypt without padding blocks of 256 bytes. Then it should pad the last block of plain text and encrypt that (even if it is a full block size or 0 bytes).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Maarten Bodewes