0004-Add-br_sha512_256.patch (8065B)
1 From 4f6c794c471789bed5e078bb0330ff08bb5936ac Mon Sep 17 00:00:00 2001 2 From: Michael Forney <mforney@mforney.org> 3 Date: Fri, 15 May 2026 02:59:18 -0700 4 Subject: [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 11 diff --git a/inc/bearssl_hash.h b/inc/bearssl_hash.h 12 index 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 168 diff --git a/src/hash/sha2big.c b/src/hash/sha2big.c 169 index 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 -- 233 2.54.0 234