日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32操作加密芯片源代码

發布時間:2023/12/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32操作加密芯片源代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

STM32操作SMEC98SP加密芯片的事例代碼,如果需要完整代碼(包括加密芯片代碼),請到中巨偉業 http://www.sinormous.com/download.html下載

#include “stm32f10x.h”
#include “stdio.h”
#include “config.h”
#include “util.h”
#include <string.h>
#include <stdlib.h>
#include “stm32f10x_i2c.h”

#include “smec98sp.h”
#include “iic_smec98sp.h”

void RCC_Configuration(void);
void NVIC_Configuration(void);
void GPIO_Configuration(void);

//---------------------------------------------------------
//函數名: 獲取STM32的UID
//參數說明:
// pSTM32_UID - 存放STM32的UID,12字節
//返回值說明:
// void
//說明:
//---------------------------------------------------------
void GetStm32Uid(unsigned char *pSTM32_UID)
{
pSTM32_UID[0] = (unsigned char)(0x1FFFF7E8);
pSTM32_UID[1] = (unsigned char)(0x1FFFF7E9);
pSTM32_UID[2] = (unsigned char)(0x1FFFF7Ea);
pSTM32_UID[3] = (unsigned char)(0x1FFFF7Eb);
pSTM32_UID[4] = (unsigned char)(0x1FFFF7Ec);
pSTM32_UID[5] = (unsigned char)(0x1FFFF7Ed);
pSTM32_UID[6] = (unsigned char)(0x1FFFF7Ee);
pSTM32_UID[7] = (unsigned char)(0x1FFFF7Ef);
pSTM32_UID[8] = (unsigned char)(0x1FFFF7f0);
pSTM32_UID[9] = (unsigned char)(0x1FFFF7f1);
pSTM32_UID[10] = (unsigned char)(0x1FFFF7f2);
pSTM32_UID[11] = (unsigned char)(0x1FFFF7f3);
}

#include “stm32f10x_adc.h”
//---------------------------------------------------------
//函數名: 初始化ADC
//參數說明:
// void
//返回值說明:
// void
//說明: 利用ADC懸空引腳產生隨機數
// 將PA1 作為模擬通道輸入引腳(一定要用懸空腳,否則獲取的隨機數,不夠隨機),
//---------------------------------------------------------
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE ); //使能ADC1通道時鐘RCC_ADCCLKConfig(RCC_PCLK2_Div6); //設置ADC分頻因子6 72M/6=12,ADC最大時間不能超過14M//PA1 作為模擬通道輸入引腳, 一定要用懸空腳,否則獲取的隨機數,不夠隨機 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模擬輸入引腳 GPIO_Init(GPIOA, &GPIO_InitStructure); ADC_DeInit(ADC1); //復位ADC1,將外設 ADC1 的全部寄存器重設為缺省值ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在獨立模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模數轉換工作在單通道模式 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//DISABLE; //模數轉換工作在單次轉換模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //轉換由軟件而不是外部觸發啟動 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC數據右對齊 ADC_InitStructure.ADC_NbrOfChannel = 1; //順序進行規則轉換的ADC通道的數目 ADC_Init(ADC1, &ADC_InitStructure); //根據ADC_InitStruct中指定的參數初始化外設ADCx的寄存器ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1 ADC_ResetCalibration(ADC1); //使能復位校準 while(ADC_GetResetCalibrationStatus(ADC1)); //等待復位校準結束 ADC_StartCalibration(ADC1); //開啟AD校準 while(ADC_GetCalibrationStatus(ADC1)); //等待校準結束 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的軟件轉換啟動功能

}

//---------------------------------------------------------
//函數名: 獲得ADC值,作為隨機數種子
//參數說明:
// void
//返回值說明:
// ADC懸空引腳產生的隨機數
//說明: 采集4次ADC的值,每次取采集的第四位,拼成16位作為種子
//---------------------------------------------------------
unsigned short Get_Adc_RandomSeek(void)
{
unsigned char Count;
unsigned short ADC_RandomSeek = 0;

//設置指定ADC的規則組通道,一個序列,采樣時間 ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采樣時間為239.5周期 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的軟件轉換啟動功能 for(Count = 0; Count < 4; Count++){while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待轉換結束ADC_RandomSeek <<= 4;ADC_RandomSeek += ADC_GetConversionValue(ADC1) & 0x000f; /*采集4次ADC的值,每次取采集的第四位,拼成16位作為種子*/ } ADC_SoftwareStartConvCmd(ADC1,DISABLE); return ADC_RandomSeek;

}

/*
1.獲取SMEC98SP的UID號, 獲取STM32的ID, 獲取STM32隨機數
2.驗證PIN
3.內外部認證
4.SHA1=>前置數據^隨機數
5.密文讀
6.讀數據
7.寫數據
8.構造算法(PA口數據->密文送加密芯片, 密文返回)

如果直接引用,請將print的調試信息去除
*/

