Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ jobs:
- name: bring_your_own_fips202
run: |
CFLAGS="-O0" make run -C examples/bring_your_own_fips202
- name: bring_your_own_fips202_static
run: |
CFLAGS="-O0" make run -C examples/bring_your_own_fips202_static
- name: custom_backend
run: |
CFLAGS="-O0" make run -C examples/custom_backend
Expand Down
2 changes: 2 additions & 0 deletions BIBLIOGRAPHY.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ source code and documentation.
- [README.md](README.md)
- [examples/bring_your_own_fips202/README.md](examples/bring_your_own_fips202/README.md)
- [examples/bring_your_own_fips202/custom_fips202/README.md](examples/bring_your_own_fips202/custom_fips202/README.md)
- [examples/bring_your_own_fips202_static/README.md](examples/bring_your_own_fips202_static/README.md)
- [examples/bring_your_own_fips202_static/custom_fips202/README.md](examples/bring_your_own_fips202_static/custom_fips202/README.md)
- [examples/custom_backend/README.md](examples/custom_backend/README.md)

### `tweetfips`
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ clean:
-$(RM) -rf *.gcno *.gcda *.lcov *.o *.so
-$(RM) -rf $(BUILD_DIR)
-make clean -C examples/bring_your_own_fips202 >/dev/null
-make clean -C examples/bring_your_own_fips202_static >/dev/null
-make clean -C examples/custom_backend >/dev/null
-make clean -C examples/basic >/dev/null
-make clean -C examples/basic_deterministic >/dev/null
Expand Down
6 changes: 6 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ security level, in such a way that level-independent code is shared, and leverag
See [bring_your_own_fips202](bring_your_own_fips202) for an example of how to use mlkem-native with your own FIPS-202
implementation.

## Custom FIPS202 implementation (static state variant)

See [bring_your_own_fips202_static](bring_your_own_fips202_static) for an example of how to use mlkem-native with a
custom FIPS-202 implementation using a static state. This variant demonstrates the serial-only FIPS-202 configuration
(`MLK_CONFIG_SERIAL_FIPS202_ONLY`).

## Custom config + custom FIPS-202 backend

See [custom_backend](custom_backend) for an example of how to use mlkem-native with a custom configuration file and a
Expand Down
115 changes: 115 additions & 0 deletions examples/bring_your_own_fips202_static/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# (SPDX-License-Identifier: CC-BY-4.0)

.PHONY: build run clean size
.DEFAULT_GOAL := all

# Append cross-prefix for cross compilation
# Remove or ignore for native builds
CC ?= gcc
SIZE ?= size
# When called from the root Makefile, CROSS_PREFIX has already been added here
ifeq (,$(findstring $(CROSS_PREFIX),$(CC)))
CC := $(CROSS_PREFIX)$(CC)
endif

ifeq (,$(findstring $(CROSS_PREFIX),$(SIZE)))
SIZE := $(CROSS_PREFIX)$(SIZE)
endif

# Part A:
#
# mlkem-native source and header files
MLK_SOURCE=$(wildcard \
mlkem_native/src/*.c \
mlkem_native/src/**/*.c \
mlkem_native/src/**/**/*.c \
mlkem_native/src/**/**/**/*.c)

INC=-Imlkem_native/src/ -Imlkem_native/

# Part B:
#
# Custom FIPS-202 implementation
#
# At present, this must be located in a directory named "fips202".
# This limitation will be lifted in the future.
FIPS202_SOURCE=custom_fips202/tiny_sha3/sha3.c

