大家好,欢迎来到IT知识分享网。
程序下载链接
下载链接: https://pan.baidu.com/s/1N91q3PTGwTd3s82rpImKxA
提取码: k2um
说明:基础 Hex 转换为 Bin 功能免注册、免费使用。注册功能需要付费获取注册码后开启软件注册功能。
注册码获取链接:
https://item.taobao.com/item.htm?id=795374128097
软件说明:
1.这个工具可以将 Hex 文件 转换为 Bin 格式文件,软件是按自己开发 STM32 OAT 功能需求开发的一款辅助 上位机软件。
2.文章提供 CRC16,CRC32校验代码,AES加密、解密代码,方便移植验证使用。
文中的介绍时 bootloader = boot
有兴趣的朋友可留言探讨。
1. 软件功能:
1.生成 bin:将 Hex 格式文件转换为 Bin 格式。
2.boot 打包为 bin:可以生成指定大小的 bin 格式文件,文件多余的空余位置填充随机数。可在生成的Bin文件指定位置填充加密后的指定数据,用于程序加密使用。
3.app 打包为 bin :可生成整个程序加密后的 Bin 文件,可用于 OTA 中的 APP 文件加密,防止APP泄漏。
4.bin 合并:可将 boot 和 app 合并为一个文件,方便生成时程序一次性烧录。
5.bin / app 加密:提供自定义秘钥的 app 加密功能,和自定义 boot 识别数据的填充设置。
说明:灰色部分为注册后才能使用。
2. Bootload 加密思路
bootloader文件的构成:
bootloader 编译文件 + flash加密数据区域 = 烧录用 bootloader;
例如:假设app的开始区域为 0x800A000 ,那boot的文件区域为 0x ~ 0x800A000
1. Flash加密数据区域:
假设取 0x ~ 0x800A000 共2kb区域作为加密数据的存储区域,简单说按app的前一个扇区作为加密数据存储区域,因为有的MCU一个扇区大小 2k ,有的 1k ,视具体型号而定,取app的上一个扇区即可。
2. boot 编译文件大小:
调整Flash分区的大小,boot 的数据不要到 Flash加密数据区域,避免交叉导致 boot 被意外擦除。
3. Flash加密数据区域数据结构:
typedef struct { uint32_t app_state; /* app 状态,无APP,有APP */ uint32_t mark[4]; /* 初始状态数据 */ uint32_t id_mark[4]; /* ID加密数据 */ ... /* 根据需求自定义 */ }APP_t;
4. boot文件打包:
4.1.设定指定大小:
使用专用 上位机软件导入 boot 程序后,按设定的大小输出输出 bin 文件,多余的地方填充随机数。例如:boot编译文件为 32k, 设定输出大小为40 k,那空余的 8k 全部填充随机数,这样混淆后即便读出boot程序也不知道boot程序具体多大。
4.2.插入加密数据:
在预留的加密扇区内指定的位置插入加密数据。
如:数据 mark[4] 是boot第一次运行时会检测的数据,检测这个数据和预期的相符才执行 boot 的加密工作,加密完成后再 修改或删除 mark[4] 数据,确保 boot 的加密工作只做一次。
id_mark[4] 是加密数据,通过读取 MCU 的 ID ,再通过AES加密算法,加密后存储到 id_mark[4] 。
uint32_t mark[4]; /* 初始状态数据 */ uint32_t id_mark[4]; /* ID加密数据 */
3. APP 加密思路
1. app 按16字节凑整,即app的大小是 16 的整数倍,这样方便 AES 加密,加密前在app文件末尾插入app文件的 CRC16 校验值,这样boot可以校验app的完整性。在凑整和添加CRC16值后再AES加密文件,最终得到的bin文件作为 boot 升级用。
2.app校验ID的有效性,app通过读取 boot 加密区域的 ID 加密数据,解密后与读取的MCU ID 做对比,判断程序的有效性。
4. boot 启动流程
4.1 boot跳转代码
在 boot 需要跳转到app的地方调用这个函数
#define OTA_CODE_START_ADD (0x0800A000) /* app 区域储存的首地址 */ void qbt_jump_to_app(void) { typedef void (*app_func_t)(void); u32 app_addr = OTA_CODE_START_ADD; u32 stk_addr = *((__IO uint32_t *)app_addr); app_func_t app_func = (app_func_t)(*((__IO uint32_t *)(app_addr + 4))); if ((((u32)app_func & 0xff000000) != 0x0) || ((stk_addr & 0x2ff00000) != 0x)) { return; } __disable_irq(); /*关闭总中断*/ HAL_DeInit(); /*函数通过写复位寄存器,将所有模块复位。*/ for (int i = 0; i < 128; i++) { HAL_NVIC_DisableIRQ((IRQn_Type) i); /*失能中断*/ HAL_NVIC_ClearPendingIRQ((IRQn_Type) i); /*清除中断标志位*/ } /* 关闭滴答定时器,复位到默认值 */ SysTick->CTRL = 0; SysTick->LOAD = 0; SysTick->VAL = 0; HAL_RCC_DeInit(); /*将RCC时钟配置重置为默认重置状态。*/ __set_CONTROL(0); /*设置CONTROL寄存器的值。在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针*/ __set_MSP(stk_addr); /* 设置MSP跳转的地址;设置主堆栈指针 */ app_func(); /* Jump to application running */ }
5. App 启动流程
app通过读取 boot 加密区域的 ID 加密数据,解密后与读取的 MCU ID 做对比,判断程序的有效性。
5.1 app跳转代码
#define OTA_CODE_START_ADD (0x0800A000) /* app 区域储存的首地址 */ /* app 初始化程序 * main 函数放在最前面调用 * */ void app_init(void) { SCB->VTOR = FLASH_BASE | OTA_CODE_START_ADD; /* 跳转到APP地址 */ __enable_irq(); }
6. AES 加密算法代码
#include <stdio.h> #include <stdint.h> #include <string.h> //---------------------------------------------------------------------------------------------------------------------------------------- // "0ABCDEF" /* 长度参考 */ #define TEST_TINY_AES_IV "0ABCDEF" /* 初始向量IV,定长 */ // "0ABCDEF0ABCDEF" /* 长度参考 */ #define TEST_TINY_AES_KEY "0ABCDEF0ABCDEF" /* AES key,定长 */ #define AES_DATA_LEN (16) /* KEY 加密后的数据长度 */ #define AES_DEC_LEN (16) /* AES 数据解密后长度 */ #define AES_ENCRYPT 1 #define AES_DECRYPT 0 typedef struct { int nr; /*!< number of rounds */ uint32_t *rk; /*!< AES round keys */ uint32_t buf[68]; /*!< unaligned data */ } tiny_aes_context; /* aes.h ---------------------------------------------------------------- */ void tiny_aes_setkey_enc(tiny_aes_context * ctx, uint8_t *key, int keysize); void tiny_aes_setkey_dec(tiny_aes_context * ctx, uint8_t *key, int keysize); void tiny_aes_crypt_ecb(tiny_aes_context * ctx,int mode,uint8_t input[16], uint8_t output[16]); void tiny_aes_crypt_cbc(tiny_aes_context * ctx,int mode,int length,uint8_t iv[16],uint8_t *input, uint8_t *output); void tiny_aes_crypt_cfb128(tiny_aes_context * ctx,int mode,int length,int *iv_off,uint8_t iv[16],uint8_t *input, uint8_t *output); /* aes.c ---------------------------------------------------------------- */ //#include <string.h> #define TINY_CRYPT_AES #if 0 #define AES_ENCRYPT 1 #define AES_DECRYPT 0 typedef struct { int nr; /*!< number of rounds */ uint32_t *rk; /*!< AES round keys */ uint32_t buf[68]; /*!< unaligned data */ } tiny_aes_context; #endif #if defined(TINY_CRYPT_AES) /* * 32-bit integer manipulation macros (little endian) */ #ifndef GET_ULONG_LE #define GET_ULONG_LE(n,b,i) \ { \ (n) = ( (uint32_t) (b)[(i) ] ) \ | ( (uint32_t) (b)[(i) + 1] << 8 ) \ | ( (uint32_t) (b)[(i) + 2] << 16 ) \ | ( (uint32_t) (b)[(i) + 3] << 24 ); \ } #endif #ifndef PUT_ULONG_LE #define PUT_ULONG_LE(n,b,i) \ { \ (b)[(i) ] = (uint8_t) ( (n) ); \ (b)[(i) + 1] = (uint8_t) ( (n) >> 8 ); \ (b)[(i) + 2] = (uint8_t) ( (n) >> 16 ); \ (b)[(i) + 3] = (uint8_t) ( (n) >> 24 ); \ } #endif #if defined(TINY_CRYPT_AES_ROM_TABLES) #else /* * Forward S-box & tables */ static uint8_t FSb[256]; static uint32_t FT0[256]; static uint32_t FT1[256]; static uint32_t FT2[256]; static uint32_t FT3[256]; /* * Reverse S-box & tables */ static uint8_t RSb[256]; static uint32_t RT0[256]; static uint32_t RT1[256]; static uint32_t RT2[256]; static uint32_t RT3[256]; /* * Round constants */ static uint32_t RCON[10]; /* * Tables generation code */ #define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 ) #define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) #define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 ) static int aes_init_done = 0; static void aes_gen_tables(void) { int i, x, y, z; int pow[256]; int log[256]; /* * compute pow and log tables over GF(2^8) */ for (i = 0, x = 1; i < 256; i++) { pow[i] = x; log[x] = i; x = (x ^ XTIME(x)) & 0xFF; } /* * calculate the round constants */ for (i = 0, x = 1; i < 10; i++) { RCON[i] = (uint32_t)x; x = XTIME(x) & 0xFF; } /* * generate the forward and reverse S-boxes */ FSb[0x00] = 0x63; RSb[0x63] = 0x00; for (i = 1; i < 256; i++) { x = pow[255 - log[i]]; y = x; y = ((y << 1) | (y >> 7)) & 0xFF; x ^= y; y = ((y << 1) | (y >> 7)) & 0xFF; x ^= y; y = ((y << 1) | (y >> 7)) & 0xFF; x ^= y; y = ((y << 1) | (y >> 7)) & 0xFF; x ^= y ^ 0x63; FSb[i] = (uint8_t)x; RSb[x] = (uint8_t)i; } /* * generate the forward and reverse tables */ for (i = 0; i < 256; i++) { x = FSb[i]; y = XTIME(x) & 0xFF; z = (y ^ x) & 0xFF; FT0[i] = ((uint32_t)y) ^ ((uint32_t)x << 8) ^ ((uint32_t)x << 16) ^ ((uint32_t)z << 24); FT1[i] = ROTL8(FT0[i]); FT2[i] = ROTL8(FT1[i]); FT3[i] = ROTL8(FT2[i]); x = RSb[i]; RT0[i] = ((uint32_t)MUL(0x0E, x)) ^ ((uint32_t)MUL(0x09, x) << 8) ^ ((uint32_t)MUL(0x0D, x) << 16) ^ ((uint32_t)MUL(0x0B, x) << 24); RT1[i] = ROTL8(RT0[i]); RT2[i] = ROTL8(RT1[i]); RT3[i] = ROTL8(RT2[i]); } } #endif /* * AES key schedule (encryption) */ void tiny_aes_setkey_enc(tiny_aes_context * ctx, uint8_t *key, int keysize) { int i; uint32_t *RK; #if !defined(TINY_CRYPT_AES_ROM_TABLES) if (aes_init_done == 0) { aes_gen_tables(); aes_init_done = 1; } #endif switch (keysize) { case 128: ctx->nr = 10; break; case 192: ctx->nr = 12; break; case 256: ctx->nr = 14; break; default: return; } ctx->rk = RK = ctx->buf; for (i = 0; i < (keysize >> 5); i++) { GET_ULONG_LE(RK[i], key, i << 2); } switch (ctx->nr) { case 10: for (i = 0; i < 10; i++, RK += 4) { RK[4] = RK[0] ^ RCON[i] ^ ((uint32_t)FSb[(RK[3] >> 8) & 0xFF]) ^ ((uint32_t)FSb[(RK[3] >> 16) & 0xFF] << 8) ^ ((uint32_t)FSb[(RK[3] >> 24) & 0xFF] << 16) ^ ((uint32_t)FSb[(RK[3]) & 0xFF] << 24); RK[5] = RK[1] ^ RK[4]; RK[6] = RK[2] ^ RK[5]; RK[7] = RK[3] ^ RK[6]; } break; case 12: for (i = 0; i < 8; i++, RK += 6) { RK[6] = RK[0] ^ RCON[i] ^ ((uint32_t)FSb[(RK[5] >> 8) & 0xFF]) ^ ((uint32_t)FSb[(RK[5] >> 16) & 0xFF] << 8) ^ ((uint32_t)FSb[(RK[5] >> 24) & 0xFF] << 16) ^ ((uint32_t)FSb[(RK[5]) & 0xFF] << 24); RK[7] = RK[1] ^ RK[6]; RK[8] = RK[2] ^ RK[7]; RK[9] = RK[3] ^ RK[8]; RK[10] = RK[4] ^ RK[9]; RK[11] = RK[5] ^ RK[10]; } break; case 14: for (i = 0; i < 7; i++, RK += 8) { RK[8] = RK[0] ^ RCON[i] ^ ((uint32_t)FSb[(RK[7] >> 8) & 0xFF]) ^ ((uint32_t)FSb[(RK[7] >> 16) & 0xFF] << 8) ^ ((uint32_t)FSb[(RK[7] >> 24) & 0xFF] << 16) ^ ((uint32_t)FSb[(RK[7]) & 0xFF] << 24); RK[9] = RK[1] ^ RK[8]; RK[10] = RK[2] ^ RK[9]; RK[11] = RK[3] ^ RK[10]; RK[12] = RK[4] ^ ((uint32_t)FSb[(RK[11]) & 0xFF]) ^ ((uint32_t)FSb[(RK[11] >> 8) & 0xFF] << 8) ^ ((uint32_t)FSb[(RK[11] >> 16) & 0xFF] << 16) ^ ((uint32_t)FSb[(RK[11] >> 24) & 0xFF] << 24); RK[13] = RK[5] ^ RK[12]; RK[14] = RK[6] ^ RK[13]; RK[15] = RK[7] ^ RK[14]; } break; default: break; } } /* * AES key schedule (decryption) */ void tiny_aes_setkey_dec(tiny_aes_context * ctx, uint8_t *key, int keysize) { int i, j; tiny_aes_context cty; uint32_t *RK; uint32_t *SK; switch (keysize) { case 128: ctx->nr = 10; break; case 192: ctx->nr = 12; break; case 256: ctx->nr = 14; break; default: return; } ctx->rk = RK = ctx->buf; tiny_aes_setkey_enc(&cty, key, keysize); SK = cty.rk + cty.nr * 4; *RK++ = *SK++; *RK++ = *SK++; *RK++ = *SK++; *RK++ = *SK++; for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) { for (j = 0; j < 4; j++, SK++) { *RK++ = RT0[FSb[(*SK) & 0xFF]] ^ RT1[FSb[(*SK >> 8) & 0xFF]] ^ RT2[FSb[(*SK >> 16) & 0xFF]] ^ RT3[FSb[(*SK >> 24) & 0xFF]]; } } *RK++ = *SK++; *RK++ = *SK++; *RK++ = *SK++; *RK++ = *SK++; memset(&cty, 0, sizeof(tiny_aes_context)); } #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ { \ X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \ FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ FT3[ ( Y3 >> 24 ) & 0xFF ]; \ \ X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \ FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ FT3[ ( Y0 >> 24 ) & 0xFF ]; \ \ X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \ FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ FT3[ ( Y1 >> 24 ) & 0xFF ]; \ \ X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \ FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ FT3[ ( Y2 >> 24 ) & 0xFF ]; \ } #define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ { \ X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \ RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ RT3[ ( Y1 >> 24 ) & 0xFF ]; \ \ X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \ RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ RT3[ ( Y2 >> 24 ) & 0xFF ]; \ \ X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \ RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ RT3[ ( Y3 >> 24 ) & 0xFF ]; \ \ X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \ RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ RT3[ ( Y0 >> 24 ) & 0xFF ]; \ } /* * AES-ECB block encryption/decryption */ void tiny_aes_crypt_ecb(tiny_aes_context * ctx, int mode, uint8_t input[16], uint8_t output[16]) { int i; uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; RK = ctx->rk; GET_ULONG_LE(X0, input, 0); X0 ^= *RK++; GET_ULONG_LE(X1, input, 4); X1 ^= *RK++; GET_ULONG_LE(X2, input, 8); X2 ^= *RK++; GET_ULONG_LE(X3, input, 12); X3 ^= *RK++; if (mode == AES_DECRYPT) { for (i = (ctx->nr >> 1) - 1; i > 0; i--) { AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); } AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); X0 = *RK++ ^ ((uint32_t)RSb[(Y0) & 0xFF]) ^ ((uint32_t)RSb[(Y3 >> 8) & 0xFF] << 8) ^ ((uint32_t)RSb[(Y2 >> 16) & 0xFF] << 16) ^ ((uint32_t)RSb[(Y1 >> 24) & 0xFF] << 24); X1 = *RK++ ^ ((uint32_t)RSb[(Y1) & 0xFF]) ^ ((uint32_t)RSb[(Y0 >> 8) & 0xFF] << 8) ^ ((uint32_t)RSb[(Y3 >> 16) & 0xFF] << 16) ^ ((uint32_t)RSb[(Y2 >> 24) & 0xFF] << 24); X2 = *RK++ ^ ((uint32_t)RSb[(Y2) & 0xFF]) ^ ((uint32_t)RSb[(Y1 >> 8) & 0xFF] << 8) ^ ((uint32_t)RSb[(Y0 >> 16) & 0xFF] << 16) ^ ((uint32_t)RSb[(Y3 >> 24) & 0xFF] << 24); X3 = *RK++ ^ ((uint32_t)RSb[(Y3) & 0xFF]) ^ ((uint32_t)RSb[(Y2 >> 8) & 0xFF] << 8) ^ ((uint32_t)RSb[(Y1 >> 16) & 0xFF] << 16) ^ ((uint32_t)RSb[(Y0 >> 24) & 0xFF] << 24); } else { /* AES_ENCRYPT */ for (i = (ctx->nr >> 1) - 1; i > 0; i--) { AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); } AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); X0 = *RK++ ^ ((uint32_t)FSb[(Y0) & 0xFF]) ^ ((uint32_t)FSb[(Y1 >> 8) & 0xFF] << 8) ^ ((uint32_t)FSb[(Y2 >> 16) & 0xFF] << 16) ^ ((uint32_t)FSb[(Y3 >> 24) & 0xFF] << 24); X1 = *RK++ ^ ((uint32_t)FSb[(Y1) & 0xFF]) ^ ((uint32_t)FSb[(Y2 >> 8) & 0xFF] << 8) ^ ((uint32_t)FSb[(Y3 >> 16) & 0xFF] << 16) ^ ((uint32_t)FSb[(Y0 >> 24) & 0xFF] << 24); X2 = *RK++ ^ ((uint32_t)FSb[(Y2) & 0xFF]) ^ ((uint32_t)FSb[(Y3 >> 8) & 0xFF] << 8) ^ ((uint32_t)FSb[(Y0 >> 16) & 0xFF] << 16) ^ ((uint32_t)FSb[(Y1 >> 24) & 0xFF] << 24); X3 = *RK++ ^ ((uint32_t)FSb[(Y3) & 0xFF]) ^ ((uint32_t)FSb[(Y0 >> 8) & 0xFF] << 8) ^ ((uint32_t)FSb[(Y1 >> 16) & 0xFF] << 16) ^ ((uint32_t)FSb[(Y2 >> 24) & 0xFF] << 24); } PUT_ULONG_LE(X0, output, 0); PUT_ULONG_LE(X1, output, 4); PUT_ULONG_LE(X2, output, 8); PUT_ULONG_LE(X3, output, 12); } /* * AES-CBC buffer encryption/decryption */ void tiny_aes_crypt_cbc(tiny_aes_context * ctx, int mode, int length, uint8_t iv[16], uint8_t *input, uint8_t *output) { int i; uint8_t temp[16]; if (mode == AES_DECRYPT) { while (length > 0) { memcpy(temp, input, 16); tiny_aes_crypt_ecb(ctx, mode, input, output); for (i = 0; i < 16; i++) output[i] = (uint8_t)(output[i] ^ iv[i]); memcpy(iv, temp, 16); input += 16; output += 16; length -= 16; } } else { while (length > 0) { for (i = 0; i < 16; i++) output[i] = (uint8_t)(input[i] ^ iv[i]); tiny_aes_crypt_ecb(ctx, mode, output, output); memcpy(iv, output, 16); input += 16; output += 16; length -= 16; } } } /* * AES-CFB128 buffer encryption/decryption */ void tiny_aes_crypt_cfb128(tiny_aes_context * ctx, int mode, int length, int *iv_off, uint8_t iv[16], uint8_t *input, uint8_t *output) { int c, n = *iv_off; if (mode == AES_DECRYPT) { while (length--) { if (n == 0) tiny_aes_crypt_ecb(ctx, AES_ENCRYPT, iv, iv); c = *input++; *output++ = (uint8_t)(c ^ iv[n]); iv[n] = (uint8_t)c; n = (n + 1) & 0x0F; } } else { while (length--) { if (n == 0) tiny_aes_crypt_ecb(ctx, AES_ENCRYPT, iv, iv); iv[n] = *output++ = (uint8_t)(iv[n] ^ *input++); n = (n + 1) & 0x0F; } } *iv_off = n; } #endif /* mode: 0 dec 解密, 1 enc 加密 * k_check_t *cd :输入数据 * uint8_t *enc_db :输出数据 * */ uint8_t key_aes_enc_dec(uint8_t mode,uint8_t *cd,uint8_t *enc_db) { tiny_aes_context ctx; uint8_t iv[16 + 1]; uint8_t private_key[32 + 1]; #if 1 if ((mode == 1)&&(enc_db != NULL)) { /* encrypt */ memcpy(iv, TEST_TINY_AES_IV, strlen(TEST_TINY_AES_IV)); iv[sizeof(iv) - 1] = '\0'; memcpy(private_key, TEST_TINY_AES_KEY, strlen(TEST_TINY_AES_KEY)); private_key[sizeof(private_key) - 1] = '\0'; memset(enc_db, 0x0, sizeof(AES_DATA_LEN)); tiny_aes_setkey_enc(&ctx, (uint8_t *) private_key, 256); tiny_aes_crypt_cbc(&ctx, AES_ENCRYPT, AES_DEC_LEN, iv, (uint8_t *)cd, enc_db); } #endif if ((mode == 0)&&(enc_db != NULL)) { /* decrypt */ memcpy(iv, TEST_TINY_AES_IV, strlen(TEST_TINY_AES_IV)); iv[sizeof(iv) - 1] = '\0'; memcpy(private_key, TEST_TINY_AES_KEY, strlen(TEST_TINY_AES_KEY)); private_key[sizeof(private_key) - 1] = '\0'; tiny_aes_setkey_dec(&ctx, (uint8_t *) private_key, 256); tiny_aes_crypt_cbc(&ctx, AES_DECRYPT, AES_DEC_LEN, iv,(uint8_t *)cd ,(uint8_t *)enc_db); } return 1; } //测试 int main() { uint8_t data[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F}; uint8_t output_enc[16]; // 加密数据 uint8_t output_dec[16]; // 解密数据 key_aes_enc_dec(1,data,output_enc); //加密 printf("enc:"); for (uint8_t var = 0; var < 16; ++var) { printf("%02X",output_enc[var]); } printf("\n"); key_aes_enc_dec(0,output_enc,output_dec); //解密 printf("dec:"); for (uint8_t var = 0; var < 16; ++var) { printf("%02X",output_dec[var]); } printf("\n"); return 0; } //计算结果 //enc:7A34715E1CB58997C76E3ECC //dec:0000A0B0C0D0E0F
7. CRC16 校验算法代码
CRC16 算法代码 1:
/* CRC16 余式表 */ static uint16_t crctalbeabs[] = { 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 }; /*! * 功 能: CRC16校验 * param1: 指向要校验的数据的指针 * param2: 要校验的数据的长度 * retval: 校验所得到的值,uint16_t 类型 * * 说 明: 本次CRC校验为查表法,多项式为 x16+x15+x2+1(0x8005),CRC的初始值为0xFFFF */ uint16_t Crc16_C(uint8_t *ptr, uint32_t len) { uint16_t crc = 0xffff; uint32_t i; uint8_t ch; for (i = 0; i < len; i++) { ch = *ptr++; crc = crctalbeabs[(ch ^ crc) & 15] ^ (crc >> 4); crc = crctalbeabs[((ch >> 4) ^ crc) & 15] ^ (crc >> 4); } return crc; } //测试代码 int main() { uint8_t data[] = {0x12, 0x34, 0x56, 0x78}; uint32_t crc = Crc16_C(data, sizeof(data)); printf("CRC16: 0x%04X\n", crc); return 0; } //输出结果 CRC16: 0x107B
CRC16 算法代码 2:
#include <stdio.h> #include <stdint.h> static uint16_t yl_crc16(unsigned char *buffer, uint16_t len) { uint16_t wcrc = 0XFFFF; //16位crc寄存器预置 uint8_t temp; uint16_t i = 0, j = 0; //计数 for (i = 0; i < len; i++) //循环计算每个数据 { temp = *buffer & 0X00FF; //将八位数据与crc寄存器亦或 buffer++; //指针地址增加,指向下个数据 wcrc ^= temp; //将数据存入crc寄存器 for (j = 0; j < 8; j++) //循环计算数据的 { if (wcrc & 0X0001) //判断右移出的是不是1,如果是1则与多项式进行异或。 { wcrc >>= 1; //先将数据右移一位 wcrc ^= 0XA001; //与上面的多项式进行异或 } else //如果不是1,则直接移出 { wcrc >>= 1; //直接移出 } } } return wcrc; } int main() { unsigned char data[] = {0x12, 0x34, 0x56, 0x78}; int len = sizeof(data) / sizeof(data[0]); uint16_t crc = yl_crc16(data, len); printf("CRC16: 0x%04X\n", crc); return 0; } //输出结果 CRC16: 0x107B
8.程序下载链接
链接: https://pan.baidu.com/s/1N91q3PTGwTd3s82rpImKxA
提取码: k2um
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/133490.html