STM32 BootLoader 刷新项目 (八) 读取Flash保护ROP-0x54

news/2024/11/8 9:59:23/

STM32 BootLoader 刷新项目 (八) 读取Flash保护ROP-0x54

下面我们来介绍一下BootLoader一上电对芯片Option Byte操作的过程,Option Byte可以配置的功能包括**Read protection (RDP) **读出保护级别,**BOR级别(Brown-out Reset)**设置电压阈值,看门狗配置Flash写保护

在当今竞争激烈的市场中,软件供应商们正致力于开发具有自主知识产权的软件产品,尤其是那些在嵌入式系统中扮演关键角色的中间件产品。这些产品不仅需要具备高性能和稳定性,还需要确保其知识产权得到充分保护,以防止非法复制和滥用。随着基于微处理器的嵌入式产品对知识产权保护的需求日益增长,保护这些核心资产已成为供应商们的首要任务。

为了应对这一挑战,STM32系列微控制器(MCU)提供了一系列的安全特性,以帮助保护产品的知识产权。以下是STM32 MCU在知识产权保护方面的一些关键特性:

  1. Read Protection (RDP):这是一种全面的芯片级保护机制,可以防止未经授权的读取操作。RDP能够限制对整个芯片的访问,包括Flash存储器、SRAM以及其他关键寄存器,确保只有授权的用户能够访问这些资源。

  2. Write Protection:为了防止意外或恶意的擦除和编程操作,STM32 MCU提供了写保护功能。这项功能可以锁定Flash存储器的特定区域,防止未授权的写入,从而保护固件和配置数据不被篡改。

  3. Proprietary Code Read Out Protection (PCROP):这是一种更为精细的保护机制,专门设计用来保护存储在Flash中的专有代码。与RDP不同,PCROP允许对Flash的特定区域进行读写保护,而不是整个芯片。这样,供应商可以保护包含关键算法和知识产权的代码段,同时仍然允许其他区域的代码进行正常的读写操作,便于进行后续的二次开发和维护。

PCROP的引入为STM32 MCU的用户带来了更多的灵活性和安全性。通过将关键代码放置在受PCROP保护的区域,供应商可以确保这些代码不会被轻易读取或复制,从而保护其知识产权不受侵犯。此外,PCROP还支持对代码的执行,这意味着受保护的代码可以被执行,但无法被读取或修改,这为嵌入式系统的安全性提供了额外的保障。

ST公司在其多个STM32产品系列中都集成了PCROP功能,包括但不限于STM32L1、STM32F4、STM32L4、STM32F7和STM32H7等。这些产品线的广泛支持表明了ST公司对于知识产权保护的重视,以及其在提供安全解决方案方面的承诺。

为了充分利用这些保护机制,软件供应商需要在设计和开发过程中采取相应的措施。这包括在编译和编程阶段正确配置RDP和PCROP,以及在产品发布前进行彻底的安全测试。通过这些努力,供应商可以确保他们的产品在面对日益复杂的安全威胁时,仍然能够保持其知识产权的安全和完整。

image-20241107071829974

1. Option Byte介绍

STM32F407的Option Byte是STM32微控制器内部Flash中的一块特殊区域,用于存放一些配置信息。这些配置信息在每次上电复位时通过Option Byte Loader (OBL)读取,并写入到Flash的5个寄存器中,从而影响微控制器的行为。以下是STM32F407 Option Byte的一些详细介绍:

  1. Option Byte区域位置:Option Byte位于STM32内部Flash的0x1FFF 7800地址处。

  2. Option Byte的作用机制:每次上电复位时,微控制器会自动读取Option Byte区域的配置,并将其加载到特定的寄存器中,从而影响系统的行为。

  3. Option Byte的配置内容:Option Byte可以配置的项目包括:

    • 读出保护级别(RDP):可以设置不同的读出保护级别,以保护程序不被非法读取或篡改。
    • BOR级别(Brown-out Reset):设置电压阈值,当电源电压下降到该阈值以下时,微控制器会自动复位。
    • 看门狗配置:可以选择硬件看门狗或软件看门狗,并配置看门狗的行为。
    • IWDG和WWDG的启动模式:配置看门狗在sleep/stop/standby模式下是否关闭。
    • Flash写保护:可以设置Flash的写保护区域,防止非法写入。
  4. 编程Option Byte:编程Option Byte需要谨慎,因为一旦写入,更改较为困难。通常需要使用STM32的HAL库函数或直接操作Flash寄存器来完成。

  5. Option Byte的安全性:Option Byte提供了一种保护机制,可以锁定微控制器,防止未授权的读取和写入,这对于保护知识产权和系统安全非常重要。

  6. RDP的回归:如果需要从较高的读出保护级别降低到较低级别,会触发一次全Flash的擦除,因此在实施RDP回归功能时需要特别注意。

