Revision 57a5ea60

View differences:

bootloader/AMiRo-BLT
1
Subproject commit 03906dc3eea1bcc0aa880aeadd1bc1ba1d26d472
1
Subproject commit dab959cd5693b0ea3f229b0268d370f544d7fa7d
unittests/periphery-lld/src/ut_alld_bq27500.c
26 26
#include <aos_thread.h>
27 27
#include <alld_bq27500.h>
28 28

  
29
// change saved unseal keys to test bruteforcing
30
#ifdef BQ27500_UT_TEST_BRUTEFORCE
31

  
32
#ifdef BQ27500_LLD_DEFAULT_UNSEAL_KEY0
33
#undef BQ27500_LLD_DEFAULT_UNSEAL_KEY0
34
#define BQ27500_LLD_DEFAULT_UNSEAL_KEY0 0x1234
35
#endif
36

  
37
#ifdef BQ27500_LLD_DEFAULT_UNSEAL_KEY1
38
#undef BQ27500_LLD_DEFAULT_UNSEAL_KEY1
39
#define BQ27500_LLD_DEFAULT_UNSEAL_KEY1 0x5678
40
#endif
41

  
42
#endif
43

  
44
bq27500_lld_control_status_t _try_unseal(BQ27500Driver* driver, uint16_t key0, uint16_t key1, apalTime_t timeout) {
45
  uint16_t dst;
46
  bq27500_lld_control_status_t ctrl;
47
  bq27500_lld_send_ctnl_data(driver, key1, timeout);
48
  aosThdUSleep(1);
49
  bq27500_lld_send_ctnl_data(driver, key0, timeout);
50
  aosThdUSleep(1);
51
  bq27500_lld_sub_command_call(driver, BQ27500_LLD_SUB_CMD_CONTROL_STATUS, timeout);
52
  aosThdUSleep(1);
53
  bq27500_lld_std_command(driver, BQ27500_LLD_STD_CMD_Control, &dst, timeout);
54
  bq27500_lld_sub_command_read(driver, &ctrl.value, timeout);
55
  return ctrl;
56
}
57

  
58
uint8_t _bruteforce_sealed_key_bitflips(BaseSequentialStream* stream, BQ27500Driver* driver, uint16_t key0, uint16_t key1, apalTime_t timeout) {
59
  bq27500_lld_control_status_t ctrl;
60
  uint16_t k0;
61
  uint16_t k1 = key1;
62
  for (uint8_t i = 0; i < 16; i++) {
63
    k0 = key0 ^ (1 << i); // flip bit i
64
    ctrl = _try_unseal(driver, k0, k1, timeout);
65
    if (ctrl.content.ss == 0x0) {
66
      chprintf(stream, "\t\tSUCCESS!\n");
67
      chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", k0, k1);
68
      return 1;
69
    }
70
  }
71
  k0 = key0;
72
  for (uint8_t i = 0; i < 16; i++) {
73
    k1 = key1 ^ (1 << i); // flip bit i
74
    ctrl = _try_unseal(driver, k0, k1, timeout);
75
    if (ctrl.content.ss == 0x0) {
76
      chprintf(stream, "\t\tSUCCESS!\n");
77
      chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", k0, k1);
78
      return 1;
79
    }
80
  }
81
  return 0;
82
}
83

  
84
void _bruteforce_sealed_key(BaseSequentialStream* stream, BQ27500Driver* driver, apalTime_t timeout) {
85
  chprintf(stream, "start bruteforcing sealed keys...\n");
86
  bq27500_lld_control_status_t ctrl;
87
  uint16_t key0_reversed = 0x7236;
88
  uint16_t key1_reversed = 0x1404;
89
  uint16_t key0 = BQ27500_LLD_DEFAULT_UNSEAL_KEY0;
90
  uint16_t key1 = BQ27500_LLD_DEFAULT_UNSEAL_KEY1;
91
  uint16_t k0 = key0;
92
  uint16_t k1 = key1;
93

  
94
  // testing default keys in different orders
95
  chprintf(stream, "\ttry reversed byte order and different key order...\n");
96
  // default unseal keys
97
  ctrl = _try_unseal(driver, k0, k1, timeout);
98
  if (ctrl.content.ss == 0x0) {
99
    chprintf(stream, "\t\tSUCCESS!\n");
100
    chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", k0, k1);
101
    return;
102
  }
103
  // default unseal keys in reversed order
104
  ctrl = _try_unseal(driver, k1, k0, timeout);
105
  if (ctrl.content.ss == 0x0) {
106
    chprintf(stream, "\t\tSUCCESS!\n");
107
    chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", k0, k1);
108
    return;
109
  }
110
  // byte reversed keys
111
  k0 = key0_reversed;
112
  k1 = key1_reversed;
113
  ctrl = _try_unseal(driver, k0, k1, timeout);
114
  if (ctrl.content.ss == 0x0) {
115
    chprintf(stream, "\t\tSUCCESS!\n");
116
    chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", k0, k1);
117
    return;
118
  }
119
  // byte reversed keys in reversed order
120
  ctrl = _try_unseal(driver, k1, k0, timeout);
121
  if (ctrl.content.ss == 0x0) {
122
    chprintf(stream, "\t\tSUCCESS!\n");
123
    chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", k0, k1);
124
    return;
125
  }
126
  chprintf(stream, "\t\tfailed\n");
127

  
128

  
129
  // testing single bit flips of the default keys in different orders
130
  chprintf(stream, "\ttry single bit flips of default keys...\n");
131
  // default unseal keys
132
  uint8_t result = 0;
133
  result = _bruteforce_sealed_key_bitflips(stream, driver, key0, key1, timeout);
134
  if (result == 1) {
135
    return;
136
  }
137
  // default unseal keys in reversed order
138
  result = _bruteforce_sealed_key_bitflips(stream, driver, key1, key0, timeout);
139
  if (result == 1) {
140
    return;
141
  }
142
  // byte reversed keys
143
  result = _bruteforce_sealed_key_bitflips(stream, driver, key0_reversed, key1_reversed, timeout);
144
  if (result == 1) {
145
    return;
146
  }
147
  // byte reversed keys in reversed order
148
  result = _bruteforce_sealed_key_bitflips(stream, driver, key1_reversed, key0_reversed, timeout);
149
  if (result == 1) {
150
    return;
151
  }
152
  chprintf(stream, "\t\tfailed\n");
153

  
154

  
155
  // bruteforcing one of the keys, assuming only one of them was changed
156
  chprintf(stream, "\ttry bruteforcing a single key...\n");
157
  // default unseal key0
158
  for (uint32_t i = 0; i <= 0xFFFF; i++) {
159
    ctrl = _try_unseal(driver, key0, i, timeout);
160
    if (ctrl.content.ss == 0x0) {
161
      chprintf(stream, "\t\tSUCCESS!\n");
162
      chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", key0, i);
163
      return;
164
    }
165
  }
166
  chprintf(stream, "\t\tkey failed. 1/8\n");
167
  // reversed unseal key0
168
  for (uint32_t i = 0; i <= 0xFFFF; i++) {
169
    ctrl = _try_unseal(driver, key0_reversed, i, timeout);
170
    if (ctrl.content.ss == 0x0) {
171
      chprintf(stream, "\t\tSUCCESS!\n");
172
      chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", key0_reversed, i);
173
      return;
174
    }
175
  }
176
  chprintf(stream, "\t\tkey failed. 2/8\n");
177
  // default unseal key0 in reversed order
178
  for (uint32_t i = 0; i <= 0xFFFF; i++) {
179
    ctrl = _try_unseal(driver, i, key0, timeout);
180
    if (ctrl.content.ss == 0x0) {
181
      chprintf(stream, "\t\tSUCCESS!\n");
182
      chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", i, key0);
183
      return;
184
    }
185
  }
186
  chprintf(stream, "\t\tkey failed. 3/8\n");
187
  // reversed unseal key0 in reversed order
188
  for (uint32_t i = 0; i <= 0xFFFF; i++) {
189
    ctrl = _try_unseal(driver, i, key0_reversed, timeout);
190
    if (ctrl.content.ss == 0x0) {
191
      chprintf(stream, "\t\tSUCCESS!\n");
192
      chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", i, key0_reversed);
193
      return;
194
    }
195
  }
196
  chprintf(stream, "\t\tkey failed. 4/8\n");
197
  // default unseal key1
198
  for (uint32_t i = 0; i <= 0xFFFF; i++) {
199
    ctrl = _try_unseal(driver, i, key1, timeout);
200
    if (ctrl.content.ss == 0x0) {
201
      chprintf(stream, "\t\tSUCCESS!\n");
202
      chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", i, key1);
203
      return;
204
    }
205
  }
206
  chprintf(stream, "\t\tkey failed. 5/8\n");
207
  // reversed unseal key1
208
  for (uint32_t i = 0; i <= 0xFFFF; i++) {
209
    ctrl = _try_unseal(driver, i, key1_reversed, timeout);
210
    if (ctrl.content.ss == 0x0) {
211
      chprintf(stream, "\t\tSUCCESS!\n");
212
      chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", i, key1_reversed);
213
      return;
214
    }
215
  }
216
  chprintf(stream, "\t\tkey failed. 6/8\n");
217
  // default unseal key1 in reversed order
218
  for (uint32_t i = 0; i <= 0xFFFF; i++) {
219
    ctrl = _try_unseal(driver, key1, i, timeout);
220
    if (ctrl.content.ss == 0x0) {
221
      chprintf(stream, "\t\tSUCCESS!\n");
222
      chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", key1, i);
223
      return;
224
    }
225
  }
226
  chprintf(stream, "\t\tkey failed. 7/8\n");
227
  // reversed unseal key1 in reversed order
228
  for (uint32_t i = 0; i <= 0xFFFF; i++) {
229
    ctrl = _try_unseal(driver, key1_reversed, i, timeout);
230
    if (ctrl.content.ss == 0x0) {
231
      chprintf(stream, "\t\tSUCCESS!\n");
232
      chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", key1_reversed, i);
233
      return;
234
    }
235
  }
236
  chprintf(stream, "\t\tkey failed. 8/8\n");
237
  chprintf(stream, "\t\tfailed\n");
238

  
239

  
240
  // full bruteforce
241
  chprintf(stream, "\tbruteforcing both keys...\t");
242
  for (uint32_t i = 0; i <= 0xFFFF; i++) {
243
    chprintf(stream, "\t\ti: %u\n", i);
244
    for (uint32_t j = 0; j <= 0xFFFF; j++) {
245
      ctrl = _try_unseal(driver, i, j, timeout);
246
      if (ctrl.content.ss == 0x0) {
247
        chprintf(stream, "\t\tSUCCESS!\n");
248
        chprintf(stream, "\t\tkey0: 0x%X, key1: 0x%X\n", i, j);
249
        return;
250
      }
251
    }
252
  }
253

  
254
  chprintf(stream, "\t\tfailed, no keys could be found");
255
}
256

  
29 257
aos_utresult_t utAlldBq27500Func(BaseSequentialStream* stream, aos_unittest_t* ut)
30 258
{
31 259
  aosDbgCheck(ut->data != NULL && ((ut_bq27500data_t*)(ut->data))->driver != NULL);
......
87 315
  }
