ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
hmac_sha256.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file hmac_sha256.h
6 * @brief HMAC-SHA2-256 (RFC 2104 + FIPS 198-1) - streaming context and one-shot API.
7 *
8 * The shared keyed-MAC primitive for the whole library: SSH binary-packet MAC (RFC 4253 ยง6.4), the
9 * TLS 1.3 / QUIC / DTLS HKDF PRF, SNMPv3 usmHMACSHAAuthProtocol, JWT HS256, CSRF tokens, and SMB 2.x
10 * message signing / the SP800-108 KDF. Built over the pc_sha256 streaming functions so the inner
11 * SHA-256 hardware acceleration (where present) is transparent.
12 *
13 * RFC 2104 construction: HMAC(K, m) = H((K XOR opad) || H((K XOR ipad) || m)), H = SHA-256.
14 *
15 * SECURITY NOTE - a MAC must be verified before the covered plaintext is acted upon; that ordering
16 * guarantee lives in each protocol's packet layer, not here. These functions are pure crypto.
17 *
18 * @author Douglas Quigg (dstroy0)
19 * @date 2026
20 */
21
22#ifndef PROTOCORE_HMAC_SHA256_H
23#define PROTOCORE_HMAC_SHA256_H
24
25#include "crypto/hash/sha256.h"
26#include <stddef.h>
27#include <stdint.h>
28
29/** @brief HMAC-SHA2-256 output length in bytes. */
30#define PC_HMAC_SHA256_LEN 32
31
32/**
33 * @brief Compute HMAC-SHA2-256 over a single contiguous buffer.
34 *
35 * @param key MAC key bytes.
36 * @param key_len Key length in bytes. Keys > 64 bytes are pre-hashed per RFC 2104; keys <= 64 bytes
37 * are zero-padded to the block length. SSH-derived keys are always 32 bytes.
38 * @param data Input bytes.
39 * @param len Input length.
40 * @param mac Output buffer, must be PC_HMAC_SHA256_LEN bytes.
41 */
42void pc_hmac_sha256(const uint8_t *key, size_t key_len, const uint8_t *data, size_t len,
43 uint8_t mac[PC_HMAC_SHA256_LEN]);
44
45/**
46 * @brief Streaming HMAC-SHA2-256 context.
47 *
48 * For MACs assembled from separate pieces - e.g. the SSH packet MAC over
49 * (uint32_be(seq_num) || plaintext_packet):
50 *
51 * pc_hmac_sha256_init(&ctx, key, key_len);
52 * pc_hmac_sha256_update(&ctx, seq_bytes, 4);
53 * pc_hmac_sha256_update(&ctx, packet, pkt_len);
54 * pc_hmac_sha256_final(&ctx, mac_out);
55 */
56typedef struct
57{
58 pc_sha256_ctx inner; ///< Inner hash context (key XOR ipad prepended).
59 uint8_t okey[64]; ///< Outer key block (key XOR opad), stored for the final step.
61
62/**
63 * @brief Initialize a streaming HMAC-SHA2-256 context.
64 * @param ctx Context to initialize.
65 * @param key Key bytes (keys > 64 are pre-hashed per RFC 2104).
66 * @param key_len Length of key in bytes.
67 */
68void pc_hmac_sha256_init(pc_hmac_sha256_ctx *ctx, const uint8_t *key, size_t key_len);
69
70/** @brief Feed @p len bytes into the running HMAC. */
71void pc_hmac_sha256_update(pc_hmac_sha256_ctx *ctx, const uint8_t *data, size_t len);
72
73/** @brief Finalize and write the 32-byte MAC. */
75
76#endif // PROTOCORE_HMAC_SHA256_H
void pc_hmac_sha256(const uint8_t *key, size_t key_len, const uint8_t *data, size_t len, uint8_t mac[PC_HMAC_SHA256_LEN])
Compute HMAC-SHA2-256 over a single contiguous buffer.
#define PC_HMAC_SHA256_LEN
HMAC-SHA2-256 output length in bytes.
Definition hmac_sha256.h:30
void pc_hmac_sha256_update(pc_hmac_sha256_ctx *ctx, const uint8_t *data, size_t len)
Feed len bytes into the running HMAC.
void pc_hmac_sha256_init(pc_hmac_sha256_ctx *ctx, const uint8_t *key, size_t key_len)
Initialize a streaming HMAC-SHA2-256 context.
void pc_hmac_sha256_final(pc_hmac_sha256_ctx *ctx, uint8_t mac[PC_HMAC_SHA256_LEN])
Finalize and write the 32-byte MAC.
SHA-256 (FIPS 180-4) - streaming context and one-shot API.
Streaming HMAC-SHA2-256 context.
Definition hmac_sha256.h:57
pc_sha256_ctx inner
Inner hash context (key XOR ipad prepended).
Definition hmac_sha256.h:58
Streaming SHA-256 context.
Definition sha256.h:40