-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d33fc52
commit beff5eb
Showing
6 changed files
with
571 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* | ||
* Functions.c | ||
* | ||
* Created on: Nov 20, 2021 | ||
* Author: mrras | ||
*/ | ||
#include "Functions.h" | ||
#include "SmartCard.h" | ||
#include "main.h" | ||
|
||
static void delay(); | ||
static void setClockOutput(); | ||
static void setIOInput(); | ||
static void setIOOutput(); | ||
static void setResetOutput(); | ||
static bool readIO(); | ||
static void writeIO(bool value); | ||
static void writeClock(bool value); | ||
static void writeReset(bool value); | ||
static void oneMiliDelay(); | ||
|
||
using namespace smartCards; | ||
|
||
smartCard sc(delay, setClockOutput, setResetOutput, setIOInput, setIOOutput, | ||
writeClock, writeIO, writeReset, readIO, oneMiliDelay); | ||
|
||
void initSmartCard(uint8_t *data) { | ||
uint8_t d; | ||
auto t = sc.initialize(data); | ||
if (t == SmartCard_Results::OK) { | ||
auto r = sc.authenticate(0xFF, 0xFF, 0xFF); | ||
if (r == SmartCardAuth_Results::PSCVerified) { | ||
for (int i = 0; i < 256; ++i) { | ||
t = sc.writeMainMemory(i, i); | ||
} | ||
for (int i = 0; i < 256; ++i) { | ||
t = sc.readMainMemory(i, &d); | ||
} | ||
} | ||
} | ||
} | ||
|
||
static void delay() { | ||
asm("nop"); | ||
} | ||
|
||
static void setClockOutput() { | ||
//TODO: set clock pin as output | ||
} | ||
|
||
static void setIOInput() { | ||
GPIO_InitTypeDef GPIO_InitStruct = { 0 }; | ||
GPIO_InitStruct.Pin = SMARTCARD_IO_Pin; | ||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; | ||
GPIO_InitStruct.Pull = GPIO_PULLUP; | ||
HAL_GPIO_Init(SMARTCARD_IO_GPIO_Port, &GPIO_InitStruct); | ||
} | ||
|
||
static void setIOOutput() { | ||
GPIO_InitTypeDef GPIO_InitStruct = { 0 }; | ||
GPIO_InitStruct.Pin = SMARTCARD_IO_Pin; | ||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; | ||
GPIO_InitStruct.Pull = GPIO_NOPULL; | ||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; | ||
HAL_GPIO_Init(SMARTCARD_IO_GPIO_Port, &GPIO_InitStruct); | ||
} | ||
|
||
static void setResetOutput() { | ||
//TODO: set reset pin as output | ||
} | ||
|
||
static bool readIO() { | ||
return (SMARTCARD_IO_GPIO_Port->IDR & SMARTCARD_IO_Pin) != 0x00U; | ||
} | ||
|
||
static void writeIO(bool value) { | ||
if (value) | ||
SMARTCARD_IO_GPIO_Port->BSRR = SMARTCARD_IO_Pin; | ||
else | ||
SMARTCARD_IO_GPIO_Port->BSRR = (uint32_t) SMARTCARD_IO_Pin << 16; | ||
} | ||
|
||
static void writeClock(bool value) { | ||
if (value) | ||
SMARTCARD_CLOCK_GPIO_Port->BSRR = SMARTCARD_CLOCK_Pin; | ||
else | ||
SMARTCARD_CLOCK_GPIO_Port->BSRR = (uint32_t) SMARTCARD_CLOCK_Pin << 16; | ||
} | ||
|
||
static void writeReset(bool value) { | ||
if (value) | ||
SMARTCARD_RESET_GPIO_Port->BSRR = SMARTCARD_RESET_Pin; | ||
else | ||
SMARTCARD_RESET_GPIO_Port->BSRR = (uint32_t) SMARTCARD_RESET_Pin << 16; | ||
} | ||
|
||
static void oneMiliDelay() { | ||
HAL_Delay(1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* Functions.h | ||
* | ||
* Created on: Nov 20, 2021 | ||
* Author: mrras | ||
*/ | ||
|
||
#ifndef MYDRIVERS_FUNCTIONS_H_ | ||
#define MYDRIVERS_FUNCTIONS_H_ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#include "stdint.h" | ||
|
||
void initSmartCard(uint8_t *data); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* MYDRIVERS_FUNCTIONS_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
/* | ||
* SLE4442.cpp | ||
* | ||
* Created on: ۲ آذر ۱۴۰۰ | ||
* Author: mrras | ||
*/ | ||
|
||
#include <SLE4442.h> | ||
|
||
namespace smartCards { | ||
|
||
/** | ||
* @brief SLE4442 class (max clock : 50KHz, minimum pulse width: 9us) | ||
* @param delayFunction : function which make 10us delay | ||
* @retval None | ||
*/ | ||
SLE4442::SLE4442() : | ||
m_readRefresh(true) { | ||
} | ||
|
||
/** | ||
* @brief Initialize the smart card | ||
* @param data : returns the first four bytes in main memory | ||
* @retval None | ||
*/ | ||
bool SLE4442::initialize(uint8_t *data) const { | ||
uint32_t *d = reinterpret_cast<uint32_t*>(data); | ||
uint8_t tmp; | ||
m_setResetOutput(); | ||
m_setClockOutput(); | ||
m_setIOInput(); | ||
m_writeReset(false); | ||
m_writeClock(false); | ||
m_writeReset(true); | ||
m_oneMiliDelay(); // A little extra wait time for this | ||
m_writeClock(true); | ||
m_delay(); | ||
m_writeClock(false); | ||
m_delay(); | ||
m_oneMiliDelay(); // A little extra wait time for this | ||
m_writeReset(false); | ||
m_delay(); | ||
*d = m_readIO(); | ||
for (int index = 0; index < 4; index++) { | ||
tmp = read(); | ||
*d |= static_cast<uint32_t>(tmp) << (index * 8 + 1); | ||
} | ||
return d[0] != 0xFF; | ||
} | ||
|
||
uint8_t SLE4442::read() const { | ||
uint8_t data = 0; | ||
m_setIOInput(); | ||
m_writeClock(true); | ||
m_delay(); | ||
for (int i = 0; i < 8; i++) { | ||
data = data >> 1; | ||
m_writeClock(false); | ||
m_delay(); | ||
m_writeClock(true); | ||
m_delay(); | ||
if (m_readIO()) { | ||
data += 0x80; | ||
} | ||
} | ||
return data; | ||
} | ||
|
||
void SLE4442::process() const { | ||
m_setIOInput(); | ||
m_writeClock(false); | ||
m_delay(); | ||
while (m_readIO() == false) { | ||
m_writeClock(true); | ||
m_delay(); | ||
m_writeClock(false); | ||
m_delay(); | ||
} | ||
} | ||
|
||
void SLE4442::sendCommand(uint8_t command, uint8_t address, | ||
uint8_t data) const { | ||
//Output(CLOCK); | ||
m_writeClock(true); | ||
m_delay(); | ||
m_setIOOutput(); | ||
m_writeIO(false); | ||
write(command); | ||
write(address); | ||
write(data); | ||
m_writeClock(false); | ||
m_delay(); | ||
m_writeIO(false); | ||
m_writeClock(true); | ||
m_delay(); | ||
m_writeIO(true); | ||
|
||
if (command == UpdateMain || command == UpdateProtection | ||
|| command == CompareData || command == UpdateSecurity) | ||
process(); | ||
} | ||
|
||
void SLE4442::write(uint8_t data) const { | ||
uint8_t command = data; | ||
bool temp = 0; | ||
|
||
for (int i = 0; i < 8; i++) { | ||
temp = command & 0x01; | ||
command = command >> 1; | ||
m_writeClock(false); | ||
m_delay(); | ||
if (temp != 0) | ||
m_writeIO(true); | ||
else | ||
m_writeIO(false); | ||
m_writeClock(true); | ||
m_delay(); | ||
} | ||
} | ||
|
||
/** | ||
* @brief Authenticate the smart card(authentication (valid or invalid) is remain until card has power) | ||
* @param None | ||
* @retval The authentication code : | ||
* 0x00 : Card is locked | ||
* 0x01 : Invalid PSC, one try remaining | ||
* 0x03 : Invalid PSC, two tries remaining | ||
* 0x07 : PSC verified, you may now write data to the card (Authentication is OK) | ||
* else : Unable to Authenticate | ||
*/ | ||
uint8_t SLE4442::authenticate(uint8_t password1, uint8_t password2, | ||
uint8_t password3) const { | ||
uint8_t data; | ||
|
||
uint8_t errCounter = readSecurity(); | ||
|
||
errCounter = errCounter & 0x07; | ||
data = errCounter >> 1; | ||
|
||
sendCommand(UpdateSecurity, 0x00, data); | ||
sendCommand(CompareData, 0x01, password1); | ||
sendCommand(CompareData, 0x02, password2); | ||
sendCommand(CompareData, 0x03, password3); | ||
|
||
sendCommand(UpdateSecurity, 0x00, 0x07); | ||
|
||
errCounter = readSecurity(); | ||
|
||
return errCounter; | ||
} | ||
|
||
void SLE4442::writeMainMemory(uint8_t location, uint8_t value) { | ||
m_readRefresh = true; | ||
sendCommand(UpdateMain, location, value); | ||
} | ||
|
||
uint8_t SLE4442::readMainMemory(uint8_t location) { | ||
if (m_readRefresh) { | ||
m_readRefresh = false; | ||
sendCommand(ReadMain, 0x00, 0x00); | ||
for (int i = 0; i < 256; i++) | ||
m_readBuffer[i] = read(); | ||
} | ||
return m_readBuffer[location]; | ||
} | ||
|
||
void SLE4442::readProtectedMemory(uint8_t *values) { | ||
sendCommand(ReadProtection, 0x00, 0x00); | ||
for (int i = 0; i < 32; i++) | ||
values[i] = read(); | ||
} | ||
|
||
void SLE4442::writeProtectedMemory(uint8_t location, uint8_t value) { | ||
sendCommand(UpdateProtection, location, value); | ||
} | ||
|
||
void SLE4442::writeSecuredMemory(uint8_t location, uint8_t value) { | ||
sendCommand(UpdateSecurity, location, value); | ||
} | ||
|
||
uint8_t SLE4442::readSecurity() const { | ||
sendCommand(ReadSecurity, 0x00, 0x00); | ||
uint8_t errCounter = read(); | ||
|
||
sendCommand(ReadSecurity, 0x01, 0x00); | ||
read(); | ||
|
||
sendCommand(ReadSecurity, 0x02, 0x00); | ||
read(); | ||
|
||
sendCommand(ReadSecurity, 0x03, 0x00); | ||
read(); | ||
|
||
return errCounter; | ||
} | ||
|
||
} /* namespace smartCards */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* SLE4442.h | ||
* | ||
* Created on: ۲ آذر ۱۴۰۰ | ||
* Author: mrras | ||
*/ | ||
|
||
#ifndef MYDRIVERS_SLE4442_H_ | ||
#define MYDRIVERS_SLE4442_H_ | ||
|
||
#include "stdint.h" | ||
|
||
#define DEVICE_ADDRESS 0xA0 // Device Address | ||
#define ACK 0 // ACK | ||
#define NAK 1 // NAK | ||
|
||
#define ReadMain 0x30 // Read main memory | ||
#define ReadProtection 0x34 // Read protection bit | ||
#define ReadSecurity 0x31 // Read PSC | ||
#define UpdateMain 0x38 // Update main memory | ||
#define UpdateSecurity 0x39 // Update PSC | ||
#define UpdateProtection 0x3C // Update Protection bits | ||
#define CompareData 0x33 // Compare Verification Data | ||
|
||
namespace smartCards { | ||
|
||
class SLE4442 { | ||
public: | ||
SLE4442(); | ||
|
||
protected: | ||
void (*m_delay)(); | ||
void (*m_setClockOutput)(); | ||
void (*m_setResetOutput)(); | ||
void (*m_setIOInput)(); | ||
void (*m_setIOOutput)(); | ||
void (*m_writeClock)(bool value); | ||
void (*m_writeIO)(bool value); | ||
void (*m_writeReset)(bool value); | ||
bool (*m_readIO)(); | ||
void (*m_oneMiliDelay)(); | ||
|
||
|
||
bool initialize(uint8_t *data) const; | ||
uint8_t authenticate(uint8_t password1 = 0xFF, uint8_t password2 = 0xFF, | ||
uint8_t password3 = 0xFF) const; | ||
|
||
uint8_t readMainMemory(uint8_t location); | ||
void writeMainMemory(uint8_t location, uint8_t value); | ||
|
||
void readProtectedMemory(uint8_t *values); | ||
void writeProtectedMemory(uint8_t location, uint8_t value); | ||
|
||
void writeSecuredMemory(uint8_t location, uint8_t value); | ||
|
||
private: | ||
bool m_readRefresh; | ||
uint8_t m_readBuffer[256]; | ||
uint8_t read() const; | ||
void write(uint8_t data) const; | ||
void process() const; | ||
void sendCommand(uint8_t command, uint8_t address, uint8_t data) const; | ||
uint8_t readSecurity() const; | ||
}; | ||
|
||
} /* namespace smartCards */ | ||
|
||
#endif /* MYDRIVERS_SLE4442_H_ */ |
Oops, something went wrong.