符合国密ZCU256标准的算法,与网站对比
https://seehttps.com/gm/zuc256 https://tools.huijusa.cn/seq
This commit is contained in:
79
inc/zuc256.h
79
inc/zuc256.h
@@ -3,57 +3,48 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
// 上下文结构体:存储算法状态
|
// 类型定义
|
||||||
|
typedef uint32_t ZUC_UINT31; // 31位无符号整数
|
||||||
|
typedef uint8_t ZUC_UINT7; // 7位无符号整数
|
||||||
|
typedef uint8_t ZUC_UINT6; // 6位无符号整数
|
||||||
|
|
||||||
|
// ZUC状态结构体
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t key[8]; // 256位密钥(拆分为8个32位字)
|
ZUC_UINT31 LFSR[16]; // 线性反馈移位寄存器
|
||||||
uint32_t iv[4]; // 128位IV(拆分为4个32位字)
|
uint32_t R1; // 寄存器1
|
||||||
uint32_t LFSR[16]; // 线性反馈移位寄存器
|
uint32_t R2; // 寄存器2
|
||||||
uint32_t NFSR[16]; // 非线性反馈移位寄存器
|
} ZUC256_STATE;
|
||||||
uint32_t R1, R2; // 密钥流生成辅助寄存器
|
|
||||||
uint32_t ks_buf; // 密钥流缓存(处理非4字节对齐数据)
|
|
||||||
size_t ks_buf_len; // 缓存的密钥流字节数(0~3)
|
|
||||||
} ZUC256_CTX;
|
|
||||||
|
|
||||||
// 错误码定义
|
// 加密上下文结构体(用于分阶段处理)
|
||||||
#define ZUC256_SUCCESS 0 // 成功
|
typedef struct {
|
||||||
#define ZUC256_ERR_NULL -1 // 空指针错误
|
ZUC256_STATE state; // 基础ZUC状态
|
||||||
#define ZUC256_ERR_KEYLEN -2 // 密钥长度错误(需32字节)
|
uint8_t buf[4]; // 输入缓冲区(处理非4字节对齐数据)
|
||||||
#define ZUC256_ERR_IVLEN -3 // IV长度错误(需16字节)
|
size_t buflen; // 缓冲区中有效字节数
|
||||||
|
} ZUC256_ENCRYPT_CTX;
|
||||||
|
|
||||||
// 公共接口声明
|
// 初始化ZUC256状态
|
||||||
/**
|
void zuc256_init(ZUC256_STATE *state, const uint8_t K[32], const uint8_t IV[23]);
|
||||||
* @brief 初始化ZUC256上下文
|
|
||||||
* @param ctx 上下文指针(需提前分配内存)
|
|
||||||
* @param key 256位密钥(32字节)
|
|
||||||
* @param iv 128位初始向量(16字节)
|
|
||||||
* @return 成功返回ZUC256_SUCCESS,失败返回错误码
|
|
||||||
*/
|
|
||||||
int ZUC256_Init(ZUC256_CTX *ctx, const uint8_t *key, const uint8_t *iv);
|
|
||||||
|
|
||||||
/**
|
// 生成单个密钥字
|
||||||
* @brief 分块处理数据(加密/解密)
|
uint32_t zuc256_generate_keyword(ZUC256_STATE *state);
|
||||||
* @param ctx 已初始化的上下文
|
|
||||||
* @param out 输出缓冲区(长度需≥in_len)
|
|
||||||
* @param in 输入数据
|
|
||||||
* @param in_len 输入数据长度(字节)
|
|
||||||
* @return 成功返回ZUC256_SUCCESS,失败返回错误码
|
|
||||||
*/
|
|
||||||
int ZUC256_Update(ZUC256_CTX *ctx, uint8_t *out, const uint8_t *in, size_t in_len);
|
|
||||||
|
|
||||||
/**
|
// 生成指定长度的密钥流
|
||||||
* @brief 结束处理(流密码无实际操作,仅对齐接口)
|
void zuc256_generate_keystream(ZUC256_STATE *state, size_t nwords, uint32_t *keystream);
|
||||||
* @param ctx 上下文指针
|
|
||||||
* @param out 输出缓冲区(可为NULL)
|
|
||||||
* @return 成功返回ZUC256_SUCCESS,失败返回错误码
|
|
||||||
*/
|
|
||||||
int ZUC256_Final(ZUC256_CTX *ctx, uint8_t *out);
|
|
||||||
|
|
||||||
/**
|
// 初始化加密上下文
|
||||||
* @brief 清理上下文(清空敏感数据)
|
void zuc256_encrypt_init(ZUC256_ENCRYPT_CTX *ctx, const uint8_t K[32], const uint8_t IV[23]);
|
||||||
* @param ctx 上下文指针
|
|
||||||
*/
|
|
||||||
void ZUC256_Cleanup(ZUC256_CTX *ctx);
|
|
||||||
|
|
||||||
|
// 分阶段处理加密数据(支持流式输入)
|
||||||
|
void zuc256_encrypt_update(ZUC256_ENCRYPT_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out);
|
||||||
|
|
||||||
|
// 完成加密处理(处理剩余数据并清理上下文)
|
||||||
|
void zuc256_encrypt_finish(ZUC256_ENCRYPT_CTX *ctx, uint8_t *out);
|
||||||
|
|
||||||
|
// 一次性加密函数
|
||||||
|
void zuc256_crypt(ZUC256_STATE *state, const uint8_t *in, size_t inlen, uint8_t *out);
|
||||||
|
|
||||||
|
void extract_iv(const uint8_t *input_25byte, uint8_t *output_23byte);
|
||||||
#endif /*__ZUC256_H */
|
#endif /*__ZUC256_H */
|
||||||
|
|
||||||
108
src/main.c
108
src/main.c
@@ -2,73 +2,63 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "zuc256.h"
|
#include "zuc256.h"
|
||||||
|
|
||||||
// 测试ZUC256加密解密功能
|
// 打印字节数组为十六进制
|
||||||
|
void print_hex(const char *label, const uint8_t *data, size_t len) {
|
||||||
|
printf("%s: ", label);
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
printf("%02x ", data[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// 1. 测试参数(256位密钥=32字节,128位IV=16字节)
|
// 1. 明文
|
||||||
uint8_t key[32] = "0123456789abcdef0123456789abcdef"; // 32字节密钥
|
uint8_t plaintext[] = "ZUC256对称加解密测试:1234567890";
|
||||||
uint8_t iv[16] = "0123456789abcdef"; // 16字节IV
|
size_t plaintext_len = strlen((char*)plaintext);
|
||||||
uint8_t plaintext[] = "Hello ZUC256! This is a test of the encryption algorithm.";
|
printf("明文: %s\n", plaintext);
|
||||||
size_t plaintext_len = strlen((const char *)plaintext);
|
print_hex("明文(十六进制)", plaintext, plaintext_len);
|
||||||
uint8_t ciphertext[1024] = {0}; // 密文缓冲区
|
|
||||||
uint8_t decrypted[1024] = {0}; // 解密后缓冲区
|
|
||||||
|
|
||||||
// 2. 初始化加密上下文并加密
|
// 2. 密钥(32字节ASCII)
|
||||||
ZUC256_CTX enc_ctx;
|
uint8_t key[32] = "0123456789abcdef0123456789abcdef";
|
||||||
int ret = ZUC256_Init(&enc_ctx, key, iv);
|
print_hex("密钥", key, 32);
|
||||||
if (ret != ZUC256_SUCCESS) {
|
|
||||||
printf("加密初始化失败!错误码: %d\n", ret);
|
// 3. 初始向量(25字节ASCII)
|
||||||
return -1;
|
//注:初始向量长度为184bit分布到25个字节中,前面17个初始向量为8bit字节,后面8个初始向量为6bit字节(占据一个字节的低6位)
|
||||||
|
uint8_t input_iv_25byte[25] = "0123456789abcdefg01234567";
|
||||||
|
uint8_t iv[23];
|
||||||
|
extract_iv(input_iv_25byte, iv);
|
||||||
|
print_hex("提取后的IV", iv, 23);
|
||||||
|
|
||||||
|
// 4. 分配加密/解密缓冲区
|
||||||
|
uint8_t *ciphertext = (uint8_t*)malloc(plaintext_len);
|
||||||
|
uint8_t *decryptedtext = (uint8_t*)malloc(plaintext_len);
|
||||||
|
if (!ciphertext || !decryptedtext) {
|
||||||
|
printf("内存分配失败\n");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ZUC256_Update(&enc_ctx, ciphertext, plaintext, plaintext_len);
|
// 5. 加密
|
||||||
if (ret != ZUC256_SUCCESS) {
|
ZUC256_STATE state;
|
||||||
printf("加密处理失败!错误码: %d\n", ret);
|
zuc256_init(&state, key, iv);
|
||||||
ZUC256_Cleanup(&enc_ctx);
|
zuc256_crypt(&state, plaintext, plaintext_len, ciphertext);
|
||||||
return -1;
|
print_hex("密文", ciphertext, plaintext_len);
|
||||||
}
|
|
||||||
|
|
||||||
ret = ZUC256_Final(&enc_ctx, NULL);
|
// 6. 解密(重新初始化状态)
|
||||||
if (ret != ZUC256_SUCCESS) {
|
zuc256_init(&state, key, iv);
|
||||||
printf("加密结束失败!错误码: %d\n", ret);
|
zuc256_crypt(&state, ciphertext, plaintext_len, decryptedtext);
|
||||||
}
|
print_hex("解密后", decryptedtext, plaintext_len);
|
||||||
ZUC256_Cleanup(&enc_ctx); // 清理加密上下文(敏感数据)
|
printf("解密文本: %s\n", decryptedtext);
|
||||||
|
|
||||||
// 3. 初始化解密上下文并解密(流密码加密解密使用相同接口)
|
// 7. 验证结果
|
||||||
ZUC256_CTX dec_ctx;
|
if (memcmp(plaintext, decryptedtext, plaintext_len) == 0) {
|
||||||
ret = ZUC256_Init(&dec_ctx, key, iv);
|
printf("=== 测试成功: 解密结果与明文一致 ===\n");
|
||||||
if (ret != ZUC256_SUCCESS) {
|
|
||||||
printf("解密初始化失败!错误码: %d\n", ret);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ZUC256_Update(&dec_ctx, decrypted, ciphertext, plaintext_len);
|
|
||||||
if (ret != ZUC256_SUCCESS) {
|
|
||||||
printf("解密处理失败!错误码: %d\n", ret);
|
|
||||||
ZUC256_Cleanup(&dec_ctx);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ZUC256_Final(&dec_ctx, NULL);
|
|
||||||
if (ret != ZUC256_SUCCESS) {
|
|
||||||
printf("解密结束失败!错误码: %d\n", ret);
|
|
||||||
}
|
|
||||||
ZUC256_Cleanup(&dec_ctx); // 清理解密上下文
|
|
||||||
|
|
||||||
// 4. 输出结果并验证
|
|
||||||
printf("原文: %s\n", plaintext);
|
|
||||||
printf("密文: ");
|
|
||||||
for (size_t i = 0; i < plaintext_len; i++) {
|
|
||||||
printf("%02x", ciphertext[i]); // 密文以十六进制显示
|
|
||||||
}
|
|
||||||
printf("\n解密后: %s\n", decrypted);
|
|
||||||
|
|
||||||
// 验证解密结果是否与原文一致
|
|
||||||
if (memcmp(plaintext, decrypted, plaintext_len) == 0) {
|
|
||||||
printf("\n测试通过:加密解密一致!\n");
|
|
||||||
} else {
|
} else {
|
||||||
printf("\n测试失败:解密结果与原文不一致!\n");
|
printf("=== 测试失败: 解密结果与明文不一致 ===\n");
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 8. 释放内存
|
||||||
|
free(ciphertext);
|
||||||
|
free(decryptedtext);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
549
src/zuc256.c
549
src/zuc256.c
@@ -1,262 +1,383 @@
|
|||||||
#include "zuc256.h"
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "zuc256.h"
|
||||||
// 内部工具函数和常量(static隐藏,不暴露给外部)
|
// S盒定义
|
||||||
|
static const uint8_t S0[256] = {
|
||||||
// S盒(ZUC标准S盒与AES一致)
|
0x3e,0x72,0x5b,0x47,0xca,0xe0,0x00,0x33,0x04,0xd1,0x54,0x98,0x09,0xb9,0x6d,0xcb,
|
||||||
static const uint8_t ZUC256_S0[256] = {
|
0x7b,0x1b,0xf9,0x32,0xaf,0x9d,0x6a,0xa5,0xb8,0x2d,0xfc,0x1d,0x08,0x53,0x03,0x90,
|
||||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
0x4d,0x4e,0x84,0x99,0xe4,0xce,0xd9,0x91,0xdd,0xb6,0x85,0x48,0x8b,0x29,0x6e,0xac,
|
||||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
0xcd,0xc1,0xf8,0x1e,0x73,0x43,0x69,0xc6,0xb5,0xbd,0xfd,0x39,0x63,0x20,0xd4,0x38,
|
||||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
0x76,0x7d,0xb2,0xa7,0xcf,0xed,0x57,0xc5,0xf3,0x2c,0xbb,0x14,0x21,0x06,0x55,0x9b,
|
||||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
0xe3,0xef,0x5e,0x31,0x4f,0x7f,0x5a,0xa4,0x0d,0x82,0x51,0x49,0x5f,0xba,0x58,0x1c,
|
||||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
0x4a,0x16,0xd5,0x17,0xa8,0x92,0x24,0x1f,0x8c,0xff,0xd8,0xae,0x2e,0x01,0xd3,0xad,
|
||||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
0x3b,0x4b,0xda,0x46,0xeb,0xc9,0xde,0x9a,0x8f,0x87,0xd7,0x3a,0x80,0x6f,0x2f,0xc8,
|
||||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
0xb1,0xb4,0x37,0xf7,0x0a,0x22,0x13,0x28,0x7c,0xcc,0x3c,0x89,0xc7,0xc3,0x96,0x56,
|
||||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
0x07,0xbf,0x7e,0xf0,0x0b,0x2b,0x97,0x52,0x35,0x41,0x79,0x61,0xa6,0x4c,0x10,0xfe,
|
||||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
0xbc,0x26,0x95,0x88,0x8a,0xb0,0xa3,0xfb,0xc0,0x18,0x94,0xf2,0xe1,0xe5,0xe9,0x5d,
|
||||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
0xd0,0xdc,0x11,0x66,0x64,0x5c,0xec,0x59,0x42,0x75,0x12,0xf5,0x74,0x9c,0xaa,0x23,
|
||||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
0x0e,0x86,0xab,0xbe,0x2a,0x02,0xe7,0x67,0xe6,0x44,0xa2,0x6c,0xc2,0x93,0x9f,0xf1,
|
||||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
0xf6,0xfa,0x36,0xd2,0x50,0x68,0x9e,0x62,0x71,0x15,0x3d,0xd6,0x40,0xc4,0xe2,0x0f,
|
||||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
0x8e,0x83,0x77,0x6b,0x25,0x05,0x3f,0x0c,0x30,0xea,0x70,0xb7,0xa1,0xe8,0xa9,0x65,
|
||||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
0x8d,0x27,0x1a,0xdb,0x81,0xb3,0xa0,0xf4,0x45,0x7a,0x19,0xdf,0xee,0x78,0x34,0x60,
|
||||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
|
||||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t ZUC256_S1[256] = {
|
static const uint8_t S1[256] = {
|
||||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
0x55,0xc2,0x63,0x71,0x3b,0xc8,0x47,0x86,0x9f,0x3c,0xda,0x5b,0x29,0xaa,0xfd,0x77,
|
||||||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
0x8c,0xc5,0x94,0x0c,0xa6,0x1a,0x13,0x00,0xe3,0xa8,0x16,0x72,0x40,0xf9,0xf8,0x42,
|
||||||
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
0x44,0x26,0x68,0x96,0x81,0xd9,0x45,0x3e,0x10,0x76,0xc6,0xa7,0x8b,0x39,0x43,0xe1,
|
||||||
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
|
0x3a,0xb5,0x56,0x2a,0xc0,0x6d,0xb3,0x05,0x22,0x66,0xbf,0xdc,0x0b,0xfa,0x62,0x48,
|
||||||
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
|
0xdd,0x20,0x11,0x06,0x36,0xc9,0xc1,0xcf,0xf6,0x27,0x52,0xbb,0x69,0xf5,0xd4,0x87,
|
||||||
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
|
0x7f,0x84,0x4c,0xd2,0x9c,0x57,0xa4,0xbc,0x4f,0x9a,0xdf,0xfe,0xd6,0x8d,0x7a,0xeb,
|
||||||
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
|
0x2b,0x53,0xd8,0x5c,0xa1,0x14,0x17,0xfb,0x23,0xd5,0x7d,0x30,0x67,0x73,0x08,0x09,
|
||||||
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
0xee,0xb7,0x70,0x3f,0x61,0xb2,0x19,0x8e,0x4e,0xe5,0x4b,0x93,0x8f,0x5d,0xdb,0xa9,
|
||||||
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
|
0xad,0xf1,0xae,0x2e,0xcb,0x0d,0xfc,0xf4,0x2d,0x46,0x6e,0x1d,0x97,0xe8,0xd1,0xe9,
|
||||||
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
|
0x4d,0x37,0xa5,0x75,0x5e,0x83,0x9e,0xab,0x82,0x9d,0xb9,0x1c,0xe0,0xcd,0x49,0x89,
|
||||||
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
|
0x01,0xb6,0xbd,0x58,0x24,0xa2,0x5f,0x38,0x78,0x99,0x15,0x90,0x50,0xb8,0x95,0xe4,
|
||||||
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
|
0xd0,0x91,0xc7,0xce,0xed,0x0f,0xb4,0x6f,0xa0,0xcc,0xf0,0x02,0x4a,0x79,0xc3,0xde,
|
||||||
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
0xa3,0xef,0xea,0x51,0xe6,0x6b,0x18,0xec,0x1b,0x2c,0x80,0xf7,0x74,0xe7,0xff,0x21,
|
||||||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
0x5a,0x6a,0x54,0x1e,0x41,0x31,0x92,0x35,0xc4,0x33,0x07,0x0a,0xba,0x7e,0x0e,0x34,
|
||||||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
0x88,0xb1,0x98,0x7c,0xf3,0x3d,0x60,0x6c,0x7b,0xca,0xd3,0x1f,0x32,0x65,0x04,0x28,
|
||||||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
|
0x64,0xbe,0x85,0x9b,0x2f,0x59,0x8a,0xd7,0xb0,0x25,0xac,0xaf,0x12,0x03,0xe2,0xf2,
|
||||||
};
|
};
|
||||||
|
|
||||||
// 循环左移工具函数
|
// 常量数组D
|
||||||
static uint32_t zuc256_rotl(uint32_t value, uint8_t shift) {
|
static const ZUC_UINT7 ZUC256_D[][16] = {
|
||||||
return ((value << shift) | (value >> (32 - shift)));
|
{0x22,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,
|
||||||
}
|
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
|
||||||
|
{0x22,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,
|
||||||
|
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
|
||||||
|
{0x23,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,
|
||||||
|
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
|
||||||
|
{0x23,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,
|
||||||
|
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
|
||||||
|
};
|
||||||
|
|
||||||
// 非线性函数F(ZUC核心变换)
|
// 核心宏定义
|
||||||
static uint32_t zuc256_F(uint32_t X0, uint32_t X1, uint32_t X2) {
|
#define ADD31(a,b) a += (b); a = (a & 0x7fffffff) + (a >> 31)
|
||||||
uint32_t W1, W2, temp;
|
#define ROT31(a,k) ((((a) << (k)) | ((a) >> (31 - (k)))) & 0x7FFFFFFF)
|
||||||
uint8_t b[4], c[4];
|
#define ROT32(a,k) (((a) << (k)) | ((a) >> (32 - (k))))
|
||||||
|
|
||||||
// 分解X0→字节→S0置换
|
#define L1(X) \
|
||||||
b[0] = (X0 >> 24) & 0xFF;
|
((X) ^ \
|
||||||
b[1] = (X0 >> 16) & 0xFF;
|
ROT32((X), 2) ^ \
|
||||||
b[2] = (X0 >> 8) & 0xFF;
|
ROT32((X), 10) ^ \
|
||||||
b[3] = X0 & 0xFF;
|
ROT32((X), 18) ^ \
|
||||||
b[0] = ZUC256_S0[b[0]];
|
ROT32((X), 24))
|
||||||
b[1] = ZUC256_S0[b[1]];
|
|
||||||
b[2] = ZUC256_S0[b[2]];
|
|
||||||
b[3] = ZUC256_S0[b[3]];
|
|
||||||
W1 = ((uint32_t)b[0] << 24) | ((uint32_t)b[1] << 16) | ((uint32_t)b[2] << 8) | b[3];
|
|
||||||
|
|
||||||
// 分解X1→字节→S1置换
|
#define L2(X) \
|
||||||
c[0] = (X1 >> 24) & 0xFF;
|
((X) ^ \
|
||||||
c[1] = (X1 >> 16) & 0xFF;
|
ROT32((X), 8) ^ \
|
||||||
c[2] = (X1 >> 8) & 0xFF;
|
ROT32((X), 14) ^ \
|
||||||
c[3] = X1 & 0xFF;
|
ROT32((X), 22) ^ \
|
||||||
c[0] = ZUC256_S1[c[0]];
|
ROT32((X), 30))
|
||||||
c[1] = ZUC256_S1[c[1]];
|
|
||||||
c[2] = ZUC256_S1[c[2]];
|
|
||||||
c[3] = ZUC256_S1[c[3]];
|
|
||||||
W2 = ((uint32_t)c[0] << 24) | ((uint32_t)c[1] << 16) | ((uint32_t)c[2] << 8) | c[3];
|
|
||||||
|
|
||||||
// ZUC标准F函数计算
|
#define LFSRWithInitialisationMode(u, LFSR, V) \
|
||||||
temp = (W1 ^ W2) ^ zuc256_rotl(W1 ^ W2, 16) ^ zuc256_rotl(W1 ^ W2, 12)
|
V = LFSR[0]; \
|
||||||
^ zuc256_rotl(W1 ^ W2, 8) ^ zuc256_rotl(W1 ^ W2, 7);
|
ADD31(V, ROT31(LFSR[ 0], 8)); \
|
||||||
return temp ^ X2;
|
ADD31(V, ROT31(LFSR[ 4], 20)); \
|
||||||
}
|
ADD31(V, ROT31(LFSR[10], 21)); \
|
||||||
|
ADD31(V, ROT31(LFSR[13], 17)); \
|
||||||
|
ADD31(V, ROT31(LFSR[15], 15)); \
|
||||||
|
ADD31(V, (u)); \
|
||||||
|
{int j; for (j=0; j<15;j++) LFSR[j]=LFSR[j+1];} \
|
||||||
|
LFSR[15] = V
|
||||||
|
|
||||||
// 生成32位密钥流字(内部使用)
|
#define LFSRWithWorkMode(LFSR, V) \
|
||||||
static int zuc256_gen_ks_word(ZUC256_CTX *ctx, uint32_t *ks_word) {
|
{ \
|
||||||
if (ctx == NULL || ks_word == NULL) {
|
int j; \
|
||||||
return ZUC256_ERR_NULL;
|
uint64_t a = LFSR[0]; \
|
||||||
|
a += ((uint64_t)LFSR[ 0]) << 8; \
|
||||||
|
a += ((uint64_t)LFSR[ 4]) << 20; \
|
||||||
|
a += ((uint64_t)LFSR[10]) << 21; \
|
||||||
|
a += ((uint64_t)LFSR[13]) << 17; \
|
||||||
|
a += ((uint64_t)LFSR[15]) << 15; \
|
||||||
|
a = (a & 0x7fffffff) + (a >> 31); \
|
||||||
|
V = (uint32_t)((a & 0x7fffffff) + (a >> 31)); \
|
||||||
|
for (j = 0; j < 15; j++) \
|
||||||
|
LFSR[j] = LFSR[j+1]; \
|
||||||
|
LFSR[15] = V; \
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t X0, X1, X2, F_res;
|
#define BitReconstruction2(X1,X2, LFSR) \
|
||||||
|
X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >> 15); \
|
||||||
|
X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >> 15)
|
||||||
|
|
||||||
// 计算F函数输入
|
#define BitReconstruction3(X0,X1,X2, LFSR) \
|
||||||
X0 = ctx->NFSR[15];
|
X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF); \
|
||||||
X1 = ctx->LFSR[15] ^ ctx->NFSR[11];
|
BitReconstruction2(X1,X2, LFSR)
|
||||||
X2 = ctx->LFSR[14];
|
|
||||||
F_res = zuc256_F(X0, X1, X2);
|
|
||||||
|
|
||||||
// 更新辅助寄存器R1/R2
|
#define BitReconstruction4(X0,X1,X2,X3, LFSR) \
|
||||||
ctx->R1 = zuc256_rotl(ctx->R1, 1) ^ (F_res >> 1);
|
BitReconstruction3(X0,X1,X2, LFSR); \
|
||||||
ctx->R2 = zuc256_rotl(ctx->R2, 1) ^ (F_res & 0x1);
|
X3 = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >> 15)
|
||||||
|
|
||||||
// 生成32位密钥流
|
#define MAKEU32(a, b, c, d) \
|
||||||
*ks_word = ctx->LFSR[15] ^ ctx->R1 ^ ctx->R2;
|
(((uint32_t)(a) << 24) | \
|
||||||
|
((uint32_t)(b) << 16) | \
|
||||||
|
((uint32_t)(c) << 8) | \
|
||||||
|
((uint32_t)(d)))
|
||||||
|
|
||||||
// LFSR移位更新(ZUC标准反馈多项式)
|
#define ZUC256_MAKEU31(a,b,c,d) \
|
||||||
uint32_t lfsr_feedback = ctx->LFSR[15] ^ (ctx->LFSR[11] & ctx->LFSR[12]) ^ ctx->LFSR[9];
|
(((uint32_t)(a) << 23) | \
|
||||||
memmove(&ctx->LFSR[1], &ctx->LFSR[0], sizeof(ctx->LFSR) - sizeof(uint32_t));
|
((uint32_t)(b) << 16) | \
|
||||||
ctx->LFSR[0] = lfsr_feedback;
|
((uint32_t)(c) << 8) | \
|
||||||
|
(uint32_t)(d)) & 0x7FFFFFFF /* 确保31位 */
|
||||||
|
|
||||||
// NFSR移位更新(ZUC标准反馈多项式)
|
//F_函数宏
|
||||||
uint32_t nfsr_feedback = ctx->NFSR[15] ^ ctx->NFSR[13] ^ ctx->NFSR[10] ^ ctx->NFSR[0]
|
#define F_(X1,X2) do { \
|
||||||
^ (ctx->NFSR[0] & ctx->NFSR[2]) ^ (ctx->NFSR[1] & ctx->NFSR[3])
|
uint32_t W1, W2, U, V; \
|
||||||
^ (ctx->NFSR[0] & ctx->NFSR[1] & ctx->NFSR[4]);
|
W1 = R1 + X1; \
|
||||||
memmove(&ctx->NFSR[1], &ctx->NFSR[0], sizeof(ctx->NFSR) - sizeof(uint32_t));
|
W2 = R2 ^ X2; \
|
||||||
ctx->NFSR[0] = nfsr_feedback;
|
U = L1((W1 << 16) | (W2 >> 16)); \
|
||||||
|
V = L2((W2 << 16) | (W1 >> 16)); \
|
||||||
|
R1 = MAKEU32(S0[U >> 24], \
|
||||||
|
S1[(U >> 16) & 0xFF], \
|
||||||
|
S0[(U >> 8) & 0xFF], \
|
||||||
|
S1[U & 0xFF]); \
|
||||||
|
R2 = MAKEU32(S0[V >> 24], \
|
||||||
|
S1[(V >> 16) & 0xFF], \
|
||||||
|
S0[(V >> 8) & 0xFF], \
|
||||||
|
S1[V & 0xFF]); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
return ZUC256_SUCCESS;
|
//F函数宏
|
||||||
|
#define F(X0,X1,X2) ({ \
|
||||||
|
uint32_t result; \
|
||||||
|
result = ((X0 ^ R1) + R2) & 0xFFFFFFFF; \
|
||||||
|
F_(X1, X2); \
|
||||||
|
result; \
|
||||||
|
})
|
||||||
|
// 辅助函数:字节序转换
|
||||||
|
static inline uint32_t GETU32(const uint8_t *p) {
|
||||||
|
return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) |
|
||||||
|
((uint32_t)p[2] << 8) | (uint32_t)p[3];
|
||||||
}
|
}
|
||||||
|
static inline void PUTU32(uint8_t *p, uint32_t v) {
|
||||||
// 初始化LFSR/NFSR寄存器
|
p[0] = (uint8_t)(v >> 24);
|
||||||
static int zuc256_init_regs(ZUC256_CTX *ctx) {
|
p[1] = (uint8_t)(v >> 16);
|
||||||
if (ctx == NULL) {
|
p[2] = (uint8_t)(v >> 8);
|
||||||
return ZUC256_ERR_NULL;
|
p[3] = (uint8_t)v;
|
||||||
}
|
}
|
||||||
|
// 设置MAC密钥(内部使用)
|
||||||
uint32_t F_res;
|
static void zuc256_set_mac_key(ZUC256_STATE *key, const uint8_t K[32],
|
||||||
|
const uint8_t IV[23], int macbits)
|
||||||
|
{
|
||||||
|
ZUC_UINT31 *LFSR = key->LFSR;
|
||||||
|
uint32_t R1 = 0, R2 = 0;
|
||||||
|
uint32_t X0, X1, X2, W;
|
||||||
|
const ZUC_UINT7 *D;
|
||||||
int i;
|
int i;
|
||||||
|
uint32_t V;
|
||||||
|
|
||||||
// 加载密钥到寄存器前8位(0~7)
|
// 从IV中提取扩展位
|
||||||
for (i = 0; i < 8; i++) {
|
ZUC_UINT6 IV17 = (IV[17] >> 2) & 0x3F;
|
||||||
ctx->LFSR[i] = ctx->key[i];
|
ZUC_UINT6 IV18 = (((IV[17] & 0x3) << 4) | (IV[18] >> 4)) & 0x3F;
|
||||||
ctx->NFSR[i] = ctx->key[i];
|
ZUC_UINT6 IV19 = (((IV[18] & 0xF) << 2) | (IV[19] >> 6)) & 0x3F;
|
||||||
}
|
ZUC_UINT6 IV20 = (IV[19] & 0x3F) & 0x3F;
|
||||||
|
ZUC_UINT6 IV21 = (IV[20] >> 2) & 0x3F;
|
||||||
|
ZUC_UINT6 IV22 = (((IV[20] & 0x3) << 4) | (IV[21] >> 4)) & 0x3F;
|
||||||
|
ZUC_UINT6 IV23 = (((IV[21] & 0xF) << 2) | (IV[22] >> 6)) & 0x3F;
|
||||||
|
ZUC_UINT6 IV24 = (IV[22] & 0x3F) & 0x3F;
|
||||||
|
|
||||||
// 修复:用IV循环填充寄存器后8位(8~15),避免越界
|
// 选择合适的D数组
|
||||||
// IV共4个元素(0~3),通过(i-8)%4循环访问
|
D = (macbits/32 < 3) ? ZUC256_D[macbits/32] : ZUC256_D[3];
|
||||||
for (i = 8; i < 16; i++) {
|
|
||||||
ctx->LFSR[i] = ctx->iv[(i - 8) % 4]; // 索引范围:0~3,安全访问
|
|
||||||
ctx->NFSR[i] = ctx->iv[(i - 8) % 4];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 32次迭代打乱初始状态(ZUC强制步骤)
|
// 初始化LFSR状态
|
||||||
|
LFSR[0] = ZUC256_MAKEU31(K[0], D[0], K[21], K[16]);
|
||||||
|
LFSR[1] = ZUC256_MAKEU31(K[1], D[1], K[22], K[17]);
|
||||||
|
LFSR[2] = ZUC256_MAKEU31(K[2], D[2], K[23], K[18]);
|
||||||
|
LFSR[3] = ZUC256_MAKEU31(K[3], D[3], K[24], K[19]);
|
||||||
|
LFSR[4] = ZUC256_MAKEU31(K[4], D[4], K[25], K[20]);
|
||||||
|
LFSR[5] = ZUC256_MAKEU31(IV[0], (D[5] | IV17), K[5], K[26]);
|
||||||
|
LFSR[6] = ZUC256_MAKEU31(IV[1], (D[6] | IV18), K[6], K[27]);
|
||||||
|
LFSR[7] = ZUC256_MAKEU31(IV[10], (D[7] | IV19), K[7], IV[2]);
|
||||||
|
LFSR[8] = ZUC256_MAKEU31(K[8], (D[8] | IV20), IV[3], IV[11]);
|
||||||
|
LFSR[9] = ZUC256_MAKEU31(K[9], (D[9] | IV21), IV[12], IV[4]);
|
||||||
|
LFSR[10] = ZUC256_MAKEU31(IV[5], (D[10] | IV22), K[10], K[28]);
|
||||||
|
LFSR[11] = ZUC256_MAKEU31(K[11], (D[11] | IV23), IV[6], IV[13]);
|
||||||
|
LFSR[12] = ZUC256_MAKEU31(K[12], (D[12] | IV24), IV[7], IV[14]);
|
||||||
|
LFSR[13] = ZUC256_MAKEU31(K[13], D[13], IV[15], IV[8]);
|
||||||
|
LFSR[14] = ZUC256_MAKEU31(K[14], (D[14] | ((K[31] >> 4) & 0x0F)), IV[16], IV[9]);
|
||||||
|
LFSR[15] = ZUC256_MAKEU31(K[15], (D[15] | (K[31] & 0x0F)), K[30], K[29]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 32轮初始迭代
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
uint32_t X0 = ctx->NFSR[15];
|
BitReconstruction3(X0, X1, X2, LFSR);
|
||||||
uint32_t X1 = ctx->LFSR[15] ^ ctx->NFSR[11];
|
W = F(X0, X1, X2);
|
||||||
uint32_t X2 = ctx->LFSR[14];
|
LFSRWithInitialisationMode(W >> 1, LFSR, V);
|
||||||
F_res = zuc256_F(X0, X1, X2);
|
|
||||||
|
|
||||||
// LFSR移位(带F函数反馈)
|
|
||||||
uint32_t lfsr_feedback = ctx->LFSR[15] ^ (ctx->LFSR[11] & ctx->LFSR[12]) ^ ctx->LFSR[9] ^ F_res;
|
|
||||||
memmove(&ctx->LFSR[1], &ctx->LFSR[0], sizeof(ctx->LFSR) - sizeof(uint32_t));
|
|
||||||
ctx->LFSR[0] = lfsr_feedback;
|
|
||||||
|
|
||||||
// NFSR移位(带F函数反馈)
|
|
||||||
uint32_t nfsr_feedback = ctx->NFSR[15] ^ ctx->NFSR[13] ^ ctx->NFSR[10] ^ ctx->NFSR[0]
|
|
||||||
^ (ctx->NFSR[0] & ctx->NFSR[2]) ^ (ctx->NFSR[1] & ctx->NFSR[3])
|
|
||||||
^ (ctx->NFSR[0] & ctx->NFSR[1] & ctx->NFSR[4]) ^ F_res;
|
|
||||||
memmove(&ctx->NFSR[1], &ctx->NFSR[0], sizeof(ctx->NFSR) - sizeof(uint32_t));
|
|
||||||
ctx->NFSR[0] = nfsr_feedback;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化辅助寄存器和密钥流缓存
|
// 切换到工作模式
|
||||||
ctx->R1 = 0;
|
BitReconstruction2(X1, X2, LFSR);
|
||||||
ctx->R2 = 0;
|
F_(X1, X2);
|
||||||
ctx->ks_buf = 0;
|
LFSRWithWorkMode(LFSR, V);
|
||||||
ctx->ks_buf_len = 0;
|
|
||||||
|
|
||||||
return ZUC256_SUCCESS;
|
// 保存寄存器状态
|
||||||
|
key->R1 = R1;
|
||||||
|
key->R2 = R2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZUC256_Init(ZUC256_CTX *ctx, const uint8_t *key, const uint8_t *iv) {
|
// 初始化ZUC256状态
|
||||||
// 参数合法性检查
|
void zuc256_init(ZUC256_STATE *state, const uint8_t K[32], const uint8_t IV[23]) {
|
||||||
if (ctx == NULL || key == NULL || iv == NULL) {
|
if (!state || !K || !IV) return;
|
||||||
return ZUC256_ERR_NULL;
|
zuc256_set_mac_key(state, K, IV, 0);
|
||||||
}
|
|
||||||
|
|
||||||
// 清空上下文(避免敏感数据残留)
|
|
||||||
memset(ctx, 0, sizeof(ZUC256_CTX));
|
|
||||||
|
|
||||||
// 加载密钥(32字节→8个32位字,大端序)
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
ctx->key[i] = ((uint32_t)key[4*i] << 24) | ((uint32_t)key[4*i + 1] << 16)
|
|
||||||
| ((uint32_t)key[4*i + 2] << 8) | (uint32_t)key[4*i + 3];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载IV(16字节→4个32位字,大端序)
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
ctx->iv[i] = ((uint32_t)iv[4*i] << 24) | ((uint32_t)iv[4*i + 1] << 16)
|
|
||||||
| ((uint32_t)iv[4*i + 2] << 8) | (uint32_t)iv[4*i + 3];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化寄存器
|
|
||||||
return zuc256_init_regs(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 生成单个密钥字
|
||||||
|
uint32_t zuc256_generate_keyword(ZUC256_STATE *state) {
|
||||||
|
if (!state) return 0;
|
||||||
|
|
||||||
int ZUC256_Update(ZUC256_CTX *ctx, uint8_t *out, const uint8_t *in, size_t in_len) {
|
ZUC_UINT31 *LFSR = state->LFSR;
|
||||||
if (ctx == NULL || out == NULL || in == NULL) {
|
uint32_t R1 = state->R1;
|
||||||
return ZUC256_ERR_NULL;
|
uint32_t R2 = state->R2;
|
||||||
|
uint32_t X0, X1, X2, X3;
|
||||||
|
uint32_t Z, V;
|
||||||
|
|
||||||
|
BitReconstruction4(X0, X1, X2, X3, LFSR);
|
||||||
|
Z = X3 ^ F(X0, X1, X2);
|
||||||
|
LFSRWithWorkMode(LFSR, V);
|
||||||
|
|
||||||
|
// 更新状态
|
||||||
|
state->R1 = R1;
|
||||||
|
state->R2 = R2;
|
||||||
|
|
||||||
|
|
||||||
|
return Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成指定长度的密钥流
|
||||||
|
void zuc256_generate_keystream(ZUC256_STATE *state, size_t nwords, uint32_t *keystream) {
|
||||||
|
if (!state || !keystream || nwords == 0) return;
|
||||||
|
|
||||||
|
ZUC_UINT31 *LFSR = state->LFSR;
|
||||||
|
uint32_t R1 = state->R1;
|
||||||
|
uint32_t R2 = state->R2;
|
||||||
|
uint32_t X0, X1, X2, X3;
|
||||||
|
uint32_t V;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < nwords; i++) {
|
||||||
|
BitReconstruction4(X0, X1, X2, X3, LFSR);
|
||||||
|
keystream[i] = X3 ^ F(X0, X1, X2);
|
||||||
|
LFSRWithWorkMode(LFSR, V);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *ks_buf_ptr = (uint8_t *)&ctx->ks_buf;
|
// 更新状态
|
||||||
size_t i = 0;
|
state->R1 = R1;
|
||||||
|
state->R2 = R2;
|
||||||
|
|
||||||
// 处理缓存中残留的密钥流(解决非4字节对齐数据)
|
}
|
||||||
if (ctx->ks_buf_len > 0 && in_len > 0) {
|
|
||||||
for (; i < in_len && ctx->ks_buf_len < 4; i++, ctx->ks_buf_len++) {
|
// 初始化加密上下文
|
||||||
out[i] = in[i] ^ ks_buf_ptr[ctx->ks_buf_len];
|
void zuc256_encrypt_init(ZUC256_ENCRYPT_CTX *ctx, const uint8_t K[32], const uint8_t IV[23]) {
|
||||||
}
|
if (!ctx) return;
|
||||||
// 缓存用尽,重置长度
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
if (ctx->ks_buf_len == 4) {
|
zuc256_init(&ctx->state, K, IV);
|
||||||
ctx->ks_buf_len = 0;
|
}
|
||||||
|
|
||||||
|
// 分阶段处理加密数据(支持流式输入)
|
||||||
|
void zuc256_encrypt_update(ZUC256_ENCRYPT_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out) {
|
||||||
|
if (!ctx || !in || !out || inlen == 0) return;
|
||||||
|
|
||||||
|
// 先处理缓冲区中剩余的非4字节数据
|
||||||
|
if (ctx->buflen > 0) {
|
||||||
|
size_t need = 4 - ctx->buflen;
|
||||||
|
size_t copy = (inlen < need) ? inlen : need;
|
||||||
|
|
||||||
|
memcpy(ctx->buf + ctx->buflen, in, copy);
|
||||||
|
ctx->buflen += copy;
|
||||||
|
in += copy;
|
||||||
|
inlen -= copy;
|
||||||
|
|
||||||
|
// 缓冲区已满,处理一个完整的4字节块
|
||||||
|
if (ctx->buflen == 4) {
|
||||||
|
uint32_t keystream = zuc256_generate_keyword(&ctx->state);
|
||||||
|
uint32_t plain = GETU32(ctx->buf);
|
||||||
|
PUTU32(out, plain ^ keystream);
|
||||||
|
|
||||||
|
ctx->buflen = 0;
|
||||||
|
memset(ctx->buf, 0, 4); // 清空缓冲区
|
||||||
|
out += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理完整的4字节块
|
// 处理完整的4字节块
|
||||||
if (i < in_len) {
|
size_t full_blocks = inlen / 4;
|
||||||
size_t remaining = in_len - i;
|
if (full_blocks > 0) {
|
||||||
size_t full_blocks = remaining / 4;
|
size_t keystream_len = full_blocks;
|
||||||
size_t rem_bytes = remaining % 4;
|
uint32_t *keystream = (uint32_t*)malloc(keystream_len * sizeof(uint32_t));
|
||||||
|
if (keystream) {
|
||||||
|
zuc256_generate_keystream(&ctx->state, keystream_len, keystream);
|
||||||
|
|
||||||
// 完整块处理
|
// 逐块异或加密
|
||||||
for (size_t b = 0; b < full_blocks; b++) {
|
for (size_t i = 0; i < full_blocks; i++) {
|
||||||
uint32_t ks_word;
|
uint32_t plain = GETU32(in + i*4);
|
||||||
if (zuc256_gen_ks_word(ctx, &ks_word) != ZUC256_SUCCESS) {
|
PUTU32(out + i*4, plain ^ keystream[i]);
|
||||||
return ZUC256_ERR_NULL;
|
|
||||||
}
|
}
|
||||||
// 密钥流与数据异或(流密码加解密统一逻辑)
|
|
||||||
out[i + 4*b + 0] = in[i + 4*b + 0] ^ ((ks_word >> 24) & 0xFF);
|
|
||||||
out[i + 4*b + 1] = in[i + 4*b + 1] ^ ((ks_word >> 16) & 0xFF);
|
|
||||||
out[i + 4*b + 2] = in[i + 4*b + 2] ^ ((ks_word >> 8) & 0xFF);
|
|
||||||
out[i + 4*b + 3] = in[i + 4*b + 3] ^ (ks_word & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理剩余不足4字节的数据(存入缓存)
|
free(keystream);
|
||||||
if (rem_bytes > 0) {
|
in += full_blocks * 4;
|
||||||
uint32_t ks_word;
|
inlen -= full_blocks * 4;
|
||||||
if (zuc256_gen_ks_word(ctx, &ks_word) != ZUC256_SUCCESS) {
|
out += full_blocks * 4;
|
||||||
return ZUC256_ERR_NULL;
|
|
||||||
}
|
|
||||||
ctx->ks_buf = ks_word;
|
|
||||||
for (size_t r = 0; r < rem_bytes; r++) {
|
|
||||||
out[i + 4*full_blocks + r] = in[i + 4*full_blocks + r] ^ ks_buf_ptr[r];
|
|
||||||
}
|
|
||||||
ctx->ks_buf_len = rem_bytes;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ZUC256_SUCCESS;
|
// 缓存剩余不足4字节的数据
|
||||||
}
|
if (inlen > 0) {
|
||||||
|
memcpy(ctx->buf, in, inlen);
|
||||||
int ZUC256_Final(ZUC256_CTX *ctx, uint8_t *out) {
|
ctx->buflen = inlen;
|
||||||
// 流密码无收尾操作,仅检查上下文合法性
|
|
||||||
(void)out; // 未使用参数,避免编译警告
|
|
||||||
return (ctx == NULL) ? ZUC256_ERR_NULL : ZUC256_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZUC256_Cleanup(ZUC256_CTX *ctx) {
|
|
||||||
if (ctx != NULL) {
|
|
||||||
memset(ctx, 0, sizeof(ZUC256_CTX)); // 覆盖敏感数据,防止泄露
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 完成加密处理(处理剩余数据并清理上下文)
|
||||||
|
void zuc256_encrypt_finish(ZUC256_ENCRYPT_CTX *ctx, uint8_t *out) {
|
||||||
|
if (!ctx || !out) return;
|
||||||
|
|
||||||
|
// 处理缓冲区中剩余的不足4字节数据
|
||||||
|
if (ctx->buflen > 0) {
|
||||||
|
uint32_t keystream = zuc256_generate_keyword(&ctx->state);
|
||||||
|
uint8_t keystream_bytes[4];
|
||||||
|
PUTU32(keystream_bytes, keystream);
|
||||||
|
|
||||||
|
// 逐字节异或
|
||||||
|
for (size_t i = 0; i < ctx->buflen; i++) {
|
||||||
|
out[i] = ctx->buf[i] ^ keystream_bytes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理上下文(安全考虑)
|
||||||
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 一次性加密函数(ZUC加密和解密相同)
|
||||||
|
void zuc256_crypt(ZUC256_STATE *state, const uint8_t *in, size_t inlen, uint8_t *out) {
|
||||||
|
if (!state || !in || !out) return;
|
||||||
|
|
||||||
|
ZUC256_ENCRYPT_CTX ctx;
|
||||||
|
zuc256_encrypt_init(&ctx, NULL, NULL);
|
||||||
|
memcpy(&ctx.state, state, sizeof(ZUC256_STATE)); // 复制当前状态
|
||||||
|
|
||||||
|
zuc256_encrypt_update(&ctx, in, inlen, out);
|
||||||
|
zuc256_encrypt_finish(&ctx, out + (inlen / 4) * 4);
|
||||||
|
|
||||||
|
memcpy(state, &ctx.state, sizeof(ZUC256_STATE)); // 回写状态
|
||||||
|
}
|
||||||
|
void extract_iv(const uint8_t *input_25byte, uint8_t *output_23byte) {
|
||||||
|
if (!input_25byte || !output_23byte) return;
|
||||||
|
for (int i = 0; i < 17; i++) {
|
||||||
|
output_23byte[i] = input_25byte[i];
|
||||||
|
}
|
||||||
|
uint8_t src[8];
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
src[i] = input_25byte[17 + i] & 0x3F;
|
||||||
|
}
|
||||||
|
output_23byte[17] = (src[0] << 2) | (src[1] >> 4);
|
||||||
|
output_23byte[18] = ((src[1] & 0x0F) << 4) | (src[2] >> 2);
|
||||||
|
output_23byte[19] = ((src[2] & 0x03) << 6) | src[3];
|
||||||
|
output_23byte[20] = (src[4] << 2) | (src[5] >> 4);
|
||||||
|
output_23byte[21] = ((src[5] & 0x0F) << 4) | (src[6] >> 2);
|
||||||
|
output_23byte[22] = ((src[6] & 0x03) << 6) | src[7];
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user