tsvenbla
tsvenbla

Reputation: 432

Decrypt function doesn't work as intended

I'm taking a course in fundamental encryption/decryption algorithms, and I'm stuck on this one lab assignment.

We're given a C file called simplecrypt.c that, when run, takes an input file and encrypts it to an output file (the input remains intact). Our assignment is to write a decrypt function in simplecrypt.c as well, so that you can encrypt and decrypt your files, not just encrypt them. And this is where I'm stuck. I don't know if I'm making it too simple or if I took water over my head with this course, but if anyone can shed some light in what I'm doing wrong, I'd greatly appreciate it.

This is how the encrypt function looks like. I believe it's AES, if I'm not mistaken? Please note that the encryption key has been given to us in plain text:

int crypt(unsigned char *key,
             unsigned char *pInputBuf,
             unsigned char *pOutputBuf,
             long nLength)
{
    int nKeyPos = 0;
    long n;
    unsigned char KeyA = 0;

    if((pInputBuf != NULL) && (pOutputBuf != NULL))
    {
        for(n = 0; n < KEY_BUF; n++)
            KeyA ^= key[n];

        nKeyPos = KeyA%KEY_BUF;

        for(n = 0; n < nLength; n++)
        {
            pOutputBuf[n] = pInputBuf[n]^(key[nKeyPos]*KeyA);
            KeyA += pOutputBuf[n];
            nKeyPos = pOutputBuf[n]%KEY_BUF;
        }
        return 0;   // success
    }
    return 1;
}

And this is the decrypt that I made:

int decrypt(unsigned char *key,
             unsigned char *pInputBuf,
             unsigned char *pOutputBuf,
             long nLength)
{
    int nKeyPos = 0;
    long n;
    unsigned char KeyA = 0;

    if((pInputBuf != NULL) && (pOutputBuf != NULL))
    {
        for(n = 0; n < KEY_BUF; n++)
            KeyA ^= key[n];

        nKeyPos = KeyA%KEY_BUF;

        for(n = 0; n < nLength; n++)
        {
            // This is where I made changes.
            pInputBuf[n] = pOutputBuf[n]^(key[nKeyPos]*KeyA);
            KeyA += pInputBuf[n];
            nKeyPos = pInputBuf[n]%KEY_BUF;
        }
        return 0;   // success
    }
    return 1;
}

Basically, all I did was to reverse the pInputBuf with pOutputBuf and vice versa. Why doesn't this work in practice when it works in theory? As I said, any help that could send me down the right direction would be awesome.

This is the full code:

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

#define KEY_BUF 20
#define FNAME_BUF 256


void stripnl(char *str) 
{
    while(strlen(str) && ((str[strlen(str) - 1] == 13) || (str[strlen(str) - 1] == 10))) 
    {
        str[strlen(str) - 1] = 0;
    }
}


long writefile(unsigned char *pOutputBuf, long size) 
{
    FILE *outfile;
    char fname[FNAME_BUF];
    unsigned char *p = pOutputBuf;
    long i=0;

    // Read in the filename
    printf("Enter the name of the output file: ");
    fgets(fname, sizeof(fname), stdin);

    // We need to get rid of the newline char
    stripnl(fname);

    // Open the file. If NULL is returned there was an error, corrected to VS2012 standard
    // if((outfile = fopen(fname, "wb")) == NULL) 
    if((fopen_s(&outfile, fname, "wb")) != 0) 
    {
        printf("Error Opening File.\n");
        return(0);
    }

    // Put characters in outfile
    while( (i < size) && (fputc(*(p++), outfile) != EOF) )
        i++;

    fclose(outfile);  // Close the file
    return i;
}


char* readfile(unsigned char *pInutBuf, long *nLength) 
{
    FILE *infile;
    char fname[FNAME_BUF];
    int ch=0;
    long i;

    // Read in the filename
    printf("Enter the name of the input file: ");
    fgets(fname, sizeof(fname), stdin);

    // We need to get rid of the newline char
    stripnl(fname);

    // Open the file. If anything else than 0 is returned there was an error
    if((fopen_s(&infile, fname, "rb")) != 0) 
    {
        printf("Error Opening File.\n");
        return(0);
    }

    // get file size
    fseek(infile, 0L, SEEK_END);
    *nLength = ftell(infile);
    // rewind
    fseek(infile, 0L, SEEK_SET);

    pInutBuf = (unsigned char *) malloc(*nLength+1);

    // Read in characters and place them in "buffer"
    ch = fgetc(infile);
    for(i=0; (i < *nLength) && (feof(infile) == 0); i++)
    {
        pInutBuf[i] = (unsigned char)ch;
        ch = fgetc(infile);
    }

    // end of buffer
    pInutBuf[i] = '\0';

    fclose(infile);
    return pInutBuf;
}


