Thread: c aes256 padding with pkcs#7 standard

  1. #1
    Registered User
    Join Date
    May 2012
    Location
    Italy
    Posts
    53

    c aes256 padding with pkcs#7 standard

    Encryption program:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <gcrypt.h>
    
    
    #define GCRYPT_VERSION "1.5.0"
    
    
    int main(void){
        if(!gcry_check_version(GCRYPT_VERSION)){
            fputs("libgcrypt version mismatch\n", stderr);
            exit(2);
        }
        //gcry_control(GCRYCTL_SUSPEND_SECMEM_WARN);
        gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0);
        //gcry_control(GCRYCTL_RESUME_SECMEM_WARN);
        gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
    
    
        int algo = -1;
        char key[32] = {0x80};
        char iniVector[16] = {0};
        char plain_text[16];
        char *encBuffer = NULL;
        const char *name = "aes256";
        size_t blkLength, keyLength, txtLenght = 16, retval = 0;
        
        blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES256);
        keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER_AES256);
        
        FILE *fp = fopen("prova", "r+");
        FILE *fpout = fopen("out", "w+");    
        algo = gcry_cipher_map_name(name);
        encBuffer = malloc(txtLenght);
    
    
        gcry_cipher_hd_t hd;
        gcry_cipher_open(&hd, algo, GCRY_CIPHER_MODE_CBC, 0);
        gcry_cipher_setkey(hd, key, keyLength);
        gcry_cipher_setiv(hd, iniVector, blkLength);
    
    
        fseek(fp, 0, SEEK_SET);
    
    
        /* AGGIUNGERE CIFRATURA DIMENSIONE FILE INIZIALE NEL FILE CIFRATO */
        
        while(!feof(fp)){
            memset(plain_text, 0, sizeof(plain_text));
            retval = fread(plain_text, 1, 16, fp);
            if(!retval) break;
            gcry_cipher_encrypt(hd, encBuffer, txtLenght, plain_text, txtLenght);
            fwrite(encBuffer, 1, 16, fpout);
        }
    
    
        gcry_cipher_close(hd);
        free(encBuffer);
        fclose(fp);
        fclose(fpout);
    
    
        return 0;
    }
    decryption program:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <gcrypt.h>
    
    
    #define GCRYPT_VERSION "1.5.0"
    
    
    int main(void){
        if(!gcry_check_version(GCRYPT_VERSION)){
            fputs("libgcrypt version mismatch\n", stderr);
            exit(2);
        }
        //gcry_control(GCRYCTL_SUSPEND_SECMEM_WARN);
        gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0);
        //gcry_control(GCRYCTL_RESUME_SECMEM_WARN);
        gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
    
    
        int algo = -1;    
        char key[32] = {0x80};
        char iniVector[16] = {0};
        char plain_text[16];
        char *encBuffer = NULL;
        const char *name = "aes256";
        size_t blkLength, keyLength, txtLenght = 16, retval = 0;
    
    
        blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES256);
        keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER_AES256);
        
        FILE *fp = fopen("out", "r+");
        FILE *fpout = fopen("origdec", "w+");
        algo = gcry_cipher_map_name(name);
        encBuffer = malloc(txtLenght);
    
    
        gcry_cipher_hd_t hd;
        gcry_cipher_open(&hd, algo, GCRY_CIPHER_MODE_CBC, 0);
        gcry_cipher_setkey(hd, key, keyLength);
        gcry_cipher_setiv(hd, iniVector, blkLength);
    
    
        fseek(fp, 0, SEEK_SET);
    
    
        /* MIGLIORARE NOME VARIABILI E AGGIUNGERE CIFRATURA DIMENSIONE FILE INIZIALE NEL FILE CIFRATO */
        while(!feof(fp)){
            memset(plain_text, 0, sizeof(plain_text));
            retval = fread(plain_text, 1, 16, fp);
            if(!retval) break;
            gcry_cipher_decrypt(hd, encBuffer, txtLenght, plain_text, txtLenght);
            fwrite(encBuffer, 1, 16, fpout); // così il file di output sarà della stessa dimensione di quello di input
        }
        
        gcry_cipher_close(hd);
        free(encBuffer);
        fclose(fp);
        fclose(fpout);
    
    
        return 0;
    }
    The first program encrypt the file prova with aes256 in cbc mode. The encrypted file is called out
    The second program decrypt the file out and the output file is origdec

    I know that these 2 programs are not well coded (i'm planning new features soon and code cleanup soon) but before doing these things i prefer to develop e GOOD encryption program :-)
    So my question is: i want to add the PKCS#7 removable padding, how can i do it? Any suggestion please? :-)

    ps: what is pkcs#7 removable padding?
    the file is encrypted block by block where each block is 16 bytes. The last block may not be 16 bytes long so there's the need to "fill" it with something. The pkcs#7 standard expects that the block is filled with the number of "non filled" position. So if in a block of 16 bytes only 4 bytes are occupied the last 12 bytes are filled with 0x12

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    https://tools.ietf.org/html/rfc2315#section-10.3
    2. Some content-encryption algorithms assume the
    input length is a multiple of k octets, where k > 1, and
    let the application define a method for handling inputs
    whose lengths are not a multiple of k octets. For such
    algorithms, the method shall be to pad the input at the
    trailing end with k - (l mod k) octets all having value k -
    (l mod k), where l is the length of the input. In other
    words, the input is padded at the trailing end with one of
    the following strings:

    01 -- if l mod k = k-1
    02 02 -- if l mod k = k-2
    .
    .
    .
    k k ... k k -- if l mod k = 0

    The padding can be removed unambiguously since all input is
    padded and no padding string is a suffix of another. This
    padding method is well-defined if and only if k < 256;
    methods for larger k are an open issue for further study.
    The first thing to do in the encoder is pay attention to retval. If that is <16, then calculate the padding byte value (as above), and pad the buffer appropriately.

    In the decoder, you need some method to determine whether you've read the last block.
    If it is the last block, then you need to look for padding bytes before writing the block to the file.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2012
    Posts
    1,066

  4. #4
    Registered User
    Join Date
    May 2012
    Location
    Italy
    Posts
    53
    Thanks Andi :-) i will solve this after the padding problem ;-)
    @Salem: so the correct flow for the encryption program could be:
    1) read the file size, divide it by 16 and get the number of total block (eventually +1 if it is a floating number)
    2) encrypt the file and when the last block is reached fill it with 0xYY

    the decryption program routine will be:
    1) read the encrypted file size, divide it by 16 and get the number of block
    2) when reached the last block check for the padding value

    Could this be ok?
    The last problem is how and where to write the padding value!
    It must be wrote to the encrypted file and i think that it must be encrypted, doesn't it?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Structure Padding in C
    By karthik537 in forum C Programming
    Replies: 3
    Last Post: 06-15-2011, 07:10 AM
  2. Structure padding
    By MK27 in forum C Programming
    Replies: 4
    Last Post: 12-15-2009, 02:25 PM
  3. padding
    By R.Stiltskin in forum C++ Programming
    Replies: 8
    Last Post: 01-31-2009, 04:24 PM
  4. 0xff padding?
    By *ClownPimp* in forum C Programming
    Replies: 3
    Last Post: 01-23-2003, 12:08 PM

Tags for this Thread