void SMEC_Test(void)
{
/*各種密鑰,不會在I2C線路上傳輸,可以使用同一組.應該將密鑰分散存儲,防止主控芯片被破解后,被攻擊者在二進制碼中找到密鑰 */
unsigned char InternalKey[16] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};//內部認證密鑰,必須和SMEC98SP一致
unsigned char ExternalKey[16] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F};//外部認證密鑰,必須和SMEC98SP一致
unsigned char SHA1_Key[16] = {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F}; //哈希算法認證密鑰,必須和SMEC98SP一致
unsigned char MKey[16] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F}; //主控密鑰,用于產生過程密鑰,必須和SMEC98SP一致

unsigned char Pin[8] = {0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc}; //Pin認證密鑰,必須和SMEC98SP一致unsigned char bStm32Uid[12] = {0}; //存放STM32的UID unsigned char bSmec98spUid[12] = {0}; //存放SMEC98SP的UID unsigned short RandomSeek; //隨機數種子 unsigned char bRandom[8] = {0}; //存放隨機數 unsigned char bSessionKey[8] = {0}; //存放過程密鑰,過程密鑰為臨時產生的密鑰 unsigned char bDataBuf[64] = {0}; unsigned char ret, bLen; unsigned short i, j;/*利用ADC懸空引腳產生隨機數*/ Adc_Init(); //可放在主程序中 RandomSeek = Get_Adc_RandomSeek(); //利用ADC懸空引腳產生隨機數/*獲取STM32的UID*/ GetStm32Uid(bStm32Uid); printf("GetStm32Uid: "); PrintHex(bStm32Uid, 12); printf("\r\n");/*獲取SMEC98SP的UID*/ ret = SMEC_GetUid(bSmec98spUid); if(ret) {printf("SMEC_GetUid -> Error !\r\n");while(1); } printf("SMEC_GetUid: "); PrintHex(bSmec98spUid, 12); printf("\r\n");/*將隨機數RandomSeek,再做一次隨機處理(與STM32的UID, SMEC98SP的UID作綁定, 使得即使相同情況下,不同的STM32,SMEC98SP隨機數種子也不同)*/ for(i = 0; i < 6; i += 2) {/*使RandomSeek與STM32的UID相關*/j = (bStm32Uid[i] << 8) + bStm32Uid[i + 1];RandomSeek ^= j;/*使RandomSeek與SMEC98SP的UID相關*/j = (bSmec98spUid[i] << 8) + bSmec98spUid[i + 1];RandomSeek ^= j; } srand(RandomSeek); printf("RandomSeek: %04x \r\n", RandomSeek);/*PIN碼驗證*/ ret = SMEC_CheckPin(Pin, (unsigned char)sizeof(Pin)); if(ret) {printf("SMEC_CheckPin -> Error !\r\n");while(1); } printf("SMEC_CheckPin OK !\r\n");/*內部認證, 主控芯片對SMEC98SP加密芯片合法性判斷*/ for(i = 0; i < 8; i ++) {bRandom[i] = (unsigned char) rand(); } ret = SMEC_IntrAuth(InternalKey, bRandom); if(ret) {printf("SMEC_IntrAuth -> Error !\r\n");while(1); } printf("SMEC_IntrAuth OK !\r\n");/*外部認證, SMEC98SP加密芯片對主控芯片合法性判斷*/ ret = SMEC_ExtrAuth(ExternalKey); if(ret) {printf("SMEC_ExtrAuth -> Error !\r\n");while(1); } printf("SMEC_ExtrAuth OK !\r\n");/*SHA1摘要算法認證, 數據長度可自己設定*/ for(i = 0; i < 16; i ++) {bDataBuf[i] = (unsigned char) rand(); } ret = SMEC_Sha1Auth(SHA1_Key, (unsigned char)sizeof(SHA1_Key), bDataBuf, 16); if(ret) {printf("SMEC_Sha1Auth -> Error !\r\n");while(1); } printf("SMEC_Sha1Auth OK !\r\n");/*調用加密芯片內部計算圓周長算法*/ bDataBuf[0] = 0x02; ret = SMEC_CircleAlg(bDataBuf, 1, bDataBuf, &bLen); if(ret) {printf("SMEC_CircleAlg -> Error !\r\n");while(1); } printf("SMEC_CircleAlg OK, C = %02x !\r\n", bDataBuf[0]);/*產生過程密鑰,用于后續的Flash數據加密讀,及構造的"端口數據運算"*/ for(i = 0; i < 8; i ++) {bRandom[i] = (unsigned char) rand(); } ret = SMEC_GenSessionKey(MKey, bRandom, bSessionKey); if(ret) {printf("SMEC_GenSessionKey -> Error !\r\n");while(1); } printf("SMEC_GenSessionKey OK !\r\n");/*密文讀取Flash數據*/ ret = SMEC_CryptReadFlash(bSessionKey, 0x0000, bDataBuf, 16); if(ret) {printf("SMEC_CryptReadFlash -> Error !\r\n");while(1); } printf("SMEC_CryptReadFlash OK:\r\n"); PrintHex(bDataBuf, 16);/*讀取Flash數據*/ ret = SMEC_ReadFlash(0x0000, bDataBuf, 16); if(ret) {printf("SMEC_ReadFlash -> Error !\r\n");while(1); } printf("SMEC_ReadFlash OK:\r\n"); PrintHex(bDataBuf, 16);/*寫Flash數據*/ for(i = 0; i < 16; i ++) {bDataBuf[i] = (unsigned char) i; } ret = SMEC_WriteFlash(0x0000, bDataBuf, 16); if(ret) {printf("SMEC_WriteFlash -> Error !\r\n");while(1); } printf("SMEC_WriteFlash OK!\r\n");/*構造"端口數據運算", 可以用實際的PA~PC端口數據*/ bDataBuf[0] = 0x00; bDataBuf[1] = 0x00; ret = SMEC_GpioAlg(bSessionKey, bDataBuf,2, bDataBuf); if(ret) {printf("SMEC_GpioAlg -> Error !\r\n");while(1); } printf("SMEC_GpioAlg OK:\r\n"); PrintHex(bDataBuf, 2);/*調用加密芯片內部計算圓周長算法,并密文在線路上傳輸*/ bDataBuf[0] = 0x02; ret = SMEC_CircleAlgCrypt(bSessionKey, bDataBuf, 1, bDataBuf, &bLen); if(ret) {printf("SMEC_CircleAlgCrypt -> Error !\r\n");while(1); } printf("SMEC_CircleAlgCrypt OK, C = %02x !\r\n", bDataBuf[0]);

}

