Skip to content

Commit 64ae351

Browse files
hanno-beckermkannwischer
authored andcommitted
Make allocation of large structures/buffers configurable
This commit introduces the configuration option MLD_CONFIG_CUSTOM_ALLOC_FREE which allows users to provide custom macros MLD_CUSTOM_ALLOC(v, T, N) MLD_CUSTOM_FREE(v, T, N) that should be used in place of the default stack-allocation to allocate/free large internal structures. Those macros are then wrapped into MLD_ALLOC/MLD_FREE and used in the source. Importantly, MLD_FREE adds zeroization ahead of calling MLD_CUSTOM_FREE, so the latter need not take care of this. The macros are put to use in sign.c, but not yet further down the call-stack. The option is documented as experimental and (hence) unstable so we have freedom to adjust this ahead of v2. A custom configuration is added which implements the macros based on C11's aligned_alloc. We enable the leak sanitizer in the tests for this configuration to catch any missing calls to MLD_FREE. Since allocation can fail, additional error paths are introduced to the functions using MLD_ALLOC. This uniformly follows the pattern of all pointers being initialized to NULL before allocation, and a cleanup section calling MLD_FREE on them before returning the result. To distinguish between out-of-memory failure and other kinds of functional failures, we introduce named error codes MLD_ERR_FAIL and MLD_ERR_OUT_OF_MEMORY. This will likely need further refinement, but this can only be done in v2. We don't yet introduce MLD_ERR_FAIL in lower level functions which signal success/failure through 0 or a (single) non-zero error code; instead, we explicitly map the non-zero failure case to MLD_ERR_FAIL at the top-level. At the occasion, however, we do add qualifiers MLD_MUST_CHECK_RETURN_VALUE to ensure we don't forget to check return values of those functions. Signed-off-by: Hanno Becker <beckphan@amazon.co.uk>
1 parent 21eca08 commit 64ae351

File tree

36 files changed

+2353
-336
lines changed

36 files changed

+2353
-336
lines changed

.github/actions/config-variations/action.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ inputs:
88
description: 'GitHub token'
99
required: true
1010
tests:
11-
description: 'List of tests to run (space-separated IDs) or "all" for all tests. Available IDs: pct-enabled, pct-enabled-broken, custom-zeroize, native-cap-ON, native-cap-OFF, native-cap-ID_AA64PFR1_EL1, native-cap-CPUID_AVX2, no-asm, serial-fips202, custom-randombytes, custom-memcpy, custom-memset, custom-stdlib'
11+
description: 'List of tests to run (space-separated IDs) or "all" for all tests. Available IDs: pct-enabled, pct-enabled-broken, custom-alloc-heap, custom-zeroize, native-cap-ON, native-cap-OFF, native-cap-ID_AA64PFR1_EL1, native-cap-CPUID_AVX2, no-asm, serial-fips202, custom-randombytes, custom-memcpy, custom-memset, custom-stdlib'
1212
required: false
1313
default: 'all'
1414
opt:
@@ -47,6 +47,20 @@ runs:
4747
else
4848
echo "PCT failed as expected"
4949
fi
50+
- name: "Custom allocation (heap based)"
51+
if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'custom-alloc-heap') }}
52+
uses: ./.github/actions/multi-functest
53+
with:
54+
gh_token: ${{ inputs.gh_token }}
55+
compile_mode: native
56+
cflags: "-std=c11 -D_GNU_SOURCE -Itest -DMLD_CONFIG_FILE=\\\\\\\"custom_heap_alloc_config.h\\\\\\\" -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
57+
ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
58+
func: true
59+
kat: true
60+
acvp: true
61+
opt: ${{ inputs.opt }}
62+
extra_env: 'ASAN_OPTIONS=detect_leaks=1'
63+
examples: false # Some examples use a custom config themselves
5064
- name: "Custom zeroization (explicit_bzero)"
5165
if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'custom-zeroize') }}
5266
uses: ./.github/actions/multi-functest

BIBLIOGRAPHY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ source code and documentation.
3939
- [mldsa/mldsa_native_config.h](mldsa/mldsa_native_config.h)
4040
- [mldsa/src/sign.c](mldsa/src/sign.c)
4141
- [test/break_pct_config.h](test/break_pct_config.h)
42+
- [test/custom_heap_alloc_config.h](test/custom_heap_alloc_config.h)
4243
- [test/custom_memcpy_config.h](test/custom_memcpy_config.h)
4344
- [test/custom_memset_config.h](test/custom_memset_config.h)
4445
- [test/custom_native_capability_config_0.h](test/custom_native_capability_config_0.h)

examples/basic_deterministic/mldsa_native/mldsa_native_config.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,51 @@
453453
}
454454
*/
455455

