ProtoCore v0.0.2
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
esp_bignum.cpp
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 esp_bignum.cpp
6 * @brief DH-2048 modexp on the Espressif RSA accelerator, via mbedtls.
7 *
8 * The bignum backend for a vendor profile that sets PC_HAS_HW_BIGNUM 1. Vendor headers are fine
9 * here - this is board_drivers/, the partition vendor code is segregated to. The core names none of
10 * them and simply calls bn_expmod_group14().
11 */
12
13#include "board_drivers/board_profiles/pc_platform.h" // PC_HAS_HW_BIGNUM
15#include "crypto/crypto_opt.h"
16#include "server/mmgr/secure.h"
17#include <string.h>
18
19#if PC_HAS_HW_BIGNUM
20
21#include <mbedtls/bignum.h> // HW bignum acceleration for the DH-2048 modexp
22
24
25// On ESP32 delegate to mbedtls which uses HW bignum acceleration.
26
27namespace
28{
29// ESP32 path: the big-endian buffers handed to mbedtls (HW bignum acceleration).
30struct BnExpmodBytes
31{
32 uint8_t base_be[256];
33 uint8_t exp_be[256];
34 uint8_t p_be[256];
35 uint8_t res_be[256];
36};
37
38// Worst-case bytes this backend borrows in one modexp. PC_SECURE_ARENA_SIZE is derived
39// from declarations like this one; the static_assert below is what proves it.
40static_assert(sizeof(BnExpmodBytes) <= PC_WORK_BIGNUM_HW,
41 "BnExpmodBytes outgrew PC_WORK_BIGNUM_HW - raise it; PC_SECURE_ARENA_SIZE derives from it");
42} // namespace
43
44void bn_expmod_group14(pc_bignum *out, const pc_bignum *base, const pc_bignum *exp)
45{
46 // Big-endian temporaries live in the shared crypto scratch, not on the stack: exp holds the DH private
47 // exponent and res the shared secret, so the whole region is wiped on exit (crypto_scratch.h).
48 SecureBorrow ws_b(sizeof(BnExpmodBytes), alignof(BnExpmodBytes));
49 const pc_span &ws = ws_b.span();
50 if (!pc_span_ok(ws))
51 {
52 memset(out, 0, sizeof(*out)); // pool exhausted: a zero result fails every downstream check
53 return;
54 }
55 BnExpmodBytes *w = reinterpret_cast<BnExpmodBytes *>(ws.buf);
56 uint8_t *base_be = w->base_be;
57 uint8_t *exp_be = w->exp_be;
58 uint8_t *p_be = w->p_be;
59 uint8_t *res_be = w->res_be;
60 bn_to_bytes(base_be, base);
61 bn_to_bytes(exp_be, exp);
62 bn_to_bytes(p_be, &group14_p);
63
64 mbedtls_mpi B;
65 mbedtls_mpi E;
66 mbedtls_mpi P;
67 mbedtls_mpi R;
68 mbedtls_mpi_init(&B);
69 mbedtls_mpi_init(&E);
70 mbedtls_mpi_init(&P);
71 mbedtls_mpi_init(&R);
72
73 mbedtls_mpi_read_binary(&B, base_be, 256);
74 mbedtls_mpi_read_binary(&E, exp_be, 256);
75 mbedtls_mpi_read_binary(&P, p_be, 256);
76
77 mbedtls_mpi_exp_mod(&R, &B, &E, &P, NULL);
78 mbedtls_mpi_write_binary(&R, res_be, 256);
79
80 mbedtls_mpi_free(&B);
81 mbedtls_mpi_free(&E);
82 mbedtls_mpi_free(&P);
83 mbedtls_mpi_free(&R);
84
85 bn_from_bytes(out, res_be, 256);
86}
87
88#endif // PC_HAS_HW_BIGNUM
PC_CRYPTO_HOT const pc_bignum group14_p
The RFC 3526 MODP group-14 prime (2048-bit).
Definition bignum.cpp:42
void bn_to_bytes(uint8_t bytes[256], const pc_bignum *in)
Write a pc_bignum as a 256-byte big-endian array.
Definition bignum.cpp:96
void bn_from_bytes(pc_bignum *out, const uint8_t *bytes, size_t len)
Read a big-endian byte array of len bytes into a pc_bignum.
Definition bignum.cpp:84
2048-bit big-integer arithmetic for DH-group14 and RSA-2048.
A secure borrow whose acquire and release are one call each.
Definition secure.h:153
Per-translation-unit optimization override for hot, pure-integer crypto.
The one vendor/die selector for the whole library.
void bn_expmod_group14(pc_bignum *out, const pc_bignum *base, const pc_bignum *exp)
#define PC_WORK_BIGNUM_HW
Worst-case bytes each module borrows from the secure pool in a single call.
Secure pool accessor - borrows that hold key material.
bool pc_span_ok(const pc_span &s)
True when the span refers to real storage and every write so far has fit.
Definition span.h:114
A 2048-bit unsigned integer stored as 64 little-endian 32-bit limbs.
Definition bignum.h:92
A writable byte region: the storage, the capacity that belongs to it, and what has been produced into...
Definition span.h:65
uint8_t * buf
first byte, or nullptr when the region could not be obtained
Definition span.h:66