Skip to content

Commit

Permalink
Document key handling and derivation algorithms
Browse files Browse the repository at this point in the history
Fixes #11
  • Loading branch information
szszszsz committed Aug 1, 2018
1 parent 435ed3f commit a35afff
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 0 deletions.
Binary file added doc/keys_usage-configuration.dia
Binary file not shown.
Binary file added doc/keys_usage-configuration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/keys_usage-u2f_authentication.dia
Binary file not shown.
Binary file added doc/keys_usage-u2f_authentication.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/keys_usage-u2f_registration.dia
Binary file not shown.
Binary file added doc/keys_usage-u2f_registration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
117 changes: 117 additions & 0 deletions doc/security_architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# FIDO U2F Security Architecture

This description is reduced to the relevant aspects so that length fields and other fields are not mentioned (indicated with “...”). The complete overview of request and response fields is covered in the official FIDO specifications.
In this document "`||`" symbol means data concatenation.

## Initialization
- Device key (also: device secret) is a 256 bit random value generated during production or first start of the device. The device key must be kept in ATECC508 at all times and not be read out.
- Global use counter is set to zero. It is shared between credentials/applications.
- `rkey` is present only on the MCU. This is a XOR-key for I2C bus encryption on read (modifying data read from ATECC chip).
- `wkey` is created on the host from the SHA-256 hash of the `device_key` number. Similarly to `wkey`, it is present only on the MCU. This is a XOR-key for I2C bus encryption on write (to the ATECC chip).




## Registration

### Registration Request:
- challenge parameter: SHA-256 hash
- application parameter: SHA-256 hash of application identity. This parameter could be also wrongly phrased as AppID, while both are actually different (but related) values.

### Registration calculation:
1. Generate random nonce from RNG
2. `private key := HMAC-SHA256(device key, application parameter || nonce)` - this private key is application-specific
3. `user public key := derive from private key`
4. `MAC := HMAC-SHA256(device key, private key || application parameter)`
5. `Key handle := nonce || MAC`
6. `signature := ecdsa(private key, application parameter || challenge parameter || key handle || user public key || ...)`

### Registration Response:
- A user public key [65 bytes]. This is the (uncompressed) x,y-representation of a curve point on the P-256 NIST elliptic curve.
- key handle: This a handle that allows the U2F token to identify the generated key pair. U2F tokens may wrap the generated private key and the application id it was generated for, and output that as the key handle.
- signature: This is a ECDSA signature (on P-256) over the following byte string:
- The application parameter [32 bytes] from the registration request message.
- The challenge parameter[32 bytes] from the registration request message.
- The above key handle [variable length]. (Note that the key handle length is not included in the signature base string. This doesn't cause confusion in the signature base string, since all other parameters in the signature base string are fixed-length.)
- The above user public key [65 bytes].
- ...

![Registration diagram][register]

## Authentication
### Authentication Request:
- The challenge parameter [32 bytes]. The challenge parameter is the SHA-256 hash of the Client Data, a stringified JSON data structure that the FIDO Client prepares. Among other things, the Client Data contains the challenge from the relying party (hence the name of the parameter). See below for a detailed explanation of Client Data.
- The application parameter [32 bytes]. The application parameter is the SHA-256 hash of the UTF-8 encoding of the application identity of the application requesting the authentication as provided by the relying party.
- A key handle [length specified in previous field]. The key handle. This is provided by the relying party, and was obtained by the relying party during registration. `Key handle = nonce || MAC`
-

### Authentication calculation:
1. `nonce := subtract from key handle`
2. `MAC1 := subtract from key handle`
3. `private key := HMAC-SHA256(device key, application parameter || nonce)` - this is the same calculation as during registration
4. `MAC2 := HMAC-SHA256(device key, private key || application parameter)`
5. `verify: MAC1 == MAC2` - during authentication, the MAC helps to ensure that a key handle is only valid for the particular combination of device and AppID that it was created for during registration
6. `signature := ecdsa(private key, application parameter || challenge parameter || global use counter || ...)`
7. increment global use counter

### Authentication Response:
- A signature. This is a ECDSA signature (on P-256) over the following byte string:
- The application parameter [32 bytes] from the authentication request message.
- The challenge parameter [32 bytes] from the authentication request message.
- ...

![Authentication diagram][auth]


# Key handling
Below is a description of secret keys movement during the device lifecycle.
Internal implementation uses additionally a couple of secret keys, which handle communication between MCU and ATECC chip (`rkey`/`wkey`).

## Certificate and attestation key generation

Certificate and attestation key are generated in this phase and stored on hard drive.

## Configuration / SETUP phase

1. RNG is run on the host to produce three 32-byte random numbers for `device key`, `_wkey` and `_rkey`. The former is the device-specific secret for U2F functionality. The latter two will be used during the device's work for encrypting communication with the ATECC chip on the I2C bus.
2. `device key` is loaded to the ATECC chip unmodified.
3. `_rkey` and `_wkey` are SHA256-hashed with a known constant. The outcomes are target `rkey` and `wkey` respectively, and written to the FINAL firmware (to the `cert.c` file).
4. `wkey` is loaded to the device and kept in the RAM.
5. Attestation key is sent to the device and saved to RAM.
6. A key hash is calculated to authenticate its encrypted write to the ATECC chip.
7. Attestation key is XORed with `wkey` and written to the ATECC chip using previously calculated key hash MAC.


![Keys handling diagram - setup][keys-setup]



## Firmware compilation
During the compilation the attestation certificate and `wkey`/`rkey` constants are included directly into the firmware files as static binary blobs.


## U2F registration / authentication
During both registration and authentication procedures, private keys are generated. These have to be written to the ATECC chip to perform further cryptographic operations. To maintain security, they are XORed with both `wkey` and `rkey` to keep the I2C bus communication encrypted.

### Registration
1. `priv_user_key_rkey := priv_user_key ^ rkey` - a generated private key is XORed with `rkey`.
2. `key_write_auth_mac := sha256(wkey || priv_user_key_rkey || privwrite_const)` - the modified key is used to compute write authentication hash for ATECC chip.
3. `priv_user_key_rkey_wkey := priv_user_key_rkey ^ wkey` - the modified key is once again XORed with `wkey`
4. `privwrite(priv_user_key_rkey_wkey, device_key || key_write_auth_mac)` - private key is saved to the device using previously calculated write hash.
5. `priv_user_key_rkey:= priv_user_key_rkey_wkey ^ wkey` - on ATECC the received data is decrypted with `wkey`, leaving `rkey` mask applied to the sent key.

![Keys handling diagram - registration][keys-registration]

### Authentication
Authentication differs from Registration usage by not computing the write MAC for the ATECC chip, and instead reusing the `key_handle`, which contains the computed on registration value.

![Keys handling diagram - authentication][keys-authentication]




[register]: u2f-registration.png "U2F Registeration"
[auth]: u2f-authentication.png "U2F Authorization"
[keys-setup]: keys_usage-configuration.png "Keys handling diagram - setup"
[keys-registration]: keys_usage-u2f_registration.png "Keys handling diagram - registration"
[keys-authentication]: keys_usage-u2f_authentication.png "Keys handling diagram - authentication"
Binary file added doc/u2f-authentication.dia
Binary file not shown.
Binary file added doc/u2f-authentication.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/u2f-registration.dia
Binary file not shown.
Binary file added doc/u2f-registration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a35afff

Please sign in to comment.