From 7de3e9eeb459ee0946c294214fe206efe034d4b1 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Mon, 14 Sep 2026 12:47:19 -0700 Subject: [PATCH 1/8] Default to RFC 9864 algorithm IDs and gate deprecated RFC 9053 IDs --- .github/workflows/build-test.yml | 9 + .github/workflows/cmdline-test.yml | 15 + .github/workflows/coverage.yml | 11 + .github/workflows/lean-build.yml | 5 + .github/workflows/minimal-build.yml | 8 + .github/workflows/misra-2012.yml | 2 + .github/workflows/misra-2023.yml | 2 + IDE/STM32Cube/wolfcose_test.c | 4 +- Makefile | 70 +- README.md | 31 +- docs/API-Reference.md | 6 +- docs/Algorithms.md | 31 +- docs/Getting-Started.md | 8 +- docs/Home.md | 3 +- docs/MISRA-Compliance.md | 2 +- docs/Macros.md | 22 +- docs/Message-Types.md | 4 +- docs/Project-Structure.md | 6 +- docs/STM32Cube.md | 2 +- docs/Testing.md | 15 +- examples/comprehensive/errors_all.c | 12 +- examples/comprehensive/sign_all.c | 448 ++--- examples/ext_sign_demo.c | 10 +- examples/lifecycle_demo.c | 32 +- examples/scenarios/firmware_update.c | 6 +- examples/scenarios/multi_party_approval.c | 24 +- examples/scenarios/sensor_attestation.c | 2 +- examples/sign1_demo.c | 34 +- examples/sign1_verify_lean.c | 22 +- include/wolfcose/settings.h | 19 +- include/wolfcose/wolfcose.h | 23 +- scripts/cmdline-test.sh | 38 +- src/wolfcose_alg.c | 151 +- src/wolfcose_countersign.c | 52 +- src/wolfcose_internal.h | 33 + src/wolfcose_sign.c | 62 +- src/wolfcose_sign1.c | 102 +- tests/test_cose.c | 1991 +++++++++++++++++---- tests/test_cose_examples.c | 8 +- tests/test_interop.c | 48 +- tests/test_psa_attestation.c | 13 +- tools/wolfcose_tool.c | 125 +- 42 files changed, 2590 insertions(+), 921 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 321f24a4..46e308c7 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -161,6 +161,15 @@ jobs: make ext-sign-test CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" + - name: Run deprecated RFC 9053 alg IDs test + run: | + export WOLFSSL_DIR=$HOME/wolfssl-install + export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib + export DYLD_LIBRARY_PATH=$WOLFSSL_DIR/lib + make deprecated-algs-test CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ + LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" + + - name: Run delegated signing forced-failure test run: | export WOLFSSL_DIR=$HOME/wolfssl-install diff --git a/.github/workflows/cmdline-test.yml b/.github/workflows/cmdline-test.yml index a82fbcbc..b124d3e0 100644 --- a/.github/workflows/cmdline-test.yml +++ b/.github/workflows/cmdline-test.yml @@ -79,3 +79,18 @@ jobs: export WOLFSSL_DIR=$HOME/wolfssl-install export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib ./scripts/cmdline-test.sh ./tools/wolfcose_tool + + - name: Build tool with deprecated RFC 9053 alg IDs + run: | + export WOLFSSL_DIR=$HOME/wolfssl-install + make tool CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -DWOLFCOSE_ENABLE_DEPRECATED_ALGS -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ + LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" + + - name: Run command-line tool test with deprecated alg names + env: + EXPECT_PQC: ${{ matrix.pqc }} + SIGN_ALGS: "ES256 EdDSA Ed448 ESP256 Ed25519" + run: | + export WOLFSSL_DIR=$HOME/wolfssl-install + export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib + ./scripts/cmdline-test.sh ./tools/wolfcose_tool diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 0ac06817..414ed05e 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -73,3 +73,14 @@ jobs: - name: Check coverage thresholds run: sh scripts/check_coverage.sh wolfcose_eat_psa.c + + - name: Run coverage with deprecated RFC 9053 alg IDs enabled + run: | + export WOLFSSL_DIR=$HOME/wolfssl-install + export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib + make coverage-force-failure CC=gcc \ + CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -DWOLFCOSE_ENABLE_DEPRECATED_ALGS -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ + LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" + + - name: Check coverage thresholds (deprecated alg IDs) + run: sh scripts/check_coverage.sh diff --git a/.github/workflows/lean-build.yml b/.github/workflows/lean-build.yml index 107601ee..0b8c5bef 100644 --- a/.github/workflows/lean-build.yml +++ b/.github/workflows/lean-build.yml @@ -177,6 +177,11 @@ jobs: -DWOLFCOSE_NO_MAC -DWOLFCOSE_NO_RECIPIENTS build_cfg "WOLFCOSE_LEAN_MLDSA (sign+verify)" -DWOLFCOSE_LEAN_MLDSA build_cfg "WOLFCOSE_LEAN_VERIFY_MLDSA (verify-only)" -DWOLFCOSE_LEAN_VERIFY_MLDSA + build_cfg "deprecated RFC 9053 alg IDs" -DWOLFCOSE_ENABLE_DEPRECATED_ALGS + build_cfg "WOLFCOSE_LEAN + deprecated RFC 9053 alg IDs" -DWOLFCOSE_LEAN \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS + build_cfg "deprecated RFC 9053 alg IDs, Ed448 only" \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS -DWOLFCOSE_NO_EDDSA echo "All lean configurations compiled clean." - name: Check PSA/EAT opt-in feature matrix diff --git a/.github/workflows/minimal-build.yml b/.github/workflows/minimal-build.yml index 5b2d686f..dd4977c0 100644 --- a/.github/workflows/minimal-build.yml +++ b/.github/workflows/minimal-build.yml @@ -61,6 +61,14 @@ jobs: wolfssl_flags: "--enable-cryptonly --enable-ecc --enable-aesgcm --enable-keygen --enable-sha384 --enable-sha512 --enable-lowresource --enable-sp-math-all --disable-dh --disable-rsa --disable-aescbc --disable-sha --disable-md5 --disable-chacha --disable-poly1305 --disable-errorstrings" cache_key: wolfssl-ecc-only-v5 cose_flags: "-DWOLFCOSE_LEAN" + - name: Deprecated RFC 9053 alg IDs (ES256/ES384/ES512/EdDSA-Ed25519) + wolfssl_flags: "--enable-cryptonly --enable-ecc --enable-ed25519 --enable-curve25519 --enable-aesgcm --enable-keygen --enable-sha384 --enable-sha512 --enable-lowresource --enable-sp-math-all --disable-dh --disable-rsa --disable-aescbc --disable-sha --disable-md5 --disable-chacha --disable-poly1305 --disable-errorstrings" + cache_key: wolfssl-ecc-ed25519-v1 + cose_flags: "-DWOLFCOSE_ENABLE_DEPRECATED_ALGS" + - name: Lean core + deprecated RFC 9053 alg IDs + wolfssl_flags: "--enable-cryptonly --enable-ecc --enable-aesgcm --enable-keygen --enable-sha384 --enable-sha512 --enable-lowresource --enable-sp-math-all --disable-dh --disable-rsa --disable-aescbc --disable-sha --disable-md5 --disable-chacha --disable-poly1305 --disable-errorstrings" + cache_key: wolfssl-ecc-only-v5 + cose_flags: "-DWOLFCOSE_LEAN -DWOLFCOSE_ENABLE_DEPRECATED_ALGS" steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/misra-2012.yml b/.github/workflows/misra-2012.yml index e9304d6a..10677c83 100644 --- a/.github/workflows/misra-2012.yml +++ b/.github/workflows/misra-2012.yml @@ -97,6 +97,7 @@ jobs: -DWOLFCOSE_ENABLE_EAT_PSA_LEGACY \ -DWOLFCOSE_ENABLE_EAT_PSA_UEID_RESOLVER \ -DWOLFCOSE_ENABLE_EAT_PSA_COMPONENT_ITERATOR \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -I include -I "$HOME/wolfssl-install/include" \ -fsyntax-only src/wolfcose_eat_psa.c tests/misra_consumer.c @@ -141,6 +142,7 @@ jobs: -DWOLFCOSE_ENABLE_HPKE_0_DECRYPT \ -DWOLFCOSE_ENABLE_HPKE_0_KE_ENCRYPT \ -DWOLFCOSE_ENABLE_HPKE_0_KE_DECRYPT \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -I include -I src -I $HOME/wolfssl-install/include \ src/*.c \ tests/misra_consumer.c \ diff --git a/.github/workflows/misra-2023.yml b/.github/workflows/misra-2023.yml index 58155dcd..bad04778 100644 --- a/.github/workflows/misra-2023.yml +++ b/.github/workflows/misra-2023.yml @@ -112,6 +112,7 @@ jobs: -DWOLFCOSE_ENABLE_EAT_PSA_LEGACY \ -DWOLFCOSE_ENABLE_EAT_PSA_UEID_RESOLVER \ -DWOLFCOSE_ENABLE_EAT_PSA_COMPONENT_ITERATOR \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -I./include -isystem $WOLFSSL_DIR/include" for f in src/*.c; do gcc $MISRA_FLAGS -c "$f" -o /dev/null 2>&1 | tee -a compiler-warnings.txt || true @@ -247,6 +248,7 @@ jobs: -DWOLFCOSE_KEY_ENCODE -DWOLFCOSE_KEY_DECODE \ -DWOLFCOSE_FLOAT \ -DWOLFCOSE_ENABLE_EXT_SIGN \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ > clang-tidy-report.txt 2>&1 || true - name: clang-tidy summary diff --git a/IDE/STM32Cube/wolfcose_test.c b/IDE/STM32Cube/wolfcose_test.c index 8171f9d7..992cf155 100644 --- a/IDE/STM32Cube/wolfcose_test.c +++ b/IDE/STM32Cube/wolfcose_test.c @@ -62,7 +62,7 @@ int wolfCOSETest(void) ret = wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); } if (ret == 0) { - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, payloadLen, NULL, 0, NULL, 0, scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); } @@ -73,7 +73,7 @@ int wolfCOSETest(void) if (ret == 0) { if ((decPayload == NULL) || (decPayloadLen != payloadLen) || (memcmp(decPayload, payload, decPayloadLen) != 0) || - (hdr.alg != WOLFCOSE_ALG_ES256)) { + (hdr.alg != WOLFCOSE_ALG_ESP256)) { ret = -1; } } diff --git a/Makefile b/Makefile index bbdafd89..8a3a23b2 100644 --- a/Makefile +++ b/Makefile @@ -74,6 +74,10 @@ LIB_SO = libwolfcose.so # configuration hash at parse time and force a core-object rebuild only when # the effective compiler or wolfSSL configuration changes. BUILD_CONFIG = .wolfcose-build-config +# Interop objects are built with the deprecated RFC 9053 IDs enabled (the pinned +# peers still emit them); its value is part of the rebuild hash below. +INTEROP_COSE_CFLAGS = -DWOLFCOSE_ENABLE_DEPRECATED_ALGS + BUILD_CONFIG_VALUE := $(shell { \ printf '%s\n' 'CC=$(CC)'; \ printf '%s\n' 'CFLAGS=$(CFLAGS)'; \ @@ -84,6 +88,7 @@ BUILD_CONFIG_VALUE := $(shell { \ printf '%s\n' 'WOLFSSL_PREFIX=$(WOLFSSL_PREFIX)'; \ printf '%s\n' 'WOLFSSL_CFLAGS=$(WOLFSSL_CFLAGS)'; \ printf '%s\n' 'WOLFSSL_LIBS=$(WOLFSSL_LIBS)'; \ + printf '%s\n' 'INTEROP_COSE_CFLAGS=$(INTEROP_COSE_CFLAGS)'; \ } | cksum) BUILD_CONFIG_SAVED := $(shell test -f $(BUILD_CONFIG) && cat $(BUILD_CONFIG)) ifneq ($(strip $(BUILD_CONFIG_VALUE)),$(strip $(BUILD_CONFIG_SAVED))) @@ -155,7 +160,7 @@ SCEN_IOTFLEET = examples/scenarios/iot_fleet_config SCEN_SENSOR = examples/scenarios/sensor_attestation SCEN_BROADCAST = examples/scenarios/group_broadcast_mac -.PHONY: all shared test pkg-config-test ecdsa-policy-test rsapss-policy-test countersign-config-test zero-alloc-check zeroize-test ecc-import-policy-test ext-sign-test ext-sign-demo ext-sign-force-failure coverage eat-psa-test eat-psa-float-test eat-psa-min-buffers-test eat-psa-claim-limits-test eat-psa-profile-test eat-psa-config-check eat-psa-ext-sign-test eat-psa-ext-sign-force-failure eat-psa-coverage eat-psa-coverage-force-failure generic-reduced-alg-test tool tool-test cmdline-test demo demos hpke-demo lean-verify psa-eat-lean-verify psa-eat-demo mldsa-demo mldsa-verify lms-demo lms-verify comprehensive scenarios interop-tcose tcose-upstream interop-go-cose interop-python-cwt interop-rust-coset c99-check c99-check-lms c99-hpke-check experimental-check clean FORCE +.PHONY: all shared test pkg-config-test ecdsa-policy-test rsapss-policy-test countersign-config-test zero-alloc-check zeroize-test deprecated-algs-test ecc-import-policy-test ext-sign-test ext-sign-demo ext-sign-force-failure coverage eat-psa-test eat-psa-float-test eat-psa-min-buffers-test eat-psa-claim-limits-test eat-psa-profile-test eat-psa-config-check eat-psa-ext-sign-test eat-psa-ext-sign-force-failure eat-psa-coverage eat-psa-coverage-force-failure generic-reduced-alg-test tool tool-test cmdline-test demo demos hpke-demo lean-verify psa-eat-lean-verify psa-eat-demo mldsa-demo mldsa-verify lms-demo lms-verify comprehensive scenarios interop-tcose tcose-upstream interop-go-cose interop-python-cwt interop-rust-coset c99-check c99-check-lms c99-hpke-check experimental-check clean FORCE # --- Core library --- all: $(LIB_A) @@ -786,6 +791,12 @@ eat-psa-ext-sign-test: -o $(TEST_BIN) $(SRC) $(TEST_SRC) $(LDFLAGS) $(LDLIBS) ./$(TEST_BIN) +# --- Deprecated RFC 9053 alg IDs (ES256/ES384/ES512/EdDSA), opt-in --- +deprecated-algs-test: + $(CC) $(CFLAGS) -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ + -o $(TEST_BIN) $(SRC) $(TEST_SRC) $(LDFLAGS) $(LDLIBS) + ./$(TEST_BIN) + # --- Coverage --- coverage: clean @set -e; for f in $(SRC); do \ @@ -855,9 +866,9 @@ tool: $(LIB_A) # --- Round-trip proof: keygen -> sign -> verify in one command --- tool-test: tool - ./$(TOOL_BIN) keygen -a ES256 -o /tmp/wolfcose_test.key + ./$(TOOL_BIN) keygen -a ESP256 -o /tmp/wolfcose_test.key echo "hello wolfCOSE" > /tmp/wolfcose_test.dat - ./$(TOOL_BIN) sign -k /tmp/wolfcose_test.key -a ES256 \ + ./$(TOOL_BIN) sign -k /tmp/wolfcose_test.key -a ESP256 \ -i /tmp/wolfcose_test.dat -o /tmp/wolfcose_test.cose ./$(TOOL_BIN) verify -k /tmp/wolfcose_test.key \ -i /tmp/wolfcose_test.cose @@ -1006,15 +1017,29 @@ TCOSE_CRYPTO_INC ?= TCOSE_CRYPTO_LIB ?= -lcrypto INTEROP_DIR = tests/interop/t_cose INTEROP_BIN = $(INTEROP_DIR)/interop_tcose -INTEROP_CFLAGS = $(CFLAGS) -std=c99 -I$(TCOSE_DIR)/inc -I$(QCBOR_DIR)/inc - -interop-tcose: +# The pinned peers still emit the RFC 9053 ES*/EdDSA IDs that RFC 9864 +# deprecates, so wire interop links a wolfCOSE with those IDs enabled. +# INTEROP_COSE_CFLAGS is defined near BUILD_CONFIG_VALUE so its value is part +# of the rebuild hash. +INTEROP_LIB_DIR = tests/interop +INTEROP_LIB_A = $(INTEROP_LIB_DIR)/libwolfcose_interop.a +INTEROP_LIB_OBJ = $(patsubst src/%.c,$(INTEROP_LIB_DIR)/%.o,$(SRC)) +INTEROP_CFLAGS = $(CFLAGS) $(INTEROP_COSE_CFLAGS) -std=c99 -I$(TCOSE_DIR)/inc -I$(QCBOR_DIR)/inc + +$(INTEROP_LIB_DIR)/%.o: src/%.c src/wolfcose_internal.h \ + include/wolfcose/wolfcose.h $(BUILD_CONFIG_CHANGED) $(BUILD_CONFIG) + $(CC) $(CFLAGS) $(EAT_PSA_FULL_FLAGS) $(INTEROP_COSE_CFLAGS) -c $< -o $@ + +$(INTEROP_LIB_A): $(INTEROP_LIB_OBJ) + rm -f $(INTEROP_LIB_A) + $(AR) rcs $(INTEROP_LIB_A) $(INTEROP_LIB_OBJ) + +interop-tcose: $(INTEROP_LIB_A) $(CC) $(INTEROP_CFLAGS) $(EAT_PSA_FULL_FLAGS) -DT_COSE_USE_OPENSSL_CRYPTO -c $(INTEROP_DIR)/interop_tcose.c -o $(INTEROP_DIR)/interop_tcose.o $(CC) -std=c99 -Wall -Wextra -I$(TCOSE_DIR)/inc -I$(QCBOR_DIR)/inc $(TCOSE_CRYPTO_INC) \ -c $(INTEROP_DIR)/interop_key_ossl.c -o $(INTEROP_DIR)/interop_key.o - $(CC) $(CFLAGS) $(EAT_PSA_FULL_FLAGS) -o $(INTEROP_BIN) $(CORE_SRC) $(EAT_PSA_SRC) \ - $(INTEROP_DIR)/interop_tcose.o $(INTEROP_DIR)/interop_key.o \ - $(TCOSE_DIR)/libt_cose.a $(QCBOR_DIR)/libqcbor.a \ + $(CC) -o $(INTEROP_BIN) $(INTEROP_DIR)/interop_tcose.o $(INTEROP_DIR)/interop_key.o \ + $(INTEROP_LIB_A) $(TCOSE_DIR)/libt_cose.a $(QCBOR_DIR)/libqcbor.a \ $(TCOSE_CRYPTO_LIB) $(LDFLAGS) $(LDLIBS) -lm ./$(INTEROP_BIN) @@ -1035,9 +1060,9 @@ GO_COSE_ORACLE = $(GO_COSE_DIR)/go_cose_oracle GO_COSE_C_SRC = $(GO_COSE_DIR)/interop_go_cose.c GO_COSE_CASES ?= es256 es384 es512 ps256 ps384 ps512 ed25519 es256-aad es256-untagged -interop-go-cose: $(LIB_A) - $(CC) $(CFLAGS) -std=c99 -o $(GO_COSE_BIN) \ - $(GO_COSE_DIR)/interop_go_cose.c $(LIB_A) $(LDFLAGS) $(LDLIBS) +interop-go-cose: $(INTEROP_LIB_A) + $(CC) $(CFLAGS) $(INTEROP_COSE_CFLAGS) -std=c99 -o $(GO_COSE_BIN) \ + $(GO_COSE_DIR)/interop_go_cose.c $(INTEROP_LIB_A) $(LDFLAGS) $(LDLIBS) $(GO) -C $(GO_COSE_DIR) build -o go_cose_oracle main.go @for test_case in $(GO_COSE_CASES); do \ bash -o pipefail -c '$(GO_COSE_BIN) sign "$$1" | $(GO_COSE_ORACLE) verify "$$1"' \ @@ -1062,9 +1087,9 @@ PYTHON_CWT_C_SRC = $(PYTHON_CWT_DIR)/interop_python_cwt.c PYTHON_CWT_CASES ?= encrypt-direct encrypt-ecdh-es mac-direct encrypt-a128kw PYTHON_CWT_TO_WOLFCOSE_CASES ?= -interop-python-cwt: $(LIB_A) - $(CC) $(CFLAGS) -std=c99 -o $(PYTHON_CWT_BIN) \ - $(PYTHON_CWT_C_SRC) $(LIB_A) $(LDFLAGS) $(LDLIBS) +interop-python-cwt: $(INTEROP_LIB_A) + $(CC) $(CFLAGS) $(INTEROP_COSE_CFLAGS) -std=c99 -o $(PYTHON_CWT_BIN) \ + $(PYTHON_CWT_C_SRC) $(INTEROP_LIB_A) $(LDFLAGS) $(LDLIBS) @for test_case in $(PYTHON_CWT_CASES); do \ bash -o pipefail -c '$(PYTHON_CWT_BIN) sign "$$1" | $(PYTHON_CWT_ORACLE) verify "$$1"' \ bash "$$test_case" || exit $$?; \ @@ -1089,9 +1114,9 @@ RUST_COSET_C_BIN = $(RUST_COSET_DIR)/interop_rust_coset RUST_COSET_C_SRC = $(RUST_COSET_DIR)/interop_rust_coset.c RUST_COSET_CASES ?= es256 ed25519 es256-aad es256-untagged es256-detached -interop-rust-coset: $(LIB_A) - $(CC) $(CFLAGS) -std=c99 -o $(RUST_COSET_C_BIN) \ - $(RUST_COSET_C_SRC) $(LIB_A) $(LDFLAGS) $(LDLIBS) +interop-rust-coset: $(INTEROP_LIB_A) + $(CC) $(CFLAGS) $(INTEROP_COSE_CFLAGS) -std=c99 -o $(RUST_COSET_C_BIN) \ + $(RUST_COSET_C_SRC) $(INTEROP_LIB_A) $(LDFLAGS) $(LDLIBS) $(CARGO) build --manifest-path $(RUST_COSET_DIR)/Cargo.toml --locked @for test_case in $(RUST_COSET_CASES); do \ bash -o pipefail -c '$(RUST_COSET_C_BIN) sign "$$1" | $(RUST_COSET_BIN) verify "$$1"' \ @@ -1119,10 +1144,14 @@ C99_SRC = $(SRC) $(TEST_SRC) $(TOOL_SRC) $(DEMO_SRC) \ $(SCEN_SENSOR).c $(SCEN_BROADCAST).c $(EXTSIGN_DEMO).c \ $(GO_COSE_C_SRC) $(PYTHON_CWT_C_SRC) $(RUST_COSET_C_SRC) # Default features plus the opt-in paths (WOLFCOSE_FLOAT, delegated signing, -# and delegated signing without EdDSA), so the gate judges every +# delegated signing without EdDSA, and the deprecated RFC 9053 alg IDs alone +# and combined with delegated signing), so the gate judges every # conditionally-compiled translation unit, not just the default subset. C99_CONFIGS = "" "-DWOLFCOSE_FLOAT" "-DWOLFCOSE_ENABLE_EXT_SIGN" \ - "-DWOLFCOSE_ENABLE_EXT_SIGN -DWOLFCOSE_NO_EDDSA -DWOLFCOSE_NO_ED448" + "-DWOLFCOSE_ENABLE_EXT_SIGN -DWOLFCOSE_NO_EDDSA -DWOLFCOSE_NO_ED448" \ + "-DWOLFCOSE_ENABLE_DEPRECATED_ALGS" \ + "-DWOLFCOSE_ENABLE_DEPRECATED_ALGS -DWOLFCOSE_ENABLE_EXT_SIGN" \ + "-DWOLFCOSE_ENABLE_DEPRECATED_ALGS -DWOLFCOSE_NO_EDDSA" HPKE_C99_CONFIG = -DWOLFCOSE_EXPERIMENTAL -DWOLFCOSE_BUILD_TOOL \ -DWOLFCOSE_ENABLE_HPKE_0_ENCRYPT \ -DWOLFCOSE_ENABLE_HPKE_0_DECRYPT \ @@ -1270,6 +1299,7 @@ clean: $(COMP_SIGN) $(COMP_ENCRYPT) $(COMP_MAC) $(COMP_ERRORS) \ $(SCEN_FIRMWARE) $(SCEN_MULTIPARTY) $(SCEN_IOTFLEET) $(SCEN_SENSOR) $(SCEN_BROADCAST) \ $(INTEROP_DIR)/*.o $(INTEROP_DIR)/*.su $(INTEROP_BIN) \ + $(INTEROP_LIB_OBJ) $(INTEROP_LIB_DIR)/*.su $(INTEROP_LIB_A) \ $(GO_COSE_BIN) $(GO_COSE_ORACLE) \ $(PYTHON_CWT_BIN) \ $(RUST_COSET_C_BIN) $(RUST_COSET_BIN) \ diff --git a/README.md b/README.md index a89400c6..551aadd1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,14 @@ # wolfCOSE -wolfCOSE is a lightweight C library implementing [CBOR (RFC 8949)](https://www.rfc-editor.org/rfc/rfc8949), [COSE (RFC 9052/9053)](https://www.rfc-editor.org/rfc/rfc9052), [COSE countersignatures (RFC 9338)](https://www.rfc-editor.org/rfc/rfc9338), post-quantum [ML-DSA for COSE (RFC 9964)](https://www.rfc-editor.org/rfc/rfc9964), [HSS/LMS for COSE (RFC 8778)](https://www.rfc-editor.org/rfc/rfc8778), and the [PSA Attestation Token profile of EAT (RFC 9783)](https://www.rfc-editor.org/rfc/rfc9783) using [wolfSSL](https://www.wolfssl.com/) as the crypto backend. +wolfCOSE is a lightweight C library built on [wolfSSL](https://www.wolfssl.com/) as the crypto backend, implementing: + +- [CBOR (RFC 8949)](https://www.rfc-editor.org/rfc/rfc8949) +- [COSE (RFC 9052/9053)](https://www.rfc-editor.org/rfc/rfc9052) +- [Fully-specified signature algorithms (RFC 9864)](https://www.rfc-editor.org/rfc/rfc9864) +- [COSE countersignatures (RFC 9338)](https://www.rfc-editor.org/rfc/rfc9338) +- Post-quantum [ML-DSA for COSE (RFC 9964)](https://www.rfc-editor.org/rfc/rfc9964) +- Post-quantum [HSS/LMS for COSE (RFC 8778)](https://www.rfc-editor.org/rfc/rfc8778) +- The [PSA Attestation Token profile of EAT (RFC 9783)](https://www.rfc-editor.org/rfc/rfc9783) ## Main Features @@ -29,7 +37,22 @@ wolfCOSE is a lightweight C library implementing [CBOR (RFC 8949)](https://www.r ## Supported Algorithms -**Signing:** `ES256, ES384, ES512, EdDSA (Ed25519/Ed448), PS256/384/512, ML-DSA-44/65/87, HSS-LMS` +**Signing:** `ESP256, ESP384, ESP512, Ed25519, Ed448, PS256/384/512, ML-DSA-44/65/87, HSS-LMS` + +The polymorphic RFC 9053 IDs `ES256, ES384, ES512, EdDSA` are deprecated by RFC 9864 and are accepted only when built with `WOLFCOSE_ENABLE_DEPRECATED_ALGS` (see [Macros](https://github.com/wolfSSL/wolfCOSE/wiki/Macros)). + +**Migrating from the RFC 9053 IDs:** a default build now rejects the deprecated +IDs with `WOLFCOSE_E_COSE_BAD_ALG`, so messages and keys that use them stop +verifying. Move to the fully-specified replacement, or rebuild with +`WOLFCOSE_ENABLE_DEPRECATED_ALGS` to keep accepting the old IDs. + +| Deprecated (RFC 9053) | Replacement (RFC 9864) | +| --- | --- | +| `ES256` (-7) | `ESP256` (-9) | +| `ES384` (-35) | `ESP384` (-51) | +| `ES512` (-36) | `ESP512` (-52) | +| `EdDSA` (-8), Ed25519 key | `Ed25519` (-19) | +| `EdDSA` (-8), Ed448 key | `Ed448` (-53) | **Encryption:** `AES-GCM (128/192/256), ChaCha20-Poly1305, AES-CCM variants` @@ -68,7 +91,7 @@ Choose a build configuration based on the algorithms you need. ### Minimal Build (ECC + AES-GCM) -This gives you COSE Sign1 (ES256/384/512) and Encrypt0 (AES-GCM): +This gives you COSE Sign1 (ESP256/384/512) and Encrypt0 (AES-GCM): ```bash cd wolfssl @@ -79,7 +102,7 @@ make && sudo make install sudo ldconfig ``` -**Algorithms enabled:** ES256, ES384, ES512, AES-GCM-128/192/256 +**Algorithms enabled:** ESP256, ESP384, ESP512, AES-GCM-128/192/256 For a smaller wolfCrypt footprint, add `--enable-cryptonly` to drop the TLS stack and disable the algorithms a Sign1 + Encrypt0 build never uses: diff --git a/docs/API-Reference.md b/docs/API-Reference.md index 9f8a4e85..3bf051f2 100644 --- a/docs/API-Reference.md +++ b/docs/API-Reference.md @@ -621,7 +621,7 @@ Create a COSE_Sign1 message (single signer). | Name | Description | |------|-------------| | `key` | Signing key with private material, or an external signing callback when enabled | -| `alg` | Algorithm: `WOLFCOSE_ALG_ES256`, `WOLFCOSE_ALG_ES384`, `WOLFCOSE_ALG_ES512`, `WOLFCOSE_ALG_EDDSA`, etc. | +| `alg` | Algorithm: `WOLFCOSE_ALG_ESP256`, `WOLFCOSE_ALG_ESP384`, `WOLFCOSE_ALG_ESP512`, `WOLFCOSE_ALG_ED25519`, `WOLFCOSE_ALG_ED448`, etc. The RFC 9053 `WOLFCOSE_ALG_ES256`/`ES384`/`ES512`/`EDDSA` IDs need `WOLFCOSE_ENABLE_DEPRECATED_ALGS`. | | `kid`, `kidLen` | Optional key identifier | | `payload`, `payloadLen` | Payload to include in message (or NULL for detached) | | `detachedPayload`, `detachedPayloadLen` | Payload to sign but not include | @@ -684,7 +684,9 @@ signer callback. The data itself is not required because only `kidLen`, `payloadLen`, and `detachedLen` affect the framing. `key` may be `NULL` when the algorithm fixes the signature length. It is -required for RSA-PSS and for EdDSA when both Ed25519 and Ed448 are enabled. +required for RSA-PSS, for HSS-LMS, and for the deprecated `WOLFCOSE_ALG_EDDSA` +when both Ed25519 and Ed448 are enabled. `WOLFCOSE_ALG_ED25519` and +`WOLFCOSE_ALG_ED448` each pin a length, so they never need a key. **Returns:** `WOLFCOSE_SUCCESS` or error code diff --git a/docs/Algorithms.md b/docs/Algorithms.md index 55ca30da..6e50dccb 100644 --- a/docs/Algorithms.md +++ b/docs/Algorithms.md @@ -1,16 +1,20 @@ # Supported Algorithms -wolfCOSE supports 41 algorithms across signing, encryption, MAC, and key distribution. This page provides the complete list with COSE algorithm IDs and required wolfSSL compile-time guards. All algorithms are usable in both single-actor messages (Sign1/Encrypt0/Mac0) and multi-actor messages (Sign/Encrypt/Mac) — see [[Message Types]] for details. +wolfCOSE supports 46 algorithms across signing, encryption, MAC, and key distribution. This page provides the complete list with COSE algorithm IDs and required wolfSSL compile-time guards. All algorithms are usable in both single-actor messages (Sign1/Encrypt0/Mac0) and multi-actor messages (Sign/Encrypt/Mac). See [[Message Types]] for details. ## COSE_Sign1 (Digital Signatures) | Algorithm | COSE ID | wolfCrypt Guard | Notes | |-----------|---------|-----------------|-------| -| ES256 | -7 | `HAVE_ECC` | ECDSA with P-256 / SHA-256 | -| ES384 | -35 | `HAVE_ECC` | ECDSA with P-384 / SHA-384 | -| ES512 | -36 | `HAVE_ECC` | ECDSA with P-521 / SHA-512 | -| EdDSA (Ed25519) | -8 | `HAVE_ED25519` | Curve25519 | -| EdDSA (Ed448) | -8 | `HAVE_ED448` | Curve448 (Goldilocks) | +| ESP256 | -9 | `HAVE_ECC` | ECDSA with P-256 / SHA-256 (RFC 9864) | +| ESP384 | -51 | `HAVE_ECC` | ECDSA with P-384 / SHA-384 (RFC 9864) | +| ESP512 | -52 | `HAVE_ECC` | ECDSA with P-521 / SHA-512 (RFC 9864) | +| Ed25519 | -19 | `HAVE_ED25519` | EdDSA on Curve25519 (RFC 9864) | +| Ed448 | -53 | `HAVE_ED448` | EdDSA on Curve448 (Goldilocks) (RFC 9864) | +| ES256 | -7 | `HAVE_ECC` | Deprecated by RFC 9864; needs `WOLFCOSE_ENABLE_DEPRECATED_ALGS` | +| ES384 | -35 | `HAVE_ECC` | Deprecated by RFC 9864; needs `WOLFCOSE_ENABLE_DEPRECATED_ALGS` | +| ES512 | -36 | `HAVE_ECC` | Deprecated by RFC 9864; needs `WOLFCOSE_ENABLE_DEPRECATED_ALGS` | +| EdDSA | -8 | `HAVE_ED25519` / `HAVE_ED448` | Deprecated by RFC 9864 (curve taken from the key); needs `WOLFCOSE_ENABLE_DEPRECATED_ALGS` | | PS256 | -37 | `WC_RSA_PSS` | RSA-PSS with SHA-256 | | PS384 | -38 | `WC_RSA_PSS` | RSA-PSS with SHA-384 | | PS512 | -39 | `WC_RSA_PSS` | RSA-PSS with SHA-512 | @@ -87,8 +91,8 @@ AES Key Wrap-based algorithms also require wolfSSL 5.9.0 or later. | COSE kty | Value | Guard | Algorithms | |----------|-------|-------|------------| -| OKP | 1 | `HAVE_ED25519` / `HAVE_ED448` | EdDSA | -| EC2 | 2 | `HAVE_ECC` | ES256, ES384, ES512 | +| OKP | 1 | `HAVE_ED25519` / `HAVE_ED448` | Ed25519, Ed448 (EdDSA) | +| EC2 | 2 | `HAVE_ECC` | ESP256, ESP384, ESP512 (ES256, ES384, ES512) | | RSA | 3 | `WC_RSA_PSS` | PS256, PS384, PS512 | | Symmetric | 4 | always | AES-GCM, AES-CCM, ChaCha20, HMAC | | AKP | 7 | `WOLFSSL_HAVE_MLDSA` | ML-DSA (RFC 9964) | @@ -124,11 +128,19 @@ the 32-byte seed in `priv` (-2). There is no `crv` parameter. wolfCOSE defines these constants in `wolfcose.h`: ```c -/* Signature algorithms */ +/* Signature algorithms (RFC 9864 fully-specified) */ +#define WOLFCOSE_ALG_ESP256 (-9) +#define WOLFCOSE_ALG_ESP384 (-51) +#define WOLFCOSE_ALG_ESP512 (-52) +#define WOLFCOSE_ALG_ED25519 (-19) +#define WOLFCOSE_ALG_ED448 (-53) +/* These four IDs are deprecated by RFC 9864 and require + * WOLFCOSE_ENABLE_DEPRECATED_ALGS. */ #define WOLFCOSE_ALG_ES256 (-7) #define WOLFCOSE_ALG_ES384 (-35) #define WOLFCOSE_ALG_ES512 (-36) #define WOLFCOSE_ALG_EDDSA (-8) +/* RSA-PSS IDs remain enabled by default. */ #define WOLFCOSE_ALG_PS256 (-37) #define WOLFCOSE_ALG_PS384 (-38) #define WOLFCOSE_ALG_PS512 (-39) @@ -185,6 +197,7 @@ Future algorithm support planned: | Algorithm | Standard | Description | |-----------|----------|-------------| | ML-KEM | FIPS 203 (Kyber) | Post-quantum key encapsulation for COSE_Encrypt (IETF draft, no codepoints yet) | +| ESB256/320/384/512 | RFC 9864 | ECDSA on the Brainpool curves (Recommended: No); needs wolfSSL `HAVE_ECC_BRAINPOOL` | | XMSS | NIST SP 800-208 | Hash-based stateful signatures (no COSE codepoints assigned yet) | | SLH-DSA | SPHINCS+ | Stateless hash-based signatures | diff --git a/docs/Getting-Started.md b/docs/Getting-Started.md index 68f487a1..78e5e072 100644 --- a/docs/Getting-Started.md +++ b/docs/Getting-Started.md @@ -164,7 +164,7 @@ int main(void) wc_CoseKey_SetEcc(&coseKey, WOLFCOSE_CRV_P256, &eccKey); /* Sign */ - wc_CoseSign1_Sign(&coseKey, WOLFCOSE_ALG_ES256, + wc_CoseSign1_Sign(&coseKey, WOLFCOSE_ALG_ESP256, kid, sizeof(kid) - 1, payload, sizeof(payload) - 1, NULL, 0, /* no detached payload */ @@ -391,12 +391,12 @@ The `wolfcose_tool` provides command-line access to all wolfCOSE operations: make tool # Generate keys -./tools/wolfcose_tool keygen -a ES256 -o ec.key +./tools/wolfcose_tool keygen -a ESP256 -o ec.key ./tools/wolfcose_tool keygen -a ML-DSA-44 -o pqc.key ./tools/wolfcose_tool keygen -a A128GCM -o sym.key # Sign and verify -./tools/wolfcose_tool sign -k ec.key -a ES256 -i data.bin -o data.cose +./tools/wolfcose_tool sign -k ec.key -a ESP256 -i data.bin -o data.cose ./tools/wolfcose_tool verify -k ec.key -i data.cose # Encrypt and decrypt @@ -454,7 +454,7 @@ version against trusted reference values. | File | Description | |------|-------------| | `firmware_update.c` | Post-quantum ML-DSA firmware signing with detached payload | -| `multi_party_approval.c` | Dual-control firmware approval (ES256 + ES384) | +| `multi_party_approval.c` | Dual-control firmware approval (ESP256 + ESP384) | | `iot_fleet_config.c` | Encrypted config push to IoT device fleet | | `sensor_attestation.c` | EAT-style attestation with replay protection via AAD | | `group_broadcast_mac.c` | Authenticated broadcast to multiple subscribers | diff --git a/docs/Home.md b/docs/Home.md index 8ef02c66..673a727b 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -6,7 +6,7 @@ Welcome to the wolfCOSE wiki. This is the complete documentation for wolfCOSE, a wolfCOSE is a C library implementing: - **CBOR** (RFC 8949): Concise Binary Object Representation -- **COSE** (RFC 9052/9053): CBOR Object Signing and Encryption +- **COSE** (RFC 9052/9053): CBOR Object Signing and Encryption, with the RFC 9864 fully-specified signature algorithms It uses [wolfSSL](https://www.wolfssl.com/) as the cryptographic backend and is designed for constrained IoT devices, FIPS-bounded deployments, and anywhere you need authenticated CBOR payloads in minimal RAM. @@ -62,6 +62,7 @@ wolfCOSE implements all six COSE message types from RFC 9052: - [RFC 8949 (CBOR)](https://www.rfc-editor.org/rfc/rfc8949) - [RFC 9052 (COSE Structures)](https://www.rfc-editor.org/rfc/rfc9052) - [RFC 9053 (COSE Algorithms)](https://www.rfc-editor.org/rfc/rfc9053) +- [RFC 9864 (Fully-Specified Algorithms)](https://www.rfc-editor.org/rfc/rfc9864) ## License diff --git a/docs/MISRA-Compliance.md b/docs/MISRA-Compliance.md index 54855dff..85d42963 100644 --- a/docs/MISRA-Compliance.md +++ b/docs/MISRA-Compliance.md @@ -15,7 +15,7 @@ Verified via cppcheck's MISRA addon (`--addon=misra`) with all wolfCOSE algorith **Workflow**: `.github/workflows/misra-2012.yml` -All wolfCOSE and wolfSSL feature macros are explicitly defined so cppcheck checks the full code path rather than enumerating wolfSSL's hundreds of platform `#ifdef` configurations. This includes all four default-off experimental COSE-HPKE operation gates, `WOLFCOSE_EXPERIMENTAL`, and wolfSSL HPKE support, so draft code is analyzed rather than silently excluded. See [[Macros]] for the complete list. +All wolfCOSE and wolfSSL feature macros are explicitly defined so cppcheck checks the full code path rather than enumerating wolfSSL's hundreds of platform `#ifdef` configurations. This includes all four default-off experimental COSE-HPKE operation gates, `WOLFCOSE_EXPERIMENTAL`, wolfSSL HPKE support, and `WOLFCOSE_ENABLE_DEPRECATED_ALGS`, so draft HPKE code and opt-in RFC 9053 algorithm paths are analyzed rather than silently excluded. See [[Macros]] for the complete list. ### MISRA C:2023 diff --git a/docs/Macros.md b/docs/Macros.md index c274f05d..d595d1c9 100644 --- a/docs/Macros.md +++ b/docs/Macros.md @@ -46,7 +46,7 @@ and graduation plan. ## Lean Configuration Layer -Defining `WOLFCOSE_LEAN` keeps only the core — `COSE_Sign1`/`Encrypt0`/`Mac0` with ES256, AES-GCM, and HMAC-SHA256 — and turns every other algorithm into an opt-in. This is the recommended starting point for constrained targets. +Defining `WOLFCOSE_LEAN` keeps only the core (`COSE_Sign1`/`Encrypt0`/`Mac0` with ESP256, AES-GCM, and HMAC-SHA256) and turns every other algorithm into an opt-in. This is the recommended starting point for constrained targets. | Define | Description | |--------|-------------| @@ -130,11 +130,11 @@ Per-algorithm opt-outs for the default (non-lean) build. Each also has a `WOLFCO | Opt-out | Algorithm | wolfSSL requirement | |---------|-----------|---------------------| -| `WOLFCOSE_NO_ES256` | ECDSA P-256 (ES256) | `HAVE_ECC`, SHA-256, P-256 not disabled by `NO_ECC256`, and `ECC_MIN_KEY_SZ <= 256` | -| `WOLFCOSE_NO_ES384` | ECDSA P-384 (ES384) | `HAVE_ECC`, `WOLFSSL_SHA384`, `HAVE_ECC384` or `HAVE_ALL_CURVES`, and `ECC_MIN_KEY_SZ <= 384` | -| `WOLFCOSE_NO_ES512` | ECDSA P-521 (ES512) | `HAVE_ECC`, `WOLFSSL_SHA512`, `HAVE_ECC521` or `HAVE_ALL_CURVES`, and `ECC_MIN_KEY_SZ <= 521` | -| `WOLFCOSE_NO_EDDSA` | Ed25519 | `HAVE_ED25519` | -| `WOLFCOSE_NO_ED448` | Ed448 | `HAVE_ED448` | +| `WOLFCOSE_NO_ES256` | ECDSA P-256 (ESP256, and ES256 with deprecated IDs enabled) | `HAVE_ECC`, SHA-256, P-256 not disabled by `NO_ECC256`, and `ECC_MIN_KEY_SZ <= 256` | +| `WOLFCOSE_NO_ES384` | ECDSA P-384 (ESP384, and ES384 with deprecated IDs enabled) | `HAVE_ECC`, `WOLFSSL_SHA384`, `HAVE_ECC384` or `HAVE_ALL_CURVES`, and `ECC_MIN_KEY_SZ <= 384` | +| `WOLFCOSE_NO_ES512` | ECDSA P-521 (ESP512, and ES512 with deprecated IDs enabled) | `HAVE_ECC`, `WOLFSSL_SHA512`, `HAVE_ECC521` or `HAVE_ALL_CURVES`, and `ECC_MIN_KEY_SZ <= 521` | +| `WOLFCOSE_NO_EDDSA` | Ed25519 (and deprecated EdDSA with an Ed25519 key) | `HAVE_ED25519` | +| `WOLFCOSE_NO_ED448` | Ed448 (and deprecated EdDSA with an Ed448 key) | `HAVE_ED448` | | `WOLFCOSE_NO_RSAPSS` | RSA-PSS (PS256/384/512) | `WC_RSA_PSS` | | `WOLFCOSE_NO_MLDSA` | ML-DSA (FIPS 204) | `WOLFSSL_HAVE_MLDSA` (wolfSSL newer than 5.9.1) | | `WOLFCOSE_NO_LMS` | HSS/LMS (RFC 8778) | `WOLFSSL_HAVE_LMS` (wolfSSL 5.9.2+) | @@ -146,6 +146,16 @@ Per-algorithm opt-outs for the default (non-lean) build. Each also has a `WOLFCO | `WOLFCOSE_NO_HMAC512` | HMAC-SHA512 | `WOLFSSL_SHA512` | | `WOLFCOSE_NO_AESMAC` | AES-CBC-MAC | `HAVE_AES_CBC` | +### Deprecated Algorithm IDs (RFC 9864) + +RFC 9864 deprecates the polymorphic RFC 9053 signature IDs `ES256` (-7), `ES384` (-35), `ES512` (-36), and `EdDSA` (-8) in favour of the fully-specified `ESP256` (-9), `ESP384` (-51), `ESP512` (-52), `Ed25519` (-19), and `Ed448` (-53). The key format and signature encoding are unchanged, but the protected `alg` value is part of the signed `Sig_structure`, so relabelling an existing message to a replacement ID requires re-signing it. The new IDs bind the curve, so `Ed25519` with an Ed448 key (or `ESP256` with a P-384 key) is rejected with `WOLFCOSE_E_COSE_BAD_ALG`. + +| Define | Description | +|--------|-------------| +| `WOLFCOSE_ENABLE_DEPRECATED_ALGS` | Also accept the deprecated `ES256`/`ES384`/`ES512`/`EdDSA` IDs on sign and verify. Off by default in both full and lean builds. | + +Without it the deprecated IDs fail with `WOLFCOSE_E_COSE_BAD_ALG`. Enable it to verify messages from peers that still emit the RFC 9053 IDs, including the pinned t_cose, go-cose, coset, and python-cwt interop peers, the COSE WG example vectors, and the RFC 9783 PSA attestation tokens (`ES256`). The CLI tool accepts the `ES256` and `EdDSA` names only in such a build; `Ed448` on the CLI always means -53. + RSA-PSS operations enforce RFC 8230's minimum 2048-bit modulus. A minimal wolfSSL RSA verify-only build must define `WOLFSSL_EXPORT_INT` so wolfCOSE can inspect the exact modulus width; builds that also enable ECC already expose diff --git a/docs/Message-Types.md b/docs/Message-Types.md index c63c67ef..4b675ee7 100644 --- a/docs/Message-Types.md +++ b/docs/Message-Types.md @@ -28,7 +28,7 @@ wc_InitRng(&rng); wc_CoseKey_Init(&key); wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccPriv); -int ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, +int ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, payload, payloadLen, NULL, 0, /* no detached payload */ NULL, 0, /* no external AAD */ @@ -43,7 +43,7 @@ int ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, ```c WOLFCOSE_SIGNATURE signers[2] = { - { .algId = WOLFCOSE_ALG_ES256, + { .algId = WOLFCOSE_ALG_ESP256, .key = &vendorKey, .kid = (const uint8_t*)"vendor-2026", .kidLen = 11 }, { .algId = WOLFCOSE_ALG_ML_DSA_65, /* hybrid: classical + PQC */ diff --git a/docs/Project-Structure.md b/docs/Project-Structure.md index b14100d7..467c6279 100644 --- a/docs/Project-Structure.md +++ b/docs/Project-Structure.md @@ -64,7 +64,7 @@ wolfCOSE/ The public API header. Contains: - All type definitions (`WOLFCOSE_KEY`, `WOLFCOSE_HDR`, etc.) -- Algorithm constants (`WOLFCOSE_ALG_ES256`, etc.) +- Algorithm constants (`WOLFCOSE_ALG_ESP256`, etc.) - Key type and curve constants - COSE tag values - Error codes @@ -211,7 +211,7 @@ test - Run self-tests | File | Description | |------|-------------| -| `sign1_demo.c` | Demonstrates all Sign1 algorithms (ES256, ES384, ES512, EdDSA, PS256/384/512, ML-DSA) | +| `sign1_demo.c` | Demonstrates all Sign1 algorithms (ESP256, ESP384, ESP512, Ed25519, PS256/384/512, ML-DSA) | | `encrypt0_demo.c` | Demonstrates all Encrypt0 algorithms (AES-GCM, ChaCha20, AES-CCM) | | `mac0_demo.c` | Demonstrates all Mac0 algorithms (HMAC, AES-MAC) | | `lifecycle_demo.c` | Full edge-to-cloud workflow with 11 algorithms | @@ -230,7 +230,7 @@ test - Run self-tests | File | Scenario | |------|----------| | `firmware_update.c` | Post-quantum ML-DSA firmware signing with detached payload | -| `multi_party_approval.c` | Dual-control firmware approval (ES256 + ES384) | +| `multi_party_approval.c` | Dual-control firmware approval (ESP256 + ESP384) | | `iot_fleet_config.c` | Encrypted config push to IoT device fleet with multiple recipients | | `sensor_attestation.c` | EAT-style attestation with replay protection via external AAD | | `group_broadcast_mac.c` | Authenticated broadcast to multiple subscribers | diff --git a/docs/STM32Cube.md b/docs/STM32Cube.md index 4b107736..fca8dde5 100644 --- a/docs/STM32Cube.md +++ b/docs/STM32Cube.md @@ -66,7 +66,7 @@ Verified on NUCLEO-H563ZI hardware, the console prints: ``` == wolfCOSE NUCLEO-H563ZI == -Running wolfCOSE test (COSE_Sign1 ES256)... +Running wolfCOSE test (COSE_Sign1 ESP256)... wolfCOSE test: PASS (COSE_Sign1 99 bytes) ``` diff --git a/docs/Testing.md b/docs/Testing.md index 8a5ff0ae..2a47c097 100644 --- a/docs/Testing.md +++ b/docs/Testing.md @@ -72,6 +72,17 @@ against a verify-only, full-`#tfm` receiver build. `psa-eat-demo` runs a complet challenge verification, and software-component appraisal workflow. See [[PSA-EAT]]. +### Deprecated Algorithm ID Tests + +```bash +make deprecated-algs-test +``` + +Rebuilds the suite with `WOLFCOSE_ENABLE_DEPRECATED_ALGS` so the RFC 9053 +`ES256`/`ES384`/`ES512`/`EdDSA` paths, the COSE WG example vectors, and the +RFC 9783 PSA tokens run. CI runs it as a dedicated step, and the minimal-build +matrix also runs the full suite with the macro enabled. + ### CLI Tool Tests ```bash @@ -202,7 +213,9 @@ make interop-go-cose This runs live, bidirectional `COSE_Sign1` interop against [Veraison go-cose](https://github.com/veraison/go-cose), pinned at v1.3.0 in `tests/interop/go_cose/go.mod`. The matrix covers ES256, ES384, ES512, PS256, -PS384, PS512, Ed25519, ES256 with external AAD, and untagged ES256. Each +PS384, PS512, Ed25519, ES256 with external AAD, and untagged ES256. The pinned +peers predate RFC 9864, so every interop target links a wolfCOSE built with +`WOLFCOSE_ENABLE_DEPRECATED_ALGS` and still exchanges the RFC 9053 IDs. Each implementation signs a message the other verifies, validates the payload, and rejects a modified signature. Go 1.21 or later is required. go-cose requires an embedded payload for Sign1 verification, so detached Sign1 remains covered diff --git a/examples/comprehensive/errors_all.c b/examples/comprehensive/errors_all.c index 306bcb9b..117880db 100644 --- a/examples/comprehensive/errors_all.c +++ b/examples/comprehensive/errors_all.c @@ -110,7 +110,7 @@ static int test_sign1_tamper(int tamperPos) } if (ret == 0) { /* Create valid signature */ - ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, @@ -320,7 +320,7 @@ static int test_sign1_truncated(void) } if (ret == 0) { /* Create valid message */ - ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, @@ -487,7 +487,7 @@ static int test_sign1_aad_mismatch(void) } if (ret == 0) { /* Sign with AAD */ - ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1u, NULL, 0, @@ -661,7 +661,7 @@ static int test_sign1_detached_missing(void) } if (ret == 0) { /* Sign with detached payload */ - ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ESP256, NULL, 0, NULL, 0, /* no inline payload */ payload, sizeof(payload) - 1u, /* detached */ @@ -717,7 +717,7 @@ static int test_sign1_with_symmetric_key(void) ret = wc_CoseKey_SetSymmetric(&cosKey, keyData, sizeof(keyData)); } if (ret == 0) { - ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, @@ -830,7 +830,7 @@ static int test_sign1_empty_payload(void) } if (ret == 0) { /* Sign empty payload (edge case, should work) */ - ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ESP256, NULL, 0, (const uint8_t*)"", 0, /* empty payload */ NULL, 0, NULL, 0, diff --git a/examples/comprehensive/sign_all.c b/examples/comprehensive/sign_all.c index c79931d9..e135194f 100644 --- a/examples/comprehensive/sign_all.c +++ b/examples/comprehensive/sign_all.c @@ -86,7 +86,7 @@ static int crv_from_size(int keySz) * Sign1 Worker Function * * Parameters: - * alg - Algorithm ID (WOLFCOSE_ALG_ES256, etc.) + * alg - Algorithm ID (WOLFCOSE_ALG_ESP256, etc.) * curveSize - Key size: 32=P-256, 48=P-384, 66=P-521, 0=Ed25519 * detached - 0=inline payload, 1=detached payload * useAad - 0=no AAD, 1=with external AAD @@ -546,7 +546,7 @@ static int test_sign_multi_4(int detached, int useAad) rngInit = 1; } - /* ES256 key */ + /* ESP256 key */ if (ret == 0) { ret = wc_ecc_init(&eccKey256); if (ret == 0) { @@ -559,7 +559,7 @@ static int test_sign_multi_4(int detached, int useAad) } } - /* ES384 key */ + /* ESP384 key */ if (ret == 0) { ret = wc_ecc_init(&eccKey384); if (ret == 0) { @@ -572,7 +572,7 @@ static int test_sign_multi_4(int detached, int useAad) } } - /* ES512 key */ + /* ESP512 key */ if (ret == 0) { ret = wc_ecc_init(&eccKey521); if (ret == 0) { @@ -585,7 +585,7 @@ static int test_sign_multi_4(int detached, int useAad) } } - /* EdDSA key */ + /* Ed25519 key */ if (ret == 0) { ret = wc_ed25519_init(&edKey); if (ret == 0) { @@ -600,22 +600,22 @@ static int test_sign_multi_4(int detached, int useAad) /* Setup signers */ if (ret == 0) { - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = &cosKey256; signers[0].kid = (const uint8_t*)"es256"; signers[0].kidLen = 5; - signers[1].algId = WOLFCOSE_ALG_ES384; + signers[1].algId = WOLFCOSE_ALG_ESP384; signers[1].key = &cosKey384; signers[1].kid = (const uint8_t*)"es384"; signers[1].kidLen = 5; - signers[2].algId = WOLFCOSE_ALG_ES512; + signers[2].algId = WOLFCOSE_ALG_ESP512; signers[2].key = &cosKey521; signers[2].kid = (const uint8_t*)"es512"; signers[2].kidLen = 5; - signers[3].algId = WOLFCOSE_ALG_EDDSA; + signers[3].algId = WOLFCOSE_ALG_ED25519; signers[3].key = &cosKeyEd; signers[3].kid = (const uint8_t*)"eddsa"; signers[3].kidLen = 5; @@ -692,81 +692,81 @@ static int test_sign1_all(void) printf("\n=== COSE_Sign1 Comprehensive Tests ===\n\n"); #if defined(WOLFCOSE_HAVE_ES256) && !defined(WOLFCOSE_NO_SIGN_ALL_ES256) - /* ES256 - 4 combinations */ - PRINT_TEST("es256_inline_noaad"); - ret = test_sign1(WOLFCOSE_ALG_ES256, 32, 0, 0); - CHECK_RESULT(ret, "es256_inline_noaad"); - - PRINT_TEST("es256_inline_aad"); - ret = test_sign1(WOLFCOSE_ALG_ES256, 32, 0, 1); - CHECK_RESULT(ret, "es256_inline_aad"); - - PRINT_TEST("es256_detached_noaad"); - ret = test_sign1(WOLFCOSE_ALG_ES256, 32, 1, 0); - CHECK_RESULT(ret, "es256_detached_noaad"); - - PRINT_TEST("es256_detached_aad"); - ret = test_sign1(WOLFCOSE_ALG_ES256, 32, 1, 1); - CHECK_RESULT(ret, "es256_detached_aad"); + /* ESP256 - 4 combinations */ + PRINT_TEST("esp256_inline_noaad"); + ret = test_sign1(WOLFCOSE_ALG_ESP256, 32, 0, 0); + CHECK_RESULT(ret, "esp256_inline_noaad"); + + PRINT_TEST("esp256_inline_aad"); + ret = test_sign1(WOLFCOSE_ALG_ESP256, 32, 0, 1); + CHECK_RESULT(ret, "esp256_inline_aad"); + + PRINT_TEST("esp256_detached_noaad"); + ret = test_sign1(WOLFCOSE_ALG_ESP256, 32, 1, 0); + CHECK_RESULT(ret, "esp256_detached_noaad"); + + PRINT_TEST("esp256_detached_aad"); + ret = test_sign1(WOLFCOSE_ALG_ESP256, 32, 1, 1); + CHECK_RESULT(ret, "esp256_detached_aad"); #endif #if defined(WOLFCOSE_HAVE_ES384) && \ !defined(WOLFCOSE_NO_SIGN_ALL_ES384) - /* ES384 - 4 combinations */ - PRINT_TEST("es384_inline_noaad"); - ret = test_sign1(WOLFCOSE_ALG_ES384, 48, 0, 0); - CHECK_RESULT(ret, "es384_inline_noaad"); - - PRINT_TEST("es384_inline_aad"); - ret = test_sign1(WOLFCOSE_ALG_ES384, 48, 0, 1); - CHECK_RESULT(ret, "es384_inline_aad"); - - PRINT_TEST("es384_detached_noaad"); - ret = test_sign1(WOLFCOSE_ALG_ES384, 48, 1, 0); - CHECK_RESULT(ret, "es384_detached_noaad"); - - PRINT_TEST("es384_detached_aad"); - ret = test_sign1(WOLFCOSE_ALG_ES384, 48, 1, 1); - CHECK_RESULT(ret, "es384_detached_aad"); + /* ESP384 - 4 combinations */ + PRINT_TEST("esp384_inline_noaad"); + ret = test_sign1(WOLFCOSE_ALG_ESP384, 48, 0, 0); + CHECK_RESULT(ret, "esp384_inline_noaad"); + + PRINT_TEST("esp384_inline_aad"); + ret = test_sign1(WOLFCOSE_ALG_ESP384, 48, 0, 1); + CHECK_RESULT(ret, "esp384_inline_aad"); + + PRINT_TEST("esp384_detached_noaad"); + ret = test_sign1(WOLFCOSE_ALG_ESP384, 48, 1, 0); + CHECK_RESULT(ret, "esp384_detached_noaad"); + + PRINT_TEST("esp384_detached_aad"); + ret = test_sign1(WOLFCOSE_ALG_ESP384, 48, 1, 1); + CHECK_RESULT(ret, "esp384_detached_aad"); #endif #if defined(WOLFCOSE_HAVE_ES512) && \ !defined(WOLFCOSE_NO_SIGN_ALL_ES512) - /* ES512 - 4 combinations */ - PRINT_TEST("es512_inline_noaad"); - ret = test_sign1(WOLFCOSE_ALG_ES512, 66, 0, 0); - CHECK_RESULT(ret, "es512_inline_noaad"); - - PRINT_TEST("es512_inline_aad"); - ret = test_sign1(WOLFCOSE_ALG_ES512, 66, 0, 1); - CHECK_RESULT(ret, "es512_inline_aad"); - - PRINT_TEST("es512_detached_noaad"); - ret = test_sign1(WOLFCOSE_ALG_ES512, 66, 1, 0); - CHECK_RESULT(ret, "es512_detached_noaad"); - - PRINT_TEST("es512_detached_aad"); - ret = test_sign1(WOLFCOSE_ALG_ES512, 66, 1, 1); - CHECK_RESULT(ret, "es512_detached_aad"); + /* ESP512 - 4 combinations */ + PRINT_TEST("esp512_inline_noaad"); + ret = test_sign1(WOLFCOSE_ALG_ESP512, 66, 0, 0); + CHECK_RESULT(ret, "esp512_inline_noaad"); + + PRINT_TEST("esp512_inline_aad"); + ret = test_sign1(WOLFCOSE_ALG_ESP512, 66, 0, 1); + CHECK_RESULT(ret, "esp512_inline_aad"); + + PRINT_TEST("esp512_detached_noaad"); + ret = test_sign1(WOLFCOSE_ALG_ESP512, 66, 1, 0); + CHECK_RESULT(ret, "esp512_detached_noaad"); + + PRINT_TEST("esp512_detached_aad"); + ret = test_sign1(WOLFCOSE_ALG_ESP512, 66, 1, 1); + CHECK_RESULT(ret, "esp512_detached_aad"); #endif #if defined(WOLFCOSE_HAVE_EDDSA) && !defined(WOLFCOSE_NO_SIGN_ALL_EDDSA) - /* EdDSA - 4 combinations */ - PRINT_TEST("eddsa_inline_noaad"); - ret = test_sign1(WOLFCOSE_ALG_EDDSA, 0, 0, 0); - CHECK_RESULT(ret, "eddsa_inline_noaad"); - - PRINT_TEST("eddsa_inline_aad"); - ret = test_sign1(WOLFCOSE_ALG_EDDSA, 0, 0, 1); - CHECK_RESULT(ret, "eddsa_inline_aad"); - - PRINT_TEST("eddsa_detached_noaad"); - ret = test_sign1(WOLFCOSE_ALG_EDDSA, 0, 1, 0); - CHECK_RESULT(ret, "eddsa_detached_noaad"); - - PRINT_TEST("eddsa_detached_aad"); - ret = test_sign1(WOLFCOSE_ALG_EDDSA, 0, 1, 1); - CHECK_RESULT(ret, "eddsa_detached_aad"); + /* Ed25519 - 4 combinations */ + PRINT_TEST("ed25519_inline_noaad"); + ret = test_sign1(WOLFCOSE_ALG_ED25519, 0, 0, 0); + CHECK_RESULT(ret, "ed25519_inline_noaad"); + + PRINT_TEST("ed25519_inline_aad"); + ret = test_sign1(WOLFCOSE_ALG_ED25519, 0, 0, 1); + CHECK_RESULT(ret, "ed25519_inline_aad"); + + PRINT_TEST("ed25519_detached_noaad"); + ret = test_sign1(WOLFCOSE_ALG_ED25519, 0, 1, 0); + CHECK_RESULT(ret, "ed25519_detached_noaad"); + + PRINT_TEST("ed25519_detached_aad"); + ret = test_sign1(WOLFCOSE_ALG_ED25519, 0, 1, 1); + CHECK_RESULT(ret, "ed25519_detached_aad"); #endif printf("\nSign1 Summary: %d passed, %d failed\n", passed, failed); @@ -785,207 +785,207 @@ static int test_sign_multi_all(void) printf("\n=== COSE_Sign Multi-Signer Comprehensive Tests ===\n\n"); /* Two-signer: ES256 + ES256 (4 modes) */ - PRINT_TEST("multi2_es256_es256_inline_noaad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES256, 32, 0, 0); - CHECK_RESULT(ret, "multi2_es256_es256_inline_noaad"); + PRINT_TEST("multi2_esp256_esp256_inline_noaad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP256, 32, 0, 0); + CHECK_RESULT(ret, "multi2_esp256_esp256_inline_noaad"); - PRINT_TEST("multi2_es256_es256_inline_aad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES256, 32, 0, 1); - CHECK_RESULT(ret, "multi2_es256_es256_inline_aad"); + PRINT_TEST("multi2_esp256_esp256_inline_aad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP256, 32, 0, 1); + CHECK_RESULT(ret, "multi2_esp256_esp256_inline_aad"); - PRINT_TEST("multi2_es256_es256_detached_noaad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES256, 32, 1, 0); - CHECK_RESULT(ret, "multi2_es256_es256_detached_noaad"); + PRINT_TEST("multi2_esp256_esp256_detached_noaad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP256, 32, 1, 0); + CHECK_RESULT(ret, "multi2_esp256_esp256_detached_noaad"); - PRINT_TEST("multi2_es256_es256_detached_aad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES256, 32, 1, 1); - CHECK_RESULT(ret, "multi2_es256_es256_detached_aad"); + PRINT_TEST("multi2_esp256_esp256_detached_aad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP256, 32, 1, 1); + CHECK_RESULT(ret, "multi2_esp256_esp256_detached_aad"); #ifdef WOLFCOSE_HAVE_ES384 /* Two-signer: ES256 + ES384 */ - PRINT_TEST("multi2_es256_es384_inline_noaad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES384, 48, 0, 0); - CHECK_RESULT(ret, "multi2_es256_es384_inline_noaad"); + PRINT_TEST("multi2_esp256_esp384_inline_noaad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP384, 48, 0, 0); + CHECK_RESULT(ret, "multi2_esp256_esp384_inline_noaad"); - PRINT_TEST("multi2_es256_es384_inline_aad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES384, 48, 0, 1); - CHECK_RESULT(ret, "multi2_es256_es384_inline_aad"); + PRINT_TEST("multi2_esp256_esp384_inline_aad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP384, 48, 0, 1); + CHECK_RESULT(ret, "multi2_esp256_esp384_inline_aad"); - PRINT_TEST("multi2_es256_es384_detached_noaad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES384, 48, 1, 0); - CHECK_RESULT(ret, "multi2_es256_es384_detached_noaad"); + PRINT_TEST("multi2_esp256_esp384_detached_noaad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP384, 48, 1, 0); + CHECK_RESULT(ret, "multi2_esp256_esp384_detached_noaad"); - PRINT_TEST("multi2_es256_es384_detached_aad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES384, 48, 1, 1); - CHECK_RESULT(ret, "multi2_es256_es384_detached_aad"); + PRINT_TEST("multi2_esp256_esp384_detached_aad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP384, 48, 1, 1); + CHECK_RESULT(ret, "multi2_esp256_esp384_detached_aad"); #endif #ifdef WOLFCOSE_HAVE_ES512 /* Two-signer: ES256 + ES512 */ - PRINT_TEST("multi2_es256_es512_inline_noaad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES512, 66, 0, 0); - CHECK_RESULT(ret, "multi2_es256_es512_inline_noaad"); + PRINT_TEST("multi2_esp256_esp512_inline_noaad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP512, 66, 0, 0); + CHECK_RESULT(ret, "multi2_esp256_esp512_inline_noaad"); - PRINT_TEST("multi2_es256_es512_inline_aad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES512, 66, 0, 1); - CHECK_RESULT(ret, "multi2_es256_es512_inline_aad"); + PRINT_TEST("multi2_esp256_esp512_inline_aad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP512, 66, 0, 1); + CHECK_RESULT(ret, "multi2_esp256_esp512_inline_aad"); - PRINT_TEST("multi2_es256_es512_detached_noaad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES512, 66, 1, 0); - CHECK_RESULT(ret, "multi2_es256_es512_detached_noaad"); + PRINT_TEST("multi2_esp256_esp512_detached_noaad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP512, 66, 1, 0); + CHECK_RESULT(ret, "multi2_esp256_esp512_detached_noaad"); - PRINT_TEST("multi2_es256_es512_detached_aad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES512, 66, 1, 1); - CHECK_RESULT(ret, "multi2_es256_es512_detached_aad"); + PRINT_TEST("multi2_esp256_esp512_detached_aad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP512, 66, 1, 1); + CHECK_RESULT(ret, "multi2_esp256_esp512_detached_aad"); #endif #ifdef WOLFCOSE_HAVE_EDDSA /* Two-signer: ES256 + EdDSA */ - PRINT_TEST("multi2_es256_eddsa_inline_noaad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_EDDSA, 0, 0, 0); - CHECK_RESULT(ret, "multi2_es256_eddsa_inline_noaad"); + PRINT_TEST("multi2_esp256_ed25519_inline_noaad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ED25519, 0, 0, 0); + CHECK_RESULT(ret, "multi2_esp256_ed25519_inline_noaad"); - PRINT_TEST("multi2_es256_eddsa_inline_aad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_EDDSA, 0, 0, 1); - CHECK_RESULT(ret, "multi2_es256_eddsa_inline_aad"); + PRINT_TEST("multi2_esp256_ed25519_inline_aad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ED25519, 0, 0, 1); + CHECK_RESULT(ret, "multi2_esp256_ed25519_inline_aad"); - PRINT_TEST("multi2_es256_eddsa_detached_noaad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_EDDSA, 0, 1, 0); - CHECK_RESULT(ret, "multi2_es256_eddsa_detached_noaad"); + PRINT_TEST("multi2_esp256_ed25519_detached_noaad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ED25519, 0, 1, 0); + CHECK_RESULT(ret, "multi2_esp256_ed25519_detached_noaad"); - PRINT_TEST("multi2_es256_eddsa_detached_aad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_EDDSA, 0, 1, 1); - CHECK_RESULT(ret, "multi2_es256_eddsa_detached_aad"); + PRINT_TEST("multi2_esp256_ed25519_detached_aad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ED25519, 0, 1, 1); + CHECK_RESULT(ret, "multi2_esp256_ed25519_detached_aad"); #endif #if defined(WOLFCOSE_HAVE_ES384) && defined(WOLFCOSE_HAVE_ES512) /* Two-signer: ES384 + ES512 */ - PRINT_TEST("multi2_es384_es512_inline_noaad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES384, 48, WOLFCOSE_ALG_ES512, 66, 0, 0); - CHECK_RESULT(ret, "multi2_es384_es512_inline_noaad"); + PRINT_TEST("multi2_esp384_esp512_inline_noaad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP384, 48, WOLFCOSE_ALG_ESP512, 66, 0, 0); + CHECK_RESULT(ret, "multi2_esp384_esp512_inline_noaad"); - PRINT_TEST("multi2_es384_es512_inline_aad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES384, 48, WOLFCOSE_ALG_ES512, 66, 0, 1); - CHECK_RESULT(ret, "multi2_es384_es512_inline_aad"); + PRINT_TEST("multi2_esp384_esp512_inline_aad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP384, 48, WOLFCOSE_ALG_ESP512, 66, 0, 1); + CHECK_RESULT(ret, "multi2_esp384_esp512_inline_aad"); - PRINT_TEST("multi2_es384_es512_detached_noaad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES384, 48, WOLFCOSE_ALG_ES512, 66, 1, 0); - CHECK_RESULT(ret, "multi2_es384_es512_detached_noaad"); + PRINT_TEST("multi2_esp384_esp512_detached_noaad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP384, 48, WOLFCOSE_ALG_ESP512, 66, 1, 0); + CHECK_RESULT(ret, "multi2_esp384_esp512_detached_noaad"); - PRINT_TEST("multi2_es384_es512_detached_aad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES384, 48, WOLFCOSE_ALG_ES512, 66, 1, 1); - CHECK_RESULT(ret, "multi2_es384_es512_detached_aad"); + PRINT_TEST("multi2_esp384_esp512_detached_aad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP384, 48, WOLFCOSE_ALG_ESP512, 66, 1, 1); + CHECK_RESULT(ret, "multi2_esp384_esp512_detached_aad"); #endif #if defined(WOLFCOSE_HAVE_ES384) && defined(WOLFCOSE_HAVE_EDDSA) /* Two-signer: ES384 + EdDSA */ - PRINT_TEST("multi2_es384_eddsa_inline_noaad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES384, 48, WOLFCOSE_ALG_EDDSA, 0, 0, 0); - CHECK_RESULT(ret, "multi2_es384_eddsa_inline_noaad"); + PRINT_TEST("multi2_esp384_ed25519_inline_noaad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP384, 48, WOLFCOSE_ALG_ED25519, 0, 0, 0); + CHECK_RESULT(ret, "multi2_esp384_ed25519_inline_noaad"); - PRINT_TEST("multi2_es384_eddsa_inline_aad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES384, 48, WOLFCOSE_ALG_EDDSA, 0, 0, 1); - CHECK_RESULT(ret, "multi2_es384_eddsa_inline_aad"); + PRINT_TEST("multi2_esp384_ed25519_inline_aad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP384, 48, WOLFCOSE_ALG_ED25519, 0, 0, 1); + CHECK_RESULT(ret, "multi2_esp384_ed25519_inline_aad"); - PRINT_TEST("multi2_es384_eddsa_detached_noaad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES384, 48, WOLFCOSE_ALG_EDDSA, 0, 1, 0); - CHECK_RESULT(ret, "multi2_es384_eddsa_detached_noaad"); + PRINT_TEST("multi2_esp384_ed25519_detached_noaad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP384, 48, WOLFCOSE_ALG_ED25519, 0, 1, 0); + CHECK_RESULT(ret, "multi2_esp384_ed25519_detached_noaad"); - PRINT_TEST("multi2_es384_eddsa_detached_aad"); - ret = test_sign_multi_2(WOLFCOSE_ALG_ES384, 48, WOLFCOSE_ALG_EDDSA, 0, 1, 1); - CHECK_RESULT(ret, "multi2_es384_eddsa_detached_aad"); + PRINT_TEST("multi2_esp384_ed25519_detached_aad"); + ret = test_sign_multi_2(WOLFCOSE_ALG_ESP384, 48, WOLFCOSE_ALG_ED25519, 0, 1, 1); + CHECK_RESULT(ret, "multi2_esp384_ed25519_detached_aad"); #endif #if defined(WOLFCOSE_HAVE_ES384) && defined(WOLFCOSE_HAVE_ES512) /* Three-signer: ES256 + ES384 + ES512 */ - PRINT_TEST("multi3_es256_es384_es512_inline_noaad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES384, 48, - WOLFCOSE_ALG_ES512, 66, 0, 0); - CHECK_RESULT(ret, "multi3_es256_es384_es512_inline_noaad"); - - PRINT_TEST("multi3_es256_es384_es512_inline_aad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES384, 48, - WOLFCOSE_ALG_ES512, 66, 0, 1); - CHECK_RESULT(ret, "multi3_es256_es384_es512_inline_aad"); - - PRINT_TEST("multi3_es256_es384_es512_detached_noaad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES384, 48, - WOLFCOSE_ALG_ES512, 66, 1, 0); - CHECK_RESULT(ret, "multi3_es256_es384_es512_detached_noaad"); - - PRINT_TEST("multi3_es256_es384_es512_detached_aad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES384, 48, - WOLFCOSE_ALG_ES512, 66, 1, 1); - CHECK_RESULT(ret, "multi3_es256_es384_es512_detached_aad"); + PRINT_TEST("multi3_esp256_esp384_esp512_inline_noaad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP384, 48, + WOLFCOSE_ALG_ESP512, 66, 0, 0); + CHECK_RESULT(ret, "multi3_esp256_esp384_esp512_inline_noaad"); + + PRINT_TEST("multi3_esp256_esp384_esp512_inline_aad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP384, 48, + WOLFCOSE_ALG_ESP512, 66, 0, 1); + CHECK_RESULT(ret, "multi3_esp256_esp384_esp512_inline_aad"); + + PRINT_TEST("multi3_esp256_esp384_esp512_detached_noaad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP384, 48, + WOLFCOSE_ALG_ESP512, 66, 1, 0); + CHECK_RESULT(ret, "multi3_esp256_esp384_esp512_detached_noaad"); + + PRINT_TEST("multi3_esp256_esp384_esp512_detached_aad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP384, 48, + WOLFCOSE_ALG_ESP512, 66, 1, 1); + CHECK_RESULT(ret, "multi3_esp256_esp384_esp512_detached_aad"); #endif #if defined(WOLFCOSE_HAVE_ES384) && defined(WOLFCOSE_HAVE_EDDSA) /* Three-signer: ES256 + ES384 + EdDSA */ - PRINT_TEST("multi3_es256_es384_eddsa_inline_noaad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES384, 48, - WOLFCOSE_ALG_EDDSA, 0, 0, 0); - CHECK_RESULT(ret, "multi3_es256_es384_eddsa_inline_noaad"); - - PRINT_TEST("multi3_es256_es384_eddsa_inline_aad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES384, 48, - WOLFCOSE_ALG_EDDSA, 0, 0, 1); - CHECK_RESULT(ret, "multi3_es256_es384_eddsa_inline_aad"); - - PRINT_TEST("multi3_es256_es384_eddsa_detached_noaad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES384, 48, - WOLFCOSE_ALG_EDDSA, 0, 1, 0); - CHECK_RESULT(ret, "multi3_es256_es384_eddsa_detached_noaad"); - - PRINT_TEST("multi3_es256_es384_eddsa_detached_aad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES384, 48, - WOLFCOSE_ALG_EDDSA, 0, 1, 1); - CHECK_RESULT(ret, "multi3_es256_es384_eddsa_detached_aad"); + PRINT_TEST("multi3_esp256_esp384_ed25519_inline_noaad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP384, 48, + WOLFCOSE_ALG_ED25519, 0, 0, 0); + CHECK_RESULT(ret, "multi3_esp256_esp384_ed25519_inline_noaad"); + + PRINT_TEST("multi3_esp256_esp384_ed25519_inline_aad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP384, 48, + WOLFCOSE_ALG_ED25519, 0, 0, 1); + CHECK_RESULT(ret, "multi3_esp256_esp384_ed25519_inline_aad"); + + PRINT_TEST("multi3_esp256_esp384_ed25519_detached_noaad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP384, 48, + WOLFCOSE_ALG_ED25519, 0, 1, 0); + CHECK_RESULT(ret, "multi3_esp256_esp384_ed25519_detached_noaad"); + + PRINT_TEST("multi3_esp256_esp384_ed25519_detached_aad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP384, 48, + WOLFCOSE_ALG_ED25519, 0, 1, 1); + CHECK_RESULT(ret, "multi3_esp256_esp384_ed25519_detached_aad"); #endif #if defined(WOLFCOSE_HAVE_ES512) && defined(WOLFCOSE_HAVE_EDDSA) /* Three-signer: ES256 + ES512 + EdDSA */ - PRINT_TEST("multi3_es256_es512_eddsa_inline_noaad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES512, 66, - WOLFCOSE_ALG_EDDSA, 0, 0, 0); - CHECK_RESULT(ret, "multi3_es256_es512_eddsa_inline_noaad"); - - PRINT_TEST("multi3_es256_es512_eddsa_inline_aad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES512, 66, - WOLFCOSE_ALG_EDDSA, 0, 0, 1); - CHECK_RESULT(ret, "multi3_es256_es512_eddsa_inline_aad"); - - PRINT_TEST("multi3_es256_es512_eddsa_detached_noaad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES512, 66, - WOLFCOSE_ALG_EDDSA, 0, 1, 0); - CHECK_RESULT(ret, "multi3_es256_es512_eddsa_detached_noaad"); - - PRINT_TEST("multi3_es256_es512_eddsa_detached_aad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES256, 32, WOLFCOSE_ALG_ES512, 66, - WOLFCOSE_ALG_EDDSA, 0, 1, 1); - CHECK_RESULT(ret, "multi3_es256_es512_eddsa_detached_aad"); + PRINT_TEST("multi3_esp256_esp512_ed25519_inline_noaad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP512, 66, + WOLFCOSE_ALG_ED25519, 0, 0, 0); + CHECK_RESULT(ret, "multi3_esp256_esp512_ed25519_inline_noaad"); + + PRINT_TEST("multi3_esp256_esp512_ed25519_inline_aad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP512, 66, + WOLFCOSE_ALG_ED25519, 0, 0, 1); + CHECK_RESULT(ret, "multi3_esp256_esp512_ed25519_inline_aad"); + + PRINT_TEST("multi3_esp256_esp512_ed25519_detached_noaad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP512, 66, + WOLFCOSE_ALG_ED25519, 0, 1, 0); + CHECK_RESULT(ret, "multi3_esp256_esp512_ed25519_detached_noaad"); + + PRINT_TEST("multi3_esp256_esp512_ed25519_detached_aad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP256, 32, WOLFCOSE_ALG_ESP512, 66, + WOLFCOSE_ALG_ED25519, 0, 1, 1); + CHECK_RESULT(ret, "multi3_esp256_esp512_ed25519_detached_aad"); #endif #if defined(WOLFCOSE_HAVE_ES384) && defined(WOLFCOSE_HAVE_ES512) && defined(WOLFCOSE_HAVE_EDDSA) /* Three-signer: ES384 + ES512 + EdDSA */ - PRINT_TEST("multi3_es384_es512_eddsa_inline_noaad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES384, 48, WOLFCOSE_ALG_ES512, 66, - WOLFCOSE_ALG_EDDSA, 0, 0, 0); - CHECK_RESULT(ret, "multi3_es384_es512_eddsa_inline_noaad"); - - PRINT_TEST("multi3_es384_es512_eddsa_inline_aad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES384, 48, WOLFCOSE_ALG_ES512, 66, - WOLFCOSE_ALG_EDDSA, 0, 0, 1); - CHECK_RESULT(ret, "multi3_es384_es512_eddsa_inline_aad"); - - PRINT_TEST("multi3_es384_es512_eddsa_detached_noaad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES384, 48, WOLFCOSE_ALG_ES512, 66, - WOLFCOSE_ALG_EDDSA, 0, 1, 0); - CHECK_RESULT(ret, "multi3_es384_es512_eddsa_detached_noaad"); - - PRINT_TEST("multi3_es384_es512_eddsa_detached_aad"); - ret = test_sign_multi_3(WOLFCOSE_ALG_ES384, 48, WOLFCOSE_ALG_ES512, 66, - WOLFCOSE_ALG_EDDSA, 0, 1, 1); - CHECK_RESULT(ret, "multi3_es384_es512_eddsa_detached_aad"); + PRINT_TEST("multi3_esp384_esp512_ed25519_inline_noaad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP384, 48, WOLFCOSE_ALG_ESP512, 66, + WOLFCOSE_ALG_ED25519, 0, 0, 0); + CHECK_RESULT(ret, "multi3_esp384_esp512_ed25519_inline_noaad"); + + PRINT_TEST("multi3_esp384_esp512_ed25519_inline_aad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP384, 48, WOLFCOSE_ALG_ESP512, 66, + WOLFCOSE_ALG_ED25519, 0, 0, 1); + CHECK_RESULT(ret, "multi3_esp384_esp512_ed25519_inline_aad"); + + PRINT_TEST("multi3_esp384_esp512_ed25519_detached_noaad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP384, 48, WOLFCOSE_ALG_ESP512, 66, + WOLFCOSE_ALG_ED25519, 0, 1, 0); + CHECK_RESULT(ret, "multi3_esp384_esp512_ed25519_detached_noaad"); + + PRINT_TEST("multi3_esp384_esp512_ed25519_detached_aad"); + ret = test_sign_multi_3(WOLFCOSE_ALG_ESP384, 48, WOLFCOSE_ALG_ESP512, 66, + WOLFCOSE_ALG_ED25519, 0, 1, 1); + CHECK_RESULT(ret, "multi3_esp384_esp512_ed25519_detached_aad"); #endif #if defined(WOLFCOSE_HAVE_ES384) && defined(WOLFCOSE_HAVE_ES512) && defined(WOLFCOSE_HAVE_EDDSA) @@ -1082,9 +1082,9 @@ static int test_sign1_interop(void) } /* Sign with known key */ - PRINT_TEST("interop_sign1_es256_roundtrip"); + PRINT_TEST("interop_sign1_esp256_roundtrip"); if (ret == 0) { - ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&cosKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, @@ -1101,7 +1101,7 @@ static int test_sign1_interop(void) } /* Validate */ - if ((ret == 0) && (hdr.alg != WOLFCOSE_ALG_ES256)) { + if ((ret == 0) && (hdr.alg != WOLFCOSE_ALG_ESP256)) { ret = -1; } if ((ret == 0) && (decPayloadLen != (sizeof(payload) - 1u))) { diff --git a/examples/ext_sign_demo.c b/examples/ext_sign_demo.c index 17600c3f..049c69ed 100644 --- a/examples/ext_sign_demo.c +++ b/examples/ext_sign_demo.c @@ -156,7 +156,7 @@ static void demo_cleanup(WOLFCOSE_KEY* signKey, int signInited, secure_element_free(); } -/* wolfCOSE pre-hashes the Sig_structure for ES256, so tbs is the 32-byte +/* wolfCOSE pre-hashes the Sig_structure for ESP256, so tbs is the 32-byte * digest and must go to a sign-hash primitive, never a sign-message one. */ static int demo_sign_cb(void* cbCtx, int32_t alg, const uint8_t* tbs, size_t tbsLen, @@ -166,9 +166,9 @@ static int demo_sign_cb(void* cbCtx, int32_t alg, (void)cbCtx; - /* The length check wolfCOSE performs cannot separate ES256 from another + /* The length check wolfCOSE performs cannot separate ESP256 from another * 64-byte algorithm, so a real signer must pin what it was built for. */ - if (alg != WOLFCOSE_ALG_ES256) { + if (alg != WOLFCOSE_ALG_ESP256) { return -1; } @@ -212,7 +212,7 @@ int main(void) ret = wc_CoseKey_Init(&signKey); if (ret == 0) { signInited = 1; - /* ES256 derives its signature length from alg alone, so the key + /* ESP256 derives its signature length from alg alone, so the key * declares only what the algorithm needs. No private key is set. */ signKey.kty = WOLFCOSE_KTY_EC2; signKey.crv = WOLFCOSE_CRV_P256; @@ -227,7 +227,7 @@ int main(void) (signKey.hasPrivate == 0u) ? "no" : "yes"); /* rng is NULL: the external signer owns its own randomness. */ - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ESP256, kid, sizeof(kid) - 1, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, diff --git a/examples/lifecycle_demo.c b/examples/lifecycle_demo.c index bda30dcb..ad8cbb70 100644 --- a/examples/lifecycle_demo.c +++ b/examples/lifecycle_demo.c @@ -103,7 +103,7 @@ static int encode_sensor_payload(uint8_t* payload, size_t payloadSz, return ret; } -/* ----- COSE_Sign1 lifecycle: ES256 ----- */ +/* ----- COSE_Sign1 lifecycle: ESP256 ----- */ #ifdef WOLFCOSE_HAVE_ES256 static int demo_sign1_es256(void) { @@ -123,7 +123,7 @@ static int demo_sign1_es256(void) int rngInited = 0; int eccInited = 0; - printf("--- COSE_Sign1 ES256 ---\n"); + printf("--- COSE_Sign1 ESP256 ---\n"); ret = encode_sensor_payload(payload, sizeof(payload), &payloadLen); if (ret != 0) { @@ -148,7 +148,7 @@ static int demo_sign1_es256(void) wc_CoseKey_Init(&signKey); wc_CoseKey_SetEcc(&signKey, WOLFCOSE_CRV_P256, &eccKey); - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ESP256, g_kid, sizeof(g_kid) - 1u, payload, payloadLen, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -187,7 +187,7 @@ static int demo_sign1_es256(void) } #endif /* WOLFCOSE_HAVE_ES256 */ -/* ----- COSE_Sign1 lifecycle: EdDSA (Ed25519) ----- */ +/* ----- COSE_Sign1 lifecycle: Ed25519 ----- */ #ifdef WOLFCOSE_HAVE_EDDSA static int demo_sign1_eddsa(void) { @@ -206,7 +206,7 @@ static int demo_sign1_eddsa(void) int rngInited = 0; int edInited = 0; - printf("--- COSE_Sign1 EdDSA (Ed25519) ---\n"); + printf("--- COSE_Sign1 Ed25519 ---\n"); ret = encode_sensor_payload(payload, sizeof(payload), &payloadLen); if (ret == 0) { @@ -228,7 +228,7 @@ static int demo_sign1_eddsa(void) wc_CoseKey_Init(&signKey); wc_CoseKey_SetEd25519(&signKey, &edKey); - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_EDDSA, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ED25519, g_kid, sizeof(g_kid) - 1u, payload, payloadLen, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -717,8 +717,8 @@ static int demo_mac0_hmac(int32_t alg) /* ----- Algorithm name parser ----- */ enum { DEMO_ALG_ALL = 0, - DEMO_ALG_ES256, - DEMO_ALG_EDDSA, + DEMO_ALG_ESP256, + DEMO_ALG_ED25519, DEMO_ALG_PS256, DEMO_ALG_A128GCM, DEMO_ALG_A256GCM, @@ -735,11 +735,11 @@ static int parse_demo_alg(const char* name) if ((name == NULL) || (strcmp(name, "all") == 0)) { return DEMO_ALG_ALL; } - if (strcmp(name, "ES256") == 0) { - return DEMO_ALG_ES256; + if (strcmp(name, "ESP256") == 0) { + return DEMO_ALG_ESP256; } - if (strcmp(name, "EdDSA") == 0) { - return DEMO_ALG_EDDSA; + if (strcmp(name, "Ed25519") == 0) { + return DEMO_ALG_ED25519; } if (strcmp(name, "PS256") == 0) { return DEMO_ALG_PS256; @@ -785,7 +785,7 @@ int main(int argc, char* argv[]) fprintf(stderr, "Unknown algorithm: %s\n", argv[2]); fprintf(stderr, "Usage: %s [-a ]\n" - " alg: all, ES256, EdDSA, PS256, ML-DSA-44, A128GCM,\n" + " alg: all, ESP256, Ed25519, PS256, ML-DSA-44, A128GCM,\n" " A256GCM, HMAC256, HMAC384, HMAC512, ChaCha20,\n" " AES-CCM\n", argv[0]); @@ -795,7 +795,7 @@ int main(int argc, char* argv[]) else if (argc != 1) { fprintf(stderr, "Usage: %s [-a ]\n" - " alg: all, ES256, EdDSA, PS256, ML-DSA-44, A128GCM,\n" + " alg: all, ESP256, Ed25519, PS256, ML-DSA-44, A128GCM,\n" " A256GCM, HMAC256, HMAC384, HMAC512, ChaCha20,\n" " AES-CCM\n", argv[0]); return 1; @@ -805,13 +805,13 @@ int main(int argc, char* argv[]) /* COSE_Sign1 demos */ #ifdef WOLFCOSE_HAVE_ES256 - if ((demoAlg == DEMO_ALG_ALL) || (demoAlg == DEMO_ALG_ES256)) { + if ((demoAlg == DEMO_ALG_ALL) || (demoAlg == DEMO_ALG_ESP256)) { tests++; if (demo_sign1_es256() != 0) { failures++; } } #endif #ifdef WOLFCOSE_HAVE_EDDSA - if ((demoAlg == DEMO_ALG_ALL) || (demoAlg == DEMO_ALG_EDDSA)) { + if ((demoAlg == DEMO_ALG_ALL) || (demoAlg == DEMO_ALG_ED25519)) { tests++; if (demo_sign1_eddsa() != 0) { failures++; } } diff --git a/examples/scenarios/firmware_update.c b/examples/scenarios/firmware_update.c index c880f12a..dade7973 100644 --- a/examples/scenarios/firmware_update.c +++ b/examples/scenarios/firmware_update.c @@ -19,7 +19,7 @@ * * Firmware Update with Post-Quantum Signature * - * Scenario: OEM signs firmware binary with ML-DSA-65 (or ES256 fallback), + * Scenario: OEM signs firmware binary with ML-DSA-65 (or ESP256 fallback), * embedded device verifies before installing. Uses detached payload since * firmware binary is transmitted separately from the COSE manifest. * @@ -317,8 +317,8 @@ int main(void) } if (ret == 0) { - alg = WOLFCOSE_ALG_ES256; - printf("Using ECDSA ES256 algorithm (ML-DSA not available)\n\n"); + alg = WOLFCOSE_ALG_ESP256; + printf("Using ECDSA ESP256 algorithm (ML-DSA not available)\n\n"); } #else diff --git a/examples/scenarios/multi_party_approval.c b/examples/scenarios/multi_party_approval.c index abec3783..e81cf2a9 100644 --- a/examples/scenarios/multi_party_approval.c +++ b/examples/scenarios/multi_party_approval.c @@ -20,8 +20,8 @@ /* Multi-Party Firmware Approval (Dual Control) * - * Scenario: Firmware must be signed by BOTH silicon vendor (ES256) - * and OEM (ES384) before device accepts it. Demonstrates COSE_Sign + * Scenario: Firmware must be signed by BOTH silicon vendor (ESP256) + * and OEM (ESP384) before device accepts it. Demonstrates COSE_Sign * with multiple signers using mixed algorithms. * * Compile-time gate: @@ -68,7 +68,7 @@ static int silicon_vendor_init(ecc_key* key, WOLFCOSE_KEY* cosKey, WC_RNG* rng) { int ret; - printf("[Silicon Vendor] Generating ES256 signing key...\n"); + printf("[Silicon Vendor] Generating ESP256 signing key...\n"); ret = wc_ecc_init(key); if (ret != 0) { @@ -99,7 +99,7 @@ static int oem_init(ecc_key* key, WOLFCOSE_KEY* cosKey, WC_RNG* rng) { int ret; - printf("[OEM] Generating ES384 signing key...\n"); + printf("[OEM] Generating ESP384 signing key...\n"); ret = wc_ecc_init(key); if (ret != 0) { @@ -142,18 +142,18 @@ static int sign_with_dual_control(WOLFCOSE_KEY* vendorKey, WOLFCOSE_KEY* oemKey, /* Setup signers array */ XMEMSET(signers, 0, sizeof(signers)); - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = vendorKey; signers[0].kid = vendorKid; signers[0].kidLen = sizeof(vendorKid) - 1u; #ifdef WOLFCOSE_HAVE_ES384 - signers[1].algId = WOLFCOSE_ALG_ES384; + signers[1].algId = WOLFCOSE_ALG_ESP384; signers[1].key = oemKey; signers[1].kid = oemKid; signers[1].kidLen = sizeof(oemKid) - 1u; #else - signers[1].algId = WOLFCOSE_ALG_ES256; + signers[1].algId = WOLFCOSE_ALG_ESP256; signers[1].key = oemKey; signers[1].kid = oemKid; signers[1].kidLen = sizeof(oemKid) - 1u; @@ -173,11 +173,11 @@ static int sign_with_dual_control(WOLFCOSE_KEY* vendorKey, WOLFCOSE_KEY* oemKey, } printf(" SUCCESS: Dual-signed message created (%zu bytes)\n", *signedLen); - printf(" Signer 0: Silicon Vendor (ES256)\n"); + printf(" Signer 0: Silicon Vendor (ESP256)\n"); #ifdef WOLFCOSE_HAVE_ES384 - printf(" Signer 1: OEM (ES384)\n"); + printf(" Signer 1: OEM (ESP384)\n"); #else - printf(" Signer 1: OEM (ES256)\n"); + printf(" Signer 1: OEM (ESP256)\n"); #endif return 0; } @@ -262,9 +262,9 @@ int main(void) } } #else - /* Fallback: use ES256 for both if SHA384 not available */ + /* Fallback: use ESP256 for both if SHA384 not available */ if (ret == 0) { - printf("[OEM] Generating ES256 signing key (SHA384 not available)...\n"); + printf("[OEM] Generating ESP256 signing key (SHA384 not available)...\n"); ret = wc_ecc_init(&oemEccKey); if (ret == 0) { ret = wc_ecc_make_key(&rng, 32, &oemEccKey); diff --git a/examples/scenarios/sensor_attestation.c b/examples/scenarios/sensor_attestation.c index 28516fa3..7cd97995 100644 --- a/examples/scenarios/sensor_attestation.c +++ b/examples/scenarios/sensor_attestation.c @@ -131,7 +131,7 @@ static int sensor_create_attestation(WOLFCOSE_KEY* deviceKey, printf(" Nonce (AAD) size: %zu bytes\n", nonceLen); /* Sign with nonce as external AAD */ - ret = wc_CoseSign1_Sign(deviceKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(deviceKey, WOLFCOSE_ALG_ESP256, kid, sizeof(kid) - 1u, reading, readingLen, NULL, 0, /* No detached payload */ diff --git a/examples/sign1_demo.c b/examples/sign1_demo.c index 9332d9c9..5586ea84 100644 --- a/examples/sign1_demo.c +++ b/examples/sign1_demo.c @@ -43,7 +43,7 @@ static int demo_sign1_es256(void) WOLFCOSE_KEY key; ecc_key eccKey; WC_RNG rng; - const uint8_t payload[] ="ES256 test payload"; + const uint8_t payload[] ="ESP256 test payload"; uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; uint8_t out[512]; size_t outLen = 0; @@ -52,7 +52,7 @@ static int demo_sign1_es256(void) WOLFCOSE_HDR hdr; int ret; - printf("--- COSE_Sign1 ES256 (P-256) ---\n"); + printf("--- COSE_Sign1 ESP256 (P-256) ---\n"); printf(" Payload: \"%s\" (%zu bytes)\n", payload, sizeof(payload) - 1u); ret = wc_InitRng(&rng); @@ -66,7 +66,7 @@ static int demo_sign1_es256(void) ret = wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); DEMO_ASSERT(ret == 0, "Set ECC key"); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, /* kid, kidLen */ payload, sizeof(payload) - 1u, /* payload, payloadLen */ NULL, 0, /* detachedPayload, detachedLen */ @@ -84,7 +84,7 @@ static int demo_sign1_es256(void) DEMO_ASSERT(ret == 0, "Verify"); DEMO_ASSERT(decPayloadLen == sizeof(payload) - 1u, "Payload length"); DEMO_ASSERT(memcmp(decPayload, payload, decPayloadLen) == 0, "Payload match"); - DEMO_ASSERT(hdr.alg == WOLFCOSE_ALG_ES256, "Algorithm"); + DEMO_ASSERT(hdr.alg == WOLFCOSE_ALG_ESP256, "Algorithm"); (void)wc_ecc_free(&eccKey); (void)wc_FreeRng(&rng); @@ -98,7 +98,7 @@ static int demo_sign1_es384(void) WOLFCOSE_KEY key; ecc_key eccKey; WC_RNG rng; - const uint8_t payload[] ="ES384 test payload"; + const uint8_t payload[] ="ESP384 test payload"; uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; uint8_t out[512]; size_t outLen = 0; @@ -107,7 +107,7 @@ static int demo_sign1_es384(void) WOLFCOSE_HDR hdr; int ret; - printf("--- COSE_Sign1 ES384 (P-384) ---\n"); + printf("--- COSE_Sign1 ESP384 (P-384) ---\n"); printf(" Payload: \"%s\" (%zu bytes)\n", payload, sizeof(payload) - 1u); ret = wc_InitRng(&rng); @@ -121,7 +121,7 @@ static int demo_sign1_es384(void) ret = wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P384, &eccKey); DEMO_ASSERT(ret == 0, "Set ECC key"); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES384, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP384, NULL, 0, /* kid, kidLen */ payload, sizeof(payload) - 1u, /* payload, payloadLen */ NULL, 0, /* detachedPayload, detachedLen */ @@ -137,7 +137,7 @@ static int demo_sign1_es384(void) scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); DEMO_ASSERT(ret == 0, "Verify"); - DEMO_ASSERT(hdr.alg == WOLFCOSE_ALG_ES384, "Algorithm"); + DEMO_ASSERT(hdr.alg == WOLFCOSE_ALG_ESP384, "Algorithm"); (void)wc_ecc_free(&eccKey); (void)wc_FreeRng(&rng); @@ -152,7 +152,7 @@ static int demo_sign1_es512(void) WOLFCOSE_KEY key; ecc_key eccKey; WC_RNG rng; - const uint8_t payload[] ="ES512 test payload"; + const uint8_t payload[] ="ESP512 test payload"; uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; uint8_t out[640]; size_t outLen = 0; @@ -161,7 +161,7 @@ static int demo_sign1_es512(void) WOLFCOSE_HDR hdr; int ret; - printf("--- COSE_Sign1 ES512 (P-521) ---\n"); + printf("--- COSE_Sign1 ESP512 (P-521) ---\n"); printf(" Payload: \"%s\" (%zu bytes)\n", payload, sizeof(payload) - 1u); ret = wc_InitRng(&rng); @@ -175,7 +175,7 @@ static int demo_sign1_es512(void) ret = wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P521, &eccKey); DEMO_ASSERT(ret == 0, "Set ECC key"); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES512, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP512, NULL, 0, /* kid, kidLen */ payload, sizeof(payload) - 1u, /* payload, payloadLen */ NULL, 0, /* detachedPayload, detachedLen */ @@ -191,7 +191,7 @@ static int demo_sign1_es512(void) scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); DEMO_ASSERT(ret == 0, "Verify"); - DEMO_ASSERT(hdr.alg == WOLFCOSE_ALG_ES512, "Algorithm"); + DEMO_ASSERT(hdr.alg == WOLFCOSE_ALG_ESP512, "Algorithm"); (void)wc_ecc_free(&eccKey); (void)wc_FreeRng(&rng); @@ -233,7 +233,7 @@ static int demo_sign1_with_aad(void) ret = wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); DEMO_ASSERT(ret == 0, "Set ECC key"); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, /* kid, kidLen */ payload, sizeof(payload) - 1u, /* payload, payloadLen */ NULL, 0, /* detachedPayload, detachedLen */ @@ -272,7 +272,7 @@ static int demo_sign1_eddsa(void) WOLFCOSE_KEY key; ed25519_key edKey; WC_RNG rng; - const uint8_t payload[] ="EdDSA test payload"; + const uint8_t payload[] ="Ed25519 test payload"; uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; uint8_t out[512]; size_t outLen = 0; @@ -281,7 +281,7 @@ static int demo_sign1_eddsa(void) WOLFCOSE_HDR hdr; int ret; - printf("--- COSE_Sign1 EdDSA (Ed25519) ---\n"); + printf("--- COSE_Sign1 Ed25519 ---\n"); printf(" Payload: \"%s\" (%zu bytes)\n", payload, sizeof(payload) - 1u); ret = wc_InitRng(&rng); @@ -295,7 +295,7 @@ static int demo_sign1_eddsa(void) ret = wc_CoseKey_SetEd25519(&key, &edKey); DEMO_ASSERT(ret == 0, "Set Ed25519 key"); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_EDDSA, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ED25519, NULL, 0, /* kid, kidLen */ payload, sizeof(payload) - 1u, /* payload, payloadLen */ NULL, 0, /* detachedPayload, detachedLen */ @@ -311,7 +311,7 @@ static int demo_sign1_eddsa(void) scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); DEMO_ASSERT(ret == 0, "Verify"); - DEMO_ASSERT(hdr.alg == WOLFCOSE_ALG_EDDSA, "Algorithm"); + DEMO_ASSERT(hdr.alg == WOLFCOSE_ALG_ED25519, "Algorithm"); (void)wc_ed25519_free(&edKey); (void)wc_FreeRng(&rng); diff --git a/examples/sign1_verify_lean.c b/examples/sign1_verify_lean.c index 0555515a..52c76789 100644 --- a/examples/sign1_verify_lean.c +++ b/examples/sign1_verify_lean.c @@ -39,19 +39,19 @@ /* P-256 public key (X and Y, 32 bytes each). The matching private key lives * off-device and is never present in a lean verify build. */ static const uint8_t PUB_X[32] = { - 0x2c,0x3c,0x9f,0xd7,0xfc,0x15,0x48,0x7b,0x37,0x18,0x0e,0x37,0x95,0x56,0xb4,0xfd, - 0xbb,0x11,0x3c,0x78,0xe0,0xa5,0x3a,0x0b,0x25,0x71,0xf5,0xff,0xb0,0xdf,0x93,0x28}; + 7,46,52,83,101,83,150,186,25,53,18,206,127,177,205,220,45,101,26,221,16,156, + 28,95,25,176,216,47,196,158,197,239}; static const uint8_t PUB_Y[32] = { - 0x10,0xc3,0x85,0xc2,0xb6,0x8f,0x79,0xd7,0xe9,0x5e,0x43,0x62,0xf5,0xf4,0x06,0x21, - 0xdc,0x2c,0xf6,0x55,0x87,0xeb,0x94,0x61,0x13,0xe5,0xe2,0x8c,0xeb,0x2e,0xd2,0xce}; + 136,120,156,232,172,90,142,203,146,225,21,226,197,205,215,56,46,213,218,74,224,185, + 96,77,100,142,235,118,138,87,130,46}; -/* A COSE_Sign1 (ES256) over the payload below, signed off-device. */ +/* A COSE_Sign1 (ESP256) over the payload below, signed off-device. */ static const uint8_t COSE_SIGN1[] = { - 210,132,67,161,1,38,160,88,31,119,111,108,102,67,79,83,69,32,115,105,122,101, - 32,98,101,110,99,104,109,97,114,107,32,112,97,121,108,111,97,100,88,64,59,0, - 231,221,224,83,68,247,200,191,96,153,241,21,82,224,140,57,84,22,93,156,13,27, - 158,52,92,1,3,133,149,6,107,5,177,236,51,215,88,17,151,62,250,187,32,253,203, - 136,234,87,178,237,194,236,125,41,120,249,26,131,6,201,71,139}; + 210,132,67,161,1,40,160,88,31,119,111,108,102,67,79,83,69,32,115,105,122,101, + 32,98,101,110,99,104,109,97,114,107,32,112,97,121,108,111,97,100,88,64,201,105, + 152,70,230,206,246,14,94,132,181,86,158,232,224,236,190,163,136,180,211,146,73,94, + 129,79,132,234,145,88,96,128,225,174,150,178,60,0,15,105,119,226,69,59,241,46, + 27,78,198,17,132,23,66,110,230,137,133,202,168,126,125,81,163,203}; static const char EXPECTED_PAYLOAD[] = "wolfCOSE size benchmark payload"; @@ -93,7 +93,7 @@ int main(void) if ((payloadLen == (sizeof(EXPECTED_PAYLOAD) - 1)) && (payload != NULL) && (memcmp(payload, EXPECTED_PAYLOAD, payloadLen) == 0)) { - (void)printf("lean verify-only: COSE_Sign1 ES256 verified, " + (void)printf("lean verify-only: COSE_Sign1 ESP256 verified, " "payload = \"%.*s\"\n", (int)payloadLen, payload); rc = 0; } diff --git a/include/wolfcose/settings.h b/include/wolfcose/settings.h index d871fc5a..cb1256de 100644 --- a/include/wolfcose/settings.h +++ b/include/wolfcose/settings.h @@ -20,11 +20,13 @@ /* wolfCOSE compile-time configuration. * - * Default: every algorithm wolfSSL provides is enabled (full build). Strip an - * individual feature with WOLFCOSE_NO_. + * Default: every algorithm wolfSSL provides is enabled (full build), except the + * RFC 9053 alg IDs that RFC 9864 deprecates (opt in with + * WOLFCOSE_ENABLE_DEPRECATED_ALGS). Strip an individual feature with + * WOLFCOSE_NO_. * - * WOLFCOSE_LEAN: lean build. Only the core stays on — COSE_Sign1/Encrypt0/Mac0 - * with ES256, AES-GCM, HMAC-SHA256 — and everything else becomes opt-in via + * WOLFCOSE_LEAN: lean build. Only the core stays on (COSE_Sign1/Encrypt0/Mac0 + * with ESP256, AES-GCM, HMAC-SHA256) and everything else becomes opt-in via * WOLFCOSE_ENABLE_. * * An extension is on when: explicitly enabled (WOLFCOSE_ENABLE_), or it is a @@ -183,8 +185,13 @@ extern "C" { /* ----- Signature algorithms ----- */ -/* ES256 — core. ECC_USER_CURVES keeps P-256 unless NO_ECC256 selects it - * out; HAVE_ALL_CURVES is the equivalent all-curves configuration. */ +/* RFC 9864 deprecates the polymorphic ES256/ES384/ES512/EdDSA IDs in favour of + * ESP256/ESP384/ESP512/Ed25519/Ed448. The deprecated IDs are opt-in. */ +#if defined(WOLFCOSE_ENABLE_DEPRECATED_ALGS) + #define WOLFCOSE_HAVE_DEPRECATED_ALGS +#endif + +/* ESP256 (and deprecated ES256), core when wolfSSL has P-256 and SHA-256. */ #if !defined(WOLFCOSE_NO_ES256) && defined(HAVE_ECC) && \ !defined(NO_SHA256) && !defined(NO_ECC256) && \ (!defined(ECC_MIN_KEY_SZ) || (ECC_MIN_KEY_SZ <= 256)) diff --git a/include/wolfcose/wolfcose.h b/include/wolfcose/wolfcose.h index 46aa7bec..efe5da12 100644 --- a/include/wolfcose/wolfcose.h +++ b/include/wolfcose/wolfcose.h @@ -187,10 +187,21 @@ extern "C" { /* Algorithms */ #define WOLFCOSE_ALG_UNSET ((int32_t)0) +/* Fully-specified signature algorithms (RFC 9864). Code points are the IANA + * COSE Algorithms registry values + * (https://www.iana.org/assignments/cose). */ +#define WOLFCOSE_ALG_ESP256 (-9) /* ECDSA P-256 w/ SHA-256 */ +#define WOLFCOSE_ALG_ESP384 (-51) /* ECDSA P-384 w/ SHA-384 */ +#define WOLFCOSE_ALG_ESP512 (-52) /* ECDSA P-521 w/ SHA-512 */ +#define WOLFCOSE_ALG_ED25519 (-19) /* EdDSA, Ed25519 */ +#define WOLFCOSE_ALG_ED448 (-53) /* EdDSA, Ed448 */ +/* The following four polymorphic RFC 9053 IDs are deprecated by RFC 9864 and + * accepted only when WOLFCOSE_ENABLE_DEPRECATED_ALGS is defined. */ #define WOLFCOSE_ALG_ES256 (-7) #define WOLFCOSE_ALG_ES384 (-35) #define WOLFCOSE_ALG_ES512 (-36) #define WOLFCOSE_ALG_EDDSA (-8) +/* RSA-PSS algorithms remain supported without the deprecated-algorithm gate. */ #define WOLFCOSE_ALG_PS256 (-37) #define WOLFCOSE_ALG_PS384 (-38) #define WOLFCOSE_ALG_PS512 (-39) @@ -453,7 +464,7 @@ typedef struct WOLFCOSE_RECIPIENT { * Represents a single signer in a COSE_Sign message. */ typedef struct WOLFCOSE_SIGNATURE { - int32_t algId; /**< Signature algorithm (ES256, EdDSA, etc.) */ + int32_t algId; /**< Signature algorithm (ESP256, Ed25519, etc.) */ WOLFCOSE_KEY* key; /**< Caller-owned signing key */ const uint8_t* kid; /**< Key ID for signer identification */ size_t kidLen; /**< Key ID length */ @@ -1134,7 +1145,7 @@ WOLFCOSE_API int wc_CoseKey_Decode(WOLFCOSE_KEY* key, const uint8_t* in, * \param key WOLFCOSE_KEY with hasPrivate=1, or an external * signing callback when enabled. Caller retains * ownership. - * \param alg Algorithm identifier (WOLFCOSE_ALG_ES256, etc). + * \param alg Algorithm identifier (WOLFCOSE_ALG_ESP256, etc). * \param kid Key ID to include in unprotected headers (NULL if none). * \param kidLen Key ID length. * \param payload Payload to sign (NULL if detached). @@ -1190,9 +1201,11 @@ WOLFCOSE_API int wc_CoseSign1_Sign_ex(WOLFCOSE_KEY* key, int32_t alg, * \param key Key whose type determines the signature length. May be * NULL when \p alg determines the exact length. Required * for RSA-PSS, for HSS-LMS (its length comes from the - * attached key's parameter set), and when both Ed25519 and - * Ed448 are enabled. - * \param alg Algorithm identifier (WOLFCOSE_ALG_ES256, etc). + * attached key's parameter set), and for the deprecated + * WOLFCOSE_ALG_EDDSA when both Ed25519 and Ed448 are enabled. + * WOLFCOSE_ALG_ED25519 and WOLFCOSE_ALG_ED448 each pin a + * length, so they never need a key. + * \param alg Algorithm identifier (WOLFCOSE_ALG_ESP256, etc). * \param kidLen Key ID length (0 if none). * \param payloadLen Attached payload length (0 if detached). * \param detachedLen Detached payload length (0 if attached). diff --git a/scripts/cmdline-test.sh b/scripts/cmdline-test.sh index 31f21fde..8441bf28 100755 --- a/scripts/cmdline-test.sh +++ b/scripts/cmdline-test.sh @@ -54,7 +54,7 @@ hpke_keygen_or() { } # Names exactly as wolfcose_tool's parser accepts them. -SIGN_ALGS="ES256 EdDSA Ed448 ML-DSA-44 ML-DSA-65 ML-DSA-87" +SIGN_ALGS="${SIGN_ALGS:-ESP256 Ed25519 Ed448 ML-DSA-44 ML-DSA-65 ML-DSA-87}" ENC_ALGS="A128GCM A192GCM A256GCM ChaCha20 AES-CCM" MAC_ALGS="HMAC256 HMAC384 HMAC512" @@ -86,26 +86,26 @@ PK="$WORK/primary.key"; CK="$WORK/counter.key" BASE="$WORK/primary.cose"; COUNTER="$WORK/counter.cose" COUNTER2="$WORK/counter2.cose"; AAD="$WORK/counter.aad" printf 'release approval policy' > "$AAD" -if "$TOOL" keygen -a ES256 -o "$PK" >/dev/null 2>&1 && \ - "$TOOL" keygen -a ES256 -o "$CK" >/dev/null 2>&1 && \ - "$TOOL" sign -k "$PK" -a ES256 -i "$IN" -o "$BASE" \ +if "$TOOL" keygen -a ESP256 -o "$PK" >/dev/null 2>&1 && \ + "$TOOL" keygen -a ESP256 -o "$CK" >/dev/null 2>&1 && \ + "$TOOL" sign -k "$PK" -a ESP256 -i "$IN" -o "$BASE" \ >/dev/null 2>&1; then - if "$TOOL" countersign -k "$CK" -a ES256 -i "$BASE" \ + if "$TOOL" countersign -k "$CK" -a ESP256 -i "$BASE" \ -o "$COUNTER" --aad "$AAD" >/dev/null 2>&1 && \ "$TOOL" counterverify -k "$CK" -i "$COUNTER" --aad "$AAD" \ >/dev/null 2>&1 && \ "$TOOL" verify -k "$PK" -i "$COUNTER" >/dev/null 2>&1; then - ok "ES256 countersign and verify both layers" + ok "ESP256 countersign and verify both layers" else - bad "ES256 countersign round-trip" + bad "ESP256 countersign round-trip" fi - if "$TOOL" countersign -k "$CK" -a ES256 -i "$COUNTER" \ + if "$TOOL" countersign -k "$CK" -a ESP256 -i "$COUNTER" \ -o "$COUNTER2" --aad "$AAD" >/dev/null 2>&1 && \ "$TOOL" counterverify -k "$CK" -i "$COUNTER2" --index 1 \ --aad "$AAD" >/dev/null 2>&1; then - ok "ES256 second countersignature index" + ok "ESP256 second countersignature index" else - bad "ES256 second countersignature index" + bad "ESP256 second countersignature index" fi if "$TOOL" counterverify -k "$CK" -i "$COUNTER" \ >/dev/null 2>&1; then @@ -114,7 +114,7 @@ if "$TOOL" keygen -a ES256 -o "$PK" >/dev/null 2>&1 && \ ok "countersignature wrong AAD rejected" fi else - skip "countersignature (ES256)" + skip "countersignature (ESP256)" fi # Public-only RSA builds can't sign a decoded key, so skip; the self-test @@ -144,8 +144,8 @@ done echo "== Tamper detection: corrupted COSE_Sign1 must NOT verify ==" TK="$WORK/tamper.key"; TC="$WORK/tamper.cose" -if "$TOOL" keygen -a ES256 -o "$TK" >/dev/null 2>&1 && \ - "$TOOL" sign -k "$TK" -a ES256 -i "$IN" -o "$TC" >/dev/null 2>&1; then +if "$TOOL" keygen -a ESP256 -o "$TK" >/dev/null 2>&1 && \ + "$TOOL" sign -k "$TK" -a ESP256 -i "$IN" -o "$TC" >/dev/null 2>&1; then SZ=$(wc -c < "$TC") # Invert the last byte rather than setting it to a fixed value: an ECDSA # signature ends in 0xff about once in 256 runs, and overwriting it with @@ -159,7 +159,7 @@ if "$TOOL" keygen -a ES256 -o "$TK" >/dev/null 2>&1 && \ ok "tampered signature rejected" fi else - skip "tamper (ES256)" + skip "tamper (ESP256)" fi echo "== Encryption: keygen -> enc -> dec ==" @@ -379,15 +379,15 @@ done echo "== info on a signed message ==" IK="$WORK/info.key"; IC="$WORK/info.cose" -if "$TOOL" keygen -a ES256 -o "$IK" >/dev/null 2>&1 && \ - "$TOOL" sign -k "$IK" -a ES256 -i "$IN" -o "$IC" >/dev/null 2>&1; then +if "$TOOL" keygen -a ESP256 -o "$IK" >/dev/null 2>&1 && \ + "$TOOL" sign -k "$IK" -a ESP256 -i "$IN" -o "$IC" >/dev/null 2>&1; then if "$TOOL" info -i "$IC" >/dev/null 2>&1; then ok "info" else bad "info" fi else - skip "info (ES256)" + skip "info (ESP256)" fi echo "== info rejects malformed CBOR ==" @@ -403,10 +403,10 @@ echo "== Usage errors must exit non-zero ==" if "$TOOL" >/dev/null 2>&1; then bad "no-args exits non-zero"; else ok "no-args exits non-zero"; fi if "$TOOL" boguscmd >/dev/null 2>&1; then bad "bad command exits non-zero"; else ok "bad command exits non-zero"; fi if "$TOOL" verify -k x -i y --index 1 >/dev/null 2>&1; then bad "counter-only option on verify exits non-zero"; else ok "counter-only option on verify exits non-zero"; fi -if "$TOOL" sign -k x -a ES256 -i y -o z --aad w >/dev/null 2>&1; then bad "counter-only option on sign exits non-zero"; else ok "counter-only option on sign exits non-zero"; fi +if "$TOOL" sign -k x -a ESP256 -i y -o z --aad w >/dev/null 2>&1; then bad "counter-only option on sign exits non-zero"; else ok "counter-only option on sign exits non-zero"; fi head -c 65536 /dev/zero > "$WORK/oversize.bin" if "$TOOL" verify -k "$WORK/oversize.bin" -i "$WORK/oversize.bin" 2>&1 | grep -q "File too large"; then ok "oversized input file is rejected, not truncated"; else bad "oversized input file is rejected, not truncated"; fi -if "$TOOL" countersign -k x -a ES256 -i y -o z --index 1 >/dev/null 2>&1; then bad "--index on countersign exits non-zero"; else ok "--index on countersign exits non-zero"; fi +if "$TOOL" countersign -k x -a ESP256 -i y -o z --index 1 >/dev/null 2>&1; then bad "--index on countersign exits non-zero"; else ok "--index on countersign exits non-zero"; fi echo echo "== Command-line test summary: $PASS passed, $FAIL failed, $SKIP skipped ==" diff --git a/src/wolfcose_alg.c b/src/wolfcose_alg.c index abc94fc3..c5083da1 100644 --- a/src/wolfcose_alg.c +++ b/src/wolfcose_alg.c @@ -59,22 +59,39 @@ int wolfCose_AlgToHashType(int32_t alg, enum wc_HashType* hashType) else { switch (alg) { #ifdef WOLFCOSE_HAVE_ES256 +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS case WOLFCOSE_ALG_ES256: +#endif + case WOLFCOSE_ALG_ESP256: *hashType = WC_HASH_TYPE_SHA256; break; #endif #ifdef WOLFCOSE_HAVE_ES384 +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS case WOLFCOSE_ALG_ES384: +#endif + case WOLFCOSE_ALG_ESP384: *hashType = WC_HASH_TYPE_SHA384; break; #endif #ifdef WOLFCOSE_HAVE_ES512 +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS case WOLFCOSE_ALG_ES512: +#endif + case WOLFCOSE_ALG_ESP512: *hashType = WC_HASH_TYPE_SHA512; break; #endif #if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS case WOLFCOSE_ALG_EDDSA: +#endif +#ifdef WOLFCOSE_HAVE_EDDSA + case WOLFCOSE_ALG_ED25519: +#endif +#ifdef WOLFCOSE_HAVE_ED448 + case WOLFCOSE_ALG_ED448: +#endif /* RFC 9053 Section 2.2: EdDSA hashes the message internally * with SHA-512 (Ed25519) or SHAKE-256 (Ed448). The "external" * hash type is unused; SHA-512 stands in for both. */ @@ -114,21 +131,31 @@ WOLFCOSE_LOCAL int wolfCose_SigSize(int32_t alg, size_t* sigSz) else { switch (alg) { #ifdef WOLFCOSE_HAVE_ES256 +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS case WOLFCOSE_ALG_ES256: +#endif + case WOLFCOSE_ALG_ESP256: *sigSz = 64; /* r(32) || s(32) */ break; #endif #ifdef WOLFCOSE_HAVE_ES384 +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS case WOLFCOSE_ALG_ES384: +#endif + case WOLFCOSE_ALG_ESP384: *sigSz = 96; /* r(48) || s(48) */ break; #endif #ifdef WOLFCOSE_HAVE_ES512 +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS case WOLFCOSE_ALG_ES512: +#endif + case WOLFCOSE_ALG_ESP512: *sigSz = 132; /* r(66) || s(66) */ break; #endif -#if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) +#if (defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448)) && \ + defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) case WOLFCOSE_ALG_EDDSA: /* Returns the worst-case signature size when both curves * are available so caller buffers are always sufficient. */ @@ -139,6 +166,16 @@ WOLFCOSE_LOCAL int wolfCose_SigSize(int32_t alg, size_t* sigSz) #endif break; #endif +#ifdef WOLFCOSE_HAVE_EDDSA + case WOLFCOSE_ALG_ED25519: + *sigSz = 64; + break; +#endif +#ifdef WOLFCOSE_HAVE_ED448 + case WOLFCOSE_ALG_ED448: + *sigSz = 114; + break; +#endif #ifdef WOLFCOSE_HAVE_MLDSA case WOLFCOSE_ALG_ML_DSA_44: *sigSz = 2420; @@ -158,6 +195,118 @@ WOLFCOSE_LOCAL int wolfCose_SigSize(int32_t alg, size_t* sigSz) return ret; } +/* The ECDSA/EdDSA algorithm set lives once, in wolfCose_AlgToCrv; the family + * predicates derive from it so a new codepoint is added in one place. An ECDSA + * alg maps to a NIST P-curve, an EdDSA alg to an OKP curve or (for the + * deprecated polymorphic WOLFCOSE_ALG_EDDSA) to crv 0. */ +WOLFCOSE_LOCAL int wolfCose_AlgIsEcdsa(int32_t alg) +{ + int isEcdsa = 0; +#if defined(WOLFCOSE_HAVE_ECDSA) + int32_t crv = 0; + if (wolfCose_AlgToCrv(alg, &crv) == WOLFCOSE_SUCCESS) { + if ((crv == WOLFCOSE_CRV_P256) || (crv == WOLFCOSE_CRV_P384) || + (crv == WOLFCOSE_CRV_P521)) { + isEcdsa = 1; + } + } +#else + (void)alg; +#endif + return isEcdsa; +} + +WOLFCOSE_LOCAL int wolfCose_AlgIsEddsa(int32_t alg) +{ + int isEddsa = 0; +#if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) + int32_t crv = 0; + if (wolfCose_AlgToCrv(alg, &crv) == WOLFCOSE_SUCCESS) { + if ((crv == WOLFCOSE_CRV_ED25519) || (crv == WOLFCOSE_CRV_ED448) || + (crv == 0)) { + isEddsa = 1; + } + } +#else + (void)alg; +#endif + return isEddsa; +} + +#if defined(WOLFCOSE_HAVE_ECDSA) || defined(WOLFCOSE_HAVE_EDDSA) || \ + defined(WOLFCOSE_HAVE_ED448) +WOLFCOSE_LOCAL int wolfCose_AlgToCrv(int32_t alg, int32_t* crv) +{ + int ret = WOLFCOSE_SUCCESS; + + if (crv == NULL) { + ret = WOLFCOSE_E_INVALID_ARG; + } + else { + switch (alg) { +#ifdef WOLFCOSE_HAVE_ES256 +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS + case WOLFCOSE_ALG_ES256: +#endif + case WOLFCOSE_ALG_ESP256: + *crv = WOLFCOSE_CRV_P256; + break; +#endif +#ifdef WOLFCOSE_HAVE_ES384 +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS + case WOLFCOSE_ALG_ES384: +#endif + case WOLFCOSE_ALG_ESP384: + *crv = WOLFCOSE_CRV_P384; + break; +#endif +#ifdef WOLFCOSE_HAVE_ES512 +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS + case WOLFCOSE_ALG_ES512: +#endif + case WOLFCOSE_ALG_ESP512: + *crv = WOLFCOSE_CRV_P521; + break; +#endif +#if (defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448)) && \ + defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) + case WOLFCOSE_ALG_EDDSA: + /* Polymorphic: the key's OKP curve selects Ed25519 or Ed448. */ + *crv = 0; + break; +#endif +#ifdef WOLFCOSE_HAVE_EDDSA + case WOLFCOSE_ALG_ED25519: + *crv = WOLFCOSE_CRV_ED25519; + break; +#endif +#ifdef WOLFCOSE_HAVE_ED448 + case WOLFCOSE_ALG_ED448: + *crv = WOLFCOSE_CRV_ED448; + break; +#endif + default: + ret = WOLFCOSE_E_COSE_BAD_ALG; + break; + } + } + return ret; +} + +WOLFCOSE_LOCAL int wolfCose_AlgCheckCrv(int32_t alg, int32_t crv) +{ + int ret; + int32_t expectedCrv = 0; + + ret = wolfCose_AlgToCrv(alg, &expectedCrv); + if ((ret == WOLFCOSE_SUCCESS) && (expectedCrv != 0) && + (crv != expectedCrv)) { + ret = WOLFCOSE_E_COSE_BAD_ALG; + } + return ret; +} +#endif /* WOLFCOSE_HAVE_ECDSA || WOLFCOSE_HAVE_EDDSA || WOLFCOSE_HAVE_ED448 */ + int wolfCose_CrvKeySize(int32_t crv, size_t* keySz) { int ret = WOLFCOSE_SUCCESS; diff --git a/src/wolfcose_countersign.c b/src/wolfcose_countersign.c index b453bc9f..83d7bbd1 100644 --- a/src/wolfcose_countersign.c +++ b/src/wolfcose_countersign.c @@ -708,30 +708,19 @@ static int wolfCose_CounterSignTbs(WOLFCOSE_KEY* key, int32_t alg, else #endif #ifdef WOLFCOSE_HAVE_ECDSA - if ((ret == WOLFCOSE_SUCCESS) && - ((alg == WOLFCOSE_ALG_ES256) || (alg == WOLFCOSE_ALG_ES384) || - (alg == WOLFCOSE_ALG_ES512))) { + if ((ret == WOLFCOSE_SUCCESS) && (wolfCose_AlgIsEcdsa(alg) != 0)) { enum wc_HashType hashType = WC_HASH_TYPE_NONE; int digestSz = 0; - int32_t expectedCrv; size_t coordSz = 0u; - if (alg == WOLFCOSE_ALG_ES256) { - expectedCrv = WOLFCOSE_CRV_P256; - } - else if (alg == WOLFCOSE_ALG_ES384) { - expectedCrv = WOLFCOSE_CRV_P384; - } - else { - expectedCrv = WOLFCOSE_CRV_P521; - } if (key->kty != WOLFCOSE_KTY_EC2) { ret = WOLFCOSE_E_COSE_KEY_TYPE; } - else if (key->crv != expectedCrv) { - ret = WOLFCOSE_E_COSE_BAD_ALG; + /* Each ECDSA alg is bound to one curve. */ + if (ret == WOLFCOSE_SUCCESS) { + ret = wolfCose_AlgCheckCrv(alg, key->crv); } - else { + if (ret == WOLFCOSE_SUCCESS) { ret = wolfCose_EccKeyCheckCurve(key->crv, key->key.ecc); } if (ret == WOLFCOSE_SUCCESS) { @@ -764,12 +753,15 @@ static int wolfCose_CounterSignTbs(WOLFCOSE_KEY* key, int32_t alg, else #endif #if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) - if ((ret == WOLFCOSE_SUCCESS) && (alg == WOLFCOSE_ALG_EDDSA)) { + if ((ret == WOLFCOSE_SUCCESS) && (wolfCose_AlgIsEddsa(alg) != 0)) { word32 outLen = (word32)sigSz; if (key->kty != WOLFCOSE_KTY_OKP) { ret = WOLFCOSE_E_COSE_KEY_TYPE; } + if (ret == WOLFCOSE_SUCCESS) { + ret = wolfCose_AlgCheckCrv(alg, key->crv); + } #ifdef WOLFCOSE_HAVE_EDDSA if ((ret == WOLFCOSE_SUCCESS) && (key->crv == WOLFCOSE_CRV_ED25519)) { @@ -925,12 +917,15 @@ static int wolfCose_CounterVerifyTbs(const WOLFCOSE_KEY* key, int32_t alg, } #if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) - if ((ret == WOLFCOSE_SUCCESS) && (alg == WOLFCOSE_ALG_EDDSA)) { + if ((ret == WOLFCOSE_SUCCESS) && (wolfCose_AlgIsEddsa(alg) != 0)) { int verified = 0; if (key->kty != WOLFCOSE_KTY_OKP) { ret = WOLFCOSE_E_COSE_KEY_TYPE; } + if (ret == WOLFCOSE_SUCCESS) { + ret = wolfCose_AlgCheckCrv(alg, key->crv); + } #ifdef WOLFCOSE_HAVE_EDDSA if ((ret == WOLFCOSE_SUCCESS) && (key->crv == WOLFCOSE_CRV_ED25519)) { @@ -985,32 +980,21 @@ static int wolfCose_CounterVerifyTbs(const WOLFCOSE_KEY* key, int32_t alg, else #endif #ifdef WOLFCOSE_HAVE_ECDSA - if ((ret == WOLFCOSE_SUCCESS) && - ((alg == WOLFCOSE_ALG_ES256) || (alg == WOLFCOSE_ALG_ES384) || - (alg == WOLFCOSE_ALG_ES512))) { + if ((ret == WOLFCOSE_SUCCESS) && (wolfCose_AlgIsEcdsa(alg) != 0)) { ecc_key* eccKey = NULL; enum wc_HashType hashType = WC_HASH_TYPE_NONE; int digestSz = 0; int verified = 0; - int32_t expectedCrv; size_t coordSz = 0u; - if (alg == WOLFCOSE_ALG_ES256) { - expectedCrv = WOLFCOSE_CRV_P256; - } - else if (alg == WOLFCOSE_ALG_ES384) { - expectedCrv = WOLFCOSE_CRV_P384; - } - else { - expectedCrv = WOLFCOSE_CRV_P521; - } if (key->kty != WOLFCOSE_KTY_EC2) { ret = WOLFCOSE_E_COSE_KEY_TYPE; } - else if (key->crv != expectedCrv) { - ret = WOLFCOSE_E_COSE_BAD_ALG; + /* Each ECDSA alg is bound to one curve. */ + if (ret == WOLFCOSE_SUCCESS) { + ret = wolfCose_AlgCheckCrv(alg, key->crv); } - else { + if (ret == WOLFCOSE_SUCCESS) { eccKey = key->key.ecc; ret = wolfCose_EccKeyCheckCurve(key->crv, eccKey); } diff --git a/src/wolfcose_internal.h b/src/wolfcose_internal.h index 417079a4..82def28d 100644 --- a/src/wolfcose_internal.h +++ b/src/wolfcose_internal.h @@ -316,6 +316,39 @@ WOLFCOSE_LOCAL int wolfCose_AlgToHashType(int32_t alg, */ WOLFCOSE_LOCAL int wolfCose_SigSize(int32_t alg, size_t* sigSz); +/** + * \brief Report whether alg is an ECDSA algorithm this build supports. + * \param alg COSE algorithm ID. + * \return 1 for ESP256/ESP384/ESP512 (and deprecated ES*), else 0. + */ +WOLFCOSE_LOCAL int wolfCose_AlgIsEcdsa(int32_t alg); + +/** + * \brief Report whether alg is an EdDSA algorithm this build supports. + * \param alg COSE algorithm ID. + * \return 1 for Ed25519/Ed448 (and deprecated EdDSA), else 0. + */ +WOLFCOSE_LOCAL int wolfCose_AlgIsEddsa(int32_t alg); + +#if defined(WOLFCOSE_HAVE_ECDSA) || defined(WOLFCOSE_HAVE_EDDSA) || \ + defined(WOLFCOSE_HAVE_ED448) +/** + * \brief Get the curve a signature algorithm is bound to (RFC 9864). + * \param alg COSE algorithm ID. + * \param crv Output: COSE curve ID, or 0 when alg binds none (EdDSA). + * \return WOLFCOSE_SUCCESS or WOLFCOSE_E_COSE_BAD_ALG. + */ +WOLFCOSE_LOCAL int wolfCose_AlgToCrv(int32_t alg, int32_t* crv); + +/** + * \brief Reject a key curve that differs from the one alg is bound to. + * \param alg COSE algorithm ID. + * \param crv COSE curve ID of the key. + * \return WOLFCOSE_SUCCESS or WOLFCOSE_E_COSE_BAD_ALG. + */ +WOLFCOSE_LOCAL int wolfCose_AlgCheckCrv(int32_t alg, int32_t crv); +#endif + /** * \brief Get key size (coordinate size) for a COSE curve. * \param crv COSE curve ID. diff --git a/src/wolfcose_sign.c b/src/wolfcose_sign.c index 6c12ac0b..0d7de492 100644 --- a/src/wolfcose_sign.c +++ b/src/wolfcose_sign.c @@ -268,23 +268,12 @@ int wc_CoseSign_Sign(const WOLFCOSE_SIGNATURE* signers, size_t signerCount, } #endif #ifdef WOLFCOSE_HAVE_ECDSA - else if ((signers[i].algId == WOLFCOSE_ALG_ES256) || - (signers[i].algId == WOLFCOSE_ALG_ES384) || - (signers[i].algId == WOLFCOSE_ALG_ES512)) { - int32_t expectedCrv; - if (signers[i].algId == WOLFCOSE_ALG_ES256) { - expectedCrv = WOLFCOSE_CRV_P256; - } - else if (signers[i].algId == WOLFCOSE_ALG_ES384) { - expectedCrv = WOLFCOSE_CRV_P384; - } - else { - expectedCrv = WOLFCOSE_CRV_P521; - } + else if (wolfCose_AlgIsEcdsa(signers[i].algId) != 0) { if (signerKey->kty != WOLFCOSE_KTY_EC2) { ret = WOLFCOSE_E_COSE_KEY_TYPE; } - else if (signerKey->crv != expectedCrv) { + else if (wolfCose_AlgCheckCrv(signers[i].algId, + signerKey->crv) != WOLFCOSE_SUCCESS) { ret = WOLFCOSE_E_COSE_BAD_ALG; } else if (wolfCose_EccKeyCheckCurve(signerKey->crv, @@ -297,9 +286,13 @@ int wc_CoseSign_Sign(const WOLFCOSE_SIGNATURE* signers, size_t signerCount, } #endif #if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) - else if ((signers[i].algId == WOLFCOSE_ALG_EDDSA) && - (signerKey->kty != WOLFCOSE_KTY_OKP)) { - ret = WOLFCOSE_E_COSE_KEY_TYPE; + else if (wolfCose_AlgIsEddsa(signers[i].algId) != 0) { + if (signerKey->kty != WOLFCOSE_KTY_OKP) { + ret = WOLFCOSE_E_COSE_KEY_TYPE; + } + else { + ret = wolfCose_AlgCheckCrv(signers[i].algId, signerKey->crv); + } } #endif #ifdef WOLFCOSE_HAVE_RSAPSS @@ -534,7 +527,7 @@ int wc_CoseSign_Sign(const WOLFCOSE_SIGNATURE* signers, size_t signerCount, #if defined(WOLFCOSE_EXT_SIGN) (signerKey->signCb == NULL) && #endif - (signer->algId != WOLFCOSE_ALG_EDDSA) && + (wolfCose_AlgIsEddsa(signer->algId) == 0) && (signer->algId != WOLFCOSE_ALG_ML_DSA_44) && (signer->algId != WOLFCOSE_ALG_ML_DSA_65) && (signer->algId != WOLFCOSE_ALG_ML_DSA_87) && @@ -586,9 +579,7 @@ int wc_CoseSign_Sign(const WOLFCOSE_SIGNATURE* signers, size_t signerCount, #endif #ifdef WOLFCOSE_HAVE_ECDSA if ((ret == WOLFCOSE_SUCCESS) && - ((signer->algId == WOLFCOSE_ALG_ES256) || - (signer->algId == WOLFCOSE_ALG_ES384) || - (signer->algId == WOLFCOSE_ALG_ES512))) { + (wolfCose_AlgIsEcdsa(signer->algId) != 0)) { size_t coordSz = 0; ret = wolfCose_CrvKeySize(signerKey->crv, &coordSz); if (ret == WOLFCOSE_SUCCESS) { @@ -603,7 +594,7 @@ int wc_CoseSign_Sign(const WOLFCOSE_SIGNATURE* signers, size_t signerCount, #endif #if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) if ((ret == WOLFCOSE_SUCCESS) && - (signer->algId == WOLFCOSE_ALG_EDDSA)) { + (wolfCose_AlgIsEddsa(signer->algId) != 0)) { word32 edSigSz = (word32)sizeof(sigBuf); #ifdef WOLFCOSE_HAVE_EDDSA if (signerKey->crv == WOLFCOSE_CRV_ED25519) { @@ -1059,7 +1050,7 @@ int wc_CoseSign_Verify(const WOLFCOSE_KEY* verifyKey, * HSS-LMS verify against the raw Sig_structure so the hash type * lookup is skipped (also avoids WOLFCOSE_E_COSE_BAD_ALG since * these algorithms have no external hash). */ - if ((ret == WOLFCOSE_SUCCESS) && (alg != WOLFCOSE_ALG_EDDSA) && + if ((ret == WOLFCOSE_SUCCESS) && (wolfCose_AlgIsEddsa(alg) == 0) && (alg != WOLFCOSE_ALG_ML_DSA_44) && (alg != WOLFCOSE_ALG_ML_DSA_65) && (alg != WOLFCOSE_ALG_ML_DSA_87) && @@ -1069,7 +1060,7 @@ int wc_CoseSign_Verify(const WOLFCOSE_KEY* verifyKey, /* Hash the Sig_structure for algorithms that pre-hash. EdDSA, * ML-DSA and HSS-LMS verify the structure directly. */ - if ((ret == WOLFCOSE_SUCCESS) && (alg != WOLFCOSE_ALG_EDDSA) && + if ((ret == WOLFCOSE_SUCCESS) && (wolfCose_AlgIsEddsa(alg) == 0) && (alg != WOLFCOSE_ALG_ML_DSA_44) && (alg != WOLFCOSE_ALG_ML_DSA_65) && (alg != WOLFCOSE_ALG_ML_DSA_87) && @@ -1091,28 +1082,16 @@ int wc_CoseSign_Verify(const WOLFCOSE_KEY* verifyKey, /* Verify signature. Dispatch by alg (consistent with Sign1_Verify) and * cross-validate the verify-key type against the algorithm. */ #ifdef WOLFCOSE_HAVE_ECDSA - if ((ret == WOLFCOSE_SUCCESS) && - ((alg == WOLFCOSE_ALG_ES256) || (alg == WOLFCOSE_ALG_ES384) || - (alg == WOLFCOSE_ALG_ES512))) { + if ((ret == WOLFCOSE_SUCCESS) && (wolfCose_AlgIsEcdsa(alg) != 0)) { ecc_key* eccKey = NULL; int verified = 0; size_t coordSz = 0; - int32_t expectedCrv; if ((verifyKey->kty != WOLFCOSE_KTY_EC2) || (verifyKey->attachedType != WOLFCOSE_ATT_ECC)) { ret = WOLFCOSE_E_COSE_KEY_TYPE; } - if (alg == WOLFCOSE_ALG_ES256) { - expectedCrv = WOLFCOSE_CRV_P256; - } - else if (alg == WOLFCOSE_ALG_ES384) { - expectedCrv = WOLFCOSE_CRV_P384; - } - else { - expectedCrv = WOLFCOSE_CRV_P521; - } - if ((ret == WOLFCOSE_SUCCESS) && (verifyKey->crv != expectedCrv)) { - ret = WOLFCOSE_E_COSE_BAD_ALG; + if (ret == WOLFCOSE_SUCCESS) { + ret = wolfCose_AlgCheckCrv(alg, verifyKey->crv); } if (ret == WOLFCOSE_SUCCESS) { eccKey = verifyKey->key.ecc; @@ -1134,11 +1113,14 @@ int wc_CoseSign_Verify(const WOLFCOSE_KEY* verifyKey, else #endif #if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) - if ((ret == WOLFCOSE_SUCCESS) && (alg == WOLFCOSE_ALG_EDDSA)) { + if ((ret == WOLFCOSE_SUCCESS) && (wolfCose_AlgIsEddsa(alg) != 0)) { int verified = 0; if (verifyKey->kty != WOLFCOSE_KTY_OKP) { ret = WOLFCOSE_E_COSE_KEY_TYPE; } + if (ret == WOLFCOSE_SUCCESS) { + ret = wolfCose_AlgCheckCrv(alg, verifyKey->crv); + } #ifdef WOLFCOSE_HAVE_EDDSA if ((ret == WOLFCOSE_SUCCESS) && (verifyKey->crv == WOLFCOSE_CRV_ED25519)) { diff --git a/src/wolfcose_sign1.c b/src/wolfcose_sign1.c index bd774aca..8688a096 100644 --- a/src/wolfcose_sign1.c +++ b/src/wolfcose_sign1.c @@ -134,7 +134,8 @@ int wolfCose_SignSigLen(const WOLFCOSE_KEY* key, int32_t alg, (void)key; switch (alg) { -#if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) +#if (defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448)) && \ + defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) case WOLFCOSE_ALG_EDDSA: if (key == NULL) { #if defined(WOLFCOSE_HAVE_EDDSA) && defined(WOLFCOSE_HAVE_ED448) @@ -205,29 +206,29 @@ int wolfCose_SignSigLen(const WOLFCOSE_KEY* key, int32_t alg, #endif default: ret = wolfCose_SigSize(alg, expSigLen); -#if defined(WOLFCOSE_HAVE_ECDSA) - /* ES* lengths come from alg alone, so a declared curve would +#if defined(WOLFCOSE_HAVE_ECDSA) || defined(WOLFCOSE_HAVE_EDDSA) || \ + defined(WOLFCOSE_HAVE_ED448) + /* Lengths come from alg alone, so a declared curve would * otherwise be ignored here while the local path rejects it. - * crv 0 means the caller declared none, which stays legal. */ - if (ret == WOLFCOSE_SUCCESS) { + * kty or crv 0 means the caller declared none, which stays legal; + * an alg outside the ECDSA and EdDSA families binds no curve. */ + if ((ret == WOLFCOSE_SUCCESS) && (key != NULL)) { int32_t expectedCrv = 0; - if (alg == WOLFCOSE_ALG_ES256) { - expectedCrv = WOLFCOSE_CRV_P256; - } - else if (alg == WOLFCOSE_ALG_ES384) { - expectedCrv = WOLFCOSE_CRV_P384; + int32_t expectedKty = 0; + int bound = wolfCose_AlgToCrv(alg, &expectedCrv); + + if (wolfCose_AlgIsEcdsa(alg) != 0) { + expectedKty = WOLFCOSE_KTY_EC2; } - else if (alg == WOLFCOSE_ALG_ES512) { - expectedCrv = WOLFCOSE_CRV_P521; + else if (wolfCose_AlgIsEddsa(alg) != 0) { + expectedKty = WOLFCOSE_KTY_OKP; } else { - /* No action required */ + /* No action required: alg binds no key type. */ } - /* expectedCrv stays 0 for non-ECDSA, which this arm does not - * bind. A declared kty or crv is honoured for ES* the way the - * local path does; 0 means the caller declared none. */ - if ((key != NULL) && (expectedCrv != 0)) { - if ((key->kty != 0) && (key->kty != WOLFCOSE_KTY_EC2)) { + if ((bound == WOLFCOSE_SUCCESS) && (expectedCrv != 0) && + (expectedKty != 0)) { + if ((key->kty != 0) && (key->kty != expectedKty)) { ret = WOLFCOSE_E_COSE_KEY_TYPE; } else if ((key->crv != 0) && (key->crv != expectedCrv)) { @@ -255,17 +256,26 @@ int wolfCose_ExtSignAlg(int32_t alg, WOLFCOSE_PREHASH_FLAG* preHashes) switch (alg) { #if defined(WOLFCOSE_HAVE_ES256) +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS case WOLFCOSE_ALG_ES256: +#endif + case WOLFCOSE_ALG_ESP256: *preHashes = (WOLFCOSE_PREHASH_FLAG)1u; break; #endif #if defined(WOLFCOSE_HAVE_ES384) +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS case WOLFCOSE_ALG_ES384: +#endif + case WOLFCOSE_ALG_ESP384: *preHashes = (WOLFCOSE_PREHASH_FLAG)1u; break; #endif #if defined(WOLFCOSE_HAVE_ES512) +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS case WOLFCOSE_ALG_ES512: +#endif + case WOLFCOSE_ALG_ESP512: *preHashes = (WOLFCOSE_PREHASH_FLAG)1u; break; #endif @@ -284,8 +294,17 @@ int wolfCose_ExtSignAlg(int32_t alg, WOLFCOSE_PREHASH_FLAG* preHashes) *preHashes = (WOLFCOSE_PREHASH_FLAG)1u; break; #endif -#if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) +#if (defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448)) && \ + defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) case WOLFCOSE_ALG_EDDSA: +#endif +#if defined(WOLFCOSE_HAVE_EDDSA) + case WOLFCOSE_ALG_ED25519: +#endif +#if defined(WOLFCOSE_HAVE_ED448) + case WOLFCOSE_ALG_ED448: +#endif +#if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) *preHashes = (WOLFCOSE_PREHASH_FLAG)0u; break; #endif @@ -688,11 +707,14 @@ int wc_CoseSign1_Sign_ex(WOLFCOSE_KEY* key, int32_t alg, else #endif #if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) - if ((ret == WOLFCOSE_SUCCESS) && (alg == WOLFCOSE_ALG_EDDSA)) { + if ((ret == WOLFCOSE_SUCCESS) && (wolfCose_AlgIsEddsa(alg) != 0)) { word32 edSigLen = (word32)sizeof(sigBuf); if (key->kty != WOLFCOSE_KTY_OKP) { ret = WOLFCOSE_E_COSE_KEY_TYPE; } + if (ret == WOLFCOSE_SUCCESS) { + ret = wolfCose_AlgCheckCrv(alg, key->crv); + } /* EdDSA signs raw Sig_structure (no pre-hash) */ if (ret == WOLFCOSE_SUCCESS) { #ifdef WOLFCOSE_HAVE_EDDSA @@ -745,8 +767,7 @@ int wc_CoseSign1_Sign_ex(WOLFCOSE_KEY* key, int32_t alg, else #endif /* WOLFCOSE_HAVE_EDDSA || WOLFCOSE_HAVE_ED448 */ #ifdef WOLFCOSE_HAVE_ECDSA - if ((ret == WOLFCOSE_SUCCESS) && ((alg == WOLFCOSE_ALG_ES256) || - (alg == WOLFCOSE_ALG_ES384) || (alg == WOLFCOSE_ALG_ES512))) { + if ((ret == WOLFCOSE_SUCCESS) && (wolfCose_AlgIsEcdsa(alg) != 0)) { enum wc_HashType hashType; int digestSz = 0; size_t coordSz = 0; @@ -757,19 +778,7 @@ int wc_CoseSign1_Sign_ex(WOLFCOSE_KEY* key, int32_t alg, /* Each ECDSA alg is bound to one curve. */ if (ret == WOLFCOSE_SUCCESS) { - int32_t expectedCrv; - if (alg == WOLFCOSE_ALG_ES256) { - expectedCrv = WOLFCOSE_CRV_P256; - } - else if (alg == WOLFCOSE_ALG_ES384) { - expectedCrv = WOLFCOSE_CRV_P384; - } - else { - expectedCrv = WOLFCOSE_CRV_P521; - } - if (key->crv != expectedCrv) { - ret = WOLFCOSE_E_COSE_BAD_ALG; - } + ret = wolfCose_AlgCheckCrv(alg, key->crv); } if (ret == WOLFCOSE_SUCCESS) { @@ -1206,11 +1215,14 @@ int wolfCose_Sign1_Verify_ex(const WOLFCOSE_KEY* key, /* Verify based on algorithm */ #if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) - if ((ret == WOLFCOSE_SUCCESS) && (alg == WOLFCOSE_ALG_EDDSA)) { + if ((ret == WOLFCOSE_SUCCESS) && (wolfCose_AlgIsEddsa(alg) != 0)) { int verified = 0; if (key->kty != WOLFCOSE_KTY_OKP) { ret = WOLFCOSE_E_COSE_KEY_TYPE; } + if (ret == WOLFCOSE_SUCCESS) { + ret = wolfCose_AlgCheckCrv(alg, key->crv); + } #ifdef WOLFCOSE_HAVE_EDDSA if ((ret == WOLFCOSE_SUCCESS) && (key->crv == WOLFCOSE_CRV_ED25519)) { if (key->attachedType != WOLFCOSE_ATT_ED25519) { @@ -1273,9 +1285,7 @@ int wolfCose_Sign1_Verify_ex(const WOLFCOSE_KEY* key, else #endif #ifdef WOLFCOSE_HAVE_ECDSA - if ((ret == WOLFCOSE_SUCCESS) && - ((alg == WOLFCOSE_ALG_ES256) || (alg == WOLFCOSE_ALG_ES384) || - (alg == WOLFCOSE_ALG_ES512))) { + if ((ret == WOLFCOSE_SUCCESS) && (wolfCose_AlgIsEcdsa(alg) != 0)) { ecc_key* eccKey = NULL; int verified = 0; size_t coordSz = 0; @@ -1288,19 +1298,7 @@ int wolfCose_Sign1_Verify_ex(const WOLFCOSE_KEY* key, } /* Each ECDSA alg is bound to one curve. */ if (ret == WOLFCOSE_SUCCESS) { - int32_t expectedCrv; - if (alg == WOLFCOSE_ALG_ES256) { - expectedCrv = WOLFCOSE_CRV_P256; - } - else if (alg == WOLFCOSE_ALG_ES384) { - expectedCrv = WOLFCOSE_CRV_P384; - } - else { - expectedCrv = WOLFCOSE_CRV_P521; - } - if (key->crv != expectedCrv) { - ret = WOLFCOSE_E_COSE_BAD_ALG; - } + ret = wolfCose_AlgCheckCrv(alg, key->crv); } if (ret == WOLFCOSE_SUCCESS) { eccKey = key->key.ecc; diff --git a/tests/test_cose.c b/tests/test_cose.c index ff2372a8..49ca589c 100644 --- a/tests/test_cose.c +++ b/tests/test_cose.c @@ -285,7 +285,7 @@ static void test_cose_countersign_ecdsa_curves(void) TEST_ASSERT(ret == 0, "ES384 countersign key"); if (ret == 0) { ret = test_cose_countersign_roundtrip(&signKey, &signKey, - WOLFCOSE_ALG_ES384, &rng, "ES384"); + WOLFCOSE_ALG_ESP384, &rng, "ESP384"); wc_CoseKey_Free(&signKey); } (void)wc_ecc_free(&eccKey); @@ -308,8 +308,8 @@ static void test_cose_countersign_ecdsa_curves(void) } TEST_ASSERT(ret == 0, "ES512 countersign key"); if (ret == 0) { - (void)test_cose_countersign_roundtrip(&signKey, &signKey, - WOLFCOSE_ALG_ES512, &rng, "ES512"); + ret = test_cose_countersign_roundtrip(&signKey, &signKey, + WOLFCOSE_ALG_ESP512, &rng, "ESP512"); wc_CoseKey_Free(&signKey); } (void)wc_ecc_free(&eccKey); @@ -716,7 +716,7 @@ static void test_cose_key_ed25519(void) "key set ed25519"); key.kid = kid; key.kidLen = sizeof(kid) - 1u; - key.alg = WOLFCOSE_ALG_EDDSA; + key.alg = WOLFCOSE_ALG_ED25519; /* Encode/decode round-trip */ /* empty-brace-scan: allow - test-local temporary scope */ @@ -738,7 +738,7 @@ static void test_cose_key_ed25519(void) ret = wc_CoseKey_Decode(&key2, cbuf, cLen); TEST_ASSERT(ret == 0 && key2.kty == WOLFCOSE_KTY_OKP && key2.hasPrivate == 1 && - key2.alg == WOLFCOSE_ALG_EDDSA && + key2.alg == WOLFCOSE_ALG_ED25519 && key2.kidLen == (sizeof(kid) - 1u) && memcmp(key2.kid, kid, sizeof(kid) - 1u) == 0, "key ed decode"); @@ -1084,7 +1084,7 @@ static void test_cose_sign1_ecc(const char* label, int32_t alg, int32_t crv, if (ret == 0) { /* Error: null args */ int nullRet; - nullRet = wc_CoseSign1_Sign(NULL, WOLFCOSE_ALG_ES256, NULL, 0, + nullRet = wc_CoseSign1_Sign(NULL, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload), NULL, 0, NULL, 0, scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); TEST_ASSERT(nullRet == WOLFCOSE_E_INVALID_ARG, "sign1 null key"); @@ -1102,7 +1102,7 @@ static void test_cose_sign1_ecc(const char* label, int32_t alg, int32_t crv, pubOnly.kty = WOLFCOSE_KTY_EC2; pubOnly.hasPrivate = 0; pubOnly.key.ecc = &eccKey; - pubRet = wc_CoseSign1_Sign(&pubOnly, WOLFCOSE_ALG_ES256, NULL, 0, + pubRet = wc_CoseSign1_Sign(&pubOnly, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload), NULL, 0, NULL, 0, scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); TEST_ASSERT(pubRet == WOLFCOSE_E_COSE_KEY_TYPE, "sign1 no privkey"); @@ -1256,7 +1256,7 @@ static void test_cose_sign1_ext_sign(void) TEST_ASSERT(signKey.key.ecc == NULL, "ext-sign no local ecc key"); } if (ret == 0) { - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ESP256, kid, sizeof(kid) - 1, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, @@ -1282,14 +1282,14 @@ static void test_cose_sign1_ext_sign(void) (decPayload != NULL) && memcmp(decPayload, payload, decPayloadLen) == 0, "ext-sign payload match"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ES256, "ext-sign hdr alg"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ESP256, "ext-sign hdr alg"); } #if defined(WOLFCOSE_COUNTERSIGN_SIGN) && \ defined(WOLFCOSE_COUNTERSIGN_VERIFY) if (ret == 0) { ret = test_cose_countersign_roundtrip(&signKey, &verifyKey, - WOLFCOSE_ALG_ES256, NULL, "external ES256"); + WOLFCOSE_ALG_ESP256, NULL, "external ESP256"); } #endif @@ -1301,7 +1301,7 @@ static void test_cose_sign1_ext_sign(void) int badRet; (void)wc_CoseKey_Init(&badKey); (void)wc_CoseKey_SetExtSigner(&badKey, test_ext_sign_cb_badlen, NULL); - badRet = wc_CoseSign1_Sign(&badKey, WOLFCOSE_ALG_ES256, + badRet = wc_CoseSign1_Sign(&badKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), badOut, sizeof(badOut), &badOutLen, NULL); @@ -1323,7 +1323,7 @@ static void test_cose_sign1_ext_sign(void) injKey.crv = WOLFCOSE_CRV_P256; (void)wc_CoseKey_SetExtSigner(&injKey, test_ext_sign_cb, &ctx); wolfForceFailure_Set(WOLF_FAIL_EXT_SIGN); - injRet = wc_CoseSign1_Sign(&injKey, WOLFCOSE_ALG_ES256, + injRet = wc_CoseSign1_Sign(&injKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), injOut, sizeof(injOut), &injOutLen, NULL); @@ -1349,7 +1349,7 @@ static void test_cose_sign1_ext_sign(void) shortKey.kty = WOLFCOSE_KTY_EC2; shortKey.crv = WOLFCOSE_CRV_P256; (void)wc_CoseKey_SetExtSigner(&shortKey, test_ext_sign_cb_short, NULL); - shortRet = wc_CoseSign1_Sign(&shortKey, WOLFCOSE_ALG_ES256, NULL, 0, + shortRet = wc_CoseSign1_Sign(&shortKey, WOLFCOSE_ALG_ESP256, NULL, 0, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, scratch, sizeof(scratch), shortOut, sizeof(shortOut), &shortOutLen, NULL); @@ -1372,7 +1372,7 @@ static void test_cose_sign1_ext_sign(void) (void)wc_CoseKey_Init(&failKey); (void)wc_CoseKey_SetExtSigner(&failKey, test_ext_sign_cb_fail, NULL); - failRet = wc_CoseSign1_Sign(&failKey, WOLFCOSE_ALG_ES256, + failRet = wc_CoseSign1_Sign(&failKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), failOut, sizeof(failOut), &failOutLen, NULL); @@ -1396,7 +1396,7 @@ static void test_cose_sign1_ext_sign(void) WOLFCOSE_SUCCESS, "ext-sign detach accepted"); /* rng is supplied so the NULL-rng precheck cannot mask the result: * the detach itself must be what refuses the signature. */ - tmpRet = wc_CoseSign1_Sign(&tmp, WOLFCOSE_ALG_ES256, + tmpRet = wc_CoseSign1_Sign(&tmp, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), tmpOut, sizeof(tmpOut), &tmpOutLen, &rng); @@ -1420,7 +1420,7 @@ static void test_cose_sign1_ext_sign(void) reRet = wc_CoseKey_SetEcc(&reKey, WOLFCOSE_CRV_P256, &eccKey); TEST_ASSERT(reRet == WOLFCOSE_SUCCESS, "ext-sign SetEcc over signer"); calledBefore = ctx.called; - reRet = wc_CoseSign1_Sign(&reKey, WOLFCOSE_ALG_ES256, + reRet = wc_CoseSign1_Sign(&reKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), reOut, sizeof(reOut), &reOutLen, &rng); @@ -1466,7 +1466,7 @@ static void test_cose_sign1_ext_sign(void) TEST_ASSERT(privLen > 0u && privBuf[0] == 0xA5u, "ext-sign detach restores private scalar export"); privLen = 0; - privRet = wc_CoseSign1_Sign(&privKey, WOLFCOSE_ALG_ES256, + privRet = wc_CoseSign1_Sign(&privKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), privBuf, sizeof(privBuf), &privLen, &rng); @@ -1524,7 +1524,7 @@ static void test_cose_sign1_ext_sign(void) smallKey.kty = WOLFCOSE_KTY_EC2; smallKey.crv = WOLFCOSE_CRV_P256; (void)wc_CoseKey_SetExtSigner(&smallKey, test_ext_sign_cb, &ctx); - smallRet = wc_CoseSign1_Sign(&smallKey, WOLFCOSE_ALG_ES256, + smallRet = wc_CoseSign1_Sign(&smallKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, smallScratch, sizeof(smallScratch), smallOut, sizeof(smallOut), &smallOutLen, NULL); @@ -1591,7 +1591,7 @@ static void test_cose_sign1_ext_sign_eddsa_capacity(void) if (ret == 0) { /* scratch leaves well under 64 bytes once the Sig_structure is built */ - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_EDDSA, NULL, 0, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ED25519, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), out, sizeof(out), &outLen, NULL); TEST_ASSERT(ret == WOLFCOSE_E_BUFFER_TOO_SMALL, @@ -1669,7 +1669,7 @@ static void test_cose_sign1_ext_sign_ed25519(void) TEST_ASSERT(signKey.key.ed25519 == NULL, "ed25519 ext no local key"); } if (ret == 0) { - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_EDDSA, NULL, 0, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ED25519, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), out, sizeof(out), &outLen, NULL); TEST_ASSERT(ret == 0 && outLen > 0, "ed25519 ext delegated sign"); @@ -1687,7 +1687,7 @@ static void test_cose_sign1_ext_sign_ed25519(void) (decPayload != NULL) && memcmp(decPayload, payload, decPayloadLen) == 0, "ed25519 ext payload match"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_EDDSA, "ed25519 ext hdr alg"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ED25519, "ed25519 ext hdr alg"); } if (edInited != 0) { @@ -2043,11 +2043,11 @@ static void test_cose_sign_ext_sign_multi(void) TEST_ASSERT(ret == 0, "multi ext signer"); } - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = &localKey; signers[0].kid = kidA; signers[0].kidLen = sizeof(kidA) - 1; - signers[1].algId = WOLFCOSE_ALG_ES256; + signers[1].algId = WOLFCOSE_ALG_ESP256; signers[1].key = &extKey; signers[1].kid = kidB; signers[1].kidLen = sizeof(kidB) - 1; @@ -2142,7 +2142,7 @@ static void test_cose_sign_ext_sign_ed25519(void) TEST_ASSERT(ret == 0, "multi ed ext set signer"); } - signers[0].algId = WOLFCOSE_ALG_EDDSA; + signers[0].algId = WOLFCOSE_ALG_ED25519; signers[0].key = &signKey; signers[0].kid = NULL; signers[0].kidLen = 0; @@ -2193,7 +2193,7 @@ static void test_cose_sign1_eddsa(void) size_t decPayloadLen = 0; WOLFCOSE_HDR hdr; - TEST_LOG(" [Sign1 EdDSA]\n"); + TEST_LOG(" [Sign1 Ed25519]\n"); ret = wc_InitRng(&rng); if (ret != 0) { TEST_ASSERT(0, "rng init"); } @@ -2212,6 +2212,7 @@ static void test_cose_sign1_eddsa(void) (void)wc_CoseKey_Init(&signKey); (void)wc_CoseKey_SetEd25519(&signKey, &edKey); +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS #if defined(WOLFCOSE_HAVE_EDDSA) && defined(WOLFCOSE_HAVE_ED448) TEST_ASSERT(wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_EDDSA, 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen) == @@ -2221,21 +2222,26 @@ static void test_cose_sign1_eddsa(void) 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen) == 0, "sign1 eddsa size without key"); #endif - ret = wc_CoseSign1_SignSize_ex(&signKey, WOLFCOSE_ALG_EDDSA, +#endif /* WOLFCOSE_HAVE_DEPRECATED_ALGS */ + /* RFC 9864 Ed25519 pins the curve, so no key is needed to size. */ + TEST_ASSERT(wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ED25519, + 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen) == 0, + "sign1 ed25519 size without key"); + ret = wc_CoseSign1_SignSize_ex(&signKey, WOLFCOSE_ALG_ED25519, 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); - TEST_ASSERT(ret == 0, "sign1 eddsa size"); + TEST_ASSERT(ret == 0, "sign1 ed25519 size"); /* Sign */ if (ret == 0) { - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_EDDSA, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ED25519, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, /* detachedPayload, detachedLen */ NULL, 0, /* extAad, extAadLen */ scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); - TEST_ASSERT(ret == 0 && outLen > 0, "sign1 eddsa sign"); - TEST_ASSERT(outLen == sizedLen, "sign1 eddsa exact size"); + TEST_ASSERT(ret == 0 && outLen > 0, "sign1 ed25519 sign"); + TEST_ASSERT(outLen == sizedLen, "sign1 ed25519 exact size"); } } @@ -2244,18 +2250,18 @@ static void test_cose_sign1_eddsa(void) ret = wc_CoseSign1_Verify(&signKey, out, outLen, NULL, 0, NULL, 0, scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); - TEST_ASSERT(ret == 0, "sign1 eddsa verify"); + TEST_ASSERT(ret == 0, "sign1 ed25519 verify"); TEST_ASSERT(decPayloadLen == sizeof(payload) - 1 && memcmp(decPayload, payload, decPayloadLen) == 0, - "sign1 eddsa payload match"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_EDDSA, "sign1 eddsa hdr alg"); + "sign1 ed25519 payload match"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ED25519, "sign1 ed25519 hdr alg"); } #if defined(WOLFCOSE_COUNTERSIGN_SIGN) && \ defined(WOLFCOSE_COUNTERSIGN_VERIFY) if (ret == 0) { ret = test_cose_countersign_roundtrip(&signKey, &signKey, - WOLFCOSE_ALG_EDDSA, &rng, "Ed25519"); + WOLFCOSE_ALG_ED25519, &rng, "Ed25519"); } #endif @@ -2268,7 +2274,7 @@ static void test_cose_sign1_eddsa(void) NULL, 0, NULL, 0, scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); TEST_ASSERT(wrongRet == WOLFCOSE_E_COSE_KEY_TYPE, - "sign1 eddsa attachedType mismatch rejected"); + "sign1 ed25519 attachedType mismatch rejected"); } if (ret == 0) { @@ -2284,7 +2290,7 @@ static void test_cose_sign1_eddsa(void) wrongRet = wc_CoseSign1_Verify(&wrongKey, out, outLen, NULL, 0, NULL, 0, scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); - TEST_ASSERT(wrongRet != 0, "sign1 eddsa wrong key fails"); + TEST_ASSERT(wrongRet != 0, "sign1 ed25519 wrong key fails"); } (void)wc_ed25519_free(&edWrong); } @@ -2336,13 +2342,13 @@ static void test_cose_sign1_ed448(void) (void)wc_CoseKey_Init(&signKey); (void)wc_CoseKey_SetEd448(&signKey, &edKey); - ret = wc_CoseSign1_SignSize_ex(&signKey, WOLFCOSE_ALG_EDDSA, + ret = wc_CoseSign1_SignSize_ex(&signKey, WOLFCOSE_ALG_ED448, 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); TEST_ASSERT(ret == 0, "sign1 ed448 size"); /* Sign */ if (ret == 0) { - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_EDDSA, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ED448, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, /* detachedPayload, detachedLen */ @@ -2365,14 +2371,14 @@ static void test_cose_sign1_ed448(void) TEST_ASSERT(decPayloadLen == sizeof(payload) - 1 && memcmp(decPayload, payload, decPayloadLen) == 0, "sign1 ed448 payload match"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_EDDSA, "sign1 ed448 hdr alg"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ED448, "sign1 ed448 hdr alg"); } #if defined(WOLFCOSE_COUNTERSIGN_SIGN) && \ defined(WOLFCOSE_COUNTERSIGN_VERIFY) if (ret == 0) { ret = test_cose_countersign_roundtrip(&signKey, &signKey, - WOLFCOSE_ALG_EDDSA, &rng, "Ed448"); + WOLFCOSE_ALG_ED448, &rng, "Ed448"); } #endif @@ -2419,7 +2425,7 @@ static void test_cose_sign1_ed448(void) signKey.kid = kid; signKey.kidLen = sizeof(kid) - 1u; - signKey.alg = WOLFCOSE_ALG_EDDSA; + signKey.alg = WOLFCOSE_ALG_ED448; encRet = wc_CoseKey_Encode(&signKey, keyBuf, sizeof(keyBuf), &keyLen); TEST_ASSERT(encRet == 0 && keyLen > 0, "key ed448 encode"); @@ -2431,7 +2437,7 @@ static void test_cose_sign1_ed448(void) encRet = wc_CoseKey_Decode(&decKey, keyBuf, keyLen); TEST_ASSERT(encRet == 0 && decKey.kty == WOLFCOSE_KTY_OKP && decKey.crv == WOLFCOSE_CRV_ED448 && - decKey.alg == WOLFCOSE_ALG_EDDSA && + decKey.alg == WOLFCOSE_ALG_ED448 && decKey.kidLen == (sizeof(kid) - 1u) && memcmp(decKey.kid, kid, sizeof(kid) - 1u) == 0, "key ed448 decode"); @@ -2581,7 +2587,7 @@ static void test_cose_sign1_word32_overflow_guard(void) /* payloadLen above word32 range must be rejected before the Sig_structure * length is cast to word32 for hashing, not truncated. */ - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, hugeLen, NULL, 0, NULL, 0, @@ -4347,7 +4353,7 @@ static void test_cose_key_lms(void) (void)wc_CBOR_EncodeInt(&enc, WOLFCOSE_KEY_LABEL_KTY); (void)wc_CBOR_EncodeUint(&enc, WOLFCOSE_KTY_HSS_LMS); (void)wc_CBOR_EncodeInt(&enc, WOLFCOSE_KEY_LABEL_ALG); - (void)wc_CBOR_EncodeInt(&enc, WOLFCOSE_ALG_ES256); + (void)wc_CBOR_EncodeInt(&enc, WOLFCOSE_ALG_ESP256); (void)wc_CBOR_EncodeInt(&enc, WOLFCOSE_KEY_LABEL_PUB); (void)wc_CBOR_EncodeBstr(&enc, pubRaw, (size_t)pubRawLen); negRet = wc_CoseKey_Decode(&decKey, badBuf, enc.idx); @@ -4473,7 +4479,7 @@ static void test_cose_lms_negative(void) if (ret == 0) { int32_t savedAlg = signKey.alg; int badAlgRet; - signKey.alg = WOLFCOSE_ALG_ES256; + signKey.alg = WOLFCOSE_ALG_ESP256; encLen = 0; badAlgRet = wc_CoseKey_EncodeSize(&signKey, &encLen); TEST_ASSERT(badAlgRet == WOLFCOSE_E_COSE_BAD_ALG, @@ -4765,7 +4771,7 @@ static void test_cose_sign_lms(void) (void)wc_CoseKey_Init(&esKey); (void)wc_CoseKey_SetEcc(&esKey, WOLFCOSE_CRV_P256, &eccKey); mixed[0] = signers[0]; - mixed[1].algId = WOLFCOSE_ALG_ES256; + mixed[1].algId = WOLFCOSE_ALG_ESP256; mixed[1].key = &esKey; mixed[1].kid = NULL; mixed[1].kidLen = 0; @@ -4779,7 +4785,7 @@ static void test_cose_sign_lms(void) sizeof(g_lmsPrivSnap)) == 0, "sign lms not last preserves state"); mixed[1] = signers[0]; - mixed[0].algId = WOLFCOSE_ALG_ES256; + mixed[0].algId = WOLFCOSE_ALG_ESP256; mixed[0].key = &esKey; mixed[0].kid = NULL; mixed[0].kidLen = 0; @@ -5132,7 +5138,7 @@ static void test_cose_sign1_with_aad(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, /* detachedPayload, detachedLen */ @@ -6142,31 +6148,31 @@ static void test_cose_sign1_buffer_too_small(void) (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); /* scratch too small */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, NULL, 0, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload), NULL, 0, NULL, 0, scratch, 10, out, sizeof(out), &outLen, &rng); TEST_ASSERT(ret != 0, "sign1 scratch too small"); /* output too small */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, NULL, 0, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload), NULL, 0, NULL, 0, scratch, sizeof(scratch), out, 5, &outLen, &rng); TEST_ASSERT(ret != 0, "sign1 out too small"); /* NULL scratch */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, NULL, 0, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload), NULL, 0, NULL, 0, NULL, 0, out, sizeof(out), &outLen, &rng); TEST_ASSERT(ret != 0, "sign1 null scratch"); /* NULL output */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, NULL, 0, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload), NULL, 0, NULL, 0, scratch, sizeof(scratch), NULL, 0, &outLen, &rng); TEST_ASSERT(ret != 0, "sign1 null out"); /* NULL outLen */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, NULL, 0, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload), NULL, 0, NULL, 0, scratch, sizeof(scratch), out, sizeof(out), NULL, &rng); TEST_ASSERT(ret != 0, "sign1 null outLen"); @@ -6178,7 +6184,7 @@ static void test_cose_sign1_buffer_too_small(void) TEST_ASSERT(ret != 0, "sign1 bad alg"); /* verify with truncated input */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, NULL, 0, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload), NULL, 0, NULL, 0, scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); if (ret == 0) { @@ -6237,7 +6243,7 @@ static void test_cose_sign1_detached(void) (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); /* Sign with detached payload (payload in message is null) */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, /* kid */ NULL, 0, /* payload in message = null */ payload, sizeof(payload) - 1, /* detached payload for signature */ @@ -6769,7 +6775,11 @@ static void test_cose_key_decode_type_confusion(void) TEST_ASSERT(ret == 0, "typeconf ecc init"); blobLen = typeconf_key_blob(blob, sizeof(blob), WOLFCOSE_KTY_OKP, +#ifdef WOLFCOSE_HAVE_EDDSA + WOLFCOSE_CRV_ED25519, 32); +#else WOLFCOSE_CRV_ED448, 57); +#endif (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); ret = wc_CoseKey_Decode(&key, blob, blobLen); @@ -7721,7 +7731,7 @@ static void test_cose_key_mldsa_negative(void) wc_CBOR_EncodeInt(&enc, WOLFCOSE_KEY_LABEL_KTY); wc_CBOR_EncodeUint(&enc, WOLFCOSE_KTY_AKP); wc_CBOR_EncodeInt(&enc, WOLFCOSE_KEY_LABEL_ALG); - wc_CBOR_EncodeInt(&enc, WOLFCOSE_ALG_ES256); + wc_CBOR_EncodeInt(&enc, WOLFCOSE_ALG_ESP256); wc_CBOR_EncodeInt(&enc, WOLFCOSE_KEY_LABEL_PUB); wc_CBOR_EncodeBstr(&enc, pubBuf, (size_t)pubSz); (void)wc_CoseKey_Init(&key); @@ -7975,7 +7985,7 @@ static void test_cose_key_encode_public_only_ecc(void) (void)wc_CoseKey_Init(&key); ret = wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); TEST_ASSERT(ret == 0 && key.hasPrivate == 1, "pubonly set ecc"); - key.alg = WOLFCOSE_ALG_ES256; + key.alg = WOLFCOSE_ALG_ESP256; ret = wc_CoseKey_Encode(&key, full, sizeof(full), &fullLen); TEST_ASSERT(ret == 0, "pubonly default encode"); @@ -8077,7 +8087,7 @@ static void test_cose_key_encode_ecc_raw(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - key.alg = WOLFCOSE_ALG_ES256; + key.alg = WOLFCOSE_ALG_ESP256; key.kid = kid; key.kidLen = sizeof(kid) - 1u; @@ -8086,7 +8096,7 @@ static void test_cose_key_encode_ecc_raw(void) WOLFCOSE_KEY_PUBLIC_ONLY); TEST_ASSERT(ret == 0, "eccraw encode via key"); ret = wc_CoseKey_EncodeEccRaw(WOLFCOSE_CRV_P256, xBuf, yBuf, NULL, 32u, - kid, sizeof(kid) - 1u, WOLFCOSE_ALG_ES256, + kid, sizeof(kid) - 1u, WOLFCOSE_ALG_ESP256, viaRaw, sizeof(viaRaw), &viaRawLen); TEST_ASSERT(ret == 0, "eccraw encode public"); TEST_ASSERT(viaRawLen == viaKeyLen && @@ -8097,7 +8107,7 @@ static void test_cose_key_encode_ecc_raw(void) ret = wc_CoseKey_Encode(&key, viaKey, sizeof(viaKey), &viaKeyLen); TEST_ASSERT(ret == 0, "eccraw encode priv via key"); ret = wc_CoseKey_EncodeEccRaw(WOLFCOSE_CRV_P256, xBuf, yBuf, dBuf, 32u, - kid, sizeof(kid) - 1u, WOLFCOSE_ALG_ES256, + kid, sizeof(kid) - 1u, WOLFCOSE_ALG_ESP256, viaRaw, sizeof(viaRaw), &viaRawLen); TEST_ASSERT(ret == 0, "eccraw encode private"); TEST_ASSERT(viaRawLen == viaKeyLen && @@ -8387,7 +8397,7 @@ static void test_cose_key_encode_size_exact(void) if (wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &edKey) == 0) { (void)wc_CoseKey_Init(&edCoseKey); (void)wc_CoseKey_SetEd25519(&edCoseKey, &edKey); - edCoseKey.alg = WOLFCOSE_ALG_EDDSA; + edCoseKey.alg = WOLFCOSE_ALG_ED25519; ret = wc_CoseKey_Encode(&edCoseKey, out, sizeof(out), &outLen); TEST_ASSERT(ret == 0, "size ed25519 encode"); ret = wc_CoseKey_EncodeSize(&edCoseKey, &sized); @@ -8546,7 +8556,7 @@ static void test_cose_key_encode_public_only_types(void) if (wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &edKey) == 0) { (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEd25519(&key, &edKey); - key.alg = WOLFCOSE_ALG_EDDSA; + key.alg = WOLFCOSE_ALG_ED25519; ret = wc_CoseKey_Encode(&key, full, sizeof(full), &fullLen); TEST_ASSERT(ret == 0 && key.hasPrivate == 1, @@ -9130,12 +9140,12 @@ static void test_cose_key_peek_info_alg(void) (void)wc_CBOR_EncodeInt(&enc, WOLFCOSE_KEY_LABEL_KTY); (void)wc_CBOR_EncodeUint(&enc, WOLFCOSE_KTY_EC2); (void)wc_CBOR_EncodeInt(&enc, WOLFCOSE_KEY_LABEL_ALG); - (void)wc_CBOR_EncodeInt(&enc, WOLFCOSE_ALG_ES256); + (void)wc_CBOR_EncodeInt(&enc, WOLFCOSE_ALG_ESP256); (void)wc_CBOR_EncodeInt(&enc, WOLFCOSE_KEY_LABEL_CRV); (void)wc_CBOR_EncodeUint(&enc, WOLFCOSE_CRV_P256); ret = wc_CoseKey_PeekInfo(buf, enc.idx, &info); TEST_ASSERT(ret == 0 && info.kty == WOLFCOSE_KTY_EC2 && - info.alg == WOLFCOSE_ALG_ES256 && + info.alg == WOLFCOSE_ALG_ESP256 && info.crv == WOLFCOSE_CRV_P256, "peek negative alg"); /* alg below INT32_MIN is rejected, not truncated. */ @@ -9164,7 +9174,7 @@ static void test_cose_key_peek_info_alg(void) /* ----- RFC 9052 interop test vectors (cose-wg/Examples) ----- */ /* ECDSA-01: P-256 / ES256 Sign1 (ecdsa-sig-01.json) */ -#ifdef WOLFCOSE_HAVE_ES256 +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) static void test_rfc_sign1_ecdsa_01(void) { /* Known P-256 public key (x, y from test vector) */ @@ -9242,7 +9252,7 @@ static void test_rfc_sign1_ecdsa_01(void) wc_CoseKey_Free(&key); (void)wc_ecc_free(&eccKey); } -#endif /* WOLFCOSE_HAVE_ES256 */ +#endif /* WOLFCOSE_HAVE_ES256 && WOLFCOSE_HAVE_DEPRECATED_ALGS */ /* HMAC-01: HMAC-SHA256 Mac0 (mac0-tests/HMac-01.json) */ #if defined(WOLFCOSE_HAVE_HMAC256) @@ -10128,12 +10138,12 @@ static void test_cose_sign_multi_signer(void) TEST_ASSERT(ret == 0, "sign key2 set"); /* Setup signers array */ - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = &key1; signers[0].kid = kid1; signers[0].kidLen = sizeof(kid1) - 1; - signers[1].algId = WOLFCOSE_ALG_ES256; + signers[1].algId = WOLFCOSE_ALG_ESP256; signers[1].key = &key2; signers[1].kid = kid2; signers[1].kidLen = sizeof(kid2) - 1; @@ -10160,7 +10170,7 @@ static void test_cose_sign_multi_signer(void) TEST_ASSERT(ret == 0, "sign verify signer 0"); TEST_ASSERT(decPayloadLen == sizeof(payload) - 1, "sign payload len 0"); TEST_ASSERT(memcmp(decPayload, payload, decPayloadLen) == 0, "sign payload match 0"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ES256, "sign verify hdr alg 0"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ESP256, "sign verify hdr alg 0"); /* Verify second signer */ memset(&hdr, 0, sizeof(hdr)); @@ -10174,7 +10184,7 @@ static void test_cose_sign_multi_signer(void) TEST_ASSERT(ret == 0, "sign verify signer 1"); TEST_ASSERT(decPayloadLen == sizeof(payload) - 1, "sign payload len 1"); TEST_ASSERT(memcmp(decPayload, payload, decPayloadLen) == 0, "sign payload match 1"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ES256, "sign verify hdr alg 1"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ESP256, "sign verify hdr alg 1"); /* Wrong key for signer 0 should fail */ ret = wc_CoseSign_Verify(&key2, 0, /* key2 for signer 0 */ @@ -10334,7 +10344,7 @@ static void test_cose_sign_verify_key_alg_mismatch(void) (void)wc_CoseKey_Init(&signKey); ret = wc_CoseKey_SetEcc(&signKey, WOLFCOSE_CRV_P256, &eccKey); TEST_ASSERT(ret == 0, "sv-mismatch sign key set"); - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = &signKey; signers[0].kid = NULL; signers[0].kidLen = 0; @@ -10351,7 +10361,7 @@ static void test_cose_sign_verify_key_alg_mismatch(void) (void)wc_CoseKey_Init(&verifyKey); ret = wc_CoseKey_SetEcc(&verifyKey, WOLFCOSE_CRV_P256, &eccKey); TEST_ASSERT(ret == 0, "sv-mismatch verify key set"); - verifyKey.alg = WOLFCOSE_ALG_ES384; + verifyKey.alg = WOLFCOSE_ALG_ESP384; memset(&hdr, 0, sizeof(hdr)); ret = wc_CoseSign_Verify(&verifyKey, 0, out, outLen, @@ -10399,7 +10409,7 @@ static void test_cose_sign_verify_unprotected_alg(void) (void)wc_CoseKey_Init(&key); ret = wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); TEST_ASSERT(ret == 0, "unprotected signer alg key set"); - key.alg = WOLFCOSE_ALG_ES256; + key.alg = WOLFCOSE_ALG_ESP256; ret = wolfCose_BuildToBeSignedMaced( WOLFCOSE_CTX_SIGNATURE, sizeof(WOLFCOSE_CTX_SIGNATURE), @@ -10447,7 +10457,7 @@ static void test_cose_sign_verify_unprotected_alg(void) ret = wc_CBOR_EncodeInt(&enc, WOLFCOSE_HDR_ALG); } if (ret == 0) { - ret = wc_CBOR_EncodeInt(&enc, WOLFCOSE_ALG_ES256); + ret = wc_CBOR_EncodeInt(&enc, WOLFCOSE_ALG_ESP256); } if (ret == 0) { ret = wc_CBOR_EncodeBstr(&enc, signature, signatureLen); @@ -10595,7 +10605,7 @@ static void test_cose_sign_both_payloads(void) (void)wc_CoseKey_Init(&key); ret = wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); TEST_ASSERT(ret == 0, "sign-both key set"); - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = &key; signers[0].kid = NULL; signers[0].kidLen = 0; @@ -10647,7 +10657,7 @@ static void test_cose_sign_with_aad(void) ret = wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); TEST_ASSERT(ret == 0, "sign aad key set"); - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = &key; signers[0].kid = NULL; signers[0].kidLen = 0; @@ -10729,7 +10739,7 @@ static void test_cose_sign_detached(void) ret = wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); TEST_ASSERT(ret == 0, "sign detached key set"); - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = &key; signers[0].kid = NULL; signers[0].kidLen = 0; @@ -10827,12 +10837,12 @@ static void test_cose_sign_mixed_algorithms(void) TEST_ASSERT(ret == 0, "sign mixed ed key set"); /* Setup signers: ES256 + EdDSA */ - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = &keyEc; signers[0].kid = NULL; signers[0].kidLen = 0; - signers[1].algId = WOLFCOSE_ALG_EDDSA; + signers[1].algId = WOLFCOSE_ALG_ED25519; signers[1].key = &keyEd; signers[1].kid = NULL; signers[1].kidLen = 0; @@ -16228,7 +16238,7 @@ static void test_cose_mac_wrong_key_type(void) /* ----- Phase 1: Algorithm Combination Tests ----- */ #ifdef WOLFCOSE_HAVE_ES384 -static void test_cose_sign1_es384(void) +static void test_cose_sign1_esp384(void) { WOLFCOSE_KEY key; ecc_key eccKey; @@ -16267,7 +16277,7 @@ static void test_cose_sign1_es384(void) if (ret == 0) { /* Sign */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES384, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP384, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -16282,7 +16292,7 @@ static void test_cose_sign1_es384(void) scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); TEST_ASSERT(ret == 0, "sign1 es384 verify"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ES384, "sign1 es384 alg"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ESP384, "sign1 es384 alg"); TEST_ASSERT(decPayloadLen == sizeof(payload) - 1, "sign1 es384 payload len"); } @@ -16297,7 +16307,7 @@ static void test_cose_sign1_es384(void) #endif /* WOLFCOSE_HAVE_ES384 */ #ifdef WOLFCOSE_HAVE_ES512 -static void test_cose_sign1_es512(void) +static void test_cose_sign1_esp512(void) { WOLFCOSE_KEY key; ecc_key eccKey; @@ -16336,7 +16346,7 @@ static void test_cose_sign1_es512(void) if (ret == 0) { /* Sign */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES512, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP512, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -16351,7 +16361,7 @@ static void test_cose_sign1_es512(void) scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); TEST_ASSERT(ret == 0, "sign1 es512 verify"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ES512, "sign1 es512 alg"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ESP512, "sign1 es512 alg"); } /* Cleanup */ @@ -16454,7 +16464,7 @@ static void test_cose_sign1_tampered_sig_byte(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -16520,7 +16530,7 @@ static void test_cose_sign1_trailing_bytes(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -16581,7 +16591,7 @@ static void test_cose_sign1_hdr_cleared_on_failure(void) if (ret == 0) { (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); @@ -16642,7 +16652,7 @@ static void test_cose_sign1_tampered_payload_byte(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -16705,7 +16715,7 @@ static void test_cose_sign1_tampered_protected_hdr(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -16714,8 +16724,8 @@ static void test_cose_sign1_tampered_protected_hdr(void) } /* Flip the inner alg byte: layout is 0xD2 (tag) 0x84 (array4) - * 0x43 (bstr3) 0xA1 0x01 0x26 ... protected map. Byte 5 is the alg - * value (0x26 == -7). The flip must change the protected-bstr + * 0x43 (bstr3) 0xA1 0x01 0x28 ... protected map. Byte 5 is the alg + * value (0x28 == -9). The flip must change the protected-bstr * contents so Sig_structure reconstruction picks up the tampered * bytes and the signature check fails. */ if (ret == 0) { @@ -16771,7 +16781,7 @@ static void test_cose_sign1_truncated_sig(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -17061,7 +17071,7 @@ static void test_cose_empty_payload(void) (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); /* Sign with zero-length payload (valid per RFC 9052) */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, emptyPayload, 0, /* empty payload */ NULL, 0, NULL, 0, @@ -17130,7 +17140,7 @@ static void test_cose_large_payload(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, largePayload, sizeof(largePayload), NULL, 0, NULL, 0, @@ -17196,7 +17206,7 @@ static void test_cose_empty_aad(void) (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); /* Sign with zero-length AAD (valid per RFC 9052) */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, @@ -17266,7 +17276,7 @@ static void test_cose_long_kid(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, longKid, sizeof(longKid), payload, sizeof(payload) - 1, NULL, 0, NULL, 0, @@ -17329,7 +17339,7 @@ static void test_cose_sign_output_too_small(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - signRet = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + signRet = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, @@ -17380,7 +17390,7 @@ static void test_cose_sign_scratch_too_small(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - signRet = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + signRet = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, @@ -17469,7 +17479,7 @@ static void test_decode_truncated_message(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -17531,7 +17541,7 @@ static void test_decode_wrong_tag(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -17901,7 +17911,7 @@ static void test_cose_error_paths(void) (void)wc_CoseKey_SetSymmetric(&symKey, keyData, sizeof(keyData)); /* Try to sign with symmetric key using ECC algorithm */ - ret = wc_CoseSign1_Sign(&symKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&symKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -18177,7 +18187,7 @@ static void test_cose_error_paths(void) (void)wc_CoseKey_SetEcc(&wrongKey, WOLFCOSE_CRV_P256, &eccWrongKey); /* Sign */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -18219,7 +18229,7 @@ static void test_cose_error_paths(void) (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); /* Sign */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -18321,7 +18331,7 @@ static void test_cose_error_paths(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), @@ -19458,18 +19468,18 @@ static void test_cose_sign_dup_signer_unprot_hdr(void) const uint8_t* payload = NULL; size_t payloadLen = 0; /* COSE_Sign with one signer whose unprotected map repeats label 4 (kid). - * [ h'', {}, 'x', [ [ h'A10126', {4:h'01',4:h'02'}, h'0000' ] ] ] */ + * [ h'', {}, 'x', [ [ h'A10128', {4:h'01',4:h'02'}, h'0000' ] ] ] */ uint8_t msg[] = { 0x84u, 0x40u, 0xA0u, 0x41u, 0x78u, 0x81u, - 0x83u, 0x43u, 0xA1u, 0x01u, 0x26u, + 0x83u, 0x43u, 0xA1u, 0x01u, 0x28u, 0xA2u, 0x04u, 0x41u, 0x01u, 0x04u, 0x41u, 0x02u, 0x42u, 0x00u, 0x00u }; uint8_t unselectedMsg[] = { 0x84u, 0x40u, 0xA0u, 0x41u, 0x78u, 0x82u, - 0x83u, 0x43u, 0xA1u, 0x01u, 0x26u, 0xA0u, + 0x83u, 0x43u, 0xA1u, 0x01u, 0x28u, 0xA0u, 0x42u, 0x00u, 0x00u, - 0x83u, 0x43u, 0xA1u, 0x01u, 0x26u, + 0x83u, 0x43u, 0xA1u, 0x01u, 0x28u, 0xA2u, 0x04u, 0x41u, 0x01u, 0x04u, 0x41u, 0x02u, 0x42u, 0x00u, 0x00u }; @@ -20634,7 +20644,7 @@ static void test_cose_sign1_alg_curve_mismatch(void) /* Do not trust a declaration changed after key attachment. */ key.crv = WOLFCOSE_CRV_P384; - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES384, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP384, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, @@ -20647,7 +20657,7 @@ static void test_cose_sign1_alg_curve_mismatch(void) key.crv = WOLFCOSE_CRV_P256; /* Ask for ES384 with a P-256 key -> bad alg */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES384, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP384, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, @@ -20689,7 +20699,7 @@ static void test_cose_sign1_inconsistent_kid(void) TEST_ASSERT(ret == 0, "set ECC key"); /* kid non-NULL but kidLen == 0 */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, kid, 0, payload, sizeof(payload) - 1, NULL, 0, @@ -20701,7 +20711,7 @@ static void test_cose_sign1_inconsistent_kid(void) "Sign1 rejects non-NULL kid with kidLen 0"); /* kid NULL but kidLen != 0 */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 4, payload, sizeof(payload) - 1, NULL, 0, @@ -20750,11 +20760,11 @@ static void test_cose_sign_multi_public_only_key(void) (void)wc_CoseKey_SetEcc(&key2, WOLFCOSE_CRV_P256, &eccKey2); key2.hasPrivate = 0u; /* second signer is public-only */ - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = &key1; signers[0].kid = NULL; signers[0].kidLen = 0; - signers[1].algId = WOLFCOSE_ALG_ES256; + signers[1].algId = WOLFCOSE_ALG_ESP256; signers[1].key = &key2; signers[1].kid = NULL; signers[1].kidLen = 0; @@ -21012,18 +21022,18 @@ static void test_cose_alg_to_hash_constants(void) TEST_LOG(" [Algorithm-to-hash constants]\n"); #ifdef WOLFCOSE_HAVE_ES256 - ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ES256, &ht); + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ESP256, &ht); TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (ht == WC_HASH_TYPE_SHA256), - "AlgToHashType ES256 -> SHA-256"); + "AlgToHashType ESP256 -> SHA-256"); #ifdef WOLFCOSE_HAVE_ES384 - ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ES384, &ht); + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ESP384, &ht); TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (ht == WC_HASH_TYPE_SHA384), - "AlgToHashType ES384 -> SHA-384"); + "AlgToHashType ESP384 -> SHA-384"); #endif #ifdef WOLFCOSE_HAVE_ES512 - ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ES512, &ht); + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ESP512, &ht); TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (ht == WC_HASH_TYPE_SHA512), - "AlgToHashType ES512 -> SHA-512"); + "AlgToHashType ESP512 -> SHA-512"); #endif #endif /* WOLFCOSE_HAVE_ES256 */ #ifdef WOLFCOSE_HAVE_RSAPSS @@ -21045,181 +21055,1353 @@ static void test_cose_alg_to_hash_constants(void) (void)ht; } -static void test_cose_build_sig_structure_context(void) +/* ----- RFC 9864 fully-specified algorithm IDs ----- */ + +static void test_cose_rfc9864_alg_helpers(void) { int ret; - uint8_t scratch[64]; - size_t structLen = 0; - /* Use a 1-byte protected-hdr placeholder, no AAD, 1-byte payload. */ - const uint8_t protectedHdr[1] = {0x40}; /* h'' bstr inside, body opaque */ - const uint8_t payload[1] = {0x00}; - - TEST_LOG(" [BuildToBeSignedMaced: context bytes]\n"); - - /* Sign1 path: expect array(4), tstr "Signature1", bstr, - * bstr, bstr. The first two bytes for an - * array of 4 + tstr(10) prefix should be 0x84 then 0x6A. */ - ret = wolfCose_BuildToBeSignedMaced( - WOLFCOSE_CTX_SIGNATURE1, sizeof(WOLFCOSE_CTX_SIGNATURE1), - protectedHdr, sizeof(protectedHdr), - NULL, 0, - NULL, 0, - payload, sizeof(payload), - scratch, sizeof(scratch), &structLen); - TEST_ASSERT(ret == WOLFCOSE_SUCCESS, - "BuildToBeSignedMaced Sign1 ok"); - TEST_ASSERT(structLen >= 12u, "Sign1 struct length"); - TEST_ASSERT(scratch[0] == 0x84u, "Sign1 array(4) header"); - TEST_ASSERT(scratch[1] == 0x6Au, "Sign1 tstr(10) header"); - TEST_ASSERT(memcmp(&scratch[2], "Signature1", 10) == 0, - "Sign1 context bytes"); - - /* Sign multi-signer path: array(5), tstr(9) "Signature". */ - ret = wolfCose_BuildToBeSignedMaced( - WOLFCOSE_CTX_SIGNATURE, sizeof(WOLFCOSE_CTX_SIGNATURE), - protectedHdr, sizeof(protectedHdr), - protectedHdr, sizeof(protectedHdr), - NULL, 0, - payload, sizeof(payload), - scratch, sizeof(scratch), &structLen); - TEST_ASSERT(ret == WOLFCOSE_SUCCESS, - "BuildToBeSignedMaced Sign multi ok"); - TEST_ASSERT(scratch[0] == 0x85u, "Sign multi array(5) header"); - TEST_ASSERT(scratch[1] == 0x69u, "Sign multi tstr(9) header"); - TEST_ASSERT(memcmp(&scratch[2], "Signature", 9) == 0, - "Sign multi context bytes"); - - /* Mac0 path: array(4), tstr(4) "MAC0". */ - ret = wolfCose_BuildToBeSignedMaced( - WOLFCOSE_CTX_MAC0, sizeof(WOLFCOSE_CTX_MAC0), - protectedHdr, sizeof(protectedHdr), - NULL, 0, - NULL, 0, - payload, sizeof(payload), - scratch, sizeof(scratch), &structLen); - TEST_ASSERT(ret == WOLFCOSE_SUCCESS, - "BuildToBeSignedMaced Mac0 ok"); - TEST_ASSERT(scratch[1] == 0x64u, "Mac0 tstr(4) header"); - TEST_ASSERT(memcmp(&scratch[2], "MAC0", 4) == 0, - "Mac0 context bytes"); - - /* Mac multi-recipient path: array(4), tstr(3) "MAC" (F-5234). */ - ret = wolfCose_BuildToBeSignedMaced( - WOLFCOSE_CTX_MAC, sizeof(WOLFCOSE_CTX_MAC), - protectedHdr, sizeof(protectedHdr), - NULL, 0, - NULL, 0, - payload, sizeof(payload), - scratch, sizeof(scratch), &structLen); - TEST_ASSERT(ret == WOLFCOSE_SUCCESS, - "BuildToBeSignedMaced Mac ok"); - TEST_ASSERT(scratch[0] == 0x84u, "Mac array(4) header"); - TEST_ASSERT(scratch[1] == 0x63u, "Mac tstr(3) header"); - TEST_ASSERT(memcmp(&scratch[2], "MAC", 3) == 0, "Mac context bytes"); + int32_t crv = 0; + enum wc_HashType ht = WC_HASH_TYPE_NONE; + size_t sz = 0; - /* AEAD Enc_structure contexts are AAD inputs; assert the context constants - * directly so a byte mutation is detected (F-5232, F-5233). */ - TEST_ASSERT(sizeof(WOLFCOSE_CTX_ENCRYPT0) == 8u && - memcmp(WOLFCOSE_CTX_ENCRYPT0, "Encrypt0", 8) == 0, - "Encrypt0 context bytes"); - TEST_ASSERT(sizeof(WOLFCOSE_CTX_ENCRYPT) == 7u && - memcmp(WOLFCOSE_CTX_ENCRYPT, "Encrypt", 7) == 0, - "Encrypt context bytes"); - TEST_ASSERT(sizeof(WOLFCOSE_CTX_MAC) == 3u && - memcmp(WOLFCOSE_CTX_MAC, "MAC", 3) == 0, - "MAC context constant bytes"); + TEST_LOG(" [RFC 9864 alg helpers]\n"); - ret = wolfCose_BuildToBeSignedMaced( - WOLFCOSE_CTX_SIGNATURE1, sizeof(WOLFCOSE_CTX_SIGNATURE1), - protectedHdr, sizeof(protectedHdr), - NULL, 0u, - NULL, 1u, - payload, sizeof(payload), - scratch, sizeof(scratch), &structLen); - TEST_ASSERT(ret == WOLFCOSE_E_INVALID_ARG, - "auth structure null aad with length rejected"); +#ifdef WOLFCOSE_HAVE_ES256 + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ESP256, &ht); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (ht == WC_HASH_TYPE_SHA256), + "AlgToHashType ESP256 -> SHA-256"); + ret = wolfCose_AlgToCrv(WOLFCOSE_ALG_ESP256, &crv); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (crv == WOLFCOSE_CRV_P256), + "AlgToCrv ESP256 -> P-256"); + ret = wolfCose_AlgCheckCrv(WOLFCOSE_ALG_ESP256, WOLFCOSE_CRV_P256); + TEST_ASSERT(ret == WOLFCOSE_SUCCESS, "AlgCheckCrv ESP256 P-256"); + ret = wolfCose_AlgCheckCrv(WOLFCOSE_ALG_ESP256, WOLFCOSE_CRV_P384); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, "AlgCheckCrv ESP256 P-384"); + TEST_ASSERT(wolfCose_AlgIsEcdsa(WOLFCOSE_ALG_ESP256) == 1, + "AlgIsEcdsa ESP256"); + TEST_ASSERT(wolfCose_AlgIsEddsa(WOLFCOSE_ALG_ESP256) == 0, + "AlgIsEddsa ESP256"); +#endif +#ifdef WOLFCOSE_HAVE_ES384 + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ESP384, &ht); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (ht == WC_HASH_TYPE_SHA384), + "AlgToHashType ESP384 -> SHA-384"); + ret = wolfCose_AlgToCrv(WOLFCOSE_ALG_ESP384, &crv); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (crv == WOLFCOSE_CRV_P384), + "AlgToCrv ESP384 -> P-384"); + TEST_ASSERT(wolfCose_AlgIsEcdsa(WOLFCOSE_ALG_ESP384) == 1, + "AlgIsEcdsa ESP384"); +#endif +#ifdef WOLFCOSE_HAVE_ES512 + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ESP512, &ht); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (ht == WC_HASH_TYPE_SHA512), + "AlgToHashType ESP512 -> SHA-512"); + ret = wolfCose_AlgToCrv(WOLFCOSE_ALG_ESP512, &crv); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (crv == WOLFCOSE_CRV_P521), + "AlgToCrv ESP512 -> P-521"); + ret = wolfCose_SigSize(WOLFCOSE_ALG_ESP512, &sz); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (sz == 132u), + "SigSize ESP512 -> 132"); + TEST_ASSERT(wolfCose_AlgIsEcdsa(WOLFCOSE_ALG_ESP512) == 1, + "AlgIsEcdsa ESP512"); +#endif +#ifdef WOLFCOSE_HAVE_EDDSA + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ED25519, &ht); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (ht == WC_HASH_TYPE_SHA512), + "AlgToHashType Ed25519"); + ret = wolfCose_AlgToCrv(WOLFCOSE_ALG_ED25519, &crv); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (crv == WOLFCOSE_CRV_ED25519), + "AlgToCrv Ed25519"); + ret = wolfCose_AlgCheckCrv(WOLFCOSE_ALG_ED25519, WOLFCOSE_CRV_ED448); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, "AlgCheckCrv Ed25519 Ed448"); + TEST_ASSERT(wolfCose_AlgIsEddsa(WOLFCOSE_ALG_ED25519) == 1, + "AlgIsEddsa Ed25519"); + TEST_ASSERT(wolfCose_AlgIsEcdsa(WOLFCOSE_ALG_ED25519) == 0, + "AlgIsEcdsa Ed25519"); +#endif +#ifdef WOLFCOSE_HAVE_ED448 + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ED448, &ht); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (ht == WC_HASH_TYPE_SHA512), + "AlgToHashType Ed448"); + ret = wolfCose_AlgToCrv(WOLFCOSE_ALG_ED448, &crv); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (crv == WOLFCOSE_CRV_ED448), + "AlgToCrv Ed448"); + TEST_ASSERT(wolfCose_AlgIsEddsa(WOLFCOSE_ALG_ED448) == 1, + "AlgIsEddsa Ed448"); +#endif +#if defined(WOLFCOSE_HAVE_ECDSA) || defined(WOLFCOSE_HAVE_EDDSA) || \ + defined(WOLFCOSE_HAVE_ED448) + ret = wolfCose_AlgToCrv(WOLFCOSE_ALG_PS256, &crv); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, "AlgToCrv PS256 unbound"); + ret = wolfCose_AlgToCrv(WOLFCOSE_ALG_PS256, NULL); + TEST_ASSERT(ret == WOLFCOSE_E_INVALID_ARG, "AlgToCrv NULL out"); + ret = wolfCose_AlgCheckCrv(WOLFCOSE_ALG_PS256, WOLFCOSE_CRV_P256); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, "AlgCheckCrv PS256 unbound"); +#endif + TEST_ASSERT(wolfCose_AlgIsEcdsa(WOLFCOSE_ALG_PS256) == 0, + "AlgIsEcdsa PS256"); + TEST_ASSERT(wolfCose_AlgIsEddsa(WOLFCOSE_ALG_PS256) == 0, + "AlgIsEddsa PS256"); + +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS +#ifdef WOLFCOSE_HAVE_ES256 + TEST_ASSERT(wolfCose_AlgIsEcdsa(WOLFCOSE_ALG_ES256) == 1, + "AlgIsEcdsa ES256 (deprecated)"); + ret = wolfCose_AlgToCrv(WOLFCOSE_ALG_ES256, &crv); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (crv == WOLFCOSE_CRV_P256), + "AlgToCrv ES256 -> P-256"); +#endif +#ifdef WOLFCOSE_HAVE_ES384 + TEST_ASSERT(wolfCose_AlgIsEcdsa(WOLFCOSE_ALG_ES384) == 1, + "AlgIsEcdsa ES384 (deprecated)"); + ret = wolfCose_AlgToCrv(WOLFCOSE_ALG_ES384, &crv); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (crv == WOLFCOSE_CRV_P384), + "AlgToCrv ES384 -> P-384"); + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ES384, &ht); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (ht == WC_HASH_TYPE_SHA384), + "AlgToHashType ES384"); + ret = wolfCose_SigSize(WOLFCOSE_ALG_ES384, &sz); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (sz == 96u), "SigSize ES384"); +#endif +#ifdef WOLFCOSE_HAVE_ES512 + TEST_ASSERT(wolfCose_AlgIsEcdsa(WOLFCOSE_ALG_ES512) == 1, + "AlgIsEcdsa ES512 (deprecated)"); + ret = wolfCose_AlgToCrv(WOLFCOSE_ALG_ES512, &crv); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (crv == WOLFCOSE_CRV_P521), + "AlgToCrv ES512 -> P-521"); + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ES512, &ht); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (ht == WC_HASH_TYPE_SHA512), + "AlgToHashType ES512"); + ret = wolfCose_SigSize(WOLFCOSE_ALG_ES512, &sz); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (sz == 132u), "SigSize ES512"); +#endif +#if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) + TEST_ASSERT(wolfCose_AlgIsEddsa(WOLFCOSE_ALG_EDDSA) == 1, + "AlgIsEddsa EdDSA (deprecated)"); + ret = wolfCose_AlgToCrv(WOLFCOSE_ALG_EDDSA, &crv); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (crv == 0), "AlgToCrv EdDSA"); + ret = wolfCose_AlgCheckCrv(WOLFCOSE_ALG_EDDSA, WOLFCOSE_CRV_ED448); + TEST_ASSERT(ret == WOLFCOSE_SUCCESS, "AlgCheckCrv EdDSA any OKP curve"); + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_EDDSA, &ht); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (ht == WC_HASH_TYPE_SHA512), + "AlgToHashType EdDSA"); +#endif +#else +#ifdef WOLFCOSE_HAVE_ES256 + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ES256, &ht); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, "ES256 rejected by default"); + ret = wolfCose_SigSize(WOLFCOSE_ALG_ES256, &sz); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, "SigSize ES256 rejected"); + ret = wolfCose_AlgToCrv(WOLFCOSE_ALG_ES256, &crv); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, "AlgToCrv ES256 rejected"); + TEST_ASSERT(wolfCose_AlgIsEcdsa(WOLFCOSE_ALG_ES256) == 0, + "AlgIsEcdsa ES256 off"); +#endif +#ifdef WOLFCOSE_HAVE_ES384 + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ES384, &ht); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, "ES384 rejected by default"); + TEST_ASSERT(wolfCose_AlgIsEcdsa(WOLFCOSE_ALG_ES384) == 0, + "AlgIsEcdsa ES384 off"); +#endif +#ifdef WOLFCOSE_HAVE_ES512 + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ES512, &ht); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, "ES512 rejected by default"); + TEST_ASSERT(wolfCose_AlgIsEcdsa(WOLFCOSE_ALG_ES512) == 0, + "AlgIsEcdsa ES512 off"); +#endif +#if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_EDDSA, &ht); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, "EdDSA rejected by default"); + ret = wolfCose_SigSize(WOLFCOSE_ALG_EDDSA, &sz); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, "SigSize EdDSA rejected"); + TEST_ASSERT(wolfCose_AlgIsEddsa(WOLFCOSE_ALG_EDDSA) == 0, + "AlgIsEddsa EdDSA off"); +#endif +#endif /* WOLFCOSE_HAVE_DEPRECATED_ALGS */ + (void)ret; + (void)crv; + (void)ht; + (void)sz; } -/* ----- Coverage boost: exercise multi-signer / multi-recipient paths - * added by recent hardening so the per-file 100% CI coverage - * threshold is preserved. ----- - */ - -#if defined(WOLFCOSE_HAVE_RSAPSS) && defined(WOLFCOSE_SIGN) && \ - defined(WOLFSSL_KEY_GEN) -static void test_cose_sign_multi_pss_roundtrip(void) +#if defined(WOLFCOSE_HAVE_EDDSA) && defined(WOLFCOSE_HAVE_ED448) && \ + defined(WOLFCOSE_SIGN1_SIGN) && defined(WOLFCOSE_SIGN1_VERIFY) +/* Ed25519 (-19) and Ed448 (-53) each bind one OKP curve. */ +static void test_cose_rfc9864_sign1_eddsa_curve_pin(void) { - WOLFCOSE_KEY key; - RsaKey rsaKey; + WOLFCOSE_KEY key25519; + WOLFCOSE_KEY key448; + ed25519_key ed25519; + ed448_key ed448; WC_RNG rng; - WOLFCOSE_SIGNATURE signers[1]; - WOLFCOSE_HDR hdr; int ret; - uint8_t out[2048]; - uint8_t scratch[2048]; + int rngInited = 0; + int ed25519Inited = 0; + int ed448Inited = 0; + int coseInited = 0; + uint8_t payload[] = "RFC 9864 EdDSA pin"; + uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; + uint8_t out[512]; size_t outLen = 0; - const uint8_t payload[] = "Multi-signer PSS payload"; + size_t sizedLen = 0; const uint8_t* decPayload = NULL; size_t decPayloadLen = 0; + WOLFCOSE_HDR hdr; - TEST_LOG(" [Sign Multi PSS roundtrip]\n"); + TEST_LOG(" [Sign1 RFC 9864 Ed25519/Ed448 curve pin]\n"); ret = wc_InitRng(&rng); - TEST_ASSERT(ret == 0, "multi pss rng init"); - ret = wc_InitRsaKey(&rsaKey, NULL); - TEST_ASSERT(ret == 0, "multi pss rsa init"); - ret = wc_MakeRsaKey(&rsaKey, 2048, WC_RSA_EXPONENT, &rng); - TEST_ASSERT(ret == 0, "multi pss keygen"); - - (void)wc_CoseKey_Init(&key); - ret = wc_CoseKey_SetRsa(&key, &rsaKey); - TEST_ASSERT(ret == 0, "multi pss key set"); + if (ret != 0) { TEST_ASSERT(0, "rng init"); } + if (ret == 0) { + rngInited = 1; + wc_ed25519_init(&ed25519); + ed25519Inited = 1; + ret = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &ed25519); + if (ret != 0) { TEST_ASSERT(0, "ed25519 keygen"); } + } + if (ret == 0) { + wc_ed448_init(&ed448); + ed448Inited = 1; + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &ed448); + if (ret != 0) { TEST_ASSERT(0, "ed448 keygen"); } + } + if (ret == 0) { + (void)wc_CoseKey_Init(&key25519); + (void)wc_CoseKey_SetEd25519(&key25519, &ed25519); + (void)wc_CoseKey_Init(&key448); + (void)wc_CoseKey_SetEd448(&key448, &ed448); + coseInited = 1; - signers[0].algId = WOLFCOSE_ALG_PS256; - signers[0].key = &key; - signers[0].kid = NULL; - signers[0].kidLen = 0; + ret = wc_CoseSign1_SignSize_ex(&key448, WOLFCOSE_ALG_ED25519, + 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "SignSize Ed25519 with Ed448 key"); + ret = wc_CoseSign1_SignSize_ex(&key25519, WOLFCOSE_ALG_ED448, + 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "SignSize Ed448 with Ed25519 key"); +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS + /* EdDSA (-8) sizes from whichever OKP curve the key carries. */ + ret = wc_CoseSign1_SignSize_ex(&key448, WOLFCOSE_ALG_EDDSA, + 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); + TEST_ASSERT(ret == 0, "SignSize EdDSA with Ed448 key"); + ret = wc_CoseSign1_SignSize_ex(&key25519, WOLFCOSE_ALG_EDDSA, + 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); + TEST_ASSERT(ret == 0, "SignSize EdDSA with Ed25519 key"); +#endif - ret = wc_CoseSign_Sign(signers, 1, - payload, sizeof(payload) - 1, - NULL, 0, - NULL, 0, - scratch, sizeof(scratch), - out, sizeof(out), &outLen, - &rng); - TEST_ASSERT(ret == 0, "multi pss sign"); + ret = wc_CoseSign1_Sign(&key448, WOLFCOSE_ALG_ED25519, NULL, 0, + payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, + scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "Sign1 Ed25519 with Ed448 key"); + ret = wc_CoseSign1_Sign(&key25519, WOLFCOSE_ALG_ED448, NULL, 0, + payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, + scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "Sign1 Ed448 with Ed25519 key"); - memset(&hdr, 0, sizeof(hdr)); - ret = wc_CoseSign_Verify(&key, 0, - out, outLen, - NULL, 0, - NULL, 0, - scratch, sizeof(scratch), - &hdr, &decPayload, &decPayloadLen); - TEST_ASSERT(ret == 0, "multi pss verify"); - TEST_ASSERT(decPayloadLen == sizeof(payload) - 1, - "multi pss payload len"); - TEST_ASSERT(memcmp(decPayload, payload, decPayloadLen) == 0, - "multi pss payload match"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_PS256, "multi pss hdr alg"); + ret = wc_CoseSign1_Sign(&key25519, WOLFCOSE_ALG_ED25519, NULL, 0, + payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, + scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == 0, "Sign1 Ed25519 sign"); + } + if (ret == 0) { + ret = wc_CoseSign1_Verify(&key448, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "Verify Ed25519 message with Ed448 key"); + ret = wc_CoseSign1_Verify(&key25519, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT((ret == 0) && (hdr.alg == WOLFCOSE_ALG_ED25519), + "Verify Ed25519 message with Ed25519 key"); + } + if (ret == 0) { + ret = wc_CoseSign1_Sign(&key448, WOLFCOSE_ALG_ED448, NULL, 0, + payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, + scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == 0, "Sign1 Ed448 sign"); + } + if (ret == 0) { + ret = wc_CoseSign1_Verify(&key25519, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "Verify Ed448 message with Ed25519 key"); + ret = wc_CoseSign1_Verify(&key448, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT((ret == 0) && (hdr.alg == WOLFCOSE_ALG_ED448), + "Verify Ed448 message with Ed448 key"); + } - wc_CoseKey_Free(&key); - (void)wc_FreeRsaKey(&rsaKey); - (void)wc_FreeRng(&rng); + if (coseInited != 0) { + wc_CoseKey_Free(&key25519); + wc_CoseKey_Free(&key448); + } + if (ed25519Inited != 0) { (void)wc_ed25519_free(&ed25519); } + if (ed448Inited != 0) { (void)wc_ed448_free(&ed448); } + if (rngInited != 0) { (void)wc_FreeRng(&rng); } } -#endif +#endif /* EDDSA && ED448 && SIGN1_SIGN && SIGN1_VERIFY */ -#if defined(WOLFCOSE_HAVE_MLDSA) && defined(WOLFCOSE_SIGN) -static void test_cose_sign_multi_mldsa_roundtrip(void) +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_EDDSA) && \ + defined(WOLFCOSE_SIGN1_SIGN) +/* Sizing honours the key type an RFC 9864 alg binds. */ +static void test_cose_rfc9864_sign1_kty_pin(void) { - WOLFCOSE_KEY key; - wc_MlDsaKey dlKey; + WOLFCOSE_KEY eccCoseKey; + WOLFCOSE_KEY edCoseKey; + ecc_key eccKey; + ed25519_key edKey; WC_RNG rng; - WOLFCOSE_SIGNATURE signers[1]; - WOLFCOSE_HDR hdr; int ret; - uint8_t out[3072]; - uint8_t scratch[8192]; + int rngInited = 0; + int eccInited = 0; + int edInited = 0; + uint8_t payload[] = "RFC 9864 kty pin"; + uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; + uint8_t out[512]; + size_t outLen = 0; + size_t sizedLen = 0; + + TEST_LOG(" [Sign1 RFC 9864 alg/kty pin]\n"); + + ret = wc_InitRng(&rng); + if (ret != 0) { TEST_ASSERT(0, "rng init"); } + if (ret == 0) { + rngInited = 1; + wc_ecc_init(&eccKey); + eccInited = 1; + ret = wc_ecc_make_key(&rng, 32, &eccKey); + if (ret != 0) { TEST_ASSERT(0, "ecc keygen"); } + } + if (ret == 0) { + wc_ed25519_init(&edKey); + edInited = 1; + ret = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &edKey); + if (ret != 0) { TEST_ASSERT(0, "ed25519 keygen"); } + } + if (ret == 0) { + (void)wc_CoseKey_Init(&eccCoseKey); + (void)wc_CoseKey_SetEcc(&eccCoseKey, WOLFCOSE_CRV_P256, &eccKey); + (void)wc_CoseKey_Init(&edCoseKey); + (void)wc_CoseKey_SetEd25519(&edCoseKey, &edKey); + + ret = wc_CoseSign1_SignSize_ex(&eccCoseKey, WOLFCOSE_ALG_ED25519, + 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_KEY_TYPE, + "SignSize Ed25519 with EC2 key"); + ret = wc_CoseSign1_SignSize_ex(&edCoseKey, WOLFCOSE_ALG_ESP256, + 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_KEY_TYPE, + "SignSize ESP256 with OKP key"); + ret = wc_CoseSign1_Sign(&eccCoseKey, WOLFCOSE_ALG_ED25519, NULL, 0, + payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, + scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_KEY_TYPE, + "Sign1 Ed25519 with EC2 key"); +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS + ret = wc_CoseSign1_SignSize_ex(&edCoseKey, WOLFCOSE_ALG_EDDSA, + 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); + TEST_ASSERT(ret == 0, "SignSize EdDSA with Ed25519 key"); + ret = wc_CoseSign1_SignSize_ex(&eccCoseKey, WOLFCOSE_ALG_EDDSA, + 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_KEY_TYPE, + "SignSize EdDSA with EC2 key"); + edCoseKey.crv = WOLFCOSE_CRV_P256; + ret = wc_CoseSign1_SignSize_ex(&edCoseKey, WOLFCOSE_ALG_EDDSA, + 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_KEY_TYPE, + "SignSize EdDSA with unknown OKP curve"); + edCoseKey.crv = WOLFCOSE_CRV_ED25519; +#endif + wc_CoseKey_Free(&eccCoseKey); + wc_CoseKey_Free(&edCoseKey); + } + + if (edInited != 0) { (void)wc_ed25519_free(&edKey); } + if (eccInited != 0) { (void)wc_ecc_free(&eccKey); } + if (rngInited != 0) { (void)wc_FreeRng(&rng); } +} +#endif /* ES256 && EDDSA && SIGN1_SIGN */ + +#if defined(WOLFCOSE_SIGN) && defined(WOLFCOSE_HAVE_EDDSA) && \ + defined(WOLFCOSE_HAVE_ED448) +static void test_cose_rfc9864_sign_multi_eddsa_curve_pin(void) +{ + WOLFCOSE_KEY key25519; + WOLFCOSE_KEY key448; + ed25519_key ed25519; + ed448_key ed448; + WC_RNG rng; + WOLFCOSE_SIGNATURE signers[2]; + int ret; + int rngInited = 0; + int ed25519Inited = 0; + int ed448Inited = 0; + int coseInited = 0; + uint8_t payload[] = "RFC 9864 multi EdDSA pin"; + uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; + uint8_t out[1024]; + size_t outLen = 0; + const uint8_t* decPayload = NULL; + size_t decPayloadLen = 0; + WOLFCOSE_HDR hdr; + + TEST_LOG(" [Sign Multi RFC 9864 Ed25519/Ed448 curve pin]\n"); + + ret = wc_InitRng(&rng); + if (ret != 0) { TEST_ASSERT(0, "rng init"); } + if (ret == 0) { + rngInited = 1; + wc_ed25519_init(&ed25519); + ed25519Inited = 1; + ret = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &ed25519); + if (ret != 0) { TEST_ASSERT(0, "ed25519 keygen"); } + } + if (ret == 0) { + wc_ed448_init(&ed448); + ed448Inited = 1; + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &ed448); + if (ret != 0) { TEST_ASSERT(0, "ed448 keygen"); } + } + if (ret == 0) { + (void)wc_CoseKey_Init(&key25519); + (void)wc_CoseKey_SetEd25519(&key25519, &ed25519); + (void)wc_CoseKey_Init(&key448); + (void)wc_CoseKey_SetEd448(&key448, &ed448); + coseInited = 1; + + XMEMSET(signers, 0, sizeof(signers)); + signers[0].algId = WOLFCOSE_ALG_ED25519; + signers[0].key = &key448; + signers[0].kid = NULL; + signers[0].kidLen = 0; + ret = wc_CoseSign_Sign(signers, 1, payload, sizeof(payload) - 1u, + NULL, 0, NULL, 0, scratch, sizeof(scratch), + out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "Sign_Sign Ed25519 with Ed448 key"); + + signers[0].algId = WOLFCOSE_ALG_ED25519; + signers[0].key = &key25519; + signers[1].algId = WOLFCOSE_ALG_ED448; + signers[1].key = &key448; + signers[1].kid = NULL; + signers[1].kidLen = 0; + ret = wc_CoseSign_Sign(signers, 2, payload, sizeof(payload) - 1u, + NULL, 0, NULL, 0, scratch, sizeof(scratch), + out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == 0, "Sign_Sign Ed25519 + Ed448"); + } + if (ret == 0) { + ret = wc_CoseSign_Verify(&key25519, 1, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "Sign_Verify Ed448 signer with Ed25519 key"); + ret = wc_CoseSign_Verify(&key448, 1, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT(ret == 0, "Sign_Verify Ed448 signer"); + ret = wc_CoseSign_Verify(&key25519, 0, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT(ret == 0, "Sign_Verify Ed25519 signer"); + } + + if (coseInited != 0) { + wc_CoseKey_Free(&key25519); + wc_CoseKey_Free(&key448); + } + if (ed25519Inited != 0) { (void)wc_ed25519_free(&ed25519); } + if (ed448Inited != 0) { (void)wc_ed448_free(&ed448); } + if (rngInited != 0) { (void)wc_FreeRng(&rng); } +} +#endif /* SIGN && EDDSA && ED448 */ + +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_SIGN1_SIGN) && \ + defined(WOLFCOSE_SIGN1_VERIFY) +/* The RFC 9053 IDs are rejected unless WOLFCOSE_ENABLE_DEPRECATED_ALGS. */ +static void test_cose_rfc9864_deprecated_ids(void) +{ + WOLFCOSE_KEY key; + ecc_key eccKey; + WC_RNG rng; + int ret; + int rngInited = 0; + int eccInited = 0; + int keyInited = 0; + uint8_t payload[] = "RFC 9053 ES256"; + uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; + uint8_t out[512]; + size_t outLen = 0; + size_t sizedLen = 0; + const uint8_t* decPayload = NULL; + size_t decPayloadLen = 0; + WOLFCOSE_HDR hdr; + + TEST_LOG(" [Sign1 RFC 9053 deprecated IDs]\n"); + + ret = wc_InitRng(&rng); + if (ret != 0) { TEST_ASSERT(0, "rng init"); } + if (ret == 0) { + rngInited = 1; + wc_ecc_init(&eccKey); + eccInited = 1; + ret = wc_ecc_make_key(&rng, 32, &eccKey); + if (ret != 0) { TEST_ASSERT(0, "ecc keygen"); } + } + if (ret == 0) { + (void)wc_CoseKey_Init(&key); + (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); + keyInited = 1; + + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, + payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, + scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == 0, "Sign1 ESP256"); + } + if (ret == 0) { + /* Tag(18), array(4), bstr(3) {1: alg}: byte 5 is the alg. */ + TEST_ASSERT((outLen > 6u) && (out[5] == 0x28u), + "ESP256 protected header carries -9"); + out[5] = 0x26u; /* -7, ES256 */ + ret = wc_CoseSign1_Verify(&key, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS + TEST_ASSERT(ret == WOLFCOSE_E_COSE_SIG_FAIL, + "ES256 relabel reaches the signature check"); + ret = wc_CoseSign1_SignSize_ex(&key, WOLFCOSE_ALG_ES256, + 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); + TEST_ASSERT(ret == 0, "SignSize ES256 (deprecated on)"); + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, NULL, 0, + payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, + scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == 0, "Sign1 ES256 (deprecated on)"); + if (ret == 0) { + ret = wc_CoseSign1_Verify(&key, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT((ret == 0) && (hdr.alg == WOLFCOSE_ALG_ES256), + "Verify ES256 (deprecated on)"); + } +#else + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "Verify rejects ES256 by default"); + ret = wc_CoseSign1_SignSize_ex(&key, WOLFCOSE_ALG_ES256, + 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "SignSize rejects ES256 by default"); + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, NULL, 0, + payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, + scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "Sign1 rejects ES256 by default"); + ret = 0; +#endif + } + + if (keyInited != 0) { wc_CoseKey_Free(&key); } + if (eccInited != 0) { (void)wc_ecc_free(&eccKey); } + if (rngInited != 0) { (void)wc_FreeRng(&rng); } +} +#endif /* ES256 && SIGN1_SIGN && SIGN1_VERIFY */ + +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_SIGN1_VERIFY) +/* RFC 9864 ECDSA (ESP256/384/512) known-answer verify vectors for the default + * profile. ECDSA signing is non-deterministic, so these are fixed public keys + * and fixed COSE_Sign1 messages signed once; they guard the decode and + * Sig_structure paths that the self-round-trips cannot, plus a tampered-byte + * rejection case. */ +static const uint8_t katPayloadEcdsa[] = "This is the content."; + +static const uint8_t katEsp256X[] = { + 0xC9, 0x29, 0xE4, 0xA5, 0xEF, 0x9F, 0xE0, 0xEB, 0x28, 0x9B, 0x52, 0xCF, + 0x24, 0x99, 0x9D, 0xB0, 0xFA, 0x66, 0x60, 0x32, 0x53, 0x26, 0xF8, 0x8A, + 0x4D, 0xC4, 0x03, 0x1C, 0x76, 0xDA, 0x61, 0xC4 +}; +static const uint8_t katEsp256Y[] = { + 0xE2, 0x3B, 0x99, 0x60, 0xF1, 0xA7, 0xD4, 0x8A, 0x31, 0x45, 0x02, 0x48, + 0x70, 0x3E, 0x9B, 0xAC, 0x1A, 0xEC, 0xDF, 0x48, 0xE3, 0xE3, 0xDE, 0x3E, + 0x5F, 0xD1, 0x7E, 0xD5, 0xCD, 0xFD, 0x41, 0x4B +}; +static const uint8_t katEsp256Cose[] = { + 0xD2, 0x84, 0x43, 0xA1, 0x01, 0x28, 0xA0, 0x54, 0x54, 0x68, 0x69, 0x73, + 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6F, 0x6E, 0x74, + 0x65, 0x6E, 0x74, 0x2E, 0x58, 0x40, 0xBC, 0x4E, 0x73, 0xA5, 0x5A, 0x98, + 0x86, 0xCA, 0x28, 0x11, 0x3A, 0x07, 0x80, 0xBA, 0xA4, 0x61, 0x22, 0x97, + 0x4A, 0x25, 0x80, 0xD8, 0x47, 0x37, 0x55, 0x2A, 0x4A, 0xA2, 0x41, 0xAC, + 0x7F, 0x8E, 0x50, 0xF9, 0xF9, 0x1B, 0x80, 0x9E, 0x59, 0x79, 0xE2, 0x70, + 0x82, 0x86, 0x74, 0xE2, 0xDE, 0x2F, 0xA7, 0x8D, 0xD8, 0x5D, 0xA2, 0xE9, + 0x50, 0x21, 0x09, 0x5D, 0x6B, 0xA4, 0x0E, 0xD4, 0x8B, 0xE4 +}; +#ifdef WOLFCOSE_HAVE_ES384 +static const uint8_t katEsp384X[] = { + 0xEC, 0xE9, 0x88, 0xA0, 0x99, 0xBA, 0x87, 0x9E, 0xE3, 0x30, 0x6A, 0x9D, + 0x4B, 0xC4, 0xCF, 0x34, 0x69, 0xE1, 0x23, 0x56, 0x3F, 0x1D, 0xFF, 0xB0, + 0xC8, 0x92, 0x89, 0x9C, 0x33, 0x54, 0xC0, 0x33, 0xD8, 0xF8, 0xB4, 0x5E, + 0xEA, 0xEB, 0xBE, 0x06, 0x52, 0x02, 0x49, 0xB3, 0x7A, 0xDD, 0xDD, 0x30 +}; +static const uint8_t katEsp384Y[] = { + 0xFF, 0xF3, 0xE8, 0x52, 0x07, 0xA9, 0x82, 0xC4, 0xFF, 0x93, 0x57, 0xFD, + 0x1A, 0x03, 0x31, 0xBB, 0xA4, 0x2B, 0x79, 0x07, 0x5F, 0x88, 0x6D, 0xE5, + 0xFE, 0x6D, 0x7D, 0x7D, 0x45, 0x8A, 0x7B, 0x70, 0x76, 0xAC, 0x73, 0x76, + 0x1E, 0xDA, 0x57, 0x02, 0x3A, 0xDC, 0x63, 0xE4, 0x37, 0xCD, 0x2E, 0xFB +}; +static const uint8_t katEsp384Cose[] = { + 0xD2, 0x84, 0x44, 0xA1, 0x01, 0x38, 0x32, 0xA0, 0x54, 0x54, 0x68, 0x69, + 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6F, 0x6E, + 0x74, 0x65, 0x6E, 0x74, 0x2E, 0x58, 0x60, 0x08, 0xB1, 0xEE, 0x7D, 0xE3, + 0xE0, 0xEB, 0xDB, 0xC3, 0x6D, 0xF0, 0xBE, 0xEB, 0x74, 0xFD, 0xE3, 0xF0, + 0x43, 0x8D, 0xCB, 0xC8, 0x54, 0x63, 0x89, 0x63, 0x08, 0xBE, 0x5E, 0xAF, + 0x3F, 0x47, 0x23, 0x14, 0x5A, 0x7B, 0x61, 0x34, 0x22, 0xFC, 0x15, 0x38, + 0xC6, 0xD7, 0xA4, 0x97, 0x35, 0x4B, 0x5E, 0x1F, 0x55, 0x03, 0x79, 0x73, + 0xDB, 0x84, 0xB5, 0x50, 0x4B, 0x31, 0x57, 0xBA, 0x16, 0x32, 0x69, 0xF5, + 0x84, 0xA2, 0xA4, 0x64, 0xE1, 0x83, 0x61, 0x4E, 0xBC, 0x0F, 0xBC, 0xEB, + 0xFD, 0x65, 0xA3, 0x17, 0x08, 0xCC, 0x16, 0xB2, 0x7E, 0x50, 0x36, 0xCC, + 0x13, 0x10, 0x5C, 0xD5, 0xA8, 0x89, 0x61 +}; +#endif +#ifdef WOLFCOSE_HAVE_ES512 +static const uint8_t katEsp512X[] = { + 0x00, 0x3C, 0x93, 0xCF, 0x51, 0xD4, 0x7F, 0xD3, 0x81, 0xF0, 0x33, 0x91, + 0xFD, 0x75, 0xD4, 0x4D, 0x4B, 0xEF, 0x03, 0x30, 0xFF, 0x1F, 0xAE, 0x4B, + 0x7D, 0xC7, 0xD9, 0x51, 0x0B, 0xF2, 0x8F, 0x41, 0x94, 0xB7, 0x37, 0xDD, + 0x0D, 0x4B, 0xE7, 0x34, 0x7D, 0x28, 0xD3, 0x45, 0x92, 0x1A, 0x36, 0x58, + 0x4A, 0xD6, 0xEC, 0x0E, 0xF5, 0x50, 0xFE, 0x7E, 0x62, 0x6C, 0x3A, 0x81, + 0xDC, 0x8B, 0xCC, 0x16, 0xCE, 0xCF +}; +static const uint8_t katEsp512Y[] = { + 0x01, 0x29, 0x66, 0xCE, 0x5A, 0x90, 0x0A, 0x0C, 0x79, 0xC2, 0xB7, 0x42, + 0xBB, 0x62, 0x0C, 0xA8, 0x86, 0x50, 0xC6, 0xF6, 0x0E, 0xC8, 0x4C, 0x34, + 0x49, 0x17, 0xA5, 0x5A, 0x9D, 0x55, 0xBF, 0x9F, 0x44, 0x60, 0xD9, 0x60, + 0xBF, 0x4B, 0x1A, 0xBC, 0x51, 0xE1, 0x72, 0x07, 0xF8, 0x0C, 0x93, 0xCA, + 0x3B, 0x3E, 0xB1, 0xB9, 0xAB, 0xEA, 0x61, 0xF1, 0x89, 0xFF, 0xDC, 0x4D, + 0xCE, 0x60, 0xA8, 0xEE, 0xA9, 0xC6 +}; +static const uint8_t katEsp512Cose[] = { + 0xD2, 0x84, 0x44, 0xA1, 0x01, 0x38, 0x33, 0xA0, 0x54, 0x54, 0x68, 0x69, + 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6F, 0x6E, + 0x74, 0x65, 0x6E, 0x74, 0x2E, 0x58, 0x84, 0x00, 0x52, 0xCE, 0x51, 0x17, + 0xCA, 0x9B, 0x69, 0x71, 0x05, 0x9D, 0x7D, 0xBB, 0x90, 0x0F, 0xBC, 0x41, + 0xC9, 0xD0, 0xC8, 0x3B, 0xDA, 0xB7, 0x36, 0x69, 0x04, 0x0B, 0xF0, 0xFF, + 0xA9, 0x71, 0x00, 0x31, 0x0E, 0xA3, 0x2A, 0xFB, 0x2F, 0x51, 0x46, 0x82, + 0xFE, 0x9A, 0x91, 0x19, 0x78, 0xF2, 0x22, 0x76, 0x79, 0x29, 0xB9, 0x8C, + 0x79, 0xEE, 0xE7, 0x84, 0x9A, 0x70, 0xF2, 0x19, 0xC7, 0x27, 0x32, 0xEE, + 0x1A, 0x00, 0x24, 0x06, 0xFE, 0x87, 0x70, 0x89, 0x8E, 0x25, 0x26, 0x30, + 0x6B, 0x5C, 0x55, 0xCA, 0x77, 0x4F, 0xD6, 0x24, 0xF2, 0xC3, 0xBD, 0x64, + 0x79, 0xBD, 0xE6, 0x28, 0xE3, 0x0B, 0x38, 0xFF, 0xAF, 0x17, 0x7A, 0x42, + 0xCF, 0xF0, 0x40, 0x91, 0x9C, 0xD0, 0x85, 0x6C, 0xC7, 0x09, 0x52, 0xBA, + 0x6A, 0x25, 0x54, 0x2F, 0x35, 0x75, 0xB1, 0x10, 0x34, 0x68, 0x4E, 0x4C, + 0x02, 0xF2, 0xE1, 0x7E, 0x30, 0x90, 0x18 +}; +#endif + +/* Verify one fixed ECDSA COSE_Sign1, check its alg and payload, then confirm a + * one-byte tamper of the message is rejected. */ +static void test_cose_esp_verify_kat(const char* tag, int wcCurve, + int32_t coseCrv, int32_t expectAlg, + const uint8_t* x, size_t xLen, const uint8_t* y, size_t yLen, + const uint8_t* cose, size_t coseLen) +{ + WOLFCOSE_KEY key; + ecc_key eccKey; + int ret; + int eccInited = 0; + int keyInited = 0; + uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; + uint8_t tampered[300]; + const uint8_t* decPayload = NULL; + size_t decPayloadLen = 0; + WOLFCOSE_HDR hdr; + + TEST_LOG(" [Sign1 RFC 9864 ECDSA known-answer vector]\n"); + (void)tag; + + ret = wc_ecc_init(&eccKey); + if (ret == 0) { + eccInited = 1; + ret = wc_ecc_import_unsigned(&eccKey, x, y, NULL, wcCurve); + (void)xLen; + (void)yLen; + } + if (ret == 0) { + (void)wc_CoseKey_Init(&key); + (void)wc_CoseKey_SetEcc(&key, coseCrv, &eccKey); + key.hasPrivate = 0; + keyInited = 1; + ret = wc_CoseSign1_Verify(&key, cose, coseLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT(ret == 0, "KAT ECDSA verifies"); + TEST_ASSERT(hdr.alg == expectAlg, "KAT ECDSA alg"); + TEST_ASSERT((decPayloadLen == sizeof(katPayloadEcdsa) - 1u) && + (XMEMCMP(decPayload, katPayloadEcdsa, decPayloadLen) == 0), + "KAT ECDSA payload"); + + /* Negative: flipping the last signature byte must fail verification. */ + if (coseLen <= sizeof(tampered)) { + XMEMCPY(tampered, cose, coseLen); + tampered[coseLen - 1u] ^= 0x01u; + ret = wc_CoseSign1_Verify(&key, tampered, coseLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT(ret != 0, "KAT ECDSA rejects tampered signature"); + } + ret = 0; + } + else { + TEST_ASSERT(0, "KAT ECDSA public import"); + } + + if (keyInited != 0) { wc_CoseKey_Free(&key); } + if (eccInited != 0) { (void)wc_ecc_free(&eccKey); } +} + +static void test_cose_rfc9864_esp256_kat(void) +{ + test_cose_esp_verify_kat("ESP256", ECC_SECP256R1, WOLFCOSE_CRV_P256, + WOLFCOSE_ALG_ESP256, katEsp256X, sizeof(katEsp256X), + katEsp256Y, sizeof(katEsp256Y), katEsp256Cose, sizeof(katEsp256Cose)); +#ifdef WOLFCOSE_HAVE_ES384 + test_cose_esp_verify_kat("ESP384", ECC_SECP384R1, WOLFCOSE_CRV_P384, + WOLFCOSE_ALG_ESP384, katEsp384X, sizeof(katEsp384X), + katEsp384Y, sizeof(katEsp384Y), katEsp384Cose, sizeof(katEsp384Cose)); +#endif +#ifdef WOLFCOSE_HAVE_ES512 + test_cose_esp_verify_kat("ESP512", ECC_SECP521R1, WOLFCOSE_CRV_P521, + WOLFCOSE_ALG_ESP512, katEsp512X, sizeof(katEsp512X), + katEsp512Y, sizeof(katEsp512Y), katEsp512Cose, sizeof(katEsp512Cose)); +#endif +} +#endif /* ES256 && SIGN1_VERIFY */ + +#if defined(WOLFCOSE_HAVE_EDDSA) && defined(WOLFCOSE_SIGN1_VERIFY) +/* RFC 9864 Ed25519 known-answer vector for the default profile. Ed25519 is + * deterministic (RFC 8032), so the whole COSE_Sign1 is fixed for a fixed key + * and payload; this guards the encode and Sig_structure paths that the + * self-round-trip tests cannot. Generated from the seed below. */ +static void test_cose_rfc9864_ed25519_kat(void) +{ + static const uint8_t katSeed[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F + }; + static const uint8_t katPub[] = { + 0x03, 0xA1, 0x07, 0xBF, 0xF3, 0xCE, 0x10, 0xBE, 0x1D, 0x70, 0xDD, 0x18, + 0xE7, 0x4B, 0xC0, 0x99, 0x67, 0xE4, 0xD6, 0x30, 0x9B, 0xA5, 0x0D, 0x5F, + 0x1D, 0xDC, 0x86, 0x64, 0x12, 0x55, 0x31, 0xB8 + }; + static const uint8_t katCose[] = { + 0xD2, 0x84, 0x43, 0xA1, 0x01, 0x32, 0xA0, 0x54, 0x54, 0x68, 0x69, 0x73, + 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6F, 0x6E, 0x74, + 0x65, 0x6E, 0x74, 0x2E, 0x58, 0x40, 0x48, 0xBA, 0x59, 0x63, 0x9B, 0x3A, + 0x0D, 0x70, 0x55, 0x23, 0x2D, 0xA6, 0xE8, 0x03, 0xE2, 0xF5, 0x73, 0x25, + 0x40, 0xDE, 0x83, 0xC6, 0xBE, 0x72, 0x19, 0x23, 0xB4, 0x2F, 0x32, 0x73, + 0x94, 0x8B, 0x99, 0x13, 0xB1, 0x9F, 0x82, 0xF2, 0x1F, 0x17, 0x20, 0x9F, + 0x58, 0x38, 0xC8, 0xE4, 0xCE, 0x82, 0xF6, 0x1C, 0xC3, 0x1F, 0x20, 0x86, + 0x67, 0xFE, 0xA6, 0x22, 0x16, 0x2E, 0xA3, 0xD0, 0x6A, 0x05 + }; + static const uint8_t katPayload[] = "This is the content."; + WOLFCOSE_KEY key; + ed25519_key edKey; + WC_RNG rng; + int ret; + int rngInited = 0; + int edInited = 0; + int keyInited = 0; + uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; + const uint8_t* decPayload = NULL; + size_t decPayloadLen = 0; + WOLFCOSE_HDR hdr; + + TEST_LOG(" [Sign1 RFC 9864 Ed25519 known-answer vector]\n"); + + wc_ed25519_init(&edKey); + edInited = 1; + + /* Import the full key from the seed so one key both verifies and re-signs; + * Ed25519 needs no private key to verify, but importing it keeps a single + * key lifetime (a verify-only build simply skips the re-sign below). */ + ret = wc_ed25519_import_private_key(katSeed, (word32)sizeof(katSeed), + katPub, (word32)sizeof(katPub), &edKey); + if (ret == 0) { + (void)wc_CoseKey_Init(&key); + (void)wc_CoseKey_SetEd25519(&key, &edKey); + keyInited = 1; + } + else { + TEST_ASSERT(0, "KAT Ed25519 key import"); + } + +#if defined(WOLFCOSE_SIGN1_SIGN) + /* Re-sign the fixed payload and byte-compare: deterministic, so exact. + * This is the only default-profile guard on the signature encode path. */ + if (ret == 0) { + uint8_t out[128]; + size_t outLen = 0; + int rngRet = wc_InitRng(&rng); + TEST_ASSERT(rngRet == 0, "KAT rng init"); + if (rngRet == 0) { + rngInited = 1; + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ED25519, NULL, 0, + katPayload, sizeof(katPayload) - 1u, NULL, 0, NULL, 0, + scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == 0, "KAT Ed25519 re-sign"); + TEST_ASSERT((outLen == sizeof(katCose)) && + (XMEMCMP(out, katCose, outLen) == 0), + "KAT Ed25519 re-sign matches vector"); + } + } +#else + (void)katSeed; + (void)rng; + (void)rngInited; +#endif + + /* Verify the fixed vector and its parsed header and payload. */ + if (ret == 0) { + ret = wc_CoseSign1_Verify(&key, katCose, sizeof(katCose), NULL, 0, + NULL, 0, scratch, sizeof(scratch), &hdr, &decPayload, + &decPayloadLen); + TEST_ASSERT(ret == 0, "KAT Ed25519 verifies"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ED25519, "KAT Ed25519 alg -19"); + TEST_ASSERT((decPayloadLen == sizeof(katPayload) - 1u) && + (XMEMCMP(decPayload, katPayload, decPayloadLen) == 0), + "KAT Ed25519 payload"); + } + + if (keyInited != 0) { wc_CoseKey_Free(&key); } + if (edInited != 0) { (void)wc_ed25519_free(&edKey); } + if (rngInited != 0) { (void)wc_FreeRng(&rng); } +} +#endif /* EDDSA && SIGN1_VERIFY */ + +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_SIGN) && \ + !defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) +/* The multi-signer path also refuses the deprecated RFC 9053 IDs by default. */ +static void test_cose_rfc9864_sign_deprecated_rejected(void) +{ + WOLFCOSE_KEY key; + ecc_key eccKey; + WC_RNG rng; + WOLFCOSE_SIGNATURE signers[1]; + int ret; + int rngInited = 0; + int eccInited = 0; + int keyInited = 0; + uint8_t payload[] = "RFC 9053 multi"; + uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; + uint8_t out[512]; + size_t outLen = 0; + const uint8_t* decPayload = NULL; + size_t decPayloadLen = 0; + WOLFCOSE_HDR hdr; + + TEST_LOG(" [Sign multi RFC 9053 rejected by default]\n"); + + ret = wc_InitRng(&rng); + if (ret != 0) { TEST_ASSERT(0, "rng init"); } + if (ret == 0) { + rngInited = 1; + wc_ecc_init(&eccKey); + eccInited = 1; + ret = wc_ecc_make_key(&rng, 32, &eccKey); + if (ret != 0) { TEST_ASSERT(0, "ecc keygen"); } + } + if (ret == 0) { + (void)wc_CoseKey_Init(&key); + (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); + keyInited = 1; + + XMEMSET(signers, 0, sizeof(signers)); + signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].key = &key; + signers[0].kid = NULL; + signers[0].kidLen = 0; + ret = wc_CoseSign_Sign(signers, 1, payload, sizeof(payload) - 1u, + NULL, 0, NULL, 0, scratch, sizeof(scratch), + out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "Sign_Sign rejects ES256 by default"); + + /* A well-formed ESP256 COSE_Sign relabelled to -7 must be refused on + * verify before the signature check. */ + signers[0].algId = WOLFCOSE_ALG_ESP256; + ret = wc_CoseSign_Sign(signers, 1, payload, sizeof(payload) - 1u, + NULL, 0, NULL, 0, scratch, sizeof(scratch), + out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == 0, "Sign_Sign ESP256"); + } + if (ret == 0) { + size_t i; + /* Signer protected bstr {1: -9} carries 0x28; flip to 0x26 (-7). */ + for (i = 0u; i + 2u < outLen; i++) { + if ((out[i] == 0x01u) && (out[i + 1u] == 0x28u)) { + out[i + 1u] = 0x26u; + break; + } + } + TEST_ASSERT(i + 2u < outLen, "located ESP256 alg byte to relabel"); + ret = wc_CoseSign_Verify(&key, 0, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT(ret == WOLFCOSE_E_COSE_BAD_ALG, + "Sign_Verify rejects -7 by default"); + ret = 0; + } + + if (keyInited != 0) { wc_CoseKey_Free(&key); } + if (eccInited != 0) { (void)wc_ecc_free(&eccKey); } + if (rngInited != 0) { (void)wc_FreeRng(&rng); } +} +#endif /* ES256 && SIGN && !DEPRECATED */ + +#if defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) && defined(WOLFCOSE_HAVE_EDDSA) && \ + defined(WOLFCOSE_SIGN1_SIGN) && defined(WOLFCOSE_SIGN1_VERIFY) && \ + defined(WOLFCOSE_SIGN) +static void test_cose_rfc9864_deprecated_eddsa(void) +{ + WOLFCOSE_KEY key; + ed25519_key edKey; + WC_RNG rng; + WOLFCOSE_SIGNATURE signers[1]; + int ret; + int rngInited = 0; + int edInited = 0; + int keyInited = 0; + uint8_t payload[] = "RFC 9053 EdDSA"; + uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; + uint8_t out[512]; + size_t outLen = 0; + const uint8_t* decPayload = NULL; + size_t decPayloadLen = 0; + WOLFCOSE_HDR hdr; + + TEST_LOG(" [Sign1/Sign RFC 9053 EdDSA (deprecated on)]\n"); + + ret = wc_InitRng(&rng); + if (ret != 0) { TEST_ASSERT(0, "rng init"); } + if (ret == 0) { + rngInited = 1; + wc_ed25519_init(&edKey); + edInited = 1; + ret = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &edKey); + if (ret != 0) { TEST_ASSERT(0, "ed25519 keygen"); } + } + if (ret == 0) { + (void)wc_CoseKey_Init(&key); + (void)wc_CoseKey_SetEd25519(&key, &edKey); + keyInited = 1; + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_EDDSA, NULL, 0, + payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, + scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == 0, "Sign1 EdDSA"); + } + if (ret == 0) { + ret = wc_CoseSign1_Verify(&key, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT((ret == 0) && (hdr.alg == WOLFCOSE_ALG_EDDSA), + "Verify EdDSA"); + } + if (ret == 0) { + signers[0].algId = WOLFCOSE_ALG_EDDSA; + signers[0].key = &key; + signers[0].kid = NULL; + signers[0].kidLen = 0; + ret = wc_CoseSign_Sign(signers, 1, payload, sizeof(payload) - 1u, + NULL, 0, NULL, 0, scratch, sizeof(scratch), + out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == 0, "Sign_Sign EdDSA"); + } + if (ret == 0) { + ret = wc_CoseSign_Verify(&key, 0, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT(ret == 0, "Sign_Verify EdDSA"); + } + + if (keyInited != 0) { wc_CoseKey_Free(&key); } + if (edInited != 0) { (void)wc_ed25519_free(&edKey); } + if (rngInited != 0) { (void)wc_FreeRng(&rng); } +} +#endif /* DEPRECATED && EDDSA && SIGN1 && SIGN */ + +#if defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) && defined(WOLFCOSE_HAVE_ES384) && \ + defined(WOLFCOSE_SIGN1_SIGN) && defined(WOLFCOSE_SIGN1_VERIFY) +/* End-to-end sign+verify with the deprecated ES384/ES512 IDs so the -35/-36 + * dispatch arms are exercised without the network interop job. */ +static void test_cose_rfc9864_deprecated_es384_es512(void) +{ + WOLFCOSE_KEY key; + ecc_key eccKey; + WC_RNG rng; + int ret; + int rngInited = 0; + int eccInited = 0; + int keyInited = 0; + uint8_t payload[] = "RFC 9053 ES384/ES512"; + uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; + uint8_t out[512]; + size_t outLen = 0; + const uint8_t* decPayload = NULL; + size_t decPayloadLen = 0; + WOLFCOSE_HDR hdr; + + TEST_LOG(" [Sign1 RFC 9053 ES384/ES512 (deprecated on)]\n"); + + ret = wc_InitRng(&rng); + if (ret != 0) { TEST_ASSERT(0, "rng init"); } + if (ret == 0) { rngInited = 1; } + + if (ret == 0) { + ret = wc_ecc_init(&eccKey); + if (ret == 0) { eccInited = 1; } + } + if (ret == 0) { + ret = wc_ecc_make_key(&rng, 48, &eccKey); + if (ret != 0) { TEST_ASSERT(0, "es384 keygen"); } + } + if (ret == 0) { + (void)wc_CoseKey_Init(&key); + (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P384, &eccKey); + keyInited = 1; + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES384, NULL, 0, + payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, + scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == 0, "Sign1 ES384"); + } + if (ret == 0) { + ret = wc_CoseSign1_Verify(&key, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT((ret == 0) && (hdr.alg == WOLFCOSE_ALG_ES384), + "Verify ES384"); + } + + if (keyInited != 0) { wc_CoseKey_Free(&key); keyInited = 0; } + if (eccInited != 0) { (void)wc_ecc_free(&eccKey); eccInited = 0; } + +#ifdef WOLFCOSE_HAVE_ES512 + if (ret == 0) { + ret = wc_ecc_init(&eccKey); + if (ret == 0) { eccInited = 1; } + } + if (ret == 0) { + ret = wc_ecc_make_key(&rng, 66, &eccKey); + if (ret != 0) { TEST_ASSERT(0, "es512 keygen"); } + } + if (ret == 0) { + (void)wc_CoseKey_Init(&key); + (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P521, &eccKey); + keyInited = 1; + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES512, NULL, 0, + payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, + scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == 0, "Sign1 ES512"); + } + if (ret == 0) { + ret = wc_CoseSign1_Verify(&key, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT((ret == 0) && (hdr.alg == WOLFCOSE_ALG_ES512), + "Verify ES512"); + } + if (keyInited != 0) { wc_CoseKey_Free(&key); keyInited = 0; } + if (eccInited != 0) { (void)wc_ecc_free(&eccKey); eccInited = 0; } +#endif /* WOLFCOSE_HAVE_ES512 */ + + if (rngInited != 0) { (void)wc_FreeRng(&rng); } +} +#endif /* DEPRECATED && ES384 && SIGN1 */ + +#if defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) && defined(WOLFCOSE_HAVE_ES256) && \ + defined(WOLFCOSE_SIGN) +/* COSE_Sign (multi-signer) round trip with the deprecated ES256 ID. */ +static void test_cose_rfc9864_deprecated_sign_es256(void) +{ + WOLFCOSE_KEY key; + ecc_key eccKey; + WC_RNG rng; + WOLFCOSE_SIGNATURE signers[1]; + int ret; + int rngInited = 0; + int eccInited = 0; + int keyInited = 0; + uint8_t payload[] = "RFC 9053 COSE_Sign"; + uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; + uint8_t out[512]; + size_t outLen = 0; + const uint8_t* decPayload = NULL; + size_t decPayloadLen = 0; + WOLFCOSE_HDR hdr; + + TEST_LOG(" [Sign multi RFC 9053 ES256 (deprecated on)]\n"); + + ret = wc_InitRng(&rng); + if (ret != 0) { TEST_ASSERT(0, "rng init"); } + if (ret == 0) { + rngInited = 1; + ret = wc_ecc_init(&eccKey); + if (ret == 0) { eccInited = 1; } + } + if (ret == 0) { + ret = wc_ecc_make_key(&rng, 32, &eccKey); + if (ret != 0) { TEST_ASSERT(0, "ecc keygen"); } + } + if (ret == 0) { + (void)wc_CoseKey_Init(&key); + (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); + keyInited = 1; + XMEMSET(signers, 0, sizeof(signers)); + signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].key = &key; + signers[0].kid = NULL; + signers[0].kidLen = 0; + ret = wc_CoseSign_Sign(signers, 1, payload, sizeof(payload) - 1u, + NULL, 0, NULL, 0, scratch, sizeof(scratch), + out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == 0, "Sign_Sign ES256"); + } + if (ret == 0) { + ret = wc_CoseSign_Verify(&key, 0, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT((ret == 0) && (hdr.alg == WOLFCOSE_ALG_ES256), + "Sign_Verify ES256"); + } + + if (keyInited != 0) { wc_CoseKey_Free(&key); } + if (eccInited != 0) { (void)wc_ecc_free(&eccKey); } + if (rngInited != 0) { (void)wc_FreeRng(&rng); } +} +#endif /* DEPRECATED && ES256 && SIGN */ + +#if defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) && defined(WOLFCOSE_HAVE_ED448) && \ + defined(WOLFCOSE_SIGN1_SIGN) && defined(WOLFCOSE_SIGN1_VERIFY) +/* Polymorphic EdDSA (-8) resolves Ed25519 vs Ed448 from the key's curve at + * sign/verify time; cover the Ed448 branch end-to-end (works in an Ed448-only + * deprecated build). */ +static void test_cose_rfc9864_deprecated_ed448(void) +{ + WOLFCOSE_KEY key; + ed448_key edKey; + WC_RNG rng; + int ret; + int rngInited = 0; + int edInited = 0; + int keyInited = 0; + uint8_t payload[] = "RFC 9053 EdDSA Ed448"; + uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; + uint8_t out[512]; + size_t outLen = 0; + size_t sizedLen = 0; + const uint8_t* decPayload = NULL; + size_t decPayloadLen = 0; + WOLFCOSE_HDR hdr; + + TEST_LOG(" [Sign1 RFC 9053 EdDSA with Ed448 key (deprecated on)]\n"); + + ret = wc_InitRng(&rng); + if (ret != 0) { TEST_ASSERT(0, "rng init"); } + if (ret == 0) { + rngInited = 1; + wc_ed448_init(&edKey); + edInited = 1; + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &edKey); + if (ret != 0) { TEST_ASSERT(0, "ed448 keygen"); } + } + if (ret == 0) { + (void)wc_CoseKey_Init(&key); + (void)wc_CoseKey_SetEd448(&key, &edKey); + keyInited = 1; + ret = wc_CoseSign1_SignSize_ex(&key, WOLFCOSE_ALG_EDDSA, + 0u, sizeof(payload) - 1u, 0u, 0u, &sizedLen); + TEST_ASSERT((ret == 0) && (sizedLen > 114u), + "SignSize EdDSA Ed448 includes 114-byte slot"); + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_EDDSA, NULL, 0, + payload, sizeof(payload) - 1u, NULL, 0, NULL, 0, + scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); + TEST_ASSERT(ret == 0, "Sign1 EdDSA Ed448"); + } + if (ret == 0) { + ret = wc_CoseSign1_Verify(&key, out, outLen, NULL, 0, NULL, 0, + scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT((ret == 0) && (hdr.alg == WOLFCOSE_ALG_EDDSA), + "Verify EdDSA Ed448"); + } + + if (keyInited != 0) { wc_CoseKey_Free(&key); } + if (edInited != 0) { (void)wc_ed448_free(&edKey); } + if (rngInited != 0) { (void)wc_FreeRng(&rng); } +} +#endif /* DEPRECATED && ED448 && SIGN1 */ + +static void test_cose_build_sig_structure_context(void) +{ + int ret; + uint8_t scratch[64]; + size_t structLen = 0; + /* Use a 1-byte protected-hdr placeholder, no AAD, 1-byte payload. */ + const uint8_t protectedHdr[1] = {0x40}; /* h'' bstr inside, body opaque */ + const uint8_t payload[1] = {0x00}; + + TEST_LOG(" [BuildToBeSignedMaced: context bytes]\n"); + + /* Sign1 path: expect array(4), tstr "Signature1", bstr, + * bstr, bstr. The first two bytes for an + * array of 4 + tstr(10) prefix should be 0x84 then 0x6A. */ + ret = wolfCose_BuildToBeSignedMaced( + WOLFCOSE_CTX_SIGNATURE1, sizeof(WOLFCOSE_CTX_SIGNATURE1), + protectedHdr, sizeof(protectedHdr), + NULL, 0, + NULL, 0, + payload, sizeof(payload), + scratch, sizeof(scratch), &structLen); + TEST_ASSERT(ret == WOLFCOSE_SUCCESS, + "BuildToBeSignedMaced Sign1 ok"); + TEST_ASSERT(structLen >= 12u, "Sign1 struct length"); + TEST_ASSERT(scratch[0] == 0x84u, "Sign1 array(4) header"); + TEST_ASSERT(scratch[1] == 0x6Au, "Sign1 tstr(10) header"); + TEST_ASSERT(memcmp(&scratch[2], "Signature1", 10) == 0, + "Sign1 context bytes"); + + /* Sign multi-signer path: array(5), tstr(9) "Signature". */ + ret = wolfCose_BuildToBeSignedMaced( + WOLFCOSE_CTX_SIGNATURE, sizeof(WOLFCOSE_CTX_SIGNATURE), + protectedHdr, sizeof(protectedHdr), + protectedHdr, sizeof(protectedHdr), + NULL, 0, + payload, sizeof(payload), + scratch, sizeof(scratch), &structLen); + TEST_ASSERT(ret == WOLFCOSE_SUCCESS, + "BuildToBeSignedMaced Sign multi ok"); + TEST_ASSERT(scratch[0] == 0x85u, "Sign multi array(5) header"); + TEST_ASSERT(scratch[1] == 0x69u, "Sign multi tstr(9) header"); + TEST_ASSERT(memcmp(&scratch[2], "Signature", 9) == 0, + "Sign multi context bytes"); + + /* Mac0 path: array(4), tstr(4) "MAC0". */ + ret = wolfCose_BuildToBeSignedMaced( + WOLFCOSE_CTX_MAC0, sizeof(WOLFCOSE_CTX_MAC0), + protectedHdr, sizeof(protectedHdr), + NULL, 0, + NULL, 0, + payload, sizeof(payload), + scratch, sizeof(scratch), &structLen); + TEST_ASSERT(ret == WOLFCOSE_SUCCESS, + "BuildToBeSignedMaced Mac0 ok"); + TEST_ASSERT(scratch[1] == 0x64u, "Mac0 tstr(4) header"); + TEST_ASSERT(memcmp(&scratch[2], "MAC0", 4) == 0, + "Mac0 context bytes"); + + /* Mac multi-recipient path: array(4), tstr(3) "MAC" (F-5234). */ + ret = wolfCose_BuildToBeSignedMaced( + WOLFCOSE_CTX_MAC, sizeof(WOLFCOSE_CTX_MAC), + protectedHdr, sizeof(protectedHdr), + NULL, 0, + NULL, 0, + payload, sizeof(payload), + scratch, sizeof(scratch), &structLen); + TEST_ASSERT(ret == WOLFCOSE_SUCCESS, + "BuildToBeSignedMaced Mac ok"); + TEST_ASSERT(scratch[0] == 0x84u, "Mac array(4) header"); + TEST_ASSERT(scratch[1] == 0x63u, "Mac tstr(3) header"); + TEST_ASSERT(memcmp(&scratch[2], "MAC", 3) == 0, "Mac context bytes"); + + /* AEAD Enc_structure contexts are AAD inputs; assert the context constants + * directly so a byte mutation is detected (F-5232, F-5233). */ + TEST_ASSERT(sizeof(WOLFCOSE_CTX_ENCRYPT0) == 8u && + memcmp(WOLFCOSE_CTX_ENCRYPT0, "Encrypt0", 8) == 0, + "Encrypt0 context bytes"); + TEST_ASSERT(sizeof(WOLFCOSE_CTX_ENCRYPT) == 7u && + memcmp(WOLFCOSE_CTX_ENCRYPT, "Encrypt", 7) == 0, + "Encrypt context bytes"); + TEST_ASSERT(sizeof(WOLFCOSE_CTX_MAC) == 3u && + memcmp(WOLFCOSE_CTX_MAC, "MAC", 3) == 0, + "MAC context constant bytes"); + + ret = wolfCose_BuildToBeSignedMaced( + WOLFCOSE_CTX_SIGNATURE1, sizeof(WOLFCOSE_CTX_SIGNATURE1), + protectedHdr, sizeof(protectedHdr), + NULL, 0u, + NULL, 1u, + payload, sizeof(payload), + scratch, sizeof(scratch), &structLen); + TEST_ASSERT(ret == WOLFCOSE_E_INVALID_ARG, + "auth structure null aad with length rejected"); +} + +/* ----- Coverage boost: exercise multi-signer / multi-recipient paths + * added by recent hardening so the per-file 100% CI coverage + * threshold is preserved. ----- + */ + +#if defined(WOLFCOSE_HAVE_RSAPSS) && defined(WOLFCOSE_SIGN) && \ + defined(WOLFSSL_KEY_GEN) +static void test_cose_sign_multi_pss_roundtrip(void) +{ + WOLFCOSE_KEY key; + RsaKey rsaKey; + WC_RNG rng; + WOLFCOSE_SIGNATURE signers[1]; + WOLFCOSE_HDR hdr; + int ret; + uint8_t out[2048]; + uint8_t scratch[2048]; + size_t outLen = 0; + const uint8_t payload[] = "Multi-signer PSS payload"; + const uint8_t* decPayload = NULL; + size_t decPayloadLen = 0; + + TEST_LOG(" [Sign Multi PSS roundtrip]\n"); + + ret = wc_InitRng(&rng); + TEST_ASSERT(ret == 0, "multi pss rng init"); + ret = wc_InitRsaKey(&rsaKey, NULL); + TEST_ASSERT(ret == 0, "multi pss rsa init"); + ret = wc_MakeRsaKey(&rsaKey, 2048, WC_RSA_EXPONENT, &rng); + TEST_ASSERT(ret == 0, "multi pss keygen"); + + (void)wc_CoseKey_Init(&key); + ret = wc_CoseKey_SetRsa(&key, &rsaKey); + TEST_ASSERT(ret == 0, "multi pss key set"); + + signers[0].algId = WOLFCOSE_ALG_PS256; + signers[0].key = &key; + signers[0].kid = NULL; + signers[0].kidLen = 0; + + ret = wc_CoseSign_Sign(signers, 1, + payload, sizeof(payload) - 1, + NULL, 0, + NULL, 0, + scratch, sizeof(scratch), + out, sizeof(out), &outLen, + &rng); + TEST_ASSERT(ret == 0, "multi pss sign"); + + memset(&hdr, 0, sizeof(hdr)); + ret = wc_CoseSign_Verify(&key, 0, + out, outLen, + NULL, 0, + NULL, 0, + scratch, sizeof(scratch), + &hdr, &decPayload, &decPayloadLen); + TEST_ASSERT(ret == 0, "multi pss verify"); + TEST_ASSERT(decPayloadLen == sizeof(payload) - 1, + "multi pss payload len"); + TEST_ASSERT(memcmp(decPayload, payload, decPayloadLen) == 0, + "multi pss payload match"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_PS256, "multi pss hdr alg"); + + wc_CoseKey_Free(&key); + (void)wc_FreeRsaKey(&rsaKey); + (void)wc_FreeRng(&rng); +} +#endif + +#if defined(WOLFCOSE_HAVE_MLDSA) && defined(WOLFCOSE_SIGN) +static void test_cose_sign_multi_mldsa_roundtrip(void) +{ + WOLFCOSE_KEY key; + wc_MlDsaKey dlKey; + WC_RNG rng; + WOLFCOSE_SIGNATURE signers[1]; + WOLFCOSE_HDR hdr; + int ret; + uint8_t out[3072]; + uint8_t scratch[8192]; size_t outLen = 0; const uint8_t payload[] = "Multi-signer ML-DSA payload"; const uint8_t* decPayload = NULL; @@ -21530,7 +22712,7 @@ static void test_cose_key_kid_alg_roundtrip(void) TEST_ASSERT(ret == 0, "key kidAlg src set"); srcKey.kid = kid; srcKey.kidLen = sizeof(kid) - 1; - srcKey.alg = WOLFCOSE_ALG_ES256; + srcKey.alg = WOLFCOSE_ALG_ESP256; ret = wc_CoseKey_Encode(&srcKey, encoded, sizeof(encoded), &encodedLen); TEST_ASSERT(ret == 0, "key kidAlg encode"); @@ -21546,7 +22728,7 @@ static void test_cose_key_kid_alg_roundtrip(void) #else TEST_ASSERT(ret == 0, "key kidAlg decode"); #endif - TEST_ASSERT(dstKey.alg == WOLFCOSE_ALG_ES256, + TEST_ASSERT(dstKey.alg == WOLFCOSE_ALG_ESP256, "key kidAlg alg preserved"); TEST_ASSERT(dstKey.kidLen == sizeof(kid) - 1, "key kidAlg kidLen preserved"); @@ -21653,9 +22835,9 @@ static void test_cose_sign_multi_alg_key_mismatch(void) (void)wc_CoseKey_Init(&key); ret = wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); TEST_ASSERT(ret == 0, "mismatch key set"); - key.alg = WOLFCOSE_ALG_ES384; /* key declares ES384 */ + key.alg = WOLFCOSE_ALG_ESP384; /* key declares ES384 */ - signers[0].algId = WOLFCOSE_ALG_ES256; /* but signer says ES256 */ + signers[0].algId = WOLFCOSE_ALG_ESP256; /* but signer says ES256 */ signers[0].key = &key; signers[0].kid = NULL; signers[0].kidLen = 0; @@ -21753,7 +22935,7 @@ static void test_cose_sign_multi_ed448_roundtrip(void) ret = wc_CoseKey_SetEd448(&key, &edKey); TEST_ASSERT(ret == 0, "multi ed448 key set"); - signers[0].algId = WOLFCOSE_ALG_EDDSA; + signers[0].algId = WOLFCOSE_ALG_ED448; signers[0].key = &key; signers[0].kid = NULL; signers[0].kidLen = 0; @@ -21796,19 +22978,30 @@ static void test_cose_sigsize_known_algs(void) TEST_LOG(" [SigSize known algorithms]\n"); #ifdef WOLFCOSE_HAVE_ES256 - ret = wolfCose_SigSize(WOLFCOSE_ALG_ES256, &sz); + ret = wolfCose_SigSize(WOLFCOSE_ALG_ESP256, &sz); TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (sz == 64u), - "SigSize ES256 -> 64"); + "SigSize ESP256 -> 64"); #ifdef WOLFCOSE_HAVE_ES384 - ret = wolfCose_SigSize(WOLFCOSE_ALG_ES384, &sz); + ret = wolfCose_SigSize(WOLFCOSE_ALG_ESP384, &sz); TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (sz == 96u), - "SigSize ES384 -> 96"); + "SigSize ESP384 -> 96"); #endif #endif -#if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) +#if (defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448)) && \ + defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) ret = wolfCose_SigSize(WOLFCOSE_ALG_EDDSA, &sz); TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && ((sz == 64u) || (sz == 114u)), "SigSize EDDSA returns curve max"); +#endif +#ifdef WOLFCOSE_HAVE_EDDSA + ret = wolfCose_SigSize(WOLFCOSE_ALG_ED25519, &sz); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (sz == 64u), + "SigSize Ed25519 -> 64"); +#endif +#ifdef WOLFCOSE_HAVE_ED448 + ret = wolfCose_SigSize(WOLFCOSE_ALG_ED448, &sz); + TEST_ASSERT((ret == WOLFCOSE_SUCCESS) && (sz == 114u), + "SigSize Ed448 -> 114"); #endif (void)ret; (void)sz; @@ -22468,10 +23661,10 @@ static void test_cose_sign1_key_alg_mismatch(void) (void)wc_CoseKey_Init(&key); ret = wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); TEST_ASSERT(ret == 0, "sign1 mismatch key set"); - key.alg = WOLFCOSE_ALG_ES256; + key.alg = WOLFCOSE_ALG_ESP256; /* Pass ES384 to a key that declares ES256 -> reject. */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES384, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP384, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, @@ -22515,7 +23708,7 @@ static void test_cose_sign1_verify_key_alg_mismatch(void) ret = wc_CoseKey_SetEcc(&signKey, WOLFCOSE_CRV_P256, &eccKey); TEST_ASSERT(ret == 0, "v-mismatch sign key set"); - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, @@ -22528,7 +23721,7 @@ static void test_cose_sign1_verify_key_alg_mismatch(void) (void)wc_CoseKey_Init(&verifyKey); ret = wc_CoseKey_SetEcc(&verifyKey, WOLFCOSE_CRV_P256, &eccKey); TEST_ASSERT(ret == 0, "v-mismatch verify key set"); - verifyKey.alg = WOLFCOSE_ALG_ES384; + verifyKey.alg = WOLFCOSE_ALG_ESP384; memset(&hdr, 0, sizeof(hdr)); ret = wc_CoseSign1_Verify(&verifyKey, out, outLen, @@ -22575,7 +23768,7 @@ static void test_cose_sign1_verify_unprotected_alg(void) (void)wc_CoseKey_Init(&key); ret = wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); TEST_ASSERT(ret == 0, "unprotected Sign1 alg key set"); - key.alg = WOLFCOSE_ALG_ES256; + key.alg = WOLFCOSE_ALG_ESP256; ret = wolfCose_BuildToBeSignedMaced( WOLFCOSE_CTX_SIGNATURE1, sizeof(WOLFCOSE_CTX_SIGNATURE1), @@ -22598,7 +23791,7 @@ static void test_cose_sign1_verify_unprotected_alg(void) if (ret == 0) { ret = wc_CBOR_EncodeBstr(&enc, NULL, 0u); } if (ret == 0) { ret = wc_CBOR_EncodeMapStart(&enc, 1u); } if (ret == 0) { ret = wc_CBOR_EncodeInt(&enc, WOLFCOSE_HDR_ALG); } - if (ret == 0) { ret = wc_CBOR_EncodeInt(&enc, WOLFCOSE_ALG_ES256); } + if (ret == 0) { ret = wc_CBOR_EncodeInt(&enc, WOLFCOSE_ALG_ESP256); } if (ret == 0) { ret = wc_CBOR_EncodeBstr(&enc, payloadData, sizeof(payloadData) - 1u); @@ -22651,7 +23844,7 @@ static void test_cose_sign1_both_payloads(void) TEST_ASSERT(ret == 0, "sign1 both key set"); /* Both payload and detachedPayload non-NULL must be rejected. */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, inline_payload, sizeof(inline_payload) - 1, detached_payload, sizeof(detached_payload) - 1, @@ -22949,7 +24142,7 @@ static void test_internal_helpers(void) /* ----- wolfCose_AlgToHashType ----- */ /* NULL output pointer */ - ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ES256, NULL); + ret = wolfCose_AlgToHashType(WOLFCOSE_ALG_ESP256, NULL); TEST_ASSERT(ret == WOLFCOSE_E_INVALID_ARG, "AlgToHashType NULL"); /* Invalid algorithm (default case) */ @@ -22958,7 +24151,7 @@ static void test_internal_helpers(void) /* ----- wolfCose_SigSize ----- */ /* NULL output pointer */ - ret = wolfCose_SigSize(WOLFCOSE_ALG_ES256, NULL); + ret = wolfCose_SigSize(WOLFCOSE_ALG_ESP256, NULL); TEST_ASSERT(ret == WOLFCOSE_E_INVALID_ARG, "SigSize NULL"); /* Invalid algorithm (default case) */ @@ -23046,7 +24239,7 @@ static void test_internal_helpers(void) #ifdef WOLFCOSE_HAVE_ES512 /* ES512 signature size */ - ret = wolfCose_SigSize(WOLFCOSE_ALG_ES512, &sz); + ret = wolfCose_SigSize(WOLFCOSE_ALG_ESP512, &sz); TEST_ASSERT(ret == WOLFCOSE_SUCCESS && sz == 132, "SigSize ES512"); #endif @@ -23126,10 +24319,10 @@ static void test_internal_helpers(void) WOLFCOSE_HDR_STATE hdrState; /* EncodeProtectedHdr with NULL */ - ret = wolfCose_EncodeProtectedHdr(WOLFCOSE_ALG_ES256, NULL, 64, &hdrLen); + ret = wolfCose_EncodeProtectedHdr(WOLFCOSE_ALG_ESP256, NULL, 64, &hdrLen); TEST_ASSERT(ret == WOLFCOSE_E_INVALID_ARG, "EncodeProtectedHdr NULL buf"); - ret = wolfCose_EncodeProtectedHdr(WOLFCOSE_ALG_ES256, hdrBuf, 64, NULL); + ret = wolfCose_EncodeProtectedHdr(WOLFCOSE_ALG_ESP256, hdrBuf, 64, NULL); TEST_ASSERT(ret == WOLFCOSE_E_INVALID_ARG, "EncodeProtectedHdr NULL outLen"); /* DecodeProtectedHdr with NULL hdr */ @@ -23202,8 +24395,8 @@ static void test_internal_helpers(void) /* Unprotected header with alg (label 1) when hdr->alg == 0 */ /* empty-brace-scan: allow - test-local temporary scope */ { - /* CBOR: {1: -7} - alg ES256 in unprotected header */ - uint8_t algHdr[] = {0xA1, 0x01, 0x26}; /* map(1), 1, -7 */ + /* CBOR: {1: -9} - alg ESP256 in unprotected header */ + uint8_t algHdr[] = {0xA1, 0x01, 0x28}; /* map(1), 1, -9 */ ctx.cbuf = algHdr; ctx.bufSz = sizeof(algHdr); ctx.idx = 0; @@ -23211,7 +24404,7 @@ static void test_internal_helpers(void) XMEMSET(&hdrState, 0, sizeof(hdrState)); ret = wolfCose_DecodeUnprotectedHdr(&ctx, &hdr, &hdrState); TEST_ASSERT(ret == WOLFCOSE_SUCCESS, "DecodeUnprotectedHdr alg"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ES256, "alg in unprotected"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ESP256, "alg in unprotected"); } /* Unprotected header with map count > 16 */ @@ -23276,7 +24469,7 @@ static void test_force_failure_crypto(void) /* Test ECC sign failure */ wolfForceFailure_Set(WOLF_FAIL_ECC_SIGN); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, /* kid */ payload, sizeof(payload), NULL, 0, /* detached */ @@ -23288,7 +24481,7 @@ static void test_force_failure_crypto(void) /* Test ECC sig_to_rs failure */ coseMsgLen = sizeof(coseMsg); wolfForceFailure_Set(WOLF_FAIL_ECC_SIG_TO_RS); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, /* kid */ payload, sizeof(payload), NULL, 0, /* detached */ @@ -23299,7 +24492,7 @@ static void test_force_failure_crypto(void) /* Create a valid signature for verify tests */ coseMsgLen = sizeof(coseMsg); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, /* kid */ payload, sizeof(payload), NULL, 0, /* detached */ @@ -23493,7 +24686,7 @@ static void test_force_failure_crypto(void) /* Test Ed25519 sign failure */ coseMsgLen = sizeof(coseMsg); wolfForceFailure_Set(WOLF_FAIL_ED25519_SIGN); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_EDDSA, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ED25519, NULL, 0, payload, sizeof(payload), NULL, 0, NULL, 0, scratch, sizeof(scratch), coseMsg, sizeof(coseMsg), &coseMsgLen, &rng); @@ -23501,7 +24694,7 @@ static void test_force_failure_crypto(void) /* Create valid signature for verify test */ coseMsgLen = sizeof(coseMsg); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_EDDSA, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ED25519, NULL, 0, payload, sizeof(payload), NULL, 0, NULL, 0, scratch, sizeof(scratch), coseMsg, sizeof(coseMsg), &coseMsgLen, &rng); @@ -23938,7 +25131,7 @@ static void test_force_failure_crypto(void) /* Test Ed448 sign failure */ ed448CoseMsgLen = sizeof(ed448CoseMsg); wolfForceFailure_Set(WOLF_FAIL_ED448_SIGN); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_EDDSA, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ED448, NULL, 0, payload, sizeof(payload), NULL, 0, NULL, 0, ed448Scratch, sizeof(ed448Scratch), ed448CoseMsg, sizeof(ed448CoseMsg), &ed448CoseMsgLen, &rng); @@ -23946,7 +25139,7 @@ static void test_force_failure_crypto(void) /* Create valid signature for verify test */ ed448CoseMsgLen = sizeof(ed448CoseMsg); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_EDDSA, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ED448, NULL, 0, payload, sizeof(payload), NULL, 0, NULL, 0, ed448Scratch, sizeof(ed448Scratch), ed448CoseMsg, sizeof(ed448CoseMsg), &ed448CoseMsgLen, &rng); @@ -24598,7 +25791,7 @@ static void test_wrong_key_type_sign(void) (void)wc_CoseKey_Init(&symmKey); (void)wc_CoseKey_SetSymmetric(&symmKey, keyData, sizeof(keyData)); - ret = wc_CoseSign1_Sign(&symmKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&symmKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, @@ -24926,7 +26119,7 @@ static void test_null_key_operations(void) ret = wc_InitRng(&rng); if (ret == 0) { /* NULL key for sign */ - ret = wc_CoseSign1_Sign(NULL, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(NULL, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, @@ -25379,7 +26572,7 @@ static void test_corrupted_eddsa_signature(void) (void)wc_CoseKey_SetEd25519(&key, &edKey); /* Create valid signature */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_EDDSA, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ED25519, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, @@ -25769,7 +26962,11 @@ static void test_key_type_eddsa_wrong_crv(void) (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); /* ECC key with EdDSA algorithm (should fail - wrong kty) */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_EDDSA, +#ifdef WOLFCOSE_HAVE_EDDSA + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ED25519, +#else + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ED448, +#endif NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, @@ -25812,7 +27009,7 @@ static void test_key_type_okp_for_ecdsa(void) (void)wc_CoseKey_SetEd25519(&key, &edKey); /* OKP/Ed25519 key with ES256 algorithm (should fail - wrong kty) */ - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, @@ -26103,9 +27300,9 @@ static void test_multi_sign_verify_wrong_signer(void) (void)wc_CoseKey_SetEcc(&wrongKey, WOLFCOSE_CRV_P256, &eccWrongKey); memset(signers, 0, sizeof(signers)); - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = &key1; - signers[1].algId = WOLFCOSE_ALG_ES256; + signers[1].algId = WOLFCOSE_ALG_ESP256; signers[1].key = &key2; ret = wc_CoseSign_Sign(signers, 2, @@ -26864,7 +28061,7 @@ static void test_sign_multi_array_count(void) ret = wc_CoseKey_SetEcc(&key1, WOLFCOSE_CRV_P256, &eccKey1); TEST_ASSERT(ret == 0, "key set"); - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = &key1; signers[0].kid = NULL; signers[0].kidLen = 0; @@ -27291,31 +28488,31 @@ static void test_cose_sign1_size_and_untagged(void) TEST_ASSERT(ret == 0, "size test key setup"); for (i = 0u; i < (sizeof(boundaryLen) / sizeof(boundaryLen[0])); i++) { - sizeRet = wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ES256, 0u, + sizeRet = wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ESP256, 0u, boundaryLen[i], 0u, 0u, &sizedLen); TEST_ASSERT(sizeRet == 0 && sizedLen == payloadExpected[i], "payload size boundary"); - sizeRet = wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ES256, + sizeRet = wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ESP256, boundaryLen[i], 0u, 0u, 0u, &sizedLen); TEST_ASSERT(sizeRet == 0 && sizedLen == kidExpected[i], "kid size boundary"); } if (ret == 0) { - ret = wc_CoseSign1_Sign_ex(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign_ex(&key, WOLFCOSE_ALG_ESP256, kid, sizeof(kid) - 1u, payload, sizeof(payload), NULL, 0u, NULL, 0u, scratch, sizeof(scratch), tagged, sizeof(tagged), &taggedLen, &rng, 0u); TEST_ASSERT(ret == 0, "tagged sign"); } if (ret == 0) { - ret = wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ESP256, sizeof(kid) - 1u, sizeof(payload), 0u, 0u, &sizedLen); TEST_ASSERT(ret == 0 && sizedLen == taggedLen, "tagged size equals signed size"); } if (ret == 0) { - ret = wc_CoseSign1_Sign_ex(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign_ex(&key, WOLFCOSE_ALG_ESP256, kid, sizeof(kid) - 1u, payload, sizeof(payload), NULL, 0u, NULL, 0u, scratch, sizeof(scratch), untagged, sizeof(untagged), &untaggedLen, &rng, @@ -27324,7 +28521,7 @@ static void test_cose_sign1_size_and_untagged(void) "untagged starts with array(4)"); } if (ret == 0) { - ret = wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ESP256, sizeof(kid) - 1u, sizeof(payload), 0u, WOLFCOSE_SIGN1_UNTAGGED, &sizedLen); TEST_ASSERT(ret == 0 && sizedLen == untaggedLen, @@ -27341,23 +28538,23 @@ static void test_cose_sign1_size_and_untagged(void) "untagged output verifies"); } if (ret == 0) { - ret = wc_CoseSign1_Sign_ex(&key, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign_ex(&key, WOLFCOSE_ALG_ESP256, NULL, 0u, NULL, 0u, detached, sizeof(detached), NULL, 0u, scratch, sizeof(scratch), tagged, sizeof(tagged), &taggedLen, &rng, 0u); TEST_ASSERT(ret == 0, "detached sign"); } if (ret == 0) { - ret = wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ESP256, 0u, 0u, sizeof(detached), 0u, &sizedLen); TEST_ASSERT(ret == 0 && sizedLen == taggedLen, "detached size equals signed size"); } - TEST_ASSERT(wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ES256, + TEST_ASSERT(wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ESP256, 0u, 1u, 1u, 0u, &sizedLen) == WOLFCOSE_E_INVALID_ARG, "attached and detached lengths rejected"); - TEST_ASSERT(wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ES256, + TEST_ASSERT(wc_CoseSign1_SignSize_ex(NULL, WOLFCOSE_ALG_ESP256, 0u, 1u, 0u, 0x80000000u, &sizedLen) == WOLFCOSE_E_INVALID_ARG, "unknown size flags rejected"); TEST_ASSERT(wc_CoseSign1_SignSize_ex(NULL, 12345, @@ -27375,7 +28572,7 @@ static void test_cose_sign1_size_and_untagged(void) delegatedKey.crv = WOLFCOSE_CRV_P256; (void)wc_CoseKey_SetExtSigner(&delegatedKey, test_ext_sign_cb, &extCtx); ret = wc_CoseSign1_SignSize_ex(&delegatedKey, - WOLFCOSE_ALG_ES256, 0u, sizeof(payload), 0u, 0u, &sizedLen); + WOLFCOSE_ALG_ESP256, 0u, sizeof(payload), 0u, 0u, &sizedLen); TEST_ASSERT(ret == 0 && extCtx.called == 0, "size query does not invoke delegated signer"); wc_CoseKey_Free(&delegatedKey); @@ -27454,7 +28651,7 @@ static void test_ecdh_es_recipient_key_alg_mismatch(void) (void)wc_CoseKey_Init(&key); (void)wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &eccKey); /* The key claims a different algorithm than the recipient entry. */ - key.alg = WOLFCOSE_ALG_ES256; + key.alg = WOLFCOSE_ALG_ESP256; recipients[0].algId = WOLFCOSE_ALG_ECDH_ES_HKDF_256; recipients[0].key = &key; @@ -27843,6 +29040,43 @@ static void test_multi_sign_mldsa65_roundtrip(void) defined(WOLFCOSE_COUNTERSIGN_VERIFY) && \ defined(WOLFCOSE_SIGN1_SIGN) && defined(WOLFCOSE_SIGN1_VERIFY) && \ defined(WOLFCOSE_HAVE_ES256) +static int test_cose_replace_counter_label(uint8_t* message, + size_t messageLen, uint8_t oldLabel, uint8_t newLabel) +{ + WOLFCOSE_CBOR_CTX ctx; + const uint8_t* value = NULL; + size_t valueLen = 0u; + size_t count = 0u; + uint64_t tag = 0u; + int ret; + + ret = wc_CBOR_DecoderInit(&ctx, message, messageLen); + if (ret == 0) { + ret = wc_CBOR_DecodeTag(&ctx, &tag); + } + if (ret == 0) { + ret = wc_CBOR_DecodeArrayStart(&ctx, &count); + } + if (ret == 0) { + ret = wc_CBOR_SkipItem(&ctx, &value, &valueLen); + } + if (ret == 0) { + ret = wc_CBOR_DecodeMapStart(&ctx, &count); + } + if ((ret == 0) && (ctx.idx < messageLen) && + (message[ctx.idx] == oldLabel)) { + message[ctx.idx] = newLabel; + } + else { + ret = -1; + } + (void)value; + (void)valueLen; + (void)count; + (void)tag; + return ret; +} + static void test_cose_countersignatures(void) { static const uint8_t payload[] = "signed release manifest"; @@ -28073,14 +29307,14 @@ static void test_cose_countersignatures(void) TEST_ASSERT(ret == 0, "countersignature key setup"); if (ret == 0) { - ret = wc_CoseSign1_Sign(&primaryKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&primaryKey, WOLFCOSE_ALG_ESP256, NULL, 0u, payload, sizeof(payload) - 1u, NULL, 0u, NULL, 0u, scratch, sizeof(scratch), message, sizeof(message), &messageLen, &rng); TEST_ASSERT(ret == 0, "create countersignature target"); } - counterSigner.algId = WOLFCOSE_ALG_ES256; + counterSigner.algId = WOLFCOSE_ALG_ESP256; counterSigner.key = &counterKey1; counterSigner.kid = counterKid1; counterSigner.kidLen = sizeof(counterKid1) - 1u; @@ -28106,11 +29340,27 @@ static void test_cose_countersignatures(void) counterMessage, counterMessageLen, NULL, 0u, counterAad, sizeof(counterAad) - 1u, scratch, sizeof(scratch), &hdr); - TEST_ASSERT(ret == 0 && hdr.alg == WOLFCOSE_ALG_ES256 && + TEST_ASSERT(ret == 0 && hdr.alg == WOLFCOSE_ALG_ESP256 && hdr.kidLen == sizeof(counterKid1) - 1u && memcmp(hdr.kid, counterKid1, hdr.kidLen) == 0, "verify full V2 countersignature headers"); } + if (ret == 0) { + int legacyRet; + + (void)memcpy(tampered, counterMessage, counterMessageLen); + legacyRet = test_cose_replace_counter_label(tampered, + counterMessageLen, (uint8_t)WOLFCOSE_HDR_COUNTERSIGNATURE_V2, + (uint8_t)WOLFCOSE_HDR_COUNTERSIGNATURE_LEGACY); + if (legacyRet == 0) { + legacyRet = wc_Cose_VerifyCounterSignature(&counterKey1, 0u, + tampered, counterMessageLen, NULL, 0u, + counterAad, sizeof(counterAad) - 1u, + scratch, sizeof(scratch), &hdr); + } + TEST_ASSERT(legacyRet != 0, + "legacy full countersignature uses legacy context"); + } if (ret == 0) { int badRet = wc_Cose_VerifyCounterSignature(&counterKey1, 0u, counterMessage, counterMessageLen, NULL, 0u, @@ -28202,7 +29452,7 @@ static void test_cose_countersignatures(void) ret = wc_CBOR_EncodeInt(&enc, WOLFCOSE_HDR_ALG); } if (ret == 0) { - ret = wc_CBOR_EncodeInt(&enc, WOLFCOSE_ALG_ES256); + ret = wc_CBOR_EncodeInt(&enc, WOLFCOSE_ALG_ESP256); } if (ret == 0) { ret = wc_CBOR_EncodeBstr(&enc, signature, signatureLen); @@ -28221,7 +29471,7 @@ static void test_cose_countersignatures(void) TEST_ASSERT(ret == 0, "create countersignature with externally bound alg"); - counterKey1.alg = WOLFCOSE_ALG_ES256; + counterKey1.alg = WOLFCOSE_ALG_ESP256; pinnedRet = wc_Cose_VerifyCounterSignature(&counterKey1, 0u, tampered, unprotectedAlgMessageLen, NULL, 0u, NULL, 0u, scratch, sizeof(scratch), &hdr); @@ -28297,7 +29547,7 @@ static void test_cose_countersignatures(void) WOLFCOSE_KEY wrongAlgKey = counterKey1; int badRet; - wrongAlgKey.alg = WOLFCOSE_ALG_ES384; + wrongAlgKey.alg = WOLFCOSE_ALG_ESP384; badRet = wc_Cose_VerifyCounterSignature(&wrongAlgKey, 0u, twoCounterMessage, twoCounterMessageLen, NULL, 0u, counterAad, sizeof(counterAad) - 1u, @@ -28388,7 +29638,7 @@ static void test_cose_countersignatures(void) "reject verify scratch overlap without input mutation"); } - counterSigner0.algId = WOLFCOSE_ALG_ES256; + counterSigner0.algId = WOLFCOSE_ALG_ESP256; counterSigner0.key = &counterKey1; if (ret == 0) { ret = wc_Cose_AddCounterSignature0(&counterSigner0, @@ -28406,6 +29656,23 @@ static void test_cose_countersignatures(void) scratch, sizeof(scratch)); TEST_ASSERT(ret == 0, "verify abbreviated V2 countersignature"); } + if (ret == 0) { + int legacyRet; + + (void)memcpy(tampered, abbreviatedMessage, abbreviatedMessageLen); + legacyRet = test_cose_replace_counter_label(tampered, + abbreviatedMessageLen, + (uint8_t)WOLFCOSE_HDR_COUNTERSIGNATURE0_V2, + (uint8_t)WOLFCOSE_HDR_COUNTERSIGNATURE0_LEGACY); + if (legacyRet == 0) { + legacyRet = wc_Cose_VerifyCounterSignature0(&counterSigner0, + tampered, abbreviatedMessageLen, NULL, 0u, + counterAad, sizeof(counterAad) - 1u, + scratch, sizeof(scratch)); + } + TEST_ASSERT(legacyRet != 0, + "legacy abbreviated countersignature uses legacy context"); + } if (ret == 0) { int badRet; @@ -28437,7 +29704,7 @@ static void test_cose_countersignatures(void) TEST_ASSERT(badRet != 0, "abbreviated countersignature rejects wrong key"); wrongSigner.key = &counterKey1; - wrongSigner.algId = WOLFCOSE_ALG_ES384; + wrongSigner.algId = WOLFCOSE_ALG_ESP384; badRet = wc_Cose_VerifyCounterSignature0(&wrongSigner, abbreviatedMessage, abbreviatedMessageLen, NULL, 0u, counterAad, sizeof(counterAad) - 1u, @@ -28454,7 +29721,7 @@ static void test_cose_countersignatures(void) } if (ret == 0) { - ret = wc_CoseSign1_Sign(&primaryKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&primaryKey, WOLFCOSE_ALG_ESP256, NULL, 0u, NULL, 0u, detached, sizeof(detached) - 1u, NULL, 0u, scratch, sizeof(scratch), detachedMessage, sizeof(detachedMessage), &detachedMessageLen, &rng); @@ -28690,7 +29957,7 @@ static void test_cose_countersign_preflight(void) ret = wc_CoseKey_SetExtSigner(&signKey, test_ext_sign_cb, &ctx); TEST_ASSERT(ret == 0, "preflight set ext signer"); } - counterSigner0.algId = WOLFCOSE_ALG_ES256; + counterSigner0.algId = WOLFCOSE_ALG_ESP256; counterSigner0.key = &signKey; if (ret == 0) { @@ -28808,7 +30075,7 @@ int test_cose(void) /* Sign1 basic tests */ #ifdef WOLFCOSE_HAVE_ES256 - test_cose_sign1_ecc("ES256", WOLFCOSE_ALG_ES256, WOLFCOSE_CRV_P256, 32); + test_cose_sign1_ecc("ESP256", WOLFCOSE_ALG_ESP256, WOLFCOSE_CRV_P256, 32); test_cose_sign1_with_aad(); test_cose_sign1_detached(); #if defined(WOLFCOSE_EXT_SIGN) @@ -28821,10 +30088,10 @@ int test_cose(void) test_cose_sign1_word32_overflow_guard(); #endif #ifdef WOLFCOSE_HAVE_ES384 - test_cose_sign1_ecc("ES384", WOLFCOSE_ALG_ES384, WOLFCOSE_CRV_P384, 48); + test_cose_sign1_ecc("ES384", WOLFCOSE_ALG_ESP384, WOLFCOSE_CRV_P384, 48); #endif #ifdef WOLFCOSE_HAVE_ES512 - test_cose_sign1_ecc("ES512", WOLFCOSE_ALG_ES512, WOLFCOSE_CRV_P521, 66); + test_cose_sign1_ecc("ES512", WOLFCOSE_ALG_ESP512, WOLFCOSE_CRV_P521, 66); #endif #endif @@ -28952,7 +30219,7 @@ int test_cose(void) #endif /* RFC 9052 interop test vectors */ -#ifdef WOLFCOSE_HAVE_ES256 +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) test_rfc_sign1_ecdsa_01(); #endif #if defined(WOLFCOSE_HAVE_HMAC256) @@ -29059,10 +30326,10 @@ int test_cose(void) /* Phase 1: Algorithm Combination Tests */ TEST_LOG("\n--- Algorithm Combination Tests ---\n"); #ifdef WOLFCOSE_HAVE_ES384 - test_cose_sign1_es384(); + test_cose_sign1_esp384(); #endif #ifdef WOLFCOSE_HAVE_ES512 - test_cose_sign1_es512(); + test_cose_sign1_esp512(); #endif #ifdef WOLFCOSE_HAVE_AESGCM test_cose_encrypt0_a192gcm(); @@ -29229,6 +30496,50 @@ int test_cose(void) test_cose_decode_unprotected_tstr_label(); #endif test_cose_sigsize_known_algs(); + test_cose_rfc9864_alg_helpers(); +#if defined(WOLFCOSE_HAVE_EDDSA) && defined(WOLFCOSE_HAVE_ED448) && \ + defined(WOLFCOSE_SIGN1_SIGN) && defined(WOLFCOSE_SIGN1_VERIFY) + test_cose_rfc9864_sign1_eddsa_curve_pin(); +#endif +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_EDDSA) && \ + defined(WOLFCOSE_SIGN1_SIGN) + test_cose_rfc9864_sign1_kty_pin(); +#endif +#if defined(WOLFCOSE_SIGN) && defined(WOLFCOSE_HAVE_EDDSA) && \ + defined(WOLFCOSE_HAVE_ED448) + test_cose_rfc9864_sign_multi_eddsa_curve_pin(); +#endif +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_SIGN1_SIGN) && \ + defined(WOLFCOSE_SIGN1_VERIFY) + test_cose_rfc9864_deprecated_ids(); +#endif +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_SIGN) && \ + !defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) + test_cose_rfc9864_sign_deprecated_rejected(); +#endif +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_SIGN1_VERIFY) + test_cose_rfc9864_esp256_kat(); +#endif +#if defined(WOLFCOSE_HAVE_EDDSA) && defined(WOLFCOSE_SIGN1_VERIFY) + test_cose_rfc9864_ed25519_kat(); +#endif +#if defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) && defined(WOLFCOSE_HAVE_EDDSA) && \ + defined(WOLFCOSE_SIGN1_SIGN) && defined(WOLFCOSE_SIGN1_VERIFY) && \ + defined(WOLFCOSE_SIGN) + test_cose_rfc9864_deprecated_eddsa(); +#endif +#if defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) && defined(WOLFCOSE_HAVE_ES384) && \ + defined(WOLFCOSE_SIGN1_SIGN) && defined(WOLFCOSE_SIGN1_VERIFY) + test_cose_rfc9864_deprecated_es384_es512(); +#endif +#if defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) && defined(WOLFCOSE_HAVE_ES256) && \ + defined(WOLFCOSE_SIGN) + test_cose_rfc9864_deprecated_sign_es256(); +#endif +#if defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) && defined(WOLFCOSE_HAVE_ED448) && \ + defined(WOLFCOSE_SIGN1_SIGN) && defined(WOLFCOSE_SIGN1_VERIFY) + test_cose_rfc9864_deprecated_ed448(); +#endif test_cose_decode_tstr_alg_values(); test_cose_key_decode_tstr_alg_rejected(); #if defined(WOLFCOSE_SIGN) && defined(WOLFCOSE_HAVE_ED448) diff --git a/tests/test_cose_examples.c b/tests/test_cose_examples.c index 5465f4c7..92be64e7 100644 --- a/tests/test_cose_examples.c +++ b/tests/test_cose_examples.c @@ -34,7 +34,7 @@ #include #include -#ifdef WOLFCOSE_HAVE_ES256 +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) #include #endif #include @@ -115,7 +115,7 @@ static size_t example_hex_decode(const char* hex, uint8_t* out, size_t out_sz) return hex_len / 2u; } -#ifdef WOLFCOSE_HAVE_ES256 +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) /* sign1-tests/sign-pass-02.json and sign1-tests/sign-fail-01.json. */ static const uint8_t example_p256_x[] = @@ -301,7 +301,7 @@ static void test_example_sign(void) #endif /* WOLFCOSE_SIGN_VERIFY */ -#endif /* WOLFCOSE_HAVE_ES256 */ +#endif /* WOLFCOSE_HAVE_ES256 && WOLFCOSE_HAVE_DEPRECATED_ALGS */ #ifdef WOLFCOSE_HAVE_HMAC256 @@ -734,7 +734,7 @@ int test_cose_examples(void) g_failures = 0; printf("\n COSE WG Examples vectors:\n"); -#ifdef WOLFCOSE_HAVE_ES256 +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) test_example_sign1(); #if defined(WOLFCOSE_SIGN_VERIFY) test_example_sign(); diff --git a/tests/test_interop.c b/tests/test_interop.c index d6b43b31..3f88513c 100644 --- a/tests/test_interop.c +++ b/tests/test_interop.c @@ -97,7 +97,7 @@ static const uint8_t sign1_vec1_keyD[] = { static const uint8_t sign1_vec1_payload[] = "This is the content."; #if defined(WOLFCOSE_COUNTERSIGN_VERIFY) && \ - defined(WOLFCOSE_HAVE_ES256) + defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) /* RFC 9338 Appendix A.1.1 COSE_Sign countersignature example. */ static const uint8_t countersign_rfc9338_sign_key_x[] = { 0xba, 0xc5, 0xb1, 0x1c, 0xad, 0x8f, 0x99, 0xf9, @@ -139,7 +139,7 @@ static const uint8_t countersign_rfc9338_sign_message[] = { #endif #if defined(WOLFCOSE_COUNTERSIGN_VERIFY) && \ - defined(WOLFCOSE_HAVE_ES512) + defined(WOLFCOSE_HAVE_ES512) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) /* RFC 9338 Appendix A.2.1 COSE_Sign1 countersignature example. */ static const uint8_t countersign_rfc9338_key_x[] = { 0x00, 0x72, 0x99, 0x2c, 0xb3, 0xac, 0x08, 0xec, @@ -203,7 +203,7 @@ static const uint8_t countersign_rfc9338_message[] = { #endif #if defined(WOLFCOSE_COUNTERSIGN_VERIFY) && \ - defined(WOLFCOSE_HAVE_EDDSA) + defined(WOLFCOSE_HAVE_EDDSA) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) static const uint8_t countersign_legacy_key[] = { 0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a, @@ -351,7 +351,7 @@ static void test_interop_sign1_roundtrip(void) /* Sign the payload */ if (ret == 0) { - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ESP256, NULL, 0, /* kid */ sign1_vec1_payload, sizeof(sign1_vec1_payload) - 1, NULL, 0, /* detached */ @@ -372,7 +372,7 @@ static void test_interop_sign1_roundtrip(void) "payload length match"); TEST_ASSERT(memcmp(decPayload, sign1_vec1_payload, decPayloadLen) == 0, "payload content match"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ES256, "algorithm match"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ESP256, "algorithm match"); } if (eccInited != 0) { @@ -434,7 +434,7 @@ static void test_interop_sign1_es384_roundtrip(void) /* Sign with ES384 */ if (ret == 0) { - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ES384, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ESP384, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, @@ -450,7 +450,7 @@ static void test_interop_sign1_es384_roundtrip(void) scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); TEST_ASSERT(ret == 0, "verify ES384"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ES384, "ES384 algorithm match"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ESP384, "ESP384 algorithm match"); } if (eccInited != 0) { @@ -513,7 +513,7 @@ static void test_interop_sign1_es512_roundtrip(void) /* Sign with ES512 */ if (ret == 0) { - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ES512, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ESP512, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, @@ -529,7 +529,7 @@ static void test_interop_sign1_es512_roundtrip(void) scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); TEST_ASSERT(ret == 0, "verify ES512"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ES512, "ES512 algorithm match"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ESP512, "ESP512 algorithm match"); } if (eccInited != 0) { @@ -590,7 +590,7 @@ static void test_interop_sign1_with_aad_roundtrip(void) wc_CoseKey_SetEcc(&signKey, WOLFCOSE_CRV_P256, &eccKey); /* Sign with AAD */ - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ESP256, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, @@ -678,7 +678,7 @@ static void test_interop_sign1_detached_roundtrip(void) wc_CoseKey_SetEcc(&signKey, WOLFCOSE_CRV_P256, &eccKey); /* Sign with detached payload */ - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ES256, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ESP256, NULL, 0, NULL, 0, /* no inline payload */ payload, sizeof(payload) - 1, /* detached payload */ @@ -1229,7 +1229,7 @@ static void test_interop_sign1_eddsa_roundtrip(void) /* Sign with EdDSA */ if (ret == 0) { - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_EDDSA, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ED25519, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, @@ -1245,7 +1245,7 @@ static void test_interop_sign1_eddsa_roundtrip(void) scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); TEST_ASSERT(ret == 0, "verify EdDSA"); - TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_EDDSA, "EdDSA algorithm"); + TEST_ASSERT(hdr.alg == WOLFCOSE_ALG_ED25519, "Ed25519 algorithm"); TEST_ASSERT(decPayloadLen == sizeof(payload) - 1, "payload length"); } @@ -1306,7 +1306,7 @@ static void test_interop_sign1_eddsa_with_aad(void) wc_CoseKey_SetEd25519(&signKey, &edKey); /* Sign with AAD */ - ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_EDDSA, + ret = wc_CoseSign1_Sign(&signKey, WOLFCOSE_ALG_ED25519, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, @@ -1336,7 +1336,7 @@ static void test_interop_sign1_eddsa_with_aad(void) #endif /* WOLFCOSE_HAVE_EDDSA */ #if defined(WOLFCOSE_COUNTERSIGN_VERIFY) && \ - defined(WOLFCOSE_HAVE_ES256) + defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) static void test_interop_countersign_rfc9338_sign(void) { static const uint8_t expectedKid[] = "11"; @@ -1391,7 +1391,7 @@ static void test_interop_countersign_rfc9338_sign(void) #endif #if defined(WOLFCOSE_COUNTERSIGN_VERIFY) && \ - defined(WOLFCOSE_HAVE_ES512) + defined(WOLFCOSE_HAVE_ES512) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) static void test_interop_countersign_rfc9338_sign1(void) { static const uint8_t expectedKid[] = @@ -1454,7 +1454,7 @@ static void test_interop_countersign_rfc9338_sign1(void) #endif #if defined(WOLFCOSE_COUNTERSIGN_VERIFY) && \ - defined(WOLFCOSE_HAVE_EDDSA) + defined(WOLFCOSE_HAVE_EDDSA) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) static void test_interop_countersign_legacy(void) { WOLFCOSE_KEY counterKey; @@ -1608,12 +1608,12 @@ static void test_interop_sign_multi_signer(void) wc_CoseKey_SetEcc(&key2, WOLFCOSE_CRV_P256, &eccKey2); /* Setup signers array */ - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = &key1; signers[0].kid = (const uint8_t*)"signer-1"; signers[0].kidLen = 8; - signers[1].algId = WOLFCOSE_ALG_ES256; + signers[1].algId = WOLFCOSE_ALG_ESP256; signers[1].key = &key2; signers[1].kid = (const uint8_t*)"signer-2"; signers[1].kidLen = 8; @@ -1721,12 +1721,12 @@ static void test_interop_sign_mixed_algorithms(void) wc_CoseKey_SetEcc(&eccKey384, WOLFCOSE_CRV_P384, &ecc384); /* Mixed algorithm signers */ - signers[0].algId = WOLFCOSE_ALG_ES256; + signers[0].algId = WOLFCOSE_ALG_ESP256; signers[0].key = &eccKey256; signers[0].kid = (const uint8_t*)"p256"; signers[0].kidLen = 4; - signers[1].algId = WOLFCOSE_ALG_ES384; + signers[1].algId = WOLFCOSE_ALG_ESP384; signers[1].key = &eccKey384; signers[1].kid = (const uint8_t*)"p384"; signers[1].kidLen = 4; @@ -1956,15 +1956,15 @@ int test_interop(void) test_interop_sign1_eddsa_with_aad(); #endif #if defined(WOLFCOSE_COUNTERSIGN_VERIFY) && \ - defined(WOLFCOSE_HAVE_ES256) + defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) test_interop_countersign_rfc9338_sign(); #endif #if defined(WOLFCOSE_COUNTERSIGN_VERIFY) && \ - defined(WOLFCOSE_HAVE_ES512) + defined(WOLFCOSE_HAVE_ES512) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) test_interop_countersign_rfc9338_sign1(); #endif #if defined(WOLFCOSE_COUNTERSIGN_VERIFY) && \ - defined(WOLFCOSE_HAVE_EDDSA) + defined(WOLFCOSE_HAVE_EDDSA) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) test_interop_countersign_legacy(); #endif diff --git a/tests/test_psa_attestation.c b/tests/test_psa_attestation.c index bb54a8c3..ec1ea1d8 100644 --- a/tests/test_psa_attestation.c +++ b/tests/test_psa_attestation.c @@ -32,7 +32,7 @@ #include #include -#ifdef WOLFCOSE_HAVE_ES256 +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) #include #endif #include @@ -52,7 +52,8 @@ static int g_failures = 0; } \ } while (0) -#if defined(WOLFCOSE_HAVE_ES256) || defined(WOLFCOSE_HAVE_HMAC256) +#if (defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS)) || \ + defined(WOLFCOSE_HAVE_HMAC256) #define PSA_UEID 256 #define PSA_NONCE 10 @@ -252,9 +253,9 @@ static void psa_parse_claims(const uint8_t* payload, size_t payload_len, TEST_ASSERT(ctx.idx == payload_len, "PSA claims consume payload"); } -#endif /* WOLFCOSE_HAVE_ES256 || WOLFCOSE_HAVE_HMAC256 */ +#endif /* (WOLFCOSE_HAVE_ES256 && WOLFCOSE_HAVE_DEPRECATED_ALGS) || WOLFCOSE_HAVE_HMAC256 */ -#ifdef WOLFCOSE_HAVE_ES256 +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) static const uint8_t psa_sign1_x[] = "\x4e\x5e\x22\x09\x9e\x3b\xce\xb4\x5b\x44\x6d\x13\x55\xfd\x1d\xc3" @@ -344,7 +345,7 @@ static void test_psa_sign1_token(void) wc_ecc_free(&ecc_key); } -#endif /* WOLFCOSE_HAVE_ES256 */ +#endif /* WOLFCOSE_HAVE_ES256 && WOLFCOSE_HAVE_DEPRECATED_ALGS */ #ifdef WOLFCOSE_HAVE_HMAC256 @@ -428,7 +429,7 @@ int test_psa_attestation(void) printf("=== PSA Attestation Token Tests ===\n\n"); -#ifdef WOLFCOSE_HAVE_ES256 +#if defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) test_psa_sign1_token(); #endif #ifdef WOLFCOSE_HAVE_HMAC256 diff --git a/tools/wolfcose_tool.c b/tools/wolfcose_tool.c index a9b460ac..ec307ae3 100644 --- a/tools/wolfcose_tool.c +++ b/tools/wolfcose_tool.c @@ -215,8 +215,9 @@ static void usage(void) " test [--all | -a ] Round-trip self-test\n" "\nCountersign options: -p --aad \n" "\n" - "Algorithms: ES256, EdDSA, Ed448, PS256, PS384, PS512,\n" + "Algorithms: ESP256, Ed25519, Ed448, PS256, PS384, PS512,\n" " ML-DSA-44, ML-DSA-65, ML-DSA-87,\n" + " (ES256, EdDSA with WOLFCOSE_ENABLE_DEPRECATED_ALGS)\n" " A128GCM, A192GCM, A256GCM, ChaCha20, AES-CCM,\n" #if defined(WOLFCOSE_HPKE_0_ENCRYPT) || defined(WOLFCOSE_HPKE_0_DECRYPT) " HPKE-0,\n" @@ -231,16 +232,31 @@ static void usage(void) /* Parse algorithm name to COSE algorithm ID */ static int parse_alg(const char* name, int32_t* alg) { - if (strcmp(name, "ES256") == 0) { - *alg = WOLFCOSE_ALG_ES256; + if (strcmp(name, "ESP256") == 0) { + *alg = WOLFCOSE_ALG_ESP256; } - else if (strcmp(name, "EdDSA") == 0) { - *alg = WOLFCOSE_ALG_EDDSA; + else if (strcmp(name, "Ed25519") == 0) { + *alg = WOLFCOSE_ALG_ED25519; } #ifdef WOLFCOSE_HAVE_ED448 else if (strcmp(name, "Ed448") == 0) { + *alg = WOLFCOSE_ALG_ED448; + } +#endif +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS + else if (strcmp(name, "ES256") == 0) { + *alg = WOLFCOSE_ALG_ES256; + } + else if (strcmp(name, "EdDSA") == 0) { *alg = WOLFCOSE_ALG_EDDSA; } +#else + else if ((strcmp(name, "ES256") == 0) || (strcmp(name, "EdDSA") == 0)) { + fprintf(stderr, "%s is deprecated by RFC 9864; use ESP256 or Ed25519, " + "or rebuild with WOLFCOSE_ENABLE_DEPRECATED_ALGS.\n", + name); + return -1; + } #endif else if (strcmp(name, "A128GCM") == 0) { *alg = WOLFCOSE_ALG_A128GCM; @@ -843,7 +859,7 @@ static int tool_content_nonce_len(int32_t alg, size_t* nonceLen) #endif /* WOLFCOSE_HAVE_HPKE_0 */ /* ----- keygen: generate a COSE key and write to file ----- */ -static int tool_keygen(int32_t alg, const char* algStr, const char* outPath) +static int tool_keygen(int32_t alg, const char* outPath) { int ret; WC_RNG rng; @@ -851,11 +867,6 @@ static int tool_keygen(int32_t alg, const char* algStr, const char* outPath) uint8_t keyBuf[WOLFCOSE_TOOL_MAX_KEY]; size_t keyLen = 0; -#if !defined(WOLFCOSE_HAVE_EDDSA) && !defined(WOLFCOSE_HAVE_ED448) - /* Only the Ed448-vs-Ed25519 disambiguation reads this. */ - (void)algStr; -#endif - ret = wc_InitRng(&rng); if (ret != 0) { fprintf(stderr, "RNG init failed: %d\n", ret); @@ -865,7 +876,7 @@ static int tool_keygen(int32_t alg, const char* algStr, const char* outPath) wc_CoseKey_Init(&coseKey); #ifdef WOLFCOSE_HAVE_ES256 - if (alg == WOLFCOSE_ALG_ES256) { + if ((alg == WOLFCOSE_ALG_ESP256) || (alg == WOLFCOSE_ALG_ES256)) { ecc_key ecc; wc_ecc_init(&ecc); ret = wc_ecc_make_key(&rng, 32, &ecc); @@ -882,7 +893,7 @@ static int tool_keygen(int32_t alg, const char* algStr, const char* outPath) else #endif #ifdef WOLFCOSE_HAVE_EDDSA - if (alg == WOLFCOSE_ALG_EDDSA && strcmp(algStr, "Ed448") != 0) { + if ((alg == WOLFCOSE_ALG_ED25519) || (alg == WOLFCOSE_ALG_EDDSA)) { ed25519_key ed; wc_ed25519_init(&ed); ret = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &ed); @@ -899,7 +910,12 @@ static int tool_keygen(int32_t alg, const char* algStr, const char* outPath) else #endif #ifdef WOLFCOSE_HAVE_ED448 - if (alg == WOLFCOSE_ALG_EDDSA && strcmp(algStr, "Ed448") == 0) { + if ((alg == WOLFCOSE_ALG_ED448) +#if defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) && \ + !defined(WOLFCOSE_HAVE_EDDSA) + || (alg == WOLFCOSE_ALG_EDDSA) +#endif + ) { ed448_key ed; wc_ed448_init(&ed); ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &ed); @@ -1036,8 +1052,8 @@ static int tool_keygen(int32_t alg, const char* algStr, const char* outPath) } /* ----- sign: COSE_Sign1 sign ----- */ -static int tool_sign(const char* keyPath, int32_t alg, const char* algStr, - const char* inPath, const char* outPath) +static int tool_sign(const char* keyPath, int32_t alg, + const char* inPath, const char* outPath) { int ret; uint8_t keyBuf[WOLFCOSE_TOOL_MAX_KEY]; @@ -1049,24 +1065,31 @@ static int tool_sign(const char* keyPath, int32_t alg, const char* algStr, uint8_t scratch[WOLFCOSE_MAX_SCRATCH_SZ]; WOLFCOSE_KEY coseKey; WC_RNG rng; - -#if !defined(WOLFCOSE_HAVE_EDDSA) && !defined(WOLFCOSE_HAVE_ED448) - /* Only the Ed448-vs-Ed25519 disambiguation reads this. */ - (void)algStr; +#if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) + int32_t crv = 0; #endif - ret = read_file(keyPath, keyBuf, sizeof(keyBuf), &keyLen); if (ret != 0) return ret; ret = read_file(inPath, msgBuf, sizeof(msgBuf), &msgLen); if (ret != 0) return ret; +#if defined(WOLFCOSE_HAVE_EDDSA) || defined(WOLFCOSE_HAVE_ED448) + /* Deprecated polymorphic EdDSA (-8) takes its curve from the key, so read + * it with nothing attached before dispatch. */ + if (alg == WOLFCOSE_ALG_EDDSA) { + WOLFCOSE_KEY peek; + wc_CoseKey_Init(&peek); + (void)wc_CoseKey_Decode(&peek, keyBuf, keyLen); + crv = peek.crv; + } +#endif + wc_CoseKey_Init(&coseKey); #ifdef WOLFCOSE_HAVE_ECDSA - if (alg == WOLFCOSE_ALG_ES256 || alg == WOLFCOSE_ALG_ES384 || - alg == WOLFCOSE_ALG_ES512) { + if (alg == WOLFCOSE_ALG_ESP256 || alg == WOLFCOSE_ALG_ES256) { ecc_key ecc; wc_ecc_init(&ecc); /* Attach curve is a placeholder; decode takes crv from the key file. */ @@ -1097,7 +1120,8 @@ static int tool_sign(const char* keyPath, int32_t alg, const char* algStr, else #endif #ifdef WOLFCOSE_HAVE_EDDSA - if (alg == WOLFCOSE_ALG_EDDSA && strcmp(algStr, "Ed448") != 0) { + if ((alg == WOLFCOSE_ALG_ED25519) || + ((alg == WOLFCOSE_ALG_EDDSA) && (crv == WOLFCOSE_CRV_ED25519))) { ed25519_key ed; wc_ed25519_init(&ed); ret = wc_CoseKey_SetEd25519(&coseKey, &ed); @@ -1127,7 +1151,8 @@ static int tool_sign(const char* keyPath, int32_t alg, const char* algStr, else #endif #ifdef WOLFCOSE_HAVE_ED448 - if (alg == WOLFCOSE_ALG_EDDSA && strcmp(algStr, "Ed448") == 0) { + if ((alg == WOLFCOSE_ALG_ED448) || + ((alg == WOLFCOSE_ALG_EDDSA) && (crv == WOLFCOSE_CRV_ED448))) { ed448_key ed; wc_ed448_init(&ed); ret = wc_CoseKey_SetEd448(&coseKey, &ed); @@ -2189,7 +2214,7 @@ static int tool_info(const char* inPath) /* Sign round-trip: keygen -> sign -> verify -> check payload */ #ifdef WOLFCOSE_HAVE_ES256 -static int test_sign_es256(void) +static int test_sign_es256(const char* name, int32_t alg) { int ret = 0; WC_RNG rng; @@ -2204,7 +2229,7 @@ static int test_sign_es256(void) size_t decodedLen; int rngInit = 0, eccInit = 0; - printf(" %-12s sign/verify ... ", "ES256"); + printf(" %-12s sign/verify ... ", name); ret = wc_InitRng(&rng); if (ret == 0) { @@ -2219,7 +2244,7 @@ static int test_sign_es256(void) wc_CoseKey_Init(&key); wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &ecc); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_ES256, NULL, 0, + ret = wc_CoseSign1_Sign(&key, alg, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); @@ -2249,7 +2274,7 @@ static int test_sign_es256(void) #endif #ifdef WOLFCOSE_HAVE_EDDSA -static int test_sign_eddsa(void) +static int test_sign_eddsa(const char* name, int32_t alg) { int ret = 0; WC_RNG rng; @@ -2264,7 +2289,7 @@ static int test_sign_eddsa(void) size_t decodedLen; int rngInit = 0, edInit = 0; - printf(" %-12s sign/verify ... ", "EdDSA"); + printf(" %-12s sign/verify ... ", name); ret = wc_InitRng(&rng); if (ret == 0) { @@ -2279,7 +2304,7 @@ static int test_sign_eddsa(void) wc_CoseKey_Init(&key); wc_CoseKey_SetEd25519(&key, &ed); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_EDDSA, NULL, 0, + ret = wc_CoseSign1_Sign(&key, alg, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); @@ -2309,7 +2334,7 @@ static int test_sign_eddsa(void) #endif #ifdef WOLFCOSE_HAVE_ED448 -static int test_sign_ed448(void) +static int test_sign_ed448(const char* name, int32_t alg) { int ret = 0; WC_RNG rng; @@ -2324,7 +2349,7 @@ static int test_sign_ed448(void) size_t decodedLen; int rngInit = 0, edInit = 0; - printf(" %-12s sign/verify ... ", "Ed448"); + printf(" %-12s sign/verify ... ", name); ret = wc_InitRng(&rng); if (ret == 0) { @@ -2339,7 +2364,7 @@ static int test_sign_ed448(void) wc_CoseKey_Init(&key); wc_CoseKey_SetEd448(&key, &ed); - ret = wc_CoseSign1_Sign(&key, WOLFCOSE_ALG_EDDSA, NULL, 0, + ret = wc_CoseSign1_Sign(&key, alg, NULL, 0, payload, sizeof(payload) - 1, NULL, 0, NULL, 0, scratch, sizeof(scratch), out, sizeof(out), &outLen, &rng); @@ -2763,19 +2788,41 @@ static int tool_test(const char* filter) /* --- COSE_Sign1 --- */ #ifdef WOLFCOSE_HAVE_ES256 + if (all || strcmp(filter, "ESP256") == 0) { + tests++; + if (test_sign_es256("ESP256", WOLFCOSE_ALG_ESP256) != 0) failures++; + } +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS if (all || strcmp(filter, "ES256") == 0) { - tests++; if (test_sign_es256() != 0) failures++; + tests++; + if (test_sign_es256("ES256", WOLFCOSE_ALG_ES256) != 0) failures++; } #endif +#endif #ifdef WOLFCOSE_HAVE_EDDSA + if (all || strcmp(filter, "Ed25519") == 0) { + tests++; + if (test_sign_eddsa("Ed25519", WOLFCOSE_ALG_ED25519) != 0) failures++; + } +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS if (all || strcmp(filter, "EdDSA") == 0) { - tests++; if (test_sign_eddsa() != 0) failures++; + tests++; + if (test_sign_eddsa("EdDSA", WOLFCOSE_ALG_EDDSA) != 0) failures++; } #endif +#endif #ifdef WOLFCOSE_HAVE_ED448 if (all || strcmp(filter, "Ed448") == 0) { - tests++; if (test_sign_ed448() != 0) failures++; + tests++; + if (test_sign_ed448("Ed448", WOLFCOSE_ALG_ED448) != 0) failures++; } +#if defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) && \ + !defined(WOLFCOSE_HAVE_EDDSA) + if (all || strcmp(filter, "EdDSA") == 0) { + tests++; + if (test_sign_ed448("EdDSA", WOLFCOSE_ALG_EDDSA) != 0) failures++; + } +#endif #endif #if defined(WOLFCOSE_HAVE_RSAPSS) && defined(WOLFSSL_KEY_GEN) if (all || strcmp(filter, "PS256") == 0) { @@ -3066,7 +3113,7 @@ int main(int argc, char* argv[]) return EXIT_USAGE; } #endif - return tool_keygen(alg, algStr, outPath); + return tool_keygen(alg, outPath); } else if (strcmp(cmd, "sign") == 0) { if (keyPath == NULL || algStr == NULL || inPath == NULL || @@ -3075,7 +3122,7 @@ int main(int argc, char* argv[]) "sign requires -k -a -i -o \n"); return EXIT_USAGE; } - return tool_sign(keyPath, alg, algStr, inPath, outPath); + return tool_sign(keyPath, alg, inPath, outPath); } else if (strcmp(cmd, "verify") == 0) { if (keyPath == NULL || inPath == NULL) { From 86ee040d422f7517c8fb904a80871da2c4661115 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 15 Sep 2026 08:14:38 -0700 Subject: [PATCH 2/8] Fix Clang C99 warning in Ed448 key generation --- tools/wolfcose_tool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/wolfcose_tool.c b/tools/wolfcose_tool.c index ec307ae3..baf52a7b 100644 --- a/tools/wolfcose_tool.c +++ b/tools/wolfcose_tool.c @@ -910,10 +910,10 @@ static int tool_keygen(int32_t alg, const char* outPath) else #endif #ifdef WOLFCOSE_HAVE_ED448 - if ((alg == WOLFCOSE_ALG_ED448) + if (alg == WOLFCOSE_ALG_ED448 #if defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) && \ !defined(WOLFCOSE_HAVE_EDDSA) - || (alg == WOLFCOSE_ALG_EDDSA) + || alg == WOLFCOSE_ALG_EDDSA #endif ) { ed448_key ed; From 3b130618128a6e4f791cd3bdcf8e3ed633bfa050 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 15 Sep 2026 13:22:15 -0700 Subject: [PATCH 3/8] Preserve RFC 9783 compatibility with deprecated IDs --- Makefile | 49 ++++++++++++++++++++----------- docs/Macros.md | 2 +- docs/PSA-EAT.md | 7 +++++ include/wolfcose/settings.h | 1 + tests/test_eat_psa_derived_gate.c | 5 ++++ 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 8a3a23b2..6dc0fde7 100644 --- a/Makefile +++ b/Makefile @@ -78,6 +78,20 @@ BUILD_CONFIG = .wolfcose-build-config # peers still emit them); its value is part of the rebuild hash below. INTEROP_COSE_CFLAGS = -DWOLFCOSE_ENABLE_DEPRECATED_ALGS +# Full PSA/EAT conformance test profile. Production integrations can select a +# smaller subset by defining only the WOLFCOSE_ENABLE_EAT_PSA_* switches they +# need; see docs/PSA-EAT.md. RFC 9783 vectors still use the deprecated ES256 +# ID, so this test profile enables it. The variable is overridable for CI. +EAT_PSA_FULL_FLAGS ?= -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ + -DWOLFCOSE_ENABLE_EAT_PSA \ + -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ + -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ + -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE -DWOLFCOSE_ENABLE_EAT_PSA_LEGACY \ + -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1_ISSUE \ + -DWOLFCOSE_ENABLE_EAT_PSA_MAC0_ISSUE \ + -DWOLFCOSE_ENABLE_EAT_PSA_UEID_RESOLVER \ + -DWOLFCOSE_ENABLE_EAT_PSA_COMPONENT_ITERATOR + BUILD_CONFIG_VALUE := $(shell { \ printf '%s\n' 'CC=$(CC)'; \ printf '%s\n' 'CFLAGS=$(CFLAGS)'; \ @@ -89,6 +103,7 @@ BUILD_CONFIG_VALUE := $(shell { \ printf '%s\n' 'WOLFSSL_CFLAGS=$(WOLFSSL_CFLAGS)'; \ printf '%s\n' 'WOLFSSL_LIBS=$(WOLFSSL_LIBS)'; \ printf '%s\n' 'INTEROP_COSE_CFLAGS=$(INTEROP_COSE_CFLAGS)'; \ + printf '%s\n' 'EAT_PSA_FULL_FLAGS=$(EAT_PSA_FULL_FLAGS)'; \ } | cksum) BUILD_CONFIG_SAVED := $(shell test -f $(BUILD_CONFIG) && cat $(BUILD_CONFIG)) ifneq ($(strip $(BUILD_CONFIG_VALUE)),$(strip $(BUILD_CONFIG_SAVED))) @@ -104,18 +119,6 @@ TEST_BIN = tests/test_wolfcose EAT_PSA_TEST_BIN = tests/test_wolfcose_eat_psa EAT_PSA_LIMITS_TEST_BIN = tests/test_wolfcose_eat_psa_limits -# Full PSA/EAT conformance test profile. Production integrations can select a -# smaller subset by defining only the WOLFCOSE_ENABLE_EAT_PSA_* switches they -# need; see docs/PSA-EAT.md. This variable is overridable for CI experiments. -EAT_PSA_FULL_FLAGS ?= -DWOLFCOSE_ENABLE_EAT_PSA \ - -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ - -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ - -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE -DWOLFCOSE_ENABLE_EAT_PSA_LEGACY \ - -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1_ISSUE \ - -DWOLFCOSE_ENABLE_EAT_PSA_MAC0_ISSUE \ - -DWOLFCOSE_ENABLE_EAT_PSA_UEID_RESOLVER \ - -DWOLFCOSE_ENABLE_EAT_PSA_COMPONENT_ITERATOR - # Remove every lean-core decode path. Issuer-only matrix builds use this to # prove that PSA/EAT claim and envelope creation do not retain CBOR decoding. EAT_PSA_NO_DECODE_FLAGS = -DWOLFCOSE_NO_SIGN1_VERIFY \ @@ -466,7 +469,8 @@ eat-psa-claim-limits-test: # remains WOLFCOSE_E_UNSUPPORTED before crypto. eat-psa-profile-test: $(MAKE) clean - $(CC) $(CFLAGS) -DWOLFCOSE_TEST_EAT_PSA_PROFILES \ + $(CC) $(CFLAGS) -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ + -DWOLFCOSE_TEST_EAT_PSA_PROFILES \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1_ISSUE \ @@ -475,7 +479,8 @@ eat-psa-profile-test: $(LDFLAGS) $(LDLIBS) ./$(EAT_PSA_TEST_BIN) $(MAKE) clean - $(CC) $(CFLAGS) -DWOLFCOSE_TEST_EAT_PSA_PROFILES \ + $(CC) $(CFLAGS) -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ + -DWOLFCOSE_TEST_EAT_PSA_PROFILES \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE \ -DWOLFCOSE_ENABLE_EAT_PSA_MAC0_ISSUE \ @@ -484,7 +489,8 @@ eat-psa-profile-test: $(LDFLAGS) $(LDLIBS) ./$(EAT_PSA_TEST_BIN) $(MAKE) clean - $(CC) $(CFLAGS) -DWOLFCOSE_TEST_EAT_PSA_PROFILES \ + $(CC) $(CFLAGS) -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ + -DWOLFCOSE_TEST_EAT_PSA_PROFILES \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_LEGACY \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 \ -o $(EAT_PSA_TEST_BIN) $(CORE_SRC) $(EAT_PSA_SRC) \ @@ -492,7 +498,8 @@ eat-psa-profile-test: $(LDFLAGS) $(LDLIBS) ./$(EAT_PSA_TEST_BIN) $(MAKE) clean - $(CC) $(CFLAGS) -DWOLFCOSE_TEST_EAT_PSA_PROFILES \ + $(CC) $(CFLAGS) -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ + -DWOLFCOSE_TEST_EAT_PSA_PROFILES \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_LEGACY \ -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ -o $(EAT_PSA_TEST_BIN) $(CORE_SRC) $(EAT_PSA_SRC) \ @@ -606,9 +613,16 @@ eat-psa-config-check: -fsyntax-only tests/test_eat_psa_curve_gates.c $(CC) $(CFLAGS) -Werror -DWOLFSSL_USER_SETTINGS \ -I./tests/config/eat_psa_min_key -DECC_MIN_KEY_SZ=256 \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ -fsyntax-only tests/test_eat_psa_min_key_gates.c + $(CC) $(CFLAGS) -Werror -DWOLFSSL_USER_SETTINGS \ + -I./tests/config/eat_psa_min_key -DECC_MIN_KEY_SZ=256 \ + -DWOLFCOSE_TEST_NO_DEPRECATED_ALGS \ + -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ + -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ + -fsyntax-only tests/test_eat_psa_derived_gate.c $(CC) $(CFLAGS) -Werror -DWOLFSSL_USER_SETTINGS \ -I./tests/config/eat_psa_min_key -DECC_MIN_KEY_SZ=257 \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ @@ -921,7 +935,8 @@ lean-verify: # A standardized #tfm receiver must retain both envelopes and all required # algorithms. Issuance and optional PSA/EAT helpers remain compiled out. psa-eat-lean-verify: - $(CC) $(CFLAGS) -DWOLFCOSE_LEAN_VERIFY -DWOLFCOSE_ENABLE_EAT_PSA \ + $(CC) $(CFLAGS) -DWOLFCOSE_LEAN_VERIFY \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS -DWOLFCOSE_ENABLE_EAT_PSA \ -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 \ -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 -DWOLFCOSE_ENABLE_ES384 \ -DWOLFCOSE_ENABLE_ES512 -DWOLFCOSE_ENABLE_HMAC384 \ diff --git a/docs/Macros.md b/docs/Macros.md index d595d1c9..4b93036b 100644 --- a/docs/Macros.md +++ b/docs/Macros.md @@ -80,7 +80,7 @@ and verifiers. The two claim-map limits exist only in verifier builds. | `WOLFCOSE_ENABLE_EAT_PSA_LEGACY` | Legacy `PSA_IOT_PROFILE_1` consumption | off | | `WOLFCOSE_ENABLE_EAT_PSA_UEID_RESOLVER` | UEID-selected key lookup helper | off | | `WOLFCOSE_ENABLE_EAT_PSA_COMPONENT_ITERATOR` | Zero-copy component callback helper | off | -| `WOLFCOSE_EAT_PSA_TFM_FULL` | Derived: all RFC 9783 `#tfm` receiver algorithms/envelopes are present; do not define manually | derived | +| `WOLFCOSE_EAT_PSA_TFM_FULL` | Derived: all RFC 9783 `#tfm` receiver algorithms/envelopes and the deprecated RFC 9053 ECDSA IDs are enabled; do not define manually | derived | | `WOLFCOSE_EAT_PSA_MAX_COMPONENTS` | Maximum accepted software-component maps | 32 | | `WOLFCOSE_EAT_PSA_MAX_CLAIMS` | Verifier-only maximum claim-map entries, including extensions | 64 | | `WOLFCOSE_EAT_PSA_MAX_COMPONENT_CLAIMS` | Verifier-only maximum entries in each component map | 16 | diff --git a/docs/PSA-EAT.md b/docs/PSA-EAT.md index 8205b1aa..95230308 100644 --- a/docs/PSA-EAT.md +++ b/docs/PSA-EAT.md @@ -37,6 +37,11 @@ lean build, or remove any supported algorithm with its `WOLFCOSE_NO_*` macro. The PSA/EAT code has no algorithm fallback: a disabled algorithm is rejected before claims are used. +RFC 9783 Sign1 tokens use the RFC 9053 ES256/ES384/ES512 IDs. Define +`WOLFCOSE_ENABLE_DEPRECATED_ALGS` for a Sign1 receiver or issuer; it is also +required for the derived full `#tfm` receiver capability. Without it, those +token algorithms are rejected. + The consume and issue directions are independent. An attester can select the common issue gate and one issue envelope without selecting either consumption gate. Such a build contains no PSA/EAT verifier symbol. A claim-encoder-only @@ -47,6 +52,7 @@ Minimal current Sign1 verifier: ```text -DWOLFCOSE_LEAN_VERIFY +-DWOLFCOSE_ENABLE_DEPRECATED_ALGS -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 @@ -70,6 +76,7 @@ Current ES256 Sign1 issuer without the PSA/EAT verifier: -DWOLFCOSE_NO_MAC0_VERIFY -DWOLFCOSE_NO_KEY_DECODE -DWOLFCOSE_NO_CBOR_DECODE +-DWOLFCOSE_ENABLE_DEPRECATED_ALGS -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE diff --git a/include/wolfcose/settings.h b/include/wolfcose/settings.h index cb1256de..5abdc550 100644 --- a/include/wolfcose/settings.h +++ b/include/wolfcose/settings.h @@ -915,6 +915,7 @@ extern "C" { #if defined(WOLFCOSE_EAT_PSA_CURRENT) && \ defined(WOLFCOSE_EAT_PSA_SIGN1) && defined(WOLFCOSE_EAT_PSA_MAC0) && \ + defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) && \ defined(WOLFCOSE_HAVE_ES256) && defined(WOLFCOSE_HAVE_ES384) && \ defined(WOLFCOSE_HAVE_ES512) && defined(WOLFCOSE_HAVE_HMAC256) && \ defined(WOLFCOSE_HAVE_HMAC384) && defined(WOLFCOSE_HAVE_HMAC512) diff --git a/tests/test_eat_psa_derived_gate.c b/tests/test_eat_psa_derived_gate.c index cf2e62dd..6ba8909d 100644 --- a/tests/test_eat_psa_derived_gate.c +++ b/tests/test_eat_psa_derived_gate.c @@ -23,6 +23,11 @@ #endif #endif +#if defined(WOLFCOSE_TEST_NO_DEPRECATED_ALGS) && \ + defined(WOLFCOSE_EAT_PSA_TFM_FULL) + #error "RFC 9783 #tfm receiver needs the RFC 9053 signature IDs" +#endif + int test_eat_psa_derived_gate(void) { return 0; From 34bd751031262f1435389d0d15043b34e47068ca Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 15 Sep 2026 14:01:10 -0700 Subject: [PATCH 4/8] Remove Clang analyzer dead stores from RFC 9864 tests --- tests/test_cose.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/test_cose.c b/tests/test_cose.c index 49ca589c..ad9862e1 100644 --- a/tests/test_cose.c +++ b/tests/test_cose.c @@ -308,7 +308,7 @@ static void test_cose_countersign_ecdsa_curves(void) } TEST_ASSERT(ret == 0, "ES512 countersign key"); if (ret == 0) { - ret = test_cose_countersign_roundtrip(&signKey, &signKey, + (void)test_cose_countersign_roundtrip(&signKey, &signKey, WOLFCOSE_ALG_ESP512, &rng, "ESP512"); wc_CoseKey_Free(&signKey); } @@ -21742,7 +21742,6 @@ static void test_cose_esp_verify_kat(const char* tag, int wcCurve, scratch, sizeof(scratch), &hdr, &decPayload, &decPayloadLen); TEST_ASSERT(ret != 0, "KAT ECDSA rejects tampered signature"); } - ret = 0; } else { TEST_ASSERT(0, "KAT ECDSA public import"); @@ -22098,8 +22097,8 @@ static void test_cose_rfc9864_deprecated_es384_es512(void) TEST_ASSERT((ret == 0) && (hdr.alg == WOLFCOSE_ALG_ES512), "Verify ES512"); } - if (keyInited != 0) { wc_CoseKey_Free(&key); keyInited = 0; } - if (eccInited != 0) { (void)wc_ecc_free(&eccKey); eccInited = 0; } + if (keyInited != 0) { wc_CoseKey_Free(&key); } + if (eccInited != 0) { (void)wc_ecc_free(&eccKey); } #endif /* WOLFCOSE_HAVE_ES512 */ if (rngInited != 0) { (void)wc_FreeRng(&rng); } From ed95d99f165f1b4f5912d85a399c2a69013de679 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 15 Sep 2026 14:47:40 -0700 Subject: [PATCH 5/8] Fix interop PSA dependency and RFC 9864 examples --- IDE/STM32Cube/wolfcose_test.c | 6 +++--- Makefile | 2 ++ docs/Message-Types.md | 6 +++--- examples/lifecycle_demo.c | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/IDE/STM32Cube/wolfcose_test.c b/IDE/STM32Cube/wolfcose_test.c index 992cf155..51282bd6 100644 --- a/IDE/STM32Cube/wolfcose_test.c +++ b/IDE/STM32Cube/wolfcose_test.c @@ -43,7 +43,7 @@ int wolfCOSETest(void) int keyInited = 0; int ret; - printf("Running wolfCOSE test (COSE_Sign1 ES256)...\n"); + printf("Running wolfCOSE test (COSE_Sign1 ESP256)...\n"); ret = wc_InitRng(&rng); if (ret == 0) { @@ -96,8 +96,8 @@ int wolfCOSETest(void) } return ret; #else - /* ES256 COSE_Sign1 not compiled in; report not run so it is not read as pass */ - printf("wolfCOSE test: needs ES256 with COSE_Sign1 sign and verify\n"); + /* ESP256 COSE_Sign1 not compiled in; report not run so it is not read as pass */ + printf("wolfCOSE test: needs ESP256 with COSE_Sign1 sign and verify\n"); return -1; #endif } diff --git a/Makefile b/Makefile index 6dc0fde7..54275c7b 100644 --- a/Makefile +++ b/Makefile @@ -1041,6 +1041,8 @@ INTEROP_LIB_A = $(INTEROP_LIB_DIR)/libwolfcose_interop.a INTEROP_LIB_OBJ = $(patsubst src/%.c,$(INTEROP_LIB_DIR)/%.o,$(SRC)) INTEROP_CFLAGS = $(CFLAGS) $(INTEROP_COSE_CFLAGS) -std=c99 -I$(TCOSE_DIR)/inc -I$(QCBOR_DIR)/inc +$(INTEROP_LIB_DIR)/wolfcose_eat_psa.o: include/wolfcose/eat_psa.h + $(INTEROP_LIB_DIR)/%.o: src/%.c src/wolfcose_internal.h \ include/wolfcose/wolfcose.h $(BUILD_CONFIG_CHANGED) $(BUILD_CONFIG) $(CC) $(CFLAGS) $(EAT_PSA_FULL_FLAGS) $(INTEROP_COSE_CFLAGS) -c $< -o $@ diff --git a/docs/Message-Types.md b/docs/Message-Types.md index 4b675ee7..2772f062 100644 --- a/docs/Message-Types.md +++ b/docs/Message-Types.md @@ -86,7 +86,7 @@ feature. ```c WOLFCOSE_COUNTERSIGNATURE approval = { - .algId = WOLFCOSE_ALG_ES256, + .algId = WOLFCOSE_ALG_ESP256, .key = &releaseKey, .kid = (const uint8_t*)"release-2026", .kidLen = 12 @@ -126,7 +126,7 @@ The command-line tool can countersign an existing message and verify a selected full countersignature: ```bash -wolfcose_tool countersign -k release-key.cbor -a ES256 \ +wolfcose_tool countersign -k release-key.cbor -a ESP256 \ -i signed.cose -o approved.cose wolfcose_tool counterverify -k release-public.cbor \ -i approved.cose --index 0 @@ -247,7 +247,7 @@ For common minimal builds, use a build profile instead of hand-listing macros | `WOLFCOSE_LEAN_MLDSA` | ML-DSA `COSE_Sign1` sign + verify | | `WOLFCOSE_LEAN_VERIFY_MLDSA` | ML-DSA `COSE_Sign1` verify-only | -A minimal Sign1-verify-only build (`WOLFCOSE_LEAN_VERIFY`) is about **5.1 KB** of wolfCOSE library code (3.5 KB COSE engine + the built-in CBOR engine), or **26.2 KB** total flash with a minimal wolfCrypt ES256 backend — rising to **6.8 KB** / **34.6 KB** for sign + verify. +A minimal Sign1-verify-only build (`WOLFCOSE_LEAN_VERIFY`) is about **5.1 KB** of wolfCOSE library code (3.5 KB COSE engine + the built-in CBOR engine), or **26.2 KB** total flash with a minimal wolfCrypt P-256 ECDSA/SHA-256 backend — rising to **6.8 KB** / **34.6 KB** for sign + verify. ## See also diff --git a/examples/lifecycle_demo.c b/examples/lifecycle_demo.c index ad8cbb70..ceed7702 100644 --- a/examples/lifecycle_demo.c +++ b/examples/lifecycle_demo.c @@ -24,13 +24,13 @@ * Simulates a produce -> transport -> consume lifecycle for all COSE * message types: * - * COSE_Sign1: ES256, EdDSA, PS256, ML-DSA-44 + * COSE_Sign1: ESP256, Ed25519, PS256, ML-DSA-44 * COSE_Encrypt0: A128GCM, A256GCM, ChaCha20, AES-CCM * COSE_Mac0: HMAC256, HMAC384, HMAC512 * * Usage: * ./lifecycle_demo Run all available algorithms - * ./lifecycle_demo -a ES256 Run only ES256 + * ./lifecycle_demo -a ESP256 Run only ESP256 * ./lifecycle_demo -a HMAC256 Run only HMAC-256 * ./lifecycle_demo -a all Run all available algorithms * From 85cf86a416fa8529065c77ce6d8bc19a913a5bb7 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 15 Sep 2026 15:02:19 -0700 Subject: [PATCH 6/8] Require legacy COSE IDs for PSA/EAT Sign1 profiles --- Makefile | 45 +++++++++++++++++++++------- docs/Macros.md | 4 +-- docs/PSA-EAT.md | 2 ++ include/wolfcose/settings.h | 6 ++-- tests/config/eat_psa_config/config.h | 1 + tests/test_eat_psa_derived_gate.c | 5 ---- 6 files changed, 43 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index 54275c7b..96babe18 100644 --- a/Makefile +++ b/Makefile @@ -544,6 +544,7 @@ eat-psa-config-check: echo "FAIL: claim-only issuer contains a verifier or envelope creator"; exit 1; \ fi $(MAKE) all EXTRA_CFLAGS='-DWOLFCOSE_LEAN $(EAT_PSA_NO_DECODE_FLAGS) \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1_ISSUE' @@ -565,18 +566,20 @@ eat-psa-config-check: fi $(MAKE) all $(CC) $(CFLAGS) -Werror -DWOLFCOSE_LEAN_VERIFY \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -fsyntax-only $(EAT_PSA_SRC) $(CC) $(CFLAGS) -Werror -DWOLFCOSE_LEAN \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 -fsyntax-only $(EAT_PSA_SRC) $(CC) $(CFLAGS) -Werror -DWOLFCOSE_LEAN_VERIFY \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_LEGACY \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -fsyntax-only $(EAT_PSA_SRC) $(CC) $(CFLAGS) -Werror -DWOLFCOSE_LEAN \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_LEGACY \ -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 -fsyntax-only $(EAT_PSA_SRC) - $(CC) $(CFLAGS) -Werror \ + $(CC) $(CFLAGS) -Werror -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1_ISSUE \ @@ -587,11 +590,13 @@ eat-psa-config-check: -DWOLFCOSE_ENABLE_EAT_PSA_MAC0_ISSUE \ -DWOLFCOSE_NO_HMAC384 -DWOLFCOSE_NO_HMAC512 -fsyntax-only $(EAT_PSA_SRC) $(CC) $(CFLAGS) -Werror -Werror=unused-function -DWOLFCOSE_LEAN \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_NO_ES256 -DWOLFCOSE_ENABLE_ES384 \ -DWOLFCOSE_NO_SIGN1_VERIFY -DWOLFCOSE_ENABLE_EAT_PSA \ -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1_ISSUE -fsyntax-only $(EAT_PSA_SRC) $(CC) $(CFLAGS) -Werror -Werror=unused-function -DWOLFCOSE_LEAN \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_NO_ES256 -DWOLFCOSE_ENABLE_ES512 \ -DWOLFCOSE_NO_SIGN1_VERIFY -DWOLFCOSE_ENABLE_EAT_PSA \ -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE \ @@ -607,6 +612,7 @@ eat-psa-config-check: -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE \ -DWOLFCOSE_ENABLE_EAT_PSA_MAC0_ISSUE -fsyntax-only $(EAT_PSA_SRC) $(CC) $(CFLAGS) -Werror -DWOLFSSL_USER_SETTINGS \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -I./tests/config/eat_psa_curves \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ @@ -617,24 +623,34 @@ eat-psa-config-check: -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ -fsyntax-only tests/test_eat_psa_min_key_gates.c - $(CC) $(CFLAGS) -Werror -DWOLFSSL_USER_SETTINGS \ - -I./tests/config/eat_psa_min_key -DECC_MIN_KEY_SZ=256 \ - -DWOLFCOSE_TEST_NO_DEPRECATED_ALGS \ + @if $(CC) $(CFLAGS) \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ - -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ - -fsyntax-only tests/test_eat_psa_derived_gate.c + -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -fsyntax-only \ + $(EAT_PSA_SRC) >/dev/null 2>&1; then \ + echo "FAIL: PSA/EAT Sign1 accepted without deprecated ES* IDs"; exit 1; \ + fi + @if $(CC) $(CFLAGS) \ + -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ + -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE \ + -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1_ISSUE -fsyntax-only \ + $(EAT_PSA_SRC) >/dev/null 2>&1; then \ + echo "FAIL: PSA/EAT Sign1 issuer accepted without deprecated ES* IDs"; exit 1; \ + fi $(CC) $(CFLAGS) -Werror -DWOLFSSL_USER_SETTINGS \ -I./tests/config/eat_psa_min_key -DECC_MIN_KEY_SZ=257 \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ -fsyntax-only tests/test_eat_psa_min_key_gates.c $(CC) $(CFLAGS) -Werror -DWOLFSSL_USER_SETTINGS \ -I./tests/config/eat_psa_min_key -DECC_MIN_KEY_SZ=384 \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ -fsyntax-only tests/test_eat_psa_min_key_gates.c $(CC) $(CFLAGS) -Werror -DWOLFSSL_USER_SETTINGS \ -I./tests/config/eat_psa_min_key -DECC_MIN_KEY_SZ=521 \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ -fsyntax-only tests/test_eat_psa_min_key_gates.c @@ -655,6 +671,7 @@ eat-psa-config-check: fi @if $(CC) $(CFLAGS) -DWOLFSSL_USER_SETTINGS \ -I./tests/config/eat_psa_min_key -DECC_MIN_KEY_SZ=522 \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -fsyntax-only \ tests/test_eat_psa_derived_gate.c >/dev/null 2>&1; then \ @@ -672,10 +689,11 @@ eat-psa-config-check: fi $(CC) $(CFLAGS) -Werror -DWOLFSSL_USER_SETTINGS \ -I./tests/config/eat_psa_no_sha256 \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ -fsyntax-only tests/test_eat_psa_hash_gates.c - @if $(CC) $(CFLAGS) -Werror \ + @if $(CC) $(CFLAGS) -Werror -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ -DWOLFCOSE_NO_ES384 -DWOLFCOSE_NO_ES512 \ @@ -685,6 +703,7 @@ eat-psa-config-check: echo "FAIL: partial receiver accepted forced #tfm capability"; exit 1; \ fi $(CC) $(CFLAGS) -Werror -DHAVE_ALL_CURVES -DNO_ECC256 \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ -DWOLFCOSE_TEST_NO_ECC256_ALL_CURVES -fsyntax-only \ @@ -714,7 +733,8 @@ eat-psa-config-check: $(EAT_PSA_SRC) >/dev/null 2>&1; then \ echo "FAIL: PSA/EAT accepted a profile without an operation"; exit 1; \ fi - @if $(CC) $(CFLAGS) -DWOLFCOSE_ENABLE_EAT_PSA \ + @if $(CC) $(CFLAGS) -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ + -DWOLFCOSE_ENABLE_EAT_PSA \ -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1_ISSUE -fsyntax-only \ $(EAT_PSA_SRC) >/dev/null 2>&1; then \ @@ -726,7 +746,8 @@ eat-psa-config-check: $(EAT_PSA_SRC) >/dev/null 2>&1; then \ echo "FAIL: Mac0 issuer accepted without common issuance"; exit 1; \ fi - @if $(CC) $(CFLAGS) -DWOLFCOSE_ENABLE_EAT_PSA \ + @if $(CC) $(CFLAGS) -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ + -DWOLFCOSE_ENABLE_EAT_PSA \ -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 \ -DWOLFCOSE_NO_ES256 -DWOLFCOSE_NO_ES384 -DWOLFCOSE_NO_ES512 \ -fsyntax-only $(EAT_PSA_SRC) >/dev/null 2>&1; then \ @@ -745,7 +766,8 @@ eat-psa-config-check: $(EAT_PSA_SRC) >/dev/null 2>&1; then \ echo "FAIL: component iterator flag accepted without PSA/EAT"; exit 1; \ fi - @if $(CC) $(CFLAGS) -DWOLFCOSE_ENABLE_EAT_PSA \ + @if $(CC) $(CFLAGS) -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ + -DWOLFCOSE_ENABLE_EAT_PSA \ -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1_ISSUE -DWOLFCOSE_NO_SIGN1_SIGN \ -fsyntax-only $(EAT_PSA_SRC) >/dev/null 2>&1; then \ @@ -757,7 +779,8 @@ eat-psa-config-check: -fsyntax-only $(EAT_PSA_SRC) >/dev/null 2>&1; then \ echo "FAIL: Mac0 issuer accepted without a creation path"; exit 1; \ fi - @if $(CC) $(CFLAGS) -DWOLFCOSE_ENABLE_EAT_PSA \ + @if $(CC) $(CFLAGS) -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ + -DWOLFCOSE_ENABLE_EAT_PSA \ -DWOLFCOSE_ENABLE_EAT_PSA_LEGACY -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 \ -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE -fsyntax-only $(EAT_PSA_SRC) \ >/dev/null 2>&1; then \ diff --git a/docs/Macros.md b/docs/Macros.md index 4b93036b..7cf68cf3 100644 --- a/docs/Macros.md +++ b/docs/Macros.md @@ -98,8 +98,8 @@ The generic operation and algorithm gates remain authoritative: | PSA/EAT path | Required generic operation | Algorithm selection | |--------------|----------------------------|---------------------| -| Sign1 consume | `WOLFCOSE_SIGN1_VERIFY` | ES256, ES384, and/or ES512 | -| Sign1 issue | `WOLFCOSE_SIGN1_SIGN` | ES256, ES384, and/or ES512 | +| Sign1 consume | `WOLFCOSE_SIGN1_VERIFY` | `WOLFCOSE_ENABLE_DEPRECATED_ALGS` plus ES256, ES384, and/or ES512 | +| Sign1 issue | `WOLFCOSE_SIGN1_SIGN` | `WOLFCOSE_ENABLE_DEPRECATED_ALGS` plus ES256, ES384, and/or ES512 | | Mac0 consume | `WOLFCOSE_MAC0_VERIFY` | HMAC256, HMAC384, and/or HMAC512 | | Mac0 issue | `WOLFCOSE_MAC0_CREATE` | HMAC256, HMAC384, and/or HMAC512 | diff --git a/docs/PSA-EAT.md b/docs/PSA-EAT.md index 95230308..6894d578 100644 --- a/docs/PSA-EAT.md +++ b/docs/PSA-EAT.md @@ -34,6 +34,8 @@ and at least one consume or issue operation after it. The generic wolfCOSE algorithm gates remain authoritative. Select ES384, ES512, HMAC384, and HMAC512 with their normal `WOLFCOSE_ENABLE_*` macros in a lean build, or remove any supported algorithm with its `WOLFCOSE_NO_*` macro. +Sign1 consumption and issuance require `WOLFCOSE_ENABLE_DEPRECATED_ALGS` +because RFC 9783 Table 4 uses the RFC 9053 ES256/384/512 IDs. The PSA/EAT code has no algorithm fallback: a disabled algorithm is rejected before claims are used. diff --git a/include/wolfcose/settings.h b/include/wolfcose/settings.h index 5abdc550..19c9e3a0 100644 --- a/include/wolfcose/settings.h +++ b/include/wolfcose/settings.h @@ -833,9 +833,10 @@ extern "C" { #if defined(WOLFCOSE_ENABLE_EAT_PSA_SIGN1) #if !defined(WOLFCOSE_EAT_PSA) || !defined(WOLFCOSE_SIGN1_VERIFY) || \ !defined(WOLFCOSE_CBOR_DECODE) || \ + !defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) || \ (!defined(WOLFCOSE_HAVE_ES256) && !defined(WOLFCOSE_HAVE_ES384) && \ !defined(WOLFCOSE_HAVE_ES512)) - #error "WOLFCOSE_ENABLE_EAT_PSA_SIGN1 requires EAT_PSA and an ECDSA COSE Sign1 verifier" + #error "WOLFCOSE_ENABLE_EAT_PSA_SIGN1 requires EAT_PSA, deprecated IDs, and an ECDSA COSE Sign1 verifier" #endif #define WOLFCOSE_EAT_PSA_SIGN1 #endif @@ -851,9 +852,10 @@ extern "C" { #if defined(WOLFCOSE_ENABLE_EAT_PSA_SIGN1_ISSUE) #if !defined(WOLFCOSE_EAT_PSA_ISSUE) || \ !defined(WOLFCOSE_SIGN1_SIGN) || \ + !defined(WOLFCOSE_HAVE_DEPRECATED_ALGS) || \ (!defined(WOLFCOSE_HAVE_ES256) && !defined(WOLFCOSE_HAVE_ES384) && \ !defined(WOLFCOSE_HAVE_ES512)) - #error "EAT_PSA_SIGN1_ISSUE needs EAT_PSA_ISSUE and ECDSA Sign1 signing" + #error "EAT_PSA_SIGN1_ISSUE needs EAT_PSA_ISSUE, deprecated IDs, and ECDSA Sign1 signing" #endif #define WOLFCOSE_EAT_PSA_SIGN1_ISSUE #endif diff --git a/tests/config/eat_psa_config/config.h b/tests/config/eat_psa_config/config.h index 9b436d79..96d9522f 100644 --- a/tests/config/eat_psa_config/config.h +++ b/tests/config/eat_psa_config/config.h @@ -4,6 +4,7 @@ #define WOLFCOSE_ENABLE_EAT_PSA #define WOLFCOSE_ENABLE_EAT_PSA_CURRENT +#define WOLFCOSE_ENABLE_DEPRECATED_ALGS #define WOLFCOSE_ENABLE_EAT_PSA_SIGN1 #endif /* WOLFCOSE_TEST_EAT_PSA_CONFIG_H */ diff --git a/tests/test_eat_psa_derived_gate.c b/tests/test_eat_psa_derived_gate.c index 6ba8909d..cf2e62dd 100644 --- a/tests/test_eat_psa_derived_gate.c +++ b/tests/test_eat_psa_derived_gate.c @@ -23,11 +23,6 @@ #endif #endif -#if defined(WOLFCOSE_TEST_NO_DEPRECATED_ALGS) && \ - defined(WOLFCOSE_EAT_PSA_TFM_FULL) - #error "RFC 9783 #tfm receiver needs the RFC 9053 signature IDs" -#endif - int test_eat_psa_derived_gate(void) { return 0; From 6a202dcb42871594a14b202b2e4466783f648aec Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 15 Sep 2026 15:07:41 -0700 Subject: [PATCH 7/8] Enable legacy IDs in PSA/EAT CI profiles --- .github/workflows/lean-build.yml | 1 + .github/workflows/misra-2012.yml | 1 + .github/workflows/misra-2023.yml | 1 + .github/workflows/stack-bounds.yml | 2 +- .github/workflows/static-analysis.yml | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lean-build.yml b/.github/workflows/lean-build.yml index 0b8c5bef..c1f4a007 100644 --- a/.github/workflows/lean-build.yml +++ b/.github/workflows/lean-build.yml @@ -166,6 +166,7 @@ jobs: build_cfg "WOLFCOSE_LEAN_VERIFY" -DWOLFCOSE_LEAN_VERIFY build_cfg "WOLFCOSE_LEAN_VERIFY + RFC 9783 PSA/EAT" \ -DWOLFCOSE_LEAN_VERIFY -DWOLFCOSE_ENABLE_EAT_PSA \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 \ -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 -DWOLFCOSE_ENABLE_ES384 \ diff --git a/.github/workflows/misra-2012.yml b/.github/workflows/misra-2012.yml index 10677c83..398b60cd 100644 --- a/.github/workflows/misra-2012.yml +++ b/.github/workflows/misra-2012.yml @@ -125,6 +125,7 @@ jobs: -DHAVE_HKDF \ -DHAVE_AES_CBC \ -DHAVE_HPKE \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA \ -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 \ diff --git a/.github/workflows/misra-2023.yml b/.github/workflows/misra-2023.yml index bad04778..2df20b87 100644 --- a/.github/workflows/misra-2023.yml +++ b/.github/workflows/misra-2023.yml @@ -232,6 +232,7 @@ jobs: -DWOLFCOSE_SIGN1 -DWOLFCOSE_SIGN1_SIGN -DWOLFCOSE_SIGN1_VERIFY \ -DWOLFCOSE_ENCRYPT0 -DWOLFCOSE_ENCRYPT0_ENCRYPT -DWOLFCOSE_ENCRYPT0_DECRYPT \ -DWOLFCOSE_MAC0 -DWOLFCOSE_MAC0_CREATE -DWOLFCOSE_MAC0_VERIFY \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 \ -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE -DWOLFCOSE_ENABLE_EAT_PSA_LEGACY \ diff --git a/.github/workflows/stack-bounds.yml b/.github/workflows/stack-bounds.yml index 0bdd089e..e6c5d47e 100644 --- a/.github/workflows/stack-bounds.yml +++ b/.github/workflows/stack-bounds.yml @@ -51,7 +51,7 @@ jobs: - name: Build full PSA/EAT wolfCOSE (-Werror=vla, -fstack-usage) run: | export WOLFSSL_DIR=$HOME/wolfssl-full - EAT_FLAGS="-DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1_ISSUE -DWOLFCOSE_ENABLE_EAT_PSA_MAC0_ISSUE -DWOLFCOSE_ENABLE_EAT_PSA_LEGACY -DWOLFCOSE_ENABLE_EAT_PSA_UEID_RESOLVER -DWOLFCOSE_ENABLE_EAT_PSA_COMPONENT_ITERATOR" + EAT_FLAGS="-DWOLFCOSE_ENABLE_DEPRECATED_ALGS -DWOLFCOSE_ENABLE_EAT_PSA -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 -DWOLFCOSE_ENABLE_EAT_PSA_MAC0 -DWOLFCOSE_ENABLE_EAT_PSA_ISSUE -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1_ISSUE -DWOLFCOSE_ENABLE_EAT_PSA_MAC0_ISSUE -DWOLFCOSE_ENABLE_EAT_PSA_LEGACY -DWOLFCOSE_ENABLE_EAT_PSA_UEID_RESOLVER -DWOLFCOSE_ENABLE_EAT_PSA_COMPONENT_ITERATOR" make CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -Wvla -Werror=vla -fstack-usage -I./include -I$WOLFSSL_DIR/include $EAT_FLAGS" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" grep -q "wc_CoseEatPsaToken_Verify" src/wolfcose_eat_psa.su diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 5bce9376..c17b4e33 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -77,6 +77,7 @@ jobs: --error-exitcode=1 \ --suppress=missingIncludeSystem \ --inline-suppr \ + -DWOLFCOSE_ENABLE_DEPRECATED_ALGS \ -DWOLFCOSE_ENABLE_EAT_PSA \ -DWOLFCOSE_ENABLE_EAT_PSA_CURRENT \ -DWOLFCOSE_ENABLE_EAT_PSA_SIGN1 \ From 3917a6cc2f3296a972e247eb24dc34d6eb25aa48 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 15 Sep 2026 15:14:13 -0700 Subject: [PATCH 8/8] Support P-384 and P-521 algorithms in CLI --- .github/workflows/cmdline-test.yml | 2 +- scripts/cmdline-test.sh | 20 +++- tools/wolfcose_tool.c | 149 ++++++++++++++++++++++++----- 3 files changed, 146 insertions(+), 25 deletions(-) diff --git a/.github/workflows/cmdline-test.yml b/.github/workflows/cmdline-test.yml index b124d3e0..64f39aa0 100644 --- a/.github/workflows/cmdline-test.yml +++ b/.github/workflows/cmdline-test.yml @@ -89,7 +89,7 @@ jobs: - name: Run command-line tool test with deprecated alg names env: EXPECT_PQC: ${{ matrix.pqc }} - SIGN_ALGS: "ES256 EdDSA Ed448 ESP256 Ed25519" + SIGN_ALGS: "ES256 ES384 ES512 EdDSA Ed448 ESP256 ESP384 ESP512 Ed25519" run: | export WOLFSSL_DIR=$HOME/wolfssl-install export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib diff --git a/scripts/cmdline-test.sh b/scripts/cmdline-test.sh index 8441bf28..41113484 100755 --- a/scripts/cmdline-test.sh +++ b/scripts/cmdline-test.sh @@ -54,7 +54,7 @@ hpke_keygen_or() { } # Names exactly as wolfcose_tool's parser accepts them. -SIGN_ALGS="${SIGN_ALGS:-ESP256 Ed25519 Ed448 ML-DSA-44 ML-DSA-65 ML-DSA-87}" +SIGN_ALGS="${SIGN_ALGS:-ESP256 ESP384 ESP512 Ed25519 Ed448 ML-DSA-44 ML-DSA-65 ML-DSA-87}" ENC_ALGS="A128GCM A192GCM A256GCM ChaCha20 AES-CCM" MAC_ALGS="HMAC256 HMAC384 HMAC512" @@ -63,6 +63,7 @@ for A in $SIGN_ALGS; do K="$WORK/sig.key"; C="$WORK/sig.cose" case "$A" in ML-DSA-*) [ "$EXPECT_PQC" = "true" ] && OPT=0 || OPT=1 ;; + ESP384|ESP512) OPT=1 ;; *) OPT=0 ;; esac if ! keygen_or "$A" "$K" "$OPT"; then continue; fi @@ -117,6 +118,23 @@ else skip "countersignature (ESP256)" fi +for A in ESP384 ESP512; do + EK="$WORK/$A-counter.key"; EC="$WORK/$A-counter.cose" + if [ -f "$BASE" ] && "$TOOL" keygen -a "$A" -o "$EK" \ + >/dev/null 2>&1; then + if "$TOOL" countersign -k "$EK" -a "$A" -i "$BASE" \ + -o "$EC" >/dev/null 2>&1 && \ + "$TOOL" counterverify -k "$EK" -i "$EC" >/dev/null 2>&1 && \ + "$TOOL" verify -k "$PK" -i "$EC" >/dev/null 2>&1; then + ok "$A countersign and verify both layers" + else + bad "$A countersign round-trip" + fi + else + skip "countersignature ($A)" + fi +done + # Public-only RSA builds can't sign a decoded key, so skip; the self-test # still covers RSA signing. echo "== RSA-PSS: keygen -> sign -> verify -> self-test ==" diff --git a/tools/wolfcose_tool.c b/tools/wolfcose_tool.c index baf52a7b..bf0acc05 100644 --- a/tools/wolfcose_tool.c +++ b/tools/wolfcose_tool.c @@ -215,9 +215,11 @@ static void usage(void) " test [--all | -a ] Round-trip self-test\n" "\nCountersign options: -p --aad \n" "\n" - "Algorithms: ESP256, Ed25519, Ed448, PS256, PS384, PS512,\n" + "Algorithms: ESP256, ESP384, ESP512, Ed25519, Ed448,\n" + " PS256, PS384, PS512,\n" " ML-DSA-44, ML-DSA-65, ML-DSA-87,\n" - " (ES256, EdDSA with WOLFCOSE_ENABLE_DEPRECATED_ALGS)\n" + " (ES256, ES384, ES512, EdDSA with" + " WOLFCOSE_ENABLE_DEPRECATED_ALGS)\n" " A128GCM, A192GCM, A256GCM, ChaCha20, AES-CCM,\n" #if defined(WOLFCOSE_HPKE_0_ENCRYPT) || defined(WOLFCOSE_HPKE_0_DECRYPT) " HPKE-0,\n" @@ -235,6 +237,16 @@ static int parse_alg(const char* name, int32_t* alg) if (strcmp(name, "ESP256") == 0) { *alg = WOLFCOSE_ALG_ESP256; } +#ifdef WOLFCOSE_HAVE_ES384 + else if (strcmp(name, "ESP384") == 0) { + *alg = WOLFCOSE_ALG_ESP384; + } +#endif +#ifdef WOLFCOSE_HAVE_ES512 + else if (strcmp(name, "ESP512") == 0) { + *alg = WOLFCOSE_ALG_ESP512; + } +#endif else if (strcmp(name, "Ed25519") == 0) { *alg = WOLFCOSE_ALG_ED25519; } @@ -247,12 +259,25 @@ static int parse_alg(const char* name, int32_t* alg) else if (strcmp(name, "ES256") == 0) { *alg = WOLFCOSE_ALG_ES256; } +#ifdef WOLFCOSE_HAVE_ES384 + else if (strcmp(name, "ES384") == 0) { + *alg = WOLFCOSE_ALG_ES384; + } +#endif +#ifdef WOLFCOSE_HAVE_ES512 + else if (strcmp(name, "ES512") == 0) { + *alg = WOLFCOSE_ALG_ES512; + } +#endif else if (strcmp(name, "EdDSA") == 0) { *alg = WOLFCOSE_ALG_EDDSA; } #else - else if ((strcmp(name, "ES256") == 0) || (strcmp(name, "EdDSA") == 0)) { - fprintf(stderr, "%s is deprecated by RFC 9864; use ESP256 or Ed25519, " + else if ((strcmp(name, "ES256") == 0) || + (strcmp(name, "ES384") == 0) || + (strcmp(name, "ES512") == 0) || + (strcmp(name, "EdDSA") == 0)) { + fprintf(stderr, "%s is deprecated by RFC 9864; use an ESP or Ed ID, " "or rebuild with WOLFCOSE_ENABLE_DEPRECATED_ALGS.\n", name); return -1; @@ -330,6 +355,44 @@ static int parse_alg(const char* name, int32_t* alg) return 0; } +#ifdef WOLFCOSE_HAVE_ECDSA +/* Keep CLI key generation and signing on the curve required by each ID. */ +static int tool_ecc_alg_params(int32_t alg, int32_t* crv, int* keySz) +{ + switch (alg) { +#ifdef WOLFCOSE_HAVE_ES256 + case WOLFCOSE_ALG_ESP256: +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS + case WOLFCOSE_ALG_ES256: +#endif + *crv = WOLFCOSE_CRV_P256; + if (keySz != NULL) *keySz = 32; + return 0; +#endif +#ifdef WOLFCOSE_HAVE_ES384 + case WOLFCOSE_ALG_ESP384: +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS + case WOLFCOSE_ALG_ES384: +#endif + *crv = WOLFCOSE_CRV_P384; + if (keySz != NULL) *keySz = 48; + return 0; +#endif +#ifdef WOLFCOSE_HAVE_ES512 + case WOLFCOSE_ALG_ESP512: +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS + case WOLFCOSE_ALG_ES512: +#endif + *crv = WOLFCOSE_CRV_P521; + if (keySz != NULL) *keySz = 66; + return 0; +#endif + default: + return -1; + } +} +#endif + /* Read an entire file into buffer, rejecting data beyond the caller's bound. */ static int read_file(const char* path, uint8_t* buf, size_t bufSz, size_t* outLen) @@ -862,6 +925,10 @@ static int tool_content_nonce_len(int32_t alg, size_t* nonceLen) static int tool_keygen(int32_t alg, const char* outPath) { int ret; +#ifdef WOLFCOSE_HAVE_ECDSA + int32_t eccCrv = 0; + int eccKeySz = 0; +#endif WC_RNG rng; WOLFCOSE_KEY coseKey; uint8_t keyBuf[WOLFCOSE_TOOL_MAX_KEY]; @@ -875,19 +942,21 @@ static int tool_keygen(int32_t alg, const char* outPath) wc_CoseKey_Init(&coseKey); -#ifdef WOLFCOSE_HAVE_ES256 - if ((alg == WOLFCOSE_ALG_ESP256) || (alg == WOLFCOSE_ALG_ES256)) { +#ifdef WOLFCOSE_HAVE_ECDSA + if (tool_ecc_alg_params(alg, &eccCrv, &eccKeySz) == 0) { ecc_key ecc; wc_ecc_init(&ecc); - ret = wc_ecc_make_key(&rng, 32, &ecc); + ret = wc_ecc_make_key(&rng, eccKeySz, &ecc); if (ret != 0) { fprintf(stderr, "ECC keygen failed: %d\n", ret); wc_ecc_free(&ecc); wc_FreeRng(&rng); return EXIT_CRYPTO; } - wc_CoseKey_SetEcc(&coseKey, WOLFCOSE_CRV_P256, &ecc); - ret = wc_CoseKey_Encode(&coseKey, keyBuf, sizeof(keyBuf), &keyLen); + ret = wc_CoseKey_SetEcc(&coseKey, eccCrv, &ecc); + if (ret == 0) { + ret = wc_CoseKey_Encode(&coseKey, keyBuf, sizeof(keyBuf), &keyLen); + } wc_ecc_free(&ecc); } else @@ -1056,6 +1125,9 @@ static int tool_sign(const char* keyPath, int32_t alg, const char* inPath, const char* outPath) { int ret; +#ifdef WOLFCOSE_HAVE_ECDSA + int32_t eccCrv = 0; +#endif uint8_t keyBuf[WOLFCOSE_TOOL_MAX_KEY]; size_t keyLen = 0; uint8_t msgBuf[WOLFCOSE_TOOL_MAX_MSG]; @@ -1089,11 +1161,11 @@ static int tool_sign(const char* keyPath, int32_t alg, wc_CoseKey_Init(&coseKey); #ifdef WOLFCOSE_HAVE_ECDSA - if (alg == WOLFCOSE_ALG_ESP256 || alg == WOLFCOSE_ALG_ES256) { + if (tool_ecc_alg_params(alg, &eccCrv, NULL) == 0) { ecc_key ecc; wc_ecc_init(&ecc); /* Attach curve is a placeholder; decode takes crv from the key file. */ - ret = wc_CoseKey_SetEcc(&coseKey, WOLFCOSE_CRV_P256, &ecc); + ret = wc_CoseKey_SetEcc(&coseKey, eccCrv, &ecc); if (ret == 0) { ret = wc_CoseKey_Decode(&coseKey, keyBuf, keyLen); } @@ -2213,10 +2285,12 @@ static int tool_info(const char* inPath) /* ----- test: in-memory round-trip self-tests for all algorithms ----- */ /* Sign round-trip: keygen -> sign -> verify -> check payload */ -#ifdef WOLFCOSE_HAVE_ES256 -static int test_sign_es256(const char* name, int32_t alg) +#ifdef WOLFCOSE_HAVE_ECDSA +static int test_sign_ecc(const char* name, int32_t alg) { int ret = 0; + int32_t crv = 0; + int keySz = 0; WC_RNG rng; ecc_key ecc; WOLFCOSE_KEY key; @@ -2231,23 +2305,28 @@ static int test_sign_es256(const char* name, int32_t alg) printf(" %-12s sign/verify ... ", name); - ret = wc_InitRng(&rng); + ret = tool_ecc_alg_params(alg, &crv, &keySz); + if (ret == 0) { + ret = wc_InitRng(&rng); + } if (ret == 0) { rngInit = 1; ret = wc_ecc_init(&ecc); } if (ret == 0) { eccInit = 1; - ret = wc_ecc_make_key(&rng, 32, &ecc); + ret = wc_ecc_make_key(&rng, keySz, &ecc); } if (ret == 0) { wc_CoseKey_Init(&key); - wc_CoseKey_SetEcc(&key, WOLFCOSE_CRV_P256, &ecc); + ret = wc_CoseKey_SetEcc(&key, crv, &ecc); - ret = wc_CoseSign1_Sign(&key, alg, NULL, 0, - payload, sizeof(payload) - 1, NULL, 0, NULL, 0, - scratch, sizeof(scratch), - out, sizeof(out), &outLen, &rng); + if (ret == 0) { + ret = wc_CoseSign1_Sign(&key, alg, NULL, 0, + payload, sizeof(payload) - 1, NULL, 0, NULL, 0, + scratch, sizeof(scratch), + out, sizeof(out), &outLen, &rng); + } } if (ret == 0) { ret = wc_CoseSign1_Verify(&key, out, outLen, NULL, 0, NULL, 0, @@ -2255,7 +2334,7 @@ static int test_sign_es256(const char* name, int32_t alg) &hdr, &decoded, &decodedLen); } if (ret == 0) { - if (decodedLen != sizeof(payload) - 1 || + if (hdr.alg != alg || decodedLen != sizeof(payload) - 1 || memcmp(decoded, payload, decodedLen) != 0) { ret = -1; } @@ -2790,12 +2869,36 @@ static int tool_test(const char* filter) #ifdef WOLFCOSE_HAVE_ES256 if (all || strcmp(filter, "ESP256") == 0) { tests++; - if (test_sign_es256("ESP256", WOLFCOSE_ALG_ESP256) != 0) failures++; + if (test_sign_ecc("ESP256", WOLFCOSE_ALG_ESP256) != 0) failures++; } #ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS if (all || strcmp(filter, "ES256") == 0) { tests++; - if (test_sign_es256("ES256", WOLFCOSE_ALG_ES256) != 0) failures++; + if (test_sign_ecc("ES256", WOLFCOSE_ALG_ES256) != 0) failures++; + } +#endif +#endif +#ifdef WOLFCOSE_HAVE_ES384 + if (all || strcmp(filter, "ESP384") == 0) { + tests++; + if (test_sign_ecc("ESP384", WOLFCOSE_ALG_ESP384) != 0) failures++; + } +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS + if (all || strcmp(filter, "ES384") == 0) { + tests++; + if (test_sign_ecc("ES384", WOLFCOSE_ALG_ES384) != 0) failures++; + } +#endif +#endif +#ifdef WOLFCOSE_HAVE_ES512 + if (all || strcmp(filter, "ESP512") == 0) { + tests++; + if (test_sign_ecc("ESP512", WOLFCOSE_ALG_ESP512) != 0) failures++; + } +#ifdef WOLFCOSE_HAVE_DEPRECATED_ALGS + if (all || strcmp(filter, "ES512") == 0) { + tests++; + if (test_sign_ecc("ES512", WOLFCOSE_ALG_ES512) != 0) failures++; } #endif #endif