feat:补充算法校验

This commit is contained in:
waner
2026-03-02 10:09:41 +08:00
parent 852d517512
commit 1bc24d4408
5 changed files with 285 additions and 169 deletions
+15 -1
View File
@@ -193,6 +193,21 @@ mvn -q -DskipTests compile
mvn -q test mvn -q test
``` ```
## PCIe Real-Card Smoke
- Checklist: `docs/plans/2026-02-28-pcie-realcard-smoke-checklist.md`
- Script template: `scripts/pcie_realcard_smoke.sh`
Example:
```bash
export BASE_URL=http://127.0.0.1:8080
export INTERNAL_TOKEN=change-me-internal-token
export ALG_SM3=1
export ALG_SM4_ECB=1025
./scripts/pcie_realcard_smoke.sh
```
- CI is pinned to JDK 17 via `.github/workflows/ci.yml`. - CI is pinned to JDK 17 via `.github/workflows/ci.yml`.
- Maven Surefire preloads Mockito javaagent to avoid dynamic self-attach failures on newer JDKs. - Maven Surefire preloads Mockito javaagent to avoid dynamic self-attach failures on newer JDKs.
@@ -203,4 +218,3 @@ mvn -q test
- Basic auth interceptors for internal/openapi are in place. - Basic auth interceptors for internal/openapi are in place.
- `init/auth/device/sign/system` modules have runnable skeleton controllers and services. - `init/auth/device/sign/system` modules have runnable skeleton controllers and services.
- `init/auth/device` modules include mapper+xml+repository-impl+DDL skeleton for TiDB. - `init/auth/device` modules include mapper+xml+repository-impl+DDL skeleton for TiDB.
>>>>>>> aeb6a4d (初始化项目)
@@ -14,6 +14,7 @@ public class CryptoCardProperties {
private Mode mode = Mode.MOCK; private Mode mode = Mode.MOCK;
private String vendorLibPath; private String vendorLibPath;
private String vendorLibName = "swsdsdf"; private String vendorLibName = "swsdsdf";
private boolean strictAlgIdValidation = true;
public boolean isEnabled() { public boolean isEnabled() {
return enabled; return enabled;
@@ -46,4 +47,12 @@ public class CryptoCardProperties {
public void setVendorLibName(String vendorLibName) { public void setVendorLibName(String vendorLibName) {
this.vendorLibName = vendorLibName; this.vendorLibName = vendorLibName;
} }
public boolean isStrictAlgIdValidation() {
return strictAlgIdValidation;
}
public void setStrictAlgIdValidation(boolean strictAlgIdValidation) {
this.strictAlgIdValidation = strictAlgIdValidation;
}
} }
@@ -25,8 +25,11 @@ public class PcieCryptoServiceConfiguration {
} }
if (properties.getMode() == CryptoCardProperties.Mode.JNA) { if (properties.getMode() == CryptoCardProperties.Mode.JNA) {
log.info("PCIe crypto service enabled in JNA mode"); log.info(
return new JnaPcieCryptoService(sessionTemplate); "PCIe crypto service enabled in JNA mode, strictAlgIdValidation={}",
properties.isStrictAlgIdValidation()
);
return new JnaPcieCryptoService(sessionTemplate, properties);
} }
log.info("PCIe crypto service fallback to mock, current mode={}", properties.getMode()); log.info("PCIe crypto service fallback to mock, current mode={}", properties.getMode());
@@ -1,5 +1,7 @@
package com.cisd.tms.integration.crypto.pcie.service; package com.cisd.tms.integration.crypto.pcie.service;
import com.cisd.tms.integration.crypto.config.CryptoCardProperties;
import com.cisd.tms.integration.crypto.pcie.Gm0018AlgorithmIds;
import com.cisd.tms.integration.crypto.pcie.PcieCryptoException; import com.cisd.tms.integration.crypto.pcie.PcieCryptoException;
import com.cisd.tms.integration.crypto.pcie.PcieKeyState; import com.cisd.tms.integration.crypto.pcie.PcieKeyState;
import com.cisd.tms.integration.crypto.pcie.PcieSessionTemplate; import com.cisd.tms.integration.crypto.pcie.PcieSessionTemplate;
@@ -91,9 +93,11 @@ public class JnaPcieCryptoService implements PcieCryptoService {
private static final int ECC_CIPHER_PREFIX_LENGTH = (EccRefPublicKey.MAX_LEN * 2) + 32 + Integer.BYTES; private static final int ECC_CIPHER_PREFIX_LENGTH = (EccRefPublicKey.MAX_LEN * 2) + 32 + Integer.BYTES;
private final PcieSessionTemplate sessionTemplate; private final PcieSessionTemplate sessionTemplate;
private final boolean strictAlgIdValidation;
public JnaPcieCryptoService(PcieSessionTemplate sessionTemplate) { public JnaPcieCryptoService(PcieSessionTemplate sessionTemplate, CryptoCardProperties properties) {
this.sessionTemplate = sessionTemplate; this.sessionTemplate = sessionTemplate;
this.strictAlgIdValidation = properties.isStrictAlgIdValidation();
} }
@Override @Override
@@ -169,13 +173,18 @@ public class JnaPcieCryptoService implements PcieCryptoService {
byte[] oldPinValue = requireNonEmptyBytes("oldPin", oldPin); byte[] oldPinValue = requireNonEmptyBytes("oldPin", oldPin);
byte[] newPinValue = requireNonEmptyBytes("newPin", newPin); byte[] newPinValue = requireNonEmptyBytes("newPin", newPin);
sessionTemplate.withSession("SDFE_InitIdentify", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess( sessionTemplate.withSession("SDFE_InitIdentify", (lib, deviceHandle, sessionHandle) -> {
"SDFE_InitIdentify", sessionTemplate.ensureSuccess(
lib.SDFE_InitIdentify(sessionHandle, oldPinValue, oldPinValue.length, newPinValue, newPinValue.length) "SDFE_InitIdentify",
); lib.SDFE_InitIdentify(sessionHandle, oldPinValue, oldPinValue.length, newPinValue, newPinValue.length)
return null; );
}); return null;
});
} finally {
wipe(oldPinValue);
wipe(newPinValue);
}
} }
@Override @Override
@@ -216,20 +225,25 @@ public class JnaPcieCryptoService implements PcieCryptoService {
byte[] oldPassword = requireNonEmptyBytes("oldPassword", req.getOldPassword()); byte[] oldPassword = requireNonEmptyBytes("oldPassword", req.getOldPassword());
byte[] newPassword = requireNonEmptyBytes("newPassword", req.getNewPassword()); byte[] newPassword = requireNonEmptyBytes("newPassword", req.getNewPassword());
sessionTemplate.withSession("SDFE_ChangePrivateKeyAccessPassword", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess( sessionTemplate.withSession("SDFE_ChangePrivateKeyAccessPassword", (lib, deviceHandle, sessionHandle) -> {
"SDFE_ChangePrivateKeyAccessPassword", sessionTemplate.ensureSuccess(
lib.SDFE_ChangePrivateKeyAccessPassword( "SDFE_ChangePrivateKeyAccessPassword",
sessionHandle, lib.SDFE_ChangePrivateKeyAccessPassword(
keyIndex, sessionHandle,
oldPassword, keyIndex,
oldPassword.length, oldPassword,
newPassword, oldPassword.length,
newPassword.length newPassword,
) newPassword.length
); )
return null; );
}); return null;
});
} finally {
wipe(oldPassword);
wipe(newPassword);
}
} }
@Override @Override
@@ -238,13 +252,17 @@ public class JnaPcieCryptoService implements PcieCryptoService {
int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex()); int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
byte[] password = requireNonEmptyBytes("password", req.getPassword()); byte[] password = requireNonEmptyBytes("password", req.getPassword());
sessionTemplate.withSession("SDF_GetPrivateKeyAccessRight", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess( sessionTemplate.withSession("SDF_GetPrivateKeyAccessRight", (lib, deviceHandle, sessionHandle) -> {
"SDF_GetPrivateKeyAccessRight", sessionTemplate.ensureSuccess(
lib.SDF_GetPrivateKeyAccessRight(sessionHandle, keyIndex, password, password.length) "SDF_GetPrivateKeyAccessRight",
); lib.SDF_GetPrivateKeyAccessRight(sessionHandle, keyIndex, password, password.length)
return null; );
}); return null;
});
} finally {
wipe(password);
}
} }
@Override @Override
@@ -352,13 +370,17 @@ public class JnaPcieCryptoService implements PcieCryptoService {
int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex()); int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
byte[] keyData = requireNonEmptyBytes("keyData", req.getKeyData()); byte[] keyData = requireNonEmptyBytes("keyData", req.getKeyData());
sessionTemplate.withSession("SDFE_ImportKEK", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess( sessionTemplate.withSession("SDFE_ImportKEK", (lib, deviceHandle, sessionHandle) -> {
"SDFE_ImportKEK", sessionTemplate.ensureSuccess(
lib.SDFE_ImportKEK(sessionHandle, keyIndex, keyData, keyData.length) "SDFE_ImportKEK",
); lib.SDFE_ImportKEK(sessionHandle, keyIndex, keyData, keyData.length)
return null; );
}); return null;
});
} finally {
wipe(keyData);
}
} }
@Override @Override
@@ -426,20 +448,24 @@ public class JnaPcieCryptoService implements PcieCryptoService {
throw new IllegalArgumentException("storeFlag must be 0 or 1"); throw new IllegalArgumentException("storeFlag must be 0 or 1");
} }
sessionTemplate.withSession("SDFE_RecoverUserKey", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess( sessionTemplate.withSession("SDFE_RecoverUserKey", (lib, deviceHandle, sessionHandle) -> {
"SDFE_RecoverUserKey", sessionTemplate.ensureSuccess(
lib.SDFE_RecoverUserKey( "SDFE_RecoverUserKey",
sessionHandle, lib.SDFE_RecoverUserKey(
keyIndex, sessionHandle,
keyType, keyIndex,
encryptedKey, keyType,
encryptedKey.length, encryptedKey,
(byte) storeFlag encryptedKey.length,
) (byte) storeFlag
); )
return null; );
}); return null;
});
} finally {
wipe(encryptedKey);
}
} }
@Override @Override
@@ -461,13 +487,17 @@ public class JnaPcieCryptoService implements PcieCryptoService {
int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex()); int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
byte[] encryptedKey = requireNonEmptyBytes("encryptedKey", req.getEncryptedKey()); byte[] encryptedKey = requireNonEmptyBytes("encryptedKey", req.getEncryptedKey());
sessionTemplate.withSession("SDFE_RecoverKEK", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess( sessionTemplate.withSession("SDFE_RecoverKEK", (lib, deviceHandle, sessionHandle) -> {
"SDFE_RecoverKEK", sessionTemplate.ensureSuccess(
lib.SDFE_RecoverKEK(sessionHandle, keyIndex, encryptedKey, encryptedKey.length) "SDFE_RecoverKEK",
); lib.SDFE_RecoverKEK(sessionHandle, keyIndex, encryptedKey, encryptedKey.length)
return null; );
}); return null;
});
} finally {
wipe(encryptedKey);
}
} }
@Override @Override
@@ -506,13 +536,17 @@ public class JnaPcieCryptoService implements PcieCryptoService {
public void restoreAllKey(byte[] keyImage) { public void restoreAllKey(byte[] keyImage) {
byte[] safeKeyImage = requireNonEmptyBytes("keyImage", keyImage); byte[] safeKeyImage = requireNonEmptyBytes("keyImage", keyImage);
sessionTemplate.withSession("SDFE_RestoryKey", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess( sessionTemplate.withSession("SDFE_RestoryKey", (lib, deviceHandle, sessionHandle) -> {
"SDFE_RestoryKey", sessionTemplate.ensureSuccess(
lib.SDFE_RestoryKey(sessionHandle, safeKeyImage, safeKeyImage.length) "SDFE_RestoryKey",
); lib.SDFE_RestoryKey(sessionHandle, safeKeyImage, safeKeyImage.length)
return null; );
}); return null;
});
} finally {
wipe(safeKeyImage);
}
} }
@Override @Override
@@ -563,10 +597,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
EnvelopedKeyBlob blob = toEnvelopedKeyBlob("envelopedKeyBlob", req.getEnvelopedKeyBlob()); EnvelopedKeyBlob blob = toEnvelopedKeyBlob("envelopedKeyBlob", req.getEnvelopedKeyBlob());
sessionTemplate.withSession("SDFE_ImportEncKeyPair_ECC", (lib, deviceHandle, sessionHandle) -> { sessionTemplate.withSession("SDFE_ImportEncKeyPair_ECC", (lib, deviceHandle, sessionHandle) -> {
sessionTemplate.ensureSuccess( sessionTemplate.ensureSuccess("SDFE_ImportEncKeyPair_ECC", lib.SDFE_ImportEncKeyPair_ECC(sessionHandle, keyIndex, blob));
"SDFE_ImportEncKeyPair_ECC",
lib.SDFE_ImportEncKeyPair_ECC(sessionHandle, keyIndex, blob)
);
return null; return null;
}); });
} }
@@ -575,25 +606,30 @@ public class JnaPcieCryptoService implements PcieCryptoService {
public void importEncryptedKeyPairRsa(ImportEncKeyPairRsaRequest request) { public void importEncryptedKeyPairRsa(ImportEncKeyPairRsaRequest request) {
ImportEncKeyPairRsaRequest req = requireRequest("request", request); ImportEncKeyPairRsaRequest req = requireRequest("request", request);
int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex()); int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
int symAlgId = requirePositive("symAlgId", req.getSymAlgId()); int symAlgId = requireValidAlgId("symAlgId", req.getSymAlgId());
byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey()); byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
byte[] encryptedData = requireNonEmptyBytes("encryptedData", req.getEncryptedData()); byte[] encryptedData = requireNonEmptyBytes("encryptedData", req.getEncryptedData());
sessionTemplate.withSession("SDFE_ImportEncKeyPair_RSA", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess( sessionTemplate.withSession("SDFE_ImportEncKeyPair_RSA", (lib, deviceHandle, sessionHandle) -> {
"SDFE_ImportEncKeyPair_RSA", sessionTemplate.ensureSuccess(
lib.SDFE_ImportEncKeyPair_RSA( "SDFE_ImportEncKeyPair_RSA",
sessionHandle, lib.SDFE_ImportEncKeyPair_RSA(
keyIndex, sessionHandle,
symAlgId, keyIndex,
wrappedKey, symAlgId,
wrappedKey.length, wrappedKey,
encryptedData, wrappedKey.length,
encryptedData.length encryptedData,
) encryptedData.length
); )
return null; );
}); return null;
});
} finally {
wipe(wrappedKey);
wipe(encryptedData);
}
} }
@Override @Override
@@ -716,7 +752,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
@Override @Override
public StandardKeyPairResult generateStandardEccKeyPair(GenerateStandardEccKeyPairRequest request) { public StandardKeyPairResult generateStandardEccKeyPair(GenerateStandardEccKeyPairRequest request) {
GenerateStandardEccKeyPairRequest req = requireRequest("request", request); GenerateStandardEccKeyPairRequest req = requireRequest("request", request);
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
int keyBits = requirePositive("keyBits", req.getKeyBits()); int keyBits = requirePositive("keyBits", req.getKeyBits());
int publicKeySize = requirePositive("publicKeyBufferSize", req.getPublicKeyBufferSize()); int publicKeySize = requirePositive("publicKeyBufferSize", req.getPublicKeyBufferSize());
int privateKeySize = requirePositive("privateKeyBufferSize", req.getPrivateKeyBufferSize()); int privateKeySize = requirePositive("privateKeyBufferSize", req.getPrivateKeyBufferSize());
@@ -742,7 +778,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
public BackupDataResult generateKeyWithKek(GenerateKeyWithKekRequest request) { public BackupDataResult generateKeyWithKek(GenerateKeyWithKekRequest request) {
GenerateKeyWithKekRequest req = requireRequest("request", request); GenerateKeyWithKekRequest req = requireRequest("request", request);
int keyBits = requirePositive("keyBits", req.getKeyBits()); int keyBits = requirePositive("keyBits", req.getKeyBits());
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
int kekIndex = requireNonNegative("kekIndex", req.getKekIndex()); int kekIndex = requireNonNegative("kekIndex", req.getKekIndex());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize()); int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
@@ -989,7 +1025,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
public BackupDataResult generateKeyWithEpkEcc(GenerateKeyWithEpkEccRequest request) { public BackupDataResult generateKeyWithEpkEcc(GenerateKeyWithEpkEccRequest request) {
GenerateKeyWithEpkEccRequest req = requireRequest("request", request); GenerateKeyWithEpkEccRequest req = requireRequest("request", request);
int keyBits = requirePositive("keyBits", req.getKeyBits()); int keyBits = requirePositive("keyBits", req.getKeyBits());
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob()); EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize()); int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
@@ -1067,7 +1103,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
public BackupDataResult exchangeDigitEnvelopeBaseOnEcc(ExchangeDigitEnvelopeEccRequest request) { public BackupDataResult exchangeDigitEnvelopeBaseOnEcc(ExchangeDigitEnvelopeEccRequest request) {
ExchangeDigitEnvelopeEccRequest req = requireRequest("request", request); ExchangeDigitEnvelopeEccRequest req = requireRequest("request", request);
int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex()); int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob()); EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
EccCipher inputEnvelopeBlob = toEccCipher("inputEnvelopeBlob", req.getInputEnvelopeBlob()); EccCipher inputEnvelopeBlob = toEccCipher("inputEnvelopeBlob", req.getInputEnvelopeBlob());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize()); int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
@@ -1213,6 +1249,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
result.setSponsorPublicKeyLength(sponsorPublicKeyBytes.length); result.setSponsorPublicKeyLength(sponsorPublicKeyBytes.length);
result.setSponsorTmpPublicKey(sponsorTmpPublicKeyBytes); result.setSponsorTmpPublicKey(sponsorTmpPublicKeyBytes);
result.setSponsorTmpPublicKeyLength(sponsorTmpPublicKeyBytes.length); result.setSponsorTmpPublicKeyLength(sponsorTmpPublicKeyBytes.length);
// SDF_GenerateKeyWithECC returns a session key handle, not plaintext key bytes.
result.setSessionKey(new byte[0]); result.setSessionKey(new byte[0]);
result.setSessionKeyLength(0); result.setSessionKeyLength(0);
result.setSessionKeyGenerated(keyHandleRef.getValue() != null); result.setSessionKeyGenerated(keyHandleRef.getValue() != null);
@@ -1247,7 +1284,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
@Override @Override
public BackupDataResult eccExternalSign(EccExternalSignRequest request) { public BackupDataResult eccExternalSign(EccExternalSignRequest request) {
EccExternalSignRequest req = requireRequest("request", request); EccExternalSignRequest req = requireRequest("request", request);
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
EccRefPrivateKey privateKeyBlob = toEccRefPrivateKey("privateKeyBlob", req.getPrivateKeyBlob()); EccRefPrivateKey privateKeyBlob = toEccRefPrivateKey("privateKeyBlob", req.getPrivateKeyBlob());
byte[] data = requireBytes("data", req.getData()); byte[] data = requireBytes("data", req.getData());
int signatureBufferSize = requirePositive("signatureBufferSize", req.getSignatureBufferSize()); int signatureBufferSize = requirePositive("signatureBufferSize", req.getSignatureBufferSize());
@@ -1285,7 +1322,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
@Override @Override
public void eccExternalVerify(EccExternalVerifyRequest request) { public void eccExternalVerify(EccExternalVerifyRequest request) {
EccExternalVerifyRequest req = requireRequest("request", request); EccExternalVerifyRequest req = requireRequest("request", request);
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob()); EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
byte[] data = requireBytes("data", req.getData()); byte[] data = requireBytes("data", req.getData());
EccSignature signature = toEccSignature("signature", req.getSignature()); EccSignature signature = toEccSignature("signature", req.getSignature());
@@ -1302,7 +1339,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
@Override @Override
public BackupDataResult eccExternalEncrypt(EccExternalEncryptRequest request) { public BackupDataResult eccExternalEncrypt(EccExternalEncryptRequest request) {
EccExternalEncryptRequest req = requireRequest("request", request); EccExternalEncryptRequest req = requireRequest("request", request);
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob()); EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
byte[] data = requireBytes("data", req.getData()); byte[] data = requireBytes("data", req.getData());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize()); int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
@@ -1324,7 +1361,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
@Override @Override
public BackupDataResult eccExternalDecrypt(EccExternalDecryptRequest request) { public BackupDataResult eccExternalDecrypt(EccExternalDecryptRequest request) {
EccExternalDecryptRequest req = requireRequest("request", request); EccExternalDecryptRequest req = requireRequest("request", request);
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
EccRefPrivateKey privateKeyBlob = toEccRefPrivateKey("privateKeyBlob", req.getPrivateKeyBlob()); EccRefPrivateKey privateKeyBlob = toEccRefPrivateKey("privateKeyBlob", req.getPrivateKeyBlob());
EccCipher encryptedData = toEccCipher("encryptedData", req.getEncryptedData()); EccCipher encryptedData = toEccCipher("encryptedData", req.getEncryptedData());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize()); int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
@@ -1343,7 +1380,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
@Override @Override
public BackupDataResult encryptWithPlainKey(SymmetricCryptoRequest request) { public BackupDataResult encryptWithPlainKey(SymmetricCryptoRequest request) {
SymmetricCryptoRequest req = requireRequest("request", request); SymmetricCryptoRequest req = requireRequest("request", request);
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
byte[] key = requireNonEmptyBytes("key", req.getKey()); byte[] key = requireNonEmptyBytes("key", req.getKey());
byte[] data = requireBytes("data", req.getData()); byte[] data = requireBytes("data", req.getData());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize()); int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
@@ -1365,7 +1402,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
@Override @Override
public BackupDataResult decryptWithPlainKey(SymmetricCryptoRequest request) { public BackupDataResult decryptWithPlainKey(SymmetricCryptoRequest request) {
SymmetricCryptoRequest req = requireRequest("request", request); SymmetricCryptoRequest req = requireRequest("request", request);
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
byte[] key = requireNonEmptyBytes("key", req.getKey()); byte[] key = requireNonEmptyBytes("key", req.getKey());
byte[] data = requireBytes("data", req.getData()); byte[] data = requireBytes("data", req.getData());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize()); int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
@@ -1387,7 +1424,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
@Override @Override
public BackupDataResult encryptWithKekWrappedKey(SymmetricKekCryptoRequest request) { public BackupDataResult encryptWithKekWrappedKey(SymmetricKekCryptoRequest request) {
SymmetricKekCryptoRequest req = requireRequest("request", request); SymmetricKekCryptoRequest req = requireRequest("request", request);
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
int kekIndex = requireNonNegative("kekIndex", req.getKekIndex()); int kekIndex = requireNonNegative("kekIndex", req.getKekIndex());
byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey()); byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
byte[] data = requireBytes("data", req.getData()); byte[] data = requireBytes("data", req.getData());
@@ -1410,7 +1447,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
@Override @Override
public BackupDataResult decryptWithKekWrappedKey(SymmetricKekCryptoRequest request) { public BackupDataResult decryptWithKekWrappedKey(SymmetricKekCryptoRequest request) {
SymmetricKekCryptoRequest req = requireRequest("request", request); SymmetricKekCryptoRequest req = requireRequest("request", request);
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
int kekIndex = requireNonNegative("kekIndex", req.getKekIndex()); int kekIndex = requireNonNegative("kekIndex", req.getKekIndex());
byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey()); byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
byte[] data = requireBytes("data", req.getData()); byte[] data = requireBytes("data", req.getData());
@@ -1433,7 +1470,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
@Override @Override
public BackupDataResult calculateMacWithPlainKey(MacCalcRequest request) { public BackupDataResult calculateMacWithPlainKey(MacCalcRequest request) {
MacCalcRequest req = requireRequest("request", request); MacCalcRequest req = requireRequest("request", request);
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
byte[] key = requireNonEmptyBytes("key", req.getKey()); byte[] key = requireNonEmptyBytes("key", req.getKey());
byte[] data = requireBytes("data", req.getData()); byte[] data = requireBytes("data", req.getData());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize()); int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
@@ -1455,7 +1492,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
@Override @Override
public BackupDataResult digest(DigestRequest request) { public BackupDataResult digest(DigestRequest request) {
DigestRequest req = requireRequest("request", request); DigestRequest req = requireRequest("request", request);
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
byte[] data = requireBytes("data", req.getData()); byte[] data = requireBytes("data", req.getData());
int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize()); int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
@@ -1474,30 +1511,34 @@ public class JnaPcieCryptoService implements PcieCryptoService {
@Override @Override
public HmacResult hmac(HmacRequest request) { public HmacResult hmac(HmacRequest request) {
HmacRequest req = requireRequest("request", request); HmacRequest req = requireRequest("request", request);
int algId = requirePositive("algId", req.getAlgId()); int algId = requireValidAlgId("algId", req.getAlgId());
byte[] key = requireNonEmptyBytes("key", req.getKey()); byte[] key = requireNonEmptyBytes("key", req.getKey());
byte[] data = requireBytes("data", req.getData()); byte[] data = requireBytes("data", req.getData());
return sessionTemplate.withSession("SDFE_Hmac", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess("SDFE_HmacInit", lib.SDFE_HmacInit(sessionHandle, algId, key, key.length)); return sessionTemplate.withSession("SDFE_Hmac", (lib, deviceHandle, sessionHandle) -> {
if (data.length > 0) { sessionTemplate.ensureSuccess("SDFE_HmacInit", lib.SDFE_HmacInit(sessionHandle, algId, key, key.length));
sessionTemplate.ensureSuccess("SDFE_HmacUpdate", lib.SDFE_HmacUpdate(sessionHandle, data, data.length)); if (data.length > 0) {
} sessionTemplate.ensureSuccess("SDFE_HmacUpdate", lib.SDFE_HmacUpdate(sessionHandle, data, data.length));
}
byte[] out = new byte[HMAC_MAX_LENGTH]; byte[] out = new byte[HMAC_MAX_LENGTH];
IntByReference outLen = new IntByReference(out.length); IntByReference outLen = new IntByReference(out.length);
sessionTemplate.ensureSuccess("SDFE_HmacFinal", lib.SDFE_HmacFinal(sessionHandle, out, outLen)); sessionTemplate.ensureSuccess("SDFE_HmacFinal", lib.SDFE_HmacFinal(sessionHandle, out, outLen));
int length = outLen.getValue(); int length = outLen.getValue();
if (length <= 0 || length > out.length) { if (length <= 0 || length > out.length) {
throw new PcieCryptoException("SDFE_HmacFinal", -1, "native returned invalid HMAC length: " + length); throw new PcieCryptoException("SDFE_HmacFinal", -1, "native returned invalid HMAC length: " + length);
} }
HmacResult result = new HmacResult(); HmacResult result = new HmacResult();
result.setHmacLength(length); result.setHmacLength(length);
result.setHmac(Arrays.copyOf(out, length)); result.setHmac(Arrays.copyOf(out, length));
return result; return result;
}); });
} finally {
wipe(key);
}
} }
@Override @Override
@@ -1641,20 +1682,25 @@ public class JnaPcieCryptoService implements PcieCryptoService {
byte[] ukeyPin = requireNonEmptyBytes("ukeyPin", req.getUkeyPin()); byte[] ukeyPin = requireNonEmptyBytes("ukeyPin", req.getUkeyPin());
byte[] loginPin = requireNonEmptyBytes("loginPin", req.getLoginPin()); byte[] loginPin = requireNonEmptyBytes("loginPin", req.getLoginPin());
sessionTemplate.withSession("SDFE_GenerateUkey", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess( sessionTemplate.withSession("SDFE_GenerateUkey", (lib, deviceHandle, sessionHandle) -> {
"SDFE_GenerateUkey", sessionTemplate.ensureSuccess(
lib.SDFE_GenerateUkey( "SDFE_GenerateUkey",
sessionHandle, lib.SDFE_GenerateUkey(
(byte) adminIndex, sessionHandle,
ukeyPin, (byte) adminIndex,
ukeyPin.length, ukeyPin,
loginPin, ukeyPin.length,
loginPin.length loginPin,
) loginPin.length
); )
return null; );
}); return null;
});
} finally {
wipe(ukeyPin);
wipe(loginPin);
}
} }
@Override @Override
@@ -1663,13 +1709,18 @@ public class JnaPcieCryptoService implements PcieCryptoService {
byte[] ukeyPin = requireNonEmptyBytes("ukeyPin", req.getUkeyPin()); byte[] ukeyPin = requireNonEmptyBytes("ukeyPin", req.getUkeyPin());
byte[] loginPin = requireNonEmptyBytes("loginPin", req.getLoginPin()); byte[] loginPin = requireNonEmptyBytes("loginPin", req.getLoginPin());
sessionTemplate.withSession("SDFE_LoginUkey", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess( sessionTemplate.withSession("SDFE_LoginUkey", (lib, deviceHandle, sessionHandle) -> {
"SDFE_LoginUkey", sessionTemplate.ensureSuccess(
lib.SDFE_LoginUkey(sessionHandle, ukeyPin, ukeyPin.length, loginPin, loginPin.length) "SDFE_LoginUkey",
); lib.SDFE_LoginUkey(sessionHandle, ukeyPin, ukeyPin.length, loginPin, loginPin.length)
return null; );
}); return null;
});
} finally {
wipe(ukeyPin);
wipe(loginPin);
}
} }
@Override @Override
@@ -1679,13 +1730,18 @@ public class JnaPcieCryptoService implements PcieCryptoService {
byte[] oldPin = requireNonEmptyBytes("oldPin", req.getOldPin()); byte[] oldPin = requireNonEmptyBytes("oldPin", req.getOldPin());
byte[] newPin = requireNonEmptyBytes("newPin", req.getNewPin()); byte[] newPin = requireNonEmptyBytes("newPin", req.getNewPin());
sessionTemplate.withSession("SDFE_ChangeUkeyPin", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess( sessionTemplate.withSession("SDFE_ChangeUkeyPin", (lib, deviceHandle, sessionHandle) -> {
"SDFE_ChangeUkeyPin", sessionTemplate.ensureSuccess(
lib.SDFE_ChangeUkeyPin(sessionHandle, pinType, oldPin, oldPin.length, newPin, newPin.length) "SDFE_ChangeUkeyPin",
); lib.SDFE_ChangeUkeyPin(sessionHandle, pinType, oldPin, oldPin.length, newPin, newPin.length)
return null; );
}); return null;
});
} finally {
wipe(oldPin);
wipe(newPin);
}
} }
@Override @Override
@@ -1694,23 +1750,32 @@ public class JnaPcieCryptoService implements PcieCryptoService {
byte[] adminPin = requireNonEmptyBytes("adminPin", req.getAdminPin()); byte[] adminPin = requireNonEmptyBytes("adminPin", req.getAdminPin());
byte[] userPin = requireNonEmptyBytes("userPin", req.getUserPin()); byte[] userPin = requireNonEmptyBytes("userPin", req.getUserPin());
sessionTemplate.withSession("SDFE_UnlockUkey", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess( sessionTemplate.withSession("SDFE_UnlockUkey", (lib, deviceHandle, sessionHandle) -> {
"SDFE_UnlockUkey", sessionTemplate.ensureSuccess(
lib.SDFE_UnlockUkey(sessionHandle, adminPin, adminPin.length, userPin, userPin.length) "SDFE_UnlockUkey",
); lib.SDFE_UnlockUkey(sessionHandle, adminPin, adminPin.length, userPin, userPin.length)
return null; );
}); return null;
});
} finally {
wipe(adminPin);
wipe(userPin);
}
} }
@Override @Override
public void readLmkComponent(byte[] ukeyPin) { public void readLmkComponent(byte[] ukeyPin) {
byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin); byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin);
sessionTemplate.withSession("SDFE_ReadLMKComponent", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess("SDFE_ReadLMKComponent", lib.SDFE_ReadLMKComponent(sessionHandle, pin, pin.length)); sessionTemplate.withSession("SDFE_ReadLMKComponent", (lib, deviceHandle, sessionHandle) -> {
return null; sessionTemplate.ensureSuccess("SDFE_ReadLMKComponent", lib.SDFE_ReadLMKComponent(sessionHandle, pin, pin.length));
}); return null;
});
} finally {
wipe(pin);
}
} }
@Override @Override
@@ -1718,23 +1783,31 @@ public class JnaPcieCryptoService implements PcieCryptoService {
int safeKeyType = requireNonNegative("keyType", keyType); int safeKeyType = requireNonNegative("keyType", keyType);
byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin); byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin);
sessionTemplate.withSession("SDFE_ReadUkeyIKComponent", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess( sessionTemplate.withSession("SDFE_ReadUkeyIKComponent", (lib, deviceHandle, sessionHandle) -> {
"SDFE_ReadUkeyIKComponent", sessionTemplate.ensureSuccess(
lib.SDFE_ReadUkeyIKComponent(sessionHandle, safeKeyType, pin, pin.length) "SDFE_ReadUkeyIKComponent",
); lib.SDFE_ReadUkeyIKComponent(sessionHandle, safeKeyType, pin, pin.length)
return null; );
}); return null;
});
} finally {
wipe(pin);
}
} }
@Override @Override
public void generateCertificate(byte[] ukeyPin) { public void generateCertificate(byte[] ukeyPin) {
byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin); byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin);
sessionTemplate.withSession("SDFE_GenerateCertificate", (lib, deviceHandle, sessionHandle) -> { try {
sessionTemplate.ensureSuccess("SDFE_GenerateCertificate", lib.SDFE_GenerateCertificate(sessionHandle, pin, pin.length)); sessionTemplate.withSession("SDFE_GenerateCertificate", (lib, deviceHandle, sessionHandle) -> {
return null; sessionTemplate.ensureSuccess("SDFE_GenerateCertificate", lib.SDFE_GenerateCertificate(sessionHandle, pin, pin.length));
}); return null;
});
} finally {
wipe(pin);
}
} }
@Override @Override
@@ -1835,6 +1908,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
return callback.apply(keyHandle); return callback.apply(keyHandle);
} finally { } finally {
destroyKeyHandle(lib, sessionHandle, keyHandle); destroyKeyHandle(lib, sessionHandle, keyHandle);
wipe(key);
} }
} }
@@ -1856,6 +1930,7 @@ public class JnaPcieCryptoService implements PcieCryptoService {
return callback.apply(keyHandle); return callback.apply(keyHandle);
} finally { } finally {
destroyKeyHandle(lib, sessionHandle, keyHandle); destroyKeyHandle(lib, sessionHandle, keyHandle);
wipe(wrappedKey);
} }
} }
@@ -1943,6 +2018,20 @@ public class JnaPcieCryptoService implements PcieCryptoService {
return value; return value;
} }
private int requireValidAlgId(String name, int algId) {
int value = requirePositive(name, algId);
if (strictAlgIdValidation && !Gm0018AlgorithmIds.isSupported(value)) {
throw new IllegalArgumentException(name + " is not a supported GM/T 0018 algorithm id: 0x" + Integer.toHexString(value));
}
return value;
}
private static void wipe(byte[] value) {
if (value != null) {
Arrays.fill(value, (byte) 0);
}
}
private static byte[] requireNonEmptyBytes(String name, byte[] value) { private static byte[] requireNonEmptyBytes(String name, byte[] value) {
if (value == null || value.length == 0) { if (value == null || value.length == 0) {
throw new IllegalArgumentException(name + " must not be empty"); throw new IllegalArgumentException(name + " must not be empty");
+1
View File
@@ -38,3 +38,4 @@ tms:
mode: ${TMS_CRYPTO_CARD_MODE:MOCK} mode: ${TMS_CRYPTO_CARD_MODE:MOCK}
vendor-lib-path: ${TMS_CRYPTO_VENDOR_LIB_PATH:} vendor-lib-path: ${TMS_CRYPTO_VENDOR_LIB_PATH:}
vendor-lib-name: ${TMS_CRYPTO_VENDOR_LIB_NAME:swsdsdf} vendor-lib-name: ${TMS_CRYPTO_VENDOR_LIB_NAME:swsdsdf}
strict-alg-id-validation: ${TMS_CRYPTO_STRICT_ALG_ID_VALIDATION:true}