Skip to content

T8132 (MacBook Air M4): add the SEP and a J715 platform profile - #200

Open
audreyt wants to merge 6 commits into
omacom:integration/aurorafrom
audreyt:t8132-sep
Open

audreyt wants to merge 6 commits into
omacom:integration/aurorafrom
audreyt:t8132-sep

Conversation

@audreyt

@audreyt audreyt commented Oct 24, 2026 •

Copy link
Copy Markdown

The original bring-up notes below describe the base of this PR. The J715 sensor-session follow-up at the end has separate verification and qualification limits.

Summary

Adds the M4 (T8132) Secure Enclave to the tree, for the 15-inch MacBook Air (J715):

  1. dt-bindings: apple,t8132-dart and apple,t8132-asc-mailbox.
  2. t8132.dtsi: the SEP, its DART and its mailbox, described like t8122.dtsi. The SEP and its DART are disabled, and the DART carries the SEP's IOVA window from the J715 ADT (0x10000004000 + 0xffff0000, no offset).
  3. apple_sep: a T8132/J715 platform profile with the T8122 warm registration and the same window, selected only on apple,j715.

The mailbox interrupts are not in ADT order. The ADT lists 390 389 392 391, which puts the line asserted while the receive FIFO is empty in the recv-not-empty slot. The ASC v4 mailbox has no IRQ acknowledge, so starting the SEP channel froze the machine every time. This uses 389 390 391 392, the order the T8122 SEP mailbox already uses.

Related

Kb2uka/Omarchy-M4-Native#168 has the matching fixes on the Omarchy M4 kit side: the same mailbox interrupt order, and two m1n1 fixes the SEP needs on T8132. Current m1n1 keeps a pointer from fdt_get_alias() across inserting memory-region, so a tree with the sep alias does not boot. And its SEP ROM random request leaves the running sepOS no longer reading its mailbox, so registration is never consumed. Upstream AsahiLinux/m1n1 has both. That is why this PR adds no sep alias to any board; the alias can follow once the bootloader carries those fixes.

Evidence

15-inch M4 MacBook Air (Mac16,13 / J715), macOS 27.0.1 alongside. Hardware runs used the Omarchy M4 kit kernel 7.1.9 with an earlier port of this driver, equivalent device-tree nodes, the same DART window and the #168 m1n1 fixes:

  • Freeze: ADT interrupt order froze at mailbox start; the order here passed it on every boot since.
  • Attach: the SEP advertised 12 endpoints, sks: identity keybag provisioned, and /dev/sep-crypto appeared.
  • Use: a P-256 key held by the SEP signed through OpenSSH (ssh-keygen -Y sign, then -Y verify: good signature; a tampered message fails). The same key signed after a reboot with the driver loaded at boot.
  • Window: with the 0..4 GiB BIT(40) offset window on that kernel, whose DART ignores apple,dma-offset, the SEP never answered. The ADT window used here works whether or not the offset is applied.

On this tree: drivers/soc/apple/ builds with Rust, APPLE_SEP=m and APPLE_SEP_KUNIT_TEST=y (clang 21.1.8, rustc 1.93.1) with no errors or warnings; t8132-j715.dtb and t8122-j613.dtb build, and the J715 DTB carries the nodes as written.

Not tested

  • The KUnit suites on a J715. They pass on a booted arm64 kernel under QEMU/KVM (see the merge note below), which is not J715 hardware.
  • The xART guard on J715 (default 1, as on the M3). The tested Mac provisioned its keybag before the guard existed.
  • Other T8132 boards other than J715.
  • dt_binding_check and rustfmt (not available in the build container).

Merge Danger

Door: two-way

Blast Radius: T8132 only. The SEP and its DART nodes are disabled, no board sets the sep alias, and the profile is selected only on apple,j715. The sep_mbox node (mbox@3aa608000 in t8132.dtsi) has no status, so the mailbox driver probes on all six T8132 boards, as it does for the same node in t8122.dtsi and t8112.dtsi. That probe requests its interrupts with IRQF_NO_AUTOEN and enables them only when a client starts the channel (drivers/soc/apple/mailbox.c), so an unclaimed mailbox stays quiet.

