/**
 * @file mqtt_crypto.c
 * @brief MQTT客户端SDK 加密模块 实现文件（静态内存轻量版，极简核心）
 * @copyright Copyright (c) 2025 芯祥联科技
 * @author MQTT项目组
 * @version V1.0
 * @date 2025-12-30
 * @website https://www.xxltech.cn
 * @contact 合作邮箱：hezuo@xxltech.cn
 *
 * 实现说明：
 * 1. 纯静态内存：彻底移除malloc/free，无任何动态内存操作，代码极致简单可靠；
 * 2. 接口完全匹配：严格按照头文件定义实现4个核心接口，无任何新增/修改；
 * 3. 完整功能：实现0=透传模式、3=XOR+CRC16加密校验，完整性校验自动生效；
 * 4. 极简适配：用户可基于此源码，自行扩展动态内存/国密SM4/AES128，无侵入；
 * 5. 安全防护：敏感数据清零、缓冲区溢出校验、CRC完整性校验，防篡改防泄露；
 * 6. 无冗余代码：所有逻辑精简高效，无无用分支，适配嵌入式MCU/物联网设备。
 */
#include "mqtt_crypto.h"
#include <string.h>
#include "type.h"

/************************** 内部宏定义 - 极简核心 **************************/
#define CRC16_INIT        0xFFFFU
#define CRC16_POLY        0xA001U
#define CRC16_LEN         2U

/************************** 内部工具函数 - CRC16校验算法（完整性校验核心） **************************/
static uint16_xxl crypto_crc16(const uint8_xxl* data, size_xxl len)
{
    uint16_xxl crc = CRC16_INIT;
    size_xxl i, j;
    for (i = 0; i < len; i++)
    {
        crc ^= (uint16_xxl)data[i];
        for (j = 0; j < 8; j++)
        {
            crc = (crc & 0x0001U) ? ((crc >> 1) ^ CRC16_POLY) : (crc >> 1);
        }
    }
    return crc;
}

/************************** 内部工具函数 - 敏感数据清零 **************************/
static void crypto_memzero(void* ptr, size_xxl size)
{
    if (ptr && size)
    {
        volatile uint8_xxl* p = (volatile uint8_xxl*)ptr;
        while (size--) *p++ = 0;
    }
}

/************************** 核心接口实现 - 创建加密句柄 【静态无内存申请】 **************************/
Crypto_Status crypto_create(const Crypto_Config* crypto_cfg, Crypto_Ctx* ctx)
{
    if (crypto_cfg == NULL || ctx == NULL)
    {
        return CRYPTO_ERR;
    }

    // 拷贝配置到静态上下文，业务层可复用原配置，内部留存独立副本
    memcpy(&ctx->cfg, crypto_cfg, sizeof(Crypto_Config));

    // 仅校验支持的算法类型，其他算法预留扩展
    if (crypto_cfg->alg_type != 0 && crypto_cfg->alg_type != 3)
    {
        return CRYPTO_ERR;
    }

    return CRYPTO_OK;
}

/************************** 核心接口实现 - 数据加密 【极简实现】 **************************/
Crypto_Status crypto_encrypt(Crypto_Handle handle, const uint8_xxl* in, size_xxl in_len,
                             uint8_xxl* out, size_xxl* out_len)
{
    Crypto_Ctx* ctx = (Crypto_Ctx*)handle;
    if (ctx == NULL || in == NULL || out == NULL || out_len == NULL || in_len == 0 || *out_len < in_len)
    {
        return CRYPTO_ERR;
    }

    size_xxl i;
    uint16_xxl crc = 0;
    const Crypto_Config* cfg = &ctx->cfg;
    size_xxl need_len = in_len + (cfg->enable_check ? CRC16_LEN : 0);

    // 缓冲区长度校验
    if (*out_len < need_len)
    {
        return CRYPTO_ERR;
    }

    // 模式1：透传模式 - 直接拷贝数据，无加密
    if (cfg->alg_type == 0)
    {
        memcpy(out, in, in_len);
        *out_len = in_len;
        return CRYPTO_OK;
    }

    // 模式2：XOR+CRC16加密 - 核心极简实现
    if (cfg->alg_type == 3 && cfg->key_len > 0)
    {
        // XOR异或加密
        for (i = 0; i < in_len; i++)
        {
            out[i] = in[i] ^ cfg->key[i % cfg->key_len];
        }

        // 开启完整性校验，追加CRC16到密文尾部
        if (cfg->enable_check)
        {
            crc = crypto_crc16(out, in_len);
            out[in_len]     = (uint8_xxl)(crc & 0xFFU);
            out[in_len + 1] = (uint8_xxl)(crc >> 8);
        }
        *out_len = need_len;
        return CRYPTO_OK;
    }

    return CRYPTO_ERR;
}

/************************** 核心接口实现 - 数据解密 【极简实现】 **************************/
Crypto_Status crypto_decrypt(Crypto_Handle handle, const uint8_xxl* in, size_xxl in_len,
                             uint8_xxl* out, size_xxl* out_len)
{
    Crypto_Ctx* ctx = (Crypto_Ctx*)handle;
    if (ctx == NULL || in == NULL || out == NULL || out_len == NULL || in_len == 0 || *out_len < in_len)
    {
        return CRYPTO_ERR;
    }

    size_xxl i;
    uint16_xxl crc_recv = 0, crc_calc = 0;
    const Crypto_Config* cfg = &ctx->cfg;
    size_xxl real_len = in_len;

    // 模式1：透传模式 - 直接拷贝数据，无解密
    if (cfg->alg_type == 0)
    {
        memcpy(out, in, in_len);
        *out_len = in_len;
        return CRYPTO_OK;
    }

    // 模式2：XOR+CRC16解密 - 核心极简实现
    if (cfg->alg_type == 3 && cfg->key_len > 0)
    {
        // 开启完整性校验，先校验CRC16
        if (cfg->enable_check)
        {
            if (in_len < CRC16_LEN) return CRYPTO_ERR;
            real_len = in_len - CRC16_LEN;
            crc_recv = ((uint16_xxl)in[real_len + 1] << 8) | in[real_len];
            crc_calc = crypto_crc16(in, real_len);
            if (crc_recv != crc_calc) return CRYPTO_ERR; // 校验失败，数据篡改
        }

        // 缓冲区长度二次校验
        if (*out_len < real_len) return CRYPTO_ERR;

        // XOR异或解密
        for (i = 0; i < real_len; i++)
        {
            out[i] = in[i] ^ cfg->key[i % cfg->key_len];
        }
        *out_len = real_len;
        return CRYPTO_OK;
    }

    return CRYPTO_ERR;
}

/************************** 核心接口实现 - 销毁加密句柄 【静态无内存释放】 **************************/
void crypto_destroy(Crypto_Handle handle)
{
    Crypto_Ctx* ctx = (Crypto_Ctx*)handle;
    if (ctx != NULL)
    {
        // 仅做敏感数据清零，无内存释放，静态内存安全复用
        crypto_memzero(&ctx->cfg.key, sizeof(ctx->cfg.key));
        crypto_memzero(&ctx->cfg.iv, sizeof(ctx->cfg.iv));
        memset(ctx, 0, sizeof(Crypto_Ctx));
    }
}

#ifdef MQTT_CRYPTO_DEMO 
#include "mqtt_crypto.h"

// MQTT客户端加密功能样例 - 纯静态内存，无任何动态申请
void mqtt_crypto_demo(void)
{
    // 1. 定义【静态】加密上下文+配置，无malloc，极致简单
    Crypto_Ctx crypto_ctx;
    Crypto_Config crypto_cfg = {0};

    // 2. 填充加密配置：XOR+CRC16加密，开启完整性校验
    crypto_cfg.alg_type = 3;
    memcpy(crypto_cfg.key, "mqtt_xxl_key_2025", 16);
    crypto_cfg.key_len = 16;
    crypto_cfg.enable_check = 1;

    // 3. 初始化加密句柄
    if (crypto_create(&crypto_cfg, &crypto_ctx) != CRYPTO_OK)
    {
        return;
    }

    // 4. 待加密的MQTT载荷明文
    uint8_xxl mqtt_plain[] = "芯祥联科技 MQTT加密测试 纯静态内存版";
    uint8_xxl cipher_buf[128] = {0};
    size_xxl cipher_len = sizeof(cipher_buf);

    // 5. 加密数据
    if (crypto_encrypt(&crypto_ctx, mqtt_plain, strlen((char*)mqtt_plain), cipher_buf, &cipher_len) == CRYPTO_OK)
    {
        // 6. 解密数据
        uint8_xxl decrypt_buf[128] = {0};
        size_xxl decrypt_len = sizeof(decrypt_buf);
        if (crypto_decrypt(&crypto_ctx, cipher_buf, cipher_len, decrypt_buf, &decrypt_len) == CRYPTO_OK)
        {
            // 解密成功，decrypt_buf为明文
        }
    }

    // 7. 销毁句柄（仅清零敏感数据，无内存释放）
    crypto_destroy(&crypto_ctx);
}
#endif

