cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
seq_auth.c File Reference
#include <cwist/core/seq/seq_auth.h>
#include <cwist/core/mem/alloc.h>
#include <cwist/sys/platform.h>
#include <cwist/core/crypto/sha256.h>
#include <limits.h>
#include <pthread.h>
#include <string.h>
Include dependency graph for seq_auth.c:

Go to the source code of this file.

Macros

#define SEQ_AUTH_WASM_CRYPTO   1
 
#define SEQ_AUTH_TAG_CAP   CWIST_SHA256_DIGEST_LEN
 
#define SEQ_AUTH_MEMCMP(a, b, len)   seq_auth_memcmp((a), (b), (len))
 
#define SEQ_AUTH_CLEANSE(ptr, len)   memset((ptr), 0, (len))
 

Functions

cwist_seq_auth_context_t * cwist_seq_auth_context_create (const uint8_t key[CWIST_SEQ_AUTH_KEY_SIZE], const uint8_t session_id[CWIST_SEQ_AUTH_SESSION_ID_SIZE], size_t replay_window)
 Create an authenticated-sequencing context.
 
void cwist_seq_auth_context_destroy (cwist_seq_auth_context_t *ctx)
 Destroy an authenticated-sequencing context.
 
bool cwist_seq_auth_random (uint8_t *out, size_t len)
 Fill a buffer with cryptographically secure random bytes.
 
bool cwist_seq_auth_wrap (const cwist_seq_auth_context_t *ctx, const uint8_t message_id[CWIST_SEQ_AUTH_MESSAGE_ID_SIZE], const uint8_t nonce[CWIST_SEQ_AUTH_NONCE_SIZE], const uint8_t *chunk, size_t chunk_len, uint8_t **out, size_t *out_len)
 Attach message id, nonce, and authentication tag to a chunk.
 
bool cwist_seq_auth_unwrap (cwist_seq_auth_context_t *ctx, const uint8_t *data, size_t len, cwist_seq_auth_metadata_t *metadata, cwist_seq_chunk_t *chunk)
 Verify, authenticate, and split an incoming authenticated chunk.
 
void cwist_seq_auth_mark_complete (cwist_seq_auth_context_t *ctx, const uint8_t message_id[CWIST_SEQ_AUTH_MESSAGE_ID_SIZE])
 Record a message id as fully received.
 

Macro Definition Documentation

◆ SEQ_AUTH_CLEANSE

#define SEQ_AUTH_CLEANSE (   ptr,
  len 
)    memset((ptr), 0, (len))

Definition at line 50 of file seq_auth.c.

◆ SEQ_AUTH_MEMCMP

#define SEQ_AUTH_MEMCMP (   a,
  b,
  len 
)    seq_auth_memcmp((a), (b), (len))

Definition at line 49 of file seq_auth.c.

◆ SEQ_AUTH_TAG_CAP

#define SEQ_AUTH_TAG_CAP   CWIST_SHA256_DIGEST_LEN

Definition at line 30 of file seq_auth.c.

◆ SEQ_AUTH_WASM_CRYPTO

#define SEQ_AUTH_WASM_CRYPTO   1

Definition at line 29 of file seq_auth.c.

Function Documentation

◆ cwist_seq_auth_context_create()

cwist_seq_auth_context_t * cwist_seq_auth_context_create ( const uint8_t  key[CWIST_SEQ_AUTH_KEY_SIZE],
const uint8_t  session_id[CWIST_SEQ_AUTH_SESSION_ID_SIZE],
size_t  replay_window 
)

Create an authenticated-sequencing context.

Allocates the context plus the nonce and completed-message-id replay caches, each sized to replay_window entries. On failure all partially allocated state is freed and NULL is returned. The returned context is owned by the caller and must be released with cwist_seq_auth_context_destroy().

Parameters
key32-byte authentication key, copied into the context.
session_id16-byte session identifier, copied into the context.
replay_windowNumber of nonces/message ids to remember for replay detection; must be non-zero and small enough that window * 28 does not overflow size_t.
Returns
New context, or NULL on invalid arguments or allocation failure.

Definition at line 237 of file seq_auth.c.

References cap, cwist_alloc(), cwist_alloc_array(), cwist_free(), cwist_seq_auth_context_destroy(), CWIST_SEQ_AUTH_MESSAGE_ID_SIZE, and CWIST_SEQ_AUTH_NONCE_SIZE.

◆ cwist_seq_auth_context_destroy()

void cwist_seq_auth_context_destroy ( cwist_seq_auth_context_t *  ctx)

Destroy an authenticated-sequencing context.

Wipes the key and session id, destroys the mutex, and frees the replay caches and the context itself. Safe to call with NULL.

Parameters
ctxContext to release, or NULL.

Definition at line 268 of file seq_auth.c.

References cap, cwist_free(), and SEQ_AUTH_CLEANSE.

