I’ve been working on the security design for the next version of Firefox Sync, which is the bit that keeps your bookmarks/history/saved-passwords/etc synchronized between Firefoxes on all your various devices. The working title is “PiCL”, which stands for “Profile In the CLoud”. In the coming year, this will be deployed to roughly 500 million Firefox users.
I’m looking for feedback on our design. It involves key-stretching (PBKDF2 and scrypt), secure handling of password-derived keys, SRP, and a healthy distrust of SSL. If you’re interested, read on!
Unlike the previous Sync design, in which a full-strength random key was transferred between paired devices with a J-PAKE-based protocol, PiCL is obligated to use a traditional email+password as account credentials. My task has been to provide as much cryptographic protection of the user’s private data as possible, given that constraint. Our goal is to enable the user to have some data that is not visible to Mozilla (we run the servers) or their email-provider (through which a forgotten password can be reset).
I’m focusing on the portion of the system that gets from email+password to a pair of master keys “kA” and “kB” (described below) and a session token. There are a lot of parts you can ignore for now, like how we use kA/kB to encrypt the user’s data later (we’ll use HKDF to get per-datatype AES/HMAC keys), how BrowserID certificates authorize communication with the storage-server, and how the data actually gets synchronized (efficient delta transfer, resolving merge conflicts, etc).
The protocol is mainly described here:
with some additional background here:
The protocol page might be missing some context, so here’s a summary:
- PICL accounts are defined by an email address and a password
- PICL will encrypt all user data, with per-datatype keys derived from either a “class-A” or a “class-B” master key (kA and kB).
- data in class-A is recoverable, even if you forget your password: you can ask us nicely (via the usual email-based account-reset process) and we’ll tell you kA.
- data is class-B is not recoverable if you forget the password
- we run a “keyserver”, which is used during signin. It knows kA and a wrapped form of kB.
- encrypted data is stored on a “storage server”, and to control it, clients must present a BrowserID assertion, whose certificate is signed by the keyserver. The Session Token gets you these signatures.
My goal is for the confidentiality of the class-B data to be no weaker than the account password, and for this password never be revealed outside the user’s browser. If your password can’t be brute-forced, your data should remain safe, even if our keyserver is compromised. Class-A data should be no weaker than the typical “service-provider sees everything” approach. We also do a lot of key-stretching on the password, to make a brute-force attack as expensive as possible.
It’s supposed to reject all but the following attacks:
- a TLS failure during initial account creation allows the MitM to offline brute-force the user’s password
- anybody can try an online brute-force attack, rate-limited of course
- the keyserver can do an offline brute-force attack
- the IdP (who sees the forgot-password email) can reset the account themselves and learn kA, but not kB
- compromising the browser itself reveals everything, of course
In particular, the storage servers shouldn’t be any better off than a random stranger, to keep the security perimeter small.
Feel free to send comments to me, or drop by the #picl IRC channel on irc.mozilla.org (I’m “warner” on #picl), or send them to the sync-dev mailing list (https://mail.mozilla.org/listinfo/sync-dev). And please forward this to anyone else you think might be interested.