456+
/******************************************************************************
457+
* Name: MLD_CONFIG_CUSTOM_ALLOC_FREE [EXPERIMENTAL]
458+
*
459+
* Description: Set this option and define `MLD_CUSTOM_ALLOC` and
460+
* `MLD_CUSTOM_FREE` if you want to use custom allocation for
461+
* large local structures or buffers.
462+
*
463+
* By default, all buffers/structures are allocated on the stack.
464+
* If this option is set, most of them will be allocated via
465+
* MLD_CUSTOM_ALLOC.
466+
*
467+
* Parameters to MLD_CUSTOM_ALLOC:
468+
* - T* v: Target pointer to declare.
469+
* - T: Type of structure to be allocated
470+
* - N: Number of elements to be allocated.
471+
*
472+
* Parameters to MLD_CUSTOM_FREE:
473+
* - T* v: Target pointer to free. May be NULL.
474+
* - T: Type of structure to be freed.
475+
* - N: Number of elements to be freed.
476+
*
477+
* WARNING: This option is experimental!
478+
* Its scope, configuration and function/macro signatures may
479+
* change at any time. We expect a stable API for v2.
480+
*
481+
* NOTE: Even if this option is set, some allocations further down
482+
* the call stack will still be made from the stack. Those will
483+
* likely be added to the scope of this option in the future.
484+
*
485+
* NOTE: MLD_CUSTOM_ALLOC need not guarantee a successful
486+
* allocation nor include error handling. Upon failure, the
487+
* target pointer should simply be set to NULL. The calling
488+
* code will handle this case and invoke MLD_CUSTOM_FREE.
489+
*
490+
*****************************************************************************/
491+
/* #define MLD_CONFIG_CUSTOM_ALLOC_FREE
492+
#if !defined(__ASSEMBLER__)
493+
#include <stdlib.h>
494+
#define MLD_CUSTOM_ALLOC(v, T, N) \
495+
T* (v) = (T *)aligned_alloc(MLD_DEFAULT_ALIGN, \
496+
MLD_ALIGN_UP(sizeof(T) * (N)))
497+
#define MLD_CUSTOM_FREE(v, T, N) free(v)
498+
#endif
499+
*/
500+
456501
/******************************************************************************
457502
* Name: MLD_CONFIG_CUSTOM_MEMCPY
458503
*

examples/bring_your_own_fips202/mldsa_native/mldsa_native_config.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,51 @@
453453
}
454454
*/
455455

456+
/******************************************************************************
457+
* Name: MLD_CONFIG_CUSTOM_ALLOC_FREE [EXPERIMENTAL]
458+
*
459+
* Description: Set this option and define `MLD_CUSTOM_ALLOC` and
460+
* `MLD_CUSTOM_FREE` if you want to use custom allocation for
461+
* large local structures or buffers.
462+
*
463+
* By default, all buffers/structures are allocated on the stack.
464+
* If this option is set, most of them will be allocated via
465+
* MLD_CUSTOM_ALLOC.
466+
*
467+
* Parameters to MLD_CUSTOM_ALLOC:
468+
* - T* v: Target pointer to declare.
469+
* - T: Type of structure to be allocated
470+
* - N: Number of elements to be allocated.
471+
*
472+
* Parameters to MLD_CUSTOM_FREE:
473+
* - T* v: Target pointer to free. May be NULL.
474+
* - T: Type of structure to be freed.
475+
* - N: Number of elements to be freed.
476+
*
477+
* WARNING: This option is experimental!
478+
* Its scope, configuration and function/macro signatures may
479+
* change at any time. We expect a stable API for v2.
480+
*
481+
* NOTE: Even if this option is set, some allocations further down
482+
* the call stack will still be made from the stack. Those will
483+
* likely be added to the scope of this option in the future.
484+
*
485+
* NOTE: MLD_CUSTOM_ALLOC need not guarantee a successful
486+
* allocation nor include error handling. Upon failure, the
487+
* target pointer should simply be set to NULL. The calling
488+
* code will handle this case and invoke MLD_CUSTOM_FREE.
489+
*
490+
*****************************************************************************/
491+
/* #define MLD_CONFIG_CUSTOM_ALLOC_FREE
492+
#if !defined(__ASSEMBLER__)
493+
#include <stdlib.h>
494+
#define MLD_CUSTOM_ALLOC(v, T, N) \
495+
T* (v) = (T *)aligned_alloc(MLD_DEFAULT_ALIGN, \
496+
MLD_ALIGN_UP(sizeof(T) * (N)))
497+
#define MLD_CUSTOM_FREE(v, T, N) free(v)
498+
#endif
499+
*/
500+
456501
/******************************************************************************
457502
* Name: MLD_CONFIG_CUSTOM_MEMCPY
458503
*

examples/bring_your_own_fips202_static/mldsa_native/mldsa_native_config.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,51 @@
454454
}
455455
*/
456456

