Skip to Content

Hello community,

with the random number generator offers Intel a powerful possibility to use a secure way to create random numbers on a hardware base. You can find more information here. Unfortunately it is not direct possible to use this kind of code inside of ABAP. I presented here an example how to use ANSI C inside ABAP. On the same way it is possible to use assembler code inside ABAP. Here an example how to use the RDRAND instruction inside ABAP via FBSLs assembler layer.

At first we check the availability via CPUID instruction. If it is successful, we call the instruction via the opcodes. To receive the text of OutputDebugString use DebugView.

We begin with the assembler include:

;-Begin-----------------------------------------------------------------

  .data
    @FeatureFlagsECX dd 0
    @RandomNumber dd 0
    @NumberFormat db "%ld",0
    @strNumber db 20 dup 0
    @msgRDRAND db "Random number generator on-chip",0

  .code
    enter 0, 0

    ;-Checks the availability of CPUID instruction----------------------
      pushfd
      pop eax
      mov ebx, eax
      xor eax, &H00200000
      push eax
      popfd
      pushfd
      pop eax

    ;-If CPUID is available---------------------------------------------
      .if eax <> ebx

       ;-Feature information-------------------------------------------
          mov eax, 1
          cpuid
          mov [FeatureFlagsECX], ecx

          clc
          bt [FeatureFlagsECX], 30
          jnc Next
            invoke OutputDebugString, msgRDRAND

            ;-rdrand eax as opcodes-------------------------------------
              db &H0F, &HC7, &HF0
            jnc Next
              mov [RandomNumber], eax
              ;-Convert number to string--------------------------------
                invoke wsprintf, strNumber, NumberFormat, [RandomNumber]
              invoke OutputDebugString, strNumber

          @Next

      .endif

    mov eax, [RandomNumber]
    leave
    ret

;-End-------------------------------------------------------------------

Here the ABAP report:

"-Begin-----------------------------------------------------------------
  Program ZASSEMBLER.

    "-Constants---------------------------------------------------------
      Constants SW_SHOWNORMAL Type i Value 1.

    "-Variables---------------------------------------------------------
      Data oScriptX Type OLE2_OBJECT.
      Data Buffer Type String Value ''.
      Data WorkDir Type String Value ''.
      Data WinInc Type String Value ''.
      Data FileName Type String Value ''.
      Data rc Type i Value 0.
      Data hFileMap Type i Value 0.
      Data ProcID Type i Value 0.
      Data InclCode Type String Value ''.
      Data FBSLFileName Type String Value 'RandomNumber.fbs'.
      Data rcRandomNumber Type String Value ''.
      Data RandomNumber Type i Value 0.

    "-Macros------------------------------------------------------------
      Define _.
        Concatenate Buffer &1 cl_abap_char_utilities=>cr_lf Into Buffer.
      End-Of-Definition.

      Define Flush.
        Call Function 'AC_SYSTEM_FLUSH' Exceptions Others = 1.
      End-Of-Definition.

    "-Main--------------------------------------------------------------
      Create Object oScriptX 'ScriptX'.
      If sy-subrc <> 0 Or  oScriptX-Handle = 0 Or oScriptX-Type <> 'OLE2'.
        Call Function 'ZSCRIPTXDLL'.
        Create Object oScriptX 'ScriptX'.
      EndIf.

      If sy-subrc = 0 And oScriptX-Handle > 0 And oScriptX-Type = 'OLE2'.

        "-Show messages in system debugger, e.g. DebugView--------------
          Set Property Of oScriptX 'DebugOutput' = 1.

        "-Get SAP GUIs work directory-----------------------------------
          Call Method cl_gui_frontend_services=>get_sapgui_workdir
            Changing SAPWORKDIR = WorkDir Exceptions Others = 1.
          Set Property Of oScriptX 'CurrentDirectory' = WorkDir.

        Concatenate '#Include "' WorkDir '\Include\Windows.inc"'
          Into WinInc.

        Call Method Of oScriptX 'ExtractFbslExe'.

        Call Method Of oScriptX 'ExtractFbslWinInc'.

        Call Method Of oScriptX 'FileMapCreate' = hFileMap
          Exporting #1 = 'SAP001' #2 = 32.

        If hFileMap <> 0.

