trackslash
VAULT-99 P1 For an agent

Encrypt items and backups with CryptoKit, and record the export compliance reasoning

0
All issues

Description

Every build tells Apple ITSAppUsesNonExemptEncryption = NO. What Vault encrypts, and with what:

  • The App Lock Password's vault file: CryptoKit (AES.GCM), Apple's own code.
  • Encrypted items and every backup: CryptoSwift's AES-GCM (CryptoEngine/Symmetric/AESGCMEncryptor.swift, AESGCMDecryptor.swift).

Background (researched 2026-09-29, not legal advice)

Apple's documentation tiers (export compliance documentation):

  • Encryption "limited to that within the Apple operating system" needs no documentation.
  • An "industry standard algorithm, not provided within the Apple operating system" needs a French encryption declaration uploaded, if the app is sold in France.
  • Proprietary algorithms need a CCATS as well.

ITSAppUsesNonExemptEncryption = NO means the encryption is "exempt from export compliance documentation requirements". So with CryptoSwift's AES, the NO is inaccurate.

The library doesn't change the law. It's the same AES, so Vault's legal classification is the same either way.

  • US: Vault is mass-market encryption software. Since BIS's March 2021 rule, a consumer app needs no filing, and published open-source code with standard crypto is released from the rules.
  • France: a "cryptology means" is defined by what it does. An app that encrypts user data is arguably one, whoever wrote the AES. Apple only enforces the declaration for apps that bring their own crypto. Filing with ANSSI (free, by email, 1–2 months) is the only route that fully covers France.

Not encryption: key derivation (scrypt, PBKDF2, HKDF, Argon2), HMAC for OTP codes, and hashing. They're one-way and can't encrypt or decrypt. The US definition of "cryptography for data confidentiality" also excludes authentication and data integrity. scrypt and Argon2 have no Apple implementation, and they can't change anyway (G67).

Decision (Bradley, 2026-09-29)

Move AES-GCM to CryptoKit. Its own benefits:

  • Apple's constant-time, hardware-accelerated AES instead of CryptoSwift's table-based pure Swift.
  • About 0.1 ms per MiB instead of about 30 ms.

It also puts all of Vault's encryption within Apple's OS, so NO is the answer Apple's guidance gives. Record the reasoning in the repo.

Change

  • AESGCMEncryptor and AESGCMDecryptor: use CryptoKit AES.GCM, with the same API, the same 16-byte tags and the same 32-byte IVs. The format is unchanged: CryptoKit handles non-96-bit nonces as the GCM spec does. I checked it against the spec's test case 6 (60-byte IV) and a 32-byte nonce round trip.
  • docs/export-compliance.md: the reasoning above, what counts as encryption in Vault, and the rule that encryption uses CryptoKit. Link it from RELEASE.md and AGENTS.md, and update the design doc's note that items use CryptoSwift.
  • CryptoSwift stays for scrypt, PBKDF2, HKDF, HMAC and SHA. None of them is encryption.

Done when

No test is changed, and every test passes, including the golden fixtures and the backup corpus. That shows the two implementations produce identical results. If any test fails, stop, review, and don't merge.

Sub-issues

0

Linked issues

0

GitHub

0

No branches or pull requests linked.

Comments

1
Bradley

Done in https://github.com/badbundle/vault-app/pull/710 (merged as f1c2bb2a).

  • Code: AESGCMEncryptor and AESGCMDecryptor use CryptoKit's AES.GCM, with the same API, keys, 32-byte IVs and 16-byte tags, and the same errors. The separate empty-message check is gone, since CryptoKit's open verifies an empty message's tag.
  • Docs: docs/export-compliance.md records the reasoning and the rule. AGENTS.md and RELEASE.md link to it, the design doc's CryptoSwift note is updated, and CHANGELOG has a line.
  • Tests:
    • No test file changed: git diff origin/main --name-only shows nothing under Vault/Tests/.
    • make validate passed with 0 failures.
    • The fixtures made with CryptoSwift decrypt with CryptoKit, in both test-plan configurations: EncryptedItemFixtureTests (encrypted note and recovery phrase), BackupCorpusRestoreTests (PDF backups, auto-backup, QR transfer), VaultDecryptorTests and VaultItemDecryptorTests.
    • CryptoEngineTests (85) also passed on macOS.

Build 100014, attached to App Store Connect version 2.0, still has the CryptoSwift code, so a new build is needed before submission.