Counter not incrementing on first authenticate operation after initial registration
Closed this issue · 7 comments
I have implemented a relying party that performs validation of U2F register and authentication responses. One of these checks is to ensure the counter is incrementing. I know that a softkey cannot be trusted from a cloning/attestation point of view, but is there any reason it can't maintain a local counter from a given machine and increment it? At the moment it always returns 0.
What version are you using? Some of the Apple Keychain APIs affecting SoftU2F counters were broken, but this was fixed in #49. The counter should work as of v0.0.16. Also, can you check whether the counter is incrementing when using Soft U2F against https://demo.yubico.com/u2f?
Thanks for getting back to me. Very odd, but the counter is incrementing now. I'm wondering if the problem was with the very first use of the Soft U2F key against my site following the very first registration. That's the only time I saw the issue (then I coded some stuff to work around it on the server). The server counter was zero (following registration), and the first use for authenticate presented a counter of zero as well (which I reported as an error). Now the counter is much higher.
Is there a way to reset the local counter to zero so I can try bootstrapping the entire test case again to see if the issue is just on first use?
You can delete the counter from the keychain with
security delete-generic-password -a "counter" -s "Soft U2F"
You can delete all your U2F registrations from the keychain with
/Applications/SoftU2F.app/Contents/MacOS/SoftU2F --delete-all
Edit: The counter is shared between registrations, so deleting that may mess with any sites you've registered with.
Thanks - I used the first technique, and I was able to reproduce the issue. The first time I use the Soft U2F registration in a U2F authenticate flow, it returns a counter value of zero when I believe it should be 1.
As a result, I've updated the title of the issue. It should be fairly easy to reproduce.
Other keys (like Yubikeys) don't have this behaviour.
I think the behavior matches what is described in the spec (emphasis mine):
A U2F token must increase a counter each time it performs an authentication operation. This counter may be 'global' (i.e., the same counter is incremented regardless of the application parameter in Authentication Request message), or per-application (i.e., one counter for each value of application parameter in the Authentication Request message).
U2F token counters should start at 0.
I respectfully disagree with the interpretation. The counter does start at zero - that happens during registration, before the first authenticate operation. The question is whether or not the counter should be incremented and then returned as part of the operation, or incremented after the response is returned. I am suggesting the former; you the latter. All the hardware U2F tokens I've ever used (about 6, from multiple different vendors, even from brand new) return the newly incremented value - I have never seen an authenticate operation return a counter of 0 until SoftU2F.
The reference implementation (which I'm not saying is perfect) here:
https://github.com/google/u2f-ref-code/blob/master/u2f-ref-code/java/src/com/google/u2f/server/impl/U2FServerReferenceImpl.java
on lines 266-268 has:
if (counter <= securityKeyData.getCounter()) {
throw new U2FException("Counter value smaller than expected!");
}
To the best of my understanding, without running that server, this would fail with SoftU2F on first use.
Ironically, webauthn has specific guidance which would work with a counter of zero on first authenticate. See https://w3c.github.io/webauthn/#verifying-assertion step 17. I cannot find this level of guidance anywhere in U2F specifications.
SoftU2F passed the FIDO conformance tests. The counter starting at zero didn't cause issues during that process, so I'm inclined to think that it isn't worth changing. I'm going to close this issue, but feel free to continue discussing the issue if you would like.