1

I am trying to read 16 bytes at a time from a file, and every 16 bytes must be encrypted and written to an output file. Assuming the encryption function shift_encrypt is working, how can I apply it to 16 bytes at time. Currently I am attempting to store the bytes in an array plaintext but it is not working

void encryption(char filename[MAX_PATH_LEN], char password[CIPHER_BLOCK_SIZE + 1]) {
    
    char output[256];
    snprintf(output, sizeof(output), "%s.ecb", filename);
    FILE *output_stream = fopen(output, "wb");
   
    if (output_stream == NULL) {
        perror(output);
    }

    FILE *input_stream = fopen(filename, "rb");
    if (input_stream == NULL) {
        perror(filename);
    } 

    char plaintext[17];
    while (fread(plaintext, 16, 1, input_stream) != 0) {
        fwrite(shift_encrypt(plaintext, password), 16, 1, output_stream);
    }

    fclose(output_stream);
}
wohlstad
  • 12,661
  • 10
  • 26
  • 39
  • 2
    `it is not working` Could you explain _what exactly_ is not working? – tkausl Aug 06 '22 at 13:47
  • 2
    FreeAntiVirus, `shift_encrypt(plaintext, password)` (from [here](https://stackoverflow.com/q/73258549/2410359)) is a problem as `plaintext[]` is not certainly a _string_. `password[]` may not be a _string_ either. Post a [mcve]. – chux - Reinstate Monica Aug 06 '22 at 13:53
  • 1
    Assuming it is a string, would the code I have work? Because I am getting a stack buffer overflow error when I run it. For example I am reading from a text file containing 'AAAABBBBCCCCDDDDE', and the password is 'passwordpassword' It says this error is occuring in shift_encrypt. Is this because there are 17 characters in the file? How would I fix this issue in the code I posted above... – FreeAntiVirus Aug 06 '22 at 14:04
  • 2
    Shouldn't you `return` after `perror()` ? – sj95126 Aug 06 '22 at 14:08
  • ^ extension of my previous comment: as in have it encrypt 16 bytes a time? – FreeAntiVirus Aug 06 '22 at 14:14
  • See @chux's comment - the input is not a string. `fread()` does not add a nul character at the end of the input for you. That's almost certainly why you're getting a stack buffer overflow, because `shift_encrypt()` is trying to parse something that's not nul-terminated at the end of the 16 bytes. – sj95126 Aug 06 '22 at 14:34
  • is there a better way to read 16 bytes at a time, I have been trying with fgetc but cant get it to work... – FreeAntiVirus Aug 06 '22 at 14:41
  • Please read the comments. If the `shift_encrypt` implementation you're using is the one referenced in the [link](https://stackoverflow.com/q/73258549/2410359) provided by @chux-ReinstateMonica , then it clearly expects a null terminated `char` array. Your `char` array `plaintext` is *not* null terminated. – G.M. Aug 06 '22 at 15:12
  • FreeAntiVirus, is it clear that, in C, a _string_ must have and ends with a terminating _null character_, else it is not a _string_? – chux - Reinstate Monica Aug 06 '22 at 18:16

1 Answers1

2

How to read 16 bytes from a file at a time and store them into an array (?)

Code is doing that part just fine.

Assuming it is a string, would the code I have work? Because I am getting a stack buffer overflow error when I run it. For example I am reading from a text file containing 'AAAABBBBCCCCDDDDE', and the password is 'passwordpassword'

The assumption is incorrect.

Consider why code is plaintext[] size 17, yet never assigned plaintext[16] and only reading 16. Code is not reading 'AAAABBBBCCCCDDDDE', but only 'AAAABBBBCCCCDDDD' and the last (17th) character of plaintext[] is never assigned.

Try char plaintext[17]; = { 0 }; to initialize the array. Then character plaintext[16] will be a null character and after a successful fread(plaintext, 16, 1, input_stream), plainttext[] will be a string suitable for shift_encrypt(plaintext, password).

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Yes that helps when there are exactly 16 bytes in the file thank you! If there aren't exact 16 bytes how would I round up the file size to the next multiple of 16? – FreeAntiVirus Aug 07 '22 at 02:16
  • Instead of `fread(plaintext, 16, 1, input_stream)`, use `size_t n = fread(plaintext, 1, 16, input_stream);` (note argument change). When `n` is 16 perform as before, when `n==0`, stop. When n = 1 to 15, you have a shorter amount to deal with. append a `\0` and process the shorter string - simplifications possible. – chux - Reinstate Monica Aug 07 '22 at 02:20