/*
 * @Description: 
 * @Author: yangsw
 * @Date: 2022-05-06 10:07:01
 * @LastEditTime: 2022-05-06 10:07:02
 * @LastEditors: yangsw
 * @Reference: 
 */
#ifndef H_UTIL_AES_H
#define H_UTIL_AES_H



#define N_ROW                   4
#define N_COL                   4
#define N_BLOCK   (N_ROW * N_COL)
#define N_MAX_ROUNDS           14

typedef unsigned char uint_8t;

typedef enum{
    PKCS7_PADDING
}Aes_Padding_Mode;

typedef struct
{   uint_8t ksch[(N_MAX_ROUNDS + 1) * N_BLOCK];
    uint_8t rnd;
    Aes_Padding_Mode padding_mode;
}Aes_Context_Struct;

/**
 * 初始化Key和AES Context
 * param： key 密钥；
 *         keylen 密钥长度(合法数据：128, 192, 16, 24 和 32)；
 *         ctx 上下文
 * return: 0成功，-1失败
 */
int Util_Aes_Set_Key( const unsigned char key[16], Aes_Padding_Mode padding_mode );

/**
 * 单个16字节的块加密
 * param： in 待加密内容；
 *         out 加密后输出；
 *         ctx 上下文
 * return: 0成功，-1失败
 */
int aes_encrypt( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK], const Aes_Context_Struct ctx[1] );

/**
 * 计算加密输出内容长度
 * param： in_len 待加密内容长度；
 * return: 0成功，-1失败
 */
int compute_out_length(int in_len);

/**
 * pkcs#7填充
 * param： in 待填充内容；
 *         out 填充后内容；
 *         in_len 待填充内容的长度;
 *         out_len 填充后内容的长度（由 compute_out_length计算出)
 * return: void
 */
void pkcs7_padding(const unsigned char *in, unsigned char *out, int in_len, int out_len);

/**
 * aes ecb 加密
 * param： in 待加密内容(填充后的内容)；
 *         out 加密后输出内容；
 *         len 机密后输出内容长度;
 *         ctx AES上下文
 * return: 0 成功；-1 失败
 */
int Util_Aes_Ecb_Encrypt(const unsigned char *in, int src_len,unsigned char *out);

/**
 * aes ecb 解密单个16字节的块
 * param： in 待解密内容；
 *         out 解密后输出内容；
 *         ctx AES上下文
 * return: 0 成功；-1 失败
 */
int aes_decrypt( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK], const Aes_Context_Struct ctx[1] );

/**
 * aes ecb 解密
 * param： in 待解密内容；
 *         out 解密后输出内容(输出内容含padding，需要自己去掉)；
 *         in_len 待解密内容长度
 *         ctx AES上下文
 * return: 0 成功；-1 失败
 */
int Util_Aes_Ecb_Decrypt(const unsigned char *in, unsigned char *out, int in_len);

#endif

