From fa08d900d4ec3bf0c2440b336a75f2b9bda29845 Mon Sep 17 00:00:00 2001 From: Yuan Tao Date: Mon, 14 Sep 2020 17:19:49 +0800 Subject: [PATCH 01/22] base-files: sysfixtime: Fix time on the fake RTC On some devices the chip has RTC but no battery save time. This leads back to getting the wrong time and skipping the check of the last file modification date. This commit ensures that the file time is checked even if the RTC exists. which would ordinarily return an approbiate system time used for e.g. certificate generation. Tested-on: NanoPi R2S Signed-off-by: Yuan Tao --- .../base-files/files/etc/init.d/sysfixtime | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/package/base-files/files/etc/init.d/sysfixtime b/package/base-files/files/etc/init.d/sysfixtime index aab5b153d0..93f792266a 100755 --- a/package/base-files/files/etc/init.d/sysfixtime +++ b/package/base-files/files/etc/init.d/sysfixtime @@ -8,23 +8,33 @@ RTC_DEV=/dev/rtc0 HWCLOCK=/sbin/hwclock boot() { - start && exit 0 - - local maxtime="$(maxtime)" + hwclock_load + local maxtime="$(find_max_time)" local curtime="$(date +%s)" - [ $curtime -lt $maxtime ] && date -s @$maxtime + if [ $curtime -lt $maxtime ]; then + date -s @$maxtime + hwclock_save + fi } start() { - [ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -s -u -f $RTC_DEV + hwclock_load } stop() { + hwclock_save +} + +hwclock_load() { + [ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -s -u -f $RTC_DEV +} + +hwclock_save(){ [ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -w -u -f $RTC_DEV && \ logger -t sysfixtime "saved '$(date)' to $RTC_DEV" } -maxtime() { +find_max_time() { local file newest for file in $( find /etc -type f ) ; do From c77913be5be5f11a0f20dba1b45b96470099e8a8 Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Sun, 19 Feb 2023 09:06:32 +0800 Subject: [PATCH 02/22] ramips: correct the PCIe port number for Zbtlink ZBT-WE1326 MT7621 gets a new PCIe driver in the 5.15+ kernel. Allocating wrong PCIe port will cause the PCIe NIC to not work properly. This commit fixes the wrong port numbers on Zbtlink ZBT-WE1326. According to the bootlog, MT7612E (5 GHz) is connected to pcie1, and MT7603E (2 GHz) is connected to pcie2: [4.197658] mt7621-pci 1e140000.pcie: pcie0 no card, disable it (RST & CLK) [4.204609] mt7621-pci 1e140000.pcie: PCIE1 enabled [4.209476] mt7621-pci 1e140000.pcie: PCIE2 enabled ... [4.307988] pci 0000:01:00.0: [14c3:7662] type 00 class 0x028000 [4.367206] pci 0000:02:00.0: [14c3:7603] type 00 class 0x028000 Signed-off-by: Shiji Yang --- target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts index 4e30dfb6c9..99b9652b7a 100644 --- a/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts +++ b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts @@ -121,7 +121,7 @@ status = "okay"; }; -&pcie0 { +&pcie1 { wifi@0,0 { compatible = "mediatek,mt76"; reg = <0x0000 0 0 0 0>; @@ -135,7 +135,7 @@ }; }; -&pcie1 { +&pcie2 { wifi1: wifi@0,0 { compatible = "mediatek,mt76"; reg = <0x0000 0 0 0 0>; From 68004f194217b7aaeef5d3163d2fb68f359ba6ad Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Sun, 19 Feb 2023 09:06:32 +0800 Subject: [PATCH 03/22] ramips: add alternative device name for Wiflyer WF3526-P Wiflyer WF3526-P and Zbtlink ZBT-WE1326 have the same circuit design. Installing the misunderstading firmware of ZBT-WE3526 will cause Wi-Fi not work due to allocate the wrong pcie port. Add alternative name to help users easily build or download the correct firmware. Signed-off-by: Shiji Yang --- target/linux/ramips/image/mt7621.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index d295f2f8c7..28f6fef681 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -2611,6 +2611,8 @@ define Device/zbtlink_zbt-we1326 IMAGE_SIZE := 16064k DEVICE_VENDOR := Zbtlink DEVICE_MODEL := ZBT-WE1326 + DEVICE_ALT0_VENDOR := Wiflyer + DEVICE_ALT0_MODEL := WF3526-P DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 kmod-sdhci-mt7620 SUPPORTED_DEVICES += zbt-we1326 endef From 3c10c42ddd4741615b896e1d429ac7d6e91a980f Mon Sep 17 00:00:00 2001 From: "Leon M. Busch-George" Date: Wed, 23 Nov 2022 18:22:36 +0100 Subject: [PATCH 04/22] hostapd: add quotes in assignments It's generally advised to use quotes for variable assignments in bash. Signed-off-by: Leon M. Busch-George --- package/network/services/hostapd/files/hostapd.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh index b165995d9f..70ad187a81 100644 --- a/package/network/services/hostapd/files/hostapd.sh +++ b/package/network/services/hostapd/files/hostapd.sh @@ -24,12 +24,12 @@ hostapd_append_wep_key() { [1234]) for idx in 1 2 3 4; do local zidx - zidx=$(($idx - 1)) + zidx="$(($idx - 1))" json_get_var ckey "key${idx}" [ -n "$ckey" ] && \ append $var "wep_key${zidx}=$(prepare_key_wep "$ckey")" "$N$T" done - wep_keyidx=$((key - 1)) + wep_keyidx="$((key - 1))" ;; *) append $var "wep_key0=$(prepare_key_wep "$key")" "$N$T" @@ -787,7 +787,7 @@ hostapd_set_bss_options() { ;; esac - local auth_algs=$((($auth_mode_shared << 1) | $auth_mode_open)) + local auth_algs="$((($auth_mode_shared << 1) | $auth_mode_open))" append bss_conf "auth_algs=${auth_algs:-1}" "$N" append bss_conf "wpa=$wpa" "$N" [ -n "$wpa_pairwise" ] && append bss_conf "wpa_pairwise=$wpa_pairwise" "$N" @@ -1156,7 +1156,7 @@ hostapd_set_bss_options() { append bss_conf "$val" "$N" done - bss_md5sum=$(echo $bss_conf | md5sum | cut -d" " -f1) + bss_md5sum="$(echo $bss_conf | md5sum | cut -d" " -f1)" append bss_conf "config_id=$bss_md5sum" "$N" append "$var" "$bss_conf" "$N" @@ -1178,7 +1178,7 @@ hostapd_set_log_options() { set_default log_iapp 1 set_default log_mlme 1 - local log_mask=$(( \ + local log_mask="$(( \ ($log_80211 << 0) | \ ($log_8021x << 1) | \ ($log_radius << 2) | \ @@ -1186,7 +1186,7 @@ hostapd_set_log_options() { ($log_driver << 4) | \ ($log_iapp << 5) | \ ($log_mlme << 6) \ - )) + ))" append "$var" "logger_syslog=$log_mask" "$N" append "$var" "logger_syslog_level=$log_level" "$N" From ae751535de0cb46978bfcbacab882dd1082e59e3 Mon Sep 17 00:00:00 2001 From: "Leon M. Busch-George" Date: Wed, 23 Nov 2022 17:40:08 +0100 Subject: [PATCH 05/22] hostapd: always use sae_password for mesh/SAE auth This patch fixes a corner case when using passwords that are exactly 64 characters in length with mesh mode or passwords longer than 63 characters with SAE because 'psk' is used instead of 'sae_password'. SAE is obligatory for 802.11s (mesh point). The 'psk' option for hostapd is suited for WPA2 and enforces length restrictions on passwords. Values of 64 characters are treated as PMKs. With SAE, PMKs are always generated during the handshake and there are no length restrictions. The 'sae_password' option is more suited for SAE and should be used instead. Before this patch, the 'sae_password' option is only used with mesh mode passwords that are not 64 characters long. As a consequence: - mesh passwords can't be 64 characters in length - SAE only works with passwords with lengths >8 and <=63 (due to psk limitation). Fix this by always using 'sae_password' with SAE/mesh and applying the PMK differentiation only when PSK is used. Fixes: #11324 Signed-off-by: Leon M. Busch-George [ improve commit description ] Signed-off-by: Christian Marangi --- package/network/services/hostapd/files/hostapd.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh index 70ad187a81..8c233a4e60 100644 --- a/package/network/services/hostapd/files/hostapd.sh +++ b/package/network/services/hostapd/files/hostapd.sh @@ -1372,11 +1372,11 @@ wpa_supplicant_add_network() { key_mgmt="$wpa_key_mgmt" - if [ ${#key} -eq 64 ]; then - passphrase="psk=${key}" + if [ "$_w_mode" = "mesh" ] || [ "$auth_type" = "sae" ]; then + passphrase="sae_password=\"${key}\"" else - if [ "$_w_mode" = "mesh" ]; then - passphrase="sae_password=\"${key}\"" + if [ ${#key} -eq 64 ]; then + passphrase="psk=${key}" else passphrase="psk=\"${key}\"" fi From cd8366ad20e0596bf9a477453effb6dc9fe48b20 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Tue, 31 Jan 2023 11:07:42 +0100 Subject: [PATCH 06/22] toolchain/binutils: fill in missing GRAPHITE_CONFIGURE This var is used further down, but it's empty. Fix that with the very same values gcc uses. Signed-off-by: Andre Heider --- toolchain/binutils/Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/toolchain/binutils/Makefile b/toolchain/binutils/Makefile index a0e112f8f6..af670f5646 100644 --- a/toolchain/binutils/Makefile +++ b/toolchain/binutils/Makefile @@ -37,6 +37,12 @@ PATCH_DIR:=./patches/$(PKG_VERSION) include $(INCLUDE_DIR)/toolchain-build.mk +ifdef CONFIG_GCC_USE_GRAPHITE + GRAPHITE_CONFIGURE:= --with-isl=$(STAGING_DIR_HOST) +else + GRAPHITE_CONFIGURE:= --without-isl --without-cloog +endif + HOST_CONFIGURE_ARGS = \ --prefix=$(TOOLCHAIN_DIR) \ --build=$(GNU_HOST_NAME) \ From 1f1d1ff918748eacf32b1b6073094bb4f3e9e669 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Wed, 8 Feb 2023 18:04:25 +0100 Subject: [PATCH 07/22] toolchain/binutils: get rid of ARC leftovers In [0] support for ARC specific binutils were added, which was later removed again [Fixes:]. Upstream binutils never had an extlib. [0] 8b5d644b "toolchain: add support of ARC architecture" Fixes: 8568dcd9 "toolchain: Remove binutils 2.29 for ARC targets" Signed-off-by: Andre Heider --- toolchain/binutils/Makefile | 6 ------ 1 file changed, 6 deletions(-) diff --git a/toolchain/binutils/Makefile b/toolchain/binutils/Makefile index af670f5646..0b7558e358 100644 --- a/toolchain/binutils/Makefile +++ b/toolchain/binutils/Makefile @@ -102,12 +102,6 @@ define Host/Install $(call FixupLibdir,$(TOOLCHAIN_DIR)/initial) $(RM) $(TOOLCHAIN_DIR)/initial/lib/libiberty.a $(CP) $(TOOLCHAIN_DIR)/bin/$(REAL_GNU_TARGET_NAME)-readelf $(HOST_BUILD_PREFIX)/bin/readelf - # ARC gcc requires extlib. - # If extlib is not available in "initial" folder - # initial gcc will fail to build libc. - if [ -d $(TOOLCHAIN_DIR)/extlib ]; then \ - $(CP) -r $(TOOLCHAIN_DIR)/extlib $(TOOLCHAIN_DIR)/initial/; \ - fi endef define Host/Clean From f090e6495d3a3ad989799b8e1522def09220cb19 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Wed, 8 Feb 2023 18:58:05 +0100 Subject: [PATCH 08/22] toolchain/binutils: get rid of outdated libiberty hack This reverts commit 68fcb15f90edd92ef36990c5696b9e79df07a6ec. binutils syncs libiberty from gcc, which defaults to not installing itself since [0], see also [1]. That change is apparently part of binutils 2.24, and the oldest supported version here is 2.37, hence we can remove this hack. [0] https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=48d7db63ff581b026e057badf39f1f23fdf47928 [1] https://gcc.gnu.org/onlinedocs/libiberty/Using.html Signed-off-by: Andre Heider --- toolchain/binutils/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/toolchain/binutils/Makefile b/toolchain/binutils/Makefile index 0b7558e358..ef3123aeb6 100644 --- a/toolchain/binutils/Makefile +++ b/toolchain/binutils/Makefile @@ -100,7 +100,6 @@ define Host/Install prefix=$(TOOLCHAIN_DIR) \ install $(call FixupLibdir,$(TOOLCHAIN_DIR)/initial) - $(RM) $(TOOLCHAIN_DIR)/initial/lib/libiberty.a $(CP) $(TOOLCHAIN_DIR)/bin/$(REAL_GNU_TARGET_NAME)-readelf $(HOST_BUILD_PREFIX)/bin/readelf endef From fb0d0c0f7903d2230d1d8c5072082879b7377818 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Wed, 8 Feb 2023 20:20:27 +0100 Subject: [PATCH 09/22] toolchain/binutils: get rid of outdated linaro version string hack This reverts commit 9d1b619cb1a7dd18cd12cab0d9f93452b10e2e11. No Linaro binutils are supported anymore, the leftover removal commit missed one line. Fixes: b648e1c0 "binutils: remove 2.25.1 support and leftovers of older versions" Signed-off-by: Andre Heider --- toolchain/binutils/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/toolchain/binutils/Makefile b/toolchain/binutils/Makefile index ef3123aeb6..636b8c4b11 100644 --- a/toolchain/binutils/Makefile +++ b/toolchain/binutils/Makefile @@ -84,7 +84,6 @@ define Host/Prepare $(call Host/Prepare/Default) ln -snf $(notdir $(HOST_BUILD_DIR)) $(BUILD_DIR_TOOLCHAIN)/$(PKG_NAME) $(CP) $(SCRIPT_DIR)/config.{guess,sub} $(HOST_BUILD_DIR)/ - $(SED) 's, " Linaro.*,,' $(HOST_BUILD_DIR)/bfd/version.h endef define Host/Compile From eb093c517421465d8636fab5eb4fb890d0858a47 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Thu, 9 Feb 2023 10:09:08 +0100 Subject: [PATCH 10/22] toolchain/gcc: remove glibc libgcc_eh hack A modern glibc only links against libgcc_eh for its tests or when building it static, which doesn't happen here. Reverts a hunk of: a3edea1b "add support for alternative C libraries..." Signed-off-by: Andre Heider --- toolchain/gcc/initial/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/toolchain/gcc/initial/Makefile b/toolchain/gcc/initial/Makefile index c71b17dd87..68a7ccd3c7 100644 --- a/toolchain/gcc/initial/Makefile +++ b/toolchain/gcc/initial/Makefile @@ -23,9 +23,7 @@ define Host/Install install-gcc \ install-target-libgcc - # XXX: glibc insists on linking against libgcc_eh ( cd $(TOOLCHAIN_DIR)/initial/lib/gcc/$(REAL_GNU_TARGET_NAME)/$(PKG_VERSION) ; \ - [ -e libgcc_eh.a ] || ln -sf libgcc.a libgcc_eh.a ; \ cp libgcc.a libgcc_initial.a; \ ) From 81fd360a6331ccaaf85440f9d5e1c9ed66e25f6b Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Mon, 30 Jan 2023 10:55:53 +0100 Subject: [PATCH 11/22] toolchain/glibc: fixup the libm.so linker script too Add it to the existing list to fix it up. Found by mold: toolchain-x86_64_gcc-12.2.0_glibc/lib/libm.so:4: GROUP ( /lib/libm.so.6 AS_NEEDED ( /lib/libmvec.so.1 ) ) ^ library not found: /lib/libm.so.6 Signed-off-by: Andre Heider --- toolchain/glibc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolchain/glibc/Makefile b/toolchain/glibc/Makefile index 24526ceec2..bfb5598274 100644 --- a/toolchain/glibc/Makefile +++ b/toolchain/glibc/Makefile @@ -20,7 +20,7 @@ define Host/Install install ( cd $(TOOLCHAIN_DIR) ; \ for d in lib usr/lib ; do \ - for f in libc.so libpthread.so libgcc_s.so ; do \ + for f in libc.so libm.so libpthread.so libgcc_s.so ; do \ if [ -f $$$$d/$$$$f -a ! -L $$$$d/$$$$f ] ; then \ $(SED) 's,/usr/lib/,,g;s,/lib/,,g' $$$$d/$$$$f ; \ fi \ From 4d384d28e44138c7619c0ab68b95cac21eeafbbf Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Thu, 9 Feb 2023 11:06:31 +0100 Subject: [PATCH 12/22] toolchain/musl: remove libgcc_initial hack This reverts r15599 [0]. This was added to fix an uclibc rebuild issue, but since uclibc isn't supported anymore [Fixes:] this can be removed. [0] https://git.openwrt.org/?p=openwrt/svn-archive/archive.git;a=commitdiff;h=016a052efeee6bc2da3f501a8c66b5aea20350b4 Fixes: 63fb1752 "toolchain: remove uClibc-ng" Signed-off-by: Andre Heider --- toolchain/gcc/initial/Makefile | 4 ---- toolchain/musl/Makefile | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/toolchain/gcc/initial/Makefile b/toolchain/gcc/initial/Makefile index 68a7ccd3c7..102fc070ae 100644 --- a/toolchain/gcc/initial/Makefile +++ b/toolchain/gcc/initial/Makefile @@ -23,10 +23,6 @@ define Host/Install install-gcc \ install-target-libgcc - ( cd $(TOOLCHAIN_DIR)/initial/lib/gcc/$(REAL_GNU_TARGET_NAME)/$(PKG_VERSION) ; \ - cp libgcc.a libgcc_initial.a; \ - ) - $(call FixupLibdir,$(TOOLCHAIN_DIR)/initial) $$(call file_copy,$(TOOLCHAIN_DIR)/initial/.,$(TOOLCHAIN_DIR)/) endef diff --git a/toolchain/musl/Makefile b/toolchain/musl/Makefile index 2b9312bcbf..d441e37684 100644 --- a/toolchain/musl/Makefile +++ b/toolchain/musl/Makefile @@ -9,7 +9,7 @@ HOST_BUILD_PARALLEL:=1 MUSL_MAKEOPTS = -C $(HOST_BUILD_DIR) \ DESTDIR="$(TOOLCHAIN_DIR)/" \ - LIBCC="$(subst libgcc.a,libgcc_initial.a,$(shell $(TARGET_CC) -print-libgcc-file-name))" + LIBCC="$(shell $(TARGET_CC) -print-libgcc-file-name)" define Host/SetToolchainInfo $(SED) 's,^\(LIBC_TYPE\)=.*,\1=$(PKG_NAME),' $(TOOLCHAIN_DIR)/info.mk From 7ae4716243dda59bcff21ba0ee704322b2db10f4 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Tue, 7 Feb 2023 21:33:33 +0100 Subject: [PATCH 13/22] toolchain: remove installing twice in the "initial" subdir This was apparently introduced to recreate the toolchain (wipe staging_dir/toolchain*, but keep build_dir/toolchain*, followed by a `make toolchain/compile`). But it leaves leftovers and causes re-links to happen at src_install phase, because of the changed paths, possibly adding yet another source of issues. With the prior commits removing various hacks related to the "initial" folder we can remove installing it twice altogether. The recreated toolchain is exactly the same as before. Signed-off-by: Andre Heider --- target/sdk/Makefile | 1 - toolchain/binutils/Makefile | 7 +------ toolchain/gcc/initial/Makefile | 4 +--- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/target/sdk/Makefile b/target/sdk/Makefile index 89cc898e9d..d9f67dae9e 100644 --- a/target/sdk/Makefile +++ b/target/sdk/Makefile @@ -29,7 +29,6 @@ EXCLUDE_DIRS:= \ */man \ */info \ */root-* \ - initial \ *.install.clean \ *.install.flags \ *.install \ diff --git a/toolchain/binutils/Makefile b/toolchain/binutils/Makefile index 636b8c4b11..42778d8d69 100644 --- a/toolchain/binutils/Makefile +++ b/toolchain/binutils/Makefile @@ -91,14 +91,9 @@ define Host/Compile endef define Host/Install - mkdir -p $(TOOLCHAIN_DIR)/initial $(MAKE) -C $(HOST_BUILD_DIR) \ - prefix=$(TOOLCHAIN_DIR)/initial \ install - $(MAKE) -C $(HOST_BUILD_DIR) \ - prefix=$(TOOLCHAIN_DIR) \ - install - $(call FixupLibdir,$(TOOLCHAIN_DIR)/initial) + $(call FixupLibdir,$(TOOLCHAIN_DIR)) $(CP) $(TOOLCHAIN_DIR)/bin/$(REAL_GNU_TARGET_NAME)-readelf $(HOST_BUILD_PREFIX)/bin/readelf endef diff --git a/toolchain/gcc/initial/Makefile b/toolchain/gcc/initial/Makefile index 102fc070ae..7cb4a73dbc 100644 --- a/toolchain/gcc/initial/Makefile +++ b/toolchain/gcc/initial/Makefile @@ -19,12 +19,10 @@ endef define Host/Install +$(GCC_MAKE) $(HOST_JOBS) -C $(GCC_BUILD_DIR) \ - prefix="$(TOOLCHAIN_DIR)/initial" \ install-gcc \ install-target-libgcc - $(call FixupLibdir,$(TOOLCHAIN_DIR)/initial) - $$(call file_copy,$(TOOLCHAIN_DIR)/initial/.,$(TOOLCHAIN_DIR)/) + $(call FixupLibdir,$(TOOLCHAIN_DIR)) endef $(eval $(call HostBuild)) From 57db2280a2155c39f545ac712766a849cf45f62c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 15 Feb 2023 19:40:02 +0100 Subject: [PATCH 14/22] mac80211: fix mesh issues and improve performance fix forwarding received mesh a-msdu packets add fast xmit support for mesh to improve performance Signed-off-by: Felix Fietkau --- ...-mac80211-fix-qos-on-mesh-interfaces.patch | 35 + ...x-race-in-mesh-sequence-number-assig.patch | 37 + ...wifi-mac80211-mesh-fast-xmit-support.patch | 764 ++++++++++++++++++ ...e-mesh-header-cache-to-speed-up-mesh.patch | 70 ++ .../321-mac80211-fix-mesh-forwarding.patch | 32 + .../500-mac80211_configure_antenna_gain.patch | 2 +- 6 files changed, 939 insertions(+), 1 deletion(-) create mode 100644 package/kernel/mac80211/patches/subsys/317-wifi-mac80211-fix-qos-on-mesh-interfaces.patch create mode 100644 package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch create mode 100644 package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch create mode 100644 package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch create mode 100644 package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch diff --git a/package/kernel/mac80211/patches/subsys/317-wifi-mac80211-fix-qos-on-mesh-interfaces.patch b/package/kernel/mac80211/patches/subsys/317-wifi-mac80211-fix-qos-on-mesh-interfaces.patch new file mode 100644 index 0000000000..c60a88d2a6 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/317-wifi-mac80211-fix-qos-on-mesh-interfaces.patch @@ -0,0 +1,35 @@ +From: Felix Fietkau +Date: Wed, 15 Feb 2023 15:11:54 +0100 +Subject: [PATCH] wifi: mac80211: fix qos on mesh interfaces + +When ieee80211_select_queue is called for mesh, the sta pointer is usually +NULL, since the nexthop is looked up much later in the tx path. +Explicitly check for unicast address in that case in order to make qos work +again. + +Fixes: 50e2ab392919 ("wifi: mac80211: fix queue selection for mesh/OCB interfaces") +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/wme.c ++++ b/net/mac80211/wme.c +@@ -147,6 +147,7 @@ u16 ieee80211_select_queue_80211(struct + u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, + struct sta_info *sta, struct sk_buff *skb) + { ++ const struct ethhdr *eth = (void *)skb->data; + struct mac80211_qos_map *qos_map; + bool qos; + +@@ -154,8 +155,9 @@ u16 ieee80211_select_queue(struct ieee80 + skb_get_hash(skb); + + /* all mesh/ocb stations are required to support WME */ +- if (sta && (sdata->vif.type == NL80211_IFTYPE_MESH_POINT || +- sdata->vif.type == NL80211_IFTYPE_OCB)) ++ if ((sdata->vif.type == NL80211_IFTYPE_MESH_POINT && ++ !is_multicast_ether_addr(eth->h_dest)) || ++ (sdata->vif.type == NL80211_IFTYPE_OCB && sta)) + qos = true; + else if (sta) + qos = sta->sta.wme; diff --git a/package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch b/package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch new file mode 100644 index 0000000000..05e368cd2e --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch @@ -0,0 +1,37 @@ +From: Felix Fietkau +Date: Wed, 15 Feb 2023 15:21:37 +0100 +Subject: [PATCH] wifi: mac80211: fix race in mesh sequence number + assignment + +Since the sequence number is shared across different tx queues, it needs +to be atomic in order to avoid accidental duplicate assignment + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -695,7 +695,7 @@ struct ieee80211_if_mesh { + struct mesh_stats mshstats; + struct mesh_config mshcfg; + atomic_t estab_plinks; +- u32 mesh_seqnum; ++ atomic_t mesh_seqnum; + bool accepting_plinks; + int num_gates; + struct beacon_data __rcu *beacon; +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -752,10 +752,8 @@ unsigned int ieee80211_new_mesh_header(s + + meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; + +- /* FIXME: racy -- TX on multiple queues can be concurrent */ +- put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); +- sdata->u.mesh.mesh_seqnum++; +- ++ put_unaligned_le32(atomic_inc_return(&sdata->u.mesh.mesh_seqnum), ++ &meshhdr->seqnum); + if (addr4or5 && !addr6) { + meshhdr->flags |= MESH_FLAGS_AE_A4; + memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN); diff --git a/package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch b/package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch new file mode 100644 index 0000000000..4bd3d4c092 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch @@ -0,0 +1,764 @@ +From: Sriram R +Date: Thu, 18 Aug 2022 12:35:42 +0530 +Subject: [PATCH] wifi: mac80211: mesh fast xmit support + +Currently fast xmit is supported in AP, STA and other device types where +the destination doesn't change for the lifetime of its association by +caching the static parts of the header that can be reused directly for +every Tx such as addresses and updates only mutable header fields such as +PN. +This technique is not directly applicable for a Mesh device type due +to the dynamic nature of the topology and protocol. The header is built +based on the destination mesh device which is proxying a certain external +device and based on the Mesh destination the next hop changes. +And the RA/A1 which is the next hop for reaching the destination can +vary during runtime as per the best route based on airtime. To accommodate +these changes and to come up with a solution to avoid overhead during header +generation, the headers comprising the MAC, Mesh and LLC part are cached +whenever data for a certain external destination is sent. +This cached header is reused every time a data is sent to that external +destination. + +To ensure the changes in network are reflected in these cached headers, +flush affected cached entries on path changes, as well as other conditions +that currently trigger a fast xmit check in other modes (key changes etc.) + +In order to keep the cache small, use a short timeout for expiring cache +entries. + +Co-developed-by: Felix Fietkau +Signed-off-by: Sriram R +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -37,6 +37,7 @@ + extern const struct cfg80211_ops mac80211_config_ops; + + struct ieee80211_local; ++struct mhdr_cache_entry; + + /* Maximum number of broadcast/multicast frames to buffer when some of the + * associated stations are using power saving. */ +@@ -655,6 +656,20 @@ struct mesh_table { + atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ + }; + ++/** ++ * struct mesh_hdr_cache - mesh fast xmit header cache ++ * ++ * @rhead: hash table containing struct mhdr_cache_entry, using skb DA as key ++ * @walk_head: linked list containing all mhdr_cache_entry objects ++ * @walk_lock: lock protecting walk_head and rhead ++ * @enabled: indicates if header cache is initialized ++ */ ++struct mesh_hdr_cache { ++ struct rhashtable rhead; ++ struct hlist_head walk_head; ++ spinlock_t walk_lock; ++}; ++ + struct ieee80211_if_mesh { + struct timer_list housekeeping_timer; + struct timer_list mesh_path_timer; +@@ -733,6 +748,7 @@ struct ieee80211_if_mesh { + struct mesh_table mpp_paths; /* Store paths for MPP&MAP */ + int mesh_paths_generation; + int mpp_paths_generation; ++ struct mesh_hdr_cache hdr_cache; + }; + + #ifdef CPTCFG_MAC80211_MESH +@@ -1998,6 +2014,9 @@ int ieee80211_tx_control_port(struct wip + int link_id, u64 *cookie); + int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, + const u8 *buf, size_t len); ++void __ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, ++ struct mhdr_cache_entry *entry, ++ struct sk_buff *skb); + + /* HT */ + void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -780,6 +780,8 @@ static void ieee80211_mesh_housekeeping( + changed = mesh_accept_plinks_update(sdata); + ieee80211_mbss_info_change_notify(sdata, changed); + ++ mesh_hdr_cache_gc(sdata); ++ + mod_timer(&ifmsh->housekeeping_timer, + round_jiffies(jiffies + + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); +--- a/net/mac80211/mesh.h ++++ b/net/mac80211/mesh.h +@@ -122,11 +122,49 @@ struct mesh_path { + u8 rann_snd_addr[ETH_ALEN]; + u32 rann_metric; + unsigned long last_preq_to_root; ++ unsigned long fast_xmit_check; + bool is_root; + bool is_gate; + u32 path_change_count; + }; + ++#define MESH_HEADER_CACHE_MAX_SIZE 512 ++#define MESH_HEADER_CACHE_THRESHOLD_SIZE 384 ++#define MESH_HEADER_CACHE_TIMEOUT 8000 /* msecs */ ++#define MESH_HEADER_MAX_LEN 68 /* mac+mesh+rfc1042 hdr */ ++ ++/** ++ * struct mhdr_cache_entry - Cached Mesh header entry ++ * @addr_key: The Ethernet DA which is the key for this entry ++ * @hdr: The cached header ++ * @machdr_len: Total length of the mac header ++ * @hdrlen: Length of this header entry ++ * @key: Key corresponding to the nexthop stored in the header ++ * @pn_offs: Offset to PN which is updated for every xmit ++ * @band: band used for tx ++ * @walk_list: list containing all the cached header entries ++ * @rhash: rhashtable pointer ++ * @mpath: The Mesh path corresponding to the Mesh DA ++ * @mppath: The MPP entry corresponding to this DA ++ * @timestamp: Last used time of this entry ++ * @rcu: rcu to free this entry ++ * @path_change_count: Stored path change value corresponding to the mpath ++ */ ++struct mhdr_cache_entry { ++ u8 addr_key[ETH_ALEN] __aligned(2); ++ u8 hdr[MESH_HEADER_MAX_LEN]; ++ u16 machdr_len; ++ u16 hdrlen; ++ u8 pn_offs; ++ u8 band; ++ struct ieee80211_key __rcu *key; ++ struct hlist_node walk_list; ++ struct rhash_head rhash; ++ struct mesh_path *mpath, *mppath; ++ unsigned long timestamp; ++ struct rcu_head rcu; ++}; ++ + /* Recent multicast cache */ + /* RMC_BUCKETS must be a power of 2, maximum 256 */ + #define RMC_BUCKETS 256 +@@ -298,6 +336,15 @@ void mesh_path_discard_frame(struct ieee + void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); + + bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); ++struct mhdr_cache_entry * ++mesh_get_cached_hdr(struct ieee80211_sub_if_data *sdata, const u8 *addr); ++void mesh_cache_hdr(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb, struct mesh_path *mpath); ++void mesh_hdr_cache_gc(struct ieee80211_sub_if_data *sdata); ++void mesh_hdr_cache_flush(struct ieee80211_sub_if_data *sdata, const u8 *addr, ++ bool is_mpp); ++void mesh_refresh_path(struct ieee80211_sub_if_data *sdata, ++ struct mesh_path *mpath, const u8 *addr); + + #ifdef CPTCFG_MAC80211_MESH + static inline +--- a/net/mac80211/mesh_hwmp.c ++++ b/net/mac80211/mesh_hwmp.c +@@ -491,8 +491,11 @@ static u32 hwmp_route_info_get(struct ie + } + + if (fresh_info) { +- if (rcu_access_pointer(mpath->next_hop) != sta) ++ if (rcu_access_pointer(mpath->next_hop) != sta) { + mpath->path_change_count++; ++ mesh_hdr_cache_flush(mpath->sdata, mpath->dst, ++ false); ++ } + mesh_path_assign_nexthop(mpath, sta); + mpath->flags |= MESH_PATH_SN_VALID; + mpath->metric = new_metric; +@@ -539,8 +542,11 @@ static u32 hwmp_route_info_get(struct ie + } + + if (fresh_info) { +- if (rcu_access_pointer(mpath->next_hop) != sta) ++ if (rcu_access_pointer(mpath->next_hop) != sta) { + mpath->path_change_count++; ++ mesh_hdr_cache_flush(mpath->sdata, mpath->dst, ++ false); ++ } + mesh_path_assign_nexthop(mpath, sta); + mpath->metric = last_hop_metric; + mpath->exp_time = time_after(mpath->exp_time, exp_time) +@@ -977,7 +983,7 @@ free: + * Locking: the function must be called from within a rcu read lock block. + * + */ +-static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) ++void mesh_queue_preq(struct mesh_path *mpath, u8 flags) + { + struct ieee80211_sub_if_data *sdata = mpath->sdata; + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; +@@ -1215,6 +1221,20 @@ static int mesh_nexthop_lookup_nolearn(s + return 0; + } + ++void mesh_refresh_path(struct ieee80211_sub_if_data *sdata, ++ struct mesh_path *mpath, const u8 *addr) ++{ ++ if (mpath->flags & (MESH_PATH_REQ_QUEUED | MESH_PATH_FIXED | ++ MESH_PATH_RESOLVING)) ++ return; ++ ++ if (time_after(jiffies, ++ mpath->exp_time - ++ msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && ++ (!addr || ether_addr_equal(sdata->vif.addr, addr))) ++ mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); ++} ++ + /** + * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling + * this function is considered "using" the associated mpath, so preempt a path +@@ -1242,19 +1262,18 @@ int mesh_nexthop_lookup(struct ieee80211 + if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE)) + return -ENOENT; + +- if (time_after(jiffies, +- mpath->exp_time - +- msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && +- ether_addr_equal(sdata->vif.addr, hdr->addr4) && +- !(mpath->flags & MESH_PATH_RESOLVING) && +- !(mpath->flags & MESH_PATH_FIXED)) +- mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); ++ mesh_refresh_path(sdata, mpath, hdr->addr4); + + next_hop = rcu_dereference(mpath->next_hop); + if (next_hop) { + memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN); + memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); + ieee80211_mps_set_frame_flags(sdata, next_hop, hdr); ++ /* Cache the whole header so as to use next time rather than resolving ++ * and building it every time ++ */ ++ if (ieee80211_hw_check(&sdata->local->hw, SUPPORT_FAST_XMIT)) ++ mesh_cache_hdr(sdata, skb, mpath); + return 0; + } + +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -14,6 +14,7 @@ + #include "wme.h" + #include "ieee80211_i.h" + #include "mesh.h" ++#include + + static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath); + +@@ -32,6 +33,41 @@ static const struct rhashtable_params me + .hashfn = mesh_table_hash, + }; + ++static const struct rhashtable_params mesh_hdr_rht_params = { ++ .nelem_hint = 10, ++ .automatic_shrinking = true, ++ .key_len = ETH_ALEN, ++ .key_offset = offsetof(struct mhdr_cache_entry, addr_key), ++ .head_offset = offsetof(struct mhdr_cache_entry, rhash), ++ .hashfn = mesh_table_hash, ++}; ++ ++static void __mesh_hdr_cache_entry_free(void *ptr, void *tblptr) ++{ ++ struct mhdr_cache_entry *mhdr = ptr; ++ ++ kfree_rcu(mhdr, rcu); ++} ++ ++static void mesh_hdr_cache_deinit(struct ieee80211_sub_if_data *sdata) ++{ ++ struct mesh_hdr_cache *cache; ++ ++ cache = &sdata->u.mesh.hdr_cache; ++ rhashtable_free_and_destroy(&cache->rhead, ++ __mesh_hdr_cache_entry_free, NULL); ++} ++ ++static void mesh_hdr_cache_init(struct ieee80211_sub_if_data *sdata) ++{ ++ struct mesh_hdr_cache *cache; ++ ++ cache = &sdata->u.mesh.hdr_cache; ++ rhashtable_init(&cache->rhead, &mesh_hdr_rht_params); ++ INIT_HLIST_HEAD(&cache->walk_head); ++ spin_lock_init(&cache->walk_lock); ++} ++ + static inline bool mpath_expired(struct mesh_path *mpath) + { + return (mpath->flags & MESH_PATH_ACTIVE) && +@@ -381,6 +417,211 @@ struct mesh_path *mesh_path_new(struct i + return new_mpath; + } + ++struct mhdr_cache_entry * ++mesh_get_cached_hdr(struct ieee80211_sub_if_data *sdata, const u8 *addr) ++{ ++ struct mesh_path *mpath, *mppath; ++ struct mhdr_cache_entry *entry; ++ struct mesh_hdr_cache *cache; ++ ++ cache = &sdata->u.mesh.hdr_cache; ++ entry = rhashtable_lookup(&cache->rhead, addr, mesh_hdr_rht_params); ++ if (!entry) ++ return NULL; ++ ++ mpath = rcu_dereference(entry->mpath); ++ mppath = rcu_dereference(entry->mppath); ++ if (!(mpath->flags & MESH_PATH_ACTIVE) || mpath_expired(mpath)) ++ return NULL; ++ ++ mesh_refresh_path(sdata, mpath, NULL); ++ if (mppath) ++ mppath->exp_time = jiffies; ++ entry->timestamp = jiffies; ++ ++ return entry; ++} ++ ++void mesh_cache_hdr(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb, struct mesh_path *mpath) ++{ ++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ struct mesh_hdr_cache *cache; ++ struct mhdr_cache_entry *mhdr, *old_mhdr; ++ struct ieee80211s_hdr *meshhdr; ++ struct sta_info *next_hop; ++ struct ieee80211_key *key; ++ struct mesh_path *mppath; ++ u16 meshhdr_len; ++ u8 pn_offs = 0; ++ int hdrlen; ++ ++ if (sdata->noack_map) ++ return; ++ ++ if (!ieee80211_is_data_qos(hdr->frame_control)) ++ return; ++ ++ hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ meshhdr = (struct ieee80211s_hdr *)(skb->data + hdrlen); ++ meshhdr_len = ieee80211_get_mesh_hdrlen(meshhdr); ++ ++ cache = &sdata->u.mesh.hdr_cache; ++ if (atomic_read(&cache->rhead.nelems) >= MESH_HEADER_CACHE_MAX_SIZE) ++ return; ++ ++ next_hop = rcu_dereference(mpath->next_hop); ++ if (!next_hop) ++ return; ++ ++ if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) { ++ /* This is required to keep the mppath alive */ ++ mppath = mpp_path_lookup(sdata, meshhdr->eaddr1); ++ if (!mppath) ++ return; ++ } else if (ieee80211_has_a4(hdr->frame_control)) { ++ mppath = mpath; ++ } else { ++ return; ++ } ++ ++ /* rate limit, in case fast xmit can't be enabled */ ++ if (mppath->fast_xmit_check == jiffies) ++ return; ++ ++ mppath->fast_xmit_check = jiffies; ++ ++ key = rcu_access_pointer(next_hop->ptk[next_hop->ptk_idx]); ++ if (!key) ++ key = rcu_access_pointer(sdata->default_unicast_key); ++ ++ if (key) { ++ bool gen_iv, iv_spc; ++ ++ gen_iv = key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV; ++ iv_spc = key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE; ++ ++ if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) || ++ (key->flags & KEY_FLAG_TAINTED)) ++ return; ++ ++ switch (key->conf.cipher) { ++ case WLAN_CIPHER_SUITE_CCMP: ++ case WLAN_CIPHER_SUITE_CCMP_256: ++ if (gen_iv) ++ pn_offs = hdrlen; ++ if (gen_iv || iv_spc) ++ hdrlen += IEEE80211_CCMP_HDR_LEN; ++ break; ++ case WLAN_CIPHER_SUITE_GCMP: ++ case WLAN_CIPHER_SUITE_GCMP_256: ++ if (gen_iv) ++ pn_offs = hdrlen; ++ if (gen_iv || iv_spc) ++ hdrlen += IEEE80211_GCMP_HDR_LEN; ++ break; ++ default: ++ return; ++ } ++ } ++ ++ if (WARN_ON_ONCE(hdrlen + meshhdr_len + sizeof(rfc1042_header) > ++ MESH_HEADER_MAX_LEN)) ++ return; ++ ++ mhdr = kzalloc(sizeof(*mhdr), GFP_ATOMIC); ++ if (!mhdr) ++ return; ++ ++ memcpy(mhdr->addr_key, mppath->dst, ETH_ALEN); ++ mhdr->machdr_len = hdrlen; ++ mhdr->hdrlen = mhdr->machdr_len + meshhdr_len + sizeof(rfc1042_header); ++ rcu_assign_pointer(mhdr->mpath, mpath); ++ if (meshhdr->flags & MESH_FLAGS_AE) ++ rcu_assign_pointer(mhdr->mppath, mppath); ++ rcu_assign_pointer(mhdr->key, key); ++ mhdr->timestamp = jiffies; ++ mhdr->band = info->band; ++ mhdr->pn_offs = pn_offs; ++ ++ if (pn_offs) { ++ memcpy(mhdr->hdr, skb->data, pn_offs); ++ memcpy(mhdr->hdr + mhdr->machdr_len, skb->data + pn_offs, ++ mhdr->hdrlen - mhdr->machdr_len); ++ } else { ++ memcpy(mhdr->hdr, skb->data, mhdr->hdrlen); ++ } ++ ++ if (key) { ++ hdr = (struct ieee80211_hdr *)mhdr->hdr; ++ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); ++ } ++ ++ spin_lock_bh(&cache->walk_lock); ++ old_mhdr = rhashtable_lookup_get_insert_fast(&cache->rhead, ++ &mhdr->rhash, ++ mesh_hdr_rht_params); ++ if (likely(!old_mhdr)) ++ hlist_add_head(&mhdr->walk_list, &cache->walk_head); ++ else ++ kfree(mhdr); ++ spin_unlock_bh(&cache->walk_lock); ++} ++ ++static void mesh_hdr_cache_entry_free(struct mesh_hdr_cache *cache, ++ struct mhdr_cache_entry *entry) ++{ ++ hlist_del_rcu(&entry->walk_list); ++ rhashtable_remove_fast(&cache->rhead, &entry->rhash, mesh_hdr_rht_params); ++ kfree_rcu(entry, rcu); ++} ++ ++void mesh_hdr_cache_gc(struct ieee80211_sub_if_data *sdata) ++{ ++ unsigned long timeout = msecs_to_jiffies(MESH_HEADER_CACHE_TIMEOUT); ++ struct mesh_hdr_cache *cache; ++ struct mhdr_cache_entry *entry; ++ struct hlist_node *n; ++ ++ cache = &sdata->u.mesh.hdr_cache; ++ if (atomic_read(&cache->rhead.nelems) < MESH_HEADER_CACHE_THRESHOLD_SIZE) ++ return; ++ ++ spin_lock_bh(&cache->walk_lock); ++ hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) ++ if (!time_is_after_jiffies(entry->timestamp + timeout)) ++ mesh_hdr_cache_entry_free(cache, entry); ++ spin_unlock_bh(&cache->walk_lock); ++} ++ ++void mesh_hdr_cache_flush(struct ieee80211_sub_if_data *sdata, const u8 *addr, ++ bool is_mpp) ++{ ++ struct mesh_hdr_cache *cache = &sdata->u.mesh.hdr_cache; ++ struct mhdr_cache_entry *entry; ++ struct hlist_node *n; ++ ++ cache = &sdata->u.mesh.hdr_cache; ++ spin_lock_bh(&cache->walk_lock); ++ ++ /* Only one header per mpp address is expected in the header cache */ ++ if (is_mpp) { ++ entry = rhashtable_lookup(&cache->rhead, addr, ++ mesh_hdr_rht_params); ++ if (entry) ++ mesh_hdr_cache_entry_free(cache, entry); ++ goto out; ++ } ++ ++ hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) ++ if (ether_addr_equal(entry->mpath->dst, addr)) ++ mesh_hdr_cache_entry_free(cache, entry); ++ ++out: ++ spin_unlock_bh(&cache->walk_lock); ++} ++ + /** + * mesh_path_add - allocate and add a new path to the mesh path table + * @dst: destination address of the path (ETH_ALEN length) +@@ -521,6 +762,8 @@ static void mesh_path_free_rcu(struct me + + static void __mesh_path_del(struct mesh_table *tbl, struct mesh_path *mpath) + { ++ mesh_hdr_cache_flush(mpath->sdata, mpath->dst, ++ tbl == &mpath->sdata->u.mesh.mpp_paths); + hlist_del_rcu(&mpath->walk_list); + rhashtable_remove_fast(&tbl->rhead, &mpath->rhash, mesh_rht_params); + mesh_path_free_rcu(tbl, mpath); +@@ -747,6 +990,7 @@ void mesh_path_fix_nexthop(struct mesh_p + mpath->exp_time = 0; + mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID; + mesh_path_activate(mpath); ++ mesh_hdr_cache_flush(mpath->sdata, mpath->dst, false); + spin_unlock_bh(&mpath->state_lock); + ewma_mesh_fail_avg_init(&next_hop->mesh->fail_avg); + /* init it at a low value - 0 start is tricky */ +@@ -758,6 +1002,7 @@ void mesh_pathtbl_init(struct ieee80211_ + { + mesh_table_init(&sdata->u.mesh.mesh_paths); + mesh_table_init(&sdata->u.mesh.mpp_paths); ++ mesh_hdr_cache_init(sdata); + } + + static +@@ -785,6 +1030,7 @@ void mesh_path_expire(struct ieee80211_s + + void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata) + { ++ mesh_hdr_cache_deinit(sdata); + mesh_table_free(&sdata->u.mesh.mesh_paths); + mesh_table_free(&sdata->u.mesh.mpp_paths); + } +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2791,6 +2791,7 @@ ieee80211_rx_mesh_data(struct ieee80211_ + if (mesh_hdr->flags & MESH_FLAGS_AE) { + struct mesh_path *mppath; + char *proxied_addr; ++ bool update = false; + + if (multicast) + proxied_addr = mesh_hdr->eaddr1; +@@ -2806,11 +2807,18 @@ ieee80211_rx_mesh_data(struct ieee80211_ + mpp_path_add(sdata, proxied_addr, eth->h_source); + } else { + spin_lock_bh(&mppath->state_lock); +- if (!ether_addr_equal(mppath->mpp, eth->h_source)) ++ if (!ether_addr_equal(mppath->mpp, eth->h_source)) { + memcpy(mppath->mpp, eth->h_source, ETH_ALEN); ++ update = true; ++ } + mppath->exp_time = jiffies; + spin_unlock_bh(&mppath->state_lock); + } ++ ++ /* flush fast xmit cache if the address path changed */ ++ if (update) ++ mesh_hdr_cache_flush(sdata, proxied_addr, true); ++ + rcu_read_unlock(); + } + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3021,6 +3021,9 @@ void ieee80211_check_fast_xmit(struct st + if (!ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT)) + return; + ++ if (ieee80211_vif_is_mesh(&sdata->vif)) ++ mesh_hdr_cache_flush(sdata, sta->addr, false); ++ + /* Locking here protects both the pointer itself, and against concurrent + * invocations winning data access races to, e.g., the key pointer that + * is used. +@@ -3723,6 +3726,155 @@ free: + kfree_skb(skb); + } + ++void __ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, ++ struct mhdr_cache_entry *entry, ++ struct sk_buff *skb) ++{ ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_tx_data tx = {}; ++ struct ieee80211_tx_info *info; ++ struct ieee80211_key *key; ++ struct ieee80211_hdr *hdr; ++ struct mesh_path *mpath; ++ ieee80211_tx_result r; ++ struct sta_info *sta; ++ u8 tid; ++ ++ if (!IS_ENABLED(CPTCFG_MAC80211_MESH)) ++ return; ++ ++ info = IEEE80211_SKB_CB(skb); ++ memset(info, 0, sizeof(*info)); ++ info->band = entry->band; ++ info->control.vif = &sdata->vif; ++ info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT | ++ IEEE80211_TX_CTL_DONTFRAG; ++ ++ info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT; ++ ++#ifdef CONFIG_MAC80211_DEBUGFS ++ if (local->force_tx_status) ++ info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; ++#endif ++ ++ mpath = entry->mpath; ++ key = entry->key; ++ sta = rcu_dereference(mpath->next_hop); ++ ++ __skb_queue_head_init(&tx.skbs); ++ ++ tx.flags = IEEE80211_TX_UNICAST; ++ tx.local = local; ++ tx.sdata = sdata; ++ tx.sta = sta; ++ tx.key = key; ++ tx.skb = skb; ++ ++ hdr = (struct ieee80211_hdr *)skb->data; ++ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; ++ *ieee80211_get_qos_ctl(hdr) = tid; ++ ++ ieee80211_aggr_check(sdata, sta, skb); ++ ++ if (ieee80211_queue_skb(local, sdata, sta, skb)) ++ return; ++ ++ r = ieee80211_xmit_fast_finish(sdata, sta, entry->pn_offs, key, &tx); ++ if (r == TX_DROP) { ++ kfree_skb(skb); ++ return; ++ } ++ ++ __skb_queue_tail(&tx.skbs, skb); ++ ieee80211_tx_frags(local, &sdata->vif, sta, &tx.skbs, false); ++} ++ ++ ++static bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb, u32 ctrl_flags) ++{ ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; ++ struct mhdr_cache_entry *entry; ++ struct ieee80211s_hdr *meshhdr; ++ u8 sa[ETH_ALEN] __aligned(2); ++ struct sta_info *sta; ++ bool copy_sa = false; ++ u16 ethertype; ++ ++ if (ctrl_flags & IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP) ++ return false; ++ ++ if (ifmsh->mshcfg.dot11MeshNolearn) ++ return false; ++ ++ if (!ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT)) ++ return false; ++ ++ /* Add support for these cases later */ ++ if (ifmsh->ps_peers_light_sleep || ifmsh->ps_peers_deep_sleep) ++ return false; ++ ++ if (is_multicast_ether_addr(skb->data)) ++ return false; ++ ++ ethertype = (skb->data[12] << 8) | skb->data[13]; ++ if (ethertype < ETH_P_802_3_MIN) ++ return false; ++ ++ if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) ++ return false; ++ ++ if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ skb_set_transport_header(skb, skb_checksum_start_offset(skb)); ++ if (skb_checksum_help(skb)) ++ return false; ++ } ++ ++ entry = mesh_get_cached_hdr(sdata, skb->data); ++ if (!entry) ++ return false; ++ ++ /* Avoid extra work in this path */ ++ if (skb_headroom(skb) < (entry->hdrlen - ETH_HLEN + 2)) ++ return false; ++ ++ /* If the skb is shared we need to obtain our own copy */ ++ if (skb_shared(skb)) { ++ struct sk_buff *oskb = skb; ++ ++ skb = skb_clone(skb, GFP_ATOMIC); ++ if (!skb) ++ return false; ++ ++ kfree_skb(oskb); ++ } ++ ++ sta = rcu_dereference(entry->mpath->next_hop); ++ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); ++ ++ meshhdr = (struct ieee80211s_hdr *)(entry->hdr + entry->machdr_len); ++ if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) { ++ /* preserve SA from eth header for 6-addr frames */ ++ ether_addr_copy(sa, skb->data + ETH_ALEN); ++ copy_sa = true; ++ } ++ ++ memcpy(skb_push(skb, entry->hdrlen - 2 * ETH_ALEN), entry->hdr, ++ entry->hdrlen); ++ ++ meshhdr = (struct ieee80211s_hdr *)(skb->data + entry->machdr_len); ++ put_unaligned_le32(atomic_inc_return(&sdata->u.mesh.mesh_seqnum), ++ &meshhdr->seqnum); ++ meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; ++ if (copy_sa) ++ ether_addr_copy(meshhdr->eaddr2, sa); ++ ++ __ieee80211_mesh_xmit_fast(sdata, entry, skb); ++ ++ return true; ++} ++ + static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, + struct sta_info *sta, + struct ieee80211_fast_tx *fast_tx, +@@ -4244,8 +4396,14 @@ void __ieee80211_subif_start_xmit(struct + return; + } + ++ sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); ++ + rcu_read_lock(); + ++ if (ieee80211_vif_is_mesh(&sdata->vif) && ++ ieee80211_mesh_xmit_fast(sdata, skb, ctrl_flags)) ++ goto out; ++ + if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) + goto out_free; + +@@ -4255,8 +4413,6 @@ void __ieee80211_subif_start_xmit(struct + skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); + ieee80211_aggr_check(sdata, sta, skb); + +- sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); +- + if (sta) { + struct ieee80211_fast_tx *fast_tx; + diff --git a/package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch b/package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch new file mode 100644 index 0000000000..e0d4e60ed7 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch @@ -0,0 +1,70 @@ +From: Felix Fietkau +Date: Thu, 16 Feb 2023 11:07:30 +0100 +Subject: [PATCH] wifi: mac80211: use mesh header cache to speed up mesh + forwarding + +Use it to look up the next hop address + sta pointer + key and call +__ieee80211_mesh_xmit_fast to queue the tx frame. + +Significantly reduces mesh forwarding path CPU usage and enables the +use of iTXQ. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2731,6 +2731,7 @@ ieee80211_rx_mesh_data(struct ieee80211_ + struct ieee80211_hdr hdr = { + .frame_control = cpu_to_le16(fc) + }; ++ struct mhdr_cache_entry *entry = NULL; + struct ieee80211_hdr *fwd_hdr; + struct ieee80211s_hdr *mesh_hdr; + struct ieee80211_tx_info *info; +@@ -2788,7 +2789,12 @@ ieee80211_rx_mesh_data(struct ieee80211_ + return RX_DROP_MONITOR; + } + +- if (mesh_hdr->flags & MESH_FLAGS_AE) { ++ if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) ++ entry = mesh_get_cached_hdr(sdata, mesh_hdr->eaddr1); ++ else if (!(mesh_hdr->flags & MESH_FLAGS_AE)) ++ entry = mesh_get_cached_hdr(sdata, eth->h_dest); ++ ++ if (!entry && (mesh_hdr->flags & MESH_FLAGS_AE)) { + struct mesh_path *mppath; + char *proxied_addr; + bool update = false; +@@ -2862,11 +2868,23 @@ ieee80211_rx_mesh_data(struct ieee80211_ + info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING; + info->control.vif = &sdata->vif; + info->control.jiffies = jiffies; ++ fwd_skb->dev = sdata->dev; + if (multicast) { + IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); + memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); + /* update power mode indication when forwarding */ + ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr); ++ } else if (entry) { ++ struct ieee80211_hdr *ehdr = (struct ieee80211_hdr *)entry->hdr; ++ ++ ether_addr_copy(fwd_hdr->addr1, ehdr->addr1); ++ ether_addr_copy(fwd_hdr->addr2, sdata->vif.addr); ++ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); ++ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); ++ qos[0] = fwd_skb->priority; ++ qos[1] = ieee80211_get_qos_ctl(ehdr)[1]; ++ __ieee80211_mesh_xmit_fast(sdata, entry, fwd_skb); ++ return RX_QUEUED; + } else if (!mesh_nexthop_lookup(sdata, fwd_skb)) { + /* mesh power mode flags updated in mesh_nexthop_lookup */ + IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); +@@ -2883,7 +2901,6 @@ ieee80211_rx_mesh_data(struct ieee80211_ + } + + IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); +- fwd_skb->dev = sdata->dev; + ieee80211_add_pending_skb(local, fwd_skb); + + rx_accept: diff --git a/package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch b/package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch new file mode 100644 index 0000000000..d9af8c7929 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch @@ -0,0 +1,32 @@ +From: Felix Fietkau +Date: Mon, 20 Feb 2023 12:50:50 +0100 +Subject: [PATCH] mac80211: fix mesh forwarding + +Linearize packets (needed for forwarding A-MSDU subframes). +Fix network header offset to fix flow dissector (and fair queueing). + +Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2847,6 +2847,9 @@ ieee80211_rx_mesh_data(struct ieee80211_ + + if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr))) + return RX_DROP_UNUSABLE; ++ ++ if (skb_linearize(fwd_skb)) ++ return RX_DROP_UNUSABLE; + } + + fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr)); +@@ -2861,7 +2864,7 @@ ieee80211_rx_mesh_data(struct ieee80211_ + hdrlen += ETH_ALEN; + else + fwd_skb->protocol = htons(fwd_skb->len - hdrlen); +- skb_set_network_header(fwd_skb, hdrlen); ++ skb_set_network_header(fwd_skb, hdrlen + 2); + + info = IEEE80211_SKB_CB(fwd_skb); + memset(info, 0, sizeof(*info)); diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch index 70d4e89c90..817be9e4d2 100644 --- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch +++ b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch @@ -87,7 +87,7 @@ CFG80211_TESTMODE_DUMP(ieee80211_testmode_dump) --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1520,6 +1520,7 @@ struct ieee80211_local { +@@ -1536,6 +1536,7 @@ struct ieee80211_local { int dynamic_ps_forced_timeout; int user_power_level; /* in dBm, for all interfaces */ From 30f2d516ba7be08f06f7ca8767472c3ea5678706 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 6 Feb 2023 23:22:43 +0100 Subject: [PATCH 15/22] tools/squashfs4: add new tool for squashfs4 images squashfs tool is finally reborn and correctly maintained. Introduce the new version as a replacement for squasfs4kit as it was a fork and also abandoned. Add additional patch to add the missing feature present in squashfskit4 but still missing on this new project. Backport each required patch that fix compilation error on macos. Signed-off-by: Christian Marangi --- tools/Makefile | 6 +- tools/squashfs4/Makefile | 41 ++++ ...nd-make-some-header-includes-conditi.patch | 39 ++++ ...-Mksquashfs-Make-sysinfo-conditional.patch | 30 +++ .../patches/003-Only-use-available-CPUs.patch | 92 +++++++++ ...k-strdupa-with-POSIX-strdup-and-free.patch | 37 ++++ ...itinfo-sigtimedwait-if-not-supported.patch | 192 ++++++++++++++++++ ...nto-the-linux-only-section-should-fi.patch | 49 +++++ ...ompilation-error-for-missing-sysctl..patch | 26 +++ tools/squashfs4/patches/100-portability.patch | 37 ++++ ...rt-multiple-lzma-configuration-optio.patch | 167 +++++++++++++++ 11 files changed, 713 insertions(+), 3 deletions(-) create mode 100644 tools/squashfs4/Makefile create mode 100644 tools/squashfs4/patches/001-Unsquashfs-Add-and-make-some-header-includes-conditi.patch create mode 100644 tools/squashfs4/patches/002-Mksquashfs-Make-sysinfo-conditional.patch create mode 100644 tools/squashfs4/patches/003-Only-use-available-CPUs.patch create mode 100644 tools/squashfs4/patches/004-action-rework-strdupa-with-POSIX-strdup-and-free.patch create mode 100644 tools/squashfs4/patches/005-Don-t-use-sigwaitinfo-sigtimedwait-if-not-supported.patch create mode 100644 tools/squashfs4/patches/006-Move-sysinfo.h-into-the-linux-only-section-should-fi.patch create mode 100644 tools/squashfs4/patches/007-Unsquashfs-fix-compilation-error-for-missing-sysctl..patch create mode 100644 tools/squashfs4/patches/100-portability.patch create mode 100644 tools/squashfs4/patches/101-xz_wrapper-support-multiple-lzma-configuration-optio.patch diff --git a/tools/Makefile b/tools/Makefile index aa80ee4ba6..bdd9f0a257 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -59,7 +59,7 @@ tools-y += patch-image tools-y += patchelf tools-y += pkgconf tools-y += quilt -tools-y += squashfskit4 +tools-y += squashfs4 tools-y += sstrip tools-y += zip tools-y += zlib @@ -117,11 +117,11 @@ $(curdir)/pkgconf/compile := $(curdir)/meson/compile $(curdir)/quilt/compile := $(curdir)/autoconf/compile $(curdir)/findutils/compile $(curdir)/sdcc/compile := $(curdir)/bison/compile $(curdir)/squashfs3-lzma/compile := $(curdir)/lzma-old/compile -$(curdir)/squashfskit4/compile := $(curdir)/xz/compile $(curdir)/zlib/compile +$(curdir)/squashfs4/compile := $(curdir)/xz/compile $(curdir)/zlib/compile $(curdir)/zstd/compile := $(curdir)/meson/compile ifneq ($(HOST_OS),Linux) - $(curdir)/squashfskit4/compile += $(curdir)/coreutils/compile + $(curdir)/squashfs4/compile += $(curdir)/coreutils/compile tools-y += coreutils endif ifeq ($(HOST_OS),Darwin) diff --git a/tools/squashfs4/Makefile b/tools/squashfs4/Makefile new file mode 100644 index 0000000000..9d4f6babfc --- /dev/null +++ b/tools/squashfs4/Makefile @@ -0,0 +1,41 @@ +# +# Copyright (C) 2006-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=squashfs4 +PKG_CPE_ID:=cpe:/a:phillip_lougher:squashfs +PKG_VERSION:=4.5.1 +PKG_RELEASE=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/plougher/squashfs-tools +PKG_SOURCE_DATE:=2022-03-17 +PKG_SOURCE_VERSION:=afdd63fc386919b4aa40d573b0a6069414d14317 +PKG_MIRROR_HASH:=caedb66cf6dcbdcee0d1525923e203d003ef15f34a13a328686794666f16171f + +include $(INCLUDE_DIR)/host-build.mk + +define Host/Compile + +$(HOST_MAKE_VARS) \ + $(MAKE) -C $(HOST_BUILD_DIR)/squashfs-tools \ + XZ_SUPPORT=1 \ + LZMA_XZ_SUPPORT=1 \ + EXTRA_CFLAGS="-I$(STAGING_DIR_HOST)/include" \ + mksquashfs unsquashfs +endef + +define Host/Install + $(INSTALL_BIN) $(HOST_BUILD_DIR)/squashfs-tools/mksquashfs $(STAGING_DIR_HOST)/bin/mksquashfs4 + $(INSTALL_BIN) $(HOST_BUILD_DIR)/squashfs-tools/unsquashfs $(STAGING_DIR_HOST)/bin/unsquashfs4 +endef + +define Host/Clean + rm -f $(STAGING_DIR_HOST)/bin/mksquashfs4 + rm -f $(STAGING_DIR_HOST)/bin/unsquashfs4 +endef + +$(eval $(call HostBuild)) diff --git a/tools/squashfs4/patches/001-Unsquashfs-Add-and-make-some-header-includes-conditi.patch b/tools/squashfs4/patches/001-Unsquashfs-Add-and-make-some-header-includes-conditi.patch new file mode 100644 index 0000000000..2fdb509492 --- /dev/null +++ b/tools/squashfs4/patches/001-Unsquashfs-Add-and-make-some-header-includes-conditi.patch @@ -0,0 +1,39 @@ +From a9119c969af0a5aa961d56978d5dd4f3eb952667 Mon Sep 17 00:00:00 2001 +From: Phillip Lougher +Date: Mon, 15 Aug 2022 17:04:43 +0100 +Subject: [PATCH 1/1] Unsquashfs: Add and make some header includes conditional + +Fixes https://github.com/plougher/squashfs-tools/issues/122 + +Signed-off-by: Phillip Lougher +--- + squashfs-tools/reader.c | 1 + + squashfs-tools/unsquashfs.c | 5 +++++ + 2 files changed, 6 insertions(+) + +--- a/squashfs-tools/reader.c ++++ b/squashfs-tools/reader.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + #include "squashfs_fs.h" + #include "mksquashfs.h" + #include "caches-queues-lists.h" +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -32,8 +32,13 @@ + #include "stdarg.h" + #include "fnmatch_compat.h" + ++#ifdef __linux__ + #include + #include ++#elif defined __FreeBSD__ ++#include ++#endif ++ + #include + #include + #include diff --git a/tools/squashfs4/patches/002-Mksquashfs-Make-sysinfo-conditional.patch b/tools/squashfs4/patches/002-Mksquashfs-Make-sysinfo-conditional.patch new file mode 100644 index 0000000000..d152181f8a --- /dev/null +++ b/tools/squashfs4/patches/002-Mksquashfs-Make-sysinfo-conditional.patch @@ -0,0 +1,30 @@ +From 374e39a786a5acda841056bec26fd0e0c4d40dac Mon Sep 17 00:00:00 2001 +From: Phillip Lougher +Date: Mon, 15 Aug 2022 17:09:05 +0100 +Subject: [PATCH 1/1] Mksquashfs: Make sysinfo() conditional + +Fixes https://github.com/plougher/squashfs-tools/issues/123 + +Signed-off-by: Phillip Lougher +--- + squashfs-tools/mksquashfs.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -5802,6 +5802,7 @@ static int get_physical_memory() + long long page_size = sysconf(_SC_PAGESIZE); + int phys_mem; + ++#ifdef __linux__ + if(num_pages == -1 || page_size == -1) { + struct sysinfo sys; + int res = sysinfo(&sys); +@@ -5812,6 +5813,7 @@ static int get_physical_memory() + num_pages = sys.totalram; + page_size = sys.mem_unit; + } ++#endif + + phys_mem = num_pages * page_size >> 20; + diff --git a/tools/squashfs4/patches/003-Only-use-available-CPUs.patch b/tools/squashfs4/patches/003-Only-use-available-CPUs.patch new file mode 100644 index 0000000000..4f608b9ed6 --- /dev/null +++ b/tools/squashfs4/patches/003-Only-use-available-CPUs.patch @@ -0,0 +1,92 @@ +From bc8e655a420d2f62bb0597947e96dce7b4d3fb36 Mon Sep 17 00:00:00 2001 +From: Wessel Dankers +Date: Sun, 30 Oct 2022 19:29:28 +0100 +Subject: [PATCH] Only use available CPUs + +Not all online CPUs may be available for the current process, +especially when CPU affinity is involved. In such cases too many +threads will be created, which will then compete unnecessarily +for CPU time. + +Use sched_getaffinity() to determine the correct number of threads +to create. +--- + squashfs-tools/mksquashfs.c | 16 ++++++++++++---- + squashfs-tools/unsquashfs.c | 13 ++++++++++--- + 2 files changed, 22 insertions(+), 7 deletions(-) + +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -52,7 +52,9 @@ + #include + #include + +-#ifndef linux ++#ifdef linux ++#include ++#else + #include + #endif + +@@ -5079,7 +5081,15 @@ static void initialise_threads(int readq + BAD_ERROR("Failed to set signal mask in intialise_threads\n"); + + if(processors == -1) { +-#ifndef linux ++#ifdef linux ++ cpu_set_t cpu_set; ++ CPU_ZERO(&cpu_set); ++ ++ if(sched_getaffinity(0, sizeof cpu_set, &cpu_set) == -1) ++ processors = sysconf(_SC_NPROCESSORS_ONLN); ++ else ++ processors = CPU_COUNT(&cpu_set); ++#else + int mib[2]; + size_t len = sizeof(processors); + +@@ -5096,8 +5106,6 @@ static void initialise_threads(int readq + ERROR_EXIT(" Defaulting to 1\n"); + processors = 1; + } +-#else +- processors = sysconf(_SC_NPROCESSORS_ONLN); + #endif + } + +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -33,6 +33,7 @@ + #include "fnmatch_compat.h" + + #ifdef __linux__ ++#include + #include + #include + #elif defined __FreeBSD__ +@@ -2719,7 +2720,15 @@ void initialise_threads(int fragment_buf + } + + if(processors == -1) { +-#ifndef linux ++#ifdef linux ++ cpu_set_t cpu_set; ++ CPU_ZERO(&cpu_set); ++ ++ if(sched_getaffinity(0, sizeof cpu_set, &cpu_set) == -1) ++ processors = sysconf(_SC_NPROCESSORS_ONLN); ++ else ++ processors = CPU_COUNT(&cpu_set); ++#else + int mib[2]; + size_t len = sizeof(processors); + +@@ -2735,8 +2744,6 @@ void initialise_threads(int fragment_buf + "Defaulting to 1\n"); + processors = 1; + } +-#else +- processors = sysconf(_SC_NPROCESSORS_ONLN); + #endif + } + diff --git a/tools/squashfs4/patches/004-action-rework-strdupa-with-POSIX-strdup-and-free.patch b/tools/squashfs4/patches/004-action-rework-strdupa-with-POSIX-strdup-and-free.patch new file mode 100644 index 0000000000..3d6f696c8e --- /dev/null +++ b/tools/squashfs4/patches/004-action-rework-strdupa-with-POSIX-strdup-and-free.patch @@ -0,0 +1,37 @@ +From 92e628ec0e26cf091d82356e3b74f73bedf4cfc8 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sat, 15 Oct 2022 00:11:20 +0200 +Subject: [PATCH] action: rework strdupa with POSIX strdup and free + +strdupa is not POSIX and cause compilation error on macos. +Fix this by using strdup and free. + +Signed-off-by: Christian Marangi +Signed-off-by: Phillip Lougher +--- + squashfs-tools/action.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/squashfs-tools/action.c ++++ b/squashfs-tools/action.c +@@ -2415,9 +2415,17 @@ static char *get_start(char *s, int n) + + static int subpathname_fn(struct atom *atom, struct action_data *action_data) + { +- return fnmatch(atom->argv[0], get_start(strdupa(action_data->subpath), +- count_components(atom->argv[0])), +- FNM_PATHNAME|FNM_EXTMATCH) == 0; ++ char *s, *tmp; ++ int ret; ++ ++ s = tmp = strdup(action_data->subpath); ++ tmp = get_start(tmp, count_components(atom->argv[0])); ++ ++ ret = fnmatch(atom->argv[0], tmp, FNM_PATHNAME|FNM_EXTMATCH); ++ ++ free(s); ++ ++ return ret == 0; + } + + /* diff --git a/tools/squashfs4/patches/005-Don-t-use-sigwaitinfo-sigtimedwait-if-not-supported.patch b/tools/squashfs4/patches/005-Don-t-use-sigwaitinfo-sigtimedwait-if-not-supported.patch new file mode 100644 index 0000000000..80e8824c46 --- /dev/null +++ b/tools/squashfs4/patches/005-Don-t-use-sigwaitinfo-sigtimedwait-if-not-supported.patch @@ -0,0 +1,192 @@ +From dbe9747b4f09bd2f4d63af06e55c2c3ed35bfca1 Mon Sep 17 00:00:00 2001 +From: Phillip Lougher +Date: Tue, 7 Feb 2023 23:09:30 +0000 +Subject: [PATCH] Don't use sigwaitinfo()/sigtimedwait() if not supported + +If sigwaitinfo() and sigtimedwait() are not supported, +use sigwait() instead. + +This will disable the queue/caches dump if ^\ (SIGQUIT) +is hit twice within a second. + +But the queue/caches dump is still available if SIGHUP +is sent to the program. + +Currently this check is applied to MAC OS X. FreeBSD and +NetBSD appear to have these functions. + +Signed-off-by: Phillip Lougher +--- + squashfs-tools/info.c | 25 ++------------- + squashfs-tools/signals.h | 54 ++++++++++++++++++++++++++++++++ + squashfs-tools/unsquashfs_info.c | 25 ++------------- + 3 files changed, 60 insertions(+), 44 deletions(-) + create mode 100644 squashfs-tools/signals.h + +--- a/squashfs-tools/info.c ++++ b/squashfs-tools/info.c +@@ -2,7 +2,7 @@ + * Create a squashfs filesystem. This is a highly compressed read only + * filesystem. + * +- * Copyright (c) 2013, 2014, 2019, 2021 ++ * Copyright (c) 2013, 2014, 2019, 2021, 2022, 2023 + * Phillip Lougher + * + * This program is free software; you can redistribute it and/or +@@ -42,6 +42,7 @@ + #include "mksquashfs_error.h" + #include "progressbar.h" + #include "caches-queues-lists.h" ++#include "signals.h" + + static int silent = 0; + static struct dir_ent *ent = NULL; +@@ -144,7 +145,6 @@ void dump_state() + void *info_thrd(void *arg) + { + sigset_t sigmask; +- struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 }; + int sig, waiting = 0; + + sigemptyset(&sigmask); +@@ -152,26 +152,7 @@ void *info_thrd(void *arg) + sigaddset(&sigmask, SIGHUP); + + while(1) { +- if(waiting) +- sig = sigtimedwait(&sigmask, NULL, ×pec); +- else +- sig = sigwaitinfo(&sigmask, NULL); +- +- if(sig == -1) { +- switch(errno) { +- case EAGAIN: +- /* interval timed out */ +- waiting = 0; +- /* FALLTHROUGH */ +- case EINTR: +- /* if waiting, the wait will be longer, but +- that's OK */ +- continue; +- default: +- BAD_ERROR("sigtimedwait/sigwaitinfo failed " +- "because %s\n", strerror(errno)); +- } +- } ++ sig = wait_for_signal(&sigmask, &waiting); + + if(sig == SIGQUIT && !waiting) { + print_filename(); +--- /dev/null ++++ b/squashfs-tools/signals.h +@@ -0,0 +1,54 @@ ++#ifndef SIGNALS_H ++#define SIGNALS_H ++/* ++ * Create a squashfs filesystem. This is a highly compressed read only ++ * filesystem. ++ * ++ * Copyright (c) 2023 ++ * Phillip Lougher ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2, ++ * or (at your option) any later version. ++ * ++ * This program 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * signals.h ++ */ ++ ++static inline int wait_for_signal(sigset_t *sigmask, int *waiting) ++{ ++ int sig; ++ ++#if defined(__APPLE__) && defined(__MACH__) ++ sigwait(sigmask, &sig); ++ *waiting = 0; ++#else ++ struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 }; ++ ++ while(1) { ++ if(*waiting) ++ sig = sigtimedwait(sigmask, NULL, ×pec); ++ else ++ sig = sigwaitinfo(sigmask, NULL); ++ ++ if(sig != -1) ++ break; ++ ++ if(errno == EAGAIN) ++ *waiting = 0; ++ else if(errno != EINTR) ++ BAD_ERROR("sigtimedwait/sigwaitinfo failed because %s\n", strerror(errno)); ++ } ++#endif ++ return sig; ++} ++#endif +--- a/squashfs-tools/unsquashfs_info.c ++++ b/squashfs-tools/unsquashfs_info.c +@@ -2,7 +2,7 @@ + * Create a squashfs filesystem. This is a highly compressed read only + * filesystem. + * +- * Copyright (c) 2013, 2021 ++ * Copyright (c) 2013, 2021, 2023 + * Phillip Lougher + * + * This program is free software; you can redistribute it and/or +@@ -40,6 +40,7 @@ + #include "squashfs_fs.h" + #include "unsquashfs.h" + #include "unsquashfs_error.h" ++#include "signals.h" + + char *pathname = NULL; + +@@ -96,7 +97,6 @@ void dump_state() + void *info_thrd(void *arg) + { + sigset_t sigmask; +- struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 }; + int sig, waiting = 0; + + sigemptyset(&sigmask); +@@ -104,26 +104,7 @@ void *info_thrd(void *arg) + sigaddset(&sigmask, SIGHUP); + + while(1) { +- if(waiting) +- sig = sigtimedwait(&sigmask, NULL, ×pec); +- else +- sig = sigwaitinfo(&sigmask, NULL); +- +- if(sig == -1) { +- switch(errno) { +- case EAGAIN: +- /* interval timed out */ +- waiting = 0; +- /* FALLTHROUGH */ +- case EINTR: +- /* if waiting, the wait will be longer, but +- that's OK */ +- continue; +- default: +- BAD_ERROR("sigtimedwait/sigwaitinfo failed " +- "because %s\n", strerror(errno)); +- } +- } ++ sig = wait_for_signal(&sigmask, &waiting); + + if(sig == SIGQUIT && !waiting) { + if(pathname) diff --git a/tools/squashfs4/patches/006-Move-sysinfo.h-into-the-linux-only-section-should-fi.patch b/tools/squashfs4/patches/006-Move-sysinfo.h-into-the-linux-only-section-should-fi.patch new file mode 100644 index 0000000000..364356188f --- /dev/null +++ b/tools/squashfs4/patches/006-Move-sysinfo.h-into-the-linux-only-section-should-fi.patch @@ -0,0 +1,49 @@ +From b2f6454a2b2517cfba7a24cf02e9bdf3b959c86a Mon Sep 17 00:00:00 2001 +From: Tony Butler +Date: Sat, 18 Feb 2023 13:20:48 -0800 +Subject: [PATCH] Move sysinfo.h into the linux-only section, should fix build + on MacOS. + +All compilers set `__linux__`, but `linux` may not be defined, and usage +was mixed. Use `__linux__` everywhere instead. + +Signed-off-by: Tony Butler +--- + squashfs-tools/mksquashfs.c | 6 +++--- + squashfs-tools/unsquashfs.c | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -50,9 +50,9 @@ + #include + #include + #include +-#include + +-#ifdef linux ++#ifdef __linux__ ++#include + #include + #else + #include +@@ -5081,7 +5081,7 @@ static void initialise_threads(int readq + BAD_ERROR("Failed to set signal mask in intialise_threads\n"); + + if(processors == -1) { +-#ifdef linux ++#ifdef __linux__ + cpu_set_t cpu_set; + CPU_ZERO(&cpu_set); + +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -2720,7 +2720,7 @@ void initialise_threads(int fragment_buf + } + + if(processors == -1) { +-#ifdef linux ++#ifdef __linux__ + cpu_set_t cpu_set; + CPU_ZERO(&cpu_set); + diff --git a/tools/squashfs4/patches/007-Unsquashfs-fix-compilation-error-for-missing-sysctl..patch b/tools/squashfs4/patches/007-Unsquashfs-fix-compilation-error-for-missing-sysctl..patch new file mode 100644 index 0000000000..b7db00e4cb --- /dev/null +++ b/tools/squashfs4/patches/007-Unsquashfs-fix-compilation-error-for-missing-sysctl..patch @@ -0,0 +1,26 @@ +From dcf492077ef10ed7550b6e2b38b81318645bbdd5 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sun, 19 Feb 2023 04:36:01 +0100 +Subject: [PATCH] Unsquashfs: fix compilation error for missing sysctl.h on + macos + +Currently the include of sys/sysctl.h is guarded and done only for +FreeBSD system. Remove this to fix compilation error on macos following +the same pattern done in mksquashfs.c + +Signed-off-by: Christian Marangi +--- + squashfs-tools/unsquashfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -36,7 +36,7 @@ + #include + #include + #include +-#elif defined __FreeBSD__ ++#else + #include + #endif + diff --git a/tools/squashfs4/patches/100-portability.patch b/tools/squashfs4/patches/100-portability.patch new file mode 100644 index 0000000000..fe804d4476 --- /dev/null +++ b/tools/squashfs4/patches/100-portability.patch @@ -0,0 +1,37 @@ +--- a/squashfs-tools/xattr.c ++++ b/squashfs-tools/xattr.c +@@ -115,6 +115,7 @@ int xattr_get_prefix(struct xattr_list * + + static int read_xattrs_from_system(char *filename, struct xattr_list **xattrs) + { ++#if defined(linux) + ssize_t size, vsize; + char *xattr_names, *p; + int i; +@@ -227,6 +228,10 @@ failed: + free(xattr_list); + free(xattr_names); + return 0; ++#else ++ *xattrs = NULL; ++ return 0; ++#endif + } + + +--- a/squashfs-tools/unsquashfs_xattr.c ++++ b/squashfs-tools/unsquashfs_xattr.c +@@ -36,6 +36,7 @@ extern int strict_errors; + + int write_xattr(char *pathname, unsigned int xattr) + { ++#if defined(linux) + unsigned int count; + struct xattr_list *xattr_list; + int i; +@@ -147,4 +148,5 @@ int write_xattr(char *pathname, unsigned + free_xattr(xattr_list, count); + + return !failed; ++#endif + } diff --git a/tools/squashfs4/patches/101-xz_wrapper-support-multiple-lzma-configuration-optio.patch b/tools/squashfs4/patches/101-xz_wrapper-support-multiple-lzma-configuration-optio.patch new file mode 100644 index 0000000000..c882529cad --- /dev/null +++ b/tools/squashfs4/patches/101-xz_wrapper-support-multiple-lzma-configuration-optio.patch @@ -0,0 +1,167 @@ +From f49793cfbd72fdc40ab75dbffef42dca774701d1 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 14 Oct 2022 15:59:16 +0200 +Subject: [PATCH] xz_wrapper: support multiple lzma configuration options + +Add option to configure preset, lc, lp and pb lzma parameters. +-Xpreset can be both a level or set to 'extreme' to use the lzma extreme +compression options. + +New option added: + -Xpreset + -Xlc + -Xlp + -Xpb + +Signed-off-by: Christian Marangi +--- + squashfs-tools/xz_wrapper.c | 112 +++++++++++++++++++++++++++++++++++- + 1 file changed, 109 insertions(+), 3 deletions(-) + +--- a/squashfs-tools/xz_wrapper.c ++++ b/squashfs-tools/xz_wrapper.c +@@ -44,7 +44,10 @@ static struct bcj bcj[] = { + static int filter_count = 1; + static int dictionary_size = 0; + static float dictionary_percent = 0; +- ++static int preset = LZMA_PRESET_DEFAULT; ++static int lc = -1; ++static int lp = -1; ++static int pb = -1; + + /* + * This function is called by the options parsing code in mksquashfs.c +@@ -53,6 +56,11 @@ static float dictionary_percent = 0; + * Two specific options are supported: + * -Xbcj + * -Xdict-size ++ * -Xpreset ++ * -Xe ++ * -Xlc ++ * -Xlp ++ * -Xpb + * + * This function returns: + * >=0 (number of additional args parsed) on success +@@ -141,6 +149,85 @@ static int xz_options(char *argv[], int + } + + return 1; ++ } else if(strcmp(argv[0], "-Xpreset") == 0) { ++ char *b; ++ long val; ++ ++ if(argc < 2) { ++ fprintf(stderr, "xz: -Xpreset missing preset-level\n"); ++ goto failed; ++ } ++ ++ if (strcmp(argv[1], "extreme") == 0) { ++ preset = LZMA_PRESET_EXTREME; ++ ++ return 1; ++ } ++ ++ val = strtol(argv[1], &b, 10); ++ if ((int) val < 0 || (int) val & ~LZMA_PRESET_LEVEL_MASK) { ++ fprintf(stderr, "xz: -Xpreset can't be " ++ "negative or more than the max preset\n"); ++ goto failed; ++ } ++ ++ preset = (int) val; ++ ++ return 1; ++ } else if(strcmp(argv[0], "-Xlc") == 0) { ++ char *b; ++ long val; ++ ++ if(argc < 2) { ++ fprintf(stderr, "xz: -Xlc missing value\n"); ++ goto failed; ++ } ++ ++ val = strtol(argv[1], &b, 10); ++ if ((int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) { ++ fprintf(stderr, "xz: -Xlc invalid value\n"); ++ goto failed; ++ } ++ ++ lc = (int) val; ++ ++ return 1; ++ } else if(strcmp(argv[0], "-Xlp") == 0) { ++ char *b; ++ long val; ++ ++ if(argc < 2) { ++ fprintf(stderr, "xz: -Xlp missing value\n"); ++ goto failed; ++ } ++ ++ val = strtol(argv[1], &b, 10); ++ if ((int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) { ++ fprintf(stderr, "xz: -Xlc invalid value\n"); ++ goto failed; ++ } ++ ++ lp = (int) val; ++ ++ return 1; ++ } else if(strcmp(argv[0], "-Xpb") == 0) { ++ char *b; ++ long val; ++ ++ if(argc < 2) { ++ fprintf(stderr, "xz: -Xpb missing value\n"); ++ goto failed; ++ } ++ ++ val = strtol(argv[1], &b, 10); ++ if ((int) val < LZMA_PB_MIN || (int) val > LZMA_PB_MAX) { ++ fprintf(stderr, "xz: -Xlc invalid value\n"); ++ goto failed; ++ } ++ ++ pb = (int) val; ++ ++ return 1; + } + + return -1; +@@ -446,11 +533,20 @@ static int xz_compress(void *strm, void + for(i = 0; i < stream->filters; i++) { + struct filter *filter = &stream->filter[i]; + +- if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT)) ++ if(lzma_lzma_preset(&stream->opt, preset)) + goto failed; + + stream->opt.dict_size = stream->dictionary_size; + ++ if (lc >= 0) ++ stream->opt.lc = lc; ++ ++ if (lp >= 0) ++ stream->opt.lp = lp; ++ ++ if (pb >= 0) ++ stream->opt.pb = pb; ++ + filter->length = 0; + res = lzma_stream_buffer_encode(filter->filter, + LZMA_CHECK_CRC32, NULL, src, size, filter->buffer, +@@ -521,6 +617,12 @@ static void xz_usage(FILE *stream) + fprintf(stream, " header as either 2^n or as 2^n+2^(n+1).\n\t\t"); + fprintf(stream, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or"); + fprintf(stream, " 32K, 16K, 8K\n\t\tetc.\n"); ++ fprintf(stream, "\t -Xpreset \n"); ++ fprintf(stream, "\t\tUse as the custom preset to use"); ++ fprintf(stream, " on compress. Can be a level number or extreme.\n"); ++ fprintf(stream, "\t -Xlc \n"); ++ fprintf(stream, "\t -Xlp \n"); ++ fprintf(stream, "\t -Xpb \n"); + } + + From a33b97dcb1bd6e68f01c571e92ef02c3ab721523 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 6 Feb 2023 23:28:14 +0100 Subject: [PATCH 16/22] image: update LZMA_XZ_OPTIONS with new squashfs4 tool The -Xpreset option changed format and dropped the -Xe and just require the extreme string to be passed to the -Xpreset option. Update the LZMA_XZ_OPTIONS to reflect this change. Signed-off-by: Christian Marangi --- include/image.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/image.mk b/include/image.mk index b801ef993c..ef242db96e 100644 --- a/include/image.mk +++ b/include/image.mk @@ -77,7 +77,7 @@ SQUASHFSOPT := -b $(SQUASHFS_BLOCKSIZE) SQUASHFSOPT += -p '/dev d 755 0 0' -p '/dev/console c 600 0 0 5 1' SQUASHFSOPT += $(if $(CONFIG_SELINUX),-xattrs,-no-xattrs) SQUASHFSCOMP := gzip -LZMA_XZ_OPTIONS := -Xpreset 9 -Xe -Xlc 0 -Xlp 2 -Xpb 2 +LZMA_XZ_OPTIONS := -Xpreset extreme -Xlc 0 -Xlp 2 -Xpb 2 ifeq ($(CONFIG_SQUASHFS_XZ),y) ifneq ($(filter arm x86 powerpc sparc,$(LINUX_KARCH)),) BCJ_FILTER:=-Xbcj $(LINUX_KARCH) From eac6fe6f742c7da980799b5583819183a9f33c01 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 14 Oct 2022 17:36:21 +0200 Subject: [PATCH 17/22] tools/squashfskit4: drop unused tool Drop squashfskit4 tool as it got replaced by new version of squashfs4 tool. Signed-off-by: Christian Marangi --- tools/squashfskit4/Makefile | 41 ------------------- .../patches/0001-fix-version.sh.patch | 21 ---------- ...002-fix-build-failure-against-gcc-10.patch | 41 ------------------- .../patches/0010-portability.patch | 37 ----------------- .../patches/0020-big-endian.patch | 14 ------- 5 files changed, 154 deletions(-) delete mode 100644 tools/squashfskit4/Makefile delete mode 100644 tools/squashfskit4/patches/0001-fix-version.sh.patch delete mode 100644 tools/squashfskit4/patches/0002-fix-build-failure-against-gcc-10.patch delete mode 100644 tools/squashfskit4/patches/0010-portability.patch delete mode 100644 tools/squashfskit4/patches/0020-big-endian.patch diff --git a/tools/squashfskit4/Makefile b/tools/squashfskit4/Makefile deleted file mode 100644 index 1800306d33..0000000000 --- a/tools/squashfskit4/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# -# Copyright (C) 2009-2012 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# -include $(TOPDIR)/rules.mk - -PKG_NAME:=squashfskit4 -PKG_VERSION:=4.14 -PKG_RELEASE:=3 -PKG_SOURCE:=squashfskit-v$(PKG_VERSION).tar.xz -PKG_SOURCE_URL:=https://github.com/squashfskit/squashfskit/releases/download/v$(PKG_VERSION)/ -PKG_HASH:=5761aaa3aedc4f7112b708367d891c9abdc1ffea972e3fe47923ddba23984d95 - -HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/squashfskit-v$(PKG_VERSION) - -include $(INCLUDE_DIR)/host-build.mk - -define Host/Compile - +$(HOST_MAKE_VARS) \ - $(MAKE) -C $(HOST_BUILD_DIR)/squashfs-tools \ - XZ_SUPPORT=1 \ - LZMA_XZ_SUPPORT=1 \ - XATTR_SUPPORT=1 \ - LZMA_LIB="$(STAGING_DIR_HOST)/lib/liblzma.a" \ - EXTRA_CFLAGS="-I$(STAGING_DIR_HOST)/include" \ - mksquashfs unsquashfs -endef - -define Host/Install - $(INSTALL_BIN) $(HOST_BUILD_DIR)/squashfs-tools/mksquashfs $(STAGING_DIR_HOST)/bin/mksquashfs4 - $(INSTALL_BIN) $(HOST_BUILD_DIR)/squashfs-tools/unsquashfs $(STAGING_DIR_HOST)/bin/unsquashfs4 -endef - -define Host/Clean - rm -f $(STAGING_DIR_HOST)/bin/mksquashfs4 - rm -f $(STAGING_DIR_HOST)/bin/unsquashfs4 -endef - -$(eval $(call HostBuild)) diff --git a/tools/squashfskit4/patches/0001-fix-version.sh.patch b/tools/squashfskit4/patches/0001-fix-version.sh.patch deleted file mode 100644 index 5f0894bc17..0000000000 --- a/tools/squashfskit4/patches/0001-fix-version.sh.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/squashfs-tools/version.sh -+++ b/squashfs-tools/version.sh -@@ -27,13 +27,11 @@ if [ -z "$OUTPUT" ] ; then - fi - - our_date() { --case $(uname) in --NetBSD|OpenBSD|DragonFly|FreeBSD|Darwin) -- date -r "$1" "$2" -- ;; --*) -- date -d "@$1" "$2" --esac -+ if date --version 2>&1 | grep -q "GNU coreutils"; then -+ date -d "@$1" "$2" -+ else -+ date -r "$1" "$2" -+ fi - } - - try_version() { diff --git a/tools/squashfskit4/patches/0002-fix-build-failure-against-gcc-10.patch b/tools/squashfskit4/patches/0002-fix-build-failure-against-gcc-10.patch deleted file mode 100644 index de77299978..0000000000 --- a/tools/squashfskit4/patches/0002-fix-build-failure-against-gcc-10.patch +++ /dev/null @@ -1,41 +0,0 @@ -From fe2f5da4b0f8994169c53e84b7cb8a0feefc97b5 Mon Sep 17 00:00:00 2001 -From: Sergei Trofimovich -Date: Sun, 26 Jan 2020 18:35:13 +0000 -Subject: [PATCH] squashfs-tools: fix build failure against gcc-10 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -On gcc-10 (and gcc-9 -fno-common) build fails as: - -``` -cc ... -o mksquashfs -ld: read_fs.o:(.bss+0x0): - multiple definition of `fwriter_buffer'; mksquashfs.o:(.bss+0x400c90): first defined here -ld: read_fs.o:(.bss+0x8): - multiple definition of `bwriter_buffer'; mksquashfs.o:(.bss+0x400c98): first defined here -``` - -gcc-10 will change the default from -fcommon to fno-common: -https://gcc.gnu.org/PR85678. - -The error also happens if CFLAGS=-fno-common passed explicitly. - -Reported-by: Toralf Förster -Bug: https://bugs.gentoo.org/706456 -Signed-off-by: Sergei Trofimovich ---- - squashfs-tools/mksquashfs.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/squashfs-tools/mksquashfs.h -+++ b/squashfs-tools/mksquashfs.h -@@ -133,7 +133,7 @@ struct append_file { - #define BLOCK_OFFSET 2 - - extern struct cache *reader_buffer, *fragment_buffer, *reserve_cache; --struct cache *bwriter_buffer, *fwriter_buffer; -+extern struct cache *bwriter_buffer, *fwriter_buffer; - extern struct queue *to_reader, *to_deflate, *to_writer, *from_writer, - *locked_fragment, *to_process_frag; - extern struct append_file **file_mapping; diff --git a/tools/squashfskit4/patches/0010-portability.patch b/tools/squashfskit4/patches/0010-portability.patch deleted file mode 100644 index 2cc50ae8f0..0000000000 --- a/tools/squashfskit4/patches/0010-portability.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- a/squashfs-tools/xattr.c -+++ b/squashfs-tools/xattr.c -@@ -113,6 +113,7 @@ static int get_prefix(struct xattr_list - - static int read_xattrs_from_system(char *filename, struct xattr_list **xattrs) - { -+#if defined(linux) - ssize_t size, vsize; - char *xattr_names, *p; - int i; -@@ -222,6 +223,10 @@ failed: - free(xattr_list); - free(xattr_names); - return 0; -+#else -+ *xattrs = NULL; -+ return 0; -+#endif - } - - ---- a/squashfs-tools/unsquashfs_xattr.c -+++ b/squashfs-tools/unsquashfs_xattr.c -@@ -34,6 +34,7 @@ extern int user_xattrs; - - void write_xattr(char *pathname, unsigned int xattr) - { -+#if defined(linux) - unsigned int count; - struct xattr_list *xattr_list; - int i; -@@ -136,4 +137,5 @@ void write_xattr(char *pathname, unsigne - } - - free_xattr(xattr_list, count); -+#endif - } diff --git a/tools/squashfskit4/patches/0020-big-endian.patch b/tools/squashfskit4/patches/0020-big-endian.patch deleted file mode 100644 index b388cb4d12..0000000000 --- a/tools/squashfskit4/patches/0020-big-endian.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/squashfs-tools/xz_wrapper.c -+++ b/squashfs-tools/xz_wrapper.c -@@ -192,7 +192,10 @@ static void xz_display_options(void *buf - if(size != sizeof(struct comp_opts)) - goto failed; - -- SQUASHFS_INSWAP_LZMA_COMP_OPTS(comp_opts); -+#if __BYTE_ORDER == __BIG_ENDIAN -+ comp_opts->dictionary_size = inswap_le32(comp_opts->dictionary_size); -+ comp_opts->flags = inswap_le32(comp_opts->flags); -+#endif - - dictionary_size = comp_opts->dictionary_size; - flags = comp_opts->flags; From 7e7e76afca7877b97bc049d8f5a83a840a20a2af Mon Sep 17 00:00:00 2001 From: Eneas U de Queiroz Date: Tue, 7 Feb 2023 18:14:27 -0300 Subject: [PATCH 18/22] openssl: bump to 3.0.8 This is a major update to the current LTS version, supported until 2026-09-07. Changelog: https://github.com/openssl/openssl/blob/openssl-3.0.8/CHANGES.md Signed-off-by: Eneas U de Queiroz --- include/openssl-engine.mk | 4 +- package/libs/openssl/Config.in | 40 +- package/libs/openssl/Makefile | 20 +- ...m-ppc-xlate.pl-add-linux64v2-flavour.patch | 55 - .../patches/100-Configure-afalg-support.patch | 2 +- .../120-strip-cflags-from-binary.patch | 8 +- .../patches/130-dont-build-fuzz-docs.patch | 20 + .../patches/130-dont-build-tests-fuzz.patch | 29 - .../patches/140-allow-prefer-chacha20.patch | 60 +- .../150-openssl.cnf-add-engines-conf.patch | 4 +- ...o-save-ioctl-if-EVP_MD_.FLAG_ONESHOT.patch | 58 - ..._devcrypto-add-configuration-options.patch | 566 ---- ...ypto-add-command-to-dump-driver-info.patch | 273 -- ...o-make-the-dev-crypto-engine-dynamic.patch | 2718 ----------------- ...default-to-not-use-digests-in-engine.patch | 41 - ...to-ignore-error-when-closing-session.patch | 24 - 16 files changed, 87 insertions(+), 3835 deletions(-) delete mode 100644 package/libs/openssl/patches/001-crypto-perlasm-ppc-xlate.pl-add-linux64v2-flavour.patch create mode 100644 package/libs/openssl/patches/130-dont-build-fuzz-docs.patch delete mode 100644 package/libs/openssl/patches/130-dont-build-tests-fuzz.patch delete mode 100644 package/libs/openssl/patches/400-eng_devcrypto-save-ioctl-if-EVP_MD_.FLAG_ONESHOT.patch delete mode 100644 package/libs/openssl/patches/410-eng_devcrypto-add-configuration-options.patch delete mode 100644 package/libs/openssl/patches/420-eng_devcrypto-add-command-to-dump-driver-info.patch delete mode 100644 package/libs/openssl/patches/430-e_devcrypto-make-the-dev-crypto-engine-dynamic.patch delete mode 100644 package/libs/openssl/patches/500-e_devcrypto-default-to-not-use-digests-in-engine.patch delete mode 100644 package/libs/openssl/patches/510-e_devcrypto-ignore-error-when-closing-session.patch diff --git a/include/openssl-engine.mk b/include/openssl-engine.mk index d8baba482e..891d284f12 100644 --- a/include/openssl-engine.mk +++ b/include/openssl-engine.mk @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only # -# Copyright (C) 2022 Enéas Ulir de Queiroz +# Copyright (C) 2022-2023 Enéas Ulir de Queiroz -ENGINES_DIR=engines-1.1 +ENGINES_DIR=engines-3 define Package/openssl/engine/Default SECTION:=libs diff --git a/package/libs/openssl/Config.in b/package/libs/openssl/Config.in index bc2f0584b6..6a668fe4cd 100644 --- a/package/libs/openssl/Config.in +++ b/package/libs/openssl/Config.in @@ -8,11 +8,9 @@ config OPENSSL_OPTIMIZE_SPEED prompt "Enable optimization for speed instead of size" select OPENSSL_WITH_ASM help - Enabling this option increases code size (around 20%) and - performance. The increase in performance and size depends on the - target CPU. EC and AES seem to benefit the most, with EC speed - increased by 20%-50% (mipsel & x86). - AES-GCM is supposed to be 3x faster on x86. YMMV. + Enabling this option increases code size and performance. + The increase in performance and size depends on the + target CPU. EC and AES seem to benefit the most. config OPENSSL_WITH_ASM bool @@ -22,19 +20,7 @@ config OPENSSL_WITH_ASM help Disabling this option will reduce code size and performance. The increase in performance and size depends on the target - CPU and on the algorithms being optimized. As of 1.1.0i*: - - Platform Pkg Inc. Algorithms where assembly is used - ~% Speed Increase - aarch64 174K BN, aes, sha1, sha256, sha512, nist256, poly1305 - arm 152K BN, aes, sha1, sha256, sha512, nist256, poly1305 - i386 183K BN+147%, aes+300%, rc4+55%, sha1+160%, sha256+114%, sha512+270%, nist256+282%, poly1305+292% - mipsel 1.5K BN+97%, aes+4%, sha1+94%, sha256+60% - mips64 3.7K BN, aes, sha1, sha256, sha512, poly1305 - powerpc 20K BN, aes, sha1, sha256, sha512, poly1305 - x86_64 228K BN+220%, aes+173%, rc4+38%, sha1+40%, sha256+64%, sha512+31%, nist256+354%, poly1305+228% - - * Only most common algorithms shown. Your mileage may vary. - BN (bignum) performance was measured using RSA sign/verify. + CPU and on the algorithms being optimized. config OPENSSL_WITH_SSE2 bool @@ -42,21 +28,17 @@ config OPENSSL_WITH_SSE2 prompt "Enable use of x86 SSE2 instructions" depends on OPENSSL_WITH_ASM && i386 help - Use of SSE2 instructions greatly increase performance (up to - 3x faster) with a minimum (~0.2%, or 23KB) increase in package - size, but it will bring no benefit if your hardware does not - support them, such as Geode GX and LX. In this case you may - save 23KB by saying yes here. AMD Geode NX, and Intel - Pentium 4 and above support SSE2. + Use of SSE2 instructions greatly increase performance with a + minimum increase in package size, but it will bring no benefit + if your hardware does not support them, such as Geode GX and LX. + AMD Geode NX, and Intel Pentium 4 and above support SSE2. config OPENSSL_WITH_DEPRECATED bool default y - prompt "Include deprecated APIs (See help for a list of packages that need this)" + prompt "Include deprecated APIs" help - Since openssl 1.1.x is still new to openwrt, some packages - requiring this option do not list it as a requirement yet: - * freeswitch-stable, freeswitch, python, python3, squid. + This drops all deprecated API, including engine support. config OPENSSL_NO_DEPRECATED bool @@ -84,7 +66,6 @@ config OPENSSL_WITH_TLS13 protocol; * to increase performance by reducing the number of round-trips when performing a full handshake. - It increases package size by ~4KB. config OPENSSL_WITH_DTLS bool @@ -233,6 +214,7 @@ comment "Engine/Hardware Support" config OPENSSL_ENGINE bool "Enable engine support" + select OPENSSL_WITH_DEPRECATED default y help This enables alternative cryptography implementations, diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile index 4883ef82ea..7dc4df0982 100644 --- a/package/libs/openssl/Makefile +++ b/package/libs/openssl/Makefile @@ -8,14 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openssl -PKG_BASE:=1.1.1 -PKG_BUGFIX:=t -PKG_VERSION:=$(PKG_BASE)$(PKG_BUGFIX) +PKG_VERSION:=3.0.8 PKG_RELEASE:=1 PKG_USE_MIPS16:=0 PKG_BUILD_PARALLEL:=1 +PKG_BASE:=$(subst $(space),.,$(wordlist 1,2,$(subst .,$(space),$(PKG_VERSION)))) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:= \ http://www.openssl.org/source/ \ @@ -25,9 +24,9 @@ PKG_SOURCE_URL:= \ ftp://ftp.pca.dfn.de/pub/tools/net/openssl/source/ \ ftp://ftp.pca.dfn.de/pub/tools/net/openssl/source/old/$(PKG_BASE)/ -PKG_HASH:=8dee9b24bdb1dcbf0c3d1e9b02fb8f6bf22165e807f45adeb7c9677536859d3b +PKG_HASH:=6c13d2bf38fdf31eac3ce2a347073673f5d63263398f1f69d0df4a41253e4b3e -PKG_LICENSE:=OpenSSL +PKG_LICENSE:=Apache-2.0 PKG_LICENSE_FILES:=LICENSE PKG_MAINTAINER:=Eneas U de Queiroz PKG_CPE_ID:=cpe:/a:openssl:openssl @@ -95,9 +94,10 @@ $(call Package/openssl/Default) DEPENDS:=+OPENSSL_WITH_COMPRESSION:zlib \ +OPENSSL_ENGINE_BUILTIN_AFALG:kmod-crypto-user \ +OPENSSL_ENGINE_BUILTIN_DEVCRYPTO:kmod-cryptodev \ - +OPENSSL_ENGINE_BUILTIN_PADLOCK:kmod-crypto-hw-padlock + +OPENSSL_ENGINE_BUILTIN_PADLOCK:kmod-crypto-hw-padlock \ + +(arm||armeb||mips||mipsel||ppc):libatomic TITLE+= (libraries) - ABI_VERSION:=1.1 + ABI_VERSION:=$(firstword $(subst .,$(space),$(PKG_VERSION))) MENU:=1 endef @@ -186,7 +186,7 @@ and https://openwrt.org/docs/techref/hardware/cryptographic.hardware.accelerator The engine_id is "padlock" endef -OPENSSL_OPTIONS:= shared +OPENSSL_OPTIONS:= shared no-tests ifndef CONFIG_OPENSSL_WITH_BLAKE2 OPENSSL_OPTIONS += no-blake2 @@ -272,7 +272,7 @@ ifdef CONFIG_OPENSSL_ENGINE OPENSSL_OPTIONS += enable-devcryptoeng endif ifndef CONFIG_OPENSSL_ENGINE_BUILTIN_PADLOCK - OPENSSL_OPTIONS += no-hw-padlock + OPENSSL_OPTIONS += no-padlockeng endif else ifdef CONFIG_PACKAGE_libopenssl-devcrypto @@ -282,7 +282,7 @@ ifdef CONFIG_OPENSSL_ENGINE OPENSSL_OPTIONS += no-afalgeng endif ifndef CONFIG_PACKAGE_libopenssl-padlock - OPENSSL_OPTIONS += no-hw-padlock + OPENSSL_OPTIONS += no-padlockeng endif endif else diff --git a/package/libs/openssl/patches/001-crypto-perlasm-ppc-xlate.pl-add-linux64v2-flavour.patch b/package/libs/openssl/patches/001-crypto-perlasm-ppc-xlate.pl-add-linux64v2-flavour.patch deleted file mode 100644 index 3da67e25fc..0000000000 --- a/package/libs/openssl/patches/001-crypto-perlasm-ppc-xlate.pl-add-linux64v2-flavour.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Andy Polyakov -Date: Sun, 5 May 2019 18:25:50 +0200 -Subject: crypto/perlasm/ppc-xlate.pl: add linux64v2 flavour -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is a big endian ELFv2 configuration. ELFv2 was already being -used for little endian, and big endian was traditionally ELFv1 -but there are practical configurations that use ELFv2 with big -endian nowadays (Adélie Linux, Void Linux, possibly Gentoo, etc.) - -Reviewed-by: Paul Dale -Reviewed-by: Richard Levitte -(Merged from https://github.com/openssl/openssl/pull/8883) - ---- a/crypto/perlasm/ppc-xlate.pl -+++ b/crypto/perlasm/ppc-xlate.pl -@@ -49,7 +49,7 @@ my $globl = sub { - /osx/ && do { $name = "_$name"; - last; - }; -- /linux.*(32|64le)/ -+ /linux.*(32|64(le|v2))/ - && do { $ret .= ".globl $name"; - if (!$$type) { - $ret .= "\n.type $name,\@function"; -@@ -80,7 +80,7 @@ my $globl = sub { - }; - my $text = sub { - my $ret = ($flavour =~ /aix/) ? ".csect\t.text[PR],7" : ".text"; -- $ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64le/); -+ $ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64(le|v2)/); - $ret; - }; - my $machine = sub { -@@ -186,7 +186,7 @@ my $vmr = sub { - - # Some ABIs specify vrsave, special-purpose register #256, as reserved - # for system use. --my $no_vrsave = ($flavour =~ /aix|linux64le/); -+my $no_vrsave = ($flavour =~ /aix|linux64(le|v2)/); - my $mtspr = sub { - my ($f,$idx,$ra) = @_; - if ($idx == 256 && $no_vrsave) { -@@ -318,7 +318,7 @@ while($line=<>) { - if ($label) { - my $xlated = ($GLOBALS{$label} or $label); - print "$xlated:"; -- if ($flavour =~ /linux.*64le/) { -+ if ($flavour =~ /linux.*64(le|v2)/) { - if ($TYPES{$label} =~ /function/) { - printf "\n.localentry %s,0\n",$xlated; - } diff --git a/package/libs/openssl/patches/100-Configure-afalg-support.patch b/package/libs/openssl/patches/100-Configure-afalg-support.patch index 746c50621f..e9cd7bf9c1 100644 --- a/package/libs/openssl/patches/100-Configure-afalg-support.patch +++ b/package/libs/openssl/patches/100-Configure-afalg-support.patch @@ -10,7 +10,7 @@ Signed-off-by: Eneas U de Queiroz --- a/Configure +++ b/Configure -@@ -1548,7 +1548,9 @@ unless ($disabled{"crypto-mdebug-backtra +@@ -1677,7 +1677,9 @@ $config{CFLAGS} = [ map { $_ eq '--ossl- unless ($disabled{afalgeng}) { $config{afalgeng}=""; diff --git a/package/libs/openssl/patches/120-strip-cflags-from-binary.patch b/package/libs/openssl/patches/120-strip-cflags-from-binary.patch index 90282706d1..e9f4fc131a 100644 --- a/package/libs/openssl/patches/120-strip-cflags-from-binary.patch +++ b/package/libs/openssl/patches/120-strip-cflags-from-binary.patch @@ -10,12 +10,12 @@ Signed-off-by: Eneas U de Queiroz --- a/crypto/build.info +++ b/crypto/build.info -@@ -10,7 +10,7 @@ EXTRA= ../ms/uplink-x86.pl ../ms/uplink - ppccpuid.pl pariscid.pl alphacpuid.pl arm64cpuid.pl armv4cpuid.pl +@@ -113,7 +113,7 @@ DEFINE[../libcrypto]=$UPLINKDEF + DEPEND[info.o]=buildinf.h DEPEND[cversion.o]=buildinf.h -GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q)" "$(PLATFORM)" +GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(filter-out -I% -iremap% -fmacro-prefix-map% -ffile-prefix-map%,$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q))" "$(PLATFORM)" - DEPEND[buildinf.h]=../configdata.pm - GENERATE[uplink-x86.s]=../ms/uplink-x86.pl $(PERLASM_SCHEME) + GENERATE[uplink-x86.S]=../ms/uplink-x86.pl + GENERATE[uplink-x86_64.s]=../ms/uplink-x86_64.pl diff --git a/package/libs/openssl/patches/130-dont-build-fuzz-docs.patch b/package/libs/openssl/patches/130-dont-build-fuzz-docs.patch new file mode 100644 index 0000000000..60c4663923 --- /dev/null +++ b/package/libs/openssl/patches/130-dont-build-fuzz-docs.patch @@ -0,0 +1,20 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Eneas U de Queiroz +Date: Thu, 27 Sep 2018 08:34:38 -0300 +Subject: Do not build tests and fuzz directories + +This shortens build time. + +Signed-off-by: Eneas U de Queiroz + +--- a/build.info ++++ b/build.info +@@ -1,7 +1,7 @@ + # Note that some of these directories are filtered in Configure. Look for + # %skipdir there for further explanations. + +-SUBDIRS=crypto ssl apps util tools fuzz providers doc ++SUBDIRS=crypto ssl apps util tools providers + IF[{- !$disabled{tests} -}] + SUBDIRS=test + ENDIF diff --git a/package/libs/openssl/patches/130-dont-build-tests-fuzz.patch b/package/libs/openssl/patches/130-dont-build-tests-fuzz.patch deleted file mode 100644 index baf8bca9e1..0000000000 --- a/package/libs/openssl/patches/130-dont-build-tests-fuzz.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Thu, 27 Sep 2018 08:34:38 -0300 -Subject: Do not build tests and fuzz directories - -This shortens build time. - -Signed-off-by: Eneas U de Queiroz - ---- a/Configure -+++ b/Configure -@@ -318,7 +318,7 @@ my $auto_threads=1; # enable threads - my $default_ranlib; - - # Top level directories to build --$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ]; -+$config{dirs} = [ "crypto", "ssl", "engines", "apps", "util", "tools" ]; - # crypto/ subdirectories to build - $config{sdirs} = [ - "objects", -@@ -330,7 +330,7 @@ $config{sdirs} = [ - "cms", "ts", "srp", "cmac", "ct", "async", "kdf", "store" - ]; - # test/ subdirectories to build --$config{tdirs} = [ "ossl_shim" ]; -+$config{tdirs} = []; - - # Known TLS and DTLS protocols - my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3); diff --git a/package/libs/openssl/patches/140-allow-prefer-chacha20.patch b/package/libs/openssl/patches/140-allow-prefer-chacha20.patch index 99afd9acf8..43fd92e388 100644 --- a/package/libs/openssl/patches/140-allow-prefer-chacha20.patch +++ b/package/libs/openssl/patches/140-allow-prefer-chacha20.patch @@ -14,30 +14,9 @@ when the client has it on top of its ciphersuite preference. Signed-off-by: Eneas U de Queiroz ---- a/include/openssl/ssl.h -+++ b/include/openssl/ssl.h -@@ -173,9 +173,15 @@ extern "C" { - # define SSL_DEFAULT_CIPHER_LIST "ALL:!COMPLEMENTOFDEFAULT:!eNULL" - /* This is the default set of TLSv1.3 ciphersuites */ - # if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) --# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \ -- "TLS_CHACHA20_POLY1305_SHA256:" \ -- "TLS_AES_128_GCM_SHA256" -+# ifdef OPENSSL_PREFER_CHACHA_OVER_GCM -+# define TLS_DEFAULT_CIPHERSUITES "TLS_CHACHA20_POLY1305_SHA256:" \ -+ "TLS_AES_256_GCM_SHA384:" \ -+ "TLS_AES_128_GCM_SHA256" -+# else -+# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \ -+ "TLS_CHACHA20_POLY1305_SHA256:" \ -+ "TLS_AES_128_GCM_SHA256" -+# endif - # else - # define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \ - "TLS_AES_128_GCM_SHA256" --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c -@@ -1465,11 +1465,29 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_ +@@ -1505,11 +1505,29 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_ ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); @@ -67,7 +46,7 @@ Signed-off-by: Eneas U de Queiroz /* * ...and generally, our preferred cipher is AES. -@@ -1525,7 +1543,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_ +@@ -1564,7 +1582,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_ * Within each group, ciphers remain sorted by strength and previous * preference, i.e., * 1) ECDHE > DHE @@ -76,3 +55,38 @@ Signed-off-by: Eneas U de Queiroz * 3) AES > rest * 4) TLS 1.2 > legacy * +@@ -2235,7 +2253,13 @@ const char *OSSL_default_cipher_list(voi + */ + const char *OSSL_default_ciphersuites(void) + { ++#ifdef OPENSSL_PREFER_CHACHA_OVER_GCM ++ return "TLS_CHACHA20_POLY1305_SHA256:" ++ "TLS_AES_256_GCM_SHA384:" ++ "TLS_AES_128_GCM_SHA256"; ++#else + return "TLS_AES_256_GCM_SHA384:" + "TLS_CHACHA20_POLY1305_SHA256:" + "TLS_AES_128_GCM_SHA256"; ++#endif + } +--- a/include/openssl/ssl.h.in ++++ b/include/openssl/ssl.h.in +@@ -195,9 +195,15 @@ extern "C" { + * DEPRECATED IN 3.0.0, in favor of OSSL_default_ciphersuites() + * Update both macro and function simultaneously + */ +-# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \ +- "TLS_CHACHA20_POLY1305_SHA256:" \ +- "TLS_AES_128_GCM_SHA256" ++# ifdef OPENSSL_PREFER_CHACHA_OVER_GCM ++# define TLS_DEFAULT_CIPHERSUITES "TLS_CHACHA20_POLY1305_SHA256:" \ ++ "TLS_AES_256_GCM_SHA384:" \ ++ "TLS_AES_128_GCM_SHA256" ++# else ++# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \ ++ "TLS_CHACHA20_POLY1305_SHA256:" \ ++ "TLS_AES_128_GCM_SHA256" ++# endif + # endif + /* + * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always diff --git a/package/libs/openssl/patches/150-openssl.cnf-add-engines-conf.patch b/package/libs/openssl/patches/150-openssl.cnf-add-engines-conf.patch index fa92fbe2ab..b1ec0cae71 100644 --- a/package/libs/openssl/patches/150-openssl.cnf-add-engines-conf.patch +++ b/package/libs/openssl/patches/150-openssl.cnf-add-engines-conf.patch @@ -10,7 +10,7 @@ Signed-off-by: Eneas U de Queiroz --- a/apps/openssl.cnf +++ b/apps/openssl.cnf -@@ -22,6 +22,16 @@ oid_section = new_oids +@@ -30,6 +30,16 @@ oid_section = new_oids # (Alternatively, use a configuration file that has only # X.509v3 extensions in its main [= default] section.) @@ -25,5 +25,5 @@ Signed-off-by: Eneas U de Queiroz +.include /etc/ssl/engines.cnf.d + [ new_oids ] - # We can add new OIDs in here for use by 'ca', 'req' and 'ts'. + # Add a simple OID like this: diff --git a/package/libs/openssl/patches/400-eng_devcrypto-save-ioctl-if-EVP_MD_.FLAG_ONESHOT.patch b/package/libs/openssl/patches/400-eng_devcrypto-save-ioctl-if-EVP_MD_.FLAG_ONESHOT.patch deleted file mode 100644 index ed8204c339..0000000000 --- a/package/libs/openssl/patches/400-eng_devcrypto-save-ioctl-if-EVP_MD_.FLAG_ONESHOT.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Mon, 5 Nov 2018 15:54:17 -0200 -Subject: eng_devcrypto: save ioctl if EVP_MD_..FLAG_ONESHOT - -Since each ioctl causes a context switch, slowing things down, if -EVP_MD_CTX_FLAG_ONESHOT is set, then: - - call the ioctl in digest_update, saving the result; and - - just copy the result in digest_final, instead of using another ioctl. - -Signed-off-by: Eneas U de Queiroz - -Reviewed-by: Matthias St. Pierre -Reviewed-by: Richard Levitte -(Merged from https://github.com/openssl/openssl/pull/7585) - ---- a/crypto/engine/eng_devcrypto.c -+++ b/crypto/engine/eng_devcrypto.c -@@ -461,6 +461,7 @@ struct digest_ctx { - struct session_op sess; - /* This signals that the init function was called, not that it succeeded. */ - int init_called; -+ unsigned char digest_res[HASH_MAX_LEN]; - }; - - static const struct digest_data_st { -@@ -564,12 +565,15 @@ static int digest_update(EVP_MD_CTX *ctx - if (digest_ctx == NULL) - return 0; - -- if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) < 0) { -- SYSerr(SYS_F_IOCTL, errno); -- return 0; -+ if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) { -+ if (digest_op(digest_ctx, data, count, digest_ctx->digest_res, 0) >= 0) -+ return 1; -+ } else if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) >= 0) { -+ return 1; - } - -- return 1; -+ SYSerr(SYS_F_IOCTL, errno); -+ return 0; - } - - static int digest_final(EVP_MD_CTX *ctx, unsigned char *md) -@@ -579,7 +583,10 @@ static int digest_final(EVP_MD_CTX *ctx, - - if (md == NULL || digest_ctx == NULL) - return 0; -- if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) { -+ -+ if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) { -+ memcpy(md, digest_ctx->digest_res, EVP_MD_CTX_size(ctx)); -+ } else if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) { - SYSerr(SYS_F_IOCTL, errno); - return 0; - } diff --git a/package/libs/openssl/patches/410-eng_devcrypto-add-configuration-options.patch b/package/libs/openssl/patches/410-eng_devcrypto-add-configuration-options.patch deleted file mode 100644 index bad7a37256..0000000000 --- a/package/libs/openssl/patches/410-eng_devcrypto-add-configuration-options.patch +++ /dev/null @@ -1,566 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Sat, 3 Nov 2018 15:41:10 -0300 -Subject: eng_devcrypto: add configuration options - -USE_SOFTDRIVERS: whether to use software (not accelerated) drivers -CIPHERS: list of ciphers to enable -DIGESTS: list of digests to enable - -Signed-off-by: Eneas U de Queiroz - -Reviewed-by: Matthias St. Pierre -Reviewed-by: Richard Levitte -(Merged from https://github.com/openssl/openssl/pull/7585) - ---- a/crypto/engine/eng_devcrypto.c -+++ b/crypto/engine/eng_devcrypto.c -@@ -16,6 +16,7 @@ - #include - #include - -+#include - #include - #include - #include -@@ -36,6 +37,30 @@ - * saner... why re-open /dev/crypto for every session? - */ - static int cfd; -+#define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */ -+#define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */ -+#define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */ -+ -+#define DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS DEVCRYPTO_REJECT_SOFTWARE -+static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS; -+ -+/* -+ * cipher/digest status & acceleration definitions -+ * Make sure the defaults are set to 0 -+ */ -+struct driver_info_st { -+ enum devcrypto_status_t { -+ DEVCRYPTO_STATUS_UNUSABLE = -1, /* session open failed */ -+ DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */ -+ DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */ -+ } status; -+ -+ enum devcrypto_accelerated_t { -+ DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */ -+ DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */ -+ DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */ -+ } accelerated; -+}; - - static int clean_devcrypto_session(struct session_op *sess) { - if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) { -@@ -119,13 +144,22 @@ static const struct cipher_data_st { - #endif - }; - --static size_t get_cipher_data_index(int nid) -+static size_t find_cipher_data_index(int nid) - { - size_t i; - - for (i = 0; i < OSSL_NELEM(cipher_data); i++) - if (nid == cipher_data[i].nid) - return i; -+ return (size_t)-1; -+} -+ -+static size_t get_cipher_data_index(int nid) -+{ -+ size_t i = find_cipher_data_index(nid); -+ -+ if (i != (size_t)-1) -+ return i; - - /* - * Code further down must make sure that only NIDs in the table above -@@ -333,19 +367,40 @@ static int cipher_cleanup(EVP_CIPHER_CTX - } - - /* -- * Keep a table of known nids and associated methods. -+ * Keep tables of known nids, associated methods, selected ciphers, and driver -+ * info. - * Note that known_cipher_nids[] isn't necessarily indexed the same way as -- * cipher_data[] above, which known_cipher_methods[] is. -+ * cipher_data[] above, which the other tables are. - */ - static int known_cipher_nids[OSSL_NELEM(cipher_data)]; - static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */ - static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, }; -+static int selected_ciphers[OSSL_NELEM(cipher_data)]; -+static struct driver_info_st cipher_driver_info[OSSL_NELEM(cipher_data)]; -+ -+ -+static int devcrypto_test_cipher(size_t cipher_data_index) -+{ -+ return (cipher_driver_info[cipher_data_index].status == DEVCRYPTO_STATUS_USABLE -+ && selected_ciphers[cipher_data_index] == 1 -+ && (cipher_driver_info[cipher_data_index].accelerated -+ == DEVCRYPTO_ACCELERATED -+ || use_softdrivers == DEVCRYPTO_USE_SOFTWARE -+ || (cipher_driver_info[cipher_data_index].accelerated -+ != DEVCRYPTO_NOT_ACCELERATED -+ && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE))); -+} - - static void prepare_cipher_methods(void) - { - size_t i; - struct session_op sess; - unsigned long cipher_mode; -+#ifdef CIOCGSESSINFO -+ struct session_info_op siop; -+#endif -+ -+ memset(&cipher_driver_info, 0, sizeof(cipher_driver_info)); - - memset(&sess, 0, sizeof(sess)); - sess.key = (void *)"01234567890123456789012345678901234567890123456789"; -@@ -353,15 +408,16 @@ static void prepare_cipher_methods(void) - for (i = 0, known_cipher_nids_amount = 0; - i < OSSL_NELEM(cipher_data); i++) { - -+ selected_ciphers[i] = 1; - /* -- * Check that the algo is really availably by trying to open and close -- * a session. -+ * Check that the cipher is usable - */ - sess.cipher = cipher_data[i].devcryptoid; - sess.keylen = cipher_data[i].keylen; -- if (ioctl(cfd, CIOCGSESSION, &sess) < 0 -- || ioctl(cfd, CIOCFSESSION, &sess.ses) < 0) -+ if (ioctl(cfd, CIOCGSESSION, &sess) < 0) { -+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE; - continue; -+ } - - cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE; - -@@ -387,15 +443,41 @@ static void prepare_cipher_methods(void) - cipher_cleanup) - || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i], - sizeof(struct cipher_ctx))) { -+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE; - EVP_CIPHER_meth_free(known_cipher_methods[i]); - known_cipher_methods[i] = NULL; - } else { -+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE; -+#ifdef CIOCGSESSINFO -+ siop.ses = sess.ses; -+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) -+ cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; -+ else if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)) -+ cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; -+ else -+ cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; -+#endif /* CIOCGSESSINFO */ -+ } -+ ioctl(cfd, CIOCFSESSION, &sess.ses); -+ if (devcrypto_test_cipher(i)) { - known_cipher_nids[known_cipher_nids_amount++] = - cipher_data[i].nid; - } - } - } - -+static void rebuild_known_cipher_nids(ENGINE *e) -+{ -+ size_t i; -+ -+ for (i = 0, known_cipher_nids_amount = 0; i < OSSL_NELEM(cipher_data); i++) { -+ if (devcrypto_test_cipher(i)) -+ known_cipher_nids[known_cipher_nids_amount++] = cipher_data[i].nid; -+ } -+ ENGINE_unregister_ciphers(e); -+ ENGINE_register_ciphers(e); -+} -+ - static const EVP_CIPHER *get_cipher_method(int nid) - { - size_t i = get_cipher_data_index(nid); -@@ -438,6 +520,36 @@ static int devcrypto_ciphers(ENGINE *e, - return *cipher != NULL; - } - -+static void devcrypto_select_all_ciphers(int *cipher_list) -+{ -+ size_t i; -+ -+ for (i = 0; i < OSSL_NELEM(cipher_data); i++) -+ cipher_list[i] = 1; -+} -+ -+static int cryptodev_select_cipher_cb(const char *str, int len, void *usr) -+{ -+ int *cipher_list = (int *)usr; -+ char *name; -+ const EVP_CIPHER *EVP; -+ size_t i; -+ -+ if (len == 0) -+ return 1; -+ if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL) -+ return 0; -+ EVP = EVP_get_cipherbyname(name); -+ if (EVP == NULL) -+ fprintf(stderr, "devcrypto: unknown cipher %s\n", name); -+ else if ((i = find_cipher_data_index(EVP_CIPHER_nid(EVP))) != (size_t)-1) -+ cipher_list[i] = 1; -+ else -+ fprintf(stderr, "devcrypto: cipher %s not available\n", name); -+ OPENSSL_free(name); -+ return 1; -+} -+ - /* - * We only support digests if the cryptodev implementation supports multiple - * data updates and session copying. Otherwise, we would be forced to maintain -@@ -493,13 +605,22 @@ static const struct digest_data_st { - #endif - }; - --static size_t get_digest_data_index(int nid) -+static size_t find_digest_data_index(int nid) - { - size_t i; - - for (i = 0; i < OSSL_NELEM(digest_data); i++) - if (nid == digest_data[i].nid) - return i; -+ return (size_t)-1; -+} -+ -+static size_t get_digest_data_index(int nid) -+{ -+ size_t i = find_digest_data_index(nid); -+ -+ if (i != (size_t)-1) -+ return i; - - /* - * Code further down must make sure that only NIDs in the table above -@@ -516,8 +637,8 @@ static const struct digest_data_st *get_ - } - - /* -- * Following are the four necessary functions to map OpenSSL functionality -- * with cryptodev. -+ * Following are the five necessary functions to map OpenSSL functionality -+ * with cryptodev: init, update, final, cleanup, and copy. - */ - - static int digest_init(EVP_MD_CTX *ctx) -@@ -630,52 +751,94 @@ static int digest_cleanup(EVP_MD_CTX *ct - return clean_devcrypto_session(&digest_ctx->sess); - } - --static int devcrypto_test_digest(size_t digest_data_index) --{ -- struct session_op sess1, sess2; -- struct cphash_op cphash; -- int ret=0; -- -- memset(&sess1, 0, sizeof(sess1)); -- memset(&sess2, 0, sizeof(sess2)); -- sess1.mac = digest_data[digest_data_index].devcryptoid; -- if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) -- return 0; -- /* Make sure the driver is capable of hash state copy */ -- sess2.mac = sess1.mac; -- if (ioctl(cfd, CIOCGSESSION, &sess2) >= 0) { -- cphash.src_ses = sess1.ses; -- cphash.dst_ses = sess2.ses; -- if (ioctl(cfd, CIOCCPHASH, &cphash) >= 0) -- ret = 1; -- ioctl(cfd, CIOCFSESSION, &sess2.ses); -- } -- ioctl(cfd, CIOCFSESSION, &sess1.ses); -- return ret; --} -- - /* -- * Keep a table of known nids and associated methods. -+ * Keep tables of known nids, associated methods, selected digests, and -+ * driver info. - * Note that known_digest_nids[] isn't necessarily indexed the same way as -- * digest_data[] above, which known_digest_methods[] is. -+ * digest_data[] above, which the other tables are. - */ - static int known_digest_nids[OSSL_NELEM(digest_data)]; - static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */ - static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, }; -+static int selected_digests[OSSL_NELEM(digest_data)]; -+static struct driver_info_st digest_driver_info[OSSL_NELEM(digest_data)]; -+ -+static int devcrypto_test_digest(size_t digest_data_index) -+{ -+ return (digest_driver_info[digest_data_index].status == DEVCRYPTO_STATUS_USABLE -+ && selected_digests[digest_data_index] == 1 -+ && (digest_driver_info[digest_data_index].accelerated -+ == DEVCRYPTO_ACCELERATED -+ || use_softdrivers == DEVCRYPTO_USE_SOFTWARE -+ || (digest_driver_info[digest_data_index].accelerated -+ != DEVCRYPTO_NOT_ACCELERATED -+ && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE))); -+} -+ -+static void rebuild_known_digest_nids(ENGINE *e) -+{ -+ size_t i; -+ -+ for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); i++) { -+ if (devcrypto_test_digest(i)) -+ known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid; -+ } -+ ENGINE_unregister_digests(e); -+ ENGINE_register_digests(e); -+} - - static void prepare_digest_methods(void) - { - size_t i; -+ struct session_op sess1, sess2; -+#ifdef CIOCGSESSINFO -+ struct session_info_op siop; -+#endif -+ struct cphash_op cphash; -+ -+ memset(&digest_driver_info, 0, sizeof(digest_driver_info)); -+ -+ memset(&sess1, 0, sizeof(sess1)); -+ memset(&sess2, 0, sizeof(sess2)); - - for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); - i++) { - -+ selected_digests[i] = 1; -+ - /* -- * Check that the algo is usable -+ * Check that the digest is usable - */ -- if (!devcrypto_test_digest(i)) -- continue; -+ sess1.mac = digest_data[i].devcryptoid; -+ sess2.ses = 0; -+ if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) { -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE; -+ goto finish; -+ } - -+#ifdef CIOCGSESSINFO -+ /* gather hardware acceleration info from the driver */ -+ siop.ses = sess1.ses; -+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) -+ digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; -+ else if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY) -+ digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; -+ else -+ digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; -+#endif -+ -+ /* digest must be capable of hash state copy */ -+ sess2.mac = sess1.mac; -+ if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) { -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE; -+ goto finish; -+ } -+ cphash.src_ses = sess1.ses; -+ cphash.dst_ses = sess2.ses; -+ if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) { -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE; -+ goto finish; -+ } - if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid, - NID_undef)) == NULL - || !EVP_MD_meth_set_input_blocksize(known_digest_methods[i], -@@ -689,11 +852,18 @@ static void prepare_digest_methods(void) - || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup) - || !EVP_MD_meth_set_app_datasize(known_digest_methods[i], - sizeof(struct digest_ctx))) { -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE; - EVP_MD_meth_free(known_digest_methods[i]); - known_digest_methods[i] = NULL; -- } else { -- known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid; -+ goto finish; - } -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_USABLE; -+finish: -+ ioctl(cfd, CIOCFSESSION, &sess1.ses); -+ if (sess2.ses != 0) -+ ioctl(cfd, CIOCFSESSION, &sess2.ses); -+ if (devcrypto_test_digest(i)) -+ known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid; - } - } - -@@ -739,7 +909,153 @@ static int devcrypto_digests(ENGINE *e, - return *digest != NULL; - } - -+static void devcrypto_select_all_digests(int *digest_list) -+{ -+ size_t i; -+ -+ for (i = 0; i < OSSL_NELEM(digest_data); i++) -+ digest_list[i] = 1; -+} -+ -+static int cryptodev_select_digest_cb(const char *str, int len, void *usr) -+{ -+ int *digest_list = (int *)usr; -+ char *name; -+ const EVP_MD *EVP; -+ size_t i; -+ -+ if (len == 0) -+ return 1; -+ if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL) -+ return 0; -+ EVP = EVP_get_digestbyname(name); -+ if (EVP == NULL) -+ fprintf(stderr, "devcrypto: unknown digest %s\n", name); -+ else if ((i = find_digest_data_index(EVP_MD_type(EVP))) != (size_t)-1) -+ digest_list[i] = 1; -+ else -+ fprintf(stderr, "devcrypto: digest %s not available\n", name); -+ OPENSSL_free(name); -+ return 1; -+} -+ -+#endif -+ -+/****************************************************************************** -+ * -+ * CONTROL COMMANDS -+ * -+ *****/ -+ -+#define DEVCRYPTO_CMD_USE_SOFTDRIVERS ENGINE_CMD_BASE -+#define DEVCRYPTO_CMD_CIPHERS (ENGINE_CMD_BASE + 1) -+#define DEVCRYPTO_CMD_DIGESTS (ENGINE_CMD_BASE + 2) -+#define DEVCRYPTO_CMD_DUMP_INFO (ENGINE_CMD_BASE + 3) -+ -+/* Helper macros for CPP string composition */ -+#ifndef OPENSSL_MSTR -+# define OPENSSL_MSTR_HELPER(x) #x -+# define OPENSSL_MSTR(x) OPENSSL_MSTR_HELPER(x) -+#endif -+ -+static const ENGINE_CMD_DEFN devcrypto_cmds[] = { -+#ifdef CIOCGSESSINFO -+ {DEVCRYPTO_CMD_USE_SOFTDRIVERS, -+ "USE_SOFTDRIVERS", -+ "specifies whether to use software (not accelerated) drivers (" -+ OPENSSL_MSTR(DEVCRYPTO_REQUIRE_ACCELERATED) "=use only accelerated drivers, " -+ OPENSSL_MSTR(DEVCRYPTO_USE_SOFTWARE) "=allow all drivers, " -+ OPENSSL_MSTR(DEVCRYPTO_REJECT_SOFTWARE) -+ "=use if acceleration can't be determined) [default=" -+ OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS) "]", -+ ENGINE_CMD_FLAG_NUMERIC}, -+#endif -+ -+ {DEVCRYPTO_CMD_CIPHERS, -+ "CIPHERS", -+ "either ALL, NONE, or a comma-separated list of ciphers to enable [default=ALL]", -+ ENGINE_CMD_FLAG_STRING}, -+ -+#ifdef IMPLEMENT_DIGEST -+ {DEVCRYPTO_CMD_DIGESTS, -+ "DIGESTS", -+ "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]", -+ ENGINE_CMD_FLAG_STRING}, -+#endif -+ -+ {0, NULL, NULL, 0} -+}; -+ -+static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -+{ -+ int *new_list; -+ switch (cmd) { -+#ifdef CIOCGSESSINFO -+ case DEVCRYPTO_CMD_USE_SOFTDRIVERS: -+ switch (i) { -+ case DEVCRYPTO_REQUIRE_ACCELERATED: -+ case DEVCRYPTO_USE_SOFTWARE: -+ case DEVCRYPTO_REJECT_SOFTWARE: -+ break; -+ default: -+ fprintf(stderr, "devcrypto: invalid value (%ld) for USE_SOFTDRIVERS\n", i); -+ return 0; -+ } -+ if (use_softdrivers == i) -+ return 1; -+ use_softdrivers = i; -+#ifdef IMPLEMENT_DIGEST -+ rebuild_known_digest_nids(e); - #endif -+ rebuild_known_cipher_nids(e); -+ return 1; -+#endif /* CIOCGSESSINFO */ -+ -+ case DEVCRYPTO_CMD_CIPHERS: -+ if (p == NULL) -+ return 1; -+ if (strcasecmp((const char *)p, "ALL") == 0) { -+ devcrypto_select_all_ciphers(selected_ciphers); -+ } else if (strcasecmp((const char*)p, "NONE") == 0) { -+ memset(selected_ciphers, 0, sizeof(selected_ciphers)); -+ } else { -+ new_list=OPENSSL_zalloc(sizeof(selected_ciphers)); -+ if (!CONF_parse_list(p, ',', 1, cryptodev_select_cipher_cb, new_list)) { -+ OPENSSL_free(new_list); -+ return 0; -+ } -+ memcpy(selected_ciphers, new_list, sizeof(selected_ciphers)); -+ OPENSSL_free(new_list); -+ } -+ rebuild_known_cipher_nids(e); -+ return 1; -+ -+#ifdef IMPLEMENT_DIGEST -+ case DEVCRYPTO_CMD_DIGESTS: -+ if (p == NULL) -+ return 1; -+ if (strcasecmp((const char *)p, "ALL") == 0) { -+ devcrypto_select_all_digests(selected_digests); -+ } else if (strcasecmp((const char*)p, "NONE") == 0) { -+ memset(selected_digests, 0, sizeof(selected_digests)); -+ } else { -+ new_list=OPENSSL_zalloc(sizeof(selected_digests)); -+ if (!CONF_parse_list(p, ',', 1, cryptodev_select_digest_cb, new_list)) { -+ OPENSSL_free(new_list); -+ return 0; -+ } -+ memcpy(selected_digests, new_list, sizeof(selected_digests)); -+ OPENSSL_free(new_list); -+ } -+ rebuild_known_digest_nids(e); -+ return 1; -+#endif /* IMPLEMENT_DIGEST */ -+ -+ default: -+ break; -+ } -+ return 0; -+} - - /****************************************************************************** - * -@@ -806,6 +1122,8 @@ void engine_load_devcrypto_int() - - if (!ENGINE_set_id(e, "devcrypto") - || !ENGINE_set_name(e, "/dev/crypto engine") -+ || !ENGINE_set_cmd_defns(e, devcrypto_cmds) -+ || !ENGINE_set_ctrl_function(e, devcrypto_ctrl) - - /* - * Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD diff --git a/package/libs/openssl/patches/420-eng_devcrypto-add-command-to-dump-driver-info.patch b/package/libs/openssl/patches/420-eng_devcrypto-add-command-to-dump-driver-info.patch deleted file mode 100644 index eee71c6c62..0000000000 --- a/package/libs/openssl/patches/420-eng_devcrypto-add-command-to-dump-driver-info.patch +++ /dev/null @@ -1,273 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Tue, 6 Nov 2018 22:54:07 -0200 -Subject: eng_devcrypto: add command to dump driver info - -This is useful to determine the kernel driver running each algorithm. - -Signed-off-by: Eneas U de Queiroz - -Reviewed-by: Matthias St. Pierre -Reviewed-by: Richard Levitte -(Merged from https://github.com/openssl/openssl/pull/7585) - ---- a/crypto/engine/eng_devcrypto.c -+++ b/crypto/engine/eng_devcrypto.c -@@ -50,16 +50,20 @@ static int use_softdrivers = DEVCRYPTO_D - */ - struct driver_info_st { - enum devcrypto_status_t { -- DEVCRYPTO_STATUS_UNUSABLE = -1, /* session open failed */ -- DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */ -- DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */ -+ DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */ -+ DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */ -+ DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */ -+ DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */ -+ DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */ - } status; - - enum devcrypto_accelerated_t { -- DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */ -- DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */ -- DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */ -+ DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */ -+ DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */ -+ DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */ - } accelerated; -+ -+ char *driver_name; - }; - - static int clean_devcrypto_session(struct session_op *sess) { -@@ -415,7 +419,7 @@ static void prepare_cipher_methods(void) - sess.cipher = cipher_data[i].devcryptoid; - sess.keylen = cipher_data[i].keylen; - if (ioctl(cfd, CIOCGSESSION, &sess) < 0) { -- cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE; -+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; - continue; - } - -@@ -443,19 +447,24 @@ static void prepare_cipher_methods(void) - cipher_cleanup) - || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i], - sizeof(struct cipher_ctx))) { -- cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE; -+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; - EVP_CIPHER_meth_free(known_cipher_methods[i]); - known_cipher_methods[i] = NULL; - } else { - cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE; - #ifdef CIOCGSESSINFO - siop.ses = sess.ses; -- if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) -+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) { - cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; -- else if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)) -- cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; -- else -- cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; -+ } else { -+ cipher_driver_info[i].driver_name = -+ OPENSSL_strndup(siop.cipher_info.cra_driver_name, -+ CRYPTODEV_MAX_ALG_NAME); -+ if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)) -+ cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; -+ else -+ cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; -+ } - #endif /* CIOCGSESSINFO */ - } - ioctl(cfd, CIOCFSESSION, &sess.ses); -@@ -505,8 +514,11 @@ static void destroy_all_cipher_methods(v - { - size_t i; - -- for (i = 0; i < OSSL_NELEM(cipher_data); i++) -+ for (i = 0; i < OSSL_NELEM(cipher_data); i++) { - destroy_cipher_method(cipher_data[i].nid); -+ OPENSSL_free(cipher_driver_info[i].driver_name); -+ cipher_driver_info[i].driver_name = NULL; -+ } - } - - static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher, -@@ -550,6 +562,40 @@ static int cryptodev_select_cipher_cb(co - return 1; - } - -+static void dump_cipher_info(void) -+{ -+ size_t i; -+ const char *name; -+ -+ fprintf (stderr, "Information about ciphers supported by the /dev/crypto" -+ " engine:\n"); -+#ifndef CIOCGSESSINFO -+ fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n"); -+#endif -+ for (i = 0; i < OSSL_NELEM(cipher_data); i++) { -+ name = OBJ_nid2sn(cipher_data[i].nid); -+ fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ", -+ name ? name : "unknown", cipher_data[i].nid, -+ cipher_data[i].devcryptoid); -+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION ) { -+ fprintf (stderr, "CIOCGSESSION (session open call) failed\n"); -+ continue; -+ } -+ fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ? -+ cipher_driver_info[i].driver_name : "unknown"); -+ if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED) -+ fprintf(stderr, "(hw accelerated)"); -+ else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED) -+ fprintf(stderr, "(software)"); -+ else -+ fprintf(stderr, "(acceleration status unknown)"); -+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE) -+ fprintf (stderr, ". Cipher setup failed"); -+ fprintf(stderr, "\n"); -+ } -+ fprintf(stderr, "\n"); -+} -+ - /* - * We only support digests if the cryptodev implementation supports multiple - * data updates and session copying. Otherwise, we would be forced to maintain -@@ -812,31 +858,36 @@ static void prepare_digest_methods(void) - sess1.mac = digest_data[i].devcryptoid; - sess2.ses = 0; - if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) { -- digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE; -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; - goto finish; - } - - #ifdef CIOCGSESSINFO - /* gather hardware acceleration info from the driver */ - siop.ses = sess1.ses; -- if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) -+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) { - digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; -- else if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY) -- digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; -- else -- digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; -+ } else { -+ digest_driver_info[i].driver_name = -+ OPENSSL_strndup(siop.hash_info.cra_driver_name, -+ CRYPTODEV_MAX_ALG_NAME); -+ if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY) -+ digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; -+ else -+ digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; -+ } - #endif - - /* digest must be capable of hash state copy */ - sess2.mac = sess1.mac; - if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) { -- digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE; -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; - goto finish; - } - cphash.src_ses = sess1.ses; - cphash.dst_ses = sess2.ses; - if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) { -- digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE; -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH; - goto finish; - } - if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid, -@@ -852,7 +903,7 @@ static void prepare_digest_methods(void) - || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup) - || !EVP_MD_meth_set_app_datasize(known_digest_methods[i], - sizeof(struct digest_ctx))) { -- digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE; -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; - EVP_MD_meth_free(known_digest_methods[i]); - known_digest_methods[i] = NULL; - goto finish; -@@ -894,8 +945,11 @@ static void destroy_all_digest_methods(v - { - size_t i; - -- for (i = 0; i < OSSL_NELEM(digest_data); i++) -+ for (i = 0; i < OSSL_NELEM(digest_data); i++) { - destroy_digest_method(digest_data[i].nid); -+ OPENSSL_free(digest_driver_info[i].driver_name); -+ digest_driver_info[i].driver_name = NULL; -+ } - } - - static int devcrypto_digests(ENGINE *e, const EVP_MD **digest, -@@ -939,6 +993,43 @@ static int cryptodev_select_digest_cb(co - return 1; - } - -+static void dump_digest_info(void) -+{ -+ size_t i; -+ const char *name; -+ -+ fprintf (stderr, "Information about digests supported by the /dev/crypto" -+ " engine:\n"); -+#ifndef CIOCGSESSINFO -+ fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n"); -+#endif -+ -+ for (i = 0; i < OSSL_NELEM(digest_data); i++) { -+ name = OBJ_nid2sn(digest_data[i].nid); -+ fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s", -+ name ? name : "unknown", digest_data[i].nid, -+ digest_data[i].devcryptoid, -+ digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown"); -+ if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) { -+ fprintf (stderr, ". CIOCGSESSION (session open) failed\n"); -+ continue; -+ } -+ if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED) -+ fprintf(stderr, " (hw accelerated)"); -+ else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED) -+ fprintf(stderr, " (software)"); -+ else -+ fprintf(stderr, " (acceleration status unknown)"); -+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE) -+ fprintf (stderr, ". Cipher setup failed\n"); -+ else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH) -+ fprintf(stderr, ", CIOCCPHASH failed\n"); -+ else -+ fprintf(stderr, ", CIOCCPHASH capable\n"); -+ } -+ fprintf(stderr, "\n"); -+} -+ - #endif - - /****************************************************************************** -@@ -983,6 +1074,11 @@ static const ENGINE_CMD_DEFN devcrypto_c - ENGINE_CMD_FLAG_STRING}, - #endif - -+ {DEVCRYPTO_CMD_DUMP_INFO, -+ "DUMP_INFO", -+ "dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'", -+ ENGINE_CMD_FLAG_NO_INPUT}, -+ - {0, NULL, NULL, 0} - }; - -@@ -1051,6 +1147,13 @@ static int devcrypto_ctrl(ENGINE *e, int - return 1; - #endif /* IMPLEMENT_DIGEST */ - -+ case DEVCRYPTO_CMD_DUMP_INFO: -+ dump_cipher_info(); -+#ifdef IMPLEMENT_DIGEST -+ dump_digest_info(); -+#endif -+ return 1; -+ - default: - break; - } diff --git a/package/libs/openssl/patches/430-e_devcrypto-make-the-dev-crypto-engine-dynamic.patch b/package/libs/openssl/patches/430-e_devcrypto-make-the-dev-crypto-engine-dynamic.patch deleted file mode 100644 index 00c74972ab..0000000000 --- a/package/libs/openssl/patches/430-e_devcrypto-make-the-dev-crypto-engine-dynamic.patch +++ /dev/null @@ -1,2718 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Tue, 6 Nov 2018 10:57:03 -0200 -Subject: e_devcrypto: make the /dev/crypto engine dynamic - -Engine has been moved from crypto/engine/eng_devcrypto.c to -engines/e_devcrypto.c. - -Signed-off-by: Eneas U de Queiroz - ---- a/crypto/engine/build.info -+++ b/crypto/engine/build.info -@@ -6,6 +6,3 @@ SOURCE[../../libcrypto]=\ - tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c tb_eckey.c \ - eng_openssl.c eng_cnf.c eng_dyn.c \ - eng_rdrand.c --IF[{- !$disabled{devcryptoeng} -}] -- SOURCE[../../libcrypto]=eng_devcrypto.c --ENDIF ---- a/crypto/init.c -+++ b/crypto/init.c -@@ -328,18 +328,6 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_ - engine_load_openssl_int(); - return 1; - } --# ifndef OPENSSL_NO_DEVCRYPTOENG --static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT; --DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto) --{ --# ifdef OPENSSL_INIT_DEBUG -- fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: " -- "engine_load_devcrypto_int()\n"); --# endif -- engine_load_devcrypto_int(); -- return 1; --} --# endif - - # ifndef OPENSSL_NO_RDRAND - static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT; -@@ -364,6 +352,18 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_ - return 1; - } - # ifndef OPENSSL_NO_STATIC_ENGINE -+# ifndef OPENSSL_NO_DEVCRYPTOENG -+static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT; -+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto) -+{ -+# ifdef OPENSSL_INIT_DEBUG -+ fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: " -+ "engine_load_devcrypto_int()\n"); -+# endif -+ engine_load_devcrypto_int(); -+ return 1; -+} -+# endif - # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) - static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT; - DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock) -@@ -704,11 +704,6 @@ int OPENSSL_init_crypto(uint64_t opts, c - if ((opts & OPENSSL_INIT_ENGINE_OPENSSL) - && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl)) - return 0; --# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG) -- if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV) -- && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto)) -- return 0; --# endif - # ifndef OPENSSL_NO_RDRAND - if ((opts & OPENSSL_INIT_ENGINE_RDRAND) - && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand)) -@@ -718,6 +713,11 @@ int OPENSSL_init_crypto(uint64_t opts, c - && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic)) - return 0; - # ifndef OPENSSL_NO_STATIC_ENGINE -+# ifndef OPENSSL_NO_DEVCRYPTOENG -+ if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV) -+ && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto)) -+ return 0; -+# endif - # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) - if ((opts & OPENSSL_INIT_ENGINE_PADLOCK) - && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock)) ---- a/engines/build.info -+++ b/engines/build.info -@@ -11,6 +11,9 @@ IF[{- !$disabled{"engine"} -}] - IF[{- !$disabled{afalgeng} -}] - SOURCE[../libcrypto]=e_afalg.c - ENDIF -+ IF[{- !$disabled{"devcryptoeng"} -}] -+ SOURCE[../libcrypto]=e_devcrypto.c -+ ENDIF - ELSE - IF[{- !$disabled{hw} && !$disabled{'hw-padlock'} -}] - ENGINES=padlock -@@ -30,6 +33,12 @@ IF[{- !$disabled{"engine"} -}] - DEPEND[afalg]=../libcrypto - INCLUDE[afalg]= ../include - ENDIF -+ IF[{- !$disabled{"devcryptoeng"} -}] -+ ENGINES=devcrypto -+ SOURCE[devcrypto]=e_devcrypto.c -+ DEPEND[devcrypto]=../libcrypto -+ INCLUDE[devcrypto]=../include -+ ENDIF - - ENGINES_NO_INST=ossltest dasync - SOURCE[dasync]=e_dasync.c ---- a/crypto/engine/eng_devcrypto.c -+++ /dev/null -@@ -1,1277 +0,0 @@ --/* -- * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. -- * -- * Licensed under the OpenSSL license (the "License"). You may not use -- * this file except in compliance with the License. You can obtain a copy -- * in the file LICENSE in the source distribution or at -- * https://www.openssl.org/source/license.html -- */ -- --#include "e_os.h" --#include --#include --#include --#include --#include --#include --#include -- --#include --#include --#include --#include --#include --#include -- --#include "crypto/engine.h" -- --/* #define ENGINE_DEVCRYPTO_DEBUG */ -- --#if CRYPTO_ALGORITHM_MIN < CRYPTO_ALGORITHM_MAX --# define CHECK_BSD_STYLE_MACROS --#endif -- --/* -- * ONE global file descriptor for all sessions. This allows operations -- * such as digest session data copying (see digest_copy()), but is also -- * saner... why re-open /dev/crypto for every session? -- */ --static int cfd; --#define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */ --#define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */ --#define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */ -- --#define DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS DEVCRYPTO_REJECT_SOFTWARE --static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS; -- --/* -- * cipher/digest status & acceleration definitions -- * Make sure the defaults are set to 0 -- */ --struct driver_info_st { -- enum devcrypto_status_t { -- DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */ -- DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */ -- DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */ -- DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */ -- DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */ -- } status; -- -- enum devcrypto_accelerated_t { -- DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */ -- DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */ -- DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */ -- } accelerated; -- -- char *driver_name; --}; -- --static int clean_devcrypto_session(struct session_op *sess) { -- if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) { -- SYSerr(SYS_F_IOCTL, errno); -- return 0; -- } -- memset(sess, 0, sizeof(struct session_op)); -- return 1; --} -- --/****************************************************************************** -- * -- * Ciphers -- * -- * Because they all do the same basic operation, we have only one set of -- * method functions for them all to share, and a mapping table between -- * NIDs and cryptodev IDs, with all the necessary size data. -- * -- *****/ -- --struct cipher_ctx { -- struct session_op sess; -- int op; /* COP_ENCRYPT or COP_DECRYPT */ -- unsigned long mode; /* EVP_CIPH_*_MODE */ -- -- /* to handle ctr mode being a stream cipher */ -- unsigned char partial[EVP_MAX_BLOCK_LENGTH]; -- unsigned int blocksize, num; --}; -- --static const struct cipher_data_st { -- int nid; -- int blocksize; -- int keylen; -- int ivlen; -- int flags; -- int devcryptoid; --} cipher_data[] = { --#ifndef OPENSSL_NO_DES -- { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC }, -- { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC }, --#endif --#ifndef OPENSSL_NO_BF -- { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC }, --#endif --#ifndef OPENSSL_NO_CAST -- { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC }, --#endif -- { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, -- { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, -- { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, --#ifndef OPENSSL_NO_RC4 -- { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4 }, --#endif --#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_CTR) -- { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, -- { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, -- { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, --#endif --#if 0 /* Not yet supported */ -- { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS }, -- { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS }, --#endif --#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB) -- { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, -- { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, -- { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, --#endif --#if 0 /* Not yet supported */ -- { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, -- { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, -- { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, --#endif --#ifndef OPENSSL_NO_CAMELLIA -- { NID_camellia_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, -- CRYPTO_CAMELLIA_CBC }, -- { NID_camellia_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, -- CRYPTO_CAMELLIA_CBC }, -- { NID_camellia_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, -- CRYPTO_CAMELLIA_CBC }, --#endif --}; -- --static size_t find_cipher_data_index(int nid) --{ -- size_t i; -- -- for (i = 0; i < OSSL_NELEM(cipher_data); i++) -- if (nid == cipher_data[i].nid) -- return i; -- return (size_t)-1; --} -- --static size_t get_cipher_data_index(int nid) --{ -- size_t i = find_cipher_data_index(nid); -- -- if (i != (size_t)-1) -- return i; -- -- /* -- * Code further down must make sure that only NIDs in the table above -- * are used. If any other NID reaches this function, there's a grave -- * coding error further down. -- */ -- assert("Code that never should be reached" == NULL); -- return -1; --} -- --static const struct cipher_data_st *get_cipher_data(int nid) --{ -- return &cipher_data[get_cipher_data_index(nid)]; --} -- --/* -- * Following are the three necessary functions to map OpenSSL functionality -- * with cryptodev. -- */ -- --static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, -- const unsigned char *iv, int enc) --{ -- struct cipher_ctx *cipher_ctx = -- (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); -- const struct cipher_data_st *cipher_d = -- get_cipher_data(EVP_CIPHER_CTX_nid(ctx)); -- -- /* cleanup a previous session */ -- if (cipher_ctx->sess.ses != 0 && -- clean_devcrypto_session(&cipher_ctx->sess) == 0) -- return 0; -- -- cipher_ctx->sess.cipher = cipher_d->devcryptoid; -- cipher_ctx->sess.keylen = cipher_d->keylen; -- cipher_ctx->sess.key = (void *)key; -- cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT; -- cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE; -- cipher_ctx->blocksize = cipher_d->blocksize; -- if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) { -- SYSerr(SYS_F_IOCTL, errno); -- return 0; -- } -- -- return 1; --} -- --static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, -- const unsigned char *in, size_t inl) --{ -- struct cipher_ctx *cipher_ctx = -- (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); -- struct crypt_op cryp; -- unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); --#if !defined(COP_FLAG_WRITE_IV) -- unsigned char saved_iv[EVP_MAX_IV_LENGTH]; -- const unsigned char *ivptr; -- size_t nblocks, ivlen; --#endif -- -- memset(&cryp, 0, sizeof(cryp)); -- cryp.ses = cipher_ctx->sess.ses; -- cryp.len = inl; -- cryp.src = (void *)in; -- cryp.dst = (void *)out; -- cryp.iv = (void *)iv; -- cryp.op = cipher_ctx->op; --#if !defined(COP_FLAG_WRITE_IV) -- cryp.flags = 0; -- -- ivlen = EVP_CIPHER_CTX_iv_length(ctx); -- if (ivlen > 0) -- switch (cipher_ctx->mode) { -- case EVP_CIPH_CBC_MODE: -- assert(inl >= ivlen); -- if (!EVP_CIPHER_CTX_encrypting(ctx)) { -- ivptr = in + inl - ivlen; -- memcpy(saved_iv, ivptr, ivlen); -- } -- break; -- -- case EVP_CIPH_CTR_MODE: -- break; -- -- default: /* should not happen */ -- return 0; -- } --#else -- cryp.flags = COP_FLAG_WRITE_IV; --#endif -- -- if (ioctl(cfd, CIOCCRYPT, &cryp) < 0) { -- SYSerr(SYS_F_IOCTL, errno); -- return 0; -- } -- --#if !defined(COP_FLAG_WRITE_IV) -- if (ivlen > 0) -- switch (cipher_ctx->mode) { -- case EVP_CIPH_CBC_MODE: -- assert(inl >= ivlen); -- if (EVP_CIPHER_CTX_encrypting(ctx)) -- ivptr = out + inl - ivlen; -- else -- ivptr = saved_iv; -- -- memcpy(iv, ivptr, ivlen); -- break; -- -- case EVP_CIPH_CTR_MODE: -- nblocks = (inl + cipher_ctx->blocksize - 1) -- / cipher_ctx->blocksize; -- do { -- ivlen--; -- nblocks += iv[ivlen]; -- iv[ivlen] = (uint8_t) nblocks; -- nblocks >>= 8; -- } while (ivlen); -- break; -- -- default: /* should not happen */ -- return 0; -- } --#endif -- -- return 1; --} -- --static int ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, -- const unsigned char *in, size_t inl) --{ -- struct cipher_ctx *cipher_ctx = -- (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); -- size_t nblocks, len; -- -- /* initial partial block */ -- while (cipher_ctx->num && inl) { -- (*out++) = *(in++) ^ cipher_ctx->partial[cipher_ctx->num]; -- --inl; -- cipher_ctx->num = (cipher_ctx->num + 1) % cipher_ctx->blocksize; -- } -- -- /* full blocks */ -- if (inl > (unsigned int) cipher_ctx->blocksize) { -- nblocks = inl/cipher_ctx->blocksize; -- len = nblocks * cipher_ctx->blocksize; -- if (cipher_do_cipher(ctx, out, in, len) < 1) -- return 0; -- inl -= len; -- out += len; -- in += len; -- } -- -- /* final partial block */ -- if (inl) { -- memset(cipher_ctx->partial, 0, cipher_ctx->blocksize); -- if (cipher_do_cipher(ctx, cipher_ctx->partial, cipher_ctx->partial, -- cipher_ctx->blocksize) < 1) -- return 0; -- while (inl--) { -- out[cipher_ctx->num] = in[cipher_ctx->num] -- ^ cipher_ctx->partial[cipher_ctx->num]; -- cipher_ctx->num++; -- } -- } -- -- return 1; --} -- --static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2) --{ -- struct cipher_ctx *cipher_ctx = -- (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); -- EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2; -- struct cipher_ctx *to_cipher_ctx; -- -- switch (type) { -- case EVP_CTRL_COPY: -- if (cipher_ctx == NULL) -- return 1; -- /* when copying the context, a new session needs to be initialized */ -- to_cipher_ctx = -- (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(to_ctx); -- memset(&to_cipher_ctx->sess, 0, sizeof(to_cipher_ctx->sess)); -- return cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx), -- (cipher_ctx->op == COP_ENCRYPT)); -- -- case EVP_CTRL_INIT: -- memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess)); -- return 1; -- -- default: -- break; -- } -- -- return -1; --} -- --static int cipher_cleanup(EVP_CIPHER_CTX *ctx) --{ -- struct cipher_ctx *cipher_ctx = -- (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); -- -- return clean_devcrypto_session(&cipher_ctx->sess); --} -- --/* -- * Keep tables of known nids, associated methods, selected ciphers, and driver -- * info. -- * Note that known_cipher_nids[] isn't necessarily indexed the same way as -- * cipher_data[] above, which the other tables are. -- */ --static int known_cipher_nids[OSSL_NELEM(cipher_data)]; --static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */ --static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, }; --static int selected_ciphers[OSSL_NELEM(cipher_data)]; --static struct driver_info_st cipher_driver_info[OSSL_NELEM(cipher_data)]; -- -- --static int devcrypto_test_cipher(size_t cipher_data_index) --{ -- return (cipher_driver_info[cipher_data_index].status == DEVCRYPTO_STATUS_USABLE -- && selected_ciphers[cipher_data_index] == 1 -- && (cipher_driver_info[cipher_data_index].accelerated -- == DEVCRYPTO_ACCELERATED -- || use_softdrivers == DEVCRYPTO_USE_SOFTWARE -- || (cipher_driver_info[cipher_data_index].accelerated -- != DEVCRYPTO_NOT_ACCELERATED -- && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE))); --} -- --static void prepare_cipher_methods(void) --{ -- size_t i; -- struct session_op sess; -- unsigned long cipher_mode; --#ifdef CIOCGSESSINFO -- struct session_info_op siop; --#endif -- -- memset(&cipher_driver_info, 0, sizeof(cipher_driver_info)); -- -- memset(&sess, 0, sizeof(sess)); -- sess.key = (void *)"01234567890123456789012345678901234567890123456789"; -- -- for (i = 0, known_cipher_nids_amount = 0; -- i < OSSL_NELEM(cipher_data); i++) { -- -- selected_ciphers[i] = 1; -- /* -- * Check that the cipher is usable -- */ -- sess.cipher = cipher_data[i].devcryptoid; -- sess.keylen = cipher_data[i].keylen; -- if (ioctl(cfd, CIOCGSESSION, &sess) < 0) { -- cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; -- continue; -- } -- -- cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE; -- -- if ((known_cipher_methods[i] = -- EVP_CIPHER_meth_new(cipher_data[i].nid, -- cipher_mode == EVP_CIPH_CTR_MODE ? 1 : -- cipher_data[i].blocksize, -- cipher_data[i].keylen)) == NULL -- || !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i], -- cipher_data[i].ivlen) -- || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i], -- cipher_data[i].flags -- | EVP_CIPH_CUSTOM_COPY -- | EVP_CIPH_CTRL_INIT -- | EVP_CIPH_FLAG_DEFAULT_ASN1) -- || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init) -- || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i], -- cipher_mode == EVP_CIPH_CTR_MODE ? -- ctr_do_cipher : -- cipher_do_cipher) -- || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl) -- || !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i], -- cipher_cleanup) -- || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i], -- sizeof(struct cipher_ctx))) { -- cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; -- EVP_CIPHER_meth_free(known_cipher_methods[i]); -- known_cipher_methods[i] = NULL; -- } else { -- cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE; --#ifdef CIOCGSESSINFO -- siop.ses = sess.ses; -- if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) { -- cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; -- } else { -- cipher_driver_info[i].driver_name = -- OPENSSL_strndup(siop.cipher_info.cra_driver_name, -- CRYPTODEV_MAX_ALG_NAME); -- if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)) -- cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; -- else -- cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; -- } --#endif /* CIOCGSESSINFO */ -- } -- ioctl(cfd, CIOCFSESSION, &sess.ses); -- if (devcrypto_test_cipher(i)) { -- known_cipher_nids[known_cipher_nids_amount++] = -- cipher_data[i].nid; -- } -- } --} -- --static void rebuild_known_cipher_nids(ENGINE *e) --{ -- size_t i; -- -- for (i = 0, known_cipher_nids_amount = 0; i < OSSL_NELEM(cipher_data); i++) { -- if (devcrypto_test_cipher(i)) -- known_cipher_nids[known_cipher_nids_amount++] = cipher_data[i].nid; -- } -- ENGINE_unregister_ciphers(e); -- ENGINE_register_ciphers(e); --} -- --static const EVP_CIPHER *get_cipher_method(int nid) --{ -- size_t i = get_cipher_data_index(nid); -- -- if (i == (size_t)-1) -- return NULL; -- return known_cipher_methods[i]; --} -- --static int get_cipher_nids(const int **nids) --{ -- *nids = known_cipher_nids; -- return known_cipher_nids_amount; --} -- --static void destroy_cipher_method(int nid) --{ -- size_t i = get_cipher_data_index(nid); -- -- EVP_CIPHER_meth_free(known_cipher_methods[i]); -- known_cipher_methods[i] = NULL; --} -- --static void destroy_all_cipher_methods(void) --{ -- size_t i; -- -- for (i = 0; i < OSSL_NELEM(cipher_data); i++) { -- destroy_cipher_method(cipher_data[i].nid); -- OPENSSL_free(cipher_driver_info[i].driver_name); -- cipher_driver_info[i].driver_name = NULL; -- } --} -- --static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher, -- const int **nids, int nid) --{ -- if (cipher == NULL) -- return get_cipher_nids(nids); -- -- *cipher = get_cipher_method(nid); -- -- return *cipher != NULL; --} -- --static void devcrypto_select_all_ciphers(int *cipher_list) --{ -- size_t i; -- -- for (i = 0; i < OSSL_NELEM(cipher_data); i++) -- cipher_list[i] = 1; --} -- --static int cryptodev_select_cipher_cb(const char *str, int len, void *usr) --{ -- int *cipher_list = (int *)usr; -- char *name; -- const EVP_CIPHER *EVP; -- size_t i; -- -- if (len == 0) -- return 1; -- if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL) -- return 0; -- EVP = EVP_get_cipherbyname(name); -- if (EVP == NULL) -- fprintf(stderr, "devcrypto: unknown cipher %s\n", name); -- else if ((i = find_cipher_data_index(EVP_CIPHER_nid(EVP))) != (size_t)-1) -- cipher_list[i] = 1; -- else -- fprintf(stderr, "devcrypto: cipher %s not available\n", name); -- OPENSSL_free(name); -- return 1; --} -- --static void dump_cipher_info(void) --{ -- size_t i; -- const char *name; -- -- fprintf (stderr, "Information about ciphers supported by the /dev/crypto" -- " engine:\n"); --#ifndef CIOCGSESSINFO -- fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n"); --#endif -- for (i = 0; i < OSSL_NELEM(cipher_data); i++) { -- name = OBJ_nid2sn(cipher_data[i].nid); -- fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ", -- name ? name : "unknown", cipher_data[i].nid, -- cipher_data[i].devcryptoid); -- if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION ) { -- fprintf (stderr, "CIOCGSESSION (session open call) failed\n"); -- continue; -- } -- fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ? -- cipher_driver_info[i].driver_name : "unknown"); -- if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED) -- fprintf(stderr, "(hw accelerated)"); -- else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED) -- fprintf(stderr, "(software)"); -- else -- fprintf(stderr, "(acceleration status unknown)"); -- if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE) -- fprintf (stderr, ". Cipher setup failed"); -- fprintf(stderr, "\n"); -- } -- fprintf(stderr, "\n"); --} -- --/* -- * We only support digests if the cryptodev implementation supports multiple -- * data updates and session copying. Otherwise, we would be forced to maintain -- * a cache, which is perilous if there's a lot of data coming in (if someone -- * wants to checksum an OpenSSL tarball, for example). -- */ --#if defined(CIOCCPHASH) && defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL) --#define IMPLEMENT_DIGEST -- --/****************************************************************************** -- * -- * Digests -- * -- * Because they all do the same basic operation, we have only one set of -- * method functions for them all to share, and a mapping table between -- * NIDs and cryptodev IDs, with all the necessary size data. -- * -- *****/ -- --struct digest_ctx { -- struct session_op sess; -- /* This signals that the init function was called, not that it succeeded. */ -- int init_called; -- unsigned char digest_res[HASH_MAX_LEN]; --}; -- --static const struct digest_data_st { -- int nid; -- int blocksize; -- int digestlen; -- int devcryptoid; --} digest_data[] = { --#ifndef OPENSSL_NO_MD5 -- { NID_md5, /* MD5_CBLOCK */ 64, 16, CRYPTO_MD5 }, --#endif -- { NID_sha1, SHA_CBLOCK, 20, CRYPTO_SHA1 }, --#ifndef OPENSSL_NO_RMD160 --# if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_RIPEMD160) -- { NID_ripemd160, /* RIPEMD160_CBLOCK */ 64, 20, CRYPTO_RIPEMD160 }, --# endif --#endif --#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_224) -- { NID_sha224, SHA256_CBLOCK, 224 / 8, CRYPTO_SHA2_224 }, --#endif --#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_256) -- { NID_sha256, SHA256_CBLOCK, 256 / 8, CRYPTO_SHA2_256 }, --#endif --#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_384) -- { NID_sha384, SHA512_CBLOCK, 384 / 8, CRYPTO_SHA2_384 }, --#endif --#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_512) -- { NID_sha512, SHA512_CBLOCK, 512 / 8, CRYPTO_SHA2_512 }, --#endif --}; -- --static size_t find_digest_data_index(int nid) --{ -- size_t i; -- -- for (i = 0; i < OSSL_NELEM(digest_data); i++) -- if (nid == digest_data[i].nid) -- return i; -- return (size_t)-1; --} -- --static size_t get_digest_data_index(int nid) --{ -- size_t i = find_digest_data_index(nid); -- -- if (i != (size_t)-1) -- return i; -- -- /* -- * Code further down must make sure that only NIDs in the table above -- * are used. If any other NID reaches this function, there's a grave -- * coding error further down. -- */ -- assert("Code that never should be reached" == NULL); -- return -1; --} -- --static const struct digest_data_st *get_digest_data(int nid) --{ -- return &digest_data[get_digest_data_index(nid)]; --} -- --/* -- * Following are the five necessary functions to map OpenSSL functionality -- * with cryptodev: init, update, final, cleanup, and copy. -- */ -- --static int digest_init(EVP_MD_CTX *ctx) --{ -- struct digest_ctx *digest_ctx = -- (struct digest_ctx *)EVP_MD_CTX_md_data(ctx); -- const struct digest_data_st *digest_d = -- get_digest_data(EVP_MD_CTX_type(ctx)); -- -- digest_ctx->init_called = 1; -- -- memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess)); -- digest_ctx->sess.mac = digest_d->devcryptoid; -- if (ioctl(cfd, CIOCGSESSION, &digest_ctx->sess) < 0) { -- SYSerr(SYS_F_IOCTL, errno); -- return 0; -- } -- -- return 1; --} -- --static int digest_op(struct digest_ctx *ctx, const void *src, size_t srclen, -- void *res, unsigned int flags) --{ -- struct crypt_op cryp; -- -- memset(&cryp, 0, sizeof(cryp)); -- cryp.ses = ctx->sess.ses; -- cryp.len = srclen; -- cryp.src = (void *)src; -- cryp.dst = NULL; -- cryp.mac = res; -- cryp.flags = flags; -- return ioctl(cfd, CIOCCRYPT, &cryp); --} -- --static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count) --{ -- struct digest_ctx *digest_ctx = -- (struct digest_ctx *)EVP_MD_CTX_md_data(ctx); -- -- if (count == 0) -- return 1; -- -- if (digest_ctx == NULL) -- return 0; -- -- if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) { -- if (digest_op(digest_ctx, data, count, digest_ctx->digest_res, 0) >= 0) -- return 1; -- } else if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) >= 0) { -- return 1; -- } -- -- SYSerr(SYS_F_IOCTL, errno); -- return 0; --} -- --static int digest_final(EVP_MD_CTX *ctx, unsigned char *md) --{ -- struct digest_ctx *digest_ctx = -- (struct digest_ctx *)EVP_MD_CTX_md_data(ctx); -- -- if (md == NULL || digest_ctx == NULL) -- return 0; -- -- if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) { -- memcpy(md, digest_ctx->digest_res, EVP_MD_CTX_size(ctx)); -- } else if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) { -- SYSerr(SYS_F_IOCTL, errno); -- return 0; -- } -- -- return 1; --} -- --static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) --{ -- struct digest_ctx *digest_from = -- (struct digest_ctx *)EVP_MD_CTX_md_data(from); -- struct digest_ctx *digest_to = -- (struct digest_ctx *)EVP_MD_CTX_md_data(to); -- struct cphash_op cphash; -- -- if (digest_from == NULL || digest_from->init_called != 1) -- return 1; -- -- if (!digest_init(to)) { -- SYSerr(SYS_F_IOCTL, errno); -- return 0; -- } -- -- cphash.src_ses = digest_from->sess.ses; -- cphash.dst_ses = digest_to->sess.ses; -- if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) { -- SYSerr(SYS_F_IOCTL, errno); -- return 0; -- } -- return 1; --} -- --static int digest_cleanup(EVP_MD_CTX *ctx) --{ -- struct digest_ctx *digest_ctx = -- (struct digest_ctx *)EVP_MD_CTX_md_data(ctx); -- -- if (digest_ctx == NULL) -- return 1; -- -- return clean_devcrypto_session(&digest_ctx->sess); --} -- --/* -- * Keep tables of known nids, associated methods, selected digests, and -- * driver info. -- * Note that known_digest_nids[] isn't necessarily indexed the same way as -- * digest_data[] above, which the other tables are. -- */ --static int known_digest_nids[OSSL_NELEM(digest_data)]; --static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */ --static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, }; --static int selected_digests[OSSL_NELEM(digest_data)]; --static struct driver_info_st digest_driver_info[OSSL_NELEM(digest_data)]; -- --static int devcrypto_test_digest(size_t digest_data_index) --{ -- return (digest_driver_info[digest_data_index].status == DEVCRYPTO_STATUS_USABLE -- && selected_digests[digest_data_index] == 1 -- && (digest_driver_info[digest_data_index].accelerated -- == DEVCRYPTO_ACCELERATED -- || use_softdrivers == DEVCRYPTO_USE_SOFTWARE -- || (digest_driver_info[digest_data_index].accelerated -- != DEVCRYPTO_NOT_ACCELERATED -- && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE))); --} -- --static void rebuild_known_digest_nids(ENGINE *e) --{ -- size_t i; -- -- for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); i++) { -- if (devcrypto_test_digest(i)) -- known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid; -- } -- ENGINE_unregister_digests(e); -- ENGINE_register_digests(e); --} -- --static void prepare_digest_methods(void) --{ -- size_t i; -- struct session_op sess1, sess2; --#ifdef CIOCGSESSINFO -- struct session_info_op siop; --#endif -- struct cphash_op cphash; -- -- memset(&digest_driver_info, 0, sizeof(digest_driver_info)); -- -- memset(&sess1, 0, sizeof(sess1)); -- memset(&sess2, 0, sizeof(sess2)); -- -- for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); -- i++) { -- -- selected_digests[i] = 1; -- -- /* -- * Check that the digest is usable -- */ -- sess1.mac = digest_data[i].devcryptoid; -- sess2.ses = 0; -- if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) { -- digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; -- goto finish; -- } -- --#ifdef CIOCGSESSINFO -- /* gather hardware acceleration info from the driver */ -- siop.ses = sess1.ses; -- if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) { -- digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; -- } else { -- digest_driver_info[i].driver_name = -- OPENSSL_strndup(siop.hash_info.cra_driver_name, -- CRYPTODEV_MAX_ALG_NAME); -- if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY) -- digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; -- else -- digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; -- } --#endif -- -- /* digest must be capable of hash state copy */ -- sess2.mac = sess1.mac; -- if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) { -- digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; -- goto finish; -- } -- cphash.src_ses = sess1.ses; -- cphash.dst_ses = sess2.ses; -- if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) { -- digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH; -- goto finish; -- } -- if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid, -- NID_undef)) == NULL -- || !EVP_MD_meth_set_input_blocksize(known_digest_methods[i], -- digest_data[i].blocksize) -- || !EVP_MD_meth_set_result_size(known_digest_methods[i], -- digest_data[i].digestlen) -- || !EVP_MD_meth_set_init(known_digest_methods[i], digest_init) -- || !EVP_MD_meth_set_update(known_digest_methods[i], digest_update) -- || !EVP_MD_meth_set_final(known_digest_methods[i], digest_final) -- || !EVP_MD_meth_set_copy(known_digest_methods[i], digest_copy) -- || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup) -- || !EVP_MD_meth_set_app_datasize(known_digest_methods[i], -- sizeof(struct digest_ctx))) { -- digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; -- EVP_MD_meth_free(known_digest_methods[i]); -- known_digest_methods[i] = NULL; -- goto finish; -- } -- digest_driver_info[i].status = DEVCRYPTO_STATUS_USABLE; --finish: -- ioctl(cfd, CIOCFSESSION, &sess1.ses); -- if (sess2.ses != 0) -- ioctl(cfd, CIOCFSESSION, &sess2.ses); -- if (devcrypto_test_digest(i)) -- known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid; -- } --} -- --static const EVP_MD *get_digest_method(int nid) --{ -- size_t i = get_digest_data_index(nid); -- -- if (i == (size_t)-1) -- return NULL; -- return known_digest_methods[i]; --} -- --static int get_digest_nids(const int **nids) --{ -- *nids = known_digest_nids; -- return known_digest_nids_amount; --} -- --static void destroy_digest_method(int nid) --{ -- size_t i = get_digest_data_index(nid); -- -- EVP_MD_meth_free(known_digest_methods[i]); -- known_digest_methods[i] = NULL; --} -- --static void destroy_all_digest_methods(void) --{ -- size_t i; -- -- for (i = 0; i < OSSL_NELEM(digest_data); i++) { -- destroy_digest_method(digest_data[i].nid); -- OPENSSL_free(digest_driver_info[i].driver_name); -- digest_driver_info[i].driver_name = NULL; -- } --} -- --static int devcrypto_digests(ENGINE *e, const EVP_MD **digest, -- const int **nids, int nid) --{ -- if (digest == NULL) -- return get_digest_nids(nids); -- -- *digest = get_digest_method(nid); -- -- return *digest != NULL; --} -- --static void devcrypto_select_all_digests(int *digest_list) --{ -- size_t i; -- -- for (i = 0; i < OSSL_NELEM(digest_data); i++) -- digest_list[i] = 1; --} -- --static int cryptodev_select_digest_cb(const char *str, int len, void *usr) --{ -- int *digest_list = (int *)usr; -- char *name; -- const EVP_MD *EVP; -- size_t i; -- -- if (len == 0) -- return 1; -- if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL) -- return 0; -- EVP = EVP_get_digestbyname(name); -- if (EVP == NULL) -- fprintf(stderr, "devcrypto: unknown digest %s\n", name); -- else if ((i = find_digest_data_index(EVP_MD_type(EVP))) != (size_t)-1) -- digest_list[i] = 1; -- else -- fprintf(stderr, "devcrypto: digest %s not available\n", name); -- OPENSSL_free(name); -- return 1; --} -- --static void dump_digest_info(void) --{ -- size_t i; -- const char *name; -- -- fprintf (stderr, "Information about digests supported by the /dev/crypto" -- " engine:\n"); --#ifndef CIOCGSESSINFO -- fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n"); --#endif -- -- for (i = 0; i < OSSL_NELEM(digest_data); i++) { -- name = OBJ_nid2sn(digest_data[i].nid); -- fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s", -- name ? name : "unknown", digest_data[i].nid, -- digest_data[i].devcryptoid, -- digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown"); -- if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) { -- fprintf (stderr, ". CIOCGSESSION (session open) failed\n"); -- continue; -- } -- if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED) -- fprintf(stderr, " (hw accelerated)"); -- else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED) -- fprintf(stderr, " (software)"); -- else -- fprintf(stderr, " (acceleration status unknown)"); -- if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE) -- fprintf (stderr, ". Cipher setup failed\n"); -- else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH) -- fprintf(stderr, ", CIOCCPHASH failed\n"); -- else -- fprintf(stderr, ", CIOCCPHASH capable\n"); -- } -- fprintf(stderr, "\n"); --} -- --#endif -- --/****************************************************************************** -- * -- * CONTROL COMMANDS -- * -- *****/ -- --#define DEVCRYPTO_CMD_USE_SOFTDRIVERS ENGINE_CMD_BASE --#define DEVCRYPTO_CMD_CIPHERS (ENGINE_CMD_BASE + 1) --#define DEVCRYPTO_CMD_DIGESTS (ENGINE_CMD_BASE + 2) --#define DEVCRYPTO_CMD_DUMP_INFO (ENGINE_CMD_BASE + 3) -- --/* Helper macros for CPP string composition */ --#ifndef OPENSSL_MSTR --# define OPENSSL_MSTR_HELPER(x) #x --# define OPENSSL_MSTR(x) OPENSSL_MSTR_HELPER(x) --#endif -- --static const ENGINE_CMD_DEFN devcrypto_cmds[] = { --#ifdef CIOCGSESSINFO -- {DEVCRYPTO_CMD_USE_SOFTDRIVERS, -- "USE_SOFTDRIVERS", -- "specifies whether to use software (not accelerated) drivers (" -- OPENSSL_MSTR(DEVCRYPTO_REQUIRE_ACCELERATED) "=use only accelerated drivers, " -- OPENSSL_MSTR(DEVCRYPTO_USE_SOFTWARE) "=allow all drivers, " -- OPENSSL_MSTR(DEVCRYPTO_REJECT_SOFTWARE) -- "=use if acceleration can't be determined) [default=" -- OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS) "]", -- ENGINE_CMD_FLAG_NUMERIC}, --#endif -- -- {DEVCRYPTO_CMD_CIPHERS, -- "CIPHERS", -- "either ALL, NONE, or a comma-separated list of ciphers to enable [default=ALL]", -- ENGINE_CMD_FLAG_STRING}, -- --#ifdef IMPLEMENT_DIGEST -- {DEVCRYPTO_CMD_DIGESTS, -- "DIGESTS", -- "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]", -- ENGINE_CMD_FLAG_STRING}, --#endif -- -- {DEVCRYPTO_CMD_DUMP_INFO, -- "DUMP_INFO", -- "dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'", -- ENGINE_CMD_FLAG_NO_INPUT}, -- -- {0, NULL, NULL, 0} --}; -- --static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) --{ -- int *new_list; -- switch (cmd) { --#ifdef CIOCGSESSINFO -- case DEVCRYPTO_CMD_USE_SOFTDRIVERS: -- switch (i) { -- case DEVCRYPTO_REQUIRE_ACCELERATED: -- case DEVCRYPTO_USE_SOFTWARE: -- case DEVCRYPTO_REJECT_SOFTWARE: -- break; -- default: -- fprintf(stderr, "devcrypto: invalid value (%ld) for USE_SOFTDRIVERS\n", i); -- return 0; -- } -- if (use_softdrivers == i) -- return 1; -- use_softdrivers = i; --#ifdef IMPLEMENT_DIGEST -- rebuild_known_digest_nids(e); --#endif -- rebuild_known_cipher_nids(e); -- return 1; --#endif /* CIOCGSESSINFO */ -- -- case DEVCRYPTO_CMD_CIPHERS: -- if (p == NULL) -- return 1; -- if (strcasecmp((const char *)p, "ALL") == 0) { -- devcrypto_select_all_ciphers(selected_ciphers); -- } else if (strcasecmp((const char*)p, "NONE") == 0) { -- memset(selected_ciphers, 0, sizeof(selected_ciphers)); -- } else { -- new_list=OPENSSL_zalloc(sizeof(selected_ciphers)); -- if (!CONF_parse_list(p, ',', 1, cryptodev_select_cipher_cb, new_list)) { -- OPENSSL_free(new_list); -- return 0; -- } -- memcpy(selected_ciphers, new_list, sizeof(selected_ciphers)); -- OPENSSL_free(new_list); -- } -- rebuild_known_cipher_nids(e); -- return 1; -- --#ifdef IMPLEMENT_DIGEST -- case DEVCRYPTO_CMD_DIGESTS: -- if (p == NULL) -- return 1; -- if (strcasecmp((const char *)p, "ALL") == 0) { -- devcrypto_select_all_digests(selected_digests); -- } else if (strcasecmp((const char*)p, "NONE") == 0) { -- memset(selected_digests, 0, sizeof(selected_digests)); -- } else { -- new_list=OPENSSL_zalloc(sizeof(selected_digests)); -- if (!CONF_parse_list(p, ',', 1, cryptodev_select_digest_cb, new_list)) { -- OPENSSL_free(new_list); -- return 0; -- } -- memcpy(selected_digests, new_list, sizeof(selected_digests)); -- OPENSSL_free(new_list); -- } -- rebuild_known_digest_nids(e); -- return 1; --#endif /* IMPLEMENT_DIGEST */ -- -- case DEVCRYPTO_CMD_DUMP_INFO: -- dump_cipher_info(); --#ifdef IMPLEMENT_DIGEST -- dump_digest_info(); --#endif -- return 1; -- -- default: -- break; -- } -- return 0; --} -- --/****************************************************************************** -- * -- * LOAD / UNLOAD -- * -- *****/ -- --static int devcrypto_unload(ENGINE *e) --{ -- destroy_all_cipher_methods(); --#ifdef IMPLEMENT_DIGEST -- destroy_all_digest_methods(); --#endif -- -- close(cfd); -- -- return 1; --} --/* -- * This engine is always built into libcrypto, so it doesn't offer any -- * ability to be dynamically loadable. -- */ --void engine_load_devcrypto_int() --{ -- ENGINE *e = NULL; -- int fd; -- -- if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) { --#ifndef ENGINE_DEVCRYPTO_DEBUG -- if (errno != ENOENT) --#endif -- fprintf(stderr, "Could not open /dev/crypto: %s\n", strerror(errno)); -- return; -- } -- --#ifdef CRIOGET -- if (ioctl(fd, CRIOGET, &cfd) < 0) { -- fprintf(stderr, "Could not create crypto fd: %s\n", strerror(errno)); -- close(fd); -- cfd = -1; -- return; -- } -- close(fd); --#else -- cfd = fd; --#endif -- -- if ((e = ENGINE_new()) == NULL -- || !ENGINE_set_destroy_function(e, devcrypto_unload)) { -- ENGINE_free(e); -- /* -- * We know that devcrypto_unload() won't be called when one of the -- * above two calls have failed, so we close cfd explicitly here to -- * avoid leaking resources. -- */ -- close(cfd); -- return; -- } -- -- prepare_cipher_methods(); --#ifdef IMPLEMENT_DIGEST -- prepare_digest_methods(); --#endif -- -- if (!ENGINE_set_id(e, "devcrypto") -- || !ENGINE_set_name(e, "/dev/crypto engine") -- || !ENGINE_set_cmd_defns(e, devcrypto_cmds) -- || !ENGINE_set_ctrl_function(e, devcrypto_ctrl) -- --/* -- * Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD -- * implementations, it seems to only exist in FreeBSD, and regarding the -- * parameters in its crypt_kop, the manual crypto(4) has this to say: -- * -- * The semantics of these arguments are currently undocumented. -- * -- * Reading through the FreeBSD source code doesn't give much more than -- * their CRK_MOD_EXP implementation for ubsec. -- * -- * It doesn't look much better with cryptodev-linux. They have the crypt_kop -- * structure as well as the command (CRK_*) in cryptodev.h, but no support -- * seems to be implemented at all for the moment. -- * -- * At the time of writing, it seems impossible to write proper support for -- * FreeBSD's asym features without some very deep knowledge and access to -- * specific kernel modules. -- * -- * /Richard Levitte, 2017-05-11 -- */ --#if 0 --# ifndef OPENSSL_NO_RSA -- || !ENGINE_set_RSA(e, devcrypto_rsa) --# endif --# ifndef OPENSSL_NO_DSA -- || !ENGINE_set_DSA(e, devcrypto_dsa) --# endif --# ifndef OPENSSL_NO_DH -- || !ENGINE_set_DH(e, devcrypto_dh) --# endif --# ifndef OPENSSL_NO_EC -- || !ENGINE_set_EC(e, devcrypto_ec) --# endif --#endif -- || !ENGINE_set_ciphers(e, devcrypto_ciphers) --#ifdef IMPLEMENT_DIGEST -- || !ENGINE_set_digests(e, devcrypto_digests) --#endif -- ) { -- ENGINE_free(e); -- return; -- } -- -- ENGINE_add(e); -- ENGINE_free(e); /* Loose our local reference */ -- ERR_clear_error(); --} ---- /dev/null -+++ b/engines/e_devcrypto.c -@@ -0,0 +1,1327 @@ -+/* -+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include "../e_os.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "crypto/engine.h" -+ -+/* #define ENGINE_DEVCRYPTO_DEBUG */ -+ -+#if CRYPTO_ALGORITHM_MIN < CRYPTO_ALGORITHM_MAX -+# define CHECK_BSD_STYLE_MACROS -+#endif -+ -+#define engine_devcrypto_id "devcrypto" -+ -+/* -+ * ONE global file descriptor for all sessions. This allows operations -+ * such as digest session data copying (see digest_copy()), but is also -+ * saner... why re-open /dev/crypto for every session? -+ */ -+static int cfd = -1; -+#define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */ -+#define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */ -+#define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */ -+ -+#define DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS DEVCRYPTO_REJECT_SOFTWARE -+static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS; -+ -+/* -+ * cipher/digest status & acceleration definitions -+ * Make sure the defaults are set to 0 -+ */ -+struct driver_info_st { -+ enum devcrypto_status_t { -+ DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */ -+ DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */ -+ DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */ -+ DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */ -+ DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */ -+ } status; -+ -+ enum devcrypto_accelerated_t { -+ DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */ -+ DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */ -+ DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */ -+ } accelerated; -+ -+ char *driver_name; -+}; -+ -+static int clean_devcrypto_session(struct session_op *sess) { -+ if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) { -+ SYSerr(SYS_F_IOCTL, errno); -+ return 0; -+ } -+ memset(sess, 0, sizeof(struct session_op)); -+ return 1; -+} -+ -+/****************************************************************************** -+ * -+ * Ciphers -+ * -+ * Because they all do the same basic operation, we have only one set of -+ * method functions for them all to share, and a mapping table between -+ * NIDs and cryptodev IDs, with all the necessary size data. -+ * -+ *****/ -+ -+struct cipher_ctx { -+ struct session_op sess; -+ int op; /* COP_ENCRYPT or COP_DECRYPT */ -+ unsigned long mode; /* EVP_CIPH_*_MODE */ -+ -+ /* to handle ctr mode being a stream cipher */ -+ unsigned char partial[EVP_MAX_BLOCK_LENGTH]; -+ unsigned int blocksize, num; -+}; -+ -+static const struct cipher_data_st { -+ int nid; -+ int blocksize; -+ int keylen; -+ int ivlen; -+ int flags; -+ int devcryptoid; -+} cipher_data[] = { -+#ifndef OPENSSL_NO_DES -+ { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC }, -+ { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC }, -+#endif -+#ifndef OPENSSL_NO_BF -+ { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC }, -+#endif -+#ifndef OPENSSL_NO_CAST -+ { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC }, -+#endif -+ { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, -+ { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, -+ { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, -+#ifndef OPENSSL_NO_RC4 -+ { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4 }, -+#endif -+#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_CTR) -+ { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, -+ { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, -+ { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, -+#endif -+#if 0 /* Not yet supported */ -+ { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS }, -+ { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS }, -+#endif -+#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB) -+ { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, -+ { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, -+ { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, -+#endif -+#if 0 /* Not yet supported */ -+ { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, -+ { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, -+ { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, -+#endif -+#ifndef OPENSSL_NO_CAMELLIA -+ { NID_camellia_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, -+ CRYPTO_CAMELLIA_CBC }, -+ { NID_camellia_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, -+ CRYPTO_CAMELLIA_CBC }, -+ { NID_camellia_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, -+ CRYPTO_CAMELLIA_CBC }, -+#endif -+}; -+ -+static size_t find_cipher_data_index(int nid) -+{ -+ size_t i; -+ -+ for (i = 0; i < OSSL_NELEM(cipher_data); i++) -+ if (nid == cipher_data[i].nid) -+ return i; -+ return (size_t)-1; -+} -+ -+static size_t get_cipher_data_index(int nid) -+{ -+ size_t i = find_cipher_data_index(nid); -+ -+ if (i != (size_t)-1) -+ return i; -+ -+ /* -+ * Code further down must make sure that only NIDs in the table above -+ * are used. If any other NID reaches this function, there's a grave -+ * coding error further down. -+ */ -+ assert("Code that never should be reached" == NULL); -+ return -1; -+} -+ -+static const struct cipher_data_st *get_cipher_data(int nid) -+{ -+ return &cipher_data[get_cipher_data_index(nid)]; -+} -+ -+/* -+ * Following are the three necessary functions to map OpenSSL functionality -+ * with cryptodev. -+ */ -+ -+static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, -+ const unsigned char *iv, int enc) -+{ -+ struct cipher_ctx *cipher_ctx = -+ (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); -+ const struct cipher_data_st *cipher_d = -+ get_cipher_data(EVP_CIPHER_CTX_nid(ctx)); -+ -+ /* cleanup a previous session */ -+ if (cipher_ctx->sess.ses != 0 && -+ clean_devcrypto_session(&cipher_ctx->sess) == 0) -+ return 0; -+ -+ cipher_ctx->sess.cipher = cipher_d->devcryptoid; -+ cipher_ctx->sess.keylen = cipher_d->keylen; -+ cipher_ctx->sess.key = (void *)key; -+ cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT; -+ cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE; -+ cipher_ctx->blocksize = cipher_d->blocksize; -+ if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) { -+ SYSerr(SYS_F_IOCTL, errno); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, -+ const unsigned char *in, size_t inl) -+{ -+ struct cipher_ctx *cipher_ctx = -+ (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); -+ struct crypt_op cryp; -+ unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); -+#if !defined(COP_FLAG_WRITE_IV) -+ unsigned char saved_iv[EVP_MAX_IV_LENGTH]; -+ const unsigned char *ivptr; -+ size_t nblocks, ivlen; -+#endif -+ -+ memset(&cryp, 0, sizeof(cryp)); -+ cryp.ses = cipher_ctx->sess.ses; -+ cryp.len = inl; -+ cryp.src = (void *)in; -+ cryp.dst = (void *)out; -+ cryp.iv = (void *)iv; -+ cryp.op = cipher_ctx->op; -+#if !defined(COP_FLAG_WRITE_IV) -+ cryp.flags = 0; -+ -+ ivlen = EVP_CIPHER_CTX_iv_length(ctx); -+ if (ivlen > 0) -+ switch (cipher_ctx->mode) { -+ case EVP_CIPH_CBC_MODE: -+ assert(inl >= ivlen); -+ if (!EVP_CIPHER_CTX_encrypting(ctx)) { -+ ivptr = in + inl - ivlen; -+ memcpy(saved_iv, ivptr, ivlen); -+ } -+ break; -+ -+ case EVP_CIPH_CTR_MODE: -+ break; -+ -+ default: /* should not happen */ -+ return 0; -+ } -+#else -+ cryp.flags = COP_FLAG_WRITE_IV; -+#endif -+ -+ if (ioctl(cfd, CIOCCRYPT, &cryp) < 0) { -+ SYSerr(SYS_F_IOCTL, errno); -+ return 0; -+ } -+ -+#if !defined(COP_FLAG_WRITE_IV) -+ if (ivlen > 0) -+ switch (cipher_ctx->mode) { -+ case EVP_CIPH_CBC_MODE: -+ assert(inl >= ivlen); -+ if (EVP_CIPHER_CTX_encrypting(ctx)) -+ ivptr = out + inl - ivlen; -+ else -+ ivptr = saved_iv; -+ -+ memcpy(iv, ivptr, ivlen); -+ break; -+ -+ case EVP_CIPH_CTR_MODE: -+ nblocks = (inl + cipher_ctx->blocksize - 1) -+ / cipher_ctx->blocksize; -+ do { -+ ivlen--; -+ nblocks += iv[ivlen]; -+ iv[ivlen] = (uint8_t) nblocks; -+ nblocks >>= 8; -+ } while (ivlen); -+ break; -+ -+ default: /* should not happen */ -+ return 0; -+ } -+#endif -+ -+ return 1; -+} -+ -+static int ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, -+ const unsigned char *in, size_t inl) -+{ -+ struct cipher_ctx *cipher_ctx = -+ (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); -+ size_t nblocks, len; -+ -+ /* initial partial block */ -+ while (cipher_ctx->num && inl) { -+ (*out++) = *(in++) ^ cipher_ctx->partial[cipher_ctx->num]; -+ --inl; -+ cipher_ctx->num = (cipher_ctx->num + 1) % cipher_ctx->blocksize; -+ } -+ -+ /* full blocks */ -+ if (inl > (unsigned int) cipher_ctx->blocksize) { -+ nblocks = inl/cipher_ctx->blocksize; -+ len = nblocks * cipher_ctx->blocksize; -+ if (cipher_do_cipher(ctx, out, in, len) < 1) -+ return 0; -+ inl -= len; -+ out += len; -+ in += len; -+ } -+ -+ /* final partial block */ -+ if (inl) { -+ memset(cipher_ctx->partial, 0, cipher_ctx->blocksize); -+ if (cipher_do_cipher(ctx, cipher_ctx->partial, cipher_ctx->partial, -+ cipher_ctx->blocksize) < 1) -+ return 0; -+ while (inl--) { -+ out[cipher_ctx->num] = in[cipher_ctx->num] -+ ^ cipher_ctx->partial[cipher_ctx->num]; -+ cipher_ctx->num++; -+ } -+ } -+ -+ return 1; -+} -+ -+static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2) -+{ -+ struct cipher_ctx *cipher_ctx = -+ (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); -+ EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2; -+ struct cipher_ctx *to_cipher_ctx; -+ -+ switch (type) { -+ case EVP_CTRL_COPY: -+ if (cipher_ctx == NULL) -+ return 1; -+ /* when copying the context, a new session needs to be initialized */ -+ to_cipher_ctx = -+ (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(to_ctx); -+ memset(&to_cipher_ctx->sess, 0, sizeof(to_cipher_ctx->sess)); -+ return cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx), -+ (cipher_ctx->op == COP_ENCRYPT)); -+ -+ case EVP_CTRL_INIT: -+ memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess)); -+ return 1; -+ -+ default: -+ break; -+ } -+ -+ return -1; -+} -+ -+static int cipher_cleanup(EVP_CIPHER_CTX *ctx) -+{ -+ struct cipher_ctx *cipher_ctx = -+ (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); -+ -+ return clean_devcrypto_session(&cipher_ctx->sess); -+} -+ -+/* -+ * Keep tables of known nids, associated methods, selected ciphers, and driver -+ * info. -+ * Note that known_cipher_nids[] isn't necessarily indexed the same way as -+ * cipher_data[] above, which the other tables are. -+ */ -+static int known_cipher_nids[OSSL_NELEM(cipher_data)]; -+static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */ -+static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, }; -+static int selected_ciphers[OSSL_NELEM(cipher_data)]; -+static struct driver_info_st cipher_driver_info[OSSL_NELEM(cipher_data)]; -+ -+ -+static int devcrypto_test_cipher(size_t cipher_data_index) -+{ -+ return (cipher_driver_info[cipher_data_index].status == DEVCRYPTO_STATUS_USABLE -+ && selected_ciphers[cipher_data_index] == 1 -+ && (cipher_driver_info[cipher_data_index].accelerated -+ == DEVCRYPTO_ACCELERATED -+ || use_softdrivers == DEVCRYPTO_USE_SOFTWARE -+ || (cipher_driver_info[cipher_data_index].accelerated -+ != DEVCRYPTO_NOT_ACCELERATED -+ && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE))); -+} -+ -+static void prepare_cipher_methods(void) -+{ -+ size_t i; -+ struct session_op sess; -+ unsigned long cipher_mode; -+#ifdef CIOCGSESSINFO -+ struct session_info_op siop; -+#endif -+ -+ memset(&cipher_driver_info, 0, sizeof(cipher_driver_info)); -+ -+ memset(&sess, 0, sizeof(sess)); -+ sess.key = (void *)"01234567890123456789012345678901234567890123456789"; -+ -+ for (i = 0, known_cipher_nids_amount = 0; -+ i < OSSL_NELEM(cipher_data); i++) { -+ -+ selected_ciphers[i] = 1; -+ /* -+ * Check that the cipher is usable -+ */ -+ sess.cipher = cipher_data[i].devcryptoid; -+ sess.keylen = cipher_data[i].keylen; -+ if (ioctl(cfd, CIOCGSESSION, &sess) < 0) { -+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; -+ continue; -+ } -+ -+ cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE; -+ -+ if ((known_cipher_methods[i] = -+ EVP_CIPHER_meth_new(cipher_data[i].nid, -+ cipher_mode == EVP_CIPH_CTR_MODE ? 1 : -+ cipher_data[i].blocksize, -+ cipher_data[i].keylen)) == NULL -+ || !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i], -+ cipher_data[i].ivlen) -+ || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i], -+ cipher_data[i].flags -+ | EVP_CIPH_CUSTOM_COPY -+ | EVP_CIPH_CTRL_INIT -+ | EVP_CIPH_FLAG_DEFAULT_ASN1) -+ || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init) -+ || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i], -+ cipher_mode == EVP_CIPH_CTR_MODE ? -+ ctr_do_cipher : -+ cipher_do_cipher) -+ || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl) -+ || !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i], -+ cipher_cleanup) -+ || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i], -+ sizeof(struct cipher_ctx))) { -+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; -+ EVP_CIPHER_meth_free(known_cipher_methods[i]); -+ known_cipher_methods[i] = NULL; -+ } else { -+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE; -+#ifdef CIOCGSESSINFO -+ siop.ses = sess.ses; -+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) { -+ cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; -+ } else { -+ cipher_driver_info[i].driver_name = -+ OPENSSL_strndup(siop.cipher_info.cra_driver_name, -+ CRYPTODEV_MAX_ALG_NAME); -+ if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)) -+ cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; -+ else -+ cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; -+ } -+#endif /* CIOCGSESSINFO */ -+ } -+ ioctl(cfd, CIOCFSESSION, &sess.ses); -+ if (devcrypto_test_cipher(i)) { -+ known_cipher_nids[known_cipher_nids_amount++] = -+ cipher_data[i].nid; -+ } -+ } -+} -+ -+static void rebuild_known_cipher_nids(ENGINE *e) -+{ -+ size_t i; -+ -+ for (i = 0, known_cipher_nids_amount = 0; i < OSSL_NELEM(cipher_data); i++) { -+ if (devcrypto_test_cipher(i)) -+ known_cipher_nids[known_cipher_nids_amount++] = cipher_data[i].nid; -+ } -+ ENGINE_unregister_ciphers(e); -+ ENGINE_register_ciphers(e); -+} -+ -+static const EVP_CIPHER *get_cipher_method(int nid) -+{ -+ size_t i = get_cipher_data_index(nid); -+ -+ if (i == (size_t)-1) -+ return NULL; -+ return known_cipher_methods[i]; -+} -+ -+static int get_cipher_nids(const int **nids) -+{ -+ *nids = known_cipher_nids; -+ return known_cipher_nids_amount; -+} -+ -+static void destroy_cipher_method(int nid) -+{ -+ size_t i = get_cipher_data_index(nid); -+ -+ EVP_CIPHER_meth_free(known_cipher_methods[i]); -+ known_cipher_methods[i] = NULL; -+} -+ -+static void destroy_all_cipher_methods(void) -+{ -+ size_t i; -+ -+ for (i = 0; i < OSSL_NELEM(cipher_data); i++) { -+ destroy_cipher_method(cipher_data[i].nid); -+ OPENSSL_free(cipher_driver_info[i].driver_name); -+ cipher_driver_info[i].driver_name = NULL; -+ } -+} -+ -+static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher, -+ const int **nids, int nid) -+{ -+ if (cipher == NULL) -+ return get_cipher_nids(nids); -+ -+ *cipher = get_cipher_method(nid); -+ -+ return *cipher != NULL; -+} -+ -+static void devcrypto_select_all_ciphers(int *cipher_list) -+{ -+ size_t i; -+ -+ for (i = 0; i < OSSL_NELEM(cipher_data); i++) -+ cipher_list[i] = 1; -+} -+ -+static int cryptodev_select_cipher_cb(const char *str, int len, void *usr) -+{ -+ int *cipher_list = (int *)usr; -+ char *name; -+ const EVP_CIPHER *EVP; -+ size_t i; -+ -+ if (len == 0) -+ return 1; -+ if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL) -+ return 0; -+ EVP = EVP_get_cipherbyname(name); -+ if (EVP == NULL) -+ fprintf(stderr, "devcrypto: unknown cipher %s\n", name); -+ else if ((i = find_cipher_data_index(EVP_CIPHER_nid(EVP))) != (size_t)-1) -+ cipher_list[i] = 1; -+ else -+ fprintf(stderr, "devcrypto: cipher %s not available\n", name); -+ OPENSSL_free(name); -+ return 1; -+} -+ -+static void dump_cipher_info(void) -+{ -+ size_t i; -+ const char *name; -+ -+ fprintf (stderr, "Information about ciphers supported by the /dev/crypto" -+ " engine:\n"); -+#ifndef CIOCGSESSINFO -+ fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n"); -+#endif -+ for (i = 0; i < OSSL_NELEM(cipher_data); i++) { -+ name = OBJ_nid2sn(cipher_data[i].nid); -+ fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ", -+ name ? name : "unknown", cipher_data[i].nid, -+ cipher_data[i].devcryptoid); -+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION ) { -+ fprintf (stderr, "CIOCGSESSION (session open call) failed\n"); -+ continue; -+ } -+ fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ? -+ cipher_driver_info[i].driver_name : "unknown"); -+ if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED) -+ fprintf(stderr, "(hw accelerated)"); -+ else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED) -+ fprintf(stderr, "(software)"); -+ else -+ fprintf(stderr, "(acceleration status unknown)"); -+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE) -+ fprintf (stderr, ". Cipher setup failed"); -+ fprintf(stderr, "\n"); -+ } -+ fprintf(stderr, "\n"); -+} -+ -+/* -+ * We only support digests if the cryptodev implementation supports multiple -+ * data updates and session copying. Otherwise, we would be forced to maintain -+ * a cache, which is perilous if there's a lot of data coming in (if someone -+ * wants to checksum an OpenSSL tarball, for example). -+ */ -+#if defined(CIOCCPHASH) && defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL) -+#define IMPLEMENT_DIGEST -+ -+/****************************************************************************** -+ * -+ * Digests -+ * -+ * Because they all do the same basic operation, we have only one set of -+ * method functions for them all to share, and a mapping table between -+ * NIDs and cryptodev IDs, with all the necessary size data. -+ * -+ *****/ -+ -+struct digest_ctx { -+ struct session_op sess; -+ /* This signals that the init function was called, not that it succeeded. */ -+ int init_called; -+ unsigned char digest_res[HASH_MAX_LEN]; -+}; -+ -+static const struct digest_data_st { -+ int nid; -+ int blocksize; -+ int digestlen; -+ int devcryptoid; -+} digest_data[] = { -+#ifndef OPENSSL_NO_MD5 -+ { NID_md5, /* MD5_CBLOCK */ 64, 16, CRYPTO_MD5 }, -+#endif -+ { NID_sha1, SHA_CBLOCK, 20, CRYPTO_SHA1 }, -+#ifndef OPENSSL_NO_RMD160 -+# if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_RIPEMD160) -+ { NID_ripemd160, /* RIPEMD160_CBLOCK */ 64, 20, CRYPTO_RIPEMD160 }, -+# endif -+#endif -+#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_224) -+ { NID_sha224, SHA256_CBLOCK, 224 / 8, CRYPTO_SHA2_224 }, -+#endif -+#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_256) -+ { NID_sha256, SHA256_CBLOCK, 256 / 8, CRYPTO_SHA2_256 }, -+#endif -+#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_384) -+ { NID_sha384, SHA512_CBLOCK, 384 / 8, CRYPTO_SHA2_384 }, -+#endif -+#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_512) -+ { NID_sha512, SHA512_CBLOCK, 512 / 8, CRYPTO_SHA2_512 }, -+#endif -+}; -+ -+static size_t find_digest_data_index(int nid) -+{ -+ size_t i; -+ -+ for (i = 0; i < OSSL_NELEM(digest_data); i++) -+ if (nid == digest_data[i].nid) -+ return i; -+ return (size_t)-1; -+} -+ -+static size_t get_digest_data_index(int nid) -+{ -+ size_t i = find_digest_data_index(nid); -+ -+ if (i != (size_t)-1) -+ return i; -+ -+ /* -+ * Code further down must make sure that only NIDs in the table above -+ * are used. If any other NID reaches this function, there's a grave -+ * coding error further down. -+ */ -+ assert("Code that never should be reached" == NULL); -+ return -1; -+} -+ -+static const struct digest_data_st *get_digest_data(int nid) -+{ -+ return &digest_data[get_digest_data_index(nid)]; -+} -+ -+/* -+ * Following are the five necessary functions to map OpenSSL functionality -+ * with cryptodev: init, update, final, cleanup, and copy. -+ */ -+ -+static int digest_init(EVP_MD_CTX *ctx) -+{ -+ struct digest_ctx *digest_ctx = -+ (struct digest_ctx *)EVP_MD_CTX_md_data(ctx); -+ const struct digest_data_st *digest_d = -+ get_digest_data(EVP_MD_CTX_type(ctx)); -+ -+ digest_ctx->init_called = 1; -+ -+ memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess)); -+ digest_ctx->sess.mac = digest_d->devcryptoid; -+ if (ioctl(cfd, CIOCGSESSION, &digest_ctx->sess) < 0) { -+ SYSerr(SYS_F_IOCTL, errno); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static int digest_op(struct digest_ctx *ctx, const void *src, size_t srclen, -+ void *res, unsigned int flags) -+{ -+ struct crypt_op cryp; -+ -+ memset(&cryp, 0, sizeof(cryp)); -+ cryp.ses = ctx->sess.ses; -+ cryp.len = srclen; -+ cryp.src = (void *)src; -+ cryp.dst = NULL; -+ cryp.mac = res; -+ cryp.flags = flags; -+ return ioctl(cfd, CIOCCRYPT, &cryp); -+} -+ -+static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count) -+{ -+ struct digest_ctx *digest_ctx = -+ (struct digest_ctx *)EVP_MD_CTX_md_data(ctx); -+ -+ if (count == 0) -+ return 1; -+ -+ if (digest_ctx == NULL) -+ return 0; -+ -+ if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) { -+ if (digest_op(digest_ctx, data, count, digest_ctx->digest_res, 0) >= 0) -+ return 1; -+ } else if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) >= 0) { -+ return 1; -+ } -+ -+ SYSerr(SYS_F_IOCTL, errno); -+ return 0; -+} -+ -+static int digest_final(EVP_MD_CTX *ctx, unsigned char *md) -+{ -+ struct digest_ctx *digest_ctx = -+ (struct digest_ctx *)EVP_MD_CTX_md_data(ctx); -+ -+ if (md == NULL || digest_ctx == NULL) -+ return 0; -+ -+ if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) { -+ memcpy(md, digest_ctx->digest_res, EVP_MD_CTX_size(ctx)); -+ } else if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) { -+ SYSerr(SYS_F_IOCTL, errno); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) -+{ -+ struct digest_ctx *digest_from = -+ (struct digest_ctx *)EVP_MD_CTX_md_data(from); -+ struct digest_ctx *digest_to = -+ (struct digest_ctx *)EVP_MD_CTX_md_data(to); -+ struct cphash_op cphash; -+ -+ if (digest_from == NULL || digest_from->init_called != 1) -+ return 1; -+ -+ if (!digest_init(to)) { -+ SYSerr(SYS_F_IOCTL, errno); -+ return 0; -+ } -+ -+ cphash.src_ses = digest_from->sess.ses; -+ cphash.dst_ses = digest_to->sess.ses; -+ if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) { -+ SYSerr(SYS_F_IOCTL, errno); -+ return 0; -+ } -+ return 1; -+} -+ -+static int digest_cleanup(EVP_MD_CTX *ctx) -+{ -+ struct digest_ctx *digest_ctx = -+ (struct digest_ctx *)EVP_MD_CTX_md_data(ctx); -+ -+ if (digest_ctx == NULL) -+ return 1; -+ -+ return clean_devcrypto_session(&digest_ctx->sess); -+} -+ -+/* -+ * Keep tables of known nids, associated methods, selected digests, and -+ * driver info. -+ * Note that known_digest_nids[] isn't necessarily indexed the same way as -+ * digest_data[] above, which the other tables are. -+ */ -+static int known_digest_nids[OSSL_NELEM(digest_data)]; -+static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */ -+static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, }; -+static int selected_digests[OSSL_NELEM(digest_data)]; -+static struct driver_info_st digest_driver_info[OSSL_NELEM(digest_data)]; -+ -+static int devcrypto_test_digest(size_t digest_data_index) -+{ -+ return (digest_driver_info[digest_data_index].status == DEVCRYPTO_STATUS_USABLE -+ && selected_digests[digest_data_index] == 1 -+ && (digest_driver_info[digest_data_index].accelerated -+ == DEVCRYPTO_ACCELERATED -+ || use_softdrivers == DEVCRYPTO_USE_SOFTWARE -+ || (digest_driver_info[digest_data_index].accelerated -+ != DEVCRYPTO_NOT_ACCELERATED -+ && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE))); -+} -+ -+static void rebuild_known_digest_nids(ENGINE *e) -+{ -+ size_t i; -+ -+ for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); i++) { -+ if (devcrypto_test_digest(i)) -+ known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid; -+ } -+ ENGINE_unregister_digests(e); -+ ENGINE_register_digests(e); -+} -+ -+static void prepare_digest_methods(void) -+{ -+ size_t i; -+ struct session_op sess1, sess2; -+#ifdef CIOCGSESSINFO -+ struct session_info_op siop; -+#endif -+ struct cphash_op cphash; -+ -+ memset(&digest_driver_info, 0, sizeof(digest_driver_info)); -+ -+ memset(&sess1, 0, sizeof(sess1)); -+ memset(&sess2, 0, sizeof(sess2)); -+ -+ for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); -+ i++) { -+ -+ selected_digests[i] = 1; -+ -+ /* -+ * Check that the digest is usable -+ */ -+ sess1.mac = digest_data[i].devcryptoid; -+ sess2.ses = 0; -+ if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) { -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; -+ goto finish; -+ } -+ -+#ifdef CIOCGSESSINFO -+ /* gather hardware acceleration info from the driver */ -+ siop.ses = sess1.ses; -+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) { -+ digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; -+ } else { -+ digest_driver_info[i].driver_name = -+ OPENSSL_strndup(siop.hash_info.cra_driver_name, -+ CRYPTODEV_MAX_ALG_NAME); -+ if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY) -+ digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; -+ else -+ digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; -+ } -+#endif -+ -+ /* digest must be capable of hash state copy */ -+ sess2.mac = sess1.mac; -+ if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) { -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; -+ goto finish; -+ } -+ cphash.src_ses = sess1.ses; -+ cphash.dst_ses = sess2.ses; -+ if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) { -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH; -+ goto finish; -+ } -+ if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid, -+ NID_undef)) == NULL -+ || !EVP_MD_meth_set_input_blocksize(known_digest_methods[i], -+ digest_data[i].blocksize) -+ || !EVP_MD_meth_set_result_size(known_digest_methods[i], -+ digest_data[i].digestlen) -+ || !EVP_MD_meth_set_init(known_digest_methods[i], digest_init) -+ || !EVP_MD_meth_set_update(known_digest_methods[i], digest_update) -+ || !EVP_MD_meth_set_final(known_digest_methods[i], digest_final) -+ || !EVP_MD_meth_set_copy(known_digest_methods[i], digest_copy) -+ || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup) -+ || !EVP_MD_meth_set_app_datasize(known_digest_methods[i], -+ sizeof(struct digest_ctx))) { -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; -+ EVP_MD_meth_free(known_digest_methods[i]); -+ known_digest_methods[i] = NULL; -+ goto finish; -+ } -+ digest_driver_info[i].status = DEVCRYPTO_STATUS_USABLE; -+finish: -+ ioctl(cfd, CIOCFSESSION, &sess1.ses); -+ if (sess2.ses != 0) -+ ioctl(cfd, CIOCFSESSION, &sess2.ses); -+ if (devcrypto_test_digest(i)) -+ known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid; -+ } -+} -+ -+static const EVP_MD *get_digest_method(int nid) -+{ -+ size_t i = get_digest_data_index(nid); -+ -+ if (i == (size_t)-1) -+ return NULL; -+ return known_digest_methods[i]; -+} -+ -+static int get_digest_nids(const int **nids) -+{ -+ *nids = known_digest_nids; -+ return known_digest_nids_amount; -+} -+ -+static void destroy_digest_method(int nid) -+{ -+ size_t i = get_digest_data_index(nid); -+ -+ EVP_MD_meth_free(known_digest_methods[i]); -+ known_digest_methods[i] = NULL; -+} -+ -+static void destroy_all_digest_methods(void) -+{ -+ size_t i; -+ -+ for (i = 0; i < OSSL_NELEM(digest_data); i++) { -+ destroy_digest_method(digest_data[i].nid); -+ OPENSSL_free(digest_driver_info[i].driver_name); -+ digest_driver_info[i].driver_name = NULL; -+ } -+} -+ -+static int devcrypto_digests(ENGINE *e, const EVP_MD **digest, -+ const int **nids, int nid) -+{ -+ if (digest == NULL) -+ return get_digest_nids(nids); -+ -+ *digest = get_digest_method(nid); -+ -+ return *digest != NULL; -+} -+ -+static void devcrypto_select_all_digests(int *digest_list) -+{ -+ size_t i; -+ -+ for (i = 0; i < OSSL_NELEM(digest_data); i++) -+ digest_list[i] = 1; -+} -+ -+static int cryptodev_select_digest_cb(const char *str, int len, void *usr) -+{ -+ int *digest_list = (int *)usr; -+ char *name; -+ const EVP_MD *EVP; -+ size_t i; -+ -+ if (len == 0) -+ return 1; -+ if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL) -+ return 0; -+ EVP = EVP_get_digestbyname(name); -+ if (EVP == NULL) -+ fprintf(stderr, "devcrypto: unknown digest %s\n", name); -+ else if ((i = find_digest_data_index(EVP_MD_type(EVP))) != (size_t)-1) -+ digest_list[i] = 1; -+ else -+ fprintf(stderr, "devcrypto: digest %s not available\n", name); -+ OPENSSL_free(name); -+ return 1; -+} -+ -+static void dump_digest_info(void) -+{ -+ size_t i; -+ const char *name; -+ -+ fprintf (stderr, "Information about digests supported by the /dev/crypto" -+ " engine:\n"); -+#ifndef CIOCGSESSINFO -+ fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n"); -+#endif -+ -+ for (i = 0; i < OSSL_NELEM(digest_data); i++) { -+ name = OBJ_nid2sn(digest_data[i].nid); -+ fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s", -+ name ? name : "unknown", digest_data[i].nid, -+ digest_data[i].devcryptoid, -+ digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown"); -+ if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) { -+ fprintf (stderr, ". CIOCGSESSION (session open) failed\n"); -+ continue; -+ } -+ if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED) -+ fprintf(stderr, " (hw accelerated)"); -+ else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED) -+ fprintf(stderr, " (software)"); -+ else -+ fprintf(stderr, " (acceleration status unknown)"); -+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE) -+ fprintf (stderr, ". Cipher setup failed\n"); -+ else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH) -+ fprintf(stderr, ", CIOCCPHASH failed\n"); -+ else -+ fprintf(stderr, ", CIOCCPHASH capable\n"); -+ } -+ fprintf(stderr, "\n"); -+} -+ -+#endif -+ -+/****************************************************************************** -+ * -+ * CONTROL COMMANDS -+ * -+ *****/ -+ -+#define DEVCRYPTO_CMD_USE_SOFTDRIVERS ENGINE_CMD_BASE -+#define DEVCRYPTO_CMD_CIPHERS (ENGINE_CMD_BASE + 1) -+#define DEVCRYPTO_CMD_DIGESTS (ENGINE_CMD_BASE + 2) -+#define DEVCRYPTO_CMD_DUMP_INFO (ENGINE_CMD_BASE + 3) -+ -+/* Helper macros for CPP string composition */ -+#ifndef OPENSSL_MSTR -+# define OPENSSL_MSTR_HELPER(x) #x -+# define OPENSSL_MSTR(x) OPENSSL_MSTR_HELPER(x) -+#endif -+ -+static const ENGINE_CMD_DEFN devcrypto_cmds[] = { -+#ifdef CIOCGSESSINFO -+ {DEVCRYPTO_CMD_USE_SOFTDRIVERS, -+ "USE_SOFTDRIVERS", -+ "specifies whether to use software (not accelerated) drivers (" -+ OPENSSL_MSTR(DEVCRYPTO_REQUIRE_ACCELERATED) "=use only accelerated drivers, " -+ OPENSSL_MSTR(DEVCRYPTO_USE_SOFTWARE) "=allow all drivers, " -+ OPENSSL_MSTR(DEVCRYPTO_REJECT_SOFTWARE) -+ "=use if acceleration can't be determined) [default=" -+ OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS) "]", -+ ENGINE_CMD_FLAG_NUMERIC}, -+#endif -+ -+ {DEVCRYPTO_CMD_CIPHERS, -+ "CIPHERS", -+ "either ALL, NONE, or a comma-separated list of ciphers to enable [default=ALL]", -+ ENGINE_CMD_FLAG_STRING}, -+ -+#ifdef IMPLEMENT_DIGEST -+ {DEVCRYPTO_CMD_DIGESTS, -+ "DIGESTS", -+ "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]", -+ ENGINE_CMD_FLAG_STRING}, -+#endif -+ -+ {DEVCRYPTO_CMD_DUMP_INFO, -+ "DUMP_INFO", -+ "dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'", -+ ENGINE_CMD_FLAG_NO_INPUT}, -+ -+ {0, NULL, NULL, 0} -+}; -+ -+static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -+{ -+ int *new_list; -+ switch (cmd) { -+#ifdef CIOCGSESSINFO -+ case DEVCRYPTO_CMD_USE_SOFTDRIVERS: -+ switch (i) { -+ case DEVCRYPTO_REQUIRE_ACCELERATED: -+ case DEVCRYPTO_USE_SOFTWARE: -+ case DEVCRYPTO_REJECT_SOFTWARE: -+ break; -+ default: -+ fprintf(stderr, "devcrypto: invalid value (%ld) for USE_SOFTDRIVERS\n", i); -+ return 0; -+ } -+ if (use_softdrivers == i) -+ return 1; -+ use_softdrivers = i; -+#ifdef IMPLEMENT_DIGEST -+ rebuild_known_digest_nids(e); -+#endif -+ rebuild_known_cipher_nids(e); -+ return 1; -+#endif /* CIOCGSESSINFO */ -+ -+ case DEVCRYPTO_CMD_CIPHERS: -+ if (p == NULL) -+ return 1; -+ if (strcasecmp((const char *)p, "ALL") == 0) { -+ devcrypto_select_all_ciphers(selected_ciphers); -+ } else if (strcasecmp((const char*)p, "NONE") == 0) { -+ memset(selected_ciphers, 0, sizeof(selected_ciphers)); -+ } else { -+ new_list=OPENSSL_zalloc(sizeof(selected_ciphers)); -+ if (!CONF_parse_list(p, ',', 1, cryptodev_select_cipher_cb, new_list)) { -+ OPENSSL_free(new_list); -+ return 0; -+ } -+ memcpy(selected_ciphers, new_list, sizeof(selected_ciphers)); -+ OPENSSL_free(new_list); -+ } -+ rebuild_known_cipher_nids(e); -+ return 1; -+ -+#ifdef IMPLEMENT_DIGEST -+ case DEVCRYPTO_CMD_DIGESTS: -+ if (p == NULL) -+ return 1; -+ if (strcasecmp((const char *)p, "ALL") == 0) { -+ devcrypto_select_all_digests(selected_digests); -+ } else if (strcasecmp((const char*)p, "NONE") == 0) { -+ memset(selected_digests, 0, sizeof(selected_digests)); -+ } else { -+ new_list=OPENSSL_zalloc(sizeof(selected_digests)); -+ if (!CONF_parse_list(p, ',', 1, cryptodev_select_digest_cb, new_list)) { -+ OPENSSL_free(new_list); -+ return 0; -+ } -+ memcpy(selected_digests, new_list, sizeof(selected_digests)); -+ OPENSSL_free(new_list); -+ } -+ rebuild_known_digest_nids(e); -+ return 1; -+#endif /* IMPLEMENT_DIGEST */ -+ -+ case DEVCRYPTO_CMD_DUMP_INFO: -+ dump_cipher_info(); -+#ifdef IMPLEMENT_DIGEST -+ dump_digest_info(); -+#endif -+ return 1; -+ -+ default: -+ break; -+ } -+ return 0; -+} -+ -+/****************************************************************************** -+ * -+ * LOAD / UNLOAD -+ * -+ *****/ -+ -+/* -+ * Opens /dev/crypto -+ */ -+static int open_devcrypto(void) -+{ -+ int fd; -+ -+ if (cfd >= 0) -+ return 1; -+ -+ if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) { -+#ifndef ENGINE_DEVCRYPTO_DEBUG -+ if (errno != ENOENT) -+#endif -+ fprintf(stderr, "Could not open /dev/crypto: %s\n", strerror(errno)); -+ return 0; -+ } -+ -+#ifdef CRIOGET -+ if (ioctl(fd, CRIOGET, &cfd) < 0) { -+ fprintf(stderr, "Could not create crypto fd: %s\n", strerror(errno)); -+ close(fd); -+ cfd = -1; -+ return 0; -+ } -+ close(fd); -+#else -+ cfd = fd; -+#endif -+ -+ return 1; -+} -+ -+static int close_devcrypto(void) -+{ -+ int ret; -+ -+ if (cfd < 0) -+ return 1; -+ ret = close(cfd); -+ cfd = -1; -+ if (ret != 0) { -+ fprintf(stderr, "Error closing /dev/crypto: %s\n", strerror(errno)); -+ return 0; -+ } -+ return 1; -+} -+ -+static int devcrypto_unload(ENGINE *e) -+{ -+ destroy_all_cipher_methods(); -+#ifdef IMPLEMENT_DIGEST -+ destroy_all_digest_methods(); -+#endif -+ -+ close_devcrypto(); -+ -+ return 1; -+} -+ -+static int bind_devcrypto(ENGINE *e) { -+ -+ if (!ENGINE_set_id(e, engine_devcrypto_id) -+ || !ENGINE_set_name(e, "/dev/crypto engine") -+ || !ENGINE_set_destroy_function(e, devcrypto_unload) -+ || !ENGINE_set_cmd_defns(e, devcrypto_cmds) -+ || !ENGINE_set_ctrl_function(e, devcrypto_ctrl)) -+ return 0; -+ -+ prepare_cipher_methods(); -+#ifdef IMPLEMENT_DIGEST -+ prepare_digest_methods(); -+#endif -+ -+ return (ENGINE_set_ciphers(e, devcrypto_ciphers) -+#ifdef IMPLEMENT_DIGEST -+ && ENGINE_set_digests(e, devcrypto_digests) -+#endif -+/* -+ * Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD -+ * implementations, it seems to only exist in FreeBSD, and regarding the -+ * parameters in its crypt_kop, the manual crypto(4) has this to say: -+ * -+ * The semantics of these arguments are currently undocumented. -+ * -+ * Reading through the FreeBSD source code doesn't give much more than -+ * their CRK_MOD_EXP implementation for ubsec. -+ * -+ * It doesn't look much better with cryptodev-linux. They have the crypt_kop -+ * structure as well as the command (CRK_*) in cryptodev.h, but no support -+ * seems to be implemented at all for the moment. -+ * -+ * At the time of writing, it seems impossible to write proper support for -+ * FreeBSD's asym features without some very deep knowledge and access to -+ * specific kernel modules. -+ * -+ * /Richard Levitte, 2017-05-11 -+ */ -+#if 0 -+# ifndef OPENSSL_NO_RSA -+ && ENGINE_set_RSA(e, devcrypto_rsa) -+# endif -+# ifndef OPENSSL_NO_DSA -+ && ENGINE_set_DSA(e, devcrypto_dsa) -+# endif -+# ifndef OPENSSL_NO_DH -+ && ENGINE_set_DH(e, devcrypto_dh) -+# endif -+# ifndef OPENSSL_NO_EC -+ && ENGINE_set_EC(e, devcrypto_ec) -+# endif -+#endif -+ ); -+} -+ -+#ifdef OPENSSL_NO_DYNAMIC_ENGINE -+/* -+ * In case this engine is built into libcrypto, then it doesn't offer any -+ * ability to be dynamically loadable. -+ */ -+void engine_load_devcrypto_int(void) -+{ -+ ENGINE *e = NULL; -+ -+ if (!open_devcrypto()) -+ return; -+ -+ if ((e = ENGINE_new()) == NULL -+ || !bind_devcrypto(e)) { -+ close_devcrypto(); -+ ENGINE_free(e); -+ return; -+ } -+ -+ ENGINE_add(e); -+ ENGINE_free(e); /* Loose our local reference */ -+ ERR_clear_error(); -+} -+ -+#else -+ -+static int bind_helper(ENGINE *e, const char *id) -+{ -+ if ((id && (strcmp(id, engine_devcrypto_id) != 0)) -+ || !open_devcrypto()) -+ return 0; -+ if (!bind_devcrypto(e)) { -+ close_devcrypto(); -+ return 0; -+ } -+ return 1; -+} -+ -+IMPLEMENT_DYNAMIC_CHECK_FN() -+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) -+ -+#endif diff --git a/package/libs/openssl/patches/500-e_devcrypto-default-to-not-use-digests-in-engine.patch b/package/libs/openssl/patches/500-e_devcrypto-default-to-not-use-digests-in-engine.patch deleted file mode 100644 index df5c16d8d2..0000000000 --- a/package/libs/openssl/patches/500-e_devcrypto-default-to-not-use-digests-in-engine.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Mon, 11 Mar 2019 09:29:13 -0300 -Subject: e_devcrypto: default to not use digests in engine - -Digests are almost always slower when using /dev/crypto because of the -cost of the context switches. Only for large blocks it is worth it. - -Also, when forking, the open context structures are duplicated, but the -internal kernel sessions are still shared between forks, which means an -update/close operation in one fork affects all processes using that -session. - -This affects digests, especially for HMAC, where the session with the -key hash is used as a source for subsequent operations. At least one -popular application does this across a fork. Disabling digests by -default will mitigate the problem, while still allowing the user to -turn them on if it is safe and fast enough. - -Signed-off-by: Eneas U de Queiroz - ---- a/engines/e_devcrypto.c -+++ b/engines/e_devcrypto.c -@@ -852,7 +852,7 @@ static void prepare_digest_methods(void) - for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); - i++) { - -- selected_digests[i] = 1; -+ selected_digests[i] = 0; - - /* - * Check that the digest is usable -@@ -1072,7 +1072,7 @@ static const ENGINE_CMD_DEFN devcrypto_c - #ifdef IMPLEMENT_DIGEST - {DEVCRYPTO_CMD_DIGESTS, - "DIGESTS", -- "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]", -+ "either ALL, NONE, or a comma-separated list of digests to enable [default=NONE]", - ENGINE_CMD_FLAG_STRING}, - #endif - diff --git a/package/libs/openssl/patches/510-e_devcrypto-ignore-error-when-closing-session.patch b/package/libs/openssl/patches/510-e_devcrypto-ignore-error-when-closing-session.patch deleted file mode 100644 index 87792cf9d0..0000000000 --- a/package/libs/openssl/patches/510-e_devcrypto-ignore-error-when-closing-session.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Eneas U de Queiroz -Date: Mon, 11 Mar 2019 10:15:14 -0300 -Subject: e_devcrypto: ignore error when closing session - -In cipher_init, ignore an eventual error when closing the previous -session. It may have been closed by another process after a fork. - -Signed-off-by: Eneas U de Queiroz - ---- a/engines/e_devcrypto.c -+++ b/engines/e_devcrypto.c -@@ -195,9 +195,8 @@ static int cipher_init(EVP_CIPHER_CTX *c - get_cipher_data(EVP_CIPHER_CTX_nid(ctx)); - - /* cleanup a previous session */ -- if (cipher_ctx->sess.ses != 0 && -- clean_devcrypto_session(&cipher_ctx->sess) == 0) -- return 0; -+ if (cipher_ctx->sess.ses != 0) -+ clean_devcrypto_session(&cipher_ctx->sess); - - cipher_ctx->sess.cipher = cipher_d->devcryptoid; - cipher_ctx->sess.keylen = cipher_d->keylen; From f56ef4c0401dd586be19002e27a64257c6b4184c Mon Sep 17 00:00:00 2001 From: Pawel Dembicki Date: Thu, 29 Sep 2022 15:18:48 +0200 Subject: [PATCH 19/22] mpc85xx: refresh kernel config It was done by "make kernel_oldconfig" command for 5.10 and 5.15. Signed-off-by: Pawel Dembicki --- target/linux/mpc85xx/config-5.10 | 10 +++------- target/linux/mpc85xx/config-5.15 | 32 ++++++++++++-------------------- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/target/linux/mpc85xx/config-5.10 b/target/linux/mpc85xx/config-5.10 index e45f9df3b0..ab2ca05f9c 100644 --- a/target/linux/mpc85xx/config-5.10 +++ b/target/linux/mpc85xx/config-5.10 @@ -36,15 +36,12 @@ CONFIG_COMPAT_32BIT_TIME=y # CONFIG_CPM2 is not set CONFIG_CPU_BIG_ENDIAN=y # CONFIG_CRYPTO_AES_PPC_SPE is not set -CONFIG_CRYPTO_AKCIPHER=y -CONFIG_CRYPTO_AKCIPHER2=y CONFIG_CRYPTO_AUTHENC=y CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_HW=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1 # CONFIG_CRYPTO_MD5_PPC is not set -CONFIG_CRYPTO_NULL=y CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_RSA=y @@ -84,7 +81,6 @@ CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_CPU=y CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_GENERIC_CPU_VULNERABILITIES=y CONFIG_GENERIC_EARLY_IOREMAP=y @@ -106,7 +102,6 @@ CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT_MAP=y # CONFIG_HIVEAP_330 is not set CONFIG_HW_RANDOM=y -# CONFIG_HW_RANDOM_XIPHERA is not set CONFIG_HZ_PERIODIC=y CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y @@ -130,8 +125,8 @@ CONFIG_LXT_PHY=y # CONFIG_MATH_EMULATION is not set CONFIG_MDIO_BUS=y CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y CONFIG_MEMFD_CREATE=y -# CONFIG_MFD_ROHM_BD71828 is not set CONFIG_MIGRATION=y CONFIG_MMU_GATHER_PAGE_SIZE=y CONFIG_MODULES_USE_ELF_RELA=y @@ -224,7 +219,6 @@ CONFIG_RAS=y # CONFIG_RED_15W_REV1 is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_GENERIC=y -# CONFIG_RTC_DRV_RV3032 is not set CONFIG_RTC_I2C_AND_SPI=y CONFIG_RTC_MC146818_LIB=y # CONFIG_SBC8548 is not set @@ -249,6 +243,8 @@ CONFIG_SRCU=y CONFIG_SWCONFIG=y CONFIG_SWPHY=y CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_TARGET_CPU="8540" +CONFIG_TARGET_CPU_BOOL=y CONFIG_TASK_SIZE=0xc0000000 CONFIG_THREAD_INFO_IN_TASK=y CONFIG_THREAD_SHIFT=13 diff --git a/target/linux/mpc85xx/config-5.15 b/target/linux/mpc85xx/config-5.15 index 8734038d33..9e143d7b87 100644 --- a/target/linux/mpc85xx/config-5.15 +++ b/target/linux/mpc85xx/config-5.15 @@ -14,7 +14,7 @@ CONFIG_ARCH_MMAP_RND_BITS_MAX=17 CONFIG_ARCH_MMAP_RND_BITS_MIN=11 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_STACKWALK=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y CONFIG_ASN1=y @@ -36,15 +36,11 @@ CONFIG_COMPAT_32BIT_TIME=y # CONFIG_CPM2 is not set CONFIG_CPU_BIG_ENDIAN=y # CONFIG_CRYPTO_AES_PPC_SPE is not set -CONFIG_CRYPTO_AKCIPHER=y -CONFIG_CRYPTO_AKCIPHER2=y CONFIG_CRYPTO_AUTHENC=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_HW=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1 # CONFIG_CRYPTO_MD5_PPC is not set -CONFIG_CRYPTO_NULL=y CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_RSA=y @@ -55,11 +51,8 @@ CONFIG_DATA_SHIFT=12 CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DNOTIFY=y CONFIG_DTC=y -# CONFIG_E200 is not set CONFIG_E500=y CONFIG_E500_CPU=y -# CONFIG_E5500_CPU is not set -# CONFIG_E6500_CPU is not set CONFIG_EARLY_PRINTK=y CONFIG_EDAC=y CONFIG_EDAC_ATOMIC_SCRUB=y @@ -67,7 +60,6 @@ CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_LEGACY_SYSFS=y CONFIG_EDAC_MPC85XX=y CONFIG_EDAC_SUPPORT=y -CONFIG_ENABLE_MUST_CHECK=y CONFIG_ETHERNET_PACKET_MANGLE=y CONFIG_FIXED_PHY=y CONFIG_FSL_BOOKE=y @@ -79,16 +71,18 @@ CONFIG_FSL_PCI=y CONFIG_FSL_PQ_MDIO=y CONFIG_FSL_SOC=y CONFIG_FSL_SOC_BOOKE=y +CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_CPU=y CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_GENERIC_CPU_VULNERABILITIES=y CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y CONFIG_GENERIC_IRQ_SHOW=y CONFIG_GENERIC_IRQ_SHOW_LEVEL=y CONFIG_GENERIC_ISA_DMA=y @@ -100,6 +94,7 @@ CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GEN_RTC=y # CONFIG_GE_IMP3A is not set CONFIG_GIANFAR=y +CONFIG_GPIO_CDEV=y CONFIG_GPIO_GENERIC=y CONFIG_GPIO_MPC8XXX=y CONFIG_HAS_DMA=y @@ -107,7 +102,6 @@ CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT_MAP=y # CONFIG_HIVEAP_330 is not set CONFIG_HW_RANDOM=y -# CONFIG_HW_RANDOM_XIPHERA is not set CONFIG_HZ_PERIODIC=y CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y @@ -131,8 +125,8 @@ CONFIG_LXT_PHY=y # CONFIG_MATH_EMULATION is not set CONFIG_MDIO_BUS=y CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y CONFIG_MEMFD_CREATE=y -# CONFIG_MFD_ROHM_BD71828 is not set CONFIG_MIGRATION=y CONFIG_MMU_GATHER_PAGE_SIZE=y CONFIG_MODULES_USE_ELF_RELA=y @@ -156,7 +150,9 @@ CONFIG_MTD_SPI_NOR=y # CONFIG_MVME2500 is not set CONFIG_NEED_PER_CPU_KM=y CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NET_SELFTESTS=y CONFIG_NLS=y +CONFIG_NR_CPUS=1 CONFIG_NR_IRQS=512 CONFIG_NVMEM=y CONFIG_OF=y @@ -168,7 +164,6 @@ CONFIG_OF_GPIO=y CONFIG_OF_IRQ=y CONFIG_OF_KOBJ=y CONFIG_OF_MDIO=y -CONFIG_OF_NET=y CONFIG_OLD_SIGACTION=y CONFIG_OLD_SIGSUSPEND=y # CONFIG_P1010_RDB is not set @@ -196,7 +191,6 @@ CONFIG_PHYSICAL_START=0x00000000 CONFIG_PPC=y CONFIG_PPC32=y # CONFIG_PPC64 is not set -# CONFIG_PPC_BOOK3S_32 is not set CONFIG_PPC_85xx=y # CONFIG_PPC_8xx is not set CONFIG_PPC_ADV_DEBUG_DACS=2 @@ -205,31 +199,27 @@ CONFIG_PPC_ADV_DEBUG_IACS=2 CONFIG_PPC_ADV_DEBUG_REGS=y CONFIG_PPC_BARRIER_NOSPEC=y CONFIG_PPC_BOOK3E_MMU=y -# CONFIG_PPC_BOOK3S_6xx is not set +# CONFIG_PPC_BOOK3S_32 is not set CONFIG_PPC_DOORBELL=y # CONFIG_PPC_E500MC is not set # CONFIG_PPC_EARLY_DEBUG is not set CONFIG_PPC_FSL_BOOK3E=y CONFIG_PPC_INDIRECT_PCI=y -# CONFIG_PPC_IRQ_SOFT_MASK_DEBUG is not set CONFIG_PPC_MMU_NOHASH=y -CONFIG_PPC_MMU_NOHASH_32=y CONFIG_PPC_PAGE_SHIFT=12 -# CONFIG_PPC_PTDUMP is not set # CONFIG_PPC_QEMU_E500 is not set CONFIG_PPC_SMP_MUXED_IPI=y CONFIG_PPC_UDBG_16550=y CONFIG_PPC_WERROR=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_QE_GPIO=y CONFIG_QUICC_ENGINE=y CONFIG_RAS=y # CONFIG_RED_15W_REV1 is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_GENERIC=y -# CONFIG_RTC_DRV_RV3032 is not set CONFIG_RTC_I2C_AND_SPI=y CONFIG_RTC_MC146818_LIB=y -# CONFIG_SBC8548 is not set # CONFIG_SCOM_DEBUGFS is not set CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_FSL=y @@ -251,6 +241,8 @@ CONFIG_SRCU=y CONFIG_SWCONFIG=y CONFIG_SWPHY=y CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_TARGET_CPU="8540" +CONFIG_TARGET_CPU_BOOL=y CONFIG_TASK_SIZE=0xc0000000 CONFIG_THREAD_INFO_IN_TASK=y CONFIG_THREAD_SHIFT=13 From bfa5e4e4eba36757826d0b5d463558f6916d3456 Mon Sep 17 00:00:00 2001 From: Pawel Dembicki Date: Thu, 29 Sep 2022 22:25:24 +0200 Subject: [PATCH 20/22] mcp85xx: Switch TP-Link TL-WDR4900 v1 to DSA This patch introduces DSA support for TP-Link TL-WDR4900 v1 switch. Swconfig driver for QCA8327 switch is removed because this router is only one device which use Qualcom swconfig switch. Signed-off-by: Pawel Dembicki Tested-by: Nick Hainke # TP Link WDR4900 v1 (5.15) --- .../mpc85xx/base-files/etc/board.d/02_network | 3 +- .../base-files/etc/board.d/05_compat-version | 15 +++ target/linux/mpc85xx/config-5.10 | 4 - target/linux/mpc85xx/config-5.15 | 4 - .../arch/powerpc/boot/dts/tl-wdr4900-v1.dts | 92 ++++++++++++++++--- target/linux/mpc85xx/image/p1010.mk | 2 + target/linux/mpc85xx/p1010/config-default | 9 ++ target/linux/mpc85xx/p1020/config-default | 1 + 8 files changed, 105 insertions(+), 25 deletions(-) create mode 100644 target/linux/mpc85xx/base-files/etc/board.d/05_compat-version diff --git a/target/linux/mpc85xx/base-files/etc/board.d/02_network b/target/linux/mpc85xx/base-files/etc/board.d/02_network index 03153b73d0..7a677ee96f 100644 --- a/target/linux/mpc85xx/base-files/etc/board.d/02_network +++ b/target/linux/mpc85xx/base-files/etc/board.d/02_network @@ -18,8 +18,7 @@ ocedo,panda) "0:lan" "1:lan" "2:lan" "3:lan" "4:lan" "5:lan" "6:lan" "7:lan" "8u@eth0" ;; tplink,tl-wdr4900-v1) - ucidef_add_switch "switch0" \ - "0@eth0" "2:lan:1" "3:lan:2" "4:lan:3" "5:lan:4" "1:wan" + ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan" ucidef_set_interface_macaddr "wan" "$(macaddr_add $(mtd_get_mac_binary u-boot 0x4fc00) 1)" ;; *) diff --git a/target/linux/mpc85xx/base-files/etc/board.d/05_compat-version b/target/linux/mpc85xx/base-files/etc/board.d/05_compat-version new file mode 100644 index 0000000000..bcc03e9502 --- /dev/null +++ b/target/linux/mpc85xx/base-files/etc/board.d/05_compat-version @@ -0,0 +1,15 @@ + +. /lib/functions.sh +. /lib/functions/uci-defaults.sh + +board_config_update + +case "$(board_name)" in + tplink,tl-wdr4900-v1) + ucidef_set_compat_version "1.1" + ;; +esac + +board_config_flush + +exit 0 diff --git a/target/linux/mpc85xx/config-5.10 b/target/linux/mpc85xx/config-5.10 index ab2ca05f9c..909cd53092 100644 --- a/target/linux/mpc85xx/config-5.10 +++ b/target/linux/mpc85xx/config-5.10 @@ -1,8 +1,6 @@ # CONFIG_40x is not set # CONFIG_44x is not set # CONFIG_ADVANCED_OPTIONS is not set -CONFIG_AR8216_PHY=y -CONFIG_AR8216_PHY_LEDS=y CONFIG_ARCH_32BIT_OFF_T=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_KEEP_MEMBLOCK=y @@ -65,7 +63,6 @@ CONFIG_EDAC_LEGACY_SYSFS=y CONFIG_EDAC_MPC85XX=y CONFIG_EDAC_SUPPORT=y CONFIG_ENABLE_MUST_CHECK=y -CONFIG_ETHERNET_PACKET_MANGLE=y CONFIG_FIXED_PHY=y CONFIG_FSL_BOOKE=y CONFIG_FSL_EMB_PERFMON=y @@ -240,7 +237,6 @@ CONFIG_SPI_MEM=y CONFIG_SRCU=y # CONFIG_STRIP_ASM_SYMS is not set # CONFIG_STX_GP3 is not set -CONFIG_SWCONFIG=y CONFIG_SWPHY=y CONFIG_SYSCTL_EXCEPTION_TRACE=y CONFIG_TARGET_CPU="8540" diff --git a/target/linux/mpc85xx/config-5.15 b/target/linux/mpc85xx/config-5.15 index 9e143d7b87..5700a247de 100644 --- a/target/linux/mpc85xx/config-5.15 +++ b/target/linux/mpc85xx/config-5.15 @@ -1,8 +1,6 @@ # CONFIG_40x is not set # CONFIG_44x is not set # CONFIG_ADVANCED_OPTIONS is not set -CONFIG_AR8216_PHY=y -CONFIG_AR8216_PHY_LEDS=y CONFIG_ARCH_32BIT_OFF_T=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_KEEP_MEMBLOCK=y @@ -60,7 +58,6 @@ CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_LEGACY_SYSFS=y CONFIG_EDAC_MPC85XX=y CONFIG_EDAC_SUPPORT=y -CONFIG_ETHERNET_PACKET_MANGLE=y CONFIG_FIXED_PHY=y CONFIG_FSL_BOOKE=y # CONFIG_FSL_DPAA2_SWITCH is not set @@ -238,7 +235,6 @@ CONFIG_SPI_MEM=y CONFIG_SRCU=y # CONFIG_STRIP_ASM_SYMS is not set # CONFIG_STX_GP3 is not set -CONFIG_SWCONFIG=y CONFIG_SWPHY=y CONFIG_SYSCTL_EXCEPTION_TRACE=y CONFIG_TARGET_CPU="8540" diff --git a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts index 12281808aa..c54cb53f94 100644 --- a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts +++ b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts @@ -102,20 +102,78 @@ }; mdio@24000 { - phy0: ethernet-phy@0 { - reg = <0x0>; - qca,ar8327-initvals = < - 0x00004 0x07600000 /* PAD0_MODE */ - 0x00008 0x00000000 /* PAD5_MODE */ - 0x0000c 0x01000000 /* PAD6_MODE */ - 0x00010 0x40000000 /* POWER_ON_STRAP */ - 0x00050 0xcf35cf35 /* LED_CTRL0 */ - 0x00054 0xcf35cf35 /* LED_CTRL1 */ - 0x00058 0xcf35cf35 /* LED_CTRL2 */ - 0x0005c 0x03ffff00 /* LED_CTRL3 */ - 0x0007c 0x0000007e /* PORT0_STATUS */ - 0x00094 0x00000200 /* PORT6_STATUS */ - >; + + phy_port1: phy@0 { + reg = <0>; + }; + + phy_port2: phy@1 { + reg = <1>; + }; + + phy_port3: phy@2 { + reg = <2>; + }; + + phy_port4: phy@3 { + reg = <3>; + }; + + phy_port5: phy@4 { + reg = <4>; + }; + + switch@0 { + compatible = "qca,qca8327"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x10>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&enet0>; + phy-mode = "rgmii-id"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + port@1 { + reg = <1>; + label = "wan"; + phy-handle = <&phy_port1>; + }; + + port@2 { + reg = <2>; + label = "lan1"; + phy-handle = <&phy_port2>; + }; + + port@3 { + reg = <3>; + label = "lan2"; + phy-handle = <&phy_port3>; + }; + + port@4 { + reg = <4>; + label = "lan3"; + phy-handle = <&phy_port4>; + }; + + port@5 { + reg = <5>; + label = "lan4"; + phy-handle = <&phy_port5>; + }; + }; }; }; @@ -128,10 +186,14 @@ }; enet0: ethernet@b0000 { - phy-handle = <&phy0>; phy-connection-type = "rgmii-id"; nvmem-cells = <&macaddr_uboot_4fc00>; nvmem-cell-names = "mac-address"; + + fixed-link { + speed = <1000>; + full-duplex; + }; }; enet1: ethernet@b1000 { diff --git a/target/linux/mpc85xx/image/p1010.mk b/target/linux/mpc85xx/image/p1010.mk index a18cd6d178..92cad3d035 100644 --- a/target/linux/mpc85xx/image/p1010.mk +++ b/target/linux/mpc85xx/image/p1010.mk @@ -18,6 +18,8 @@ define Device/tplink_tl-wdr4900-v1 DEVICE_VENDOR := TP-Link DEVICE_MODEL := TL-WDR4900 DEVICE_VARIANT := v1 + DEVICE_COMPAT_VERSION := 1.1 + DEVICE_COMPAT_MESSAGE := Config cannot be migrated from swconfig to DSA TPLINK_HEADER_VERSION := 1 TPLINK_HWID := 0x49000001 TPLINK_HWREV := 1 diff --git a/target/linux/mpc85xx/p1010/config-default b/target/linux/mpc85xx/p1010/config-default index 8a065f7944..5ca65812d7 100644 --- a/target/linux/mpc85xx/p1010/config-default +++ b/target/linux/mpc85xx/p1010/config-default @@ -1,3 +1,4 @@ +CONFIG_AT803X_PHY=y # CONFIG_FSL_CORENET_CF is not set CONFIG_MTD_NAND_FSL_IFC=y CONFIG_MTD_SPLIT_FIRMWARE=y @@ -6,7 +7,15 @@ CONFIG_MTD_UBI=y CONFIG_MTD_UBI_BEB_LIMIT=20 CONFIG_MTD_UBI_BLOCK=y CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_QCA8K=y +CONFIG_NET_DSA_TAG_QCA=y +CONFIG_NET_SWITCHDEV=y +CONFIG_PHYLINK=y CONFIG_REALTEK_PHY=y CONFIG_RED_15W_REV1=y +CONFIG_REGMAP=y +CONFIG_REGULATOR=y CONFIG_TL_WDR4900_V1=y CONFIG_UBIFS_FS=y diff --git a/target/linux/mpc85xx/p1020/config-default b/target/linux/mpc85xx/p1020/config-default index 73176a87dc..65b40e1d7d 100644 --- a/target/linux/mpc85xx/p1020/config-default +++ b/target/linux/mpc85xx/p1020/config-default @@ -43,6 +43,7 @@ CONFIG_RPS=y CONFIG_RWSEM_SPIN_ON_OWNER=y CONFIG_SMP=y CONFIG_SPI_GPIO=y +CONFIG_SWCONFIG=y CONFIG_SWCONFIG_B53=y # CONFIG_SWCONFIG_B53_MMAP_DRIVER is not set CONFIG_SWCONFIG_B53_PHY_DRIVER=y From 52ddb3846975cbb1c3cb504ffde6efdd69bb5622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 21 Feb 2023 11:25:49 +0100 Subject: [PATCH 21/22] kernel: update NVMEM subsystem to the v6.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki --- ...mem-core-remove-spurious-white-space.patch | 26 + ...e-add-an-index-parameter-to-the-cell.patch | 180 ++++++ ...struct-nvmem_cell_info-to-nvmem-prov.patch | 78 +++ ...the-removal-of-the-cells-in-nvmem_ad.patch | 65 ++ ...05-nvmem-core-add-nvmem_add_one_cell.patch | 122 ++++ ...vmem_add_one_cell-in-nvmem_add_cells.patch | 93 +++ ...32-add-OP-TEE-support-for-STM32MP13x.patch | 562 ++++++++++++++++++ ...ect-bsec-pta-presence-for-STM32MP15x.patch | 85 +++ ...eprm-fix-kernel-doc-bad-line-warning.patch | 32 + ...mi-sdam-register-at-device-init-time.patch | 43 ++ ...011-nvmem-stm32-fix-OPTEE-dependency.patch | 46 ++ ...mem-core-remove-spurious-white-space.patch | 26 + ...e-add-an-index-parameter-to-the-cell.patch | 180 ++++++ ...struct-nvmem_cell_info-to-nvmem-prov.patch | 78 +++ ...the-removal-of-the-cells-in-nvmem_ad.patch | 65 ++ ...05-nvmem-core-add-nvmem_add_one_cell.patch | 122 ++++ ...vmem_add_one_cell-in-nvmem_add_cells.patch | 93 +++ ...32-add-OP-TEE-support-for-STM32MP13x.patch | 562 ++++++++++++++++++ ...ect-bsec-pta-presence-for-STM32MP15x.patch | 85 +++ ...eprm-fix-kernel-doc-bad-line-warning.patch | 32 + ...mi-sdam-register-at-device-init-time.patch | 43 ++ ...011-nvmem-stm32-fix-OPTEE-dependency.patch | 46 ++ ...nv-align-endianness-of-crc32-values.patch} | 0 ...nv-align-endianness-of-crc32-values.patch} | 0 24 files changed, 2664 insertions(+) create mode 100644 target/linux/generic/backport-5.10/813-v6.3-0001-nvmem-core-remove-spurious-white-space.patch create mode 100644 target/linux/generic/backport-5.10/813-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch create mode 100644 target/linux/generic/backport-5.10/813-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch create mode 100644 target/linux/generic/backport-5.10/813-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch create mode 100644 target/linux/generic/backport-5.10/813-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch create mode 100644 target/linux/generic/backport-5.10/813-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch create mode 100644 target/linux/generic/backport-5.10/813-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch create mode 100644 target/linux/generic/backport-5.10/813-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch create mode 100644 target/linux/generic/backport-5.10/813-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch create mode 100644 target/linux/generic/backport-5.10/813-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch create mode 100644 target/linux/generic/backport-5.10/813-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch create mode 100644 target/linux/generic/backport-5.15/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch create mode 100644 target/linux/generic/backport-5.15/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch create mode 100644 target/linux/generic/backport-5.15/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch create mode 100644 target/linux/generic/backport-5.15/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch create mode 100644 target/linux/generic/backport-5.15/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch create mode 100644 target/linux/generic/backport-5.15/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch create mode 100644 target/linux/generic/backport-5.15/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch create mode 100644 target/linux/generic/backport-5.15/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch create mode 100644 target/linux/generic/backport-5.15/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch create mode 100644 target/linux/generic/backport-5.15/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch create mode 100644 target/linux/generic/backport-5.15/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch rename target/linux/generic/{backport-5.10/813-nvmem-u-boot-env-align-endianness-of-crc32-values.patch => pending-5.10/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch} (100%) rename target/linux/generic/{backport-5.15/809-nvmem-u-boot-env-align-endianness-of-crc32-values.patch => pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch} (100%) diff --git a/target/linux/generic/backport-5.10/813-v6.3-0001-nvmem-core-remove-spurious-white-space.patch b/target/linux/generic/backport-5.10/813-v6.3-0001-nvmem-core-remove-spurious-white-space.patch new file mode 100644 index 0000000000..01400fd490 --- /dev/null +++ b/target/linux/generic/backport-5.10/813-v6.3-0001-nvmem-core-remove-spurious-white-space.patch @@ -0,0 +1,26 @@ +From 2e8dc541ae207349b51c65391be625ffe1f86e0c Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Mon, 6 Feb 2023 13:43:41 +0000 +Subject: [PATCH] nvmem: core: remove spurious white space + +Remove a spurious white space in for the ida_alloc() call. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-8-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -764,7 +764,7 @@ struct nvmem_device *nvmem_register(cons + if (!nvmem) + return ERR_PTR(-ENOMEM); + +- rval = ida_alloc(&nvmem_ida, GFP_KERNEL); ++ rval = ida_alloc(&nvmem_ida, GFP_KERNEL); + if (rval < 0) { + kfree(nvmem); + return ERR_PTR(rval); diff --git a/target/linux/generic/backport-5.10/813-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch b/target/linux/generic/backport-5.10/813-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch new file mode 100644 index 0000000000..4f1bfac806 --- /dev/null +++ b/target/linux/generic/backport-5.10/813-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch @@ -0,0 +1,180 @@ +From 5d8e6e6c10a3d37486d263b16ddc15991a7e4a88 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:46 +0000 +Subject: [PATCH] nvmem: core: add an index parameter to the cell + +Sometimes a cell can represend multiple values. For example, a base +ethernet address stored in the NVMEM can be expanded into multiple +discreet ones by adding an offset. + +For this use case, introduce an index parameter which is then used to +distiguish between values. This parameter will then be passed to the +post process hook which can then use it to create different values +during reading. + +At the moment, there is only support for the device tree path. You can +add the index to the phandle, e.g. + + &net { + nvmem-cells = <&base_mac_address 2>; + nvmem-cell-names = "mac-address"; + }; + + &nvmem_provider { + base_mac_address: base-mac-address@0 { + #nvmem-cell-cells = <1>; + reg = <0 6>; + }; + }; + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-13-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 37 ++++++++++++++++++++++++---------- + drivers/nvmem/imx-ocotp.c | 4 ++-- + include/linux/nvmem-provider.h | 4 ++-- + 3 files changed, 30 insertions(+), 15 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -60,6 +60,7 @@ struct nvmem_cell_entry { + struct nvmem_cell { + struct nvmem_cell_entry *entry; + const char *id; ++ int index; + }; + + static DEFINE_MUTEX(nvmem_mutex); +@@ -1127,7 +1128,8 @@ struct nvmem_device *devm_nvmem_device_g + } + EXPORT_SYMBOL_GPL(devm_nvmem_device_get); + +-static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id) ++static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, ++ const char *id, int index) + { + struct nvmem_cell *cell; + const char *name = NULL; +@@ -1146,6 +1148,7 @@ static struct nvmem_cell *nvmem_create_c + + cell->id = name; + cell->entry = entry; ++ cell->index = index; + + return cell; + } +@@ -1184,7 +1187,7 @@ nvmem_cell_get_from_lookup(struct device + __nvmem_device_put(nvmem); + cell = ERR_PTR(-ENOENT); + } else { +- cell = nvmem_create_cell(cell_entry, con_id); ++ cell = nvmem_create_cell(cell_entry, con_id, 0); + if (IS_ERR(cell)) + __nvmem_device_put(nvmem); + } +@@ -1232,15 +1235,27 @@ struct nvmem_cell *of_nvmem_cell_get(str + struct nvmem_device *nvmem; + struct nvmem_cell_entry *cell_entry; + struct nvmem_cell *cell; ++ struct of_phandle_args cell_spec; + int index = 0; ++ int cell_index = 0; ++ int ret; + + /* if cell name exists, find index to the name */ + if (id) + index = of_property_match_string(np, "nvmem-cell-names", id); + +- cell_np = of_parse_phandle(np, "nvmem-cells", index); +- if (!cell_np) +- return ERR_PTR(-ENOENT); ++ ret = of_parse_phandle_with_optional_args(np, "nvmem-cells", ++ "#nvmem-cell-cells", ++ index, &cell_spec); ++ if (ret) ++ return ERR_PTR(ret); ++ ++ if (cell_spec.args_count > 1) ++ return ERR_PTR(-EINVAL); ++ ++ cell_np = cell_spec.np; ++ if (cell_spec.args_count) ++ cell_index = cell_spec.args[0]; + + nvmem_np = of_get_next_parent(cell_np); + if (!nvmem_np) +@@ -1257,7 +1272,7 @@ struct nvmem_cell *of_nvmem_cell_get(str + return ERR_PTR(-ENOENT); + } + +- cell = nvmem_create_cell(cell_entry, id); ++ cell = nvmem_create_cell(cell_entry, id, cell_index); + if (IS_ERR(cell)) + __nvmem_device_put(nvmem); + +@@ -1410,8 +1425,8 @@ static void nvmem_shift_read_buffer_in_p + } + + static int __nvmem_cell_read(struct nvmem_device *nvmem, +- struct nvmem_cell_entry *cell, +- void *buf, size_t *len, const char *id) ++ struct nvmem_cell_entry *cell, ++ void *buf, size_t *len, const char *id, int index) + { + int rc; + +@@ -1425,7 +1440,7 @@ static int __nvmem_cell_read(struct nvme + nvmem_shift_read_buffer_in_place(cell, buf); + + if (nvmem->cell_post_process) { +- rc = nvmem->cell_post_process(nvmem->priv, id, ++ rc = nvmem->cell_post_process(nvmem->priv, id, index, + cell->offset, buf, cell->bytes); + if (rc) + return rc; +@@ -1460,7 +1475,7 @@ void *nvmem_cell_read(struct nvmem_cell + if (!buf) + return ERR_PTR(-ENOMEM); + +- rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id); ++ rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id, cell->index); + if (rc) { + kfree(buf); + return ERR_PTR(rc); +@@ -1773,7 +1788,7 @@ ssize_t nvmem_device_cell_read(struct nv + if (rc) + return rc; + +- rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL); ++ rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL, 0); + if (rc) + return rc; + +--- a/drivers/nvmem/imx-ocotp.c ++++ b/drivers/nvmem/imx-ocotp.c +@@ -222,8 +222,8 @@ read_end: + return ret; + } + +-static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset, +- void *data, size_t bytes) ++static int imx_ocotp_cell_pp(void *context, const char *id, int index, ++ unsigned int offset, void *data, size_t bytes) + { + struct ocotp_priv *priv = context; + +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -20,8 +20,8 @@ typedef int (*nvmem_reg_read_t)(void *pr + typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, + void *val, size_t bytes); + /* used for vendor specific post processing of cell data */ +-typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset, +- void *buf, size_t bytes); ++typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index, ++ unsigned int offset, void *buf, size_t bytes); + + enum nvmem_type { + NVMEM_TYPE_UNKNOWN = 0, diff --git a/target/linux/generic/backport-5.10/813-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch b/target/linux/generic/backport-5.10/813-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch new file mode 100644 index 0000000000..f3829b3e17 --- /dev/null +++ b/target/linux/generic/backport-5.10/813-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch @@ -0,0 +1,78 @@ +From fbd03d27776c6121a483921601418e3c8f0ff37e Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:47 +0000 +Subject: [PATCH] nvmem: core: move struct nvmem_cell_info to nvmem-provider.h + +struct nvmem_cell_info is used to describe a cell. Thus this should +really be in the nvmem-provider's header. There are two (unused) nvmem +access methods which use the nvmem_cell_info to describe the cell to be +accesses. One can argue, that they will create a cell before accessing, +thus they are both a provider and a consumer. + +struct nvmem_cell_info will get used more and more by nvmem-providers, +don't force them to also include the consumer header, although they are +not. + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-14-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/nvmem-consumer.h | 10 +--------- + include/linux/nvmem-provider.h | 19 ++++++++++++++++++- + 2 files changed, 19 insertions(+), 10 deletions(-) + +--- a/include/linux/nvmem-consumer.h ++++ b/include/linux/nvmem-consumer.h +@@ -18,15 +18,7 @@ struct device_node; + /* consumer cookie */ + struct nvmem_cell; + struct nvmem_device; +- +-struct nvmem_cell_info { +- const char *name; +- unsigned int offset; +- unsigned int bytes; +- unsigned int bit_offset; +- unsigned int nbits; +- struct device_node *np; +-}; ++struct nvmem_cell_info; + + /** + * struct nvmem_cell_lookup - cell lookup entry +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -14,7 +14,6 @@ + #include + + struct nvmem_device; +-struct nvmem_cell_info; + typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset, + void *val, size_t bytes); + typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, +@@ -48,6 +47,24 @@ struct nvmem_keepout { + }; + + /** ++ * struct nvmem_cell_info - NVMEM cell description ++ * @name: Name. ++ * @offset: Offset within the NVMEM device. ++ * @bytes: Length of the cell. ++ * @bit_offset: Bit offset if cell is smaller than a byte. ++ * @nbits: Number of bits. ++ * @np: Optional device_node pointer. ++ */ ++struct nvmem_cell_info { ++ const char *name; ++ unsigned int offset; ++ unsigned int bytes; ++ unsigned int bit_offset; ++ unsigned int nbits; ++ struct device_node *np; ++}; ++ ++/** + * struct nvmem_config - NVMEM device configuration + * + * @dev: Parent device. diff --git a/target/linux/generic/backport-5.10/813-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch b/target/linux/generic/backport-5.10/813-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch new file mode 100644 index 0000000000..8f996eab34 --- /dev/null +++ b/target/linux/generic/backport-5.10/813-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch @@ -0,0 +1,65 @@ +From cc5bdd323dde6494623f3ffe3a5b887fa21cd375 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:48 +0000 +Subject: [PATCH] nvmem: core: drop the removal of the cells in + nvmem_add_cells() + +If nvmem_add_cells() fails, the whole nvmem_register() will fail +and the cells will then be removed anyway. This is a preparation +to introduce a nvmem_add_one_cell() which can then be used by +nvmem_add_cells(). + +This is then the same to what nvmem_add_cells_from_table() and +nvmem_add_cells_from_of() do. + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-15-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -515,7 +515,7 @@ static int nvmem_add_cells(struct nvmem_ + int ncells) + { + struct nvmem_cell_entry **cells; +- int i, rval; ++ int i, rval = 0; + + cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); + if (!cells) +@@ -525,28 +525,22 @@ static int nvmem_add_cells(struct nvmem_ + cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL); + if (!cells[i]) { + rval = -ENOMEM; +- goto err; ++ goto out; + } + + rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); + if (rval) { + kfree(cells[i]); +- goto err; ++ goto out; + } + + nvmem_cell_entry_add(cells[i]); + } + ++out: + /* remove tmp array */ + kfree(cells); + +- return 0; +-err: +- while (i--) +- nvmem_cell_entry_drop(cells[i]); +- +- kfree(cells); +- + return rval; + } + diff --git a/target/linux/generic/backport-5.10/813-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch b/target/linux/generic/backport-5.10/813-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch new file mode 100644 index 0000000000..2f3d5bb1f2 --- /dev/null +++ b/target/linux/generic/backport-5.10/813-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch @@ -0,0 +1,122 @@ +From 2ded6830d376d5e7bf43d59f7f7fdf1a59abc676 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:49 +0000 +Subject: [PATCH] nvmem: core: add nvmem_add_one_cell() + +Add a new function to add exactly one cell. This will be used by the +nvmem layout drivers to add custom cells. In contrast to the +nvmem_add_cells(), this has the advantage that we don't have to assemble +a list of cells on runtime. + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-16-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 59 ++++++++++++++++++++-------------- + include/linux/nvmem-provider.h | 8 +++++ + 2 files changed, 43 insertions(+), 24 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -502,6 +502,36 @@ static int nvmem_cell_info_to_nvmem_cell + } + + /** ++ * nvmem_add_one_cell() - Add one cell information to an nvmem device ++ * ++ * @nvmem: nvmem device to add cells to. ++ * @info: nvmem cell info to add to the device ++ * ++ * Return: 0 or negative error code on failure. ++ */ ++int nvmem_add_one_cell(struct nvmem_device *nvmem, ++ const struct nvmem_cell_info *info) ++{ ++ struct nvmem_cell_entry *cell; ++ int rval; ++ ++ cell = kzalloc(sizeof(*cell), GFP_KERNEL); ++ if (!cell) ++ return -ENOMEM; ++ ++ rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell); ++ if (rval) { ++ kfree(cell); ++ return rval; ++ } ++ ++ nvmem_cell_entry_add(cell); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(nvmem_add_one_cell); ++ ++/** + * nvmem_add_cells() - Add cell information to an nvmem device + * + * @nvmem: nvmem device to add cells to. +@@ -514,34 +544,15 @@ static int nvmem_add_cells(struct nvmem_ + const struct nvmem_cell_info *info, + int ncells) + { +- struct nvmem_cell_entry **cells; +- int i, rval = 0; +- +- cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); +- if (!cells) +- return -ENOMEM; ++ int i, rval; + + for (i = 0; i < ncells; i++) { +- cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL); +- if (!cells[i]) { +- rval = -ENOMEM; +- goto out; +- } +- +- rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); +- if (rval) { +- kfree(cells[i]); +- goto out; +- } +- +- nvmem_cell_entry_add(cells[i]); ++ rval = nvmem_add_one_cell(nvmem, &info[i]); ++ if (rval) ++ return rval; + } + +-out: +- /* remove tmp array */ +- kfree(cells); +- +- return rval; ++ return 0; + } + + /** +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -155,6 +155,9 @@ struct nvmem_device *devm_nvmem_register + void nvmem_add_cell_table(struct nvmem_cell_table *table); + void nvmem_del_cell_table(struct nvmem_cell_table *table); + ++int nvmem_add_one_cell(struct nvmem_device *nvmem, ++ const struct nvmem_cell_info *info); ++ + #else + + static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c) +@@ -172,6 +175,11 @@ devm_nvmem_register(struct device *dev, + + static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {} + static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {} ++static inline int nvmem_add_one_cell(struct nvmem_device *nvmem, ++ const struct nvmem_cell_info *info) ++{ ++ return -EOPNOTSUPP; ++} + + #endif /* CONFIG_NVMEM */ + #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-5.10/813-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch b/target/linux/generic/backport-5.10/813-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch new file mode 100644 index 0000000000..e1791e5c83 --- /dev/null +++ b/target/linux/generic/backport-5.10/813-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch @@ -0,0 +1,93 @@ +From 50014d659617dc58780a5d31ceb76c82779a9d8b Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:50 +0000 +Subject: [PATCH] nvmem: core: use nvmem_add_one_cell() in + nvmem_add_cells_from_of() + +Convert nvmem_add_cells_from_of() to use the new nvmem_add_one_cell(). +This will remove duplicate code and it will make it possible to add a +hook to a nvmem layout in between, which can change fields before the +cell is finally added. + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-17-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 45 ++++++++++++++------------------------------ + 1 file changed, 14 insertions(+), 31 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -688,15 +688,14 @@ static int nvmem_validate_keepouts(struc + + static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) + { +- struct device_node *parent, *child; + struct device *dev = &nvmem->dev; +- struct nvmem_cell_entry *cell; ++ struct device_node *child; + const __be32 *addr; +- int len; ++ int len, ret; + +- parent = dev->of_node; ++ for_each_child_of_node(dev->of_node, child) { ++ struct nvmem_cell_info info = {0}; + +- for_each_child_of_node(parent, child) { + addr = of_get_property(child, "reg", &len); + if (!addr) + continue; +@@ -706,40 +705,24 @@ static int nvmem_add_cells_from_of(struc + return -EINVAL; + } + +- cell = kzalloc(sizeof(*cell), GFP_KERNEL); +- if (!cell) { +- of_node_put(child); +- return -ENOMEM; +- } +- +- cell->nvmem = nvmem; +- cell->offset = be32_to_cpup(addr++); +- cell->bytes = be32_to_cpup(addr); +- cell->name = kasprintf(GFP_KERNEL, "%pOFn", child); ++ info.offset = be32_to_cpup(addr++); ++ info.bytes = be32_to_cpup(addr); ++ info.name = kasprintf(GFP_KERNEL, "%pOFn", child); + + addr = of_get_property(child, "bits", &len); + if (addr && len == (2 * sizeof(u32))) { +- cell->bit_offset = be32_to_cpup(addr++); +- cell->nbits = be32_to_cpup(addr); ++ info.bit_offset = be32_to_cpup(addr++); ++ info.nbits = be32_to_cpup(addr); + } + +- if (cell->nbits) +- cell->bytes = DIV_ROUND_UP( +- cell->nbits + cell->bit_offset, +- BITS_PER_BYTE); +- +- if (!IS_ALIGNED(cell->offset, nvmem->stride)) { +- dev_err(dev, "cell %s unaligned to nvmem stride %d\n", +- cell->name, nvmem->stride); +- /* Cells already added will be freed later. */ +- kfree_const(cell->name); +- kfree(cell); ++ info.np = of_node_get(child); ++ ++ ret = nvmem_add_one_cell(nvmem, &info); ++ kfree(info.name); ++ if (ret) { + of_node_put(child); +- return -EINVAL; ++ return ret; + } +- +- cell->np = of_node_get(child); +- nvmem_cell_entry_add(cell); + } + + return 0; diff --git a/target/linux/generic/backport-5.10/813-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch b/target/linux/generic/backport-5.10/813-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch new file mode 100644 index 0000000000..172a78b76a --- /dev/null +++ b/target/linux/generic/backport-5.10/813-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch @@ -0,0 +1,562 @@ +From 6a0bc3522e746025e2d9a63ab2cb5d7062c2d39c Mon Sep 17 00:00:00 2001 +From: Patrick Delaunay +Date: Mon, 6 Feb 2023 13:43:51 +0000 +Subject: [PATCH] nvmem: stm32: add OP-TEE support for STM32MP13x + +For boot with OP-TEE on STM32MP13, the communication with the secure +world no more use STMicroelectronics SMC but communication with the +STM32MP BSEC TA, for data access (read/write) or lock operation: +- all the request are sent to OP-TEE trusted application, +- for upper OTP with ECC protection and with word programming only + each OTP are permanently locked when programmed to avoid ECC error + on the second write operation + +Signed-off-by: Patrick Delaunay +Reviewed-by: Etienne Carriere +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-18-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 11 + + drivers/nvmem/Makefile | 1 + + drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++ + drivers/nvmem/stm32-bsec-optee-ta.h | 80 ++++++++ + drivers/nvmem/stm32-romem.c | 54 ++++- + 5 files changed, 441 insertions(+), 3 deletions(-) + create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c + create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -290,9 +290,20 @@ config NVMEM_SPRD_EFUSE + This driver can also be built as a module. If so, the module + will be called nvmem-sprd-efuse. + ++config NVMEM_STM32_BSEC_OPTEE_TA ++ bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver" ++ depends on OPTEE ++ help ++ Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE ++ trusted application STM32MP BSEC. ++ ++ This library is a used by stm32-romem driver or included in the module ++ called nvmem-stm32-romem. ++ + config NVMEM_STM32_ROMEM + tristate "STMicroelectronics STM32 factory-programmed memory support" + depends on ARCH_STM32 || COMPILE_TEST ++ imply NVMEM_STM32_BSEC_OPTEE_TA + help + Say y here to enable read-only access for STMicroelectronics STM32 + factory-programmed memory area. +--- a/drivers/nvmem/Makefile ++++ b/drivers/nvmem/Makefile +@@ -61,6 +61,7 @@ obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem + nvmem_sprd_efuse-y := sprd-efuse.o + obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o + nvmem_stm32_romem-y := stm32-romem.o ++nvmem_stm32_romem-$(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) += stm32-bsec-optee-ta.o + obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o + nvmem_sunplus_ocotp-y := sunplus-ocotp.o + obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o +--- /dev/null ++++ b/drivers/nvmem/stm32-bsec-optee-ta.c +@@ -0,0 +1,298 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver ++ * ++ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include ++ ++#include "stm32-bsec-optee-ta.h" ++ ++/* ++ * Read OTP memory ++ * ++ * [in] value[0].a OTP start offset in byte ++ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock) ++ * [out] memref[1].buffer Output buffer to store read values ++ * [out] memref[1].size Size of OTP to be read ++ * ++ * Return codes: ++ * TEE_SUCCESS - Invoke command success ++ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param ++ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller ++ */ ++#define PTA_BSEC_READ_MEM 0x0 ++ ++/* ++ * Write OTP memory ++ * ++ * [in] value[0].a OTP start offset in byte ++ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock) ++ * [in] memref[1].buffer Input buffer to read values ++ * [in] memref[1].size Size of OTP to be written ++ * ++ * Return codes: ++ * TEE_SUCCESS - Invoke command success ++ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param ++ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller ++ */ ++#define PTA_BSEC_WRITE_MEM 0x1 ++ ++/* value of PTA_BSEC access type = value[in] b */ ++#define SHADOW_ACCESS 0 ++#define FUSE_ACCESS 1 ++#define LOCK_ACCESS 2 ++ ++/* Bitfield definition for LOCK status */ ++#define LOCK_PERM BIT(30) ++ ++/* OP-TEE STM32MP BSEC TA UUID */ ++static const uuid_t stm32mp_bsec_ta_uuid = ++ UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5, ++ 0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03); ++ ++/* ++ * Check whether this driver supports the BSEC TA in the TEE instance ++ * represented by the params (ver/data) to this function. ++ */ ++static int stm32_bsec_optee_ta_match(struct tee_ioctl_version_data *ver, ++ const void *data) ++{ ++ /* Currently this driver only supports GP compliant, OP-TEE based TA */ ++ if ((ver->impl_id == TEE_IMPL_ID_OPTEE) && ++ (ver->gen_caps & TEE_GEN_CAP_GP)) ++ return 1; ++ else ++ return 0; ++} ++ ++/* Open a session to OP-TEE for STM32MP BSEC TA */ ++static int stm32_bsec_ta_open_session(struct tee_context *ctx, u32 *id) ++{ ++ struct tee_ioctl_open_session_arg sess_arg; ++ int rc; ++ ++ memset(&sess_arg, 0, sizeof(sess_arg)); ++ export_uuid(sess_arg.uuid, &stm32mp_bsec_ta_uuid); ++ sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; ++ sess_arg.num_params = 0; ++ ++ rc = tee_client_open_session(ctx, &sess_arg, NULL); ++ if ((rc < 0) || (sess_arg.ret != 0)) { ++ pr_err("%s: tee_client_open_session failed err:%#x, ret:%#x\n", ++ __func__, sess_arg.ret, rc); ++ if (!rc) ++ rc = -EINVAL; ++ } else { ++ *id = sess_arg.session; ++ } ++ ++ return rc; ++} ++ ++/* close a session to OP-TEE for STM32MP BSEC TA */ ++static void stm32_bsec_ta_close_session(void *ctx, u32 id) ++{ ++ tee_client_close_session(ctx, id); ++} ++ ++/* stm32_bsec_optee_ta_open() - initialize the STM32MP BSEC TA */ ++int stm32_bsec_optee_ta_open(struct tee_context **ctx) ++{ ++ struct tee_context *tee_ctx; ++ u32 session_id; ++ int rc; ++ ++ /* Open context with TEE driver */ ++ tee_ctx = tee_client_open_context(NULL, stm32_bsec_optee_ta_match, NULL, NULL); ++ if (IS_ERR(tee_ctx)) { ++ rc = PTR_ERR(tee_ctx); ++ if (rc == -ENOENT) ++ return -EPROBE_DEFER; ++ pr_err("%s: tee_client_open_context failed (%d)\n", __func__, rc); ++ ++ return rc; ++ } ++ ++ /* Check STM32MP BSEC TA presence */ ++ rc = stm32_bsec_ta_open_session(tee_ctx, &session_id); ++ if (rc) { ++ tee_client_close_context(tee_ctx); ++ return rc; ++ } ++ ++ stm32_bsec_ta_close_session(tee_ctx, session_id); ++ ++ *ctx = tee_ctx; ++ ++ return 0; ++} ++ ++/* stm32_bsec_optee_ta_open() - release the PTA STM32MP BSEC TA */ ++void stm32_bsec_optee_ta_close(void *ctx) ++{ ++ tee_client_close_context(ctx); ++} ++ ++/* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */ ++int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset, ++ void *buf, size_t bytes) ++{ ++ struct tee_shm *shm; ++ struct tee_ioctl_invoke_arg arg; ++ struct tee_param param[2]; ++ u8 *shm_buf; ++ u32 start, num_bytes; ++ int ret; ++ u32 session_id; ++ ++ ret = stm32_bsec_ta_open_session(ctx, &session_id); ++ if (ret) ++ return ret; ++ ++ memset(&arg, 0, sizeof(arg)); ++ memset(¶m, 0, sizeof(param)); ++ ++ arg.func = PTA_BSEC_READ_MEM; ++ arg.session = session_id; ++ arg.num_params = 2; ++ ++ /* align access on 32bits */ ++ start = ALIGN_DOWN(offset, 4); ++ num_bytes = round_up(offset + bytes - start, 4); ++ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; ++ param[0].u.value.a = start; ++ param[0].u.value.b = SHADOW_ACCESS; ++ ++ shm = tee_shm_alloc_kernel_buf(ctx, num_bytes); ++ if (IS_ERR(shm)) { ++ ret = PTR_ERR(shm); ++ goto out_tee_session; ++ } ++ ++ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; ++ param[1].u.memref.shm = shm; ++ param[1].u.memref.size = num_bytes; ++ ++ ret = tee_client_invoke_func(ctx, &arg, param); ++ if (ret < 0 || arg.ret != 0) { ++ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", ++ arg.ret, ret); ++ if (!ret) ++ ret = -EIO; ++ } ++ if (!ret) { ++ shm_buf = tee_shm_get_va(shm, 0); ++ if (IS_ERR(shm_buf)) { ++ ret = PTR_ERR(shm_buf); ++ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret); ++ } else { ++ /* read data from 32 bits aligned buffer */ ++ memcpy(buf, &shm_buf[offset % 4], bytes); ++ } ++ } ++ ++ tee_shm_free(shm); ++ ++out_tee_session: ++ stm32_bsec_ta_close_session(ctx, session_id); ++ ++ return ret; ++} ++ ++/* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */ ++int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower, ++ unsigned int offset, void *buf, size_t bytes) ++{ struct tee_shm *shm; ++ struct tee_ioctl_invoke_arg arg; ++ struct tee_param param[2]; ++ u8 *shm_buf; ++ int ret; ++ u32 session_id; ++ ++ ret = stm32_bsec_ta_open_session(ctx, &session_id); ++ if (ret) ++ return ret; ++ ++ /* Allow only writing complete 32-bits aligned words */ ++ if ((bytes % 4) || (offset % 4)) ++ return -EINVAL; ++ ++ memset(&arg, 0, sizeof(arg)); ++ memset(¶m, 0, sizeof(param)); ++ ++ arg.func = PTA_BSEC_WRITE_MEM; ++ arg.session = session_id; ++ arg.num_params = 2; ++ ++ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; ++ param[0].u.value.a = offset; ++ param[0].u.value.b = FUSE_ACCESS; ++ ++ shm = tee_shm_alloc_kernel_buf(ctx, bytes); ++ if (IS_ERR(shm)) { ++ ret = PTR_ERR(shm); ++ goto out_tee_session; ++ } ++ ++ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; ++ param[1].u.memref.shm = shm; ++ param[1].u.memref.size = bytes; ++ ++ shm_buf = tee_shm_get_va(shm, 0); ++ if (IS_ERR(shm_buf)) { ++ ret = PTR_ERR(shm_buf); ++ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret); ++ tee_shm_free(shm); ++ ++ goto out_tee_session; ++ } ++ ++ memcpy(shm_buf, buf, bytes); ++ ++ ret = tee_client_invoke_func(ctx, &arg, param); ++ if (ret < 0 || arg.ret != 0) { ++ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret); ++ if (!ret) ++ ret = -EIO; ++ } ++ pr_debug("Write OTPs %d to %zu, ret=%d\n", offset / 4, (offset + bytes) / 4, ret); ++ ++ /* Lock the upper OTPs with ECC protection, word programming only */ ++ if (!ret && ((offset + bytes) >= (lower * 4))) { ++ u32 start, nb_lock; ++ u32 *lock = (u32 *)shm_buf; ++ int i; ++ ++ /* ++ * don't lock the lower OTPs, no ECC protection and incremental ++ * bit programming, a second write is allowed ++ */ ++ start = max_t(u32, offset, lower * 4); ++ nb_lock = (offset + bytes - start) / 4; ++ ++ param[0].u.value.a = start; ++ param[0].u.value.b = LOCK_ACCESS; ++ param[1].u.memref.size = nb_lock * 4; ++ ++ for (i = 0; i < nb_lock; i++) ++ lock[i] = LOCK_PERM; ++ ++ ret = tee_client_invoke_func(ctx, &arg, param); ++ if (ret < 0 || arg.ret != 0) { ++ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret); ++ if (!ret) ++ ret = -EIO; ++ } ++ pr_debug("Lock upper OTPs %d to %d, ret=%d\n", ++ start / 4, start / 4 + nb_lock, ret); ++ } ++ ++ tee_shm_free(shm); ++ ++out_tee_session: ++ stm32_bsec_ta_close_session(ctx, session_id); ++ ++ return ret; ++} +--- /dev/null ++++ b/drivers/nvmem/stm32-bsec-optee-ta.h +@@ -0,0 +1,80 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver ++ * ++ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved ++ */ ++ ++#if IS_ENABLED(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) ++/** ++ * stm32_bsec_optee_ta_open() - initialize the STM32 BSEC TA ++ * @ctx: the OP-TEE context on success ++ * ++ * Return: ++ * On success, 0. On failure, -errno. ++ */ ++int stm32_bsec_optee_ta_open(struct tee_context **ctx); ++ ++/** ++ * stm32_bsec_optee_ta_close() - release the STM32 BSEC TA ++ * @ctx: the OP-TEE context ++ * ++ * This function used to clean the OP-TEE resources initialized in ++ * stm32_bsec_optee_ta_open(); it can be used as callback to ++ * devm_add_action_or_reset() ++ */ ++void stm32_bsec_optee_ta_close(void *ctx); ++ ++/** ++ * stm32_bsec_optee_ta_read() - nvmem read access using TA client driver ++ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open ++ * @offset: nvmem offset ++ * @buf: buffer to fill with nvem values ++ * @bytes: number of bytes to read ++ * ++ * Return: ++ * On success, 0. On failure, -errno. ++ */ ++int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset, ++ void *buf, size_t bytes); ++ ++/** ++ * stm32_bsec_optee_ta_write() - nvmem write access using TA client driver ++ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open ++ * @lower: number of lower OTP, not protected by ECC ++ * @offset: nvmem offset ++ * @buf: buffer with nvem values ++ * @bytes: number of bytes to write ++ * ++ * Return: ++ * On success, 0. On failure, -errno. ++ */ ++int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower, ++ unsigned int offset, void *buf, size_t bytes); ++ ++#else ++ ++static inline int stm32_bsec_optee_ta_open(struct tee_context **ctx) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline void stm32_bsec_optee_ta_close(void *ctx) ++{ ++} ++ ++static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx, ++ unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx, ++ unsigned int lower, ++ unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ return -EOPNOTSUPP; ++} ++#endif /* CONFIG_NVMEM_STM32_BSEC_OPTEE_TA */ +--- a/drivers/nvmem/stm32-romem.c ++++ b/drivers/nvmem/stm32-romem.c +@@ -11,6 +11,9 @@ + #include + #include + #include ++#include ++ ++#include "stm32-bsec-optee-ta.h" + + /* BSEC secure service access from non-secure */ + #define STM32_SMC_BSEC 0x82001003 +@@ -25,12 +28,14 @@ + struct stm32_romem_cfg { + int size; + u8 lower; ++ bool ta; + }; + + struct stm32_romem_priv { + void __iomem *base; + struct nvmem_config cfg; + u8 lower; ++ struct tee_context *ctx; + }; + + static int stm32_romem_read(void *context, unsigned int offset, void *buf, +@@ -138,12 +143,29 @@ static int stm32_bsec_write(void *contex + return 0; + } + ++static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ struct stm32_romem_priv *priv = context; ++ ++ return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes); ++} ++ ++static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ struct stm32_romem_priv *priv = context; ++ ++ return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes); ++} ++ + static int stm32_romem_probe(struct platform_device *pdev) + { + const struct stm32_romem_cfg *cfg; + struct device *dev = &pdev->dev; + struct stm32_romem_priv *priv; + struct resource *res; ++ int rc; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) +@@ -173,15 +195,31 @@ static int stm32_romem_probe(struct plat + } else { + priv->cfg.size = cfg->size; + priv->lower = cfg->lower; +- priv->cfg.reg_read = stm32_bsec_read; +- priv->cfg.reg_write = stm32_bsec_write; ++ if (cfg->ta) { ++ rc = stm32_bsec_optee_ta_open(&priv->ctx); ++ /* wait for OP-TEE client driver to be up and ready */ ++ if (rc) ++ return rc; ++ } ++ if (priv->ctx) { ++ rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx); ++ if (rc) { ++ dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", rc); ++ return rc; ++ } ++ priv->cfg.reg_read = stm32_bsec_pta_read; ++ priv->cfg.reg_write = stm32_bsec_pta_write; ++ } else { ++ priv->cfg.reg_read = stm32_bsec_read; ++ priv->cfg.reg_write = stm32_bsec_write; ++ } + } + + return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg)); + } + + /* +- * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) ++ * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) + * => 96 x 32-bits data words + * - Lower: 1K bits, 2:1 redundancy, incremental bit programming + * => 32 (x 32-bits) lower shadow registers = words 0 to 31 +@@ -191,6 +229,13 @@ static int stm32_romem_probe(struct plat + static const struct stm32_romem_cfg stm32mp15_bsec_cfg = { + .size = 384, + .lower = 32, ++ .ta = false, ++}; ++ ++static const struct stm32_romem_cfg stm32mp13_bsec_cfg = { ++ .size = 384, ++ .lower = 32, ++ .ta = true, + }; + + static const struct of_device_id stm32_romem_of_match[] = { +@@ -198,7 +243,10 @@ static const struct of_device_id stm32_r + .compatible = "st,stm32mp15-bsec", + .data = (void *)&stm32mp15_bsec_cfg, + }, { ++ .compatible = "st,stm32mp13-bsec", ++ .data = (void *)&stm32mp13_bsec_cfg, + }, ++ { /* sentinel */ }, + }; + MODULE_DEVICE_TABLE(of, stm32_romem_of_match); + diff --git a/target/linux/generic/backport-5.10/813-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch b/target/linux/generic/backport-5.10/813-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch new file mode 100644 index 0000000000..cea8e93858 --- /dev/null +++ b/target/linux/generic/backport-5.10/813-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch @@ -0,0 +1,85 @@ +From df2f34ef1d924125ffaf29dfdaf7cdbd3183c321 Mon Sep 17 00:00:00 2001 +From: Patrick Delaunay +Date: Mon, 6 Feb 2023 13:43:52 +0000 +Subject: [PATCH] nvmem: stm32: detect bsec pta presence for STM32MP15x + +On STM32MP15x SoC, the SMC backend is optional when OP-TEE is used; +the PTA BSEC should be used as it is done on STM32MP13x platform, +but the BSEC SMC can be also used: it is a legacy mode in OP-TEE, +not recommended but used in previous OP-TEE firmware. + +The presence of OP-TEE is dynamically detected in STM32MP15x device tree +and the supported NVMEM backend is dynamically detected: +- PTA with stm32_bsec_pta_find +- SMC with stm32_bsec_check + +With OP-TEE but without PTA and SMC detection, the probe is deferred for +STM32MP15x devices. + +On STM32MP13x platform, only the PTA is supported with cfg->ta = true +and this detection is skipped. + +Signed-off-by: Patrick Delaunay +Reviewed-by: Etienne Carriere +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-19-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/stm32-romem.c | 38 +++++++++++++++++++++++++++++++++---- + 1 file changed, 34 insertions(+), 4 deletions(-) + +--- a/drivers/nvmem/stm32-romem.c ++++ b/drivers/nvmem/stm32-romem.c +@@ -159,6 +159,31 @@ static int stm32_bsec_pta_write(void *co + return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes); + } + ++static bool stm32_bsec_smc_check(void) ++{ ++ u32 val; ++ int ret; ++ ++ /* check that the OP-TEE support the BSEC SMC (legacy mode) */ ++ ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, 0, 0, &val); ++ ++ return !ret; ++} ++ ++static bool optee_presence_check(void) ++{ ++ struct device_node *np; ++ bool tee_detected = false; ++ ++ /* check that the OP-TEE node is present and available. */ ++ np = of_find_compatible_node(NULL, NULL, "linaro,optee-tz"); ++ if (np && of_device_is_available(np)) ++ tee_detected = true; ++ of_node_put(np); ++ ++ return tee_detected; ++} ++ + static int stm32_romem_probe(struct platform_device *pdev) + { + const struct stm32_romem_cfg *cfg; +@@ -195,11 +220,16 @@ static int stm32_romem_probe(struct plat + } else { + priv->cfg.size = cfg->size; + priv->lower = cfg->lower; +- if (cfg->ta) { ++ if (cfg->ta || optee_presence_check()) { + rc = stm32_bsec_optee_ta_open(&priv->ctx); +- /* wait for OP-TEE client driver to be up and ready */ +- if (rc) +- return rc; ++ if (rc) { ++ /* wait for OP-TEE client driver to be up and ready */ ++ if (rc == -EPROBE_DEFER) ++ return -EPROBE_DEFER; ++ /* BSEC PTA is required or SMC not supported */ ++ if (cfg->ta || !stm32_bsec_smc_check()) ++ return rc; ++ } + } + if (priv->ctx) { + rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx); diff --git a/target/linux/generic/backport-5.10/813-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch b/target/linux/generic/backport-5.10/813-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch new file mode 100644 index 0000000000..9d6275a737 --- /dev/null +++ b/target/linux/generic/backport-5.10/813-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch @@ -0,0 +1,32 @@ +From 3e5ac22aa564026e99defc3a8e02082521a5b231 Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Mon, 6 Feb 2023 13:43:53 +0000 +Subject: [PATCH] nvmem: rave-sp-eeprm: fix kernel-doc bad line warning + +Convert an empty line to " *" to avoid a kernel-doc warning: + +drivers/nvmem/rave-sp-eeprom.c:48: warning: bad line: + +Signed-off-by: Randy Dunlap +Cc: Srinivas Kandagatla +Cc: Andrey Vostrikov +Cc: Nikita Yushchenko +Cc: Andrey Smirnov +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-20-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/rave-sp-eeprom.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/rave-sp-eeprom.c ++++ b/drivers/nvmem/rave-sp-eeprom.c +@@ -45,7 +45,7 @@ enum rave_sp_eeprom_header_size { + * @type: Access type (see enum rave_sp_eeprom_access_type) + * @success: Success flag (Success = 1, Failure = 0) + * @data: Read data +- ++ * + * Note this structure corresponds to RSP_*_EEPROM payload from RAVE + * SP ICD + */ diff --git a/target/linux/generic/backport-5.10/813-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch b/target/linux/generic/backport-5.10/813-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch new file mode 100644 index 0000000000..1ab9e609d3 --- /dev/null +++ b/target/linux/generic/backport-5.10/813-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch @@ -0,0 +1,43 @@ +From eb7dda20f42a9137e9ee53d5ed3b743d49338cb5 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 6 Feb 2023 13:43:54 +0000 +Subject: [PATCH] nvmem: qcom-spmi-sdam: register at device init time + +There are currently no in-tree users of the Qualcomm SDAM nvmem driver +and there is generally no point in registering a driver that can be +built as a module at subsys init time. + +Register the driver at the normal device init time instead and let +driver core sort out the probe order. + +Signed-off-by: Johan Hovold +Reviewed-by: Bjorn Andersson +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-21-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/qcom-spmi-sdam.c | 13 +------------ + 1 file changed, 1 insertion(+), 12 deletions(-) + +--- a/drivers/nvmem/qcom-spmi-sdam.c ++++ b/drivers/nvmem/qcom-spmi-sdam.c +@@ -175,18 +175,7 @@ static struct platform_driver sdam_drive + }, + .probe = sdam_probe, + }; +- +-static int __init sdam_init(void) +-{ +- return platform_driver_register(&sdam_driver); +-} +-subsys_initcall(sdam_init); +- +-static void __exit sdam_exit(void) +-{ +- return platform_driver_unregister(&sdam_driver); +-} +-module_exit(sdam_exit); ++module_platform_driver(sdam_driver); + + MODULE_DESCRIPTION("QCOM SPMI SDAM driver"); + MODULE_LICENSE("GPL v2"); diff --git a/target/linux/generic/backport-5.10/813-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch b/target/linux/generic/backport-5.10/813-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch new file mode 100644 index 0000000000..dcf704c6ff --- /dev/null +++ b/target/linux/generic/backport-5.10/813-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch @@ -0,0 +1,46 @@ +From 1dc7e37bb0ec1c997fac82031332a38c7610352f Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Mon, 6 Feb 2023 13:43:56 +0000 +Subject: [PATCH] nvmem: stm32: fix OPTEE dependency + +The stm32 nvmem driver fails to link as built-in when OPTEE +is a loadable module: + +aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec: +stm32-bsec-optee-ta.c:(.text+0xc8): undefined reference to `tee_client_open_session' +aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec: +stm32-bsec-optee-ta.c:(.text+0x1fc): undefined reference to `tee_client_open_context' + +Change the CONFIG_NVMEM_STM32_ROMEM definition so it can only +be built-in if OPTEE is either built-in or disabled, and +make NVMEM_STM32_BSEC_OPTEE_TA a hidden symbol instead. + +Signed-off-by: Arnd Bergmann +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-23-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -291,8 +291,7 @@ config NVMEM_SPRD_EFUSE + will be called nvmem-sprd-efuse. + + config NVMEM_STM32_BSEC_OPTEE_TA +- bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver" +- depends on OPTEE ++ def_bool NVMEM_STM32_ROMEM && OPTEE + help + Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE + trusted application STM32MP BSEC. +@@ -303,7 +302,7 @@ config NVMEM_STM32_BSEC_OPTEE_TA + config NVMEM_STM32_ROMEM + tristate "STMicroelectronics STM32 factory-programmed memory support" + depends on ARCH_STM32 || COMPILE_TEST +- imply NVMEM_STM32_BSEC_OPTEE_TA ++ depends on OPTEE || !OPTEE + help + Say y here to enable read-only access for STMicroelectronics STM32 + factory-programmed memory area. diff --git a/target/linux/generic/backport-5.15/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch b/target/linux/generic/backport-5.15/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch new file mode 100644 index 0000000000..01400fd490 --- /dev/null +++ b/target/linux/generic/backport-5.15/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch @@ -0,0 +1,26 @@ +From 2e8dc541ae207349b51c65391be625ffe1f86e0c Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Mon, 6 Feb 2023 13:43:41 +0000 +Subject: [PATCH] nvmem: core: remove spurious white space + +Remove a spurious white space in for the ida_alloc() call. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-8-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -764,7 +764,7 @@ struct nvmem_device *nvmem_register(cons + if (!nvmem) + return ERR_PTR(-ENOMEM); + +- rval = ida_alloc(&nvmem_ida, GFP_KERNEL); ++ rval = ida_alloc(&nvmem_ida, GFP_KERNEL); + if (rval < 0) { + kfree(nvmem); + return ERR_PTR(rval); diff --git a/target/linux/generic/backport-5.15/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch b/target/linux/generic/backport-5.15/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch new file mode 100644 index 0000000000..d6b3057e48 --- /dev/null +++ b/target/linux/generic/backport-5.15/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch @@ -0,0 +1,180 @@ +From 5d8e6e6c10a3d37486d263b16ddc15991a7e4a88 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:46 +0000 +Subject: [PATCH] nvmem: core: add an index parameter to the cell + +Sometimes a cell can represend multiple values. For example, a base +ethernet address stored in the NVMEM can be expanded into multiple +discreet ones by adding an offset. + +For this use case, introduce an index parameter which is then used to +distiguish between values. This parameter will then be passed to the +post process hook which can then use it to create different values +during reading. + +At the moment, there is only support for the device tree path. You can +add the index to the phandle, e.g. + + &net { + nvmem-cells = <&base_mac_address 2>; + nvmem-cell-names = "mac-address"; + }; + + &nvmem_provider { + base_mac_address: base-mac-address@0 { + #nvmem-cell-cells = <1>; + reg = <0 6>; + }; + }; + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-13-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 37 ++++++++++++++++++++++++---------- + drivers/nvmem/imx-ocotp.c | 4 ++-- + include/linux/nvmem-provider.h | 4 ++-- + 3 files changed, 30 insertions(+), 15 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -60,6 +60,7 @@ struct nvmem_cell_entry { + struct nvmem_cell { + struct nvmem_cell_entry *entry; + const char *id; ++ int index; + }; + + static DEFINE_MUTEX(nvmem_mutex); +@@ -1125,7 +1126,8 @@ struct nvmem_device *devm_nvmem_device_g + } + EXPORT_SYMBOL_GPL(devm_nvmem_device_get); + +-static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id) ++static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, ++ const char *id, int index) + { + struct nvmem_cell *cell; + const char *name = NULL; +@@ -1144,6 +1146,7 @@ static struct nvmem_cell *nvmem_create_c + + cell->id = name; + cell->entry = entry; ++ cell->index = index; + + return cell; + } +@@ -1182,7 +1185,7 @@ nvmem_cell_get_from_lookup(struct device + __nvmem_device_put(nvmem); + cell = ERR_PTR(-ENOENT); + } else { +- cell = nvmem_create_cell(cell_entry, con_id); ++ cell = nvmem_create_cell(cell_entry, con_id, 0); + if (IS_ERR(cell)) + __nvmem_device_put(nvmem); + } +@@ -1230,15 +1233,27 @@ struct nvmem_cell *of_nvmem_cell_get(str + struct nvmem_device *nvmem; + struct nvmem_cell_entry *cell_entry; + struct nvmem_cell *cell; ++ struct of_phandle_args cell_spec; + int index = 0; ++ int cell_index = 0; ++ int ret; + + /* if cell name exists, find index to the name */ + if (id) + index = of_property_match_string(np, "nvmem-cell-names", id); + +- cell_np = of_parse_phandle(np, "nvmem-cells", index); +- if (!cell_np) +- return ERR_PTR(-ENOENT); ++ ret = of_parse_phandle_with_optional_args(np, "nvmem-cells", ++ "#nvmem-cell-cells", ++ index, &cell_spec); ++ if (ret) ++ return ERR_PTR(ret); ++ ++ if (cell_spec.args_count > 1) ++ return ERR_PTR(-EINVAL); ++ ++ cell_np = cell_spec.np; ++ if (cell_spec.args_count) ++ cell_index = cell_spec.args[0]; + + nvmem_np = of_get_next_parent(cell_np); + if (!nvmem_np) +@@ -1255,7 +1270,7 @@ struct nvmem_cell *of_nvmem_cell_get(str + return ERR_PTR(-ENOENT); + } + +- cell = nvmem_create_cell(cell_entry, id); ++ cell = nvmem_create_cell(cell_entry, id, cell_index); + if (IS_ERR(cell)) + __nvmem_device_put(nvmem); + +@@ -1408,8 +1423,8 @@ static void nvmem_shift_read_buffer_in_p + } + + static int __nvmem_cell_read(struct nvmem_device *nvmem, +- struct nvmem_cell_entry *cell, +- void *buf, size_t *len, const char *id) ++ struct nvmem_cell_entry *cell, ++ void *buf, size_t *len, const char *id, int index) + { + int rc; + +@@ -1423,7 +1438,7 @@ static int __nvmem_cell_read(struct nvme + nvmem_shift_read_buffer_in_place(cell, buf); + + if (nvmem->cell_post_process) { +- rc = nvmem->cell_post_process(nvmem->priv, id, ++ rc = nvmem->cell_post_process(nvmem->priv, id, index, + cell->offset, buf, cell->bytes); + if (rc) + return rc; +@@ -1458,7 +1473,7 @@ void *nvmem_cell_read(struct nvmem_cell + if (!buf) + return ERR_PTR(-ENOMEM); + +- rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id); ++ rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id, cell->index); + if (rc) { + kfree(buf); + return ERR_PTR(rc); +@@ -1771,7 +1786,7 @@ ssize_t nvmem_device_cell_read(struct nv + if (rc) + return rc; + +- rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL); ++ rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL, 0); + if (rc) + return rc; + +--- a/drivers/nvmem/imx-ocotp.c ++++ b/drivers/nvmem/imx-ocotp.c +@@ -222,8 +222,8 @@ read_end: + return ret; + } + +-static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset, +- void *data, size_t bytes) ++static int imx_ocotp_cell_pp(void *context, const char *id, int index, ++ unsigned int offset, void *data, size_t bytes) + { + struct ocotp_priv *priv = context; + +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -20,8 +20,8 @@ typedef int (*nvmem_reg_read_t)(void *pr + typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, + void *val, size_t bytes); + /* used for vendor specific post processing of cell data */ +-typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset, +- void *buf, size_t bytes); ++typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index, ++ unsigned int offset, void *buf, size_t bytes); + + enum nvmem_type { + NVMEM_TYPE_UNKNOWN = 0, diff --git a/target/linux/generic/backport-5.15/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch b/target/linux/generic/backport-5.15/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch new file mode 100644 index 0000000000..f3829b3e17 --- /dev/null +++ b/target/linux/generic/backport-5.15/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch @@ -0,0 +1,78 @@ +From fbd03d27776c6121a483921601418e3c8f0ff37e Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:47 +0000 +Subject: [PATCH] nvmem: core: move struct nvmem_cell_info to nvmem-provider.h + +struct nvmem_cell_info is used to describe a cell. Thus this should +really be in the nvmem-provider's header. There are two (unused) nvmem +access methods which use the nvmem_cell_info to describe the cell to be +accesses. One can argue, that they will create a cell before accessing, +thus they are both a provider and a consumer. + +struct nvmem_cell_info will get used more and more by nvmem-providers, +don't force them to also include the consumer header, although they are +not. + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-14-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/nvmem-consumer.h | 10 +--------- + include/linux/nvmem-provider.h | 19 ++++++++++++++++++- + 2 files changed, 19 insertions(+), 10 deletions(-) + +--- a/include/linux/nvmem-consumer.h ++++ b/include/linux/nvmem-consumer.h +@@ -18,15 +18,7 @@ struct device_node; + /* consumer cookie */ + struct nvmem_cell; + struct nvmem_device; +- +-struct nvmem_cell_info { +- const char *name; +- unsigned int offset; +- unsigned int bytes; +- unsigned int bit_offset; +- unsigned int nbits; +- struct device_node *np; +-}; ++struct nvmem_cell_info; + + /** + * struct nvmem_cell_lookup - cell lookup entry +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -14,7 +14,6 @@ + #include + + struct nvmem_device; +-struct nvmem_cell_info; + typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset, + void *val, size_t bytes); + typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, +@@ -48,6 +47,24 @@ struct nvmem_keepout { + }; + + /** ++ * struct nvmem_cell_info - NVMEM cell description ++ * @name: Name. ++ * @offset: Offset within the NVMEM device. ++ * @bytes: Length of the cell. ++ * @bit_offset: Bit offset if cell is smaller than a byte. ++ * @nbits: Number of bits. ++ * @np: Optional device_node pointer. ++ */ ++struct nvmem_cell_info { ++ const char *name; ++ unsigned int offset; ++ unsigned int bytes; ++ unsigned int bit_offset; ++ unsigned int nbits; ++ struct device_node *np; ++}; ++ ++/** + * struct nvmem_config - NVMEM device configuration + * + * @dev: Parent device. diff --git a/target/linux/generic/backport-5.15/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch b/target/linux/generic/backport-5.15/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch new file mode 100644 index 0000000000..8f996eab34 --- /dev/null +++ b/target/linux/generic/backport-5.15/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch @@ -0,0 +1,65 @@ +From cc5bdd323dde6494623f3ffe3a5b887fa21cd375 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:48 +0000 +Subject: [PATCH] nvmem: core: drop the removal of the cells in + nvmem_add_cells() + +If nvmem_add_cells() fails, the whole nvmem_register() will fail +and the cells will then be removed anyway. This is a preparation +to introduce a nvmem_add_one_cell() which can then be used by +nvmem_add_cells(). + +This is then the same to what nvmem_add_cells_from_table() and +nvmem_add_cells_from_of() do. + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-15-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -515,7 +515,7 @@ static int nvmem_add_cells(struct nvmem_ + int ncells) + { + struct nvmem_cell_entry **cells; +- int i, rval; ++ int i, rval = 0; + + cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); + if (!cells) +@@ -525,28 +525,22 @@ static int nvmem_add_cells(struct nvmem_ + cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL); + if (!cells[i]) { + rval = -ENOMEM; +- goto err; ++ goto out; + } + + rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); + if (rval) { + kfree(cells[i]); +- goto err; ++ goto out; + } + + nvmem_cell_entry_add(cells[i]); + } + ++out: + /* remove tmp array */ + kfree(cells); + +- return 0; +-err: +- while (i--) +- nvmem_cell_entry_drop(cells[i]); +- +- kfree(cells); +- + return rval; + } + diff --git a/target/linux/generic/backport-5.15/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch b/target/linux/generic/backport-5.15/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch new file mode 100644 index 0000000000..711ce229b2 --- /dev/null +++ b/target/linux/generic/backport-5.15/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch @@ -0,0 +1,122 @@ +From 2ded6830d376d5e7bf43d59f7f7fdf1a59abc676 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:49 +0000 +Subject: [PATCH] nvmem: core: add nvmem_add_one_cell() + +Add a new function to add exactly one cell. This will be used by the +nvmem layout drivers to add custom cells. In contrast to the +nvmem_add_cells(), this has the advantage that we don't have to assemble +a list of cells on runtime. + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-16-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 59 ++++++++++++++++++++-------------- + include/linux/nvmem-provider.h | 8 +++++ + 2 files changed, 43 insertions(+), 24 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -502,6 +502,36 @@ static int nvmem_cell_info_to_nvmem_cell + } + + /** ++ * nvmem_add_one_cell() - Add one cell information to an nvmem device ++ * ++ * @nvmem: nvmem device to add cells to. ++ * @info: nvmem cell info to add to the device ++ * ++ * Return: 0 or negative error code on failure. ++ */ ++int nvmem_add_one_cell(struct nvmem_device *nvmem, ++ const struct nvmem_cell_info *info) ++{ ++ struct nvmem_cell_entry *cell; ++ int rval; ++ ++ cell = kzalloc(sizeof(*cell), GFP_KERNEL); ++ if (!cell) ++ return -ENOMEM; ++ ++ rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell); ++ if (rval) { ++ kfree(cell); ++ return rval; ++ } ++ ++ nvmem_cell_entry_add(cell); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(nvmem_add_one_cell); ++ ++/** + * nvmem_add_cells() - Add cell information to an nvmem device + * + * @nvmem: nvmem device to add cells to. +@@ -514,34 +544,15 @@ static int nvmem_add_cells(struct nvmem_ + const struct nvmem_cell_info *info, + int ncells) + { +- struct nvmem_cell_entry **cells; +- int i, rval = 0; +- +- cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); +- if (!cells) +- return -ENOMEM; ++ int i, rval; + + for (i = 0; i < ncells; i++) { +- cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL); +- if (!cells[i]) { +- rval = -ENOMEM; +- goto out; +- } +- +- rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); +- if (rval) { +- kfree(cells[i]); +- goto out; +- } +- +- nvmem_cell_entry_add(cells[i]); ++ rval = nvmem_add_one_cell(nvmem, &info[i]); ++ if (rval) ++ return rval; + } + +-out: +- /* remove tmp array */ +- kfree(cells); +- +- return rval; ++ return 0; + } + + /** +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -153,6 +153,9 @@ struct nvmem_device *devm_nvmem_register + void nvmem_add_cell_table(struct nvmem_cell_table *table); + void nvmem_del_cell_table(struct nvmem_cell_table *table); + ++int nvmem_add_one_cell(struct nvmem_device *nvmem, ++ const struct nvmem_cell_info *info); ++ + #else + + static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c) +@@ -170,6 +173,11 @@ devm_nvmem_register(struct device *dev, + + static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {} + static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {} ++static inline int nvmem_add_one_cell(struct nvmem_device *nvmem, ++ const struct nvmem_cell_info *info) ++{ ++ return -EOPNOTSUPP; ++} + + #endif /* CONFIG_NVMEM */ + #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-5.15/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch b/target/linux/generic/backport-5.15/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch new file mode 100644 index 0000000000..e1791e5c83 --- /dev/null +++ b/target/linux/generic/backport-5.15/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch @@ -0,0 +1,93 @@ +From 50014d659617dc58780a5d31ceb76c82779a9d8b Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:50 +0000 +Subject: [PATCH] nvmem: core: use nvmem_add_one_cell() in + nvmem_add_cells_from_of() + +Convert nvmem_add_cells_from_of() to use the new nvmem_add_one_cell(). +This will remove duplicate code and it will make it possible to add a +hook to a nvmem layout in between, which can change fields before the +cell is finally added. + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-17-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 45 ++++++++++++++------------------------------ + 1 file changed, 14 insertions(+), 31 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -688,15 +688,14 @@ static int nvmem_validate_keepouts(struc + + static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) + { +- struct device_node *parent, *child; + struct device *dev = &nvmem->dev; +- struct nvmem_cell_entry *cell; ++ struct device_node *child; + const __be32 *addr; +- int len; ++ int len, ret; + +- parent = dev->of_node; ++ for_each_child_of_node(dev->of_node, child) { ++ struct nvmem_cell_info info = {0}; + +- for_each_child_of_node(parent, child) { + addr = of_get_property(child, "reg", &len); + if (!addr) + continue; +@@ -706,40 +705,24 @@ static int nvmem_add_cells_from_of(struc + return -EINVAL; + } + +- cell = kzalloc(sizeof(*cell), GFP_KERNEL); +- if (!cell) { +- of_node_put(child); +- return -ENOMEM; +- } +- +- cell->nvmem = nvmem; +- cell->offset = be32_to_cpup(addr++); +- cell->bytes = be32_to_cpup(addr); +- cell->name = kasprintf(GFP_KERNEL, "%pOFn", child); ++ info.offset = be32_to_cpup(addr++); ++ info.bytes = be32_to_cpup(addr); ++ info.name = kasprintf(GFP_KERNEL, "%pOFn", child); + + addr = of_get_property(child, "bits", &len); + if (addr && len == (2 * sizeof(u32))) { +- cell->bit_offset = be32_to_cpup(addr++); +- cell->nbits = be32_to_cpup(addr); ++ info.bit_offset = be32_to_cpup(addr++); ++ info.nbits = be32_to_cpup(addr); + } + +- if (cell->nbits) +- cell->bytes = DIV_ROUND_UP( +- cell->nbits + cell->bit_offset, +- BITS_PER_BYTE); +- +- if (!IS_ALIGNED(cell->offset, nvmem->stride)) { +- dev_err(dev, "cell %s unaligned to nvmem stride %d\n", +- cell->name, nvmem->stride); +- /* Cells already added will be freed later. */ +- kfree_const(cell->name); +- kfree(cell); ++ info.np = of_node_get(child); ++ ++ ret = nvmem_add_one_cell(nvmem, &info); ++ kfree(info.name); ++ if (ret) { + of_node_put(child); +- return -EINVAL; ++ return ret; + } +- +- cell->np = of_node_get(child); +- nvmem_cell_entry_add(cell); + } + + return 0; diff --git a/target/linux/generic/backport-5.15/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch b/target/linux/generic/backport-5.15/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch new file mode 100644 index 0000000000..172a78b76a --- /dev/null +++ b/target/linux/generic/backport-5.15/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch @@ -0,0 +1,562 @@ +From 6a0bc3522e746025e2d9a63ab2cb5d7062c2d39c Mon Sep 17 00:00:00 2001 +From: Patrick Delaunay +Date: Mon, 6 Feb 2023 13:43:51 +0000 +Subject: [PATCH] nvmem: stm32: add OP-TEE support for STM32MP13x + +For boot with OP-TEE on STM32MP13, the communication with the secure +world no more use STMicroelectronics SMC but communication with the +STM32MP BSEC TA, for data access (read/write) or lock operation: +- all the request are sent to OP-TEE trusted application, +- for upper OTP with ECC protection and with word programming only + each OTP are permanently locked when programmed to avoid ECC error + on the second write operation + +Signed-off-by: Patrick Delaunay +Reviewed-by: Etienne Carriere +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-18-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 11 + + drivers/nvmem/Makefile | 1 + + drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++ + drivers/nvmem/stm32-bsec-optee-ta.h | 80 ++++++++ + drivers/nvmem/stm32-romem.c | 54 ++++- + 5 files changed, 441 insertions(+), 3 deletions(-) + create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c + create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -290,9 +290,20 @@ config NVMEM_SPRD_EFUSE + This driver can also be built as a module. If so, the module + will be called nvmem-sprd-efuse. + ++config NVMEM_STM32_BSEC_OPTEE_TA ++ bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver" ++ depends on OPTEE ++ help ++ Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE ++ trusted application STM32MP BSEC. ++ ++ This library is a used by stm32-romem driver or included in the module ++ called nvmem-stm32-romem. ++ + config NVMEM_STM32_ROMEM + tristate "STMicroelectronics STM32 factory-programmed memory support" + depends on ARCH_STM32 || COMPILE_TEST ++ imply NVMEM_STM32_BSEC_OPTEE_TA + help + Say y here to enable read-only access for STMicroelectronics STM32 + factory-programmed memory area. +--- a/drivers/nvmem/Makefile ++++ b/drivers/nvmem/Makefile +@@ -61,6 +61,7 @@ obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem + nvmem_sprd_efuse-y := sprd-efuse.o + obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o + nvmem_stm32_romem-y := stm32-romem.o ++nvmem_stm32_romem-$(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) += stm32-bsec-optee-ta.o + obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o + nvmem_sunplus_ocotp-y := sunplus-ocotp.o + obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o +--- /dev/null ++++ b/drivers/nvmem/stm32-bsec-optee-ta.c +@@ -0,0 +1,298 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver ++ * ++ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include ++ ++#include "stm32-bsec-optee-ta.h" ++ ++/* ++ * Read OTP memory ++ * ++ * [in] value[0].a OTP start offset in byte ++ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock) ++ * [out] memref[1].buffer Output buffer to store read values ++ * [out] memref[1].size Size of OTP to be read ++ * ++ * Return codes: ++ * TEE_SUCCESS - Invoke command success ++ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param ++ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller ++ */ ++#define PTA_BSEC_READ_MEM 0x0 ++ ++/* ++ * Write OTP memory ++ * ++ * [in] value[0].a OTP start offset in byte ++ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock) ++ * [in] memref[1].buffer Input buffer to read values ++ * [in] memref[1].size Size of OTP to be written ++ * ++ * Return codes: ++ * TEE_SUCCESS - Invoke command success ++ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param ++ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller ++ */ ++#define PTA_BSEC_WRITE_MEM 0x1 ++ ++/* value of PTA_BSEC access type = value[in] b */ ++#define SHADOW_ACCESS 0 ++#define FUSE_ACCESS 1 ++#define LOCK_ACCESS 2 ++ ++/* Bitfield definition for LOCK status */ ++#define LOCK_PERM BIT(30) ++ ++/* OP-TEE STM32MP BSEC TA UUID */ ++static const uuid_t stm32mp_bsec_ta_uuid = ++ UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5, ++ 0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03); ++ ++/* ++ * Check whether this driver supports the BSEC TA in the TEE instance ++ * represented by the params (ver/data) to this function. ++ */ ++static int stm32_bsec_optee_ta_match(struct tee_ioctl_version_data *ver, ++ const void *data) ++{ ++ /* Currently this driver only supports GP compliant, OP-TEE based TA */ ++ if ((ver->impl_id == TEE_IMPL_ID_OPTEE) && ++ (ver->gen_caps & TEE_GEN_CAP_GP)) ++ return 1; ++ else ++ return 0; ++} ++ ++/* Open a session to OP-TEE for STM32MP BSEC TA */ ++static int stm32_bsec_ta_open_session(struct tee_context *ctx, u32 *id) ++{ ++ struct tee_ioctl_open_session_arg sess_arg; ++ int rc; ++ ++ memset(&sess_arg, 0, sizeof(sess_arg)); ++ export_uuid(sess_arg.uuid, &stm32mp_bsec_ta_uuid); ++ sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; ++ sess_arg.num_params = 0; ++ ++ rc = tee_client_open_session(ctx, &sess_arg, NULL); ++ if ((rc < 0) || (sess_arg.ret != 0)) { ++ pr_err("%s: tee_client_open_session failed err:%#x, ret:%#x\n", ++ __func__, sess_arg.ret, rc); ++ if (!rc) ++ rc = -EINVAL; ++ } else { ++ *id = sess_arg.session; ++ } ++ ++ return rc; ++} ++ ++/* close a session to OP-TEE for STM32MP BSEC TA */ ++static void stm32_bsec_ta_close_session(void *ctx, u32 id) ++{ ++ tee_client_close_session(ctx, id); ++} ++ ++/* stm32_bsec_optee_ta_open() - initialize the STM32MP BSEC TA */ ++int stm32_bsec_optee_ta_open(struct tee_context **ctx) ++{ ++ struct tee_context *tee_ctx; ++ u32 session_id; ++ int rc; ++ ++ /* Open context with TEE driver */ ++ tee_ctx = tee_client_open_context(NULL, stm32_bsec_optee_ta_match, NULL, NULL); ++ if (IS_ERR(tee_ctx)) { ++ rc = PTR_ERR(tee_ctx); ++ if (rc == -ENOENT) ++ return -EPROBE_DEFER; ++ pr_err("%s: tee_client_open_context failed (%d)\n", __func__, rc); ++ ++ return rc; ++ } ++ ++ /* Check STM32MP BSEC TA presence */ ++ rc = stm32_bsec_ta_open_session(tee_ctx, &session_id); ++ if (rc) { ++ tee_client_close_context(tee_ctx); ++ return rc; ++ } ++ ++ stm32_bsec_ta_close_session(tee_ctx, session_id); ++ ++ *ctx = tee_ctx; ++ ++ return 0; ++} ++ ++/* stm32_bsec_optee_ta_open() - release the PTA STM32MP BSEC TA */ ++void stm32_bsec_optee_ta_close(void *ctx) ++{ ++ tee_client_close_context(ctx); ++} ++ ++/* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */ ++int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset, ++ void *buf, size_t bytes) ++{ ++ struct tee_shm *shm; ++ struct tee_ioctl_invoke_arg arg; ++ struct tee_param param[2]; ++ u8 *shm_buf; ++ u32 start, num_bytes; ++ int ret; ++ u32 session_id; ++ ++ ret = stm32_bsec_ta_open_session(ctx, &session_id); ++ if (ret) ++ return ret; ++ ++ memset(&arg, 0, sizeof(arg)); ++ memset(¶m, 0, sizeof(param)); ++ ++ arg.func = PTA_BSEC_READ_MEM; ++ arg.session = session_id; ++ arg.num_params = 2; ++ ++ /* align access on 32bits */ ++ start = ALIGN_DOWN(offset, 4); ++ num_bytes = round_up(offset + bytes - start, 4); ++ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; ++ param[0].u.value.a = start; ++ param[0].u.value.b = SHADOW_ACCESS; ++ ++ shm = tee_shm_alloc_kernel_buf(ctx, num_bytes); ++ if (IS_ERR(shm)) { ++ ret = PTR_ERR(shm); ++ goto out_tee_session; ++ } ++ ++ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; ++ param[1].u.memref.shm = shm; ++ param[1].u.memref.size = num_bytes; ++ ++ ret = tee_client_invoke_func(ctx, &arg, param); ++ if (ret < 0 || arg.ret != 0) { ++ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", ++ arg.ret, ret); ++ if (!ret) ++ ret = -EIO; ++ } ++ if (!ret) { ++ shm_buf = tee_shm_get_va(shm, 0); ++ if (IS_ERR(shm_buf)) { ++ ret = PTR_ERR(shm_buf); ++ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret); ++ } else { ++ /* read data from 32 bits aligned buffer */ ++ memcpy(buf, &shm_buf[offset % 4], bytes); ++ } ++ } ++ ++ tee_shm_free(shm); ++ ++out_tee_session: ++ stm32_bsec_ta_close_session(ctx, session_id); ++ ++ return ret; ++} ++ ++/* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */ ++int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower, ++ unsigned int offset, void *buf, size_t bytes) ++{ struct tee_shm *shm; ++ struct tee_ioctl_invoke_arg arg; ++ struct tee_param param[2]; ++ u8 *shm_buf; ++ int ret; ++ u32 session_id; ++ ++ ret = stm32_bsec_ta_open_session(ctx, &session_id); ++ if (ret) ++ return ret; ++ ++ /* Allow only writing complete 32-bits aligned words */ ++ if ((bytes % 4) || (offset % 4)) ++ return -EINVAL; ++ ++ memset(&arg, 0, sizeof(arg)); ++ memset(¶m, 0, sizeof(param)); ++ ++ arg.func = PTA_BSEC_WRITE_MEM; ++ arg.session = session_id; ++ arg.num_params = 2; ++ ++ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; ++ param[0].u.value.a = offset; ++ param[0].u.value.b = FUSE_ACCESS; ++ ++ shm = tee_shm_alloc_kernel_buf(ctx, bytes); ++ if (IS_ERR(shm)) { ++ ret = PTR_ERR(shm); ++ goto out_tee_session; ++ } ++ ++ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; ++ param[1].u.memref.shm = shm; ++ param[1].u.memref.size = bytes; ++ ++ shm_buf = tee_shm_get_va(shm, 0); ++ if (IS_ERR(shm_buf)) { ++ ret = PTR_ERR(shm_buf); ++ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret); ++ tee_shm_free(shm); ++ ++ goto out_tee_session; ++ } ++ ++ memcpy(shm_buf, buf, bytes); ++ ++ ret = tee_client_invoke_func(ctx, &arg, param); ++ if (ret < 0 || arg.ret != 0) { ++ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret); ++ if (!ret) ++ ret = -EIO; ++ } ++ pr_debug("Write OTPs %d to %zu, ret=%d\n", offset / 4, (offset + bytes) / 4, ret); ++ ++ /* Lock the upper OTPs with ECC protection, word programming only */ ++ if (!ret && ((offset + bytes) >= (lower * 4))) { ++ u32 start, nb_lock; ++ u32 *lock = (u32 *)shm_buf; ++ int i; ++ ++ /* ++ * don't lock the lower OTPs, no ECC protection and incremental ++ * bit programming, a second write is allowed ++ */ ++ start = max_t(u32, offset, lower * 4); ++ nb_lock = (offset + bytes - start) / 4; ++ ++ param[0].u.value.a = start; ++ param[0].u.value.b = LOCK_ACCESS; ++ param[1].u.memref.size = nb_lock * 4; ++ ++ for (i = 0; i < nb_lock; i++) ++ lock[i] = LOCK_PERM; ++ ++ ret = tee_client_invoke_func(ctx, &arg, param); ++ if (ret < 0 || arg.ret != 0) { ++ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret); ++ if (!ret) ++ ret = -EIO; ++ } ++ pr_debug("Lock upper OTPs %d to %d, ret=%d\n", ++ start / 4, start / 4 + nb_lock, ret); ++ } ++ ++ tee_shm_free(shm); ++ ++out_tee_session: ++ stm32_bsec_ta_close_session(ctx, session_id); ++ ++ return ret; ++} +--- /dev/null ++++ b/drivers/nvmem/stm32-bsec-optee-ta.h +@@ -0,0 +1,80 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver ++ * ++ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved ++ */ ++ ++#if IS_ENABLED(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) ++/** ++ * stm32_bsec_optee_ta_open() - initialize the STM32 BSEC TA ++ * @ctx: the OP-TEE context on success ++ * ++ * Return: ++ * On success, 0. On failure, -errno. ++ */ ++int stm32_bsec_optee_ta_open(struct tee_context **ctx); ++ ++/** ++ * stm32_bsec_optee_ta_close() - release the STM32 BSEC TA ++ * @ctx: the OP-TEE context ++ * ++ * This function used to clean the OP-TEE resources initialized in ++ * stm32_bsec_optee_ta_open(); it can be used as callback to ++ * devm_add_action_or_reset() ++ */ ++void stm32_bsec_optee_ta_close(void *ctx); ++ ++/** ++ * stm32_bsec_optee_ta_read() - nvmem read access using TA client driver ++ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open ++ * @offset: nvmem offset ++ * @buf: buffer to fill with nvem values ++ * @bytes: number of bytes to read ++ * ++ * Return: ++ * On success, 0. On failure, -errno. ++ */ ++int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset, ++ void *buf, size_t bytes); ++ ++/** ++ * stm32_bsec_optee_ta_write() - nvmem write access using TA client driver ++ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open ++ * @lower: number of lower OTP, not protected by ECC ++ * @offset: nvmem offset ++ * @buf: buffer with nvem values ++ * @bytes: number of bytes to write ++ * ++ * Return: ++ * On success, 0. On failure, -errno. ++ */ ++int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower, ++ unsigned int offset, void *buf, size_t bytes); ++ ++#else ++ ++static inline int stm32_bsec_optee_ta_open(struct tee_context **ctx) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline void stm32_bsec_optee_ta_close(void *ctx) ++{ ++} ++ ++static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx, ++ unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx, ++ unsigned int lower, ++ unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ return -EOPNOTSUPP; ++} ++#endif /* CONFIG_NVMEM_STM32_BSEC_OPTEE_TA */ +--- a/drivers/nvmem/stm32-romem.c ++++ b/drivers/nvmem/stm32-romem.c +@@ -11,6 +11,9 @@ + #include + #include + #include ++#include ++ ++#include "stm32-bsec-optee-ta.h" + + /* BSEC secure service access from non-secure */ + #define STM32_SMC_BSEC 0x82001003 +@@ -25,12 +28,14 @@ + struct stm32_romem_cfg { + int size; + u8 lower; ++ bool ta; + }; + + struct stm32_romem_priv { + void __iomem *base; + struct nvmem_config cfg; + u8 lower; ++ struct tee_context *ctx; + }; + + static int stm32_romem_read(void *context, unsigned int offset, void *buf, +@@ -138,12 +143,29 @@ static int stm32_bsec_write(void *contex + return 0; + } + ++static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ struct stm32_romem_priv *priv = context; ++ ++ return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes); ++} ++ ++static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ struct stm32_romem_priv *priv = context; ++ ++ return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes); ++} ++ + static int stm32_romem_probe(struct platform_device *pdev) + { + const struct stm32_romem_cfg *cfg; + struct device *dev = &pdev->dev; + struct stm32_romem_priv *priv; + struct resource *res; ++ int rc; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) +@@ -173,15 +195,31 @@ static int stm32_romem_probe(struct plat + } else { + priv->cfg.size = cfg->size; + priv->lower = cfg->lower; +- priv->cfg.reg_read = stm32_bsec_read; +- priv->cfg.reg_write = stm32_bsec_write; ++ if (cfg->ta) { ++ rc = stm32_bsec_optee_ta_open(&priv->ctx); ++ /* wait for OP-TEE client driver to be up and ready */ ++ if (rc) ++ return rc; ++ } ++ if (priv->ctx) { ++ rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx); ++ if (rc) { ++ dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", rc); ++ return rc; ++ } ++ priv->cfg.reg_read = stm32_bsec_pta_read; ++ priv->cfg.reg_write = stm32_bsec_pta_write; ++ } else { ++ priv->cfg.reg_read = stm32_bsec_read; ++ priv->cfg.reg_write = stm32_bsec_write; ++ } + } + + return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg)); + } + + /* +- * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) ++ * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) + * => 96 x 32-bits data words + * - Lower: 1K bits, 2:1 redundancy, incremental bit programming + * => 32 (x 32-bits) lower shadow registers = words 0 to 31 +@@ -191,6 +229,13 @@ static int stm32_romem_probe(struct plat + static const struct stm32_romem_cfg stm32mp15_bsec_cfg = { + .size = 384, + .lower = 32, ++ .ta = false, ++}; ++ ++static const struct stm32_romem_cfg stm32mp13_bsec_cfg = { ++ .size = 384, ++ .lower = 32, ++ .ta = true, + }; + + static const struct of_device_id stm32_romem_of_match[] = { +@@ -198,7 +243,10 @@ static const struct of_device_id stm32_r + .compatible = "st,stm32mp15-bsec", + .data = (void *)&stm32mp15_bsec_cfg, + }, { ++ .compatible = "st,stm32mp13-bsec", ++ .data = (void *)&stm32mp13_bsec_cfg, + }, ++ { /* sentinel */ }, + }; + MODULE_DEVICE_TABLE(of, stm32_romem_of_match); + diff --git a/target/linux/generic/backport-5.15/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch b/target/linux/generic/backport-5.15/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch new file mode 100644 index 0000000000..cea8e93858 --- /dev/null +++ b/target/linux/generic/backport-5.15/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch @@ -0,0 +1,85 @@ +From df2f34ef1d924125ffaf29dfdaf7cdbd3183c321 Mon Sep 17 00:00:00 2001 +From: Patrick Delaunay +Date: Mon, 6 Feb 2023 13:43:52 +0000 +Subject: [PATCH] nvmem: stm32: detect bsec pta presence for STM32MP15x + +On STM32MP15x SoC, the SMC backend is optional when OP-TEE is used; +the PTA BSEC should be used as it is done on STM32MP13x platform, +but the BSEC SMC can be also used: it is a legacy mode in OP-TEE, +not recommended but used in previous OP-TEE firmware. + +The presence of OP-TEE is dynamically detected in STM32MP15x device tree +and the supported NVMEM backend is dynamically detected: +- PTA with stm32_bsec_pta_find +- SMC with stm32_bsec_check + +With OP-TEE but without PTA and SMC detection, the probe is deferred for +STM32MP15x devices. + +On STM32MP13x platform, only the PTA is supported with cfg->ta = true +and this detection is skipped. + +Signed-off-by: Patrick Delaunay +Reviewed-by: Etienne Carriere +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-19-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/stm32-romem.c | 38 +++++++++++++++++++++++++++++++++---- + 1 file changed, 34 insertions(+), 4 deletions(-) + +--- a/drivers/nvmem/stm32-romem.c ++++ b/drivers/nvmem/stm32-romem.c +@@ -159,6 +159,31 @@ static int stm32_bsec_pta_write(void *co + return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes); + } + ++static bool stm32_bsec_smc_check(void) ++{ ++ u32 val; ++ int ret; ++ ++ /* check that the OP-TEE support the BSEC SMC (legacy mode) */ ++ ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, 0, 0, &val); ++ ++ return !ret; ++} ++ ++static bool optee_presence_check(void) ++{ ++ struct device_node *np; ++ bool tee_detected = false; ++ ++ /* check that the OP-TEE node is present and available. */ ++ np = of_find_compatible_node(NULL, NULL, "linaro,optee-tz"); ++ if (np && of_device_is_available(np)) ++ tee_detected = true; ++ of_node_put(np); ++ ++ return tee_detected; ++} ++ + static int stm32_romem_probe(struct platform_device *pdev) + { + const struct stm32_romem_cfg *cfg; +@@ -195,11 +220,16 @@ static int stm32_romem_probe(struct plat + } else { + priv->cfg.size = cfg->size; + priv->lower = cfg->lower; +- if (cfg->ta) { ++ if (cfg->ta || optee_presence_check()) { + rc = stm32_bsec_optee_ta_open(&priv->ctx); +- /* wait for OP-TEE client driver to be up and ready */ +- if (rc) +- return rc; ++ if (rc) { ++ /* wait for OP-TEE client driver to be up and ready */ ++ if (rc == -EPROBE_DEFER) ++ return -EPROBE_DEFER; ++ /* BSEC PTA is required or SMC not supported */ ++ if (cfg->ta || !stm32_bsec_smc_check()) ++ return rc; ++ } + } + if (priv->ctx) { + rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx); diff --git a/target/linux/generic/backport-5.15/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch b/target/linux/generic/backport-5.15/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch new file mode 100644 index 0000000000..9d6275a737 --- /dev/null +++ b/target/linux/generic/backport-5.15/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch @@ -0,0 +1,32 @@ +From 3e5ac22aa564026e99defc3a8e02082521a5b231 Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Mon, 6 Feb 2023 13:43:53 +0000 +Subject: [PATCH] nvmem: rave-sp-eeprm: fix kernel-doc bad line warning + +Convert an empty line to " *" to avoid a kernel-doc warning: + +drivers/nvmem/rave-sp-eeprom.c:48: warning: bad line: + +Signed-off-by: Randy Dunlap +Cc: Srinivas Kandagatla +Cc: Andrey Vostrikov +Cc: Nikita Yushchenko +Cc: Andrey Smirnov +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-20-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/rave-sp-eeprom.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/rave-sp-eeprom.c ++++ b/drivers/nvmem/rave-sp-eeprom.c +@@ -45,7 +45,7 @@ enum rave_sp_eeprom_header_size { + * @type: Access type (see enum rave_sp_eeprom_access_type) + * @success: Success flag (Success = 1, Failure = 0) + * @data: Read data +- ++ * + * Note this structure corresponds to RSP_*_EEPROM payload from RAVE + * SP ICD + */ diff --git a/target/linux/generic/backport-5.15/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch b/target/linux/generic/backport-5.15/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch new file mode 100644 index 0000000000..1ab9e609d3 --- /dev/null +++ b/target/linux/generic/backport-5.15/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch @@ -0,0 +1,43 @@ +From eb7dda20f42a9137e9ee53d5ed3b743d49338cb5 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 6 Feb 2023 13:43:54 +0000 +Subject: [PATCH] nvmem: qcom-spmi-sdam: register at device init time + +There are currently no in-tree users of the Qualcomm SDAM nvmem driver +and there is generally no point in registering a driver that can be +built as a module at subsys init time. + +Register the driver at the normal device init time instead and let +driver core sort out the probe order. + +Signed-off-by: Johan Hovold +Reviewed-by: Bjorn Andersson +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-21-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/qcom-spmi-sdam.c | 13 +------------ + 1 file changed, 1 insertion(+), 12 deletions(-) + +--- a/drivers/nvmem/qcom-spmi-sdam.c ++++ b/drivers/nvmem/qcom-spmi-sdam.c +@@ -175,18 +175,7 @@ static struct platform_driver sdam_drive + }, + .probe = sdam_probe, + }; +- +-static int __init sdam_init(void) +-{ +- return platform_driver_register(&sdam_driver); +-} +-subsys_initcall(sdam_init); +- +-static void __exit sdam_exit(void) +-{ +- return platform_driver_unregister(&sdam_driver); +-} +-module_exit(sdam_exit); ++module_platform_driver(sdam_driver); + + MODULE_DESCRIPTION("QCOM SPMI SDAM driver"); + MODULE_LICENSE("GPL v2"); diff --git a/target/linux/generic/backport-5.15/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch b/target/linux/generic/backport-5.15/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch new file mode 100644 index 0000000000..dcf704c6ff --- /dev/null +++ b/target/linux/generic/backport-5.15/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch @@ -0,0 +1,46 @@ +From 1dc7e37bb0ec1c997fac82031332a38c7610352f Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Mon, 6 Feb 2023 13:43:56 +0000 +Subject: [PATCH] nvmem: stm32: fix OPTEE dependency + +The stm32 nvmem driver fails to link as built-in when OPTEE +is a loadable module: + +aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec: +stm32-bsec-optee-ta.c:(.text+0xc8): undefined reference to `tee_client_open_session' +aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec: +stm32-bsec-optee-ta.c:(.text+0x1fc): undefined reference to `tee_client_open_context' + +Change the CONFIG_NVMEM_STM32_ROMEM definition so it can only +be built-in if OPTEE is either built-in or disabled, and +make NVMEM_STM32_BSEC_OPTEE_TA a hidden symbol instead. + +Signed-off-by: Arnd Bergmann +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-23-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -291,8 +291,7 @@ config NVMEM_SPRD_EFUSE + will be called nvmem-sprd-efuse. + + config NVMEM_STM32_BSEC_OPTEE_TA +- bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver" +- depends on OPTEE ++ def_bool NVMEM_STM32_ROMEM && OPTEE + help + Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE + trusted application STM32MP BSEC. +@@ -303,7 +302,7 @@ config NVMEM_STM32_BSEC_OPTEE_TA + config NVMEM_STM32_ROMEM + tristate "STMicroelectronics STM32 factory-programmed memory support" + depends on ARCH_STM32 || COMPILE_TEST +- imply NVMEM_STM32_BSEC_OPTEE_TA ++ depends on OPTEE || !OPTEE + help + Say y here to enable read-only access for STMicroelectronics STM32 + factory-programmed memory area. diff --git a/target/linux/generic/backport-5.10/813-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/pending-5.10/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch similarity index 100% rename from target/linux/generic/backport-5.10/813-nvmem-u-boot-env-align-endianness-of-crc32-values.patch rename to target/linux/generic/pending-5.10/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch diff --git a/target/linux/generic/backport-5.15/809-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch similarity index 100% rename from target/linux/generic/backport-5.15/809-nvmem-u-boot-env-align-endianness-of-crc32-values.patch rename to target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch From 00c5276659cb9929fc5010ebe2f2f10b4d4cf9ef Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Sun, 19 Feb 2023 12:58:56 +0100 Subject: [PATCH 22/22] mvebu: mochabin: enlarge PCI memory window Armada 7040 uses a rather small 15MB memory window for every PCI adapter, however this is not sufficient for Qualcomm QCA6390 802.11ax cards that are shipped along with the OpenWrt WLAN model of MOCHAbin as ath11k requires at least 16MB of memory. So, similar to what MACCHIATOBin has been doing for years, lets move to using the second PCIe 2 memory window and expand it to 128MB to make it future proof. This has been already sent upstream [1]. [1] https://lore.kernel.org/linux-arm-kernel/20230219121418.1395401-1-robert.marko@sartura.hr/ Signed-off-by: Robert Marko --- .../files/arch/arm64/boot/dts/marvell/armada-7040-mochabin.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/armada-7040-mochabin.dts b/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/armada-7040-mochabin.dts index c198061af7..c4e11b5049 100644 --- a/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/armada-7040-mochabin.dts +++ b/target/linux/mvebu/files/arch/arm64/boot/dts/marvell/armada-7040-mochabin.dts @@ -445,4 +445,5 @@ phys = <&cp0_comphy5 2>; phy-names = "cp0-pcie2-x1-phy"; reset-gpio = <&cp0_gpio1 9 GPIO_ACTIVE_LOW>; + ranges = <0x82000000 0x0 0xc0000000 0x0 0xc0000000 0x0 0x8000000>; };