以上是STM32F407 Option Byte的一些基本介绍和配置信息,具体的配置方法和细节可以参考STM32F407的官方参考手册。

image-20241105212018459image-20241105212129080

2. ROP 读保护Read protection

STM32F407的Option Byte中的RDP(Read-out Protection)是用于保护微控制器内部Flash存储器不被非法读取的一种安全特性。以下是RDP的详细介绍:

  1. RDP保护级别

    • Level 0(无保护):RDP设置为0xAA时,没有启用读出保护。这是默认的设置,允许对内部Flash和备份SRAM的完整访问权限,包括通过调试接口的访问。
    • Level 1(使能读写保护):除了内部Flash自举的情况外,任何尝试从外部访问内部Flash和备份SRAM的操作都被禁止,包括使用调试器或从内部SRAM自举时的读写和擦除操作。如果需要从Level 1降级到Level 0,需要将RDP重新设置为0xAA,但这会导致内部Flash和备份SRAM的内容被自动擦除,因此原Flash中的代码会丢失。
    • Level 2(禁止调试):这是最高级别的读保护,一旦设置,无法再降级。它会永久禁止用于调试的JTAG接口,相当于物理熔断。设置为0xCC时,启用Level 2保护。
  2. RDP的配置和修改

    • 要修改RDP的值,需要通过编程Option Byte来实现。这通常涉及到擦除Option Byte区域,然后写入新的RDP值。需要注意的是,一旦RDP被设置为非0xAA的值,就启用了读保护,此时无法通过调试接口访问内部Flash和备份SRAM。
    • 在降级RDP级别时,从Level 1降到Level 0会导致内部Flash和备份SRAM的内容被擦除,因此这是一个不可逆的过程,需要谨慎操作。
  3. RDP的安全性

    • RDP提供了一种防止未经授权的代码读取和复制的机制,这对于保护知识产权和系统安全至关重要。在产品发布时,启用RDP可以防止竞争对手或恶意用户通过读取Flash内容来复制或篡改程序。
  4. RDP的注意事项

    • 在编程Option Byte后,需要重启微控制器以使新的RDP设置生效。一旦RDP被设置为Level 1或Level 2,就无法再通过调试接口进行访问,除非降级到Level 0,但这样做会丢失所有内部Flash的内容。

image-20241105212554571

剩下还有STM32的其他Option Byte介绍,由于和本篇文章的内容不相关,后续大家可以自己阅读芯片手册。

3. 命令0x54介绍

在本篇文章,我们的主要是介绍0x54的命令,这个命令主要是读取STM32目前flash的保护等级。

通过上位机发送6 Byte的数据,其中第1 Byte为整个数据的长度,第2Byte为指令码,第3-6 Byte为前2个Byte的CRC校验值。上位机通过串口UART发送给下位机,下位机回复RDP 读保护的状态。

image-20241106075654092

下面是整个程序执行读取RDP命令的流程图:

BootLoader_Flow_RDP_0x54

4. 程序设计

下面我们来进行程序设计,下面是读取上位机指令,并解析指令的过程,通过switch case判断执行哪种命令。

void  bootloader_uart_read_data(void)
{uint8_t rcv_len=0;printmsg_Host("BL_DEBUG_MSG: Receive CMD\n\r");while (1){HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);memset(bl_rx_buffer, 0, 200);//here we will read and decode the commands coming from host//first read only one byte from the host , which is the "length" field of the command packetHAL_UART_Receive(C_UART,bl_rx_buffer,1,HAL_MAX_DELAY);rcv_len= bl_rx_buffer[0];HAL_UART_Receive(C_UART,&bl_rx_buffer[1],rcv_len,HAL_MAX_DELAY);switch(bl_rx_buffer[1]){case BL_GET_VER:bootloader_handle_getver_cmd(bl_rx_buffer);break;case BL_GET_HELP:bootloader_handle_gethelp_cmd(bl_rx_buffer);break;case BL_GET_CID:bootloader_handle_getcid_cmd(bl_rx_buffer);break;case BL_GET_RDP_STATUS:bootloader_handle_getrdp_cmd(bl_rx_buffer);break;default:printmsg("BL_DEBUG_MSG:Invalid command code received from host \n");break;}}
}

下面是过去rdp保护的函数,如果CRC校验正确,则进入到get_flash_rdp_level()的函数,获取RDP的Level。