/--------------///

/*******************************************************************************

  • Function Name : main

  • Description : Main program.

  • Input : None

  • Output : None

  • Return : None
    *******************************************************************************/
    int main(void)
    {
    RCC_Configuration(); // Configure the system clocks
    NVIC_Configuration(); // NVIC Configuration
    GPIO_Configuration();
    USART1_Init();
    SMEC_I2cInit(); //初始化加密芯片IIC IO
    Delay_ms(10); //等待保證加密芯片已經運行

    printf(“Z\r\n”);

    SMEC_Test(); //加密芯片功能演示

    while(1);
    }

void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
AFIO_TypeDef AFIO_InitStructure;
// Configure the USART1_Tx as Alternate function Push-Pull
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = USART1_TX;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

// Configure the USART1_Rx as input floating GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = USART1_RX; GPIO_Init(GPIOA, &GPIO_InitStructure);

}

/*******************************************************************************

  • Function Name : RCC_Configuration

  • Description : Configures the different system clocks.

  • Input : None

  • Output : None

  • Return : None
    *******************************************************************************/
    void RCC_Configuration(void)
    {
    ErrorStatus HSEStartUpStatus;

    /* RCC system reset(for debug purpose) */
    RCC_DeInit();

    /* Enable HSE */
    RCC_HSEConfig(RCC_HSE_ON);

    /* Wait till HSE is ready */
    HSEStartUpStatus = RCC_WaitForHSEStartUp();

    if(HSEStartUpStatus == SUCCESS)
    {
    /* Enable Prefetch Buffer */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    /* Flash 2 wait state */
    FLASH_SetLatency(FLASH_Latency_2);

    /* HCLK = SYSCLK */
    RCC_HCLKConfig(RCC_SYSCLK_Div1);

    /* PCLK2 = HCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1);

    /* PCLK1 = HCLK/2 */
    RCC_PCLK1Config(RCC_HCLK_Div2);

    /* PLLCLK = 8MHz * 9 = 72 MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

    /* Enable PLL */
    RCC_PLLCmd(ENABLE);

    /* Wait till PLL is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }

    /* Select PLL as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
    }

    /* TIM2 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC
    |RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1, ENABLE);
    }

/*******************************************************************************

  • Function Name : NVIC_Configuration
  • Description : Configures Vector Table base location.
  • Input : None
  • Output : None
  • Return : None
    *******************************************************************************/
    void NVIC_Configuration(void)
    {
    NVIC_InitTypeDef NVIC_InitStructure;

#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

#else /* VECT_TAB_FLASH /
/ Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// /* Enable the USART2 Interrupt */
// NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);

/* Enable the USART3 Interrupt */

/* Enable the TIM2 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable the TIM2 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

/* Set the Vector Table base location at 0x08002000 -> USE AIP*/
// NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2000);
// NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000);
#endif
}

總結

以上是生活随笔為你收集整理的STM32操作加密芯片源代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。