首页 > 其他分享 >H7-TOOL脱机烧录的UID加密操作方法,支持一键生成目标板C代码,方便大家轻松操作(2024-08-20,已发布)

H7-TOOL脱机烧录的UID加密操作方法,支持一键生成目标板C代码,方便大家轻松操作(2024-08-20,已发布)

时间:2024-08-22 21:17:33浏览次数:12  
标签:烧录 20 UID RNG uint8 uid 加密 define

UID加密使用比较方便,对应的C代码模板已经做好,使用TOOL上位机生成后,直接复制粘贴到自己的工程即可使用。返回1表示解密成功,返回0表示失败。

【UID加密原理】

1、烧录器在烧录芯片时,按照指定的算法将UID码编码为一个加密数据,并写入FLASH指定区域。
2、用户的程序必须增加一段UID校验程序比较UID和加密数据是否满足算法规则,不满足则停止运行或呈现随机错误。
3、用户程序只要进行了UID加密,就可以防止初级盗版者直接复制程序到其他芯片。
4、用户可以自行修改加密算法,以增加保密性。

点击上位机这个按钮可以查看了解:


【UID界面功能介绍】


1、算法公式

当前做了三个
(1)encrypt_001.lua,  这个最安全,对UID做了各种加密,当前支持的一键C文件生成也是基于这个制作,大家配置的时候要选择这个选项
(2)encrypt_copy_uid.lua, 这个最简单,就是单纯的读取UID,未对UID做加密处理。
(3)encrypt_crc32_uid.lua, 这个是对UID做了简单的CRC32方式加密。

本贴的实现是基于第1中UID加密,实际应用也推荐用这种。


2、参数名A1 -A16,每个参数值范围1 - 16
 

这里默认即可,一般无需修改


3、选择算法随机数

这个的对应关系是这样的,  一个选项对应一个:


4、算法函数用的常量

这里是8bit的hex,推荐配置8个值即可,  每个值范围0x00 - 0xFF


5、随机数

随机数1,随机数2,随机数3,随机数4设置都是一样的

以随机数1为例进行说明,可以设置跟随那个分区一起写入

这里的分区是跟前面这里分区对应的:

长度推荐就设置为默认的4,而写入地址,可以根据自己的需要设置。


6、UID加密启用

可以设置跟随那个分区一起写入,与前面第5步的含义一样

长度推荐就设置为默认的4,而写入地址,可以根据自己的需要设置。


【实际操作举例】

使用H7-TOOL给我们的STM32H7开发板加密为例进行说明

1、选择脱机烧录的芯片型号,优先配置UID,生成UID加密算法的C实现


2、点击这里生成C算法:

#include <stdio.h>
#include <stdlib.h>
#include "stdint.h"
#include <string.h>
 
/*
*********************************************************************************************************
*                                           定义
*********************************************************************************************************
*/
typedef struct {
    uint32_t enable;  // 使能位
    uint32_t address; // 存储地址
    uint32_t length;  // 随机数长度
} RNG_TAB_t;
 
uint8_t UidArray[16] = {0};
uint8_t EncryptUidArray[16] = {0};
uint8_t ReEncryptUidArray[16] = {0};
 
/*
*********************************************************************************************************
*                                 通过上位机更新,与上位机保持一致
*********************************************************************************************************
*/
 
/*--PC_DEFINE_BEGIN--*/
 
#define A1   1
#define A2   2
#define A3   3
#define A4   4
#define A5   5
#define A6   6
#define A7   7
#define A8   8
#define A9   9
#define A10   10
#define A11   11
#define A12   12
#define A13   13
#define A14   14
#define A15   15
#define A16   16
 
#define ENCRYPT_ADDR     0x08100000  //UID加密数据存储地址
#define ENCRYPT_LEN      8 //加密结果长度
 
#define ENCRYPT_RND_IDX  0   //加密用初值选择 0:固定数,1-4是随机数
#define RNG_CONST_DATA = "11 22 33 44 55 66 77 88"   //常量值
#define RNG_TAB_t RNG_TAB = {     //使能位, 存储地址, 随机数长度
    {0, 0x08000000, 4},
    {0, 0x08000000, 4},
    {0, 0x08000000, 4},
    {0, 0x08000000, 4}
};
 
#define UID_ADDR  0x1FF1E800
#define UID_BYTES 12
 
 
/*--PC_DEFINE_END--*/
 
/*
*********************************************************************************************************
*                                             UID相关API
*********************************************************************************************************
*/
static uint8_t stringToHexArray(const char *str, uint8_t *hexArray) 
{
    uint32_t  index = 0;
 
    while (*str != '\0') 
        {
        while (*str == ' ') 
        {
            str++;
        }
                 
        if (*str == '\0') 
        {
            break;
        }
 
        sscanf(str, "%2hhx", &hexArray[index++]);
 
        str += 2;
    }
         
        return index;
}
 
