ProtoCore v0.0.2
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
md.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 md.h
6 * @brief MD4 (RFC 1320), MD5 (RFC 1321), and HMAC-MD5 (RFC 2104) - the legacy digests NTLM needs.
7 *
8 * The shared library home for the MD-family digests. The only consumer is the SMB2 client's NTLMv2
9 * (MS-NLMP): the NT hash is MD4(UTF-16LE(password)); the NTLMv2 response and session key are HMAC-MD5
10 * chains. MD4/MD5 are cryptographically broken and are included ONLY because SMB/NTLM requires them on
11 * the wire - do not use them for anything security-new. Zero heap, streaming; verified against the RFC
12 * test vectors (see test_smb_crypto).
13 *
14 * @author Douglas Quigg (dstroy0)
15 * @date 2026
16 */
17
18#ifndef PROTOCORE_MD_H
19#define PROTOCORE_MD_H
20
21#include <stddef.h>
22#include <stdint.h>
23
24/**
25 * @brief Opaque streaming digest context (MD4 / MD5). Forward-declared only: the definition is private to
26 * md.cpp, so other translation units know the symbol but never its members - they hold it via `MdCtx *`,
27 * getting their storage from pc_md_wants() below.
28 */
29struct MdCtx;
30
31/**
32 * @brief Storage this module wants for one MD4/MD5 context.
33 *
34 * The type is opaque, so a consumer cannot size it - this module owns the definition and therefore
35 * owns the allocation. Call inside a SecureScope: the scope states how long the caller needs the
36 * resource, and the pool wipes the digest state when that scope ends. MD4/MD5 here carry NTLM
37 * password and session-key material, so the storage comes from the secure pool.
38 *
39 * @return a context to pass to pc_md4_init() / pc_md5_init(), or nullptr if the pool could not
40 * satisfy it.
41 */
42MdCtx *pc_md_wants(void);
43
44void pc_md5_init(MdCtx *c);
45void pc_md5_update(MdCtx *c, const uint8_t *data, size_t len);
46void pc_md5_final(MdCtx *c, uint8_t out[16]);
47/** @brief One-shot MD5. */
48void md5(const uint8_t *data, size_t len, uint8_t out[16]);
49
50void pc_md4_init(MdCtx *c);
51void pc_md4_update(MdCtx *c, const uint8_t *data, size_t len);
52void pc_md4_final(MdCtx *c, uint8_t out[16]);
53/** @brief One-shot MD4 (the NT-hash primitive). */
54void md4(const uint8_t *data, size_t len, uint8_t out[16]);
55
56/** @brief HMAC-MD5 (RFC 2104): the NTLMv2 MAC primitive. */
57void pc_hmac_md5(const uint8_t *key, size_t key_len, const uint8_t *msg, size_t msg_len, uint8_t out[16]);
58
59#endif // PROTOCORE_MD_H
void pc_md5_init(MdCtx *c)
Definition md.cpp:103
void pc_md4_init(MdCtx *c)
Definition md.cpp:192
void pc_md4_update(MdCtx *c, const uint8_t *data, size_t len)
Definition md.cpp:258
MdCtx * pc_md_wants(void)
Storage this module wants for one MD4/MD5 context.
Definition md.cpp:28
void pc_md5_update(MdCtx *c, const uint8_t *data, size_t len)
Definition md.cpp:250
void pc_md5_final(MdCtx *c, uint8_t out[16])
Definition md.cpp:254
void md4(const uint8_t *data, size_t len, uint8_t out[16])
One-shot MD4 (the NT-hash primitive).
Definition md.cpp:274
void md5(const uint8_t *data, size_t len, uint8_t out[16])
One-shot MD5.
Definition md.cpp:267
void pc_md4_final(MdCtx *c, uint8_t out[16])
Definition md.cpp:262
void pc_hmac_md5(const uint8_t *key, size_t key_len, const uint8_t *msg, size_t msg_len, uint8_t out[16])
HMAC-MD5 (RFC 2104): the NTLMv2 MAC primitive.
Definition md.cpp:284
Definition md.cpp:19