-
Notifications
You must be signed in to change notification settings - Fork 18
/
usi.c
149 lines (130 loc) · 3.76 KB
/
usi.c
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* USI - USER INPUT state machine */
#include "usi.h"
#include "uif.h"
#include "uib.h"
#include "crd.h"
#include "ucp.h"
#include "print.h"
#define USI_PIN_RETRIES (2u)
/** Global Data */
// PIN: 0000 default HASH
const uint8_t LOCK_HASH[16] EEMEM = {
0xd4,0x4f,0xb2,0x7a,0x58,0xb4,0x27,0x4a,0x21,0xe6,0x8f,0x39,0x69,0x74,0x23,0x54
};
static const char erasePin[4] PROGMEM = {'9','9','9','9'};
/** Local Data */
static char userText[16];
static char userPin[4];
static uint8_t userTextIndex;
static const char USI_keys[] PROGMEM = {'0','1','2','3','4','5','6','7','8','9'};
static const char PIN_str[] PROGMEM = "PIN: ";
static const char LOCKED_str[] PROGMEM = "PIN ERR";
static const char PINRESET_str[] PROGMEM = "PIN RESET to 0000";
static const uint8_t LOCK_HASH_PGM[16] PROGMEM = {
0xd4,0x4f,0xb2,0x7a,0x58,0xb4,0x27,0x4a,0x21,0xe6,0x8f,0x39,0x69,0x74,0x23,0x54
};
static uint8_t pin_retries = USI_PIN_RETRIES;
/** Private Function declaration */
static void usi_print(void);
static void usi_previous(void);
static void usi_next(void);
static void usi_resetPin(void);
static uint8_t usi_pinCheck(char pin[4]);
void USI_Init(void){
userTextIndex = 0;
UIF_userInputIndex = 0;
memcpy_P((void*)userText, (void*)PIN_str, sizeof(PIN_str));
usi_print();
UCP_Lock();
}
// user input finitestate machine
void USI_fsm(uint8_t button){
switch(button) {
case LEFT:
print_deleteStr();
USI_Init();
break;
case UP:
print_deleteStr();
usi_next();
break;
case RIGHT:
print_deleteStr();
if(userTextIndex == (sizeof(userPin)-1)) // real array elements (\0)
{
/* Device Unlocked */
if(usi_pinCheck(userPin) == 1)
{
CRD_fsmStart();
}
/* Device Locked */
else
{
if(pin_retries > 0){
printStr((void*)LOCKED_str,FLASH);
pin_retries--;
} else{
printStr((void*)PINRESET_str,FLASH);
usi_resetPin();
pin_retries = USI_PIN_RETRIES;
}
userTextIndex = 0;
UIF_userInputIndex = 0;
userPin[0] = '0';
memcpy_P((void*)userText, (void*)PIN_str, sizeof(PIN_str));
}
}
else
{
userText[sizeof(PIN_str)-1+userTextIndex] = '*';
userTextIndex++;
usi_print();
}
break;
case DOWN:
print_deleteStr();
usi_previous();
break;
default:
break;
}
}
static void usi_print(void){
userPin[userTextIndex] = pgm_read_byte(&USI_keys[UIF_userInputIndex]);
userText[sizeof(PIN_str)-1+userTextIndex] = userPin[userTextIndex];
userText[sizeof(PIN_str)-1+userTextIndex+1] = 0;
printStr(userText,RAM);
}
static void usi_previous(void){
UIF_decrement(&UIF_userInputIndex, sizeof(USI_keys));
usi_print();
}
static void usi_next(void){
UIF_increment(&UIF_userInputIndex, sizeof(USI_keys));
usi_print();
}
static uint8_t usi_pinCheck(char pin[4]){
uint8_t i;
if ( (pin[0]==erasePin[0]) && (pin[1]==erasePin[1]) && (pin[2]==erasePin[2]) && (pin[3]==erasePin[3]) )
{
usi_resetPin();
while (1) {};
}
for(i=0; i<16; i++) {
cipher.key[i] = pin[(i%4)];
cipher.plain[i] = pin[(i%4)];
}
noekeon_encrypt();
for(i=0; i<16; i++)
{
if(eeprom_read_byte(LOCK_HASH+i) != cipher.plain[i]) {
break;
}
}
return i==16;
}
static void usi_resetPin(void){
uint8_t hash[16];
memcpy_P((void*)hash, (void*)LOCK_HASH_PGM, sizeof(LOCK_HASH_PGM));
eeprom_update_block ((void*)hash, (void*)LOCK_HASH, sizeof(hash));
}