"-FBSL script begin-----------------------------------------------------

  "-Directives----------------------------------------------------------
  _ '#AppType GUI'.
  _ '#Option Strict'.
  _ WinInc.

  "-Function Assembler--------------------------------------------------
  _ 'DynAsm RandomNumber() As Long'.

    "-Read Assembler code from include file-----------------------------
      Call Function 'ZREADINCLASSTRING'
        Exporting I_InclName = 'ZASM_INC'
        Importing E_strIncl = InclCode.
      _ InclCode.

  _ 'End DynAsm'.

  "-Sub RC--------------------------------------------------------------
  _ 'Sub RC(ByVal FileMapName As String, ByVal RetCode As String)'.
  _ '  Dim hMMF As Long'.
  _ '  Dim Buffer As Long'.
  _ '  Dim Temp As String'.
  _ '  hMMF = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, FileMapName)'.
  _ '  If hMMF Then'.
  _ '    Buffer = MapViewOfFile(hMMF, FILE_MAP_ALL_ACCESS, 0, 0, 0)'.
  _ '    If Buffer Then'.
  _ '      Poke(Buffer, RetCode)'.
  _ '      UnmapViewOffile(Buffer)'.
  _ '    End If'.
  _ '    CloseHandle(hMMF)'.
  _ '  End If'.
  _ 'End Sub'.

  "-Main----------------------------------------------------------------
  _ 'Sub Main()'.
  _ '  RC("SAP001", RandomNumber())'.
  _ 'End Sub'.

"-FBSL script end-------------------------------------------------------

          Concatenate WorkDir '\' FBSLFileName Into FileName.
          Call Method Of oScriptX 'WriteFile' Exporting #1 = FileName
            #2 = Buffer.
          Flush.

          Concatenate '"' FileName '"' Into FileName.
          Call Method Of oScriptX 'Shell' = ProcID Exporting
            #1 = 'Fbsl.exe' #2 = FileName
            #3 = SW_SHOWNORMAL #4 = 1.
          Flush.
          Replace All Occurrences Of '"' In FileName With ''.

          Call Method Of oScriptX 'FileMapRead' = rcRandomNumber
            Exporting #1 = 'SAP001' #2 = 32.
          Flush.

          "-Delete files------------------------------------------------
            Call Method Of oScriptX 'DeleteFileA'
              Exporting #1 = FileName.

            Call Method Of oScriptX 'DeleteFileA'
              Exporting #1 = 'Fbsl.exe'.
            Call Method Of oScriptX 'DeleteDirectory'
              Exporting #1 = 'Include'.
            Flush.

         RandomNumber = rcRandomNumber.
         Write: / RandomNumber.

         Call Method Of oScriptX 'FileMapClose' = rc
            Exporting #1 = hFileMap.
          Flush.

        EndIf.

        Free Object oScriptX.
      EndIf.

"-End-------------------------------------------------------------------

To execute this code you need ScriptX, which I introduced here.

As you can see it is possible to use Intel-style assembler code inside ABAP. In my case I need the CPU functions for doument management, here for creating (security) keys, AES chiffres and CRC checks,

Enjoy the code.

Cheers
Stefan

To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

  1. Holger Stumm

    Great article and a complete new view on ABAP Tools of the trade – I gladly add this to my arsenal.  You are right, especially in Cryptography, you need barebone System function and ressources.

    But one word of caution with RDRAND – there was (and is) a large discussion of this algorithm..

    Look at the WIKI discussion http://en.wikipedia.org/wiki/RdRand and you can research (and decide) , if this is a concern for using this algorithm.

    (0) 

Leave a Reply