fix:主密钥恢复

This commit is contained in:
waner 2026-05-15 17:09:27 +08:00
parent 9e4ba759e4
commit 8fa76cd99e
2 changed files with 58 additions and 35 deletions

View File

@ -1931,7 +1931,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
List<RecoverUserKeyRequest> userKeyRequests = requireUserKeyRequests(req.getUserKeyRequests()); List<RecoverUserKeyRequest> userKeyRequests = requireUserKeyRequests(req.getUserKeyRequests());
try { try {
return sessionTemplate.withSession("SDFE_RecoverMasterKeyMaterial", (lib, deviceHandle, sessionHandle) -> { DeviceStatusResult deviceStatus = sessionTemplate.withSession("SDFE_RecoverMasterKeyMaterial", (lib, deviceHandle, sessionHandle) -> {
sessionTemplate.ensureSuccess( sessionTemplate.ensureSuccess(
"SDFE_InitIdentify", "SDFE_InitIdentify",
lib.SDFE_InitIdentify(sessionHandle, oldPin, oldPin.length, newPin, newPin.length) lib.SDFE_InitIdentify(sessionHandle, oldPin, oldPin.length, newPin, newPin.length)
@ -1946,19 +1946,23 @@ public class JnaPcieCryptoService implements PcieCryptoService {
"SDFE_RecoverIK_EX", "SDFE_RecoverIK_EX",
lib.SDFE_RecoverIK_EX(sessionHandle, IK_KEY_TYPE_DEVICE, deviceIkComponent) lib.SDFE_RecoverIK_EX(sessionHandle, IK_KEY_TYPE_DEVICE, deviceIkComponent)
); );
DeviceStatusResult deviceStatus = readDeviceStatus(lib, sessionHandle); return readDeviceStatus(lib, sessionHandle);
});
byte[] seedMac = sessionTemplate.withSession("SDFE_RecoverUserKey", (lib, deviceHandle, sessionHandle) -> {
for (RecoverUserKeyRequest userKeyRequest : userKeyRequests) { for (RecoverUserKeyRequest userKeyRequest : userKeyRequests) {
recoverUserKeyInCurrentSession(lib, sessionHandle, userKeyRequest); recoverUserKeyInCurrentSession(lib, sessionHandle, userKeyRequest);
} }
sessionTemplate.ensureSuccess("SDFE_CheckLMK", lib.SDFE_CheckLMK(sessionHandle)); sessionTemplate.ensureSuccess("SDFE_CheckLMK", lib.SDFE_CheckLMK(sessionHandle));
byte[] mac = new byte[LMK_SEED_MAC_LENGTH]; byte[] mac = new byte[LMK_SEED_MAC_LENGTH];
sessionTemplate.ensureSuccess("SDFE_ExportLMKSeedMAC", lib.SDFE_ExportLMKSeedMAC(sessionHandle, mac)); sessionTemplate.ensureSuccess("SDFE_ExportLMKSeedMAC", lib.SDFE_ExportLMKSeedMAC(sessionHandle, mac));
return Arrays.copyOf(mac, mac.length);
MasterKeyRecoveryResult result = new MasterKeyRecoveryResult();
result.setDeviceStatus(deviceStatus);
result.setLmkSeedMac(Arrays.copyOf(mac, mac.length));
return result;
}); });
MasterKeyRecoveryResult result = new MasterKeyRecoveryResult();
result.setDeviceStatus(deviceStatus);
result.setLmkSeedMac(seedMac);
return result;
} finally { } finally {
wipe(oldPin); wipe(oldPin);
wipe(newPin); wipe(newPin);

View File

@ -11,6 +11,7 @@ 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.SdfeIkComponent;
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.model.BackupDataResult; import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult;
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.EccInternalDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalEncryptRequest; import com.cisd.tms.integration.crypto.pcie.model.EccInternalEncryptRequest;
@ -141,11 +142,12 @@ class JnaPcieCryptoServiceTest {
} }
@Test @Test
void shouldRecoverMasterKeyMaterialWithinSingleSessionAndReturnSeedMac() { void shouldRecoverMasterKeyMaterialWithUserKeysInSeparateSessionAndReturnSeedMac() {
PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class); PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class);
CryptoCardProperties properties = new CryptoCardProperties(); CryptoCardProperties properties = new CryptoCardProperties();
JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties); JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties);
Pointer session = Pointer.createConstant(2); Pointer restoreSession = Pointer.createConstant(2);
Pointer userKeySession = Pointer.createConstant(3);
byte[] seedMac = new byte[] {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; byte[] seedMac = new byte[] {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
MasterKeyRecoveryRequest request = new MasterKeyRecoveryRequest(); MasterKeyRecoveryRequest request = new MasterKeyRecoveryRequest();
@ -164,46 +166,63 @@ class JnaPcieCryptoServiceTest {
encKey.setEncryptedKey(new byte[] {0x11, 0x12, 0x13}); encKey.setEncryptedKey(new byte[] {0x11, 0x12, 0x13});
request.setUserKeyRequests(List.of(signKey, encKey)); request.setUserKeyRequests(List.of(signKey, encKey));
AtomicReference<PcieNativeLibrary> libRef = new AtomicReference<>(); AtomicReference<PcieNativeLibrary> restoreLibRef = new AtomicReference<>();
AtomicReference<PcieNativeLibrary> userKeyLibRef = new AtomicReference<>();
Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_RecoverMasterKeyMaterial"), Mockito.any())) Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_RecoverMasterKeyMaterial"), Mockito.any()))
.thenAnswer(invocation -> { .thenAnswer(invocation -> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<MasterKeyRecoveryResult> callback = PcieSessionTemplate.SessionCallback<DeviceStatusResult> callback =
(PcieSessionTemplate.SessionCallback<MasterKeyRecoveryResult>) invocation.getArgument(1); (PcieSessionTemplate.SessionCallback<DeviceStatusResult>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class); PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
libRef.set(lib); restoreLibRef.set(lib);
Mockito.when(lib.SDFE_InitIdentify(Mockito.eq(session), Mockito.any(), Mockito.anyInt(), Mockito.any(), Mockito.anyInt())).thenReturn(0); Mockito.when(lib.SDFE_InitIdentify(Mockito.eq(restoreSession), Mockito.any(), Mockito.anyInt(), Mockito.any(), Mockito.anyInt())).thenReturn(0);
Mockito.when(lib.SDFE_RecoverLMK_EX(Mockito.eq(session), Mockito.any(SdfeLmkComponent.class))).thenReturn(0); Mockito.when(lib.SDFE_RecoverLMK_EX(Mockito.eq(restoreSession), Mockito.any(SdfeLmkComponent.class))).thenReturn(0);
Mockito.when(lib.SDFE_LoadLMK(Mockito.eq(session))).thenReturn(0); Mockito.when(lib.SDFE_LoadLMK(Mockito.eq(restoreSession))).thenReturn(0);
Mockito.when(lib.SDFE_RecoverIK_EX(Mockito.eq(session), Mockito.eq(2), Mockito.any(SdfeIkComponent.class))).thenReturn(0); Mockito.when(lib.SDFE_RecoverIK_EX(Mockito.eq(restoreSession), Mockito.eq(2), Mockito.any(SdfeIkComponent.class))).thenReturn(0);
Mockito.when(lib.SDFE_RecoverIK_EX(Mockito.eq(session), Mockito.eq(1), Mockito.any(SdfeIkComponent.class))).thenReturn(0); Mockito.when(lib.SDFE_RecoverIK_EX(Mockito.eq(restoreSession), Mockito.eq(1), Mockito.any(SdfeIkComponent.class))).thenReturn(0);
Mockito.when(lib.SDFE_DeviceStatusGet(Mockito.eq(session), Mockito.any(SdfeDeviceStatus.class))).thenReturn(0); Mockito.when(lib.SDFE_DeviceStatusGet(Mockito.eq(restoreSession), Mockito.any(SdfeDeviceStatus.class))).thenReturn(0);
Mockito.when(lib.SDFE_RecoverUserKey(Mockito.eq(session), Mockito.eq(1), Mockito.anyInt(), Mockito.any(), Mockito.anyInt(), Mockito.anyByte())).thenReturn(0); return callback.apply(lib, Pointer.createConstant(1), restoreSession);
Mockito.when(lib.SDFE_CheckLMK(Mockito.eq(session))).thenReturn(0); });
Mockito.when(lib.SDFE_ExportLMKSeedMAC(Mockito.eq(session), Mockito.any())).thenAnswer(exportInvocation -> { Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_RecoverUserKey"), Mockito.any()))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
PcieSessionTemplate.SessionCallback<byte[]> callback =
(PcieSessionTemplate.SessionCallback<byte[]>) invocation.getArgument(1);
PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class);
userKeyLibRef.set(lib);
Mockito.when(lib.SDFE_RecoverUserKey(Mockito.eq(userKeySession), Mockito.eq(1), Mockito.anyInt(), Mockito.any(), Mockito.anyInt(), Mockito.anyByte())).thenReturn(0);
Mockito.when(lib.SDFE_CheckLMK(Mockito.eq(userKeySession))).thenReturn(0);
Mockito.when(lib.SDFE_ExportLMKSeedMAC(Mockito.eq(userKeySession), Mockito.any())).thenAnswer(exportInvocation -> {
byte[] out = exportInvocation.getArgument(1); byte[] out = exportInvocation.getArgument(1);
System.arraycopy(seedMac, 0, out, 0, seedMac.length); System.arraycopy(seedMac, 0, out, 0, seedMac.length);
return 0; return 0;
}); });
return callback.apply(lib, Pointer.createConstant(1), session); return callback.apply(lib, Pointer.createConstant(1), userKeySession);
}); });
MasterKeyRecoveryResult result = service.recoverMasterKeyMaterial(request); MasterKeyRecoveryResult result = service.recoverMasterKeyMaterial(request);
Assertions.assertArrayEquals(seedMac, result.getLmkSeedMac()); Assertions.assertArrayEquals(seedMac, result.getLmkSeedMac());
Assertions.assertNotNull(result.getDeviceStatus()); Assertions.assertNotNull(result.getDeviceStatus());
Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_RecoverMasterKeyMaterial"), Mockito.any()); InOrder sessionOrder = Mockito.inOrder(sessionTemplate);
PcieNativeLibrary lib = libRef.get(); sessionOrder.verify(sessionTemplate).withSession(Mockito.eq("SDFE_RecoverMasterKeyMaterial"), Mockito.any());
InOrder inOrder = Mockito.inOrder(lib); sessionOrder.verify(sessionTemplate).withSession(Mockito.eq("SDFE_RecoverUserKey"), Mockito.any());
inOrder.verify(lib).SDFE_InitIdentify(Mockito.eq(session), Mockito.any(), Mockito.anyInt(), Mockito.any(), Mockito.anyInt());
inOrder.verify(lib).SDFE_RecoverLMK_EX(Mockito.eq(session), Mockito.any(SdfeLmkComponent.class)); PcieNativeLibrary restoreLib = restoreLibRef.get();
inOrder.verify(lib).SDFE_LoadLMK(Mockito.eq(session)); InOrder restoreOrder = Mockito.inOrder(restoreLib);
inOrder.verify(lib).SDFE_RecoverIK_EX(Mockito.eq(session), Mockito.eq(2), Mockito.any(SdfeIkComponent.class)); restoreOrder.verify(restoreLib).SDFE_InitIdentify(Mockito.eq(restoreSession), Mockito.any(), Mockito.anyInt(), Mockito.any(), Mockito.anyInt());
inOrder.verify(lib).SDFE_RecoverIK_EX(Mockito.eq(session), Mockito.eq(1), Mockito.any(SdfeIkComponent.class)); restoreOrder.verify(restoreLib).SDFE_RecoverLMK_EX(Mockito.eq(restoreSession), Mockito.any(SdfeLmkComponent.class));
inOrder.verify(lib).SDFE_DeviceStatusGet(Mockito.eq(session), Mockito.any(SdfeDeviceStatus.class)); restoreOrder.verify(restoreLib).SDFE_LoadLMK(Mockito.eq(restoreSession));
inOrder.verify(lib, Mockito.times(2)).SDFE_RecoverUserKey(Mockito.eq(session), Mockito.eq(1), Mockito.anyInt(), Mockito.any(), Mockito.anyInt(), Mockito.anyByte()); restoreOrder.verify(restoreLib).SDFE_RecoverIK_EX(Mockito.eq(restoreSession), Mockito.eq(2), Mockito.any(SdfeIkComponent.class));
inOrder.verify(lib).SDFE_CheckLMK(Mockito.eq(session)); restoreOrder.verify(restoreLib).SDFE_RecoverIK_EX(Mockito.eq(restoreSession), Mockito.eq(1), Mockito.any(SdfeIkComponent.class));
inOrder.verify(lib).SDFE_ExportLMKSeedMAC(Mockito.eq(session), Mockito.any()); restoreOrder.verify(restoreLib).SDFE_DeviceStatusGet(Mockito.eq(restoreSession), Mockito.any(SdfeDeviceStatus.class));
Mockito.verify(restoreLib, Mockito.never()).SDFE_RecoverUserKey(Mockito.any(), Mockito.anyInt(), Mockito.anyInt(), Mockito.any(), Mockito.anyInt(), Mockito.anyByte());
PcieNativeLibrary userKeyLib = userKeyLibRef.get();
InOrder userKeyOrder = Mockito.inOrder(userKeyLib);
userKeyOrder.verify(userKeyLib, Mockito.times(2)).SDFE_RecoverUserKey(Mockito.eq(userKeySession), Mockito.eq(1), Mockito.anyInt(), Mockito.any(), Mockito.anyInt(), Mockito.anyByte());
userKeyOrder.verify(userKeyLib).SDFE_CheckLMK(Mockito.eq(userKeySession));
userKeyOrder.verify(userKeyLib).SDFE_ExportLMKSeedMAC(Mockito.eq(userKeySession), Mockito.any());
} }
@Test @Test