88 316

  
89 317
  chprintf(stream, "sub command: CTRL Status...\n");
90
  aosThdMSleep(5);
318
  aosThdUSleep(1);
91 319
  status = bq27500_lld_sub_command_call(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_SUB_CMD_CONTROL_STATUS, ((ut_bq27500data_t*)ut->data)->timeout);
92
  aosThdMSleep(5);
320
  aosThdUSleep(1);
93 321
  status |= bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_Control, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
94
  aosThdMSleep(5);
322
  aosThdUSleep(1);
95 323
  bq27500_lld_control_status_t ctrl;
96 324
  status |= bq27500_lld_sub_command_read(((ut_bq27500data_t*)ut->data)->driver, &ctrl.value, ((ut_bq27500data_t*)ut->data)->timeout);
97 325
  chprintf(stream, "\t\tdst: 0x%X\n", ctrl.value);
......
194 422

  
195 423
  chprintf(stream, "unseale...\n");
196 424
  status = bq27500_lld_send_ctnl_data(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_DEFAULT_UNSEAL_KEY1, ((ut_bq27500data_t*)ut->data)->timeout);
197
  aosThdMSleep(50);
425
  aosThdMSleep(1);
198 426
  status |= bq27500_lld_send_ctnl_data(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_DEFAULT_UNSEAL_KEY0, ((ut_bq27500data_t*)ut->data)->timeout);
199
  aosThdMSleep(50);
427
  aosThdMSleep(1);
200 428
  status |= bq27500_lld_sub_command_call(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_SUB_CMD_CONTROL_STATUS, ((ut_bq27500data_t*)ut->data)->timeout);
201
  aosThdMSleep(50);
429
  aosThdMSleep(1);
202 430
  status |= bq27500_lld_std_command(((ut_bq27500data_t*)ut->data)->driver, BQ27500_LLD_STD_CMD_Control, &dst, ((ut_bq27500data_t*)ut->data)->timeout);
203 431
  status |= bq27500_lld_sub_command_read(((ut_bq27500data_t*)ut->data)->driver, &ctrl.value, ((ut_bq27500data_t*)ut->data)->timeout);
204 432
  if (status == APAL_STATUS_SUCCESS && ctrl.content.ss == 0x0) {
205 433
    aosUtPassed(stream, &result);
206 434
  } else {
207 435
    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
436
    _bruteforce_sealed_key(stream, ((ut_bq27500data_t*)ut->data)->driver, ((ut_bq27500data_t*)ut->data)->timeout);
208 437
  }
209 438

  
210 439
  chprintf(stream, "read device name from data flash...\n");

Also available in: Unified diff