/*
*********************************************************************************************************
*        函 数 名: encrypt
*        功能说明: 计算UID加密
*        形    参: ---
*        返 回 值: 无
*********************************************************************************************************
*/
static void encrypt(const uint8_t* _uid, const uint8_t* _rnd, uint8_t _rndsize, uint8_t* out) 
{
    uint8_t uid[16] = {0};
    uint8_t rnd[16] = {0};
    int i, j;
 
    if (_uid == NULL) 
        {
        return;
    }
 
    for (i = 0; i < UID_BYTES; i++) 
        {
        uid[i] = _uid[i];
    }
 
    j = 0;
    for (i = UID_BYTES; i < 16; i++) 
        {
        uid[i] = uid[j++];
    }
 
    if (_rnd != NULL) 
        {
        for (i = 0; i < _rndsize; i++) 
                {
            rnd[i] = _rnd[i];
        }
    }
 
    out[0] = uid[A1 - 1] ^ (uid[A2 - 1] >> 1) ^ (uid[A3 - 1] >> 1);
    out[1] = uid[A4 - 1] ^ (uid[A5 - 1] >> 0) ^ (uid[A6 - 1] >> 1);
    out[2] = uid[A7 - 1] ^ (uid[A8 - 1] >> 1) ^ (uid[A9 - 1] >> 3);
    out[3] = uid[A10 - 1] ^ (uid[A11 - 1] >> 2) ^ (uid[A12 - 1] >> 0);
 
    out[4] = uid[A1 - 1] ^ (uid[A10 - 1] << 1) ^ (uid[A2 - 1] >> 0);
    out[5] = uid[A4 - 1] ^ (uid[A7 - 1] << 1) ^ (uid[A5 - 1] << 2);
    out[6] = uid[A7 - 1] ^ (uid[A4 - 1] >> 0) ^ (uid[A8 - 1] << 0);
    out[7] = uid[A10 - 1] ^ (uid[A1 - 1] >> 2) ^ (uid[A11 - 1] << 1);
 
    out[8] = uid[A2 - 1] ^ (uid[A10 - 1] >> 1);
    out[9] = uid[A3 - 1] ^ (uid[A7 - 1] << 1);
    out[10] = uid[A6 - 1] ^ (uid[A4 - 1] << 1);
    out[11] = uid[A9 - 1] ^ (uid[A1 - 1] >> 2);
 
    out[12] = uid[A1 - 1] ^ (uid[A2 - 1] >> 1);
    out[13] = uid[A3 - 1] ^ (uid[A5 - 1] >> 0);
    out[14] = uid[A6 - 1] ^ (uid[A8 - 1] << 2);
    out[15] = uid[A9 - 1] ^ (uid[A11 - 1] >> 0);
 
    for (i = 0; i < 16; i++) 
        {
        out[i] ^= rnd[i % _rndsize];
    }
}
 
/*
*********************************************************************************************************
*        函 数 名: UidCompare
*        功能说明: 比较加密的UID
*        形    参: 1表示成功,0表示失败
*        返 回 值: 反
*********************************************************************************************************
*/
uint8_t UidCompare(void)
{
    uint8_t tempbuf[16] = {0};
    uint16_t i;
        uint8_t size;
        uint8_t index;        
 
    for(i = 0; i < UID_BYTES; i++)
    {
        UidArray[i] = *(volatile uint8_t*)(UID_ADDR+i);
    }
         
    for(i = 0; i < ENCRYPT_LEN; i++)
    {
        EncryptUidArray[i] = *(volatile uint8_t*)(ENCRYPT_ADDR + i);
    }        
 
    if(ENCRYPT_RND_IDX == 0)
    {
        size = stringToHexArray((const char *)RNG_CONST_DATA, tempbuf);
 
        encrypt(UidArray, tempbuf, size, ReEncryptUidArray);
    }
    else
    {
                index = (uint8_t)(ENCRYPT_RND_IDX - 1);
        for(i = 0; i < RNG_TAB[index].length; i++)
        {
            tempbuf[i] = *((uint8_t *)(uintptr_t)(RNG_TAB[index].address + i));
        }
        encrypt(UidArray, tempbuf, RNG_TAB[index].length, ReEncryptUidArray);        
    }
 
    for (i = 0; i < ENCRYPT_LEN; i++) 
    {
        if (ReEncryptUidArray[i] != EncryptUidArray[i]) 
        {
            return 0;
        }
    }
 
    return 1;
}

 

3、用户仅需调用UidCompare()即可,返回值是1表示验证成功,返回值是0表示验证失败

 

int main() 
{
        uint8_t re;
 
        re = UidCompare();
         
        if(re == 1)
        {
                printf("验证成功\r\n");
                 
        }
        else
        {
                printf("验证失败\r\n");                
        }
 
    while(1);
}

 

4、修改一个bug的地方

特别注意,当前2.26版本生成的C算法这两个写错了:

#define RNG_CONST_DATA = "11 22 33 44 55 66 77 88"   //常量值
#define RNG_TAB_t RNG_TAB = {     //使能位, 存储地址, 随机数长度
    {0, 0x08000000, 4},
    {0, 0x08000000, 4},
    {0, 0x08000000, 4},
    {0, 0x08000000, 4}
};

修改为如下即可:

