Search code examples
copensslsha

sha512: c program using the openSSL library


I have a program in C, which calculates sha256 hash of input file. It is using the openSSL library. Here is the core of the program:

#include <openssl/sha.h>

SHA256_CTX ctx;
unsigned char buffer[512];

SHA256_Init(&ctx);
SHA256_Update(&ctx, buffer, len);
SHA256_Final(buffer, &ctx);

fwrite(&buffer,32,1,stdout);

I need to change it to calculate sha512 hash instead.

Can I just (naively) change all the names of the functions from SHA256 to SHA512, and then in the last step fwrite 64 bytes, instead of the 32 bytes ? Is that all, or do I have to make more changes ?


Solution

  • Yes, this will work. The man page for the SHA family of functions lists the following:

     int SHA256_Init(SHA256_CTX *c);
     int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
     int SHA256_Final(unsigned char *md, SHA256_CTX *c);
     unsigned char *SHA256(const unsigned char *d, size_t n,
                           unsigned char *md);
    

    ...

    int SHA512_Init(SHA512_CTX *c);
     int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
     int SHA512_Final(unsigned char *md, SHA512_CTX *c);
     unsigned char *SHA512(const unsigned char *d, size_t n,
                           unsigned char *md);
    

    ...

    SHA1_Init() initializes a SHA_CTX structure.

    SHA1_Update() can be called repeatedly with chunks of the message to be hashed (len bytes at data).

    SHA1_Final() places the message digest in md, which must have space for SHA_DIGEST_LENGTH == 20 bytes of output, and erases the SHA_CTX.

    The SHA224, SHA256, SHA384 and SHA512 families of functions operate in the same way as for the SHA1 functions. Note that SHA224 and SHA256 use a SHA256_CTX object instead of SHA_CTX. SHA384 and SHA512 use SHA512_CTX. The buffer md must have space for the output from the SHA variant being used (defined by SHA224_DIGEST_LENGTH, SHA256_DIGEST_LENGTH, SHA384_DIGEST_LENGTH and SHA512_DIGEST_LENGTH). Also note that, as for the SHA1() function above, the SHA224(), SHA256(), SHA384() and SHA512() functions are not thread safe if md is NULL.

    To confirm, let's look at some code segments. First with SHA256:

    SHA256_CTX ctx;
    unsigned char buffer[512];
    
    char *str = "this is a test";
    int len = strlen(str);
    
    strcpy(buffer,str);
    
    SHA256_Init(&ctx);
    SHA256_Update(&ctx, buffer, len);
    SHA256_Final(buffer, &ctx);
    
    fwrite(&buffer,32,1,stdout);
    

    When run as:

    ./test1 | od -t x1
    

    Outputs:

    0000000 2e 99 75 85 48 97 2a 8e 88 22 ad 47 fa 10 17 ff
    0000020 72 f0 6f 3f f6 a0 16 85 1f 45 c3 98 73 2b c5 0c
    0000040
    

    Which matches the output of:

    echo -n "this is a test" | openssl sha256
    

    Which is:

    (stdin)= 2e99758548972a8e8822ad47fa1017ff72f06f3ff6a016851f45c398732bc50c
    

    Now the same code with the changes you suggested:

    SHA512_CTX ctx;
    unsigned char buffer[512];
    
    char *str = "this is a test";
    int len = strlen(str);
    
    strcpy(buffer,str);
    
    SHA512_Init(&ctx);
    SHA512_Update(&ctx, buffer, len);
    SHA512_Final(buffer, &ctx);
    
    fwrite(&buffer,64,1,stdout);
    

    The output when passed through "od" gives us:

    0000000 7d 0a 84 68 ed 22 04 00 c0 b8 e6 f3 35 ba a7 e0
    0000020 70 ce 88 0a 37 e2 ac 59 95 b9 a9 7b 80 90 26 de
    0000040 62 6d a6 36 ac 73 65 24 9b b9 74 c7 19 ed f5 43
    0000060 b5 2e d2 86 64 6f 43 7d c7 f8 10 cc 20 68 37 5c
    0000100
    

    Which matches the output of:

    echo -n "this is a test" | openssl sha512 
    

    Which is:

    (stdin)= 7d0a8468ed220400c0b8e6f335baa7e070ce880a37e2ac5995b9a97b809026de626da636ac7365249bb974c719edf543b52ed286646f437dc7f810cc2068375c