Add sha 256 library and adapt license sections in documentation
This commit is contained in:
		
							
								
								
									
										46
									
								
								stm-firmware/updater/ram-code/3rd-party/sha256/LICENSE.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								stm-firmware/updater/ram-code/3rd-party/sha256/LICENSE.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
# Licensing Information
 | 
			
		||||
 | 
			
		||||
Except as otherwise noted (below and/or in individual files), this project is
 | 
			
		||||
licensed under the [Unlicense](#the-unlicense)
 | 
			
		||||
(https://opensource.org/licenses/unlicense) or the [Zero Clause BSD
 | 
			
		||||
license](#zero-clause-bsd-license) (https://opensource.org/licenses/0bsd), at
 | 
			
		||||
your option.
 | 
			
		||||
 | 
			
		||||
## The Unlicense
 | 
			
		||||
 | 
			
		||||
This is free and unencumbered software released into the public domain.
 | 
			
		||||
 | 
			
		||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
 | 
			
		||||
software, either in source code form or as a compiled binary, for any purpose,
 | 
			
		||||
commercial or non-commercial, and by any means.
 | 
			
		||||
 | 
			
		||||
In jurisdictions that recognize copyright laws, the author or authors of this
 | 
			
		||||
software dedicate any and all copyright interest in the software to the public
 | 
			
		||||
domain. We make this dedication for the benefit of the public at large and to
 | 
			
		||||
the detriment of our heirs and successors. We intend this dedication to be an
 | 
			
		||||
overt act of relinquishment in perpetuity of all present and future rights to
 | 
			
		||||
this software under copyright law.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
			
		||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 | 
			
		||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
For more information, please refer to <http://unlicense.org>
 | 
			
		||||
 | 
			
		||||
## Zero Clause BSD License
 | 
			
		||||
 | 
			
		||||
© 2021 Alain Mosnier
 | 
			
		||||
 | 
			
		||||
Permission to use, copy, modify, and/or distribute this software for any
 | 
			
		||||
purpose with or without fee is hereby granted.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 | 
			
		||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 | 
			
		||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 | 
			
		||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
			
		||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
			
		||||
PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
							
								
								
									
										134
									
								
								stm-firmware/updater/ram-code/3rd-party/sha256/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								stm-firmware/updater/ram-code/3rd-party/sha256/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
# sha-2 [](https://travis-ci.com/amosnier/sha-2)
 | 
			
		||||
 | 
			
		||||
## Disclaimer
 | 
			
		||||
The SHA256 implementation used in thsi project is taken from https://github.com/amosnier/sha-2. Check the appropriate license file.
 | 
			
		||||
 | 
			
		||||
## Contents
 | 
			
		||||
 | 
			
		||||
SHA-2 algorithm implementations.
 | 
			
		||||
 | 
			
		||||
At the moment, only SHA-256 is implemented.
 | 
			
		||||
 | 
			
		||||
## NEW: streaming API
 | 
			
		||||
 | 
			
		||||
In response to [an enhancement
 | 
			
		||||
request](https://github.com/amosnier/sha-2/issues/9), a new streaming
 | 
			
		||||
API has been created.
 | 
			
		||||
 | 
			
		||||
The following code is a silly but complete example:
 | 
			
		||||
 | 
			
		||||
```C
 | 
			
		||||
struct Sha_256 sha_256;
 | 
			
		||||
uint8_t hash[32];
 | 
			
		||||
sha_256_init(&sha_256, hash);
 | 
			
		||||
sha_256_write(&sha_256, "ab", strlen("ab"));
 | 
			
		||||
sha_256_write(&sha_256, "c", strlen("c"));
 | 
			
		||||
sha_256_close(&sha_256);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
That is the equivalent of the (of course still supported) legacy way:
 | 
			
		||||
 | 
			
		||||
```C
 | 
			
		||||
uint8_t hash[32];
 | 
			
		||||
calc_sha_256(hash, "abc", strlen("abc"));
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
See [header file](https://github.com/amosnier/sha-2/blob/master/sha-256.h)
 | 
			
		||||
for more information.
 | 
			
		||||
 | 
			
		||||
Since the streaming API is a generalization of the non-streaming one,
 | 
			
		||||
the latter has been ported to the former, without measurable performance
 | 
			
		||||
impact. However, [a legacy
 | 
			
		||||
branch](https://github.com/amosnier/sha-2/tree/legacy) has been created
 | 
			
		||||
in order to make the legacy implementation easily available. If you can
 | 
			
		||||
measure a significant difference between the two, please post an issue.
 | 
			
		||||
 | 
			
		||||
## Design criteria
 | 
			
		||||
 | 
			
		||||
- Easy to test, include in any project, compile and link.
 | 
			
		||||
 | 
			
		||||
- ANSI C with as little specific C99 as possible (e.g. extended
 | 
			
		||||
  integer types are used, but not bool).
 | 
			
		||||
 | 
			
		||||
- Portable. Makes no assumptions on the target system's endianess or
 | 
			
		||||
  word size.
 | 
			
		||||
 | 
			
		||||
- The SHA-256 implementation is a straightforward implementation of
 | 
			
		||||
  the algorithm specified on
 | 
			
		||||
  [Wikipedia](https://en.wikipedia.org/wiki/SHA-2).
 | 
			
		||||
 | 
			
		||||
## Notes
 | 
			
		||||
 | 
			
		||||
The Makefile is as minimal as possible. No effort was put into making
 | 
			
		||||
it general. Its purpose is mainly to ease testing for the developer's
 | 
			
		||||
host machine. The actual implementation is however extremely easy to
 | 
			
		||||
include in any project, may it use GNU make or any other build tool.
 | 
			
		||||
 | 
			
		||||
## Code review
 | 
			
		||||
 | 
			
		||||
This code has been reviewed at [Stack Exchange CODE
 | 
			
		||||
REVIEW](https://codereview.stackexchange.com/questions/182812/self-contained-sha-256-implementation-in-c),
 | 
			
		||||
and the implementation has been improved accordingly.
 | 
			
		||||
 | 
			
		||||
## Testing
 | 
			
		||||
 | 
			
		||||
Testing is continuously performed on Travis CI (see above).
 | 
			
		||||
 | 
			
		||||
Apart from that, the implementation has been successfully tested on an x86-64 machine
 | 
			
		||||
under Linux as well as on a 16-bit DSP. On the x86-64 machine, all the
 | 
			
		||||
available NIST test vectors where successfully tested ([SHA-256
 | 
			
		||||
examples](https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA256.pdf)
 | 
			
		||||
and [SHA-2 Additional
 | 
			
		||||
examples](https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA2_Additional.pdf),
 | 
			
		||||
plus a few others).
 | 
			
		||||
 | 
			
		||||
In particular:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
Input Message: "abc"
 | 
			
		||||
Message Digest is BA7816BF 8F01CFEA 414140DE 5DAE2223 B00361A3 96177A9C B410FF61 F20015AD
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
Input Message: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
 | 
			
		||||
Message Digest is 248D6A61 D20638B8 E5C02693 0C3E6039 A33CE459 64FF2167 F6ECEDD4 19DB06C1
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
SHA-256 Test Data
 | 
			
		||||
#1) 1 byte 0xbd
 | 
			
		||||
68325720 aabd7c82 f30f554b 313d0570 c95accbb 7dc4b5aa e11204c0 8ffe732b
 | 
			
		||||
#2) 4 bytes 0xc98c8e55
 | 
			
		||||
7abc22c0 ae5af26c e93dbb94 433a0e0b 2e119d01 4f8e7f65 bd56c61c cccd9504
 | 
			
		||||
#3) 55 bytes of zeros
 | 
			
		||||
02779466 cdec1638 11d07881 5c633f21 90141308 1449002f 24aa3e80 f0b88ef7
 | 
			
		||||
#4) 56 bytes of zeros
 | 
			
		||||
d4817aa5 497628e7 c77e6b60 6107042b bba31308 88c5f47a 375e6179 be789fbb
 | 
			
		||||
#5) 57 bytes of zeros
 | 
			
		||||
65a16cb7 861335d5 ace3c607 18b5052e 44660726 da4cd13b b745381b 235a1785
 | 
			
		||||
#6) 64 bytes of zeros
 | 
			
		||||
f5a5fd42 d16a2030 2798ef6e d309979b 43003d23 20d9f0e8 ea9831a9 2759fb4b
 | 
			
		||||
#7) 1000 bytes of zeros
 | 
			
		||||
541b3e9d aa09b20b f85fa273 e5cbd3e8 0185aa4e c298e765 db87742b 70138a53
 | 
			
		||||
#8) 1000 bytes of 0x41 ‘A’
 | 
			
		||||
c2e68682 3489ced2 017f6059 b8b23931 8b6364f6 dcd835d0 a519105a 1eadd6e4
 | 
			
		||||
#9) 1005 bytes of 0x55 ‘U’
 | 
			
		||||
f4d62dde c0f3dd90 ea1380fa 16a5ff8d c4c54b21 740650f2 4afc4120 903552b0
 | 
			
		||||
#10) 1000000 bytes of zeros
 | 
			
		||||
d29751f2 649b32ff 572b5e0a 9f541ea6 60a50f94 ff0beedf b0b692b9 24cc8025
 | 
			
		||||
#11) 0x20000000 (536870912) bytes of 0x5a ‘Z’
 | 
			
		||||
15a1868c 12cc5395 1e182344 277447cd 0979536b adcc512a d24c67e9 b2d4f3dd
 | 
			
		||||
#12) 0x41000000 (1090519040) bytes of zeros
 | 
			
		||||
461c19a9 3bd4344f 9215f5ec 64357090 342bc66b 15a14831 7d276e31 cbc20b53
 | 
			
		||||
#13) 0x6000003e (1610612798) bytes of 0x42 ‘B’
 | 
			
		||||
c23ce8a7 895f4b21 ec0daf37 920ac0a2 62a22004 5a03eb2d fed48ef9 b05aabea
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
This repository is made available under a permissive license. See
 | 
			
		||||
[LICENSE FILE](LICENSE.md).
 | 
			
		||||
 | 
			
		||||
## Reference implementation
 | 
			
		||||
 | 
			
		||||
I had missed that when I made this implementation but [RFC 6234, chapter 8](https://tools.ietf.org/html/rfc6234#section-8) actually includes a reference implementation in C that is (at least in ambition) broader in scope than this one. I have however neither compiled nor tested it.
 | 
			
		||||
							
								
								
									
										226
									
								
								stm-firmware/updater/ram-code/3rd-party/sha256/sha-256.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								stm-firmware/updater/ram-code/3rd-party/sha256/sha-256.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,226 @@
 | 
			
		||||
#include "sha-256.h"
 | 
			
		||||
 | 
			
		||||
#define TOTAL_LEN_LEN 8
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ABOUT bool: this file does not use bool in order to be as pre-C99 compatible as possible.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Comments from pseudo-code at https://en.wikipedia.org/wiki/SHA-2 are reproduced here.
 | 
			
		||||
 * When useful for clarification, portions of the pseudo-code are reproduced here too.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @brief Rotate a 32-bit value by a number of bits to the right.
 | 
			
		||||
 * @param value The value to be rotated.
 | 
			
		||||
 * @param count The number of bits to rotate by.
 | 
			
		||||
 * @return The rotated value.
 | 
			
		||||
 */
 | 
			
		||||
static inline uint32_t right_rot(uint32_t value, unsigned int count)
 | 
			
		||||
{
 | 
			
		||||
	/*
 | 
			
		||||
	 * Defined behaviour in standard C for all count where 0 < count < 32, which is what we need here.
 | 
			
		||||
	 */
 | 
			
		||||
	return value >> count | value << (32 - count);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @brief Update a hash value under calculation with a new chunk of data.
 | 
			
		||||
 * @param h Pointer to the first hash item, of a total of eight.
 | 
			
		||||
 * @param p Pointer to the chunk data, which has a standard length.
 | 
			
		||||
 *
 | 
			
		||||
 * @note This is the SHA-256 work horse.
 | 
			
		||||
 */
 | 
			
		||||
static inline void consume_chunk(uint32_t *h, const uint8_t *p)
 | 
			
		||||
{
 | 
			
		||||
	unsigned i, j;
 | 
			
		||||
	uint32_t ah[8];
 | 
			
		||||
 | 
			
		||||
	/* Initialize working variables to current hash value: */
 | 
			
		||||
	for (i = 0; i < 8; i++)
 | 
			
		||||
		ah[i] = h[i];
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The w-array is really w[64], but since we only need 16 of them at a time, we save stack by
 | 
			
		||||
	 * calculating 16 at a time.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This optimization was not there initially and the rest of the comments about w[64] are kept in their
 | 
			
		||||
	 * initial state.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * create a 64-entry message schedule array w[0..63] of 32-bit words (The initial values in w[0..63]
 | 
			
		||||
	 * don't matter, so many implementations zero them here) copy chunk into first 16 words w[0..15] of the
 | 
			
		||||
	 * message schedule array
 | 
			
		||||
	 */
 | 
			
		||||
	uint32_t w[16];
 | 
			
		||||
 | 
			
		||||
	/* Compression function main loop: */
 | 
			
		||||
	for (i = 0; i < 4; i++) {
 | 
			
		||||
		for (j = 0; j < 16; j++) {
 | 
			
		||||
			if (i == 0) {
 | 
			
		||||
				w[j] =
 | 
			
		||||
				    (uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | (uint32_t)p[3];
 | 
			
		||||
				p += 4;
 | 
			
		||||
			} else {
 | 
			
		||||
				/* Extend the first 16 words into the remaining 48 words w[16..63] of the
 | 
			
		||||
				 * message schedule array: */
 | 
			
		||||
				const uint32_t s0 = right_rot(w[(j + 1) & 0xf], 7) ^ right_rot(w[(j + 1) & 0xf], 18) ^
 | 
			
		||||
						    (w[(j + 1) & 0xf] >> 3);
 | 
			
		||||
				const uint32_t s1 = right_rot(w[(j + 14) & 0xf], 17) ^
 | 
			
		||||
						    right_rot(w[(j + 14) & 0xf], 19) ^ (w[(j + 14) & 0xf] >> 10);
 | 
			
		||||
				w[j] = w[j] + s0 + w[(j + 9) & 0xf] + s1;
 | 
			
		||||
			}
 | 
			
		||||
			const uint32_t s1 = right_rot(ah[4], 6) ^ right_rot(ah[4], 11) ^ right_rot(ah[4], 25);
 | 
			
		||||
			const uint32_t ch = (ah[4] & ah[5]) ^ (~ah[4] & ah[6]);
 | 
			
		||||
 | 
			
		||||
			/*
 | 
			
		||||
			 * Initialize array of round constants:
 | 
			
		||||
			 * (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311):
 | 
			
		||||
			 */
 | 
			
		||||
			static const uint32_t k[] = {
 | 
			
		||||
			    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
 | 
			
		||||
			    0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
 | 
			
		||||
			    0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f,
 | 
			
		||||
			    0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
 | 
			
		||||
			    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
 | 
			
		||||
			    0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
 | 
			
		||||
			    0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116,
 | 
			
		||||
			    0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
 | 
			
		||||
			    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
 | 
			
		||||
			    0xc67178f2};
 | 
			
		||||
 | 
			
		||||
			const uint32_t temp1 = ah[7] + s1 + ch + k[i << 4 | j] + w[j];
 | 
			
		||||
			const uint32_t s0 = right_rot(ah[0], 2) ^ right_rot(ah[0], 13) ^ right_rot(ah[0], 22);
 | 
			
		||||
			const uint32_t maj = (ah[0] & ah[1]) ^ (ah[0] & ah[2]) ^ (ah[1] & ah[2]);
 | 
			
		||||
			const uint32_t temp2 = s0 + maj;
 | 
			
		||||
 | 
			
		||||
			ah[7] = ah[6];
 | 
			
		||||
			ah[6] = ah[5];
 | 
			
		||||
			ah[5] = ah[4];
 | 
			
		||||
			ah[4] = ah[3] + temp1;
 | 
			
		||||
			ah[3] = ah[2];
 | 
			
		||||
			ah[2] = ah[1];
 | 
			
		||||
			ah[1] = ah[0];
 | 
			
		||||
			ah[0] = temp1 + temp2;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Add the compressed chunk to the current hash value: */
 | 
			
		||||
	for (i = 0; i < 8; i++)
 | 
			
		||||
		h[i] += ah[i];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public functions. See header file for documentation.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void sha_256_init(struct Sha_256 *sha_256, uint8_t hash[SIZE_OF_SHA_256_HASH])
 | 
			
		||||
{
 | 
			
		||||
	sha_256->hash = hash;
 | 
			
		||||
	sha_256->chunk_pos = sha_256->chunk;
 | 
			
		||||
	sha_256->space_left = SIZE_OF_SHA_256_CHUNK;
 | 
			
		||||
	sha_256->total_len = 0;
 | 
			
		||||
	/*
 | 
			
		||||
	 * Initialize hash values (first 32 bits of the fractional parts of the square roots of the first 8 primes
 | 
			
		||||
	 * 2..19):
 | 
			
		||||
	 */
 | 
			
		||||
	sha_256->h[0] = 0x6a09e667;
 | 
			
		||||
	sha_256->h[1] = 0xbb67ae85;
 | 
			
		||||
	sha_256->h[2] = 0x3c6ef372;
 | 
			
		||||
	sha_256->h[3] = 0xa54ff53a;
 | 
			
		||||
	sha_256->h[4] = 0x510e527f;
 | 
			
		||||
	sha_256->h[5] = 0x9b05688c;
 | 
			
		||||
	sha_256->h[6] = 0x1f83d9ab;
 | 
			
		||||
	sha_256->h[7] = 0x5be0cd19;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sha_256_write(struct Sha_256 *sha_256, const void *data, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	sha_256->total_len += len;
 | 
			
		||||
 | 
			
		||||
	const uint8_t *p = data;
 | 
			
		||||
 | 
			
		||||
	while (len > 0) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * If the input chunks have sizes that are multiples of the calculation chunk size, no copies are
 | 
			
		||||
		 * necessary. We operate directly on the input data instead.
 | 
			
		||||
		 */
 | 
			
		||||
		if (sha_256->space_left == SIZE_OF_SHA_256_CHUNK && len >= SIZE_OF_SHA_256_CHUNK) {
 | 
			
		||||
			consume_chunk(sha_256->h, p);
 | 
			
		||||
			len -= SIZE_OF_SHA_256_CHUNK;
 | 
			
		||||
			p += SIZE_OF_SHA_256_CHUNK;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		/* General case, no particular optimization. */
 | 
			
		||||
		const size_t consumed_len = len < sha_256->space_left ? len : sha_256->space_left;
 | 
			
		||||
		memcpy(sha_256->chunk_pos, p, consumed_len);
 | 
			
		||||
		sha_256->space_left -= consumed_len;
 | 
			
		||||
		len -= consumed_len;
 | 
			
		||||
		p += consumed_len;
 | 
			
		||||
		if (sha_256->space_left == 0) {
 | 
			
		||||
			consume_chunk(sha_256->h, sha_256->chunk);
 | 
			
		||||
			sha_256->chunk_pos = sha_256->chunk;
 | 
			
		||||
			sha_256->space_left = SIZE_OF_SHA_256_CHUNK;
 | 
			
		||||
		} else {
 | 
			
		||||
			sha_256->chunk_pos += consumed_len;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t *sha_256_close(struct Sha_256 *sha_256)
 | 
			
		||||
{
 | 
			
		||||
	uint8_t *pos = sha_256->chunk_pos;
 | 
			
		||||
	size_t space_left = sha_256->space_left;
 | 
			
		||||
	uint32_t *const h = sha_256->h;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The current chunk cannot be full. Otherwise, it would already have be consumed. I.e. there is space left for
 | 
			
		||||
	 * at least one byte. The next step in the calculation is to add a single one-bit to the data.
 | 
			
		||||
	 */
 | 
			
		||||
	*pos++ = 0x80;
 | 
			
		||||
	--space_left;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Now, the last step is to add the total data length at the end of the last chunk, and zero padding before
 | 
			
		||||
	 * that. But we do not necessarily have enough space left. If not, we pad the current chunk with zeroes, and add
 | 
			
		||||
	 * an extra chunk at the end.
 | 
			
		||||
	 */
 | 
			
		||||
	if (space_left < TOTAL_LEN_LEN) {
 | 
			
		||||
		memset(pos, 0x00, space_left);
 | 
			
		||||
		consume_chunk(h, sha_256->chunk);
 | 
			
		||||
		pos = sha_256->chunk;
 | 
			
		||||
		space_left = SIZE_OF_SHA_256_CHUNK;
 | 
			
		||||
	}
 | 
			
		||||
	const size_t left = space_left - TOTAL_LEN_LEN;
 | 
			
		||||
	memset(pos, 0x00, left);
 | 
			
		||||
	pos += left;
 | 
			
		||||
	size_t len = sha_256->total_len;
 | 
			
		||||
	pos[7] = (uint8_t)(len << 3);
 | 
			
		||||
	len >>= 5;
 | 
			
		||||
	int i;
 | 
			
		||||
	for (i = 6; i >= 0; --i) {
 | 
			
		||||
		pos[i] = (uint8_t)len;
 | 
			
		||||
		len >>= 8;
 | 
			
		||||
	}
 | 
			
		||||
	consume_chunk(h, sha_256->chunk);
 | 
			
		||||
	/* Produce the final hash value (big-endian): */
 | 
			
		||||
	int j;
 | 
			
		||||
	uint8_t *const hash = sha_256->hash;
 | 
			
		||||
	for (i = 0, j = 0; i < 8; i++) {
 | 
			
		||||
		hash[j++] = (uint8_t)(h[i] >> 24);
 | 
			
		||||
		hash[j++] = (uint8_t)(h[i] >> 16);
 | 
			
		||||
		hash[j++] = (uint8_t)(h[i] >> 8);
 | 
			
		||||
		hash[j++] = (uint8_t)h[i];
 | 
			
		||||
	}
 | 
			
		||||
	return sha_256->hash;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void calc_sha_256(uint8_t hash[SIZE_OF_SHA_256_HASH], const void *input, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	struct Sha_256 sha_256;
 | 
			
		||||
	sha_256_init(&sha_256, hash);
 | 
			
		||||
	sha_256_write(&sha_256, input, len);
 | 
			
		||||
	(void)sha_256_close(&sha_256);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										103
									
								
								stm-firmware/updater/ram-code/3rd-party/sha256/sha-256.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								stm-firmware/updater/ram-code/3rd-party/sha256/sha-256.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
#ifndef SHA_256_H
 | 
			
		||||
#define SHA_256_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @brief Size of the SHA-256 sum. This times eight is 256 bits.
 | 
			
		||||
 */
 | 
			
		||||
#define SIZE_OF_SHA_256_HASH 32
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @brief Size of the chunks used for the calculations.
 | 
			
		||||
 *
 | 
			
		||||
 * @note This should mostly be ignored by the user, although when using the streaming API, it has an impact for
 | 
			
		||||
 * performance. Add chunks whose size is a multiple of this, and you will avoid a lot of superfluous copying in RAM!
 | 
			
		||||
 */
 | 
			
		||||
#define SIZE_OF_SHA_256_CHUNK 64
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @brief The opaque SHA-256 type, that should be instantiated when using the streaming API.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Although the details are exposed here, in order to make instantiation easy, you should refrain from directly
 | 
			
		||||
 * accessing the fields, as they may change in the future.
 | 
			
		||||
 */
 | 
			
		||||
struct Sha_256 {
 | 
			
		||||
	uint8_t *hash;
 | 
			
		||||
	uint8_t chunk[SIZE_OF_SHA_256_CHUNK];
 | 
			
		||||
	uint8_t *chunk_pos;
 | 
			
		||||
	size_t space_left;
 | 
			
		||||
	size_t total_len;
 | 
			
		||||
	uint32_t h[8];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @brief The simple SHA-256 calculation function.
 | 
			
		||||
 * @param hash Hash array, where the result is delivered.
 | 
			
		||||
 * @param input Pointer to the data the hash shall be calculated on.
 | 
			
		||||
 * @param len Length of the input data, in byte.
 | 
			
		||||
 *
 | 
			
		||||
 * @note If all of the data you are calculating the hash value on is available in a contiguous buffer in memory, this is
 | 
			
		||||
 * the function you should use.
 | 
			
		||||
 *
 | 
			
		||||
 * @note If either of the passed pointers is NULL, the results are unpredictable.
 | 
			
		||||
 */
 | 
			
		||||
void calc_sha_256(uint8_t hash[SIZE_OF_SHA_256_HASH], const void *input, size_t len);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @brief Initialize a SHA-256 streaming calculation.
 | 
			
		||||
 * @param sha_256 A pointer to a SHA-256 structure.
 | 
			
		||||
 * @param hash Hash array, where the result will be delivered.
 | 
			
		||||
 *
 | 
			
		||||
 * @note If all of the data you are calculating the hash value on is not available in a contiguous buffer in memory, this is
 | 
			
		||||
 * where you should start. Instantiate a SHA-256 structure, for instance by simply declaring it locally, make your hash
 | 
			
		||||
 * buffer available, and invoke this function. Once a SHA-256 hash has been calculated (see further below) a SHA-256
 | 
			
		||||
 * structure can be initialized again for the next calculation.
 | 
			
		||||
 *
 | 
			
		||||
 * @note If either of the passed pointers is NULL, the results are unpredictable.
 | 
			
		||||
 */
 | 
			
		||||
void sha_256_init(struct Sha_256 *sha_256, uint8_t hash[SIZE_OF_SHA_256_HASH]);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @brief Stream more input data for an on-going SHA-256 calculation.
 | 
			
		||||
 * @param sha_256 A pointer to a previously initialized SHA-256 structure.
 | 
			
		||||
 * @param data Pointer to the data to be added to the calculation.
 | 
			
		||||
 * @param len Length of the data to add, in byte.
 | 
			
		||||
 *
 | 
			
		||||
 * @note This function may be invoked an arbitrary number of times between initialization and closing, but the maximum
 | 
			
		||||
 * data length is limited by the SHA-256 algorithm: the total number of bits (i.e. the total number of bytes times
 | 
			
		||||
 * eight) must be representable by a 64-bit unsigned integer. While that is not a practical limitation, the results are
 | 
			
		||||
 * unpredictable if that limit is exceeded.
 | 
			
		||||
 *
 | 
			
		||||
 * @note This function may be invoked on empty data (zero length), although that obviously will not add any data.
 | 
			
		||||
 *
 | 
			
		||||
 * @note If either of the passed pointers is NULL, the results are unpredictable.
 | 
			
		||||
 */
 | 
			
		||||
void sha_256_write(struct Sha_256 *sha_256, const void *data, size_t len);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @brief Conclude a SHA-256 streaming calculation, making the hash value available.
 | 
			
		||||
 * @param sha_256 A pointer to a previously initialized SHA-256 structure.
 | 
			
		||||
 * @return Pointer to the hash array, where the result is delivered.
 | 
			
		||||
 *
 | 
			
		||||
 * @note After this function has been invoked, the result is available in the hash buffer that initially was provided. A
 | 
			
		||||
 * pointer to the hash value is returned for convenience, but you should feel free to ignore it: it is simply a pointer
 | 
			
		||||
 * to the first byte of your initially provided hash array.
 | 
			
		||||
 *
 | 
			
		||||
 * @note If the passed pointer is NULL, the results are unpredictable.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Invoking this function for a calculation with no data (the writing function has never been invoked, or it only
 | 
			
		||||
 * has been invoked with empty data) is legal. It will calculate the SHA-256 value of the empty string.
 | 
			
		||||
 */
 | 
			
		||||
uint8_t *sha_256_close(struct Sha_256 *sha_256);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user