From 3dddeb80e0cc38103f562c6ce90cbefc047d8309 Mon Sep 17 00:00:00 2001 From: cfif Date: Mon, 2 Jun 2025 13:26:40 +0300 Subject: [PATCH] Init --- Inc/SignaturePduSpecific.h | 31 ++++ Src/EraGlonassUveos_PackageSignature.c | 99 +++++++++++ Src/SignaturePduSpecific.c | 237 +++++++++++++++++++++++++ modular.json | 12 ++ 4 files changed, 379 insertions(+) create mode 100644 Inc/SignaturePduSpecific.h create mode 100644 Src/EraGlonassUveos_PackageSignature.c create mode 100644 Src/SignaturePduSpecific.c create mode 100644 modular.json diff --git a/Inc/SignaturePduSpecific.h b/Inc/SignaturePduSpecific.h new file mode 100644 index 0000000..909ef7a --- /dev/null +++ b/Inc/SignaturePduSpecific.h @@ -0,0 +1,31 @@ +// +// Created by zemon on 07.02.23. +// + +#ifndef UVEOS_ON_NATION_SIGNATUREPDUSPECIFIC_H +#define UVEOS_ON_NATION_SIGNATUREPDUSPECIFIC_H + +#include "LoggerInterface.h" +#include "AtCmdBase.h" +#include "LoggerToSerialPort.h" + +typedef struct { + tAtCmd *atCmd; + uint8_t pduChanal; + tLoggerToSerialPort *slog; +// tEraGlonassMsd *eraGlonassUveos; +} tSignPack; + +void EraTSK_GetPackSignature(tSignPack *env, uint8_t *packetg, uint16_t packLenght); +AtCommandResult AtCmdSignaturePduContext(tAtCmd *env); +AtCommandResult AtCmdSignaturePdu_CloseContext(tAtCmd *env); + +void xGsmSendApdu(tAtCmd *env, uint8_t* data,uint16_t length) ; + +AtCommandResult AtCmdSignaturePdu_SelectApplet(tAtCmd *env, uint8_t canNum); + +AtCommandResult AtCmdSignaturePdu_GetChannalNum(tAtCmd *env, uint8_t *result); +AtCommandResult AtCmdSignaturePdu_UpdateData(tAtCmd *env, uint8_t canNum, uint8_t length, uint8_t *data); +AtCommandResult AtCmdSignaturePdu_SignData(tAtCmd *env, uint8_t canNum, uint8_t *mac, uint8_t *keyId); + +#endif //UVEOS_ON_NATION_SIGNATUREPDUSPECIFIC_H diff --git a/Src/EraGlonassUveos_PackageSignature.c b/Src/EraGlonassUveos_PackageSignature.c new file mode 100644 index 0000000..7b21e88 --- /dev/null +++ b/Src/EraGlonassUveos_PackageSignature.c @@ -0,0 +1,99 @@ +// +// Created by zemon on 07.02.23. +// + + +#include "SignaturePduSpecific.h" +#include "SystemDelayInterface.h" +#include "stdbool.h" + +#define LOGGER &env->slog->logger +#define LOG_SIGN "ПОДПИСЬ ТСК" + +bool vEraReadyModeSignOnePacket( + tSignPack *env, + uint8_t apduChanel, + uint8_t *packet, + uint16_t length, + uint8_t *macResult, + uint8_t *keyResult +) +{ + uint16_t left = length; + uint16_t offset = 0; + uint8_t lengthData = 0; + volatile AtCommandResult result; + while(left){ + lengthData = left<255?left:255; + result = AtCmdSignaturePdu_UpdateData(env->atCmd, apduChanel, lengthData, packet+offset); + if(result==AT_OK){ + LoggerInfoStatic(LOGGER, LOG_SIGN, "Подпись добавлена") + }else{ + LoggerInfoStatic(LOGGER, LOG_SIGN, "UpdateData error") + return false; + } + + offset+=lengthData; + left-=lengthData; + } + SystemDelayMs(1000); + result = AtCmdSignaturePdu_SignData(env->atCmd,apduChanel, macResult,keyResult); + if(result==AT_OK){ + LoggerInfoStatic(LOGGER, LOG_SIGN, "Пакет подписан") + return true; + }else{ + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка подписи") + return false; + } + +} + +//void EraGlonassUveos_GetOnePackSignature(tSignPack *env) +//{ +// uint16_t packetLength = 0; +// uint8_t packet[320] = {0}; +// uint8_t macSign[33]; +// uint8_t keyId; +// vEraReadyModeSignOnePacket( +// env, +// env->pduChanal, +// packet, +// packetLength, +// macSign, +// &keyId +// ); +//} + +void EraTSK_GetPackSignature(tSignPack *env, uint8_t *packetg, uint16_t packLenght) +{ + uint8_t chanNum; + volatile AtCommandResult res; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Попытка получить канал подписи из апплета") + res = AtCmdSignaturePdu_GetChannalNum(env->atCmd,&chanNum); + if (res == AT_OK) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Канал подписи на апплете получен и открыт, открытие апплета") + res = AtCmdSignaturePdu_SelectApplet(env->atCmd, chanNum); + if (res == AT_OK) { + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Апплет открыт") + env->pduChanal = chanNum; + uint8_t macSign[33]; + uint8_t keyId; + + volatile bool res = vEraReadyModeSignOnePacket( + env, + env->pduChanal, + packetg, + packLenght, + macSign, + &keyId + ); + LoggerInfoStatic(LOGGER, LOG_SIGN, "-") + LoggerInfo(LOGGER, LOG_SIGN, (char*)macSign, sizeof(macSign)) +// while (1){ SystemDelayMs(10);} + } + } + +} +// + diff --git a/Src/SignaturePduSpecific.c b/Src/SignaturePduSpecific.c new file mode 100644 index 0000000..f2bce1b --- /dev/null +++ b/Src/SignaturePduSpecific.c @@ -0,0 +1,237 @@ +// +// Created by zemon on 07.02.23. +// + +#include +#include "SignaturePduSpecific.h" +#include "AtCmdCommonProtected.h" +#include "SystemDelayInterface.h" +#include "AsciiStringAssmeblingUtils.h" +#include "AsciiStringParsingUtils.h" + +#define TO_HEX(NIBBLE) ((NIBBLE) <= 9 ? '0' + (NIBBLE) : 'A' - 10 + (NIBBLE)) +#define FROM_HEX(HEX) ((HEX) <= '9' ? (HEX) - '0' : HEX + 10 - 'A') + +void vConvertAsciiToBytes(const unsigned char *hexString, uint16_t hexStringLength, char *dataResult) { + uint16_t i = 0; + uint16_t byte_idx = 0; + uint8_t low = 0; + + for (i = 0; i < hexStringLength; i++) { + byte_idx = i / 2; + low = i % 2; + + if (low) { + dataResult[byte_idx] = dataResult[byte_idx] & 0xF0; + dataResult[byte_idx] = dataResult[byte_idx] | FROM_HEX(hexString[i]); + } else { + dataResult[byte_idx] = dataResult[byte_idx] & 0x0F; + dataResult[byte_idx] = dataResult[byte_idx] | (FROM_HEX(hexString[i]) << 4); + } + } +} + +AtCommandResult AtCmdSignaturePduContext(tAtCmd *env) { + AtCmdRxClear(env); + AtCmdPrepare(env); + AtCmdSendStatic(env, "AT#SGACT=1,1\r\n"); + return AtCmdWaitOk(env, 10, 500); +} + +AtCommandResult AtCmdSignaturePdu_CloseContext(tAtCmd *env) { + AtCmdRxClear(env); + AtCmdPrepare(env); + AtCmdSendStatic(env, "AT+CSIM=%i,\""); + return AtCmdWaitOk(env, 10, 500); +} + + + +void AtCmdSignature_SendApduStr(tAtCmd *env, uint8_t *data, uint16_t length) { + char apduAscii[length * 2]; + size_t lenPdu = 0; + + vAsciiStringAddBytesAsHex(apduAscii, &lenPdu, data, length); + + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT+CSIM="); + AtCmdTxAddDecimalIntWithLimit(env, lenPdu, 3); + AtCmdTxAddStatic(env, ", "); + AtCmdTxAddStatic(env, "\""); + AtCmdTxAdd(env, apduAscii, lenPdu); + AtCmdTxAddStatic(env, "\""); + AtCmdTxSendLn(env); + +} + + +void AtCmdSignature_SendApdu(tAtCmd *env, uint8_t *data, uint16_t length) { + char apduAscii[length * 2]; + size_t lenPdu = 0; + + vAsciiStringAddBytesAsHex(apduAscii, &lenPdu, data, length); + + AtCmdPrepare(env); + AtCmdTxClear(env); + AtCmdTxAddStatic(env, "AT+CSIM="); + AtCmdTxAddDecimalIntWithLimit(env, lenPdu, 3); + AtCmdTxAddStatic(env, ", "); + AtCmdTxAddStatic(env, "\""); + AtCmdTxAdd(env, apduAscii, lenPdu); + AtCmdTxAddStatic(env, "\""); + AtCmdTxSendLn(env); + +} + +AtCommandResult AtCmdSignaturePdu_SelectApplet(tAtCmd *env, uint8_t canNum) { +///old +//uint8_t APDU_SELECT[] = {0x00, 0xA4, 0x04, 0x00, 0x0C, 0xA1, 0x13, 0x00, 0x01, 0x18, 0x00, 0x06, 0xFF, 0xF7, 0xFF, 0xFF, 0x08}; + +///new +// uint8_t APDU_SELECy[] = {0x00, 0xA4, 0x04, 0x00, 0x0C, 0xA0,0x00,0x00,0x05,0x33,0xC0,0x00,0xFF, 0xF7,0x00,0x00,0x00,0x05,0x5C}; + uint8_t APDU_SELECT[] = {0x01, 0xA4, 0x04, 0x00, 0x0E, 0xA0,0x00,0x00,0x05,0x33,0xC0,0x00,0xFF, 0xF7,0x00,0x00,0x00,0x05,0x5C}; + + + AtCommandResult res; + APDU_SELECT[0] = canNum; + APDU_SELECT[4] = 14; + AtCmdSignature_SendApdu(env, APDU_SELECT, sizeof(APDU_SELECT)); + res = AtCmdWaitOk(env, 10, 4000); + return res; +} + + +AtCommandResult AtCmdSignaturePdu_GetChannalNum(tAtCmd *env, uint8_t *result) { + + int tries = 10; + volatile size_t binaryDataSize; + + AtCmdPrepare(env); + AtCmdSendStatic(env, "AT+CSIM=10, \"0070000001\"\r\n"); + + uint32_t endMs = SystemGetMs() + 4000; + while (endMs > SystemGetMs()) { + if (AtCmdReceiveNextLine(env, 500) == AT_OK) { + if (AtCmdRxBeginWithStatic(env, "+CSIM: 6,")) { + binaryDataSize = iAsciiStringParseHexBytes(result, env->rxBuffer.data + sizeof("+CSIM: 6,"), 2); +// if (AtCmdReceiveNextLine(env, 1000) == AT_OK) { + return AT_OK; +// } +// continue; + } + + if (AtCmdRxBeginWithStatic(env, "ERROR")) { + return AT_ERROR; + } + +// if (tries) { +// --tries; +// } else { +// return AT_ERROR; +// } +// AtCmdProcessUnresolvedLine(env); + } + } + return AT_TIMEOUT; +} + + +AtCommandResult AtCmdSignaturePdu_UpdateData(tAtCmd *env, uint8_t canNum, uint8_t lengthData, uint8_t *data) { +// lengthData = lengthData *2; + size_t binaryDataSize; + uint8_t apdu[260]; + apdu[0] = canNum; + apdu[1] = 0xCC; + apdu[2] = 0; + apdu[3] = 0; + apdu[4] = lengthData; + SystemDelayMs(1); + memcpy(apdu + 5, data, lengthData); + + SystemDelayMs(1); + int tries = 10; + volatile AtCommandResult res; + AtCmdSignature_SendApdu(env, apdu, lengthData + 5); + + uint32_t endMs = SystemGetMs() + 8000; + while (endMs > SystemGetMs()) { + res = AtCmdReceiveNextLine(env, 1000); + if (res == AT_OK) { + if (AtCmdRxBeginWithStatic(env, "+CSIM: 4,")) { + volatile uint8_t result; + + binaryDataSize = iAsciiStringParseHexBytes(&result, env->rxBuffer.data + sizeof("+CSIM: 4,"), 4); +// return AT_OK; + if(result == 0x0090){ + return AT_OK; + }else{ + return AT_ERROR; + } + + } else if (AtCmdRxBeginWithStatic(env, "ERROR")) { + return AT_ERROR; + } + + if (tries) { + --tries; + } else { + return AT_ERROR; + } + +// AtCmdProcessUnresolvedLine(env); + } + AtCmdRxClear(env); + } + + return AT_TIMEOUT; +} + + +AtCommandResult AtCmdSignaturePdu_SignData(tAtCmd *env, uint8_t canNum, uint8_t *mac, uint8_t *keyId) { + AtCmdRxClear(env); + uint8_t apdu[5]; + + apdu[0] = canNum; + apdu[1] = 0xCC; + apdu[2] = 0x80; + apdu[3] = 0x00; + apdu[4] = 0x00; + + AtCmdSignature_SendApdu(env, apdu, 5); + int tries = 10; + + volatile size_t binaryDataSize; + + uint32_t endMs = SystemGetMs() + 5000; + while (endMs > SystemGetMs()) { + if (AtCmdReceiveNextLine(env, 500) == AT_OK) { + if (AtCmdRxBeginWithStatic(env, "+CSIM: 72,")) { + binaryDataSize = 0; + binaryDataSize = iAsciiStringParseHexBytes(mac, env->rxBuffer.data + sizeof("+CSIM: 72,"), 33); + binaryDataSize = iAsciiStringParseHexBytes(keyId, env->rxBuffer.data + sizeof("+CSIM: 72,") + 33, 2); + if (AtCmdReceiveNextLine(env, 1000) == AT_OK) { + return AT_OK; + } + continue; + } + + if (AtCmdRxBeginWithStatic(env, "ERROR")) { + return AT_ERROR; + } + + if (tries) { + --tries; + } else { + return AT_ERROR; + } + +// AtCmdProcessUnresolvedLine(env); + } + } + + return AT_TIMEOUT; + +} + + diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..d4d574e --- /dev/null +++ b/modular.json @@ -0,0 +1,12 @@ +{ + "dep": [ + ], + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file