commit fda402b
Michael Forney
·
2026-05-15 19:46:50 +0000 UTC
parent 744b378
bearssl: Add SHA-512/256 implementation
2 files changed,
+235,
-1
1@@ -0,0 +1,234 @@
2+From 4f6c794c471789bed5e078bb0330ff08bb5936ac Mon Sep 17 00:00:00 2001
3+From: Michael Forney <mforney@mforney.org>
4+Date: Fri, 15 May 2026 02:59:18 -0700
5+Subject: [PATCH] Add br_sha512_256
6+
7+---
8+ inc/bearssl_hash.h | 132 +++++++++++++++++++++++++++++++++++++++++----
9+ src/hash/sha2big.c | 42 +++++++++++++++
10+ 2 files changed, 164 insertions(+), 10 deletions(-)
11+
12+diff --git a/inc/bearssl_hash.h b/inc/bearssl_hash.h
13+index ca4fa26..769e7ac 100644
14+--- a/inc/bearssl_hash.h
15++++ b/inc/bearssl_hash.h
16+@@ -156,15 +156,16 @@ extern "C" {
17+ *
18+ * Implemented hash functions are:
19+ *
20+- * | Function | Name | Output length | State length |
21+- * | :-------- | :------ | :-----------: | :----------: |
22+- * | MD5 | md5 | 16 | 16 |
23+- * | SHA-1 | sha1 | 20 | 20 |
24+- * | SHA-224 | sha224 | 28 | 32 |
25+- * | SHA-256 | sha256 | 32 | 32 |
26+- * | SHA-384 | sha384 | 48 | 64 |
27+- * | SHA-512 | sha512 | 64 | 64 |
28+- * | MD5+SHA-1 | md5sha1 | 36 | 36 |
29++ * | Function | Name | Output length | State length |
30++ * | :---------- | :--------- | :-----------: | :----------: |
31++ * | MD5 | md5 | 16 | 16 |
32++ * | SHA-1 | sha1 | 20 | 20 |
33++ * | SHA-224 | sha224 | 28 | 32 |
34++ * | SHA-256 | sha256 | 32 | 32 |
35++ * | SHA-384 | sha384 | 48 | 64 |
36++ * | SHA-512 | sha512 | 64 | 64 |
37++ * | SHA-512/256 | sha512_256 | 32 | 64 |
38++ * | MD5+SHA-1 | md5sha1 | 36 | 36 |
39+ *
40+ * (MD5+SHA-1 is the concatenation of MD5 and SHA-1 computed over the
41+ * same input; in the implementation, the internal data buffer is
42+@@ -359,7 +360,7 @@ struct br_hash_class_ {
43+ * -- First field is called 'vtable' and is a pointer to a
44+ * const-qualified br_hash_class instance (pointer is set by init()).
45+ * -- SHA-224 and SHA-256 contexts are identical.
46+- * -- SHA-384 and SHA-512 contexts are identical.
47++ * -- SHA-384, SHA-512, and SHA-512/256 contexts are identical.
48+ *
49+ * Thus, contexts can be moved and cloned to capture the hash function
50+ * current state; and there is no need for any explicit "release" function.
51+@@ -961,6 +962,117 @@ void br_sha512_set_state(br_sha512_context *ctx,
52+ #define br_sha512_set_state br_sha384_set_state
53+ #endif
54+
55++/**
56++ * \brief Symbolic identifier for SHA-512/256.
57++ *
58++ * SHA-512/256 is the truncation of SHA-512 to 32 bytes with a
59++ * special IV. It is not one of the functions identified in TLS,
60++ * so we give it a symbolic identifier of value 0.
61++ */
62++#define br_sha512_256_ID 0
63++
64++/**
65++ * \brief SHA-512 output size (in bytes).
66++ */
67++#define br_sha512_256_SIZE 32
68++
69++/**
70++ * \brief Constant vtable for SHA-512/256.
71++ */
72++extern const br_hash_class br_sha512_256_vtable;
73++
74++#ifdef BR_DOXYGEN_IGNORE
75++/**
76++ * \brief SHA-512/256 context.
77++ *
78++ * First field is a pointer to the vtable; it is set by the initialisation
79++ * function. Other fields are not supposed to be accessed by user code.
80++ */
81++typedef struct {
82++ /**
83++ * \brief Pointer to vtable for this context.
84++ */
85++ const br_hash_class *vtable;
86++} br_sha512_256_context;
87++#else
88++typedef br_sha384_context br_sha512_256_context;
89++#endif
90++
91++/**
92++ * \brief SHA-512/256 context initialisation.
93++ *
94++ * This function initialises or resets a context for a new SHA-512/256
95++ * computation. It also sets the vtable pointer.
96++ *
97++ * \param ctx pointer to the context structure.
98++ */
99++void br_sha512_256_init(br_sha512_256_context *ctx);
100++
101++#ifdef BR_DOXYGEN_IGNORE
102++/**
103++ * \brief Inject some data bytes in a running SHA-512/256 computation.
104++ *
105++ * The provided context is updated with some data bytes. If the number
106++ * of bytes (`len`) is zero, then the data pointer (`data`) is ignored
107++ * and may be `NULL`, and this function does nothing.
108++ *
109++ * \param ctx pointer to the context structure.
110++ * \param data pointer to the injected data.
111++ * \param len injected data length (in bytes).
112++ */
113++void br_sha512_256_update(br_sha512_256_context *ctx, const void *data, size_t len);
114++#else
115++#define br_sha512_256_update br_sha384_update
116++#endif
117++
118++/**
119++ * \brief Compute SHA-512/256 output.
120++ *
121++ * The SHA-512/256 output for the concatenation of all bytes injected
122++ * in the provided context since the last initialisation or reset
123++ * call, is computed and written in the buffer pointed to by `out`.
124++ * The context itself is not modified, so extra bytes may be injected
125++ * afterwards to continue that computation.
126++ *
127++ * \param ctx pointer to the context structure.
128++ * \param out destination buffer for the hash output.
129++ */
130++void br_sha512_256_out(const br_sha512_256_context *ctx, void *out);
131++
132++#ifdef BR_DOXYGEN_IGNORE
133++/**
134++ * \brief Save SHA-512/256 running state.
135++ *
136++ * The running state for SHA-512/256 (output of the last internal
137++ * block processing) is written in the buffer pointed to by `out`.
138++ * The number of bytes injected since the last initialisation or
139++ * reset call is returned. The context is not modified.
140++ *
141++ * \param ctx pointer to the context structure.
142++ * \param out destination buffer for the running state.
143++ * \return the injected total byte length.
144++ */
145++uint64_t br_sha512_256_state(const br_sha512_256_context *ctx, void *out);
146++#else
147++#define br_sha512_256_state br_sha384_state
148++#endif
149++
150++#ifdef BR_DOXYGEN_IGNORE
151++/**
152++ * \brief Restore SHA-512/256 running state.
153++ *
154++ * The running state for SHA-512/256 is set to the provided values.
155++ *
156++ * \param ctx pointer to the context structure.
157++ * \param stb source buffer for the running state.
158++ * \param count the injected total byte length.
159++ */
160++void br_sha512_256_set_state(br_sha512_256_context *ctx,
161++ const void *stb, uint64_t count);
162++#else
163++#define br_sha512_256_set_state br_sha384_set_state
164++#endif
165++
166+ /*
167+ * "md5sha1" is a special hash function that computes both MD5 and SHA-1
168+ * on the same input, and produces a 36-byte output (MD5 and SHA-1
169+diff --git a/src/hash/sha2big.c b/src/hash/sha2big.c
170+index 5be92ed..a8b930c 100644
171+--- a/src/hash/sha2big.c
172++++ b/src/hash/sha2big.c
173+@@ -48,6 +48,13 @@ static const uint64_t IV512[8] = {
174+ 0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179
175+ };
176+
177++static const uint64_t IV512_256[8] = {
178++ 0x22312194FC2BF72C, 0x9F555FA3C84C64C2,
179++ 0x2393B86B6F53B151, 0x963877195940EABD,
180++ 0x96283EE2A88EFFE3, 0xBE5E1E2553863992,
181++ 0x2B0199FC2C85B8AA, 0x0EB72DDC81C52CA2
182++};
183++
184+ static const uint64_t K[80] = {
185+ 0x428A2F98D728AE22, 0x7137449123EF65CD,
186+ 0xB5C0FBCFEC4D3B2F, 0xE9B5DBA58189DBBC,
187+@@ -246,6 +253,22 @@ br_sha512_out(const br_sha512_context *cc, void *dst)
188+ sha2big_out(cc, dst, 8);
189+ }
190+
191++/* see bearssl.h */
192++void
193++br_sha512_256_init(br_sha512_context *cc)
194++{
195++ cc->vtable = &br_sha512_256_vtable;
196++ memcpy(cc->val, IV512_256, sizeof IV512_256);
197++ cc->count = 0;
198++}
199++
200++/* see bearssl.h */
201++void
202++br_sha512_256_out(const br_sha512_context *cc, void *dst)
203++{
204++ sha2big_out(cc, dst, 4);
205++}
206++
207+ /* see bearssl.h */
208+ const br_hash_class br_sha384_vtable = {
209+ sizeof(br_sha384_context),
210+@@ -283,3 +306,22 @@ const br_hash_class br_sha512_vtable = {
211+ (void (*)(const br_hash_class **, const void *, uint64_t))
212+ &br_sha512_set_state
213+ };
214++
215++/* see bearssl.h */
216++const br_hash_class br_sha512_256_vtable = {
217++ sizeof(br_sha512_256_context),
218++ BR_HASHDESC_ID(br_sha512_ID)
219++ | BR_HASHDESC_OUT(32)
220++ | BR_HASHDESC_STATE(64)
221++ | BR_HASHDESC_LBLEN(7)
222++ | BR_HASHDESC_MD_PADDING
223++ | BR_HASHDESC_MD_PADDING_BE
224++ | BR_HASHDESC_MD_PADDING_128,
225++ (void (*)(const br_hash_class **))&br_sha512_256_init,
226++ (void (*)(const br_hash_class **, const void *, size_t))
227++ &br_sha512_256_update,
228++ (void (*)(const br_hash_class *const *, void *))&br_sha512_256_out,
229++ (uint64_t (*)(const br_hash_class *const *, void *))&br_sha512_256_state,
230++ (void (*)(const br_hash_class **, const void *, uint64_t))
231++ &br_sha512_256_set_state
232++};
233+--
234+2.54.0
235+
+1,
-1
1@@ -1 +1 @@
2-0.6-39-g7bea48e r1
3+0.6-39-g7bea48e r2