Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Дипломный проект. А.В. Шпак.docx
Скачиваний:
146
Добавлен:
24.02.2016
Размер:
3.35 Mб
Скачать

Приложение а

Листинг кода программы системы аутентификации пользователя транспортного средства

/*

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);

}

99