diff --git a/.github/workflows/freestanding-build.yml b/.github/workflows/freestanding-build.yml new file mode 100644 index 00000000..ab940b70 --- /dev/null +++ b/.github/workflows/freestanding-build.yml @@ -0,0 +1,63 @@ +name: Freestanding Build (WOLFTPM_NO_STD_HEADERS) + +# Builds the standalone (WOLFTPM2_NO_WOLFCRYPT) library with no hosted C library +# (-nostdinc) to prove WOLFTPM_NO_STD_HEADERS keeps the standard headers out. +# The fixed-width types and mem/str prototypes are supplied via user_settings.h, +# exactly as a bare-metal integrator would. -nostdinc is applied only to the +# build (make CFLAGS), not to configure, whose feature probes need libc. + +on: + push: + branches: [ 'master', 'main', 'release/**' ] + pull_request: + branches: [ '*' ] + types: [opened, synchronize, reopened, ready_for_review] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + freestanding: + if: github.event_name != 'pull_request' || github.event.pull_request.draft == false + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Write freestanding user_settings.h (types + mem/str, no libc) + run: | + mkdir -p freestanding + cat > freestanding/user_settings.h <<'EOF' + #ifndef FREESTANDING_USER_SETTINGS_H + #define FREESTANDING_USER_SETTINGS_H + /* Standalone bare-metal-style config: supply the fixed-width integer + * types and mem/str prototypes the library needs, so the standard + * headers stay guarded out by WOLFTPM_NO_STD_HEADERS. */ + #define WOLFTPM2_NO_HEAP + typedef __UINT8_TYPE__ uint8_t; typedef __UINT16_TYPE__ uint16_t; + typedef __UINT32_TYPE__ uint32_t; typedef __UINT64_TYPE__ uint64_t; + typedef __INT8_TYPE__ int8_t; typedef __INT16_TYPE__ int16_t; + typedef __INT32_TYPE__ int32_t; typedef __INT64_TYPE__ int64_t; + typedef __SIZE_TYPE__ size_t; typedef __UINTPTR_TYPE__ uintptr_t; + void *memcpy(void*, const void*, size_t); + void *memset(void*, int, size_t); + int memcmp(const void*, const void*, size_t); + size_t strlen(const char*); + #ifndef NULL + #define NULL ((void*)0) + #endif + #define XTPM_WAIT() + #define XSLEEP_MS(ms) + #endif + EOF + + - name: Configure standalone (no wolfCrypt, SPI HAL, no autodetect/fwtpm/example-HAL) + run: | + ./autogen.sh + ./configure --disable-wolfcrypt --enable-spi \ + --disable-autodetect --disable-fwtpm --disable-hal + + - name: Build library with no standard library (-nostdinc) + run: | + make src/libwolftpm.la \ + CFLAGS="-nostdinc -Ifreestanding -DWOLFTPM_USER_SETTINGS -DWOLFTPM_NO_STD_HEADERS" diff --git a/src/tpm2_util.c b/src/tpm2_util.c index 2b9de825..88560eb2 100644 --- a/src/tpm2_util.c +++ b/src/tpm2_util.c @@ -30,7 +30,9 @@ #include #include +#ifndef WOLFTPM_NO_STD_HEADERS #include +#endif #ifndef WOLFTPM2_NO_WOLFCRYPT #include diff --git a/wolftpm/tpm2_types.h b/wolftpm/tpm2_types.h index d1893447..1e225fe2 100644 --- a/wolftpm/tpm2_types.h +++ b/wolftpm/tpm2_types.h @@ -22,7 +22,12 @@ #ifndef __TPM2_TYPES_H__ #define __TPM2_TYPES_H__ +/* Freestanding targets with no hosted C library define WOLFTPM_NO_STD_HEADERS + * and provide the fixed-width integer types (and the mem/str functions used via + * the X* wrappers) through user_settings.h instead of the standard headers. */ +#ifndef WOLFTPM_NO_STD_HEADERS #include +#endif #ifdef WOLFTPM_USER_SETTINGS #include "user_settings.h" @@ -213,7 +218,7 @@ typedef int64_t INT64; #include /* for wolfSSL_ERR_reason_error_string */ #endif - #ifdef DEBUG_WOLFTPM + #if defined(DEBUG_WOLFTPM) && !defined(WOLFTPM_NO_STD_HEADERS) #include #endif @@ -249,9 +254,11 @@ typedef int64_t INT64; #endif #else + #ifndef WOLFTPM_NO_STD_HEADERS #include #include #include + #endif typedef uint8_t byte; typedef uint16_t word16; @@ -369,7 +376,9 @@ typedef int64_t INT64; #endif #ifndef WOLFTPM_CUSTOM_TYPES + #ifndef WOLFTPM_NO_STD_HEADERS #include + #endif #define XSTRTOUL(s,e,b) strtoul((s),(e),(b)) #define XATOI(s) atoi((s)) @@ -577,13 +586,14 @@ typedef int64_t INT64; * keep the raw TPM response code; opt in at runtime with TPM2_SetCommandRetries * or at build time with -DWOLFTPM_MAX_RETRIES=N. Define WOLFTPM_NO_RETRY to * compile the handling out entirely. */ -#ifdef WOLFTPM_NO_RETRY - #undef WOLFTPM_MAX_RETRIES - #define WOLFTPM_MAX_RETRIES 0 -#endif #ifndef WOLFTPM_MAX_RETRIES #define WOLFTPM_MAX_RETRIES 0 #endif +/* WOLFTPM_MAX_RETRIES is always defined by here, so the check below stays + * -Wundef-clean even when WOLFTPM_NO_RETRY is set without WOLFTPM_MAX_RETRIES. */ +#if defined(WOLFTPM_NO_RETRY) && (WOLFTPM_MAX_RETRIES > 0) + #error "WOLFTPM_NO_RETRY conflicts with WOLFTPM_MAX_RETRIES > 0" +#endif #ifndef MAX_SYM_BLOCK_SIZE #define MAX_SYM_BLOCK_SIZE 20 @@ -1064,7 +1074,9 @@ typedef int64_t INT64; #ifdef INTEL_INTRINSICS /* for non visual studio probably need no long version, 32 bit only * i.e., _rotl and _rotr */ + #ifndef WOLFTPM_NO_STD_HEADERS #include /* get intrinsic definitions */ + #endif #pragma intrinsic(_lrotl, _lrotr) static inline word32 rotlFixed(word32 x, word32 y) { return y ? _lrotl(x, y) : x;