457+
/******************************************************************************
458+
* Name: MLD_CONFIG_CUSTOM_ALLOC_FREE [EXPERIMENTAL]
459+
*
460+
* Description: Set this option and define `MLD_CUSTOM_ALLOC` and
461+
* `MLD_CUSTOM_FREE` if you want to use custom allocation for
462+
* large local structures or buffers.
463+
*
464+
* By default, all buffers/structures are allocated on the stack.
465+
* If this option is set, most of them will be allocated via
466+
* MLD_CUSTOM_ALLOC.
467+
*
468+
* Parameters to MLD_CUSTOM_ALLOC:
469+
* - T* v: Target pointer to declare.
470+
* - T: Type of structure to be allocated
471+
* - N: Number of elements to be allocated.
472+
*
473+
* Parameters to MLD_CUSTOM_FREE:
474+
* - T* v: Target pointer to free. May be NULL.
475+
* - T: Type of structure to be freed.
476+
* - N: Number of elements to be freed.
477+
*
478+
* WARNING: This option is experimental!
479+
* Its scope, configuration and function/macro signatures may
480+
* change at any time. We expect a stable API for v2.
481+
*
482+
* NOTE: Even if this option is set, some allocations further down
483+
* the call stack will still be made from the stack. Those will
484+
* likely be added to the scope of this option in the future.
485+
*
486+
* NOTE: MLD_CUSTOM_ALLOC need not guarantee a successful
487+
* allocation nor include error handling. Upon failure, the
488+
* target pointer should simply be set to NULL. The calling
489+
* code will handle this case and invoke MLD_CUSTOM_FREE.
490+
*
491+
*****************************************************************************/
492+
/* #define MLD_CONFIG_CUSTOM_ALLOC_FREE
493+
#if !defined(__ASSEMBLER__)
494+
#include <stdlib.h>
495+
#define MLD_CUSTOM_ALLOC(v, T, N) \
496+
T* (v) = (T *)aligned_alloc(MLD_DEFAULT_ALIGN, \
497+
MLD_ALIGN_UP(sizeof(T) * (N)))
498+
#define MLD_CUSTOM_FREE(v, T, N) free(v)
499+
#endif
500+
*/
501+
457502
/******************************************************************************
458503
* Name: MLD_CONFIG_CUSTOM_MEMCPY
459504
*

examples/custom_backend/mldsa_native/mldsa_native_config.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,51 @@
449449
}
450450
*/
451451

452+
/******************************************************************************
453+
* Name: MLD_CONFIG_CUSTOM_ALLOC_FREE [EXPERIMENTAL]
454+
*
455+
* Description: Set this option and define `MLD_CUSTOM_ALLOC` and
456+
* `MLD_CUSTOM_FREE` if you want to use custom allocation for
457+
* large local structures or buffers.
458+
*
459+
* By default, all buffers/structures are allocated on the stack.
460+
* If this option is set, most of them will be allocated via
461+
* MLD_CUSTOM_ALLOC.
462+
*
463+
* Parameters to MLD_CUSTOM_ALLOC:
464+
* - T* v: Target pointer to declare.
465+
* - T: Type of structure to be allocated
466+
* - N: Number of elements to be allocated.
467+
*
468+
* Parameters to MLD_CUSTOM_FREE:
469+
* - T* v: Target pointer to free. May be NULL.
470+
* - T: Type of structure to be freed.
471+
* - N: Number of elements to be freed.
472+
*
473+
* WARNING: This option is experimental!
474+
* Its scope, configuration and function/macro signatures may
475+
* change at any time. We expect a stable API for v2.
476+
*
477+
* NOTE: Even if this option is set, some allocations further down
478+
* the call stack will still be made from the stack. Those will
479+
* likely be added to the scope of this option in the future.
480+
*
481+
* NOTE: MLD_CUSTOM_ALLOC need not guarantee a successful
482+
* allocation nor include error handling. Upon failure, the
483+
* target pointer should simply be set to NULL. The calling
484+
* code will handle this case and invoke MLD_CUSTOM_FREE.
485+
*
486+
*****************************************************************************/
487+
/* #define MLD_CONFIG_CUSTOM_ALLOC_FREE
488+
#if !defined(__ASSEMBLER__)
489+
#include <stdlib.h>
490+
#define MLD_CUSTOM_ALLOC(v, T, N) \
491+
T* (v) = (T *)aligned_alloc(MLD_DEFAULT_ALIGN, \
492+
MLD_ALIGN_UP(sizeof(T) * (N)))
493+
#define MLD_CUSTOM_FREE(v, T, N) free(v)
494+
#endif
495+
*/
496+
452497
/******************************************************************************
453498
* Name: MLD_CONFIG_CUSTOM_MEMCPY
454499
*

examples/monolithic_build/mldsa_native/mldsa_native_config.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,51 @@
452452
}
453453
*/
454454

