Example: Working with PINs on your Cryptographic Coprocessor

Change this program example to suit your needs for working with PINs on your Cryptographic Coprocessor.

Note: Read the Code license and disclaimer information for important legal information.

If you choose to use this program example, change it to suit your specific needs. For security reasons, IBM® recommends that you individualize these program examples rather than using the default values provided.

 F*************************************************************
     F* PINSAMPLE
     F*
     F*  Sample program that shows the use of the appropriate
     F*  CCA Security API (SAPI) verbs for generating and verifying
     F*  PINS
     F*
     F*  The keys are created by first building a key token
     F*  and then importing key parts using Key_Part_Import.
     F*  Four keys are created each with a different
     F*  key type - PINGEN, PINVER, IPINENC, and OPINENC.  The
     F*  PINGEN key will be used to generate a Clear PIN with the
     F*  Clear_PIN_Generate verb.  The OPINENC key will be used
     F*  to encrypt the PIN with the Clear_PIN_Encrypt verb.
     F*  The Encrypted_PIN_Verify with verify that the PIN is good
     F*  using the IPINENC key (to decrypt) and the PINVER key
     F*  to verify the PIN.
     F*
     F* COPYRIGHT 5769-SS1 (C) IBM CORP.  1999
     F*
     F* This material contains programming source code for your
     F* consideration.  These example has not been thoroughly
     F* tested under all conditions.  IBM, therefore, cannot
     F* guarantee or imply reliability, serviceability, or function
     F* of these programs.  All programs contained herein are
     F* provided to you "AS IS".  THE IMPLIED WARRANTIES OF
     F* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     F* ARE EXPRESSLY DISCLAIMED.  IBM provides no program services for
     F* these programs and files.
     F*
     F*
     F* Note: Input format is more fully described in Chapter 2 of
     F*       IBM  CCA Basic Services Reference and Guide
     F*       (SC31-8609) publication.
     F*
     F* Parameters:
     F*   none.
     F*
     F* Example:
     F*  CALL PGM(PINSAMPLE)
     F*
     F* Use these commands to compile this program on the system:
     F* CRTRPGMOD MODULE(PINSAMPLE) SRCFILE(SAMPLE)
     F* CRTPGM  PGM(PINSAMPLE) MODULE(PINSAMPLE)
     F*         BNDSRVPGM(QCCA/CSNBKPI QCCA/CSNBPGN +
     F*                   QCCA/CSNBCPE QCCA/CSNBPVR)
     F*
     F* Note: Authority to the CSNBKPI, CSNBPGN, CSNBCPE, and
     F*       CSNBPVR service programs in the QCCA library is assumed.
     F*
     F* The Common Cryptographic Architecture (CCA) verbs used are
     F* Key_Part_Import (CSNBKPI), Clear_PIN_Generate (CSNBPGN),
     F* Clear_PIN_Encrypt (CSNBCPE), and Encrypted_PIN_Verify (CSNBPVR).
     F*
     F* Note: This program assumes the card you want to load is
     F*       already identifed either by defaulting to the CRP01
     F*       device or has been explicitly named using the
     F*       Cryptographic_Resource_Allocate verb. Also this
     F*       device must be varied on and you must be authorized
     F*       to use this device descrption.
     F*
     F**************************************************************
     F* Declare parameters that are common to all of the CCA verbs
     F*
     F**************************************************************
     DRETURNCODE       S              9B 0
     DREASONCODE       S              9B 0
     DEXITDATALEN      S              9B 0
     DEXITDATA         S              4
     DRULEARRAYCNT     S              9B 0
     DRULEARRAY        S             16
     D*
     D**************************************************************
     D* Declare Key tokens used by this program
     D*
     D**************************************************************
     DIPINKEY          S             64
     DOPINKEY          S             64
     DPINGENKEY        S             64
     DPINVERKEY        S             64
     DKEYTOKEN         DS
     DKEYFORM                  1      1
     DKEYVERSION               5      5
     DKEYFLAG1                 7      7
     DKEYVALUE                17     32
     DKEYCV                   33     48
     DKEYTVV                  61     64B 0
     DTOKENPART1               1     16
     DTOKENPART2              17     32
     DTOKENPART3              33     48
     DTOKENPART4              49     64
     DKEYTVV1                  1      4B 0
     DKEYTVV2                  5      8B 0
     DKEYTVV3                  9     12B 0
     DKEYTVV4                 13     16B 0
     DKEYTVV5                 17     20B 0
     DKEYTVV6                 21     24B 0
     DKEYTVV7                 25     28B 0
     DKEYTVV8                 29     32B 0
     DKEYTVV9                 33     36B 0
     DKEYTVV10                37     40B 0
     DKEYTVV11                41     44B 0
     DKEYTVV12                45     48B 0
     DKEYTVV13                49     52B 0
     DKEYTVV14                53     56B 0
     DKEYTVV15                57     60B 0
     D*
     D**************************************************************
     D* Declare parameters unique to Key_Part_Import
     D*
     D**************************************************************
     DCLEARKEY         S             16
     D*
     D**************************************************************
     D* Declare parameters unique to Clear_PIN_Generate,
     D*  Clear_PIN_Encrypt, and Encrypted_PIN_Verify
     D**************************************************************
     DPINLEN           S              9B 0
     DPINCKL           S              9B 0
     DSEQNUMBER        S              9B 0
     DCPIN             S             16
     DEPIN             S             16
     DPAN              S             12
     DDATAARRAY        DS
     DDECTABLE                 1     16
     DVALDATA                 17     32
     DCLRPIN                  33     48
     DPROFILE          DS
     DPINFORMAT                1      8
     DFORMATCONTROL            9     16
     DPADDIGIT                17     24
     D*
     D**************************************************************
     D* Declare variables used for creating a control vector and
     D* clear key.
     D**************************************************************
     DBLDKEY           DS
     DLEFTHALF                 1      8
     DLEFTHALFA                1      4B 0
     DLEFTHALFB                5      8B 0
     DRIGHTHALF                9     16
     D*
     D*
     D**************************************************
     D* Prototype for Key Part Import (CSNBKPI)
     D**************************************************
     DCSNBKPI          PR
     DRETCODE                         9B 0
     DRSNCODE                         9B 0
     DEXTDTALEN                       9B 0
     DEXTDTA                          4
     DRARRAYCT                        9B 0
     DRARRAY                         16
     DCLRKEY                         16
     DIMPKEY                         64
     D*
     D**************************************************
     D* Prototype for Clear PIN Generate (CSNBPGN)
     D**************************************************
     DCSNBPGN          PR
     DRETCODE                         9B 0
     DRSNCODE                         9B 0
     DEXTDTALEN                       9B 0
     DEXTDTA                          4
     DPINGEN                         64
     DRARRAYCT                        9B 0
     DRARRAY                         16
     DPINL                            9B 0
     DPINCHKLEN                       9B 0
     DDTAARRY                        48
     DRESULT                         16
     D*
     D**************************************************
     D* Prototype for Clear PIN Encrypt (CSNBCPE)
     D**************************************************
     DCSNBCPE          PR
     DRETCODE                         9B 0
     DRSNCODE                         9B 0
     DEXTDTALEN                       9B 0
     DEXTDTA                          4
     DPINENC                         64
     DRARRAYCT                        9B 0
     DRARRAY                         16
     DCLRPIN                         16
     DPINPROFILE                     24
     DPANDATA                        12
     DSEQN                            9B 0
     DEPINBLCK                        8
     D*
     D**************************************************
     D* Prototype for Encrypted PIN Verify (CSNBPVR)
     D**************************************************
     DCSNBPVR          PR
     DRETCODE                         9B 0
     DRSNCODE                         9B 0
     DEXTDTALEN                       9B 0
     DEXTDTA                          4
     DPINENC                         64
     DPINVER                         64
     DPINPROFILE                     24
     DPANDATA                        12
     DEPINBLCK                        8
     DRARRAYCT                        9B 0
     DRARRAY                         16
     DCHECKLEN                        9B 0
     DDTAARRAY                       24
     D*
     D**************************************************************
     D* Declares for sending messages to job log
     D**************************************************************
     DFAILMESSAGE      S             50
     DGOODMESSAGE      S             50
     DFAILMSG          DS
     DFAILMSGTEXT              1     50
     DFAILRETC                41     44
     DFAILRSNC                46     49
     DRETSTRUCT        DS
     DRETCODE                  1      4I 0
     DSLASH                    5      5    INZ('/')
     DRSNCODE                  6      9I 0
     DFAILMSGLENGTH    S              9B 0 INZ(49)
     DGOODMSGLENGTH    S              9B 0 INZ(29)
     DMESSAGEID        S              7    INZ('       ')
     DMESSAGEFILE      S             21    INZ('                     ')
     DMSGKEY           S              4    INZ('    ')
     DMSGTYPE          S             10    INZ('*INFO     ')
     DSTACKENTRY       S             10    INZ('*         ')
     DSTACKCOUNTER     S              9B 0 INZ(2)
     DERRCODE          DS
     DBYTESIN                  1      4B 0 INZ(0)
     DBYTESOUT                 5      8B 0 INZ(0)
     C                   EVAL      FAILMESSAGE = '******* failed with return+
     C                                            /reason codes 9999/9999'
     C                   EVAL      GOODMESSAGE = 'PIN Validation was successful'
     C**************************************************************
     C* START OF PROGRAM                                           *
     C*                                                            *
     C**************************************************************
     C* Build a PINGEN key token
     C*
     C**************************************************************
     C* Zero out the key token to start with
     C*
     C                   Z-ADD     0             KEYTVV1
     C                   Z-ADD     0             KEYTVV2
     C                   Z-ADD     0             KEYTVV3
     C                   Z-ADD     0             KEYTVV4
     C                   MOVE      TOKENPART1    TOKENPART2
     C                   MOVE      TOKENPART1    TOKENPART3
     C                   MOVE      TOKENPART1    TOKENPART4
     C*
     C* Set the form, version, and flag byte
     C*
     C                   BITON     '7'           KEYFORM
     C                   BITON     '67'          KEYVERSION
     C                   BITON     '1'           KEYFLAG1
     C*
     C* The control vector for a PINGEN key that has the key part
     C* flag set is (in hex):
     C*
     C*       00227E00  03480000  00227E00  03280000
     C*
     C* If each 4 byte hex part is converted to decimal you get:
     C*
     C*       2260480   55050240  2260480   52953088
     C*
     C* Build the control vector by placing the decimal number in
     C* the appropriate half of the control vector field.
     C**************************************************************
     C                   Z-ADD     2260480       LEFTHALFA
     C                   Z-ADD     55050240      LEFTHALFB
     C                   MOVEL     LEFTHALF      KEYCV
     C                   Z-ADD     2260480       LEFTHALFA
     C                   Z-ADD     52953088      LEFTHALFB
     C                   MOVE      LEFTHALF      KEYCV
     C*
     C* Calculate the Token Validation value by adding every 4 bytes
     C* and storing the result in the last 4 bytes.
     C*
     C                   ADD       KEYTVV1       KEYTVV
     C                   ADD       KEYTVV2       KEYTVV
     C                   ADD       KEYTVV3       KEYTVV
     C                   ADD       KEYTVV4       KEYTVV
     C                   ADD       KEYTVV5       KEYTVV
     C                   ADD       KEYTVV6       KEYTVV
     C                   ADD       KEYTVV7       KEYTVV
     C                   ADD       KEYTVV8       KEYTVV
     C                   ADD       KEYTVV9       KEYTVV
     C                   ADD       KEYTVV10      KEYTVV
     C                   ADD       KEYTVV11      KEYTVV
     C                   ADD       KEYTVV12      KEYTVV
     C                   ADD       KEYTVV13      KEYTVV
     C                   ADD       KEYTVV14      KEYTVV
     C                   ADD       KEYTVV15      KEYTVV
     C*
     C* Copy token to PINGENKEY
     C*
     C                   MOVE      KEYTOKEN      PINGENKEY
     C*
     C**************************************************************
     C* Build a PINVER key token
     C*
     C* The control vector for a PINVER key that
     C* has the key part flag set is (in hex):
     C*
     C*       00224200  03480000  00224200  03280000
     C*
     C* If each 4 byte hex part is converted to decimal you get:
     C*
     C*       2260480   55050240  2260480   52953088
     C*
     C* Build the control vector by placing the decimal number in
     C* the appropriate half of the control vector field.
     C                   Z-ADD     2245120       LEFTHALFA
     C                   Z-ADD     55050240      LEFTHALFB
     C                   MOVEL     LEFTHALF      KEYCV
     C                   Z-ADD     2245120       LEFTHALFA
     C                   Z-ADD     52953088      LEFTHALFB
     C                   MOVE      LEFTHALF      KEYCV
     C*
     C* Calculate the Token Validation value by adding every 4 bytes
     C* and storing the result in the last 4 bytes.
     C*
     C                   Z-ADD     0             KEYTVV
     C                   ADD       KEYTVV1       KEYTVV
     C                   ADD       KEYTVV2       KEYTVV
     C                   ADD       KEYTVV3       KEYTVV
     C                   ADD       KEYTVV4       KEYTVV
     C                   ADD       KEYTVV5       KEYTVV
     C                   ADD       KEYTVV6       KEYTVV
     C                   ADD       KEYTVV7       KEYTVV
     C                   ADD       KEYTVV8       KEYTVV
     C                   ADD       KEYTVV9       KEYTVV
     C                   ADD       KEYTVV10      KEYTVV
     C                   ADD       KEYTVV11      KEYTVV
     C                   ADD       KEYTVV12      KEYTVV
     C                   ADD       KEYTVV13      KEYTVV
     C                   ADD       KEYTVV14      KEYTVV
     C                   ADD       KEYTVV15      KEYTVV
     C*
     C* Copy token to PINVERKEY
     C*
     C                   MOVE      KEYTOKEN      PINVERKEY
     C*
     C*
     C**************************************************************
     C* Build an IPINENC key token
     C*
     C* The control vector for an IPINENC key that
     C* has the key part flag set is (in hex):
     C*
     C*       00215F00  03480000  00215F00  03280000
     C*
     C* If each 4 byte hex part is converted to decimal you get:
     C*
     C*       2187008   55050240  2187008   52953088
     C*
     C**************************************************************
     C* Build the control vector by placing the decimal number in
     C* the appropriate half of the control vector field.
     C**************************************************************
     C                   Z-ADD     2187008       LEFTHALFA
     C                   Z-ADD     55050240      LEFTHALFB
     C                   MOVEL     LEFTHALF      KEYCV
     C                   Z-ADD     2187008       LEFTHALFA
     C                   Z-ADD     52953088      LEFTHALFB
     C                   MOVE      LEFTHALF      KEYCV
     C*
     C* Calculate the Token Validation value by adding every 4 bytes
     C* and storing the result in the last 4 bytes.
     C*
     C                   Z-ADD     0             KEYTVV
     C                   ADD       KEYTVV1       KEYTVV
     C                   ADD       KEYTVV2       KEYTVV
     C                   ADD       KEYTVV3       KEYTVV
     C                   ADD       KEYTVV4       KEYTVV
     C                   ADD       KEYTVV5       KEYTVV
     C                   ADD       KEYTVV6       KEYTVV
     C                   ADD       KEYTVV7       KEYTVV
     C                   ADD       KEYTVV8       KEYTVV
     C                   ADD       KEYTVV9       KEYTVV
     C                   ADD       KEYTVV10      KEYTVV
     C                   ADD       KEYTVV11      KEYTVV
     C                   ADD       KEYTVV12      KEYTVV
     C                   ADD       KEYTVV13      KEYTVV
     C                   ADD       KEYTVV14      KEYTVV
     C                   ADD       KEYTVV15      KEYTVV
     C*
     C* Copy token to IPINENC
     C*
     C                   MOVE      KEYTOKEN      IPINKEY
     C*
     C*
     C**************************************************************
     C* Build an OPINENC key token
     C*
     C* The control vector for an OPINENC key that
     C* has the key part flag set is (in hex):
     C*
     C*       00247700  03480000  00247700  03280000
     C*
     C* If each 4 byte hex part is converted to decimal you get:
     C*
     C*       2389760   55050240  2389760   52953088
     C*
     C**************************************************************
     C* Build the control vector by placing the decimal numbers in
     C* the appropriate half of the control vector field.
     C**************************************************************
     C                   Z-ADD     2389760       LEFTHALFA
     C                   Z-ADD     55050240      LEFTHALFB
     C                   MOVEL     LEFTHALF      KEYCV
     C                   Z-ADD     2389760       LEFTHALFA
     C                   Z-ADD     52953088      LEFTHALFB
     C                   MOVE      LEFTHALF      KEYCV
     C*
     C* Calculate the Token Validation value by adding every 4 bytes
     C* and storing the result in the last 4 bytes.
     C*
     C                   Z-ADD     0             KEYTVV
     C                   ADD       KEYTVV1       KEYTVV
     C                   ADD       KEYTVV2       KEYTVV
     C                   ADD       KEYTVV3       KEYTVV
     C                   ADD       KEYTVV4       KEYTVV
     C                   ADD       KEYTVV5       KEYTVV
     C                   ADD       KEYTVV6       KEYTVV
     C                   ADD       KEYTVV7       KEYTVV
     C                   ADD       KEYTVV8       KEYTVV
     C                   ADD       KEYTVV9       KEYTVV
     C                   ADD       KEYTVV10      KEYTVV
     C                   ADD       KEYTVV11      KEYTVV
     C                   ADD       KEYTVV12      KEYTVV
     C                   ADD       KEYTVV13      KEYTVV
     C                   ADD       KEYTVV14      KEYTVV
     C                   ADD       KEYTVV15      KEYTVV
     C*
     C* Copy token to OPINENC
     C*
     C                   MOVE      KEYTOKEN      OPINKEY
     C*
     C*
     C**************************************************************
     C*
     C* Clear key value for PINGEN/PINVER form will be:
     C*
     C*    01234567 01765432  01234567 01765432
     C*
     C* The key will be imported into two parts that get exclusived
     C* OR'ed together.  This program uses as key parts:
     C*
     C*    00224466 00775533  00224466 00775533  and
     C*
     C*    01010101 01010101  01010101 01010101
     C*
     C* Converting these to decimal results in
     C*
     C*    2245734  7820595   2245734  7820595  and
     C*
     C*    16843009 16843009  16843009 16843009
     C*
     C*  In this example, the left half of the key is the same as
     C*  the right half.  PIN keys in CCA are double length keys.
     C*  However, some implementation of DES (including Cryptographic
     C*  Support/400) use single length keys for PINs.  If both
     C*  halves of a double are the same, then they produce the
     C*  same output as a single length key, thereby allowing you
     C*  to exchange data with non-CCA systems.
     C**************************************************************
     C* Import the PINGEN key
     C*************************
     C                   MOVEL     'FIRST   '    RULEARRAY
     C                   Z-ADD     1             RULEARRAYCNT
     C**************************************************************
     C* Build the next clear key part by placing the decimal numbers
     C* in the appropriate half of the clear key field.
     C**************************************************************
     C                   Z-ADD     16843009      LEFTHALFA
     C                   Z-ADD     16843009      LEFTHALFB
     C                   MOVEL     LEFTHALF      CLEARKEY
     C                   MOVE      LEFTHALF      CLEARKEY
     C**************************************************************
     C*  Call Key Part Import the first time for the PINGEN key
     C**************************************************************
     C                   CALLP     CSNBKPI       (RETURNCODE:
     C                                            REASONCODE:
     C                                            EXITDATALEN:
     C                                            EXITDATA:
     C                                            RULEARRAYCNT:
     C                                            RULEARRAY:
     C                                            CLEARKEY:
     C                                            PINGENKEY)
     C     RETURNCODE    IFGT      4
     C                   MOVEL     'CSNBKPI'     FAILMESSAGE
     C                   EXSR      SNDFAILMSG
     C                   SETON                                            LR
     C                   ENDIF
     C**************************************************************
     C* Build the clear key part by placing the decimal number in
     C* the appropriate half of the clear key field.
     C**************************************************************
     C                   Z-ADD     2245734       LEFTHALFA
     C                   Z-ADD     7820595       LEFTHALFB
     C                   MOVEL     LEFTHALF      CLEARKEY
     C                   MOVE      LEFTHALF      CLEARKEY
     C**************************************************************
     C*  Call Key Part Import the second time for the PINGEN key
     C**************************************************************
     C                   MOVEL     'LAST    '    RULEARRAY
     C                   CALLP     CSNBKPI       (RETURNCODE:
     C                                            REASONCODE:
     C                                            EXITDATALEN:
     C                                            EXITDATA:
     C                                            RULEARRAYCNT:
     C                                            RULEARRAY:
     C                                            CLEARKEY:
     C                                            PINGENKEY)
     C     RETURNCODE    IFGT      4
     C                   MOVEL     'CSNBKPI'     FAILMESSAGE
     C                   EXSR      SNDFAILMSG
     C                   SETON                                            LR
     C                   ENDIF
     C**************************************************************
     C* Import the PINVER key *
     C*************************
     C                   MOVEL     'FIRST   '    RULEARRAY
     C                   Z-ADD     1             RULEARRAYCNT
     C                   Z-ADD     16843009      LEFTHALFA
     C                   Z-ADD     16843009      LEFTHALFB
     C                   MOVEL     LEFTHALF      CLEARKEY
     C                   MOVE      LEFTHALF      CLEARKEY
     C**************************************************************
     C*  Call Key Part Import the first time for the PINVER key
     C**************************************************************
     C                   CALLP     CSNBKPI       (RETURNCODE:
     C                                            REASONCODE:
     C                                            EXITDATALEN:
     C                                            EXITDATA:
     C                                            RULEARRAYCNT:
     C                                            RULEARRAY:
     C                                            CLEARKEY:
     C                                            PINVERKEY)
     C     RETURNCODE    IFGT      4
     C                   MOVEL     'CSNBKPI'     FAILMESSAGE
     C                   EXSR      SNDFAILMSG
     C                   SETON                                            LR
     C                   ENDIF
     C**************************************************************
     C* Build the clear key part by placing the decimal number in
     C* the appropriate half of the clear key field.
     C**************************************************************
     C                   Z-ADD     2245734       LEFTHALFA
     C                   Z-ADD     7820595       LEFTHALFB
     C                   MOVEL     LEFTHALF      CLEARKEY
     C                   MOVE      LEFTHALF      CLEARKEY
     C**************************************************************
     C*  Call Key Part Import the second time for the PINVER key
     C**************************************************************
     C                   MOVEL     'LAST    '    RULEARRAY
     C                   CALLP     CSNBKPI       (RETURNCODE:
     C                                            REASONCODE:
     C                                            EXITDATALEN:
     C                                            EXITDATA:
     C                                            RULEARRAYCNT:
     C                                            RULEARRAY:
     C                                            CLEARKEY:
     C                                            PINVERKEY)
     C     RETURNCODE    IFGT      4
     C                   MOVEL     'CSNBKPI'     FAILMESSAGE
     C                   EXSR      SNDFAILMSG
     C                   SETON                                            LR
     C                   ENDIF
     C**************************************************************
     C* Clear key value for IPINENC/OPINENC key pair will be:
     C*    012332EF 01020408  012332EF 01020408
     C*
     C* The key will be imported into two parts that get exclusived
     C* OR'ed together.  This program uses as key parts:
     C*
     C*    002233EE 00030509  002233EE 00030509  and
     C*
     C*    01010101 01010101  01010101 01010101
     C*
     C* Converting these to decimal results in
     C*
     C*    2241518  197897    2241518  197897   and
     C*
     C*    16843009 16843009  16843009 16843009
     C**************************************************************
     C* Import the PINVER key *
     C*************************
     C                   MOVEL     'FIRST   '    RULEARRAY
     C                   Z-ADD     1             RULEARRAYCNT
     C**************************************************************
     C* Build the clear key part by placing the decimal number in
     C* the appropriate half of the clear key field.
     C**************************************************************
     C                   Z-ADD     16843009      LEFTHALFA
     C                   Z-ADD     16843009      LEFTHALFB
     C                   MOVEL     LEFTHALF      CLEARKEY
     C                   MOVE      LEFTHALF      CLEARKEY
     C**************************************************************
     C*  Call Key Part Import the first time for the IPINENC key
     C**************************************************************
     C                   CALLP     CSNBKPI       (RETURNCODE:
     C                                            REASONCODE:
     C                                            EXITDATALEN:
     C                                            EXITDATA:
     C                                            RULEARRAYCNT:
     C                                            RULEARRAY:
     C                                            CLEARKEY:
     C                                            IPINKEY)
     C     RETURNCODE    IFGT      4
     C                   MOVEL     'CSNBKPI'     FAILMESSAGE
     C                   EXSR      SNDFAILMSG
     C                   SETON                                            LR
     C                   ENDIF
     C**************************************************************
     C* Build the clear key part by placing the decimal number in
     C* the appropriate half of the clear key field.
     C**************************************************************
     C                   Z-ADD     2241518       LEFTHALFA
     C                   Z-ADD     197897        LEFTHALFB
     C                   MOVEL     LEFTHALF      CLEARKEY
     C                   MOVE      LEFTHALF      CLEARKEY
     C**************************************************************
     C*  Call Key Part Import the second time for the IPINENC key
     C**************************************************************
     C                   MOVEL     'LAST    '    RULEARRAY
     C                   CALLP     CSNBKPI       (RETURNCODE:
     C                                            REASONCODE:
     C                                            EXITDATALEN:
     C                                            EXITDATA:
     C                                            RULEARRAYCNT:
     C                                            RULEARRAY:
     C                                            CLEARKEY:
     C                                            IPINKEY)
     C     RETURNCODE    IFGT      4
     C                   MOVEL     'CSNBKPI'     FAILMESSAGE
     C                   EXSR      SNDFAILMSG
     C                   SETON                                            LR
     C                   ENDIF
     C**************************************************************
     C* Import the OPINENC key *
     C*************************
     C                   MOVEL     'FIRST   '    RULEARRAY
     C                   Z-ADD     1             RULEARRAYCNT
     C**************************************************************
     C* Build the clear key part by placing the decimal number in
     C* the appropriate half of the clear key field.
     C**************************************************************
     C                   Z-ADD     16843009      LEFTHALFA
     C                   Z-ADD     16843009      LEFTHALFB
     C                   MOVEL     LEFTHALF      CLEARKEY
     C                   MOVE      LEFTHALF      CLEARKEY
     C**************************************************************
     C*  Call Key Part Import the first time for the OPINENC key
     C**************************************************************
     C                   CALLP     CSNBKPI       (RETURNCODE:
     C                                            REASONCODE:
     C                                            EXITDATALEN:
     C                                            EXITDATA:
     C                                            RULEARRAYCNT:
     C                                            RULEARRAY:
     C                                            CLEARKEY:
     C                                            OPINKEY)
     C     RETURNCODE    IFGT      4
     C                   MOVEL     'CSNBKPI'     FAILMESSAGE
     C                   EXSR      SNDFAILMSG
     C                   SETON                                            LR
     C                   ENDIF
     C**************************************************************
     C* Build the clear key part by placing the decimal number in
     C* the appropriate half of the clear key field.
     C**************************************************************
     C                   Z-ADD     2241518       LEFTHALFA
     C                   Z-ADD     197897        LEFTHALFB
     C                   MOVEL     LEFTHALF      CLEARKEY
     C                   MOVE      LEFTHALF      CLEARKEY
     C**************************************************************
     C*  Call Key Part Import the second time for the OPINENC key
     C**************************************************************
     C                   MOVEL     'LAST    '    RULEARRAY
     C                   CALLP     CSNBKPI       (RETURNCODE:
     C                                            REASONCODE:
     C                                            EXITDATALEN:
     C                                            EXITDATA:
     C                                            RULEARRAYCNT:
     C                                            RULEARRAY:
     C                                            CLEARKEY:
     C                                            OPINKEY)
     C     RETURNCODE    IFGT      4
     C                   MOVEL     'CSNBKPI'     FAILMESSAGE
     C                   EXSR      SNDFAILMSG
     C                   SETON                                            LR
     C                   ENDIF
     C*
     C**************************************************************
     C* Generate a Clear PIN with CSNBPGN (Clear_PIN_Generate)
     C*  Rule_array_count = 1
     C*  Rule_array = "IBM-PIN "   (Same as Crypto Support/400)
     C*  PIN length = 8
     C*  PIN Check length = 8  (But is ignored for IBM-PIN)
     C*  Data array:
     C*     Dec. table set to  0123456789123456
     C*     validation dta =   1111222233334444
     C*     clear PIN   =  ignored
     C**************************************************************
     C                   Z-ADD     1             RULEARRAYCNT
     C                   MOVEL     'IBM-PIN '    RULEARRAY
     C                   Z-ADD     8             PINLEN
     C                   Z-ADD     8             PINCKL
     C                   MOVEL     '01234567'    DECTABLE
     C                   MOVE      '89123456'    DECTABLE
     C                   MOVEL     '11112222'    VALDATA
     C                   MOVE      '33334444'    VALDATA
     C**************************************************************
     C*  Call Clear PIN Generate
     C**************************************************************
     C                   CALLP     CSNBPGN       (RETURNCODE:
     C                                            REASONCODE:
     C                                            EXITDATALEN:
     C                                            EXITDATA:
     C                                            PINGENKEY:
     C                                            RULEARRAYCNT:
     C                                            RULEARRAY:
     C                                            PINLEN:
     C                                            PINCKL:
     C                                            DATAARRAY:
     C                                            CPIN)
     C     RETURNCODE    IFGT      4
     C                   MOVEL     'CSNBPGN'     FAILMESSAGE
     C                   EXSR      SNDFAILMSG
     C                   SETON                                            LR
     C                   ENDIF
     C*
     C*
     C**************************************************************
     C* Encrypt the clear PIN using CSNBCPE (Clear_PIN_Encrypt)
     C*  Rule_array_count = 1
     C*  Rule_array = "ENCRYPT "
     C*  PIN Profile = "3624    NONE           F"
     C*  PAN data is ignored
     C*  Sequence number is ignored but set to 99999 anyway
     C**************************************************************
     C                   Z-ADD     1             RULEARRAYCNT
     C                   MOVEL     'ENCRYPT '    RULEARRAY
     C                   MOVEL     '3624    '    PINFORMAT
     C                   MOVE      'NONE    '    FORMATCONTROL
     C                   MOVE      '       F'    PADDIGIT
     C                   Z-ADD     99999         SEQNUMBER
     C**************************************************************
     C*  Call Clear PIN Encrypt
     C**************************************************************
     C                   CALLP     CSNBCPE       (RETURNCODE:
     C                                            REASONCODE:
     C                                            EXITDATALEN:
     C                                            EXITDATA:
     C                                            OPINKEY:
     C                                            RULEARRAYCNT:
     C                                            RULEARRAY:
     C                                            CPIN:
     C                                            PROFILE:
     C                                            PAN:
     C                                            SEQNUMBER:
     C                                            EPIN)
     C     RETURNCODE    IFGT      4
     C                   MOVEL     'CSNBCPE'     FAILMESSAGE
     C                   EXSR      SNDFAILMSG
     C                   SETON                                            LR
     C                   ENDIF
     C*
     C*
     C**************************************************************
     C* Verify encrypted PIN using CSNBPVR (Encrypted_PIN_Verify)
     C**************************************************************
     C                   MOVEL     'IBM-PIN '    RULEARRAY
     C
     C                   CALLP     CSNBPVR       (RETURNCODE:
     C                                            REASONCODE:
     C                                            EXITDATALEN:
     C                                            EXITDATA:
     C                                            IPINKEY:
     C                                            PINVERKEY:
     C                                            PROFILE:
     C                                            PAN:
     C                                            EPIN:
     C                                            RULEARRAYCNT:
     C                                            RULEARRAY:
     C                                            PINCKL:
     C                                            DATAARRAY)
     C     RETURNCODE    IFGT      4
     C                   MOVEL     'CSNBPVR'     FAILMESSAGE
     C                   EXSR      SNDFAILMSG
     C                   SETON                                            LR
     C                   ENDIF
     C*
     C**************************************************************
     C* Send successful completion message
     C**************************************************************
     C                   CALL      'QMHSNDPM'
     C                   PARM                    MESSAGEID
     C                   PARM                    MESSAGEFILE
     C                   PARM                    GOODMESSAGE
     C                   PARM                    GOODMSGLENGTH
     C                   PARM                    MSGTYPE
     C                   PARM                    STACKENTRY
     C                   PARM                    STACKCOUNTER
     C                   PARM                    MSGKEY
     C                   PARM                    ERRCODE
     C*
     C                   SETON                                            LR
     C*
     C**************************************************************
     C* Subroutine to send a failure message
     C**************************************************************
     C     SNDFAILMSG    BEGSR
     C                   MOVE      FAILMESSAGE   FAILMSGTEXT
     C                   MOVE      RETURNCODE    FAILRETC
     C                   MOVE      REASONCODE    FAILRSNC
     C                   CALL      'QMHSNDPM'
     C                   PARM                    MESSAGEID
     C                   PARM                    MESSAGEFILE
     C                   PARM                    FAILMSG
     C                   PARM                    FAILMSGLENGTH
     C                   PARM                    MSGTYPE
     C                   PARM                    STACKENTRY
     C                   PARM                    STACKCOUNTER
     C                   PARM                    MSGKEY
     C                   PARM                    ERRCODE
     C                   ENDSR