piątek, 6 kwietnia 2018

LPC1769 - Ustawianie mechanizmu CRP

W tym poście chciałbym opisać sposób ustawienia mechanizmu CRP w mikrokontrolerze LPC1769.

Znalezione obrazy dla zapytania lpc1769
[Źródło: https://www.nxp.com]



Opis CRP:


Mechanizm CRP (Code Read Protection) zabezpiecza dostęp do mikrokontrolera wyłączając mu opcje zapisu bądź odczytu przez określone źródła dostępu.

Dostępne są trzy poziomy ustawień:

CRP1 - wyłączenie opcji dostępu przez SWD oraz odczytanie kodu.
CRP2 - wyłaczenie SWD, odczytania kodu oraz wyczyszczenie poszczególnych sektorów.
CRP3 - wszystkie możliwości dostępu są zablokowane
NO_ISP - dodatkowy tryb zostawiający tylko dostęp przez SWD

Obraz z dokumentacji, obrazujący powyższy opis:


Dokładny opis tryb jak i całego mechanizmu można znaleźć w dokumentacji od NXP.

Pliki:


Pliki poniżej zostały przygotowane przez firmę NXP i w zależności od wykorzystywanych bibliotek mogą być domyślnie niedostępne. Można je też znaleźć w projektach użytkowników w serwisie GitHub.

Plik crp.h:

  1. /****************************************************************************
  2.  *   Description:
  3.  *     Code Read Protection macros
  4.  ****************************************************************************
  5.  * Software that is described herein is for illustrative purposes only
  6.  * which provides customers with programming information regarding the
  7.  * products. This software is supplied "AS IS" without any warranties.
  8.  * NXP Semiconductors assumes no responsibility or liability for the
  9.  * use of the software, conveys no license or title under any patent,
  10.  * copyright, or mask work right to the product. NXP Semiconductors
  11.  * reserves the right to make changes in the software without
  12.  * notification. NXP Semiconductors also make no representation or
  13.  * warranty that such application will be suitable for the specified
  14.  * use without further testing or modification.
  15. ****************************************************************************/
  16. #ifndef _CRP_H_INCLUDED_
  17. #define _CRP_H_INCLUDED_
  18. // A macro for placing data into the Code Read Protect (CRP) section,
  19. // which is then located at the correct address for the selected MCU
  20. // by the automatically generated linker script. The CRP section should
  21. // contain a single 32-bit value which is the CRP value. See appropriate
  22. // documentation for the MCU to determine CRP values.
  23. //
  24. // This feature is only available for NXP MCU targets with the Code Read
  25. // Protect Feature
  26. //
  27. // Example:
  28. //        __CRP const uint32_t CRP_WORD = CRP_NO_CRP ;
  29. //
  30. #define __CRP __attribute__ ((used,section(".crp")))
  31. #define CRP_NO_CRP          0xFFFFFFFF
  32. // Disables UART and USB In System Programming (reads and writes)
  33. // Leaves SWD debugging, with reads and writes, enabled
  34. #define CRP_NO_ISP    0x4E697370
  35. // Disables SWD debugging & JTAG, leaves ISP with with reads and writes enabled
  36. // You will need UART connectivity and FlashMagic (flashmagictool.com) to reverse
  37. // this. Don't even try this without these tools; most likely the SWD flash
  38. // programming will not even complete.
  39. // Allows reads and writes only to RAM above 0x10000300 and flash other than
  40. // sector 0 (the first 4 kB). Full erase also allowed- again only through UART
  41. // and FlashMagic (NO JTAG/SWD)
  42. #define CRP_CRP1      0x12345678
  43. // Disables SWD debugging & JTAG, leaves UART ISP with with only full erase
  44. // enabled. You must have UART access and FlashMagic before setting this
  45. // option.
  46. // Don't even try this without these tools; most likely the SWD flash
  47. // programming will not even complete.
  48. #define CRP_CRP2      0x87654321
  49. /************************************************************/
  50. /**** DANGER CRP3 WILL LOCK PART TO ALL READS and WRITES ****/
  51. #define CRP_CRP3_CONSUME_PART 0x43218765
  52. /************************************************************/
  53. # define CONFIG_CRP_SETTING_CRP1  1
  54. #if CONFIG_CRP_SETTING_NO_CRP == 1
  55. #define CURRENT_CRP_SETTING CRP_NO_CRP
  56. #endif
  57. #if CONFIG_CRP_SETTING_NOISP == 1
  58. #define CURRENT_CRP_SETTING CRP_NO_ISP
  59. #endif
  60. #if CONFIG_CRP_SETTING_CRP1 == 1
  61. #define CURRENT_CRP_SETTING CRP_CRP1
  62. #endif
  63. #if CONFIG_CRP_SETTING_CRP2 == 1
  64. #define CURRENT_CRP_SETTING CRP_CRP2
  65. #endif
  66. #if CONFIG_CRP_SETTING_CRP3_CONSUME_PART == 1
  67. #define CURRENT_CRP_SETTING CRP_CRP3_CONSUME_PART
  68. #endif
  69. #ifndef CURRENT_CRP_SETTING
  70. #define CURRENT_CRP_SETTING CRP_NO_CRP
  71. #endif
  72. #endif /* _CRP_H_INCLUDED_ */

Plik crp.c:

  1. #include <crp.h>
  2. // Variable to store CRP value in. Will be placed automatically
  3. // by the linker when "Enable Code Read Protect" selected.
  4. // See crp.h header for more information
  5. __CRP const unsigned int CRP_WORD = CRP_CRP2;

W pliku crp.c wybiera się ustawienia blokowania. Dla uzyskania pełnego dostępu należy ustawić CRP_WORD jako CRP_NO_CRP.

LPCExpresso ustawienia:


Samo dodanie plików nie wprowadzi zabezpieczenia układu. W tym celu należy zmodyfikować ustawienia projektu (Settings -> Managed Linker Script) i zaznaczyć Enable Code Read Protection.
Dopiero to ustawienie spowoduje egzekwowanie wpisywanych ustawień CRP.


Programowanie:


Ustawienie CRP1 w programie na niezabezpieczony procesor pozwala na wgranie danych przez SWD (LPC_Link2). Natomiast gdy wgrywa się dane na procesor z ustawionym CRP1 to wyświetli się następująca informacja:


Podobna sytuacja dotyczy opcji Debug:


Przejdźmy do programu Flash Magic. Najpierw próba odczytu przez LPC_Link2:


Nie ma możliwości dostępu przez SWD z jakiegokolwiek programu do mikrokontrolera. Wobec tego należy przesiąść się na ISP( UART0). 


Tutaj jak widać możliwa jest komunikacja. Natomiast możliwość odczytu pamięci została zablokowana:


Można za to wykorzystać opcje Blank Check:


Jest ona blokowana dla trybu CRP2.

Przez program Flash Magic można wgrać bądź usunąć program całkowicie z układu. Nie ma natomiast możliwości odczytu zawartości mikrokontrolera. 

W przypadku potrzeby zmiany programu należy zmodyfikować ustawienia CRP_WORD i wgrać nowy projekt przez Flash Magic. To pozwoli na powrót do normalnej pracy tzn. z trybem Debug oraz programatorem SWD.

Najbezpieczniej jest ustawić poziom blokowania na maksymalnie CRP2. Dzięki temu gdy nastąpi potrzeba aktualizacji oprogramowania to bez problemów będzie można to wykonać przez Flash Magic. 

Wersja programu:


Należy także pamiętać o udostępnianiu w końcowej wersji programu kompilacji jako Release a nie Debug. Ponieważ ta ostania będzie zawierać w pamięci procesora pełną tablicę zmiennych oraz symboli. Która w przypadku złamania zabezpieczeń jest podana na tacy.