SHA-256 library (libsha256)¶
SHA-256 message digest (FIPS 180-4) for callers that need a hash without pulling in a TLS stack, for example to verify
what has been written back to flash or to check a firmware payload before applying it.
The implementation is a single-file extract from libtomcrypt, kept in the
upstream formatting so that it stays diffable against the original. The snapshot it was taken from is recorded in
libsha256/sbom.json.
Application interface¶
Data types¶
sha256_ctx_t- hashing state, allocated by the caller and initialized bysha256_init. Its contents are internal to the library.typedef union { struct sha256_state { uint64_t length; uint32_t state[8], curlen; unsigned char buf[SHA256_BLOCK_SIZE]; } sha256; } sha256_ctx_t;
Constants¶
SHA256_DIGEST_SIZE- digest length in bytes (32),SHA256_BLOCK_SIZE- compression function block length in bytes (64).
Functions¶
All functions return 0 on success and a non-zero value on failure (invalid arguments, or a message longer than the
algorithm allows).
sha256_init- Initializes the hashing statemd. Has to be called before any other operation on it.int sha256_init(sha256_ctx_t *md);
sha256_process- Processesinlenbytes ofinthrough the hash. The API is streaming, so it can be called any number of times and the message never has to be held in memory as a whole.int sha256_process(sha256_ctx_t *md, const unsigned char *in, unsigned long inlen);
sha256_done- Terminates the hash, writingSHA256_DIGEST_SIZEbytes of digest toout. The state must not be used afterward without re-initializing it.int sha256_done(sha256_ctx_t *md, unsigned char *out);
mem_neq- Compareslenbytes ofaandbin constant time, returning0when they are equal and non-zero when they are not. Use it wherever inequality means a wrong key or a forged digest - a plainmemcmp()leaks the position of the first mismatch through its execution time. Test the result against0and never against1: aNULLargument is reported with a different non-zero value, soif (mem_neq(...) == 1)would accept what it was meant to reject.int mem_neq(const void *a, const void *b, size_t len);
Using libsha256¶
Add the library to the LIBS variable in the Makefile and include the header:
Makefile - linking with the
libsha256library.NAME := fwverify LOCAL_SRCS := main.c LIBS := libsha256 include $(binary.mk)
main.c- hashing a file without holding it in memory.#include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <libsha256.h> int main(int argc, char *argv[]) { sha256_ctx_t ctx; unsigned char digest[SHA256_DIGEST_SIZE], buf[512]; ssize_t n; int fd, i; fd = open(argv[1], O_RDONLY); if (fd < 0) { return 1; } sha256_init(&ctx); while ((n = read(fd, buf, sizeof(buf))) > 0) { sha256_process(&ctx, buf, n); } close(fd); sha256_done(&ctx, digest); for (i = 0; i < SHA256_DIGEST_SIZE; i++) { printf("%02x", digest[i]); } printf("\n"); return 0; }
Tests¶
The library is covered by unit tests placed next to it, which are built and run by the build system - see Unit tests placed next to the code.