J715 sensor-session follow-up (2026-10-26)

The J715 profile now selects nonce authentication and this Mac's own FDR MSRk body (apple/msrk-j715.bin, 10,848 bytes). An explicit SESSION_SHARE status 0x16 loads that body and permits one retry. Other refusal and transport failures stop the attempt. The existing source-6 calibration path is selected by the nonce policy; provisioning must supply the machine's FSC2 input. No private key, calibration body or extractor is included.

J700 keeps its existing pre-share, once-per-enclave signed-container load. Other profiles select no sensor root-key file. The xART, registration, persistence and capture-qualification guards remain in place. Four KUnit cases cover the board policy, length boundaries and refusal classification. Documentation/input/devices/j715-touchid.rst records provisioning and qualification boundaries.

Validation of this follow-up: the complete drivers/soc/apple/ target compiled on DGX with Rust 1.93.1, clang 23.1.3, APPLE_SEP=m, APPLE_SEP_KUNIT_TEST=y and KCFLAGS=-Werror; both sep.o and linked apple-sep.o were produced. An unchanged rust/kernel/dma_fence.rs emitted an into_raw dead-code warning, retained in the build record. This was a compile check, not a KUnit runtime pass.

Review follow-up (2526790cd): load_sensor_root_key now calls sensor_step_failed(SENSOR_ROOT_KEY) when a root-key container is rejected for its length, so an empty msrk-j700.bin reports the same step failure as before the profile rework. One line in drivers/soc/apple/sbio.rs. It compiled on DGX with rustc 1.93.1 against this tree with APPLE_SEP=m and APPLE_SEP_KUNIT_TEST=y (KUNIT=y), and apple-sep.ko linked. That build had no Module.symvers, so modpost ran with KBUILD_MODPOST_WARN=1; no warning or error in the log names sbio.rs or the SEP sources. Still a compile check only.

