diff options
| author | Jack O'Connor <[email protected]> | 2020-09-10 14:54:15 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2020-09-10 14:54:15 -0500 |
| commit | 27b7f610e0c64cfac3161075c7a997742024143b (patch) | |
| tree | a30601f986c65fc4c08aac047c1d4b3a59dc91e1 | |
| parent | cc04130eaa67627abaf8c7d1fb7f1d3d35f659a2 (diff) | |
| parent | b205e0efa1a1390dd91e3c015976e3d4ce999fff (diff) | |
Merge pull request #114 from k0001/no-cstr
C: Add blake3_hasher_init_derive_key_len
| -rw-r--r-- | c/README.md | 59 | ||||
| -rw-r--r-- | c/blake3.c | 9 | ||||
| -rw-r--r-- | c/blake3.h | 2 |
3 files changed, 61 insertions, 9 deletions
diff --git a/c/README.md b/c/README.md index c66c66a..89802bd 100644 --- a/c/README.md +++ b/c/README.md @@ -104,18 +104,35 @@ Initialize a `blake3_hasher` in the keyed hashing mode. The key must be exactly 32 bytes. ```c +void blake3_hasher_init_derive_key_raw( + blake3_hasher *self, + const void *context, + size_t context_len); +``` + +Initialize a `blake3_hasher` in the key derivation mode. Key material +is to be given as input after initialization, using +`blake3_hasher_update`. The key derivation `context` +should follow the __Key Derivation Context Guidelines__ +described below. `context_len` indicates the size of `context` in bytes. + +```c void blake3_hasher_init_derive_key( blake3_hasher *self, const char *context); ``` -Initialize a `blake3_hasher` in the key derivation mode. Key material -should be given as input after initialization, using -`blake3_hasher_update`. `context` is a standard null-terminated C string -of any length. The context string should be hardcoded, globally unique, -and application-specific. A good default format for the context string -is `"[application] [commit timestamp] [purpose]"`, e.g., `"example.com -2019-12-25 16:18:03 session tokens v1"`. +Similar to `blake3_hasher_init_derive_key_raw`, except it takes the key +derivation `context` as a null-terminated C string. + +This function is offered as a convenience. It is recommended to use this +function when giving a literal, hardcoded C string as parameter. + +Notice that contrary to `blake3_hasher_init_derive_key_raw`, this function +cannot accept `context`s containing the byte `0x00` except as a the +terminating byte. For this reason, `blake3_hasher_init_derive_key_raw` is +preferred in more general contexts, such as when implementing bindings to +this C library. ```c void blake3_hasher_finalize_seek( @@ -130,6 +147,34 @@ parameter for the starting byte position in the output stream. To efficiently stream a large output without allocating memory, call this function in a loop, incrementing `seek` by the output length each time. +## Key Derivation Context Guidelines + +The key derivation context should uniquely describe the +application, place and purpose of the derivation. + +The context should be **statically known, +hardcoded, globally unique, and application-specific**. + +The context should not depend on any dynamic input such as salts, +nonces, or identifiers read from a database at runtime. + +A good format for the context string is: + +``` +[application] [commit timestamp] [purpose] +``` + +For example: + +``` +example.com 2019-12-25 16:18:03 session tokens v1 +``` + +It's recommended that the context string consists of ASCII bytes +containing only alphanumeric characters, whitespace and punctuation. +However, any bytes are acceptable as long as they satisfy the +static constraints described above. + # Building This implementation is just C and assembly files. It doesn't include a @@ -367,10 +367,11 @@ void blake3_hasher_init_keyed(blake3_hasher *self, hasher_init_base(self, key_words, KEYED_HASH); } -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) { blake3_hasher context_hasher; hasher_init_base(&context_hasher, IV, DERIVE_KEY_CONTEXT); - blake3_hasher_update(&context_hasher, context, strlen(context)); + blake3_hasher_update(&context_hasher, context, context_len); uint8_t context_key[BLAKE3_KEY_LEN]; blake3_hasher_finalize(&context_hasher, context_key, BLAKE3_KEY_LEN); uint32_t context_key_words[8]; @@ -378,6 +379,10 @@ void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context) { hasher_init_base(self, context_key_words, DERIVE_KEY_MATERIAL); } +void blake3_hasher_init_derive_key(blake3_hasher *self, const char *context) { + blake3_hasher_init_derive_key_raw(self, context, strlen(context)); +} + // As described in hasher_push_cv() below, we do "lazy merging", delaying // merges until right before the next CV is about to be added. This is // different from the reference implementation. Another difference is that we @@ -42,6 +42,8 @@ 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, |
