Wednesday, January 5, 2022

[SOLVED] Need Help Finding Segmentation fault in C Program

Issue

I'm implementing the Data Encryption Standard in C for a personal learning project and I have a seg fault that has been driving me up the wall for the past 3 days. I understand this isn't the place for "fix my code for me" type questions, but I need a second pair of eyes to look over this:

/*we must define our own modulo, as the C modulo returns unexpected results:*/

#define MOD(x, n) ((x % n + n) % n)

/*example: the 12th bit should be in the second byte so return 1 (the first byte being 0)*/

#define GET_BYTE_NUM(bit_index) (bit_index/8)

/*example: a bit index of 12 means this bit is the 4th bit of the second byte so return 4*/ 

#define GET_BIT_NUM(bit_index) MOD(bit_index, 8)

typedef unsigned char byte;
 
/*each row represents a byte, at the bit to be place in the position
 * for example for the first row (first byte) we will place bits 31, 0, 1, 2, 3, 4 in
 * in bit positions 0-6, respectively. The last two bits will be left blank. Since this is supposed to be a crypto implementation, static prevents this value from being accessed outside the file.*/
const static byte e_box[8][6] = { {31, 0, 1, 2, 3, 4}, {3, 4, 5, 6, 7, 8}, {7, 8, 9, 10, 11, 12}, {11, 12, 13, 14, 15, 16}, {12, 16, 17, 18, 19, 20}, {19, 20, 21, 22, 23, 24},
{23, 24, 25, 26, 27, 28}, {27, 28, 29, 30, 31, 0} }


void e(byte **four_byte_block)
{
    int i, n, l = 0, four_bit_num, four_byte_num;
    /*create the new byte_block and initialize all values to 0, we will have 4 spaces of bytes, so 32 bits in total*/
    byte *new_byte_block = (byte*)calloc(4, sizeof(byte));
    byte bit;
    for(i = 0 i < 8; i++)
    {
        for(n = 0; n < 6; n++)
        {
            /*get the byte number of the bit at l*/
            four_byte_num = GET_BYTE_NUM(e_box[i][n]);
            /*find what index the bit at l is in its byte*/
            half_bit_num = GET_BIT_NUM(e_box[i][n]);
   
            bit = *four_byte_block[half_byte_num]; /*SEG FAULT!*/

        }
    }
    /*finally, set four_byte_block equal to new_byte_block*/
    /*four_byte_block = NULL;
     * four_byte_block = new_byte_block;*/
}

I have narrowed the problem down to the line marked /SEG FAULT!/ but I can't see what the issue is. When I print the half_byte_num, I get a number that is within bounds of half_block, and when I print the values of half_block, I can confirm that those values exist.

I believe I may be doing something wrong with the pointers ie by passing **four_byte_block, (a pointer to a pointer) and it's manipulation could be causing the seg fault.


Solution

Have you tried this:

bit = (*four_byte_block)[half_byte_num];

Instead of this:

bit = *four_byte_block[half_byte_num];

Those are not the same, as an example, take the following code:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char **lines = malloc(sizeof(char *) * 8);

    for (int i = 0; i < 8l; i++)
        lines[i] = strdup("hey");

    printf("%c\n", *lines[1]);
    printf("%c\n",(*lines)[1]);
    return 0;
}

The former will output h. The latter will output e.

This is because of the operators precedence, [] will be evalued before *, thus if you want to go to the nth index of *foo, you need to type (*foo)[n].



Answered By - lfalkau