You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: slip-0016.md
+53-56
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,6 @@ Created: 2016-18-02
13
13
14
14
SLIP-0016 describes simple encryption concept for hardware device for secure storage of passwords.
15
15
16
-
17
16
## General design
18
17
19
18
At first, we derive a master key from HW device itself, which is divided in two parts.
@@ -22,110 +21,109 @@ Second part is used for primary storage encryption.
22
21
23
22
Storage file is encrypted JSON object, which contains configuration, tags and separate entries. Each entry has other two encrypted properties derivated from device to provide higher level of security with low risk of leaks.
24
23
25
-
26
24
## Design details
27
25
28
-
####Deriving master key
26
+
### Deriving master key
29
27
30
28
We derive masterKey from hardware device by sending cipherKeyValue with following params:
31
-
- path: ```m/10016'/0``` (hardened path, see BIP32)
- ENC_VALUE: ```'2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee'``` (in hexadecimal (128 /2), max length is 1024 bytes)
- ENC_VALUE: `'2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee'` (in hexadecimal (128 /2), max length is 1024 bytes)
CipherKeyValue will be defined in SLIP-0011; right now you can check the source code in [trezor source code](https://github.com/trezor/trezor-mcu/blob/master/firmware/fsm.c#L451-L483).
50
47
51
-
52
-
#### Deriving file name
48
+
### Deriving file name
53
49
54
50
From the first half of master key, we derive the file name for every user/device in the following way:
-```title```: title is represented as string. If given string is matching URL, it will be shown on device as domain without protocol prefix.
115
-
-```username```: string, will be passed to device, in encryption/decryption process
116
-
-```nonce```: hidden generated string which is output of cipherKeyValue over Title + Username key and random values
117
-
-```password```: is buffer array output of plain string and nonce (encryption process described later)
118
-
-```safe_note```: is also buffer array output of plain string and nonce (also described later)
119
-
-```note```: is plain UTF8 string
120
-
-```tags```: is array of Tags key values
121
-
109
+
110
+
-`title`: title is represented as string. If given string is matching URL, it will be shown on device as domain without protocol prefix.
111
+
-`username`: string, will be passed to device, in encryption/decryption process
112
+
-`nonce`: hidden generated string which is output of cipherKeyValue over Title + Username key and random values
113
+
-`password`: is buffer array output of plain string and nonce (encryption process described later)
114
+
-`safe_note`: is also buffer array output of plain string and nonce (also described later)
115
+
-`note`: is plain UTF8 string
116
+
-`tags`: is array of Tags key values
117
+
122
118
Step by step entry encryption:
123
-
1. Generate random 32 bytes buffer and convert to HEX string inadequately called ```nonce```
124
-
2. Set key as ```'Unlock ' + title + ' for user ' + username + '?'```
125
-
3. Ask device for ```cipherKeyValue```, where path is the same as in the deriving file name, key is described in second step and enc_value is our ```nonce``` from the first step. Do not forget to setup properly other three bool values!
126
119
127
-
EXAMPLE:
128
-
```javascript
120
+
1. Generate random 32 bytes buffer and convert to HEX string inadequately called `nonce`
121
+
2. Set key as `'Unlock ' + title + ' for user ' + username + '?'`
122
+
3. Ask device for `cipherKeyValue`, where path is the same as in the deriving file name, key is described in second step and enc_value is our `nonce` from the first step. Do not forget to setup properly other three bool values!
123
+
124
+
EXAMPLE:
125
+
126
+
```javascript
129
127
session.cipherKeyValue(
130
128
[(10016|0x80000000) >>>0, 0], // same path
131
129
'Unlock github.com for user Satoshi Nakamoto?',
@@ -135,14 +133,16 @@ false, //askOnEncrypt? is the same in encryption and decryption
135
133
true) // askOnDecrypt? we want this becuase otherwise somebody could rob us!
136
134
```
137
135
138
-
4. Then we use our famous ```nonce``` from the first step in ```AES-256-GCM``` algorithm encryption for ```password``` string and ```safe_note``` string. Process of encryption is the same as in the deriving encryption key and file level encryption. So basically we get some Buffer array output with 12 bytes of IV and 16 bytes of GCM authTag and the rest is cipherText.
139
-
5. Output of each encryption is stored to appropriate keys, just instead of generated ```nonce``` we store result from third step ( ```cipherKeyValue ```) which we later use for decryption process
136
+
4. Then we use our famous `nonce` from the first step in `AES-256-GCM` algorithm encryption for `password` string and `safe_note` string. Process of encryption is the same as in the deriving encryption key and file level encryption. So basically we get some Buffer array output with 12 bytes of IV and 16 bytes of GCM authTag and the rest is cipherText.
137
+
5. Output of each encryption is stored to appropriate keys, just instead of generated `nonce` we store result from third step ( `cipherKeyValue`) which we later use for decryption process
138
+
139
+
### Entry decryption
140
140
141
-
Entry decryption:
142
-
1. We ask device for the same ```cipherKeyValue ``` as in encryption process, just instead of ```nonce```, we use our encrypted result and boolean value ```encrypt? ``` is **false**!
141
+
1. We ask device for the same `cipherKeyValue` as in encryption process, just instead of `nonce`, we use our encrypted result and boolean value `encrypt?` is **false**!
143
142
144
-
EXAMPLE:
145
-
```javascript
143
+
EXAMPLE:
144
+
145
+
```javascript
146
146
session.cipherKeyValue(
147
147
[(10016|0x80000000) >>>0, 0], // same path
148
148
'Unlock github.com for user Satoshi Nakamoto?',
@@ -151,8 +151,5 @@ false, //encrypt? - has to be FALSE in decryption
151
151
false, //askOnEncrypt? is the same in encryption and decryption
152
152
true) // askOnDecrypt? we want this becuase otherwise somebody could rob us!
153
153
```
154
-
2. Other steps are the same as in entry encryption, we just symetrically decrypt values of ```password``` and ```safe_note``` via ```AES-256-GCM``` algorithm. Size of IV and authTag for AES is the same as in encryption. Beware on cipher Key data type - it must be hex. Output is in JSON.
155
-
156
-
157
-
158
154
155
+
2. Other steps are the same as in entry encryption, we just symetrically decrypt values of `password` and `safe_note` via `AES-256-GCM` algorithm. Size of IV and authTag for AES is the same as in encryption. Beware on cipher Key data type - it must be hex. Output is in JSON.
0 commit comments