Merge (399659282): integration/aurora is merged into this branch (clean, no conflicts; this PR's own diff is still the same six files). It brings in 1f4512149 and 5447fa259, the first-setup window for a fresh install's first keybag, which this branch predated. Without them the first CREATE_KEYBAG under xart_guard level 1 on a Linux-first install was refused on a J713 (reported below in this PR). KUnit on a booted kernel: arm64 defconfig plus Rust, APPLE_SEP=y and APPLE_SEP_KUNIT_TEST=y built in, rustc 1.93.1, booted under QEMU 11.1.2 with KVM on an arm64 host; all 11 apple_sep suites pass, 127 cases, 0 failures (xart_guard is 28 cases with the window tests; 22 before the merge, 121 in total). The driver found no platform profile on the virtual machine and stayed disabled, so this touched no SEP, DART, mailbox or xART store. It is not a J715 run. The window has not been run on any M4, and the fresh-keybag J715 run is still outstanding.

The earlier M4-kit port completed Linux enrollment and same-boot verify-match. On a subsequent owner-controlled cold boot, that same fixed module restored the existing enrollment and completed an SDDM fingerprint login. The service returned 0, the SDDM journal recorded its right-index prompt and successful authentication, and the owner confirmed the result. The login keyring needed separate unlocking. These observations do not qualify this upstream kernel, concurrent Camera operation or suspend/resume. Userspace support is omacom/omarchy-mac-pkgs#69 and must not be released before the matching driver is qualified. That includes one fresh-keybag J715 run with the xART guard on (J715 inherits xart_guard 1 from T8122; omarchy-mac-pkgs#69 loads the driver with xart_writes=1 provision_keybag=1, so the first owner to enable Touch ID is the first run of that path on a store macOS also reads) and the KUnit suites run on a booted kernel. Neither has been done.

The M4 (T8132) SEP DART and SEP mailbox are the same parts as on T8122.
Add apple,t8132-dart, with the apple,t8110-dart fallback, and
apple,t8132-asc-mailbox, with the apple,asc-mailbox-v4 fallback.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Audrey Tang <au@civic.ai>
Describe the M4 SEP the way t8122.dtsi does: the SEP and its DART
disabled, the DART carrying the SEP's own IOVA window from the J715 ADT
(dart-sep vm-base-0 0x10000004000, vm-size-0 0xffff0000) with no offset,
and the ASC mailbox inside the SEP wrapper at +0x8000.

The ADT lists the mailbox interrupts as 390 389 392 391. In that order
the recv-not-empty slot holds the line that is asserted while the
receive FIFO is empty; the ASC v4 mailbox has no IRQ acknowledge, so
starting the channel polls an empty FIFO in hard IRQ context and the
machine freezes. Use 389 390 391 392, the order the T8122 SEP mailbox
and the other T8132 ASC mailboxes use.

No board adds the sep alias yet. With the alias, m1n1 hands the SEP its
firmware region and manifests, but current m1n1 keeps a pointer from
fdt_get_alias() across inserting memory-region, and on T8132 its SEP ROM
random request leaves the running sepOS no longer reading its mailbox.
Both are fixed in Kb2uka/Omarchy-M4-Native#168; the alias can follow
once the bootloader carries them.

Tested on a 15-inch M4 MacBook Air (J715) with equivalent nodes in the
Omarchy M4 kit tree: the mailbox starts without freezing and the SEP
answers.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Audrey Tang <au@civic.ai>
The 15-inch M4 MacBook Air (J715) hands over a running SEP (ADT
sepfw-booted), like the M3 Air, so this is T8122's warm registration,
shared-memory geometry, variant-5 key store and xART guard default.

Its SEP DART window is the ADT's own, 0x100_0000_4000 + 0xffff0000,
given as a range with no offset. This matches what t8132.dtsi carries,
and unlike the BIT(40) offset window it also reaches the SEP on kernels
whose DART driver does not apply apple,dma-offset. The Mesa sensor is on
spi2 at 0x3ad108000; its identity is unchecked, so capture stays
unqualified. Only J715 selects the profile.

Tested on a J715 (macOS 27.0.1) with an earlier port of this driver on
the Omarchy M4 kit kernel (7.1.9), the DART window set the same way and
the m1n1 fixes from Kb2uka/Omarchy-M4-Native#168: the SEP attaches with
12 endpoints, the identity keybag is provisioned, a P-256 key held by
the SEP signs through OpenSSH, and the same key signs after a reboot
with the driver loaded at boot. With the 0..4 GiB offset window on that
kernel the SEP never answered.

Not tested: this tree on hardware, the xART guard on J715 (the tested
Mac provisioned before the guard existed), and Touch ID.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Audrey Tang <au@civic.ai>
@audreyt
audreyt marked this pull request as ready for review October 24, 2026 03:33
@greptile-apps

greptile-apps Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge within its stated J715 scope.

Summary

Adds SEP support descriptions and a board-specific profile for the 15-inch M4 MacBook Air.

  • The J715 MacBook Air can attach Linux to its running SEP.

No actionable issues were found. This review checked source paths; it did not run builds or hardware tests.

Acknowledged limits from audreyt:

  • The missing sep alias is intentional until the bootloader fixes are available.
  • Runtime KUnit tests and the J715 xART guard remain untested.
  • Sensor capture and other T8132 boards remain unqualified.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Load apple_sep] --> B{T8132 and J715?}
  B -- No --> C[Do not select the new profile]
  B -- Yes --> D[Select T8132 profile]
  D --> E[Enable DART with the declared DMA window]
  E --> F[Enable SEP]
  F --> G[Register shared memory through the mailbox]
Loading

Reviews (1) · Last reviewed commit: "soc: apple: sep: Add a T8132 (MacBook Ai..." · Reviewed by Greptile

Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>

@scottjones scottjones left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We read through this with the SEP side in mind and did not find a bug in the code. Notes and what we would like before approving:

  1. Other boards are unchanged. detect() only returns the new profile for t8132 plus j715 (drivers/soc/apple/profile.rs:663-666), so J713, J604, J623/J624 and J773g still get ENODEV. The establish_session rewrite (drivers/soc/apple/sbio.rs:2526) runs on every board through init_sequence_counter, but for a profile whose sensor_root_key is None it takes the same success, refusal and transfer-failure paths, with the same messages, as the old sensor_enclave_step call. The root-key load that used to run for every nonce-session profile now runs only for J700, which was the only nonce-session profile before this PR. J700 still loads its container before SESSION_SHARE once per enclave.

  2. Small J700 change: an empty msrk-j700.bin used to call sensor_step_failed, and now load_sensor_root_key returns false after "unsupported length" without it (sbio.rs, load_sensor_root_key). Only the diagnostics change, but worth keeping if it was intended.

  3. The blast radius note says the new nodes are disabled, but sep_mbox has no status (arch/arm64/boot/dts/apple/t8132.dtsi, mbox@3aa608000), so the mailbox probes on all six T8132 boards. That matches t8122.dtsi and t8112.dtsi and the mailbox probe requests its interrupts with IRQF_NO_AUTOEN and enables them only when a client starts the channel (drivers/soc/apple/mailbox.c), so we do not think it is a problem. The description should say so.

  4. xART: J715 inherits xart_guard 1 from T8122, which is the safe setting, but a fresh J715 keybag has never been created under the guard. omarchy-mac-pkgs#69 loads this with xart_writes=1 provision_keybag=1, so the first J715 owner who enables Touch ID is the first run of that path, on a store macOS also reads. Before #69 ships J715 we would like one fresh-keybag J715 run with the guard on, and the KUnit suites run on a booted kernel, not just compiled.

No J715 here, so none of the hardware claims are checked by us.

load_sensor_root_key returned without sensor_step_failed when the container length was rejected, so an empty msrk-j700.bin lost the SENSOR_ROOT_KEY step failure it reported before the profile rework. Report it again for every rejected length.

Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
@MuBai-He

Copy link
Copy Markdown

J713 data for point 4 of the review above

I have the 13-inch M4 (J713), the board most like J715. I can't do the J715 run, but J713 has data for both requests in point 4. A J713 profile on top of this PR is in #248. Point 1 still holds here: without it, J713 gets ENODEV.

KUnit on a booted kernel.

Setup:

  • This branch's drivers/soc/apple, ported to the Omarchy M4 kit kernel 7.1.9.
  • The kit kernel has CONFIG_KUNIT=m, so the module was built with APPLE_SEP_KUNIT_TEST on and kunit was loaded with enable=1.

Results at insmod on the J713: all 11 apple_sep suites passed, 124 cases with 0 failures and 0 skips. That includes apple_sep_sensor_root_key with the J715 cases.

One side effect. apple_sep_xart_guard tests refusals through Guard::check(), and each refusal also goes to crate::diag::xart_guard_refused(). After the suites run:

  • diag/xart_guard_refusals reads 13;
  • diag/matching reads blocked;
  • diag/touchid reads ready and matching works, so the driver refused nothing.

A readiness check that trusts diag/matching would get a false block on any kernel built with the tests.

Fresh keybag under the guard.

On J713, the first CREATE_KEYBAG under level 1 fails on this PR's base. It fails the same way 1f45121 describes for a Linux-first M2 Max:

apple_sep: xART guard: refused to rewrite a kind-4 record this Linux install did not create
apple_sep 3aa600000.sep: sks: CREATE_KEYBAG got no reply after 2040 ms
apple_sep 3aa600000.sep: sks: CREATE_KEYBAG exchange did not complete (buffers unregistered, wedged, or OOL write failed)

Conditions of that run:

  • level 1, with the owned list loaded and empty;
  • the first create on this install;
  • a development build using this branch's sks and xart_guard;
  • as far as I recall, macOS had not been booted since Linux was installed, so this install was Linux-first as in 1f45121.

Touch ID setup could not continue in that boot. Under level 2, the enclave's rewrite of the kind-2 root was refused before that point.

