4 ms·
> The ATECC508A is not used correctly. It is used as a RNG and for it's crypto functions, but not for key storage. Where did you get that idea from? Preparing
by dimonomid 8y ago
> The ATECC508A is not used correctly. It is used as a RNG and for it's crypto functions, but not for key storage.
Where did you get that idea from? Preparing a device consists of the following steps:
- Flash temporary configuration firmware
- Send keys to the device, which are stored on ATECC508A
- Flash actual u2f-zero firmware
So on the second step (configuring the device), the host writes keys on the device, and those keys are stored on ATECC508A. It happens there: https://github.com/conorpp/u2f-zero/blob/master/firmware/src/atecc508a.c#L568 https://github.com/conorpp/u2f-zero/blob/master/firmware/src...
I do agree that the code is bad though, but alas. I did consider reimplementing it properly, also on a more powerful chip, but I don't think I'll be able to find time for that.
Anyway, dirty code doesn't mean that the device is insecure. From what I see, among other things, ATECC508A is used properly.
- jiveturkey 8y ago> From what I see, among other things, ATECC508A is used properly. You have completely misread/misanalyzed it. It's used only as a "hardware library" to avoid implementing ECDSA. Or perhaps you don't understand U2F well enough? I can't understand why you are downvoted. It's a valid (albeit wrong) contributing comment.
- dimonomid 8y agoI'd actually appreciate if you could elaborate on this. Which features of ATECC508A are not used, but should be used to make the whole thing more secure?
- jiveturkey 8y agoFirst, note that on your own site, the description of key generation is wrong. That's not how "U2F works", that's how a particular implementation derives keys. U2F tokens are free to create keys any way they like; it's opaque to the RP. Most critically for u2fzero, the MCU sees the enrollment key. On enrollment, a new key is derived, and the nonce used in derivation is sent to the site as the key handle. On use, the key is re-derived from the returned nonce, given to the MCU, then loaded into the ATECC508A, then the "secure counter" is read and a signature generated. I haven't looked in detail at RMASK vs WMASK but it smells like they are not useful. In the yubikey, the entirety of this code is implemented inside the secure element. In the u2fzero, except for the actual signature itself, the important parts of this code are executed outside of the secure area. The security of the key derivation is good because it prevents one-time access to the device from compromising future enrollments, but for the use case you propose (lost token) it isn't secure since the strongly-generated already-enrolled key is revealed. A simplistic correction would be to limit the privacy preserving aspect of U2F to 16 sites (the key slot limit on the ATECC508A). This is a fine compromise since there are only 11 sites that accept U2F, per https://www.dongleauth.info/dongles/ https://www.dongleauth.info/dongles/ . On the 17th reg, u2fzero can refuse to register, or it can cycle back to the 1st key, or it can keep reusing the 16th key, or it can regenerate (and thus unenroll) a key, or other choice. Rather than a wrapped key, or nonce, or other data for key regeneration, the handle returned to the site is just a key slot index. In this way, the key is generated by and never leaves the ATECC508A. So, if you're following along, you now realize that this defeats your backup methodology, since the keys would not be wrapped and passed back and forth between site and token. You could pre-generate all the 16 keys outside of the device and program 2 of them identically. Or you could use the ATECC508A internal DeriveKey command. This can use just the appid as nonce and doesn't need an actual random nonce. This doesn't limit the number of sites that can be registered and also allows duplicates (by programming the same master key into all equivalent devices, along with a starting counter value). The handle in this case can just be a static token-id. If you wanted multiple users to actually register different keys using the same token, then you should add a random nonce. This prevents a site from identifying 2 users sharing a token, and learning something about their relationship. Or a site from identifying 1 user with multiple accounts. But the nonce isn't a security aspect per se, just privacy. Regardless, your desired use case cannot be met "securely" with the ATECC508A, because the counter is not secure. Anyone with access to the lost primary token can just set whatever counter they like. This is mitigated by the token being a 2nd factor. I would further mitigate it by burning the JTAG fuse, and potting the ATECC508A. Then the MCU can't be reflashed or read out, and the ATECC508A can't simply be popped off trivially and put on a new custom board. If you mix a partial static data from the MCU, along with random nonce, as part of key derivation, then the MCU and ATECC508A pair are married and you have to depot both of them and now the attack is hard enough (beyond amateur hour) that you should have plenty of time to enroll a new token. Let me just also laugh at the u2fzero site: "It is implemented securely."
- dimonomid 8y agoFirst, I agree that there certainly are ways to do that more secure, like generate keys on-chip so that nobody knows them, but as I mentioned, together with security we have to think about a good recovery plan, otherwise one has to come up with some back-way which compromises this (good) security. And I still believe that having a second U2F token easily accessible at my home is way less secure than even the current implementation of u2f-zero with the backups as explained. It's all about tradeoffs. Second, it looks like you're assuming that it's easy to just pick the MCU and read the code programmed into it. From my past embedded experience I know that e.g. MCUs by Microchip have read-protection bits in their config, so that if it's programmed with those bits set, one can't just read out the hex. Not saying it's totally impossible, but it takes considerable amount of time. This is the part of datasheet for e.g. PIC32: > 27.2 Device Code Protection > The PIC32MX Family features a single device code protection bit, CP that when programmed = 0, protects boot Flash and program Flash from being read or modified by an external programming device. When code protection is enabled, only the Device ID registers is available to be read by an external programmer. Boot Flash and program Flash memory are not protected from self-programming during program execution when code protection is enabled. HOWEVER, that said, after briefly looking at the u2f-zero's MCU datasheet (https://www.silabs.com/documents/public/data-sheets/efm8ub1-datasheet.pdf https://www.silabs.com/documents/public/data-sheets/efm8ub1-...), I failed to find any mention of read-protection, which does seem strange to me. Need to figure out more before I can say for sure. But nevertheless: suppose I get some time and reimplement something like u2f-zero but on the MCU which does have code protection, e.g. PIC32. Does it address your concerns?
- jiveturkey 8y ago> way less secure First you argue that the device is secure. When I point out that it is not, you switch tack to argue that when you take other factors into account, it's still "better" than doing it some other way because of some other factor, so overall security is good. You also want to conveniently forget aspects of your original argument at your blog, such as the defect with OTP that a phone can be stolen. A phone is much, much, much more secure than u2fzero. You're also insisting that your particular use case for needing a backup is the only and best use case. If you want to design a system for your individual desire and needs, that's great, but this doesn't generalize. I'm guessing most people will not want their device baseline to be insecure so that they can have a 2nd insecure backup at hand. As I hinted, the best solution is likely a cloud based token. This can be simulated with u2fzero by using a method similar to what @ecesena proposed. With either knowledge of an authorized external transport key, or by sharing a transport key, the atecc508a can share key material securely. I won't work out the details here, but basically you just need a single initialization-time secret that you store in the cloud. With that, you can take an arbitrary fresh unprogrammed u2fzero and initialize it to look like the one you lost. It has to be done this way (at user's direct control) because if you buy u2fzero's pre-programmed all security is lost. The secret blob can be stored on your [secure] phone and backed up in a safe on a piece of paper, or any other storage scheme which a particular user may require to meet their needs. Personally, I would store it in icloud. or if you used publickey, closer to @ecesena's proposal, you don't need to keep a secret. (at the expense of having to prepare the backup devices ahead of time.)