SHA

Digest

digest is a single operation, equivalent to the following pseudo-code:

h = sha.init()
h.update(data)
h.digest()

Naming convention

CC_<algorithm>_digest

Where algorithm is one of:

  • SHA_1

  • SHA_224, SHA_256, SHA_384, SHA_512.
    • SHA_512_224 and SHA_512_256.

  • SHA_3_224, SHA_3_256, SHA_3_384, SHA_3_512.

Function signature

The function must have the following signature:

int SHA_digest(
uint8_t *digest,
const size_t digest_size,
const uint8_t *input,
const size_t input_size,
)
Parameters:
  • digest[Out] An allocated buffer to return the resulting digest.

  • digest_size[In] The size of the digest buffer.

  • input[In] The input data.

  • input_size[In] The size of the input data in bytes.

Returns:

A status value, following OpenSSL’s convention.

Return values:
  • 1 – OK.

  • 0 – Digest failed.

Example

To test that the harness integration is working correctly, we use the following OpenSSL harness:

#include <openssl/evp.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

int generic_digest(uint8_t *digest, const uint8_t *input,
                   const size_t input_size, const char *name);

int CC_SHA_256_digest(uint8_t *digest, const size_t digest_size,
                      const uint8_t *input, const size_t input_size) {
  return generic_digest(digest, input, input_size, "SHA256");
}

int CC_SHA_384_digest(uint8_t *digest, const size_t digest_size,
                      const uint8_t *input, const size_t input_size) {
  return generic_digest(digest, input, input_size, "SHA384");
}

int CC_SHA_512_digest(uint8_t *digest, const size_t digest_size,
                      const uint8_t *input, const size_t input_size) {
  return generic_digest(digest, input, input_size, "SHA512");
}

int CC_SHA_512_224_digest(uint8_t *digest, const size_t digest_size,
                      const uint8_t *input, const size_t input_size) {
  return generic_digest(digest, input, input_size, "SHA512-224");
}

int CC_SHA_3_384_digest(uint8_t *digest, const size_t digest_size,
                      const uint8_t *input, const size_t input_size) {
  return generic_digest(digest, input, input_size, "SHA3-384");
}

int generic_digest(uint8_t *digest, const uint8_t *input,
                   const size_t input_size, const char *name) {
  const EVP_MD *md = EVP_get_digestbyname(name);
  if (md == NULL) {
    fprintf(stderr, "Failed to get digest %s\n", name);
    return 0;
  }

  EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
  if (!EVP_DigestInit_ex2(mdctx, md, NULL)) {
    fprintf(stderr, "Init failed\n");
    goto clean;
  }
  if (!EVP_DigestUpdate(mdctx, input, input_size)) {
    fprintf(stderr, "Update failed\n");
    goto clean;
  }
  if (!EVP_DigestFinal_ex(mdctx, digest, NULL)) {
    fprintf(stderr, "Final failed\n");
    goto clean;
  }

  EVP_MD_CTX_free(mdctx);
  return 1;

clean:
  EVP_MD_CTX_free(mdctx);
  return 0;
}

Compile the shared library with the -lssl -lcrypto options.

gcc -fPIC -shared sha_harness.c -o sha.so -lssl -lcrypto

Then test the harness.

crypto-condor-cli test harness sha.so