int crypt(unsigned char *key,
             unsigned char *pInputBuf,
             unsigned char *pOutputBuf,
             long nLength)
{
    int nKeyPos = 0;
    long n;
    unsigned char KeyA = 0;

    if((pInputBuf != NULL) && (pOutputBuf != NULL))
    {
        for(n = 0; n < KEY_BUF; n++)
            KeyA ^= key[n];

        nKeyPos = KeyA%KEY_BUF;

        for(n = 0; n < nLength; n++)
        {
            pOutputBuf[n] = pInputBuf[n]^(key[nKeyPos]*KeyA);
            KeyA += pOutputBuf[n];
            nKeyPos = pOutputBuf[n]%KEY_BUF;
        }
        return 0;   // success
    }
    return 1;
}

int decrypt(unsigned char *key,
     unsigned char *pOutputBuf,
     unsigned char *pInputBuf,
     long nLength)
{
     int nKeyPos = 0;
     long n;
     unsigned char KeyA = 0;

     if ((pInputBuf != NULL) && (pOutputBuf != NULL))
     {
          for (n = 0; n < KEY_BUF; n++)
               KeyA ^= key[n];

          nKeyPos = KeyA%KEY_BUF;

          for (n = 0; n < nLength; n++)
          {
               pInputBuf[n] = pOutputBuf[n] ^ (key[nKeyPos] * KeyA);
               KeyA += pInputBuf[n];
               nKeyPos = pInputBuf[n] % KEY_BUF;
          }
          return 0; // success
     }
     return 1;
}


int main(int argc, char *argv[])
{
    // KEY_BUF+1 corrected to VS2012 standard, we never use the last +1 ('\0') uchar
    unsigned char key[KEY_BUF+1]="abcdefghijklmnopqrst";
    unsigned char *pInputBuf=NULL;
    unsigned char *pOutputBuf=NULL;
    long nLength=0, n;

    if((pInputBuf = readfile(pInputBuf, &nLength)) == NULL)
        return 1;

    pOutputBuf = (unsigned char *) malloc(nLength);

    //if(crypt(key, pInputBuf, pOutputBuf, nLength) != 0)
        //return 2;

    if(decrypt(key, pOutputBuf, pInputBuf, nLength) != 0)
        return 2;

    if(writefile(pOutputBuf, nLength) == 0)
        return 3;
/*
    for(n = 0; n < nLength; n++)
        printf("%c", pInputBuf[n]);
    printf("\n");

    for(n = 0; n < nLength; n++)
        printf("%X", pOutputBuf[n]);
    printf("\n");
*/
    // Free up memory
    if(pInputBuf)
        free(pInputBuf);
    if(pOutputBuf)
        free(pOutputBuf);

    getchar(); // pause and wait for key
    return 0;
}

Upvotes: 0

Views: 173

Answers (1)

user5329483
user5329483

Reputation: 1272

In crypt() you alter KeyA/nKeyPos based of the encrypted cipher text. In decrypt() you alter KeyA/nKeyPos based of the decrypted plain text.

Try this:

int crypt( unsigned char *key,
           const unsigned char *pPlaintext, //input
           unsigned char *pCiphertext,      //output
           long nLength)
{
    ...
    for(n = 0; n < nLength; n++)
    {
        pCiphertext[n] = pPlaintext[n] ^ (key[nKeyPos]*KeyA);
        KeyA += pCiphertext[n];
        nKeyPos = pCiphertext[n] % KEY_BUF;
    }
}

int decrypt( unsigned char *key,
             const unsigned char *pCiphertext, //input
             unsigned char *pPlaintext,        //output
             long nLength)
{
    ...
    for(n = 0; n < nLength; n++)
    {
        pPlaintext[n] = pCiphertext[n] ^ (key[nKeyPos]*KeyA);
        KeyA += pCiphertext[n];
        nKeyPos = pCiphertext[n] % KEY_BUF;
    }
}

Upvotes: 4

Related Questions