21#include <Preferences.h>
22#include <esp_random.h>
23#include <freertos/FreeRTOS.h>
24#include <freertos/semphr.h>
25#include <mbedtls/md.h>
26#include <mbedtls/pk.h>
27#include <mbedtls/rsa.h>
38static int ssh_mbedtls_rng(
void *ctx,
unsigned char *buf,
size_t len)
41 esp_fill_random(buf, len);
52 mbedtls_pk_context
pk;
62 s_rsa.
lock = xSemaphoreCreateMutex();
66 if (!prefs.begin(
"ssh_host_key",
true))
72 size_t der_len = prefs.getBytesLength(
"priv_der");
78 prefs.getBytes(
"priv_der", der, der_len);
84 mbedtls_pk_free(&s_rsa.
pk);
87 mbedtls_pk_init(&s_rsa.
pk);
88 int rc = mbedtls_pk_parse_key(&s_rsa.
pk, der, der_len,
nullptr, 0
89#
if MBEDTLS_VERSION_MAJOR >= 3
91 ssh_mbedtls_rng,
nullptr
94 pc_secure_wipe(der, der_len);
98 mbedtls_pk_free(&s_rsa.
pk);
102 mbedtls_rsa_context *rsa = mbedtls_pk_rsa(s_rsa.
pk);
105 mbedtls_pk_free(&s_rsa.
pk);
112 mbedtls_mpi_init(&n_mpi);
113 mbedtls_mpi_init(&e_mpi);
114 mbedtls_rsa_export(rsa, &n_mpi,
nullptr,
nullptr,
nullptr, &e_mpi);
118 mbedtls_mpi_free(&n_mpi);
119 mbedtls_mpi_free(&e_mpi);
137 const mbedtls_md_type_t md = sha512 ? MBEDTLS_MD_SHA512 : MBEDTLS_MD_SHA256;
152 xSemaphoreTake(s_rsa.
lock, portMAX_DELAY);
155#if MBEDTLS_VERSION_MAJOR >= 3
156 int rc = mbedtls_pk_sign(&s_rsa.
pk, md, digest, dlen, sig,
PC_RSA_SIG_BYTES, &sig_len, ssh_mbedtls_rng,
nullptr);
158 int rc = mbedtls_pk_sign(&s_rsa.
pk, md, digest, dlen, sig, &sig_len, ssh_mbedtls_rng,
nullptr);
162 xSemaphoreGive(s_rsa.
lock);
164 pc_secure_wipe(digest,
sizeof(digest));
178uint8_t _test_rsa_e[4];
190 return pc_rsa_sign_sw(_test_rsa_n, _test_rsa_d, msg, msg_len, hash, sig);
200static uint8_t *put_u32(uint8_t *p, uint32_t v)
202 p[0] = (uint8_t)(v >> 24);
203 p[1] = (uint8_t)(v >> 16);
204 p[2] = (uint8_t)(v >> 8);
210static uint8_t *put_mpint(uint8_t *p,
const uint8_t *data,
size_t data_len)
213 while (off < data_len && data[off] == 0)
217 const uint8_t *src = data + off;
218 size_t src_len = data_len - off;
219 bool need_pad = (src_len > 0) && (src[0] & 0x80u);
220 uint32_t mpint_len = (uint32_t)src_len + (need_pad ? 1u : 0u);
221 p = put_u32(p, mpint_len);
226 memcpy(p, src, src_len);
245 p = put_u32(p, (uint32_t)alg_len);
246 memcpy(p, alg, alg_len);
251 *out_len = (size_t)(p - out);
RSA-2048 PKCS#1 v1.5 signature primitive (RFC 8017) - verify + software sign.
pc_rsa_hash
Hash algorithm selecting the RSA signature scheme (RFC 8017 §9.2).
@ SHA512
RSASSA-PKCS1-v1.5 with SHA-512.
#define PC_RSA_SIG_BYTES
PKCS#1 v1.5 signature size for RSA-2048 in bytes.
#define PC_RSA_KEY_BYTES
RSA modulus / signature size in bytes (RSA-2048).
Secure pool accessor - borrows that hold key material.
void pc_sha256(const uint8_t *data, size_t len, uint8_t digest[PC_SHA256_DIGEST_LEN])
One-shot SHA-256: hash len bytes of data into digest (32 bytes).
SHA-256 (FIPS 180-4) - streaming context and one-shot API.
#define PC_SHA256_DIGEST_LEN
SHA-256 digest length in bytes.
void pc_sha512(const uint8_t *data, size_t len, uint8_t digest[PC_SHA512_DIGEST_LEN])
One-shot SHA-512: hash len bytes of data into digest (64 bytes).
SHA-512 (FIPS 180-4) - streaming context and one-shot API.
#define PC_SHA512_DIGEST_LEN
SHA-512 digest length in bytes.
SSH session key material - types, pools, and security model.
int pc_ssh_rsa_load_pubkey(void)
Load the public portion of the RSA host key into ssh_host_pubkey.
SshRsaPubKey ssh_host_pubkey
Static host public key (BSS). Set by pc_ssh_rsa_load_pubkey().
int ssh_rsa_sign(const uint8_t *msg, size_t msg_len, pc_rsa_hash hash, uint8_t sig[PC_RSA_SIG_BYTES])
Sign msg with the RSA host key (PKCS#1 v1.5, rsa-sha2-256/512).
int ssh_rsa_encode_pubkey(uint8_t *out, size_t *out_len, size_t out_cap)
Encode ssh_host_pubkey as the RFC 4253 §6.6 "ssh-rsa" public-key blob.
SSH RSA host-key layer: NVS-backed host key, host-key signing, and "ssh-rsa" blob encoding.
#define SSH_RSA_PUBKEY_ALG_LEN
Length of SSH_RSA_PUBKEY_ALG ("ssh-rsa" = 7 bytes).
#define SSH_RSA_KEY_DER_MAX
Maximum DER size for a PKCS#1 RSAPrivateKey with 2048-bit fields.
#define SSH_RSA_PUBKEY_BLOB_MAX
Upper bound on the encoded "ssh-rsa" public-key blob (len+alg + mpint e + mpint n).
#define SSH_RSA_PUBKEY_ALG
Key-blob type string for an RSA host key.
SemaphoreHandle_t lock
serializes signs on the shared context
bool ready
pk holds a valid parsed key
mbedtls_pk_context pk
parsed host key + cached blinding state
RSA-2048 public host key parameters. Allocated in BSS; contains only n and e.
uint8_t n[PC_RSA_KEY_BYTES]
Modulus n (256 bytes, big-endian).
bool loaded
True after pc_ssh_rsa_load_pubkey() succeeds.
uint8_t e_bytes[4]
Public exponent e (big-endian uint32).