#include <SPI.h>
|
#include <MFRC522.h>
|
#include <EEPROM.h> // Libreria di gestione EEPROM
|
MFRC522 mfrc522(10, 9);
|
MFRC522::MIFARE_Key key;
|
boolean prog_flg = true;
|
/*
|
* Initialize.
|
*/
|
// Define variables
|
#define LED_ON LOW
|
#define LED_OFF HIGH
|
constexpr uint8_t Tx_pin = 8; // Pin di trasmissione
|
constexpr uint8_t Supply_pin = 7; // Pin di alimentazione del trasmettirote (attivo HIGH)
|
constexpr uint8_t UNO = LOW; // Segnale di uno logico
|
constexpr uint8_t ZERO = HIGH; // Segnale di zero logico
|
/*
|
**************
|
Mappa EEPROM
|
**************
|
|
00-03 Contatore di chiave
|
04 Flag di inizializzazione
|
05-FF non usati
|
|
*/
|
|
constexpr uint8_t Led_Rosso = 4;
|
constexpr uint8_t Led_Verde = 3;
|
/*
|
* PASSWORD GENERATRICE
|
*
|
1CA97A224432B78088A91048A5C739C54BAB2C8400372600B8A37C0F825A5386F65F62368CDBF3A69492DB949DE0D7D069C35640632C7811A6C03C7651A1D070
|
414A8E117B18F5FF9C971568F491AF16D7C752584B8130DC5B37C37A540E9EC2945289FA2E424411FDFEA903918119483687A82D7C40A0C8B2D3ACC3DF6E7A15
|
41885C9090E2FE1652CF87FF35A9CD87456D13944398DD26192672AF8D588D9AD03431173C581C114F3BA5B849211A7AC13009833B9AA277EC95A54C943303F2
|
0E77972C8F631E0E5565B05D853D7BCD2AF969D3C38E10906FCE03BD6A3E4EA2176A9A887582F1CC81901D907C8ACC36CEC8124EE2BB8146C83F2FB2E0C2E621
|
AF57E4EAE8DE641BA14027631FDB1C4E20C5E9FFC8DA14A73229122122B7D5F519E2DA9D9DC8CCF394AFC8FFF34ADA97DC4E70958E11DBB1424AAA55B0738ABD
|
C478E46212A00FC7617599265EF717B621CCBD2125F780945DDEA454AF2EA2D74A34262770C21A8A862EC61E0022D09D00ADFA815F33BB32866E6713DB85639E
|
8EBB8B3E129D3FA312F7B90876F495DFC9CC0BB7ED630FCDFD128D67FFA78059D7AAC3965A0A0C49D25C2C09D136779049E4C14555745CF53352B3C69ECF6389
|
8B6A75991CAEC19270ECBF7E1095D2E1E745F7DFA42B53CE987B6B0881CE0A802C3018EDA109A8FACFCBEA5B9FDC8C18DB0E131E27DF124B2B2C5E101E5D162D
|
968193F815A2A09B5D692D8C450D81D8
|
*
|
*/
|
byte Key [][8] = {
|
{203, 129, 150, 202, 104, 213, 42, 252},
|
{6, 240, 136, 110, 195, 193, 237, 109},
|
{218, 208, 198, 117, 74, 137, 219, 76},
|
{191, 35, 77, 220, 136, 155, 119, 134},
|
{183, 26, 29, 164, 170, 66, 214, 180},
|
{223, 11, 22, 186, 122, 42, 126, 133},
|
{126, 224, 172, 32, 242, 55, 61, 51},
|
{43, 231, 27, 38, 72, 142, 1, 149},
|
{52, 6, 93, 0, 117, 239, 26, 26},
|
{151, 113, 214, 179, 155, 13, 191, 107},
|
{58, 65, 180, 66, 136, 249, 149, 70},
|
{176, 20, 66, 20, 58, 248, 67, 150},
|
{157, 97, 233, 185, 77, 217, 246, 175},
|
{194, 101, 44, 253, 61, 206, 47, 210},
|
{199, 20, 201, 193, 206, 164, 24, 48},
|
{198, 134, 153, 159, 238, 115, 12, 83},
|
{26, 240, 158, 222, 163, 239, 29, 247},
|
{201, 83, 138, 247, 42, 56, 116, 21},
|
{210, 217, 66, 196, 186, 130, 160, 188},
|
{155, 122, 155, 152, 199, 61, 72, 107},
|
{7, 220, 21, 14, 155, 109, 135, 75},
|
{100, 245, 160, 203, 63, 16, 94, 76},
|
{73, 213, 140, 117, 4, 214, 145, 199},
|
{131, 65, 111, 158, 17, 6, 7, 32},
|
{72, 107, 212, 38, 94, 152, 79, 201},
|
{236, 147, 71, 143, 183, 114, 58, 130},
|
{101, 196, 214, 23, 35, 6, 85, 129},
|
{227, 97, 34, 16, 118, 197, 168, 124},
|
{219, 169, 131, 61, 114, 79, 39, 201},
|
{85, 150, 166, 90, 233, 238, 254, 26},
|
{112, 74, 236, 48, 17, 144, 71, 23},
|
{92, 122, 206, 207, 164, 179, 109, 39},
|
{183, 80, 89, 133, 74, 245, 39, 227},
|
{135, 43, 38, 36, 63, 45, 83, 15},
|
{131, 28, 200, 125, 101, 241, 71, 58},
|
{51, 89, 255, 81, 106, 83, 79, 131},
|
{194, 254, 197, 43, 26, 73, 223, 11},
|
{163, 76, 219, 137, 119, 121, 151, 16},
|
{96, 125, 131, 86, 83, 180, 152, 251},
|
{100, 85, 125, 109, 238, 104, 184, 227},
|
{182, 170, 106, 226, 32, 238, 245, 238},
|
{83, 32, 127, 45, 85, 121, 170, 157},
|
{189, 234, 171, 40, 174, 89, 122, 102},
|
{13, 47, 3, 83, 81, 239, 181, 12},
|
{197, 79, 183, 173, 25, 219, 88, 50},
|
{247, 45, 142, 72, 244, 191, 204, 100},
|
{171, 62, 153, 255, 245, 205, 17, 133},
|
{41, 155, 189, 246, 48, 223, 236, 42},
|
{239, 179, 233, 71, 155, 165, 116, 147},
|
{48, 160, 13, 155, 122, 158, 62, 51},
|
{140, 177, 253, 6, 41, 40, 151, 159},
|
{135, 30, 159, 192, 173, 42, 191, 187},
|
{195, 229, 201, 146, 221, 213, 224, 213},
|
{236, 204, 248, 34, 53, 218, 65, 3},
|
{47, 38, 136, 61, 35, 129, 123, 211},
|
{71, 22, 107, 217, 15, 1, 216, 185},
|
{186, 185, 241, 184, 158, 69, 115, 206},
|
{218, 109, 153, 244, 64, 224, 53, 129},
|
{37, 148, 168, 19, 167, 134, 170, 20},
|
{41, 172, 153, 72, 176, 134, 164, 152},
|
{126, 196, 216, 186, 192, 191, 164, 106},
|
{33, 99, 126, 224, 137, 161, 62, 98},
|
{4, 176, 112, 177, 169, 247, 203, 103},
|
{82, 73, 45, 227, 206, 165, 156, 37},
|
{168, 201, 113, 232, 82, 20, 174, 53},
|
{208, 181, 253, 161, 239, 174, 203, 112}
|
};
|
char s[33];
|
byte a[8], b[8];
|
byte icnt[8] = {0, 0, 0, 1, 0,0,0,0};
|
|
byte trailerBlock, blockAddr;
|
byte sector = 1;
|
byte blockoff = 0;
|
byte sectdata[4][16];
|
byte blockdata[16];
|
byte LockN[7]; // codice dispositivo
|
|
void setup() {
|
Serial.begin(9600);
|
pinMode(Led_Rosso, OUTPUT);
|
pinMode(Led_Verde, OUTPUT);
|
pinMode(Supply_pin, OUTPUT);
|
digitalWrite(Supply_pin, LOW); // trasmissione disabilitata
|
pinMode(Tx_pin, OUTPUT);
|
digitalWrite(Tx_pin, ZERO); // segnale di trasmissione basso
|
|
for (byte i = 0; i < 6; i++) {
|
key.keyByte[i] = 0xff;
|
}
|
digitalWrite(Led_Rosso, LOW);
|
digitalWrite(Led_Verde, LOW);
|
delay(1000);
|
digitalWrite(Led_Rosso, HIGH);
|
digitalWrite(Led_Verde, HIGH);
|
}
|
void loop() {
|
SPI.begin();
|
delay(500);
|
mfrc522.PCD_Init();
|
delay(500);
|
blockoff = blockoff + 1;
|
if(blockoff > 2) {
|
blockoff = 0;
|
sector = sector + 1;
|
if(sector > 15) sector = 1;
|
}
|
blockAddr = sector*4 + blockoff;
|
// Look for new cards
|
if ( ! mfrc522.PICC_IsNewCardPresent()) return;
|
// Select one of the cards
|
if ( ! mfrc522.PICC_ReadCardSerial()) return;
|
trailerBlock = sector * 4 + 3;
|
mfrc522.PICC_DumpMifareClassicBlockToRead(&(mfrc522.uid), &key, sector, blockAddr, blockdata);
|
for ( uint8_t i = 0; i < 8; i++) {
|
a[i] = blockdata[i];
|
}
|
for ( uint8_t i = 0; i < 8; i++) {
|
b[i] = blockdata[i+8];
|
}
|
DeKrypto(a,b, 31);
|
// Test di coerenza di a
|
boolean valid_flg = true;
|
// Test sul blocco
|
if(a[3] != blockAddr){
|
valid_flg = false;
|
}
|
// Confronta a con l'UID
|
for ( uint8_t i = 0; i < 4; i++) {
|
if(mfrc522.uid.uidByte[i] != a[i+4]) valid_flg = false;
|
}
|
if(valid_flg) {
|
// Verifica la tipologia di card
|
if(b[7] == 255){
|
// Passepartout Card:
|
if(prog_flg){
|
//Appena dopo il reset imposta il codice serratura
|
EEPROMWrite(b, 7, 8);
|
EEPROMRead(LockN, 7, 8); // salva il nuovo valore della serratura in LockN[
|
}
|
EEPROMCounterReset(); // Azzera il contatore nella EEPROM
|
RFTransmit(); // Comunque trasmette il codice
|
}
|
else if(b[7] == 0){
|
// User Card: verifica la coerenza di codice di serratura
|
if(CompareVector(b, LockN, 0, 7)){
|
for(byte i=0;i<4;++i){
|
a[i+4] = LockN[i];
|
}
|
RFTransmit();
|
}
|
}
|
prog_flg = false;
|
}
|
else {
|
digitalWrite(Led_Rosso, LOW);
|
delay(1000);
|
digitalWrite(Led_Rosso, HIGH);
|
}
|
// Halt PICC
|
mfrc522.PICC_HaltA();
|
// Stop encryption on PCD
|
mfrc522.PCD_StopCrypto1();
|
}
|
boolean CompareVector(byte *x, byte *z, byte inz, byte dv) {
|
byte j;
|
boolean flg = true;
|
for (j = inz; j |
if(x[j] != z[j]) flg = false;
|
}
|
return flg;
|
}
|
void VectorValue(char* code, byte *x) {
|
byte j=0;
|
for(byte i=0; i<8; i=i+2) {
|
x[j] = HextoDec(code[i], code[i+1]);
|
j=j+1;
|
}
|
}
|
byte HextoDec(char x, char y) {
|
byte h, l, r;
|
h = 0;
|
l = 0;
|
if(x>64) h = x - 55;
|
else h = x - 48;
|
if(y>64) l = y - 55;
|
else l = y - 48;
|
r = h*16 + l;
|
return r;
|
}
|
|
/*-----( Funzioni di Cifratura )-----*/
|
|
void Krypto(byte a[8], byte b[8], byte nit) {
|
byte i, j, rck, rtb;
|
byte rs[8];
|
Sum(a, Key[0], a);
|
Sum(b, Key[1], b);
|
for (i = 1; i |
Xor(a, b, rs);
|
rck = b[7] & 1;
|
if(rck > 0){
|
Swap(rs, rs);
|
}
|
rck = b[7] & 63;
|
rtb = b[7] & 64;
|
if(rtb > 0) LeftRot(rs, rck, rs);
|
else RightRot(rs, rck, rs);
|
Sum(rs, Key[2*i], a);
|
Xor(b, a, rs);
|
rck = a[7] & 1;
|
if(rck > 0){
|
Swap(rs, rs);
|
}
|
rck = a[7] & 63;
|
rtb = a[7] & 64;
|
if(rtb > 0) LeftRot(rs, rck, rs);
|
else RightRot(rs, rck, rs);
|
Sum(rs, Key[2*i+1], b);
|
}
|
}
|
|
void DeKrypto(byte a[8], byte b[8], byte nit) {
|
byte i, j, k, rck, rtb;
|
byte rs[8];
|
for (k = 0; k |
i = nit - k;
|
Subt (b, Key[2*i+1], rs);
|
rck = a[7] & 63;
|
rtb = a[7] & 64;
|
if(rtb > 0) {
|
RightRot(rs, rck, rs);
|
}
|
else {
|
LeftRot(rs, rck, rs);
|
}
|
rck = a[7] & 1;
|
if(rck > 0){
|
Swap(rs, rs);
|
}
|
Xor(rs, a, b);
|
Subt (a, Key[2*i], rs);
|
rck = b[7] & 63;
|
rtb = b[7] & 64;
|
if(rtb > 0){
|
RightRot(rs, rck, rs);
|
}
|
else {
|
LeftRot(rs, rck, rs);
|
}
|
rck = b[7] & 1;
|
if(rck > 0){
|
Swap(rs, rs);
|
}
|
Xor(rs, b, a);
|
}
|
Subt(b, Key[1], b);
|
Subt(a, Key[0], a);
|
}
|
|
void Sum(byte x[8], byte y[8], byte z[8]) {
|
byte rp = 0, i, j;
|
int rs;
|
for (j = 0; j<8; j++) {
|
i = 7 - j;
|
rs = x[i] + y[i] + rp;
|
if(rs > 255) {
|
rs = rs - 256;
|
rp = 1;
|
}
|
else rp = 0;
|
z[i] = byte(rs);
|
}
|
}
|
|
void Subt(byte x[8], byte y[8], byte z[8]) {
|
byte rp = 0, i, j;
|
int rs;
|
for (j = 0; j<8; j++) {
|
i = 7 - j;
|
rs = x[i] - y[i] - rp;
|
if(rs < 0) {
|
rs = rs + 256;
|
rp = 1;
|
}
|
else rp = 0;
|
z[i] = byte(rs);
|
}
|
}
|
|
void LeftRot(byte x[8], byte rotn, byte z[8]) {
|
byte rp;
|
int rs;
|
byte i;
|
byte j;
|
byte k;
|
for (k = 0; k |
rp = 0;
|
for (j = 0; j<8; j++) {
|
i = 7 - j;
|
rs = x[i] << 1;
|
rs = rs | int(rp);
|
if(rs > 255) {
|
rs = rs - 256;
|
rp = 1;
|
}
|
else rp = 0;
|
z[i] = byte(rs);
|
}
|
z[7] = z[7] | rp;
|
}
|
}
|
|
void RightRot(byte x[8], byte rotn, byte z[8]) {
|
byte rp;
|
byte rs;
|
byte j;
|
byte k;
|
for (k = 0; k |
rp = 0;
|
for (j = 0; j<8; j++) {
|
rs = rp;
|
if((x[j] & 1) > 0) rp = 128;
|
else rp = 0;
|
z[j] = (x[j] >> 1) | rs;
|
}
|
z[0] = z[0] | rp;
|
}
|
}
|
|
void Xor(byte x[8], byte y[8], byte z[8]) {
|
byte j;
|
for (j = 0; j<8; j++) {
|
z[j] = x[j]^y[j];
|
}
|
}
|
|
byte UnoNB(byte x[8], byte y[8]) {
|
byte u = 0;
|
for (byte i = 0; i<8; i++) {
|
for (byte j = 0; j < 8; j++) {
|
if(bitRead(x[i], j) == 1) u = u + 1;
|
if(bitRead(y[i], j) == 1) u = u + 1;
|
}
|
}
|
return u;
|
}
|
|
void Swap(byte x[8], byte z[8]) {
|
byte j;
|
for (j = 0; j<8; j++) {
|
z[j] = (x[j] << 4) | (x[j] >> 4);
|
}
|
}
|
|
void RFTransmit() {
|
digitalWrite(Led_Verde, LOW);
|
byte unocnt;
|
EEPROMRead(a, 4, 0);
|
Sum(a, icnt, a); // Incremento
|
EEPROMWrite(a, 4, 0);
|
VectorPrint(a, 8);
|
VectorPrint(b, 8);
|
Serial.println();
|
Krypto(a, b, 33);
|
unocnt = UnoNB(a, b);
|
digitalWrite(Supply_pin, HIGH); // Abilitazione trasmissione
|
for (byte k = 0; k < 10; k++) {
|
digitalWrite(Tx_pin, UNO); // Start bit
|
delayMicroseconds(1200);
|
for (byte i = 0; i < 8; i++) {
|
ByteTx(a[i]);
|
}
|
for (byte i = 0; i < 8; i++) {
|
ByteTx(b[i]);
|
}
|
ByteTx(unocnt); // Invio di un byte di controllo (numero di uno)
|
}
|
digitalWrite(Supply_pin, LOW); // Disabilitazione trasmissione
|
delay(1000);
|
digitalWrite(Led_Verde, HIGH);
|
}
|
|
void ByteTx(byte xc){
|
for (byte i = 0; i < 8; i++) {
|
digitalWrite(Tx_pin, ZERO); // ith bit
|
if(bitRead(xc, 7-i) == 1){
|
delayMicroseconds(600); // bit a 1
|
}
|
else {
|
delayMicroseconds(300); // bit a 0
|
}
|
digitalWrite(Tx_pin, UNO); // end bit
|
delayMicroseconds(300); // durata end bit
|
}
|
}
|
|
void CopyVector(byte *src, byte *dst, byte inz, byte dv) {
|
for (byte j = inz; j |
dst[j] = src[j];
|
}
|
}
|
|
void DectoHex(byte z, char ch[2]) {
|
byte nb;
|
nb = z / 16;
|
if (nb>9){nb = nb + 55;}
|
else {nb = nb + 48;}
|
ch[0] = char(nb);
|
nb = z % 16;
|
if (nb>9){nb = nb + 55;}
|
else {nb = nb + 48;}
|
ch[1] = char(nb);
|
}
|
void VectorPrint(byte *x, byte dv) {
|
char ch[2];
|
for (byte i = 0; i < dv; i++) {
|
DectoHex(x[i], ch);
|
Serial.print(ch[0]);
|
Serial.print(ch[1]);
|
}
|
}
|
|
/////////////////////////////////////// Gestione Contatore su EEPROM 00-03 //////////////////////////////
|
|
void EEPROMRead(byte *x, int dv, int adr){
|
for ( int i = 0; i < dv; i++) { // Legge il vettore dalla EEPROM
|
x[i] = EEPROM.read(adr+i); // Salva il byte nel vettore
|
}
|
}
|
|
void EEPROMWrite(byte *x, int dv, int adr){
|
for ( int i = 0; i < dv; i++) { // Scrive il vettore nella EEPROM
|
EEPROM.write(adr+i, x[i]);
|
}
|
}
|
|
void EEPROMCounterReset(){
|
for ( int i = 0; i < 4; i++) { // Azzera il contatore nella EEPROM
|
EEPROM.write(i, 0);
|
}
|
}
|