新增jna接口

This commit is contained in:
waner
2026-04-01 16:47:20 +08:00
parent 1dec24a10c
commit 6d72f78281
22 changed files with 1527 additions and 204 deletions
@@ -27,6 +27,11 @@ public class PcieSessionTemplate {
T apply(PcieNativeLibrary lib, Pointer deviceHandle, Pointer sessionHandle);
}
@FunctionalInterface
public interface TwoSessionCallback<T> {
T apply(PcieNativeLibrary lib, Pointer deviceHandle, Pointer sessionHandleFrom, Pointer sessionHandleTo);
}
private static final Logger log = LoggerFactory.getLogger(PcieSessionTemplate.class);
private final CryptoCardProperties properties;
@@ -71,6 +76,27 @@ public class PcieSessionTemplate {
}
}
public <T> T withTwoSessions(String apiName, TwoSessionCallback<T> callback) {
synchronized (lock) {
PcieNativeLibrary lib = ensureLibraryLoaded();
Pointer deviceHandle = ensureSharedDeviceOpened(apiName, lib);
Pointer sessionFrom = tryOpenSession(apiName, lib, deviceHandle);
if (sessionFrom == null) {
resetSharedDevice(lib);
deviceHandle = ensureSharedDeviceOpened(apiName, lib);
sessionFrom = openSessionOrThrow(apiName, lib, deviceHandle);
}
Pointer sessionTo = openSessionOrThrow(apiName, lib, deviceHandle);
try {
return callback.apply(lib, deviceHandle, sessionFrom, sessionTo);
} finally {
closeSessionQuietly(apiName, lib, sessionTo);
closeSessionQuietly(apiName, lib, sessionFrom);
}
}
}
public void ensureSuccess(String apiName, int retCode) {
if (retCode != 0) {
throw new PcieCryptoException(apiName, retCode, errorMapper.toMessage(retCode));
@@ -146,6 +172,16 @@ public class PcieSessionTemplate {
return sessionRef.getValue();
}
private void closeSessionQuietly(String apiName, PcieNativeLibrary lib, Pointer sessionHandle) {
if (sessionHandle == null) {
return;
}
int closeSessionRc = lib.SDF_CloseSession(sessionHandle);
if (closeSessionRc != 0) {
log.warn("{} close session failed: {}", apiName, errorMapper.toMessage(closeSessionRc));
}
}
private void resetSharedDevice(PcieNativeLibrary lib) {
closeSharedDevice(lib);
}
@@ -200,10 +200,6 @@ public interface PcieNativeLibrary extends Library {
int SDFE_ImportEncKeyPair_ECC(Pointer hSessionHandle, int keyIndex, EnvelopedKeyBlob envelopedKeyBlob);
int SDFE_ImportEncKeyPair_RSA(Pointer hSessionHandle, int keyIndex, int symAlgId,
byte[] wrappedKey, int wrappedKeyLen,
byte[] encryptedData, int encryptedDataLen);
int SDFE_UpdateBackedKey(Pointer hSessionHandle, byte[] oldData, int oldDataLength,
byte[] newData, IntByReference newDataLength);
@@ -231,6 +227,18 @@ public interface PcieNativeLibrary extends Library {
int SDFE_RecoverIK(Pointer hSessionHandle, int keyType);
int SDFE_BackupIK_EX(Pointer hSessionHandle, int keyType, SdfeIkComponent ikComponent);
int SDFE_RecoverIK_EX(Pointer hSessionHandle, int keyType, SdfeIkComponent ikComponent);
int SDFE_ExportIKPublicKey(Pointer hSessionHandle, int ikType, EccRefPublicKey publicKey);
int SDFE_ExportIKMac(Pointer hSessionHandle, int ikType, byte[] mac);
int SDFE_SignIK(Pointer hSessionHandle, int ikType, byte[] data, int dataLength, EccSignature signature);
int SDFE_VerifyIK(Pointer hSessionHandle, int ikType, byte[] data, int dataLength, EccSignature signature);
int SDFE_DestroyIK(Pointer hSessionHandle, int keyType);
int SDFE_StatusIK(Pointer hSessionHandle, int keyType, IntByReference keyState);
@@ -264,4 +272,22 @@ public interface PcieNativeLibrary extends Library {
int SDFE_HmacUpdate(Pointer hSessionHandle, byte[] data, int dataLength);
int SDFE_HmacFinal(Pointer hSessionHandle, byte[] hmac, IntByReference hmacLength);
int SDFE_GetFirmwareInfo(Pointer hSessionHandle, SdfFirmwareInfo firmwareInfo);
int SDFE_HashCopy(Pointer hSessionHandleTo, Pointer hSessionHandleFrom);
int SDFE_Encrypt(Pointer hSessionHandle, byte[] key, int keyLength, int algId, byte[] iv,
byte[] data, int dataLength, byte[] encData, IntByReference encDataLength);
int SDFE_Decrypt(Pointer hSessionHandle, byte[] key, int keyLength, int algId, byte[] iv,
byte[] encData, int encDataLength, byte[] data, IntByReference dataLength);
int SDFE_Hash(Pointer hSessionHandle, int algId, byte[] data, int dataLength,
byte[] hash, IntByReference hashLength);
int SDFE_InternalEncrypt_ECC(Pointer hSessionHandle, int keyIndex, byte[] data, int dataLength, EccCipher encData);
int SDFE_InternalDecrypt_ECC(Pointer hSessionHandle, int keyIndex, EccCipher encData,
byte[] data, IntByReference dataLength);
}
@@ -0,0 +1,15 @@
package com.cisd.tms.integration.crypto.pcie.jna;
import com.sun.jna.Structure;
@Structure.FieldOrder({"bomInfo", "gd32Info", "n32s033Info"})
public class SdfFirmwareInfo extends Structure {
public byte[] bomInfo = new byte[5];
public byte[] gd32Info = new byte[5];
public byte[] n32s033Info = new byte[5];
public SdfFirmwareInfo() {
super(ALIGN_NONE);
}
}
@@ -0,0 +1,16 @@
package com.cisd.tms.integration.crypto.pcie.jna;
import com.sun.jna.Structure;
@Structure.FieldOrder({"component", "priMac", "pubkey", "pubMac"})
public class SdfeIkComponent extends Structure {
public byte[] component = new byte[3 * EccRefPublicKey.MAX_LEN];
public byte[] priMac = new byte[8];
public EccRefPublicKey pubkey = new EccRefPublicKey();
public byte[] pubMac = new byte[8];
public SdfeIkComponent() {
super(ALIGN_NONE);
}
}
@@ -0,0 +1,32 @@
package com.cisd.tms.integration.crypto.pcie.model;
public class EccInternalDecryptRequest {
private int keyIndex;
private byte[] cipherBlob;
private int outBufferSize;
public int getKeyIndex() {
return keyIndex;
}
public void setKeyIndex(int keyIndex) {
this.keyIndex = keyIndex;
}
public byte[] getCipherBlob() {
return cipherBlob;
}
public void setCipherBlob(byte[] cipherBlob) {
this.cipherBlob = cipherBlob;
}
public int getOutBufferSize() {
return outBufferSize;
}
public void setOutBufferSize(int outBufferSize) {
this.outBufferSize = outBufferSize;
}
}
@@ -0,0 +1,32 @@
package com.cisd.tms.integration.crypto.pcie.model;
public class EccInternalEncryptRequest {
private int keyIndex;
private byte[] data;
private int outBufferSize;
public int getKeyIndex() {
return keyIndex;
}
public void setKeyIndex(int keyIndex) {
this.keyIndex = keyIndex;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public int getOutBufferSize() {
return outBufferSize;
}
public void setOutBufferSize(int outBufferSize) {
this.outBufferSize = outBufferSize;
}
}
@@ -0,0 +1,32 @@
package com.cisd.tms.integration.crypto.pcie.model;
public class FirmwareInfoResult {
private byte[] bomInfo;
private byte[] gd32Info;
private byte[] n32s033Info;
public byte[] getBomInfo() {
return bomInfo;
}
public void setBomInfo(byte[] bomInfo) {
this.bomInfo = bomInfo;
}
public byte[] getGd32Info() {
return gd32Info;
}
public void setGd32Info(byte[] gd32Info) {
this.gd32Info = gd32Info;
}
public byte[] getN32s033Info() {
return n32s033Info;
}
public void setN32s033Info(byte[] n32s033Info) {
this.n32s033Info = n32s033Info;
}
}
@@ -0,0 +1,32 @@
package com.cisd.tms.integration.crypto.pcie.model;
public class IkSignRequest {
private int keyType;
private byte[] data;
private int signatureBufferSize;
public int getKeyType() {
return keyType;
}
public void setKeyType(int keyType) {
this.keyType = keyType;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public int getSignatureBufferSize() {
return signatureBufferSize;
}
public void setSignatureBufferSize(int signatureBufferSize) {
this.signatureBufferSize = signatureBufferSize;
}
}
@@ -0,0 +1,32 @@
package com.cisd.tms.integration.crypto.pcie.model;
public class IkVerifyRequest {
private int keyType;
private byte[] data;
private byte[] signature;
public int getKeyType() {
return keyType;
}
public void setKeyType(int keyType) {
this.keyType = keyType;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public byte[] getSignature() {
return signature;
}
public void setSignature(byte[] signature) {
this.signature = signature;
}
}
@@ -1,41 +0,0 @@
package com.cisd.tms.integration.crypto.pcie.model;
public class ImportEncKeyPairRsaRequest {
private int keyIndex;
private int symAlgId;
private byte[] wrappedKey;
private byte[] encryptedData;
public int getKeyIndex() {
return keyIndex;
}
public void setKeyIndex(int keyIndex) {
this.keyIndex = keyIndex;
}
public int getSymAlgId() {
return symAlgId;
}
public void setSymAlgId(int symAlgId) {
this.symAlgId = symAlgId;
}
public byte[] getWrappedKey() {
return wrappedKey;
}
public void setWrappedKey(byte[] wrappedKey) {
this.wrappedKey = wrappedKey;
}
public byte[] getEncryptedData() {
return encryptedData;
}
public void setEncryptedData(byte[] encryptedData) {
this.encryptedData = encryptedData;
}
}
@@ -15,12 +15,13 @@ import com.cisd.tms.integration.crypto.pcie.jna.PcieNativeLibrary;
import com.cisd.tms.integration.crypto.pcie.jna.RsaRefPrivateKey;
import com.cisd.tms.integration.crypto.pcie.jna.RsaRefPublicKey;
import com.cisd.tms.integration.crypto.pcie.jna.SdfDeviceInfo;
import com.cisd.tms.integration.crypto.pcie.jna.SdfFirmwareInfo;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeDeviceConf;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeDeviceStatus;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeIkComponent;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeKekComponent;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeLmkComponent;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeLoginState;
import com.cisd.tms.integration.crypto.pcie.jna.SydIkComponent;
import com.cisd.tms.integration.crypto.pcie.model.AgreementDataAndKeyEccResult;
import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult;
import com.cisd.tms.integration.crypto.pcie.model.ChangePrivateKeyPasswordRequest;
@@ -29,6 +30,8 @@ import com.cisd.tms.integration.crypto.pcie.model.DeviceCountResult;
import com.cisd.tms.integration.crypto.pcie.model.DeviceInfoResult;
import com.cisd.tms.integration.crypto.pcie.model.DeviceStatusResult;
import com.cisd.tms.integration.crypto.pcie.model.DigestRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalEncryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalEncryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalSignRequest;
@@ -55,12 +58,14 @@ import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.HmacRequest;
import com.cisd.tms.integration.crypto.pcie.model.HmacResult;
import com.cisd.tms.integration.crypto.pcie.model.FirmwareInfoResult;
import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairEccRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskEccRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.IkSignRequest;
import com.cisd.tms.integration.crypto.pcie.model.IkVerifyRequest;
import com.cisd.tms.integration.crypto.pcie.model.KekComponentRequest;
import com.cisd.tms.integration.crypto.pcie.model.KeyStatusResult;
import com.cisd.tms.integration.crypto.pcie.model.LoginStatusResult;
@@ -655,36 +660,6 @@ public class JnaPcieCryptoService implements PcieCryptoService {
});
}
@Override
public void importEncryptedKeyPairRsa(ImportEncKeyPairRsaRequest request) {
ImportEncKeyPairRsaRequest req = requireRequest("request", request);
int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
int symAlgId = requireValidAlgId("symAlgId", req.getSymAlgId());
byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
byte[] encryptedData = requireNonEmptyBytes("encryptedData", req.getEncryptedData());
try {
sessionTemplate.withSession("SDFE_ImportEncKeyPair_RSA", (lib, deviceHandle, sessionHandle) -> {
sessionTemplate.ensureSuccess(
"SDFE_ImportEncKeyPair_RSA",
lib.SDFE_ImportEncKeyPair_RSA(
sessionHandle,
keyIndex,
symAlgId,
wrappedKey,
wrappedKey.length,
encryptedData,
encryptedData.length
)
);
return null;
});
} finally {
wipe(wrappedKey);
wipe(encryptedData);
}
}
@Override
public BackupDataResult updateBackedKey(UpdateBackedKeyRequest request) {
UpdateBackedKeyRequest req = requireRequest("request", request);
@@ -778,6 +753,39 @@ public class JnaPcieCryptoService implements PcieCryptoService {
});
}
@Override
public BackupDataResult exportIkPublicKey(int keyType, int outBufferSize) {
int safeKeyType = requireNonNegative("keyType", keyType);
int size = requirePositive("outBufferSize", outBufferSize);
return sessionTemplate.withSession("SDFE_ExportIKPublicKey", (lib, deviceHandle, sessionHandle) -> {
EccRefPublicKey out = new EccRefPublicKey();
if (size < out.size()) {
throw new IllegalArgumentException("outBufferSize must be >= " + out.size());
}
sessionTemplate.ensureSuccess(
"SDFE_ExportIKPublicKey",
lib.SDFE_ExportIKPublicKey(sessionHandle, safeKeyType, out)
);
byte[] outBytes = toBytes(out);
return toBackupResult("SDFE_ExportIKPublicKey", outBytes, outBytes.length);
});
}
@Override
public BackupDataResult exportIkMac(int keyType) {
int safeKeyType = requireNonNegative("keyType", keyType);
return sessionTemplate.withSession("SDFE_ExportIKMac", (lib, deviceHandle, sessionHandle) -> {
byte[] out = new byte[8];
sessionTemplate.ensureSuccess(
"SDFE_ExportIKMac",
lib.SDFE_ExportIKMac(sessionHandle, safeKeyType, out)
);
return toBackupResult("SDFE_ExportIKMac", out, out.length);
});
}
@Override
public StandardKeyPairResult generateStandardRsaKeyPair(GenerateStandardRsaKeyPairRequest request) {
GenerateStandardRsaKeyPairRequest req = requireRequest("request", request);
@@ -1334,6 +1342,27 @@ public class JnaPcieCryptoService implements PcieCryptoService {
});
}
@Override
public BackupDataResult signIk(IkSignRequest request) {
IkSignRequest req = requireRequest("request", request);
int keyType = requireNonNegative("keyType", req.getKeyType());
byte[] data = requireBytes("data", req.getData());
int signatureBufferSize = requirePositive("signatureBufferSize", req.getSignatureBufferSize());
return sessionTemplate.withSession("SDFE_SignIK", (lib, deviceHandle, sessionHandle) -> {
EccSignature signature = new EccSignature();
if (signatureBufferSize < signature.size()) {
throw new IllegalArgumentException("signatureBufferSize must be >= " + signature.size());
}
sessionTemplate.ensureSuccess(
"SDFE_SignIK",
lib.SDFE_SignIK(sessionHandle, keyType, data, data.length, signature)
);
byte[] signatureBytes = toBytes(signature);
return toBackupResult("SDFE_SignIK", signatureBytes, signatureBytes.length);
});
}
@Override
public BackupDataResult eccExternalSign(EccExternalSignRequest request) {
EccExternalSignRequest req = requireRequest("request", request);
@@ -1372,6 +1401,22 @@ public class JnaPcieCryptoService implements PcieCryptoService {
});
}
@Override
public void verifyIk(IkVerifyRequest request) {
IkVerifyRequest req = requireRequest("request", request);
int keyType = requireNonNegative("keyType", req.getKeyType());
byte[] data = requireBytes("data", req.getData());
EccSignature signature = toEccSignature("signature", req.getSignature());
sessionTemplate.withSession("SDFE_VerifyIK", (lib, deviceHandle, sessionHandle) -> {
sessionTemplate.ensureSuccess(
"SDFE_VerifyIK",
lib.SDFE_VerifyIK(sessionHandle, keyType, data, data.length, signature)
);
return null;
});
}
@Override
public void eccExternalVerify(EccExternalVerifyRequest request) {
EccExternalVerifyRequest req = requireRequest("request", request);
@@ -1561,6 +1606,134 @@ public class JnaPcieCryptoService implements PcieCryptoService {
});
}
@Override
public FirmwareInfoResult getFirmwareInfo() {
return sessionTemplate.withSession("SDFE_GetFirmwareInfo", (lib, deviceHandle, sessionHandle) -> {
SdfFirmwareInfo info = new SdfFirmwareInfo();
sessionTemplate.ensureSuccess("SDFE_GetFirmwareInfo", lib.SDFE_GetFirmwareInfo(sessionHandle, info));
info.read();
FirmwareInfoResult result = new FirmwareInfoResult();
result.setBomInfo(Arrays.copyOf(info.bomInfo, info.bomInfo.length));
result.setGd32Info(Arrays.copyOf(info.gd32Info, info.gd32Info.length));
result.setN32s033Info(Arrays.copyOf(info.n32s033Info, info.n32s033Info.length));
return result;
});
}
@Override
public void sdfeHashCopy() {
sessionTemplate.withTwoSessions("SDFE_HashCopy", (lib, deviceHandle, sessionFrom, sessionTo) -> {
sessionTemplate.ensureSuccess("SDFE_HashCopy", lib.SDFE_HashCopy(sessionTo, sessionFrom));
return null;
});
}
@Override
public BackupDataResult sdfeEncrypt(SymmetricCryptoRequest request) {
SymmetricCryptoRequest req = requireRequest("request", request);
int algId = requireValidAlgId("algId", req.getAlgId());
byte[] key = requireNonEmptyBytes("key", req.getKey());
byte[] data = requireBytes("data", req.getData());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
byte[] iv = req.getIv();
try {
return sessionTemplate.withSession("SDFE_Encrypt", (lib, deviceHandle, sessionHandle) -> {
byte[] out = new byte[outBufferSize];
IntByReference outLen = new IntByReference(out.length);
sessionTemplate.ensureSuccess(
"SDFE_Encrypt",
lib.SDFE_Encrypt(sessionHandle, key, key.length, algId, iv, data, data.length, out, outLen)
);
return toBackupResult("SDFE_Encrypt", out, outLen.getValue());
});
} finally {
wipe(key);
}
}
@Override
public BackupDataResult sdfeDecrypt(SymmetricCryptoRequest request) {
SymmetricCryptoRequest req = requireRequest("request", request);
int algId = requireValidAlgId("algId", req.getAlgId());
byte[] key = requireNonEmptyBytes("key", req.getKey());
byte[] data = requireBytes("data", req.getData());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
byte[] iv = req.getIv();
try {
return sessionTemplate.withSession("SDFE_Decrypt", (lib, deviceHandle, sessionHandle) -> {
byte[] out = new byte[outBufferSize];
IntByReference outLen = new IntByReference(out.length);
sessionTemplate.ensureSuccess(
"SDFE_Decrypt",
lib.SDFE_Decrypt(sessionHandle, key, key.length, algId, iv, data, data.length, out, outLen)
);
return toBackupResult("SDFE_Decrypt", out, outLen.getValue());
});
} finally {
wipe(key);
}
}
@Override
public BackupDataResult sdfeHash(DigestRequest request) {
DigestRequest req = requireRequest("request", request);
int algId = requireValidAlgId("algId", req.getAlgId());
byte[] data = requireBytes("data", req.getData());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
return sessionTemplate.withSession("SDFE_Hash", (lib, deviceHandle, sessionHandle) -> {
byte[] out = new byte[outBufferSize];
IntByReference outLen = new IntByReference(out.length);
sessionTemplate.ensureSuccess(
"SDFE_Hash",
lib.SDFE_Hash(sessionHandle, algId, data, data.length, out, outLen)
);
return toBackupResult("SDFE_Hash", out, outLen.getValue());
});
}
@Override
public BackupDataResult sdfeInternalEncryptEcc(EccInternalEncryptRequest request) {
EccInternalEncryptRequest req = requireRequest("request", request);
int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
byte[] data = requireBytes("data", req.getData());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
return sessionTemplate.withSession("SDFE_InternalEncrypt_ECC", (lib, deviceHandle, sessionHandle) -> {
EccCipher cipher = new EccCipher();
if (outBufferSize < cipher.size()) {
throw new IllegalArgumentException("outBufferSize must be >= " + cipher.size());
}
sessionTemplate.ensureSuccess(
"SDFE_InternalEncrypt_ECC",
lib.SDFE_InternalEncrypt_ECC(sessionHandle, keyIndex, data, data.length, cipher)
);
byte[] cipherBytes = toEccCipherBytes("SDFE_InternalEncrypt_ECC", cipher);
return toBackupResult("SDFE_InternalEncrypt_ECC", cipherBytes, cipherBytes.length);
});
}
@Override
public BackupDataResult sdfeInternalDecryptEcc(EccInternalDecryptRequest request) {
EccInternalDecryptRequest req = requireRequest("request", request);
int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
EccCipher cipher = toEccCipher("cipherBlob", req.getCipherBlob());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
return sessionTemplate.withSession("SDFE_InternalDecrypt_ECC", (lib, deviceHandle, sessionHandle) -> {
byte[] out = new byte[outBufferSize];
IntByReference outLen = new IntByReference(out.length);
sessionTemplate.ensureSuccess(
"SDFE_InternalDecrypt_ECC",
lib.SDFE_InternalDecrypt_ECC(sessionHandle, keyIndex, cipher, out, outLen)
);
return toBackupResult("SDFE_InternalDecrypt_ECC", out, outLen.getValue());
});
}
@Override
public HmacResult hmac(HmacRequest request) {
HmacRequest req = requireRequest("request", request);
@@ -1693,22 +1866,21 @@ public class JnaPcieCryptoService implements PcieCryptoService {
public BackupDataResult backupIkComponent(int keyType) {
int safeKeyType = requireNonNegative("keyType", keyType);
//todo 对接真实接口
return sessionTemplate.withSession("SYD_IK_BackUp", (lib, deviceHandle, sessionHandle) -> {
SydIkComponent output = new SydIkComponent();
sessionTemplate.ensureSuccess("SYD_IK_BackUp", lib.SYD_IK_BackUp(deviceHandle, safeKeyType, 1, output));
return sessionTemplate.withSession("SDFE_BackupIK_EX", (lib, deviceHandle, sessionHandle) -> {
SdfeIkComponent output = new SdfeIkComponent();
sessionTemplate.ensureSuccess("SDFE_BackupIK_EX", lib.SDFE_BackupIK_EX(sessionHandle, safeKeyType, output));
byte[] outputBytes = toBytes(output);
return toBackupResult("SYD_IK_BackUp", outputBytes, outputBytes.length);
return toBackupResult("SDFE_BackupIK_EX", outputBytes, outputBytes.length);
});
}
@Override
public void recoverIkComponent(int keyType, byte[] ikComponent) {
int safeKeyType = requireNonNegative("keyType", keyType);
SydIkComponent input = toSydIkComponent("ikComponent", ikComponent);
SdfeIkComponent input = toSdfeIkComponent("ikComponent", ikComponent);
sessionTemplate.withSession("SYD_IK_Recover", (lib, deviceHandle, sessionHandle) -> {
sessionTemplate.ensureSuccess("SYD_IK_Recover", lib.SYD_IK_Recover(deviceHandle, safeKeyType, 1, input));
sessionTemplate.withSession("SDFE_RecoverIK_EX", (lib, deviceHandle, sessionHandle) -> {
sessionTemplate.ensureSuccess("SDFE_RecoverIK_EX", lib.SDFE_RecoverIK_EX(sessionHandle, safeKeyType, input));
return null;
});
}
@@ -2163,8 +2335,8 @@ public class JnaPcieCryptoService implements PcieCryptoService {
return toStructure(name, value, new SdfeLmkComponent(), false);
}
private static SydIkComponent toSydIkComponent(String name, byte[] value) {
return toStructure(name, value, new SydIkComponent(), false);
private static SdfeIkComponent toSdfeIkComponent(String name, byte[] value) {
return toStructure(name, value, new SdfeIkComponent(), false);
}
private static EnvelopedKeyBlob toEnvelopedKeyBlob(String name, byte[] value) {
@@ -11,6 +11,8 @@ import com.cisd.tms.integration.crypto.pcie.model.DeviceCountResult;
import com.cisd.tms.integration.crypto.pcie.model.DeviceInfoResult;
import com.cisd.tms.integration.crypto.pcie.model.DeviceStatusResult;
import com.cisd.tms.integration.crypto.pcie.model.DigestRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalEncryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalEncryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalSignRequest;
@@ -37,12 +39,14 @@ import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.HmacRequest;
import com.cisd.tms.integration.crypto.pcie.model.HmacResult;
import com.cisd.tms.integration.crypto.pcie.model.FirmwareInfoResult;
import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairEccRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskEccRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.IkSignRequest;
import com.cisd.tms.integration.crypto.pcie.model.IkVerifyRequest;
import com.cisd.tms.integration.crypto.pcie.model.KekComponentRequest;
import com.cisd.tms.integration.crypto.pcie.model.KeyStatusResult;
import com.cisd.tms.integration.crypto.pcie.model.LoginStatusResult;
@@ -297,15 +301,6 @@ public class MockPcieCryptoService implements PcieCryptoService {
requireNonEmptyBytes("envelopedKeyBlob", req.getEnvelopedKeyBlob());
}
@Override
public void importEncryptedKeyPairRsa(ImportEncKeyPairRsaRequest request) {
ImportEncKeyPairRsaRequest req = requireRequest("request", request);
requireNonNegative("keyIndex", req.getKeyIndex());
requirePositive("symAlgId", req.getSymAlgId());
requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
requireNonEmptyBytes("encryptedData", req.getEncryptedData());
}
@Override
public BackupDataResult updateBackedKey(UpdateBackedKeyRequest request) {
UpdateBackedKeyRequest req = requireRequest("request", request);
@@ -342,6 +337,19 @@ public class MockPcieCryptoService implements PcieCryptoService {
return mockBackup(size, 0x44);
}
@Override
public BackupDataResult exportIkPublicKey(int keyType, int outBufferSize) {
requireNonNegative("keyType", keyType);
int size = requirePositive("outBufferSize", outBufferSize);
return mockBackup(size, 0x45);
}
@Override
public BackupDataResult exportIkMac(int keyType) {
requireNonNegative("keyType", keyType);
return mockBackup(8, 0x46);
}
@Override
public StandardKeyPairResult generateStandardRsaKeyPair(GenerateStandardRsaKeyPairRequest request) {
GenerateStandardRsaKeyPairRequest req = requireRequest("request", request);
@@ -540,6 +548,15 @@ public class MockPcieCryptoService implements PcieCryptoService {
return mockBackup(size, 0x49);
}
@Override
public BackupDataResult signIk(IkSignRequest request) {
IkSignRequest req = requireRequest("request", request);
requireNonNegative("keyType", req.getKeyType());
requireBytes("data", req.getData());
int size = requirePositive("signatureBufferSize", req.getSignatureBufferSize());
return mockBackup(size, 0x5A);
}
@Override
public BackupDataResult eccExternalSign(EccExternalSignRequest request) {
EccExternalSignRequest req = requireRequest("request", request);
@@ -558,6 +575,14 @@ public class MockPcieCryptoService implements PcieCryptoService {
requireNonEmptyBytes("signature", req.getSignature());
}
@Override
public void verifyIk(IkVerifyRequest request) {
IkVerifyRequest req = requireRequest("request", request);
requireNonNegative("keyType", req.getKeyType());
requireBytes("data", req.getData());
requireNonEmptyBytes("signature", req.getSignature());
}
@Override
public void eccExternalVerify(EccExternalVerifyRequest request) {
EccExternalVerifyRequest req = requireRequest("request", request);
@@ -637,6 +662,67 @@ public class MockPcieCryptoService implements PcieCryptoService {
return mockBackup(size, 0x77);
}
@Override
public FirmwareInfoResult getFirmwareInfo() {
FirmwareInfoResult result = new FirmwareInfoResult();
result.setBomInfo(new byte[5]);
result.setGd32Info(new byte[5]);
result.setN32s033Info(new byte[5]);
return result;
}
@Override
public void sdfeHashCopy() {
// no-op
}
@Override
public BackupDataResult sdfeEncrypt(SymmetricCryptoRequest request) {
SymmetricCryptoRequest req = requireRequest("request", request);
requirePositive("algId", req.getAlgId());
requireNonEmptyBytes("key", req.getKey());
requireBytes("data", req.getData());
int size = requirePositive("outBufferSize", req.getOutBufferSize());
return mockBackup(size, 0x72);
}
@Override
public BackupDataResult sdfeDecrypt(SymmetricCryptoRequest request) {
SymmetricCryptoRequest req = requireRequest("request", request);
requirePositive("algId", req.getAlgId());
requireNonEmptyBytes("key", req.getKey());
requireBytes("data", req.getData());
int size = requirePositive("outBufferSize", req.getOutBufferSize());
return mockBackup(size, 0x73);
}
@Override
public BackupDataResult sdfeHash(DigestRequest request) {
DigestRequest req = requireRequest("request", request);
requirePositive("algId", req.getAlgId());
requireBytes("data", req.getData());
int size = requirePositive("outBufferSize", req.getOutBufferSize());
return mockBackup(size, 0x74);
}
@Override
public BackupDataResult sdfeInternalEncryptEcc(EccInternalEncryptRequest request) {
EccInternalEncryptRequest req = requireRequest("request", request);
requireNonNegative("keyIndex", req.getKeyIndex());
requireBytes("data", req.getData());
int size = requirePositive("outBufferSize", req.getOutBufferSize());
return mockBackup(size, 0x75);
}
@Override
public BackupDataResult sdfeInternalDecryptEcc(EccInternalDecryptRequest request) {
EccInternalDecryptRequest req = requireRequest("request", request);
requireNonNegative("keyIndex", req.getKeyIndex());
requireNonEmptyBytes("cipherBlob", req.getCipherBlob());
int size = requirePositive("outBufferSize", req.getOutBufferSize());
return mockBackup(size, 0x76);
}
@Override
public HmacResult hmac(HmacRequest request) {
HmacRequest req = requireRequest("request", request);
@@ -710,7 +796,7 @@ public class MockPcieCryptoService implements PcieCryptoService {
@Override
public BackupDataResult backupIkComponent(int keyType) {
requireNonNegative("keyType", keyType);
return mockBackup(new com.cisd.tms.integration.crypto.pcie.jna.SydIkComponent().size(), keyType);
return mockBackup(new com.cisd.tms.integration.crypto.pcie.jna.SdfeIkComponent().size(), keyType);
}
@Override
@@ -8,6 +8,8 @@ import com.cisd.tms.integration.crypto.pcie.model.DeviceCountResult;
import com.cisd.tms.integration.crypto.pcie.model.DeviceInfoResult;
import com.cisd.tms.integration.crypto.pcie.model.DeviceStatusResult;
import com.cisd.tms.integration.crypto.pcie.model.DigestRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalEncryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalEncryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalSignRequest;
@@ -34,12 +36,14 @@ import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.HmacRequest;
import com.cisd.tms.integration.crypto.pcie.model.HmacResult;
import com.cisd.tms.integration.crypto.pcie.model.FirmwareInfoResult;
import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairEccRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskEccRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.IkSignRequest;
import com.cisd.tms.integration.crypto.pcie.model.IkVerifyRequest;
import com.cisd.tms.integration.crypto.pcie.model.KekComponentRequest;
import com.cisd.tms.integration.crypto.pcie.model.KeyStatusResult;
import com.cisd.tms.integration.crypto.pcie.model.LoginStatusResult;
@@ -59,199 +63,580 @@ import com.cisd.tms.integration.crypto.pcie.model.UkeyPinChangeRequest;
import com.cisd.tms.integration.crypto.pcie.model.UkeyUnlockRequest;
import com.cisd.tms.integration.crypto.pcie.model.UpdateBackedKeyRequest;
/**
* PCIe 密码卡强类型服务接口。
*
* <p>该接口面向上层业务和控制器,屏蔽底层 JNA/native 指针细节,
* 统一暴露设备管理、密钥管理、算法运算、LMK/IK 生命周期、
* UKey 操作以及文件管理等能力。</p>
*/
public interface PcieCryptoService {
//----------------------------------------设备信息与初始化类接口-----------------------------------------
/**
* 查询当前环境可见的密码卡设备数量和正常设备数量。
*/
DeviceCountResult getDeviceCount();
/**
* 读取密码卡配置信息快照。
*/
DeviceConfResult getDeviceConf();
/**
* 读取密码卡基础设备信息。
*/
DeviceInfoResult getDeviceInfo();
/**
* 生成指定长度的随机数。
*
* @param length 随机数字节长度
*/
byte[] generateRandom(int length);
/**
* 执行密码卡初始化识别流程,通常用于设置或切换初始化 PIN。
*
* @param oldPin 旧 PIN
* @param newPin 新 PIN
*/
void initIdentify(byte[] oldPin, byte[] newPin);
/**
* 初始化主密钥体系,通常包含 LMK、IK 和用户密钥初始化。
*
* @param oldPin 旧 PIN
* @param newPin 新 PIN
* @return LMK seed MAC
*/
byte[] initializeMasterKey(byte[] oldPin, byte[] newPin);
/**
* 触发设备自检。
*/
void deviceSelfTest();
/**
* 获取设备运行状态详情。
*/
DeviceStatusResult getDeviceStatus();
/**
* 执行设备恢复出厂设置。
*/
void deviceFactoryReset();
//----------------------------------------私钥访问控制类接口------------------------------------------
/**
* 修改指定私钥索引的访问口令。
*/
void changePrivateKeyAccessPassword(ChangePrivateKeyPasswordRequest request);
/**
* 获取指定私钥索引的访问权限。
*/
void getPrivateKeyAccessRight(PrivateKeyAccessRequest request);
/**
* 释放指定私钥索引的访问权限。
*/
void releasePrivateKeyAccessRight(int keyIndex);
//----------------------------------------用户密钥与 KEK 管理类接口------------------------------------------
/**
* 在设备内部生成 ECC 用户密钥对。
*/
void generateKeyPairEcc(GenerateKeyPairRequest request);
/**
* 在设备内部生成 RSA 用户密钥对。
*/
void generateKeyPairRsa(GenerateKeyPairRequest request);
/**
* 导入 ECC 用户密钥对。
*/
void importKeyPairEcc(ImportKeyPairRequest request);
/**
* 导入 RSA 用户密钥对。
*/
void importKeyPairRsa(ImportKeyPairRequest request);
/**
* 生成 KEK。
*/
void generateKek(GenerateKekRequest request);
/**
* 导入 KEK 明文。
*/
void importKek(ImportKekRequest request);
/**
* 导入 KEK 分量。
*/
void importKekComponent(KekComponentRequest request);
/**
* 导出 KEK 分量。
*/
BackupDataResult exportKekComponent(ExportKekComponentRequest request);
/**
* 备份指定用户密钥。
*/
BackupDataResult backupUserKey(int keyIndex, int keyType, int outBufferSize);
/**
* 恢复指定用户密钥。
*/
void recoverUserKey(RecoverUserKeyRequest request);
/**
* 备份指定 KEK。
*/
BackupDataResult backupKek(int keyIndex, int outBufferSize);
/**
* 恢复指定 KEK。
*/
void recoverKek(RecoverKekRequest request);
/**
* 删除指定用户密钥。
*/
void deleteUserKey(int keyIndex);
/**
* 删除指定 KEK。
*/
void deleteKek(int keyIndex);
/**
* 备份整卡全部密钥数据。
*/
BackupDataResult backupAllKey(int outBufferSize);
/**
* 使用整卡备份数据恢复全部密钥。
*/
void restoreAllKey(byte[] keyImage);
/**
* 查询 ECC 用户密钥状态。
*/
KeyStatusResult statusUserKeyEcc(int keyIndex, int keyType);
/**
* 查询 RSA 用户密钥状态。
*/
KeyStatusResult statusUserKeyRsa(int keyIndex, int keyType);
/**
* 查询 KEK 状态。
*/
KeyStatusResult statusKek(int keyIndex);
/**
* 导入加密封装的 ECC 密钥对。
*/
void importEncryptedKeyPairEcc(ImportEncKeyPairEccRequest request);
void importEncryptedKeyPairRsa(ImportEncKeyPairRsaRequest request);
/**
* 更新旧备份数据,返回新备份数据。
*/
BackupDataResult updateBackedKey(UpdateBackedKeyRequest request);
//----------------------------------------公钥导出与标准密钥对类接口------------------------------------------
/**
* 导出 RSA 签名公钥。
*/
BackupDataResult exportSignPublicKeyRsa(int keyIndex, int outBufferSize);
/**
* 导出 RSA 加密公钥。
*/
BackupDataResult exportEncPublicKeyRsa(int keyIndex, int outBufferSize);
/**
* 导出 ECC 签名公钥。
*/
BackupDataResult exportSignPublicKeyEcc(int keyIndex, int outBufferSize);
/**
* 导出 ECC 加密公钥。
*/
BackupDataResult exportEncPublicKeyEcc(int keyIndex, int outBufferSize);
/**
* 生成标准 RSA 密钥对并导出结果。
*/
StandardKeyPairResult generateStandardRsaKeyPair(GenerateStandardRsaKeyPairRequest request);
/**
* 生成标准 ECC 密钥对并导出结果。
*/
StandardKeyPairResult generateStandardEccKeyPair(GenerateStandardEccKeyPairRequest request);
//----------------------------------------会话密钥与数字信封类接口------------------------------------------
/**
* 使用指定 KEK 生成会话密钥并导出包裹结果。
*/
BackupDataResult generateKeyWithKek(GenerateKeyWithKekRequest request);
/**
* 执行 RSA 外部公钥运算。
*/
BackupDataResult rsaExternalPublicKeyOperation(RsaExternalPublicKeyOpRequest request);
/**
* 执行 RSA 外部私钥运算。
*/
BackupDataResult rsaExternalPrivateKeyOperation(RsaExternalPrivateKeyOpRequest request);
/**
* 执行 RSA 内部公钥运算。
*/
BackupDataResult rsaInternalPublicKeyOperation(RsaInternalKeyOpRequest request);
/**
* 执行 RSA 内部私钥运算。
*/
BackupDataResult rsaInternalPrivateKeyOperation(RsaInternalKeyOpRequest request);
/**
* 使用内部 RSA 公钥生成会话密钥。
*/
BackupDataResult generateKeyWithIpkRsa(GenerateKeyWithIpkRsaRequest request);
/**
* 使用外部 RSA 公钥生成会话密钥。
*/
BackupDataResult generateKeyWithEpkRsa(GenerateKeyWithEpkRsaRequest request);
/**
* 使用内部 RSA 私钥导入会话密钥。
*/
void importKeyWithIskRsa(ImportKeyWithIskRsaRequest request);
/**
* 使用内部 ECC 公钥生成会话密钥。
*/
BackupDataResult generateKeyWithIpkEcc(GenerateKeyWithIpkEccRequest request);
/**
* 使用外部 ECC 公钥生成会话密钥。
*/
BackupDataResult generateKeyWithEpkEcc(GenerateKeyWithEpkEccRequest request);
/**
* 使用内部 ECC 私钥导入会话密钥。
*/
void importKeyWithIskEcc(ImportKeyWithIskEccRequest request);
/**
* 执行基于 RSA 的数字信封交换。
*/
BackupDataResult exchangeDigitEnvelopeBaseOnRsa(ExchangeDigitEnvelopeRsaRequest request);
/**
* 执行基于 ECC 的数字信封交换。
*/
BackupDataResult exchangeDigitEnvelopeBaseOnEcc(ExchangeDigitEnvelopeEccRequest request);
/**
* 生成 ECC 协商所需公钥材料并返回会话密钥。
*/
AgreementDataAndKeyEccResult generateAgreementDataAndKeyWithEcc(GenerateAgreementDataAndKeyEccRequest request);
/**
* 基于既有 ECC 协商材料生成会话密钥。
*/
EccAgreementSessionKeyResult generateSessionKeyWithEccAgreement(EccAgreementSessionKeyRequest request);
//----------------------------------------SDF通用算法运算类接口------------------------------------------
/**
* 使用通用内部 ECC 密钥执行签名。
*/
BackupDataResult eccInternalSign(EccInternalSignRequest request);
/**
* 使用外部 ECC 私钥执行签名。
*/
BackupDataResult eccExternalSign(EccExternalSignRequest request);
/**
* 使用通用内部 ECC 密钥执行验签。
*/
void eccInternalVerify(EccInternalVerifyRequest request);
/**
* 使用外部 ECC 公钥执行验签。
*/
void eccExternalVerify(EccExternalVerifyRequest request);
/**
* 使用外部 ECC 公钥执行加密。
*/
BackupDataResult eccExternalEncrypt(EccExternalEncryptRequest request);
/**
* 使用外部 ECC 私钥执行解密。
*/
BackupDataResult eccExternalDecrypt(EccExternalDecryptRequest request);
/**
* 使用明文对称密钥执行加密。
*/
BackupDataResult encryptWithPlainKey(SymmetricCryptoRequest request);
/**
* 使用明文对称密钥执行解密。
*/
BackupDataResult decryptWithPlainKey(SymmetricCryptoRequest request);
/**
* 使用 KEK 包裹密钥执行加密。
*/
BackupDataResult encryptWithKekWrappedKey(SymmetricKekCryptoRequest request);
/**
* 使用 KEK 包裹密钥执行解密。
*/
BackupDataResult decryptWithKekWrappedKey(SymmetricKekCryptoRequest request);
/**
* 使用明文对称密钥计算 MAC。
*/
BackupDataResult calculateMacWithPlainKey(MacCalcRequest request);
/**
* 使用通用 SDF 摘要流程计算杂凑。
*/
BackupDataResult digest(DigestRequest request);
//----------------------------------------SD FE 专用算法扩展接口------------------------------------------
/**
* 读取固件版本信息。
*/
FirmwareInfoResult getFirmwareInfo();
/**
* 复制两个会话之间的 SD FE Hash 状态。
*/
void sdfeHashCopy();
/**
* 使用 SD FE 明文对称密钥接口执行加密。
*/
BackupDataResult sdfeEncrypt(SymmetricCryptoRequest request);
/**
* 使用 SD FE 明文对称密钥接口执行解密。
*/
BackupDataResult sdfeDecrypt(SymmetricCryptoRequest request);
/**
* 使用 SD FE 单包摘要接口执行杂凑。
*/
BackupDataResult sdfeHash(DigestRequest request);
/**
* 使用内部 ECC 用户密钥执行加密。
*/
BackupDataResult sdfeInternalEncryptEcc(EccInternalEncryptRequest request);
/**
* 使用内部 ECC 用户密钥执行解密。
*/
BackupDataResult sdfeInternalDecryptEcc(EccInternalDecryptRequest request);
/**
* 使用 SD FE HMAC 流程计算 HMAC。
*/
HmacResult hmac(HmacRequest request);
//----------------------------------------LMK 生命周期类接口------------------------------------------
/**
* 生成 LMK。
*/
void generateLmk();
/**
* 加载 LMK。
*/
void loadLmk();
/**
* 备份 LMK。
*/
void backupLmk();
/**
* 恢复 LMK。
*/
void recoverLmk();
/**
* 销毁 LMK。
*/
void destroyLmk();
/**
* 检查 LMK 是否存在且可用。
*/
boolean checkLmk();
/**
* 导出 LMK seed MAC。
*/
byte[] exportLmkSeedMac();
/**
* 导出 LMK 分量扩展备份数据。
*/
BackupDataResult backupLmkEx();
/**
* 使用扩展备份数据恢复 LMK。
*/
void recoverLmkEx(byte[] lmkComponent);
//----------------------------------------IK 生命周期类接口。------------------------------------------
/**
* 生成 IK。
*/
void generateIk(int keyType);
/**
* 导出 IK 公钥。
*/
BackupDataResult exportIkPublicKey(int keyType, int outBufferSize);
/**
* 导出 IK 校验值。
*/
BackupDataResult exportIkMac(int keyType);
/**
* 使用 IK 执行专用签名。
*/
BackupDataResult signIk(IkSignRequest request);
/**
* 使用 IK 执行专用验签。
*/
void verifyIk(IkVerifyRequest request);
/**
* 导出 IK 分量扩展备份数据。
*/
BackupDataResult backupIkComponent(int keyType);
/**
* 使用扩展备份数据恢复 IK。
*/
void recoverIkComponent(int keyType, byte[] ikComponent);
/**
* 触发 IK 设备内备份。
*/
void backupIk(int keyType);
/**
* 触发 IK 设备内恢复。
*/
void recoverIk(int keyType);
/**
* 销毁 IK。
*/
void destroyIk(int keyType);
/**
* 查询 IK 状态。
*/
KeyStatusResult statusIk(int keyType);
//----------------------------------------UKey 管理类接口-------------------------------------------
/**
* 生成 UKey 管理员。
*/
void generateUkey(UkeyGenerateRequest request);
/**
* 登录 UKey。
*/
void loginUkey(UkeyLoginRequest request);
/**
* 修改 UKey PIN。
*/
void changeUkeyPin(UkeyPinChangeRequest request);
/**
* 解锁 UKey。
*/
void unlockUkey(UkeyUnlockRequest request);
/**
* 从 UKey 读取 LMK 分量到设备运行态。
*/
void readLmkComponent(byte[] ukeyPin);
/**
* 从 UKey 读取 IK 分量到设备运行态。
*/
void readUkeyIkComponent(int keyType, byte[] ukeyPin);
/**
* 为 UKey 生成证书。
*/
void generateCertificate(byte[] ukeyPin);
/**
* 注销指定管理员索引的 UKey 登录态。
*/
void logoutAdmin(int adminIndex);
/**
* 查询 UKey 登录状态。
*/
LoginStatusResult loginStatus();
/**
* 设备文件系统类接口。
*/
/**
* 在设备文件系统中创建文件。
*/
void createFile(FileCreateRequest request);
/**
* 向设备文件系统写入文件内容。
*/
void writeFile(FileWriteRequest request);
/**
* 从设备文件系统读取文件内容。
*/
BackupDataResult readFile(FileReadRequest request);
/**
* 删除设备文件系统中的文件。
*/
void deleteFile(String fileName);
}
@@ -598,15 +598,6 @@ public class CryptoCardController {
return ApiResponse.success();
}
@PostMapping("/keypair/rsa/import-encrypted")
@Operation(summary = "导入加密 RSA 密钥对", description = "导入包裹密钥保护的 RSA 密钥对数据。")
public ApiResponse<Void> importEncryptedKeyPairRsa(
@Valid @RequestBody CryptoImportEncryptedKeyPairRsaInternalRequest request
) {
pcieCryptoService.importEncryptedKeyPairRsa(toImportEncryptedKeyPairRsaRequest(request));
return ApiResponse.success();
}
@PostMapping("/keys/update-backed")
@Operation(summary = "更新备份数据", description = "更新旧备份结构并返回新的备份数据 HEX。")
public ApiResponse<Map<String, Object>> updateBackedKey(
@@ -1,51 +0,0 @@
package com.cisd.tms.modules.device.dto.crypto.request;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
public class CryptoImportEncryptedKeyPairRsaInternalRequest {
@Min(0)
private int keyIndex;
@Min(1)
private int symAlgId;
@NotBlank
private String wrappedKeyBase64;
@NotBlank
private String encryptedDataBase64;
public int getKeyIndex() {
return keyIndex;
}
public void setKeyIndex(int keyIndex) {
this.keyIndex = keyIndex;
}
public int getSymAlgId() {
return symAlgId;
}
public void setSymAlgId(int symAlgId) {
this.symAlgId = symAlgId;
}
public String getWrappedKeyBase64() {
return wrappedKeyBase64;
}
public void setWrappedKeyBase64(String wrappedKeyBase64) {
this.wrappedKeyBase64 = wrappedKeyBase64;
}
public String getEncryptedDataBase64() {
return encryptedDataBase64;
}
public void setEncryptedDataBase64(String encryptedDataBase64) {
this.encryptedDataBase64 = encryptedDataBase64;
}
}
@@ -3,7 +3,6 @@ package com.cisd.tms.modules.device.support.crypto;
import com.cisd.tms.integration.crypto.pcie.model.ChangePrivateKeyPasswordRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairEccRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.KekComponentRequest;
@@ -20,7 +19,6 @@ import com.cisd.tms.integration.crypto.pcie.model.UpdateBackedKeyRequest;
import com.cisd.tms.modules.device.dto.crypto.request.CryptoChangePrivateKeyPasswordInternalRequest;
import com.cisd.tms.modules.device.dto.crypto.request.CryptoGenerateKeyPairInternalRequest;
import com.cisd.tms.modules.device.dto.crypto.request.CryptoImportEncryptedKeyPairEccInternalRequest;
import com.cisd.tms.modules.device.dto.crypto.request.CryptoImportEncryptedKeyPairRsaInternalRequest;
import com.cisd.tms.modules.device.dto.crypto.request.CryptoImportKekInternalRequest;
import com.cisd.tms.modules.device.dto.crypto.request.CryptoImportKeyPairInternalRequest;
import com.cisd.tms.modules.device.dto.crypto.request.CryptoKekComponentImportInternalRequest;
@@ -131,15 +129,6 @@ public final class CryptoRequestMapper {
return req;
}
public static ImportEncKeyPairRsaRequest toImportEncryptedKeyPairRsaRequest(CryptoImportEncryptedKeyPairRsaInternalRequest request) {
ImportEncKeyPairRsaRequest req = new ImportEncKeyPairRsaRequest();
req.setKeyIndex(request.getKeyIndex());
req.setSymAlgId(request.getSymAlgId());
req.setWrappedKey(CryptoPayloadCodec.decodeBase64(request.getWrappedKeyBase64()));
req.setEncryptedData(CryptoPayloadCodec.decodeBase64(request.getEncryptedDataBase64()));
return req;
}
public static UpdateBackedKeyRequest toUpdateBackedKeyRequest(CryptoUpdateBackedKeyInternalRequest request) {
UpdateBackedKeyRequest req = new UpdateBackedKeyRequest();
req.setOldData(CryptoPayloadCodec.decodeBase64(request.getOldDataBase64()));
@@ -35,6 +35,7 @@ public class LmkController {
@PostMapping("/masterKey/destroy")
@Operation(summary = "销毁主密钥", description = "销毁当前密码卡中的主密钥,失败直接抛出异常。")
public ApiResponse<Void> destroyMasterKey() {
//销毁主密钥、内部密钥、用户密钥
lmkService.destroyMasterKey();
return ApiResponse.success();
}
@@ -5,14 +5,22 @@ public class MasterKeyPacketIkPart {
private int keyType;
private String mac;
private String component;
private String publicKey;
private String publicKeyMac;
public MasterKeyPacketIkPart() {
}
public MasterKeyPacketIkPart(int keyType, String mac, String component) {
this(keyType, mac, component, null, null);
}
public MasterKeyPacketIkPart(int keyType, String mac, String component, String publicKey, String publicKeyMac) {
this.keyType = keyType;
this.mac = mac;
this.component = component;
this.publicKey = publicKey;
this.publicKeyMac = publicKeyMac;
}
public int getKeyType() {
@@ -38,4 +46,20 @@ public class MasterKeyPacketIkPart {
public void setComponent(String component) {
this.component = component;
}
public String getPublicKey() {
return publicKey;
}
public void setPublicKey(String publicKey) {
this.publicKey = publicKey;
}
public String getPublicKeyMac() {
return publicKeyMac;
}
public void setPublicKeyMac(String publicKeyMac) {
this.publicKeyMac = publicKeyMac;
}
}
@@ -6,8 +6,8 @@ import com.cisd.tms.integration.crypto.pcie.jna.EccRefPublicKey;
import com.cisd.tms.integration.crypto.pcie.jna.EccSignature;
import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult;
import com.cisd.tms.integration.crypto.pcie.model.DigestRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalSignRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalVerifyRequest;
import com.cisd.tms.integration.crypto.pcie.model.IkSignRequest;
import com.cisd.tms.integration.crypto.pcie.model.IkVerifyRequest;
import com.cisd.tms.integration.crypto.pcie.model.RecoverUserKeyRequest;
import com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService;
import com.cisd.tms.modules.mk.common.LMKConstant;
@@ -45,6 +45,10 @@ public class LmkServiceImpl implements LmkService {
private static final int LMK_MAC_BYTE_LENGTH = 8;
private static final int IK_COMPONENT_MAC_BYTE_LENGTH = 8;
private static final int IK_COMPONENT_DATA_LENGTH = 3 * 64;
private static final int IK_PUBLIC_KEY_BYTE_LENGTH = new EccRefPublicKey().size();
private static final int IK_PUBLIC_KEY_MAC_BYTE_LENGTH = 8;
private static final int IK_COMPONENT_TOTAL_BYTE_LENGTH =
IK_COMPONENT_DATA_LENGTH + IK_COMPONENT_MAC_BYTE_LENGTH + IK_PUBLIC_KEY_BYTE_LENGTH + IK_PUBLIC_KEY_MAC_BYTE_LENGTH;
private static final int USER_KEY_INDEX = 1;
private static final int USER_KEY_TYPE_SIGN = 0;
private static final int USER_KEY_TYPE_ENC = 1;
@@ -83,29 +87,29 @@ public class LmkServiceImpl implements LmkService {
@Override
public String exportIkPublicKeyHex() {
int outBufferSize = new EccRefPublicKey().size();
BackupDataResult result = pcieCryptoService.exportSignPublicKeyEcc(AUTH_SIGN_KEY_INDEX, outBufferSize);
BackupDataResult result = pcieCryptoService.exportIkPublicKey(AUTH_SIGN_KEY_INDEX, outBufferSize);
return Hex.toHexString(result.getData());
}
@Override
public String signIk(String rawData) {
byte[] digest = digestForInternalSign(rawData);
EccInternalSignRequest request = new EccInternalSignRequest();
request.setKeyIndex(AUTH_SIGN_KEY_INDEX);
IkSignRequest request = new IkSignRequest();
request.setKeyType(AUTH_SIGN_KEY_INDEX);
request.setData(digest);
request.setSignatureBufferSize(new EccSignature().size());
BackupDataResult result = pcieCryptoService.eccInternalSign(request);
BackupDataResult result = pcieCryptoService.signIk(request);
return Hex.toHexString(result.getData());
}
@Override
public void verifyIk(String rawData, String signatureHex) {
byte[] digest = digestForInternalSign(rawData);
EccInternalVerifyRequest request = new EccInternalVerifyRequest();
request.setKeyIndex(AUTH_SIGN_KEY_INDEX);
IkVerifyRequest request = new IkVerifyRequest();
request.setKeyType(AUTH_SIGN_KEY_INDEX);
request.setData(digest);
request.setSignature(Hex.decode(signatureHex));
pcieCryptoService.eccInternalVerify(request);
pcieCryptoService.verifyIk(request);
}
@Override
@@ -124,12 +128,16 @@ public class LmkServiceImpl implements LmkService {
packet.setIkAuth(new MasterKeyPacketIkPart(
IKEnums.KEY_TYPE_AUTH.getCode(),
authIkBackup.macHex(),
requiredComponent(authIkBackup.componentMap(), index, "ikAuth")
requiredComponent(authIkBackup.componentMap(), index, "ikAuth"),
authIkBackup.publicKeyHex(),
authIkBackup.publicKeyMacHex()
));
packet.setIkDevice(new MasterKeyPacketIkPart(
IKEnums.KEY_TYPE_DEVICE.getCode(),
deviceIkBackup.macHex(),
requiredComponent(deviceIkBackup.componentMap(), index, "ikDevice")
requiredComponent(deviceIkBackup.componentMap(), index, "ikDevice"),
deviceIkBackup.publicKeyHex(),
deviceIkBackup.publicKeyMacHex()
));
packet.setUserKeys(List.of(
buildUserKeyPacket(USER_KEY_INDEX, USER_KEY_TYPE_SIGN, index),
@@ -215,6 +223,8 @@ public class LmkServiceImpl implements LmkService {
private String composeIkHex(List<MasterKeyBackupPacket> packets, boolean authKey) {
int keyType = authKey ? IKEnums.KEY_TYPE_AUTH.getCode() : IKEnums.KEY_TYPE_DEVICE.getCode();
String mac = requireConsistentIkMac(packets, keyType);
String publicKey = requireConsistentIkPublicKey(packets, keyType);
String publicKeyMac = requireConsistentIkPublicKeyMac(packets, keyType);
StringBuilder builder = new StringBuilder();
for (MasterKeyBackupPacket packet : packets) {
MasterKeyPacketIkPart part = authKey ? packet.getIkAuth() : packet.getIkDevice();
@@ -223,7 +233,7 @@ public class LmkServiceImpl implements LmkService {
}
builder.append(part.getComponent());
}
builder.append(mac);
builder.append(mac).append(publicKey).append(publicKeyMac);
return builder.toString();
}
@@ -263,17 +273,27 @@ public class LmkServiceImpl implements LmkService {
private ParsedIkBackup parseIkBackupMaterial(int keyType) {
BackupDataResult backupData = pcieCryptoService.backupIkComponent(keyType);
byte[] normalized = normalizeBackupData(backupData);
if (normalized.length < IK_COMPONENT_DATA_LENGTH + IK_COMPONENT_MAC_BYTE_LENGTH) {
if (normalized.length < IK_COMPONENT_TOTAL_BYTE_LENGTH) {
throw new IllegalStateException("backup ik data length is too short: " + normalized.length);
}
byte[] componentBytes = Arrays.copyOfRange(normalized, 0, IK_COMPONENT_DATA_LENGTH);
byte[] mac = Arrays.copyOfRange(normalized, IK_COMPONENT_DATA_LENGTH, IK_COMPONENT_DATA_LENGTH + IK_COMPONENT_MAC_BYTE_LENGTH);
byte[] publicKey = Arrays.copyOfRange(
normalized,
IK_COMPONENT_DATA_LENGTH + IK_COMPONENT_MAC_BYTE_LENGTH,
IK_COMPONENT_DATA_LENGTH + IK_COMPONENT_MAC_BYTE_LENGTH + IK_PUBLIC_KEY_BYTE_LENGTH
);
byte[] publicKeyMac = Arrays.copyOfRange(
normalized,
IK_COMPONENT_DATA_LENGTH + IK_COMPONENT_MAC_BYTE_LENGTH + IK_PUBLIC_KEY_BYTE_LENGTH,
IK_COMPONENT_DATA_LENGTH + IK_COMPONENT_MAC_BYTE_LENGTH + IK_PUBLIC_KEY_BYTE_LENGTH + IK_PUBLIC_KEY_MAC_BYTE_LENGTH
);
String[] splitComponents = DivisionUtils.equalDivision(Hex.toHexString(componentBytes), LMKConstant.COMPONENT_NUM);
Map<Integer, String> componentMap = new HashMap<>();
for (int i = 0; i < LMKConstant.COMPONENT_NUM; i++) {
componentMap.put(LMKConstant.KEY_ORDER[i], splitComponents[i]);
}
return new ParsedIkBackup(Hex.toHexString(mac), componentMap);
return new ParsedIkBackup(Hex.toHexString(mac), componentMap, Hex.toHexString(publicKey), Hex.toHexString(publicKeyMac));
}
private MasterKeyPacketUserKeyPart buildUserKeyPacket(int keyIndex, int keyType, int componentIndex) {
@@ -365,6 +385,42 @@ public class LmkServiceImpl implements LmkService {
return mac;
}
private String requireConsistentIkPublicKey(List<MasterKeyBackupPacket> packets, int keyType) {
String publicKey = null;
for (MasterKeyBackupPacket packet : packets) {
MasterKeyPacketIkPart part = keyType == IKEnums.KEY_TYPE_AUTH.getCode() ? packet.getIkAuth() : packet.getIkDevice();
if (part == null || part.getPublicKey() == null || part.getPublicKey().isBlank()) {
throw new IllegalArgumentException("ik publicKey missing");
}
if (publicKey == null) {
publicKey = part.getPublicKey();
continue;
}
if (!publicKey.equals(part.getPublicKey())) {
throw new IllegalArgumentException("ik publicKey is inconsistent");
}
}
return publicKey;
}
private String requireConsistentIkPublicKeyMac(List<MasterKeyBackupPacket> packets, int keyType) {
String publicKeyMac = null;
for (MasterKeyBackupPacket packet : packets) {
MasterKeyPacketIkPart part = keyType == IKEnums.KEY_TYPE_AUTH.getCode() ? packet.getIkAuth() : packet.getIkDevice();
if (part == null || part.getPublicKeyMac() == null || part.getPublicKeyMac().isBlank()) {
throw new IllegalArgumentException("ik publicKeyMac missing");
}
if (publicKeyMac == null) {
publicKeyMac = part.getPublicKeyMac();
continue;
}
if (!publicKeyMac.equals(part.getPublicKeyMac())) {
throw new IllegalArgumentException("ik publicKeyMac is inconsistent");
}
}
return publicKeyMac;
}
private MasterKeyPacketUserKeyPart findUserKeyPart(MasterKeyBackupPacket packet, int keyIndex, int keyType) {
return packet.getUserKeys().stream()
.filter(item -> item.getKeyIndex() == keyIndex && item.getKeyType() == keyType)
@@ -390,6 +446,6 @@ public class LmkServiceImpl implements LmkService {
private record ParsedMasterKeyBackup(String lmkMacHex, Map<Integer, String> componentMap) {
}
private record ParsedIkBackup(String macHex, Map<Integer, String> componentMap) {
private record ParsedIkBackup(String macHex, Map<Integer, String> componentMap, String publicKeyHex, String publicKeyMacHex) {
}
}