aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack O'Connor <[email protected]>2020-09-10 14:54:15 -0500
committerGitHub <[email protected]>2020-09-10 14:54:15 -0500
commit27b7f610e0c64cfac3161075c7a997742024143b (patch)
treea30601f986c65fc4c08aac047c1d4b3a59dc91e1
parentcc04130eaa67627abaf8c7d1fb7f1d3d35f659a2 (diff)
parentb205e0efa1a1390dd91e3c015976e3d4ce999fff (diff)
Merge pull request #114 from k0001/no-cstr
C: Add blake3_hasher_init_derive_key_len
-rw-r--r--c/README.md59
-rw-r--r--c/blake3.c9
-rw-r--r--c/blake3.h2
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
diff --git a/c/blake3.c b/c/blake3.c
index c99d059..71aed71 100644
--- a/c/blake3.c
+++ b/c/blake3.c
@@ -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
diff --git a/c/blake3.h b/c/blake3.h
index 5060e38..51f1d2a 100644
--- a/c/blake3.h
+++ b/c/blake3.h
@@ -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,