       IDENTIFICATION DIVISION.
       PROGRAM-ID.  SOFCRHSH.
       AUTHOR.      LIMES DATENTECHNIK GMBH.

      *           EXAMPLE FOR USING HASH AND MAC FUNCTIONS
      *
      *  THE USE OF THE PROGRAM IS DOCUMENTED IN THE CORRESPONDING
      *  JOBLIB MEMBER.
      *

       ENVIRONMENT DIVISION.

       INPUT-OUTPUT SECTION.

       DATA DIVISION.

       WORKING-STORAGE SECTION.
       77  F-HTMD                      PIC   9(8) COMP.
           88  FLCHSH-ALGO-NON         value           0.
           88  FLCHSH-ALGO-MD5         value           1.
           88  FLCHSH-ALGO-RMD128      value           2.
           88  FLCHSH-ALGO-RMD160      value           3.
           88  FLCHSH-ALGO-SHA1        value          10.
           88  FLCHSH-ALGO-SHA160      value          10.
           88  FLCHSH-ALGO-SHA224      value          20.
           88  FLCHSH-ALGO-SHA256      value          21.
           88  FLCHSH-ALGO-SHA384      value          22.
           88  FLCHSH-ALGO-SHA512      value          23.
           88  FLCHSH-ALGO-CRC08       value         100.
           88  FLCHSH-ALGO-CRC16       value         101.
           88  FLCHSH-ALGO-CRC24       value         102.
           88  FLCHSH-ALGO-CRC32       value         103.
           88  FLCHSH-ALGO-CRC32C      value         104.
           88  FLCHSH-ALGO-CRC40       value         105.
           88  FLCHSH-ALGO-CRC64       value         106.
       77  F-KTMD                        PIC 9(8)  COMP.
           88  FLCMAC-ALGO-NON         value           0.
           88  FLCMAC-ALGO-HMAC        value           1.
       77  F-HMK0                        PIC 9(8)  COMP VALUE 3.
       77  F-HMKSTRING                   PIC X(10) VALUE X'616263'.
       77  F-INP0                        PIC 9(8)  COMP VALUE 3.
       77  F-INPSTRING                   PIC X(10) VALUE X'616263'.
       77  F-ICV0                        PIC 9(8)  COMP VALUE 0.
       77  F-ICVSTRING                   PIC X(10) VALUE ' '.
       77  F-HSH0                        PIC 9(8)  COMP VALUE 1024.
       77  F-HSHSTRING                   PIC X(1024).
       77  WX-HSH1                       PIC X(1024).
       77  WX-HSH2                       PIC X(1024).
       77  WX-CMPHSH                     PIC X(1024).
       77  WX-MAC0-SHA256         PIC X(32) VALUE X'2f02e24ae2e1fe880399
      -    'f27600afa88364e6062bf9bbe114b32fa8f23d03608a'.
       77  WX-MAC0-SHA512         PIC X(64) VALUE X"ddaf35a193617abacc41
      -    "7349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a8
      -    "36ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f".

       77  HEXDATA                       PIC X(1024).
       77  HEXVAL                        PIC X(2048).
       77  HEXSTR                    PIC X(16) VALUE "0123456789ABCDEF".
       01  DEC                           PIC S9(4) COMP.
       01  FILLER   REDEFINES DEC.
           02  FILLER                    PIC X.
           02  DECBYTE                   PIC X.
       01  I                         PIC S9(8) COMP.
       01  J                         PIC S9(8) COMP.
       01  Q                         PIC S9(8) COMP.
       01  R                         PIC S9(8) COMP.
       01  J1                        PIC S9(8) COMP.
       01  Q1                        PIC S9(8) COMP.
       01  R1                        PIC S9(8) COMP.


       77  MAXTRCLEN                     PIC 9(8)  COMP VALUE 4096.

       77  OPERATION                     PIC X(30).
           88 OPERATION-HASH             VALUE 'DO-HASH'.
           88 OPERATION-INIT             VALUE 'INIT-HASH'.
           88 OPERATION-ADD-HASH         VALUE 'ADD-HASH'.
           88 OPERATION-FINISH           VALUE 'FINISH-HASH'.

       77  DISP-LEN                      PIC 9(8)  COMP VALUE ZERO.
       77  DISP-AREA                     PIC X(4096).
       77  DISP-DLM                      PIC X.
       77  DISP-PTR                      PIC 9(8)  COMP VALUE 1.
       77  DISP-NUM                      PIC ZZZZZZZ9.

      *    ALL CALLS
       01  F-RETCO                    PIC S9(8) COMP  VALUE 0.
           88 F-RETCO-OK              VALUE  0.
           88 F-RETCO-END-OF-FILE     VALUE  43.
           88 F-RETCO-END-OF-TABLE    VALUE  138.

      *    ALL INPUT CALLS
       01  F-ID-HSH                    PIC S9(8) COMP.

      *    FCRTRC
       01  TRCRC                      PIC S9(8) COMP.
       01  TRCLEN                     PIC S9(8) COMP VALUE 4096.
       01  TRCBUFF                    PIC X(4096) VALUE SPACES.


       LINKAGE SECTION.

       01  DISP-BUFFER                PIC X(65536).

       PROCEDURE DIVISION.

      *----------------------------------------------------------------
      *    Main
      *----------------------------------------------------------------

       MAIN SECTION.
           DISPLAY 'start on console ...' UPON CONSOLE
           DISPLAY 'now calculate SHA256 ...' UPON CONSOLE

           MOVE LOW-VALUE TO WX-CMPHSH
           MOVE WX-MAC0-SHA256 TO WX-CMPHSH
           MOVE LOW-VALUE TO F-HSHSTRING

           PERFORM S-FLUC-HASH
           PERFORM S-FLUC-PROTOCOL
           PERFORM S-HASH-COMPARE

           DISPLAY 'now calculate SHA512 ...' UPON CONSOLE
      *     MOVE F-HSHSTRING TO WX-CMPHSH
      *     MOVE WX-MAC0   TO WX-CMPHSH
           MOVE WX-MAC0-SHA512 TO WX-CMPHSH
           MOVE LOW-VALUE TO F-HSHSTRING

           PERFORM S-FLUC-INIT-HASH
           PERFORM S-FLUC-ADD-HASH
           PERFORM S-FLUC-FINI-HASH

           PERFORM S-FLUC-PROTOCOL
           PERFORM S-HASH-COMPARE

           MOVE F-RETCO TO RETURN-CODE

           STOP RUN.

      *----------------------------------------------------------------
      *    Routinen
      *----------------------------------------------------------------

      * Call FLUC record interface to calculate hash
       S-FLUC-HASH SECTION.

           SET OPERATION-HASH TO TRUE
           SET FLCHSH-ALGO-SHA256 TO TRUE
           SET FLCMAC-ALGO-HMAC TO TRUE
           MOVE 1024 TO F-HSH0

           CALL 'FCRHASH' USING F-HTMD, F-KTMD,
                                F-HMK0, F-HMKSTRING,
                                F-ICV0, F-ICVSTRING,
                                F-INP0, F-INPSTRING,
                                F-HSH0, F-HSHSTRING
                          RETURNING F-RETCO

           PERFORM T-FLUC-RC
           MOVE F-HSHSTRING TO WX-HSH1

           EXIT.

      * Call FLUC record interface to init hash
       S-FLUC-INIT-HASH SECTION.

           SET OPERATION-INIT TO TRUE
           SET FLCHSH-ALGO-SHA512 TO TRUE
           SET FLCMAC-ALGO-NON TO TRUE

           CALL 'FCRHINI'  USING F-ID-HSH, F-HTMD, F-KTMD,
                                F-HMK0, F-HMKSTRING,
                                F-ICV0, F-ICVSTRING
                           RETURNING F-RETCO

           PERFORM T-FLUC-RC

           EXIT.

      * Call FLUC record interface to add data to hash
       S-FLUC-ADD-HASH SECTION.

           SET OPERATION-ADD-HASH TO TRUE

           CALL 'FCRHADD' USING F-ID-HSH, F-INP0, F-INPSTRING
                          RETURNING F-RETCO

           PERFORM T-FLUC-RC

           EXIT.

      * Call FLUC record interface to finish hash
       S-FLUC-FINI-HASH SECTION.

           SET OPERATION-FINISH TO TRUE
           MOVE 1024 TO F-HSH0

           CALL 'FCRHFIN' USING F-ID-HSH, F-HSH0, F-HSHSTRING
                                RETURNING F-RETCO

           PERFORM T-FLUC-RC
           MOVE F-HSHSTRING TO WX-HSH2

           EXIT.


      * Write protocol summary
       S-FLUC-PROTOCOL SECTION.

           MOVE F-HSHSTRING TO HEXDATA
           PERFORM S-HASH-CONVERT
           COMPUTE J = 2 * F-HSH0
           DISPLAY 'HASH(' F-HSH0 '): ' HEXVAL(1:J) UPON CONSOLE
           DISPLAY SPACE UPON CONSOLE

           MOVE F-RETCO  TO DISP-NUM
           DISPLAY OPERATION 'SOFCRHSH ENDS WITH RC ' DISP-NUM
                   UPON CONSOLE

           EXIT.

      * Compare hashes
       S-HASH-COMPARE SECTION.

           IF F-HSHSTRING(1:F-HSH0) NOT = WX-CMPHSH(1:F-HSH0)
               MOVE WX-CMPHSH TO HEXDATA
               PERFORM S-HASH-CONVERT
               COMPUTE J = 2 * F-HSH0
               DISPLAY 'hash is wrong, expected is:' UPON CONSOLE
               DISPLAY 'HASH: ' HEXVAL(1:J) UPON CONSOLE
           ELSE
               DISPLAY 'hash is correct' UPON CONSOLE
           END-IF.

           EXIT.

       S-HASH-CONVERT SECTION.
           PERFORM VARYING I FROM 1 BY 1 UNTIL I > F-HSH0
      *     PERFORM VARYING I FROM 1 BY 1 UNTIL I > LENGTH OF HEXDATA
               COMPUTE J = 2 * I - 1
               MOVE HEXDATA(I:1) TO DECBYTE
               DIVIDE DEC BY 16 GIVING Q REMAINDER R
               COMPUTE J1 = J + 1
               COMPUTE Q1 = Q + 1
               COMPUTE R1 = R + 1
               MOVE HEXSTR(Q1:1) TO HEXVAL(J:1)
               MOVE HEXSTR(R1:1) TO HEXVAL(J1:1)
           END-PERFORM.
           EXIT.
      *----------------------------------------------------------------
      *    Sub-Routinen
      *----------------------------------------------------------------

       T-FLUC-RC SECTION.

           EVALUATE TRUE
           WHEN F-RETCO-OK
              CONTINUE
           WHEN OTHER
              PERFORM U-FLUC-RC-ERROR
           END-EVALUATE

           EXIT.


      *----------------------------------------------------------------
      *    Sub-Routinen
      *----------------------------------------------------------------

       U-FLUC-RC-ERROR SECTION.

           PERFORM V-FLUC-RC-ERROR-RETCO

           PERFORM V-FLUC-RC-ERROR-TRACE

           SET ADDRESS OF DISP-BUFFER TO ADDRESS OF TRCBUFF
           PERFORM V-FLUC-DISP-BUFFER

           MOVE F-RETCO TO RETURN-CODE

           STOP RUN.

      *----------------------------------------------------------------
      *    Sub-Routinen
      *----------------------------------------------------------------

       V-FLUC-RC-ERROR-RETCO SECTION.

           DISPLAY 'SOFCRHSH: ERROR IN OPERATION ' OPERATION
                    UPON CONSOLE

           COMPUTE DISP-NUM = F-RETCO

           DISPLAY 'RETURNCODE: ' DISP-NUM UPON CONSOLE

           EXIT.

       V-FLUC-RC-ERROR-TRACE SECTION.

           COMPUTE TRCLEN = MAXTRCLEN

      *    Get the error trace from FLUC record interface
           CALL 'FCRTRC' USING TRCRC, F-RETCO,
                               TRCLEN, TRCBUFF

           DISPLAY 'ERROR MESSAGE FROM FLUC:' UPON CONSOLE

           COMPUTE DISP-NUM = TRCRC
           DISPLAY 'TRCRC : ' DISP-NUM UPON CONSOLE

           COMPUTE DISP-NUM = TRCLEN
           DISPLAY 'TRCLEN: ' DISP-NUM UPON CONSOLE

           EXIT.

       V-FLUC-DISP-BUFFER SECTION.

           COMPUTE DISP-PTR = 1
           COMPUTE DISP-LEN = ZERO

           PERFORM W-FLUC-DISP-BUFFER

           PERFORM UNTIL DISP-DLM NOT = X'15'
              PERFORM W-FLUC-DISP-BUFFER
           END-PERFORM

           DISPLAY SPACE UPON CONSOLE

           EXIT.

      *----------------------------------------------------------------
      *    Sub-Routinen
      *----------------------------------------------------------------

       W-FLUC-DISP-BUFFER SECTION.

           UNSTRING DISP-BUFFER DELIMITED BY X'15' OR X'00'
               INTO DISP-AREA DELIMITER DISP-DLM COUNT DISP-LEN
               WITH POINTER DISP-PTR

           DISPLAY DISP-AREA(1:DISP-LEN) UPON CONSOLE

           EXIT.
