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