/**
*@file    sr_md5.c
*@brief   哈希计算接口
*@details 提供哈希计算接口
*@copyright Copyright (c) 2024 lierda. All rights reserved.
*@author  Lierda-RDC
*@date    2024-05-07
*@example ZhaoyangSDK\example\component\crypto\crypto_example.c
*/

#include "sr_md5.h"

//#include "sr_osal.h"

#include "sr_log.h"

/**  
* @brief 初始化HASH上下文  
*  
* @param[in] ctx  HASH上下文指针
*
* @return 错误码   成功返回0，失败返回负值错误码
*/ 
int SR_HashStart(SR_HASH_CTX_T *ctx,SR_HASH_TYPE_E type)
{
	int ret =-1;
	const mbedtls_md_info_t *info;

	// 初始化md结构体
    mbedtls_md_init(&ctx->mdCtx);

	// 根据算法类型获得md信息指针
    info = mbedtls_md_info_from_type(type);
	SR_LOG(INFO,"info=%d",info);
	if(info==0) SR_LOG(INFO,"info=0",info);
	
    // 设置 md 结构体，完成 md 结构体内部接口初始化
    ret = mbedtls_md_setup(&ctx->mdCtx, info, 0);
	if(ret !=0) 
	{
		SR_LOG(ERR,"md_setup err(%d)",ret);
		goto _END;
	}

	// md 启动接口
    ret = mbedtls_md_starts(&ctx->mdCtx);
	if(ret !=0) 
	{
		SR_LOG(ERR,"md_starts err(%d)",ret);
		goto _END;
	}

_END:
    if(ret != 0) mbedtls_md_free(&ctx->mdCtx);  // 释放 md 结构体
	return (ret==0)? SR_OK:SR_FAIL;
}


/**  
* @brief 更新哈希计算 
*  
* @param[in] ctx HASH上下文指针
* @param[in] in  输入数据指针  
* @param[in] inLen 输入数据的长度（字节） 
*
* @return 错误码   成功返回0，失败返回负值错误码 
*/
int SR_HashUpdate(SR_HASH_CTX_T *ctx, uint8_t *in, uint32_t inLen)
{
	int ret=-1;
	// md 更新接口，处理输入数据，包括消息预处理和计算
    ret = mbedtls_md_update(&ctx->mdCtx, in, inLen);	
	if(ret != 0) mbedtls_md_free(&ctx->mdCtx);
;	return (ret==0)? SR_OK:SR_FAIL;
}


/**  
* @brief 完成哈希计算并获取结果  
*  
* @param[in]  ctx HASH上下文指针  
* @param[out] out 存储哈希值的缓存，MD5至少16个字节的空间  
*
* @return 错误码   成功(>0):返回输出长度，失败返回负值错误码
*/  
int SR_HashFinish(SR_HASH_CTX_T *ctx, uint8_t *out)
{
	int ret=-1;
	unsigned char oLen=0;
	// md 完成接口，输出消息摘要结果
    ret = mbedtls_md_finish(&ctx->mdCtx, out);

	oLen =mbedtls_md_get_size(ctx->mdCtx.md_info);
	
	// 释放 md 结构体
    mbedtls_md_free(&ctx->mdCtx);
	return (ret==0)? oLen:SR_FAIL;
}




