ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
ssh_kexhash.h
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 ssh_kexhash.h
6 * @brief One key-exchange digest that dispatches SHA-256 or SHA-512 by the negotiated method.
7 *
8 * RFC 4253 §8 ties the exchange hash H (and the §7.2 key derivation) to the KEX method's hash: the
9 * `-sha256` methods (curve25519-sha256, ecdh-sha2-nistp256, dh-group14-sha256, mlkem768x25519-sha256)
10 * use SHA-256; `-sha512` methods (sntrup761x25519-sha512@openssh.com) use SHA-512. Rather than fork
11 * every hash site, the exchange hash and the KDF run over this small wrapper, so adding a KEX with a
12 * different hash is a one-line change (SshKexHash + ssh_kex_hash_is512()), not a new code path.
13 *
14 * The digest length is 32 (SHA-256) or 64 (SHA-512); H and the session_id are sized to the max (64).
15 */
16
17#ifndef PROTOCORE_SSH_KEXHASH_H
18#define PROTOCORE_SSH_KEXHASH_H
19
20#include "crypto/hash/sha256.h"
21#include "crypto/hash/sha512.h"
22#include <stddef.h>
23#include <stdint.h>
24
25#define SSH_KEXHASH_MAX_LEN 64 ///< longest exchange-hash / session_id (SHA-512)
26
27/** @brief A key-exchange digest bound to one of the SSH KEX hashes (SHA-256 or SHA-512). */
34
35static inline void ssh_kexhash_init(SshKexHash *h, bool is512)
36{
37 h->is512 = is512;
38 if (is512)
39 {
41 }
42 else
43 {
45 }
46}
47
48static inline void ssh_kexhash_update(SshKexHash *h, const uint8_t *data, size_t len)
49{
50 if (h->is512)
51 {
52 pc_sha512_update(&h->c512, data, len);
53 }
54 else
55 {
56 pc_sha256_update(&h->c256, data, len);
57 }
58}
59
60/** @brief Finalize into @p out (must hold SSH_KEXHASH_MAX_LEN); returns the digest length (32 or 64). */
61static inline size_t ssh_kexhash_final(SshKexHash *h, uint8_t out[SSH_KEXHASH_MAX_LEN])
62{
63 if (h->is512)
64 {
65 pc_sha512_final(&h->c512, out);
67 }
68 pc_sha256_final(&h->c256, out);
70}
71
72/** @brief The digest length for a given hash selection (32 or 64). */
73static inline size_t ssh_kexhash_len(bool is512)
74{
76}
77
78#endif // PROTOCORE_SSH_KEXHASH_H
PC_CRYPTO_HOT void pc_sha256_init(pc_sha256_ctx *ctx)
Initialize a streaming SHA-256 context (ctx must not be NULL).
Definition sha256.cpp:29
void pc_sha256_final(pc_sha256_ctx *ctx, uint8_t digest[PC_SHA256_DIGEST_LEN])
Finalize the hash and write the 32-byte digest. The context is undefined afterwards; call init() agai...
Definition sha256.cpp:48
void pc_sha256_update(pc_sha256_ctx *ctx, const uint8_t *data, size_t len)
Feed len bytes of data into the running hash.
Definition sha256.cpp:39
SHA-256 (FIPS 180-4) - streaming context and one-shot API.
#define PC_SHA256_DIGEST_LEN
SHA-256 digest length in bytes.
Definition sha256.h:25
void pc_sha512_update(pc_sha512_ctx *ctx, const uint8_t *data, size_t len)
Feed len bytes of data into the running hash.
Definition sha512.cpp:38
PC_CRYPTO_HOT void pc_sha512_init(pc_sha512_ctx *ctx)
Initialize a streaming SHA-512 context (ctx must not be NULL).
Definition sha512.cpp:28
void pc_sha512_final(pc_sha512_ctx *ctx, uint8_t digest[PC_SHA512_DIGEST_LEN])
Finalize the hash and write the 64-byte digest. The context is undefined afterwards; call init() agai...
Definition sha512.cpp:47
SHA-512 (FIPS 180-4) - streaming context and one-shot API.
#define PC_SHA512_DIGEST_LEN
SHA-512 digest length in bytes.
Definition sha512.h:24
#define SSH_KEXHASH_MAX_LEN
longest exchange-hash / session_id (SHA-512)
Definition ssh_kexhash.h:25
A key-exchange digest bound to one of the SSH KEX hashes (SHA-256 or SHA-512).
Definition ssh_kexhash.h:29
pc_sha256_ctx c256
Definition ssh_kexhash.h:31
pc_sha512_ctx c512
Definition ssh_kexhash.h:32
Streaming SHA-256 context.
Definition sha256.h:40
Streaming SHA-512 context.
Definition sha512.h:33