# Poynt Device Remote Key Loading
Poynt Terminal Remote Key Loading requires the Terminal to have a Device Signing Certificate (RSA 2048 Key Pair) and the corresponding Trusted CA Chain, to be able to exchange Terminal Encryption Keys (P2PE/PIN) with Poynt Remote Key Management System (RKMS).
Please refer to Poynt Device Object Signing Specification for information on how to load a Device Signing Certificate for all Terminals at the manufacturing facility.
Poynt Remote Key Loading consists of 3 specific requests & responses to establish secure connection, exchange and validation of the keys. The following diagram outlines the overall process flow of the Remote Key Loading process.
- Device sends Device Signing Cert (DSC) to RKMS in device login request
- RKMS verifies DSC and sends its working certificates
- RKMS signing certificate (RSC): used by device to verify signature in RKMS messages sent to device
- RKMS encrypting certificates (REC): used by device to encrypt messages sent to RKMS
- A randomly generated RKMS nonce to prevent replay
- Device verifies RSC and REC against its certificates chain of trust and generates a TR-34 blob containing a symmetric TR-34 session key to be used subsequently as a Key Block Protection Key (KBPK) for the TR-31 Key blocks. This TR-34 blob contains:
- An PKCS7 enveloped data containing:
- an ephemeral 3DES key encrypted with the REC public key using RSAES-OAEP scheme
- a TR-34 Session key encrypted with the ephemeral key using 3DES/CBC.
- An IV to be used when decrypting the TR-34 Session Key using the ephemeral Key.
- A SHA256 hash and RSASA-PKCS1_V1.5 signature of the enveloped data generated using the DSC private key.
- An PKCS7 enveloped data containing:
- A random device nonce, the TR-34 blob and RSASA-PSS signature is included in the key request sent to the RKMS. Signature is generated with DSC private key and is calculated from a payload containing the RKMS nonce, TR-34 blob and Device nonce.
- RKMS verifies key request signature and TR-34 signature (both using DSC public key), as well as SHA256 hashes.
- RKMS decrypt the ephemeral key from TR-34 blob (using REC private key), and TR-34 Session Key (using ephemeral key with TDES/CBC and IV from found in TR-34 blob)
- RKMS generates a set of TR-31 key block in an ASN1 structure. TR-31 key blocks are generated using the TR-34 Session Key as KBPK.
- RKMS generates a key response including the ASN1 structure, a new random RKMS nonce, and a signature using RSC private key (signature is based on the payload containing ASN1 structure, current RKMS nonce, current device nonce)
- Device verifies key response signature and inject keys extracted from TR-31 key blocks
- Device generates key injection report encoded in an ASN1 structure.
- Device generates a key validation request containing the ASN1 structure, a new random device nonce and a signature using DSC private key (signature is based on the payload containing ASN1 structure, current RKMS nonce, current device nonce)
- RKMS verifies key validation request signature (with DSC public key)
- RKMS generates a key validation response indicating acknowledgment and a signature containing acknowledgment information, current device nonce and a new RKMS nonce (using RSC private key)
- Device verifies key validation response signature using (RSC public key).
- Device deletes Session Key, Ephemeral Key, IV and nonces from its memory (upon error during the injection process, these data are also deleted right away)
# Prerequisites
Terminal must be Object Signed and supports all the necessary methods as described in the Poynt Device Object Signing Specification document.
Support for the following specifications is required to implement the remote key loading functionality:
- TR-34 - to implement TR-34 spec generation to securely exchange a Symmetric Transport Key using PKI
- Version: ASC X9 TR 34-2012
- http://webstore.ansi.org/RecordDetail.aspx?sku=ASC+X9+TR+34-2012
- TR-31 - to support interchange of symmetric keys in a secure manner
- Version: X9 TR-31-2010
- https://webstore.ansi.org/standards/ascx9/x9tr312010
- useful reference: https://www.ibm.com/support/knowledgecenter/linuxonibm/com.ibm.linux.z.wskc.doc/wskc_c_l0wskc03_zapgtr31.html
- CMS - to support the cryptographic message syntax
- Version: ANSI X9.73-2010
- http://webstore.ansi.org/RecordDetail.aspx?sku=ANSI+X9.73-2010
# Remote Key Loading APIs
The following are the methods that must be provided by the card reader to support Remote Key Loading process. These methods are defined as part of IPoyntPaymentSecuritySPI.aidl and must be implemented by the Card Reader provider in order to be compatible with Poynt Remote Key Loading process.
# eraseAllKeys()
This command is used to erase all PCI keys on the card reader that are related to PIN and Data Encryption. This includes all Key Protection Keys, DUKPT Keys, Master/Session Keys, etc. This command MUST NOT erase the Device Signing Certificate (RSA 2048 Key Pair).
# Input Params
Callback - where the result of erasing all keys is returned. Following are the 2 methods defined in the callback.
onSuccess()
onError(PoyntError error)
# Output Params
Callback onSuccess() or onError() as appropriate.
# Error Conditions
Unable to erase keys due to permission error, return error
- PoyntError.ERASE_KEYS_FAILURE
# initiateRemoteKeyLoading()
This method is used to initiate remote key loading requests by providing RKMS signing and encryption certificates retrieved from the Poynt RKMS system. Card readers must verify the given RKMS Signing and encryption certificates, and store them for subsequent operations. The previously loaded CA Trust chain is used for the RKMS Signing and Encryption Certificate verification.
# Input Params
RKMS Signing Certificate - Certificate used to sign the remote key loading messages
RKMS Encryption Certificate - certificate used to encrypt the session key used to exchange terminal keys
Secure nonce - Random data (nonce) of length 8 used for replay detection
Callback - where the result of RKMS certification verification is returned. Following are the 2 methods defined in the callback.
onSuccess()
onError(PoyntError error)
# Output Params
When the RKMS Signing and Encryption Certificates are validated successfully, returns a onSuccess() callback otherwise onError().
# Error Conditions
If RKMS certificate validation failed, return error
- PoyntError.RMKS_CERT_VALIDATION_FAILED
If saving of RKMS certificates failed, return error
- PoyntError.REMOTE_KEY_INITIATION_FAILED
If secure nonce has been used in the session already, return error
- PoyntError.NONCE_REPLAYED
# generateDeviceKeyRequest()
This method is used for the terminal to request keys from the RKMS server. The key request must include a TR34 block containing the Session Key that is used to encrypt the terminal keys in the subsequent commands. The Session Key is encrypted with the RKMS Encryption Certificate loaded in the initiateRemoteKeyLoading() method above.
# Input Params
Callback - where the key request is returned. Following are the 2 methods defined in the callback.
onSuccess()
onError(PoyntError error)
# Output Params
Card readers must generate a session key used for key exchange with RKMS. The session key is packaged in TR-34 format encrypted with RKMS encryption certificate.
The response to onSuccess() callback must return the following parameters:
onSuccess(String sessionKey, String signature, int maxKeysToReturn,String signingPaddingMethod, String nonce) -- where,
Session key in the form of a TR-34 blob encrypted using RKMS Encryption Certificate
Signature - RSA signature, using the SHA256
Max # of keys to return in one request || Session key TR-34 blob || The current device nonce || The current RKMS nonce (nonce from initiateRemoteKeyLoading() call) || Padding method || Salt length (64) Signed by the private key associated with the device’s signing certificate
Max number of keys to return in one request (eg. 10)
Signing Padding Method: 1 or 2
1 -- PKCS1v1.5 (recommended)
2 -- PSS
Random data (nonce) of length 8 used for replay detection
# Error Conditions
If no RKMS Signing and Encryption Certificates are found, return error
- PoyntError.NO_RKMS_CERTS_FOUND
If session key generation failed, return error
- PoyntError.RKL_SESSION_KEY_GENERATION_FAILED
If key request generation failed, return error
- PoyntError.RKL_KEY_REQUEST_GENERATION_FAILED
# loadDeviceKeyResponse()
This method is used to load the keys from RKMS. The input contains the keys encrypted with the Session Key sent in the Key Request.
# Input Params
keysRemaining - if more keys are available to download
encryptedKey - HEX-ASCII encoded ASN.1 Structure, which contains a sequence of TR-31 key blocks - please see Appendix for details.
Signature
RSA signature (SHA-256) of Total number of keys remaining || Success Code (Y = Keys delivered successfully or N = Error sending keys) || Maximum number of keys || The session key TR-34 blob (if provided) || ASN.1 Structure from Encrypted key || The current device nonce || The current RKMS Series nonce || Padding Method || Salt Length (if provided) Signed by the private key associated with the RKMS Series' signing certificate sent in the initiateRemoteKeyLoading() method
Secure nonce - random data (nonce) of length 8 used for replay detection
Signing Padding Method - Signing Padding Method (1 or 2)
1 -- PKCS1v1.5
2 -- PSS
Salt length - Optional PSS padding
Callback - where the result of key request response is returned. Following are the 2 methods defined in the callback.
onSuccess()
onError(PoyntError error)
# Output Params
When the encryption keys are validated and loaded successfully, returns a onSuccess() callback, otherwise onError().
# Error Conditions
If secure nonce has been used in the session already, return error
- PoyntError.NONCE_REPLAYED
If encrypted Key is invalid or failed validations, return error
- PoyntError.RKL_INVALID_KEY_STRUCTURE
If key loading failed, return error
- PoyntError.RKL_KEY_LOAD_FAILED
# generateDeviceKeyValidationRequest()
This method is used to validate the injected keys with the RKMS server. When this method is invoked, card reader must generate the key validation report which is sent to the RKMS server for confirming the loaded encryption keys.
# Input Params
Callback - where the key validation report is returned. Following are the 2 methods defined in the callback.
onSuccess(String keyVerificationReport, long saltLength, String signingPaddingMethod, String nonce)
onError(PoyntError error)
# Output Params
Card readers must generate a key report with the details of the keys loaded in the loadDeviceKeyResponse() method.
The response to onSuccess() callback must return the following parameters:
Key verification report - Key Verification ASN.1 structure, hex encoded - please see appendix for details
signature - RSA signature, using the SHA256
The Key Verification ASN.1 structure || The current device nonce || The current RKMS Series nonce from loadDeviceKeyResponse() || Padding method || Salt Length (64) Signed by the private key associated with the device’s signing certificate
Salt length - optional - PSS padding
Signing Padding Method: 1 or 2
1 -- PKCS1 v1.5 (recommended)
2 -- PSS
Random data (nonce) of length 8 used for replay detection
# Error Conditions
If secure nonce has been used in the session already, return error
- PoyntError.NONCE_REPLAYED
If no encrypted keys are loaded, return error
- PoyntError.RKL_NO_KEYS_FOUND
If key report generation failed, return error
- PoyntError.RKL_KEY_REPORT_GENERATION_FAILED
# validateDeviceKeyValidationResponse()
This method is used to confirm the keys loaded from the key validation report generated by generateDeviceKeyValidationRequest(). If more keys are available to load, remaining keys are loaded using the same sequence of comments as described above.
# Input Params
All keys loaded - if true - all keys confirmed loaded and device is locked, if false - more keys are available to fetch from RKMS
Signature - RSA signature of following data, signed by the RKMS signing certificate
the Return code (string literal: "BBY" -- if all keys are loaded or "BBN"-- if more keys are available) || The current device nonce || The current RKMS Series nonce (Located in the RD tag) || Padding method || Salt Length (if provided) Signed by the private key associated with the RKMS Series' signing certificate
Padding method - 1 or 2
1 = PKCS #1 1.5
2.= PKCS #1 PSS
Secure nonce - Random data (nonce) of length 8 used for replay detection
Salt length - Optional -- PSS padding
Callback - where the key validation repose is returned. Following are the 2 methods defined in the callback.
onSuccess()
onError(PoyntError error)
# Output Params
When the RKMS signature is validated successfully, returns a onSuccess() callback otherwise onError().
# Error Conditions
If secure nonce has been used in the session already, return error
- PoyntError.NONCE_REPLAYED
If no key load in progress, return error
- PoyntError.RKL_NO_KEY_LOAD_IN_PROGRESS
If cannot handle more keys to load, return error
- PoyntError.RKL_KEY_LIMIT_REACHED
# Appendix
# ASN.1 Structure
The format of an ASN.1 Structure used in loadDeviceKeyResponse() is as below:
KeyBlock ::= Sequence
{
keyblock version = 1 (INTEGER)
Keys ::= Set
{
keyinfo ::= Sequence
{
TR31Key = (PRINTABLESTRING)
keyType = (INTEGER)
ksn = (OCTET STRING) – If keyType is not DUKT 00000000000000000000
keySlot = (INTEGER)
cryptoMode = (PRINTBLESTRING) - Optional Field
}
}
keyName = (PRINTABLESTRING)
keyCheck = (OCTET STRING)
}
Where:
TR31Key: X9 TR-31 Key Block encrypted using the TR-34 Session Key as its Key Block Protection Key.
keyType: Indicates the type of Key.
0 Unknown 1 Master Session Key 2 DUKPT Initial Key 3 DUKPT BDK Key (Derived DUKPT Initial Key) 4 MAC Key 5 PIN Encryption Key 6 Key Transfer Key 7 Host Verification Key 8 DUKPT 3DES BDK Key (Derived DUKPT Initial Key) 9 Default KTK 10 Data Encryption Key 11 Data Decryption Key 12 Detach BDK Key 13 Terminal Master Key
ksn: unused, since KSN is included in TR31 Key Block as an optional header
keySlot: the destination slot (0-9)
keyName: a ASCII string describing the key
keyCheck: Key Check Value (2 first byte of the 8-byte zeros encrypted with key-to-be-injected in clear using TDES ECB)
A key of type 1 (Master Session Key) should be inserted in the key slots as a Master Key.
A key of type 2 (Derived Dukpt Initial Key) should be injected as Initial DUKPT key
A key of type 4 (MAC Key) should be injected in the key slots as a "Data MAC Session Key"
A key of type 5 should be injected in the key slots as a "Pin Session Key"
A key of type 10 should be injected in the key slots as a "Data Session Key"
All the keys to be injected will be passed in this ASN.1 structure as TR-31 Key Blocks and all TR-31 Key Blocks in this structure will use the same temporary TR-34 Session Key securely exchanged via the GET KEY REQUEST command.
Note that the TR-34 Session Key is discarded once all the keys are injected successfully or unsuccessfully (for instance due to an incorrect MAC, or invalid KCV).
# TR-34 Structure Breakdown
Below are the specific TR-34 fields that are utilized in the TR-34 structure.
- TR-34 (http://webstore.ansi.org/RecordDetail.aspx?sku=ASC+X9+TR+34-2012)
- CMS (http://webstore.ansi.org/RecordDetail.aspx?sku=ANSI+X9.73-2010)
Offset | Where to find data | Description | Value |
---|---|---|---|
23 | Static | Version number of TR-34. Number is in hex representation. We use version 73 which is 49 in hex. | See TR-34 page 101 |
30 | Static | Hashing method OID | See TR-34 page 101 |
45 | Static | envelopedData OID | See TR-34 page 101 |
60 | Generated | enveloped data structure | See TR-34 page 65 |
64 | Static | Enveloped data version. Specified in TR-34 page 65, CMS x9.73 page 48 | 0 |
75 | Static | KeyTransRecipientInfo version. We use version 1, see page 48,50 of CMS X9.73. | 1 |
82 | Device Encryption Certificate | Certificate information for the device signing certificate. This SET is repeated for every item in the certificate subject field | Variable |
147 | Device Encryption Certificate | Certificate serial # | Variable |
156 | Static | OAEP padding OID | See TR-34 page 101 |
171 | Static | Hashing method OID | See TR-34 page 101 |
186 | Static | id-mgf1 OID | See TR-34 page 101 |
199 | Static | Hashing method OID | See TR-34 page 101 |
225 | Generated | Public key encrypted ephemeral key (CEK – CMS Content Encryption Key) | See CMS X9.73 |
488 | Static | pkcs-7 data OID | See TR-34 page 101 |
502 | Static | 3DES-EDE OID | See TR-34 page 101 |
512 | Generated | IV used for CEK. | Variable |
522 | Generated | Session key encrypted with the ephemeral key. | Generated by device |
661-1137 | N/A | CRL. We do not currently utilize this field. | N/A |
1145 | Static | SignedData version. We currently use version 1. | See TR-34 page 101 |
1148-1217 | Device Signing Certificate | Certificate information for the device signing certificate. This SET is repeated for every item in the certificate subject field | Variable |
1226 | Static | hash method OID | See TR-34 page 101 |
1242 | Static | content type OID | See TR-34 page 101 |
1255 | Static | envelopedData OID | See TR-34 page 101 |
1268 | Static | nonce OID | See TR-34 page 101 |
1282 | Generated | A nonce. Required by TR-34 standard | See TR-34 page 101 |
1315 | Generated | TR-31 header of session key | Variable |
1335 | Generated | SHA-256 hash of signed attributes. | See TR-34 section B.2.2.5 |
1397 | Generated | Signature with device signing key. | See TR-34 section B.2.2.5 |