- •Содержание
- •Введение
- •1 Анализ существующих систем аутентификации, выбор решения для аутентификации пользователя транспортного средства
- •1.1 Системы со статическим и динамическим кодом
- •1.2 Шифрование с открытым ключом
- •1.3 Схема проверки подлинности ключа
- •1.4 Вывод
- •2 Разработка структурной схемы
- •2.1 Упрощённая структурная схема системы
- •2.2 Структурная схема модуля аутентификации
- •2.3 Генерация случайной последовательности
- •2.4 Структурная схема модуля радиоключа
- •2.5 Вывод
- •3 Разработка программного обеспечения
- •3.1 Выбор языка программирования
- •3.2 Выбор параметров математического метода
- •3.3 Тестирование скорости выполнения протокола
- •3.4 Проектирование алгоритма работы системы
- •3.5 Разработка общего алгоритма работы системы
- •3.6 Проектирование программной части генератора случайных чисел
- •3.6.3 Программный пул.Пул – программный блок памяти, осуществляющий накопление случайных данных перед их использованием в генераторе псевдо случайных чисел.
- •3.6.4 Rc4. Rc4 – потоковый шифр, широко применяющийся в различных системах защиты информации в компьютерных сетях (например, в протоколах ssl и tls, алгоритме безопасности беспроводных сетей wep).
- •3.6.6 Блок-схема алгоритма модуля генератора случайных чисел.Блок схема конечного алгоритма модуля генератора случайных чисел изображена на рисунке 3.8.
- •3.6 Вывод
- •4 Разработка принципиальной схемы системы
- •4.1 Выбор микроконтроллера
- •4.2 Выбор приёмопередатчика
- •4.3 Схема понижения напряжения из бортовой сети автомобиля
- •4.4 Схема генератора случайных чисел
- •4.5 Выбор источника питания радиоключа
- •4.6 Проектирование принципиальной схемы радиоключа
- •4.7 Проектирование принципиальной схемы системы автомобиля
- •4.8 Вывод
- •5 Энергосбережение при проектировании систем радиоэлектронной связи
- •5.1 Анализ энергозатрат при эксплуатации указанных систем
- •5.2 Поиск инженерно-технических и конструкторско-технологических решений экономии энергозатрат разрабатываемой системы
- •5.3 Вывод
- •6 Технико-экономическое обоснование эффективности разработки системы аутентификации пользователя транспортного средства
- •6.1 Характеристика программного продукта
- •6.2 Расчет затрат и отпускной цены программного средства
- •6.3 Расчет стоимостной оценки результата
- •6.4 Расчет показателей эффективности использования программного продукта
- •6.5 Вывод
- •Заключение
- •Список использованных источников
- •Приложение а
Приложение а
Листинг кода программы системы аутентификации пользователя транспортного средства
/*
main.hзаголовочный файл главного файла
*/
#define F_CPU 8000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdint.h>
uint8_t crandom();
/*
main.c главный файл
*/
#include "main.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include "ecc.h"
#include "fatfs/ff.h"
#include "sha256.h"
#include "usart.h"
#include "rc4.h"
#define STOPCODE 2
#define POOLSIZE 256
uint8_t randoms[POOLSIZE];
volatile uint32_t randomsi=0;
FATFS FatFs;
struct rc4state randstate;
uint8_t crandom(){
if(randomsi<(POOLSIZE/8))
USART1_SendByte(POOLSIZE-randomsi);
while(!randomsi);
return randoms[--randomsi]^nextRand(&randstate);
}
ISR(USART1_RX_vect){
if(randomsi<POOLSIZE)
randoms[randomsi++]=UDR1;
}
void sha256file(char* path,uint8_t* code){
FIL fil;
uint8_t buffer[SHABUFLEN];
unsigned temp;
struct sha256state state;
sha256new(&state);
if(f_open(&fil,path,FA_OPEN_EXISTING|FA_READ)==FR_OK){
while(f_read(&fil,buffer,SHABUFLEN,&temp)==FR_OK&&temp)
sha256update(&state,buffer,temp);
sha256end(&state,code);
f_close(&fil);
}
}
void main(void){
int32_t i;
FIL fil;
DIR dir;
FRESULT res;
FILINFO fno;
rc4new(&randstate,__TIME__,sizeof(__TIME__));
// rc4new(&randstate,"a2345",5);
uint8_t code[(NUMLEN>SHACODELEN)?NUMLEN:SHACODELEN];
uint8_t path[256];
//ECC variables
uint8_t e;
uint8_t el[NUMLEN]={};
uint8_t d[NUMLEN];
uint8_t n[NUMLEN];
USART0_init();
USART1_init();
sei();
USART0_SendStr("Starting ECC key generation procedure.\n\n");
getECCkeys(&e,d,n);
el[0]=e;
USART0_SendStr("\n");
USART0_SendStr("Public key exponent:\ne=");
USART0_SendNum(e);
USART0_SendStr("\nPrivate key exponent:\nd=");
bigPrint(d);
USART0_SendStr("Modulus:\nn=");
bigPrint(n);
USART0_SendStr("\n");
USART0_SendStr("Starting signing files.\n\n");
f_mount(&FatFs, "", 0);
f_opendir(&dir,"/code");
while(f_readdir(&dir,&fno)==FR_OK&&fno.fname[0]!=0){
sprintf(path,"/code/%s",fno.fname);
USART0_SendStr("FILE: ");
USART0_SendStr(path);
USART0_SendStr("\nHASH: ");
sha256file(path,code);
USART0_SendArr(code,SHACODELEN);
for(i=SHACODELEN;i<NUMLEN;++i)
code[i]=0;
eccCode(code,d,n);
USART0_SendStr("MAC: ");
bigPrint(code);
eccDecode(code,el,n);
USART0_SendStr("DECR: ");
bigPrint(code);
USART0_SendStr("\n");
}
USART1_SendByte(STOPCODE);
USART0_SendStr("All files processed.");
while(1);
}
/*
ecc.hзаголовочный файлecc.c
*/
#include <stdio.h>
#include "curve"
#defineMILLER_RABIN_K32//Хорошо, если здесь 128, но это долго
#define ECCDEBUG 0
#define ECCDEBUG0 1
int32_t isPrime(uint8_t* num);
int32_t millerRabin(uint8_t* num);
uint8_t crandom();
void getLargePrime(uint8_t* arr,uint32_t to);
uint8_t getOpenExp(uint8_t* num);
void getECCkeys(uint8_t* e,uint8_t* d,uint8_t* n);
void eccCode(uint8_t* message, uint8_t* e, uint8_t* n);
void eccDecode(uint8_t* message, uint8_t* e, uint8_t* n);
/*
ecc.cкриптографические функции
*/
#include<stdio.h>
#include <stdint.h>
#include "big_num.h"
#include "ecc.h"
#include "usart.h"
uint8_t small_primes[]={2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251};
// uint8_t_t crandom(){
// return rand();
// }
void eccCode(uint8_t* message, uint8_t* e, uint8_t* n){
bigExp(message,e,n);
}
void eccDecode(uint8_t* message, uint8_t* e, uint8_t* n){
bigExp(message,e,n);
}
int32_t isPrime(uint8_t* num){
int32_t i=0;
for(;i<sizeof(small_primes);++i)
if(bigSMod(num,small_primes[i])==0)
return 0;
return millerRabin(num);
}
int32_t millerRabin(uint8_t* n){
//Most memory requirement part. mem=8*NUMLEN
#if ECCDEBUG==1
USART0_SendStr("Start MR test:\n");
#endif
if(n[0]&1==0)
return 0;
uint32_t t=0;
int32_t i=0,k;
uint8_t temp;
uint8_t s[NUMLEN];
uint8_t a[NUMLEN];
int32_t next=0;
bigCopy(s,n);
s[0]^=1;//s=s-1
while(!s[i]){
++i;
t+=8;
}
temp=s[i];
while((temp&1)==0){
++t;
temp>>=1;
}
bigRShift(s,t);
k=0;
while(k<MILLER_RABIN_K){
#if ECCDEBUG==1
USART0_SendByte('.');
#endif
n[0]|=1;
bigRandom(a,n);
bigExp(a,s,n);//a=a**s mod n
n[0]^=1;
if(!(bigIsOne(a)||bigEqual(a,n))){
next=0;
for(i=0;(i<t-1)&&!next;++i){
n[0]|=1;
bigMul(a,a,n);
if(bigIsOne(a)){
#if ECCDEBUG==1
USART0_SendByte(' ');
#endif
return 0;
}
n[0]^=1;
if(bigEqual(a,n))
next=1;
}
if(!next){
#if ECCDEBUG==1
USART0_SendByte(' ');
#endif
return 0;
}
}
k+=2;
}
#if ECCDEBUG==1
USART0_SendStr("\n");
#endif
n[0]|=1;
return 1;
}
void getLargePrime(uint8_t* arr,uint32_t to){
#if ECCDEBUG0==1
USART0_SendStr("Attempt: ");
#endif
uint32_t k=0;
do{
++k;
bigRandomTo(arr,to);
arr[0]|=1;
#if ECCDEBUG0==1
USART0_SendNum(k);
if(k%20==0)
USART0_SendStr("\n");
else
USART0_SendByte(' ');
USART0_SendByte('\n');
bigPrint(arr);
#endif
}while(!isPrime(arr));
#if ECCDEBUG0==1
USART0_SendStr("\n");
#endif
}
uint8_t getOpenExp(uint8_t* num){
int32_t i=1;
for(;i<sizeof(small_primes);++i){
if(bigSMod(num,small_primes[i])!=0)
return small_primes[i];
}
return 0;
}
void getECCkeys(uint8_t* e,uint8_t* d,uint8_t* n){
uint32_t expected=0.693147*NUMLEN;
uint8_t q[NUMLEN],p[NUMLEN];
*e=0;
while(!*e){
#if ECCDEBUG0==1
USART0_SendStr("Generating ");
USART0_SendNum(PRIMELEN);
USART0_SendStr("-byte primes.\n");
USART0_SendStr("Expected number of attempts: ");
USART0_SendNum(expected);
USART0_SendStr("\n\nGenerating prime (1/2):\n");
#endif
getLargePrime(q,PRIMELEN);
unsigned temp=bigBitLen(q);
USART0_SendStr("===========");
USART0_SendNum(temp);
USART0_SendStr("===========");
#if ECCDEBUG0==1
USART0_SendStr("Generating prime (2/2):\n");
#endif
getLargePrime(p,PRIMELEN);
q[0]&=~1;//q-=1
p[0]&=~1;//p-=1
bigCopy(n,q);
bigMul(n,p,NULL);//n=(q-1)(p-1)=phi(q*p)
if(bigBitLen(n)<=MSGBITLEN)
continue;
q[0]|=1;
p[0]|=1;
*e=getOpenExp(n);
}
bigReverseBS(n,*e,d);
bigCopy(n,q);
bigMul(n,p,NULL);//n=q*p
}
/*
rng.cглавный файл генератора случайных чисел
*/
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include "rc4.h"
#define STOPCODE 2
#define POOLSIZE 256
#define USART_BAUDRATE 4800UL
#define BAUD_PRESCALE (((F_CPU/(USART_BAUDRATE*16UL)))-1)
#define EOL 0x0D
struct rc4state state;
uint8_t pool[POOLSIZE];
uint8_t pooli=0;
uint8_t poolBit=0;
volatile uint8_t poolFull=0;
volatile uint32_t bytesToSend=0;
void saveRNGstate(){
eeprom_write_block(0,state->s,256);
}
ISR(USART_RXC_vect){
bytesToSend=UDR;
if(bytesToSend==0)
bytesToSend=256;
}
void USART_init(void){
UBRRL=BAUD_PRESCALE;
UBRRH=BAUD_PRESCALE>>8;
UCSRB=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
}
void USART_SendByte(uint8_t u8Data){
while((UCSRA&(1<<UDRE))==0);
UDR=u8Data;
}
ISR(ADC_vect){
uint32_t temp=ADC;
int32_t i=1;
for(;i<10;++i)
temp^=temp<<i;
temp^=PC1;
pool[pooli]^=temp>>poolBit;
++poolBit;
if(poolBit==8){
if(pooli==POOLSIZE-1)
poolFull=1;
++pooli;
poolBit=0;
}
ADCSRA|=1<<ADSC;
}
void ADC_init(){
// SFIOR=0b00000000;
ADMUX=0b00000000;
ADCSRA=0b11001011;
MCUCR=0b00100100;
}
void main(void){
DDRB=0xff;
USART_init();
ADC_init();
sei();
eeprom_read_block(pool,0,POOLSIZE);
while(!poolFull);
rc4new(&state,pool,POOLSIZE);
poolFull=!poolFull;
while(bytesToSend!=STOPCODE){
if(bytesToSend){
cli(); // Чтобы быстрее отослать данные, а не потому что прерывания могут что-то испортить в переменных
while(bytesToSend){
USART_SendByte(nextRand(&state));
--bytesToSend;
}
sei();
}
if(poolFull){
poolFull=0;
rc4update(&state,pool,POOLSIZE);
}
nextRand(&state);
}
saveRNGstate();
while(1);
}