# 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.

Remote Key Loading Process

  1. Device sends Device Signing Cert (DSC) to RKMS in device login request
  2. RKMS verifies DSC and sends its working certificates
    1. RKMS signing certificate (RSC): used by device to verify signature in RKMS messages sent to device
    2. RKMS encrypting certificates (REC): used by device to encrypt messages sent to RKMS
    3. A randomly generated RKMS nonce to prevent replay
  3. 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:
    1. An PKCS7 enveloped data containing:
      1. an ephemeral 3DES key encrypted with the REC public key using RSAES-OAEP scheme
      2. a TR-34 Session key encrypted with the ephemeral key using 3DES/CBC.
      3. An IV to be used when decrypting the TR-34 Session Key using the ephemeral Key.
    2. A SHA256 hash and RSASA-PKCS1_V1.5 signature of the enveloped data generated using the DSC private key.
  4. 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.
    1. RKMS verifies key request signature and TR-34 signature (both using DSC public key), as well as SHA256 hashes.
    2. 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)
    3. 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.
  5. 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)
    1. Device verifies key response signature and inject keys extracted from TR-31 key blocks
    2. Device generates key injection report encoded in an ASN1 structure.
  6. 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)
  7. RKMS verifies key validation request signature (with DSC public key)
  8. 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)
  9. Device verifies key validation response signature using (RSC public key).
  10. 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:

  1. TR-34 - to implement TR-34 spec generation to securely exchange a Symmetric Transport Key using PKI
    1. Version: ASC X9 TR 34-2012
    2. http://webstore.ansi.org/RecordDetail.aspx?sku=ASC+X9+TR+34-2012
  2. TR-31 - to support interchange of symmetric keys in a secure manner
    1. Version: X9 TR-31-2010
    2. https://webstore.ansi.org/standards/ascx9/x9tr312010
    3. useful reference: https://www.ibm.com/support/knowledgecenter/linuxonibm/com.ibm.linux.z.wskc.doc/wskc_c_l0wskc03_zapgtr31.html
  3. CMS - to support the cryptographic message syntax
    1. Version: ANSI X9.73-2010
    2. 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
Last Updated: 11/30/2020, 5:56:55 PM