Referenced by cwist_seq_auth_context_create().

◆ cwist_seq_auth_mark_complete()

void cwist_seq_auth_mark_complete ( cwist_seq_auth_context_t *  ctx,
const uint8_t  message_id[CWIST_SEQ_AUTH_MESSAGE_ID_SIZE] 
)

Record a message id as fully received.

Adds the message id to the completed-message replay cache so any later chunk claiming that id is rejected by cwist_seq_auth_unwrap(). Duplicate ids are ignored. Safe to call with NULL; otherwise takes the context lock.

Parameters
ctxAuthenticated-sequencing context, or NULL.
message_id16-byte message id to record.

Definition at line 418 of file seq_auth.c.

References cap, and CWIST_SEQ_AUTH_MESSAGE_ID_SIZE.

◆ cwist_seq_auth_random()

bool cwist_seq_auth_random ( uint8_t *  out,
size_t  len 
)

Fill a buffer with cryptographically secure random bytes.

Source is crypto.getRandomValues on Emscripten, getentropy under WASI, the firmware TRNG (cwist_port_entropy) on bare metal, and OpenSSL RAND_bytes elsewhere.

Parameters
outOutput buffer.
lenNumber of bytes to write; must be non-zero and at most INT_MAX.
Return values
trueThe buffer was filled successfully.
falseInvalid arguments or the random source failed.

Definition at line 290 of file seq_auth.c.

References cap, cwist_port_entropy(), and RAND_bytes.

◆ cwist_seq_auth_unwrap()

bool cwist_seq_auth_unwrap ( cwist_seq_auth_context_t *  ctx,
const uint8_t *  data,
size_t  len,
cwist_seq_auth_metadata_t *  metadata,
cwist_seq_chunk_t *  chunk 
)

Verify, authenticate, and split an incoming authenticated chunk.

Validates the chunk layout, recomputes the HMAC-SHA256 tag (compared in constant time), and rejects replays by checking the nonce and message id against the context's replay caches under the context lock; a fresh nonce is recorded in the cache on success. Chunks of fully completed messages can be rejected by recording their ids with cwist_seq_auth_mark_complete().

Parameters
ctxAuthenticated-sequencing context.
dataWire-format authenticated chunk.
lenLength of data in bytes.
metadataReceives the verified message id and nonce.
chunkReceives the parsed chunk header and a payload pointer into data; untouched on failure.
Return values
trueThe tag is valid and the chunk is not a replay.
falseInvalid arguments, malformed chunk, bad tag, or replayed nonce/message id.

Definition at line 374 of file seq_auth.c.

References cap, CWIST_SEQ_AUTH_HEADER_SIZE, CWIST_SEQ_AUTH_MESSAGE_ID_SIZE, CWIST_SEQ_AUTH_NONCE_SIZE, CWIST_SEQ_AUTH_TAG_SIZE, CWIST_SEQ_HEADER_SIZE, SEQ_AUTH_MEMCMP, and SEQ_AUTH_TAG_CAP.

◆ cwist_seq_auth_wrap()

bool cwist_seq_auth_wrap ( const cwist_seq_auth_context_t *  ctx,
const uint8_t  message_id[CWIST_SEQ_AUTH_MESSAGE_ID_SIZE],
const uint8_t  nonce[CWIST_SEQ_AUTH_NONCE_SIZE],
const uint8_t *  chunk,
size_t  chunk_len,
uint8_t **  out,
size_t *  out_len 
)

Attach message id, nonce, and authentication tag to a chunk.

Builds the wire-format authenticated chunk (sequence header || message id || nonce || payload || tag) without modifying the caller's chunk. The tag is an HMAC-SHA256 truncated to CWIST_SEQ_AUTH_TAG_SIZE over the session id and the header/payload contents. The output buffer is owned by the caller and must be freed with cwist_free().

Parameters
ctxAuthenticated-sequencing context.
message_id16-byte message identifier to embed.
nonce12-byte nonce to embed.
chunkBuffer holding one sequence chunk (header + payload).
chunk_lenLength of chunk in bytes.
outReceives a newly allocated wire-format chunk on success.
out_lenReceives the wire chunk length on success.
Return values
trueThe chunk was authenticated and wrapped.
falseInvalid arguments, malformed chunk, allocation failure, or tag computation failure; no output is produced.

Definition at line 323 of file seq_auth.c.

References cap, cwist_alloc(), cwist_free(), CWIST_SEQ_AUTH_HEADER_SIZE, CWIST_SEQ_AUTH_MESSAGE_ID_SIZE, CWIST_SEQ_AUTH_NONCE_SIZE, CWIST_SEQ_AUTH_TAG_SIZE, cwist_seq_chunk_parse(), CWIST_SEQ_HEADER_SIZE, and SEQ_AUTH_TAG_CAP.