@@ -284,6 +284,7 @@ WOLFIP_ENABLE_PEAP_MSCHAPV2 ?= 0
284284WOLFIP_ENABLE_SAE ?= 1
285285WOLFIP_ENABLE_SAE_H2E ?= 1
286286WOLFIP_ENABLE_SAE_HNP ?= 1
287+ WOLFIP_ENABLE_MACSEC ?= 0
287288
288289ifneq ($(WOLFSSL_PREFIX ) ,)
289290WOLFSSL_CFLAGS := -I$(WOLFSSL_PREFIX ) /include
@@ -335,7 +336,40 @@ $(error WOLFIP_ENABLE_SAE_H2E=1 requires WOLFIP_ENABLE_SAE=1)
335336endif
336337endif
337338
338- SUPPLICANT_OBJ := $(patsubst src/% .c,build/% .o,$(SUPPLICANT_SRC ) )
339+ # MACsec / MKA (IEEE 802.1AE + 802.1X-2010). Standalone module under
340+ # src/macsec/ that reuses the supplicant crypto layer (AES key wrap, secure
341+ # zero). Requires wolfSSL built with --enable-cmac (WOLFSSL_CMAC).
342+ # The software SecY (macsec_crypto/macsec_secy/macsec_sa) is always built with
343+ # MACsec. The MKA control plane is provided by the wolfDen wolfMKA library
344+ # (https://github.com/wolfSSL/wolfDen/tree/main/mka) from a local clone (not a
345+ # submodule): set WOLFMKA_DIR to build it. Without it, only the SecY data plane
346+ # (usable with a static SAK) is built.
347+ WOLFMKA_DIR ?=
348+ WOLFMKA_OBJ :=
349+ WOLFIP_HAVE_WOLFMKA :=
350+
351+ ifeq ($(WOLFIP_ENABLE_MACSEC ) ,1)
352+ SUPPLICANT_SRC += src/macsec/macsec_crypto.c \
353+ src/macsec/macsec_secy.c \
354+ src/macsec/macsec_sa.c
355+ CFLAGS += -DWOLFIP_ENABLE_MACSEC=1 -Isrc/macsec
356+ ifneq ($(WOLFMKA_DIR ) ,)
357+ ifeq ($(wildcard $(WOLFMKA_DIR ) /include/wolfmka/mka_kay.h) ,)
358+ $(error WOLFMKA_DIR is set but does not point at a wolfMKA clone (got '$(WOLFMKA_DIR)'))
359+ endif
360+ WOLFIP_HAVE_WOLFMKA := 1
361+ SUPPLICANT_SRC += src/macsec/mka_wolfmka.c
362+ # WOLFMKA_ICV_L2_ADDR makes wolfMKA include the L2 addresses (DA||SA||EtherType)
363+ # in the MKA ICV, matching wpa_supplicant / the Linux kernel (802.1X-2010
364+ # 11.11.3); required to interoperate with them (wolfSSL/wolfDen PR #2).
365+ CFLAGS += -DWOLFIP_MKA_WOLFMKA=1 -DWOLFMKA_ICV_L2_ADDR -I$(WOLFMKA_DIR ) /include
366+ # wolfMKA library objects live outside src/, compiled to build/wolfmka/.
367+ WOLFMKA_OBJ := build/wolfmka/mka_crypto.o build/wolfmka/mka_kay.o \
368+ build/wolfmka/mka_pdu.o build/wolfmka/mka_status.o
369+ endif
370+ endif
371+
372+ SUPPLICANT_OBJ := $(patsubst src/% .c,build/% .o,$(SUPPLICANT_SRC ) ) $(WOLFMKA_OBJ )
339373
340374# Header-dependency tracking for the supplicant + its host glue. Without
341375# this, editing a supplicant header (e.g. a struct in supplicant.h) would
@@ -351,6 +385,17 @@ build/supplicant/%.o: src/supplicant/%.c
351385 @echo " [CC] $<"
352386 @$(CC ) $(CFLAGS ) $(WOLFSSL_CFLAGS ) $(NL80211_CFLAGS ) -MMD -MP -Isrc/supplicant -c $< -o $@
353387
388+ build/macsec/% .o : src/macsec/% .c
389+ @mkdir -p ` dirname $@ ` || true
390+ @echo " [CC] $<"
391+ @$(CC ) $(CFLAGS ) $(WOLFSSL_CFLAGS ) -MMD -MP -Isrc/supplicant -Isrc/macsec -c $< -o $@
392+
393+ # wolfMKA library sources from the local clone ($(WOLFMKA_DIR)/src).
394+ build/wolfmka/% .o : $(WOLFMKA_DIR ) /src/% .c
395+ @mkdir -p build/wolfmka || true
396+ @echo " [CC] $<"
397+ @$(CC ) $(CFLAGS ) $(WOLFSSL_CFLAGS ) -I$(WOLFMKA_DIR ) /include -c $< -o $@
398+
354399# WOLFSSL_LIBS / WOLFSSL_CFLAGS may already be set above when
355400# WOLFSSL_PREFIX is provided. Otherwise default to pkg-config detection
356401# and a plain -lwolfssl fallback.
@@ -368,6 +413,59 @@ build/test-wpa-crypto: $(SUPPLICANT_OBJ) build/supplicant/test_wpa_crypto.o
368413 @echo " [LD] $@ "
369414 @$(CC ) $(CFLAGS ) -o $@ $(BEGIN_GROUP ) $(^ ) $(LDFLAGS ) $(WOLFSSL_LIBS ) $(END_GROUP )
370415
416+ build/test-macsec-crypto : $(SUPPLICANT_OBJ ) build/macsec/test_macsec_crypto.o
417+ @echo " [LD] $@ "
418+ @$(CC ) $(CFLAGS ) -o $@ $(BEGIN_GROUP ) $(^ ) $(LDFLAGS ) $(WOLFSSL_LIBS ) $(END_GROUP )
419+
420+ build/test-macsec-secy : $(SUPPLICANT_OBJ ) build/macsec/test_macsec_secy.o
421+ @echo " [LD] $@ "
422+ @$(CC ) $(CFLAGS ) -o $@ $(BEGIN_GROUP ) $(^ ) $(LDFLAGS ) $(WOLFSSL_LIBS ) $(END_GROUP )
423+
424+ build/test-macsec-sa : $(SUPPLICANT_OBJ ) build/macsec/test_macsec_sa.o
425+ @echo " [LD] $@ "
426+ @$(CC ) $(CFLAGS ) -o $@ $(BEGIN_GROUP ) $(^ ) $(LDFLAGS ) $(WOLFSSL_LIBS ) $(END_GROUP )
427+
428+ # macsec_probe: byte-level SecY cross-check tool used by the kernel-macsec
429+ # interop scripts (tools/macsec/run_macsec_static_test.sh).
430+ build/tools/macsec_probe.o : tools/macsec/macsec_probe.c
431+ @mkdir -p build/tools || true
432+ @echo " [CC] $<"
433+ @$(CC ) $(CFLAGS ) $(WOLFSSL_CFLAGS ) -Isrc/supplicant -Isrc/macsec -c $< -o $@
434+
435+ build/macsec-probe : $(SUPPLICANT_OBJ ) build/tools/macsec_probe.o
436+ @echo " [LD] $@ "
437+ @$(CC ) $(CFLAGS ) -o $@ $(BEGIN_GROUP ) $(^ ) $(LDFLAGS ) $(WOLFSSL_LIBS ) $(END_GROUP )
438+
439+ # macsec_sta: AF_PACKET host harness that runs the wolfMKA participant for
440+ # interop against wpa_supplicant (run_macsec_mka_test.sh). Linux only; requires
441+ # WOLFMKA_DIR (the wolfMKA library provides the MKA control plane).
442+ build/tools/macsec_sta.o : tools/macsec/macsec_sta.c
443+ @test -n " $( WOLFMKA_DIR) " || { echo " macsec-sta requires WOLFMKA_DIR=<wolfMKA clone>" ; exit 1; }
444+ @mkdir -p build/tools || true
445+ @echo " [CC] $<"
446+ @$(CC ) $(CFLAGS ) $(WOLFSSL_CFLAGS ) -Isrc/supplicant -Isrc/macsec -I$(WOLFMKA_DIR ) /include -c $< -o $@
447+
448+ build/macsec-sta : $(SUPPLICANT_OBJ ) build/tools/macsec_sta.o
449+ @echo " [LD] $@ "
450+ @$(CC ) $(CFLAGS ) -o $@ $(BEGIN_GROUP ) $(^ ) $(LDFLAGS ) $(WOLFSSL_LIBS ) $(END_GROUP )
451+
452+ # libFuzzer harness for the network-facing SecY receive path. Needs clang
453+ # (-fsanitize=fuzzer); the macsec sources are compiled straight into the
454+ # harness so the instrumentation is consistent. Not built by default. Requires
455+ # a CMAC-enabled wolfSSL (WOLFSSL_CFLAGS/LIBS).
456+ FUZZ_CC ?= clang
457+ FUZZ_FLAGS ?= -fsanitize=fuzzer,address,undefined -fno-sanitize-recover=all -g -O1
458+ FUZZ_MACSEC_SRC := src/macsec/macsec_crypto.c src/macsec/macsec_secy.c \
459+ src/macsec/macsec_sa.c src/supplicant/wpa_crypto.c
460+
461+ build/fuzz-macsec-secy : src/macsec/fuzz_macsec_secy.c $(FUZZ_MACSEC_SRC )
462+ @mkdir -p build || true
463+ @echo " [FUZZ] $@ "
464+ @$(FUZZ_CC ) $(FUZZ_FLAGS ) $(WOLFSSL_CFLAGS ) -Isrc/supplicant -Isrc/macsec \
465+ $(^ ) -o $@ $(WOLFSSL_LIBS )
466+
467+ macsec-fuzz : build/fuzz-macsec-secy
468+
371469build/test-supplicant-4way : $(SUPPLICANT_OBJ ) build/supplicant/test_supplicant_4way.o
372470 @echo " [LD] $@ "
373471 @$(CC ) $(CFLAGS ) -o $@ $(BEGIN_GROUP ) $(^ ) $(LDFLAGS ) $(WOLFSSL_LIBS ) $(END_GROUP )
@@ -535,10 +633,23 @@ endif
535633ifeq ($(WOLFIP_ENABLE_SAE ) ,1)
536634SUPPLICANT_TEST_BINS += build/test-sae-crypto build/test-supplicant-sae
537635endif
636+ ifeq ($(WOLFIP_ENABLE_MACSEC ) ,1)
637+ SUPPLICANT_TEST_BINS += build/test-macsec-crypto build/test-macsec-secy \
638+ build/test-macsec-sa
639+ endif
538640
539641supplicant-tests : $(SUPPLICANT_TEST_BINS )
540642 @for t in $(SUPPLICANT_TEST_BINS ) ; do echo " ==> $$ t" ; $$ t || exit 1; done
541643
644+ # The same in-process unit tests built with AddressSanitizer + UBSan, to catch
645+ # memory / undefined-behaviour bugs in the parsers. Target-specific flags flow
646+ # to the object + link rules of the prerequisite bins. Run from a clean tree
647+ # (sanitizer objects must not be reused by a normal build).
648+ supplicant-tests-sanitize : CFLAGS += -fsanitize=address,undefined \
649+ -fno-sanitize-recover =all -g
650+ supplicant-tests-sanitize : LDFLAGS += -fsanitize=address,undefined
651+ supplicant-tests-sanitize : supplicant-tests
652+
542653# Real-authenticator interop tests. Both require hostapd installed and
543654# root (veth pair + AF_PACKET raw socket). Not part of supplicant-tests
544655# because of those constraints.
0 commit comments