arch/arm/src/stm32h7: Extend crypto interface to support HW CRC32#19449
Closed
pbarada wants to merge 10 commits into
Closed
arch/arm/src/stm32h7: Extend crypto interface to support HW CRC32#19449pbarada wants to merge 10 commits into
pbarada wants to merge 10 commits into
Conversation
Add stm32h7 support for CRC32 HW accelerator. Signed-off-by: Peter Barada <peter.barada@gmail.com>
pbarada
force-pushed
the
test/stmh32h7-hash-crypt7
branch
from
July 15, 2026 20:37
267a663 to
a0b2c54
Compare
|
The ihm07m1_b16 (FOC motor control) configuration overflows the STM32F302R8 64 KiB flash region by ~470 bytes, so it no longer links. Enable GNU Full LTO (CONFIG_LTO_FULL=y); cross-module dead-code elimination brings the image back under the limit (flash drops from ~66.0 KiB to ~57.7 KiB, 88%). Signed-off-by: anjiahao <anjiahao@xiaomi.com>
xcp.ustkptr is only assigned once in up_initial_state() when a task is created and, since the syscall fast path was optimized in e6973c7, is never updated afterwards. up_backtrace() used "ustkptr != NULL" to decide whether a task is currently blocked inside a syscall, and *(ustkptr + 1) as the frame pointer to resume tracing from. Since ustkptr is now a dead value fixed at task creation time, the check is always true and the "frame pointer" it derives points at stale data near the initial stack top, unrelated to where the task is actually blocked. Use rtcb->flags & TCB_FLAG_SYSCALL together with xcp.sregs, which dispatch_syscall() maintains precisely across the entire syscall execution window (including any nested context switches caused by blocking), to locate the frame pointer/return address saved at syscall entry instead. Signed-off-by: liang.huang <liang.huang@houmo.ai>
up_backtrace() on a different tcb dereferences that task's own stack to walk its frame pointer chain, but never selected that task's address environment first. Under CONFIG_ARCH_ADDRENV each task's stack lives behind its own page tables mapped at the same fixed virtual range, so reading tcb->stack_base_ptr without first switching to that task's addrenv reads whatever physical page the caller's own mapping of that virtual range happens to point to, not the target task's real stack. A cross-tid dumpstack of a task running in a different address environment therefore returns garbage or an all-zero backtrace instead of failing cleanly or resolving the real call chain. Add an addrenv parameter to backtrace() and select the target tcb's addrenv_own only around the two dereferences that read the target's saved ra/fp (ra = *(fp - 1), next_fp = *(fp - 2)), then restore the caller's own addrenv before writing the result into buffer. buffer belongs to the caller, not the target tcb, so it must always be written back in the caller's own address environment; writing it while the target's addrenv is still selected would corrupt the access instead of fixing it. Signed-off-by: liang.huang <liang.huang@houmo.ai>
sys_callN() wraps a bare ecall and calls no other function, so the compiler treats it as a leaf function: with frame pointers enabled, it only needs to spill the caller's s0, which it places in what up_backtrace()'s fp-chain walk assumes is ra's stack slot, while the real ra slot is never written. sched_backtrace() then misreads that slot as the return address for this frame, either resolving to a bogus symbol or, if the adjacent garbage happens to look out-of-range, terminating the backtrace early. Add "ra" to the ecall clobber list so the compiler spills/reloads ra around the ecall like a normal call site, keeping ra and the saved s0 in their expected slots. Gate this on CONFIG_FRAME_POINTER && CONFIG_SCHED_BACKTRACE, the only combination where up_backtrace()'s fp-chain walk is both valid (FRAME_POINTER) and actually exercised (SCHED_BACKTRACE); other configurations keep the original "memory"-only clobber and pay no extra cost. This only fixes the syscall boundary. Leaf functions that do not cross a syscall (e.g. up_idle()) can still lose their ra slot the same way and are not addressed here. Signed-off-by: liang.huang <liang.huang@houmo.ai>
The existing CRYPTO_AES_CTR is the RFC 3686 profile: the last 4 bytes of the key are a nonce, the IV is 8 bytes and only the low 32 bits of the counter block are incremented. SSH aes128/192/256-ctr (RFC 4344) instead uses the key as-is (no embedded nonce) and treats the whole 16-byte IV as the initial counter block, incremented as a 128-bit big-endian integer, with the first keystream block being E(IV). Add CRYPTO_AES_CTR_SSH as a new enc_xform mirroring the CRYPTO_CHACHA20_DJB addition. It reuses struct aes_ctr_ctx and the AES block; only setkey (full key, no nonce), reinit (full 16-byte counter) and crypt (encrypt-then- increment over all 16 bytes) differ from the RFC 3686 variant. Keystream validated against `openssl enc -aes-128-ctr`, including a counter that carries across byte boundaries and a non-block-aligned tail. Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
usbdev_register() calls CLASS_BIND, which ends with DEV_CONNECT (composite_bind/cdcacm_bind) and sets SIE_CTRL.PULLUP_EN, and then performs a wholesale putreg32 of SIE_CTRL to set EP0_INT_1BUF -- clobbering the pull-up microseconds after it was asserted. Enumeration only ever succeeded because the host happened to latch the microsecond pull-up blip and issued a bus reset, whose handler (CLASS_DISCONNECT -> DEV_CONNECT) re-arms the pull-up. A warm host port catches the blip; a cold-plugged port is still in attach debounce, misses it, and never resets -- PULLUP_EN stays 0 forever and the device is totally silent on the bus while NuttX runs normally underneath. This presented as an intermittent, image-dependent "cold boot brick" (boot timing shifts the blip in or out of the host's blind window). Fix: set EP0_INT_1BUF with setbits_reg32 so PULLUP_EN survives. Validated on RP2350 silicon (Raspberry Pi Pico 2 W): an image that failed 0/10 cold plugs enumerated 10/10 with the fix; a second board that had never enumerated at all was recovered by it. The rp2040 driver has the identical code and receives the identical fix (build-tested; the RP2350 validation exercised the shared logic). Fixes apache#19434 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Ricard Rosson <ricard@groundbits.com>
Three defects that together prevented macOS from ever mounting a composite USBMSC function (Linux was mostly unaffected because its probe sequence and recovery timing never exercised these paths): 1. usbmsc_setup() compared the class-request wIndex against the compile-time constant USBMSC_INTERFACEID (= CONFIG_USBMSC_IFNOBASE, i.e. 0) instead of the composite-assigned priv->devinfo.ifnobase. In composite mode the MSC interface number is nonzero, so GET MAX LUN, Bulk-Only Mass Storage Reset, and GET/SET INTERFACE all failed the index check and stalled EP0. Standalone MSC is unaffected (ifnobase == 0), which is why this went unnoticed. 2. usbmsc_deferredresponse() has its entire body inside #ifndef CONFIG_USBMSC_COMPOSITE, so the deferred EP0 status stage for MSRESET/SETINTERFACE was never sent in composite mode and the host's Bulk-Only reset timed out. (Unreachable before fix 1 -- MSRESET used to stall at the wrong-interface check.) Compile the body in composite mode too, but suppress the worker's deferred response for SETCONFIGURATION there: the composite driver answers that request itself, and a duplicate zero-length packet corrupts the EP0 state. 3. usbmsc_cmdfinishstate() stalled the bulk IN endpoint whenever a device-to-host command left a residue, even when the response had already been sent and terminated by a short packet (or ZLP). The stall is BOT-legal (USB MSC BOT 6.7.2) but gratuitous: the short packet already ended the data phase and the residue is reported in dCSWDataResidue. Hosts such as macOS answer any bulk-IN halt during device probing with a full Bulk-Only reset sequence, which costs seconds per command or aborts the probe entirely (macOS probes MODE SENSE(6) with allocation lengths that exceed the response; Linux's probe does not). Only halt the endpoint when nothing terminated the data phase. Root-cause analysis and host traces in apache#19435. Validated on RP2350 silicon (Raspberry Pi Pico 2 W, composite CDC-ACM + CDC-NCM + USBMSC): GET MAX LUN answers 1 LUN (previously EP0 stall and a garbage LUN count on macOS), MSRESET completes 10/10 (previously ETIMEDOUT), MODE SENSE(6) alloc=0xC0 returns short data plus a CSW with dCSWDataResidue and zero bulk-IN stalls across the exact-length suite, and macOS now mounts the volume (together with the companion DCD fixes). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Ricard Rosson <ricard@groundbits.com>
Summary Permissions (Part 3) Description: In kernel builds, any unprivileged process running on the NuttX device can open /dev/efuse and attempt to read/write fuse content. Reading the fuses may provide valuable information to an attacker controlling the user process. The write operation, in extreme cases where the fuse blocks are not locked, may brick the device. DISCLAIMER: I tried to be strict with the settings, better to relax them later if it's needed. This is part of apache#19410 Impact See apache#19410 Testing Compiles ok. Signed-off-by: Catalin Visinescu <catalin_visinescu@yahoo.com>
New RISC-V chip port for the GigaDevice GD32VW55x (Nuclei N307, Wi-Fi 6 and BLE 5.3 combo), with the GD32VW553K-START board. Core: - ECLIC interrupt controller, clock tree (160 MHz / 40 MHz HXTAL), 64-bit machine timer, serial (USART0/UART1/UART2) and RTC. - The instruction cache must be enabled in head.S or the UART drops characters under load; the mask ROM uses the first 0x200 bytes of SRAM so the image is linked at 0x20000200; the RTC needs PMU_CTL0.BKPWEN or the register writes are silently discarded. - The ECLIC only auto-clears the interrupt pending bit in hardware-vectored mode, so the trap dispatch clears it for edge-triggered sources or they re-fire forever (level-triggered peripherals clear their own). Peripherals: DMA (8 channels), GPIO + EXTI, SPI (optional DMA), I2C0/I2C1 (the new STM32-v2-style IP, not the GD32F4 one), ADC, PWM and input capture on the timers, both watchdogs, PROGMEM, TRNG and CRC. All use the standard NuttX lower-half interfaces and direct register access, not the vendor SPL. Three user LEDs (GPIOC), and a software reset through the Nuclei SysTimer. Internal flash: it is a system-in-package NOR die behind the real-time decryption block, so it is not programmed through the FMC registers -- the driver goes through the mask ROM API (rom_flash_*), the same way the vendor code does. PROGMEM can be mounted as LittleFS; the region sits below the Wi-Fi NVDS and must not overlap it. Wi-Fi (wlan0), station and softAP: - The MAC/PHY, RF and WPA supplicant are linked as prebuilt BSD-3 libraries. They are RTOS-agnostic, so the OS binding is a sys_* facade on NuttX primitives (gdwifi/wrapper_nuttx.c). Critical sections mask by ECLIC priority threshold, not by disabling every interrupt, or the MAC misses its microsecond deadlines. - The lwIP stack of the SDK is not used: the interface is a netdev_lowerhalf driver driven by the standard tools (wapi, ifup, renew, ping, dhcpd). EAPOL is handed to the supplicant instead of the IP stack. The lowerhalf "priority" field is the work-queue id (HPWORK/ LPWORK), not a task priority -- a wrong value makes receive() never run and every packet is dropped. - The vendor gives the radio 32 KB of shared SRAM as an extra heap; this needs CONFIG_MM_REGIONS >= 2 or the kernel silently drops the region. - The DHCP client needs CONFIG_NETUTILS_DHCPC_BOOTP_FLAGS=0x8000 so the server answers the OFFER by broadcast. - softAP (wapi master mode -> wifi_management_ap_start): the single-VIF firmware does station or AP at a time. Use WPA2, not WPA3: the SAE handshake is deep on the stack and overflows the elliptic-curve crypto with the default task stacks, so the Wi-Fi configs raise CONFIG_INIT_STACKSIZE/DEFAULT_TASK_STACKSIZE. Vendor SDK: cloned by the build at "context" time, pinned to a validated commit and patched in place -- so CI can build with nothing preinstalled, the same pattern as esp-hal-3rdparty. The prebuilt libraries are built for the hard-float ilp32f ABI. BLE 5.3, marked EXPERIMENTAL and off by default: the prebuilt libble is an all-in-one controller plus RivieraWaves host (GAP/GATT/SMP inside the blob) with no HCI transport, so the port drives the vendor host directly (ble_adp_*, ble_adv_*, ble_gap_*) instead of registering a bt_driver_s. The SDK's radio interrupt handlers must be attached to the NuttX IRQ table (they are reached through the ECLIC hardware vector table in the vendor build); attaching also keeps --gc-sections from dropping them. It ships with no configuration; enabling it advertises as "NuttX", connectable. Boards: gd32vw553k-start with nsh, wapi, sta_softap, periph and littlefs configurations, and the board added to the CI build list. Tested on hardware (GD32VW553K-START): NSH, the peripheral drivers (TRNG entropy and the LEDs exercised), LittleFS (write, read, survives a reboot), the full Wi-Fi station path (scan, WPA2, DHCP, ping to the internet), the softAP (a client associates with WPA2, gets an address from the board's DHCP server, and pings the board), and BLE (advertises as "NuttX"; a central connects and enumerates the GATT database). Assisted-by: Claude Opus 4.8 Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
pbarada
requested review from
Donny9,
GUIDINGLI,
acassis,
anchao,
antmerlino,
davids5,
eren-terzioglu,
gustavonihei,
jerpelea,
johannes-nivus,
pkarashchenko,
pussuw,
raiden00pl,
simbit18,
tmedicci and
xiaoxiang781216
as code owners
July 16, 2026 14:38
Contributor
Author
|
Closing - mis-merged master into my branch(caused rebase instead of merge); will recreate branch from updated master and resubmit PR. |
Contributor
Author
|
Closing - mismerged master. Will recreate branch/PR from latest master. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add stm32h7 support for CRC32 HW accelerator.
Extend stm32_crypto.c to add CRYPTO_CRC32 HW acceleration.
Impact
Testing
Build Host:
Target:
Testing performed:
Runtime testing:
From target console: