Skip to content

Provide RFC 3394 default IV explicitly for AES key wrap#1

Closed
gregakespret wants to merge 1 commit into
thisiscam:findmy-export-supportfrom
gregakespret:fix-openssl-aes-wrap-iv
Closed

Provide RFC 3394 default IV explicitly for AES key wrap#1
gregakespret wants to merge 1 commit into
thisiscam:findmy-export-supportfrom
gregakespret:fix-openssl-aes-wrap-iv

Conversation

@gregakespret
Copy link
Copy Markdown

The two Crypter::new(...ID_AES128_WRAP..., None) / decrypt(..., None, ...)
calls in rfc6637_wrap_key / rfc6637_unwrap_key panic at runtime against
recent openssl crate releases (0.10.80+) with:

thread 'main' panicked at openssl/symm.rs:623:
an IV is required for this cipher

openssl's Crypter::new now enforces that any cipher whose iv_len()
is non-zero must be supplied an IV explicitly; passing None no longer
falls through to the cipher's default.

The two call sites here are RFC 6637 OpenPGP key-wrap helpers and both
internally use AES Key Wrap (RFC 3394). RFC 3394 §2.2.3.1
defines the default initial value for the wrap function as the constant
0xA6A6A6A6A6A6A6A6, used when no Alternative Initial Value is supplied.

This PR passes that constant explicitly. The wire-level output is
identical
to what older openssl versions produced when None was passed
— the constant is exactly what the cipher was already using internally as
its IV default; we're just no longer relying on openssl to fill it in.

How was this tested

Built locally against openssl = 0.10.80 and ran export-findmy against
my live iCloud account: previously panicked at the first
pcs_keys_for_record call (the FindMy BeaconStore zone returns
PCS-encrypted records that need RFC 6637 unwrap during key derivation);
after the fix, all 9 MasterBeaconRecords decrypt cleanly and downstream
findmy.py location fetch returns reports for all 4 AirTags on the
account.

Reproducible: any CloudKit zone returning PCS-encrypted records will hit
this path. The FindMy BeaconStore zone is the easiest reproduction (via
thisiscam/export-findmy).

openssl 0.10.80 enforces that any cipher with a defined IV must have one
supplied explicitly — passing `None` panics at runtime with
"an IV is required for this cipher" inside `Crypter::new` / `decrypt`
(see openssl-rs/symm.rs around the IV-required check).

The two call sites here are in the RFC 6637 OpenPGP key-wrap helpers and
both go through AES Key Wrap (RFC 3394). RFC 3394 §2.2.3.1 defines the
"default initial value" for the wrap function as the constant
`A6A6A6A6A6A6A6A6`, used when no Alternative Initial Value is supplied.

Pass that constant explicitly so the cipher contract is satisfied without
changing the wire-level behaviour (the byte stream produced/consumed on
the network is identical to what older openssl versions did when `None`
was passed).

Reproduces with the export-findmy tool against any CloudKit zone that
returns PCS-encrypted records (e.g. the FindMy BeaconStore zone) when
built against current openssl crate releases.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
gregakespret added a commit to gregakespret/rustpush that referenced this pull request May 25, 2026
gregakespret added a commit to gregakespret/export-findmy that referenced this pull request May 25, 2026
thisiscam/rustpush#1 contains a one-line openssl-compatibility fix
required for `cargo build` against openssl >= 0.10.80 (without it the
extractor panics on the first PCS-encrypted record). Until that PR
merges upstream, this fork's main points at gregakespret/rustpush which
has the patch already merged on the same findmy-export-support branch.

Revert this commit (or rebase onto upstream main) once
thisiscam/rustpush#1 is merged and thisiscam/master is updated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@gregakespret
Copy link
Copy Markdown
Author

Closing as a duplicate of OpenBubbles/rustpush#22 — same one-line fix (RFC 3394 default IV constant for AES_128_WRAP), opened upstream by @malmeloo 2026-05-05 and still awaiting review.

Leaving a reproduction signal on the upstream PR so it can be picked up there. If/when upstream merges and this fork rebases, the fix will land here automatically. Apologies for the noise — should have grep'd upstream PRs before filing.

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.

1 participant