Merge branch 'master' into eac

This commit is contained in:
Pol Henarejos
2022-04-07 18:18:50 +02:00
3 changed files with 253 additions and 5 deletions

View File

@@ -6,7 +6,7 @@ This is a project to create a Hardware Security Module (HSM) with a Raspberry Pi
- RSA key generation from 1024 to 4096 bits.
- ECDSA key generation from 192 to 521 bits.
- ECC curves secp192r1, secp256r1, secp384r1, secp521r1, brainpoolP256r1, brainpoolP384r1, brainpoolP512r1, secp192k1 (insecure), secp256k1.
- SHA1, SHA224, SHA256, SHA384, SHA256 digests.
- SHA1, SHA224, SHA256, SHA384, SHA512 digests.
- RSA-PSS, RSA-PKCS and raw RSA signature.
- ECDSA raw and hash signature.
- ECDH key derivation.
@@ -25,6 +25,9 @@ This is a project to create a Hardware Security Module (HSM) with a Raspberry Pi
- Extended APDU support.
- Private keys and certificates import from WKY or PKCS#12 files.[^2][^3]
- Transport PIN for provisioning and forcing to set a new PIN.[^2]
- Press-to-confirm button optional feature to authorize operations with private/secret keys.
- Store and retrieve binary data.
- Real time clock with external datetime setting and getting.
[^1]: PKCS11 modules (`pkcs11-tool` and `sc-tool`) do not support CMAC and key derivation. It must be processed through raw APDU command (`opensc-tool -s`).
[^2]: Available via SCS3 tool. See [SCS3](/doc/rsa_4096.md "SCS3") for more information.
@@ -86,15 +89,57 @@ For AES key generation, encryption and decryption, check [doc/aes.md](/doc/aes.m
For 4096 bits RSA support, check [doc/rsa_4096_support.md](/doc/rsa_4096.md).
## Key generation time
Generating EC keys is almost instant. RSA keypair generation takes some time, specially for `2048` and `4096` bits.
For storing and retrieving arbitrary data, check [doc/store_data.md](/doc/store_data.md).
For extra options, such as set/get real datetime or enable/disable press-to-confirm button, check [doc/extra_command.md](/doc/extra_command.md).
## Operation time
### Keypair generation
Generating EC keys is almost instant. RSA keypair generation takes some time, specially for `3072` and `4096` bits.
| RSA key length (bits) | Average time (seconds) |
| :---: | :---: |
| 1024 | 16 |
| 2048 | 124 |
| 3072 | N/A |
| 4096 | N/A |
| 3072 | 600 |
| 4096 | ~1000 |
### Signature and decrypt
| RSA key length (bits) | Average time (seconds) |
| :---: | :---: |
| 1024 | 1 |
| 2048 | 3 |
| 3072 | 7 |
| 4096 | 15 |
## Press-to-confirm button
Raspberry Pico comes with the BOOTSEL button to load the firmware. When this firmware is running, the button can be used for other purposes. Pico HSM uses this button to confirm private/secret operations. This feature is optional and it shall be enabled. For more information, see [doc/extra_command.md](/doc/extra_command.md).
With this feature enabled, everytime that a private/secret key is loaded, the Pico HSM awaits for the user confirmation by pressing the BOOTSEL button. The Led of the Pico HSM will remain almost illuminated, turning off quickly once a second, indicating that the user must press the button to confirm the operation. Otherwise, the Pico HSM waits indefinitely. See [Led blink](#press-to-confirm) for a picture of the blinking sequence. When in this mode, the Pico HSM sends periodic timeout commands to the host to do not trigger the timeout operation.
This feature is an extra layer of security, as it requires the user intervention to sign or decrypt and it ensures that any application will use the Pico HSM without user awareness. However, it is not recommended for servers or other environments where operations are authomatized, since it requires a physical access to the Pico HSM to push the button.
## Led blink
Pico HSM uses the led to indicate the current status. Four states are available:
### Press to confirm
The Led is almost on all the time. It goes off for 100 miliseconds every second.
![Press to confirm](https://user-images.githubusercontent.com/55573252/162008917-6a730eac-396c-44cc-890e-802294be30a3.gif)
### Idle mode
In idle mode, the Pico HSM goes to sleep. It waits for a command and it is awaken by the driver. The Led is almost off all the time. It goes on for 500 milliseconds every second.
![Idle mode](https://user-images.githubusercontent.com/55573252/162008980-d5a5caad-072e-400c-98e3-2c606b4b2af9.gif)
### Active mode
In active mode, the Pico HSM is awaken and ready to receive a command. It blinks four times in a second.
![Active](https://user-images.githubusercontent.com/55573252/162008997-1ea8cd7e-5384-4893-9dcb-b473153fc375.gif)
### Processing
While processing, the Pico HSM is busy and cannot receive additional commands until the current is processed. In this state, the Led blinks 20 times in a second.
![Processing](https://user-images.githubusercontent.com/55573252/162009007-df45111e-2473-4a92-97c5-15c3cd19babd.gif)
## Driver

86
doc/extra_command.md Normal file
View File

@@ -0,0 +1,86 @@
# Extra command
Pico HSM supports a customized extra command to use with different options. Since the drivers in the market do not support the following features, a raw APDU command shall be sent.
To send a raw APDU command, `opensc-tool -s <APDU>` can be used. The `APDU` parameter is a string of hexadecimal numbers and it takes the following form:
```
8088XX00YYZZZZRR
```
It composed by the following fields:
- `80` to indicate that it is a custom vendor type command.
- `88` is the `INS` custom command.
- `XX` is the command to execute. It varies depending on the targeted command.
- `00` is the parameter of the command. At this moment, no commands support parameters.
- `YY` is the length of the data. If no data is provided, this field is absent.
- `ZZZZ` is the data to be sent. Optional. The length is variable.
- `RR` is the length of the expected response. If no response is expected, this field is absent.
## Real time clock and datetime
Pico HSM has an internal real time clock (RTC) which can track precisely the date and the time. However, when it is reset or powered down, the Pico HSM is reset to the initial datetime: 2020 January 1, 00:00:00.
### Getting the datetime
To obtain the current datetime (referenced to 00:00:00 2020/01/01), the `XX` parameter must be set to `0A`. There is no data and, thus, `YY` and `ZZZZ` are absent. The expected response is 8 bytes length.
For example, to obtain the current datetime:
```
$ opensc-tool -s 80880A0008
Using reader with a card: Free Software Initiative of Japan Gnuk
Sending: 80 88 0A 00 08
Received (SW1=0x90, SW2=0x00):
07 E6 04 06 03 13 29 1E ......).
```
The response is composed by 8 bytes:
- The first two bytes are the current year, MSB first. Hence, `07E6h` equals to `2022`.
- 1 byte for the current month, `01h` is January and `0Ch` is December.
- 1 byte for the current day, from `01h` (1) to `1Fh` (31).
- 1 byte for the day of the week, `00h` is Sunday, `01h` is Monday, etc.
- 1 byte for the hours, from `00h` (0) to `17h` (23).
- 1 byte for the minutes, from `00h` (0) to `3Bh` (59).
- 1 byte for the seconds, from `00h` (0) to `3Bh` (59).
If the command is correctly received, `SW1=0x90` and `SW2=0x00`. Other values mean that an error has ocurred.
### Setting the datetime
To set the reference datetime, a datetime string must be provided. For example:
```
$ opensc-tool -s 80880A000807E6040603132917
Using reader with a card: Free Software Initiative of Japan Gnuk
Sending: 80 88 0A 00 08 07 E6 04 06 03 13 29 17
Received (SW1=0x90, SW2=0x00)
```
will set the reference datetime to `Wednesday, 2022 April 6th, 19:41:23`.
## Dynamic options
Pico HSM support initialize options, such as setting Transport PIN or reset retry counter options. However, once it is initialized, these options cannot be modified anymore, without a new initialization (loosing all stored keys). Pico HSM offers the chance to define a set of dynamic options that can be enabled/disabled dynamically without initializing the device at every moment.
To specify a set of options, the `XX` parameter shall be set to `06`. The data parameter shall be 1 byte, where the options are combined with the or operand `|`. The length `YY` shall be set to `01`.
### Press-to-confirm button
Press-to-confirm button offers an extra security layer by requiring the user confirmation everytime that a private/secret key is loaded. This avoids ghost applications thay may perform hidden opperations without noticing the user, such as signing or decrypting. Pico HSM will inform the user that is awaiting for a confirmation by making almost a fixed Led blink.
This feature is disabled by default but can be enabled rapidly by setting the LSB bit to 1:
```
$ opensc-tool -s 808806000101
Using reader with a card: Free Software Initiative of Japan Gnuk
Sending: 80 88 06 00 01 01
Received (SW1=0x90, SW2=0x00)
```
At this moment, when a private/secret key is loaded, the Pico HSM will wait for the pressed BOOTSEL button to confirm the operation.
To disable, the LSB bit must be set to 0:
```
$ opensc-tool -s 808806000100
Using reader with a card: Free Software Initiative of Japan Gnuk
Sending: 80 88 06 00 01 00
Received (SW1=0x90, SW2=0x00)
```

117
doc/store_data.md Normal file
View File

@@ -0,0 +1,117 @@
# Store binary data
Pico HSM has a internal flash which can store binary data. With this approach, you can save different files, encrypt into the Pico HSM and retrieve them after.
## Maximum size
Due to internal constraints with the flash components, the maximum file size is `4096` bytes. This mechanism is mainly used to store small files, such as keys in plain text, certificates, credentials, etc.
## Store a file
Before writting a file into the Pico HSM, we generate the data file with the following text:
```
$ echo 'Pico HSM is awesome!' > test
```
Then, we can store the data file with the following command:
```
$ pkcs11-tool --pin 648219 --write-object test --type data --id 1 --label 'test1'
Using slot 0 with a present token (0x0)
Created Data Object:
Data object 1236368320
label: 'test1'
application: 'test1'
app_id: <empty>
flags: modifiable
```
This file can also be protected with the PIN. In this case, use the previous command with the `--private` flag:
```
$ pkcs11-tool --pin 648219 --write-object test --type data --id 2 --label 'test2' --private
Using slot 0 with a present token (0x0)
Created Data Object:
Data object 1329612320
label: 'test2'
application: 'test2'
app_id: <empty>
flags: modifiable private
```
Always provide a unique `--label`, as it will be used to index and reference the file for retrieving.
## Retrieve a file
To view the stored file, we can use the following command with the same label we employed:
```
$ pkcs11-tool --read-object --type data --label 'test1'
Using slot 0 with a present token (0x0)
Pico HSM is awesome!
```
Note that if the `--private` flag is not provided during the writting stage, the file can be accessed without the PIN.
To retrieve a private file with the PIN:
```
$ pkcs11-tool --read-object --type data --label 'test2' --pin 648219
Using slot 0 with a present token (0x0)
Pico HSM is awesome!
```
## Using `pkcs15-tool`
PKCS15 tool can be used to list the stored files. For instance:
```
$ pkcs15-tool -D
Using reader with a card: Free Software Initiative of Japan Gnuk
PKCS#15 Card [Pico-HSM]:
Version : 1
Serial number : ESTERMHSM
Manufacturer ID: Pol Henarejos
Flags : PRN generation, EID compliant
PIN [UserPIN]
Object Flags : [0x03], private, modifiable
Auth ID : 02
ID : 01
Flags : [0x812], local, initialized, exchangeRefData
Length : min_len:6, max_len:15, stored_len:0
Pad char : 0x00
Reference : 129 (0x81)
Type : ascii-numeric
Path : e82b0601040181c31f0201::
Tries left : 3
PIN [SOPIN]
Object Flags : [0x01], private
ID : 02
Flags : [0x9A], local, unblock-disabled, initialized, soPin
Length : min_len:16, max_len:16, stored_len:0
Pad char : 0x00
Reference : 136 (0x88)
Type : bcd
Path : e82b0601040181c31f0201::
Tries left : 15
Data object 'test1'
applicationName: test1
Path: e82b0601040181c31f0201::cf00
Data (21 bytes): 5069636F2048534D20697320617765736F6D65210A
Data object 'test2'
applicationName: test2
Path: e82b0601040181c31f0201::cd01
Auth ID: 01
```
As expected, the public file is displayed (in hexadecimal string). The private file contains the `Auth ID` flag and it is not displayed.
## Delete a file
A stored file can be deleted with the following command:
```
$ pkcs11-tool --login --pin 648219 --delete-object --type data --application-label test1
```