-1

encrypt:

while(!feof(fp)){
    memset(plain_text, 0, sizeof(plain_text));
    retval = fread(plain_text, 1, 16, fp);
    if(!retval) break;
    for(i=0; i<16; i++){
        if(plain_text[i] == 0){
            for(j=i; j<16; j++){
                plain_text[j] = 0x0i;
            }
            break;
        }
    }
    gcry_cipher_encrypt(hd, encBuffer, txtLenght, plain_text, txtLenght);
    fwrite(encBuffer, 1, 16, fpout);
}

decrypt:

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);
    for(i=0; i<16; i++){
        if(encBuffer[i] == 0x0i){
            j = 0;
            j += i;
            if(encBuffer[++i] == 0x0j){
                last = 1;
                i--;
                j=i;
                printf("found a %d\n", i);
                break;
            }
            else i--;
        }
    }
    //printf("%d\n", j);
    if(last == 1) fwrite(encBuffer, 1, j, fpout);
    else fwrite(encBuffer, 1, 16, fpout);
}

i'm trying to add the removable padding from the pkcs#7 standard but i have a problem.
If i work with txt files my program work perfectly but if i try to decrypt some tar.gz or pdf file the decrypt program stop at half of file size!
For example let's take a tar.gz archive which size is 28272 bytes (prova is the original file, out is the encrypted file and origdec is the decrypted file):

28272   prova
28272   out
12147   origdec

i'm using libgcrypt on gnu/linux!

polslinux
  • 1,739
  • 9
  • 34
  • 73

2 Answers2

3

The problem is probably that you are, without your knowledge, using an extension to the C language in GCC: Imaginary numbers. The literals 0x0i and 0x0j are imaginary number literals. If you use any other name for your variable you will get compilation errors.

It seems like you are mistaking the presentation of numbers with the representation of them. In your program, the integer literal 0x0a is the presentation of the binary representation 00001010. This means that you can use the variables i and j directly, instead of trying to present them as hexadecimal numbers:

plain_text[j] = i;

and

if(encBuffer[i] == i)
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
3

There are many things wrong:

  • You're adding the padding to any block that contains a zero byte. A binary file such as your tar.gz will likely contain many zero bytes unlike your text file. You need to identify when you have read the last block (and its size) by looking at fread's return value (it will be < 16) and checking ferror in case there was a read error.
  • You are using 0xi and 0xj when you mean just i and j.
  • For PKCS#7 you need to write the number of padding bytes as the padding value (16-i), not i, which is the remaining data bytes.
  • On decryption you are trying to detect padding somehow in any block. This is why your decryot is short. You need to read and decrypt all the cipher text, then remove the padding only from the last block.

Hope that helps!

Frank
  • 403
  • 2
  • 5