|
DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
|
NIST P-256 primitives for SSH: ECDSA signatures and ECDH (RFC 5656 / FIPS 186-4). More...
#include <stddef.h>#include <stdint.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). | |
NIST P-256 primitives for SSH: ECDSA signatures and ECDH (RFC 5656 / FIPS 186-4).
Backs three P-256 SSH mechanisms, all sharing the one curve:
═══════════════════════════════════════════════════════════════════════════ ARDUINO VS NATIVE ═══════════════════════════════════════════════════════════════════════════
Arduino: mbedTLS (mbedtls_ecdsa_*, mbedtls_ecp_*) - hardware-accelerated big-integer math on the ESP32 and side-channel-hardened. This is the production path. Signing uses the ESP32 hardware RNG (randomized ECDSA, RFC 6979 not required for validity).
Native: self-contained software P-256 - 256-bit field/scalar arithmetic (bit-serial reduction mod p and mod n), Jacobian point arithmetic, and RFC 6979 deterministic signing so the sign path is byte-exact against the RFC 6979 A.2.5 (P-256/SHA-256) known-answer vectors. Test-only, like the native RSA path; not compiled into firmware.
═══════════════════════════════════════════════════════════════════════════ WIRE FORMATS (assembled by the SSH transport/auth layers, not here) ═══════════════════════════════════════════════════════════════════════════
Public-key blob (RFC 5656 §3.1): string("ecdsa-sha2-nistp256") || string("nistp256") || string(Q) where Q is the uncompressed point 0x04 || X || Y (65 bytes). This module exposes Q as ssh_ecdsa_p256_pubkey; the layers wrap it.
Signature blob (RFC 5656 §3.1.2): string("ecdsa-sha2-nistp256") || string( mpint(r) || mpint(s) ) This module exposes the raw r || s (32 + 32 big-endian); the layers mpint-wrap them.
ECDH shared secret (RFC 5656 §4): K = the X coordinate of d * Q_peer. ssh_ecdsa_p256_ecdh returns the raw 32-byte X; the transport encodes it as an mpint in the exchange hash and the key derivation.
Definition in file ssh_ecdsa.h.
| 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().