/*Helper function to handle BL_GET_RDP_STATUS command */
void bootloader_handle_getrdp_cmd(uint8_t *pBuffer)
{uint8_t rdp_level = 0x00;printmsg("BL_DEBUG_MSG:bootloader_handle_getrdp_cmd\n");//Total length of the command packetuint32_t command_packet_len = bl_rx_buffer[0] + 1 ;//extract the CRC32 sent by the Hostuint32_t host_crc = *((uint32_t * ) (bl_rx_buffer + command_packet_len - 4) ) ;if (! bootloader_verify_crc(&bl_rx_buffer[0], command_packet_len-4, host_crc)){printmsg("BL_DEBUG_MSG:checksum success !!\n");bootloader_send_ack(pBuffer[0], 1);rdp_level = get_flash_rdp_level();printmsg("BL_DEBUG_MSG:RDP level: %d %#x\n",rdp_level,rdp_level);bootloader_uart_write_data(&rdp_level, 1);}else{printmsg("BL_DEBUG_MSG:checksum fail !!\n");bootloader_send_nack();}
}

下面是读取Option Byte的0x1FFFC000地址的高八位,其为RDP Level的等级。

/*This function reads the RDP ( Read protection option byte) value*For more info refer "Table 9. Description of the option bytes" in stm32f446xx RM*/
uint8_t get_flash_rdp_level(void)
{uint8_t rdp_status=0;volatile uint32_t *pOB_addr = (uint32_t*) 0x1FFFC000;rdp_status =  (uint8_t)(*pOB_addr >> 8) ;return rdp_status;
}

5. 实操演练

下面是上位机的命令菜单,上位机链接下位机的串口号,即可进入命令界面:

image-20240713104433991

在上位机中输入命令4,即为获取RDP状态命令0x54,MCU根据读取Option Byte中0x1FFF C000地址中的值,来告诉上位机当前读保护处于什么状态,由下图可以看出,当前状态为0xAA,处于为保护状态。

image-20241107080747434

5. 系列文章

STM32 BootLoader 刷新项目 (一) STM32CubeMX UART串口通信工程搭建

STM32 BootLoader 刷新项目 (二) 方案介绍

STM32 BootLoader 刷新项目 (三) 程序框架搭建及刷新演示

STM32 BootLoader 刷新项目 (四) 通信协议

STM32 BootLoader 刷新项目 (五) 获取软件版本号-命令0x51

STM32 BootLoader 刷新项目 (六) 获取帮助-命令0x52

STM32 BootLoader 刷新项目 (七) 获取芯片ID-0x53


http://www.ppmy.cn/news/1545327.html

相关文章

# SpringMVC学习

SpringMVC 1、SpringMVC是什么? SpringMVC 是 Spring 框架的一个模块,专门用于构建 Web 应用程序。它基于 Model-View-Controller (MVC) 设计模式,帮助开发者将应用程序的不同部分(模型、视图和控制器)分离&#xff…

人工智能:重塑生活与工作的神奇力量

人工智能,宛如一颗璀璨的科技之星,正以燎原之势改变着世界。从医疗到企业,从生活点滴到出行方式,它无处不在。 在医疗领域,诊断疾病不再仅仅依靠医生的经验。AI 系统能够快速分析大量的病例数据,识别出细微…

“农田奇迹:如何用遥感技术实现作物分类与产量精准估算“

在科技飞速发展的时代,遥感数据的精准分析已经成为推动各行业智能决策的关键工具。从无人机监测农田到卫星数据支持气候研究,空天地遥感数据正以前所未有的方式为科研和商业带来深刻变革。然而,对于许多专业人士而言,如何高效地处…

Python配合Flask搭建简单的个人博客案例demo

开发一个简单的博客网站使用 Python,通常可以选择一些流行的 web 框架,如 Flask 或 Django。下面我将以 Flask 为例,带你开发一个简单的博客网站。 环境准备: Flask 非常适合构建轻量级的博客网站,如果想要更多功能&am…

「C/C++」C/C++ 之 变量作用域详解

✨博客主页何曾参静谧的博客📌文章专栏「C/C」C/C程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…

Transformer和BERT的区别

Transformer和BERT的区别比较表: 两者的位置编码: 为什么要对位置进行编码? Attention提取特征的时候,可以获取全局每个词对之间的关系,但是并没有显式保留时序信息,或者说位置信息。就算打乱序列中token…

Fork突然报错

现象: Could not resolve hostname github.com: No address associated with hostname fatal: Could not read from remote repository. 原因:需要为fork设置代理 步骤: 1.通过winR输入%localappdata%\fork\gitInstance打开文件夹 2.找到…

【功能介绍】信创终端系统上各WPS版本的授权差异

原文链接:【功能介绍】信创终端系统上各WPS版本的授权差异 Hello,大家好啊!今天给大家带来一篇关于信创终端操作系统上WPS Office各版本(不包括政务版、企业版等)之间的差异的文章。WPS Office作为国内广泛使用的办公软…