On a later boot, the same create succeeded with xart_guard=0. Comparing gigalocker images from before and after, the create rewrote:

  • the kind-2 root;
  • the kind-1 root;
  • exactly one pre-existing kind-4 locker, which shrank from 2320 to 1334 bytes.

That last change looks like the pending-locker commit that 1f45121's window allows: one pre-existing kind-4 rewrite, at level 1, with an empty list, on a warm-attach Mac. Nothing else in the gigalocker changed.

So a J715 owner whose first Touch ID setup happens in Linux under #69 (xart_writes=1 provision_keybag=1, level 1) would probably hit the same refusal. That holds unless the kernel also carries 1f45121 and 5447fa2, and this PR's base predates both. The J713 changes fit inside that window, but I have not run the window on an M4. I can't repeat a first create on this J713 without rolling back the gigalocker, which I won't do.

After setup, under the guard. With that keybag in place and the default level 1, J713 passed:

  • enrolment, and a match of the enrolled finger with another finger rejected;
  • three cold-boot restores, each followed by a match.

No write was refused. The only gigalocker change in those runs was the enclave rewriting the kind-1 root.

None of this is a J715 run. It is the closest board, on the same SoC, the same SEP window and the same sensor session.

Assisted-by: Claude:claude-opus-5-5

@audreyt

audreyt commented Oct 27, 2026

Copy link
Copy Markdown
Author

Thanks for the careful read.

  1. Other boards: agreed, no change intended. detect() only returns the new profile for t8132 + j715.

  2. Empty or wrong-length root-key container: this was an unintended diagnostics regression. load_sensor_root_key now calls sensor_step_failed(SENSOR_ROOT_KEY) when the container length is rejected, so an empty msrk-j700.bin reports the same step failure as before. One line in drivers/soc/apple/sbio.rs, pushed as 2526790. It compiled on DGX with rustc 1.93.1 (APPLE_SEP=m, APPLE_SEP_KUNIT_TEST=y, apple-sep.ko linked). That is a compile check only; nothing was run on hardware.

  3. sep_mbox status: you're right, the description was wrong. The SEP and its DART are disabled, but the mailbox node has no status, so it probes on all six T8132 boards, matching t8112/t8122. Its interrupts are requested with IRQF_NO_AUTOEN and enabled only when a client starts the channel, so an unclaimed mailbox stays quiet. I have corrected the Blast Radius note in the description.

  4. xART: agreed on both asks. A fresh-keybag J715 run with xart_guard on, and the KUnit suites on a booted kernel, are still outstanding. I have not done either, and the description now says they are needed before omarchy-mac-pkgs#69 ships J715.

Bring in the first-setup window for a fresh install's first keybag
(1f45121 and 5447fa2), which this branch predates. Without it the
first CREATE_KEYBAG on a Linux-first install is refused by the xART guard
at level 1, as reported on a J713 in omacom#200.

The merge is clean; this branch's own changes are unchanged.

Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
@audreyt

audreyt commented Oct 28, 2026

Copy link
Copy Markdown
Author

Merged integration/aurora into this branch (399659282). The merge is clean, and this PR's own diff is still the same six files. It brings in 1f4512149 and 5447fa259, the first-setup window, which this branch predated. Thanks @MuBai-He: the J713 data is what showed the first CREATE_KEYBAG being refused without them.

KUnit on a booted kernel. arm64 defconfig plus Rust, APPLE_SEP=y and APPLE_SEP_KUNIT_TEST=y built in (rustc 1.93.1), booted under QEMU 11.1.2 with KVM on an arm64 host. All 11 apple_sep suites pass: 127 cases, 0 failures. xart_guard is 28 cases with the window tests, 22 before the merge (121 in total on the old head). MuBai-He's J713 run gave 124 cases on the older head with the module loaded on hardware. The virtual machine has no platform profile, so the driver stayed disabled and touched no hardware. Neither run is a J715.

