mirror of
https://github.com/BLAKE3-team/BLAKE3
synced 2025-01-21 15:50:01 +01:00
Changes since 1.1.0: - SECURITY FIX: Fixed an instance of undefined behavior in the Windows SSE2 assembly implementations, which affected both the Rust and C libraries in their default build configurations. See https://github.com/BLAKE3-team/BLAKE3/issues/206. The cause was a vector register that wasn't properly saved and restored. This bug has been present since SSE2 support was initially added in v0.3.7. The effects of this bug depend on surrounding code and compiler optimizations; see test_issue_206_windows_sse2 for an example of this bug causing incorrect hash output. Note that even when surrounding code is arranged to trigger this bug, the SSE2 implementation is normally only invoked on CPUs where SSE4.1 (introduced in 2007) isn't supported. One notable exception, however, is if the Rust library is built in `no_std` mode, with `default_features = false` or similar. In that case, runtime CPU feature detection is disabled, and since LLVM assumes that all x86-64 targets support SSE2, the SSE2 implementation will be invoked. For that reason, Rust callers who build `blake3` in `no_std` mode for x86-64 Windows targets are the most likely to trigger this bug. We found this bug in internal testing, and we aren't aware of any callers encountering it in practice. - Added the Hasher::count() method.
60 lines
1.9 KiB
C
60 lines
1.9 KiB
C
#ifndef BLAKE3_H
|
|
#define BLAKE3_H
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define BLAKE3_VERSION_STRING "1.2.0"
|
|
#define BLAKE3_KEY_LEN 32
|
|
#define BLAKE3_OUT_LEN 32
|
|
#define BLAKE3_BLOCK_LEN 64
|
|
#define BLAKE3_CHUNK_LEN 1024
|
|
#define BLAKE3_MAX_DEPTH 54
|
|
|
|
// This struct is a private implementation detail. It has to be here because
|
|
// it's part of blake3_hasher below.
|
|
typedef struct {
|
|
uint32_t cv[8];
|
|
uint64_t chunk_counter;
|
|
uint8_t buf[BLAKE3_BLOCK_LEN];
|
|
uint8_t buf_len;
|
|
uint8_t blocks_compressed;
|
|
uint8_t flags;
|
|
} blake3_chunk_state;
|
|
|
|
typedef struct {
|
|
uint32_t key[8];
|
|
blake3_chunk_state chunk;
|
|
uint8_t cv_stack_len;
|
|
// The stack size is MAX_DEPTH + 1 because we do lazy merging. For example,
|
|
// with 7 chunks, we have 3 entries in the stack. Adding an 8th chunk
|
|
// requires a 4th entry, rather than merging everything down to 1, because we
|
|
// don't know whether more input is coming. This is different from how the
|
|
// reference implementation does things.
|
|
uint8_t cv_stack[(BLAKE3_MAX_DEPTH + 1) * BLAKE3_OUT_LEN];
|
|
} blake3_hasher;
|
|
|
|
const char *blake3_version(void);
|
|
void blake3_hasher_init(blake3_hasher *self);
|
|
void blake3_hasher_init_keyed(blake3_hasher *self,
|
|
const uint8_t key[BLAKE3_KEY_LEN]);
|
|
void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context);
|
|
void blake3_hasher_init_derive_key_raw(blake3_hasher *self, const void *context,
|
|
size_t context_len);
|
|
void blake3_hasher_update(blake3_hasher *self, const void *input,
|
|
size_t input_len);
|
|
void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out,
|
|
size_t out_len);
|
|
void blake3_hasher_finalize_seek(const blake3_hasher *self, uint64_t seek,
|
|
uint8_t *out, size_t out_len);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* BLAKE3_H */
|