public interface SecureChannelService extends CSPService
Provides secure messaging and authentication services.
init(..)
method initializes the service with cryptographic resources.processSecurity(..)
method manages the protocol, processes incoming APDUs and creates response APDUs.getSecurityState(..)
method to retrieve the current protocol-specific security state of the secure channel.wrap(..)
method applies session encryption to the message.unwrap(..)
method removes session encryption.updateWrap(..)
updateUnwrap(..)
methods process multiple data chunks for wrapping and unwrapping.
Secure messaging algorithms must be pre-configured by the CSP Admin and cannot be selected via the CSP-API.
Supported algorithms are defined in Section 6.4.1 of GlobalPlatform Amendment N [GPC_SPE_230] and may include:
Protocol | Value (Hex) | Description | APDU Definition |
PROTOCOL_PACE | 0x11 | PACE standalone | TR-03110-3 |
PROTOCOL_EAC_ID | 0x12 | PACE, TA2, CA2/CA3 | TR-03110-3 |
PROTOCOL_EAC_MRTD | 0x13 | PACE, CA1, TA1 | ICAO 9303-11 or TR-03110-3 |
PROTOCOL_PACE_CAM | 0x14 | PACE, CA1, TA1 optimized | ICAO 9303-11 or TR-03110-3 |
PROTOCOL_SCP03 | 0x05 | AES-based | GP AMD D SCP03 |
PROTOCOL_SCP04 | 0x15 | AES-based configurable | GP AMD K SCP04 |
The key, certificate and password resources must be configured by the CSP Admin. Their resource identifiers,
assigned during creation, must then be used to initialize the service via the init(..)
method.
For details on admin commands of the CSP-Protocol, see Chapter 7 of GlobalPlatform Amendment N [GPC_SPE_230].
Below are pseudo admin command examples using CSP-Protocol ASN.1 types.
// Create PACE PIN resource and import it. CSPCreateResource(PACE_PIN_ID, PASSWORD_NUMERIC, minSize=5, maxSize=5) CSPSetValue(PACE_PIN_ID, data) // Create TA Certificate resource and import it. CSPCreateResource(TA_AT_CERT_ID, CERT_CVC) CSPSetValue(TA_AT_CERT_ID, data) CSPCreateResource(TA_AT_LINKED_CERT_ID, CERT_CVC) CSPSetValue(TA_AT_LINKED_CERT_ID, data) // Create CA Key resource and generate it. CSPCreateResource(CA2_KEY_ID, KEY_ECC_PRIVATE, CURVE_BRAINPOOL_P256_R1) CSPCreateResource(CA2_KEY_ID_PUBLIC, KEY_ECC_PUBLIC, CURVE_BRAINPOOL_P256_R1) CSPGenerateKey(CA2_KEY_ID) CSPComputePublicKey(CA2_KEY_ID, CA2_KEY_ID_PUBLIC) // Configure access control. CSPConfigureResource(PACE_PIN_ID, ACR_USE & ACR_SETUP) CSPConfigureResource(TA_AT_CERT_ID, ACR_CLEAR & ACR_SETUP & ACR_USE) CSPConfigureResource(TA_AT_LINKED_CERT_ID, ACR_CLEAR & ACR_SETUP & ACR_USE) CSPConfigureResource(CA2_KEY_ID, ACR_USE) // Configure usage and algorithms. CSPConfigureResource(PACE_PIN_ID, USAGE_SECCHANNEL, SEC_PACE) CSPConfigureResource(TA_AT_CERT_ID, USAGE_SECCHANNEL, SEC_TA2) CSPConfigureResource(TA_AT_LINKED_CERT_ID, USAGE_SECCHANNEL, SEC_TA2_LINKED) CSPConfigureResource(CA2_KEY_ID, USAGE_SECCHANNEL, SEC_CA2)
Sample code for using the SecureChannelService
:
// Retrieve CSP Shareable Instance. AID cspAID = JCSystem.lookupAID(CSP_AID_DATA, (short) 0, (byte) CSP_AID_DATA.length); GlobalService cspGlobalService = GPSystem.getService(cspAID, CSP.GLOBAL_SERVICE_ID_CSP); AID clientAID = JCSystem.getAID(); GPRegistryEntry clientRegistryEntry = GPSystem.getRegistryEntry(clientAID); CSP csp = (CSP) cspGlobalService.getServiceInterface(clientRegistryEntry, CSP.DEFAULT_SERVICE_ID, null, (short) 0, (short) 0); // Init service. SecureChannelService secChannelService = csp.makeSecureChannelService(SecureChannelService.PROTOCOL_EAC_ID); secChannelService.init(PACE_PIN_ID); secChannelService.init(PACE_PUK_ID); secChannelService.init(PACE_CAN_ID); secChannelService.init(TA_AT_CERT_ID); secChannelService.init(CA2_KEY_ID); secChannelService.init(CA2_PRIVILEGED_KEY_ID); secChannelService.init(CA3_KEY_ID); secChannelService.init(CA3_PSA_KEY_ID); secChannelService.init(TA_DV_CERT_ID); secChannelService.init(TA_TERMINAL_CERT_ID); secChannelService.init(TA_AT_LINKED_CERT_ID); switch (ins) { // Process PACE, TA2 & CA2 authentication. case INS_AUTHENTICATE: // Remove session encryption from incoming APDU. secChannelService.initUnwrap(); apduLen = secChannelService.unwrap(inputBuffer, (short) 0, inputLen, apduData, (short) 0); secChannelService.assertSensitiveResult(apduLen); // Process the authentication and create the response APDU. responseLen = secChannelService.processSecurity(apduData, (short) 0, apduLen, responseAPDU, (short) 0); SensitiveArrays.assertIntegrity(responseAPDU); // Add session encryption to the response APDU. outputLen = secChannelService.initWrap(responseLen); secChannelService.wrap(responseAPDU, (short) 0, responseLen, outputBuffer, (short) 0); secChannelService.assertSensitiveResult(outputLen); // Process the encrypted APDU response ... SensitiveArrays.assertIntegrity(outputBuffer); break; // Reset the secure channel session. case INS_TERMINATE: secChannelService.resetSecurity(); break; // Process secure messaging. case INS_ECHO: // Unwrap incoming data. secChannelService.initUnwrap(); requestLen = secChannelService.unwrap(inputBuffer, (short) 0, inputLen, requestBuffer, (short) 0); secChannelService.assertSensitiveResult(requestLen); // Create response 'echo: <<input>>'. responseLen = (short) (requestLen + 6); responseBuffer[0] = (byte) responseLen; responseBuffer[1] = 'e'; responseBuffer[2] = 'c'; responseBuffer[3] = 'h'; responseBuffer[4] = 'o'; responseBuffer[5] = ':'; Util.arrayCopy(requestBuffer, (short) 0, responseBuffer, (short) 6, requestLen); SensitiveArrays.assertIntegrity(requestBuffer); // Wrap the outgoing data. outputLen = secChannelService.initWrap(responseLen); secChannelService.wrap(responseBuffer, (short) 0, responseLen, outputBuffer, (short) 0); secChannelService.assertSensitiveResult(outputLen); // Process the encrypted message ... SensitiveArrays.assertIntegrity(outputBuffer); break; }
ConfidentialDataTransferService
,
KeyService
Modifier and Type | Field and Description |
---|---|
static byte |
PROTOCOL_EAC_ID
Extended Access Control Version integrated with PACE, TA2 and CA2/CA3 tailored for eID scenarios.
|
static byte |
PROTOCOL_EAC_MRTD
Extended Access Control Version 1 (EACv1) includes TA1 and CA1 tailored for MRTD scenarios.
|
static byte |
PROTOCOL_PACE
Password Authenticated Connection Establishment (PACE).
|
static byte |
PROTOCOL_PACE_CAM
PACE with Chip Authentication Mapping (CAM) includes PACE, CA1 and optional TA1.
|
static byte |
PROTOCOL_SCP03
GlobalPlatform Secure Channel Protocol '03' (SCP03).
|
static byte |
PROTOCOL_SCP04
GlobalPlatform Secure Channel Protocol '04' (SCP04) is a configurable version of SCP03.
|
RESULT_FALSE, RESULT_TRUE
Modifier and Type | Method and Description |
---|---|
byte |
getSecurityState()
Returns the current security state of this secure channel.
|
void |
init(short resourceId)
Initialize service with the cryptographic resources required by the protocol.
|
void |
initUnwrap()
Prepare service for session decryption.
|
short |
initWrap(short dataLength)
Prepare service for session encryption.
|
short |
processSecurity(byte[] inBuffer,
short inOffset,
short inLength,
byte[] outBuffer,
short outOffset)
Process authentication.
|
void |
resetSecurity()
Reset the secure channel session.
|
short |
unwrap(byte[] inBuffer,
short inOffset,
short inLength,
byte[] outBuffer,
short outOffset)
Remove session encryption from incoming data.
|
short |
updateUnwrap(byte[] inBuffer,
short inOffset,
short inLength,
byte[] outBuffer,
short outOffset)
Multipart session decryption.
|
short |
updateWrap(byte[] inBuffer,
short inOffset,
short inLength,
byte[] outBuffer,
short outOffset)
Multipart session encryption.
|
short |
wrap(byte[] inBuffer,
short inOffset,
short inLength,
byte[] outBuffer,
short outOffset)
Add session encryption to outgoing data.
|
assertSensitiveResult
static final byte PROTOCOL_PACE
PACE establishes a secure channel through password-based authentication between a user and the CSP (i.e., the chip).
Required resources:
SEC_PACE_PIN
processSecurity(..)
,
Constant Field Valuesstatic final byte PROTOCOL_EAC_ID
Integrates Password Authenticated Connection Establishment (PACE) with Terminal Authentication Version 2 (TA2) and Chip Authentication Version 2/3 (CA2, CA3) for mutual authentication between an off-card entity (i.e., the terminal) and the CSP (i.e., the chip).
Input resources:
SEC_PACE_PIN
SEC_PACE_PUK
SEC_PACE_CAN
SEC_TA_AT_ROOT
SEC_CA2
SEC_CA2_PRIVILEGED
SEC_CA3
SEC_CA3_PSA
Output resources:
SEC_TA_DV
SEC_TA_TERMINAL
SEC_TA_AT_LINKED
Note: Only the resources needed must be provided through the init(..)
method.
For example, if CA3 is not needed, CA3 resources can be omitted. If CA2-privileged or CA3-PSA are missing,
the corresponding CA2 or CA3 keys are used instead. Missing output resources do not trigger exceptions.
processSecurity(..)
,
Constant Field Valuesstatic final byte PROTOCOL_EAC_MRTD
Integrates Password Authenticated Connection Establishment (PACE) with Chip Authentication Version 1 (TA1) and Terminal Authentication Version 1 (CA1) for mutual authentication between an off-card entity (i.e., the terminal) and the CSP (i.e., the chip). Typically used for Machine Readable Travel Documents (MRTD) such as passports.
Input resources:
SEC_PACE_CAN
SEC_PACE_MRZ
SEC_CA1
SEC_TA_IS_ROOT
Output resources:
SEC_TA_DV
SEC_TA_TERMINAL
SEC_TA_AT_LINKED
Note: Only the resources needed must be provided through the init(..)
method.
For example, missing output resources do not trigger exceptions.
processSecurity(..)
,
Constant Field Valuesstatic final byte PROTOCOL_PACE_CAM
Integrates Password Authenticated Connection Establishment (PACE) with Chip Authentication 1 (CA1) using Chip Authentication Mapping (CAM) and optionally supports a Terminal Authentication 1 (TA1) step afterward to ensure mutual authentication between an off-card entity (e.g., the terminal) and the CSP (e.g., the chip). Typically used for Machine Readable Travel Documents (MRTD), such as passports.
Input resources:
SEC_PACE_CAN
SEC_PACE_MRZ
SEC_CA1
SEC_TA_IS_ROOT
Output resources:
SEC_TA_DV
SEC_TA_TERMINAL
Note: Only the resources needed must be provided through the init(..)
method.
For example, missing output resources do not trigger exceptions.
processSecurity(..)
,
Constant Field Valuesstatic final byte PROTOCOL_SCP03
Utilizes symmetric key cryptography for mutual authentication between an off-card entity and the CSP.
Input resources:
SEC_KENC
SEC_KMAC
processSecurity(..)
,
Constant Field Valuesstatic final byte PROTOCOL_SCP04
Input resources:
SEC_KENC
SEC_KMAC
processSecurity(..)
,
Constant Field Valuesvoid init(short resourceId)
Method Behavior:
This method initializes this service using the parameters and algorithms configured to the provided resource. Completeness of resources is not checked during initialization. Exceptions for missing resources are thrown only when they are used.
If a resource for a specific algorithm is re-provided, it replaces the previous one. Resources can be set or replaced during active secure channel session.
The method handles access control and events according to Section 6.4.3 of GlobalPlatform Amendment N.
Usage Guidelines:
resourceId
- Resource required by the protocol.CSPException
- with reason:
ILLEGAL_VALUE
: Resource ID does not exist [2001].NOT_ALLOWED
: Resource missing ACCESS_USE
[5007] or not configured for USAGE_SECCHANNEL
[5040].processSecurity(..)
short processSecurity(byte[] inBuffer, short inOffset, short inLength, byte[] outBuffer, short outOffset)
Data Format:
Supports only plain (unwrapped) incoming APDUs. Input and output APDU formats must follow the protocol; for details, see Section 6.4.1 of GlobalPlatform Amendment N.Method Behavior:
This method processes incoming APDUs and generates the response APDUs according to the selected protocol, using cryptographic resource configurations from previousinit(..)
calls.
The method handles access control, counters, timers and events according to Section 6.4.3 of GlobalPlatform Amendment N.
Usage Guidelines:
CSPSensitiveArrays
for input APDU.CSPSensitiveArrays
for the output APDU and invoke assertIntegrity(..)
after processing it.assertSensitiveResult(..)
.init(..)
before calling this method.wrap
and unwrap
to remove session encryption from incoming APDUs and add it to outgoing APDUs. If the security is SECURITY_NOT_ESTABLISHED
, these methods will not modify the data.inBuffer
- Incoming (plain) APDU.inOffset
- Offset in the APDU buffer to start reading.inLength
- Length of the APDU in bytes.outBuffer
- Output buffer for storing the response APDU.outOffset
- Offset in the output buffer where the result should be written.CSPException
- with reason:
ILLEGAL_BUFFER
: Illegal input or output buffer [1001], [1002], [1004], [1005], [1006], [1007].ILLEGAL_CONFIG
: CSP not activated [3001], missing resource(s) [3002], resource(s) not initialized [3003] or inconsistent secure channel configuration [3040].INVALID_INIT
: Service not initialized
[4040].NOT_ALLOWED
: Resource(s) exhausted [50A0] or expired [50B1].ILLEGAL_USE
: Illegal APDU data [6040].init(..)
,
resetSecurity(..)
,
wrap(..)
,
unwrap(..)
,
updateWrap(..)
,
updateUnwrap(..)
void resetSecurity()
This method revokes the authenticated state and invalidates all session data.
Resources set by init(..)
are not affected.
processSecurity(..)
byte getSecurityState()
Possible values are defined in Section 6.4.1 of GlobalPlatform Amendment N.
short initWrap(short dataLength)
Method Behavior:
This method sets the service to wrapping mode.If not authenticated, the method returns the same length without throwing an exception.
If already in unwrapping mode, it switches to wrapping mode without error.
The method handles access control, secure channel timeout and events according to Section 6.4.3 of GlobalPlatform Amendment N.
dataLength
- Length of the data to be wrapped; can be 0
.CSPException
- with reason:
INVALID_INIT
: Unwrapping mode active [4044].wrap(..)
,
updateWrap(..)
,
processSecurity(..)
short updateWrap(byte[] inBuffer, short inOffset, short inLength, byte[] outBuffer, short outOffset)
Method Behavior:
This method processes a data chunk for multipart session encryption when the full dataset isn't available in one array,
using session keys based on the security level from recent processSecurity(..)
calls.
If not authenticated, the method returns the plain (unmodified) input data without throwing an exception.
Incomplete blocks are stored for processing in the next updateWrap(..)
or wrap(..)
call.
For input buffer length 0
, this method does nothing.
The method handles access control and events according to Section 6.4.3 of GlobalPlatform Amendment N.
Usage Guidelines:
CSPSensitiveArrays
for the input message.assertSensitiveResult(..)
.initWrap(..)
before calling this method.wrap(..)
after one or more updateWrap(..)
calls.processSecurity(..)
to set the appropriate security level.wrap(..)
if all data fits in one array.inBuffer
- Input message to be wrapped.inOffset
- Offset in the input buffer to start reading.inLength
- Length of the input message in bytes.outBuffer
- Output buffer for storing the wrapped message.outOffset
- Offset in the output buffer where the result should be written.CSPException
- with reason:
ILLEGAL_BUFFER
: Illegal input or output buffer [1001], [1002], [1004], [1005], [1006], [1007].INVALID_INIT
: Wrapping not initialized [4041].initWrap(..)
,
wrap(..)
short wrap(byte[] inBuffer, short inOffset, short inLength, byte[] outBuffer, short outOffset)
Method Behavior:
This method applies session encryption using session keys based on the security level from recent processSecurity(..)
calls.
After resetSecurity(..)
, new calls to processSecurity(..)
are needed to re-establish session keys.
If updateWrap(..)
was previously invoked, it processes any buffered data before handling the new data provided.
The method handles access control and events according to Section 6.4.3 of GlobalPlatform Amendment N.
Usage Guidelines:
CSPSensitiveArrays
for the input message.assertSensitiveResult(..)
.initWrap(..)
before calling this method.updateWrap(..)
as needed before finalizing with this method.processSecurity(..)
to set the appropriate security level.inBuffer
- The message to be wrapped.inOffset
- Offset in the message buffer to start reading.inLength
- Length of the message in bytes.outBuffer
- Output buffer for storing the wrapped message.outOffset
- Offset in the output buffer where the result should be written.CSPException
- with reason:
ILLEGAL_BUFFER
: Illegal input or output buffer [1001], [1002], [1004], [1005], [1006], [1007].INVALID_INIT
: Wrapping not initialized [4041].processSecurity(..)
,
initWrap(..)
,
updateWrap(..)
void initUnwrap()
Method Behavior:
This method sets the service to unwrapping mode. If already in wrapping mode, it throws an error.
The method handles access control, secure channel timeout, and events according to Section 6.4.3 of GlobalPlatform Amendment N.
CSPException
- with reason:
INVALID_INIT
: Wrapping mode active [4043].unwrap(..)
,
updateUnwrap(..)
,
processSecurity(..)
short updateUnwrap(byte[] inBuffer, short inOffset, short inLength, byte[] outBuffer, short outOffset)
Method Behavior:
This method processes a data chunk for multipart session decryption when the full dataset isn't available in one array,
using session keys based on the current security state from recent processSecurity(..)
calls.
If not authenticated, the method returns the plain (unmodified) input data without throwing an exception.
Incomplete blocks are stored for processing in the next updateUnwrap(..)
or unwrap(..)
call.
For input buffer length 0
, this method does nothing.
The method handles access control and events according to Section 6.4.3 of GlobalPlatform Amendment N.
Usage Guidelines:
CSPSensitiveArrays
for the output data and invoke assertIntegrity(..)
after processing it.assertSensitiveResult(..)
.initUnwrap(..)
before calling this method.processSecurity(..)
to establish the appropriate security state.inBuffer
- The message to be unwrapped.inOffset
- Offset in the message buffer to start reading.inLength
- Length of the message in bytes.outBuffer
- Output buffer for storing the unwrapped message.outOffset
- Offset in the output buffer where the result should be written.CSPException
- with reason:
ILLEGAL_BUFFER
: Illegal input or output buffer [1001], [1002], [1004], [1005], [1006], [1007].INVALID_INIT
: Unwrapping not initialized [4042].initUnwrap(..)
,
unwrap(..)
short unwrap(byte[] inBuffer, short inOffset, short inLength, byte[] outBuffer, short outOffset)
Method Behavior:
This method removes session encryption from the input data using session keys
based on the current security state from recent processSecurity(..)
calls.
After resetSecurity(..)
, new calls to processSecurity(..)
are needed to re-establish session keys.
If updateUnwrap(..)
was previously invoked, it processes any buffered data before handling the new data provided.
The method handles access control and events according to Section 6.4.3 of GlobalPlatform Amendment N.
Usage Guidelines:
CSPSensitiveArrays
for the output data and invoke assertIntegrity(..)
after processing it.assertSensitiveResult(..)
.initUnwrap(..)
before calling this method.updateUnwrap(..)
as needed before finalizing with this method.processSecurity(..)
to establish the appropriate security state.inBuffer
- The message to be unwrapped.inOffset
- Offset in the message buffer to start reading.inLength
- Length of the message in bytes.outBuffer
- Output buffer for storing the unwrapped message.outOffset
- Offset in the output buffer where the result should be written.CSPException
- with reason:
ILLEGAL_BUFFER
: Illegal input or output buffer [1001], [1002], [1004], [1005], [1006], [1007].INVALID_INIT
: Unwrapping not initialized [4042].processSecurity(..)
,
initUnwrap(..)
,
updateUnwrap(..)
Copyright © 2023-2025 GlobalPlatform, Inc. All rights reserved. The technology provided or described in this specification is subject to updates, revisions, and extensions by GlobalPlatform. Recipients of this document are invited to submit, with their comments, notification of any relevant patent rights or other intellectual property rights of which they may be aware which might be necessarily infringed by the implementation of the specification or other work product set forth in this document, and to provide supporting documentation.
THIS SPECIFICATION OR OTHER WORK PRODUCT IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NON-INFRINGEMENT IS EXPRESSLY DISCLAIMED. ANY IMPLEMENTATION OF THIS SPECIFICATION OR OTHER WORK PRODUCT SHALL BE MADE ENTIRELY AT THE IMPLEMENTER'S OWN RISK, AND NEITHER THE COMPANY, NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF ANY NATURE WHATSOEVER DIRECTLY OR INDIRECTLY ARISING FROM THE IMPLEMENTATION OF THIS SPECIFICATION OR OTHER WORK PRODUCT.