Still open

  1. The fresh-keybag J715 run with the guard on, on this head. The window has not been run on any M4; its commit message reports an M2 Max. So the first J715 owner's first create under DMA heap: release reserved fd and buffer when returning the allocation fails #69 is still the first time on M4.
  2. MuBai-He's finding that the suites leave diag/xart_guard_refusals nonzero and diag/matching at blocked on a kernel built with the tests is real: Guard::check() reports every refusal to diag::xart_guard_refused(), test or not. I did not change it here; it should be a separate fix, and DMA heap: release reserved fd and buffer when returning the allocation fails #69's readiness check should not trust diag/matching on such a kernel.

@audreyt

audreyt commented Oct 28, 2026

Copy link
Copy Markdown
Author

J715 hardware data point (15-inch M4 MacBook Air, J715). This is NOT a fresh install: this Mac installed Linux before the xART guard existed, so its xART already held Linux-written session records and there was no owned list.

Setup. This PR's head (399659282, integration/aurora merged) ported to the Omarchy M4 kit kernel 7.1.9 (build #20): device::Core without the lifetime, workqueue::system(), dma_rmb()/dma_wmb() as dmb oshld/oshst, firmware through request_firmware (the kernel crate has no RUST_FW_LOADER_ABSTRACTIONS), trusted-key registration off, KUnit off. On a cold boot where the production module was skipped, I moved the existing keybag aside and loaded the ported module once with xart_writes=1 provision_keybag=1 and the default guard level (1).

Result.

  • xART guard level 1: 11 session records exist, 0 created by Linux; the other 11 are protected, then sks: identity keybag provisioned.
  • xart_guard_refusals=0, diag/matching=unverified.
  • The owned list was created (32 bytes, the first-setup marker). There is no "allowed the enclave to commit an existing kind-N locker" line, so no pending kind-4 locker was committed in this run: it did not exercise that path.
  • On the next boot the production module reported abi=4 sensor_present=1 enrolled=1 with the new keybag in place.

Not shown. A fresh install; the pending-locker commit that 1f4512149 allows; a fingerprint match on this driver build; the state of the xART store as macOS sees it afterwards (I have not booted macOS to check). The Linux-side backup cannot undo what the enclave wrote to the shared store.

So on this J715, CREATE_KEYBAG under guard level 1 did not wedge when the store held pre-guard Linux records. It does not answer the fresh-install case Scott asked about.

@audreyt

audreyt commented Oct 29, 2026

Copy link
Copy Markdown
Author

Follow-up to the J715 hardware report above:

  • The owner has since booted macOS and reports that Touch ID still works there. This closes only the earlier "macOS not checked" observation; it is not a full comparison of the shared xART store.
  • The KUnit diagnostic side effect is addressed separately in soc: apple: sep: Report xART guard refusals only from the live guard #257. With the added regression test but without the fix, apple_sep_xart_guard has 28 passes and 1 failure. With the fix it has 29 passes and no failures under arm64 QEMU/KVM. The test guards no longer report refusals into the live diagnostics.
  • The fresh-install case and the pending kind-4 locker path remain untested on this J715. The successful keybag creation reported above was on a pre-guard Linux installation; neither the macOS result nor QEMU changes that limitation.

@scottjones, your point 4 distinguished the evidence needed before omarchy-mac-pkgs#69 ships J715. Would you be comfortable reviewing this driver PR for integration/aurora with J715 package release still gated on the fresh-install qualification, or is that run also a prerequisite for merging this PR? I will keep the package qualification gate either way. #257 can be reviewed separately from the board enablement.

@scottjones

Copy link
Copy Markdown
Collaborator

Thanks, Audrey. We don't think the fresh-install run needs to block merging this driver into integration/aurora, because the J715 profile only activates on a J715 (apple,t8132 plus apple,j715), so other Macs don't change. It's still a prerequisite before omarchy-mac-pkgs#69 ships Touch ID and SDDM fingerprint login for J715, and thanks for keeping that gate. One thing to keep in mind is that the M4 isn't in the RC's scope (M1, M2, M3 and the Neo), so the maintainers may prefer to land this after the RC pin, and that's Marcelo's call. Thanks too for splitting the KUnit side effect out into #257 as its own fix; we're reviewing it now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants