新增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); 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 static final Logger log = LoggerFactory.getLogger(PcieSessionTemplate.class);
private final CryptoCardProperties properties; 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) { public void ensureSuccess(String apiName, int retCode) {
if (retCode != 0) { if (retCode != 0) {
throw new PcieCryptoException(apiName, retCode, errorMapper.toMessage(retCode)); throw new PcieCryptoException(apiName, retCode, errorMapper.toMessage(retCode));
@@ -146,6 +172,16 @@ public class PcieSessionTemplate {
return sessionRef.getValue(); 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) { private void resetSharedDevice(PcieNativeLibrary lib) {
closeSharedDevice(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_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, int SDFE_UpdateBackedKey(Pointer hSessionHandle, byte[] oldData, int oldDataLength,
byte[] newData, IntByReference newDataLength); byte[] newData, IntByReference newDataLength);
@@ -231,6 +227,18 @@ public interface PcieNativeLibrary extends Library {
int SDFE_RecoverIK(Pointer hSessionHandle, int keyType); 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_DestroyIK(Pointer hSessionHandle, int keyType);
int SDFE_StatusIK(Pointer hSessionHandle, int keyType, IntByReference keyState); 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_HmacUpdate(Pointer hSessionHandle, byte[] data, int dataLength);
int SDFE_HmacFinal(Pointer hSessionHandle, byte[] hmac, IntByReference hmacLength); 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.RsaRefPrivateKey;
import com.cisd.tms.integration.crypto.pcie.jna.RsaRefPublicKey; 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.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.SdfeDeviceConf;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeDeviceStatus; 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.SdfeKekComponent;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeLmkComponent; 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.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.AgreementDataAndKeyEccResult;
import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult; import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult;
import com.cisd.tms.integration.crypto.pcie.model.ChangePrivateKeyPasswordRequest; 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.DeviceInfoResult;
import com.cisd.tms.integration.crypto.pcie.model.DeviceStatusResult; 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.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.EccExternalDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalEncryptRequest; import com.cisd.tms.integration.crypto.pcie.model.EccExternalEncryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalSignRequest; 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.GenerateKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.HmacRequest; 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.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.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.ImportKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskEccRequest; 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.ImportKeyWithIskRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyPairRequest; 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.KekComponentRequest;
import com.cisd.tms.integration.crypto.pcie.model.KeyStatusResult; import com.cisd.tms.integration.crypto.pcie.model.KeyStatusResult;
import com.cisd.tms.integration.crypto.pcie.model.LoginStatusResult; 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 @Override
public BackupDataResult updateBackedKey(UpdateBackedKeyRequest request) { public BackupDataResult updateBackedKey(UpdateBackedKeyRequest request) {
UpdateBackedKeyRequest req = requireRequest("request", 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 @Override
public StandardKeyPairResult generateStandardRsaKeyPair(GenerateStandardRsaKeyPairRequest request) { public StandardKeyPairResult generateStandardRsaKeyPair(GenerateStandardRsaKeyPairRequest request) {
GenerateStandardRsaKeyPairRequest req = requireRequest("request", 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 @Override
public BackupDataResult eccExternalSign(EccExternalSignRequest request) { public BackupDataResult eccExternalSign(EccExternalSignRequest request) {
EccExternalSignRequest req = requireRequest("request", 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 @Override
public void eccExternalVerify(EccExternalVerifyRequest request) { public void eccExternalVerify(EccExternalVerifyRequest request) {
EccExternalVerifyRequest req = requireRequest("request", 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 @Override
public HmacResult hmac(HmacRequest request) { public HmacResult hmac(HmacRequest request) {
HmacRequest req = requireRequest("request", request); HmacRequest req = requireRequest("request", request);
@@ -1693,22 +1866,21 @@ public class JnaPcieCryptoService implements PcieCryptoService {
public BackupDataResult backupIkComponent(int keyType) { public BackupDataResult backupIkComponent(int keyType) {
int safeKeyType = requireNonNegative("keyType", keyType); int safeKeyType = requireNonNegative("keyType", keyType);
//todo 对接真实接口 return sessionTemplate.withSession("SDFE_BackupIK_EX", (lib, deviceHandle, sessionHandle) -> {
return sessionTemplate.withSession("SYD_IK_BackUp", (lib, deviceHandle, sessionHandle) -> { SdfeIkComponent output = new SdfeIkComponent();
SydIkComponent output = new SydIkComponent(); sessionTemplate.ensureSuccess("SDFE_BackupIK_EX", lib.SDFE_BackupIK_EX(sessionHandle, safeKeyType, output));
sessionTemplate.ensureSuccess("SYD_IK_BackUp", lib.SYD_IK_BackUp(deviceHandle, safeKeyType, 1, output));
byte[] outputBytes = toBytes(output); byte[] outputBytes = toBytes(output);
return toBackupResult("SYD_IK_BackUp", outputBytes, outputBytes.length); return toBackupResult("SDFE_BackupIK_EX", outputBytes, outputBytes.length);
}); });
} }
@Override @Override
public void recoverIkComponent(int keyType, byte[] ikComponent) { public void recoverIkComponent(int keyType, byte[] ikComponent) {
int safeKeyType = requireNonNegative("keyType", keyType); int safeKeyType = requireNonNegative("keyType", keyType);
SydIkComponent input = toSydIkComponent("ikComponent", ikComponent); SdfeIkComponent input = toSdfeIkComponent("ikComponent", ikComponent);
sessionTemplate.withSession("SYD_IK_Recover", (lib, deviceHandle, sessionHandle) -> { sessionTemplate.withSession("SDFE_RecoverIK_EX", (lib, deviceHandle, sessionHandle) -> {
sessionTemplate.ensureSuccess("SYD_IK_Recover", lib.SYD_IK_Recover(deviceHandle, safeKeyType, 1, input)); sessionTemplate.ensureSuccess("SDFE_RecoverIK_EX", lib.SDFE_RecoverIK_EX(sessionHandle, safeKeyType, input));
return null; return null;
}); });
} }
@@ -2163,8 +2335,8 @@ public class JnaPcieCryptoService implements PcieCryptoService {
return toStructure(name, value, new SdfeLmkComponent(), false); return toStructure(name, value, new SdfeLmkComponent(), false);
} }
private static SydIkComponent toSydIkComponent(String name, byte[] value) { private static SdfeIkComponent toSdfeIkComponent(String name, byte[] value) {
return toStructure(name, value, new SydIkComponent(), false); return toStructure(name, value, new SdfeIkComponent(), false);
} }
private static EnvelopedKeyBlob toEnvelopedKeyBlob(String name, byte[] value) { 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.DeviceInfoResult;
import com.cisd.tms.integration.crypto.pcie.model.DeviceStatusResult; 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.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.EccExternalDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalEncryptRequest; import com.cisd.tms.integration.crypto.pcie.model.EccExternalEncryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalSignRequest; 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.GenerateKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.HmacRequest; 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.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.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.ImportKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskEccRequest; 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.ImportKeyWithIskRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyPairRequest; 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.KekComponentRequest;
import com.cisd.tms.integration.crypto.pcie.model.KeyStatusResult; import com.cisd.tms.integration.crypto.pcie.model.KeyStatusResult;
import com.cisd.tms.integration.crypto.pcie.model.LoginStatusResult; import com.cisd.tms.integration.crypto.pcie.model.LoginStatusResult;
@@ -297,15 +301,6 @@ public class MockPcieCryptoService implements PcieCryptoService {
requireNonEmptyBytes("envelopedKeyBlob", req.getEnvelopedKeyBlob()); 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 @Override
public BackupDataResult updateBackedKey(UpdateBackedKeyRequest request) { public BackupDataResult updateBackedKey(UpdateBackedKeyRequest request) {
UpdateBackedKeyRequest req = requireRequest("request", request); UpdateBackedKeyRequest req = requireRequest("request", request);
@@ -342,6 +337,19 @@ public class MockPcieCryptoService implements PcieCryptoService {
return mockBackup(size, 0x44); 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 @Override
public StandardKeyPairResult generateStandardRsaKeyPair(GenerateStandardRsaKeyPairRequest request) { public StandardKeyPairResult generateStandardRsaKeyPair(GenerateStandardRsaKeyPairRequest request) {
GenerateStandardRsaKeyPairRequest req = requireRequest("request", request); GenerateStandardRsaKeyPairRequest req = requireRequest("request", request);
@@ -540,6 +548,15 @@ public class MockPcieCryptoService implements PcieCryptoService {
return mockBackup(size, 0x49); 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 @Override
public BackupDataResult eccExternalSign(EccExternalSignRequest request) { public BackupDataResult eccExternalSign(EccExternalSignRequest request) {
EccExternalSignRequest req = requireRequest("request", request); EccExternalSignRequest req = requireRequest("request", request);
@@ -558,6 +575,14 @@ public class MockPcieCryptoService implements PcieCryptoService {
requireNonEmptyBytes("signature", req.getSignature()); 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 @Override
public void eccExternalVerify(EccExternalVerifyRequest request) { public void eccExternalVerify(EccExternalVerifyRequest request) {
EccExternalVerifyRequest req = requireRequest("request", request); EccExternalVerifyRequest req = requireRequest("request", request);
@@ -637,6 +662,67 @@ public class MockPcieCryptoService implements PcieCryptoService {
return mockBackup(size, 0x77); 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 @Override
public HmacResult hmac(HmacRequest request) { public HmacResult hmac(HmacRequest request) {
HmacRequest req = requireRequest("request", request); HmacRequest req = requireRequest("request", request);
@@ -710,7 +796,7 @@ public class MockPcieCryptoService implements PcieCryptoService {
@Override @Override
public BackupDataResult backupIkComponent(int keyType) { public BackupDataResult backupIkComponent(int keyType) {
requireNonNegative("keyType", 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 @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.DeviceInfoResult;
import com.cisd.tms.integration.crypto.pcie.model.DeviceStatusResult; 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.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.EccExternalDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalEncryptRequest; import com.cisd.tms.integration.crypto.pcie.model.EccExternalEncryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalSignRequest; 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.GenerateKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.HmacRequest; 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.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.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.ImportKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskEccRequest; 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.ImportKeyWithIskRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyPairRequest; 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.KekComponentRequest;
import com.cisd.tms.integration.crypto.pcie.model.KeyStatusResult; import com.cisd.tms.integration.crypto.pcie.model.KeyStatusResult;
import com.cisd.tms.integration.crypto.pcie.model.LoginStatusResult; 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.UkeyUnlockRequest;
import com.cisd.tms.integration.crypto.pcie.model.UpdateBackedKeyRequest; import com.cisd.tms.integration.crypto.pcie.model.UpdateBackedKeyRequest;
/**
* PCIe 密码卡强类型服务接口。
*
* <p>该接口面向上层业务和控制器,屏蔽底层 JNA/native 指针细节,
* 统一暴露设备管理、密钥管理、算法运算、LMK/IK 生命周期、
* UKey 操作以及文件管理等能力。</p>
*/
public interface PcieCryptoService { public interface PcieCryptoService {
//----------------------------------------设备信息与初始化类接口-----------------------------------------
/**
* 查询当前环境可见的密码卡设备数量和正常设备数量。
*/
DeviceCountResult getDeviceCount(); DeviceCountResult getDeviceCount();
/**
* 读取密码卡配置信息快照。
*/
DeviceConfResult getDeviceConf(); DeviceConfResult getDeviceConf();
/**
* 读取密码卡基础设备信息。
*/
DeviceInfoResult getDeviceInfo(); DeviceInfoResult getDeviceInfo();
/**
* 生成指定长度的随机数。
*
* @param length 随机数字节长度
*/
byte[] generateRandom(int length); byte[] generateRandom(int length);
/**
* 执行密码卡初始化识别流程,通常用于设置或切换初始化 PIN。
*
* @param oldPin 旧 PIN
* @param newPin 新 PIN
*/
void initIdentify(byte[] oldPin, byte[] newPin); void initIdentify(byte[] oldPin, byte[] newPin);
/**
* 初始化主密钥体系,通常包含 LMK、IK 和用户密钥初始化。
*
* @param oldPin 旧 PIN
* @param newPin 新 PIN
* @return LMK seed MAC
*/
byte[] initializeMasterKey(byte[] oldPin, byte[] newPin); byte[] initializeMasterKey(byte[] oldPin, byte[] newPin);
/**
* 触发设备自检。
*/
void deviceSelfTest(); void deviceSelfTest();
/**
* 获取设备运行状态详情。
*/
DeviceStatusResult getDeviceStatus(); DeviceStatusResult getDeviceStatus();
/**
* 执行设备恢复出厂设置。
*/
void deviceFactoryReset(); void deviceFactoryReset();
//----------------------------------------私钥访问控制类接口------------------------------------------
/**
* 修改指定私钥索引的访问口令。
*/
void changePrivateKeyAccessPassword(ChangePrivateKeyPasswordRequest request); void changePrivateKeyAccessPassword(ChangePrivateKeyPasswordRequest request);
/**
* 获取指定私钥索引的访问权限。
*/
void getPrivateKeyAccessRight(PrivateKeyAccessRequest request); void getPrivateKeyAccessRight(PrivateKeyAccessRequest request);
/**
* 释放指定私钥索引的访问权限。
*/
void releasePrivateKeyAccessRight(int keyIndex); void releasePrivateKeyAccessRight(int keyIndex);
//----------------------------------------用户密钥与 KEK 管理类接口------------------------------------------
/**
* 在设备内部生成 ECC 用户密钥对。
*/
void generateKeyPairEcc(GenerateKeyPairRequest request); void generateKeyPairEcc(GenerateKeyPairRequest request);
/**
* 在设备内部生成 RSA 用户密钥对。
*/
void generateKeyPairRsa(GenerateKeyPairRequest request); void generateKeyPairRsa(GenerateKeyPairRequest request);
/**
* 导入 ECC 用户密钥对。
*/
void importKeyPairEcc(ImportKeyPairRequest request); void importKeyPairEcc(ImportKeyPairRequest request);
/**
* 导入 RSA 用户密钥对。
*/
void importKeyPairRsa(ImportKeyPairRequest request); void importKeyPairRsa(ImportKeyPairRequest request);
/**
* 生成 KEK。
*/
void generateKek(GenerateKekRequest request); void generateKek(GenerateKekRequest request);
/**
* 导入 KEK 明文。
*/
void importKek(ImportKekRequest request); void importKek(ImportKekRequest request);
/**
* 导入 KEK 分量。
*/
void importKekComponent(KekComponentRequest request); void importKekComponent(KekComponentRequest request);
/**
* 导出 KEK 分量。
*/
BackupDataResult exportKekComponent(ExportKekComponentRequest request); BackupDataResult exportKekComponent(ExportKekComponentRequest request);
/**
* 备份指定用户密钥。
*/
BackupDataResult backupUserKey(int keyIndex, int keyType, int outBufferSize); BackupDataResult backupUserKey(int keyIndex, int keyType, int outBufferSize);
/**
* 恢复指定用户密钥。
*/
void recoverUserKey(RecoverUserKeyRequest request); void recoverUserKey(RecoverUserKeyRequest request);
/**
* 备份指定 KEK。
*/
BackupDataResult backupKek(int keyIndex, int outBufferSize); BackupDataResult backupKek(int keyIndex, int outBufferSize);
/**
* 恢复指定 KEK。
*/
void recoverKek(RecoverKekRequest request); void recoverKek(RecoverKekRequest request);
/**
* 删除指定用户密钥。
*/
void deleteUserKey(int keyIndex); void deleteUserKey(int keyIndex);
/**
* 删除指定 KEK。
*/
void deleteKek(int keyIndex); void deleteKek(int keyIndex);
/**
* 备份整卡全部密钥数据。
*/
BackupDataResult backupAllKey(int outBufferSize); BackupDataResult backupAllKey(int outBufferSize);
/**
* 使用整卡备份数据恢复全部密钥。
*/
void restoreAllKey(byte[] keyImage); void restoreAllKey(byte[] keyImage);
/**
* 查询 ECC 用户密钥状态。
*/
KeyStatusResult statusUserKeyEcc(int keyIndex, int keyType); KeyStatusResult statusUserKeyEcc(int keyIndex, int keyType);
/**
* 查询 RSA 用户密钥状态。
*/
KeyStatusResult statusUserKeyRsa(int keyIndex, int keyType); KeyStatusResult statusUserKeyRsa(int keyIndex, int keyType);
/**
* 查询 KEK 状态。
*/
KeyStatusResult statusKek(int keyIndex); KeyStatusResult statusKek(int keyIndex);
/**
* 导入加密封装的 ECC 密钥对。
*/
void importEncryptedKeyPairEcc(ImportEncKeyPairEccRequest request); void importEncryptedKeyPairEcc(ImportEncKeyPairEccRequest request);
void importEncryptedKeyPairRsa(ImportEncKeyPairRsaRequest request); /**
* 更新旧备份数据,返回新备份数据。
*/
BackupDataResult updateBackedKey(UpdateBackedKeyRequest request); BackupDataResult updateBackedKey(UpdateBackedKeyRequest request);
//----------------------------------------公钥导出与标准密钥对类接口------------------------------------------
/**
* 导出 RSA 签名公钥。
*/
BackupDataResult exportSignPublicKeyRsa(int keyIndex, int outBufferSize); BackupDataResult exportSignPublicKeyRsa(int keyIndex, int outBufferSize);
/**
* 导出 RSA 加密公钥。
*/
BackupDataResult exportEncPublicKeyRsa(int keyIndex, int outBufferSize); BackupDataResult exportEncPublicKeyRsa(int keyIndex, int outBufferSize);
/**
* 导出 ECC 签名公钥。
*/
BackupDataResult exportSignPublicKeyEcc(int keyIndex, int outBufferSize); BackupDataResult exportSignPublicKeyEcc(int keyIndex, int outBufferSize);
/**
* 导出 ECC 加密公钥。
*/
BackupDataResult exportEncPublicKeyEcc(int keyIndex, int outBufferSize); BackupDataResult exportEncPublicKeyEcc(int keyIndex, int outBufferSize);
/**
* 生成标准 RSA 密钥对并导出结果。
*/
StandardKeyPairResult generateStandardRsaKeyPair(GenerateStandardRsaKeyPairRequest request); StandardKeyPairResult generateStandardRsaKeyPair(GenerateStandardRsaKeyPairRequest request);
/**
* 生成标准 ECC 密钥对并导出结果。
*/
StandardKeyPairResult generateStandardEccKeyPair(GenerateStandardEccKeyPairRequest request); StandardKeyPairResult generateStandardEccKeyPair(GenerateStandardEccKeyPairRequest request);
//----------------------------------------会话密钥与数字信封类接口------------------------------------------
/**
* 使用指定 KEK 生成会话密钥并导出包裹结果。
*/
BackupDataResult generateKeyWithKek(GenerateKeyWithKekRequest request); BackupDataResult generateKeyWithKek(GenerateKeyWithKekRequest request);
/**
* 执行 RSA 外部公钥运算。
*/
BackupDataResult rsaExternalPublicKeyOperation(RsaExternalPublicKeyOpRequest request); BackupDataResult rsaExternalPublicKeyOperation(RsaExternalPublicKeyOpRequest request);
/**
* 执行 RSA 外部私钥运算。
*/
BackupDataResult rsaExternalPrivateKeyOperation(RsaExternalPrivateKeyOpRequest request); BackupDataResult rsaExternalPrivateKeyOperation(RsaExternalPrivateKeyOpRequest request);
/**
* 执行 RSA 内部公钥运算。
*/
BackupDataResult rsaInternalPublicKeyOperation(RsaInternalKeyOpRequest request); BackupDataResult rsaInternalPublicKeyOperation(RsaInternalKeyOpRequest request);
/**
* 执行 RSA 内部私钥运算。
*/
BackupDataResult rsaInternalPrivateKeyOperation(RsaInternalKeyOpRequest request); BackupDataResult rsaInternalPrivateKeyOperation(RsaInternalKeyOpRequest request);
/**
* 使用内部 RSA 公钥生成会话密钥。
*/
BackupDataResult generateKeyWithIpkRsa(GenerateKeyWithIpkRsaRequest request); BackupDataResult generateKeyWithIpkRsa(GenerateKeyWithIpkRsaRequest request);
/**
* 使用外部 RSA 公钥生成会话密钥。
*/
BackupDataResult generateKeyWithEpkRsa(GenerateKeyWithEpkRsaRequest request); BackupDataResult generateKeyWithEpkRsa(GenerateKeyWithEpkRsaRequest request);
/**
* 使用内部 RSA 私钥导入会话密钥。
*/
void importKeyWithIskRsa(ImportKeyWithIskRsaRequest request); void importKeyWithIskRsa(ImportKeyWithIskRsaRequest request);
/**
* 使用内部 ECC 公钥生成会话密钥。
*/
BackupDataResult generateKeyWithIpkEcc(GenerateKeyWithIpkEccRequest request); BackupDataResult generateKeyWithIpkEcc(GenerateKeyWithIpkEccRequest request);
/**
* 使用外部 ECC 公钥生成会话密钥。
*/
BackupDataResult generateKeyWithEpkEcc(GenerateKeyWithEpkEccRequest request); BackupDataResult generateKeyWithEpkEcc(GenerateKeyWithEpkEccRequest request);
/**
* 使用内部 ECC 私钥导入会话密钥。
*/
void importKeyWithIskEcc(ImportKeyWithIskEccRequest request); void importKeyWithIskEcc(ImportKeyWithIskEccRequest request);
/**
* 执行基于 RSA 的数字信封交换。
*/
BackupDataResult exchangeDigitEnvelopeBaseOnRsa(ExchangeDigitEnvelopeRsaRequest request); BackupDataResult exchangeDigitEnvelopeBaseOnRsa(ExchangeDigitEnvelopeRsaRequest request);
/**
* 执行基于 ECC 的数字信封交换。
*/
BackupDataResult exchangeDigitEnvelopeBaseOnEcc(ExchangeDigitEnvelopeEccRequest request); BackupDataResult exchangeDigitEnvelopeBaseOnEcc(ExchangeDigitEnvelopeEccRequest request);
/**
* 生成 ECC 协商所需公钥材料并返回会话密钥。
*/
AgreementDataAndKeyEccResult generateAgreementDataAndKeyWithEcc(GenerateAgreementDataAndKeyEccRequest request); AgreementDataAndKeyEccResult generateAgreementDataAndKeyWithEcc(GenerateAgreementDataAndKeyEccRequest request);
/**
* 基于既有 ECC 协商材料生成会话密钥。
*/
EccAgreementSessionKeyResult generateSessionKeyWithEccAgreement(EccAgreementSessionKeyRequest request); EccAgreementSessionKeyResult generateSessionKeyWithEccAgreement(EccAgreementSessionKeyRequest request);
//----------------------------------------SDF通用算法运算类接口------------------------------------------
/**
* 使用通用内部 ECC 密钥执行签名。
*/
BackupDataResult eccInternalSign(EccInternalSignRequest request); BackupDataResult eccInternalSign(EccInternalSignRequest request);
/**
* 使用外部 ECC 私钥执行签名。
*/
BackupDataResult eccExternalSign(EccExternalSignRequest request); BackupDataResult eccExternalSign(EccExternalSignRequest request);
/**
* 使用通用内部 ECC 密钥执行验签。
*/
void eccInternalVerify(EccInternalVerifyRequest request); void eccInternalVerify(EccInternalVerifyRequest request);
/**
* 使用外部 ECC 公钥执行验签。
*/
void eccExternalVerify(EccExternalVerifyRequest request); void eccExternalVerify(EccExternalVerifyRequest request);
/**
* 使用外部 ECC 公钥执行加密。
*/
BackupDataResult eccExternalEncrypt(EccExternalEncryptRequest request); BackupDataResult eccExternalEncrypt(EccExternalEncryptRequest request);
/**
* 使用外部 ECC 私钥执行解密。
*/
BackupDataResult eccExternalDecrypt(EccExternalDecryptRequest request); BackupDataResult eccExternalDecrypt(EccExternalDecryptRequest request);
/**
* 使用明文对称密钥执行加密。
*/
BackupDataResult encryptWithPlainKey(SymmetricCryptoRequest request); BackupDataResult encryptWithPlainKey(SymmetricCryptoRequest request);
/**
* 使用明文对称密钥执行解密。
*/
BackupDataResult decryptWithPlainKey(SymmetricCryptoRequest request); BackupDataResult decryptWithPlainKey(SymmetricCryptoRequest request);
/**
* 使用 KEK 包裹密钥执行加密。
*/
BackupDataResult encryptWithKekWrappedKey(SymmetricKekCryptoRequest request); BackupDataResult encryptWithKekWrappedKey(SymmetricKekCryptoRequest request);
/**
* 使用 KEK 包裹密钥执行解密。
*/
BackupDataResult decryptWithKekWrappedKey(SymmetricKekCryptoRequest request); BackupDataResult decryptWithKekWrappedKey(SymmetricKekCryptoRequest request);
/**
* 使用明文对称密钥计算 MAC。
*/
BackupDataResult calculateMacWithPlainKey(MacCalcRequest request); BackupDataResult calculateMacWithPlainKey(MacCalcRequest request);
/**
* 使用通用 SDF 摘要流程计算杂凑。
*/
BackupDataResult digest(DigestRequest request); 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); HmacResult hmac(HmacRequest request);
//----------------------------------------LMK 生命周期类接口------------------------------------------
/**
* 生成 LMK。
*/
void generateLmk(); void generateLmk();
/**
* 加载 LMK。
*/
void loadLmk(); void loadLmk();
/**
* 备份 LMK。
*/
void backupLmk(); void backupLmk();
/**
* 恢复 LMK。
*/
void recoverLmk(); void recoverLmk();
/**
* 销毁 LMK。
*/
void destroyLmk(); void destroyLmk();
/**
* 检查 LMK 是否存在且可用。
*/
boolean checkLmk(); boolean checkLmk();
/**
* 导出 LMK seed MAC。
*/
byte[] exportLmkSeedMac(); byte[] exportLmkSeedMac();
/**
* 导出 LMK 分量扩展备份数据。
*/
BackupDataResult backupLmkEx(); BackupDataResult backupLmkEx();
/**
* 使用扩展备份数据恢复 LMK。
*/
void recoverLmkEx(byte[] lmkComponent); void recoverLmkEx(byte[] lmkComponent);
//----------------------------------------IK 生命周期类接口。------------------------------------------
/**
* 生成 IK。
*/
void generateIk(int keyType); 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); BackupDataResult backupIkComponent(int keyType);
/**
* 使用扩展备份数据恢复 IK。
*/
void recoverIkComponent(int keyType, byte[] ikComponent); void recoverIkComponent(int keyType, byte[] ikComponent);
/**
* 触发 IK 设备内备份。
*/
void backupIk(int keyType); void backupIk(int keyType);
/**
* 触发 IK 设备内恢复。
*/
void recoverIk(int keyType); void recoverIk(int keyType);
/**
* 销毁 IK。
*/
void destroyIk(int keyType); void destroyIk(int keyType);
/**
* 查询 IK 状态。
*/
KeyStatusResult statusIk(int keyType); KeyStatusResult statusIk(int keyType);
//----------------------------------------UKey 管理类接口-------------------------------------------
/**
* 生成 UKey 管理员。
*/
void generateUkey(UkeyGenerateRequest request); void generateUkey(UkeyGenerateRequest request);
/**
* 登录 UKey。
*/
void loginUkey(UkeyLoginRequest request); void loginUkey(UkeyLoginRequest request);
/**
* 修改 UKey PIN。
*/
void changeUkeyPin(UkeyPinChangeRequest request); void changeUkeyPin(UkeyPinChangeRequest request);
/**
* 解锁 UKey。
*/
void unlockUkey(UkeyUnlockRequest request); void unlockUkey(UkeyUnlockRequest request);
/**
* 从 UKey 读取 LMK 分量到设备运行态。
*/
void readLmkComponent(byte[] ukeyPin); void readLmkComponent(byte[] ukeyPin);
/**
* 从 UKey 读取 IK 分量到设备运行态。
*/
void readUkeyIkComponent(int keyType, byte[] ukeyPin); void readUkeyIkComponent(int keyType, byte[] ukeyPin);
/**
* 为 UKey 生成证书。
*/
void generateCertificate(byte[] ukeyPin); void generateCertificate(byte[] ukeyPin);
/**
* 注销指定管理员索引的 UKey 登录态。
*/
void logoutAdmin(int adminIndex); void logoutAdmin(int adminIndex);
/**
* 查询 UKey 登录状态。
*/
LoginStatusResult loginStatus(); LoginStatusResult loginStatus();
/**
* 设备文件系统类接口。
*/
/**
* 在设备文件系统中创建文件。
*/
void createFile(FileCreateRequest request); void createFile(FileCreateRequest request);
/**
* 向设备文件系统写入文件内容。
*/
void writeFile(FileWriteRequest request); void writeFile(FileWriteRequest request);
/**
* 从设备文件系统读取文件内容。
*/
BackupDataResult readFile(FileReadRequest request); BackupDataResult readFile(FileReadRequest request);
/**
* 删除设备文件系统中的文件。
*/
void deleteFile(String fileName); void deleteFile(String fileName);
} }
@@ -598,15 +598,6 @@ public class CryptoCardController {
return ApiResponse.success(); 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") @PostMapping("/keys/update-backed")
@Operation(summary = "更新备份数据", description = "更新旧备份结构并返回新的备份数据 HEX。") @Operation(summary = "更新备份数据", description = "更新旧备份结构并返回新的备份数据 HEX。")
public ApiResponse<Map<String, Object>> updateBackedKey( 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.ChangePrivateKeyPasswordRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyPairRequest; 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.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.ImportKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyPairRequest; import com.cisd.tms.integration.crypto.pcie.model.ImportKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.KekComponentRequest; 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.CryptoChangePrivateKeyPasswordInternalRequest;
import com.cisd.tms.modules.device.dto.crypto.request.CryptoGenerateKeyPairInternalRequest; 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.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.CryptoImportKekInternalRequest;
import com.cisd.tms.modules.device.dto.crypto.request.CryptoImportKeyPairInternalRequest; import com.cisd.tms.modules.device.dto.crypto.request.CryptoImportKeyPairInternalRequest;
import com.cisd.tms.modules.device.dto.crypto.request.CryptoKekComponentImportInternalRequest; import com.cisd.tms.modules.device.dto.crypto.request.CryptoKekComponentImportInternalRequest;
@@ -131,15 +129,6 @@ public final class CryptoRequestMapper {
return req; 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) { public static UpdateBackedKeyRequest toUpdateBackedKeyRequest(CryptoUpdateBackedKeyInternalRequest request) {
UpdateBackedKeyRequest req = new UpdateBackedKeyRequest(); UpdateBackedKeyRequest req = new UpdateBackedKeyRequest();
req.setOldData(CryptoPayloadCodec.decodeBase64(request.getOldDataBase64())); req.setOldData(CryptoPayloadCodec.decodeBase64(request.getOldDataBase64()));
@@ -35,6 +35,7 @@ public class LmkController {
@PostMapping("/masterKey/destroy") @PostMapping("/masterKey/destroy")
@Operation(summary = "销毁主密钥", description = "销毁当前密码卡中的主密钥,失败直接抛出异常。") @Operation(summary = "销毁主密钥", description = "销毁当前密码卡中的主密钥,失败直接抛出异常。")
public ApiResponse<Void> destroyMasterKey() { public ApiResponse<Void> destroyMasterKey() {
//销毁主密钥、内部密钥、用户密钥
lmkService.destroyMasterKey(); lmkService.destroyMasterKey();
return ApiResponse.success(); return ApiResponse.success();
} }
@@ -5,14 +5,22 @@ public class MasterKeyPacketIkPart {
private int keyType; private int keyType;
private String mac; private String mac;
private String component; private String component;
private String publicKey;
private String publicKeyMac;
public MasterKeyPacketIkPart() { public MasterKeyPacketIkPart() {
} }
public MasterKeyPacketIkPart(int keyType, String mac, String component) { 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.keyType = keyType;
this.mac = mac; this.mac = mac;
this.component = component; this.component = component;
this.publicKey = publicKey;
this.publicKeyMac = publicKeyMac;
} }
public int getKeyType() { public int getKeyType() {
@@ -38,4 +46,20 @@ public class MasterKeyPacketIkPart {
public void setComponent(String component) { public void setComponent(String component) {
this.component = 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.jna.EccSignature;
import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult; 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.DigestRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalSignRequest; import com.cisd.tms.integration.crypto.pcie.model.IkSignRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalVerifyRequest; 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.model.RecoverUserKeyRequest;
import com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService; import com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService;
import com.cisd.tms.modules.mk.common.LMKConstant; 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 LMK_MAC_BYTE_LENGTH = 8;
private static final int IK_COMPONENT_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_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_INDEX = 1;
private static final int USER_KEY_TYPE_SIGN = 0; private static final int USER_KEY_TYPE_SIGN = 0;
private static final int USER_KEY_TYPE_ENC = 1; private static final int USER_KEY_TYPE_ENC = 1;
@@ -83,29 +87,29 @@ public class LmkServiceImpl implements LmkService {
@Override @Override
public String exportIkPublicKeyHex() { public String exportIkPublicKeyHex() {
int outBufferSize = new EccRefPublicKey().size(); 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()); return Hex.toHexString(result.getData());
} }
@Override @Override
public String signIk(String rawData) { public String signIk(String rawData) {
byte[] digest = digestForInternalSign(rawData); byte[] digest = digestForInternalSign(rawData);
EccInternalSignRequest request = new EccInternalSignRequest(); IkSignRequest request = new IkSignRequest();
request.setKeyIndex(AUTH_SIGN_KEY_INDEX); request.setKeyType(AUTH_SIGN_KEY_INDEX);
request.setData(digest); request.setData(digest);
request.setSignatureBufferSize(new EccSignature().size()); request.setSignatureBufferSize(new EccSignature().size());
BackupDataResult result = pcieCryptoService.eccInternalSign(request); BackupDataResult result = pcieCryptoService.signIk(request);
return Hex.toHexString(result.getData()); return Hex.toHexString(result.getData());
} }
@Override @Override
public void verifyIk(String rawData, String signatureHex) { public void verifyIk(String rawData, String signatureHex) {
byte[] digest = digestForInternalSign(rawData); byte[] digest = digestForInternalSign(rawData);
EccInternalVerifyRequest request = new EccInternalVerifyRequest(); IkVerifyRequest request = new IkVerifyRequest();
request.setKeyIndex(AUTH_SIGN_KEY_INDEX); request.setKeyType(AUTH_SIGN_KEY_INDEX);
request.setData(digest); request.setData(digest);
request.setSignature(Hex.decode(signatureHex)); request.setSignature(Hex.decode(signatureHex));
pcieCryptoService.eccInternalVerify(request); pcieCryptoService.verifyIk(request);
} }
@Override @Override
@@ -124,12 +128,16 @@ public class LmkServiceImpl implements LmkService {
packet.setIkAuth(new MasterKeyPacketIkPart( packet.setIkAuth(new MasterKeyPacketIkPart(
IKEnums.KEY_TYPE_AUTH.getCode(), IKEnums.KEY_TYPE_AUTH.getCode(),
authIkBackup.macHex(), authIkBackup.macHex(),
requiredComponent(authIkBackup.componentMap(), index, "ikAuth") requiredComponent(authIkBackup.componentMap(), index, "ikAuth"),
authIkBackup.publicKeyHex(),
authIkBackup.publicKeyMacHex()
)); ));
packet.setIkDevice(new MasterKeyPacketIkPart( packet.setIkDevice(new MasterKeyPacketIkPart(
IKEnums.KEY_TYPE_DEVICE.getCode(), IKEnums.KEY_TYPE_DEVICE.getCode(),
deviceIkBackup.macHex(), deviceIkBackup.macHex(),
requiredComponent(deviceIkBackup.componentMap(), index, "ikDevice") requiredComponent(deviceIkBackup.componentMap(), index, "ikDevice"),
deviceIkBackup.publicKeyHex(),
deviceIkBackup.publicKeyMacHex()
)); ));
packet.setUserKeys(List.of( packet.setUserKeys(List.of(
buildUserKeyPacket(USER_KEY_INDEX, USER_KEY_TYPE_SIGN, index), 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) { private String composeIkHex(List<MasterKeyBackupPacket> packets, boolean authKey) {
int keyType = authKey ? IKEnums.KEY_TYPE_AUTH.getCode() : IKEnums.KEY_TYPE_DEVICE.getCode(); int keyType = authKey ? IKEnums.KEY_TYPE_AUTH.getCode() : IKEnums.KEY_TYPE_DEVICE.getCode();
String mac = requireConsistentIkMac(packets, keyType); String mac = requireConsistentIkMac(packets, keyType);
String publicKey = requireConsistentIkPublicKey(packets, keyType);
String publicKeyMac = requireConsistentIkPublicKeyMac(packets, keyType);
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
for (MasterKeyBackupPacket packet : packets) { for (MasterKeyBackupPacket packet : packets) {
MasterKeyPacketIkPart part = authKey ? packet.getIkAuth() : packet.getIkDevice(); MasterKeyPacketIkPart part = authKey ? packet.getIkAuth() : packet.getIkDevice();
@@ -223,7 +233,7 @@ public class LmkServiceImpl implements LmkService {
} }
builder.append(part.getComponent()); builder.append(part.getComponent());
} }
builder.append(mac); builder.append(mac).append(publicKey).append(publicKeyMac);
return builder.toString(); return builder.toString();
} }
@@ -263,17 +273,27 @@ public class LmkServiceImpl implements LmkService {
private ParsedIkBackup parseIkBackupMaterial(int keyType) { private ParsedIkBackup parseIkBackupMaterial(int keyType) {
BackupDataResult backupData = pcieCryptoService.backupIkComponent(keyType); BackupDataResult backupData = pcieCryptoService.backupIkComponent(keyType);
byte[] normalized = normalizeBackupData(backupData); 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); throw new IllegalStateException("backup ik data length is too short: " + normalized.length);
} }
byte[] componentBytes = Arrays.copyOfRange(normalized, 0, IK_COMPONENT_DATA_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[] 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); String[] splitComponents = DivisionUtils.equalDivision(Hex.toHexString(componentBytes), LMKConstant.COMPONENT_NUM);
Map<Integer, String> componentMap = new HashMap<>(); Map<Integer, String> componentMap = new HashMap<>();
for (int i = 0; i < LMKConstant.COMPONENT_NUM; i++) { for (int i = 0; i < LMKConstant.COMPONENT_NUM; i++) {
componentMap.put(LMKConstant.KEY_ORDER[i], splitComponents[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) { private MasterKeyPacketUserKeyPart buildUserKeyPacket(int keyIndex, int keyType, int componentIndex) {
@@ -365,6 +385,42 @@ public class LmkServiceImpl implements LmkService {
return mac; 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) { private MasterKeyPacketUserKeyPart findUserKeyPart(MasterKeyBackupPacket packet, int keyIndex, int keyType) {
return packet.getUserKeys().stream() return packet.getUserKeys().stream()
.filter(item -> item.getKeyIndex() == keyIndex && item.getKeyType() == keyType) .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 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) {
} }
} }
@@ -2,8 +2,22 @@ package com.cisd.tms.integration.crypto.pcie.service;
import com.cisd.tms.integration.crypto.config.CryptoCardProperties; import com.cisd.tms.integration.crypto.config.CryptoCardProperties;
import com.cisd.tms.integration.crypto.pcie.PcieSessionTemplate; import com.cisd.tms.integration.crypto.pcie.PcieSessionTemplate;
import com.cisd.tms.integration.crypto.pcie.jna.EccCipher;
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.jna.PcieNativeLibrary; import com.cisd.tms.integration.crypto.pcie.jna.PcieNativeLibrary;
import com.cisd.tms.integration.crypto.pcie.jna.SdfFirmwareInfo;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeIkComponent;
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.EccInternalDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalEncryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.FirmwareInfoResult;
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.SymmetricCryptoRequest;
import com.sun.jna.Pointer; import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
@@ -47,4 +61,399 @@ class JnaPcieCryptoServiceTest {
Assertions.assertArrayEquals(new byte[] {0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF}, mac); Assertions.assertArrayEquals(new byte[] {0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF}, mac);
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_InitializeMasterKey"), Mockito.any()); Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_InitializeMasterKey"), Mockito.any());
} }
@Test
void shouldBackupIkComponentViaSdfeBackupIkEx() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_BackupIK_EX"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<BackupDataResult> callback =
(PcieSessionTemplate.SessionCallback<BackupDataResult>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
Mockito.when(lib.SDFE_BackupIK_EX(Mockito.any(), Mockito.eq(2), Mockito.any(SdfeIkComponent.class)))
.thenAnswer(call -> {
SdfeIkComponent output = call.getArgument(2);
Arrays.fill(output.component, (byte) 0x11);
Arrays.fill(output.priMac, (byte) 0x22);
output.pubkey.bits = 256;
Arrays.fill(output.pubkey.x, (byte) 0x33);
Arrays.fill(output.pubkey.y, (byte) 0x44);
Arrays.fill(output.pubMac, (byte) 0x55);
return 0;
});
return callback.apply(lib, Pointer.createConstant(1), Pointer.createConstant(2));
});
byte[] data = service.backupIkComponent(2).getData();
Assertions.assertEquals(new SdfeIkComponent().size(), data.length);
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_BackupIK_EX"), Mockito.any());
}
@Test
void shouldRecoverIkComponentViaSdfeRecoverIkEx() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
byte[] ikComponent = new byte[new SdfeIkComponent().size()];
Arrays.fill(ikComponent, (byte) 0x5A);
Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_RecoverIK_EX"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<Void> callback =
(PcieSessionTemplate.SessionCallback<Void>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
Mockito.when(lib.SDFE_RecoverIK_EX(Mockito.any(), Mockito.eq(1), Mockito.any(SdfeIkComponent.class)))
.thenReturn(0);
return callback.apply(lib, Pointer.createConstant(1), Pointer.createConstant(2));
});
service.recoverIkComponent(1, ikComponent);
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_RecoverIK_EX"), Mockito.any());
}
@Test
void shouldExportIkPublicKeyViaSdfeExportIkPublicKey() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_ExportIKPublicKey"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<BackupDataResult> callback =
(PcieSessionTemplate.SessionCallback<BackupDataResult>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
Mockito.when(lib.SDFE_ExportIKPublicKey(Mockito.any(), Mockito.eq(2), Mockito.any(EccRefPublicKey.class)))
.thenAnswer(call -> {
EccRefPublicKey output = call.getArgument(2);
output.bits = 256;
Arrays.fill(output.x, (byte) 0x66);
Arrays.fill(output.y, (byte) 0x77);
return 0;
});
return callback.apply(lib, Pointer.createConstant(1), Pointer.createConstant(2));
});
byte[] data = service.exportIkPublicKey(2, new EccRefPublicKey().size()).getData();
Assertions.assertEquals(new EccRefPublicKey().size(), data.length);
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_ExportIKPublicKey"), Mockito.any());
}
@Test
void shouldExportIkMacViaSdfeExportIkMac() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_ExportIKMac"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<BackupDataResult> callback =
(PcieSessionTemplate.SessionCallback<BackupDataResult>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
Mockito.when(lib.SDFE_ExportIKMac(Mockito.any(), Mockito.eq(2), Mockito.any(byte[].class)))
.thenAnswer(call -> {
byte[] out = call.getArgument(2);
Arrays.fill(out, (byte) 0x6A);
return 0;
});
return callback.apply(lib, Pointer.createConstant(1), Pointer.createConstant(2));
});
byte[] data = service.exportIkMac(2).getData();
Assertions.assertEquals(8, data.length);
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_ExportIKMac"), Mockito.any());
}
@Test
void shouldSignIkViaSdfeSignIk() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
IkSignRequest request = new IkSignRequest();
request.setKeyType(2);
request.setData(new byte[] {0x01, 0x02});
request.setSignatureBufferSize(new EccSignature().size());
Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_SignIK"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<BackupDataResult> callback =
(PcieSessionTemplate.SessionCallback<BackupDataResult>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
Mockito.when(lib.SDFE_SignIK(Mockito.any(), Mockito.eq(2), Mockito.any(byte[].class), Mockito.eq(2), Mockito.any(EccSignature.class)))
.thenAnswer(call -> {
EccSignature signature = call.getArgument(4);
Arrays.fill(signature.r, (byte) 0x12);
Arrays.fill(signature.s, (byte) 0x34);
return 0;
});
return callback.apply(lib, Pointer.createConstant(1), Pointer.createConstant(2));
});
byte[] data = service.signIk(request).getData();
Assertions.assertEquals(new EccSignature().size(), data.length);
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_SignIK"), Mockito.any());
}
@Test
void shouldVerifyIkViaSdfeVerifyIk() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
IkVerifyRequest request = new IkVerifyRequest();
request.setKeyType(2);
request.setData(new byte[] {0x01, 0x02});
request.setSignature(new byte[new EccSignature().size()]);
Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_VerifyIK"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<Void> callback =
(PcieSessionTemplate.SessionCallback<Void>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
Mockito.when(lib.SDFE_VerifyIK(Mockito.any(), Mockito.eq(2), Mockito.any(byte[].class), Mockito.eq(2), Mockito.any(EccSignature.class)))
.thenReturn(0);
return callback.apply(lib, Pointer.createConstant(1), Pointer.createConstant(2));
});
service.verifyIk(request);
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_VerifyIK"), Mockito.any());
}
@Test
void shouldReadFirmwareInfoViaSdfeGetFirmwareInfo() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_GetFirmwareInfo"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<FirmwareInfoResult> callback =
(PcieSessionTemplate.SessionCallback<FirmwareInfoResult>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
Mockito.when(lib.SDFE_GetFirmwareInfo(Mockito.any(), Mockito.any(SdfFirmwareInfo.class)))
.thenAnswer(call -> {
SdfFirmwareInfo info = call.getArgument(1);
info.bomInfo[0] = 1;
info.gd32Info[0] = 2;
info.n32s033Info[0] = 3;
return 0;
});
return callback.apply(lib, Pointer.createConstant(1), Pointer.createConstant(2));
});
FirmwareInfoResult result = service.getFirmwareInfo();
Assertions.assertNotNull(result);
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_GetFirmwareInfo"), Mockito.any());
}
@Test
void shouldEncryptViaSdfeEncrypt() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
SymmetricCryptoRequest request = new SymmetricCryptoRequest();
request.setAlgId(1);
request.setKey(new byte[] {0x01, 0x02});
request.setIv(new byte[16]);
request.setData(new byte[] {0x03, 0x04});
request.setOutBufferSize(8);
Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_Encrypt"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<BackupDataResult> callback =
(PcieSessionTemplate.SessionCallback<BackupDataResult>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
Mockito.when(lib.SDFE_Encrypt(Mockito.any(), Mockito.any(byte[].class), Mockito.eq(2), Mockito.eq(1),
Mockito.any(byte[].class), Mockito.any(byte[].class), Mockito.eq(2), Mockito.any(byte[].class), Mockito.any(IntByReference.class)))
.thenAnswer(call -> {
byte[] out = call.getArgument(7);
IntByReference outLen = call.getArgument(8);
out[0] = 0x55;
out[1] = 0x66;
outLen.setValue(2);
return 0;
});
return callback.apply(lib, Pointer.createConstant(1), Pointer.createConstant(2));
});
byte[] data = service.sdfeEncrypt(request).getData();
Assertions.assertArrayEquals(new byte[] {0x55, 0x66}, data);
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_Encrypt"), Mockito.any());
}
@Test
void shouldDecryptViaSdfeDecrypt() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
SymmetricCryptoRequest request = new SymmetricCryptoRequest();
request.setAlgId(1);
request.setKey(new byte[] {0x01, 0x02});
request.setIv(new byte[16]);
request.setData(new byte[] {0x03, 0x04});
request.setOutBufferSize(8);
Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_Decrypt"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<BackupDataResult> callback =
(PcieSessionTemplate.SessionCallback<BackupDataResult>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
Mockito.when(lib.SDFE_Decrypt(Mockito.any(), Mockito.any(byte[].class), Mockito.eq(2), Mockito.eq(1),
Mockito.any(byte[].class), Mockito.any(byte[].class), Mockito.eq(2), Mockito.any(byte[].class), Mockito.any(IntByReference.class)))
.thenAnswer(call -> {
byte[] out = call.getArgument(7);
IntByReference outLen = call.getArgument(8);
out[0] = 0x21;
out[1] = 0x22;
outLen.setValue(2);
return 0;
});
return callback.apply(lib, Pointer.createConstant(1), Pointer.createConstant(2));
});
byte[] data = service.sdfeDecrypt(request).getData();
Assertions.assertArrayEquals(new byte[] {0x21, 0x22}, data);
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_Decrypt"), Mockito.any());
}
@Test
void shouldHashViaSdfeHash() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
DigestRequest request = new DigestRequest();
request.setAlgId(1);
request.setData(new byte[] {0x01, 0x02});
request.setOutBufferSize(8);
Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_Hash"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<BackupDataResult> callback =
(PcieSessionTemplate.SessionCallback<BackupDataResult>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
Mockito.when(lib.SDFE_Hash(Mockito.any(), Mockito.eq(1), Mockito.any(byte[].class), Mockito.eq(2), Mockito.any(byte[].class), Mockito.any(IntByReference.class)))
.thenAnswer(call -> {
byte[] out = call.getArgument(4);
IntByReference outLen = call.getArgument(5);
out[0] = 0x0A;
out[1] = 0x0B;
outLen.setValue(2);
return 0;
});
return callback.apply(lib, Pointer.createConstant(1), Pointer.createConstant(2));
});
byte[] data = service.sdfeHash(request).getData();
Assertions.assertArrayEquals(new byte[] {0x0A, 0x0B}, data);
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_Hash"), Mockito.any());
}
@Test
void shouldCopyHashStateViaSdfeHashCopy() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
Mockito.when(sessionTemplate.withTwoSessions(Mockito.eq("SDFE_HashCopy"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.TwoSessionCallback<Void> callback =
(PcieSessionTemplate.TwoSessionCallback<Void>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
Mockito.when(lib.SDFE_HashCopy(Mockito.any(), Mockito.any())).thenReturn(0);
return callback.apply(lib, Pointer.createConstant(1), Pointer.createConstant(2), Pointer.createConstant(3));
});
service.sdfeHashCopy();
Mockito.verify(sessionTemplate).withTwoSessions(Mockito.eq("SDFE_HashCopy"), Mockito.any());
}
@Test
void shouldInternalEncryptEccViaSdfeInternalEncrypt() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
EccInternalEncryptRequest request = new EccInternalEncryptRequest();
request.setKeyIndex(1);
request.setData(new byte[] {0x01, 0x02});
request.setOutBufferSize(new EccCipher().size());
Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_InternalEncrypt_ECC"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<BackupDataResult> callback =
(PcieSessionTemplate.SessionCallback<BackupDataResult>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
Mockito.when(lib.SDFE_InternalEncrypt_ECC(Mockito.any(), Mockito.eq(1), Mockito.any(byte[].class), Mockito.eq(2), Mockito.any(EccCipher.class)))
.thenAnswer(call -> {
EccCipher cipher = call.getArgument(4);
cipher.l = 2;
cipher.c[0] = 0x01;
cipher.c[1] = 0x02;
return 0;
});
return callback.apply(lib, Pointer.createConstant(1), Pointer.createConstant(2));
});
BackupDataResult result = service.sdfeInternalEncryptEcc(request);
Assertions.assertNotNull(result);
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_InternalEncrypt_ECC"), Mockito.any());
}
@Test
void shouldInternalDecryptEccViaSdfeInternalDecrypt() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
EccInternalDecryptRequest request = new EccInternalDecryptRequest();
request.setKeyIndex(1);
request.setCipherBlob(new byte[new EccCipher().size()]);
request.setOutBufferSize(8);
Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_InternalDecrypt_ECC"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<BackupDataResult> callback =
(PcieSessionTemplate.SessionCallback<BackupDataResult>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
Mockito.when(lib.SDFE_InternalDecrypt_ECC(Mockito.any(), Mockito.eq(1), Mockito.any(EccCipher.class), Mockito.any(byte[].class), Mockito.any(IntByReference.class)))
.thenAnswer(call -> {
byte[] out = call.getArgument(3);
IntByReference outLen = call.getArgument(4);
out[0] = 0x31;
out[1] = 0x32;
outLen.setValue(2);
return 0;
});
return callback.apply(lib, Pointer.createConstant(1), Pointer.createConstant(2));
});
byte[] data = service.sdfeInternalDecryptEcc(request).getData();
Assertions.assertArrayEquals(new byte[] {0x31, 0x32}, data);
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_InternalDecrypt_ECC"), Mockito.any());
}
} }
@@ -49,6 +49,15 @@ class CryptoCardControllerTest {
assertFalse(helperMethods.contains("normalizeBinary")); assertFalse(helperMethods.contains("normalizeBinary"));
} }
@Test
void shouldRemoveEncryptedRsaImportEndpoint() {
java.util.Set<String> controllerMethods = java.util.Arrays.stream(CryptoCardController.class.getDeclaredMethods())
.map(java.lang.reflect.Method::getName)
.collect(java.util.stream.Collectors.toSet());
assertFalse(controllerMethods.contains("importEncryptedKeyPairRsa"));
}
@Test @Test
void shouldReturnDeviceStatusAsHex() throws Exception { void shouldReturnDeviceStatusAsHex() throws Exception {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class); PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
@@ -1,10 +1,14 @@
package com.cisd.tms.modules.mk.service; package com.cisd.tms.modules.mk.service;
import com.cisd.tms.integration.crypto.pcie.Gm0018AlgorithmIds; import com.cisd.tms.integration.crypto.pcie.Gm0018AlgorithmIds;
import com.cisd.tms.integration.crypto.pcie.jna.EccRefPublicKey;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeIkComponent;
import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult; 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.DigestRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalSignRequest; 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.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.model.RecoverUserKeyRequest;
import com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService; import com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService;
import com.cisd.tms.modules.mk.config.MasterKeyInitProperties; import com.cisd.tms.modules.mk.config.MasterKeyInitProperties;
@@ -87,6 +91,24 @@ class LmkServiceTest {
Assertions.assertEquals("aabb", result.getSeedMac()); Assertions.assertEquals("aabb", result.getSeedMac());
} }
@Test
void shouldExportIkPublicKeyHexViaDedicatedIkApi() {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
MasterKeyInitProperties properties = configuredPins("MTIzNDU2Nzg=", "ODc2NTQzMjE=");
BackupDataResult publicKey = new BackupDataResult();
publicKey.setLength(new EccRefPublicKey().size());
publicKey.setData(sequentialBytes(new EccRefPublicKey().size(), 0x31));
Mockito.when(pcieCryptoService.exportIkPublicKey(2, new EccRefPublicKey().size())).thenReturn(publicKey);
LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
String result = service.exportIkPublicKeyHex();
Assertions.assertEquals(org.bouncycastle.util.encoders.Hex.toHexString(publicKey.getData()), result);
Mockito.verify(pcieCryptoService).exportIkPublicKey(2, new EccRefPublicKey().size());
Mockito.verify(pcieCryptoService, Mockito.never()).exportSignPublicKeyEcc(Mockito.anyInt(), Mockito.anyInt());
}
@Test @Test
void shouldBuildBackupPacketForSingleComponentIndex() { void shouldBuildBackupPacketForSingleComponentIndex() {
PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class); PcieCryptoService pcieCryptoService = Mockito.mock(PcieCryptoService.class);
@@ -100,11 +122,11 @@ class LmkServiceTest {
0x09, 0x0A, 0x0B, 0x0C 0x09, 0x0A, 0x0B, 0x0C
}); });
BackupDataResult ikAuthBackup = new BackupDataResult(); BackupDataResult ikAuthBackup = new BackupDataResult();
ikAuthBackup.setLength(200); ikAuthBackup.setLength(new SdfeIkComponent().size());
ikAuthBackup.setData(sequentialBytes(200, 0x21)); ikAuthBackup.setData(sequentialBytes(new SdfeIkComponent().size(), 0x21));
BackupDataResult ikDeviceBackup = new BackupDataResult(); BackupDataResult ikDeviceBackup = new BackupDataResult();
ikDeviceBackup.setLength(200); ikDeviceBackup.setLength(new SdfeIkComponent().size());
ikDeviceBackup.setData(sequentialBytes(200, 0x41)); ikDeviceBackup.setData(sequentialBytes(new SdfeIkComponent().size(), 0x41));
BackupDataResult userSignBackup = new BackupDataResult(); BackupDataResult userSignBackup = new BackupDataResult();
userSignBackup.setLength(12); userSignBackup.setLength(12);
userSignBackup.setData(new byte[] {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C}); userSignBackup.setData(new byte[] {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C});
@@ -129,11 +151,27 @@ class LmkServiceTest {
org.bouncycastle.util.encoders.Hex.toHexString(java.util.Arrays.copyOfRange(ikAuthBackup.getData(), 64, 128)), org.bouncycastle.util.encoders.Hex.toHexString(java.util.Arrays.copyOfRange(ikAuthBackup.getData(), 64, 128)),
packet.getIkAuth().getComponent() packet.getIkAuth().getComponent()
); );
Assertions.assertEquals(
org.bouncycastle.util.encoders.Hex.toHexString(java.util.Arrays.copyOfRange(ikAuthBackup.getData(), 200, 332)),
packet.getIkAuth().getPublicKey()
);
Assertions.assertEquals(
org.bouncycastle.util.encoders.Hex.toHexString(java.util.Arrays.copyOfRange(ikAuthBackup.getData(), 332, 340)),
packet.getIkAuth().getPublicKeyMac()
);
Assertions.assertEquals(1, packet.getIkDevice().getKeyType()); Assertions.assertEquals(1, packet.getIkDevice().getKeyType());
Assertions.assertEquals( Assertions.assertEquals(
org.bouncycastle.util.encoders.Hex.toHexString(java.util.Arrays.copyOfRange(ikDeviceBackup.getData(), 64, 128)), org.bouncycastle.util.encoders.Hex.toHexString(java.util.Arrays.copyOfRange(ikDeviceBackup.getData(), 64, 128)),
packet.getIkDevice().getComponent() packet.getIkDevice().getComponent()
); );
Assertions.assertEquals(
org.bouncycastle.util.encoders.Hex.toHexString(java.util.Arrays.copyOfRange(ikDeviceBackup.getData(), 200, 332)),
packet.getIkDevice().getPublicKey()
);
Assertions.assertEquals(
org.bouncycastle.util.encoders.Hex.toHexString(java.util.Arrays.copyOfRange(ikDeviceBackup.getData(), 332, 340)),
packet.getIkDevice().getPublicKeyMac()
);
Assertions.assertEquals(2, packet.getUserKeys().size()); Assertions.assertEquals(2, packet.getUserKeys().size());
Assertions.assertEquals("65666768", packet.getUserKeys().get(0).getComponent()); Assertions.assertEquals("65666768", packet.getUserKeys().get(0).getComponent());
Assertions.assertEquals("75767778", packet.getUserKeys().get(1).getComponent()); Assertions.assertEquals("75767778", packet.getUserKeys().get(1).getComponent());
@@ -148,8 +186,8 @@ class LmkServiceTest {
MasterKeyBackupPacket packet1 = new MasterKeyBackupPacket(); MasterKeyBackupPacket packet1 = new MasterKeyBackupPacket();
packet1.setComponentIndex(1); packet1.setComponentIndex(1);
packet1.setLmk(new MasterKeyPacketLmkPart("1112131415161718", "0102")); packet1.setLmk(new MasterKeyPacketLmkPart("1112131415161718", "0102"));
packet1.setIkAuth(new MasterKeyPacketIkPart(2, "2122232425262728", "1112")); packet1.setIkAuth(new MasterKeyPacketIkPart(2, "2122232425262728", "1112", "31323334", "4142434445464748"));
packet1.setIkDevice(new MasterKeyPacketIkPart(1, "3132333435363738", "2122")); packet1.setIkDevice(new MasterKeyPacketIkPart(1, "3132333435363738", "2122", "51525354", "6162636465666768"));
packet1.setUserKeys(List.of( packet1.setUserKeys(List.of(
new MasterKeyPacketUserKeyPart(1, 0, "0102"), new MasterKeyPacketUserKeyPart(1, 0, "0102"),
new MasterKeyPacketUserKeyPart(1, 1, "1112") new MasterKeyPacketUserKeyPart(1, 1, "1112")
@@ -158,8 +196,8 @@ class LmkServiceTest {
MasterKeyBackupPacket packet2 = new MasterKeyBackupPacket(); MasterKeyBackupPacket packet2 = new MasterKeyBackupPacket();
packet2.setComponentIndex(2); packet2.setComponentIndex(2);
packet2.setLmk(new MasterKeyPacketLmkPart("1112131415161718", "0304")); packet2.setLmk(new MasterKeyPacketLmkPart("1112131415161718", "0304"));
packet2.setIkAuth(new MasterKeyPacketIkPart(2, "2122232425262728", "1314")); packet2.setIkAuth(new MasterKeyPacketIkPart(2, "2122232425262728", "1314", "31323334", "4142434445464748"));
packet2.setIkDevice(new MasterKeyPacketIkPart(1, "3132333435363738", "2324")); packet2.setIkDevice(new MasterKeyPacketIkPart(1, "3132333435363738", "2324", "51525354", "6162636465666768"));
packet2.setUserKeys(List.of( packet2.setUserKeys(List.of(
new MasterKeyPacketUserKeyPart(1, 0, "0304"), new MasterKeyPacketUserKeyPart(1, 0, "0304"),
new MasterKeyPacketUserKeyPart(1, 1, "1314") new MasterKeyPacketUserKeyPart(1, 1, "1314")
@@ -168,8 +206,8 @@ class LmkServiceTest {
MasterKeyBackupPacket packet3 = new MasterKeyBackupPacket(); MasterKeyBackupPacket packet3 = new MasterKeyBackupPacket();
packet3.setComponentIndex(3); packet3.setComponentIndex(3);
packet3.setLmk(new MasterKeyPacketLmkPart("1112131415161718", "0506")); packet3.setLmk(new MasterKeyPacketLmkPart("1112131415161718", "0506"));
packet3.setIkAuth(new MasterKeyPacketIkPart(2, "2122232425262728", "1516")); packet3.setIkAuth(new MasterKeyPacketIkPart(2, "2122232425262728", "1516", "31323334", "4142434445464748"));
packet3.setIkDevice(new MasterKeyPacketIkPart(1, "3132333435363738", "2526")); packet3.setIkDevice(new MasterKeyPacketIkPart(1, "3132333435363738", "2526", "51525354", "6162636465666768"));
packet3.setUserKeys(List.of( packet3.setUserKeys(List.of(
new MasterKeyPacketUserKeyPart(1, 0, "0506"), new MasterKeyPacketUserKeyPart(1, 0, "0506"),
new MasterKeyPacketUserKeyPart(1, 1, "1516") new MasterKeyPacketUserKeyPart(1, 1, "1516")
@@ -196,8 +234,8 @@ class LmkServiceTest {
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06 0x01, 0x02, 0x03, 0x04, 0x05, 0x06
}, lmkCaptor.getValue()); }, lmkCaptor.getValue());
Assertions.assertArrayEquals(hex("1112131415162122232425262728"), ikAuthCaptor.getValue()); Assertions.assertArrayEquals(hex("1112131415162122232425262728313233344142434445464748"), ikAuthCaptor.getValue());
Assertions.assertArrayEquals(hex("2122232425263132333435363738"), ikDeviceCaptor.getValue()); Assertions.assertArrayEquals(hex("2122232425263132333435363738515253546162636465666768"), ikDeviceCaptor.getValue());
Assertions.assertEquals(2, userKeyCaptor.getAllValues().size()); Assertions.assertEquals(2, userKeyCaptor.getAllValues().size());
Assertions.assertArrayEquals(hex("010203040506"), userKeyCaptor.getAllValues().get(0).getEncryptedKey()); Assertions.assertArrayEquals(hex("010203040506"), userKeyCaptor.getAllValues().get(0).getEncryptedKey());
Assertions.assertArrayEquals(hex("111213141516"), userKeyCaptor.getAllValues().get(1).getEncryptedKey()); Assertions.assertArrayEquals(hex("111213141516"), userKeyCaptor.getAllValues().get(1).getEncryptedKey());
@@ -219,7 +257,7 @@ class LmkServiceTest {
signResult.setLength(2); signResult.setLength(2);
signResult.setData(new byte[] {(byte) 0xAA, (byte) 0xBB}); signResult.setData(new byte[] {(byte) 0xAA, (byte) 0xBB});
Mockito.when(pcieCryptoService.digest(Mockito.any())).thenReturn(digestResult); Mockito.when(pcieCryptoService.digest(Mockito.any())).thenReturn(digestResult);
Mockito.when(pcieCryptoService.eccInternalSign(Mockito.any())).thenReturn(signResult); Mockito.when(pcieCryptoService.signIk(Mockito.any())).thenReturn(signResult);
LmkService service = new LmkServiceImpl(pcieCryptoService, properties); LmkService service = new LmkServiceImpl(pcieCryptoService, properties);
@@ -227,13 +265,14 @@ class LmkServiceTest {
Assertions.assertEquals("aabb", signatureHex); Assertions.assertEquals("aabb", signatureHex);
ArgumentCaptor<DigestRequest> digestCaptor = ArgumentCaptor.forClass(DigestRequest.class); ArgumentCaptor<DigestRequest> digestCaptor = ArgumentCaptor.forClass(DigestRequest.class);
ArgumentCaptor<EccInternalSignRequest> signCaptor = ArgumentCaptor.forClass(EccInternalSignRequest.class); ArgumentCaptor<IkSignRequest> signCaptor = ArgumentCaptor.forClass(IkSignRequest.class);
InOrder inOrder = Mockito.inOrder(pcieCryptoService); InOrder inOrder = Mockito.inOrder(pcieCryptoService);
inOrder.verify(pcieCryptoService).digest(digestCaptor.capture()); inOrder.verify(pcieCryptoService).digest(digestCaptor.capture());
inOrder.verify(pcieCryptoService).eccInternalSign(signCaptor.capture()); inOrder.verify(pcieCryptoService).signIk(signCaptor.capture());
Assertions.assertEquals(Gm0018AlgorithmIds.SM3, digestCaptor.getValue().getAlgId()); Assertions.assertEquals(Gm0018AlgorithmIds.SM3, digestCaptor.getValue().getAlgId());
Assertions.assertArrayEquals("1223".getBytes(StandardCharsets.UTF_8), digestCaptor.getValue().getData()); Assertions.assertArrayEquals("1223".getBytes(StandardCharsets.UTF_8), digestCaptor.getValue().getData());
Assertions.assertArrayEquals(digestResult.getData(), signCaptor.getValue().getData()); Assertions.assertArrayEquals(digestResult.getData(), signCaptor.getValue().getData());
Assertions.assertEquals(2, signCaptor.getValue().getKeyType());
} }
@Test @Test
@@ -255,14 +294,15 @@ class LmkServiceTest {
service.verifyIk("1223", "aabb"); service.verifyIk("1223", "aabb");
ArgumentCaptor<DigestRequest> digestCaptor = ArgumentCaptor.forClass(DigestRequest.class); ArgumentCaptor<DigestRequest> digestCaptor = ArgumentCaptor.forClass(DigestRequest.class);
ArgumentCaptor<EccInternalVerifyRequest> verifyCaptor = ArgumentCaptor.forClass(EccInternalVerifyRequest.class); ArgumentCaptor<IkVerifyRequest> verifyCaptor = ArgumentCaptor.forClass(IkVerifyRequest.class);
InOrder inOrder = Mockito.inOrder(pcieCryptoService); InOrder inOrder = Mockito.inOrder(pcieCryptoService);
inOrder.verify(pcieCryptoService).digest(digestCaptor.capture()); inOrder.verify(pcieCryptoService).digest(digestCaptor.capture());
inOrder.verify(pcieCryptoService).eccInternalVerify(verifyCaptor.capture()); inOrder.verify(pcieCryptoService).verifyIk(verifyCaptor.capture());
Assertions.assertEquals(Gm0018AlgorithmIds.SM3, digestCaptor.getValue().getAlgId()); Assertions.assertEquals(Gm0018AlgorithmIds.SM3, digestCaptor.getValue().getAlgId());
Assertions.assertArrayEquals("1223".getBytes(StandardCharsets.UTF_8), digestCaptor.getValue().getData()); Assertions.assertArrayEquals("1223".getBytes(StandardCharsets.UTF_8), digestCaptor.getValue().getData());
Assertions.assertArrayEquals(digestResult.getData(), verifyCaptor.getValue().getData()); Assertions.assertArrayEquals(digestResult.getData(), verifyCaptor.getValue().getData());
Assertions.assertArrayEquals(new byte[] {(byte) 0xAA, (byte) 0xBB}, verifyCaptor.getValue().getSignature()); Assertions.assertArrayEquals(new byte[] {(byte) 0xAA, (byte) 0xBB}, verifyCaptor.getValue().getSignature());
Assertions.assertEquals(2, verifyCaptor.getValue().getKeyType());
} }
private static MasterKeyInitProperties configuredPins(String oldPinBase64, String newPinBase64) { private static MasterKeyInitProperties configuredPins(String oldPinBase64, String newPinBase64) {