webauthn icon indicating copy to clipboard operation
webauthn copied to clipboard

Authenticator flag to indicate internal knowledge of rk (discoverable credential creation).

Open Firstyear opened this issue 2 years ago • 31 comments

Suggestion: That in https://w3c.github.io/webauthn/#sctn-authenticator-data RFU2 or RFU1 is used to represent an authenticators internal knowledge of if it created a key internal only to the secure element. This flag would be 0 for "the authenticator may or may not have created an SE key, and you should consult other knowledge sources". 1 would represent "the authenticator internally guarantees it created an SE key".

Why: This is important is in high security and certified deployments, where absolute knowledge of the storage of the private key is required in a tamper resistant and attested signal. It is important for security teams to allow them to make decisions about their environment and possible risks. This also helps deployments where BYOD or other risk factors may be fed into risk analytics.

Compatibility: This would not be a "breaking" change since the property of the flag currently as 0 is "status quo", and devices in the future can indicate that flag set to "1" to provide a stricter assurance about the storage of the private key. In addition this positively coordinates with the backup state flags allowing an RP to distinguish a passkey that is in a secure enclave vs a passkey that is a soft token or similar (such as a password manager). This would assist in threat modelling and risk assessment for RPs.

Alternates: Currently as an RP there is no signed proof of secure enclave key status during registration. The current signals we can use are to provide a discoverable authentication (empty allowed credentials) or to request the credProps extension. However, both have limitations. Discoverability to the client is not the same property as the key being inside a secure element and bound inside hardware. A client could theoretically populate allowedCredentials with key-wrapped-keys during an authentication which would satisfy client side discovery, but is not proof of the key being inside a secure element. credProps as a client extension, may be altered by client side javascript, which may or may not undermine the RP's intent to have a resident key that is client side discoverable AND part of a secure element created. credProps is a good signal for a user experience guide that discoverability should work, but it's not a security property that is asserted.

This allows for a "hierachy" of signals where:

  • The Secure Element flag is the strongest guarantee that a key is both resident/discoverable and only known to the internals of this secure device.
  • That crepProps is a weak assurance that the client can proceed with discoverable workflows, but the storage of the key may be key-wrapped or another form of storage on the client
  • Neither of these indicates that you likely need to provide the credential ID as it is a key-wrapped-key that the client requires for future ceremonies.

Firstyear avatar Jul 05 '22 03:07 Firstyear

