same passkey synced on 2 devices generate different prf outputs for the same salt

Steps to reproduce:

  • register a passkey on device A
  • authenticate on device A, using the prf extension and a constant salt. Note the prf output
  • go to device B. wait for iCloud sync
  • authenticate on device B using the prf extension and the same constant salt. Note the prf output
  • The prf outputs are different.

Note: Repeat the authentication on each device. The prf output is identical for a given device, which seems to point towards the inclusion of a device specific component in the prf derivation.

In my scenario, I need the prf output to be the same regardless of the device since I use it as the recovery key for my app data.

Could you confirm that this is the expected behavior or not?

Thanks,

This should work as expected, that is, the prf should be identical in this case.

What I would suggest is to first make sure you don't have anything in your code that is changing the salt or anything else on one device vs. the other, and the data blobs are bit identical.

If you come to the conclusion that there is no issue in your code, it is always possible that something may have broken on the system side, so we would like to see a bug report about this.

If you do so via https://feedbackassistant.apple.com/ please also include a sysdiagnose from both devices right after you reproduce the issue. In your bug report please include any and all relevant information like your data blobs, etc.

Once you have done so, please share your Feedback ID here, and @mention me in your response so I can forward the issue to the team right away.

Hello, we are facing the same issue. The issue is more narrow though, if you create a passkey on an iPhone, then use it on a Mac, it produces different PRF outputs.

If you create the passkey on a mac, then use it on the phone, it creates the same PRF output.

I will also report that through feedbackassistant and sysdiagnose if it helps.

@Engineer I ran into the same issue, but its directional, consistent, and you guys should be able to easily reproduce it.

I’m testing Cove 1.3.0 (build 112) using the AuthenticationServices PRF extension with RP ID covebitcoinwallet.com.

The devices were:

  • iPhone 15 running iOS 26.5.2 (23F84)
  • iPhone SE, 3rd generation, initially running iOS 18.6.2

Here is the behavior I reproduced:

  1. I created an Apple Passwords passkey and encrypted cloud backup on the iPhone 15 running iOS 26.5.2.

  2. The passkey synchronized through iCloud and appeared locally in Apple Passwords on the iPhone SE running iOS 18.6.2.

  3. When I selected that locally synchronized passkey on the SE, authentication completed, but Cove could not decrypt the backup wrapper using the PRF result. The app reported that the passkey did not match any available backup.

  4. If I immediately tried again on the SE, selected the QR/use-another-device option, and authenticated using the original iPhone 15, the same backup restored successfully.

The reverse direction worked correctly:

  • I created an Apple Passwords passkey and backup on the iPhone SE running iOS 18.6.2.
  • After it synchronized, the passkey worked locally on the iPhone 15 running iOS 26.5.2.

I also tested the equivalent cross-device flow with a passkey stored in 1Password, and that worked.

The clearest confirmation came after I upgraded the same iPhone SE from iOS 18.6.2 to iOS 26. After the upgrade, the locally synchronized Apple Passwords passkey originally created on the iPhone 15 worked correctly on the SE. The QR workaround was no longer necessary.

So the complete test matrix is:

  • Created on iOS 18.6.2 → used locally on iOS 26: works
  • Created on iOS 26.5.2 → used locally on iOS 18.6.2: fails
  • Created on iOS 26.5.2 → used via QR with the original iOS 26 device: works
  • Created on iOS 26.5.2 → used locally after upgrading the SE to iOS 26: works
  • Comparable cross-device test using 1Password: works

The SE did not need to be wiped or reset. I reproduced the failure multiple times on the normally configured device. Waiting longer for iCloud synchronization also did not help.

I additionally tried explicitly setting this on both registration and assertion requests:

request.userVerificationPreference = .required

That did not change the behavior while the SE was running iOS 18.6.2.

Our app does not construct separate requests for local and QR authentication. Both options originate from the same ASAuthorizationController assertion request, configured with the same RP ID, required user verification, and the exact PRF salt stored in the downloaded encrypted backup wrapper. The application does not modify the salt based on the selected transport or device.

I also had the relevant Swift and Rust code paths independently reviewed. We could not find an application branch that would produce transport-specific PRF inputs, and the focused passkey-matching tests pass.

Since the same physical iPhone SE began working after it was upgraded from iOS 18.6.2 to iOS 26, this appears to be a backward-compatibility issue: iOS 18.6.2 cannot locally reproduce the expected PRF result for an Apple Passwords passkey created on iOS 26, while iOS 26 can use passkeys created on iOS 18.6.2.

We're facing the same issue:

  • iPhone → iPhone: resolved on iOS 18.4 and above.
  • iPhone → Mac: PRF outputs differ.
  • Mac → iPhone: PRF outputs match.
same passkey synced on 2 devices generate different prf outputs for the same salt
 
 
Q