1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18 #include <variant/inc/variant.h>
19
20 #include <plat/inc/cmsis.h>
21 #include <plat/inc/gpio.h>
22 #include <plat/inc/pwr.h>
23 #include <plat/inc/bl.h>
24
25 #include <nanohub/sha2.h>
26 #include <nanohub/aes.h>
27 #include <nanohub/rsa.h>
28 #include <nanohub/nanohub.h>
29
30 #include <printf.h>
31 #include <string.h>
32 #include <alloca.h>
33 #include <gpio.h>
34
35 static uint32_t blVerifyOsImage(const uint8_t *addr, struct OsUpdateHdr **start, uint32_t *size);
36
37 struct StmCrc
38 {
39 volatile uint32_t DR;
40 volatile uint32_t IDR;
41 volatile uint32_t CR;
42 };
43
44 struct StmFlash
45 {
46 volatile uint32_t ACR;
47 volatile uint32_t KEYR;
48 volatile uint32_t OPTKEYR;
49 volatile uint32_t SR;
50 volatile uint32_t CR;
51 volatile uint32_t OPTCR;
52 };
53
54 struct StmRcc {
55 volatile uint32_t CR;
56 volatile uint32_t PLLCFGR;
57 volatile uint32_t CFGR;
58 volatile uint32_t CIR;
59 volatile uint32_t AHB1RSTR;
60 volatile uint32_t AHB2RSTR;
61 volatile uint32_t AHB3RSTR;
62 uint8_t unused0[4];
63 volatile uint32_t APB1RSTR;
64 volatile uint32_t APB2RSTR;
65 uint8_t unused1[8];
66 volatile uint32_t AHB1ENR;
67 volatile uint32_t AHB2ENR;
68 volatile uint32_t AHB3ENR;
69 uint8_t unused2[4];
70 volatile uint32_t APB1ENR;
71 volatile uint32_t APB2ENR;
72 uint8_t unused3[8];
73 volatile uint32_t AHB1LPENR;
74 volatile uint32_t AHB2LPENR;
75 volatile uint32_t AHB3LPENR;
76 uint8_t unused4[4];
77 volatile uint32_t APB1LPENR;
78 volatile uint32_t APB2LPENR;
79 uint8_t unused5[8];
80 volatile uint32_t BDCR;
81 volatile uint32_t CSR;
82 uint8_t unused6[8];
83 volatile uint32_t SSCGR;
84 volatile uint32_t PLLI2SCFGR;
85 };
86
87 struct StmUdid
88 {
89 volatile uint32_t U_ID[3];
90 };
91
92 struct StmSpi {
93 volatile uint32_t CR1;
94 volatile uint32_t CR2;
95 volatile uint32_t SR;
96 volatile uint32_t DR;
97 volatile uint32_t CRCPR;
98 volatile uint32_t RXCRCR;
99 volatile uint32_t TXCRCR;
100 volatile uint32_t I2SCFGR;
101 volatile uint32_t I2SPR;
102 };
103
104 struct StmGpio {
105 volatile uint32_t MODER;
106 volatile uint32_t OTYPER;
107 volatile uint32_t OSPEEDR;
108 volatile uint32_t PUPDR;
109 volatile uint32_t IDR;
110 volatile uint32_t ODR;
111 volatile uint32_t BSRR;
112 volatile uint32_t LCKR;
113 volatile uint32_t AFR[2];
114 };
115
116 //stm defines
117 #define BL_MAX_FLASH_CODE 1024
118
119
120 #define FLASH_ACR_LAT(x) ((x) & FLASH_ACR_LAT_MASK)
121 #define FLASH_ACR_LAT_MASK 0x0F
122 #define FLASH_ACR_PRFTEN 0x00000100
123 #define FLASH_ACR_ICEN 0x00000200
124 #define FLASH_ACR_DCEN 0x00000400
125 #define FLASH_ACR_ICRST 0x00000800
126 #define FLASH_ACR_DCRST 0x00001000
127
128 #define FLASH_SR_EOP 0x00000001
129 #define FLASH_SR_OPERR 0x00000002
130 #define FLASH_SR_WRPERR 0x00000010
131 #define FLASH_SR_PGAERR 0x00000020
132 #define FLASH_SR_PGPERR 0x00000040
133 #define FLASH_SR_PGSERR 0x00000080
134 #define FLASH_SR_RDERR 0x00000100
135 #define FLASH_SR_BSY 0x00010000
136
137 #define FLASH_CR_PG 0x00000001
138 #define FLASH_CR_SER 0x00000002
139 #define FLASH_CR_MER 0x00000004
140 #define FLASH_CR_SNB(x) (((x) << FLASH_CR_SNB_SHIFT) & FLASH_CR_SNB_MASK)
141 #define FLASH_CR_SNB_MASK 0x00000078
142 #define FLASH_CR_SNB_SHIFT 3
143 #define FLASH_CR_PSIZE(x) (((x) << FLASH_CR_PSIZE_SHIFT) & FLASH_CR_PSIZE_MASK)
144 #define FLASH_CR_PSIZE_MASK 0x00000300
145 #define FLASH_CR_PSIZE_SHIFT 8
146 #define FLASH_CR_PSIZE_8 0x0
147 #define FLASH_CR_PSIZE_16 0x1
148 #define FLASH_CR_PSIZE_32 0x2
149 #define FLASH_CR_PSIZE_64 0x3
150 #define FLASH_CR_STRT 0x00010000
151 #define FLASH_CR_EOPIE 0x01000000
152 #define FLASH_CR_ERRIE 0x02000000
153 #define FLASH_CR_LOCK 0x80000000
154
155 //for comms protocol
156 #define BL_SYNC_IN 0x5A
157 #define BL_ACK 0x79
158 #define BL_NAK 0x1F
159 #define BL_SYNC_OUT 0xA5
160
161 #define BL_CMD_GET 0x00
162 #define BL_CMD_READ_MEM 0x11
163 #define BL_CMD_WRITE_MEM 0x31
164 #define BL_CMD_ERASE 0x44
165 #define BL_CMD_GET_SIZES 0xEE /* our own command. reports: {u32 osSz, u32 sharedSz, u32 eeSz} all in big endian */
166 #define BL_CMD_UPDATE_FINISHED 0xEF /* our own command. attempts to verify the update -> ACK/NAK. MUST be called after upload to mark it as completed */
167
168 #define BL_SHARED_AREA_FAKE_ERASE_BLK 0xFFF0
169 #define BL_SHARED_AREA_FAKE_ADDR 0x50000000
170
171
172 typedef void (*FlashEraseF)(volatile uint32_t *, uint32_t, volatile uint32_t *);
173 typedef void (*FlashWriteF)(volatile uint8_t *, uint8_t, volatile uint32_t *);
174
175 //linker provides these
176 extern uint32_t __pubkeys_start[];
177 extern uint32_t __pubkeys_end[];
178 extern uint8_t __stack_top[];
179 extern uint8_t __ram_start[];
180 extern uint8_t __ram_end[];
181 extern uint8_t __eedata_start[];
182 extern uint8_t __eedata_end[];
183 extern uint8_t __code_start[];
184 extern uint8_t __code_end[];
185 extern uint8_t __shared_start[];
186 extern uint8_t __shared_end[];
187 extern void __VECTORS();
188
189 //make GCC happy
190 void __blEntry(void);
191
192 enum BlFlashType
193 {
194 BL_FLASH_BL,
195 BL_FLASH_EEDATA,
196 BL_FLASH_KERNEL,
197 BL_FLASH_SHARED
198 };
199
200 static const struct blFlashTable // For erase code, we need to know which page a given memory address is in
201 {
202 uint8_t *address;
203 uint32_t length;
204 uint32_t type;
205 } mBlFlashTable[] =
206 #ifndef BL_FLASH_TABLE
207 {
208 { (uint8_t *)(&BL), 0x04000, BL_FLASH_BL },
209 { (uint8_t *)(__eedata_start), 0x04000, BL_FLASH_EEDATA },
210 { (uint8_t *)(__eedata_start + 0x04000), 0x04000, BL_FLASH_EEDATA },
211 { (uint8_t *)(__code_start), 0x04000, BL_FLASH_KERNEL },
212 { (uint8_t *)(__code_start + 0x04000), 0x10000, BL_FLASH_KERNEL },
213 { (uint8_t *)(__shared_start), 0x20000, BL_FLASH_SHARED },
214 { (uint8_t *)(__shared_start + 0x20000), 0x20000, BL_FLASH_SHARED },
215 { (uint8_t *)(__shared_start + 0x40000), 0x20000, BL_FLASH_SHARED },
216 };
217 #else
218 BL_FLASH_TABLE;
219 #endif
220
221 static const char mOsUpdateMagic[] = OS_UPDT_MAGIC;
222
223 //BL stack
224 uint64_t __attribute__ ((section (".stack"))) _STACK[BL_STACK_SIZE / sizeof(uint64_t)];
225
226
227 #ifdef DEBUG_UART_PIN
228
blLogPutcharF(void * userData,char ch)229 static bool blLogPutcharF(void *userData, char ch)
230 {
231 if (ch == '\n')
232 gpioBitbangedUartOut('\r');
233
234 gpioBitbangedUartOut(ch);
235
236 return true;
237 }
238
blLog(const char * str,...)239 void blLog(const char *str, ...)
240 {
241 va_list vl;
242
243 va_start(vl, str);
244 cvprintf(blLogPutcharF, NULL, str, vl);
245 va_end(vl);
246 }
247
248 #else
249
250 #define blLog(...)
251
252 #endif
253
blDisableInts(void)254 static inline uint32_t blDisableInts(void)
255 {
256 uint32_t state;
257
258 asm volatile (
259 "mrs %0, PRIMASK \n"
260 "cpsid i \n"
261 :"=r"(state)
262 );
263
264 return state;
265 }
266
blRestoreInts(uint32_t state)267 static inline void blRestoreInts(uint32_t state)
268 {
269 asm volatile(
270 "msr PRIMASK, %0 \n"
271 ::"r"((uint32_t)state)
272 );
273 }
274
blExtApiGetVersion(void)275 static uint32_t blExtApiGetVersion(void)
276 {
277 return BL_VERSION_CUR;
278 }
279
blExtApiReboot(void)280 static void blExtApiReboot(void)
281 {
282 SCB->AIRCR = 0x05FA0004;
283 //we never get here
284 while(1);
285 }
286
blExtApiGetSnum(uint32_t * snum,uint32_t length)287 static void blExtApiGetSnum(uint32_t *snum, uint32_t length)
288 {
289 struct StmUdid *reg = (struct StmUdid *)UDID_BASE;
290 uint32_t i;
291
292 if (length > 3)
293 length = 3;
294
295 for (i = 0; i < length; i++)
296 snum[i] = reg->U_ID[i];
297 }
298
299 /*
300 * Return the address of the erase code and the length of the code
301 *
302 * This code needs to run out of ram and not flash since accessing flash
303 * while erasing is undefined (best case the processor stalls, worst case
304 * it starts executing garbage)
305 *
306 * This function is used to get a pointer to the actual code that does the
307 * erase and polls for completion (so we can copy it to ram) as well as the
308 * length of the code (so we know how much space to allocate for it)
309 *
310 * void FlashEraseF(volatile uint32_t *addr, uint32_t value, volatile uint32_t *status)
311 * {
312 * *addr = value;
313 * while (*status & FLASH_SR_BSY) ;
314 * }
315 */
blGetFlashEraseCode(uint16_t ** addr,uint32_t * size)316 static void __attribute__((naked)) blGetFlashEraseCode(uint16_t **addr, uint32_t *size)
317 {
318 asm volatile (
319 " push {lr} \n"
320 " bl 9f \n"
321 " str r1, [r0, #0] \n" // *addr = value
322 "1: \n"
323 " ldr r3, [r2, #0] \n" // r3 = *status
324 " lsls r3, #15 \n" // r3 <<= 15
325 " bmi 1b \n" // if (r3 < 0) goto 1
326 " bx lr \n" // return
327 "9: \n"
328 " bic lr, #0x1 \n"
329 " adr r3, 9b \n"
330 " sub r3, lr \n"
331 " str lr, [r0] \n"
332 " str r3, [r1] \n"
333 " pop {pc} \n"
334 );
335 }
336
337 /*
338 * Return the address of the write code and the length of the code
339 *
340 * This code needs to run out of ram and not flash since accessing flash
341 * while writing to flash is undefined (best case the processor stalls, worst
342 * case it starts executing garbage)
343 *
344 * This function is used to get a pointer to the actual code that does the
345 * write and polls for completion (so we can copy it to ram) as well as the
346 * length of the code (so we know how much space to allocate for it)
347 *
348 * void FlashWriteF(volatile uint8_t *addr, uint8_t value, volatile uint32_t *status)
349 * {
350 * *addr = value;
351 * while (*status & FLASH_SR_BSY) ;
352 * }
353 */
blGetFlashWriteCode(uint16_t ** addr,uint32_t * size)354 static void __attribute__((naked)) blGetFlashWriteCode(uint16_t **addr, uint32_t *size)
355 {
356 asm volatile (
357 " push {lr} \n"
358 " bl 9f \n"
359 " strb r1, [r0, #0] \n" // *addr = value
360 "1: \n"
361 " ldr r3, [r2, #0] \n" // r3 = *status
362 " lsls r3, #15 \n" // r3 <<= 15
363 " bmi 1b \n" // if (r3 < 0) goto 1
364 " bx lr \n" // return
365 "9: \n"
366 " bic lr, #0x1 \n"
367 " adr r3, 9b \n"
368 " sub r3, lr \n"
369 " str lr, [r0] \n"
370 " str r3, [r1] \n"
371 " pop {pc} \n"
372 );
373 }
374
blEraseSectors(uint32_t sector_cnt,uint8_t * erase_mask)375 static void blEraseSectors(uint32_t sector_cnt, uint8_t *erase_mask)
376 {
377 struct StmFlash *flash = (struct StmFlash *)FLASH_BASE;
378 uint16_t *code_src, *code;
379 uint32_t i, code_length;
380 FlashEraseF func;
381
382 blGetFlashEraseCode(&code_src, &code_length);
383
384 if (code_length < BL_MAX_FLASH_CODE) {
385 code = (uint16_t *)(((uint32_t)alloca(code_length + 1) + 1) & ~0x1);
386 func = (FlashEraseF)((uint8_t *)code+1);
387
388 for (i = 0; i < code_length / sizeof(uint16_t); i++)
389 code[i] = code_src[i];
390
391 for (i = 0; i < sector_cnt; i++) {
392 if (erase_mask[i]) {
393 flash->CR = (flash->CR & ~(FLASH_CR_SNB_MASK)) |
394 FLASH_CR_SNB(i) | FLASH_CR_SER;
395 func(&flash->CR, flash->CR | FLASH_CR_STRT, &flash->SR);
396 flash->CR &= ~(FLASH_CR_SNB_MASK | FLASH_CR_SER);
397 }
398 }
399 }
400 }
401
blWriteBytes(uint8_t * dst,const uint8_t * src,uint32_t length)402 static void blWriteBytes(uint8_t *dst, const uint8_t *src, uint32_t length)
403 {
404 struct StmFlash *flash = (struct StmFlash *)FLASH_BASE;
405 uint16_t *code_src, *code;
406 uint32_t i, code_length;
407 FlashWriteF func;
408
409 blGetFlashWriteCode(&code_src, &code_length);
410
411 if (code_length < BL_MAX_FLASH_CODE) {
412 code = (uint16_t *)(((uint32_t)alloca(code_length+1) + 1) & ~0x1);
413 func = (FlashWriteF)((uint8_t *)code+1);
414
415 for (i = 0; i < code_length / sizeof(uint16_t); i++)
416 code[i] = code_src[i];
417
418 flash->CR |= FLASH_CR_PG;
419
420 for (i = 0; i < length; i++) {
421 if (dst[i] != src[i])
422 func(&dst[i], src[i], &flash->SR);
423 }
424
425 flash->CR &= ~FLASH_CR_PG;
426 }
427 }
428
blProgramFlash(uint8_t * dst,const uint8_t * src,uint32_t length,uint32_t key1,uint32_t key2)429 static bool blProgramFlash(uint8_t *dst, const uint8_t *src, uint32_t length, uint32_t key1, uint32_t key2)
430 {
431 struct StmFlash *flash = (struct StmFlash *)FLASH_BASE;
432 const uint32_t sector_cnt = sizeof(mBlFlashTable) / sizeof(struct blFlashTable);
433 uint32_t acr_cache, cr_cache, offset, i, j = 0, int_state = 0;
434 uint8_t *ptr;
435
436 if (((length == 0)) ||
437 ((0xFFFFFFFF - (uint32_t)dst) < (length - 1)) ||
438 ((dst < mBlFlashTable[0].address)) ||
439 ((dst + length) > (mBlFlashTable[sector_cnt-1].address +
440 mBlFlashTable[sector_cnt-1].length))) {
441 return false;
442 }
443
444 // compute which flash block we are starting from
445 for (i = 0; i < sector_cnt; i++) {
446 if (dst >= mBlFlashTable[i].address &&
447 dst < (mBlFlashTable[i].address + mBlFlashTable[i].length)) {
448 break;
449 }
450 }
451
452 // now loop through all the flash blocks and see if we have to do any
453 // 0 -> 1 transitions of a bit. If so, return false
454 // 1 -> 0 transitions of a bit do not require an erase
455 offset = (uint32_t)(dst - mBlFlashTable[i].address);
456 ptr = mBlFlashTable[i].address;
457 while (j < length && i < sector_cnt) {
458 if (offset == mBlFlashTable[i].length) {
459 i++;
460 offset = 0;
461 ptr = mBlFlashTable[i].address;
462 }
463
464 if ((ptr[offset] & src[j]) != src[j]) {
465 return false;
466 } else {
467 j++;
468 offset++;
469 }
470 }
471
472 // disable interrupts
473 // otherwise an interrupt during flash write will stall the processor
474 // until the write completes
475 int_state = blDisableInts();
476
477 // wait for flash to not be busy (should never be set at this point)
478 while (flash->SR & FLASH_SR_BSY);
479
480 cr_cache = flash->CR;
481
482 if (flash->CR & FLASH_CR_LOCK) {
483 // unlock flash
484 flash->KEYR = key1;
485 flash->KEYR = key2;
486 }
487
488 if (flash->CR & FLASH_CR_LOCK) {
489 // unlock failed, restore interrupts
490 blRestoreInts(int_state);
491
492 return false;
493 }
494
495 flash->CR = FLASH_CR_PSIZE(FLASH_CR_PSIZE_8);
496
497 acr_cache = flash->ACR;
498
499 // disable and flush data and instruction caches
500 flash->ACR &= ~(FLASH_ACR_DCEN | FLASH_ACR_ICEN);
501 flash->ACR |= (FLASH_ACR_DCRST | FLASH_ACR_ICRST);
502
503 blWriteBytes(dst, src, length);
504
505 flash->ACR = acr_cache;
506 flash->CR = cr_cache;
507
508 blRestoreInts(int_state);
509
510 return !memcmp(dst, src, length);
511 }
512
blProgramTypedArea(uint8_t * dst,const uint8_t * src,uint32_t length,uint32_t type,uint32_t key1,uint32_t key2)513 static bool blProgramTypedArea(uint8_t *dst, const uint8_t *src, uint32_t length, uint32_t type, uint32_t key1, uint32_t key2)
514 {
515 const uint32_t sector_cnt = sizeof(mBlFlashTable) / sizeof(struct blFlashTable);
516 uint32_t i;
517
518 for (i = 0; i < sector_cnt; i++) {
519
520 if ((dst >= mBlFlashTable[i].address &&
521 dst < (mBlFlashTable[i].address + mBlFlashTable[i].length)) ||
522 (dst < mBlFlashTable[i].address &&
523 (dst + length > mBlFlashTable[i].address))) {
524 if (mBlFlashTable[i].type != type)
525 return false;
526 }
527 }
528
529 return blProgramFlash(dst, src, length, key1, key2);
530 }
531
blExtApiProgramSharedArea(uint8_t * dst,const uint8_t * src,uint32_t length,uint32_t key1,uint32_t key2)532 static bool blExtApiProgramSharedArea(uint8_t *dst, const uint8_t *src, uint32_t length, uint32_t key1, uint32_t key2)
533 {
534 return blProgramTypedArea(dst, src, length, BL_FLASH_SHARED, key1, key2);
535 }
536
blExtApiProgramEe(uint8_t * dst,const uint8_t * src,uint32_t length,uint32_t key1,uint32_t key2)537 static bool blExtApiProgramEe(uint8_t *dst, const uint8_t *src, uint32_t length, uint32_t key1, uint32_t key2)
538 {
539 return blProgramTypedArea(dst, src, length, BL_FLASH_EEDATA, key1, key2);
540 }
541
blEraseTypedArea(uint32_t type,uint32_t key1,uint32_t key2)542 static bool blEraseTypedArea(uint32_t type, uint32_t key1, uint32_t key2)
543 {
544 struct StmFlash *flash = (struct StmFlash *)FLASH_BASE;
545 const uint32_t sector_cnt = sizeof(mBlFlashTable) / sizeof(struct blFlashTable);
546 uint32_t i, acr_cache, cr_cache, erase_cnt = 0, int_state = 0;
547 uint8_t erase_mask[sector_cnt];
548
549 for (i = 0; i < sector_cnt; i++) {
550 if (mBlFlashTable[i].type == type) {
551 erase_mask[i] = 1;
552 erase_cnt++;
553 } else {
554 erase_mask[i] = 0;
555 }
556 }
557
558 // disable interrupts
559 // otherwise an interrupt during flash write/erase will stall the processor
560 // until the write/erase completes
561 int_state = blDisableInts();
562
563 // wait for flash to not be busy (should never be set at this point)
564 while (flash->SR & FLASH_SR_BSY);
565
566 cr_cache = flash->CR;
567
568 if (flash->CR & FLASH_CR_LOCK) {
569 // unlock flash
570 flash->KEYR = key1;
571 flash->KEYR = key2;
572 }
573
574 if (flash->CR & FLASH_CR_LOCK) {
575 // unlock failed, restore interrupts
576 blRestoreInts(int_state);
577
578 return false;
579 }
580
581 flash->CR = FLASH_CR_PSIZE(FLASH_CR_PSIZE_8);
582
583 acr_cache = flash->ACR;
584
585 // disable and flush data and instruction caches
586 flash->ACR &= ~(FLASH_ACR_DCEN | FLASH_ACR_ICEN);
587 flash->ACR |= (FLASH_ACR_DCRST | FLASH_ACR_ICRST);
588
589 if (erase_cnt)
590 blEraseSectors(sector_cnt, erase_mask);
591
592 flash->ACR = acr_cache;
593 flash->CR = cr_cache;
594
595 // restore interrupts
596 blRestoreInts(int_state);
597
598 return true; //we assume erase worked
599 }
600
blExtApiEraseSharedArea(uint32_t key1,uint32_t key2)601 static bool blExtApiEraseSharedArea(uint32_t key1, uint32_t key2)
602 {
603 return blEraseTypedArea(BL_FLASH_SHARED, key1, key2);
604 }
605
blVerifyOsUpdate(struct OsUpdateHdr ** start,uint32_t * size)606 static uint32_t blVerifyOsUpdate(struct OsUpdateHdr **start, uint32_t *size)
607 {
608 uint32_t ret;
609 int i;
610
611 for (i = 0; i < BL_SCAN_OFFSET; i += 4) {
612 ret = blVerifyOsImage(__shared_start + i, start, size);
613 if (ret != OS_UPDT_HDR_CHECK_FAILED)
614 break;
615 }
616
617 return ret;
618 }
619
blExtApiVerifyOsUpdate(void)620 static uint32_t blExtApiVerifyOsUpdate(void)
621 {
622 return blVerifyOsUpdate(NULL, NULL);
623 }
624
blSupirousIntHandler(void)625 static void blSupirousIntHandler(void)
626 {
627 //BAD!
628 blExtApiReboot();
629 }
630
blExtApiGetRsaKeyInfo(uint32_t * numKeys)631 static const uint32_t *blExtApiGetRsaKeyInfo(uint32_t *numKeys)
632 {
633 uint32_t numWords = __pubkeys_end - __pubkeys_start;
634
635 if (numWords % RSA_WORDS) // something is wrong
636 return NULL;
637
638 *numKeys = numWords / RSA_WORDS;
639 return __pubkeys_start;
640 }
641
blExtApiSigPaddingVerify(const uint32_t * rsaResult)642 static const uint32_t* blExtApiSigPaddingVerify(const uint32_t *rsaResult)
643 {
644 uint32_t i;
645
646 //all but first and last word of padding MUST have no zero bytes
647 for (i = SHA2_HASH_WORDS + 1; i < RSA_WORDS - 1; i++) {
648 if (!(uint8_t)(rsaResult[i] >> 0))
649 return NULL;
650 if (!(uint8_t)(rsaResult[i] >> 8))
651 return NULL;
652 if (!(uint8_t)(rsaResult[i] >> 16))
653 return NULL;
654 if (!(uint8_t)(rsaResult[i] >> 24))
655 return NULL;
656 }
657
658 //first padding word must have all nonzero bytes except low byte
659 if ((rsaResult[SHA2_HASH_WORDS] & 0xff) || !(rsaResult[SHA2_HASH_WORDS] & 0xff00) || !(rsaResult[SHA2_HASH_WORDS] & 0xff0000) || !(rsaResult[SHA2_HASH_WORDS] & 0xff000000))
660 return NULL;
661
662 //last padding word must have 0x0002 in top 16 bits and nonzero random bytes in lower bytes
663 if ((rsaResult[RSA_WORDS - 1] >> 16) != 2)
664 return NULL;
665 if (!(rsaResult[RSA_WORDS - 1] & 0xff00) || !(rsaResult[RSA_WORDS - 1] & 0xff))
666 return NULL;
667
668 return rsaResult;
669 }
670
671 const struct BlVecTable __attribute__((section(".blvec"))) __BL_VECTORS =
672 {
673 /* cortex */
674 .blStackTop = (uint32_t)&__stack_top,
675 .blEntry = &__blEntry,
676 .blNmiHandler = &blSupirousIntHandler,
677 .blMmuFaultHandler = &blSupirousIntHandler,
678 .blBusFaultHandler = &blSupirousIntHandler,
679 .blUsageFaultHandler = &blSupirousIntHandler,
680
681 /* api */
682 .blGetVersion = &blExtApiGetVersion,
683 .blReboot = &blExtApiReboot,
684 .blGetSnum = &blExtApiGetSnum,
685 .blProgramShared = &blExtApiProgramSharedArea,
686 .blEraseShared = &blExtApiEraseSharedArea,
687 .blProgramEe = &blExtApiProgramEe,
688 .blGetPubKeysInfo = &blExtApiGetRsaKeyInfo,
689 .blRsaPubOpIterative = &rsaPubOpIterative,
690 .blSha2init = &sha2init,
691 .blSha2processBytes = &sha2processBytes,
692 .blSha2finish = &sha2finish,
693 .blAesInitForEncr = &aesInitForEncr,
694 .blAesInitForDecr = &aesInitForDecr,
695 .blAesEncr = &aesEncr,
696 .blAesDecr = &aesDecr,
697 .blAesCbcInitForEncr = &aesCbcInitForEncr,
698 .blAesCbcInitForDecr = &aesCbcInitForDecr,
699 .blAesCbcEncr = &aesCbcEncr,
700 .blAesCbcDecr = &aesCbcDecr,
701 .blSigPaddingVerify = &blExtApiSigPaddingVerify,
702 .blVerifyOsUpdate = &blExtApiVerifyOsUpdate,
703 };
704
blApplyVerifiedUpdate(const struct OsUpdateHdr * os)705 static void blApplyVerifiedUpdate(const struct OsUpdateHdr *os) //only called if an update has been found to exist and be valid, signed, etc!
706 {
707 //copy shared to code, and if successful, erase shared area
708 if (blEraseTypedArea(BL_FLASH_KERNEL, BL_FLASH_KEY1, BL_FLASH_KEY2))
709 if (blProgramTypedArea(__code_start, (const uint8_t*)(os + 1), os->size, BL_FLASH_KERNEL, BL_FLASH_KEY1, BL_FLASH_KEY2))
710 (void)blExtApiEraseSharedArea(BL_FLASH_KEY1, BL_FLASH_KEY2);
711 }
712
blWriteMark(struct OsUpdateHdr * hdr,uint32_t mark)713 static void blWriteMark(struct OsUpdateHdr *hdr, uint32_t mark)
714 {
715 uint8_t dstVal = mark;
716
717 (void)blExtApiProgramSharedArea(&hdr->marker, &dstVal, sizeof(hdr->marker), BL_FLASH_KEY1, BL_FLASH_KEY2);
718 }
719
blUpdateMark(uint32_t old,uint32_t new)720 static void blUpdateMark(uint32_t old, uint32_t new)
721 {
722 struct OsUpdateHdr *hdr = (struct OsUpdateHdr *)__shared_start;
723
724 if (hdr->marker != old)
725 return;
726
727 blWriteMark(hdr, new);
728 }
729
blVerifyOsImage(const uint8_t * addr,struct OsUpdateHdr ** start,uint32_t * size)730 static uint32_t blVerifyOsImage(const uint8_t *addr, struct OsUpdateHdr **start, uint32_t *size)
731 {
732 const uint32_t *rsaKey, *osSigHash, *osSigPubkey, *ourHash, *rsaResult, *expectedHash = NULL;
733 struct OsUpdateHdr *hdr = (struct OsUpdateHdr*)addr;
734 struct OsUpdateHdr cpy;
735 uint32_t i, numRsaKeys = 0, rsaStateVar1, rsaStateVar2, rsaStep = 0;
736 const uint8_t *updateBinaryData;
737 bool isValid = false;
738 struct Sha2state sha;
739 struct RsaState rsa;
740 uint32_t ret = OS_UPDT_HDR_CHECK_FAILED;
741 const uint32_t overhead = sizeof(*hdr) + 2 * RSA_WORDS;
742
743 // header does not fit or is not aligned
744 if (addr < __shared_start || addr > (__shared_end - overhead) || ((uintptr_t)addr & 3))
745 return OS_UPDT_HDR_CHECK_FAILED;
746
747 // image does not fit
748 if (hdr->size > (__shared_end - addr - overhead))
749 return OS_UPDT_HDR_CHECK_FAILED;
750
751 // OS magic does not match
752 if (memcmp(hdr->magic, mOsUpdateMagic, sizeof(hdr->magic)) != 0)
753 return OS_UPDT_HDR_CHECK_FAILED;
754
755 // we don't allow shortcuts on success path, but we want to fail quickly
756 if (hdr->marker == OS_UPDT_MARKER_INVALID)
757 return OS_UPDT_HDR_MARKER_INVALID;
758
759 // download did not finish
760 if (hdr->marker == OS_UPDT_MARKER_INPROGRESS)
761 return OS_UPDT_HDR_MARKER_INVALID;
762
763 //get pointers
764 updateBinaryData = (const uint8_t*)(hdr + 1);
765 osSigHash = (const uint32_t*)(updateBinaryData + hdr->size);
766 osSigPubkey = osSigHash + RSA_WORDS;
767
768 //make sure the pub key is known
769 for (i = 0, rsaKey = blExtApiGetRsaKeyInfo(&numRsaKeys); i < numRsaKeys; i++, rsaKey += RSA_WORDS) {
770 if (memcmp(rsaKey, osSigPubkey, RSA_BYTES) == 0)
771 break;
772 }
773
774 if (i == numRsaKeys) {
775 ret = OS_UPDT_UNKNOWN_PUBKEY;
776 //signed with an unknown key -> fail
777 goto fail;
778 }
779
780 //decode sig using pubkey
781 do {
782 rsaResult = rsaPubOpIterative(&rsa, osSigHash, osSigPubkey, &rsaStateVar1, &rsaStateVar2, &rsaStep);
783 } while (rsaStep);
784
785 if (!rsaResult) {
786 //decode fails -> invalid sig
787 ret = OS_UPDT_INVALID_SIGNATURE;
788 goto fail;
789 }
790
791 //verify padding
792 expectedHash = blExtApiSigPaddingVerify(rsaResult);
793
794 if (!expectedHash) {
795 //padding check fails -> invalid sig
796 ret = OS_UPDT_INVALID_SIGNATURE_HASH;
797 goto fail;
798 }
799
800 //hash the update
801 sha2init(&sha);
802
803 memcpy(&cpy, hdr, sizeof(cpy));
804 cpy.marker = OS_UPDT_MARKER_INPROGRESS;
805 sha2processBytes(&sha, &cpy, sizeof(cpy));
806 sha2processBytes(&sha, (uint8_t*)(hdr + 1), hdr->size);
807 ourHash = sha2finish(&sha);
808
809 //verify hash match
810 if (memcmp(expectedHash, ourHash, SHA2_HASH_SIZE) != 0) {
811 //hash does not match -> data tampered with
812 ret = OS_UPDT_INVALID_SIGNATURE_HASH; // same error; do not disclose nature of hash problem
813 goto fail;
814 }
815
816 //it is valid
817 isValid = true;
818 ret = OS_UPDT_SUCCESS;
819 if (start)
820 *start = hdr;
821 if (size)
822 *size = hdr->size;
823
824 fail:
825 //mark it appropriately
826 blWriteMark(hdr, isValid ? OS_UPDT_MARKER_VERIFIED : OS_UPDT_MARKER_INVALID);
827 return ret;
828 }
829
blUpdateVerify()830 static inline bool blUpdateVerify()
831 {
832 return blVerifyOsImage(__shared_start, NULL, NULL) == OS_UPDT_SUCCESS;
833 }
834
blSpiLoaderDrainRxFifo(struct StmSpi * spi)835 static void blSpiLoaderDrainRxFifo(struct StmSpi *spi)
836 {
837 (void)spi->DR;
838 while (!(spi->SR & 1));
839 (void)spi->DR;
840 }
841
blSpiLoaderTxRxByte(struct StmSpi * spi,uint32_t val)842 static uint8_t blSpiLoaderTxRxByte(struct StmSpi *spi, uint32_t val)
843 {
844 while (!(spi->SR & 2));
845 spi->DR = val;
846 while (!(spi->SR & 1));
847 return spi->DR;
848 }
849
blSpiLoaderTxBytes(struct StmSpi * spi,const void * data,uint32_t len)850 static void blSpiLoaderTxBytes(struct StmSpi *spi, const void *data, uint32_t len)
851 {
852 const uint8_t *buf = (const uint8_t*)data;
853
854 blSpiLoaderTxRxByte(spi, len - 1);
855 while (len--)
856 blSpiLoaderTxRxByte(spi, *buf++);
857 }
858
blSpiLoaderSendSyncOut(struct StmSpi * spi)859 static bool blSpiLoaderSendSyncOut(struct StmSpi *spi)
860 {
861 return blSpiLoaderTxRxByte(spi, BL_SYNC_OUT) == BL_SYNC_IN;
862 }
863
blSpiLoaderSendAck(struct StmSpi * spi,bool ack)864 static bool blSpiLoaderSendAck(struct StmSpi *spi, bool ack)
865 {
866 blSpiLoaderTxRxByte(spi, 0);
867 blSpiLoaderTxRxByte(spi, ack ? BL_ACK : BL_NAK);
868 return blSpiLoaderTxRxByte(spi, 0) == BL_ACK;
869 }
870
blSpiLoader(bool force)871 static void blSpiLoader(bool force)
872 {
873 const uint32_t intInPin = SH_INT_WAKEUP - GPIO_PA(0);
874 struct StmGpio *gpioa = (struct StmGpio*)GPIOA_BASE;
875 struct StmSpi *spi = (struct StmSpi*)SPI1_BASE;
876 struct StmRcc *rcc = (struct StmRcc*)RCC_BASE;
877 uint32_t oldApb2State, oldAhb1State, nRetries;
878 bool seenErase = false;
879 uint32_t nextAddr = 0;
880 uint32_t expectedSize = 0;
881
882 if (SH_INT_WAKEUP < GPIO_PA(0) || SH_INT_WAKEUP > GPIO_PA(15)) {
883
884 //link time assert :)
885 extern void ThisIsAnError_BlIntPinNotInGpioA(void);
886 ThisIsAnError_BlIntPinNotInGpioA();
887 }
888
889 //SPI & GPIOA on
890 oldApb2State = rcc->APB2ENR;
891 oldAhb1State = rcc->AHB1ENR;
892 rcc->APB2ENR |= PERIPH_APB2_SPI1;
893 rcc->AHB1ENR |= PERIPH_AHB1_GPIOA;
894
895 //reset units
896 rcc->APB2RSTR |= PERIPH_APB2_SPI1;
897 rcc->AHB1RSTR |= PERIPH_AHB1_GPIOA;
898 rcc->APB2RSTR &=~ PERIPH_APB2_SPI1;
899 rcc->AHB1RSTR &=~ PERIPH_AHB1_GPIOA;
900
901 //configure GPIOA for SPI A4..A7 for SPI use (function 5), int pin as not func, high speed, no pullups, not open drain, proper directions
902 gpioa->AFR[0] = (gpioa->AFR[0] & 0x0000ffff & ~(0x0f << (intInPin * 4))) | 0x55550000;
903 gpioa->OSPEEDR |= 0x0000ff00 | (3 << (intInPin * 2));
904 gpioa->PUPDR &=~ (0x0000ff00 | (3 << (intInPin * 2)));
905 gpioa->OTYPER &=~ (0x00f0 | (1 << intInPin));
906 gpioa->MODER = (gpioa->MODER & 0xffff00ff & ~(0x03 << (intInPin * 2))) | 0x0000aa00;
907
908 //if int pin is not low, do not bother any further
909 if (!(gpioa->IDR & (1 << intInPin)) || force) {
910
911 //config SPI
912 spi->CR1 = 0x00000040; //spi is on, configured same as bootloader would
913 spi->CR2 = 0x00000000; //spi is on, configured same as bootloader would
914
915 //wait for sync
916 for (nRetries = 10000; nRetries; nRetries--) {
917 if (spi->SR & 1) {
918 if (spi->DR == BL_SYNC_IN)
919 break;
920 (void)spi->SR; //re-read to clear overlfow condition (if any)
921 }
922 }
923
924 //if we saw a sync, do the bootloader thing
925 if (nRetries) {
926 static const uint8_t supportedCmds[] = {BL_CMD_GET, BL_CMD_READ_MEM, BL_CMD_WRITE_MEM, BL_CMD_ERASE, BL_CMD_GET_SIZES, BL_CMD_UPDATE_FINISHED};
927 uint32_t allSizes[] = {__builtin_bswap32(__code_end - __code_start), __builtin_bswap32(__shared_end - __shared_start), __builtin_bswap32(__eedata_end - __eedata_start)};
928 bool ack = true; //we ack the sync
929
930 ack = blSpiLoaderSendSyncOut(spi);
931
932 //loop forever listening to commands
933 while (1) {
934 uint32_t sync, cmd, cmdNot, addr = 0, len, checksum = 0, i;
935 uint8_t data[256];
936
937 //send ack or NAK for last thing
938 if (!blSpiLoaderSendAck(spi, ack))
939 goto out;
940
941 while ((sync = blSpiLoaderTxRxByte(spi, 0)) != BL_SYNC_IN);
942 cmd = blSpiLoaderTxRxByte(spi, 0);
943 cmdNot = blSpiLoaderTxRxByte(spi, BL_ACK);
944
945 ack = false;
946 if (sync == BL_SYNC_IN && (cmd ^ cmdNot) == 0xff) switch (cmd) {
947 case BL_CMD_GET:
948
949 //ACK the command
950 (void)blSpiLoaderSendAck(spi, true);
951
952 blSpiLoaderTxBytes(spi, supportedCmds, sizeof(supportedCmds));
953 ack = true;
954 break;
955
956 case BL_CMD_READ_MEM:
957 if (!seenErase) //no reading till we erase the shared area (this way we do not leak encrypted apps' plaintexts)
958 break;
959
960 //ACK the command
961 (void)blSpiLoaderSendAck(spi, true);
962
963 //get address
964 for (i = 0; i < 4; i++) {
965 uint32_t byte = blSpiLoaderTxRxByte(spi, 0);
966 checksum ^= byte;
967 addr = (addr << 8) + byte;
968 }
969
970 //reject addresses outside of our fake area or on invalid checksum
971 if (blSpiLoaderTxRxByte(spi, 0) != checksum || addr < BL_SHARED_AREA_FAKE_ADDR || addr - BL_SHARED_AREA_FAKE_ADDR > __shared_end - __shared_start)
972 break;
973
974 //ack the address
975 (void)blSpiLoaderSendAck(spi, true);
976
977 //get the length
978 len = blSpiLoaderTxRxByte(spi, 0);
979
980 //reject invalid checksum
981 if (blSpiLoaderTxRxByte(spi, 0) != (uint8_t)~len || addr + len - BL_SHARED_AREA_FAKE_ADDR > __shared_end - __shared_start)
982 break;
983
984 len++;
985
986 //reject reads past the end of the shared area
987 if (addr + len - BL_SHARED_AREA_FAKE_ADDR > __shared_end - __shared_start)
988 break;
989
990 //ack the length
991 (void)blSpiLoaderSendAck(spi, true);
992
993 //read the data & send it
994 blSpiLoaderTxBytes(spi, __shared_start + addr - BL_SHARED_AREA_FAKE_ADDR, len);
995 ack = true;
996 break;
997
998 case BL_CMD_WRITE_MEM:
999 if (!seenErase) //no writing till we erase the shared area (this way we do not purposefully modify encrypted apps' plaintexts in a nefarious fashion)
1000 break;
1001
1002 //ACK the command
1003 (void)blSpiLoaderSendAck(spi, true);
1004
1005 //get address
1006 for (i = 0; i < 4; i++) {
1007 uint32_t byte = blSpiLoaderTxRxByte(spi, 0);
1008 checksum ^= byte;
1009 addr = (addr << 8) + byte;
1010 }
1011
1012 //reject addresses outside of our fake area or on invalid checksum
1013 if (blSpiLoaderTxRxByte(spi, 0) != checksum ||
1014 addr < BL_SHARED_AREA_FAKE_ADDR ||
1015 addr - BL_SHARED_AREA_FAKE_ADDR > __shared_end - __shared_start)
1016 break;
1017
1018 addr -= BL_SHARED_AREA_FAKE_ADDR;
1019 if (addr != nextAddr)
1020 break;
1021
1022 //ack the address
1023 (void)blSpiLoaderSendAck(spi, true);
1024
1025 //get the length
1026 checksum = len = blSpiLoaderTxRxByte(spi, 0);
1027 len++;
1028
1029 //get bytes
1030 for (i = 0; i < len; i++) {
1031 uint32_t byte = blSpiLoaderTxRxByte(spi, 0);
1032 checksum ^= byte;
1033 data[i] = byte;
1034 }
1035
1036 //reject writes that takes out outside fo shared area or invalid checksums
1037 if (blSpiLoaderTxRxByte(spi, 0) != checksum || addr + len > __shared_end - __shared_start)
1038 break;
1039
1040 // OBSOLETE: superseded by sequential contiguous write requirement
1041 //if (addr && addr < sizeof(struct OsUpdateHdr))
1042 // break;
1043
1044 //a write starting at zero must be big enough to contain a full OS update header
1045 if (!addr) {
1046 const struct OsUpdateHdr *hdr = (const struct OsUpdateHdr*)data;
1047
1048 //verify it is at least as big as the header
1049 if (len < sizeof(struct OsUpdateHdr))
1050 break;
1051
1052 //check for magic
1053 for (i = 0; i < sizeof(hdr->magic) && hdr->magic[i] == mOsUpdateMagic[i]; i++);
1054
1055 //verify magic check passed & marker is properly set to inprogress
1056 if (i != sizeof(hdr->magic) || hdr->marker != OS_UPDT_MARKER_INPROGRESS)
1057 break;
1058 expectedSize = sizeof(*hdr) + hdr->size + 2 * RSA_BYTES;
1059 }
1060 if (addr + len > expectedSize)
1061 break;
1062
1063 //do it
1064 ack = blExtApiProgramSharedArea(__shared_start + addr, data, len, BL_FLASH_KEY1, BL_FLASH_KEY2);
1065 blSpiLoaderDrainRxFifo(spi);
1066 nextAddr += len;
1067 break;
1068
1069 case BL_CMD_ERASE:
1070
1071 //ACK the command
1072 (void)blSpiLoaderSendAck(spi, true);
1073
1074 //get address
1075 for (i = 0; i < 2; i++) {
1076 uint32_t byte = blSpiLoaderTxRxByte(spi, 0);
1077 checksum ^= byte;
1078 addr = (addr << 8) + byte;
1079 }
1080
1081 //reject addresses that are not our magic address or on invalid checksum
1082 if (blSpiLoaderTxRxByte(spi, 0) != checksum || addr != BL_SHARED_AREA_FAKE_ERASE_BLK)
1083 break;
1084
1085 //do it
1086 ack = blExtApiEraseSharedArea(BL_FLASH_KEY1, BL_FLASH_KEY2);
1087 if (ack) {
1088 seenErase = true;
1089 nextAddr = 0;
1090 expectedSize = 0;
1091 }
1092 blSpiLoaderDrainRxFifo(spi);
1093 break;
1094
1095 case BL_CMD_GET_SIZES:
1096
1097 //ACK the command
1098 (void)blSpiLoaderSendAck(spi, true);
1099
1100 blSpiLoaderTxBytes(spi, allSizes, sizeof(allSizes));
1101 break;
1102
1103 case BL_CMD_UPDATE_FINISHED:
1104 blUpdateMark(OS_UPDT_MARKER_INPROGRESS, OS_UPDT_MARKER_DOWNLOADED);
1105 ack = blUpdateVerify();
1106 break;
1107 }
1108 }
1109 }
1110 }
1111
1112 out:
1113 //reset units & return APB2 & AHB1 to initial state
1114 rcc->APB2RSTR |= PERIPH_APB2_SPI1;
1115 rcc->AHB1RSTR |= PERIPH_AHB1_GPIOA;
1116 rcc->APB2RSTR &=~ PERIPH_APB2_SPI1;
1117 rcc->AHB1RSTR &=~ PERIPH_AHB1_GPIOA;
1118 rcc->APB2ENR = oldApb2State;
1119 rcc->AHB1ENR = oldAhb1State;
1120 }
1121
__blEntry(void)1122 void __blEntry(void)
1123 {
1124 extern char __bss_end[], __bss_start[], __data_end[], __data_start[], __data_data[];
1125 uint32_t appBase = ((uint32_t)&__code_start) & ~1;
1126 bool forceLoad = false;
1127
1128 //make sure we're the vector table and no ints happen (BL does not use them)
1129 blDisableInts();
1130 SCB->VTOR = (uint32_t)&BL;
1131
1132 //init things a little for the higher levels
1133 memset(__bss_start, 0, __bss_end - __bss_start);
1134 memcpy(__data_start, __data_data, __data_end - __data_start);
1135
1136 //say hello
1137 blLog("NanohubOS bootloader up @ %p\n", &__blEntry);
1138
1139 //enter SPI loader if requested
1140 do {
1141 uint32_t res;
1142 struct OsUpdateHdr *os;
1143
1144 blSpiLoader(forceLoad);
1145 res = blVerifyOsUpdate(&os, NULL);
1146 if (res == OS_UPDT_SUCCESS)
1147 blApplyVerifiedUpdate(os);
1148 else if (res != OS_UPDT_HDR_CHECK_FAILED)
1149 blExtApiEraseSharedArea(BL_FLASH_KEY1, BL_FLASH_KEY2);
1150
1151 forceLoad = true;
1152 } while (*(volatile uint32_t*)appBase == 0xFFFFFFFF);
1153
1154 //call main app with ints off
1155 blDisableInts();
1156 SCB->VTOR = appBase;
1157 asm volatile(
1158 "LDR SP, [%0, #0] \n"
1159 "LDR PC, [%0, #4] \n"
1160 :
1161 :"r"(appBase)
1162 :"memory", "cc"
1163 );
1164
1165 //we should never return here
1166 while(1);
1167 }
1168