|
DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
|
ECDSA over NIST P-256 for ecdsa-sha2-nistp256 (RFC 5656 / FIPS 186-4). More...
#include "network_drivers/presentation/ssh/crypto/ssh_ecdsa.h"#include "network_drivers/presentation/ssh/crypto/ssh_sha256.h"#include <string.h>#include "sdkconfig.h"#include <esp_random.h>#include <mbedtls/ecdh.h>#include <mbedtls/ecdsa.h>#include <mbedtls/ecp.h>Go to the source code of this file.
Functions | |
| bool | ssh_ecdsa_p256_pubkey (uint8_t pub[SSH_ECDSA_P256_PUB_LEN], const uint8_t priv[SSH_ECDSA_P256_PRIV_LEN]) |
| Derive the uncompressed public point Q = d*G from a P-256 private scalar. | |
| bool | ssh_ecdsa_p256_sign (uint8_t sig[SSH_ECDSA_P256_SIG_LEN], const uint8_t *msg, size_t mlen, const uint8_t priv[SSH_ECDSA_P256_PRIV_LEN]) |
Sign mlen bytes of msg with a P-256 private key (ECDSA, SHA-256). | |
| bool | ssh_ecdsa_p256_verify (const uint8_t pub[SSH_ECDSA_P256_PUB_LEN], const uint8_t *msg, size_t mlen, const uint8_t sig[SSH_ECDSA_P256_SIG_LEN]) |
| Verify a P-256 ECDSA signature (SHA-256) against an uncompressed public point. | |
| bool | ssh_ecdsa_p256_ecdh (uint8_t shared_x[SSH_ECDSA_P256_COORD_LEN], const uint8_t peer_pub[SSH_ECDSA_P256_PUB_LEN], const uint8_t priv[SSH_ECDSA_P256_PRIV_LEN]) |
| P-256 ECDH: the shared-secret X coordinate of d * Q_peer (RFC 5656 §4 / RFC 5903). | |
ECDSA over NIST P-256 for ecdsa-sha2-nistp256 (RFC 5656 / FIPS 186-4).
═══════════════════════════════════════════════════════════════════════════ THREE BUILD PATHS ═══════════════════════════════════════════════════════════════════════════
ESP32-S3 (Arduino): a self-contained P-256 whose every 256-bit field / scalar multiply is one modular multiply on the RSA/MPI hardware accelerator (the same engine ssh_fe25519.h drives for X25519 / Ed25519) - the MODMULT is modulus-generic, so it serves both the field domain (mod p) and the scalar domain (mod n) by swapping the {M, m', R^2} constants. Point arithmetic uses the exception-free complete formulas (Renes-Costello-Batina 2016, EFD add/dbl-2015-rcb, a = -3) driven by a constant-time 4-bit fixed-window scalar multiply (uniform op sequence, full-table masked select, no input-dependent branches). Signing is RFC 6979 deterministic, so the on-device output is byte-exact to the published vectors (same KATs as native). This is the production path (DETWS_ECDSA_MPI_HW); sign / verify / ecdh run ~2.7-2.9x faster than the mbedTLS ECP path it replaces on non-S3 targets.
Native: the identical complete-formula / RFC 6979 code, but each field multiply is a software schoolbook product reduced bit-serially. Only fp_mul differs from the S3 path, so the native KATs validate the exact point / scalar arithmetic the accelerator runs. Test-only, not in firmware.
Other Arduino (classic ESP32 etc.): mbedTLS (mbedtls_ecdsa_*, mbedtls_ecp_*) - hardware big-integer math and side-channel hardening, signing with the ESP32 hardware RNG. The MODMULT register layout is an S3 specialization, so non-S3 targets keep the portable mbedTLS path (no perf regression).
═══════════════════════════════════════════════════════════════════════════ WIRE FORMATS (assembled by the SSH transport/auth layers, not here) ═══════════════════════════════════════════════════════════════════════════
Public-key blob: string("ecdsa-sha2-nistp256") || string("nistp256") || string(Q), Q = 0x04||X||Y. Signature blob: string("ecdsa-sha2-nistp256") || string( mpint(r) || mpint(s) ); this module exposes raw r||s (32+32 big-endian) and the layers mpint-wrap them. ECDH shared secret (RFC 5656 sec 4): K = X coordinate of d*Q_peer, raw 32-byte big-endian.
Definition in file ssh_ecdsa.cpp.
| bool ssh_ecdsa_p256_pubkey | ( | uint8_t | pub[SSH_ECDSA_P256_PUB_LEN], |
| const uint8_t | priv[SSH_ECDSA_P256_PRIV_LEN] | ||
| ) |
Derive the uncompressed public point Q = d*G from a P-256 private scalar.
| [out] | pub | 65-byte uncompressed point 0x04 || X || Y. |
| [in] | priv | 32-byte big-endian private scalar d (must satisfy 1 <= d < n). |
priv is 0 or >= the group order n. Definition at line 79 of file ssh_ecdsa.cpp.
Referenced by ssh_hostkey_ecdsa_set(), ssh_kex_generate(), and ssh_kexdh_handle().
| bool ssh_ecdsa_p256_sign | ( | uint8_t | sig[SSH_ECDSA_P256_SIG_LEN], |
| const uint8_t * | msg, | ||
| size_t | mlen, | ||
| const uint8_t | priv[SSH_ECDSA_P256_PRIV_LEN] | ||
| ) |
Sign mlen bytes of msg with a P-256 private key (ECDSA, SHA-256).
The message is hashed with SHA-256 internally. Native builds sign deterministically (RFC 6979); Arduino builds sign with the hardware RNG. Both produce a valid signature.
| [out] | sig | 64-byte raw signature r || s (big-endian, 32 + 32). |
| [in] | msg | Message to sign (typically the KEX exchange hash H). |
| [in] | mlen | Length of msg. |
| [in] | priv | 32-byte big-endian private scalar d. |
Definition at line 106 of file ssh_ecdsa.cpp.
References ssh_sha256(), and SSH_SHA256_DIGEST_LEN.
| bool ssh_ecdsa_p256_verify | ( | const uint8_t | pub[SSH_ECDSA_P256_PUB_LEN], |
| const uint8_t * | msg, | ||
| size_t | mlen, | ||
| const uint8_t | sig[SSH_ECDSA_P256_SIG_LEN] | ||
| ) |
Verify a P-256 ECDSA signature (SHA-256) against an uncompressed public point.
| [in] | pub | 65-byte uncompressed point 0x04 || X || Y (rejected if not on-curve). |
| [in] | msg | Signed message. |
| [in] | mlen | Length of msg. |
| [in] | sig | 64-byte raw signature r || s (big-endian, 32 + 32). |
Definition at line 136 of file ssh_ecdsa.cpp.
References ssh_sha256(), and SSH_SHA256_DIGEST_LEN.
| bool ssh_ecdsa_p256_ecdh | ( | uint8_t | shared_x[SSH_ECDSA_P256_COORD_LEN], |
| const uint8_t | peer_pub[SSH_ECDSA_P256_PUB_LEN], | ||
| const uint8_t | priv[SSH_ECDSA_P256_PRIV_LEN] | ||
| ) |
P-256 ECDH: the shared-secret X coordinate of d * Q_peer (RFC 5656 §4 / RFC 5903).
Backs the ecdh-sha2-nistp256 SSH key exchange. Validates that peer_pub is a valid on-curve point and that the product is not the identity; the returned 32-byte big-endian X coordinate is the shared field element the transport encodes as an mpint.
| [out] | shared_x | 32-byte big-endian X coordinate of d * Q_peer. |
| [in] | peer_pub | 65-byte uncompressed peer point 0x04 || X || Y. |
| [in] | priv | 32-byte big-endian private scalar d (1 <= d < n). |
Definition at line 166 of file ssh_ecdsa.cpp.
Referenced by ssh_kexdh_handle().