diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..334506a
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,27 @@
+name: CI
+
+on:
+ push:
+ branches:
+ - '**'
+ pull_request:
+
+jobs:
+ build-test:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup Java 17
+ uses: actions/setup-java@v4
+ with:
+ distribution: temurin
+ java-version: '17'
+ cache: maven
+
+ - name: Compile
+ run: mvn -q -DskipTests compile
+
+ - name: Test
+ run: mvn -q test
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5533775
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+target/
+.idea/
+.vscode/
+*.iml
+.m2repo/
+.DS_Store
+logs/
diff --git a/README.md b/README.md
index 8e8a5c0..6d6692d 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,206 @@
-# cisd.service
+# TMS Framework
+
+Single-process TMS monolith scaffold built with:
+- JDK 17
+- Spring Boot 3.5.x
+- MyBatis-Plus
+- TiDB (MySQL driver)
+- Swagger (springdoc-openapi)
+
+## Quick Start
+
+```bash
+cd tms-framework
+mvn spring-boot:run
+```
+
+Runtime recommendation:
+- Use JDK 17 for local build/test to match project and CI runtime.
+
+Open:
+- Swagger UI: http://localhost:8080/swagger-ui.html
+- Internal health API: `GET /api/v1/device/status`
+- Internal sign preview API: `POST /api/v1/sign/preview`
+- External sign API: `POST /openapi/v1/sign/signature`
+- Init template API: `GET /api/v1/init/template`
+- Init preview API: `POST /api/v1/init/preview`
+- Auth login API: `POST /api/v1/auth/login`
+- Device info API: `GET /api/v1/device/info`
+- PCIe crypto count API: `GET /api/v1/device/crypto/device-count`
+- PCIe crypto HMAC API: `POST /api/v1/device/crypto/hmac`
+
+## Architecture (Monolith + Modular)
+
+- One deployable Spring Boot application.
+- Module-first packaging under `modules/*`.
+- Default module layout: `controller/internal + service + repository + entity + dto`.
+- `sign` module has extra `controller/openapi`, `dto/openapi`, and `support`.
+- Cross-cutting concerns moved to top-level `security` and `integration`.
+
+## Project Structure
+
+```text
+src/main/java/com/cisd/tms
+├── TmsApplication.java
+├── common
+│ ├── api
+│ ├── config
+│ │ └── properties
+│ ├── constant
+│ ├── enums
+│ ├── exception
+│ └── util
+├── infrastructure
+│ └── persistence
+│ ├── entity
+│ ├── mapper
+│ └── mybatis
+├── integration
+│ ├── cips
+│ ├── mq
+│ ├── crypto
+│ └── file
+├── security
+│ ├── internal
+│ └── openapi
+└── modules
+ ├── system
+ │ ├── controller/internal
+ │ ├── service
+ │ └── dto
+ ├── sign
+ │ ├── controller/internal
+ │ ├── controller/openapi
+ │ ├── service
+ │ ├── dto/internal
+ │ ├── dto/openapi
+ │ ├── support
+ │ ├── repository
+ │ └── entity
+ ├── init
+ ├── auth
+ ├── device
+ ├── upgrade
+ ├── cert
+ ├── key
+ ├── audit
+ ├── backup
+ └── activation
+```
+
+```text
+src/main/resources
+├── application.yml
+├── application-dev.yml
+├── application-prod.yml
+├── mapper
+│ ├── init/InitTaskMapper.xml
+│ ├── auth/AuthUserMapper.xml
+│ └── device/DeviceNodeMapper.xml
+└── db/migration
+ └── V1__init_auth_device_tables.sql
+```
+
+## API Boundary Rules
+
+- Internal API controllers only in `*/controller/internal`, path prefix `/api/**`.
+- External API controllers only in `*/controller/openapi`, path prefix `/openapi/**`.
+- Internal and external DTOs are separated.
+- Cross-module calls must go through `service`, not `repository`.
+- Internal token interceptor exclusions: `/api/v1/device/status`, `/api/v1/auth/login`.
+
+## Auth Configuration
+
+```yaml
+tms:
+ security:
+ internal-token: ${TMS_INTERNAL_TOKEN:change-me-internal-token}
+ openapi:
+ timestamp-skew-seconds: 300
+ clients:
+ demo-app: ${TMS_OPENAPI_DEMO_SECRET:change-me-openapi-secret}
+```
+
+## Crypto Card Configuration
+
+```yaml
+tms:
+ crypto-card:
+ enabled: ${TMS_CRYPTO_CARD_ENABLED:false}
+ mode: ${TMS_CRYPTO_CARD_MODE:MOCK} # MOCK / JNA
+ vendor-lib-path: ${TMS_CRYPTO_VENDOR_LIB_PATH:}
+ vendor-lib-name: ${TMS_CRYPTO_VENDOR_LIB_NAME:swsdsdf}
+```
+
+- Internal PCIe debug APIs (strong-typed service):
+ - `GET /api/v1/device/crypto/device-count`
+ - `GET /api/v1/device/crypto/device-conf`
+ - `GET /api/v1/device/crypto/device-info`
+ - `GET /api/v1/device/crypto/random?length=16`
+ - `POST /api/v1/device/crypto/self-test`
+ - `POST /api/v1/device/crypto/hmac`
+ - `POST /api/v1/device/crypto/digest`
+ - `POST /api/v1/device/crypto/encrypt/plain`
+ - `POST /api/v1/device/crypto/decrypt/plain`
+ - `POST /api/v1/device/crypto/encrypt/kek`
+ - `POST /api/v1/device/crypto/decrypt/kek`
+ - `POST /api/v1/device/crypto/mac/plain`
+ - `POST /api/v1/device/crypto/file/create`
+ - `POST /api/v1/device/crypto/file/write`
+ - `POST /api/v1/device/crypto/file/read`
+ - `POST /api/v1/device/crypto/file/delete`
+ - `POST /api/v1/device/crypto/kek/generate`
+ - `GET /api/v1/device/crypto/kek/status?keyIndex=1`
+ - `GET /api/v1/device/crypto/lmk/seed-mac`
+ - `POST /api/v1/device/crypto/std/keypair/rsa`
+ - `POST /api/v1/device/crypto/std/keypair/ecc`
+ - `POST /api/v1/device/crypto/envelope/exchange/rsa`
+ - `POST /api/v1/device/crypto/envelope/exchange/ecc`
+ - `POST /api/v1/device/crypto/agreement/data-key/ecc`
+ - `POST /api/v1/device/crypto/agreement/session-key/ecc`
+
+## PCIe Crypto Unified Wrapper (JNA)
+
+The project keeps JNA native mappings for PCIe card `SDF/SDFE` interfaces from
+`PCIE密码卡应用接口说明书 V1.02`, and provides strong-typed service APIs via
+`com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService`.
+
+```yaml
+tms:
+ crypto-card:
+ enabled: ${TMS_CRYPTO_CARD_ENABLED:false}
+ mode: ${TMS_CRYPTO_CARD_MODE:JNA} # MOCK / JNA
+ vendor-lib-path: ${TMS_CRYPTO_VENDOR_LIB_PATH:}
+ vendor-lib-name: ${TMS_CRYPTO_VENDOR_LIB_NAME:swsdsdf}
+```
+
+- JNA native mapping: `com.cisd.tms.integration.crypto.pcie.jna.PcieNativeLibrary`
+- JNA implementation: `com.cisd.tms.integration.crypto.pcie.service.JnaPcieCryptoService`
+- Mock fallback: `com.cisd.tms.integration.crypto.pcie.service.MockPcieCryptoService`
+
+### OpenAPI Signature Rules
+
+- Headers: `X-App-Id`, `X-Timestamp`, `X-Nonce`, `X-Signature`
+- Canonical string: `appId + "\\n" + timestamp + "\\n" + nonce`
+- Signature algorithm: `HMAC-SHA256` with app secret, lowercase hex
+- Replay protection: nonce one-time in time window
+
+## Build And Test
+
+```bash
+mvn -q -DskipTests compile
+mvn -q test
+```
+
+- 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.
+
+## Current Status
+
+- Structure refactored to lightweight monolith modules.
+- Internal and external API entry points separated.
+- Basic auth interceptors for internal/openapi are in place.
+- `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.
+>>>>>>> aeb6a4d (初始化项目)
diff --git a/docs/plans/2026-02-28-jdk21-mockito-ci-stability-plan.md b/docs/plans/2026-02-28-jdk21-mockito-ci-stability-plan.md
new file mode 100644
index 0000000..2fdf058
--- /dev/null
+++ b/docs/plans/2026-02-28-jdk21-mockito-ci-stability-plan.md
@@ -0,0 +1,48 @@
+# JDK17 + Mockito + CI Stability Implementation Plan
+
+> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
+
+**Goal:** Stabilize local/CI test execution by fixing Mockito agent startup behavior and pinning CI to JDK 17.
+
+**Architecture:** Configure Maven Surefire to preload Mockito as a javaagent and set required JVM flags to avoid runtime self-attach failures. Add a CI workflow that always uses JDK 17 and runs compile/test checks. Update README for explicit developer/CI runtime expectations.
+
+**Tech Stack:** Maven Surefire, Mockito, GitHub Actions, JDK 17, Spring Boot 3.5
+
+---
+
+### Task 1: Build/Test runtime hardening
+
+**Files:**
+- Modify: `pom.xml`
+
+1. Add explicit `mockito.version` property.
+2. Add `maven-surefire-plugin` with `argLine` including:
+ - `-Djdk.attach.allowAttachSelf=true`
+ - `-XX:+EnableDynamicAgentLoading`
+ - `-javaagent:${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar`
+
+### Task 2: CI JDK pinning
+
+**Files:**
+- Create: `.github/workflows/ci.yml`
+
+1. Add workflow on `push` + `pull_request`.
+2. Use `actions/setup-java` with Temurin `17`.
+3. Run `mvn -q -DskipTests compile` then `mvn -q test`.
+
+### Task 3: Documentation sync
+
+**Files:**
+- Modify: `README.md`
+
+1. Add explicit local recommended JDK 17 note.
+2. Add CI note: workflow runs JDK 17 and compile+test.
+3. Add troubleshooting note for Mockito agent behavior on newer JDKs.
+
+### Task 4: Verification
+
+**Commands:**
+1. `mvn -q -DskipTests compile`
+2. `mvn -q test` (sandbox)
+3. `mvn -q test` (escalated fallback if sandbox attach restrictions block)
+4. Key checks with `rg` for workflow and surefire config.
diff --git a/docs/plans/2026-02-28-pcie-crypto-typed-service-design.md b/docs/plans/2026-02-28-pcie-crypto-typed-service-design.md
new file mode 100644
index 0000000..0bd22a0
--- /dev/null
+++ b/docs/plans/2026-02-28-pcie-crypto-typed-service-design.md
@@ -0,0 +1,168 @@
+# PCIe密码卡强类型封装设计(第一期)
+
+- 日期:2026-02-28
+- 范围:基于 `0018接口.pdf`(国密标准SDF)与 `PCIE密码卡应用接口说明书.docx`(SDFE扩展)
+- 目标:为上层提供强类型业务方法,屏蔽底层JNA细节
+
+## 1. 设计目标与约束
+
+### 1.1 目标
+
+1. 提供强类型业务方法,不要求上层使用 `execute(command, params)`。
+2. 采用短连接会话模型:每个业务方法内部完成 `openDevice/openSession/call/closeSession/closeDevice`。
+3. 第一期开通核心子集接口,覆盖设备管理、会话、HMAC、LMK与常用密钥管理。
+4. 统一错误模型与错误码映射,便于上层处理与运维排障。
+
+### 1.2 非目标
+
+1. 不在第一期覆盖文档所有SDF/SDFE接口。
+2. 不在第一期做多设备负载均衡与高并发优化。
+3. 不在第一期实现JNI桥代码生成。
+
+## 2. 方案选型
+
+### 2.1 备选方案
+
+1. 动态命令入口(`execute(command, params)`)+ 强类型外观。
+2. 纯强类型服务(推荐)。
+3. 从头文件自动生成绑定与服务代码。
+
+### 2.2 选型结论
+
+采用方案2:新增 `PcieCryptoService` 及其 `JnaPcieCryptoService` 实现,
+强类型方法直接调用JNA映射,统一通过短连接模板管理句柄生命周期。
+
+## 3. 总体架构
+
+### 3.1 分层
+
+1. `PcieCryptoService`:面向上层的强类型业务接口。
+2. `JnaPcieCryptoService`:服务实现,调用 `PcieNativeLibrary`。
+3. `PcieSessionTemplate`:统一短连接模板。
+4. `PcieNativeLibrary`:JNA native函数映射。
+5. `PcieErrorMapper`:错误码映射(`retCode -> 业务可读信息`)。
+
+### 3.2 调用路径
+
+上层业务 -> `PcieCryptoService` 强类型方法 -> `PcieSessionTemplate` -> `PcieNativeLibrary` -> 厂商 `.so`
+
+## 4. 第一期开通接口(核心子集)
+
+### 4.1 设备与会话
+
+1. `getDeviceNumber()` -> `SDFE_GetDeviceNumber`
+2. `getNormalDeviceNumber()` -> `SDFE_GetNormalDeviceNumber`
+3. `deviceSelfTest()` -> `SDFE_DeviceSelfTest`
+4. `deviceConfGet()` -> `SDFE_DeviceConfGet`
+5. `initIdentify(oldPin, newPin)` -> `SDFE_InitIdentify`
+
+> 注:`open/close` 作为模板内部行为,不暴露给上层业务接口。
+
+### 4.2 常用密钥管理(用户确认的8组)
+
+1. `generateKeyPairEcc` / `generateKeyPairRsa`
+2. `generateKek`
+3. `backupUserKey` / `recoverUserKey`
+4. `backupKek` / `recoverKek`
+5. `deleteUserKey` / `deleteKek`
+6. `statusUserKeyEcc` / `statusUserKeyRsa`
+7. `statusKek`
+8. `changePrivateKeyAccessPassword`
+
+### 4.3 HMAC
+
+1. `hmac(algId, key, data)`
+2. 内部流程:`SDFE_HmacInit` -> `SDFE_HmacUpdate` -> `SDFE_HmacFinal`
+
+### 4.4 LMK(核心)
+
+1. `generateLmk` / `loadLmk` / `backupLmk` / `recoverLmk` / `destroyLmk`
+2. `checkLmk` / `exportLmkSeedMac`
+
+## 5. 强类型模型
+
+### 5.1 请求对象
+
+1. `GenerateKeyRequest`:`keyIndex`, `keyBits`, `keyType`
+2. `RecoverUserKeyRequest`:`keyIndex`, `keyType`, `cipherKeyData`, `storeFlag`
+3. `RecoverKekRequest`:`keyIndex`, `cipherKeyData`
+4. `ChangePrivateKeyPasswordRequest`:`keyIndex`, `oldPassword`, `newPassword`
+5. `HmacRequest`:`algId`, `key`, `data`
+
+### 5.2 响应对象
+
+1. `OperationResult`:`success`, `retCode`, `message`
+2. `DeviceCountResult`:`deviceNumber`, `normalDeviceNumber`
+3. `DeviceConfResult`:映射 `SDFE_DeviceConf`
+4. `BackupUserKeyResult` / `BackupKekResult`:`data`, `length`
+5. `KeyStatusResult`:`keyState`
+6. `HmacResult`:`hmac`, `hmacLength`
+
+## 6. 会话模板(短连接)
+
+定义统一模板方法:
+
+```text
+executeWithSession(apiName, callback):
+ SDF_OpenDevice
+ SDF_OpenSession
+ callback(session)
+ SDF_CloseSession
+ SDF_CloseDevice
+```
+
+约束:
+
+1. 所有强类型方法必须通过模板执行。
+2. 关闭失败仅记录日志,不覆盖主调用错误。
+3. 模板保证异常场景也能回收句柄。
+
+## 7. 错误处理
+
+1. `retCode == 0`:成功。
+2. `retCode != 0`:抛 `PcieCryptoException(apiName, retCode, mappedMessage)`。
+3. 映射文档补充错误码:
+ - `SDR_UKEYERR`
+ - `SDR_GENKEYERR`
+ - `SDR_STATEERR`
+ - `SDR_RETRYERR`
+ - `SDR_DEVICE_BUSY`
+ - `SDR_RET_ERR_STATUS`
+ - `SDR_RET_INIT_STATUS`
+ - `SDR_RET_LOGINED`
+ - `SDR_RET_GD32_TIMEOUT`
+4. 参数校验失败在服务层抛 `IllegalArgumentException`,不下发至设备。
+
+## 8. 并发与安全
+
+1. 第一期开启串行访问(单设备锁)避免状态错乱。
+2. PIN/口令参数不打印明文日志。
+3. 密钥备份字节在服务层保持二进制,不做文本日志输出。
+
+## 9. 对上层的使用方式
+
+示例:
+
+1. `pcieCryptoService.generateLmk()`
+2. `pcieCryptoService.backupKek(keyIndex, outBufferSize)`
+3. `pcieCryptoService.hmac(request)`
+
+上层仅依赖强类型接口与DTO,不直接依赖JNA类型和指针。
+
+## 10. 验收标准
+
+1. 强类型接口可完成第一期核心子集调用。
+2. 每个方法均使用短连接模板。
+3. 统一异常中包含 `apiName + retCode + mappedMessage`。
+4. `mvn -DskipTests compile` 通过。
+5. 关键路径联调用例可跑通:
+ - `getDeviceNumber`
+ - `deviceConfGet`
+ - `hmac`
+ - `generateKek + statusKek`
+
+## 11. 后续扩展
+
+1. 第二期覆盖U盾与内部密钥管理。
+2. 第三期覆盖全量SDF/SDFE并补充结构体严格对齐校验。
+3. 加入真实设备集成测试与回放测试。
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..b934f21
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,140 @@
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.5.0
+
+
+
+ com.cisd
+ tms-framework
+ 0.0.1-SNAPSHOT
+ tms-framework
+ CISD TMS base framework
+
+
+ 17
+ 3.5.10.1
+ 2.8.5
+ 5.17.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+
+ com.baomidou
+ mybatis-plus-spring-boot3-starter
+ ${mybatis-plus.version}
+
+
+ com.mysql
+ mysql-connector-j
+ runtime
+
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-ui
+ ${springdoc.version}
+
+
+ net.java.dev.jna
+ jna
+ 5.14.0
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ -Djdk.attach.allowAttachSelf=true -XX:+EnableDynamicAgentLoading -javaagent:${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+ ci
+
+
+ env.CI
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+ enforce-java-17-in-ci
+
+ enforce
+
+
+
+
+ [17,18)
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/cisd/tms/TmsApplication.java b/src/main/java/com/cisd/tms/TmsApplication.java
new file mode 100644
index 0000000..239bb5b
--- /dev/null
+++ b/src/main/java/com/cisd/tms/TmsApplication.java
@@ -0,0 +1,14 @@
+package com.cisd.tms;
+
+import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@ConfigurationPropertiesScan
+public class TmsApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(TmsApplication.class, args);
+ }
+}
diff --git a/src/main/java/com/cisd/tms/common/api/ApiResponse.java b/src/main/java/com/cisd/tms/common/api/ApiResponse.java
new file mode 100644
index 0000000..21fed58
--- /dev/null
+++ b/src/main/java/com/cisd/tms/common/api/ApiResponse.java
@@ -0,0 +1,128 @@
+package com.cisd.tms.common.api;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.time.Instant;
+import java.util.Map;
+import org.slf4j.MDC;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ApiResponse {
+
+ private static final int SUCCESS_CODE = 200;
+ private static final String DEFAULT_SUCCESS_MSG = "success";
+
+ private boolean success;
+ private int code;
+ private String msg;
+ private T data;
+ private long timestamp;
+ private String traceId;
+ private String path;
+ private Map details;
+
+ public ApiResponse() {
+ }
+
+ public ApiResponse(boolean success, int code, String msg, T data) {
+ this.success = success;
+ this.code = code;
+ this.msg = msg;
+ this.data = data;
+ this.timestamp = Instant.now().toEpochMilli();
+ this.traceId = MDC.get("traceId");
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public String getTraceId() {
+ return traceId;
+ }
+
+ public void setTraceId(String traceId) {
+ this.traceId = traceId;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public Map getDetails() {
+ return details;
+ }
+
+ public void setDetails(Map details) {
+ this.details = details;
+ }
+
+ public ApiResponse withPath(String path) {
+ this.path = path;
+ return this;
+ }
+
+ public ApiResponse withDetails(Map details) {
+ this.details = details;
+ return this;
+ }
+
+ public static ApiResponse success(T data) {
+ return new ApiResponse<>(true, SUCCESS_CODE, DEFAULT_SUCCESS_MSG, data);
+ }
+
+ public static ApiResponse success(String msg, T data) {
+ return new ApiResponse<>(true, SUCCESS_CODE, msg, data);
+ }
+
+ public static ApiResponse success() {
+ return new ApiResponse<>(true, SUCCESS_CODE, DEFAULT_SUCCESS_MSG, null);
+ }
+
+ public static ApiResponse fail(int code, String msg) {
+ return new ApiResponse<>(false, code, msg, null);
+ }
+
+ public static ApiResponse fail(int code, String msg, T data) {
+ return new ApiResponse<>(false, code, msg, data);
+ }
+}
diff --git a/src/main/java/com/cisd/tms/common/config/MybatisPlusConfig.java b/src/main/java/com/cisd/tms/common/config/MybatisPlusConfig.java
new file mode 100644
index 0000000..96d9499
--- /dev/null
+++ b/src/main/java/com/cisd/tms/common/config/MybatisPlusConfig.java
@@ -0,0 +1,14 @@
+package com.cisd.tms.common.config;
+
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class MybatisPlusConfig {
+
+ @Bean
+ public MybatisPlusInterceptor mybatisPlusInterceptor() {
+ return new MybatisPlusInterceptor();
+ }
+}
diff --git a/src/main/java/com/cisd/tms/common/config/OpenApiConfig.java b/src/main/java/com/cisd/tms/common/config/OpenApiConfig.java
new file mode 100644
index 0000000..d6f9fb0
--- /dev/null
+++ b/src/main/java/com/cisd/tms/common/config/OpenApiConfig.java
@@ -0,0 +1,42 @@
+package com.cisd.tms.common.config;
+
+import io.swagger.v3.oas.models.ExternalDocumentation;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.info.License;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springdoc.core.models.GroupedOpenApi;
+
+@Configuration
+public class OpenApiConfig {
+
+ @Bean
+ public OpenAPI tmsOpenApi() {
+ return new OpenAPI()
+ .info(new Info()
+ .title("CISD TMS API")
+ .description("CISD Terminal Management System API")
+ .version("v0.0.1")
+ .license(new License().name("Internal Use")))
+ .externalDocs(new ExternalDocumentation()
+ .description("CISD design docs")
+ .url("https://example.internal/cisd"));
+ }
+
+ @Bean
+ public GroupedOpenApi internalApiGroup() {
+ return GroupedOpenApi.builder()
+ .group("internal-api")
+ .pathsToMatch("/api/**")
+ .build();
+ }
+
+ @Bean
+ public GroupedOpenApi openApiGroup() {
+ return GroupedOpenApi.builder()
+ .group("openapi-sign")
+ .pathsToMatch("/openapi/**")
+ .build();
+ }
+}
diff --git a/src/main/java/com/cisd/tms/common/config/WebMvcConfig.java b/src/main/java/com/cisd/tms/common/config/WebMvcConfig.java
new file mode 100644
index 0000000..aee63a7
--- /dev/null
+++ b/src/main/java/com/cisd/tms/common/config/WebMvcConfig.java
@@ -0,0 +1,65 @@
+package com.cisd.tms.common.config;
+
+import com.cisd.tms.security.internal.InternalApiAuthInterceptor;
+import com.cisd.tms.security.openapi.OpenApiSignAuthInterceptor;
+import com.cisd.tms.common.util.TraceIdUtil;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import org.slf4j.MDC;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.filter.OncePerRequestFilter;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+ private final InternalApiAuthInterceptor internalApiAuthInterceptor;
+ private final OpenApiSignAuthInterceptor openApiSignAuthInterceptor;
+
+ public WebMvcConfig(
+ InternalApiAuthInterceptor internalApiAuthInterceptor,
+ OpenApiSignAuthInterceptor openApiSignAuthInterceptor
+ ) {
+ this.internalApiAuthInterceptor = internalApiAuthInterceptor;
+ this.openApiSignAuthInterceptor = openApiSignAuthInterceptor;
+ }
+
+ @Bean
+ public OncePerRequestFilter traceIdFilter() {
+ return new OncePerRequestFilter() {
+ @Override
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
+ throws ServletException, IOException {
+ String traceId = request.getHeader("X-Trace-Id");
+ if (traceId == null || traceId.isBlank()) {
+ traceId = TraceIdUtil.newTraceId();
+ }
+ MDC.put("traceId", traceId);
+ response.setHeader("X-Trace-Id", traceId);
+ try {
+ filterChain.doFilter(request, response);
+ } finally {
+ MDC.remove("traceId");
+ }
+ }
+ };
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(internalApiAuthInterceptor)
+ .addPathPatterns("/api/**")
+ .excludePathPatterns(
+ "/api/v1/device/status",
+ "/api/v1/auth/login"
+ );
+
+ registry.addInterceptor(openApiSignAuthInterceptor)
+ .addPathPatterns("/openapi/**");
+ }
+}
diff --git a/src/main/java/com/cisd/tms/common/config/properties/TmsSecurityProperties.java b/src/main/java/com/cisd/tms/common/config/properties/TmsSecurityProperties.java
new file mode 100644
index 0000000..4b8c50f
--- /dev/null
+++ b/src/main/java/com/cisd/tms/common/config/properties/TmsSecurityProperties.java
@@ -0,0 +1,45 @@
+package com.cisd.tms.common.config.properties;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties(prefix = "tms.security")
+public class TmsSecurityProperties {
+
+ private String internalToken = "change-me-internal-token";
+ private final Openapi openapi = new Openapi();
+
+ public String getInternalToken() {
+ return internalToken;
+ }
+
+ public void setInternalToken(String internalToken) {
+ this.internalToken = internalToken;
+ }
+
+ public Openapi getOpenapi() {
+ return openapi;
+ }
+
+ public static class Openapi {
+ private long timestampSkewSeconds = 300;
+ private Map clients = new HashMap<>();
+
+ public long getTimestampSkewSeconds() {
+ return timestampSkewSeconds;
+ }
+
+ public void setTimestampSkewSeconds(long timestampSkewSeconds) {
+ this.timestampSkewSeconds = timestampSkewSeconds;
+ }
+
+ public Map getClients() {
+ return clients;
+ }
+
+ public void setClients(Map clients) {
+ this.clients = clients;
+ }
+ }
+}
diff --git a/src/main/java/com/cisd/tms/common/constant/Profiles.java b/src/main/java/com/cisd/tms/common/constant/Profiles.java
new file mode 100644
index 0000000..b286811
--- /dev/null
+++ b/src/main/java/com/cisd/tms/common/constant/Profiles.java
@@ -0,0 +1,10 @@
+package com.cisd.tms.common.constant;
+
+public final class Profiles {
+
+ public static final String DEV = "dev";
+ public static final String PROD = "prod";
+
+ private Profiles() {
+ }
+}
diff --git a/src/main/java/com/cisd/tms/common/enums/ErrorCode.java b/src/main/java/com/cisd/tms/common/enums/ErrorCode.java
new file mode 100644
index 0000000..fd1951f
--- /dev/null
+++ b/src/main/java/com/cisd/tms/common/enums/ErrorCode.java
@@ -0,0 +1,26 @@
+package com.cisd.tms.common.enums;
+
+public enum ErrorCode {
+ BAD_REQUEST(400, "bad request"),
+ UNAUTHORIZED(4010, "unauthorized"),
+ VALIDATE_FAILED(4001, "parameter validation failed"),
+ BIZ_ERROR(5001, "business exception"),
+ CRYPTO_CARD_ERROR(5201, "crypto card adapter error"),
+ INTERNAL_ERROR(5000, "internal server error");
+
+ private final int code;
+ private final String message;
+
+ ErrorCode(int code, String message) {
+ this.code = code;
+ this.message = message;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/common/exception/BizException.java b/src/main/java/com/cisd/tms/common/exception/BizException.java
new file mode 100644
index 0000000..c9843ce
--- /dev/null
+++ b/src/main/java/com/cisd/tms/common/exception/BizException.java
@@ -0,0 +1,15 @@
+package com.cisd.tms.common.exception;
+
+public class BizException extends RuntimeException {
+
+ private final int code;
+
+ public BizException(int code, String message) {
+ super(message);
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/common/exception/GlobalExceptionHandler.java b/src/main/java/com/cisd/tms/common/exception/GlobalExceptionHandler.java
new file mode 100644
index 0000000..5d6e4b7
--- /dev/null
+++ b/src/main/java/com/cisd/tms/common/exception/GlobalExceptionHandler.java
@@ -0,0 +1,60 @@
+package com.cisd.tms.common.exception;
+
+import com.cisd.tms.common.api.ApiResponse;
+import com.cisd.tms.common.enums.ErrorCode;
+import com.cisd.tms.integration.crypto.pcie.PcieCryptoException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.ConstraintViolationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+ private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
+
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ public ApiResponse handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpServletRequest request) {
+ String msg = ex.getBindingResult().getAllErrors().stream()
+ .findFirst()
+ .map(error -> {
+ if (error instanceof FieldError fieldError) {
+ return fieldError.getField() + ": " + fieldError.getDefaultMessage();
+ }
+ return error.getDefaultMessage();
+ })
+ .orElse(ErrorCode.VALIDATE_FAILED.getMessage());
+ return ApiResponse.fail(ErrorCode.VALIDATE_FAILED.getCode(), msg).withPath(request.getRequestURI());
+ }
+
+ @ExceptionHandler(ConstraintViolationException.class)
+ public ApiResponse handleConstraintViolation(ConstraintViolationException ex, HttpServletRequest request) {
+ return ApiResponse.fail(ErrorCode.VALIDATE_FAILED.getCode(), ex.getMessage()).withPath(request.getRequestURI());
+ }
+
+ @ExceptionHandler(BizException.class)
+ public ApiResponse handleBizException(BizException ex, HttpServletRequest request) {
+ return ApiResponse.fail(ex.getCode(), ex.getMessage()).withPath(request.getRequestURI());
+ }
+
+ @ExceptionHandler(IllegalArgumentException.class)
+ public ApiResponse handleIllegalArgument(IllegalArgumentException ex, HttpServletRequest request) {
+ return ApiResponse.fail(ErrorCode.VALIDATE_FAILED.getCode(), ex.getMessage()).withPath(request.getRequestURI());
+ }
+
+ @ExceptionHandler(PcieCryptoException.class)
+ public ApiResponse handleCryptoCardException(PcieCryptoException ex, HttpServletRequest request) {
+ return ApiResponse.fail(ErrorCode.CRYPTO_CARD_ERROR.getCode(), ex.getMessage())
+ .withPath(request.getRequestURI());
+ }
+
+ @ExceptionHandler(Exception.class)
+ public ApiResponse handleException(Exception ex, HttpServletRequest request) {
+ log.error("Unhandled exception", ex);
+ return ApiResponse.fail(ErrorCode.INTERNAL_ERROR.getCode(), ErrorCode.INTERNAL_ERROR.getMessage())
+ .withPath(request.getRequestURI());
+ }
+}
diff --git a/src/main/java/com/cisd/tms/common/util/HmacUtil.java b/src/main/java/com/cisd/tms/common/util/HmacUtil.java
new file mode 100644
index 0000000..38ce923
--- /dev/null
+++ b/src/main/java/com/cisd/tms/common/util/HmacUtil.java
@@ -0,0 +1,30 @@
+package com.cisd.tms.common.util;
+
+import java.nio.charset.StandardCharsets;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+public final class HmacUtil {
+
+ private HmacUtil() {
+ }
+
+ public static String hmacSha256Hex(String key, String content) {
+ try {
+ Mac mac = Mac.getInstance("HmacSHA256");
+ mac.init(new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
+ byte[] digest = mac.doFinal(content.getBytes(StandardCharsets.UTF_8));
+ return toHex(digest);
+ } catch (Exception ex) {
+ throw new IllegalStateException("Cannot calculate hmac", ex);
+ }
+ }
+
+ private static String toHex(byte[] bytes) {
+ StringBuilder builder = new StringBuilder(bytes.length * 2);
+ for (byte b : bytes) {
+ builder.append(String.format("%02x", b));
+ }
+ return builder.toString();
+ }
+}
diff --git a/src/main/java/com/cisd/tms/common/util/HttpResponseUtil.java b/src/main/java/com/cisd/tms/common/util/HttpResponseUtil.java
new file mode 100644
index 0000000..9bb24fc
--- /dev/null
+++ b/src/main/java/com/cisd/tms/common/util/HttpResponseUtil.java
@@ -0,0 +1,20 @@
+package com.cisd.tms.common.util;
+
+import com.cisd.tms.common.api.ApiResponse;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public final class HttpResponseUtil {
+
+ private HttpResponseUtil() {
+ }
+
+ public static void writeJson(HttpServletResponse response, int httpStatus, ApiResponse> body, ObjectMapper objectMapper)
+ throws IOException {
+ response.setStatus(httpStatus);
+ response.setCharacterEncoding("UTF-8");
+ response.setContentType("application/json;charset=UTF-8");
+ response.getWriter().write(objectMapper.writeValueAsString(body));
+ }
+}
diff --git a/src/main/java/com/cisd/tms/common/util/TraceIdUtil.java b/src/main/java/com/cisd/tms/common/util/TraceIdUtil.java
new file mode 100644
index 0000000..6d2c85c
--- /dev/null
+++ b/src/main/java/com/cisd/tms/common/util/TraceIdUtil.java
@@ -0,0 +1,13 @@
+package com.cisd.tms.common.util;
+
+import java.util.UUID;
+
+public final class TraceIdUtil {
+
+ private TraceIdUtil() {
+ }
+
+ public static String newTraceId() {
+ return UUID.randomUUID().toString().replace("-", "");
+ }
+}
diff --git a/src/main/java/com/cisd/tms/infrastructure/persistence/entity/BaseEntity.java b/src/main/java/com/cisd/tms/infrastructure/persistence/entity/BaseEntity.java
new file mode 100644
index 0000000..83a5237
--- /dev/null
+++ b/src/main/java/com/cisd/tms/infrastructure/persistence/entity/BaseEntity.java
@@ -0,0 +1,43 @@
+package com.cisd.tms.infrastructure.persistence.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+
+public class BaseEntity {
+
+ @TableId(type = IdType.ASSIGN_ID)
+ private Long id;
+
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private LocalDateTime updateTime;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public LocalDateTime getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(LocalDateTime createTime) {
+ this.createTime = createTime;
+ }
+
+ public LocalDateTime getUpdateTime() {
+ return updateTime;
+ }
+
+ public void setUpdateTime(LocalDateTime updateTime) {
+ this.updateTime = updateTime;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/infrastructure/persistence/mapper/BaseMapperX.java b/src/main/java/com/cisd/tms/infrastructure/persistence/mapper/BaseMapperX.java
new file mode 100644
index 0000000..89449b0
--- /dev/null
+++ b/src/main/java/com/cisd/tms/infrastructure/persistence/mapper/BaseMapperX.java
@@ -0,0 +1,6 @@
+package com.cisd.tms.infrastructure.persistence.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+public interface BaseMapperX extends BaseMapper {
+}
diff --git a/src/main/java/com/cisd/tms/infrastructure/persistence/mybatis/CommonMetaObjectHandler.java b/src/main/java/com/cisd/tms/infrastructure/persistence/mybatis/CommonMetaObjectHandler.java
new file mode 100644
index 0000000..69d9f79
--- /dev/null
+++ b/src/main/java/com/cisd/tms/infrastructure/persistence/mybatis/CommonMetaObjectHandler.java
@@ -0,0 +1,21 @@
+package com.cisd.tms.infrastructure.persistence.mybatis;
+
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import java.time.LocalDateTime;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CommonMetaObjectHandler implements MetaObjectHandler {
+
+ @Override
+ public void insertFill(MetaObject metaObject) {
+ this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
+ this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
+ }
+
+ @Override
+ public void updateFill(MetaObject metaObject) {
+ this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/cips/package-info.java b/src/main/java/com/cisd/tms/integration/cips/package-info.java
new file mode 100644
index 0000000..09dccef
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/cips/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * cips integration adapters.
+ */
+package com.cisd.tms.integration.cips;
diff --git a/src/main/java/com/cisd/tms/integration/crypto/config/CryptoCardProperties.java b/src/main/java/com/cisd/tms/integration/crypto/config/CryptoCardProperties.java
new file mode 100644
index 0000000..8ce6dcd
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/config/CryptoCardProperties.java
@@ -0,0 +1,49 @@
+package com.cisd.tms.integration.crypto.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties(prefix = "tms.crypto-card")
+public class CryptoCardProperties {
+
+ public enum Mode {
+ MOCK,
+ JNA
+ }
+
+ private boolean enabled;
+ private Mode mode = Mode.MOCK;
+ private String vendorLibPath;
+ private String vendorLibName = "swsdsdf";
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public Mode getMode() {
+ return mode;
+ }
+
+ public void setMode(Mode mode) {
+ this.mode = mode;
+ }
+
+ public String getVendorLibPath() {
+ return vendorLibPath;
+ }
+
+ public void setVendorLibPath(String vendorLibPath) {
+ this.vendorLibPath = vendorLibPath;
+ }
+
+ public String getVendorLibName() {
+ return vendorLibName;
+ }
+
+ public void setVendorLibName(String vendorLibName) {
+ this.vendorLibName = vendorLibName;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/config/PcieCryptoServiceConfiguration.java b/src/main/java/com/cisd/tms/integration/crypto/config/PcieCryptoServiceConfiguration.java
new file mode 100644
index 0000000..0bd607a
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/config/PcieCryptoServiceConfiguration.java
@@ -0,0 +1,35 @@
+package com.cisd.tms.integration.crypto.config;
+
+import com.cisd.tms.integration.crypto.pcie.PcieSessionTemplate;
+import com.cisd.tms.integration.crypto.pcie.service.JnaPcieCryptoService;
+import com.cisd.tms.integration.crypto.pcie.service.MockPcieCryptoService;
+import com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class PcieCryptoServiceConfiguration {
+
+ private static final Logger log = LoggerFactory.getLogger(PcieCryptoServiceConfiguration.class);
+
+ @Bean
+ public PcieCryptoService pcieCryptoService(
+ CryptoCardProperties properties,
+ PcieSessionTemplate sessionTemplate
+ ) {
+ if (!properties.isEnabled()) {
+ log.info("PCIe crypto service disabled, fallback to mock service");
+ return new MockPcieCryptoService();
+ }
+
+ if (properties.getMode() == CryptoCardProperties.Mode.JNA) {
+ log.info("PCIe crypto service enabled in JNA mode");
+ return new JnaPcieCryptoService(sessionTemplate);
+ }
+
+ log.info("PCIe crypto service fallback to mock, current mode={}", properties.getMode());
+ return new MockPcieCryptoService();
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/config/package-info.java b/src/main/java/com/cisd/tms/integration/crypto/config/package-info.java
new file mode 100644
index 0000000..6fea552
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/config/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Crypto card configuration and properties.
+ */
+package com.cisd.tms.integration.crypto.config;
diff --git a/src/main/java/com/cisd/tms/integration/crypto/package-info.java b/src/main/java/com/cisd/tms/integration/crypto/package-info.java
new file mode 100644
index 0000000..955f701
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Crypto integration entry points.
+ */
+package com.cisd.tms.integration.crypto;
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieCryptoException.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieCryptoException.java
new file mode 100644
index 0000000..599298e
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieCryptoException.java
@@ -0,0 +1,27 @@
+package com.cisd.tms.integration.crypto.pcie;
+
+public class PcieCryptoException extends RuntimeException {
+
+ private final String apiName;
+ private final int nativeRetCode;
+
+ public PcieCryptoException(String apiName, int nativeRetCode, String message) {
+ super("[" + apiName + "] " + message + " (errorCode=" + nativeRetCode + ")");
+ this.apiName = apiName;
+ this.nativeRetCode = nativeRetCode;
+ }
+
+ public PcieCryptoException(String apiName, String message, Throwable cause) {
+ super("[" + apiName + "] " + message, cause);
+ this.apiName = apiName;
+ this.nativeRetCode = -1;
+ }
+
+ public String getApiName() {
+ return apiName;
+ }
+
+ public int getNativeRetCode() {
+ return nativeRetCode;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieErrorMapper.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieErrorMapper.java
new file mode 100644
index 0000000..45770d1
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieErrorMapper.java
@@ -0,0 +1,38 @@
+package com.cisd.tms.integration.crypto.pcie;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PcieErrorMapper {
+
+ private final Map lowByteErrorMap = new HashMap<>();
+
+ public PcieErrorMapper() {
+ // From PCIe custom document (SDR_BASE + 0x1F ~ 0x27)
+ lowByteErrorMap.put(0x1F, "ukey error");
+ lowByteErrorMap.put(0x20, "generate key error");
+ lowByteErrorMap.put(0x21, "state error");
+ lowByteErrorMap.put(0x22, "retry exceeded");
+ lowByteErrorMap.put(0x23, "device busy");
+ lowByteErrorMap.put(0x24, "error status");
+ lowByteErrorMap.put(0x25, "init status");
+ lowByteErrorMap.put(0x26, "already logined");
+ lowByteErrorMap.put(0x27, "timeout");
+ }
+
+ public String toMessage(int retCode) {
+ if (retCode == 0) {
+ return "success";
+ }
+
+ int lowByte = retCode & 0xFF;
+ String known = lowByteErrorMap.get(lowByte);
+ if (known != null) {
+ return known + " (retCode=0x" + Integer.toHexString(retCode) + ")";
+ }
+
+ return "native error (retCode=0x" + Integer.toHexString(retCode) + ")";
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieKeyState.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieKeyState.java
new file mode 100644
index 0000000..242d26e
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieKeyState.java
@@ -0,0 +1,27 @@
+package com.cisd.tms.integration.crypto.pcie;
+
+public enum PcieKeyState {
+ NO_VALID(0),
+ NO_RIGHT(1),
+ RIGHT(2),
+ UNKNOWN(-1);
+
+ private final int code;
+
+ PcieKeyState(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public static PcieKeyState from(int code) {
+ for (PcieKeyState state : values()) {
+ if (state.code == code) {
+ return state;
+ }
+ }
+ return UNKNOWN;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieSessionTemplate.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieSessionTemplate.java
new file mode 100644
index 0000000..adf0172
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieSessionTemplate.java
@@ -0,0 +1,116 @@
+package com.cisd.tms.integration.crypto.pcie;
+
+import com.cisd.tms.integration.crypto.config.CryptoCardProperties;
+import com.cisd.tms.integration.crypto.pcie.jna.PcieNativeLibrary;
+import com.sun.jna.Library;
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.ptr.PointerByReference;
+import java.util.HashMap;
+import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PcieSessionTemplate {
+
+ @FunctionalInterface
+ public interface DeviceCallback {
+ T apply(PcieNativeLibrary lib, Pointer deviceHandle);
+ }
+
+ @FunctionalInterface
+ public interface SessionCallback {
+ T apply(PcieNativeLibrary lib, Pointer deviceHandle, Pointer sessionHandle);
+ }
+
+ private static final Logger log = LoggerFactory.getLogger(PcieSessionTemplate.class);
+
+ private final CryptoCardProperties properties;
+ private final PcieErrorMapper errorMapper;
+
+ private final Object lock = new Object();
+ private volatile PcieNativeLibrary nativeLibrary;
+
+ public PcieSessionTemplate(CryptoCardProperties properties, PcieErrorMapper errorMapper) {
+ this.properties = properties;
+ this.errorMapper = errorMapper;
+ }
+
+ public T withDevice(String apiName, DeviceCallback callback) {
+ synchronized (lock) {
+ PcieNativeLibrary lib = ensureLibraryLoaded();
+
+ PointerByReference deviceRef = new PointerByReference();
+ int openRc = lib.SDF_OpenDevice(deviceRef);
+ ensureSuccess(apiName + ":SDF_OpenDevice", openRc);
+
+ Pointer device = deviceRef.getValue();
+ try {
+ return callback.apply(lib, device);
+ } finally {
+ int closeRc = lib.SDF_CloseDevice(device);
+ if (closeRc != 0) {
+ log.warn("{} close device failed: {}", apiName, errorMapper.toMessage(closeRc));
+ }
+ }
+ }
+ }
+
+ public T withSession(String apiName, SessionCallback callback) {
+ return withDevice(apiName, (lib, deviceHandle) -> {
+ PointerByReference sessionRef = new PointerByReference();
+ int openSessionRc = lib.SDF_OpenSession(deviceHandle, sessionRef);
+ ensureSuccess(apiName + ":SDF_OpenSession", openSessionRc);
+
+ Pointer session = sessionRef.getValue();
+ try {
+ return callback.apply(lib, deviceHandle, session);
+ } finally {
+ int closeSessionRc = lib.SDF_CloseSession(session);
+ if (closeSessionRc != 0) {
+ log.warn("{} close session failed: {}", apiName, errorMapper.toMessage(closeSessionRc));
+ }
+ }
+ });
+ }
+
+ public void ensureSuccess(String apiName, int retCode) {
+ if (retCode != 0) {
+ throw new PcieCryptoException(apiName, retCode, errorMapper.toMessage(retCode));
+ }
+ }
+
+ private PcieNativeLibrary ensureLibraryLoaded() {
+ PcieNativeLibrary cached = nativeLibrary;
+ if (cached != null) {
+ return cached;
+ }
+
+ synchronized (this) {
+ if (nativeLibrary != null) {
+ return nativeLibrary;
+ }
+
+ Map options = new HashMap<>();
+ options.put(Library.OPTION_STRING_ENCODING, "UTF-8");
+
+ String libPath = properties.getVendorLibPath();
+ String libName = properties.getVendorLibName();
+
+ try {
+ if (libPath != null && !libPath.isBlank()) {
+ nativeLibrary = Native.load(libPath, PcieNativeLibrary.class, options);
+ log.info("Loaded PCIe native library by path: {}", libPath);
+ } else {
+ nativeLibrary = Native.load(libName, PcieNativeLibrary.class, options);
+ log.info("Loaded PCIe native library by name: {}", libName);
+ }
+ } catch (UnsatisfiedLinkError ex) {
+ throw new PcieCryptoException("Native.load", "load PCIe native library failed", ex);
+ }
+ return nativeLibrary;
+ }
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieUserKeyType.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieUserKeyType.java
new file mode 100644
index 0000000..7c2cb1d
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/PcieUserKeyType.java
@@ -0,0 +1,16 @@
+package com.cisd.tms.integration.crypto.pcie;
+
+public enum PcieUserKeyType {
+ SIGN(0),
+ ENC(1);
+
+ private final int code;
+
+ PcieUserKeyType(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EccCipher.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EccCipher.java
new file mode 100644
index 0000000..749523b
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EccCipher.java
@@ -0,0 +1,22 @@
+package com.cisd.tms.integration.crypto.pcie.jna;
+
+import com.sun.jna.Structure;
+import java.util.List;
+
+@Structure.FieldOrder({"x", "y", "m", "l", "c"})
+public class EccCipher extends Structure {
+
+ // GM/T 0018定义为C[1]变长数组;JNA侧采用固定上限承载。
+ public static final int C_MAX_LEN = 1024;
+
+ public byte[] x = new byte[EccRefPublicKey.MAX_LEN];
+ public byte[] y = new byte[EccRefPublicKey.MAX_LEN];
+ public byte[] m = new byte[32];
+ public int l;
+ public byte[] c = new byte[C_MAX_LEN];
+
+ @Override
+ protected List getFieldOrder() {
+ return List.of("x", "y", "m", "l", "c");
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EccRefPrivateKey.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EccRefPrivateKey.java
new file mode 100644
index 0000000..3bef2ff
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EccRefPrivateKey.java
@@ -0,0 +1,19 @@
+package com.cisd.tms.integration.crypto.pcie.jna;
+
+import com.sun.jna.Structure;
+import java.util.List;
+
+@Structure.FieldOrder({"bits", "k"})
+public class EccRefPrivateKey extends Structure {
+
+ public static final int MAX_BITS = 512;
+ public static final int MAX_LEN = (MAX_BITS + 7) / 8;
+
+ public int bits;
+ public byte[] k = new byte[MAX_LEN];
+
+ @Override
+ protected List getFieldOrder() {
+ return List.of("bits", "k");
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EccRefPublicKey.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EccRefPublicKey.java
new file mode 100644
index 0000000..39615d5
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EccRefPublicKey.java
@@ -0,0 +1,20 @@
+package com.cisd.tms.integration.crypto.pcie.jna;
+
+import com.sun.jna.Structure;
+import java.util.List;
+
+@Structure.FieldOrder({"bits", "x", "y"})
+public class EccRefPublicKey extends Structure {
+
+ public static final int MAX_BITS = 512;
+ public static final int MAX_LEN = (MAX_BITS + 7) / 8;
+
+ public int bits;
+ public byte[] x = new byte[MAX_LEN];
+ public byte[] y = new byte[MAX_LEN];
+
+ @Override
+ protected List getFieldOrder() {
+ return List.of("bits", "x", "y");
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EccSignature.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EccSignature.java
new file mode 100644
index 0000000..1990c77
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EccSignature.java
@@ -0,0 +1,16 @@
+package com.cisd.tms.integration.crypto.pcie.jna;
+
+import com.sun.jna.Structure;
+import java.util.List;
+
+@Structure.FieldOrder({"r", "s"})
+public class EccSignature extends Structure {
+
+ public byte[] r = new byte[EccRefPublicKey.MAX_LEN];
+ public byte[] s = new byte[EccRefPublicKey.MAX_LEN];
+
+ @Override
+ protected List getFieldOrder() {
+ return List.of("r", "s");
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EnvelopedKeyBlob.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EnvelopedKeyBlob.java
new file mode 100644
index 0000000..9b61484
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/EnvelopedKeyBlob.java
@@ -0,0 +1,21 @@
+package com.cisd.tms.integration.crypto.pcie.jna;
+
+import com.sun.jna.NativeLong;
+import com.sun.jna.Structure;
+import java.util.List;
+
+@Structure.FieldOrder({"version", "symmAlgId", "bits", "encryptedPriKey", "pubKey", "eccCipherBlob"})
+public class EnvelopedKeyBlob extends Structure {
+
+ public NativeLong version = new NativeLong();
+ public NativeLong symmAlgId = new NativeLong();
+ public NativeLong bits = new NativeLong();
+ public byte[] encryptedPriKey = new byte[64];
+ public EccRefPublicKey pubKey = new EccRefPublicKey();
+ public EccCipher eccCipherBlob = new EccCipher();
+
+ @Override
+ protected List getFieldOrder() {
+ return List.of("version", "symmAlgId", "bits", "encryptedPriKey", "pubKey", "eccCipherBlob");
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/PcieNativeLibrary.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/PcieNativeLibrary.java
new file mode 100644
index 0000000..a69d744
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/PcieNativeLibrary.java
@@ -0,0 +1,263 @@
+package com.cisd.tms.integration.crypto.pcie.jna;
+
+import com.sun.jna.Library;
+import com.sun.jna.Pointer;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.PointerByReference;
+
+public interface PcieNativeLibrary extends Library {
+
+ int SDF_OpenDevice(PointerByReference phDeviceHandle);
+
+ int SDF_CloseDevice(Pointer hDeviceHandle);
+
+ int SDF_OpenSession(Pointer hDeviceHandle, PointerByReference phSessionHandle);
+
+ int SDF_CloseSession(Pointer hSessionHandle);
+
+ int SDF_GetPrivateKeyAccessRight(Pointer hSessionHandle, int uiKeyIndex, byte[] pucPassword, int uiPwdLength);
+
+ int SDF_ReleasePrivateKeyAccessRight(Pointer hSessionHandle, int uiKeyIndex);
+
+ int SDF_GetDeviceInfo(Pointer hSessionHandle, SdfDeviceInfo deviceInfo);
+
+ int SDF_GenerateRandom(Pointer hSessionHandle, int uiLength, byte[] pucRandom);
+
+ int SDF_ImportKey(Pointer hSessionHandle, byte[] pucKey, int uiKeyLength, PointerByReference phKeyHandle);
+
+ int SDF_ImportKeyWithKEK(Pointer hSessionHandle, int uiAlgID, byte[] pucKey, int uiKeyLength,
+ int uiKEKIndex, PointerByReference phKeyHandle);
+
+ int SDF_GenerateKeyWithKEK(Pointer hSessionHandle, int uiKeyBits, int uiAlgID, int uiKEKIndex,
+ byte[] pucKey, IntByReference puiKeyLength, PointerByReference phKeyHandle);
+
+ int SDF_DestroyKey(Pointer hSessionHandle, Pointer hKeyHandle);
+
+ int SDF_ExportSignPublicKey_RSA(Pointer hSessionHandle, int uiKeyIndex, RsaRefPublicKey pucPublicKey);
+
+ int SDF_ExportEncPublicKey_RSA(Pointer hSessionHandle, int uiKeyIndex, RsaRefPublicKey pucPublicKey);
+
+ int SDF_ExportSignPublicKey_ECC(Pointer hSessionHandle, int uiKeyIndex, EccRefPublicKey pucPublicKey);
+
+ int SDF_ExportEncPublicKey_ECC(Pointer hSessionHandle, int uiKeyIndex, EccRefPublicKey pucPublicKey);
+
+ int SDF_GenerateKeyPair_RSA(Pointer hSessionHandle, int uiKeyBits, RsaRefPublicKey pucPublicKey, RsaRefPrivateKey pucPrivateKey);
+
+ int SDF_GenerateKeyPair_ECC(Pointer hSessionHandle, int uiAlgID, int uiKeyBits, EccRefPublicKey pucPublicKey, EccRefPrivateKey pucPrivateKey);
+
+ int SDF_ExternalPublicKeyOperation_RSA(Pointer hSessionHandle, RsaRefPublicKey pucPublicKey,
+ byte[] pucInput, int uiInputLength,
+ byte[] pucOutput, IntByReference puiOutputLength);
+
+ int SDF_ExternalPrivateKeyOperation_RSA(Pointer hSessionHandle, RsaRefPrivateKey pucPrivateKey,
+ byte[] pucInput, int uiInputLength,
+ byte[] pucOutput, IntByReference puiOutputLength);
+
+ int SDF_InternalPublicKeyOperation_RSA(Pointer hSessionHandle, int uiKeyIndex,
+ byte[] pucInput, int uiInputLength,
+ byte[] pucOutput, IntByReference puiOutputLength);
+
+ int SDF_InternalPrivateKeyOperation_RSA(Pointer hSessionHandle, int uiKeyIndex,
+ byte[] pucInput, int uiInputLength,
+ byte[] pucOutput, IntByReference puiOutputLength);
+
+ int SDF_InternalSign_ECC(Pointer hSessionHandle, int uiISKIndex, byte[] pucData, int uiDataLength, EccSignature pucSignature);
+
+ int SDF_InternalVerify_ECC(Pointer hSessionHandle, int uiISKIndex, byte[] pucData, int uiDataLength, EccSignature pucSignature);
+
+ int SDF_ExternalSign_ECC(Pointer hSessionHandle, int uiAlgID, EccRefPrivateKey pucPrivateKey,
+ byte[] pucData, int uiDataLength, EccSignature pucSignature);
+
+ int SDF_ExternalVerify_ECC(Pointer hSessionHandle, int uiAlgID, EccRefPublicKey pucPublicKey,
+ byte[] pucData, int uiDataLength, EccSignature pucSignature);
+
+ int SDF_ExternalEncrypt_ECC(Pointer hSessionHandle, int uiAlgID, EccRefPublicKey pucPublicKey,
+ byte[] pucData, int uiDataLength, EccCipher pucEncData);
+
+ int SDF_ExternalDecrypt_ECC(Pointer hSessionHandle, int uiAlgID, EccRefPrivateKey pucPrivateKey, EccCipher pucEncData,
+ byte[] pucData, IntByReference puiDataLength);
+
+ int SDF_GenerateKeyWithIPK_RSA(Pointer hSessionHandle, int uiIPKIndex, int uiKeyBits,
+ byte[] pucKey, IntByReference puiKeyLength, PointerByReference phKeyHandle);
+
+ int SDF_GenerateKeyWithEPK_RSA(Pointer hSessionHandle, int uiKeyBits, RsaRefPublicKey pucPublicKey,
+ byte[] pucKey, IntByReference puiKeyLength, PointerByReference phKeyHandle);
+
+ int SDF_ImportKeyWithISK_RSA(Pointer hSessionHandle, int uiISKIndex, byte[] pucKey, int uiKeyLength,
+ PointerByReference phKeyHandle);
+
+ int SDF_GenerateKeyWithIPK_ECC(Pointer hSessionHandle, int uiIPKIndex, int uiKeyBits,
+ EccCipher pucKey, PointerByReference phKeyHandle);
+
+ int SDF_GenerateKeyWithEPK_ECC(Pointer hSessionHandle, int uiKeyBits, int uiAlgID, EccRefPublicKey pucPublicKey,
+ EccCipher pucKey, PointerByReference phKeyHandle);
+
+ int SDF_ImportKeyWithISK_ECC(Pointer hSessionHandle, int uiISKIndex, EccCipher pucKey, PointerByReference phKeyHandle);
+
+ int SDF_GenerateAgreementDataAndKeyWithECC(Pointer hSessionHandle, int uiISKIndex, int uiKeyBits,
+ byte[] pucResponseID, int uiResponseIDLength,
+ byte[] pucSponsorID, int uiSponsorIDLength,
+ EccRefPublicKey pucSponsorPublicKey, EccRefPublicKey pucSponsorTmpPublicKey,
+ EccRefPublicKey pucResponsePublicKey, EccRefPublicKey pucResponseTmpPublicKey,
+ PointerByReference phKeyHandle);
+
+ int SDF_GenerateAgreementDataWithECC(Pointer hSessionHandle, int uiISKIndex, int uiKeyBits,
+ byte[] pucSponsorID, int uiSponsorIDLength,
+ EccRefPublicKey pucSponsorPublicKey, EccRefPublicKey pucSponsorTmpPublicKey,
+ PointerByReference phAgreementHandle);
+
+ int SDF_GenerateKeyWithECC(Pointer hSessionHandle, byte[] pucResponseID, int uiResponseIDLength,
+ EccRefPublicKey pucResponsePublicKey, EccRefPublicKey pucResponseTmpPublicKey,
+ Pointer hAgreementHandle,
+ PointerByReference phKeyHandle);
+
+ int SDF_ExchangeDigitEnvelopeBaseOnRSA(Pointer hSessionHandle, int uiKeyIndex, RsaRefPublicKey pucPublicKey,
+ byte[] pucDEInput, int uiDELength, byte[] pucDEOutput, IntByReference puiDELength);
+
+ int SDF_ExchangeDigitEnvelopeBaseOnECC(Pointer hSessionHandle, int uiKeyIndex, int uiAlgID,
+ EccRefPublicKey pucPublicKey, EccCipher pucEncDataIn, EccCipher pucEncDataOut);
+
+ int SDF_Encrypt(Pointer hSessionHandle, Pointer hKeyHandle, int uiAlgID, byte[] pucIV,
+ byte[] pucData, int uiDataLength, byte[] pucEncData, IntByReference puiEncDataLength);
+
+ int SDF_Decrypt(Pointer hSessionHandle, Pointer hKeyHandle, int uiAlgID, byte[] pucIV,
+ byte[] pucEncData, int uiEncDataLength, byte[] pucData, IntByReference puiDataLength);
+
+ int SDF_CalculateMAC(Pointer hSessionHandle, Pointer hKeyHandle, int uiAlgID, byte[] pucIV,
+ byte[] pucData, int uiDataLength, byte[] pucMAC, IntByReference puiMACLength);
+
+ int SDF_HashInit(Pointer hSessionHandle, int uiAlgID, EccRefPublicKey publicKey, byte[] pucID, int uiIDLength);
+
+ int SDF_HashUpdate(Pointer hSessionHandle, byte[] pucData, int uiDataLength);
+
+ int SDF_HashFinal(Pointer hSessionHandle, byte[] pucHash, IntByReference puiHashLength);
+
+ int SDF_CreateFile(Pointer hSessionHandle, byte[] pucFileName, int uiNameLen, int uiFileSize);
+
+ int SDF_DeleteFile(Pointer hSessionHandle, byte[] pucFileName, int uiNameLen);
+
+ int SDF_ReadFile(Pointer hSessionHandle, byte[] pucFileName, int uiNameLen, int uiOffset,
+ IntByReference puiReadLength, byte[] pucBuffer);
+
+ int SDF_WriteFile(Pointer hSessionHandle, byte[] pucFileName, int uiNameLen, int uiOffset,
+ int uiWriteLength, byte[] pucBuffer);
+
+ int SDFE_GetDeviceNumber(IntByReference number);
+
+ int SDFE_GetNormalDeviceNumber(Pointer hDeviceHandle, IntByReference number);
+
+ int SDFE_ChangePrivateKeyAccessPassword(Pointer hSessionHandle, int uiKeyIndex,
+ byte[] oldPassword, int oldLength,
+ byte[] newPassword, int newLength);
+
+ int SDFE_DeviceConfGet(Pointer hSessionHandle, SdfeDeviceConf deviceConf);
+
+ int SDFE_InitIdentify(Pointer hSessionHandle, byte[] oldPin, int oldPinLen, byte[] newPin, int newPinLen);
+
+ int SDFE_DeviceStatusGet(Pointer hSessionHandle, Pointer pDeviceStatus);
+
+ int SDFE_DeviceSelfTest(Pointer hSessionHandle);
+
+ int SDFE_DeviceFactoryReset(Pointer hSessionHandle);
+
+ int SDFE_GenerateKeyPair_ECC(Pointer hSessionHandle, int keyBits, int keyIndex, int keyType);
+
+ int SDFE_GenerateKeyPair_RSA(Pointer hSessionHandle, int keyBits, int keyIndex, int keyType);
+
+ int SDFE_GenerateKEK(Pointer hSessionHandle, int keyBits, int keyIndex);
+
+ int SDFE_ImportKeyPair_ECC(Pointer hSessionHandle, int keyIndex, int keyType, EccRefPublicKey publicKey, EccRefPrivateKey privateKey);
+
+ int SDFE_ImportKeyPair_RSA(Pointer hSessionHandle, int keyIndex, int keyType, RsaRefPublicKey publicKey, RsaRefPrivateKey privateKey);
+
+ int SDFE_ImportKEK(Pointer hSessionHandle, int keyIndex, byte[] keyData, int keyLen);
+
+ int SDFE_ImportKEKComponent(Pointer hSessionHandle, int keyIndex, int componentNum, SdfeKekComponent keyComponent);
+
+ int SDFE_ExportKEKComponent(Pointer hSessionHandle, int keyIndex, int componentNum, SdfeKekComponent keyComponent);
+
+ int SDFE_BackupUserKey(Pointer hSessionHandle, int keyIndex, int keyType, byte[] userKey, IntByReference userKeyLen);
+
+ int SDFE_BackupKEK(Pointer hSessionHandle, int keyIndex, byte[] key, IntByReference keyLen);
+
+ int SDFE_RecoverUserKey(Pointer hSessionHandle, int keyIndex, int keyType, byte[] userKey, int userKeyLen, byte storeFlag);
+
+ int SDFE_RecoverKEK(Pointer hSessionHandle, int keyIndex, byte[] key, int keyLen);
+
+ int SDFE_BackKey(Pointer hSessionHandle, byte[] keyImage, IntByReference keyImageSize);
+
+ int SDFE_RestoryKey(Pointer hSessionHandle, byte[] keyImage, int keyImageSize);
+
+ int SDFE_DeleteUserKey(Pointer hSessionHandle, int keyIndex);
+
+ int SDFE_DeleteKey_KEK(Pointer hSessionHandle, int keyIndex);
+
+ int SDFE_StatusUserKey_ECC(Pointer hSessionHandle, int keyIndex, int keyType, IntByReference keyState);
+
+ int SDFE_StatusUserKey_RSA(Pointer hSessionHandle, int keyIndex, int keyType, IntByReference keyState);
+
+ int SDFE_StatusKey_KEK(Pointer hSessionHandle, int keyIndex, IntByReference keyState);
+
+ int SDFE_ImportEncKeyPair_ECC(Pointer hSessionHandle, int keyIndex, EnvelopedKeyBlob envelopedKeyBlob);
+
+ int SDFE_ImportEncKeyPair_RSA(Pointer hSessionHandle, int keyIndex, int symAlgId,
+ byte[] wrappedKey, int wrappedKeyLen,
+ byte[] encryptedData, int encryptedDataLen);
+
+ int SDFE_UpdateBackedKey(Pointer hSessionHandle, byte[] oldData, int oldDataLength,
+ byte[] newData, IntByReference newDataLength);
+
+ int SDFE_GenerateLMK(Pointer hSessionHandle);
+
+ int SDFE_LoadLMK(Pointer hSessionHandle);
+
+ int SDFE_BackupLMK(Pointer hSessionHandle);
+
+ int SDFE_RecoverLMK(Pointer hSessionHandle);
+
+ int SDFE_DestroyLMK(Pointer hSessionHandle);
+
+ int SDFE_ExportLMKSeedMAC(Pointer hSessionHandle, byte[] mac);
+
+ int SDFE_CheckLMK(Pointer hSessionHandle);
+
+ int SDFE_BackupLMK_EX(Pointer hSessionHandle, SdfeLmkComponent lmkComponent);
+
+ int SDFE_RecoverLMK_EX(Pointer hSessionHandle, SdfeLmkComponent lmkComponent);
+
+ int SDFE_GenerateIK(Pointer hSessionHandle, int keyType);
+
+ int SDFE_BackupIK(Pointer hSessionHandle, int keyType);
+
+ int SDFE_RecoverIK(Pointer hSessionHandle, int keyType);
+
+ int SDFE_DestroyIK(Pointer hSessionHandle, int keyType);
+
+ int SDFE_StatusIK(Pointer hSessionHandle, int keyType, IntByReference keyState);
+
+ int SDFE_GenerateUkey(Pointer hSessionHandle, byte adminIndex,
+ byte[] ukeyPin, int ukeyPinLen,
+ byte[] loginPin, int loginPinLen);
+
+ int SDFE_LoginUkey(Pointer hSessionHandle, byte[] ukeyPin, int ukeyPinLen, byte[] loginPin, int loginPinLen);
+
+ int SDFE_ChangeUkeyPin(Pointer hSessionHandle, int pinType, byte[] oldPin, int oldPinLen, byte[] newPin, int newPinLen);
+
+ int SDFE_UnlockUkey(Pointer hSessionHandle, byte[] adminPin, int adminPinLen, byte[] userPin, int userPinLen);
+
+ int SDFE_ReadLMKComponent(Pointer hSessionHandle, byte[] ukeyPin, int ukeyPinLen);
+
+ int SDFE_ReadUkeyIKComponent(Pointer hSessionHandle, int keyType, byte[] ukeyPin, int ukeyPinLen);
+
+ int SDFE_GenerateCertificate(Pointer hSessionHandle, byte[] ukeyPin, int ukeyPinLen);
+
+ int SDFE_LoginoutAdmin(Pointer hSessionHandle, byte adminIndex);
+
+ int SDFE_LoginStatus(Pointer hSessionHandle, SdfeLoginState loginState);
+
+ int SDFE_HmacInit(Pointer hSessionHandle, int algId, byte[] key, int keyLen);
+
+ int SDFE_HmacUpdate(Pointer hSessionHandle, byte[] data, int dataLength);
+
+ int SDFE_HmacFinal(Pointer hSessionHandle, byte[] hmac, IntByReference hmacLength);
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/RsaRefPrivateKey.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/RsaRefPrivateKey.java
new file mode 100644
index 0000000..9b7768d
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/RsaRefPrivateKey.java
@@ -0,0 +1,26 @@
+package com.cisd.tms.integration.crypto.pcie.jna;
+
+import com.sun.jna.Structure;
+import java.util.List;
+
+@Structure.FieldOrder({"bits", "m", "e", "d", "prime", "pexp", "coef"})
+public class RsaRefPrivateKey extends Structure {
+
+ public static final int MAX_BITS = 2048;
+ public static final int MAX_LEN = (MAX_BITS + 7) / 8;
+ public static final int MAX_PBITS = (MAX_BITS + 1) / 2;
+ public static final int MAX_PLEN = (MAX_PBITS + 7) / 8;
+
+ public int bits;
+ public byte[] m = new byte[MAX_LEN];
+ public byte[] e = new byte[MAX_LEN];
+ public byte[] d = new byte[MAX_LEN];
+ public byte[] prime = new byte[2 * MAX_PLEN];
+ public byte[] pexp = new byte[2 * MAX_PLEN];
+ public byte[] coef = new byte[MAX_PLEN];
+
+ @Override
+ protected List getFieldOrder() {
+ return List.of("bits", "m", "e", "d", "prime", "pexp", "coef");
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/RsaRefPublicKey.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/RsaRefPublicKey.java
new file mode 100644
index 0000000..6bf001f
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/RsaRefPublicKey.java
@@ -0,0 +1,20 @@
+package com.cisd.tms.integration.crypto.pcie.jna;
+
+import com.sun.jna.Structure;
+import java.util.List;
+
+@Structure.FieldOrder({"bits", "m", "e"})
+public class RsaRefPublicKey extends Structure {
+
+ public static final int MAX_BITS = 2048;
+ public static final int MAX_LEN = (MAX_BITS + 7) / 8;
+
+ public int bits;
+ public byte[] m = new byte[MAX_LEN];
+ public byte[] e = new byte[MAX_LEN];
+
+ @Override
+ protected List getFieldOrder() {
+ return List.of("bits", "m", "e");
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfDeviceInfo.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfDeviceInfo.java
new file mode 100644
index 0000000..b0e5f08
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfDeviceInfo.java
@@ -0,0 +1,31 @@
+package com.cisd.tms.integration.crypto.pcie.jna;
+
+import com.sun.jna.Structure;
+
+@Structure.FieldOrder({
+ "issuerName",
+ "deviceName",
+ "deviceSerial",
+ "deviceVersion",
+ "standardVersion",
+ "asymAlgAbility",
+ "symAlgAbility",
+ "hashAlgAbility",
+ "bufferSize"
+})
+public class SdfDeviceInfo extends Structure {
+
+ public byte[] issuerName = new byte[40];
+ public byte[] deviceName = new byte[16];
+ public byte[] deviceSerial = new byte[16];
+ public int deviceVersion;
+ public int standardVersion;
+ public int[] asymAlgAbility = new int[2];
+ public int symAlgAbility;
+ public int hashAlgAbility;
+ public int bufferSize;
+
+ public SdfDeviceInfo() {
+ super(ALIGN_NONE);
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfeDeviceConf.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfeDeviceConf.java
new file mode 100644
index 0000000..7a19b64
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfeDeviceConf.java
@@ -0,0 +1,27 @@
+package com.cisd.tms.integration.crypto.pcie.jna;
+
+import com.sun.jna.Structure;
+
+@Structure.FieldOrder({
+ "level",
+ "devCount",
+ "rsaKeyCount",
+ "sm2KeyCount",
+ "kekCount",
+ "sessKeyCount",
+ "fileSysCapacity"
+})
+public class SdfeDeviceConf extends Structure {
+
+ public int level;
+ public int devCount;
+ public int rsaKeyCount;
+ public int sm2KeyCount;
+ public int kekCount;
+ public int sessKeyCount;
+ public int fileSysCapacity;
+
+ public SdfeDeviceConf() {
+ super(ALIGN_NONE);
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfeKekComponent.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfeKekComponent.java
new file mode 100644
index 0000000..440a9a4
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfeKekComponent.java
@@ -0,0 +1,19 @@
+package com.cisd.tms.integration.crypto.pcie.jna;
+
+import com.sun.jna.Structure;
+import java.util.List;
+
+@Structure.FieldOrder({"keyLen", "component", "kekMac"})
+public class SdfeKekComponent extends Structure {
+
+ public static final int KEK_MAX_LEN = 32;
+
+ public byte keyLen;
+ public byte[] component = new byte[9 * KEK_MAX_LEN];
+ public byte[] kekMac = new byte[8];
+
+ @Override
+ protected List getFieldOrder() {
+ return List.of("keyLen", "component", "kekMac");
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfeLmkComponent.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfeLmkComponent.java
new file mode 100644
index 0000000..52bdc1b
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfeLmkComponent.java
@@ -0,0 +1,16 @@
+package com.cisd.tms.integration.crypto.pcie.jna;
+
+import com.sun.jna.Structure;
+import java.util.List;
+
+@Structure.FieldOrder({"lmkMac", "component"})
+public class SdfeLmkComponent extends Structure {
+
+ public byte[] lmkMac = new byte[8];
+ public byte[] component = new byte[3 * 16];
+
+ @Override
+ protected List getFieldOrder() {
+ return List.of("lmkMac", "component");
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfeLoginState.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfeLoginState.java
new file mode 100644
index 0000000..6783ff2
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/SdfeLoginState.java
@@ -0,0 +1,11 @@
+package com.cisd.tms.integration.crypto.pcie.jna;
+
+import com.sun.jna.Structure;
+
+@Structure.FieldOrder({"admin1", "admin2", "admin3"})
+public class SdfeLoginState extends Structure {
+
+ public int admin1;
+ public int admin2;
+ public int admin3;
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/package-info.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/package-info.java
new file mode 100644
index 0000000..c2b8aec
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/jna/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * JNA bindings and provider implementation for PCIe crypto card native library.
+ */
+package com.cisd.tms.integration.crypto.pcie.jna;
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/AgreementDataAndKeyEccResult.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/AgreementDataAndKeyEccResult.java
new file mode 100644
index 0000000..0acfb07
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/AgreementDataAndKeyEccResult.java
@@ -0,0 +1,50 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class AgreementDataAndKeyEccResult {
+
+ private byte[] responsePublicKey;
+ private int responsePublicKeyLength;
+ private byte[] responseTmpPublicKey;
+ private int responseTmpPublicKeyLength;
+ private boolean sessionKeyGenerated;
+
+ public byte[] getResponsePublicKey() {
+ return responsePublicKey;
+ }
+
+ public void setResponsePublicKey(byte[] responsePublicKey) {
+ this.responsePublicKey = responsePublicKey;
+ }
+
+ public int getResponsePublicKeyLength() {
+ return responsePublicKeyLength;
+ }
+
+ public void setResponsePublicKeyLength(int responsePublicKeyLength) {
+ this.responsePublicKeyLength = responsePublicKeyLength;
+ }
+
+ public byte[] getResponseTmpPublicKey() {
+ return responseTmpPublicKey;
+ }
+
+ public void setResponseTmpPublicKey(byte[] responseTmpPublicKey) {
+ this.responseTmpPublicKey = responseTmpPublicKey;
+ }
+
+ public int getResponseTmpPublicKeyLength() {
+ return responseTmpPublicKeyLength;
+ }
+
+ public void setResponseTmpPublicKeyLength(int responseTmpPublicKeyLength) {
+ this.responseTmpPublicKeyLength = responseTmpPublicKeyLength;
+ }
+
+ public boolean isSessionKeyGenerated() {
+ return sessionKeyGenerated;
+ }
+
+ public void setSessionKeyGenerated(boolean sessionKeyGenerated) {
+ this.sessionKeyGenerated = sessionKeyGenerated;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/BackupDataResult.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/BackupDataResult.java
new file mode 100644
index 0000000..c064e61
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/BackupDataResult.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class BackupDataResult {
+
+ private byte[] data;
+ private int length;
+
+ public byte[] getData() {
+ return data;
+ }
+
+ public void setData(byte[] data) {
+ this.data = data;
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ public void setLength(int length) {
+ this.length = length;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ChangePrivateKeyPasswordRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ChangePrivateKeyPasswordRequest.java
new file mode 100644
index 0000000..6319abc
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ChangePrivateKeyPasswordRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class ChangePrivateKeyPasswordRequest {
+
+ private int keyIndex;
+ private byte[] oldPassword;
+ private byte[] newPassword;
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public byte[] getOldPassword() {
+ return oldPassword;
+ }
+
+ public void setOldPassword(byte[] oldPassword) {
+ this.oldPassword = oldPassword;
+ }
+
+ public byte[] getNewPassword() {
+ return newPassword;
+ }
+
+ public void setNewPassword(byte[] newPassword) {
+ this.newPassword = newPassword;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DeviceConfResult.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DeviceConfResult.java
new file mode 100644
index 0000000..4169d11
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DeviceConfResult.java
@@ -0,0 +1,68 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class DeviceConfResult {
+
+ private int level;
+ private int devCount;
+ private int rsaKeyCount;
+ private int sm2KeyCount;
+ private int kekCount;
+ private int sessKeyCount;
+ private int fileSysCapacity;
+
+ public int getLevel() {
+ return level;
+ }
+
+ public void setLevel(int level) {
+ this.level = level;
+ }
+
+ public int getDevCount() {
+ return devCount;
+ }
+
+ public void setDevCount(int devCount) {
+ this.devCount = devCount;
+ }
+
+ public int getRsaKeyCount() {
+ return rsaKeyCount;
+ }
+
+ public void setRsaKeyCount(int rsaKeyCount) {
+ this.rsaKeyCount = rsaKeyCount;
+ }
+
+ public int getSm2KeyCount() {
+ return sm2KeyCount;
+ }
+
+ public void setSm2KeyCount(int sm2KeyCount) {
+ this.sm2KeyCount = sm2KeyCount;
+ }
+
+ public int getKekCount() {
+ return kekCount;
+ }
+
+ public void setKekCount(int kekCount) {
+ this.kekCount = kekCount;
+ }
+
+ public int getSessKeyCount() {
+ return sessKeyCount;
+ }
+
+ public void setSessKeyCount(int sessKeyCount) {
+ this.sessKeyCount = sessKeyCount;
+ }
+
+ public int getFileSysCapacity() {
+ return fileSysCapacity;
+ }
+
+ public void setFileSysCapacity(int fileSysCapacity) {
+ this.fileSysCapacity = fileSysCapacity;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DeviceCountResult.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DeviceCountResult.java
new file mode 100644
index 0000000..3022f11
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DeviceCountResult.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class DeviceCountResult {
+
+ private int deviceNumber;
+ private int normalDeviceNumber;
+
+ public int getDeviceNumber() {
+ return deviceNumber;
+ }
+
+ public void setDeviceNumber(int deviceNumber) {
+ this.deviceNumber = deviceNumber;
+ }
+
+ public int getNormalDeviceNumber() {
+ return normalDeviceNumber;
+ }
+
+ public void setNormalDeviceNumber(int normalDeviceNumber) {
+ this.normalDeviceNumber = normalDeviceNumber;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DeviceInfoResult.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DeviceInfoResult.java
new file mode 100644
index 0000000..ba7e5ae
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DeviceInfoResult.java
@@ -0,0 +1,95 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class DeviceInfoResult {
+
+ private String issuerName;
+ private String deviceName;
+ private String deviceSerial;
+ private int deviceVersion;
+ private int standardVersion;
+ private int asymAlgAbility0;
+ private int asymAlgAbility1;
+ private int symAlgAbility;
+ private int hashAlgAbility;
+ private int bufferSize;
+
+ public String getIssuerName() {
+ return issuerName;
+ }
+
+ public void setIssuerName(String issuerName) {
+ this.issuerName = issuerName;
+ }
+
+ public String getDeviceName() {
+ return deviceName;
+ }
+
+ public void setDeviceName(String deviceName) {
+ this.deviceName = deviceName;
+ }
+
+ public String getDeviceSerial() {
+ return deviceSerial;
+ }
+
+ public void setDeviceSerial(String deviceSerial) {
+ this.deviceSerial = deviceSerial;
+ }
+
+ public int getDeviceVersion() {
+ return deviceVersion;
+ }
+
+ public void setDeviceVersion(int deviceVersion) {
+ this.deviceVersion = deviceVersion;
+ }
+
+ public int getStandardVersion() {
+ return standardVersion;
+ }
+
+ public void setStandardVersion(int standardVersion) {
+ this.standardVersion = standardVersion;
+ }
+
+ public int getAsymAlgAbility0() {
+ return asymAlgAbility0;
+ }
+
+ public void setAsymAlgAbility0(int asymAlgAbility0) {
+ this.asymAlgAbility0 = asymAlgAbility0;
+ }
+
+ public int getAsymAlgAbility1() {
+ return asymAlgAbility1;
+ }
+
+ public void setAsymAlgAbility1(int asymAlgAbility1) {
+ this.asymAlgAbility1 = asymAlgAbility1;
+ }
+
+ public int getSymAlgAbility() {
+ return symAlgAbility;
+ }
+
+ public void setSymAlgAbility(int symAlgAbility) {
+ this.symAlgAbility = symAlgAbility;
+ }
+
+ public int getHashAlgAbility() {
+ return hashAlgAbility;
+ }
+
+ public void setHashAlgAbility(int hashAlgAbility) {
+ this.hashAlgAbility = hashAlgAbility;
+ }
+
+ public int getBufferSize() {
+ return bufferSize;
+ }
+
+ public void setBufferSize(int bufferSize) {
+ this.bufferSize = bufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DeviceStatusResult.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DeviceStatusResult.java
new file mode 100644
index 0000000..e5a5dbe
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DeviceStatusResult.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class DeviceStatusResult {
+
+ private byte[] statusData;
+ private int length;
+
+ public byte[] getStatusData() {
+ return statusData;
+ }
+
+ public void setStatusData(byte[] statusData) {
+ this.statusData = statusData;
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ public void setLength(int length) {
+ this.length = length;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DigestRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DigestRequest.java
new file mode 100644
index 0000000..fe57146
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/DigestRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class DigestRequest {
+
+ private int algId;
+ private byte[] data;
+ private int outBufferSize = 64;
+
+ public int getAlgId() {
+ return algId;
+ }
+
+ public void setAlgId(int algId) {
+ this.algId = algId;
+ }
+
+ 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;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccAgreementSessionKeyRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccAgreementSessionKeyRequest.java
new file mode 100644
index 0000000..74b6dae
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccAgreementSessionKeyRequest.java
@@ -0,0 +1,86 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class EccAgreementSessionKeyRequest {
+
+ private int iskIndex;
+ private int keyBits;
+ private byte[] sponsorId;
+ private byte[] responseId;
+ private byte[] responsePublicKeyBlob;
+ private byte[] responseTmpPublicKeyBlob;
+ private int sponsorPublicKeyBufferSize;
+ private int sponsorTmpPublicKeyBufferSize;
+ private int sessionKeyBufferSize;
+
+ public int getIskIndex() {
+ return iskIndex;
+ }
+
+ public void setIskIndex(int iskIndex) {
+ this.iskIndex = iskIndex;
+ }
+
+ public int getKeyBits() {
+ return keyBits;
+ }
+
+ public void setKeyBits(int keyBits) {
+ this.keyBits = keyBits;
+ }
+
+ public byte[] getSponsorId() {
+ return sponsorId;
+ }
+
+ public void setSponsorId(byte[] sponsorId) {
+ this.sponsorId = sponsorId;
+ }
+
+ public byte[] getResponseId() {
+ return responseId;
+ }
+
+ public void setResponseId(byte[] responseId) {
+ this.responseId = responseId;
+ }
+
+ public byte[] getResponsePublicKeyBlob() {
+ return responsePublicKeyBlob;
+ }
+
+ public void setResponsePublicKeyBlob(byte[] responsePublicKeyBlob) {
+ this.responsePublicKeyBlob = responsePublicKeyBlob;
+ }
+
+ public byte[] getResponseTmpPublicKeyBlob() {
+ return responseTmpPublicKeyBlob;
+ }
+
+ public void setResponseTmpPublicKeyBlob(byte[] responseTmpPublicKeyBlob) {
+ this.responseTmpPublicKeyBlob = responseTmpPublicKeyBlob;
+ }
+
+ public int getSponsorPublicKeyBufferSize() {
+ return sponsorPublicKeyBufferSize;
+ }
+
+ public void setSponsorPublicKeyBufferSize(int sponsorPublicKeyBufferSize) {
+ this.sponsorPublicKeyBufferSize = sponsorPublicKeyBufferSize;
+ }
+
+ public int getSponsorTmpPublicKeyBufferSize() {
+ return sponsorTmpPublicKeyBufferSize;
+ }
+
+ public void setSponsorTmpPublicKeyBufferSize(int sponsorTmpPublicKeyBufferSize) {
+ this.sponsorTmpPublicKeyBufferSize = sponsorTmpPublicKeyBufferSize;
+ }
+
+ public int getSessionKeyBufferSize() {
+ return sessionKeyBufferSize;
+ }
+
+ public void setSessionKeyBufferSize(int sessionKeyBufferSize) {
+ this.sessionKeyBufferSize = sessionKeyBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccAgreementSessionKeyResult.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccAgreementSessionKeyResult.java
new file mode 100644
index 0000000..120cd4f
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccAgreementSessionKeyResult.java
@@ -0,0 +1,68 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class EccAgreementSessionKeyResult {
+
+ private byte[] sponsorPublicKey;
+ private int sponsorPublicKeyLength;
+ private byte[] sponsorTmpPublicKey;
+ private int sponsorTmpPublicKeyLength;
+ private byte[] sessionKey;
+ private int sessionKeyLength;
+ private boolean sessionKeyGenerated;
+
+ public byte[] getSponsorPublicKey() {
+ return sponsorPublicKey;
+ }
+
+ public void setSponsorPublicKey(byte[] sponsorPublicKey) {
+ this.sponsorPublicKey = sponsorPublicKey;
+ }
+
+ public int getSponsorPublicKeyLength() {
+ return sponsorPublicKeyLength;
+ }
+
+ public void setSponsorPublicKeyLength(int sponsorPublicKeyLength) {
+ this.sponsorPublicKeyLength = sponsorPublicKeyLength;
+ }
+
+ public byte[] getSponsorTmpPublicKey() {
+ return sponsorTmpPublicKey;
+ }
+
+ public void setSponsorTmpPublicKey(byte[] sponsorTmpPublicKey) {
+ this.sponsorTmpPublicKey = sponsorTmpPublicKey;
+ }
+
+ public int getSponsorTmpPublicKeyLength() {
+ return sponsorTmpPublicKeyLength;
+ }
+
+ public void setSponsorTmpPublicKeyLength(int sponsorTmpPublicKeyLength) {
+ this.sponsorTmpPublicKeyLength = sponsorTmpPublicKeyLength;
+ }
+
+ public byte[] getSessionKey() {
+ return sessionKey;
+ }
+
+ public void setSessionKey(byte[] sessionKey) {
+ this.sessionKey = sessionKey;
+ }
+
+ public int getSessionKeyLength() {
+ return sessionKeyLength;
+ }
+
+ public void setSessionKeyLength(int sessionKeyLength) {
+ this.sessionKeyLength = sessionKeyLength;
+ }
+
+ public boolean isSessionKeyGenerated() {
+ return sessionKeyGenerated;
+ }
+
+ public void setSessionKeyGenerated(boolean sessionKeyGenerated) {
+ this.sessionKeyGenerated = sessionKeyGenerated;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccExternalDecryptRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccExternalDecryptRequest.java
new file mode 100644
index 0000000..9a1569c
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccExternalDecryptRequest.java
@@ -0,0 +1,41 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class EccExternalDecryptRequest {
+
+ private int algId;
+ private byte[] privateKeyBlob;
+ private byte[] encryptedData;
+ private int outBufferSize;
+
+ public int getAlgId() {
+ return algId;
+ }
+
+ public void setAlgId(int algId) {
+ this.algId = algId;
+ }
+
+ public byte[] getPrivateKeyBlob() {
+ return privateKeyBlob;
+ }
+
+ public void setPrivateKeyBlob(byte[] privateKeyBlob) {
+ this.privateKeyBlob = privateKeyBlob;
+ }
+
+ public byte[] getEncryptedData() {
+ return encryptedData;
+ }
+
+ public void setEncryptedData(byte[] encryptedData) {
+ this.encryptedData = encryptedData;
+ }
+
+ public int getOutBufferSize() {
+ return outBufferSize;
+ }
+
+ public void setOutBufferSize(int outBufferSize) {
+ this.outBufferSize = outBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccExternalEncryptRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccExternalEncryptRequest.java
new file mode 100644
index 0000000..004b291
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccExternalEncryptRequest.java
@@ -0,0 +1,41 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class EccExternalEncryptRequest {
+
+ private int algId;
+ private byte[] publicKeyBlob;
+ private byte[] data;
+ private int outBufferSize;
+
+ public int getAlgId() {
+ return algId;
+ }
+
+ public void setAlgId(int algId) {
+ this.algId = algId;
+ }
+
+ public byte[] getPublicKeyBlob() {
+ return publicKeyBlob;
+ }
+
+ public void setPublicKeyBlob(byte[] publicKeyBlob) {
+ this.publicKeyBlob = publicKeyBlob;
+ }
+
+ 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;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccExternalSignRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccExternalSignRequest.java
new file mode 100644
index 0000000..a3d7feb
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccExternalSignRequest.java
@@ -0,0 +1,41 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class EccExternalSignRequest {
+
+ private int algId;
+ private byte[] privateKeyBlob;
+ private byte[] data;
+ private int signatureBufferSize;
+
+ public int getAlgId() {
+ return algId;
+ }
+
+ public void setAlgId(int algId) {
+ this.algId = algId;
+ }
+
+ public byte[] getPrivateKeyBlob() {
+ return privateKeyBlob;
+ }
+
+ public void setPrivateKeyBlob(byte[] privateKeyBlob) {
+ this.privateKeyBlob = privateKeyBlob;
+ }
+
+ 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;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccExternalVerifyRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccExternalVerifyRequest.java
new file mode 100644
index 0000000..b94dea8
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccExternalVerifyRequest.java
@@ -0,0 +1,41 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class EccExternalVerifyRequest {
+
+ private int algId;
+ private byte[] publicKeyBlob;
+ private byte[] data;
+ private byte[] signature;
+
+ public int getAlgId() {
+ return algId;
+ }
+
+ public void setAlgId(int algId) {
+ this.algId = algId;
+ }
+
+ public byte[] getPublicKeyBlob() {
+ return publicKeyBlob;
+ }
+
+ public void setPublicKeyBlob(byte[] publicKeyBlob) {
+ this.publicKeyBlob = publicKeyBlob;
+ }
+
+ 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;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccInternalSignRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccInternalSignRequest.java
new file mode 100644
index 0000000..b59f617
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccInternalSignRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class EccInternalSignRequest {
+
+ private int keyIndex;
+ private byte[] data;
+ private int signatureBufferSize;
+
+ 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 getSignatureBufferSize() {
+ return signatureBufferSize;
+ }
+
+ public void setSignatureBufferSize(int signatureBufferSize) {
+ this.signatureBufferSize = signatureBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccInternalVerifyRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccInternalVerifyRequest.java
new file mode 100644
index 0000000..df56170
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/EccInternalVerifyRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class EccInternalVerifyRequest {
+
+ private int keyIndex;
+ private byte[] data;
+ private byte[] signature;
+
+ 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 byte[] getSignature() {
+ return signature;
+ }
+
+ public void setSignature(byte[] signature) {
+ this.signature = signature;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ExchangeDigitEnvelopeEccRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ExchangeDigitEnvelopeEccRequest.java
new file mode 100644
index 0000000..ddc744b
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ExchangeDigitEnvelopeEccRequest.java
@@ -0,0 +1,50 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class ExchangeDigitEnvelopeEccRequest {
+
+ private int keyIndex;
+ private int algId;
+ private byte[] publicKeyBlob;
+ private byte[] inputEnvelopeBlob;
+ private int outBufferSize;
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public int getAlgId() {
+ return algId;
+ }
+
+ public void setAlgId(int algId) {
+ this.algId = algId;
+ }
+
+ public byte[] getPublicKeyBlob() {
+ return publicKeyBlob;
+ }
+
+ public void setPublicKeyBlob(byte[] publicKeyBlob) {
+ this.publicKeyBlob = publicKeyBlob;
+ }
+
+ public byte[] getInputEnvelopeBlob() {
+ return inputEnvelopeBlob;
+ }
+
+ public void setInputEnvelopeBlob(byte[] inputEnvelopeBlob) {
+ this.inputEnvelopeBlob = inputEnvelopeBlob;
+ }
+
+ public int getOutBufferSize() {
+ return outBufferSize;
+ }
+
+ public void setOutBufferSize(int outBufferSize) {
+ this.outBufferSize = outBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ExchangeDigitEnvelopeRsaRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ExchangeDigitEnvelopeRsaRequest.java
new file mode 100644
index 0000000..4d9361b
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ExchangeDigitEnvelopeRsaRequest.java
@@ -0,0 +1,41 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class ExchangeDigitEnvelopeRsaRequest {
+
+ private int keyIndex;
+ private byte[] publicKeyBlob;
+ private byte[] inputEnvelopeBlob;
+ private int outBufferSize;
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public byte[] getPublicKeyBlob() {
+ return publicKeyBlob;
+ }
+
+ public void setPublicKeyBlob(byte[] publicKeyBlob) {
+ this.publicKeyBlob = publicKeyBlob;
+ }
+
+ public byte[] getInputEnvelopeBlob() {
+ return inputEnvelopeBlob;
+ }
+
+ public void setInputEnvelopeBlob(byte[] inputEnvelopeBlob) {
+ this.inputEnvelopeBlob = inputEnvelopeBlob;
+ }
+
+ public int getOutBufferSize() {
+ return outBufferSize;
+ }
+
+ public void setOutBufferSize(int outBufferSize) {
+ this.outBufferSize = outBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ExportKekComponentRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ExportKekComponentRequest.java
new file mode 100644
index 0000000..bec135e
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ExportKekComponentRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class ExportKekComponentRequest {
+
+ private int keyIndex;
+ private int componentNum;
+ private int componentSize;
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public int getComponentNum() {
+ return componentNum;
+ }
+
+ public void setComponentNum(int componentNum) {
+ this.componentNum = componentNum;
+ }
+
+ public int getComponentSize() {
+ return componentSize;
+ }
+
+ public void setComponentSize(int componentSize) {
+ this.componentSize = componentSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/FileCreateRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/FileCreateRequest.java
new file mode 100644
index 0000000..c37e0d7
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/FileCreateRequest.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class FileCreateRequest {
+
+ private String fileName;
+ private int fileSize;
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public int getFileSize() {
+ return fileSize;
+ }
+
+ public void setFileSize(int fileSize) {
+ this.fileSize = fileSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/FileReadRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/FileReadRequest.java
new file mode 100644
index 0000000..cda6251
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/FileReadRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class FileReadRequest {
+
+ private String fileName;
+ private int offset;
+ private int readLength;
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public void setOffset(int offset) {
+ this.offset = offset;
+ }
+
+ public int getReadLength() {
+ return readLength;
+ }
+
+ public void setReadLength(int readLength) {
+ this.readLength = readLength;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/FileWriteRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/FileWriteRequest.java
new file mode 100644
index 0000000..bb48010
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/FileWriteRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class FileWriteRequest {
+
+ private String fileName;
+ private int offset;
+ private byte[] data;
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public void setOffset(int offset) {
+ this.offset = offset;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+
+ public void setData(byte[] data) {
+ this.data = data;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateAgreementDataAndKeyEccRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateAgreementDataAndKeyEccRequest.java
new file mode 100644
index 0000000..8915110
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateAgreementDataAndKeyEccRequest.java
@@ -0,0 +1,77 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class GenerateAgreementDataAndKeyEccRequest {
+
+ private int iskIndex;
+ private int keyBits;
+ private byte[] responseId;
+ private byte[] sponsorId;
+ private byte[] sponsorPublicKeyBlob;
+ private byte[] sponsorTmpPublicKeyBlob;
+ private int responsePublicKeyBufferSize;
+ private int responseTmpPublicKeyBufferSize;
+
+ public int getIskIndex() {
+ return iskIndex;
+ }
+
+ public void setIskIndex(int iskIndex) {
+ this.iskIndex = iskIndex;
+ }
+
+ public int getKeyBits() {
+ return keyBits;
+ }
+
+ public void setKeyBits(int keyBits) {
+ this.keyBits = keyBits;
+ }
+
+ public byte[] getResponseId() {
+ return responseId;
+ }
+
+ public void setResponseId(byte[] responseId) {
+ this.responseId = responseId;
+ }
+
+ public byte[] getSponsorId() {
+ return sponsorId;
+ }
+
+ public void setSponsorId(byte[] sponsorId) {
+ this.sponsorId = sponsorId;
+ }
+
+ public byte[] getSponsorPublicKeyBlob() {
+ return sponsorPublicKeyBlob;
+ }
+
+ public void setSponsorPublicKeyBlob(byte[] sponsorPublicKeyBlob) {
+ this.sponsorPublicKeyBlob = sponsorPublicKeyBlob;
+ }
+
+ public byte[] getSponsorTmpPublicKeyBlob() {
+ return sponsorTmpPublicKeyBlob;
+ }
+
+ public void setSponsorTmpPublicKeyBlob(byte[] sponsorTmpPublicKeyBlob) {
+ this.sponsorTmpPublicKeyBlob = sponsorTmpPublicKeyBlob;
+ }
+
+ public int getResponsePublicKeyBufferSize() {
+ return responsePublicKeyBufferSize;
+ }
+
+ public void setResponsePublicKeyBufferSize(int responsePublicKeyBufferSize) {
+ this.responsePublicKeyBufferSize = responsePublicKeyBufferSize;
+ }
+
+ public int getResponseTmpPublicKeyBufferSize() {
+ return responseTmpPublicKeyBufferSize;
+ }
+
+ public void setResponseTmpPublicKeyBufferSize(int responseTmpPublicKeyBufferSize) {
+ this.responseTmpPublicKeyBufferSize = responseTmpPublicKeyBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKekRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKekRequest.java
new file mode 100644
index 0000000..13f1229
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKekRequest.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class GenerateKekRequest {
+
+ private int keyBits;
+ private int keyIndex;
+
+ public int getKeyBits() {
+ return keyBits;
+ }
+
+ public void setKeyBits(int keyBits) {
+ this.keyBits = keyBits;
+ }
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyPairRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyPairRequest.java
new file mode 100644
index 0000000..9bddab0
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyPairRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class GenerateKeyPairRequest {
+
+ private int keyBits;
+ private int keyIndex;
+ private int keyType;
+
+ public int getKeyBits() {
+ return keyBits;
+ }
+
+ public void setKeyBits(int keyBits) {
+ this.keyBits = keyBits;
+ }
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public int getKeyType() {
+ return keyType;
+ }
+
+ public void setKeyType(int keyType) {
+ this.keyType = keyType;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithEpkEccRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithEpkEccRequest.java
new file mode 100644
index 0000000..77bded0
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithEpkEccRequest.java
@@ -0,0 +1,41 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class GenerateKeyWithEpkEccRequest {
+
+ private int keyBits;
+ private int algId;
+ private byte[] publicKeyBlob;
+ private int outBufferSize;
+
+ public int getKeyBits() {
+ return keyBits;
+ }
+
+ public void setKeyBits(int keyBits) {
+ this.keyBits = keyBits;
+ }
+
+ public int getAlgId() {
+ return algId;
+ }
+
+ public void setAlgId(int algId) {
+ this.algId = algId;
+ }
+
+ public byte[] getPublicKeyBlob() {
+ return publicKeyBlob;
+ }
+
+ public void setPublicKeyBlob(byte[] publicKeyBlob) {
+ this.publicKeyBlob = publicKeyBlob;
+ }
+
+ public int getOutBufferSize() {
+ return outBufferSize;
+ }
+
+ public void setOutBufferSize(int outBufferSize) {
+ this.outBufferSize = outBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithEpkRsaRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithEpkRsaRequest.java
new file mode 100644
index 0000000..2c6894c
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithEpkRsaRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class GenerateKeyWithEpkRsaRequest {
+
+ private int keyBits;
+ private byte[] publicKeyBlob;
+ private int outBufferSize;
+
+ public int getKeyBits() {
+ return keyBits;
+ }
+
+ public void setKeyBits(int keyBits) {
+ this.keyBits = keyBits;
+ }
+
+ public byte[] getPublicKeyBlob() {
+ return publicKeyBlob;
+ }
+
+ public void setPublicKeyBlob(byte[] publicKeyBlob) {
+ this.publicKeyBlob = publicKeyBlob;
+ }
+
+ public int getOutBufferSize() {
+ return outBufferSize;
+ }
+
+ public void setOutBufferSize(int outBufferSize) {
+ this.outBufferSize = outBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithIpkEccRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithIpkEccRequest.java
new file mode 100644
index 0000000..5742ced
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithIpkEccRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class GenerateKeyWithIpkEccRequest {
+
+ private int ipkIndex;
+ private int keyBits;
+ private int outBufferSize;
+
+ public int getIpkIndex() {
+ return ipkIndex;
+ }
+
+ public void setIpkIndex(int ipkIndex) {
+ this.ipkIndex = ipkIndex;
+ }
+
+ public int getKeyBits() {
+ return keyBits;
+ }
+
+ public void setKeyBits(int keyBits) {
+ this.keyBits = keyBits;
+ }
+
+ public int getOutBufferSize() {
+ return outBufferSize;
+ }
+
+ public void setOutBufferSize(int outBufferSize) {
+ this.outBufferSize = outBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithIpkRsaRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithIpkRsaRequest.java
new file mode 100644
index 0000000..458e75e
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithIpkRsaRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class GenerateKeyWithIpkRsaRequest {
+
+ private int ipkIndex;
+ private int keyBits;
+ private int outBufferSize;
+
+ public int getIpkIndex() {
+ return ipkIndex;
+ }
+
+ public void setIpkIndex(int ipkIndex) {
+ this.ipkIndex = ipkIndex;
+ }
+
+ public int getKeyBits() {
+ return keyBits;
+ }
+
+ public void setKeyBits(int keyBits) {
+ this.keyBits = keyBits;
+ }
+
+ public int getOutBufferSize() {
+ return outBufferSize;
+ }
+
+ public void setOutBufferSize(int outBufferSize) {
+ this.outBufferSize = outBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithKekRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithKekRequest.java
new file mode 100644
index 0000000..e000e9d
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateKeyWithKekRequest.java
@@ -0,0 +1,41 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class GenerateKeyWithKekRequest {
+
+ private int keyBits;
+ private int algId;
+ private int kekIndex;
+ private int outBufferSize;
+
+ public int getKeyBits() {
+ return keyBits;
+ }
+
+ public void setKeyBits(int keyBits) {
+ this.keyBits = keyBits;
+ }
+
+ public int getAlgId() {
+ return algId;
+ }
+
+ public void setAlgId(int algId) {
+ this.algId = algId;
+ }
+
+ public int getKekIndex() {
+ return kekIndex;
+ }
+
+ public void setKekIndex(int kekIndex) {
+ this.kekIndex = kekIndex;
+ }
+
+ public int getOutBufferSize() {
+ return outBufferSize;
+ }
+
+ public void setOutBufferSize(int outBufferSize) {
+ this.outBufferSize = outBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateStandardEccKeyPairRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateStandardEccKeyPairRequest.java
new file mode 100644
index 0000000..385fc8a
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateStandardEccKeyPairRequest.java
@@ -0,0 +1,41 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class GenerateStandardEccKeyPairRequest {
+
+ private int algId;
+ private int keyBits;
+ private int publicKeyBufferSize;
+ private int privateKeyBufferSize;
+
+ public int getAlgId() {
+ return algId;
+ }
+
+ public void setAlgId(int algId) {
+ this.algId = algId;
+ }
+
+ public int getKeyBits() {
+ return keyBits;
+ }
+
+ public void setKeyBits(int keyBits) {
+ this.keyBits = keyBits;
+ }
+
+ public int getPublicKeyBufferSize() {
+ return publicKeyBufferSize;
+ }
+
+ public void setPublicKeyBufferSize(int publicKeyBufferSize) {
+ this.publicKeyBufferSize = publicKeyBufferSize;
+ }
+
+ public int getPrivateKeyBufferSize() {
+ return privateKeyBufferSize;
+ }
+
+ public void setPrivateKeyBufferSize(int privateKeyBufferSize) {
+ this.privateKeyBufferSize = privateKeyBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateStandardRsaKeyPairRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateStandardRsaKeyPairRequest.java
new file mode 100644
index 0000000..51bbfe9
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/GenerateStandardRsaKeyPairRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class GenerateStandardRsaKeyPairRequest {
+
+ private int keyBits;
+ private int publicKeyBufferSize;
+ private int privateKeyBufferSize;
+
+ public int getKeyBits() {
+ return keyBits;
+ }
+
+ public void setKeyBits(int keyBits) {
+ this.keyBits = keyBits;
+ }
+
+ public int getPublicKeyBufferSize() {
+ return publicKeyBufferSize;
+ }
+
+ public void setPublicKeyBufferSize(int publicKeyBufferSize) {
+ this.publicKeyBufferSize = publicKeyBufferSize;
+ }
+
+ public int getPrivateKeyBufferSize() {
+ return privateKeyBufferSize;
+ }
+
+ public void setPrivateKeyBufferSize(int privateKeyBufferSize) {
+ this.privateKeyBufferSize = privateKeyBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/HmacRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/HmacRequest.java
new file mode 100644
index 0000000..55647a1
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/HmacRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class HmacRequest {
+
+ private int algId;
+ private byte[] key;
+ private byte[] data;
+
+ public int getAlgId() {
+ return algId;
+ }
+
+ public void setAlgId(int algId) {
+ this.algId = algId;
+ }
+
+ public byte[] getKey() {
+ return key;
+ }
+
+ public void setKey(byte[] key) {
+ this.key = key;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+
+ public void setData(byte[] data) {
+ this.data = data;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/HmacResult.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/HmacResult.java
new file mode 100644
index 0000000..4849042
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/HmacResult.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class HmacResult {
+
+ private byte[] hmac;
+ private int hmacLength;
+
+ public byte[] getHmac() {
+ return hmac;
+ }
+
+ public void setHmac(byte[] hmac) {
+ this.hmac = hmac;
+ }
+
+ public int getHmacLength() {
+ return hmacLength;
+ }
+
+ public void setHmacLength(int hmacLength) {
+ this.hmacLength = hmacLength;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportEncKeyPairEccRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportEncKeyPairEccRequest.java
new file mode 100644
index 0000000..83fcb18
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportEncKeyPairEccRequest.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class ImportEncKeyPairEccRequest {
+
+ private int keyIndex;
+ private byte[] envelopedKeyBlob;
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public byte[] getEnvelopedKeyBlob() {
+ return envelopedKeyBlob;
+ }
+
+ public void setEnvelopedKeyBlob(byte[] envelopedKeyBlob) {
+ this.envelopedKeyBlob = envelopedKeyBlob;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportEncKeyPairRsaRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportEncKeyPairRsaRequest.java
new file mode 100644
index 0000000..979952b
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportEncKeyPairRsaRequest.java
@@ -0,0 +1,41 @@
+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;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportKekRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportKekRequest.java
new file mode 100644
index 0000000..028819b
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportKekRequest.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class ImportKekRequest {
+
+ private int keyIndex;
+ private byte[] keyData;
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public byte[] getKeyData() {
+ return keyData;
+ }
+
+ public void setKeyData(byte[] keyData) {
+ this.keyData = keyData;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportKeyPairRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportKeyPairRequest.java
new file mode 100644
index 0000000..151ab7b
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportKeyPairRequest.java
@@ -0,0 +1,41 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class ImportKeyPairRequest {
+
+ private int keyIndex;
+ private int keyType;
+ private byte[] publicKey;
+ private byte[] privateKey;
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public int getKeyType() {
+ return keyType;
+ }
+
+ public void setKeyType(int keyType) {
+ this.keyType = keyType;
+ }
+
+ public byte[] getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(byte[] publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public byte[] getPrivateKey() {
+ return privateKey;
+ }
+
+ public void setPrivateKey(byte[] privateKey) {
+ this.privateKey = privateKey;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportKeyWithIskEccRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportKeyWithIskEccRequest.java
new file mode 100644
index 0000000..82915c6
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportKeyWithIskEccRequest.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class ImportKeyWithIskEccRequest {
+
+ private int iskIndex;
+ private byte[] encryptedKeyBlob;
+
+ public int getIskIndex() {
+ return iskIndex;
+ }
+
+ public void setIskIndex(int iskIndex) {
+ this.iskIndex = iskIndex;
+ }
+
+ public byte[] getEncryptedKeyBlob() {
+ return encryptedKeyBlob;
+ }
+
+ public void setEncryptedKeyBlob(byte[] encryptedKeyBlob) {
+ this.encryptedKeyBlob = encryptedKeyBlob;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportKeyWithIskRsaRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportKeyWithIskRsaRequest.java
new file mode 100644
index 0000000..967393f
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/ImportKeyWithIskRsaRequest.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class ImportKeyWithIskRsaRequest {
+
+ private int iskIndex;
+ private byte[] wrappedKey;
+
+ public int getIskIndex() {
+ return iskIndex;
+ }
+
+ public void setIskIndex(int iskIndex) {
+ this.iskIndex = iskIndex;
+ }
+
+ public byte[] getWrappedKey() {
+ return wrappedKey;
+ }
+
+ public void setWrappedKey(byte[] wrappedKey) {
+ this.wrappedKey = wrappedKey;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/KekComponentRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/KekComponentRequest.java
new file mode 100644
index 0000000..a1bf110
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/KekComponentRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class KekComponentRequest {
+
+ private int keyIndex;
+ private int componentNum;
+ private byte[] componentData;
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public int getComponentNum() {
+ return componentNum;
+ }
+
+ public void setComponentNum(int componentNum) {
+ this.componentNum = componentNum;
+ }
+
+ public byte[] getComponentData() {
+ return componentData;
+ }
+
+ public void setComponentData(byte[] componentData) {
+ this.componentData = componentData;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/KeyStatusResult.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/KeyStatusResult.java
new file mode 100644
index 0000000..eabe52c
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/KeyStatusResult.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class KeyStatusResult {
+
+ private int keyState;
+ private String keyStateName;
+
+ public int getKeyState() {
+ return keyState;
+ }
+
+ public void setKeyState(int keyState) {
+ this.keyState = keyState;
+ }
+
+ public String getKeyStateName() {
+ return keyStateName;
+ }
+
+ public void setKeyStateName(String keyStateName) {
+ this.keyStateName = keyStateName;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/LoginStatusResult.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/LoginStatusResult.java
new file mode 100644
index 0000000..5ef6ba8
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/LoginStatusResult.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class LoginStatusResult {
+
+ private int admin1;
+ private int admin2;
+ private int admin3;
+
+ public int getAdmin1() {
+ return admin1;
+ }
+
+ public void setAdmin1(int admin1) {
+ this.admin1 = admin1;
+ }
+
+ public int getAdmin2() {
+ return admin2;
+ }
+
+ public void setAdmin2(int admin2) {
+ this.admin2 = admin2;
+ }
+
+ public int getAdmin3() {
+ return admin3;
+ }
+
+ public void setAdmin3(int admin3) {
+ this.admin3 = admin3;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/MacCalcRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/MacCalcRequest.java
new file mode 100644
index 0000000..7f208c8
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/MacCalcRequest.java
@@ -0,0 +1,50 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class MacCalcRequest {
+
+ private int algId;
+ private byte[] key;
+ private byte[] iv;
+ private byte[] data;
+ private int outBufferSize = 32;
+
+ public int getAlgId() {
+ return algId;
+ }
+
+ public void setAlgId(int algId) {
+ this.algId = algId;
+ }
+
+ public byte[] getKey() {
+ return key;
+ }
+
+ public void setKey(byte[] key) {
+ this.key = key;
+ }
+
+ public byte[] getIv() {
+ return iv;
+ }
+
+ public void setIv(byte[] iv) {
+ this.iv = iv;
+ }
+
+ 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;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/PrivateKeyAccessRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/PrivateKeyAccessRequest.java
new file mode 100644
index 0000000..2e65989
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/PrivateKeyAccessRequest.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class PrivateKeyAccessRequest {
+
+ private int keyIndex;
+ private byte[] password;
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public byte[] getPassword() {
+ return password;
+ }
+
+ public void setPassword(byte[] password) {
+ this.password = password;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RecoverKekRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RecoverKekRequest.java
new file mode 100644
index 0000000..770f42e
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RecoverKekRequest.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class RecoverKekRequest {
+
+ private int keyIndex;
+ private byte[] encryptedKey;
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public byte[] getEncryptedKey() {
+ return encryptedKey;
+ }
+
+ public void setEncryptedKey(byte[] encryptedKey) {
+ this.encryptedKey = encryptedKey;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RecoverUserKeyRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RecoverUserKeyRequest.java
new file mode 100644
index 0000000..38d5541
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RecoverUserKeyRequest.java
@@ -0,0 +1,41 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class RecoverUserKeyRequest {
+
+ private int keyIndex;
+ private int keyType;
+ private byte[] encryptedKey;
+ private int storeFlag = 1;
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public int getKeyType() {
+ return keyType;
+ }
+
+ public void setKeyType(int keyType) {
+ this.keyType = keyType;
+ }
+
+ public byte[] getEncryptedKey() {
+ return encryptedKey;
+ }
+
+ public void setEncryptedKey(byte[] encryptedKey) {
+ this.encryptedKey = encryptedKey;
+ }
+
+ public int getStoreFlag() {
+ return storeFlag;
+ }
+
+ public void setStoreFlag(int storeFlag) {
+ this.storeFlag = storeFlag;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RsaExternalPrivateKeyOpRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RsaExternalPrivateKeyOpRequest.java
new file mode 100644
index 0000000..5873a9c
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RsaExternalPrivateKeyOpRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class RsaExternalPrivateKeyOpRequest {
+
+ private byte[] privateKeyBlob;
+ private byte[] input;
+ private int outBufferSize;
+
+ public byte[] getPrivateKeyBlob() {
+ return privateKeyBlob;
+ }
+
+ public void setPrivateKeyBlob(byte[] privateKeyBlob) {
+ this.privateKeyBlob = privateKeyBlob;
+ }
+
+ public byte[] getInput() {
+ return input;
+ }
+
+ public void setInput(byte[] input) {
+ this.input = input;
+ }
+
+ public int getOutBufferSize() {
+ return outBufferSize;
+ }
+
+ public void setOutBufferSize(int outBufferSize) {
+ this.outBufferSize = outBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RsaExternalPublicKeyOpRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RsaExternalPublicKeyOpRequest.java
new file mode 100644
index 0000000..52601be
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RsaExternalPublicKeyOpRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class RsaExternalPublicKeyOpRequest {
+
+ private byte[] publicKeyBlob;
+ private byte[] input;
+ private int outBufferSize;
+
+ public byte[] getPublicKeyBlob() {
+ return publicKeyBlob;
+ }
+
+ public void setPublicKeyBlob(byte[] publicKeyBlob) {
+ this.publicKeyBlob = publicKeyBlob;
+ }
+
+ public byte[] getInput() {
+ return input;
+ }
+
+ public void setInput(byte[] input) {
+ this.input = input;
+ }
+
+ public int getOutBufferSize() {
+ return outBufferSize;
+ }
+
+ public void setOutBufferSize(int outBufferSize) {
+ this.outBufferSize = outBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RsaInternalKeyOpRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RsaInternalKeyOpRequest.java
new file mode 100644
index 0000000..f80dfa2
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/RsaInternalKeyOpRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class RsaInternalKeyOpRequest {
+
+ private int keyIndex;
+ private byte[] input;
+ private int outBufferSize;
+
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ public void setKeyIndex(int keyIndex) {
+ this.keyIndex = keyIndex;
+ }
+
+ public byte[] getInput() {
+ return input;
+ }
+
+ public void setInput(byte[] input) {
+ this.input = input;
+ }
+
+ public int getOutBufferSize() {
+ return outBufferSize;
+ }
+
+ public void setOutBufferSize(int outBufferSize) {
+ this.outBufferSize = outBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/StandardKeyPairResult.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/StandardKeyPairResult.java
new file mode 100644
index 0000000..b0da95d
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/StandardKeyPairResult.java
@@ -0,0 +1,41 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class StandardKeyPairResult {
+
+ private byte[] publicKey;
+ private int publicKeyLength;
+ private byte[] privateKey;
+ private int privateKeyLength;
+
+ public byte[] getPublicKey() {
+ return publicKey;
+ }
+
+ public void setPublicKey(byte[] publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public int getPublicKeyLength() {
+ return publicKeyLength;
+ }
+
+ public void setPublicKeyLength(int publicKeyLength) {
+ this.publicKeyLength = publicKeyLength;
+ }
+
+ public byte[] getPrivateKey() {
+ return privateKey;
+ }
+
+ public void setPrivateKey(byte[] privateKey) {
+ this.privateKey = privateKey;
+ }
+
+ public int getPrivateKeyLength() {
+ return privateKeyLength;
+ }
+
+ public void setPrivateKeyLength(int privateKeyLength) {
+ this.privateKeyLength = privateKeyLength;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/SymmetricCryptoRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/SymmetricCryptoRequest.java
new file mode 100644
index 0000000..ba9afce
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/SymmetricCryptoRequest.java
@@ -0,0 +1,50 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class SymmetricCryptoRequest {
+
+ private int algId;
+ private byte[] key;
+ private byte[] iv;
+ private byte[] data;
+ private int outBufferSize;
+
+ public int getAlgId() {
+ return algId;
+ }
+
+ public void setAlgId(int algId) {
+ this.algId = algId;
+ }
+
+ public byte[] getKey() {
+ return key;
+ }
+
+ public void setKey(byte[] key) {
+ this.key = key;
+ }
+
+ public byte[] getIv() {
+ return iv;
+ }
+
+ public void setIv(byte[] iv) {
+ this.iv = iv;
+ }
+
+ 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;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/SymmetricKekCryptoRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/SymmetricKekCryptoRequest.java
new file mode 100644
index 0000000..7fe20b5
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/SymmetricKekCryptoRequest.java
@@ -0,0 +1,59 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class SymmetricKekCryptoRequest {
+
+ private int algId;
+ private int kekIndex;
+ private byte[] wrappedKey;
+ private byte[] iv;
+ private byte[] data;
+ private int outBufferSize;
+
+ public int getAlgId() {
+ return algId;
+ }
+
+ public void setAlgId(int algId) {
+ this.algId = algId;
+ }
+
+ public int getKekIndex() {
+ return kekIndex;
+ }
+
+ public void setKekIndex(int kekIndex) {
+ this.kekIndex = kekIndex;
+ }
+
+ public byte[] getWrappedKey() {
+ return wrappedKey;
+ }
+
+ public void setWrappedKey(byte[] wrappedKey) {
+ this.wrappedKey = wrappedKey;
+ }
+
+ public byte[] getIv() {
+ return iv;
+ }
+
+ public void setIv(byte[] iv) {
+ this.iv = iv;
+ }
+
+ 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;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UkeyGenerateRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UkeyGenerateRequest.java
new file mode 100644
index 0000000..312e7ad
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UkeyGenerateRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class UkeyGenerateRequest {
+
+ private int adminIndex;
+ private byte[] ukeyPin;
+ private byte[] loginPin;
+
+ public int getAdminIndex() {
+ return adminIndex;
+ }
+
+ public void setAdminIndex(int adminIndex) {
+ this.adminIndex = adminIndex;
+ }
+
+ public byte[] getUkeyPin() {
+ return ukeyPin;
+ }
+
+ public void setUkeyPin(byte[] ukeyPin) {
+ this.ukeyPin = ukeyPin;
+ }
+
+ public byte[] getLoginPin() {
+ return loginPin;
+ }
+
+ public void setLoginPin(byte[] loginPin) {
+ this.loginPin = loginPin;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UkeyLoginRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UkeyLoginRequest.java
new file mode 100644
index 0000000..d1602b0
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UkeyLoginRequest.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class UkeyLoginRequest {
+
+ private byte[] ukeyPin;
+ private byte[] loginPin;
+
+ public byte[] getUkeyPin() {
+ return ukeyPin;
+ }
+
+ public void setUkeyPin(byte[] ukeyPin) {
+ this.ukeyPin = ukeyPin;
+ }
+
+ public byte[] getLoginPin() {
+ return loginPin;
+ }
+
+ public void setLoginPin(byte[] loginPin) {
+ this.loginPin = loginPin;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UkeyPinChangeRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UkeyPinChangeRequest.java
new file mode 100644
index 0000000..aca2685
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UkeyPinChangeRequest.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class UkeyPinChangeRequest {
+
+ private int pinType;
+ private byte[] oldPin;
+ private byte[] newPin;
+
+ public int getPinType() {
+ return pinType;
+ }
+
+ public void setPinType(int pinType) {
+ this.pinType = pinType;
+ }
+
+ public byte[] getOldPin() {
+ return oldPin;
+ }
+
+ public void setOldPin(byte[] oldPin) {
+ this.oldPin = oldPin;
+ }
+
+ public byte[] getNewPin() {
+ return newPin;
+ }
+
+ public void setNewPin(byte[] newPin) {
+ this.newPin = newPin;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UkeyUnlockRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UkeyUnlockRequest.java
new file mode 100644
index 0000000..eacd963
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UkeyUnlockRequest.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class UkeyUnlockRequest {
+
+ private byte[] adminPin;
+ private byte[] userPin;
+
+ public byte[] getAdminPin() {
+ return adminPin;
+ }
+
+ public void setAdminPin(byte[] adminPin) {
+ this.adminPin = adminPin;
+ }
+
+ public byte[] getUserPin() {
+ return userPin;
+ }
+
+ public void setUserPin(byte[] userPin) {
+ this.userPin = userPin;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UpdateBackedKeyRequest.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UpdateBackedKeyRequest.java
new file mode 100644
index 0000000..b386c4b
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/UpdateBackedKeyRequest.java
@@ -0,0 +1,23 @@
+package com.cisd.tms.integration.crypto.pcie.model;
+
+public class UpdateBackedKeyRequest {
+
+ private byte[] oldData;
+ private int newDataBufferSize;
+
+ public byte[] getOldData() {
+ return oldData;
+ }
+
+ public void setOldData(byte[] oldData) {
+ this.oldData = oldData;
+ }
+
+ public int getNewDataBufferSize() {
+ return newDataBufferSize;
+ }
+
+ public void setNewDataBufferSize(int newDataBufferSize) {
+ this.newDataBufferSize = newDataBufferSize;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/package-info.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/package-info.java
new file mode 100644
index 0000000..f550c2d
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Unified PCIe crypto card wrapper for SDF/SDFE commands.
+ */
+package com.cisd.tms.integration.crypto.pcie;
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoService.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoService.java
new file mode 100644
index 0000000..f51aef4
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoService.java
@@ -0,0 +1,2037 @@
+package com.cisd.tms.integration.crypto.pcie.service;
+
+import com.cisd.tms.integration.crypto.pcie.PcieCryptoException;
+import com.cisd.tms.integration.crypto.pcie.PcieKeyState;
+import com.cisd.tms.integration.crypto.pcie.PcieSessionTemplate;
+import com.cisd.tms.integration.crypto.pcie.PcieUserKeyType;
+import com.cisd.tms.integration.crypto.pcie.jna.EccCipher;
+import com.cisd.tms.integration.crypto.pcie.jna.EccRefPrivateKey;
+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.EnvelopedKeyBlob;
+import com.cisd.tms.integration.crypto.pcie.jna.PcieNativeLibrary;
+import com.cisd.tms.integration.crypto.pcie.jna.RsaRefPrivateKey;
+import com.cisd.tms.integration.crypto.pcie.jna.RsaRefPublicKey;
+import com.cisd.tms.integration.crypto.pcie.jna.SdfDeviceInfo;
+import com.cisd.tms.integration.crypto.pcie.jna.SdfeDeviceConf;
+import com.cisd.tms.integration.crypto.pcie.jna.SdfeKekComponent;
+import com.cisd.tms.integration.crypto.pcie.jna.SdfeLmkComponent;
+import com.cisd.tms.integration.crypto.pcie.jna.SdfeLoginState;
+import com.cisd.tms.integration.crypto.pcie.model.AgreementDataAndKeyEccResult;
+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.DeviceConfResult;
+import com.cisd.tms.integration.crypto.pcie.model.DeviceCountResult;
+import com.cisd.tms.integration.crypto.pcie.model.DeviceInfoResult;
+import com.cisd.tms.integration.crypto.pcie.model.DeviceStatusResult;
+import com.cisd.tms.integration.crypto.pcie.model.DigestRequest;
+import com.cisd.tms.integration.crypto.pcie.model.EccExternalDecryptRequest;
+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.EccAgreementSessionKeyRequest;
+import com.cisd.tms.integration.crypto.pcie.model.EccAgreementSessionKeyResult;
+import com.cisd.tms.integration.crypto.pcie.model.EccExternalVerifyRequest;
+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.ExchangeDigitEnvelopeEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ExchangeDigitEnvelopeRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ExportKekComponentRequest;
+import com.cisd.tms.integration.crypto.pcie.model.FileCreateRequest;
+import com.cisd.tms.integration.crypto.pcie.model.FileReadRequest;
+import com.cisd.tms.integration.crypto.pcie.model.FileWriteRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateAgreementDataAndKeyEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKekRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateStandardEccKeyPairRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateStandardRsaKeyPairRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithEpkEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithEpkRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithIpkEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithIpkRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithKekRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyPairRequest;
+import com.cisd.tms.integration.crypto.pcie.model.HmacRequest;
+import com.cisd.tms.integration.crypto.pcie.model.HmacResult;
+import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportKekRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportKeyPairRequest;
+import com.cisd.tms.integration.crypto.pcie.model.KekComponentRequest;
+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.MacCalcRequest;
+import com.cisd.tms.integration.crypto.pcie.model.PrivateKeyAccessRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RecoverKekRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RecoverUserKeyRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RsaExternalPrivateKeyOpRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RsaExternalPublicKeyOpRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RsaInternalKeyOpRequest;
+import com.cisd.tms.integration.crypto.pcie.model.SymmetricCryptoRequest;
+import com.cisd.tms.integration.crypto.pcie.model.SymmetricKekCryptoRequest;
+import com.cisd.tms.integration.crypto.pcie.model.StandardKeyPairResult;
+import com.cisd.tms.integration.crypto.pcie.model.UkeyGenerateRequest;
+import com.cisd.tms.integration.crypto.pcie.model.UkeyLoginRequest;
+import com.cisd.tms.integration.crypto.pcie.model.UkeyPinChangeRequest;
+import com.cisd.tms.integration.crypto.pcie.model.UkeyUnlockRequest;
+import com.cisd.tms.integration.crypto.pcie.model.UpdateBackedKeyRequest;
+import com.sun.jna.Memory;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.PointerByReference;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+public class JnaPcieCryptoService implements PcieCryptoService {
+
+ private static final int ECC_KEY_BITS = 256;
+ private static final int LMK_SEED_MAC_LENGTH = 8;
+ private static final int HMAC_MAX_LENGTH = 64;
+ private static final int ECC_CIPHER_PREFIX_LENGTH = (EccRefPublicKey.MAX_LEN * 2) + 32 + Integer.BYTES;
+
+ private final PcieSessionTemplate sessionTemplate;
+
+ public JnaPcieCryptoService(PcieSessionTemplate sessionTemplate) {
+ this.sessionTemplate = sessionTemplate;
+ }
+
+ @Override
+ public DeviceCountResult getDeviceCount() {
+ return sessionTemplate.withDevice("SDFE_GetDeviceNumber", (lib, deviceHandle) -> {
+ IntByReference total = new IntByReference();
+ sessionTemplate.ensureSuccess("SDFE_GetDeviceNumber", lib.SDFE_GetDeviceNumber(total));
+
+ IntByReference normal = new IntByReference();
+ sessionTemplate.ensureSuccess("SDFE_GetNormalDeviceNumber", lib.SDFE_GetNormalDeviceNumber(deviceHandle, normal));
+
+ DeviceCountResult result = new DeviceCountResult();
+ result.setDeviceNumber(total.getValue());
+ result.setNormalDeviceNumber(normal.getValue());
+ return result;
+ });
+ }
+
+ @Override
+ public DeviceConfResult getDeviceConf() {
+ return sessionTemplate.withSession("SDFE_DeviceConfGet", (lib, deviceHandle, sessionHandle) -> {
+ SdfeDeviceConf conf = new SdfeDeviceConf();
+ sessionTemplate.ensureSuccess("SDFE_DeviceConfGet", lib.SDFE_DeviceConfGet(sessionHandle, conf));
+ conf.read();
+
+ DeviceConfResult result = new DeviceConfResult();
+ result.setLevel(conf.level);
+ result.setDevCount(conf.devCount);
+ result.setRsaKeyCount(conf.rsaKeyCount);
+ result.setSm2KeyCount(conf.sm2KeyCount);
+ result.setKekCount(conf.kekCount);
+ result.setSessKeyCount(conf.sessKeyCount);
+ result.setFileSysCapacity(conf.fileSysCapacity);
+ return result;
+ });
+ }
+
+ @Override
+ public DeviceInfoResult getDeviceInfo() {
+ return sessionTemplate.withSession("SDF_GetDeviceInfo", (lib, deviceHandle, sessionHandle) -> {
+ SdfDeviceInfo info = new SdfDeviceInfo();
+ sessionTemplate.ensureSuccess("SDF_GetDeviceInfo", lib.SDF_GetDeviceInfo(sessionHandle, info));
+ info.read();
+
+ DeviceInfoResult result = new DeviceInfoResult();
+ result.setIssuerName(zeroTerminatedString(info.issuerName));
+ result.setDeviceName(zeroTerminatedString(info.deviceName));
+ result.setDeviceSerial(zeroTerminatedString(info.deviceSerial));
+ result.setDeviceVersion(info.deviceVersion);
+ result.setStandardVersion(info.standardVersion);
+ result.setAsymAlgAbility0(info.asymAlgAbility[0]);
+ result.setAsymAlgAbility1(info.asymAlgAbility[1]);
+ result.setSymAlgAbility(info.symAlgAbility);
+ result.setHashAlgAbility(info.hashAlgAbility);
+ result.setBufferSize(info.bufferSize);
+ return result;
+ });
+ }
+
+ @Override
+ public byte[] generateRandom(int length) {
+ int randomLength = requirePositive("length", length);
+
+ return sessionTemplate.withSession("SDF_GenerateRandom", (lib, deviceHandle, sessionHandle) -> {
+ byte[] output = new byte[randomLength];
+ sessionTemplate.ensureSuccess("SDF_GenerateRandom", lib.SDF_GenerateRandom(sessionHandle, randomLength, output));
+ return output;
+ });
+ }
+
+ @Override
+ public void initIdentify(byte[] oldPin, byte[] newPin) {
+ byte[] oldPinValue = requireNonEmptyBytes("oldPin", oldPin);
+ byte[] newPinValue = requireNonEmptyBytes("newPin", newPin);
+
+ sessionTemplate.withSession("SDFE_InitIdentify", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_InitIdentify",
+ lib.SDFE_InitIdentify(sessionHandle, oldPinValue, oldPinValue.length, newPinValue, newPinValue.length)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void deviceSelfTest() {
+ sessionTemplate.withSession("SDFE_DeviceSelfTest", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_DeviceSelfTest", lib.SDFE_DeviceSelfTest(sessionHandle));
+ return null;
+ });
+ }
+
+ @Override
+ public DeviceStatusResult getDeviceStatus(int statusBufferSize) {
+ int size = requirePositive("statusBufferSize", statusBufferSize);
+
+ return sessionTemplate.withSession("SDFE_DeviceStatusGet", (lib, deviceHandle, sessionHandle) -> {
+ Memory statusMemory = new Memory(size);
+ sessionTemplate.ensureSuccess("SDFE_DeviceStatusGet", lib.SDFE_DeviceStatusGet(sessionHandle, statusMemory));
+
+ DeviceStatusResult result = new DeviceStatusResult();
+ result.setLength(size);
+ result.setStatusData(statusMemory.getByteArray(0, size));
+ return result;
+ });
+ }
+
+ @Override
+ public void deviceFactoryReset() {
+ sessionTemplate.withSession("SDFE_DeviceFactoryReset", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_DeviceFactoryReset", lib.SDFE_DeviceFactoryReset(sessionHandle));
+ return null;
+ });
+ }
+
+ @Override
+ public void changePrivateKeyAccessPassword(ChangePrivateKeyPasswordRequest request) {
+ ChangePrivateKeyPasswordRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ byte[] oldPassword = requireNonEmptyBytes("oldPassword", req.getOldPassword());
+ byte[] newPassword = requireNonEmptyBytes("newPassword", req.getNewPassword());
+
+ sessionTemplate.withSession("SDFE_ChangePrivateKeyAccessPassword", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_ChangePrivateKeyAccessPassword",
+ lib.SDFE_ChangePrivateKeyAccessPassword(
+ sessionHandle,
+ keyIndex,
+ oldPassword,
+ oldPassword.length,
+ newPassword,
+ newPassword.length
+ )
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void getPrivateKeyAccessRight(PrivateKeyAccessRequest request) {
+ PrivateKeyAccessRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ byte[] password = requireNonEmptyBytes("password", req.getPassword());
+
+ sessionTemplate.withSession("SDF_GetPrivateKeyAccessRight", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDF_GetPrivateKeyAccessRight",
+ lib.SDF_GetPrivateKeyAccessRight(sessionHandle, keyIndex, password, password.length)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void releasePrivateKeyAccessRight(int keyIndex) {
+ int safeKeyIndex = requireNonNegative("keyIndex", keyIndex);
+
+ sessionTemplate.withSession("SDF_ReleasePrivateKeyAccessRight", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDF_ReleasePrivateKeyAccessRight",
+ lib.SDF_ReleasePrivateKeyAccessRight(sessionHandle, safeKeyIndex)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void generateKeyPairEcc(GenerateKeyPairRequest request) {
+ GenerateKeyPairRequest req = requireRequest("request", request);
+ int keyBits = req.getKeyBits();
+ if (keyBits != ECC_KEY_BITS) {
+ throw new IllegalArgumentException("keyBits must be 256 for ECC");
+ }
+
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ int keyType = requireUserKeyType(req.getKeyType());
+
+ sessionTemplate.withSession("SDFE_GenerateKeyPair_ECC", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_GenerateKeyPair_ECC",
+ lib.SDFE_GenerateKeyPair_ECC(sessionHandle, keyBits, keyIndex, keyType)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void generateKeyPairRsa(GenerateKeyPairRequest request) {
+ GenerateKeyPairRequest req = requireRequest("request", request);
+ int keyBits = requirePositive("keyBits", req.getKeyBits());
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ int keyType = requireUserKeyType(req.getKeyType());
+
+ sessionTemplate.withSession("SDFE_GenerateKeyPair_RSA", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_GenerateKeyPair_RSA",
+ lib.SDFE_GenerateKeyPair_RSA(sessionHandle, keyBits, keyIndex, keyType)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void importKeyPairEcc(ImportKeyPairRequest request) {
+ ImportKeyPairRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ int keyType = requireUserKeyType(req.getKeyType());
+ EccRefPublicKey publicKey = toEccRefPublicKey("publicKey", req.getPublicKey());
+ EccRefPrivateKey privateKey = toEccRefPrivateKey("privateKey", req.getPrivateKey());
+
+ sessionTemplate.withSession("SDFE_ImportKeyPair_ECC", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_ImportKeyPair_ECC",
+ lib.SDFE_ImportKeyPair_ECC(sessionHandle, keyIndex, keyType, publicKey, privateKey)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void importKeyPairRsa(ImportKeyPairRequest request) {
+ ImportKeyPairRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ int keyType = requireUserKeyType(req.getKeyType());
+ RsaRefPublicKey publicKey = toRsaRefPublicKey("publicKey", req.getPublicKey());
+ RsaRefPrivateKey privateKey = toRsaRefPrivateKey("privateKey", req.getPrivateKey());
+
+ sessionTemplate.withSession("SDFE_ImportKeyPair_RSA", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_ImportKeyPair_RSA",
+ lib.SDFE_ImportKeyPair_RSA(sessionHandle, keyIndex, keyType, publicKey, privateKey)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void generateKek(GenerateKekRequest request) {
+ GenerateKekRequest req = requireRequest("request", request);
+ int keyBits = req.getKeyBits();
+ if (keyBits != 128 && keyBits != 192 && keyBits != 256) {
+ throw new IllegalArgumentException("keyBits must be one of 128/192/256 for KEK");
+ }
+
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+
+ sessionTemplate.withSession("SDFE_GenerateKEK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_GenerateKEK", lib.SDFE_GenerateKEK(sessionHandle, keyBits, keyIndex));
+ return null;
+ });
+ }
+
+ @Override
+ public void importKek(ImportKekRequest request) {
+ ImportKekRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ byte[] keyData = requireNonEmptyBytes("keyData", req.getKeyData());
+
+ sessionTemplate.withSession("SDFE_ImportKEK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_ImportKEK",
+ lib.SDFE_ImportKEK(sessionHandle, keyIndex, keyData, keyData.length)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void importKekComponent(KekComponentRequest request) {
+ KekComponentRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ int componentNum = requirePositive("componentNum", req.getComponentNum());
+ SdfeKekComponent componentData = toSdfeKekComponent("componentData", req.getComponentData());
+
+ sessionTemplate.withSession("SDFE_ImportKEKComponent", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_ImportKEKComponent",
+ lib.SDFE_ImportKEKComponent(sessionHandle, keyIndex, componentNum, componentData)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public BackupDataResult exportKekComponent(ExportKekComponentRequest request) {
+ ExportKekComponentRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ int componentNum = requirePositive("componentNum", req.getComponentNum());
+ int componentSize = requirePositive("componentSize", req.getComponentSize());
+
+ return sessionTemplate.withSession("SDFE_ExportKEKComponent", (lib, deviceHandle, sessionHandle) -> {
+ SdfeKekComponent output = new SdfeKekComponent();
+ int structSize = output.size();
+ if (componentSize < structSize) {
+ throw new IllegalArgumentException("componentSize must be >= " + structSize);
+ }
+ sessionTemplate.ensureSuccess(
+ "SDFE_ExportKEKComponent",
+ lib.SDFE_ExportKEKComponent(sessionHandle, keyIndex, componentNum, output)
+ );
+ return toBackupResult("SDFE_ExportKEKComponent", toBytes(output), structSize);
+ });
+ }
+
+ @Override
+ public BackupDataResult backupUserKey(int keyIndex, int keyType, int outBufferSize) {
+ int safeKeyIndex = requireNonNegative("keyIndex", keyIndex);
+ int safeKeyType = requireUserKeyType(keyType);
+ int safeOutBufferSize = requirePositive("outBufferSize", outBufferSize);
+
+ return sessionTemplate.withSession("SDFE_BackupUserKey", (lib, deviceHandle, sessionHandle) -> {
+ byte[] out = new byte[safeOutBufferSize];
+ IntByReference outLen = new IntByReference(out.length);
+ sessionTemplate.ensureSuccess(
+ "SDFE_BackupUserKey",
+ lib.SDFE_BackupUserKey(sessionHandle, safeKeyIndex, safeKeyType, out, outLen)
+ );
+ return toBackupResult("SDFE_BackupUserKey", out, outLen.getValue());
+ });
+ }
+
+ @Override
+ public void recoverUserKey(RecoverUserKeyRequest request) {
+ RecoverUserKeyRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ int keyType = requireUserKeyType(req.getKeyType());
+ byte[] encryptedKey = requireNonEmptyBytes("encryptedKey", req.getEncryptedKey());
+ int storeFlag = req.getStoreFlag();
+ if (storeFlag != 0 && storeFlag != 1) {
+ throw new IllegalArgumentException("storeFlag must be 0 or 1");
+ }
+
+ sessionTemplate.withSession("SDFE_RecoverUserKey", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_RecoverUserKey",
+ lib.SDFE_RecoverUserKey(
+ sessionHandle,
+ keyIndex,
+ keyType,
+ encryptedKey,
+ encryptedKey.length,
+ (byte) storeFlag
+ )
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public BackupDataResult backupKek(int keyIndex, int outBufferSize) {
+ int safeKeyIndex = requireNonNegative("keyIndex", keyIndex);
+ int safeOutBufferSize = requirePositive("outBufferSize", outBufferSize);
+
+ return sessionTemplate.withSession("SDFE_BackupKEK", (lib, deviceHandle, sessionHandle) -> {
+ byte[] out = new byte[safeOutBufferSize];
+ IntByReference outLen = new IntByReference(out.length);
+ sessionTemplate.ensureSuccess("SDFE_BackupKEK", lib.SDFE_BackupKEK(sessionHandle, safeKeyIndex, out, outLen));
+ return toBackupResult("SDFE_BackupKEK", out, outLen.getValue());
+ });
+ }
+
+ @Override
+ public void recoverKek(RecoverKekRequest request) {
+ RecoverKekRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ byte[] encryptedKey = requireNonEmptyBytes("encryptedKey", req.getEncryptedKey());
+
+ sessionTemplate.withSession("SDFE_RecoverKEK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_RecoverKEK",
+ lib.SDFE_RecoverKEK(sessionHandle, keyIndex, encryptedKey, encryptedKey.length)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void deleteUserKey(int keyIndex) {
+ int safeKeyIndex = requireNonNegative("keyIndex", keyIndex);
+
+ sessionTemplate.withSession("SDFE_DeleteUserKey", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_DeleteUserKey", lib.SDFE_DeleteUserKey(sessionHandle, safeKeyIndex));
+ return null;
+ });
+ }
+
+ @Override
+ public void deleteKek(int keyIndex) {
+ int safeKeyIndex = requireNonNegative("keyIndex", keyIndex);
+
+ sessionTemplate.withSession("SDFE_DeleteKey_KEK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_DeleteKey_KEK", lib.SDFE_DeleteKey_KEK(sessionHandle, safeKeyIndex));
+ return null;
+ });
+ }
+
+ @Override
+ public BackupDataResult backupAllKey(int outBufferSize) {
+ int safeOutBufferSize = requirePositive("outBufferSize", outBufferSize);
+
+ return sessionTemplate.withSession("SDFE_BackKey", (lib, deviceHandle, sessionHandle) -> {
+ byte[] out = new byte[safeOutBufferSize];
+ IntByReference outLen = new IntByReference(out.length);
+ sessionTemplate.ensureSuccess("SDFE_BackKey", lib.SDFE_BackKey(sessionHandle, out, outLen));
+ return toBackupResult("SDFE_BackKey", out, outLen.getValue());
+ });
+ }
+
+ @Override
+ public void restoreAllKey(byte[] keyImage) {
+ byte[] safeKeyImage = requireNonEmptyBytes("keyImage", keyImage);
+
+ sessionTemplate.withSession("SDFE_RestoryKey", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_RestoryKey",
+ lib.SDFE_RestoryKey(sessionHandle, safeKeyImage, safeKeyImage.length)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public KeyStatusResult statusUserKeyEcc(int keyIndex, int keyType) {
+ int safeKeyIndex = requireNonNegative("keyIndex", keyIndex);
+ int safeKeyType = requireUserKeyType(keyType);
+
+ return sessionTemplate.withSession("SDFE_StatusUserKey_ECC", (lib, deviceHandle, sessionHandle) -> {
+ IntByReference stateRef = new IntByReference();
+ sessionTemplate.ensureSuccess(
+ "SDFE_StatusUserKey_ECC",
+ lib.SDFE_StatusUserKey_ECC(sessionHandle, safeKeyIndex, safeKeyType, stateRef)
+ );
+ return toKeyStatus(stateRef.getValue());
+ });
+ }
+
+ @Override
+ public KeyStatusResult statusUserKeyRsa(int keyIndex, int keyType) {
+ int safeKeyIndex = requireNonNegative("keyIndex", keyIndex);
+ int safeKeyType = requireUserKeyType(keyType);
+
+ return sessionTemplate.withSession("SDFE_StatusUserKey_RSA", (lib, deviceHandle, sessionHandle) -> {
+ IntByReference stateRef = new IntByReference();
+ sessionTemplate.ensureSuccess(
+ "SDFE_StatusUserKey_RSA",
+ lib.SDFE_StatusUserKey_RSA(sessionHandle, safeKeyIndex, safeKeyType, stateRef)
+ );
+ return toKeyStatus(stateRef.getValue());
+ });
+ }
+
+ @Override
+ public KeyStatusResult statusKek(int keyIndex) {
+ int safeKeyIndex = requireNonNegative("keyIndex", keyIndex);
+
+ return sessionTemplate.withSession("SDFE_StatusKey_KEK", (lib, deviceHandle, sessionHandle) -> {
+ IntByReference stateRef = new IntByReference();
+ sessionTemplate.ensureSuccess("SDFE_StatusKey_KEK", lib.SDFE_StatusKey_KEK(sessionHandle, safeKeyIndex, stateRef));
+ return toKeyStatus(stateRef.getValue());
+ });
+ }
+
+ @Override
+ public void importEncryptedKeyPairEcc(ImportEncKeyPairEccRequest request) {
+ ImportEncKeyPairEccRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ EnvelopedKeyBlob blob = toEnvelopedKeyBlob("envelopedKeyBlob", req.getEnvelopedKeyBlob());
+
+ sessionTemplate.withSession("SDFE_ImportEncKeyPair_ECC", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_ImportEncKeyPair_ECC",
+ lib.SDFE_ImportEncKeyPair_ECC(sessionHandle, keyIndex, blob)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void importEncryptedKeyPairRsa(ImportEncKeyPairRsaRequest request) {
+ ImportEncKeyPairRsaRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ int symAlgId = requirePositive("symAlgId", req.getSymAlgId());
+ byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
+ byte[] encryptedData = requireNonEmptyBytes("encryptedData", req.getEncryptedData());
+
+ 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;
+ });
+ }
+
+ @Override
+ public BackupDataResult updateBackedKey(UpdateBackedKeyRequest request) {
+ UpdateBackedKeyRequest req = requireRequest("request", request);
+ byte[] oldData = requireNonEmptyBytes("oldData", req.getOldData());
+ int bufferSize = requirePositive("newDataBufferSize", req.getNewDataBufferSize());
+
+ return sessionTemplate.withSession("SDFE_UpdateBackedKey", (lib, deviceHandle, sessionHandle) -> {
+ byte[] newData = new byte[bufferSize];
+ IntByReference newLength = new IntByReference(newData.length);
+ sessionTemplate.ensureSuccess(
+ "SDFE_UpdateBackedKey",
+ lib.SDFE_UpdateBackedKey(sessionHandle, oldData, oldData.length, newData, newLength)
+ );
+ return toBackupResult("SDFE_UpdateBackedKey", newData, newLength.getValue());
+ });
+ }
+
+ @Override
+ public BackupDataResult exportSignPublicKeyRsa(int keyIndex, int outBufferSize) {
+ int safeKeyIndex = requireNonNegative("keyIndex", keyIndex);
+ int size = requirePositive("outBufferSize", outBufferSize);
+
+ return sessionTemplate.withSession("SDF_ExportSignPublicKey_RSA", (lib, deviceHandle, sessionHandle) -> {
+ RsaRefPublicKey out = new RsaRefPublicKey();
+ if (size < out.size()) {
+ throw new IllegalArgumentException("outBufferSize must be >= " + out.size());
+ }
+ sessionTemplate.ensureSuccess(
+ "SDF_ExportSignPublicKey_RSA",
+ lib.SDF_ExportSignPublicKey_RSA(sessionHandle, safeKeyIndex, out)
+ );
+ byte[] outBytes = toBytes(out);
+ return toBackupResult("SDF_ExportSignPublicKey_RSA", outBytes, outBytes.length);
+ });
+ }
+
+ @Override
+ public BackupDataResult exportEncPublicKeyRsa(int keyIndex, int outBufferSize) {
+ int safeKeyIndex = requireNonNegative("keyIndex", keyIndex);
+ int size = requirePositive("outBufferSize", outBufferSize);
+
+ return sessionTemplate.withSession("SDF_ExportEncPublicKey_RSA", (lib, deviceHandle, sessionHandle) -> {
+ RsaRefPublicKey out = new RsaRefPublicKey();
+ if (size < out.size()) {
+ throw new IllegalArgumentException("outBufferSize must be >= " + out.size());
+ }
+ sessionTemplate.ensureSuccess(
+ "SDF_ExportEncPublicKey_RSA",
+ lib.SDF_ExportEncPublicKey_RSA(sessionHandle, safeKeyIndex, out)
+ );
+ byte[] outBytes = toBytes(out);
+ return toBackupResult("SDF_ExportEncPublicKey_RSA", outBytes, outBytes.length);
+ });
+ }
+
+ @Override
+ public BackupDataResult exportSignPublicKeyEcc(int keyIndex, int outBufferSize) {
+ int safeKeyIndex = requireNonNegative("keyIndex", keyIndex);
+ int size = requirePositive("outBufferSize", outBufferSize);
+
+ return sessionTemplate.withSession("SDF_ExportSignPublicKey_ECC", (lib, deviceHandle, sessionHandle) -> {
+ EccRefPublicKey out = new EccRefPublicKey();
+ if (size < out.size()) {
+ throw new IllegalArgumentException("outBufferSize must be >= " + out.size());
+ }
+ sessionTemplate.ensureSuccess(
+ "SDF_ExportSignPublicKey_ECC",
+ lib.SDF_ExportSignPublicKey_ECC(sessionHandle, safeKeyIndex, out)
+ );
+ byte[] outBytes = toBytes(out);
+ return toBackupResult("SDF_ExportSignPublicKey_ECC", outBytes, outBytes.length);
+ });
+ }
+
+ @Override
+ public BackupDataResult exportEncPublicKeyEcc(int keyIndex, int outBufferSize) {
+ int safeKeyIndex = requireNonNegative("keyIndex", keyIndex);
+ int size = requirePositive("outBufferSize", outBufferSize);
+
+ return sessionTemplate.withSession("SDF_ExportEncPublicKey_ECC", (lib, deviceHandle, sessionHandle) -> {
+ EccRefPublicKey out = new EccRefPublicKey();
+ if (size < out.size()) {
+ throw new IllegalArgumentException("outBufferSize must be >= " + out.size());
+ }
+ sessionTemplate.ensureSuccess(
+ "SDF_ExportEncPublicKey_ECC",
+ lib.SDF_ExportEncPublicKey_ECC(sessionHandle, safeKeyIndex, out)
+ );
+ byte[] outBytes = toBytes(out);
+ return toBackupResult("SDF_ExportEncPublicKey_ECC", outBytes, outBytes.length);
+ });
+ }
+
+ @Override
+ public StandardKeyPairResult generateStandardRsaKeyPair(GenerateStandardRsaKeyPairRequest request) {
+ GenerateStandardRsaKeyPairRequest req = requireRequest("request", request);
+ int keyBits = requirePositive("keyBits", req.getKeyBits());
+ int publicKeySize = requirePositive("publicKeyBufferSize", req.getPublicKeyBufferSize());
+ int privateKeySize = requirePositive("privateKeyBufferSize", req.getPrivateKeyBufferSize());
+
+ return sessionTemplate.withSession("SDF_GenerateKeyPair_RSA", (lib, deviceHandle, sessionHandle) -> {
+ RsaRefPublicKey publicKey = new RsaRefPublicKey();
+ RsaRefPrivateKey privateKey = new RsaRefPrivateKey();
+ if (publicKeySize < publicKey.size()) {
+ throw new IllegalArgumentException("publicKeyBufferSize must be >= " + publicKey.size());
+ }
+ if (privateKeySize < privateKey.size()) {
+ throw new IllegalArgumentException("privateKeyBufferSize must be >= " + privateKey.size());
+ }
+ sessionTemplate.ensureSuccess(
+ "SDF_GenerateKeyPair_RSA",
+ lib.SDF_GenerateKeyPair_RSA(sessionHandle, keyBits, publicKey, privateKey)
+ );
+ return toStandardKeyPairResult(toBytes(publicKey), toBytes(privateKey));
+ });
+ }
+
+ @Override
+ public StandardKeyPairResult generateStandardEccKeyPair(GenerateStandardEccKeyPairRequest request) {
+ GenerateStandardEccKeyPairRequest req = requireRequest("request", request);
+ int algId = requirePositive("algId", req.getAlgId());
+ int keyBits = requirePositive("keyBits", req.getKeyBits());
+ int publicKeySize = requirePositive("publicKeyBufferSize", req.getPublicKeyBufferSize());
+ int privateKeySize = requirePositive("privateKeyBufferSize", req.getPrivateKeyBufferSize());
+
+ return sessionTemplate.withSession("SDF_GenerateKeyPair_ECC", (lib, deviceHandle, sessionHandle) -> {
+ EccRefPublicKey publicKey = new EccRefPublicKey();
+ EccRefPrivateKey privateKey = new EccRefPrivateKey();
+ if (publicKeySize < publicKey.size()) {
+ throw new IllegalArgumentException("publicKeyBufferSize must be >= " + publicKey.size());
+ }
+ if (privateKeySize < privateKey.size()) {
+ throw new IllegalArgumentException("privateKeyBufferSize must be >= " + privateKey.size());
+ }
+ sessionTemplate.ensureSuccess(
+ "SDF_GenerateKeyPair_ECC",
+ lib.SDF_GenerateKeyPair_ECC(sessionHandle, algId, keyBits, publicKey, privateKey)
+ );
+ return toStandardKeyPairResult(toBytes(publicKey), toBytes(privateKey));
+ });
+ }
+
+ @Override
+ public BackupDataResult generateKeyWithKek(GenerateKeyWithKekRequest request) {
+ GenerateKeyWithKekRequest req = requireRequest("request", request);
+ int keyBits = requirePositive("keyBits", req.getKeyBits());
+ int algId = requirePositive("algId", req.getAlgId());
+ int kekIndex = requireNonNegative("kekIndex", req.getKekIndex());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_GenerateKeyWithKEK", (lib, deviceHandle, sessionHandle) -> {
+ byte[] wrappedKey = new byte[outBufferSize];
+ IntByReference wrappedKeyLen = new IntByReference(wrappedKey.length);
+ PointerByReference keyHandleRef = new PointerByReference();
+ sessionTemplate.ensureSuccess(
+ "SDF_GenerateKeyWithKEK",
+ lib.SDF_GenerateKeyWithKEK(
+ sessionHandle,
+ keyBits,
+ algId,
+ kekIndex,
+ wrappedKey,
+ wrappedKeyLen,
+ keyHandleRef
+ )
+ );
+ try {
+ return toBackupResult("SDF_GenerateKeyWithKEK", wrappedKey, wrappedKeyLen.getValue());
+ } finally {
+ destroyKeyHandle(lib, sessionHandle, keyHandleRef.getValue());
+ }
+ });
+ }
+
+ @Override
+ public BackupDataResult rsaExternalPublicKeyOperation(RsaExternalPublicKeyOpRequest request) {
+ RsaExternalPublicKeyOpRequest req = requireRequest("request", request);
+ RsaRefPublicKey publicKey = toRsaRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
+ byte[] input = requireBytes("input", req.getInput());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_ExternalPublicKeyOperation_RSA", (lib, deviceHandle, sessionHandle) -> {
+ byte[] output = new byte[outBufferSize];
+ IntByReference outputLen = new IntByReference(output.length);
+ sessionTemplate.ensureSuccess(
+ "SDF_ExternalPublicKeyOperation_RSA",
+ lib.SDF_ExternalPublicKeyOperation_RSA(
+ sessionHandle,
+ publicKey,
+ input,
+ input.length,
+ output,
+ outputLen
+ )
+ );
+ return toBackupResult("SDF_ExternalPublicKeyOperation_RSA", output, outputLen.getValue());
+ });
+ }
+
+ @Override
+ public BackupDataResult rsaExternalPrivateKeyOperation(RsaExternalPrivateKeyOpRequest request) {
+ RsaExternalPrivateKeyOpRequest req = requireRequest("request", request);
+ RsaRefPrivateKey privateKey = toRsaRefPrivateKey("privateKeyBlob", req.getPrivateKeyBlob());
+ byte[] input = requireBytes("input", req.getInput());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_ExternalPrivateKeyOperation_RSA", (lib, deviceHandle, sessionHandle) -> {
+ byte[] output = new byte[outBufferSize];
+ IntByReference outputLen = new IntByReference(output.length);
+ sessionTemplate.ensureSuccess(
+ "SDF_ExternalPrivateKeyOperation_RSA",
+ lib.SDF_ExternalPrivateKeyOperation_RSA(
+ sessionHandle,
+ privateKey,
+ input,
+ input.length,
+ output,
+ outputLen
+ )
+ );
+ return toBackupResult("SDF_ExternalPrivateKeyOperation_RSA", output, outputLen.getValue());
+ });
+ }
+
+ @Override
+ public BackupDataResult rsaInternalPublicKeyOperation(RsaInternalKeyOpRequest request) {
+ RsaInternalKeyOpRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ byte[] input = requireBytes("input", req.getInput());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_InternalPublicKeyOperation_RSA", (lib, deviceHandle, sessionHandle) -> {
+ byte[] output = new byte[outBufferSize];
+ IntByReference outputLen = new IntByReference(output.length);
+ sessionTemplate.ensureSuccess(
+ "SDF_InternalPublicKeyOperation_RSA",
+ lib.SDF_InternalPublicKeyOperation_RSA(
+ sessionHandle,
+ keyIndex,
+ input,
+ input.length,
+ output,
+ outputLen
+ )
+ );
+ return toBackupResult("SDF_InternalPublicKeyOperation_RSA", output, outputLen.getValue());
+ });
+ }
+
+ @Override
+ public BackupDataResult rsaInternalPrivateKeyOperation(RsaInternalKeyOpRequest request) {
+ RsaInternalKeyOpRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ byte[] input = requireBytes("input", req.getInput());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_InternalPrivateKeyOperation_RSA", (lib, deviceHandle, sessionHandle) -> {
+ byte[] output = new byte[outBufferSize];
+ IntByReference outputLen = new IntByReference(output.length);
+ sessionTemplate.ensureSuccess(
+ "SDF_InternalPrivateKeyOperation_RSA",
+ lib.SDF_InternalPrivateKeyOperation_RSA(
+ sessionHandle,
+ keyIndex,
+ input,
+ input.length,
+ output,
+ outputLen
+ )
+ );
+ return toBackupResult("SDF_InternalPrivateKeyOperation_RSA", output, outputLen.getValue());
+ });
+ }
+
+ @Override
+ public BackupDataResult generateKeyWithIpkRsa(GenerateKeyWithIpkRsaRequest request) {
+ GenerateKeyWithIpkRsaRequest req = requireRequest("request", request);
+ int ipkIndex = requireNonNegative("ipkIndex", req.getIpkIndex());
+ int keyBits = requirePositive("keyBits", req.getKeyBits());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_GenerateKeyWithIPK_RSA", (lib, deviceHandle, sessionHandle) -> {
+ byte[] wrappedKey = new byte[outBufferSize];
+ IntByReference wrappedKeyLen = new IntByReference(wrappedKey.length);
+ PointerByReference keyHandleRef = new PointerByReference();
+ sessionTemplate.ensureSuccess(
+ "SDF_GenerateKeyWithIPK_RSA",
+ lib.SDF_GenerateKeyWithIPK_RSA(
+ sessionHandle,
+ ipkIndex,
+ keyBits,
+ wrappedKey,
+ wrappedKeyLen,
+ keyHandleRef
+ )
+ );
+ try {
+ return toBackupResult("SDF_GenerateKeyWithIPK_RSA", wrappedKey, wrappedKeyLen.getValue());
+ } finally {
+ destroyKeyHandle(lib, sessionHandle, keyHandleRef.getValue());
+ }
+ });
+ }
+
+ @Override
+ public BackupDataResult generateKeyWithEpkRsa(GenerateKeyWithEpkRsaRequest request) {
+ GenerateKeyWithEpkRsaRequest req = requireRequest("request", request);
+ int keyBits = requirePositive("keyBits", req.getKeyBits());
+ RsaRefPublicKey publicKeyBlob = toRsaRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_GenerateKeyWithEPK_RSA", (lib, deviceHandle, sessionHandle) -> {
+ byte[] wrappedKey = new byte[outBufferSize];
+ IntByReference wrappedKeyLen = new IntByReference(wrappedKey.length);
+ PointerByReference keyHandleRef = new PointerByReference();
+ sessionTemplate.ensureSuccess(
+ "SDF_GenerateKeyWithEPK_RSA",
+ lib.SDF_GenerateKeyWithEPK_RSA(
+ sessionHandle,
+ keyBits,
+ publicKeyBlob,
+ wrappedKey,
+ wrappedKeyLen,
+ keyHandleRef
+ )
+ );
+ try {
+ return toBackupResult("SDF_GenerateKeyWithEPK_RSA", wrappedKey, wrappedKeyLen.getValue());
+ } finally {
+ destroyKeyHandle(lib, sessionHandle, keyHandleRef.getValue());
+ }
+ });
+ }
+
+ @Override
+ public void importKeyWithIskRsa(ImportKeyWithIskRsaRequest request) {
+ ImportKeyWithIskRsaRequest req = requireRequest("request", request);
+ int iskIndex = requireNonNegative("iskIndex", req.getIskIndex());
+ byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
+
+ sessionTemplate.withSession("SDF_ImportKeyWithISK_RSA", (lib, deviceHandle, sessionHandle) -> {
+ PointerByReference keyHandleRef = new PointerByReference();
+ sessionTemplate.ensureSuccess(
+ "SDF_ImportKeyWithISK_RSA",
+ lib.SDF_ImportKeyWithISK_RSA(
+ sessionHandle,
+ iskIndex,
+ wrappedKey,
+ wrappedKey.length,
+ keyHandleRef
+ )
+ );
+ destroyKeyHandle(lib, sessionHandle, keyHandleRef.getValue());
+ return null;
+ });
+ }
+
+ @Override
+ public BackupDataResult generateKeyWithIpkEcc(GenerateKeyWithIpkEccRequest request) {
+ GenerateKeyWithIpkEccRequest req = requireRequest("request", request);
+ int ipkIndex = requireNonNegative("ipkIndex", req.getIpkIndex());
+ int keyBits = requirePositive("keyBits", req.getKeyBits());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_GenerateKeyWithIPK_ECC", (lib, deviceHandle, sessionHandle) -> {
+ EccCipher encryptedKey = new EccCipher();
+ if (outBufferSize < encryptedKey.size()) {
+ throw new IllegalArgumentException("outBufferSize must be >= " + encryptedKey.size());
+ }
+ PointerByReference keyHandleRef = new PointerByReference();
+ sessionTemplate.ensureSuccess(
+ "SDF_GenerateKeyWithIPK_ECC",
+ lib.SDF_GenerateKeyWithIPK_ECC(
+ sessionHandle,
+ ipkIndex,
+ keyBits,
+ encryptedKey,
+ keyHandleRef
+ )
+ );
+ try {
+ byte[] outBytes = toEccCipherBytes("SDF_GenerateKeyWithIPK_ECC", encryptedKey);
+ return toBackupResult("SDF_GenerateKeyWithIPK_ECC", outBytes, outBytes.length);
+ } finally {
+ destroyKeyHandle(lib, sessionHandle, keyHandleRef.getValue());
+ }
+ });
+ }
+
+ @Override
+ public BackupDataResult generateKeyWithEpkEcc(GenerateKeyWithEpkEccRequest request) {
+ GenerateKeyWithEpkEccRequest req = requireRequest("request", request);
+ int keyBits = requirePositive("keyBits", req.getKeyBits());
+ int algId = requirePositive("algId", req.getAlgId());
+ EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_GenerateKeyWithEPK_ECC", (lib, deviceHandle, sessionHandle) -> {
+ EccCipher encryptedKey = new EccCipher();
+ if (outBufferSize < encryptedKey.size()) {
+ throw new IllegalArgumentException("outBufferSize must be >= " + encryptedKey.size());
+ }
+ PointerByReference keyHandleRef = new PointerByReference();
+ sessionTemplate.ensureSuccess(
+ "SDF_GenerateKeyWithEPK_ECC",
+ lib.SDF_GenerateKeyWithEPK_ECC(
+ sessionHandle,
+ keyBits,
+ algId,
+ publicKeyBlob,
+ encryptedKey,
+ keyHandleRef
+ )
+ );
+ try {
+ byte[] outBytes = toEccCipherBytes("SDF_GenerateKeyWithEPK_ECC", encryptedKey);
+ return toBackupResult("SDF_GenerateKeyWithEPK_ECC", outBytes, outBytes.length);
+ } finally {
+ destroyKeyHandle(lib, sessionHandle, keyHandleRef.getValue());
+ }
+ });
+ }
+
+ @Override
+ public void importKeyWithIskEcc(ImportKeyWithIskEccRequest request) {
+ ImportKeyWithIskEccRequest req = requireRequest("request", request);
+ int iskIndex = requireNonNegative("iskIndex", req.getIskIndex());
+ EccCipher encryptedKeyBlob = toEccCipher("encryptedKeyBlob", req.getEncryptedKeyBlob());
+
+ sessionTemplate.withSession("SDF_ImportKeyWithISK_ECC", (lib, deviceHandle, sessionHandle) -> {
+ PointerByReference keyHandleRef = new PointerByReference();
+ sessionTemplate.ensureSuccess(
+ "SDF_ImportKeyWithISK_ECC",
+ lib.SDF_ImportKeyWithISK_ECC(sessionHandle, iskIndex, encryptedKeyBlob, keyHandleRef)
+ );
+ destroyKeyHandle(lib, sessionHandle, keyHandleRef.getValue());
+ return null;
+ });
+ }
+
+ @Override
+ public BackupDataResult exchangeDigitEnvelopeBaseOnRsa(ExchangeDigitEnvelopeRsaRequest request) {
+ ExchangeDigitEnvelopeRsaRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ RsaRefPublicKey publicKeyBlob = toRsaRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
+ byte[] inputEnvelopeBlob = requireNonEmptyBytes("inputEnvelopeBlob", req.getInputEnvelopeBlob());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_ExchangeDigitEnvelopeBaseOnRSA", (lib, deviceHandle, sessionHandle) -> {
+ byte[] outputEnvelopeBlob = new byte[outBufferSize];
+ IntByReference outputEnvelopeLength = new IntByReference(outputEnvelopeBlob.length);
+ sessionTemplate.ensureSuccess(
+ "SDF_ExchangeDigitEnvelopeBaseOnRSA",
+ lib.SDF_ExchangeDigitEnvelopeBaseOnRSA(
+ sessionHandle,
+ keyIndex,
+ publicKeyBlob,
+ inputEnvelopeBlob,
+ inputEnvelopeBlob.length,
+ outputEnvelopeBlob,
+ outputEnvelopeLength
+ )
+ );
+ return toBackupResult("SDF_ExchangeDigitEnvelopeBaseOnRSA", outputEnvelopeBlob, outputEnvelopeLength.getValue());
+ });
+ }
+
+ @Override
+ public BackupDataResult exchangeDigitEnvelopeBaseOnEcc(ExchangeDigitEnvelopeEccRequest request) {
+ ExchangeDigitEnvelopeEccRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ int algId = requirePositive("algId", req.getAlgId());
+ EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
+ EccCipher inputEnvelopeBlob = toEccCipher("inputEnvelopeBlob", req.getInputEnvelopeBlob());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_ExchangeDigitEnvelopeBaseOnECC", (lib, deviceHandle, sessionHandle) -> {
+ EccCipher outputEnvelopeBlob = new EccCipher();
+ if (outBufferSize < outputEnvelopeBlob.size()) {
+ throw new IllegalArgumentException("outBufferSize must be >= " + outputEnvelopeBlob.size());
+ }
+ sessionTemplate.ensureSuccess(
+ "SDF_ExchangeDigitEnvelopeBaseOnECC",
+ lib.SDF_ExchangeDigitEnvelopeBaseOnECC(
+ sessionHandle,
+ keyIndex,
+ algId,
+ publicKeyBlob,
+ inputEnvelopeBlob,
+ outputEnvelopeBlob
+ )
+ );
+ byte[] outBytes = toEccCipherBytes("SDF_ExchangeDigitEnvelopeBaseOnECC", outputEnvelopeBlob);
+ return toBackupResult("SDF_ExchangeDigitEnvelopeBaseOnECC", outBytes, outBytes.length);
+ });
+ }
+
+ @Override
+ public AgreementDataAndKeyEccResult generateAgreementDataAndKeyWithEcc(GenerateAgreementDataAndKeyEccRequest request) {
+ GenerateAgreementDataAndKeyEccRequest req = requireRequest("request", request);
+ int iskIndex = requireNonNegative("iskIndex", req.getIskIndex());
+ int keyBits = requirePositive("keyBits", req.getKeyBits());
+ byte[] responseId = requireNonEmptyBytes("responseId", req.getResponseId());
+ byte[] sponsorId = requireNonEmptyBytes("sponsorId", req.getSponsorId());
+ EccRefPublicKey sponsorPublicKey = toEccRefPublicKey("sponsorPublicKeyBlob", req.getSponsorPublicKeyBlob());
+ EccRefPublicKey sponsorTmpPublicKey = toEccRefPublicKey("sponsorTmpPublicKeyBlob", req.getSponsorTmpPublicKeyBlob());
+ int responsePublicKeySize = requirePositive("responsePublicKeyBufferSize", req.getResponsePublicKeyBufferSize());
+ int responseTmpPublicKeySize = requirePositive("responseTmpPublicKeyBufferSize", req.getResponseTmpPublicKeyBufferSize());
+
+ return sessionTemplate.withSession("SDF_GenerateAgreementDataAndKeyWithECC", (lib, deviceHandle, sessionHandle) -> {
+ EccRefPublicKey responsePublicKey = new EccRefPublicKey();
+ EccRefPublicKey responseTmpPublicKey = new EccRefPublicKey();
+ if (responsePublicKeySize < responsePublicKey.size()) {
+ throw new IllegalArgumentException("responsePublicKeyBufferSize must be >= " + responsePublicKey.size());
+ }
+ if (responseTmpPublicKeySize < responseTmpPublicKey.size()) {
+ throw new IllegalArgumentException("responseTmpPublicKeyBufferSize must be >= " + responseTmpPublicKey.size());
+ }
+ PointerByReference keyHandleRef = new PointerByReference();
+ sessionTemplate.ensureSuccess(
+ "SDF_GenerateAgreementDataAndKeyWithECC",
+ lib.SDF_GenerateAgreementDataAndKeyWithECC(
+ sessionHandle,
+ iskIndex,
+ keyBits,
+ responseId,
+ responseId.length,
+ sponsorId,
+ sponsorId.length,
+ sponsorPublicKey,
+ sponsorTmpPublicKey,
+ responsePublicKey,
+ responseTmpPublicKey,
+ keyHandleRef
+ )
+ );
+ try {
+ AgreementDataAndKeyEccResult result = new AgreementDataAndKeyEccResult();
+ byte[] responsePublicKeyBytes = toBytes(responsePublicKey);
+ byte[] responseTmpPublicKeyBytes = toBytes(responseTmpPublicKey);
+ result.setResponsePublicKey(responsePublicKeyBytes);
+ result.setResponsePublicKeyLength(responsePublicKeyBytes.length);
+ result.setResponseTmpPublicKey(responseTmpPublicKeyBytes);
+ result.setResponseTmpPublicKeyLength(responseTmpPublicKeyBytes.length);
+ result.setSessionKeyGenerated(keyHandleRef.getValue() != null);
+ return result;
+ } finally {
+ destroyKeyHandle(lib, sessionHandle, keyHandleRef.getValue());
+ }
+ });
+ }
+
+ @Override
+ public EccAgreementSessionKeyResult generateSessionKeyWithEccAgreement(EccAgreementSessionKeyRequest request) {
+ EccAgreementSessionKeyRequest req = requireRequest("request", request);
+ int iskIndex = requireNonNegative("iskIndex", req.getIskIndex());
+ int keyBits = requirePositive("keyBits", req.getKeyBits());
+ byte[] sponsorId = requireNonEmptyBytes("sponsorId", req.getSponsorId());
+ byte[] responseId = requireNonEmptyBytes("responseId", req.getResponseId());
+ EccRefPublicKey responsePublicKey = toEccRefPublicKey("responsePublicKeyBlob", req.getResponsePublicKeyBlob());
+ EccRefPublicKey responseTmpPublicKey = toEccRefPublicKey("responseTmpPublicKeyBlob", req.getResponseTmpPublicKeyBlob());
+ int sponsorPublicKeySize = requirePositive("sponsorPublicKeyBufferSize", req.getSponsorPublicKeyBufferSize());
+ int sponsorTmpPublicKeySize = requirePositive("sponsorTmpPublicKeyBufferSize", req.getSponsorTmpPublicKeyBufferSize());
+ requirePositive("sessionKeyBufferSize", req.getSessionKeyBufferSize());
+
+ return sessionTemplate.withSession("SDF_GenerateAgreementDataWithECC+SDF_GenerateKeyWithECC", (lib, deviceHandle, sessionHandle) -> {
+ EccRefPublicKey sponsorPublicKey = new EccRefPublicKey();
+ EccRefPublicKey sponsorTmpPublicKey = new EccRefPublicKey();
+ if (sponsorPublicKeySize < sponsorPublicKey.size()) {
+ throw new IllegalArgumentException("sponsorPublicKeyBufferSize must be >= " + sponsorPublicKey.size());
+ }
+ if (sponsorTmpPublicKeySize < sponsorTmpPublicKey.size()) {
+ throw new IllegalArgumentException("sponsorTmpPublicKeyBufferSize must be >= " + sponsorTmpPublicKey.size());
+ }
+ PointerByReference agreementHandleRef = new PointerByReference();
+ sessionTemplate.ensureSuccess(
+ "SDF_GenerateAgreementDataWithECC",
+ lib.SDF_GenerateAgreementDataWithECC(
+ sessionHandle,
+ iskIndex,
+ keyBits,
+ sponsorId,
+ sponsorId.length,
+ sponsorPublicKey,
+ sponsorTmpPublicKey,
+ agreementHandleRef
+ )
+ );
+
+ Pointer agreementHandle = agreementHandleRef.getValue();
+ if (agreementHandle == null) {
+ throw new PcieCryptoException("SDF_GenerateAgreementDataWithECC", -1, "native returned null agreement handle");
+ }
+
+ PointerByReference keyHandleRef = new PointerByReference();
+
+ sessionTemplate.ensureSuccess(
+ "SDF_GenerateKeyWithECC",
+ lib.SDF_GenerateKeyWithECC(
+ sessionHandle,
+ responseId,
+ responseId.length,
+ responsePublicKey,
+ responseTmpPublicKey,
+ agreementHandle,
+ keyHandleRef
+ )
+ );
+
+ try {
+ EccAgreementSessionKeyResult result = new EccAgreementSessionKeyResult();
+ byte[] sponsorPublicKeyBytes = toBytes(sponsorPublicKey);
+ byte[] sponsorTmpPublicKeyBytes = toBytes(sponsorTmpPublicKey);
+ result.setSponsorPublicKey(sponsorPublicKeyBytes);
+ result.setSponsorPublicKeyLength(sponsorPublicKeyBytes.length);
+ result.setSponsorTmpPublicKey(sponsorTmpPublicKeyBytes);
+ result.setSponsorTmpPublicKeyLength(sponsorTmpPublicKeyBytes.length);
+ result.setSessionKey(new byte[0]);
+ result.setSessionKeyLength(0);
+ result.setSessionKeyGenerated(keyHandleRef.getValue() != null);
+ return result;
+ } finally {
+ destroyKeyHandle(lib, sessionHandle, keyHandleRef.getValue());
+ }
+ });
+ }
+
+ @Override
+ public BackupDataResult eccInternalSign(EccInternalSignRequest request) {
+ EccInternalSignRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ byte[] data = requireBytes("data", req.getData());
+ int signatureBufferSize = requirePositive("signatureBufferSize", req.getSignatureBufferSize());
+
+ return sessionTemplate.withSession("SDF_InternalSign_ECC", (lib, deviceHandle, sessionHandle) -> {
+ EccSignature signature = new EccSignature();
+ if (signatureBufferSize < signature.size()) {
+ throw new IllegalArgumentException("signatureBufferSize must be >= " + signature.size());
+ }
+ sessionTemplate.ensureSuccess(
+ "SDF_InternalSign_ECC",
+ lib.SDF_InternalSign_ECC(sessionHandle, keyIndex, data, data.length, signature)
+ );
+ byte[] signatureBytes = toBytes(signature);
+ return toBackupResult("SDF_InternalSign_ECC", signatureBytes, signatureBytes.length);
+ });
+ }
+
+ @Override
+ public BackupDataResult eccExternalSign(EccExternalSignRequest request) {
+ EccExternalSignRequest req = requireRequest("request", request);
+ int algId = requirePositive("algId", req.getAlgId());
+ EccRefPrivateKey privateKeyBlob = toEccRefPrivateKey("privateKeyBlob", req.getPrivateKeyBlob());
+ byte[] data = requireBytes("data", req.getData());
+ int signatureBufferSize = requirePositive("signatureBufferSize", req.getSignatureBufferSize());
+
+ return sessionTemplate.withSession("SDF_ExternalSign_ECC", (lib, deviceHandle, sessionHandle) -> {
+ EccSignature signature = new EccSignature();
+ if (signatureBufferSize < signature.size()) {
+ throw new IllegalArgumentException("signatureBufferSize must be >= " + signature.size());
+ }
+ sessionTemplate.ensureSuccess(
+ "SDF_ExternalSign_ECC",
+ lib.SDF_ExternalSign_ECC(sessionHandle, algId, privateKeyBlob, data, data.length, signature)
+ );
+ byte[] signatureBytes = toBytes(signature);
+ return toBackupResult("SDF_ExternalSign_ECC", signatureBytes, signatureBytes.length);
+ });
+ }
+
+ @Override
+ public void eccInternalVerify(EccInternalVerifyRequest request) {
+ EccInternalVerifyRequest req = requireRequest("request", request);
+ int keyIndex = requireNonNegative("keyIndex", req.getKeyIndex());
+ byte[] data = requireBytes("data", req.getData());
+ EccSignature signature = toEccSignature("signature", req.getSignature());
+
+ sessionTemplate.withSession("SDF_InternalVerify_ECC", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDF_InternalVerify_ECC",
+ lib.SDF_InternalVerify_ECC(sessionHandle, keyIndex, data, data.length, signature)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void eccExternalVerify(EccExternalVerifyRequest request) {
+ EccExternalVerifyRequest req = requireRequest("request", request);
+ int algId = requirePositive("algId", req.getAlgId());
+ EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
+ byte[] data = requireBytes("data", req.getData());
+ EccSignature signature = toEccSignature("signature", req.getSignature());
+
+ sessionTemplate.withSession("SDF_ExternalVerify_ECC", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDF_ExternalVerify_ECC",
+ lib.SDF_ExternalVerify_ECC(sessionHandle, algId, publicKeyBlob, data, data.length, signature)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public BackupDataResult eccExternalEncrypt(EccExternalEncryptRequest request) {
+ EccExternalEncryptRequest req = requireRequest("request", request);
+ int algId = requirePositive("algId", req.getAlgId());
+ EccRefPublicKey publicKeyBlob = toEccRefPublicKey("publicKeyBlob", req.getPublicKeyBlob());
+ byte[] data = requireBytes("data", req.getData());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_ExternalEncrypt_ECC", (lib, deviceHandle, sessionHandle) -> {
+ EccCipher encrypted = new EccCipher();
+ if (outBufferSize < encrypted.size()) {
+ throw new IllegalArgumentException("outBufferSize must be >= " + encrypted.size());
+ }
+ sessionTemplate.ensureSuccess(
+ "SDF_ExternalEncrypt_ECC",
+ lib.SDF_ExternalEncrypt_ECC(sessionHandle, algId, publicKeyBlob, data, data.length, encrypted)
+ );
+ byte[] encryptedBytes = toEccCipherBytes("SDF_ExternalEncrypt_ECC", encrypted);
+ return toBackupResult("SDF_ExternalEncrypt_ECC", encryptedBytes, encryptedBytes.length);
+ });
+ }
+
+ @Override
+ public BackupDataResult eccExternalDecrypt(EccExternalDecryptRequest request) {
+ EccExternalDecryptRequest req = requireRequest("request", request);
+ int algId = requirePositive("algId", req.getAlgId());
+ EccRefPrivateKey privateKeyBlob = toEccRefPrivateKey("privateKeyBlob", req.getPrivateKeyBlob());
+ EccCipher encryptedData = toEccCipher("encryptedData", req.getEncryptedData());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_ExternalDecrypt_ECC", (lib, deviceHandle, sessionHandle) -> {
+ byte[] plain = new byte[outBufferSize];
+ IntByReference plainLen = new IntByReference(plain.length);
+ sessionTemplate.ensureSuccess(
+ "SDF_ExternalDecrypt_ECC",
+ lib.SDF_ExternalDecrypt_ECC(sessionHandle, algId, privateKeyBlob, encryptedData, plain, plainLen)
+ );
+ return toBackupResult("SDF_ExternalDecrypt_ECC", plain, plainLen.getValue());
+ });
+ }
+
+ @Override
+ public BackupDataResult encryptWithPlainKey(SymmetricCryptoRequest request) {
+ SymmetricCryptoRequest req = requireRequest("request", request);
+ int algId = requirePositive("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();
+
+ return sessionTemplate.withSession("SDF_Encrypt", (lib, deviceHandle, sessionHandle) ->
+ withImportedPlainKey(lib, sessionHandle, key, handle -> {
+ byte[] out = new byte[outBufferSize];
+ IntByReference outLen = new IntByReference(out.length);
+ sessionTemplate.ensureSuccess(
+ "SDF_Encrypt",
+ lib.SDF_Encrypt(sessionHandle, handle, algId, iv, data, data.length, out, outLen)
+ );
+ return toBackupResult("SDF_Encrypt", out, outLen.getValue());
+ })
+ );
+ }
+
+ @Override
+ public BackupDataResult decryptWithPlainKey(SymmetricCryptoRequest request) {
+ SymmetricCryptoRequest req = requireRequest("request", request);
+ int algId = requirePositive("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();
+
+ return sessionTemplate.withSession("SDF_Decrypt", (lib, deviceHandle, sessionHandle) ->
+ withImportedPlainKey(lib, sessionHandle, key, handle -> {
+ byte[] out = new byte[outBufferSize];
+ IntByReference outLen = new IntByReference(out.length);
+ sessionTemplate.ensureSuccess(
+ "SDF_Decrypt",
+ lib.SDF_Decrypt(sessionHandle, handle, algId, iv, data, data.length, out, outLen)
+ );
+ return toBackupResult("SDF_Decrypt", out, outLen.getValue());
+ })
+ );
+ }
+
+ @Override
+ public BackupDataResult encryptWithKekWrappedKey(SymmetricKekCryptoRequest request) {
+ SymmetricKekCryptoRequest req = requireRequest("request", request);
+ int algId = requirePositive("algId", req.getAlgId());
+ int kekIndex = requireNonNegative("kekIndex", req.getKekIndex());
+ byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
+ byte[] data = requireBytes("data", req.getData());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+ byte[] iv = req.getIv();
+
+ return sessionTemplate.withSession("SDF_Encrypt", (lib, deviceHandle, sessionHandle) ->
+ withImportedKekKey(lib, sessionHandle, algId, kekIndex, wrappedKey, handle -> {
+ byte[] out = new byte[outBufferSize];
+ IntByReference outLen = new IntByReference(out.length);
+ sessionTemplate.ensureSuccess(
+ "SDF_Encrypt",
+ lib.SDF_Encrypt(sessionHandle, handle, algId, iv, data, data.length, out, outLen)
+ );
+ return toBackupResult("SDF_Encrypt", out, outLen.getValue());
+ })
+ );
+ }
+
+ @Override
+ public BackupDataResult decryptWithKekWrappedKey(SymmetricKekCryptoRequest request) {
+ SymmetricKekCryptoRequest req = requireRequest("request", request);
+ int algId = requirePositive("algId", req.getAlgId());
+ int kekIndex = requireNonNegative("kekIndex", req.getKekIndex());
+ byte[] wrappedKey = requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
+ byte[] data = requireBytes("data", req.getData());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+ byte[] iv = req.getIv();
+
+ return sessionTemplate.withSession("SDF_Decrypt", (lib, deviceHandle, sessionHandle) ->
+ withImportedKekKey(lib, sessionHandle, algId, kekIndex, wrappedKey, handle -> {
+ byte[] out = new byte[outBufferSize];
+ IntByReference outLen = new IntByReference(out.length);
+ sessionTemplate.ensureSuccess(
+ "SDF_Decrypt",
+ lib.SDF_Decrypt(sessionHandle, handle, algId, iv, data, data.length, out, outLen)
+ );
+ return toBackupResult("SDF_Decrypt", out, outLen.getValue());
+ })
+ );
+ }
+
+ @Override
+ public BackupDataResult calculateMacWithPlainKey(MacCalcRequest request) {
+ MacCalcRequest req = requireRequest("request", request);
+ int algId = requirePositive("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();
+
+ return sessionTemplate.withSession("SDF_CalculateMAC", (lib, deviceHandle, sessionHandle) ->
+ withImportedPlainKey(lib, sessionHandle, key, handle -> {
+ byte[] out = new byte[outBufferSize];
+ IntByReference outLen = new IntByReference(out.length);
+ sessionTemplate.ensureSuccess(
+ "SDF_CalculateMAC",
+ lib.SDF_CalculateMAC(sessionHandle, handle, algId, iv, data, data.length, out, outLen)
+ );
+ return toBackupResult("SDF_CalculateMAC", out, outLen.getValue());
+ })
+ );
+ }
+
+ @Override
+ public BackupDataResult digest(DigestRequest request) {
+ DigestRequest req = requireRequest("request", request);
+ int algId = requirePositive("algId", req.getAlgId());
+ byte[] data = requireBytes("data", req.getData());
+ int outBufferSize = requirePositive("outBufferSize", req.getOutBufferSize());
+
+ return sessionTemplate.withSession("SDF_Hash", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDF_HashInit", lib.SDF_HashInit(sessionHandle, algId, null, null, 0));
+ if (data.length > 0) {
+ sessionTemplate.ensureSuccess("SDF_HashUpdate", lib.SDF_HashUpdate(sessionHandle, data, data.length));
+ }
+ byte[] out = new byte[outBufferSize];
+ IntByReference outLen = new IntByReference(out.length);
+ sessionTemplate.ensureSuccess("SDF_HashFinal", lib.SDF_HashFinal(sessionHandle, out, outLen));
+ return toBackupResult("SDF_HashFinal", out, outLen.getValue());
+ });
+ }
+
+ @Override
+ public HmacResult hmac(HmacRequest request) {
+ HmacRequest req = requireRequest("request", request);
+ int algId = requirePositive("algId", req.getAlgId());
+ byte[] key = requireNonEmptyBytes("key", req.getKey());
+ byte[] data = requireBytes("data", req.getData());
+
+ return sessionTemplate.withSession("SDFE_Hmac", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_HmacInit", lib.SDFE_HmacInit(sessionHandle, algId, key, key.length));
+ if (data.length > 0) {
+ sessionTemplate.ensureSuccess("SDFE_HmacUpdate", lib.SDFE_HmacUpdate(sessionHandle, data, data.length));
+ }
+
+ byte[] out = new byte[HMAC_MAX_LENGTH];
+ IntByReference outLen = new IntByReference(out.length);
+ sessionTemplate.ensureSuccess("SDFE_HmacFinal", lib.SDFE_HmacFinal(sessionHandle, out, outLen));
+
+ int length = outLen.getValue();
+ if (length <= 0 || length > out.length) {
+ throw new PcieCryptoException("SDFE_HmacFinal", -1, "native returned invalid HMAC length: " + length);
+ }
+
+ HmacResult result = new HmacResult();
+ result.setHmacLength(length);
+ result.setHmac(Arrays.copyOf(out, length));
+ return result;
+ });
+ }
+
+ @Override
+ public void generateLmk() {
+ sessionTemplate.withSession("SDFE_GenerateLMK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_GenerateLMK", lib.SDFE_GenerateLMK(sessionHandle));
+ return null;
+ });
+ }
+
+ @Override
+ public void loadLmk() {
+ sessionTemplate.withSession("SDFE_LoadLMK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_LoadLMK", lib.SDFE_LoadLMK(sessionHandle));
+ return null;
+ });
+ }
+
+ @Override
+ public void backupLmk() {
+ sessionTemplate.withSession("SDFE_BackupLMK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_BackupLMK", lib.SDFE_BackupLMK(sessionHandle));
+ return null;
+ });
+ }
+
+ @Override
+ public void recoverLmk() {
+ sessionTemplate.withSession("SDFE_RecoverLMK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_RecoverLMK", lib.SDFE_RecoverLMK(sessionHandle));
+ return null;
+ });
+ }
+
+ @Override
+ public void destroyLmk() {
+ sessionTemplate.withSession("SDFE_DestroyLMK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_DestroyLMK", lib.SDFE_DestroyLMK(sessionHandle));
+ return null;
+ });
+ }
+
+ @Override
+ public void checkLmk() {
+ sessionTemplate.withSession("SDFE_CheckLMK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_CheckLMK", lib.SDFE_CheckLMK(sessionHandle));
+ return null;
+ });
+ }
+
+ @Override
+ public byte[] exportLmkSeedMac() {
+ return sessionTemplate.withSession("SDFE_ExportLMKSeedMAC", (lib, deviceHandle, sessionHandle) -> {
+ byte[] mac = new byte[LMK_SEED_MAC_LENGTH];
+ sessionTemplate.ensureSuccess("SDFE_ExportLMKSeedMAC", lib.SDFE_ExportLMKSeedMAC(sessionHandle, mac));
+ return Arrays.copyOf(mac, mac.length);
+ });
+ }
+
+ @Override
+ public BackupDataResult backupLmkEx(int outBufferSize) {
+ int size = requirePositive("outBufferSize", outBufferSize);
+
+ return sessionTemplate.withSession("SDFE_BackupLMK_EX", (lib, deviceHandle, sessionHandle) -> {
+ SdfeLmkComponent output = new SdfeLmkComponent();
+ int structSize = output.size();
+ if (size < structSize) {
+ throw new IllegalArgumentException("outBufferSize must be >= " + structSize);
+ }
+ sessionTemplate.ensureSuccess("SDFE_BackupLMK_EX", lib.SDFE_BackupLMK_EX(sessionHandle, output));
+ byte[] outputBytes = toBytes(output);
+ return toBackupResult("SDFE_BackupLMK_EX", outputBytes, outputBytes.length);
+ });
+ }
+
+ @Override
+ public void recoverLmkEx(byte[] lmkComponent) {
+ SdfeLmkComponent input = toSdfeLmkComponent("lmkComponent", lmkComponent);
+
+ sessionTemplate.withSession("SDFE_RecoverLMK_EX", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_RecoverLMK_EX", lib.SDFE_RecoverLMK_EX(sessionHandle, input));
+ return null;
+ });
+ }
+
+ @Override
+ public void generateIk(int keyType) {
+ int safeKeyType = requireNonNegative("keyType", keyType);
+
+ sessionTemplate.withSession("SDFE_GenerateIK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_GenerateIK", lib.SDFE_GenerateIK(sessionHandle, safeKeyType));
+ return null;
+ });
+ }
+
+ @Override
+ public void backupIk(int keyType) {
+ int safeKeyType = requireNonNegative("keyType", keyType);
+
+ sessionTemplate.withSession("SDFE_BackupIK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_BackupIK", lib.SDFE_BackupIK(sessionHandle, safeKeyType));
+ return null;
+ });
+ }
+
+ @Override
+ public void recoverIk(int keyType) {
+ int safeKeyType = requireNonNegative("keyType", keyType);
+
+ sessionTemplate.withSession("SDFE_RecoverIK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_RecoverIK", lib.SDFE_RecoverIK(sessionHandle, safeKeyType));
+ return null;
+ });
+ }
+
+ @Override
+ public void destroyIk(int keyType) {
+ int safeKeyType = requireNonNegative("keyType", keyType);
+
+ sessionTemplate.withSession("SDFE_DestroyIK", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_DestroyIK", lib.SDFE_DestroyIK(sessionHandle, safeKeyType));
+ return null;
+ });
+ }
+
+ @Override
+ public KeyStatusResult statusIk(int keyType) {
+ int safeKeyType = requireNonNegative("keyType", keyType);
+
+ return sessionTemplate.withSession("SDFE_StatusIK", (lib, deviceHandle, sessionHandle) -> {
+ IntByReference stateRef = new IntByReference();
+ sessionTemplate.ensureSuccess("SDFE_StatusIK", lib.SDFE_StatusIK(sessionHandle, safeKeyType, stateRef));
+ return toKeyStatus(stateRef.getValue());
+ });
+ }
+
+ @Override
+ public void generateUkey(UkeyGenerateRequest request) {
+ UkeyGenerateRequest req = requireRequest("request", request);
+ int adminIndex = requireByteRange("adminIndex", req.getAdminIndex());
+ byte[] ukeyPin = requireNonEmptyBytes("ukeyPin", req.getUkeyPin());
+ byte[] loginPin = requireNonEmptyBytes("loginPin", req.getLoginPin());
+
+ sessionTemplate.withSession("SDFE_GenerateUkey", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_GenerateUkey",
+ lib.SDFE_GenerateUkey(
+ sessionHandle,
+ (byte) adminIndex,
+ ukeyPin,
+ ukeyPin.length,
+ loginPin,
+ loginPin.length
+ )
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void loginUkey(UkeyLoginRequest request) {
+ UkeyLoginRequest req = requireRequest("request", request);
+ byte[] ukeyPin = requireNonEmptyBytes("ukeyPin", req.getUkeyPin());
+ byte[] loginPin = requireNonEmptyBytes("loginPin", req.getLoginPin());
+
+ sessionTemplate.withSession("SDFE_LoginUkey", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_LoginUkey",
+ lib.SDFE_LoginUkey(sessionHandle, ukeyPin, ukeyPin.length, loginPin, loginPin.length)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void changeUkeyPin(UkeyPinChangeRequest request) {
+ UkeyPinChangeRequest req = requireRequest("request", request);
+ int pinType = requireNonNegative("pinType", req.getPinType());
+ byte[] oldPin = requireNonEmptyBytes("oldPin", req.getOldPin());
+ byte[] newPin = requireNonEmptyBytes("newPin", req.getNewPin());
+
+ sessionTemplate.withSession("SDFE_ChangeUkeyPin", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_ChangeUkeyPin",
+ lib.SDFE_ChangeUkeyPin(sessionHandle, pinType, oldPin, oldPin.length, newPin, newPin.length)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void unlockUkey(UkeyUnlockRequest request) {
+ UkeyUnlockRequest req = requireRequest("request", request);
+ byte[] adminPin = requireNonEmptyBytes("adminPin", req.getAdminPin());
+ byte[] userPin = requireNonEmptyBytes("userPin", req.getUserPin());
+
+ sessionTemplate.withSession("SDFE_UnlockUkey", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_UnlockUkey",
+ lib.SDFE_UnlockUkey(sessionHandle, adminPin, adminPin.length, userPin, userPin.length)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void readLmkComponent(byte[] ukeyPin) {
+ byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin);
+
+ sessionTemplate.withSession("SDFE_ReadLMKComponent", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_ReadLMKComponent", lib.SDFE_ReadLMKComponent(sessionHandle, pin, pin.length));
+ return null;
+ });
+ }
+
+ @Override
+ public void readUkeyIkComponent(int keyType, byte[] ukeyPin) {
+ int safeKeyType = requireNonNegative("keyType", keyType);
+ byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin);
+
+ sessionTemplate.withSession("SDFE_ReadUkeyIKComponent", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDFE_ReadUkeyIKComponent",
+ lib.SDFE_ReadUkeyIKComponent(sessionHandle, safeKeyType, pin, pin.length)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public void generateCertificate(byte[] ukeyPin) {
+ byte[] pin = requireNonEmptyBytes("ukeyPin", ukeyPin);
+
+ sessionTemplate.withSession("SDFE_GenerateCertificate", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_GenerateCertificate", lib.SDFE_GenerateCertificate(sessionHandle, pin, pin.length));
+ return null;
+ });
+ }
+
+ @Override
+ public void logoutAdmin(int adminIndex) {
+ int safeAdminIndex = requireByteRange("adminIndex", adminIndex);
+
+ sessionTemplate.withSession("SDFE_LoginoutAdmin", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDFE_LoginoutAdmin", lib.SDFE_LoginoutAdmin(sessionHandle, (byte) safeAdminIndex));
+ return null;
+ });
+ }
+
+ @Override
+ public LoginStatusResult loginStatus() {
+ return sessionTemplate.withSession("SDFE_LoginStatus", (lib, deviceHandle, sessionHandle) -> {
+ SdfeLoginState state = new SdfeLoginState();
+ sessionTemplate.ensureSuccess("SDFE_LoginStatus", lib.SDFE_LoginStatus(sessionHandle, state));
+ state.read();
+
+ LoginStatusResult result = new LoginStatusResult();
+ result.setAdmin1(state.admin1);
+ result.setAdmin2(state.admin2);
+ result.setAdmin3(state.admin3);
+ return result;
+ });
+ }
+
+ @Override
+ public void createFile(FileCreateRequest request) {
+ FileCreateRequest req = requireRequest("request", request);
+ byte[] fileName = fileNameBytes(req.getFileName());
+ int fileSize = requirePositive("fileSize", req.getFileSize());
+
+ sessionTemplate.withSession("SDF_CreateFile", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDF_CreateFile", lib.SDF_CreateFile(sessionHandle, fileName, fileName.length, fileSize));
+ return null;
+ });
+ }
+
+ @Override
+ public void writeFile(FileWriteRequest request) {
+ FileWriteRequest req = requireRequest("request", request);
+ byte[] fileName = fileNameBytes(req.getFileName());
+ int offset = requireNonNegative("offset", req.getOffset());
+ byte[] data = requireBytes("data", req.getData());
+
+ sessionTemplate.withSession("SDF_WriteFile", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess(
+ "SDF_WriteFile",
+ lib.SDF_WriteFile(sessionHandle, fileName, fileName.length, offset, data.length, data)
+ );
+ return null;
+ });
+ }
+
+ @Override
+ public BackupDataResult readFile(FileReadRequest request) {
+ FileReadRequest req = requireRequest("request", request);
+ byte[] fileName = fileNameBytes(req.getFileName());
+ int offset = requireNonNegative("offset", req.getOffset());
+ int readLength = requirePositive("readLength", req.getReadLength());
+
+ return sessionTemplate.withSession("SDF_ReadFile", (lib, deviceHandle, sessionHandle) -> {
+ byte[] data = new byte[readLength];
+ IntByReference outLen = new IntByReference(readLength);
+ sessionTemplate.ensureSuccess(
+ "SDF_ReadFile",
+ lib.SDF_ReadFile(sessionHandle, fileName, fileName.length, offset, outLen, data)
+ );
+ return toBackupResult("SDF_ReadFile", data, outLen.getValue());
+ });
+ }
+
+ @Override
+ public void deleteFile(String fileName) {
+ byte[] name = fileNameBytes(fileName);
+ sessionTemplate.withSession("SDF_DeleteFile", (lib, deviceHandle, sessionHandle) -> {
+ sessionTemplate.ensureSuccess("SDF_DeleteFile", lib.SDF_DeleteFile(sessionHandle, name, name.length));
+ return null;
+ });
+ }
+
+ @FunctionalInterface
+ private interface KeyHandleCallback {
+ T apply(Pointer keyHandle);
+ }
+
+ private T withImportedPlainKey(
+ PcieNativeLibrary lib,
+ Pointer sessionHandle,
+ byte[] key,
+ KeyHandleCallback callback
+ ) {
+ PointerByReference keyHandleRef = new PointerByReference();
+ sessionTemplate.ensureSuccess("SDF_ImportKey", lib.SDF_ImportKey(sessionHandle, key, key.length, keyHandleRef));
+ Pointer keyHandle = keyHandleRef.getValue();
+ try {
+ return callback.apply(keyHandle);
+ } finally {
+ destroyKeyHandle(lib, sessionHandle, keyHandle);
+ }
+ }
+
+ private T withImportedKekKey(
+ PcieNativeLibrary lib,
+ Pointer sessionHandle,
+ int algId,
+ int kekIndex,
+ byte[] wrappedKey,
+ KeyHandleCallback callback
+ ) {
+ PointerByReference keyHandleRef = new PointerByReference();
+ sessionTemplate.ensureSuccess(
+ "SDF_ImportKeyWithKEK",
+ lib.SDF_ImportKeyWithKEK(sessionHandle, algId, wrappedKey, wrappedKey.length, kekIndex, keyHandleRef)
+ );
+ Pointer keyHandle = keyHandleRef.getValue();
+ try {
+ return callback.apply(keyHandle);
+ } finally {
+ destroyKeyHandle(lib, sessionHandle, keyHandle);
+ }
+ }
+
+ private static void destroyKeyHandle(
+ PcieNativeLibrary lib,
+ Pointer sessionHandle,
+ Pointer keyHandle
+ ) {
+ if (keyHandle == null) {
+ return;
+ }
+ int destroyCode = lib.SDF_DestroyKey(sessionHandle, keyHandle);
+ if (destroyCode != 0) {
+ throw new PcieCryptoException("SDF_DestroyKey", destroyCode, "destroy key failed");
+ }
+ }
+
+ private static byte[] fileNameBytes(String fileName) {
+ if (fileName == null || fileName.isBlank()) {
+ throw new IllegalArgumentException("fileName must not be blank");
+ }
+ return fileName.getBytes(StandardCharsets.UTF_8);
+ }
+
+ private static String zeroTerminatedString(byte[] value) {
+ int len = 0;
+ while (len < value.length && value[len] != 0) {
+ len++;
+ }
+ return new String(value, 0, len, StandardCharsets.UTF_8).trim();
+ }
+
+ private static StandardKeyPairResult toStandardKeyPairResult(byte[] publicKey, byte[] privateKey) {
+ StandardKeyPairResult result = new StandardKeyPairResult();
+ result.setPublicKey(Arrays.copyOf(publicKey, publicKey.length));
+ result.setPublicKeyLength(publicKey.length);
+ result.setPrivateKey(Arrays.copyOf(privateKey, privateKey.length));
+ result.setPrivateKeyLength(privateKey.length);
+ return result;
+ }
+
+ private static BackupDataResult toBackupResult(String apiName, byte[] out, int outLen) {
+ if (outLen < 0 || outLen > out.length) {
+ throw new PcieCryptoException(apiName, -1, "native returned invalid output length: " + outLen);
+ }
+ BackupDataResult result = new BackupDataResult();
+ result.setLength(outLen);
+ result.setData(Arrays.copyOf(out, outLen));
+ return result;
+ }
+
+ private static KeyStatusResult toKeyStatus(int stateCode) {
+ PcieKeyState state = PcieKeyState.from(stateCode);
+ KeyStatusResult result = new KeyStatusResult();
+ result.setKeyState(stateCode);
+ result.setKeyStateName(state.name());
+ return result;
+ }
+
+ private static int requireUserKeyType(int keyType) {
+ if (keyType != PcieUserKeyType.SIGN.getCode() && keyType != PcieUserKeyType.ENC.getCode()) {
+ throw new IllegalArgumentException("keyType must be 0(SIGN) or 1(ENC)");
+ }
+ return keyType;
+ }
+
+ private static int requirePositive(String name, int value) {
+ if (value <= 0) {
+ throw new IllegalArgumentException(name + " must be > 0");
+ }
+ return value;
+ }
+
+ private static int requireNonNegative(String name, int value) {
+ if (value < 0) {
+ throw new IllegalArgumentException(name + " must be >= 0");
+ }
+ return value;
+ }
+
+ private static int requireByteRange(String name, int value) {
+ if (value < 0 || value > 255) {
+ throw new IllegalArgumentException(name + " must be in [0,255]");
+ }
+ return value;
+ }
+
+ private static byte[] requireNonEmptyBytes(String name, byte[] value) {
+ if (value == null || value.length == 0) {
+ throw new IllegalArgumentException(name + " must not be empty");
+ }
+ return value;
+ }
+
+ private static byte[] requireBytes(String name, byte[] value) {
+ if (value == null) {
+ throw new IllegalArgumentException(name + " must not be null");
+ }
+ return value;
+ }
+
+ private static RsaRefPublicKey toRsaRefPublicKey(String name, byte[] value) {
+ return toStructure(name, value, new RsaRefPublicKey(), false);
+ }
+
+ private static RsaRefPrivateKey toRsaRefPrivateKey(String name, byte[] value) {
+ return toStructure(name, value, new RsaRefPrivateKey(), false);
+ }
+
+ private static EccRefPublicKey toEccRefPublicKey(String name, byte[] value) {
+ return toStructure(name, value, new EccRefPublicKey(), false);
+ }
+
+ private static EccRefPrivateKey toEccRefPrivateKey(String name, byte[] value) {
+ return toStructure(name, value, new EccRefPrivateKey(), false);
+ }
+
+ private static EccSignature toEccSignature(String name, byte[] value) {
+ return toStructure(name, value, new EccSignature(), false);
+ }
+
+ private static EccCipher toEccCipher(String name, byte[] value) {
+ return toStructure(name, value, new EccCipher(), true);
+ }
+
+ private static SdfeKekComponent toSdfeKekComponent(String name, byte[] value) {
+ return toStructure(name, value, new SdfeKekComponent(), false);
+ }
+
+ private static SdfeLmkComponent toSdfeLmkComponent(String name, byte[] value) {
+ return toStructure(name, value, new SdfeLmkComponent(), false);
+ }
+
+ private static EnvelopedKeyBlob toEnvelopedKeyBlob(String name, byte[] value) {
+ return toStructure(name, value, new EnvelopedKeyBlob(), true);
+ }
+
+ private static byte[] toBytes(Structure structure) {
+ structure.read();
+ return structure.getPointer().getByteArray(0, structure.size());
+ }
+
+ private static byte[] toEccCipherBytes(String apiName, EccCipher cipher) {
+ cipher.read();
+ int cLength = cipher.l;
+ if (cLength < 0 || cLength > EccCipher.C_MAX_LEN) {
+ throw new PcieCryptoException(apiName, -1, "native returned invalid ECC cipher C length: " + cLength);
+ }
+ int totalLength = ECC_CIPHER_PREFIX_LENGTH + cLength;
+ if (totalLength < 0 || totalLength > cipher.size()) {
+ throw new PcieCryptoException(apiName, -1, "native returned invalid ECC cipher blob length: " + totalLength);
+ }
+ return cipher.getPointer().getByteArray(0, totalLength);
+ }
+
+ private static T toStructure(String name, byte[] value, T structure, boolean allowPartial) {
+ byte[] source = requireNonEmptyBytes(name, value);
+ int size = structure.size();
+ if (allowPartial) {
+ if (source.length > size) {
+ throw new IllegalArgumentException(name + " length must be <= " + size + ", actual: " + source.length);
+ }
+ } else if (source.length != size) {
+ throw new IllegalArgumentException(name + " length must be exactly " + size + ", actual: " + source.length);
+ }
+ Pointer pointer = structure.getPointer();
+ pointer.clear(size);
+ pointer.write(0, source, 0, source.length);
+ structure.read();
+ return structure;
+ }
+
+ private static T requireRequest(String name, T request) {
+ if (request == null) {
+ throw new IllegalArgumentException(name + " must not be null");
+ }
+ return request;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/service/MockPcieCryptoService.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/service/MockPcieCryptoService.java
new file mode 100644
index 0000000..df96808
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/service/MockPcieCryptoService.java
@@ -0,0 +1,896 @@
+package com.cisd.tms.integration.crypto.pcie.service;
+
+import com.cisd.tms.integration.crypto.pcie.PcieKeyState;
+import com.cisd.tms.integration.crypto.pcie.PcieUserKeyType;
+import com.cisd.tms.integration.crypto.pcie.model.AgreementDataAndKeyEccResult;
+import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult;
+import com.cisd.tms.integration.crypto.pcie.model.ChangePrivateKeyPasswordRequest;
+import com.cisd.tms.integration.crypto.pcie.model.DeviceConfResult;
+import com.cisd.tms.integration.crypto.pcie.model.DeviceCountResult;
+import com.cisd.tms.integration.crypto.pcie.model.DeviceInfoResult;
+import com.cisd.tms.integration.crypto.pcie.model.DeviceStatusResult;
+import com.cisd.tms.integration.crypto.pcie.model.DigestRequest;
+import com.cisd.tms.integration.crypto.pcie.model.EccExternalDecryptRequest;
+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.EccAgreementSessionKeyRequest;
+import com.cisd.tms.integration.crypto.pcie.model.EccAgreementSessionKeyResult;
+import com.cisd.tms.integration.crypto.pcie.model.EccExternalVerifyRequest;
+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.ExchangeDigitEnvelopeEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ExchangeDigitEnvelopeRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ExportKekComponentRequest;
+import com.cisd.tms.integration.crypto.pcie.model.FileCreateRequest;
+import com.cisd.tms.integration.crypto.pcie.model.FileReadRequest;
+import com.cisd.tms.integration.crypto.pcie.model.FileWriteRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateAgreementDataAndKeyEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKekRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateStandardEccKeyPairRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateStandardRsaKeyPairRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithEpkEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithEpkRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithIpkEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithIpkRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithKekRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyPairRequest;
+import com.cisd.tms.integration.crypto.pcie.model.HmacRequest;
+import com.cisd.tms.integration.crypto.pcie.model.HmacResult;
+import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportKekRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportKeyPairRequest;
+import com.cisd.tms.integration.crypto.pcie.model.KekComponentRequest;
+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.MacCalcRequest;
+import com.cisd.tms.integration.crypto.pcie.model.PrivateKeyAccessRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RecoverKekRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RecoverUserKeyRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RsaExternalPrivateKeyOpRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RsaExternalPublicKeyOpRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RsaInternalKeyOpRequest;
+import com.cisd.tms.integration.crypto.pcie.model.SymmetricCryptoRequest;
+import com.cisd.tms.integration.crypto.pcie.model.SymmetricKekCryptoRequest;
+import com.cisd.tms.integration.crypto.pcie.model.StandardKeyPairResult;
+import com.cisd.tms.integration.crypto.pcie.model.UkeyGenerateRequest;
+import com.cisd.tms.integration.crypto.pcie.model.UkeyLoginRequest;
+import com.cisd.tms.integration.crypto.pcie.model.UkeyPinChangeRequest;
+import com.cisd.tms.integration.crypto.pcie.model.UkeyUnlockRequest;
+import com.cisd.tms.integration.crypto.pcie.model.UpdateBackedKeyRequest;
+import java.util.Arrays;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+public class MockPcieCryptoService implements PcieCryptoService {
+
+ private static final int ECC_KEY_BITS = 256;
+
+ @Override
+ public DeviceCountResult getDeviceCount() {
+ DeviceCountResult result = new DeviceCountResult();
+ result.setDeviceNumber(0);
+ result.setNormalDeviceNumber(0);
+ return result;
+ }
+
+ @Override
+ public DeviceConfResult getDeviceConf() {
+ return new DeviceConfResult();
+ }
+
+ @Override
+ public DeviceInfoResult getDeviceInfo() {
+ return new DeviceInfoResult();
+ }
+
+ @Override
+ public byte[] generateRandom(int length) {
+ int randomLength = requirePositive("length", length);
+ byte[] output = new byte[randomLength];
+ Arrays.fill(output, (byte) 0x6A);
+ return output;
+ }
+
+ @Override
+ public void initIdentify(byte[] oldPin, byte[] newPin) {
+ requireNonEmptyBytes("oldPin", oldPin);
+ requireNonEmptyBytes("newPin", newPin);
+ }
+
+ @Override
+ public void deviceSelfTest() {
+ // no-op
+ }
+
+ @Override
+ public DeviceStatusResult getDeviceStatus(int statusBufferSize) {
+ int size = requirePositive("statusBufferSize", statusBufferSize);
+ DeviceStatusResult result = new DeviceStatusResult();
+ result.setLength(size);
+ result.setStatusData(new byte[size]);
+ return result;
+ }
+
+ @Override
+ public void deviceFactoryReset() {
+ // no-op
+ }
+
+ @Override
+ public void changePrivateKeyAccessPassword(ChangePrivateKeyPasswordRequest request) {
+ ChangePrivateKeyPasswordRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireNonEmptyBytes("oldPassword", req.getOldPassword());
+ requireNonEmptyBytes("newPassword", req.getNewPassword());
+ }
+
+ @Override
+ public void getPrivateKeyAccessRight(PrivateKeyAccessRequest request) {
+ PrivateKeyAccessRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireNonEmptyBytes("password", req.getPassword());
+ }
+
+ @Override
+ public void releasePrivateKeyAccessRight(int keyIndex) {
+ requireNonNegative("keyIndex", keyIndex);
+ }
+
+ @Override
+ public void generateKeyPairEcc(GenerateKeyPairRequest request) {
+ GenerateKeyPairRequest req = requireRequest("request", request);
+ if (req.getKeyBits() != ECC_KEY_BITS) {
+ throw new IllegalArgumentException("keyBits must be 256 for ECC");
+ }
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireUserKeyType(req.getKeyType());
+ }
+
+ @Override
+ public void generateKeyPairRsa(GenerateKeyPairRequest request) {
+ GenerateKeyPairRequest req = requireRequest("request", request);
+ requirePositive("keyBits", req.getKeyBits());
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireUserKeyType(req.getKeyType());
+ }
+
+ @Override
+ public void importKeyPairEcc(ImportKeyPairRequest request) {
+ validateImportKeyPair(request);
+ }
+
+ @Override
+ public void importKeyPairRsa(ImportKeyPairRequest request) {
+ validateImportKeyPair(request);
+ }
+
+ @Override
+ public void generateKek(GenerateKekRequest request) {
+ GenerateKekRequest req = requireRequest("request", request);
+ int keyBits = req.getKeyBits();
+ if (keyBits != 128 && keyBits != 192 && keyBits != 256) {
+ throw new IllegalArgumentException("keyBits must be one of 128/192/256 for KEK");
+ }
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ }
+
+ @Override
+ public void importKek(ImportKekRequest request) {
+ ImportKekRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireNonEmptyBytes("keyData", req.getKeyData());
+ }
+
+ @Override
+ public void importKekComponent(KekComponentRequest request) {
+ KekComponentRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requirePositive("componentNum", req.getComponentNum());
+ requireNonEmptyBytes("componentData", req.getComponentData());
+ }
+
+ @Override
+ public BackupDataResult exportKekComponent(ExportKekComponentRequest request) {
+ ExportKekComponentRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requirePositive("componentNum", req.getComponentNum());
+ int size = requirePositive("componentSize", req.getComponentSize());
+ return mockBackup(size, req.getComponentNum());
+ }
+
+ @Override
+ public BackupDataResult backupUserKey(int keyIndex, int keyType, int outBufferSize) {
+ requireNonNegative("keyIndex", keyIndex);
+ requireUserKeyType(keyType);
+ int size = requirePositive("outBufferSize", outBufferSize);
+ return mockBackup(size, keyIndex);
+ }
+
+ @Override
+ public void recoverUserKey(RecoverUserKeyRequest request) {
+ RecoverUserKeyRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireUserKeyType(req.getKeyType());
+ requireNonEmptyBytes("encryptedKey", req.getEncryptedKey());
+ int storeFlag = req.getStoreFlag();
+ if (storeFlag != 0 && storeFlag != 1) {
+ throw new IllegalArgumentException("storeFlag must be 0 or 1");
+ }
+ }
+
+ @Override
+ public BackupDataResult backupKek(int keyIndex, int outBufferSize) {
+ requireNonNegative("keyIndex", keyIndex);
+ int size = requirePositive("outBufferSize", outBufferSize);
+ return mockBackup(size, keyIndex);
+ }
+
+ @Override
+ public void recoverKek(RecoverKekRequest request) {
+ RecoverKekRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireNonEmptyBytes("encryptedKey", req.getEncryptedKey());
+ }
+
+ @Override
+ public void deleteUserKey(int keyIndex) {
+ requireNonNegative("keyIndex", keyIndex);
+ }
+
+ @Override
+ public void deleteKek(int keyIndex) {
+ requireNonNegative("keyIndex", keyIndex);
+ }
+
+ @Override
+ public BackupDataResult backupAllKey(int outBufferSize) {
+ int size = requirePositive("outBufferSize", outBufferSize);
+ return mockBackup(size, 0x5A);
+ }
+
+ @Override
+ public void restoreAllKey(byte[] keyImage) {
+ requireNonEmptyBytes("keyImage", keyImage);
+ }
+
+ @Override
+ public KeyStatusResult statusUserKeyEcc(int keyIndex, int keyType) {
+ requireNonNegative("keyIndex", keyIndex);
+ requireUserKeyType(keyType);
+ return keyStatus(PcieKeyState.RIGHT);
+ }
+
+ @Override
+ public KeyStatusResult statusUserKeyRsa(int keyIndex, int keyType) {
+ requireNonNegative("keyIndex", keyIndex);
+ requireUserKeyType(keyType);
+ return keyStatus(PcieKeyState.RIGHT);
+ }
+
+ @Override
+ public KeyStatusResult statusKek(int keyIndex) {
+ requireNonNegative("keyIndex", keyIndex);
+ return keyStatus(PcieKeyState.RIGHT);
+ }
+
+ @Override
+ public void importEncryptedKeyPairEcc(ImportEncKeyPairEccRequest request) {
+ ImportEncKeyPairEccRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireNonEmptyBytes("envelopedKeyBlob", req.getEnvelopedKeyBlob());
+ }
+
+ @Override
+ public void importEncryptedKeyPairRsa(ImportEncKeyPairRsaRequest request) {
+ ImportEncKeyPairRsaRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requirePositive("symAlgId", req.getSymAlgId());
+ requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
+ requireNonEmptyBytes("encryptedData", req.getEncryptedData());
+ }
+
+ @Override
+ public BackupDataResult updateBackedKey(UpdateBackedKeyRequest request) {
+ UpdateBackedKeyRequest req = requireRequest("request", request);
+ requireNonEmptyBytes("oldData", req.getOldData());
+ int size = requirePositive("newDataBufferSize", req.getNewDataBufferSize());
+ return mockBackup(size, 0x33);
+ }
+
+ @Override
+ public BackupDataResult exportSignPublicKeyRsa(int keyIndex, int outBufferSize) {
+ requireNonNegative("keyIndex", keyIndex);
+ int size = requirePositive("outBufferSize", outBufferSize);
+ return mockBackup(size, 0x41);
+ }
+
+ @Override
+ public BackupDataResult exportEncPublicKeyRsa(int keyIndex, int outBufferSize) {
+ requireNonNegative("keyIndex", keyIndex);
+ int size = requirePositive("outBufferSize", outBufferSize);
+ return mockBackup(size, 0x42);
+ }
+
+ @Override
+ public BackupDataResult exportSignPublicKeyEcc(int keyIndex, int outBufferSize) {
+ requireNonNegative("keyIndex", keyIndex);
+ int size = requirePositive("outBufferSize", outBufferSize);
+ return mockBackup(size, 0x43);
+ }
+
+ @Override
+ public BackupDataResult exportEncPublicKeyEcc(int keyIndex, int outBufferSize) {
+ requireNonNegative("keyIndex", keyIndex);
+ int size = requirePositive("outBufferSize", outBufferSize);
+ return mockBackup(size, 0x44);
+ }
+
+ @Override
+ public StandardKeyPairResult generateStandardRsaKeyPair(GenerateStandardRsaKeyPairRequest request) {
+ GenerateStandardRsaKeyPairRequest req = requireRequest("request", request);
+ requirePositive("keyBits", req.getKeyBits());
+ int pubSize = requirePositive("publicKeyBufferSize", req.getPublicKeyBufferSize());
+ int priSize = requirePositive("privateKeyBufferSize", req.getPrivateKeyBufferSize());
+ return mockStandardKeyPair(pubSize, priSize, 0x53, 0x54);
+ }
+
+ @Override
+ public StandardKeyPairResult generateStandardEccKeyPair(GenerateStandardEccKeyPairRequest request) {
+ GenerateStandardEccKeyPairRequest req = requireRequest("request", request);
+ requirePositive("algId", req.getAlgId());
+ requirePositive("keyBits", req.getKeyBits());
+ int pubSize = requirePositive("publicKeyBufferSize", req.getPublicKeyBufferSize());
+ int priSize = requirePositive("privateKeyBufferSize", req.getPrivateKeyBufferSize());
+ return mockStandardKeyPair(pubSize, priSize, 0x55, 0x56);
+ }
+
+ @Override
+ public BackupDataResult generateKeyWithKek(GenerateKeyWithKekRequest request) {
+ GenerateKeyWithKekRequest req = requireRequest("request", request);
+ requirePositive("keyBits", req.getKeyBits());
+ requirePositive("algId", req.getAlgId());
+ requireNonNegative("kekIndex", req.getKekIndex());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x45);
+ }
+
+ @Override
+ public BackupDataResult rsaExternalPublicKeyOperation(RsaExternalPublicKeyOpRequest request) {
+ RsaExternalPublicKeyOpRequest req = requireRequest("request", request);
+ requireNonEmptyBytes("publicKeyBlob", req.getPublicKeyBlob());
+ requireBytes("input", req.getInput());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x46);
+ }
+
+ @Override
+ public BackupDataResult rsaExternalPrivateKeyOperation(RsaExternalPrivateKeyOpRequest request) {
+ RsaExternalPrivateKeyOpRequest req = requireRequest("request", request);
+ requireNonEmptyBytes("privateKeyBlob", req.getPrivateKeyBlob());
+ requireBytes("input", req.getInput());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x4C);
+ }
+
+ @Override
+ public BackupDataResult rsaInternalPublicKeyOperation(RsaInternalKeyOpRequest request) {
+ RsaInternalKeyOpRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireBytes("input", req.getInput());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x47);
+ }
+
+ @Override
+ public BackupDataResult rsaInternalPrivateKeyOperation(RsaInternalKeyOpRequest request) {
+ RsaInternalKeyOpRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireBytes("input", req.getInput());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x48);
+ }
+
+ @Override
+ public BackupDataResult generateKeyWithIpkRsa(GenerateKeyWithIpkRsaRequest request) {
+ GenerateKeyWithIpkRsaRequest req = requireRequest("request", request);
+ requireNonNegative("ipkIndex", req.getIpkIndex());
+ requirePositive("keyBits", req.getKeyBits());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x4D);
+ }
+
+ @Override
+ public BackupDataResult generateKeyWithEpkRsa(GenerateKeyWithEpkRsaRequest request) {
+ GenerateKeyWithEpkRsaRequest req = requireRequest("request", request);
+ requirePositive("keyBits", req.getKeyBits());
+ requireNonEmptyBytes("publicKeyBlob", req.getPublicKeyBlob());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x4E);
+ }
+
+ @Override
+ public void importKeyWithIskRsa(ImportKeyWithIskRsaRequest request) {
+ ImportKeyWithIskRsaRequest req = requireRequest("request", request);
+ requireNonNegative("iskIndex", req.getIskIndex());
+ requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
+ }
+
+ @Override
+ public BackupDataResult generateKeyWithIpkEcc(GenerateKeyWithIpkEccRequest request) {
+ GenerateKeyWithIpkEccRequest req = requireRequest("request", request);
+ requireNonNegative("ipkIndex", req.getIpkIndex());
+ requirePositive("keyBits", req.getKeyBits());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x50);
+ }
+
+ @Override
+ public BackupDataResult generateKeyWithEpkEcc(GenerateKeyWithEpkEccRequest request) {
+ GenerateKeyWithEpkEccRequest req = requireRequest("request", request);
+ requirePositive("keyBits", req.getKeyBits());
+ requirePositive("algId", req.getAlgId());
+ requireNonEmptyBytes("publicKeyBlob", req.getPublicKeyBlob());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x51);
+ }
+
+ @Override
+ public void importKeyWithIskEcc(ImportKeyWithIskEccRequest request) {
+ ImportKeyWithIskEccRequest req = requireRequest("request", request);
+ requireNonNegative("iskIndex", req.getIskIndex());
+ requireNonEmptyBytes("encryptedKeyBlob", req.getEncryptedKeyBlob());
+ }
+
+ @Override
+ public BackupDataResult exchangeDigitEnvelopeBaseOnRsa(ExchangeDigitEnvelopeRsaRequest request) {
+ ExchangeDigitEnvelopeRsaRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireNonEmptyBytes("publicKeyBlob", req.getPublicKeyBlob());
+ requireNonEmptyBytes("inputEnvelopeBlob", req.getInputEnvelopeBlob());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x52);
+ }
+
+ @Override
+ public BackupDataResult exchangeDigitEnvelopeBaseOnEcc(ExchangeDigitEnvelopeEccRequest request) {
+ ExchangeDigitEnvelopeEccRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requirePositive("algId", req.getAlgId());
+ requireNonEmptyBytes("publicKeyBlob", req.getPublicKeyBlob());
+ requireNonEmptyBytes("inputEnvelopeBlob", req.getInputEnvelopeBlob());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x57);
+ }
+
+ @Override
+ public AgreementDataAndKeyEccResult generateAgreementDataAndKeyWithEcc(GenerateAgreementDataAndKeyEccRequest request) {
+ GenerateAgreementDataAndKeyEccRequest req = requireRequest("request", request);
+ requireNonNegative("iskIndex", req.getIskIndex());
+ requirePositive("keyBits", req.getKeyBits());
+ requireNonEmptyBytes("responseId", req.getResponseId());
+ requireNonEmptyBytes("sponsorId", req.getSponsorId());
+ requireNonEmptyBytes("sponsorPublicKeyBlob", req.getSponsorPublicKeyBlob());
+ requireNonEmptyBytes("sponsorTmpPublicKeyBlob", req.getSponsorTmpPublicKeyBlob());
+ int responsePublicKeySize = requirePositive("responsePublicKeyBufferSize", req.getResponsePublicKeyBufferSize());
+ int responseTmpPublicKeySize = requirePositive("responseTmpPublicKeyBufferSize", req.getResponseTmpPublicKeyBufferSize());
+
+ BackupDataResult responsePublicKey = mockBackup(responsePublicKeySize, 0x58);
+ BackupDataResult responseTmpPublicKey = mockBackup(responseTmpPublicKeySize, 0x59);
+
+ AgreementDataAndKeyEccResult result = new AgreementDataAndKeyEccResult();
+ result.setResponsePublicKey(responsePublicKey.getData());
+ result.setResponsePublicKeyLength(responsePublicKey.getLength());
+ result.setResponseTmpPublicKey(responseTmpPublicKey.getData());
+ result.setResponseTmpPublicKeyLength(responseTmpPublicKey.getLength());
+ result.setSessionKeyGenerated(true);
+ return result;
+ }
+
+ @Override
+ public EccAgreementSessionKeyResult generateSessionKeyWithEccAgreement(EccAgreementSessionKeyRequest request) {
+ EccAgreementSessionKeyRequest req = requireRequest("request", request);
+ requireNonNegative("iskIndex", req.getIskIndex());
+ requirePositive("keyBits", req.getKeyBits());
+ requireNonEmptyBytes("sponsorId", req.getSponsorId());
+ requireNonEmptyBytes("responseId", req.getResponseId());
+ requireNonEmptyBytes("responsePublicKeyBlob", req.getResponsePublicKeyBlob());
+ requireNonEmptyBytes("responseTmpPublicKeyBlob", req.getResponseTmpPublicKeyBlob());
+ int sponsorPublicKeySize = requirePositive("sponsorPublicKeyBufferSize", req.getSponsorPublicKeyBufferSize());
+ int sponsorTmpPublicKeySize = requirePositive("sponsorTmpPublicKeyBufferSize", req.getSponsorTmpPublicKeyBufferSize());
+ int sessionKeySize = requirePositive("sessionKeyBufferSize", req.getSessionKeyBufferSize());
+
+ BackupDataResult sponsorPublicKey = mockBackup(sponsorPublicKeySize, 0x5A);
+ BackupDataResult sponsorTmpPublicKey = mockBackup(sponsorTmpPublicKeySize, 0x5B);
+ BackupDataResult sessionKey = mockBackup(sessionKeySize, 0x5C);
+
+ EccAgreementSessionKeyResult result = new EccAgreementSessionKeyResult();
+ result.setSponsorPublicKey(sponsorPublicKey.getData());
+ result.setSponsorPublicKeyLength(sponsorPublicKey.getLength());
+ result.setSponsorTmpPublicKey(sponsorTmpPublicKey.getData());
+ result.setSponsorTmpPublicKeyLength(sponsorTmpPublicKey.getLength());
+ result.setSessionKey(sessionKey.getData());
+ result.setSessionKeyLength(sessionKey.getLength());
+ result.setSessionKeyGenerated(true);
+ return result;
+ }
+
+ @Override
+ public BackupDataResult eccInternalSign(EccInternalSignRequest request) {
+ EccInternalSignRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireBytes("data", req.getData());
+ int size = requirePositive("signatureBufferSize", req.getSignatureBufferSize());
+ return mockBackup(size, 0x49);
+ }
+
+ @Override
+ public BackupDataResult eccExternalSign(EccExternalSignRequest request) {
+ EccExternalSignRequest req = requireRequest("request", request);
+ requirePositive("algId", req.getAlgId());
+ requireNonEmptyBytes("privateKeyBlob", req.getPrivateKeyBlob());
+ requireBytes("data", req.getData());
+ int size = requirePositive("signatureBufferSize", req.getSignatureBufferSize());
+ return mockBackup(size, 0x4F);
+ }
+
+ @Override
+ public void eccInternalVerify(EccInternalVerifyRequest request) {
+ EccInternalVerifyRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireBytes("data", req.getData());
+ requireNonEmptyBytes("signature", req.getSignature());
+ }
+
+ @Override
+ public void eccExternalVerify(EccExternalVerifyRequest request) {
+ EccExternalVerifyRequest req = requireRequest("request", request);
+ requirePositive("algId", req.getAlgId());
+ requireNonEmptyBytes("publicKeyBlob", req.getPublicKeyBlob());
+ requireBytes("data", req.getData());
+ requireNonEmptyBytes("signature", req.getSignature());
+ }
+
+ @Override
+ public BackupDataResult eccExternalEncrypt(EccExternalEncryptRequest request) {
+ EccExternalEncryptRequest req = requireRequest("request", request);
+ requirePositive("algId", req.getAlgId());
+ requireNonEmptyBytes("publicKeyBlob", req.getPublicKeyBlob());
+ requireBytes("data", req.getData());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x4A);
+ }
+
+ @Override
+ public BackupDataResult eccExternalDecrypt(EccExternalDecryptRequest request) {
+ EccExternalDecryptRequest req = requireRequest("request", request);
+ requirePositive("algId", req.getAlgId());
+ requireNonEmptyBytes("privateKeyBlob", req.getPrivateKeyBlob());
+ requireNonEmptyBytes("encryptedData", req.getEncryptedData());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x4B);
+ }
+
+ @Override
+ public BackupDataResult encryptWithPlainKey(SymmetricCryptoRequest request) {
+ SymmetricCryptoRequest req = requireRequest("request", request);
+ requirePositive("algId", req.getAlgId());
+ requireNonEmptyBytes("key", req.getKey());
+ byte[] data = requireBytes("data", req.getData());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, data.length);
+ }
+
+ @Override
+ public BackupDataResult decryptWithPlainKey(SymmetricCryptoRequest request) {
+ return encryptWithPlainKey(request);
+ }
+
+ @Override
+ public BackupDataResult encryptWithKekWrappedKey(SymmetricKekCryptoRequest request) {
+ SymmetricKekCryptoRequest req = requireRequest("request", request);
+ requirePositive("algId", req.getAlgId());
+ requireNonNegative("kekIndex", req.getKekIndex());
+ requireNonEmptyBytes("wrappedKey", req.getWrappedKey());
+ byte[] data = requireBytes("data", req.getData());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, data.length + req.getKekIndex());
+ }
+
+ @Override
+ public BackupDataResult decryptWithKekWrappedKey(SymmetricKekCryptoRequest request) {
+ return encryptWithKekWrappedKey(request);
+ }
+
+ @Override
+ public BackupDataResult calculateMacWithPlainKey(MacCalcRequest request) {
+ MacCalcRequest 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, 0x55);
+ }
+
+ @Override
+ public BackupDataResult digest(DigestRequest request) {
+ DigestRequest req = requireRequest("request", request);
+ requirePositive("algId", req.getAlgId());
+ requireBytes("data", req.getData());
+ int size = requirePositive("outBufferSize", req.getOutBufferSize());
+ return mockBackup(size, 0x77);
+ }
+
+ @Override
+ public HmacResult hmac(HmacRequest request) {
+ HmacRequest req = requireRequest("request", request);
+ requirePositive("algId", req.getAlgId());
+ byte[] key = requireNonEmptyBytes("key", req.getKey());
+ byte[] data = requireBytes("data", req.getData());
+
+ try {
+ Mac mac = Mac.getInstance("HmacSHA256");
+ mac.init(new SecretKeySpec(key, "HmacSHA256"));
+ byte[] hmac = mac.doFinal(data);
+ HmacResult result = new HmacResult();
+ result.setHmac(hmac);
+ result.setHmacLength(hmac.length);
+ return result;
+ } catch (Exception ex) {
+ throw new IllegalStateException("mock hmac failed", ex);
+ }
+ }
+
+ @Override
+ public void generateLmk() {
+ // no-op
+ }
+
+ @Override
+ public void loadLmk() {
+ // no-op
+ }
+
+ @Override
+ public void backupLmk() {
+ // no-op
+ }
+
+ @Override
+ public void recoverLmk() {
+ // no-op
+ }
+
+ @Override
+ public void destroyLmk() {
+ // no-op
+ }
+
+ @Override
+ public void checkLmk() {
+ // no-op
+ }
+
+ @Override
+ public byte[] exportLmkSeedMac() {
+ return new byte[8];
+ }
+
+ @Override
+ public BackupDataResult backupLmkEx(int outBufferSize) {
+ int size = requirePositive("outBufferSize", outBufferSize);
+ return mockBackup(size, 0x11);
+ }
+
+ @Override
+ public void recoverLmkEx(byte[] lmkComponent) {
+ requireNonEmptyBytes("lmkComponent", lmkComponent);
+ }
+
+ @Override
+ public void generateIk(int keyType) {
+ requireNonNegative("keyType", keyType);
+ }
+
+ @Override
+ public void backupIk(int keyType) {
+ requireNonNegative("keyType", keyType);
+ }
+
+ @Override
+ public void recoverIk(int keyType) {
+ requireNonNegative("keyType", keyType);
+ }
+
+ @Override
+ public void destroyIk(int keyType) {
+ requireNonNegative("keyType", keyType);
+ }
+
+ @Override
+ public KeyStatusResult statusIk(int keyType) {
+ requireNonNegative("keyType", keyType);
+ return keyStatus(PcieKeyState.RIGHT);
+ }
+
+ @Override
+ public void generateUkey(UkeyGenerateRequest request) {
+ UkeyGenerateRequest req = requireRequest("request", request);
+ requireByteRange("adminIndex", req.getAdminIndex());
+ requireNonEmptyBytes("ukeyPin", req.getUkeyPin());
+ requireNonEmptyBytes("loginPin", req.getLoginPin());
+ }
+
+ @Override
+ public void loginUkey(UkeyLoginRequest request) {
+ UkeyLoginRequest req = requireRequest("request", request);
+ requireNonEmptyBytes("ukeyPin", req.getUkeyPin());
+ requireNonEmptyBytes("loginPin", req.getLoginPin());
+ }
+
+ @Override
+ public void changeUkeyPin(UkeyPinChangeRequest request) {
+ UkeyPinChangeRequest req = requireRequest("request", request);
+ requireNonNegative("pinType", req.getPinType());
+ requireNonEmptyBytes("oldPin", req.getOldPin());
+ requireNonEmptyBytes("newPin", req.getNewPin());
+ }
+
+ @Override
+ public void unlockUkey(UkeyUnlockRequest request) {
+ UkeyUnlockRequest req = requireRequest("request", request);
+ requireNonEmptyBytes("adminPin", req.getAdminPin());
+ requireNonEmptyBytes("userPin", req.getUserPin());
+ }
+
+ @Override
+ public void readLmkComponent(byte[] ukeyPin) {
+ requireNonEmptyBytes("ukeyPin", ukeyPin);
+ }
+
+ @Override
+ public void readUkeyIkComponent(int keyType, byte[] ukeyPin) {
+ requireNonNegative("keyType", keyType);
+ requireNonEmptyBytes("ukeyPin", ukeyPin);
+ }
+
+ @Override
+ public void generateCertificate(byte[] ukeyPin) {
+ requireNonEmptyBytes("ukeyPin", ukeyPin);
+ }
+
+ @Override
+ public void logoutAdmin(int adminIndex) {
+ requireByteRange("adminIndex", adminIndex);
+ }
+
+ @Override
+ public LoginStatusResult loginStatus() {
+ return new LoginStatusResult();
+ }
+
+ @Override
+ public void createFile(FileCreateRequest request) {
+ FileCreateRequest req = requireRequest("request", request);
+ requireNonBlank("fileName", req.getFileName());
+ requirePositive("fileSize", req.getFileSize());
+ }
+
+ @Override
+ public void writeFile(FileWriteRequest request) {
+ FileWriteRequest req = requireRequest("request", request);
+ requireNonBlank("fileName", req.getFileName());
+ requireNonNegative("offset", req.getOffset());
+ requireBytes("data", req.getData());
+ }
+
+ @Override
+ public BackupDataResult readFile(FileReadRequest request) {
+ FileReadRequest req = requireRequest("request", request);
+ requireNonBlank("fileName", req.getFileName());
+ requireNonNegative("offset", req.getOffset());
+ int size = requirePositive("readLength", req.getReadLength());
+ return mockBackup(size, req.getOffset());
+ }
+
+ @Override
+ public void deleteFile(String fileName) {
+ requireNonBlank("fileName", fileName);
+ }
+
+ private static void validateImportKeyPair(ImportKeyPairRequest request) {
+ ImportKeyPairRequest req = requireRequest("request", request);
+ requireNonNegative("keyIndex", req.getKeyIndex());
+ requireUserKeyType(req.getKeyType());
+ requireNonEmptyBytes("publicKey", req.getPublicKey());
+ requireNonEmptyBytes("privateKey", req.getPrivateKey());
+ }
+
+ private static KeyStatusResult keyStatus(PcieKeyState state) {
+ KeyStatusResult result = new KeyStatusResult();
+ result.setKeyState(state.getCode());
+ result.setKeyStateName(state.name());
+ return result;
+ }
+
+ private static StandardKeyPairResult mockStandardKeyPair(int publicKeySize, int privateKeySize, int publicSeed, int privateSeed) {
+ BackupDataResult publicPart = mockBackup(publicKeySize, publicSeed);
+ BackupDataResult privatePart = mockBackup(privateKeySize, privateSeed);
+
+ StandardKeyPairResult result = new StandardKeyPairResult();
+ result.setPublicKey(publicPart.getData());
+ result.setPublicKeyLength(publicPart.getLength());
+ result.setPrivateKey(privatePart.getData());
+ result.setPrivateKeyLength(privatePart.getLength());
+ return result;
+ }
+
+ private static BackupDataResult mockBackup(int outBufferSize, int seed) {
+ int length = Math.min(outBufferSize, 32);
+ byte[] data = new byte[length];
+ Arrays.fill(data, (byte) (seed & 0xFF));
+
+ BackupDataResult result = new BackupDataResult();
+ result.setData(data);
+ result.setLength(length);
+ return result;
+ }
+
+ private static int requireUserKeyType(int keyType) {
+ if (keyType != PcieUserKeyType.SIGN.getCode() && keyType != PcieUserKeyType.ENC.getCode()) {
+ throw new IllegalArgumentException("keyType must be 0(SIGN) or 1(ENC)");
+ }
+ return keyType;
+ }
+
+ private static int requirePositive(String name, int value) {
+ if (value <= 0) {
+ throw new IllegalArgumentException(name + " must be > 0");
+ }
+ return value;
+ }
+
+ private static int requireNonNegative(String name, int value) {
+ if (value < 0) {
+ throw new IllegalArgumentException(name + " must be >= 0");
+ }
+ return value;
+ }
+
+ private static int requireByteRange(String name, int value) {
+ if (value < 0 || value > 255) {
+ throw new IllegalArgumentException(name + " must be in [0,255]");
+ }
+ return value;
+ }
+
+ private static byte[] requireNonEmptyBytes(String name, byte[] value) {
+ if (value == null || value.length == 0) {
+ throw new IllegalArgumentException(name + " must not be empty");
+ }
+ return value;
+ }
+
+ private static byte[] requireBytes(String name, byte[] value) {
+ if (value == null) {
+ throw new IllegalArgumentException(name + " must not be null");
+ }
+ return value;
+ }
+
+ private static String requireNonBlank(String name, String value) {
+ if (value == null || value.isBlank()) {
+ throw new IllegalArgumentException(name + " must not be blank");
+ }
+ return value;
+ }
+
+ private static T requireRequest(String name, T request) {
+ if (request == null) {
+ throw new IllegalArgumentException(name + " must not be null");
+ }
+ return request;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/service/PcieCryptoService.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/service/PcieCryptoService.java
new file mode 100644
index 0000000..84d53f1
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/service/PcieCryptoService.java
@@ -0,0 +1,251 @@
+package com.cisd.tms.integration.crypto.pcie.service;
+
+import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult;
+import com.cisd.tms.integration.crypto.pcie.model.AgreementDataAndKeyEccResult;
+import com.cisd.tms.integration.crypto.pcie.model.ChangePrivateKeyPasswordRequest;
+import com.cisd.tms.integration.crypto.pcie.model.DeviceConfResult;
+import com.cisd.tms.integration.crypto.pcie.model.DeviceCountResult;
+import com.cisd.tms.integration.crypto.pcie.model.DeviceInfoResult;
+import com.cisd.tms.integration.crypto.pcie.model.DeviceStatusResult;
+import com.cisd.tms.integration.crypto.pcie.model.DigestRequest;
+import com.cisd.tms.integration.crypto.pcie.model.EccExternalDecryptRequest;
+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.EccAgreementSessionKeyRequest;
+import com.cisd.tms.integration.crypto.pcie.model.EccAgreementSessionKeyResult;
+import com.cisd.tms.integration.crypto.pcie.model.EccExternalVerifyRequest;
+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.ExchangeDigitEnvelopeEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ExchangeDigitEnvelopeRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ExportKekComponentRequest;
+import com.cisd.tms.integration.crypto.pcie.model.FileCreateRequest;
+import com.cisd.tms.integration.crypto.pcie.model.FileReadRequest;
+import com.cisd.tms.integration.crypto.pcie.model.FileWriteRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKekRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateAgreementDataAndKeyEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateStandardEccKeyPairRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateStandardRsaKeyPairRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithEpkEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithEpkRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithIpkEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithIpkRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithKekRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyPairRequest;
+import com.cisd.tms.integration.crypto.pcie.model.HmacRequest;
+import com.cisd.tms.integration.crypto.pcie.model.HmacResult;
+import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportKekRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ImportKeyPairRequest;
+import com.cisd.tms.integration.crypto.pcie.model.KekComponentRequest;
+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.MacCalcRequest;
+import com.cisd.tms.integration.crypto.pcie.model.PrivateKeyAccessRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RecoverKekRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RecoverUserKeyRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RsaExternalPrivateKeyOpRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RsaExternalPublicKeyOpRequest;
+import com.cisd.tms.integration.crypto.pcie.model.RsaInternalKeyOpRequest;
+import com.cisd.tms.integration.crypto.pcie.model.SymmetricCryptoRequest;
+import com.cisd.tms.integration.crypto.pcie.model.SymmetricKekCryptoRequest;
+import com.cisd.tms.integration.crypto.pcie.model.StandardKeyPairResult;
+import com.cisd.tms.integration.crypto.pcie.model.UkeyGenerateRequest;
+import com.cisd.tms.integration.crypto.pcie.model.UkeyLoginRequest;
+import com.cisd.tms.integration.crypto.pcie.model.UkeyPinChangeRequest;
+import com.cisd.tms.integration.crypto.pcie.model.UkeyUnlockRequest;
+import com.cisd.tms.integration.crypto.pcie.model.UpdateBackedKeyRequest;
+
+public interface PcieCryptoService {
+
+ DeviceCountResult getDeviceCount();
+
+ DeviceConfResult getDeviceConf();
+
+ DeviceInfoResult getDeviceInfo();
+
+ byte[] generateRandom(int length);
+
+ void initIdentify(byte[] oldPin, byte[] newPin);
+
+ void deviceSelfTest();
+
+ DeviceStatusResult getDeviceStatus(int statusBufferSize);
+
+ void deviceFactoryReset();
+
+ void changePrivateKeyAccessPassword(ChangePrivateKeyPasswordRequest request);
+
+ void getPrivateKeyAccessRight(PrivateKeyAccessRequest request);
+
+ void releasePrivateKeyAccessRight(int keyIndex);
+
+ void generateKeyPairEcc(GenerateKeyPairRequest request);
+
+ void generateKeyPairRsa(GenerateKeyPairRequest request);
+
+ void importKeyPairEcc(ImportKeyPairRequest request);
+
+ void importKeyPairRsa(ImportKeyPairRequest request);
+
+ void generateKek(GenerateKekRequest request);
+
+ void importKek(ImportKekRequest request);
+
+ void importKekComponent(KekComponentRequest request);
+
+ BackupDataResult exportKekComponent(ExportKekComponentRequest request);
+
+ BackupDataResult backupUserKey(int keyIndex, int keyType, int outBufferSize);
+
+ void recoverUserKey(RecoverUserKeyRequest request);
+
+ BackupDataResult backupKek(int keyIndex, int outBufferSize);
+
+ void recoverKek(RecoverKekRequest request);
+
+ void deleteUserKey(int keyIndex);
+
+ void deleteKek(int keyIndex);
+
+ BackupDataResult backupAllKey(int outBufferSize);
+
+ void restoreAllKey(byte[] keyImage);
+
+ KeyStatusResult statusUserKeyEcc(int keyIndex, int keyType);
+
+ KeyStatusResult statusUserKeyRsa(int keyIndex, int keyType);
+
+ KeyStatusResult statusKek(int keyIndex);
+
+ void importEncryptedKeyPairEcc(ImportEncKeyPairEccRequest request);
+
+ void importEncryptedKeyPairRsa(ImportEncKeyPairRsaRequest request);
+
+ BackupDataResult updateBackedKey(UpdateBackedKeyRequest request);
+
+ BackupDataResult exportSignPublicKeyRsa(int keyIndex, int outBufferSize);
+
+ BackupDataResult exportEncPublicKeyRsa(int keyIndex, int outBufferSize);
+
+ BackupDataResult exportSignPublicKeyEcc(int keyIndex, int outBufferSize);
+
+ BackupDataResult exportEncPublicKeyEcc(int keyIndex, int outBufferSize);
+
+ StandardKeyPairResult generateStandardRsaKeyPair(GenerateStandardRsaKeyPairRequest request);
+
+ StandardKeyPairResult generateStandardEccKeyPair(GenerateStandardEccKeyPairRequest request);
+
+ BackupDataResult generateKeyWithKek(GenerateKeyWithKekRequest request);
+
+ BackupDataResult rsaExternalPublicKeyOperation(RsaExternalPublicKeyOpRequest request);
+
+ BackupDataResult rsaExternalPrivateKeyOperation(RsaExternalPrivateKeyOpRequest request);
+
+ BackupDataResult rsaInternalPublicKeyOperation(RsaInternalKeyOpRequest request);
+
+ BackupDataResult rsaInternalPrivateKeyOperation(RsaInternalKeyOpRequest request);
+
+ BackupDataResult generateKeyWithIpkRsa(GenerateKeyWithIpkRsaRequest request);
+
+ BackupDataResult generateKeyWithEpkRsa(GenerateKeyWithEpkRsaRequest request);
+
+ void importKeyWithIskRsa(ImportKeyWithIskRsaRequest request);
+
+ BackupDataResult generateKeyWithIpkEcc(GenerateKeyWithIpkEccRequest request);
+
+ BackupDataResult generateKeyWithEpkEcc(GenerateKeyWithEpkEccRequest request);
+
+ void importKeyWithIskEcc(ImportKeyWithIskEccRequest request);
+
+ BackupDataResult exchangeDigitEnvelopeBaseOnRsa(ExchangeDigitEnvelopeRsaRequest request);
+
+ BackupDataResult exchangeDigitEnvelopeBaseOnEcc(ExchangeDigitEnvelopeEccRequest request);
+
+ AgreementDataAndKeyEccResult generateAgreementDataAndKeyWithEcc(GenerateAgreementDataAndKeyEccRequest request);
+
+ EccAgreementSessionKeyResult generateSessionKeyWithEccAgreement(EccAgreementSessionKeyRequest request);
+
+ BackupDataResult eccInternalSign(EccInternalSignRequest request);
+
+ BackupDataResult eccExternalSign(EccExternalSignRequest request);
+
+ void eccInternalVerify(EccInternalVerifyRequest request);
+
+ void eccExternalVerify(EccExternalVerifyRequest request);
+
+ BackupDataResult eccExternalEncrypt(EccExternalEncryptRequest request);
+
+ BackupDataResult eccExternalDecrypt(EccExternalDecryptRequest request);
+
+ BackupDataResult encryptWithPlainKey(SymmetricCryptoRequest request);
+
+ BackupDataResult decryptWithPlainKey(SymmetricCryptoRequest request);
+
+ BackupDataResult encryptWithKekWrappedKey(SymmetricKekCryptoRequest request);
+
+ BackupDataResult decryptWithKekWrappedKey(SymmetricKekCryptoRequest request);
+
+ BackupDataResult calculateMacWithPlainKey(MacCalcRequest request);
+
+ BackupDataResult digest(DigestRequest request);
+
+ HmacResult hmac(HmacRequest request);
+
+ void generateLmk();
+
+ void loadLmk();
+
+ void backupLmk();
+
+ void recoverLmk();
+
+ void destroyLmk();
+
+ void checkLmk();
+
+ byte[] exportLmkSeedMac();
+
+ BackupDataResult backupLmkEx(int outBufferSize);
+
+ void recoverLmkEx(byte[] lmkComponent);
+
+ void generateIk(int keyType);
+
+ void backupIk(int keyType);
+
+ void recoverIk(int keyType);
+
+ void destroyIk(int keyType);
+
+ KeyStatusResult statusIk(int keyType);
+
+ void generateUkey(UkeyGenerateRequest request);
+
+ void loginUkey(UkeyLoginRequest request);
+
+ void changeUkeyPin(UkeyPinChangeRequest request);
+
+ void unlockUkey(UkeyUnlockRequest request);
+
+ void readLmkComponent(byte[] ukeyPin);
+
+ void readUkeyIkComponent(int keyType, byte[] ukeyPin);
+
+ void generateCertificate(byte[] ukeyPin);
+
+ void logoutAdmin(int adminIndex);
+
+ LoginStatusResult loginStatus();
+
+ void createFile(FileCreateRequest request);
+
+ void writeFile(FileWriteRequest request);
+
+ BackupDataResult readFile(FileReadRequest request);
+
+ void deleteFile(String fileName);
+}
diff --git a/src/main/java/com/cisd/tms/integration/file/package-info.java b/src/main/java/com/cisd/tms/integration/file/package-info.java
new file mode 100644
index 0000000..58c1185
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/file/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * file integration adapters.
+ */
+package com.cisd.tms.integration.file;
diff --git a/src/main/java/com/cisd/tms/integration/mq/package-info.java b/src/main/java/com/cisd/tms/integration/mq/package-info.java
new file mode 100644
index 0000000..2467160
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/mq/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * mq integration adapters.
+ */
+package com.cisd.tms.integration.mq;
diff --git a/src/main/java/com/cisd/tms/integration/package-info.java b/src/main/java/com/cisd/tms/integration/package-info.java
new file mode 100644
index 0000000..fe673dd
--- /dev/null
+++ b/src/main/java/com/cisd/tms/integration/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * External integrations (CIPS scripts, MQ, crypto devices, filesystem adapters).
+ */
+package com.cisd.tms.integration;
diff --git a/src/main/java/com/cisd/tms/modules/activation/package-info.java b/src/main/java/com/cisd/tms/modules/activation/package-info.java
new file mode 100644
index 0000000..368a56d
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/activation/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * activation module.
+ */
+package com.cisd.tms.modules.activation;
diff --git a/src/main/java/com/cisd/tms/modules/audit/package-info.java b/src/main/java/com/cisd/tms/modules/audit/package-info.java
new file mode 100644
index 0000000..703d507
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/audit/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * audit module.
+ */
+package com.cisd.tms.modules.audit;
diff --git a/src/main/java/com/cisd/tms/modules/auth/controller/AuthInternalController.java b/src/main/java/com/cisd/tms/modules/auth/controller/AuthInternalController.java
new file mode 100644
index 0000000..3e13acb
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/auth/controller/AuthInternalController.java
@@ -0,0 +1,35 @@
+package com.cisd.tms.modules.auth.controller;
+
+import com.cisd.tms.common.api.ApiResponse;
+import com.cisd.tms.modules.auth.dto.CurrentUserResponse;
+import com.cisd.tms.modules.auth.dto.LoginRequest;
+import com.cisd.tms.modules.auth.dto.LoginResponse;
+import com.cisd.tms.modules.auth.service.AuthService;
+import jakarta.validation.Valid;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/api/v1/auth")
+public class AuthInternalController {
+
+ private final AuthService authService;
+
+ public AuthInternalController(AuthService authService) {
+ this.authService = authService;
+ }
+
+ @PostMapping("/login")
+ public ApiResponse login(@Valid @RequestBody LoginRequest request) {
+ return ApiResponse.success(authService.login(request));
+ }
+
+ @GetMapping("/me")
+ public ApiResponse me(@RequestHeader(value = "X-User", required = false) String user) {
+ return ApiResponse.success(authService.me(user));
+ }
+}
diff --git a/src/main/java/com/cisd/tms/modules/auth/dto/CurrentUserResponse.java b/src/main/java/com/cisd/tms/modules/auth/dto/CurrentUserResponse.java
new file mode 100644
index 0000000..976a6bf
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/auth/dto/CurrentUserResponse.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.modules.auth.dto;
+
+public class CurrentUserResponse {
+
+ private String username;
+ private String displayName;
+ private String role;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/modules/auth/dto/LoginRequest.java b/src/main/java/com/cisd/tms/modules/auth/dto/LoginRequest.java
new file mode 100644
index 0000000..da97d99
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/auth/dto/LoginRequest.java
@@ -0,0 +1,28 @@
+package com.cisd.tms.modules.auth.dto;
+
+import jakarta.validation.constraints.NotBlank;
+
+public class LoginRequest {
+
+ @NotBlank(message = "username is required")
+ private String username;
+
+ @NotBlank(message = "password is required")
+ private String password;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/modules/auth/dto/LoginResponse.java b/src/main/java/com/cisd/tms/modules/auth/dto/LoginResponse.java
new file mode 100644
index 0000000..1341d1f
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/auth/dto/LoginResponse.java
@@ -0,0 +1,32 @@
+package com.cisd.tms.modules.auth.dto;
+
+public class LoginResponse {
+
+ private String username;
+ private String token;
+ private String expiresAt;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ public String getExpiresAt() {
+ return expiresAt;
+ }
+
+ public void setExpiresAt(String expiresAt) {
+ this.expiresAt = expiresAt;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/modules/auth/entity/AuthUserEntity.java b/src/main/java/com/cisd/tms/modules/auth/entity/AuthUserEntity.java
new file mode 100644
index 0000000..1affcd4
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/auth/entity/AuthUserEntity.java
@@ -0,0 +1,36 @@
+package com.cisd.tms.modules.auth.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.cisd.tms.infrastructure.persistence.entity.BaseEntity;
+
+@TableName("tms_auth_user")
+public class AuthUserEntity extends BaseEntity {
+
+ private String username;
+ private String displayName;
+ private String role;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/modules/auth/mapper/AuthUserMapper.java b/src/main/java/com/cisd/tms/modules/auth/mapper/AuthUserMapper.java
new file mode 100644
index 0000000..de266ec
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/auth/mapper/AuthUserMapper.java
@@ -0,0 +1,12 @@
+package com.cisd.tms.modules.auth.mapper;
+
+import com.cisd.tms.infrastructure.persistence.mapper.BaseMapperX;
+import com.cisd.tms.modules.auth.entity.AuthUserEntity;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+@Mapper
+public interface AuthUserMapper extends BaseMapperX {
+
+ AuthUserEntity selectByUsername(@Param("username") String username);
+}
diff --git a/src/main/java/com/cisd/tms/modules/auth/package-info.java b/src/main/java/com/cisd/tms/modules/auth/package-info.java
new file mode 100644
index 0000000..bfa1e5a
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/auth/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * auth module.
+ */
+package com.cisd.tms.modules.auth;
diff --git a/src/main/java/com/cisd/tms/modules/auth/repository/AuthUserRepository.java b/src/main/java/com/cisd/tms/modules/auth/repository/AuthUserRepository.java
new file mode 100644
index 0000000..ae4ca8b
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/auth/repository/AuthUserRepository.java
@@ -0,0 +1,9 @@
+package com.cisd.tms.modules.auth.repository;
+
+import com.cisd.tms.modules.auth.entity.AuthUserEntity;
+import java.util.Optional;
+
+public interface AuthUserRepository {
+
+ Optional findByUsername(String username);
+}
diff --git a/src/main/java/com/cisd/tms/modules/auth/repository/impl/AuthUserRepositoryImpl.java b/src/main/java/com/cisd/tms/modules/auth/repository/impl/AuthUserRepositoryImpl.java
new file mode 100644
index 0000000..b7645b0
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/auth/repository/impl/AuthUserRepositoryImpl.java
@@ -0,0 +1,22 @@
+package com.cisd.tms.modules.auth.repository.impl;
+
+import com.cisd.tms.modules.auth.entity.AuthUserEntity;
+import com.cisd.tms.modules.auth.mapper.AuthUserMapper;
+import com.cisd.tms.modules.auth.repository.AuthUserRepository;
+import java.util.Optional;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class AuthUserRepositoryImpl implements AuthUserRepository {
+
+ private final AuthUserMapper authUserMapper;
+
+ public AuthUserRepositoryImpl(AuthUserMapper authUserMapper) {
+ this.authUserMapper = authUserMapper;
+ }
+
+ @Override
+ public Optional findByUsername(String username) {
+ return Optional.ofNullable(authUserMapper.selectByUsername(username));
+ }
+}
diff --git a/src/main/java/com/cisd/tms/modules/auth/service/AuthService.java b/src/main/java/com/cisd/tms/modules/auth/service/AuthService.java
new file mode 100644
index 0000000..32ae517
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/auth/service/AuthService.java
@@ -0,0 +1,46 @@
+package com.cisd.tms.modules.auth.service;
+
+import com.cisd.tms.modules.auth.dto.CurrentUserResponse;
+import com.cisd.tms.modules.auth.dto.LoginRequest;
+import com.cisd.tms.modules.auth.dto.LoginResponse;
+import com.cisd.tms.modules.auth.entity.AuthUserEntity;
+import com.cisd.tms.modules.auth.repository.AuthUserRepository;
+import java.time.OffsetDateTime;
+import java.util.UUID;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AuthService {
+
+ private final AuthUserRepository authUserRepository;
+
+ public AuthService(AuthUserRepository authUserRepository) {
+ this.authUserRepository = authUserRepository;
+ }
+
+ public LoginResponse login(LoginRequest request) {
+ LoginResponse response = new LoginResponse();
+ response.setUsername(request.getUsername());
+ response.setToken("tms-" + UUID.randomUUID());
+ response.setExpiresAt(OffsetDateTime.now().plusHours(8).toString());
+ return response;
+ }
+
+ public CurrentUserResponse me(String username) {
+ String normalized = username == null || username.isBlank() ? "admin" : username;
+ AuthUserEntity entity = authUserRepository.findByUsername(normalized).orElse(null);
+
+ CurrentUserResponse response = new CurrentUserResponse();
+ if (entity == null) {
+ response.setUsername(normalized);
+ response.setDisplayName("TMS Administrator");
+ response.setRole("ADMIN");
+ return response;
+ }
+
+ response.setUsername(entity.getUsername());
+ response.setDisplayName(entity.getDisplayName());
+ response.setRole(entity.getRole());
+ return response;
+ }
+}
diff --git a/src/main/java/com/cisd/tms/modules/backup/package-info.java b/src/main/java/com/cisd/tms/modules/backup/package-info.java
new file mode 100644
index 0000000..30a2c5b
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/backup/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * backup module.
+ */
+package com.cisd.tms.modules.backup;
diff --git a/src/main/java/com/cisd/tms/modules/cert/package-info.java b/src/main/java/com/cisd/tms/modules/cert/package-info.java
new file mode 100644
index 0000000..c339fb4
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/cert/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * cert module.
+ */
+package com.cisd.tms.modules.cert;
diff --git a/src/main/java/com/cisd/tms/modules/device/controller/CryptoCardInternalController.java b/src/main/java/com/cisd/tms/modules/device/controller/CryptoCardInternalController.java
new file mode 100644
index 0000000..2da8d49
--- /dev/null
+++ b/src/main/java/com/cisd/tms/modules/device/controller/CryptoCardInternalController.java
@@ -0,0 +1,1142 @@
+package com.cisd.tms.modules.device.controller;
+
+import com.cisd.tms.common.api.ApiResponse;
+import com.cisd.tms.integration.crypto.pcie.model.AgreementDataAndKeyEccResult;
+import com.cisd.tms.integration.crypto.pcie.model.DeviceConfResult;
+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.DigestRequest;
+import com.cisd.tms.integration.crypto.pcie.model.EccAgreementSessionKeyRequest;
+import com.cisd.tms.integration.crypto.pcie.model.EccAgreementSessionKeyResult;
+import com.cisd.tms.integration.crypto.pcie.model.ExchangeDigitEnvelopeEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.ExchangeDigitEnvelopeRsaRequest;
+import com.cisd.tms.integration.crypto.pcie.model.FileCreateRequest;
+import com.cisd.tms.integration.crypto.pcie.model.FileReadRequest;
+import com.cisd.tms.integration.crypto.pcie.model.FileWriteRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateAgreementDataAndKeyEccRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateKekRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateStandardEccKeyPairRequest;
+import com.cisd.tms.integration.crypto.pcie.model.GenerateStandardRsaKeyPairRequest;
+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.KeyStatusResult;
+import com.cisd.tms.integration.crypto.pcie.model.MacCalcRequest;
+import com.cisd.tms.integration.crypto.pcie.model.SymmetricCryptoRequest;
+import com.cisd.tms.integration.crypto.pcie.model.SymmetricKekCryptoRequest;
+import com.cisd.tms.integration.crypto.pcie.model.StandardKeyPairResult;
+import com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.Min;
+import jakarta.validation.constraints.NotBlank;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Map;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@Validated
+@RestController
+@RequestMapping("/api/v1/device/crypto")
+public class CryptoCardInternalController {
+
+ private final PcieCryptoService pcieCryptoService;
+
+ public CryptoCardInternalController(PcieCryptoService pcieCryptoService) {
+ this.pcieCryptoService = pcieCryptoService;
+ }
+
+ @GetMapping("/device-count")
+ public ApiResponse getDeviceCount() {
+ return ApiResponse.success(pcieCryptoService.getDeviceCount());
+ }
+
+ @GetMapping("/device-conf")
+ public ApiResponse getDeviceConf() {
+ return ApiResponse.success(pcieCryptoService.getDeviceConf());
+ }
+
+ @GetMapping("/device-info")
+ public ApiResponse getDeviceInfo() {
+ return ApiResponse.success(pcieCryptoService.getDeviceInfo());
+ }
+
+ @GetMapping("/random")
+ public ApiResponse