Files
se-algo/Project/Src/com/cscn/Zuc256EncryptCtx.java
zcy 4dcf92584c Merge remote-tracking branch 'origin/main' into zcy_dev_cap
# Conflicts:
#	Project/Src/com/cscn/Zuc256EncryptCtx.java
#	Project/Src/com/cscn/Zuc256Tables.java
#	src/com/zuc/zuc256/Zuc256MacCtx.java
#	src/com/zuc/zuc256/Zuc256State.java
2025-09-05 17:20:38 +08:00

142 lines
5.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.zuc.zuc256;
import javacard.framework.JCSystem;
import javacard.framework.Util;
/**
* 加密上下文类Java Card兼容版本
*/
public final class Zuc256EncryptCtx {
Zuc256State state;
byte[] buf;
short buflen;
// 构造函数 - 使用已分配的缓冲区
public Zuc256EncryptCtx(Zuc256State state, byte[] buf) {
this.state = state;
this.buf = buf;
this.buflen = 0;
}
// 构造函数 - 自动分配缓冲区
public Zuc256EncryptCtx(Zuc256State state) {
this.state = state;
this.buf = JCSystem.makeTransientByteArray((short)4, JCSystem.CLEAR_ON_DESELECT);
this.buflen = 0;
}
// 构造函数 - 完整初始化
public Zuc256EncryptCtx() {
this.state = new Zuc256State();
this.buf = JCSystem.makeTransientByteArray((short)4, JCSystem.CLEAR_ON_DESELECT);
this.buflen = 0;
}
// 初始化加密上下文
public void init(byte[] key32, short keyOff, short keyLen, byte[] iv, short ivOff, short ivLen) {
// 清空缓冲区
Util.arrayFillNonAtomic(buf, (short)0, (short)buf.length, (byte)0);
this.buflen = 0;
// 初始化状态
Zuc256Core.initState(this.state, key32, keyOff, keyLen, iv, ivOff, ivLen);
}
// 分阶段处理加密数据
public void update(byte[] in, short inOff, short inlen, byte[] out, short outOff) {
if (in == null || out == null || inlen == 0) return;
short currentInOff = inOff;
short currentOutOff = outOff;
// 处理缓冲区中剩余的非4字节数据
if (this.buflen > 0) {
short need = (short)(4 - this.buflen);
short copy = (short)Math.min(inlen, need);
// 复制数据到缓冲区
Util.arrayCopyNonAtomic(in, currentInOff, this.buf, this.buflen, copy);
this.buflen += copy;
// 调整输入指针和长度
currentInOff += copy;
inlen -= copy;
// 缓冲区已满处理一个完整的4字节块
if (this.buflen == 4) {
short keystream = zuc256GenerateKeyword(this.state);
short plain = getU16(this.buf, (short)0); // 改为16位操作
putU16(out, currentOutOff, (short)(plain ^ keystream));
// 重置缓冲区
this.buflen = 0;
Util.arrayFillNonAtomic(this.buf, (short)0, (short)this.buf.length, (byte)0);
// 调整输出指针
currentOutOff += 2; // 16位数据占2字节
}
}
// 处理完整的2字节块Java Card 16位操作
if (inlen > 0) {
short fullBlocks = (short)(inlen / 2); // 16位块
if (fullBlocks > 0) {
short[] keystream = JCSystem.makeTransientShortArray(fullBlocks, JCSystem.CLEAR_ON_DESELECT);
zuc256GenerateKeystream(this.state, fullBlocks, keystream);
// 逐块异或加密
for (short i = 0; i < fullBlocks; i++) {
short plain = getU16(in, (short)(currentInOff + (short)(i * 2)));
putU16(out, (short)(currentOutOff + (short)(i * 2)), (short)(plain ^ keystream[i]));
}
// 调整输入指针和长度
short processed = (short)(fullBlocks * 2);
currentInOff += processed;
inlen -= processed;
}
// 缓存剩余不足2字节的数据
if (inlen > 0) {
Util.arrayCopyNonAtomic(in, currentInOff, this.buf, (short)0, inlen);
this.buflen = inlen;
}
}
}
// 完成加密处理
public void finish(byte[] out, short outOff) {
if (out == null) return;
// 处理缓冲区中剩余的不足2字节数据
if (this.buflen > 0) {
short keystream = zuc256GenerateKeyword(this.state);
byte[] keystreamBytes = JCSystem.makeTransientByteArray((short)2, JCSystem.CLEAR_ON_DESELECT);
putU16(keystreamBytes, (short)0, keystream);
// 逐字节异或
for (short i = 0; i < this.buflen; i++) {
out[(short)(outOff + i)] = (byte)(this.buf[i] ^ keystreamBytes[i]);
}
}
// 清理上下文
Util.arrayFillNonAtomic(this.buf, (short)0, (short)this.buf.length, (byte)0);
this.buflen = 0;
// 清理状态
Util.arrayFillNonAtomic(this.state.LFSR, (short)0, (short)this.state.LFSR.length, (short)0);
this.state.R1 = 0;
this.state.R2 = 0;
}
// 16位数据读取替代原32位实现
private short getU16(byte[] buf, short off) {
return (short)(((buf[off] & 0xFF) << 8) | (buf[(short)(off + 1)] & 0xFF));
}
// 16位数据写入替代原32位实现
private void putU16(byte[] buf, short off, short value) {
buf[off] = (byte)((value >>> 8) & 0xFF);
buf[(short)(off + 1)] = (byte)(value & 0xFF);
}
}