2

Here's how I calculate a SHA512 hash in C.

#include <openssl/sha.h>
#include <stdio.h>

char *calc_sha512(char *data) {
    SHA512_CTX ctx;
    char *md = malloc(sizeof(char)*(SHA512_DIGEST_LENGTH+1));

    SHA512_Init(&ctx);
    SHA512_Update(&ctx, data, strlen(data));
    SHA512_Final(md, &ctx);
    md[SHA512_DIGEST_LENGTH] = '\0';

    return md;
}

int main() {
    printf("%s\n", calc_sha512("foo"));

    return 1;
}

Now when I try to transform it to 512/t (either 512/224 or 512/256), it doesn't work. I initially thought that for calculating a 512/t hash, you'd simply have to truncate the output to t bits, but upon further reading, it doesn't only truncate the output, it also have different initial constant values. So I'm trying to figure out any function in OpenSSL that supports that? So far I have looked into docs and header files, I can't find such method under either SHA or EVP. Does OpenSSL even support SHA512/t hashing algorithms? Does it provide the functionality out of the box? Any pointers to that would be helpful.

Umayr
  • 933
  • 1
  • 10
  • 19
  • 1
    Also see Kelsey's talks on truncation hashes. Their is no reduction in proof that the truncated hash from SHA-1 and SHA-2 family have the same security as the full size hash. [Cryptographic Hash Workshop (2005) - Truncation Mode for SHA](https://csrc.nist.gov/CSRC/media/Events/First-Cryptographic-Hash-Workshop/documents/Kelsey_Truncation.pdf). – jww Dec 26 '17 at 21:24
  • *`return md`* will probably break since the hash will likely have an embedded NULL. Or it won't have a NULL where you expect. Do you realize it is a binary string and not an ASCIIZ string? Also see [Calculate and print SHA256 hash of a file using OpenSSL](https://stackoverflow.com/q/7853156/608639), [How to print SHA512 hash in C](https://stackoverflow.com/q/36381509/608639), [Generate SHA hash in C++ using OpenSSL library](https://stackoverflow.com/q/918676/608639) (and friends). – jww Dec 26 '17 at 21:32
  • @jww That was something I came up with over the top of my head, I don't expect it to run the way its written. I was trying to achieve something like [this](https://play.golang.org/p/qjLvPiRsj1e) in C using OpenSSL. I couldn't find anything in APIs whatsoever. Is there a way I could do that even manually in C? – Umayr Dec 27 '17 at 07:47
  • *"Is there a way I could do that even manually in C"* - Do what? OpenSSL has SHA-1 through SHA-512. The linked questions show you how to do it. – jww Dec 31 '17 at 08:39

2 Answers2

0

As you noticed, those truncated sha512 hashes use different initalisation vectors, probably to avoid giving away part of the actual sha512 hash if they would just literally truncate those bytes.

Support for sha512_256 has been implemented in the OpenSSL master tree a few months ago and will likely be in OpenSSL 1.1.1.

Check the changelog: https://www.openssl.org/news/changelog.txt

Or the commit on Github: https://github.com/openssl/openssl/commit/4bed94f0c11ef63587c6b2edb03c3c438e221604

... so depending on the platform you're on, you could use those new functions in the near future just like you are doing with the sha512 example you provided.

wvh
  • 181
  • 1
  • 6
0

this function should return the SHA512/256 hash (binary form, not printable)

char *calc_sha512_256(char *data, unsigned int data_len) {
    char *hash = malloc(SHA256_DIGEST_LENGTH);

    if (!EVP_Digest(data, data_len, hash, NULL, EVP_sha512_256(), NULL)) {
        free(hash);
        hash = NULL;
    }
    return hash;
}
Arthur H
  • 181
  • 3