DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
snmp_crypto.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 snmp_crypto.h
6 * @brief USM cryptographic primitives for SNMPv3 (DETWS_ENABLE_SNMP_V3).
7 *
8 * Provides exactly what the User-based Security Model needs and nothing more:
9 *
10 * - **Key localization** (RFC 3414 §2.6, SHA-256 variant per RFC 7860): turn a
11 * human password into the engine-localized authentication/privacy key.
12 * - **AES-128 in CFB-128 mode** (RFC 3826): the v3 privacy transform. A compact
13 * portable software AES is used on both host and ESP32 - SNMP payloads are a
14 * few hundred bytes, so this is not a throughput path; it is therefore
15 * identical and unit-testable off-target. (Like the SSH software crypto, it is
16 * not constant-time; for SNMP this is acceptable - see SECURITY.md.)
17 *
18 * SHA-256 and HMAC-SHA-256 are reused from the existing SSH crypto layer.
19 */
20
21#ifndef DETERMINISTICESPASYNCWEBSERVER_SNMP_CRYPTO_H
22#define DETERMINISTICESPASYNCWEBSERVER_SNMP_CRYPTO_H
23
24#include "ServerConfig.h"
25#include <stddef.h>
26#include <stdint.h>
27
28#if DETWS_ENABLE_SNMP_V3
29
30/** @brief Localized-key length (SHA-256 digest size). */
31#define SNMP_USM_KEY_LEN 32
32
33/**
34 * @brief Derive the engine-localized USM key from a password (RFC 3414 §2.6).
35 *
36 * Expands @p password to 2^20 bytes and hashes it with SHA-256 to form the
37 * user key Ku, then computes the localized key Kul = SHA-256(Ku || engineID ||
38 * Ku). The same procedure produces both the authentication key and the privacy
39 * key (each from its own password). The privacy transform uses the first 16
40 * bytes of the result as the AES-128 key.
41 *
42 * @param password NUL-terminated auth/priv password (>= 8 chars per RFC 3414).
43 * @param engine_id authoritative engine ID bytes.
44 * @param engine_id_len length of @p engine_id.
45 * @param key_out receives SNMP_USM_KEY_LEN localized key bytes.
46 */
47void snmp_usm_localize_key(const char *password, const uint8_t *engine_id, size_t engine_id_len,
48 uint8_t key_out[SNMP_USM_KEY_LEN]);
49
50/**
51 * @brief AES-128 CFB-128 transform (RFC 3826), used for SNMPv3 privacy.
52 *
53 * CFB is a stream mode: the output length equals the input length (no padding),
54 * and decryption is the same construction with the feedback taken from the
55 * ciphertext. Safe for in-place use (@p out may equal @p in).
56 *
57 * @param key 16-byte AES-128 key (first 16 bytes of the localized priv key).
58 * @param iv 16-byte IV = engineBoots(4, big-endian) || engineTime(4) || privParams(8).
59 * @param in input bytes.
60 * @param out output bytes (length @p len).
61 * @param len number of bytes.
62 * @param encrypt true to encrypt, false to decrypt.
63 */
64void snmp_aes128_cfb(const uint8_t key[16], const uint8_t iv[16], const uint8_t *in, uint8_t *out, size_t len,
65 bool encrypt);
66
67#endif // DETWS_ENABLE_SNMP_V3
68
69#endif // DETERMINISTICESPASYNCWEBSERVER_SNMP_CRYPTO_H
User-facing configuration for DeterministicESPAsyncWebServer.