forked from Nitrokey/nitrokey-app
-
Notifications
You must be signed in to change notification settings - Fork 0
/
OTP_full_specification.txt
125 lines (94 loc) · 6.06 KB
/
OTP_full_specification.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
Flash storage description OTP
OTP parameter block
The OTP parameter block save the configuration data of each slot. The size of each slot is 64 byte
Slot Start End
GLOBAL_CONFIG 0 2
free 3 63
HOTP_SLOT1 64 127
HOTP_SLOT2 128 191
HOTP_SLOT3 192 255
TOTP_SLOT1 256 319
TOTP_SLOT2 320 383
TOTP_SLOT3 384 447
TOTP_SLOT4 448 511
TOTP_SLOT5 512 575
TOTP_SLOT6 576 639
TOTP_SLOT7 640 703
TOTP_SLOT8 704 767
TOTP_SLOT9 768 831
TOTP_SLOT10 832 896
TOTP_SLOT11 896 939
TOTP_SLOT12 1088 1151 //Start of second OTP slot page
TOTP_SLOT13 1152 1215 //The first slot has been left empty
TOTP_SLOT14 1216 1280 //in case of future need
TOTP_SLOT15 1280 1343
OTP configuration slot
Slot size 64 byte
Contain the parameter data - 50 data byte
Start Description
SLOT_TYPE_OFFSET 0 1 byte slot type TOTP, HOTP
SLOT_NAME_OFFSET 1 15 byte slot name
SECRET_OFFSET 16 20 byte secret key
CONFIG_OFFSET 36 1 byte config byte
TOKEN_ID_OFFSET 37 12 byte token ID
OTP counter storage slot
This field is used for storing the actual counter value. Because of the limitation of flash
erase accesses (10,000 for a Stick 1.4 flash page (1024 byte), 100,000 for a Stick 2.0 flash page (512 byte)).
it is necessary to reduce the erase access of the flash. This is done by using a greater area of the flash.
The limitation of flash accesses is only in the change of the bits to 1 in a flash page.
Only all bit in a hole flash page can set to 1 in a single process (this is the erase access).
The setting to 0 of a bit in the flash page is independent to other bits.
The implementation:
The first 8 byte of the slot contains the base counter of stored value as an unsigned 64 bit value. The
remaining page stored a token per flash byte for a used number. When all tokens in a slot are used, the
base counter is raised and the tokens are reseted to 0xff
Flash page layout
Entry Position
Counter base 0 - 7 8 byte, unsigned 64 bit
Use flags 8 - 1023 1016 byte marked a used value (for Stick 1.4)
Use flags 8 - 511 504 byte marked a used value (for Stick 2.0)
Flash page byte order
0 1 2 3 4 End of flash page
01234567890123456789012345678901234567890123456789.... X
VVVVVVVVFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.... .
V = 64 bit counter base value
F = token for a used value, 0xFF = unused, 0x00 = used
The actual counter is the sum of the counter base value and the number of tokens with a 0 in the slot.
Example:
Flash page byte order
0 1 2 3 4 End of flash page
01234567890123456789012345678901234567890123456789.... X
xHi 0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.... .
xLo 0000001000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.... .
V = 0x0100 = 256
Token 0-7 are marked as used = 8 tokens are marked
Counter value = 256 + 8 = 264
Slot size 1024 byte Stick 1.4
Slot size 512 byte Stick 2.0
OTP time storage slot
The time storage has the same limitation as the OTP counter storage. For reference read above.
Store time command data:
The data that is send from the Utility for the storing of the time has the following format: The first byte
of the *report is the command type ( similar to all other command data). The second byte is used for the
overriding of the time. If that byte is set to 1 it means that the user has requested an overriding of the
time in firmware and provided correct Admin PIN to authorize that. If this has any other value the time
shouldn't be overwritten. The next 64 bits represent the seconds since epoch (1 January 1970). That
value is stored in a RAM variable which is used to calculate the TOTP token and is also used to calculate
the value to be stored in the flash ( (Epoch value - 1388534400)/60 , the value 1388534400 is the number
of seconds from 1 January 1970 to 1 January 2014 ). The time is only written in three cases: the second
byte of the command data is 1, the old time (return by the function get_time_value) has a value smaller
than the new time (in minutes) and if the old time is 0xFFFFFFFF (bellow is an explanation when this happens).
Implementation:
The time is stored as a 24 bit value representing the minutes that have passed since 1 January 2014 plus
a 8 bit CRC code of the value (The polynomial used for the crc calculation is 100110001). On request for
the reset of time (when the device and utility connect to each other and every time a new TOTP token is
requested) the time is stored on a new position in the time slot that is 32 bit offset from the begging.
If the slot is empty ( the first position has value 0xFFFFFFFF ) that is returned by the get_time_value()
function. When there are no empty positions in the slot it is reset and the time is stored on the position with
offset 0. To find the last position on which the time has been set we iterate trough all the possible
positions and check if position has value of 0xFFFFFFFF if it has the previous position holds the last
time. If the value is different then we continue the iteration. To find the next free position in which
the time can be written we do the same as when looking for the last written time and when we find a position
with the value 0xFFFFFFFF that is the next free position.
OTP backup slot
Backup of the OTP parameter block