This issue has been discussed before (#1060). But, it seems better to revisit this issue since the market changes to leverage the RK for the passkey implementation.

Kieun avatar Jul 05 '22 03:07 Kieun

Resident doesn’t mean hardware bound. They are different properties.

At the CTAP layer the resident true flag requires the authenticator to make a discoverable credential (one that can be used without an allow list).

A security key could easily make non discoverable credentials roaming. Just because Google may choose to make non discoverable credentials hardware bound we should not confuse the issue by making that part of the spec.

We all ready have a bit flag for backupable which is not hardware bound.

That is set to 1 if the credential can be backed up. How is that different from the flag you are looking for?

No flags can be trusted without an attestation, but that is a separate issue.

ve7jtb avatar Jul 05 '22 04:07 ve7jtb

Such deployments already use certified hardware (e.g. CC EAL) and filters security keys using attestation, AAGUID and MDS.

serianox avatar Jul 05 '22 07:07 serianox

This change would be beneficial for a RP from the debugging / troubleshooting / auditing perspective. Sometimes the client (JS) portion of the RP code is tweaked by the customer, so the server side has wrong assumptions about the discoverability of the credentials. Knowing that the credential was created as discoverable, or not, would simplify troubleshooting in some cases, and potentially raise alerts on the server side if the behaviour is inconsistent with the server side code.

ndpar avatar Jul 05 '22 18:07 ndpar

We already have credprops https://www.w3.org/TR/webauthn-2/#sctn-authenticator-credential-properties-extension

That tells an interested RP if the credential was created with option RK true.

Authenticators should not make discoverable credentials if option rk is not true. They may make credentials like Android that have refrence credentialID and store the keys locally rather than wrapp them in the credentialID, however that is an implementation detail not relevant to the RP.

If you want to know if the credential is discoverable look at credprops. If you want to know if the credential is hardware bound or backupable then look at the BE flag in authenticator data https://w3c.github.io/webauthn/#sctn-credential-backup

I am trying to understand what is new here?

ve7jtb avatar Jul 05 '22 20:07 ve7jtb

Thanks John, credProps is what I need. I wonder if Safari supports it.

ndpar avatar Jul 05 '22 20:07 ndpar

Apple should support it as part of level 2. The question is when they will release the level 2 API update.

ve7jtb avatar Jul 05 '22 20:07 ve7jtb

We already have credprops https://www.w3.org/TR/webauthn-2/#sctn-authenticator-credential-properties-extension

But isn't the issue with client extensions like credProps is that it's not part of any signed value, so strictly speaking it can't be trusted? I feel like that's a common refrain when talking about these kinds of extensions that aren't in authenticatorData.

Edit: Which is exactly what @Firstyear mentioned in the OP 🤦‍♂️

And credProps as a client extension, may be altered by client side javascript, which may or may not undermine the RP's intent to have an RK created.

MasterKale avatar Jul 05 '22 21:07 MasterKale

@Firstyear seems to be confusing 2 things in the OP. 1 is the credential hardware bound. That is in the current L3 draft returned as part of the signed authenticator data. 2. is the credential discoverable. That is returned unsigned by the client. The question is what attack is there other than the user messing up their own UX by tampering with it? If the platform reports that it is discoverable in credprops and it is not then the credential won't work in flows without an allow list. If the client lies the other way and says it is not discoverable then perhaps the UX will be worse but it will still work in second factor flows even though it is discoverable.

The downside to putting a flag in authenticator data is that it won't be supported by current authenticators.

We could come up with another way to do credprops, but someone needs to articulate a good reason why having it unsigned by the authenticator is a security risk. I just don't see that for the discoverable flag.

ve7jtb avatar Jul 05 '22 22:07 ve7jtb

Since apparently I have confused everyone, with the highly confusing language of "resident key" I have rewritten the issue to be clearer.

Firstyear avatar Jul 06 '22 00:07 Firstyear

I believe @ve7jtb's assessment is still accurate. The new BE flag in L3 signals whether the credential is hardware-bound to the secure element (when combined with an appropriate attestation). It does not differentiate whether the private key storage is internal or wrapped external (i.e., encoded into the credential ID), but those two should not be considered different in terms of security strength.

Although the definition of backup eligibility and a single-device credential doesn't currently specify that single-device credentials should be hardware-bound to a secure element if the authenticator has one. Perhaps we should explicitly state this expectation in the definition.

emlun avatar Jul 06 '22 15:07 emlun

The new BE flag in L3 signals whether the credential is hardware-bound to the secure element (when combined with an appropriate attestation).

I disagree with this statement. The BE flag means that the key is allowed to be backed up. It does not make any statements about the storage of the key or its security properties.

As mentioned in the original PR comments, these bits are designed to drive business logic and user experiences, not convey authenticator security properties.

timcappalli avatar Jul 06 '22 19:07 timcappalli

Can you provide me with a reference for a specification that doesn't allow wrapped keys?

I know of implementations where Discoverable keys are wrapped by the SE and stored on external unsecured flash.

This should perhaps be taken up with the Fido SPWG as a certification issue. I don't think a simple flag without certification can solve this, if wrapping is not allowed for some reason.

I haven't seen this with NIST AAL3 or FIPS 140.

This would potentially cause fragmentation if exposed to RP so we need to understand the use case.

At the moment there are almost no authenticators certified above Fido L1 software storage, and only a handful FIPS or cc certified.

Yubico's first Fips 140-2 general 2 physical 3 authenticator the YK4 FIPS was U2F (wrapped) only and is used at AAL3.

Wrapping done properly in a certified device is no less secure than keeping the keys on the secure element.
True someone could do a crap job of wrapping but a weak random number generator is probably a much larger concern. All of that should be covered in certification.

ve7jtb avatar Jul 06 '22 19:07 ve7jtb

@timcappalli sorry if I was impercise. The attestation provides a lookup to MDS metadata that states the keystorrage properties of credentials that are returned with BE 0.

If BE is 1 then the key storage is effectively unknown.

In the BE 0 case, the credential may be wrapped by a key stored in the SE and encrypted into the credentialID with a key of equal or greater strength than the signing key for certified authenticators. Authenticators using TPM like Windows or other small secure elements may also wrap credentials and store them on disk with appropriate encryotion as long as the wrapping key itself is in secure storage.

Unless the RP knows the exact architecture of the authenticator no flag like that can tell you if the key is stored wrapped at some point on some external storage. It is more complicated than just if it is in the credentilsID.

ve7jtb avatar Jul 06 '22 19:07 ve7jtb

The new BE flag in L3 signals whether the credential is hardware-bound to the secure element (when combined with an appropriate attestation).

I disagree with this statement. The BE flag means that the key is allowed to be backed up. It does not make any statements about the storage of the key or its security properties.

As mentioned in the original PR comments, these bits are designed to drive business logic and user experiences, not convey authenticator security properties.

Yep, agreed. This would be an extra bit field that gives an extended property about the storage of the key. When combined with the BE flags, it allows an RP to understand quite a lot about the authenticators properties above and beyond the MDS "descriptions".

Firstyear avatar Jul 07 '22 00:07 Firstyear

@emlun Also suggested offline that in addition to this, we should have better resources to educate about the threats/risks of how key wrapped keys work to help people make valid assertions about threats (because key wrapped keys are indeed secure).

Firstyear avatar Jul 07 '22 00:07 Firstyear

I didn't suggest in addition to this, I suggested instead of this. I think we should not entertain the misconception that wrapped keys are less secure than resident keys.

emlun avatar Jul 13 '22 19:07 emlun

Okay, I agree @emlun. Lets improve that education then. Where would be the best place to target that?

Firstyear avatar Jul 13 '22 23:07 Firstyear

I don't know, to be honest, but I'm pretty sure it's not this spec. That seems to be about a better understanding of cryptography in general, rather than any particular application of it.

emlun avatar Jul 15 '22 10:07 emlun

Broad stroke reaction: attestation of particular storage and secure element binding of a key would be better as part of an attestation, and better still indirectly through lookup based on attestations.

The BE flag exists because it is a user experience flag that makes sense for non-attested data. The BS flag exists because it varies per response and not based on authenticator make/model.

The case for additional flags or extensions to report on key protections would be if an authenticator actually made this dynamic - say if a vendor created a single platform authenticator that made it a user decision or policy decision whether the credential is bound to hardware - and used the same aaguid and same attestation in both cases rather than representing these different policies as multiple distinct platform authenticators.

dwaite avatar Jul 15 '22 18:07 dwaite

Broad stroke reaction: attestation of particular storage and secure element binding of a key would be better as part of an attestation, and better still indirectly through lookup based on attestations.

The BE flag exists because it is a user experience flag that makes sense for non-attested data. The BS flag exists because it varies per response and not based on authenticator make/model.

The case for additional flags or extensions to report on key protections would be if an authenticator actually made this dynamic - say if a vendor created a single platform authenticator that made it a user decision or policy decision whether the credential is bound to hardware - and used the same aaguid and same attestation in both cases rather than representing these different policies as multiple distinct platform authenticators.

But today an authenticator does use the same aaguid for an attested credential regardless of it's rk state or not. So you can't really use attestation for this purpose. That's why I suggested this signed boolean flag.

Firstyear avatar Jul 17 '22 23:07 Firstyear

But today an authenticator does use the same aaguid for an attested credential regardless of it's rk state or not. So you can't really use attestation for this purpose. That's why I suggested this signed boolean flag.

Are you talking about (the now misnamed) resident key as a state used to convey a desire for discoverable credential behavior?

Or are you talking about a security property to know that a private key is held by a Secure Enclave and is not exportable?

dwaite avatar Jul 18 '22 03:07 dwaite

The latter.

Firstyear avatar Jul 18 '22 04:07 Firstyear

Could a possible reason for this to exist be that currently when a platform requests a rk to be created, the current credprops extension only is true if the browser thinks it asked for an rk to be created. But that doesn't mean that the authenticator "really did" make an rk. So it means that credprops in the case of a "weird authenticator" is unreliable even from a user-interaction hint perspective.

Some protos like CTAP2.1 enforce that if rk was sent from the browser to the device it MUST create an rk or error ( https://fidoalliance.org/specs/fido-v2.1-rd-20210309/fido-client-to-authenticator-protocol-v2.1-rd-20210309.html#op-makecred-step-rk ) but this may not be necesarily be true for all classes of authenticators. @emlun

Firstyear avatar Jul 19 '22 07:07 Firstyear

Can you provide me with a reference for a specification that doesn't allow wrapped keys?

I know of implementations where Discoverable keys are wrapped by the SE and stored on external unsecured flash.

This should perhaps be taken up with the Fido SPWG as a certification issue. I don't think a simple flag without certification can solve this, if wrapping is not allowed for some reason.

I haven't seen this with NIST AAL3 or FIPS 140.

This would potentially cause fragmentation if exposed to RP so we need to understand the use case.

At the moment there are almost no authenticators certified above Fido L1 software storage, and only a handful FIPS or cc certified.

Yubico's first Fips 140-2 general 2 physical 3 authenticator the YK4 FIPS was U2F (wrapped) only and is used at AAL3.

Wrapping done properly in a certified device is no less secure than keeping the keys on the secure element. True someone could do a crap job of wrapping but a weak random number generator is probably a much larger concern. All of that should be covered in certification.

To complement @ve7jtb 's answer,

Current Protection Profile for FIDO devices (and possibly future 😉) require the key not to be wrapped, see BSI-PP-CC-0096-V3-2018. The fact that the key is hardware bound in a Secure Element is a property of any L3/L3+ (EAL4+, AVA_VAN.5) FIDO device.

All in all, this is covered by the certification, and is the reason why we have device attestation in the first place.

serianox avatar Jul 19 '22 09:07 serianox

From the BSI PP.

During authentication, the authenticator receives (via the user device) the AppID, the previously registered key handle as well as a challenge. The authenticator verifies the message authentication code and thus checks whether the supplied key handle contains a nonce generated by the authenticator that fits to the supplied AppID. After successful verification, the KDF is activated with the seed together with the AppID and nonce to re-generate the private key

The PP is one implementation choice including a nonce in the credentialID and integrity protecting the credentialID then running the KDF again for each signature vs randomly generating the key and encrypting using AAD (eg AES GCM) the result with a key derived from the RPID and seed maintained inside the secure element. Certifications at AAL3 don't require the BSI profile, however, that is the profile that was used for the one AAL3+ certified key as I understand it. The profile reflects the device it was written for.

In both cases, the protection of the seed is the issue. If CC somewhere expresses a preference for one approach over the other that would be news to me. The Fido security requirements don't make that distinction.

For a number of reasons including FIPS certification Yubikeys take the latter approach, though older keys did use the BSI approach.

The finer points of this are really a topic for the SPWG.

To @serianox point RP concerned about this should be looking at the AAGUID and the certification level of the authenticator. Untill you get to AAL3 this flag really makes no difference and after that, the AAL3 certification should be enough assurance independent of if the credential is discoverable or not.

ve7jtb avatar Jul 19 '22 22:07 ve7jtb

@emlun An extra reason to follow my previous comment, is for the RP if the authenticator sends an unsolicited discoverable credential, this wouldn't be indicated in credProps, so having the authenticator actually signal it's internal knowledge of discoverability would really make it "crystal clear" if discoverable is possible or not. credprops is a very weak signal the more I think about it

Firstyear avatar Jul 20 '22 00:07 Firstyear

Some protos like CTAP2.1 enforce that if rk was sent from the browser to the device it MUST create an rk or error ( https://fidoalliance.org/specs/fido-v2.1-rd-20210309/fido-client-to-authenticator-protocol-v2.1-rd-20210309.html#op-makecred-step-rk ) but this may not be necesarily be true for all classes of authenticators. @emlun

Since ctap2.1 spec has addressed it, RP could use attestation on this part for different types of authenticators.

  • ctap2.0 authenticators, the credential is discoverable or not may be different to the parameter or credProps.
  • ctap2.1 authenticators, the credential's type is equal to this in credProps.
  • Else (un-attestable authenticators), no authenticator flags could be trusted even specs add this flag finally.

My points are,

  • The flag from "weird ctap2.1 authenticator" may be still wrong. It should be another topics that how to address wrong behaviors from certified and attestable authenticators.
  • Add a new authenticator flag definition into ctap2.2/2.3 specs to address an optional behavior of ctap2.0 authenticator is weird too.

nuno0529 avatar Jul 20 '22 03:07 nuno0529

Some protos like CTAP2.1 enforce that if rk was sent from the browser to the device it MUST create an rk or error ( https://fidoalliance.org/specs/fido-v2.1-rd-20210309/fido-client-to-authenticator-protocol-v2.1-rd-20210309.html#op-makecred-step-rk ) but this may not be necesarily be true for all classes of authenticators. @emlun

Since ctap2.1 spec has addressed it, RP could use attestation on this part for different types of authenticators.

  • ctap2.0 authenticators, the credential is discoverable or not may be different to the parameter or credProps.
  • ctap2.1 authenticators, the credential's type is equal to this in credProps.
  • Else (un-attestable authenticators), no authenticator flags could be trusted even specs add this flag finally.

My points are,

  • The flag from "weird ctap2.1 authenticator" may be still wrong. It should be another topics that how to address wrong behaviors from certified and attestable authenticators.
  • Add a new authenticator flag definition into ctap2.2/2.3 specs to address an optional behavior of ctap2.0 authenticator is weird too.

well, for a long time the apple touch id was attested by apple but didn't ever flag in credProps that it was sending a resident key 🙃

Additionally, this DOES have use with passkeys, where the use can "use whatever authenticator they feel like" because you CAN NOT require attestation with these (beacuse it breaks apple devices) but you may want to know if a resident key was created. Having a way for the authenticator to tell us internally if it probably created an rk (attested or not) is useful because credProps doesn't cover the scenario when an rk is made without being requested.

Firstyear avatar Jul 20 '22 03:07 Firstyear

To expand on this to make it a bit clearer. Apple's Passkeys will not register if you request attestation conveyance direct/indirect. As a result, when people go to use Passkeys, you can't request any kind of attestation at all, meaning you have no indication about the type of device used as a passkey.

Now, passkeys when you combine with conditional ui allow a discoverable workflow. As an RP we need to know if the credential that was registered can work with a discoverable workflow.

Now, we can use credProps, but that only reflects if the browser thinks it requested a resident key. As a result, when we use this with a TPM or an Apple Passkey it's likely to indicate 'false' for resident key status (pretty sure Safari has not supported credProps for ages anyway ...).

We also can't set require_resident_key in the creation request, because then users of things like yubikeys will quickly hit the storage limits of their devices. Nitrokeys have a limit of 8 rk slots I think, modern yubikeys have about 20 or so, but looking at my password manager I have more than 120 passwords saved, so this won't scale.

So we need a way to know "when did the authenticator give us a resident key, without the RP or Browser asking for it, or having knowledge that an RK was created". CredProps doesn't work here because the browser might not know what the authenticator did. We can't use attestation because Apple's Passkeys completely block attestation from being requested at all. So there really isn't a "reliable signal" today of discoverable status, so having the authenticator internally indicate this in the future could really help.

Firstyear avatar Jul 20 '22 04:07 Firstyear