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
andSHA_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