2

When I write the code SHA_CTX shash to SHA1_Final(hash, &shash), I have an error of Segmentation Fault, or in another case I have return value of 255. I don't understand why happen. This is a simple example.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <openssl/sha.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/obj_mac.h>

int main() {

    BIGNUM *x=BN_new();
    BIGNUM *y=BN_new();
    BIGNUM *n=BN_new();
    BIGNUM *e=BN_new();

    EC_POINT *P;

    BN_CTX *ctx;//Buffer

    const EC_POINT *G; //Generator Point

    unsigned char hash[SHA_DIGEST_LENGTH];

    SHA_CTX shash;
    SHA1_Init(&shash);
    SHA1_Update(&shash, "abc", 3);
    SHA1_Final(hash, &shash);

    const EC_GROUP *curve = EC_GROUP_new_by_curve_name(NID_secp224r1);

    P=EC_POINT_new(curve);

    G=EC_GROUP_get0_generator(curve);

    EC_GROUP_get_order(curve,n,ctx);

    BN_rand_range(e,n);

    EC_POINT_mul(curve,P,e,NULL,NULL,ctx);

    if (!EC_POINT_is_on_curve(curve,P,ctx)) return -1; 
    if (!EC_POINT_get_affine_coordinates_GFp(curve, P, x, y, ctx)) return -1;


    for(int i=0;i<SHA_DIGEST_LENGTH;i++)
    {
        printf("%02x",hash[i]);
    }


    return 0;
}
JLo
  • 53
  • 1
  • 7
  • If I comment the code from SHA_CTX to SHA1_Final, then this code works. – JLo Jun 12 '16 at 10:19
  • The recommended way to do this with later versions of OpenSSL, like 1.0.2 and 1.1.0, is the EVP interface. Also see [EVP Message Digests](http://wiki.openssl.org/index.php/EVP_Message_Digests) on the OpenSSL wiki. – jww Jun 12 '16 at 21:57

1 Answers1

3

The flag -Wall can be added to enable every warnings as the program is compiled. One of the warnings suggests the origin of the problem:

main4.c:36:23: warning: ‘ctx’ is used uninitialized in this function [-Wuninitialized]

Indeed, the value of the pointer ctx is not initialized. Hence, ctx can point anywhere and this leads to undefined behavior, such as segmentation faults.

Could you add the following line ?

BN_CTX *ctx=BN_CTX_new();//Buffer 

It seems to solve the segmentation fault. I compiled by gcc main.c -o main -I /usr/local/ssl/include -L /usr/local/ssl/lib -lssl -lcrypto -ldl -Wall -std=c99

francis
  • 9,525
  • 2
  • 25
  • 41
  • Thanks for you support @francis. Little curiosity: Why do you select C99 Standard and not C89 or C11 ? Again thanks. – JLo Jun 12 '16 at 16:19
  • You're welcome ! I used c99 because my compiler is running c89 by default. Hence, i got the following error: `‘for’ loop initial declarations are only allowed in C99 mode`. Hence, i switched to c99. Of course, c11 could have been used instead. – francis Jun 12 '16 at 16:24
  • Thanks very much @francis. Great ! – JLo Jun 12 '16 at 17:08