# Part C:
#
# Random number generator
#
# !!! WARNING !!!
#
# The randombytes() implementation used here is for TESTING ONLY.
# You MUST NOT use this implementation outside of testing.
#
# !!! WARNING !!!
RNG_SOURCE=$(wildcard test_only_rng/*.c)

# Part D:
#
# Your application source code
APP_SOURCE=$(wildcard *.c)

ALL_SOURCE=$(MLK_SOURCE) $(FIPS202_SOURCE) $(RNG_SOURCE) $(APP_SOURCE)

BUILD_DIR=build
BIN=test_binary

CFLAGS := \
-Wall \
-Wextra \
-Werror \
-Wmissing-prototypes \
-Wshadow \
-Wpointer-arith \
-Wredundant-decls \
-Wconversion \
-Wno-long-long \
-Wno-unknown-pragmas \
-Wno-unused-command-line-argument \
-fomit-frame-pointer \
-std=c99 \
-pedantic \
-MMD \
-O3 \
$(CFLAGS)
CFLAGS += -DMLK_CONFIG_FIPS202_CUSTOM_HEADER="\"../custom_fips202/fips202.h\""
CFLAGS += -DMLK_CONFIG_FIPS202X4_CUSTOM_HEADER="\"../custom_fips202/fips202x4.h\""
CFLAGS += -DMLK_CONFIG_NAMESPACE_PREFIX=mlkem
CFLAGS += -DMLK_CONFIG_SERIAL_FIPS202_ONLY

BINARY_NAME_FULL_512=$(BUILD_DIR)/$(BIN)512
BINARY_NAME_FULL_768=$(BUILD_DIR)/$(BIN)768
BINARY_NAME_FULL_1024=$(BUILD_DIR)/$(BIN)1024
BINARIES_FULL=$(BINARY_NAME_FULL_512) $(BINARY_NAME_FULL_768) $(BINARY_NAME_FULL_1024)

$(BINARY_NAME_FULL_512): CFLAGS += -DMLK_CONFIG_PARAMETER_SET=512
$(BINARY_NAME_FULL_768): CFLAGS += -DMLK_CONFIG_PARAMETER_SET=768
$(BINARY_NAME_FULL_1024): CFLAGS += -DMLK_CONFIG_PARAMETER_SET=1024

$(BINARIES_FULL): $(ALL_SOURCE)
echo "$@"
mkdir -p $(BUILD_DIR)
$(CC) $(CFLAGS) $(INC) $^ -o $@

all: build size

build: $(BINARIES_FULL)

run: $(BINARIES_FULL)
$(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_512)
$(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_768)
$(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_1024)

size: build
@echo "=== Size info for binaries $(BINARY_NAME_FULL_512) ==="
@$(SIZE) $(BINARY_NAME_FULL_512)
@echo "=== Size info for binaries $(BINARY_NAME_FULL_768) ==="
@$(SIZE) $(BINARY_NAME_FULL_768)
@echo "=== Size info for binaries $(BINARY_NAME_FULL_1024) ==="
@$(SIZE) $(BINARY_NAME_FULL_1024)

clean:
rm -rf $(BUILD_DIR)
28 changes: 28 additions & 0 deletions examples/bring_your_own_fips202_static/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[//]: # (SPDX-License-Identifier: CC-BY-4.0)

# Bring your own FIPS-202 (Static State Variant)

This directory contains a minimal example for how to use mlkem-native with external FIPS202
HW/SW-implementations that use a single global state (for example, some hardware accelerators).
Specifically, this example demonstrates the use of the serial-only FIPS-202 configuration
`MLK_CONFIG_SERIAL_FIPS202_ONLY`.

## Components

An application using mlkem-native with a custom FIPS-202 implementation needs the following:

1. Arithmetic part of the mlkem-native source tree: [`mlkem/src/`](../../mlkem/src)
2. A secure pseudo random number generator, implementing [`randombytes.h`](../../mlkem/src/randombytes.h).
2. A custom FIPS202 with `fips202.h` header compatible with [`mlkem/src/fips202/fips202.h`](../../mlkem/src/fips202/fips202.h).
The FIPS202x4 header `fips202x4.h` can is unused with `MLK_CONFIG_SERIAL_FIPS202_ONLY` and can be filled with stubs.
3. The application source code

**WARNING:** The `randombytes()` implementation used here is for TESTING ONLY. You MUST NOT use this implementation
outside of testing.

## Usage

Build this example with `make build`, run with `make run`.

<!--- bibliography --->
[^tiny_sha3]: Markku-Juhani O. Saarinen: tiny_sha3, [https://github.com/mjosaarinen/tiny_sha3](https://github.com/mjosaarinen/tiny_sha3)
12 changes: 12 additions & 0 deletions examples/bring_your_own_fips202_static/custom_fips202/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[//]: # (SPDX-License-Identifier: CC-BY-4.0)

# Custom FIPS-202 with Static State

This directory contains a copy of tiny_sha3 [^tiny_sha3], but wrapped so that is operates on a single global state only.

This illustrates and tests the configuration option `MLK_CONFIG_SERIAL_FIPS202_ONLY` which should be used
when interfacing with an external FIPS202 implementation -- for example, a hardware accelerator -- that has only
a single global state.

<!--- bibliography --->
[^tiny_sha3]: Markku-Juhani O. Saarinen: tiny_sha3, [https://github.com/mjosaarinen/tiny_sha3](https://github.com/mjosaarinen/tiny_sha3)
170 changes: 170 additions & 0 deletions examples/bring_your_own_fips202_static/custom_fips202/fips202.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/

/*
* This is a shim establishing the FIPS-202 API required by mlkem-native
* from the API exposed by tiny_sha3, using a static state.
*/

#ifndef FIPS202_H
#define FIPS202_H

#include <assert.h>

#include "common.h"
#include "tiny_sha3/sha3.h"
typedef enum
{
FIPS202_STATE_ABSORBING = 1,
FIPS202_STATE_SQUEEZING = 2,
FIPS202_STATE_RESET = 3
} fips202_state_t;

#define SHAKE128_RATE 168
#define SHAKE256_RATE 136
#define SHA3_256_RATE 136
#define SHA3_384_RATE 104
#define SHA3_512_RATE 72

/* Static state for serial FIPS202 */
static struct
{
fips202_state_t state;
sha3_ctx_t ctx;
} static_shake128_state = {FIPS202_STATE_RESET, {{{0}}, 0, 0, 0}};

/* Dummy context type - the actual state is static */
typedef struct
{
int dummy;
} mlk_shake128ctx;

static MLK_INLINE void mlk_shake128_init(mlk_shake128ctx *state)
{
(void)state;
assert(static_shake128_state.state == FIPS202_STATE_RESET);
shake128_init(&static_shake128_state.ctx);
static_shake128_state.state = FIPS202_STATE_ABSORBING;
}

#define mlk_shake128_absorb_once MLK_NAMESPACE(shake128_absorb_once)
/*************************************************
* Name: mlk_shake128_absorb_once
*
* Description: Absorb step of the SHAKE128 XOF.
*
* Arguments: - mlk_shake128ctx *state: pointer to zeroized output Keccak
* state
* - const uint8_t *input: pointer to input to be absorbed into
* state
* - size_t inlen: length of input in bytes
**************************************************/
static MLK_INLINE void mlk_shake128_absorb_once(mlk_shake128ctx *state,
const uint8_t *input,
size_t inlen)
{
(void)state;
assert(static_shake128_state.state == FIPS202_STATE_ABSORBING);
shake_update(&static_shake128_state.ctx, input, inlen);
shake_xof(&static_shake128_state.ctx);
static_shake128_state.state = FIPS202_STATE_SQUEEZING;
}

/* Squeeze output out of the sponge.
*
* Supports being called multiple times
*/
#define mlk_shake128_squeezeblocks MLK_NAMESPACE(shake128_squeezeblocks)
/*************************************************
* Name: mlk_shake128_squeezeblocks
*
* Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of
* SHAKE128_RATE bytes each. Modifies the state. Can be called
* multiple times to keep squeezing, i.e., is incremental.
*
* Arguments: - uint8_t *output: pointer to output blocks
* - size_t nblocks: number of blocks to be squeezed (written
* to output)
* - mlk_shake128ctx *state: pointer to in/output Keccak state
**************************************************/
static MLK_INLINE void mlk_shake128_squeezeblocks(uint8_t *output,
size_t nblocks,
mlk_shake128ctx *state)
{
(void)state;
assert(static_shake128_state.state == FIPS202_STATE_SQUEEZING);
shake_out(&static_shake128_state.ctx, output, nblocks * SHAKE128_RATE);
}

/* Free the state */
#define mlk_shake128_release MLK_NAMESPACE(shake128_release)
static MLK_INLINE void mlk_shake128_release(mlk_shake128ctx *state)
{
(void)state;
static_shake128_state.state = FIPS202_STATE_RESET;
}

/* One-stop SHAKE256 call. Aliasing between input and
* output is not permitted */
#define mlk_shake256 MLK_NAMESPACE(shake256)
/*************************************************
* Name: mlk_shake256
*
* Description: SHAKE256 XOF with non-incremental API
*
* Arguments: - uint8_t *output: pointer to output
* - size_t outlen: requested output length in bytes
* - const uint8_t *input: pointer to input
* - size_t inlen: length of input in bytes
**************************************************/
static MLK_INLINE void mlk_shake256(uint8_t *output, size_t outlen,
const uint8_t *input, size_t inlen)
{
sha3_ctx_t c;
shake256_init(&c);
shake_update(&c, input, inlen);
shake_xof(&c);
shake_out(&c, output, outlen);
}

/* One-stop SHA3_256 call. Aliasing between input and
* output is not permitted */
#define SHA3_256_HASHBYTES 32
#define mlk_sha3_256 MLK_NAMESPACE(sha3_256)
/*************************************************
* Name: mlk_sha3_256
*
* Description: SHA3-256 with non-incremental API
*
* Arguments: - uint8_t *output: pointer to output
* - const uint8_t *input: pointer to input
* - size_t inlen: length of input in bytes
**************************************************/
static MLK_INLINE void mlk_sha3_256(uint8_t *output, const uint8_t *input,
size_t inlen)
{
(void)sha3(input, inlen, output, SHA3_256_HASHBYTES);
}

/* One-stop SHA3_512 call. Aliasing between input and
* output is not permitted */
#define SHA3_512_HASHBYTES 64
#define mlk_sha3_512 MLK_NAMESPACE(sha3_512)
/*************************************************
* Name: mlk_sha3_512
*
* Description: SHA3-512 with non-incremental API
*
* Arguments: - uint8_t *output: pointer to output
* - const uint8_t *input: pointer to input
* - size_t inlen: length of input in bytes
**************************************************/
static MLK_INLINE void mlk_sha3_512(uint8_t *output, const uint8_t *input,
size_t inlen)
{
(void)sha3(input, inlen, output, SHA3_512_HASHBYTES);
}

#endif /* !FIPS202_H */
Loading