|
ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
|
NIST P-256 primitives for SSH: ECDSA signatures and ECDH (RFC 5656 / FIPS 186-4). More...
#include "protocore_config.h"Go to the source code of this file.
Classes | |
| struct | EcdsaNs |
| Dispatch table. Addressed by offset, so the layout is asserted below. More... | |
Macros | |
| #define | PROTOCORE_ECDSA_P256_PRIV_LEN 32 |
| P-256 private key (scalar d) length. | |
| #define | PROTOCORE_ECDSA_P256_COORD_LEN 32 |
| P-256 coordinate length (one of X, Y). | |
| #define | PROTOCORE_ECDSA_P256_PUB_LEN 65 |
| P-256 uncompressed public point length: 0x04 || X || Y. | |
| #define | PROTOCORE_ECDSA_P256_SIG_LEN 64 |
| Raw ECDSA signature length: r || s (32 + 32, big-endian). | |
Functions | |
| PROTOCORE_NS_LAYOUT (EcdsaNs, pubkey, sign, verify, ecdh) | |
| proto_bool | protocore_ecdsa_pubkey (uint8_t *work, const uint8_t *priv, uint8_t *pub) |
| Derive Q = d*G and write it uncompressed. | |
| proto_bool | protocore_ecdsa_sign (uint8_t *work, const uint8_t *msg, size_t mlen, const uint8_t *priv, uint8_t *sig) |
| Hash the message with SHA-256 and write the raw r || s. | |
| proto_bool | protocore_ecdsa_verify (uint8_t *work, const uint8_t *pub, const uint8_t *msg, size_t mlen, const uint8_t *sig) |
| Hash the message with SHA-256 and check r || s against the point. | |
| proto_bool | protocore_ecdsa_ecdh (uint8_t *work, const uint8_t *peer_pub, const uint8_t *priv, uint8_t *shared_x) |
| Write the X coordinate of d * Q_peer. | |
Variables | |
| PROTOCORE_NS EcdsaNs Ecdsa | PROTOCORE_UNUSED |
| Module namespace. | |
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:
═══════════════════════════════════════════════════════════════════════════ THE TWO ARMS ═══════════════════════════════════════════════════════════════════════════
One self-contained software P-256 serves both: 256-bit field and scalar arithmetic, the exception-free complete addition formulas, a constant-time fixed-window scalar multiply, 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 on every target.
Only the field multiply changes arm. A die whose MPI accelerator carries a single-shot MODMULT does each 256-bit multiply on it; every other target, and a host build, runs the software product. The vectors are the same either way, which is what makes the native run a check on the accelerated one.
The entries below are one surface over every arm: which one runs the curve math is this module's and is never visible here.
═══════════════════════════════════════════════════════════════════════════ 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 writes Q through EcdsaNs::pubkey; the layers wrap it.
Signature blob (RFC 5656 §3.1.2): string("ecdsa-sha2-nistp256") || string( mpint(r) || mpint(s) ) This module writes 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. EcdsaNs::ecdh writes the raw 32-byte X; the transport encodes it as an mpint in the exchange hash and the key derivation.
work is PROTOCORE_ECDSA_BORROW secure bytes the CALLER took, at an address it knows. It is not held past the call, so nothing here aliases it. The caller releases it, and the pool wipes on release; this module neither takes it, holds it, releases it, nor wipes it. That is what keeps the message hash and the RFC 6979 nonce chain from outliving the caller.
Definition in file ecdsa.h.
| #define PROTOCORE_ECDSA_P256_PRIV_LEN 32 |
| #define PROTOCORE_ECDSA_P256_COORD_LEN 32 |
| #define PROTOCORE_ECDSA_P256_PUB_LEN 65 |
| #define PROTOCORE_ECDSA_P256_SIG_LEN 64 |
| PROTOCORE_NS_LAYOUT | ( | EcdsaNs | , |
| pubkey | , | ||
| sign | , | ||
| verify | , | ||
| ecdh | |||
| ) |
| proto_bool protocore_ecdsa_pubkey | ( | uint8_t * | work, |
| const uint8_t * | priv, | ||
| uint8_t * | pub | ||
| ) |
Derive Q = d*G and write it uncompressed.
| work | PROTOCORE_ECDSA_BORROW bytes the caller took. Not held past the call. |
| priv | PROTOCORE_ECDSA_P256_PRIV_LEN big-endian scalar d, 1 <= d < n |
| pub | PROTOCORE_ECDSA_P256_PUB_LEN bytes: 0x04 || X || Y |
| proto_bool protocore_ecdsa_sign | ( | uint8_t * | work, |
| const uint8_t * | msg, | ||
| size_t | mlen, | ||
| const uint8_t * | priv, | ||
| uint8_t * | sig | ||
| ) |
Hash the message with SHA-256 and write the raw r || s.
| work | PROTOCORE_ECDSA_BORROW bytes the caller took. Not held past the call. |
| msg | the message, hashed with SHA-256 here |
| mlen | its length |
| priv | PROTOCORE_ECDSA_P256_PRIV_LEN big-endian scalar d |
| sig | PROTOCORE_ECDSA_P256_SIG_LEN bytes: r || s, 32 + 32 big-endian |
| proto_bool protocore_ecdsa_verify | ( | uint8_t * | work, |
| const uint8_t * | pub, | ||
| const uint8_t * | msg, | ||
| size_t | mlen, | ||
| const uint8_t * | sig | ||
| ) |
Hash the message with SHA-256 and check r || s against the point.
| work | PROTOCORE_ECDSA_BORROW bytes the caller took. Not held past the call. |
| pub | PROTOCORE_ECDSA_P256_PUB_LEN uncompressed point, rejected if not on-curve |
| msg | the signed message |
| mlen | its length |
| sig | PROTOCORE_ECDSA_P256_SIG_LEN bytes: r || s, 32 + 32 big-endian |
| proto_bool protocore_ecdsa_ecdh | ( | uint8_t * | work, |
| const uint8_t * | peer_pub, | ||
| const uint8_t * | priv, | ||
| uint8_t * | shared_x | ||
| ) |
Write the X coordinate of d * Q_peer.
| work | PROTOCORE_ECDSA_BORROW bytes the caller took. Not held past the call. |
| peer_pub | PROTOCORE_ECDSA_P256_PUB_LEN uncompressed peer point 0x04 || X || Y |
| priv | PROTOCORE_ECDSA_P256_PRIV_LEN big-endian scalar d, 1 <= d < n |
| shared_x | PROTOCORE_ECDSA_P256_COORD_LEN big-endian X coordinate of d * Q_peer |
| PROTOCORE_NS EcdsaNs Ecdsa PROTOCORE_UNUSED |
Module namespace.