// // Created by cfif on 05.07.2024. // #include "EgtsFirmware.h" #include "AtGsmSimComA7600_SSL_LOAD_CA.h" #include "aes.h" /* #define LOG_SIGN "EGTS_UPDATE" #define LOGGER &env->slog->logger void receivedUpdateFirmware(tEgtsProcessing *env) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Получен пакет прошивки, %d из %d (%d байт данных)", env->egtsEnv.firmware->PartNumber, env->egtsEnv.firmware->ExpectedPartsQuantity, env->egtsEnv.firmware->dataLength); if (env->egtsEnv.firmware->PartNumber == 1) { env->firmwareOffset = 0; LoggerInfoStatic(LOGGER, LOG_SIGN, "Подготовка ОЗУ"); env->firmwareBufCrc = env->egtsEnv.firmware->WholeObjectSignature; } memcpy(&env->firmwareBuf[env->firmwareOffset], env->egtsEnv.firmware->dataPointer, env->egtsEnv.firmware->dataLength); env->firmwareOffset += env->egtsEnv.firmware->dataLength; if (env->firmwareOffset > sizeof(env->firmwareBuf) - 1024) { env->firmwareOffset = 0; LoggerInfoStatic(LOGGER, LOG_SIGN, "Переполнение буфера ОЗУ"); } uint8_t rst; if (env->egtsEnv.firmware->PartNumber == env->egtsEnv.firmware->ExpectedPartsQuantity) { uint32_t pos = env->firmwareOffset - 256; uint32_t offsetMetaCrc = *(uint32_t *) &env->firmwareBuf[pos]; pos += 4; uint32_t offsetMetaSize = *(uint32_t *) &env->firmwareBuf[pos]; pos += 4; tString32 FW_NAME; FW_NAME.length = (*(uint8_t *) &env->firmwareBuf[pos]); pos += 1; if (FW_NAME.length > 32) { FW_NAME.length = 0; } else { memcpy(FW_NAME.data, &env->firmwareBuf[pos], FW_NAME.length); } uint8_t posDel = findDelimiter(FW_NAME, '_') + 1; if (memcmp(&FW_NAME.data[posDel], "TELE", 4) == 0) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена прошивка телематики"); } else if (memcmp(&FW_NAME.data[0], "CERT", 4) == 0) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена прошивка ключей"); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена не известная прошивка"); } uint32_t crc32 = 0; for (uint32_t i = 0; i < offsetMetaSize; ++i) { crc32 += env->firmwareBuf[i]; } if (crc32 != offsetMetaCrc) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка контрольной суммы"); } else { if (memcmp(&FW_NAME.data[0], "CERT", 4) == 0) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Загрузка ключей"); tIsFind check; memset(&check, 0, sizeof(check)); if (osMutexAcquire(env->gsm->gsmAt->access, 5000) == osOK) { tEgtsCertInfo *egtsCertInfo = (tEgtsCertInfo *) env->firmwareBuf; AtGsmSimComA7600_SSL_DEL_CA(env->gsm->gsmAt, file_ca, strlen(file_ca), file_crt, strlen(file_crt), file_key, strlen(file_key)); check = AtGsmSimComA7600_SSL_CHECK_CA(env->gsm->gsmAt, file_ca, strlen(file_ca), file_crt, strlen(file_crt), file_key, strlen(file_key), 2000); if (egtsCertInfo->ENC) { uint32_t lenEnc = offsetMetaSize - sizeof(tEgtsCertInfo); struct AES_ctx ctx; uint8_t key[16]; uint8_t iv[16]; memset(iv, '3', sizeof(key)); memset(key, '0', sizeof(key)); uint8_t offsetKey = 0; if (env->storage->nvm.device.ccid.length < 16) offsetKey = 16 - env->storage->nvm.device.ccid.length; memcpy(&key[offsetKey], env->storage->nvm.device.ccid.data, env->storage->nvm.device.ccid.length); AES_init_ctx_iv(&ctx, key, iv); AES_CBC_decrypt_buffer(&ctx, &env->firmwareBuf[sizeof(tEgtsCertInfo)], lenEnc); } AtGsmSimComA7600_SSL_LOAD_CA(env->gsm->gsmAt, file_ca, strlen(file_ca), &env->firmwareBuf[sizeof(tEgtsCertInfo)], egtsCertInfo->SIZE_ROOT_CA, 2000); AtGsmSimComA7600_SSL_LOAD_CA(env->gsm->gsmAt, file_key, strlen(file_key), &env->firmwareBuf[sizeof(tEgtsCertInfo) + egtsCertInfo->SIZE_ROOT_CA], egtsCertInfo->SIZE_CLIENT_KEY, 2000); AtGsmSimComA7600_SSL_LOAD_CA(env->gsm->gsmAt, file_crt, strlen(file_crt), &env->firmwareBuf[sizeof(tEgtsCertInfo) + egtsCertInfo->SIZE_ROOT_CA + egtsCertInfo->SIZE_CLIENT_KEY], egtsCertInfo->SIZE_CLIENT_CRT, 2000); osMutexRelease(env->gsm->gsmAt->access); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа при загрузке ключей"); } } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Получена не известная прошивка"); } } rst = 0; } else { rst = 1; } EgtsProcessing_SendResponse(env, EGTS_FIRMWARE_SERVICE, EGTS_FIRMWARE_SERVICE, EGTS_SERVICE_FLAGS_FIRMWARE, rst, env->egtsEnv.recordNumber); } */