uint8_t RNG_CONST_DATA[] = "11 22 33 44 55 66 77 88";   //常量值
RNG_TAB_t RNG_TAB[] = {     //使能位, 存储地址, 随机数长度
    {0, 0x08000000, 4},
    {0, 0x08000000, 4},
    {0, 0x08000000, 4},
    {0, 0x08000000, 4}
};

然后编译生成hex文件。添加到TOOL上位机进行下载:

为了方便查看验证是否正常,我们这里简单做了个串口答应,成了就提示验证成功:


5、实际验证是没问题的,完整的测试例子如下,方便大家参考:
H7-TOOL UID加密.7z (1.28MB)

 

标签:烧录,20,UID,RNG,uint8,uid,加密,define
From: https://www.cnblogs.com/armfly/p/18374790

相关文章

  • 免输密码全自动登录金山文档Windows客户端 2024年8月22日
     免输密码全自动登录金山文档Windows客户端2024年8月22日  ;免输密码全自动登录金山文档Windows客户端2024年8月22日;;指纹加密U盘&FindText-v9.7-by-FeiYue&Loop-if-break&金山文档&Index-Your-Files&mstsc&零层壹号&WinSCP&USMv5&Acronis-true-Image-2021-WinPE&......
  • 2024河南省萌新联赛第(六)场 郑州大学
    文章目录2024河南省萌新联赛第(六)场郑州大学A.装备二选一(一)题意:思路:AC代码:B.百变吗喽题意:思路:AC代码:C.16进制世界题意:思路:AC代码:D.四散而逃题意:思路:AC代码:F.追寻光的方向题意:思路:AC代码:G.等公交车题意:思路:AC代码:I.正义从不打背身题意:思路:AC代码:2024河南省萌新......
  • 2024暑假集训测试31
    前言比赛链接。本来挺水的一场,挂分挂狠了,T1被unordered_map害死了;T2赛时一看这不OSU嘛,反正也会先把部分分打满回来再写吧……T3只想说出题人三天不骂上房揭瓦,你大样例锅了就锅了能不能说明白,就发一条消息“T3样例输出”总共\(6\)个字,鬼知道你说的是大样例,看一......
  • P4216[SCOI2015情报传递 树上主席树
    题意:维护一棵树,某些点有点权(没有则为正无穷),点权为正整数,查询树上路径点权小于等于某个值的点的个数。分析:考虑维护主席树,root[i]数组存储第i个节点到根的点权的权值线段树的树根。更具体地,把第i个节点到根的路径上的点权累积到权值线段树中,对一个询问x,y,记lca为z,查询值为k,答案a......
  • sqli-labs靶场通关攻略 16-20
    主页有sqli-labs靶场通关攻略1-15第十六关less-16​步骤一:判断闭合方式为admin") and1=1#​步骤二:判断列数admin")orderby2 #数据正常admin")orderby3#数据报错得出结果2列​​步骤三:判断数据库长度1")orlength(database())=8#​说明数据裤字符......
  • 【Windows Server2016下Oracle11g DG配置实操步骤】
    WindowsServer2016下Oracle11gDG配置实操步骤文章目录WindowsServer2016下Oracle11gDG配置实操步骤前言一、部署规划1.1、虚拟机搭建:1.2、环境规划:1.3、主库操作系统配置1.4、数据库安装和实例创建1.5、监听配置1.6、网络配置1.7、克隆虚拟机二、主库配置2.1、查看......
  • 2024杭电多校第10场
    101002scenery(hdu7542)由于\(l\)序列不增、\(r\)序列不降,每处景色的拍摄安排在可选时间的开始/结束位置显然是最优的。设\(dp[i][j]\)表示(从后往前)考虑到第\(i\)处景色、可选时间从\(j\)开始的最晚结束位置,则转移方程:\(dp[i][max(l_i,j)+t_i]=max(dp[i][max(......
  • 【专题】2023-2024中国游戏企业研发竞争力报告合集PDF分享(附原数据表)
    原文链接: https://tecdat.cn/?p=37447 在当今的数字时代,游戏产业已然成为经济与文化领域中一股不可忽视的重要力量。2023年,中国自研游戏市场更是呈现出一片繁荣且复杂的景象,实际销售收入达到了令人瞩目的2563.8亿元,同比增长15.3%,不仅刷新历史纪录,还彰显出其强大的市场活力......
  • FPGA开发——DS18B20读取温度并且在数码管上显示
    一、简介        在上一篇文章中我们对于DS18B20的相关理论进行了详细的解释,同时也对怎样使用DS18B20进行了一个简单的叙述。在这篇文章我们通过工程来实现DS18B20的温度读取并且实现在数码管伤显示。1、基本实现思路根据不同时刻的操作,我们可以使用一个状态机来实......
  • 2024年8月【最新】《黑神话:悟空》【电脑配置要求】黑神话 悟空 电脑配置【推荐】
    (本人经核验测评后推荐二、三、四配置)目录:一、最低配置:(官方发布)二、普通配置:三、高端配置:四、豪华配置: 正文:一、最低配置:(官方发布)1、CPU:因特尔i58400或AMDRyzen516002、内存:16G3、显卡:GTX1060缓存6G或AMDRX5808G4、硬盘:130G(固态)(安装后大小128G)(忽略)......