455+
/******************************************************************************
456+
* Name: MLD_CONFIG_CUSTOM_ALLOC_FREE [EXPERIMENTAL]
457+
*
458+
* Description: Set this option and define `MLD_CUSTOM_ALLOC` and
459+
* `MLD_CUSTOM_FREE` if you want to use custom allocation for
460+
* large local structures or buffers.
461+
*
462+
* By default, all buffers/structures are allocated on the stack.
463+
* If this option is set, most of them will be allocated via
464+
* MLD_CUSTOM_ALLOC.
465+
*
466+
* Parameters to MLD_CUSTOM_ALLOC:
467+
* - T* v: Target pointer to declare.
468+
* - T: Type of structure to be allocated
469+
* - N: Number of elements to be allocated.
470+
*
471+
* Parameters to MLD_CUSTOM_FREE:
472+
* - T* v: Target pointer to free. May be NULL.
473+
* - T: Type of structure to be freed.
474+
* - N: Number of elements to be freed.
475+
*
476+
* WARNING: This option is experimental!
477+
* Its scope, configuration and function/macro signatures may
478+
* change at any time. We expect a stable API for v2.
479+
*
480+
* NOTE: Even if this option is set, some allocations further down
481+
* the call stack will still be made from the stack. Those will
482+
* likely be added to the scope of this option in the future.
483+
*
484+
* NOTE: MLD_CUSTOM_ALLOC need not guarantee a successful
485+
* allocation nor include error handling. Upon failure, the
486+
* target pointer should simply be set to NULL. The calling
487+
* code will handle this case and invoke MLD_CUSTOM_FREE.
488+
*
489+
*****************************************************************************/
490+
/* #define MLD_CONFIG_CUSTOM_ALLOC_FREE
491+
#if !defined(__ASSEMBLER__)
492+
#include <stdlib.h>
493+
#define MLD_CUSTOM_ALLOC(v, T, N) \
494+
T* (v) = (T *)aligned_alloc(MLD_DEFAULT_ALIGN, \
495+
MLD_ALIGN_UP(sizeof(T) * (N)))
496+
#define MLD_CUSTOM_FREE(v, T, N) free(v)
497+
#endif
498+
*/
499+
455500
/******************************************************************************
456501
* Name: MLD_CONFIG_CUSTOM_MEMCPY
457502
*

examples/monolithic_build_multilevel/mldsa_native/mldsa_native_config.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,51 @@
453453
}
454454
*/
455455

456+
/******************************************************************************
457+
* Name: MLD_CONFIG_CUSTOM_ALLOC_FREE [EXPERIMENTAL]
458+
*
459+
* Description: Set this option and define `MLD_CUSTOM_ALLOC` and
460+
* `MLD_CUSTOM_FREE` if you want to use custom allocation for
461+
* large local structures or buffers.
462+
*
463+
* By default, all buffers/structures are allocated on the stack.
464+
* If this option is set, most of them will be allocated via
465+
* MLD_CUSTOM_ALLOC.
466+
*
467+
* Parameters to MLD_CUSTOM_ALLOC:
468+
* - T* v: Target pointer to declare.
469+
* - T: Type of structure to be allocated
470+
* - N: Number of elements to be allocated.
471+
*
472+
* Parameters to MLD_CUSTOM_FREE:
473+
* - T* v: Target pointer to free. May be NULL.
474+
* - T: Type of structure to be freed.
475+
* - N: Number of elements to be freed.
476+
*
477+
* WARNING: This option is experimental!
478+
* Its scope, configuration and function/macro signatures may
479+
* change at any time. We expect a stable API for v2.
480+
*
481+
* NOTE: Even if this option is set, some allocations further down
482+
* the call stack will still be made from the stack. Those will
483+
* likely be added to the scope of this option in the future.
484+
*
485+
* NOTE: MLD_CUSTOM_ALLOC need not guarantee a successful
486+
* allocation nor include error handling. Upon failure, the
487+
* target pointer should simply be set to NULL. The calling
488+
* code will handle this case and invoke MLD_CUSTOM_FREE.
489+
*
490+
*****************************************************************************/
491+
/* #define MLD_CONFIG_CUSTOM_ALLOC_FREE
492+
#if !defined(__ASSEMBLER__)
493+
#include <stdlib.h>
494+
#define MLD_CUSTOM_ALLOC(v, T, N) \
495+
T* (v) = (T *)aligned_alloc(MLD_DEFAULT_ALIGN, \
496+
MLD_ALIGN_UP(sizeof(T) * (N)))
497+
#define MLD_CUSTOM_FREE(v, T, N) free(v)
498+
#endif
499+
*/
500+
456501
/******************************************************************************
457502
* Name: MLD_CONFIG_CUSTOM_MEMCPY
458503
*

0 commit comments

Comments
 (0)