2020-08-31 20:53:58 -05:00
# libwolfssl Linux kernel module Makefile (wraps Kbuild-native makefile)
#
2026-02-18 09:52:21 -07:00
# Copyright (C) 2006-2026 wolfSSL Inc.
2020-08-31 20:53:58 -05:00
#
# This file is part of wolfSSL.
#
# wolfSSL is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
2025-07-10 16:01:52 -06:00
# the Free Software Foundation; either version 3 of the License, or
2020-08-31 20:53:58 -05:00
# (at your option) any later version.
#
# wolfSSL is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
2020-08-28 17:25:25 -05:00
2025-09-17 13:06:32 -05:00
.ONESHELL :
2024-07-16 14:24:37 -05:00
SHELL = bash
2020-08-28 17:25:25 -05:00
2026-02-19 17:42:01 -06:00
ifeq "$(quiet)" "silent_"
QFLAG := --quiet
else ifeq "$(V)" "1"
VFLAG := --verbose
else
QFLAG := --quiet
endif
2026-02-18 23:58:11 -06:00
ifndef LIBWOLFSSL_NAME
LIBWOLFSSL_NAME := libwolfssl
endif
2026-02-28 00:25:06 -06:00
module : $( LIBWOLFSSL_NAME ) .ko
2026-02-18 23:58:11 -06:00
all : $( LIBWOLFSSL_NAME ) .ko $( LIBWOLFSSL_NAME ) .ko .signed
2020-08-18 14:17:44 -05:00
ifndef MODULE_TOP
2020-08-28 17:25:25 -05:00
MODULE_TOP = $( CURDIR)
2020-08-18 14:17:44 -05:00
endif
ifndef SRC_TOP
2020-08-28 17:25:25 -05:00
SRC_TOP = $( shell dirname $( MODULE_TOP))
2020-08-18 14:17:44 -05:00
endif
2021-08-27 23:03:14 -05:00
WOLFSSL_CFLAGS = -DHAVE_CONFIG_H -I$( SRC_TOP) -DBUILDING_WOLFSSL $( AM_CPPFLAGS) $( CPPFLAGS) $( AM_CFLAGS) $( CFLAGS) -Wno-declaration-after-statement -Wno-redundant-decls -DLIBWOLFSSL_GLOBAL_EXTRA_CFLAGS= "\" $( KERNEL_EXTRA_CFLAGS) \""
2020-09-01 14:39:30 -05:00
ifdef KERNEL_EXTRA_CFLAGS
WOLFSSL_CFLAGS += $( KERNEL_EXTRA_CFLAGS)
2020-08-22 00:32:32 -05:00
endif
2025-10-08 13:15:22 -05:00
ifeq "$(FIPS_OPTEST)" "1"
WOLFSSL_CFLAGS += -DFIPS_OPTEST
endif
2020-08-22 00:32:32 -05:00
2020-08-18 14:17:44 -05:00
WOLFSSL_ASFLAGS = -DHAVE_CONFIG_H -I$( SRC_TOP) -DBUILDING_WOLFSSL $( AM_CCASFLAGS) $( CCASFLAGS)
2020-08-18 23:51:32 -05:00
2020-08-28 10:32:30 -05:00
WOLFSSL_OBJ_FILES = $( patsubst %.lo, %.o, $( patsubst src/src_libwolfssl_la-%, src/%, $( patsubst src/libwolfssl_la-%, src/%, $( patsubst wolfcrypt/src/src_libwolfssl_la-%, wolfcrypt/src/%, $( src_libwolfssl_la_OBJECTS)))))
2020-08-18 14:17:44 -05:00
2020-08-21 00:10:45 -05:00
ifeq "$(ENABLED_CRYPT_TESTS)" "yes"
2020-08-28 17:25:25 -05:00
WOLFSSL_OBJ_FILES += wolfcrypt/test/test.o
2025-04-01 01:17:10 -05:00
else ifneq "$(ENABLED_LINUXKM_LKCAPI_REGISTER)" "none"
WOLFSSL_OBJ_FILES += wolfcrypt/test/test.o
2020-08-21 00:10:45 -05:00
else
2020-08-28 17:25:25 -05:00
WOLFSSL_CFLAGS += -DNO_CRYPT_TEST
2020-08-21 00:10:45 -05:00
endif
2025-11-18 01:28:08 -06:00
ifeq "$(ENABLED_KERNEL_BENCHMARKS)" "yes"
2024-02-16 02:32:18 -06:00
WOLFSSL_OBJ_FILES += wolfcrypt/benchmark/benchmark.o
endif
2021-08-19 11:15:52 -05:00
ifeq "$(ENABLED_LINUXKM_PIE)" "yes"
2025-10-31 16:03:51 -05:00
WOLFCRYPT_PIE_FILES := \
$( filter wolfcrypt/src/%,$( WOLFSSL_OBJ_FILES)) \
linuxkm/pie_redirect_table.o \
linuxkm/wc_linuxkm_pie_reloc_tab.o
2021-08-19 11:15:52 -05:00
WOLFSSL_OBJ_FILES := $( WOLFCRYPT_PIE_FILES) $( filter-out $( WOLFCRYPT_PIE_FILES) ,$( WOLFSSL_OBJ_FILES))
endif
export WOLFSSL_CFLAGS WOLFSSL_ASFLAGS WOLFSSL_OBJ_FILES WOLFCRYPT_PIE_FILES
2020-08-18 14:17:44 -05:00
2024-07-16 14:24:37 -05:00
ifneq "$(host_triplet)" "$(build_triplet)"
CROSS_COMPILE := 'CROSS_COMPILE=$(host_triplet)-'
endif
OVERRIDE_PATHS :=
ifdef CC
ifneq "$(CC)" "cc"
2025-11-14 19:24:53 -06:00
OVERRIDE_PATHS := $( OVERRIDE_PATHS) 'CC=$(CC)'
2024-07-16 14:24:37 -05:00
endif
endif
ifdef AS
ifneq "$(AS)" "as"
2025-11-14 19:24:53 -06:00
OVERRIDE_PATHS := $( OVERRIDE_PATHS) 'AS=$(AS)'
2024-07-16 14:24:37 -05:00
endif
endif
ifdef LD
ifneq "$(LD)" "ld"
2025-11-14 19:24:53 -06:00
OVERRIDE_PATHS := $( OVERRIDE_PATHS) 'LD=$(LD)'
2024-07-16 14:24:37 -05:00
endif
endif
2025-08-22 00:34:01 -05:00
ifndef READELF
READELF := readelf
endif
ifndef AWK
AWK := awk
endif
2025-09-16 14:38:51 -05:00
ifndef TMPDIR
TMPDIR := /tmp
endif
ifndef MAKE_TMPDIR
MAKE_TMPDIR := $( TMPDIR)
endif
2025-11-14 19:24:53 -06:00
GENERATE_SECTION_MAP := $( AWK) ' BEGIN { printf( "" ) >ENVIRON[ "SECTION_MAP" ] ; } \
2025-12-09 17:03:16 -06:00
/^Section Headers:/ { \
in_sections = 1; \
in_symbols = 0; \
next; \
} \
/^Symbol table / { \
if ( ! in_sections) { \
print "symbol table appeared before section headers." >"/dev/stderr" ; \
exit( 1) ; \
2025-11-14 19:24:53 -06:00
} \
2025-12-09 17:03:16 -06:00
in_sections = 0; \
in_symbols = 1; \
next; \
} \
{ \
if ( in_sections) { \
if ( match( $$ 0, \
"^[[:space:]]*\\[[[:space:]]*([0-9]+)[[:space:]]*\\][[:space:]]+([^[:space:]]+)[[:space:]]" ,\
section_line_a)) { \
sections[ section_line_a[ 1]] = section_line_a[ 2] ; \
2025-11-14 19:24:53 -06:00
next; \
2025-12-09 17:03:16 -06:00
} \
} \
if ( in_symbols) { \
if ( $$ 7 !~ "^[0-9]+ $$ " ) \
next; \
if (( $$4 == "NOTYPE" ) || ( $$4 == "OBJECT" ) || ( $$4 == "FUNC" )) { \
if (( $$8 == " $$ d" ) || ( $$8 == " $$ t" )) \
next; \
if ( $$ 7 in sections) { \
if ( sections[ $$ 7] ~ "_wolfcrypt $$ " ) \
print $$ 8 "\t" sections[ $$ 7] >>ENVIRON[ "SECTION_MAP" ] ; \
} else \
print $$ 8 " is in section " $$ 7 " with no name mapping." >"/dev/stderr" ; \
} \
2025-11-14 19:24:53 -06:00
} \
} '
GENERATE_RELOC_TAB := $( AWK) ' \
2026-04-28 12:57:27 -05:00
function open_seg(seg) { \
seen_seg[seg] = 1; \
printf("%s\n ", \
"WOLFSSL_LOCAL const struct wc_reloc_table_ent wc_linuxkm_pie_" seg "_reloc_tab[] = { "); \
cur_seg = seg; \
} \
function close_cur_seg() { \
print " { .offset = ~0U, .dest_offset = ~0U, .dest_addend = 0, .dest_segment = WC_R_SEG_NONE, .reloc_type = WC_R_NONE } };"; \
print "WOLFSSL_LOCAL const unsigned int wc_linuxkm_pie_" cur_seg "_reloc_tab_length = (unsigned int)(sizeof wc_linuxkm_pie_" cur_seg "_reloc_tab / sizeof wc_linuxkm_pie_" cur_seg "_reloc_tab[0]);"; \
cur_seg = ""; \
} \
BEGIN { \
2025-08-23 17:21:24 -05:00
bad_relocs=0; \
2025-10-31 16:03:51 -05:00
print "\#include <wolfssl/wolfcrypt/libwolfssl_sources.h>"; \
2026-02-18 23:58:11 -06:00
print "\#include <wolfssl/wolfcrypt/memory.h>"; \
2026-04-28 12:57:27 -05:00
print ""; \
2025-11-14 19:24:53 -06:00
if ("SECTION_MAP" in ENVIRON) { \
while (getline <ENVIRON["SECTION_MAP"] > 0) \
section_map[$$1] = $$2; \
close(ENVIRON["SECTION_MAP"]); \
} \
2025-08-22 00:34:01 -05:00
} \
2026-04-28 12:57:27 -05:00
\
2025-08-22 00:34:01 -05:00
/^Relocation section/ { \
2026-04-28 12:57:27 -05:00
if (cur_seg) { \
close_cur_seg(); \
} \
{ \
if (match($$0, "^Relocation section ' \' '\\.rela?\\.(text|rodata)_wolfcrypt' \' ' ", a)) {\
open_seg(a[1]); \
next; \
} \
} \
} \
\
{ \
if (! cur_seg) \
next; \
2025-08-22 00:34:01 -05:00
} \
/^0/ { \
2026-04-28 12:57:27 -05:00
if ( $$ 3 !~ " ^( R_X86_.*| R_AARCH64_.*| R_ARM.*) $$ ") { \
print " Unexpected relocation type in " cur_seg " :\n " $$ 0 >" /dev/stderr"; \
2025-11-14 19:24:53 -06:00
++bad_relocs; \
} \
if ( $$ 5 in section_map) \
section = section_map[ $$ 5]; \
else if ( $$ 5 ~ " ^\\ .") \
section = $$ 5; \
else \
section = ""; \
if (section) { \
switch (section) { \
case " .text_wolfcrypt": \
2026-01-30 17:34:02 -06:00
section_tag = " WC_R_SEG_TEXT"; \
2025-11-14 19:24:53 -06:00
break; \
case " .rodata_wolfcrypt": \
2026-01-30 17:34:02 -06:00
section_tag = " WC_R_SEG_RODATA"; \
2025-11-14 19:24:53 -06:00
break; \
case " .data_wolfcrypt": \
2026-01-30 17:34:02 -06:00
section_tag = " WC_R_SEG_RWDATA"; \
2025-11-14 19:24:53 -06:00
break; \
case " .bss_wolfcrypt": \
2026-01-30 17:34:02 -06:00
section_tag = " WC_R_SEG_BSS"; \
2025-11-14 19:24:53 -06:00
break; \
default: \
print " Unexpected section:\n " $$ 0 >" /dev/stderr"; \
++bad_relocs; \
2026-01-30 17:34:02 -06:00
section_tag = " WC_R_SEG_OTHER"; \
2025-11-14 19:24:53 -06:00
} \
} else { \
print " Unresolvable symbol reference for relocation:\n " $$ 0 >" /dev/stderr";\
++bad_relocs; \
2026-01-30 17:34:02 -06:00
section_tag = " WC_R_SEG_OTHER"; \
2025-11-14 19:24:53 -06:00
} \
2026-01-30 17:34:02 -06:00
reloc_type = $$ 3; \
2025-11-14 19:24:53 -06:00
if (strtonum(" 0x" gensub(" ^0*","",1, $$ 1)) >= lshift(1, 29)) { \
print " Relocation offset overflow:" >" /dev/stderr"; \
print >" /dev/stderr"; \
exit(1); \
} \
2026-02-18 23:58:11 -06:00
printf(" { .offset = 0x%xU, .dest_offset = 0x%xU, .dest_addend = %+d, .dest_segment = %s, .reloc_type = WC_%s } ,\n ", \
strtonum(" 0x" $$ 1), \
strtonum(" 0x" $$ 4), \
$$ 6 strtonum(" 0x" $$ 7), \
2026-01-30 17:34:02 -06:00
section_tag, reloc_type); \
2025-08-22 00:34:01 -05:00
} \
END { \
2026-04-28 12:57:27 -05:00
if (cur_seg) { \
close_cur_seg(); \
} \
n = split(" text rodata", segs, " "); \
for (i = 1; i <= n; ++i) { \
if (! (segs[i] in seen_seg)) { \
open_seg(segs[i]); \
close_cur_seg(); \
} \
} \
2025-08-23 17:21:24 -05:00
if (bad_relocs) { \
2025-11-14 19:24:53 -06:00
print " Found " bad_relocs " unresolvable relocations." >" /dev/stderr"; \
exit(1); \
2025-08-23 17:21:24 -05:00
} \
2025-09-16 14:38:51 -05:00
} '
2025-10-08 13:15:22 -05:00
ifeq "$(V)" "1"
vflag := --verbose
endif
2025-11-14 19:24:53 -06:00
# This rule is .PHONY because it doesn't actually build the module -- Kbuild
# does, and we always need to call Kbuild to enforce rebuild for dependencies
# and config changes.
2026-02-18 23:58:11 -06:00
.PHONY : $( LIBWOLFSSL_NAME ) .ko
$(LIBWOLFSSL_NAME).ko :
2025-11-14 19:24:53 -06:00
@set -e
2025-11-19 17:20:14 -06:00
@[[ '$(V)' == 1 ]] && { echo 'MODULE_TOP = "$(MODULE_TOP)"' ;
echo 'SRC_TOP = "$(SRC_TOP)"' ;
echo 'AM_CPPFLAGS = "$(AM_CPPFLAGS)"' ;
echo 'CPPFLAGS = "$(CPPFLAGS)"' ;
echo 'AM_CFLAGS = "$(AM_CFLAGS)"' ;
echo 'CFLAGS = "$(CFLAGS)"' ;
2026-02-28 00:25:06 -06:00
echo 'HOSTCFLAGS = "$(HOSTCFLAGS)"' ;
2025-11-19 17:20:14 -06:00
echo 'KERNEL_EXTRA_CFLAGS = "$(KERNEL_EXTRA_CFLAGS)"' ;
echo 'FIPS_OPTEST = "$(FIPS_OPTEST)"' ;
echo 'AM_CCASFLAGS = "$(AM_CCASFLAGS)"' ;
echo 'CCASFLAGS = "$(CCASFLAGS)"' ;
echo 'src_libwolfssl_la_OBJECTS = "$(src_libwolfssl_la_OBJECTS)"' ;
echo 'ENABLED_CRYPT_TESTS = "$(ENABLED_CRYPT_TESTS)"' ;
echo 'ENABLED_LINUXKM_LKCAPI_REGISTER = "$(ENABLED_LINUXKM_LKCAPI_REGISTER)"' ;
echo 'ENABLED_LINUXKM_BENCHMARKS = "$(ENABLED_LINUXKM_BENCHMARKS)"' ;
echo 'ENABLED_LINUXKM_PIE = "$(ENABLED_LINUXKM_PIE)"' ;
echo 'host_triplet = "$(host_triplet)"' ;
echo 'build_triplet = "$(build_triplet)"' ;
echo 'CC = "$(CC)"' ;
2026-02-28 00:25:06 -06:00
echo 'HOSTCC = "$(HOSTCC)"' ;
2025-11-19 17:20:14 -06:00
echo 'AS = "$(AS)"' ;
echo 'LD = "$(LD)"' ;
echo 'READELF = "$(READELF)"' ;
echo 'AWK = "$(AWK)"' ;
echo 'TMPDIR = "$(TMPDIR)"' ;
echo 'MAKE_TMPDIR = "$(MAKE_TMPDIR)"' ;
echo 'KERNEL_ROOT = "$(KERNEL_ROOT)"' ;
echo 'obj = "$(obj)"' ;
echo 'RM = "$(RM)"' ;
echo 'KERNEL_ARCH = "$(KERNEL_ARCH)"' ;
echo 'FIPS_HASH = "$(FIPS_HASH)"' ;
echo 'MAKE = "$(MAKE)"' ;
echo 'ENABLED_ASM = "$(ENABLED_ASM)"' ;
echo 'CFLAGS_FPU_DISABLE = "$(CFLAGS_FPU_DISABLE)"' ;
echo 'CFLAGS_FPU_ENABLE = "$(CFLAGS_FPU_ENABLE)"' ;
echo 'CFLAGS_SIMD_DISABLE = "$(CFLAGS_SIMD_DISABLE)"' ;
echo 'CFLAGS_SIMD_ENABLE = "$(CFLAGS_SIMD_ENABLE)"' ;
echo 'CFLAGS_AUTO_VECTORIZE_DISABLE = "$(CFLAGS_AUTO_VECTORIZE_DISABLE)"' ;
echo 'CFLAGS_AUTO_VECTORIZE_ENABLE = "$(CFLAGS_AUTO_VECTORIZE_ENABLE)"' ;
echo 'ASFLAGS_FPU_DISABLE_SIMD_ENABLE = "$(ASFLAGS_FPU_DISABLE_SIMD_ENABLE)"' ;
echo 'ASFLAGS_FPU_ENABLE_SIMD_DISABLE = "$(ASFLAGS_FPU_ENABLE_SIMD_DISABLE)"' ;
echo 'ASFLAGS_FPUSIMD_DISABLE = "$(ASFLAGS_FPUSIMD_DISABLE)"' ;
echo 'ASFLAGS_FPUSIMD_ENABLE = "$(ASFLAGS_FPUSIMD_ENABLE)"' ; }
2025-11-14 19:24:53 -06:00
@function resolved_link_is_equal() { [[ -L " $$ 1" && " $$ (readlink -f " $$ 1")" == " $$ (readlink -f " $$ 2")" ]] ; }
2025-09-16 14:38:51 -05:00
@if test -z '$(KERNEL_ROOT)' ; then echo '$$KERNEL_ROOT is unset' >& 2; exit 1; fi
@if test -z '$(AM_CFLAGS)$(CFLAGS)' ; then echo '$$AM_CFLAGS and $$CFLAGS are both unset.' >& 2; exit 1; fi
@if test -z '$(src_libwolfssl_la_OBJECTS)' ; then echo '$$src_libwolfssl_la_OBJECTS is unset.' >& 2; exit 1; fi
2025-11-14 19:24:53 -06:00
# after commit 9a0ebe5011 (6.10), sources must be in $(obj). work around this by making links to all needed sources:
2025-09-16 14:38:51 -05:00
@mkdir -p '$(MODULE_TOP)/linuxkm'
2025-10-31 16:03:51 -05:00
@resolved_link_is_equal '$(MODULE_TOP)/linuxkm/module_hooks.c' '$(MODULE_TOP)/module_hooks.c' || cp $( vflag) --no-dereference --symbolic-link --no-clobber '$(MODULE_TOP)' /*.[ ch] '$(MODULE_TOP)/linuxkm/'
@resolved_link_is_equal '$(MODULE_TOP)/wolfcrypt/src/wc_port.c' '$(SRC_TOP)/wolfcrypt/src/wc_port.c' || cp $( vflag) --no-dereference --symbolic-link --no-clobber --recursive '$(SRC_TOP)/wolfcrypt' '$(MODULE_TOP)/'
@resolved_link_is_equal '$(MODULE_TOP)/src/wolfio.c' '$(SRC_TOP)/src/wolfio.c' || cp $( vflag) --no-dereference --symbolic-link --no-clobber --recursive '$(SRC_TOP)/src' '$(MODULE_TOP)/'
2025-10-08 13:15:22 -05:00
ifeq "$(FIPS_OPTEST)" "1"
2025-11-14 19:24:53 -06:00
@resolved_link_is_equal '$(MODULE_TOP)/linuxkm/optest-140-3/linuxkm_optest_wrapper.c' '$(SRC_TOP)/../fips/optest-140-3/linuxkm_optest_wrapper.c' || cp $( vflag ) --no-dereference --symbolic-link --no-clobber --recursive '$(SRC_TOP)/../fips/optest-140-3' '$(MODULE_TOP)/linuxkm/'
2025-10-08 13:15:22 -05:00
endif
2025-09-16 14:38:51 -05:00
ifeq "$(ENABLED_LINUXKM_PIE)" "yes"
2025-11-03 12:00:40 -06:00
@[[ -f '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c' && ! -L '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c' ]] || \
2025-10-31 16:03:51 -05:00
{ $( RM ) -f '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c' && $( GENERATE_RELOC_TAB ) < /dev/null > '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c' ; }
2025-11-14 19:24:53 -06:00
@ RELOC_TMP = $$ ( mktemp " $( MAKE_TMPDIR) /wc_linuxkm_pie_reloc_tab.c.XXXXXX" )
@trap 'rm "$$RELOC_TMP"' EXIT
@if [[ -f " $@ " ]] ; then touch -r " $@ " " $$ RELOC_TMP" ; fi
2026-02-28 00:25:06 -06:00
# --no-silent works around make bug that otherwise leads to "No rule to make target 's'. Stop." (due to a bug around $(MAKEFLAGS)) in --quiet builds.
+$( MAKE) $( QFLAG) --no-print-directory --no-silent ARCH = '$(KERNEL_ARCH)' $( OVERRIDE_PATHS) $( CROSS_COMPILE) -C '$(KERNEL_ROOT)' M = '$(MODULE_TOP)' $( KBUILD_EXTRA_FLAGS) CC_FLAGS_FTRACE =
2025-09-17 13:06:32 -05:00
# if the above make didn't build a fresh libwolfssl.ko, then the module is already up to date and we leave it untouched, assuring stability for purposes of module-update-fips-hash.
2025-11-14 19:24:53 -06:00
@if [[ ! " $@ " -nt " $$ RELOC_TMP" ]] ; then echo ' Module already up-to-date.' ; exit 0; fi
@SECTION_MAP= $$ ( mktemp)
2025-12-29 20:33:34 -06:00
@trap 'rm "$$RELOC_TMP" "$$SECTION_MAP"' EXIT
2025-11-14 19:24:53 -06:00
@export SECTION_MAP
2025-12-09 17:03:16 -06:00
@$( READELF) --wide --sections --symbols " $@ " | $( GENERATE_SECTION_MAP)
2025-11-14 19:24:53 -06:00
@$( READELF) --wide --relocs " $@ " | $( GENERATE_RELOC_TAB) >| '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c'
2026-02-28 00:25:06 -06:00
+$( MAKE) $( QFLAG) --no-print-directory --no-silent ARCH = '$(KERNEL_ARCH)' $( OVERRIDE_PATHS) $( CROSS_COMPILE) -C '$(KERNEL_ROOT)' M = '$(MODULE_TOP)' $( KBUILD_EXTRA_FLAGS) CC_FLAGS_FTRACE =
2025-11-14 19:24:53 -06:00
@$( READELF) --wide --relocs " $@ " | $( GENERATE_RELOC_TAB) >| " $$ RELOC_TMP"
@if diff '$(MODULE_TOP)/linuxkm/wc_linuxkm_pie_reloc_tab.c' " $$ RELOC_TMP" ; then echo " Relocation table is stable." ; else echo "PIE failed: relocation table is unstable." 1>& 2; exit 1; fi
2021-09-15 23:05:32 -05:00
else
2026-02-28 00:25:06 -06:00
# --no-silent works around make bug that otherwise leads to "No rule to make target 's'. Stop." (due to a bug around $(MAKEFLAGS)) in --quiet builds.
+$( MAKE) $( QFLAG) --no-print-directory --no-silent ARCH = '$(KERNEL_ARCH)' $( OVERRIDE_PATHS) $( CROSS_COMPILE) -C '$(KERNEL_ROOT)' M = '$(MODULE_TOP)' $( KBUILD_EXTRA_FLAGS)
2021-09-15 23:05:32 -05:00
endif
2026-02-28 00:25:06 -06:00
$(MODULE_TOP)/$(LIBWOLFSSL_NAME).ko : $( LIBWOLFSSL_NAME ) .ko
2025-09-16 14:38:51 -05:00
.PHONY : module -update -fips -hash
2026-02-18 23:58:11 -06:00
module-update-fips-hash : $( LIBWOLFSSL_NAME ) .ko
2025-11-14 19:24:53 -06:00
@set -e
@if test -z '$(FIPS_HASH)' ; then echo ' $$FIPS_HASH is unset' >& 2; exit 1; fi
2025-09-16 14:38:51 -05:00
@if [[ ! '$(FIPS_HASH)' = ~ [ 0-9a-fA-F]{ 64} ]] ; then echo ' $$FIPS_HASH is malformed' >& 2; exit 1; fi
2025-11-14 19:24:53 -06:00
@readarray -t rodata_segment < <( $( READELF) --wide --sections " $<" | \
2025-10-18 03:23:38 -05:00
sed -E -n 's/^[[:space:]]*\[[[:space:]]*([0-9]+)\][[:space:]]+\.rodata_wolfcrypt[[:space:]]+PROGBITS[[:space:]]+[0-9a-fA-F]+[[:space:]]+([0-9a-fA-F]+)[[:space:]].*$$/\1\n\2/p' ) ; \
2025-09-16 14:38:51 -05:00
if [[ $$ { #rodata_segment[@]} != 2 ]]; then echo ' unexpected rodata_segment.' >&2; exit 1; fi; \
2025-11-14 19:24:53 -06:00
readarray -t verifyCore_attrs < <( $( READELF) --wide --symbols " $<" | \
2025-09-16 14:38:51 -05:00
sed -E -n 's/^[[:space:]]*[0-9]+: ([0-9a-fA-F]+)[[:space:]]+([0-9]+)[[:space:]]+OBJECT[[:space:]]+[A-Z]+[[:space:]]+[A-Z]+[[:space:]]+' " $$ {rodata_segment[0]}" '[[:space:]]+verifyCore$$/\1\n\2/p' ) ; \
if [[ $$ { #verifyCore_attrs[@]} != 2 ]]; then echo ' unexpected verifyCore_attrs.' >&2; exit 1; fi; \
2025-11-14 19:24:53 -06:00
if [[ " $$ {verifyCore_attrs[1]}" != "65" ]] ; then echo " verifyCore has unexpected length $$ {verifyCore_attrs[1]}." >& 2; exit 1; fi ; \
2025-09-16 14:38:51 -05:00
verifyCore_offset = $$ (( 0x$$ { rodata_segment[ 1]} + 0x$$ { verifyCore_attrs[ 0]})) ; \
2025-11-14 19:24:53 -06:00
current_verifyCore = $$ ( dd bs = 1 if = " $<" skip = $$ verifyCore_offset count = 64 status = none) ; \
2025-09-16 14:38:51 -05:00
if [[ ! " $$ current_verifyCore" = ~ [ 0-9a-fA-F]{ 64} ]] ; then echo " verifyCore at offset $$ verifyCore_offset has unexpected value." >& 2; exit 1; fi ; \
2025-11-14 19:24:53 -06:00
if [[ '$(FIPS_HASH)' == " $$ current_verifyCore" ]] ; then echo ' Supplied FIPS_HASH matches existing verifyCore -- no update needed.' ; exit 0; fi ; \
echo -n '$(FIPS_HASH)' | dd bs = 1 conv = notrunc of = " $<" seek = $$ verifyCore_offset count = 64 status = none && \
echo " FIPS verifyCore updated successfully." && \
2026-02-28 00:25:06 -06:00
if [[ -f '$(LIBWOLFSSL_NAME).ko.signed' ]] ; then $( MAKE) $( QFLAG) --no-print-directory --no-silent -C . '$(LIBWOLFSSL_NAME).ko.signed' ; fi
2025-09-16 14:38:51 -05:00
2026-02-18 23:58:11 -06:00
# linuxkm-fips-hash implements offline (no-load) FIPS hash calculation and graft-in.
#
# libwolfssl.so is built from the same sources as the kernel module, with the
# same FIPS setting, then used with linuxkm-fips-hash to calculate and overwrite
# the hash in libwolfssl.ko. Finally, the module is [re]signed.
#
# Note that libwolfssl.so has to be built from a hierarchy of symlinks, to avoid
# depending on changes/config in the source directory. Also, aside from
# FIPS_FLAVOR, inherited configuration settings in the environment are cleansed.
2026-02-28 00:25:06 -06:00
FRESH_MAKEFLAGS := $( patsubst -j%,-j %,$( filter -%,$( filter-out -- --jobserver-auth= %,$( MAKEFLAGS))))
FRESH_ENV := env -i HOME = " $$ HOME" PATH = "/usr/local/bin:/usr/bin:/bin: $$ PATH" LANG = " $$ {LANG-C.UTF-8}" LC_ALL = " $$ {LC_ALL-C.UTF-8}" TERM = " $$ {TERM-dumb}"
2026-02-18 23:58:11 -06:00
2026-02-28 00:25:06 -06:00
.PHONY : $( MODULE_TOP ) /libwolfssl -user -build /src /.libs /libwolfssl .so
$(MODULE_TOP)/libwolfssl-user-build/src/.libs/libwolfssl.so : $( LIBWOLFSSL_NAME ) .ko
@set -o errexit -o pipefail
@if [[ '$(SRC_TOP)/configure' -nt '$@' ]] ; then
@ echo 'Purging stale libwolfssl-user-build tree.'
@ $( RM) -rf '$(MODULE_TOP)/libwolfssl-user-build'
@fi
@mkdir -p '$(MODULE_TOP)/libwolfssl-user-build'
@cd '$(MODULE_TOP)/libwolfssl-user-build'
@if [[ ! -e '$(MODULE_TOP)/libwolfssl-user-build/configure' ]] ; then
@ pushd '$(SRC_TOP)' >/dev/null
@ echo -n 'Populating tree of symlinks for user libwolfssl.so build...'
@ readarray -t srcfiles < <( find examples src support tests testsuite wolfcrypt wolfssl configure *.in build-aux debian rpm scripts certs doc mcapi cmake linuxkm/*.[ ch] \( -name options.h -o -name user_settings\* \) -prune -o \( ! -type d \) \( -name '*.[chsSi]' -o -name configure -o -name '*.in' -o -name \* .sh -o -path support/\* -o -path build-aux/\* -o -path debian/\* -o -path rpm/\* -o -path scripts/\* -o -path certs/\* -o -path doc/\* -o -path mcapi/\* -o -path cmake/\* \) -print)
@ popd >/dev/null
@ for file in " $$ {srcfiles[@]}" ; do if [[ ! -e " $$ file" ]] ; then mkdir -p " $$ (dirname " $$ file")" && cp --no-dereference --symbolic-link --no-clobber '$(SRC_TOP)' /" $$ file" " $$ file" ; fi ; done
@ echo ' done.'
@fi
@if [[ ! -f user_settings.h ]] ; then
@ echo '__attribute__ ((visibility("default"))) extern const char coreKey[];' > user_settings.h
@ echo > user_settings_asm.h
@fi
@if [[ -f Makefile ]] ; then
@ echo 'Using existing Makefile for libwolfssl.so.'
@else
@ echo -n 'Configuring user libwolfssl.so...'
2026-04-28 12:57:27 -05:00
@ $( FRESH_ENV) ./configure $( QFLAG) $( VFLAG) --disable-jobserver --enable-cryptonly --enable-fips= " $$ FIPS_FLAVOR" CFLAGS = '-DWC_SYM_RELOC_TABLES_SUPPORT -DWOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE -DWOLFSSL_USER_SETTINGS -DWOLFSSL_USER_SETTINGS_ASM -DDEBUG_LINUXKM_PIE_SUPPORT' $(if $( HOSTCC) ,CC= '$(HOSTCC)' )
2026-02-28 00:25:06 -06:00
@ echo ' done.'
@fi
@echo -n 'Building user libwolfssl.so...'
@$( FRESH_ENV) $( MAKE) $( QFLAG) $( FRESH_MAKEFLAGS) >/dev/null
@echo ' done.'
@echo -n 'Fixing FIPS hash in user libwolfssl.so...'
@if ! userhash = $$ ( wolfcrypt/test/testwolfcrypt 2>& 1 | sed -n -E 's/^hash = (.+)$$/\1/p' ) ; then
@ if [[ -z " $$ userhash" ]] ; then echo ' FIPS hash not found!' >& 2; exit 1; fi
@ find wolfcrypt/src -name '*fips_test*o' -delete
@ $( FRESH_ENV) $( MAKE) $( QFLAG) $( FRESH_MAKEFLAGS) EXTRA_CFLAGS = -DWOLFCRYPT_FIPS_CORE_HASH_VALUE= " $$ userhash" >/dev/null
@ echo ' done.'
@else
@ @echo ' already matches (no update needed).'
@fi
linuxkm-fips-hash : $( MODULE_TOP ) /libwolfssl -user -build /src /.libs /libwolfssl .so linuxkm -fips -hash .c
2026-02-19 17:42:01 -06:00
@set -e
2026-02-18 23:58:11 -06:00
@echo -n 'Compiling linuxkm-fips-hash...'
2026-02-28 00:25:06 -06:00
@$( or $( HOSTCC) ,cc) $( or $( HOSTCFLAGS) ,-Wall -Wextra -O2) -I'$(MODULE_TOP)/libwolfssl-user-build' -o linuxkm-fips-hash linuxkm/linuxkm-fips-hash.c -L '$(MODULE_TOP)/libwolfssl-user-build/src/.libs' -Wl,-rpath-link= '$(MODULE_TOP)/libwolfssl-user-build/src/.libs' -Wl,-rpath= '$(MODULE_TOP)/libwolfssl-user-build/src/.libs' -lwolfssl
2026-02-18 23:58:11 -06:00
@echo ' done.'
.PHONY : module -with -matching -fips -hash
module-with-matching-fips-hash : $( LIBWOLFSSL_NAME ) .ko linuxkm -fips -hash
@set -e
2026-02-19 17:42:01 -06:00
@./linuxkm-fips-hash-wrapper.sh " $<" $( QFLAG) $( VFLAG)
2026-02-28 00:25:06 -06:00
+$( MAKE) $( QFLAG) --no-print-directory --no-silent -C . '$(LIBWOLFSSL_NAME).ko.signed'
2026-02-18 23:58:11 -06:00
.PHONY : module -with -matching -fips -hash -no -sign
module-with-matching-fips-hash-no-sign : $( LIBWOLFSSL_NAME ) .ko linuxkm -fips -hash
@set -e
2026-02-19 17:42:01 -06:00
@./linuxkm-fips-hash-wrapper.sh " $<"
2026-02-18 23:58:11 -06:00
$(LIBWOLFSSL_NAME).ko.signed : $( LIBWOLFSSL_NAME ) .ko
2025-07-23 14:43:33 -05:00
ifdef FORCE_NO_MODULE_SIG
@echo 'Skipping module signature operation because FORCE_NO_MODULE_SIG.'
else
2025-11-14 19:24:53 -06:00
@set -e
@cd '$(KERNEL_ROOT)'
while read configline; do
case "$$configline" in
CONFIG_MODULE_SIG*=*)
declare "$${configline%=*}" = "$${configline#*=}"
;;
esac
done < .config
2026-02-28 00:25:06 -06:00
if [[ "$${CONFIG_MODULE_SIG}" != "y" ]]; then
echo ' [skipping $@ -- CONFIG_MODULE_SIG is unset in target kernel]'
elif [[ -n "$${CONFIG_MODULE_SIG_KEY}" && \
2025-11-14 19:24:53 -06:00
-n "$${CONFIG_MODULE_SIG_HASH}" && ( ! -f '$(MODULE_TOP)/$@' || \
'$(MODULE_TOP)/$<' -nt '$(MODULE_TOP)/$@' ) ]]; then
CONFIG_MODULE_SIG_KEY = " $$ {CONFIG_MODULE_SIG_KEY#\"}"
CONFIG_MODULE_SIG_KEY = " $$ {CONFIG_MODULE_SIG_KEY%\"}"
CONFIG_MODULE_SIG_HASH = " $$ {CONFIG_MODULE_SIG_HASH#\"}"
CONFIG_MODULE_SIG_HASH = " $$ {CONFIG_MODULE_SIG_HASH%\"}"
cp -p '$(MODULE_TOP)/$<' '$(MODULE_TOP)/$@' || exit $$ ?
./scripts/sign-file " $$ {CONFIG_MODULE_SIG_HASH}" \
" $$ {CONFIG_MODULE_SIG_KEY}" \
" $$ {CONFIG_MODULE_SIG_KEY/%.pem/.x509}" \
'$(MODULE_TOP)/$@'
sign_file_exitval = $$ ?
if [[ $$ sign_file_exitval != 0 ]] ; then
$( RM) -f '$(MODULE_TOP)/$@'
exit $$ sign_file_exitval
fi
if [[ " $( quiet) " != "silent_" ]] ; then
echo " Module $@ signed by $$ {CONFIG_MODULE_SIG_KEY}."
fi
2026-02-28 00:25:06 -06:00
elif [[ ! -f '$(MODULE_TOP)/$@' || '$(MODULE_TOP)/$<' -nt '$(MODULE_TOP)/$@' ]] ; then
echo 'Unable to generate $@ from $<: CONFIG_MODULE_SIG_KEY and/or CONFIG_MODULE_SIG_HASH is missing.' >& 2
exit 1
2021-09-15 23:05:32 -05:00
fi
2025-07-23 14:43:33 -05:00
endif
2021-09-15 23:05:32 -05:00
2020-08-28 17:25:25 -05:00
2020-11-04 14:13:39 -06:00
.PHONY : install modules_install
install modules_install :
2026-02-28 00:25:06 -06:00
+$( MAKE) $( QFLAG) --no-silent -C $( KERNEL_ROOT) M = $( MODULE_TOP) src = $( SRC_TOP) INSTALL_MOD_DIR = wolfssl modules_install
2020-08-18 23:51:32 -05:00
.PHONY : clean
2021-09-30 00:53:58 -05:00
# note, must supply $(MODULE_TOP) as the src value for clean so that Kbuild is included, else
# the top Makefile (which is not for the kernel build) would be included here.
2020-08-18 23:51:32 -05:00
clean :
2026-02-28 00:25:06 -06:00
+$( MAKE) $( QFLAG) --no-silent -C $( KERNEL_ROOT) M = $( MODULE_TOP) src = $( MODULE_TOP) clean
2024-07-16 14:24:37 -05:00
$( RM) -rf '$(MODULE_TOP)/linuxkm'
$( RM) -rf '$(MODULE_TOP)/wolfcrypt'
$( RM) -rf '$(MODULE_TOP)/src'
2026-02-18 23:58:11 -06:00
$( RM) -rf '$(MODULE_TOP)/libwolfssl-user-build'
$( RM) -f '$(MODULE_TOP)/linuxkm-fips-hash'
2020-08-24 17:49:38 -05:00
2021-11-22 05:36:12 +09:00
.PHONY : check
check :
2021-11-22 05:46:13 +09:00
.PHONY : distclean
distclean : clean
2020-08-24 17:49:38 -05:00
.PHONY : dist
dist :
2020-08-24 17:54:46 -05:00
.PHONY : distdir
distdir :