New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use key wrapping to eliminate 15-site limit #38

Closed
darconeous opened this Issue Nov 29, 2016 · 11 comments

Comments

Projects
None yet
3 participants
@darconeous

darconeous commented Nov 29, 2016

While 15-sites is a lot of sites, the limit is frustrating because there is no easy way to manage these keys without erasing all of them. It also isn't clear what happens when you reach this limit (I assume some sort of failure indication?).

Having such a limit is unnecessary if you use key wrapping to store the key inside of the key handle (or use a mechanism similar to what Yubico uses to securely derive the keys from the key handle) instead of storing the keys locally.

@conorpp

This comment has been minimized.

Show comment
Hide comment
@conorpp

conorpp Nov 29, 2016

Owner

Key wrapping is a good idea but I decided against it at the start of the project. The token was designed to be cheap and secure. So it has a secure chip that only does P256 ECC and just enough memory to do U2F and USB HID. So no AES/other secure crypto KDFs can be implemented as the resources are not there. My though was, if a user needs more than 15 registrations, he can afford to get two keys because they are cheap.

Now I see it's caused more frustration than I thought it would. So a new revision that does key wrapping would require a new chip with ~8KB more memory and slightly better throughput.

I currently can't work on another revision. I'd love to hand the project off to someone else that would be interested.

Also relevant: #9

Owner

conorpp commented Nov 29, 2016

Key wrapping is a good idea but I decided against it at the start of the project. The token was designed to be cheap and secure. So it has a secure chip that only does P256 ECC and just enough memory to do U2F and USB HID. So no AES/other secure crypto KDFs can be implemented as the resources are not there. My though was, if a user needs more than 15 registrations, he can afford to get two keys because they are cheap.

Now I see it's caused more frustration than I thought it would. So a new revision that does key wrapping would require a new chip with ~8KB more memory and slightly better throughput.

I currently can't work on another revision. I'd love to hand the project off to someone else that would be interested.

Also relevant: #9

@darconeous

This comment has been minimized.

Show comment
Hide comment
@darconeous

darconeous Nov 30, 2016

For what it's worth, you don't need AES to implement a scheme like what Yubico is using: you just need SHA2, which is provided by your secure element.

darconeous commented Nov 30, 2016

For what it's worth, you don't need AES to implement a scheme like what Yubico is using: you just need SHA2, which is provided by your secure element.

@conorpp

This comment has been minimized.

Show comment
Hide comment
@conorpp

conorpp Nov 30, 2016

Owner

And implement an HMAC to derive key? Good point, there should be enough memory to add that.

Owner

conorpp commented Nov 30, 2016

And implement an HMAC to derive key? Good point, there should be enough memory to add that.

@conorpp

This comment has been minimized.

Show comment
Hide comment
@conorpp

conorpp Jan 28, 2017

Owner

Just added support for this. A 256 bit master secret is stored write-only on the ATECC508 so the security level and isolation should be the same as before. New key pairs are generated based on a sha256 hmac with the 256 bit master key, 32 bit random number, and appid. The 32 bit random number is stored in the keyid along with sha256(private-key + some constants) which acts as a MAC to write a new private key to the ATECC508.

Private keys are written to the ATECC508 are masked with another random secret stored on the USB MCU. This is done so an eavesdropper on the I2C bus cannot see the private key. The ATECC508 supports unmasking it.

If anyone sees any potential issues, please share them here.

Owner

conorpp commented Jan 28, 2017

Just added support for this. A 256 bit master secret is stored write-only on the ATECC508 so the security level and isolation should be the same as before. New key pairs are generated based on a sha256 hmac with the 256 bit master key, 32 bit random number, and appid. The 32 bit random number is stored in the keyid along with sha256(private-key + some constants) which acts as a MAC to write a new private key to the ATECC508.

Private keys are written to the ATECC508 are masked with another random secret stored on the USB MCU. This is done so an eavesdropper on the I2C bus cannot see the private key. The ATECC508 supports unmasking it.

If anyone sees any potential issues, please share them here.

@ad-m

This comment has been minimized.

Show comment
Hide comment
@ad-m

ad-m Feb 2, 2017

Contributor

Well I think that even the master key is not sufficient to make do an identical token?

I make awaraness about TREZOR feature:

When logging into a website, you generally authenticate yourself by providing a user name and a password. With TREZOR and U2F, you will have to additionally confirm the login with a click on your TREZOR device.
Unlike some other tokens, TREZOR always uses a unique signature for each and every user account registered. Additionally, TREZOR brings U2F to a completely new level:

  1. Easy to back up and recover. TREZOR requires you to back up your so-called recovery seed during the initial setup of the device. This is a one-time process for all functions of the device. The recovery seed represents all the secrets (private keys) generated by the device and can be used to restore your hardware wallet at any time.
    (…)
Contributor

ad-m commented Feb 2, 2017

Well I think that even the master key is not sufficient to make do an identical token?

I make awaraness about TREZOR feature:

When logging into a website, you generally authenticate yourself by providing a user name and a password. With TREZOR and U2F, you will have to additionally confirm the login with a click on your TREZOR device.
Unlike some other tokens, TREZOR always uses a unique signature for each and every user account registered. Additionally, TREZOR brings U2F to a completely new level:

  1. Easy to back up and recover. TREZOR requires you to back up your so-called recovery seed during the initial setup of the device. This is a one-time process for all functions of the device. The recovery seed represents all the secrets (private keys) generated by the device and can be used to restore your hardware wallet at any time.
    (…)
