1

I can run a c programm without problems on my Linux Mint system on a other Linux system I get a memory access error.

void digest_message(const unsigned char *message, size_t message_len, unsigned char **digest, unsigned int *digest_len)
{
    EVP_MD_CTX *mdctx;

    if((mdctx = EVP_MD_CTX_create()) == NULL)
        handleErrors();
    if(1 != EVP_DigestInit_ex(mdctx, EVP_sha1(), NULL))
        handleErrors();
    if(1 != EVP_DigestUpdate(mdctx, message, message_len))
        handleErrors();
    if((*digest = (unsigned char *)OPENSSL_malloc(EVP_MD_size(EVP_sha1()))) == NULL)
        handleErrors();
    if(1 != EVP_DigestFinal_ex(mdctx, *digest, digest_len))
        handleErrors();

    EVP_MD_CTX_destroy(mdctx);
}

void main ()

{
...
    const unsigned char *message= (const unsigned char*) decryptedtext;
    size_t mlen=x;
    unsigned char *digest;
    unsigned int dlen;
    digest_message(message,mlen,&digest,&dlen);

    // if i printf in a for loop i get this memmory access error 
    for(int i=0;i<dlen;i++)
        printf("%x ",digest[i]);
    }

I tried it with:

printf("%x ",digest[0]);
printf("%x ",digest[1]);
printf("%x ",digest[2]);
...

and got no error

Why does this happen? How can I change it?

Thanks in advance

DrosvarG
  • 483
  • 3
  • 14
Detlef7able
  • 191
  • 1
  • 2
  • 12
  • Will you please copy/paste the error message? It will help a lot in finding out what the problem is. – virolino Jun 26 '19 at 08:54
  • Also, please provide us a compilable and executable code, in order to be able to understand what is not OK. We do not need the confidential information in the code, but just what is needed for us to understand. – virolino Jun 26 '19 at 08:57
  • What happens when you step through the program with a debugger? (And being able to step through a program with a debugger is just **another** reason why stuffing everything into one line of code like `if((*digest = (unsigned char *)OPENSSL_malloc(EVP_MD_size(EVP_sha1()))) == NULL)` is a really **BAD** idea. Given your code, you simply can not tell if a call to `EVP_MD_size()` or `EVP_sha1()` ever failed.) – Andrew Henle Jun 26 '19 at 09:02

2 Answers2

-1

I can spot the following (potential) problems.


I can run a c programm without problems on my Linux Mint

I think that it is just a happy coincidence, that you do not see the problems.


const unsigned char *message= (const unsigned char*) decryptedtext;

If decryptedtext is just a pointer, then accessing it further using message is quite a bad idea. Normally, you should have memory allocated, in order to access it.


size_t mlen=x;

Ideally, mlen should be related to the length of message. If mlen is bigger then the real length of message, you are in trouble (buffer overflow, memory corruption...).


unsigned int dlen;

How do you make sure that dlen is not bigger than the number of entries available in digest?


printf("%x ",digest[i]);

Why do you want to printf a string (digest) as a hexadecimal number?

---------------------

if(decryptedtext[0]==0x25 &&   //%
    decryptedtext[1]==0x50 &&  //P
    decryptedtext[2]==0x44 &&  //D
    decryptedtext[3]==0x46)    //F
{ printf("%s",decryptedtext);
  break;
}

This is ugly. decryptedtext is not a null-terminated string, therefore printf() will not print only 4 characters.


int x;
f = fopen("test.pdf", "w+b");
if(f == NULL) {
printf("Datei konnte nicht geoeffnet werden.\n");
}else {

while(x<decryptedtext_len)  {
    putc(decryptedtext[x],f);
    x++;
}

x is not initialized before being used.


unsigned char hasharrayone[20];
unsigned char hasharraytwo[20];
unsigned char hasharraythree[20];

You could have used:

unsigned char hasharray[3][20];

int xc;
file = fopen("sxxxxx-dest-cipher.bin", "w+b");
if(file == NULL) {
printf("Datei konnte nicht geoeffnet werden.\n");
}else {
while(xc<cpl)  {
    putc(cfbciphertext[xc],file);
    xc++;
}

xc is not initialized.

virolino
  • 2,073
  • 5
  • 21
  • I have a bin file and i want to compare something so hex is helpful. The function digest_message gives dlen the value. – Detlef7able Jun 26 '19 at 08:54
  • OK, but the buffer is longer than 1 character, I assume. That `printf()` only prints 1 hex code. – virolino Jun 26 '19 at 10:58
-1

You have an undefined behavior using printf("%x ", digest[i]).

As mentionned in this answer using the wrong format specifier results in an undefined behavior. This is probably why the behavior of your program depends on the OS you are running on (it may also depend of your hardware and compiler).

As I don't have the error message, it's hard to know what happens in your case, but as "%x" format specifier usually works with unsigned int it should reads 4bytes in memory. As disgest[i] is a unsigned char, it is written on 1byte only and this is probably why you get a memory access error.

Converting your unsigned char variable digest[i] to an unsigned int before using printf should resolve your issue.

Also, this topic should help you printing hexadecimal characters

DrosvarG
  • 483
  • 3
  • 14
  • 1
    Because of default argument promotions that happen to arguments passed to the variable argument list, the rvalue `digetst[i]` is implicitly converted from `unsigned char` to `int`. Because of this `%x` should work [cppreference](https://en.cppreference.com/w/c/language/conversion#Default_argument_promotions) – KamilCuk Jun 26 '19 at 10:43
  • @KamilCuk Good point didn't know about it. Though, `digetst[i]` refers to a part of the memory so it should not be an rvalue but an lvalue, am I wrong ? Is there any possibility this fact change anything ? I mean... Is it possible to implicitely type convert an lvalue ? – DrosvarG Jun 26 '19 at 11:43
  • 1
    C doesn't really have any distinction between "lvalue" and "rvalue". "lvalue" is just an expression that can be assigned to. "rvalue" means just a "value of an expression". In C++ there happens something called "lvalue to rvalue conversion" and some other magic, in C it's more or less meaningless. In C "rvalue" is more like a jargon. The `digest[i]` is an lvalue, for sure, cause the `*` operator. I meant to say "rvalue" only meaning "the value of the `digest[i]` expression". The only place "rvalue" term is ever used in C is only [in a note](https://port70.net/~nsz/c/c11/n1570.html#note64). – KamilCuk Jun 26 '19 at 11:52