@conorpp

This comment has been minimized.

Show comment
Hide comment
@conorpp

conorpp Feb 2, 2017

Owner

@ad-m I'm not sure your point. The master key is only located on the token which means you cannot make an identical token by design. If you are programming on your own, you can choose to keep a copy of the master secret to allow copies to be made.

Allowing a user to change the master secret and make backups should be a separate issue.

Owner

conorpp commented Feb 2, 2017

@ad-m I'm not sure your point. The master key is only located on the token which means you cannot make an identical token by design. If you are programming on your own, you can choose to keep a copy of the master secret to allow copies to be made.

Allowing a user to change the master secret and make backups should be a separate issue.

@ad-m

This comment has been minimized.

Show comment
Hide comment
@ad-m

ad-m Feb 2, 2017

Contributor

@conorpp , thanks for you opinion. I'm not sure all terms, hence my wrong impression. But I try to get to know about it. I might go back to backup issue later in the future, but first I have to know well the source code and U2F implementations details.

Thanks for your works and project development.

Contributor

ad-m commented Feb 2, 2017

@conorpp , thanks for you opinion. I'm not sure all terms, hence my wrong impression. But I try to get to know about it. I might go back to backup issue later in the future, but first I have to know well the source code and U2F implementations details.

Thanks for your works and project development.

@darconeous

This comment has been minimized.

Show comment
Hide comment
@darconeous

darconeous Feb 27, 2017

One thing I was thinking about was using some of the unused key slots for multiple attestation certificate keys---the goal being to further obscure the relationship between registrations on multiple websites with the same token.

Whenever a new service is registered, it would use a different attestation certificate. The first attestation certificate used would be picked at random, and then it would go in a round-robbin.

For each new batch of keys, maybe the two oldest attestation certificates would be retired. This would make it much more ambiguous as to even which batch a key came from.

Ideally we would have a collection of counters as well and we would use a random one for each service. Unfortunately there are only two secure hardware counters...

Anyway, implementing both mechanisms would almost completely eliminate any ability to correlate the token across services.

darconeous commented Feb 27, 2017

One thing I was thinking about was using some of the unused key slots for multiple attestation certificate keys---the goal being to further obscure the relationship between registrations on multiple websites with the same token.

Whenever a new service is registered, it would use a different attestation certificate. The first attestation certificate used would be picked at random, and then it would go in a round-robbin.

For each new batch of keys, maybe the two oldest attestation certificates would be retired. This would make it much more ambiguous as to even which batch a key came from.

Ideally we would have a collection of counters as well and we would use a random one for each service. Unfortunately there are only two secure hardware counters...

Anyway, implementing both mechanisms would almost completely eliminate any ability to correlate the token across services.

@conorpp conorpp closed this Apr 29, 2017

@darconeous

This comment has been minimized.

Show comment
Hide comment
@darconeous

darconeous May 11, 2017

I was having a look at 01e8528.

Unless I'm reading this wrong, I don't seem to see where you are using a nonce in the calculation of the private key. Without a random nonce, using the same key on the same service for different accounts would yield the same key handle! This would make it trivial for a service to determine if two accounts are using the same token.

Could you describe the algorithm you are using for deriving the keys?

darconeous commented May 11, 2017

I was having a look at 01e8528.

Unless I'm reading this wrong, I don't seem to see where you are using a nonce in the calculation of the private key. Without a random nonce, using the same key on the same service for different accounts would yield the same key handle! This would make it trivial for a service to determine if two accounts are using the same token.

Could you describe the algorithm you are using for deriving the keys?

@conorpp

This comment has been minimized.

Show comment
Hide comment
@conorpp

conorpp May 11, 2017

Owner

Key generation can be seen here. It is done using a 256-bit master secret for a sha256 digest that is generated offline during setup/programming of the token. See script and setup-firmware. A 32 bit random number and the appid is also included in the sha256 calculation.

Owner

conorpp commented May 11, 2017

Key generation can be seen here. It is done using a 256-bit master secret for a sha256 digest that is generated offline during setup/programming of the token. See script and setup-firmware. A 32 bit random number and the appid is also included in the sha256 calculation.

@darconeous

This comment has been minimized.

Show comment
Hide comment
@darconeous

darconeous May 17, 2017

Ah, I see. Looks reasonable.

But what's the purpose of RMASK and WMASK? And why is the implementation of u2f_appid_eq() commented out?

EDIT: Nevermind about the RMASK/WMASK bit, I just saw this from above:

Private keys are written to the ATECC508 are masked with another random secret stored on the USB MCU. This is done so an eavesdropper on the I2C bus cannot see the private key. The ATECC508 supports unmasking it.

darconeous commented May 17, 2017

Ah, I see. Looks reasonable.

But what's the purpose of RMASK and WMASK? And why is the implementation of u2f_appid_eq() commented out?

EDIT: Nevermind about the RMASK/WMASK bit, I just saw this from above:

Private keys are written to the ATECC508 are masked with another random secret stored on the USB MCU. This is done so an eavesdropper on the I2C bus cannot see the private key. The ATECC508 supports unmasking it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment