Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Key derivation functions KDF1, KDF2, KDF3 (ISO-18033-2)

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • PBWin/PBCC Key derivation functions KDF1, KDF2, KDF3 (ISO-18033-2)

    See also - Password-based key derivation functions - PBKDF1, PBKDF2 (PKCS5 v2.0)
    ---

    In cryptography, a key derivation function (or KDF) derives one or more secret keys from a secret value such as a master key or other known information such as a password or passphrase using a pseudo-random function. - http://en.wikipedia.org/wiki/Key_derivation_function


    KDF.BAS
    Code:
    #COMPILE EXE
    
    #INCLUDE "SHA-1.inc"
    %hLen = (160 / 8)   '// hLen = number of octets output by the hash PRF. Here we use SHA-1 which is 160-bit.
    
    
    FUNCTION Hash(sInput AS STRING) AS STRING
     LOCAL SHA AS tSHA
     CalcSHA sInput, SHA
     FUNCTION = PEEK$(VARPTR(SHA), %hLen)
    END FUNCTION
    
    
    FUNCTION BMKDWD(BYVAL dwx AS DWORD) AS STRING   '// Dword-to-string (big-endian)
    #REGISTER NONE
    LOCAL sDwd AS STRING * 4, dwPtr AS DWORD: dwPtr = VARPTR(sDwd)
    ! mov eax, dwx
    ! bswap eax
    ! mov esi, dwPtr
    ! mov [esi], eax
    FUNCTION = sDwd
    END FUNCTION
    
    
    '--------------------------------------------------------------------------------------------------------------
    
    '// KDF1 is defined in ISO-18033-2 and is the same as the MGF1 function from IEEE P1363a and PKCS#1 v2.1.
    FUNCTION KDF1 (sSecret AS STRING, BYVAL dkLen AS DWORD, sOtherInfo AS STRING) AS STRING
     LOCAL Counter AS LONG, T AS STRING, C AS STRING * 4
     FOR Counter = 0 TO CEIL((dkLen + %hLen - 1) \ %hLen) - 1
         C = BMKDWD(Counter)
         T = T & Hash(sSecret & C & sOtherInfo)
     NEXT Counter
     FUNCTION = LEFT$(T, dkLen)
    END FUNCTION
    
    
    '// KDF2 is the same as KDF1 except the counter runs from 1 to d. It is defined in ISO-18033-2,
    '// and is the same as the KDF based on concatenation algorithm in Section 7.7.2 of ANSI X9.42
    FUNCTION KDF2 (sSecret AS STRING, BYVAL dkLen AS DWORD, sOtherInfo AS STRING) AS STRING
     LOCAL Counter AS LONG, T AS STRING, C AS STRING * 4
     FOR Counter = 1 TO CEIL((dkLen + %hLen - 1) \ %hLen)
         C = BMKDWD(Counter)
         T = T & Hash(sSecret & C & sOtherInfo)
     NEXT Counter
     FUNCTION = LEFT$(T, dkLen)
    END FUNCTION
    
    
    '// KDF3 is defined in ISO-18033-2 [ISO18033] and uses essentially the same algorithm as the KDF function in NIST SP800-56A.
    '// In the ISO-18033-2 version, KDF3 has an additional parameter pAmt, an integer of value 4 or more.
    '// It is recommended that this value is either 4 or is the length of the input block to the Hash function (64 for SHA-1).
    '// The NIST version has pAmt equal to 4 and has stricter, non-optional rules for the OtherInfo parameter.
    FUNCTION KDF3 (sSecret AS STRING, BYVAL dkLen AS DWORD, sOtherInfo AS STRING, BYVAL pAmt AS DWORD) AS STRING
     LOCAL T AS STRING, Counter AS DWORD, C AS STRING
     FOR Counter = 0 TO CEIL((dkLen + %hLen - 1) \ %hLen) - 1
         C = RIGHT$(REPEAT$(pAmt,CHR$(0)) & BMKDWD(Counter), pAmt)
         T = T & Hash(C & sSecret & sOtherInfo)
     NEXT Counter
     FUNCTION = LEFT$(T, dkLen)
    END FUNCTION
    
    
    'FUNCTION KDF4 ...
    ' KDF4 is defined in ISO-18033-2. It uses a Hash function and requires a deterministic pseudo-random byte generator (PRBG) function
    ' which takes an input seed of length equal to hLen and outputs a random-looking, but pre-determined, byte string of length kLen.
    ' To our knowledge, KDF4 is not in common use, if it is at all.  - http://www.di-mgt.com.au/cryptoKDFs.html#kdf4
    '   KDF4 derived key = PRBG(Hash(sSecret), dkLen)
    'END FUNCTION
    
    
    '--------------------------------------------------------------------------------------------------------------
    
    
    FUNCTION StrToHex$(sStr AS STRING)
     LOCAL bPtr AS BYTE PTR, sHex AS STRING
     IF LEN(sStr) = 0 THEN EXIT FUNCTION
     FOR bPtr = STRPTR(sStr) TO STRPTR(sStr) + LEN(sStr) - 1: sHex = sHex & HEX$(@bPtr,2): NEXT
     FUNCTION = LCASE$(sHex)
    END FUNCTION
    
    
    FUNCTION PBMAIN() AS LONG
     LOCAL sSecret AS STRING, sOtherInfo AS STRING, dkLen AS DWORD
    
     'The example parameters used here for testing are from http://www.di-mgt.com.au/cryptoKDFs.html
     sSecret = CHR$(&hDE,&hAD,&hBE,&hEF,&hFE,&hEB,&hDA,&hED)
     sOtherInfo = ""
     dkLen = (256 / 8)   'How many octets we want the derived key to be. For a 256-bit key, dkLen = 32 octets
    
     ? "KDF1 key = " & StrToHex$( KDF1(sSecret, BYVAL dkLen, sOtherInfo) )
     ? "KDF2 key = " & StrToHex$( KDF2(sSecret, BYVAL dkLen, sOtherInfo) )
     ? "KDF3 key = " & StrToHex$( KDF3(sSecret, BYVAL dkLen, sOtherInfo, 4) )
    
     WAITKEY$
    END FUNCTION
    SHA-1.inc
    Code:
    '// SHA-1, 160-bit cryptographic hash algorithm
    '// PB x86 implementation by Semen Matusovski, November 2000
    '// Original: http://www.powerbasic.com/support/pbforums/showthread.php?t=023371
    
    TYPE tSHA    '160-bit hash
       H0 AS LONG
       H1 AS LONG
       H2 AS LONG
       H3 AS LONG
       H4 AS LONG
    END TYPE
    
    FUNCTION CalcSHA (Str AS STRING, SHA AS tSHA) AS LONG
     #REGISTER NONE
      DIM lStr AS LONG, nq AS LONG, n AS LONG, adrW AS LONG, adrWW AS LONG
      DIM H0 AS LONG, H1 AS LONG, H2 AS LONG, H3 AS LONG, H4 AS LONG, W(0 TO 79) AS LONG
      DIM A AS LONG, B AS LONG, C AS LONG, D AS LONG, E AS LONG, TEMP AS LONG
    
      lStr = LEN(Str)
      nq = FIX((lStr + 8) / 64) + 1
      n = 16 * nq
      REDIM WW(0 TO n - 1) AS LONG
      WW(n - 1) = lStr * 8
      adrW = VARPTR(W(0))
      adrWW = VARPTR(WW(0))
      A = STRPTR(Str)
    
      ! PUSH EDI
      ! PUSH ESI
    
      ! MOV EDI, adrWW
      ! MOV ESI, A
      ! MOV ECX, lStr
      ! REP MOVSB
    
      ! MOV CL, &H80
      ! MOV [EDI], CL
    
      ! MOV EDI, adrWW
      ! MOV ECX, 2
    SHA_lbl1:
      ! MOV AX, [EDI]
      ! MOV DX, [EDI + 2]
      ! MOV [EDI], DH
      ! MOV [EDI + 1], DL
      ! MOV [EDI + 2], AH
      ! MOV [EDI + 3], AL
      ! ADD EDI, 4
      ! INC ECX
      ! CMP ECX, n
      ! JNE SHA_lbl1
    
      ! MOV H0, &H67452301&
      ! MOV H1, &HEFCDAB89&
      ! MOV H2, &H98BADCFE&
      ! MOV H3, &H10325476&
      ! MOV H4, &HC3D2E1F0&
    
    SHA_lbl2:
      ! MOV EDI, adrW
      ! MOV ESI, adrWW
      ! MOV ECX, 64
      ! REP MOVSB
      ! MOV adrWW, ESI
    
      ! MOV ECX, 0
    SHA_lbl3:
      ! MOV ESI, ECX
      ! ADD ESI, ESI
      ! ADD ESI, ESI
      ! ADD ESI, adrW
    
      ! MOV EAX, [ESI + 52]
      ! XOR EAX, [ESI + 32]
      ! XOR EAX, [ESI + 8]
      ! XOR EAX, [ESI]
    
      ! MOV EDX, EAX
      ! SHL EAX, 1
      ! SHR EDX, 31
      ! OR  EAX, EDX
      ! MOV [ESI + 64], EAX
    
      ! INC ECX
      ! CMP ECX, 64
      ! JNE SHA_lbl3
    
      ! MOV EAX, H0
      ! MOV A, EAX
      ! MOV EAX, H1
      ! MOV B, EAX
      ! MOV EAX, H2
      ! MOV C, EAX
      ! MOV EAX, H3
      ! MOV D, EAX
      ! MOV EAX, H4
      ! MOV E, EAX
    
      ! MOV EDI, 0
    SHA_lbl4:
      ! CMP EDI, 19
      ! JA SHA_lbl5
    
      ! MOV ECX, B
      ! AND ECX, C
      ! MOV EAX, B
      ! NOT EAX
      ! AND EAX, D
      ! OR  ECX, EAX
      ! ADD ECX, &H5A827999&
      ! JMP SHA_lbl8
    
    SHA_lbl5:
      ! CMP EDI, 39
      ! JA SHA_lbl6
    
      ! MOV ECX, B
      ! XOR ECX, C
      ! XOR ECX, D
      ! ADD ECX, &H6ED9EBA1&
      ! JMP SHA_lbl8
    
    SHA_lbl6:
      ! CMP EDI, 59
      ! JA SHA_lbl7
    
      ! MOV EAX, B
      ! AND EAX, C
      ! MOV ECX, B
      ! AND ECX, D
      ! MOV EDX, C
      ! AND EDX, D
      ! OR  ECX, EAX
      ! OR  ECX, EDX
      ! ADD ECX, &H8F1BBCDC&
      ! JMP SHA_lbl8
    
    SHA_lbl7:
      ! MOV ECX, B
      ! XOR ECX, C
      ! XOR ECX, D
      ! ADD ECX, &HCA62C1D6&
    
    SHA_lbl8:
      ! MOV EAX, A
      ! MOV EDX, EAX
      ! SHL EAX, 5
      ! SHR EDX, 27
      ! OR  EAX, EDX
      ! ADD EAX, E
      ! ADD ECX, EAX
    
      ! MOV ESI, EDI
      ! ADD ESI, ESI
      ! ADD ESI, ESI
      ! ADD ESI, adrW
      ! MOV ESI, [ESI]
      ! MOV TEMP, ESI
    
      ! ADD Temp, ECX
      ! MOV EAX, D
      ! MOV E, EAX
      ! MOV EAX, C
      ! MOV D, EAX
      ! MOV EAX, B
      ! MOV EDX, EAX
      ! SHL EAX, 30
      ! SHR EDX, 2
      ! OR  EAX, EDX
      ! MOV C, EAX
      ! MOV EAX, A
      ! MOV B, EAX
      ! MOV EAX, TEMP
      ! MOV A, EAX
    
      ! INC EDI
      ! CMP EDI, 80
      ! JNE SHA_lbl4
    
      ! MOV EAX, A
      ! ADD H0, EAX
      ! MOV EAX, B
      ! ADD H1, EAX
      ! MOV EAX, C
      ! ADD H2, EAX
      ! MOV EAX, D
      ! ADD H3, EAX
      ! MOV EAX, E
      ! ADD H4, EAX
    
      ! SUB nq, 1
      ! JNE SHA_lbl2
    
      ! MOV EAX, H0
      ! BSWAP EAX
      ! MOV H0, EAX
      ! MOV EAX, H1
      ! BSWAP EAX
      ! MOV H1, EAX
      ! MOV EAX, H2
      ! BSWAP EAX
      ! MOV H2, EAX
      ! MOV EAX, H3
      ! BSWAP EAX
      ! MOV H3, EAX
      ! MOV EAX, H4
      ! BSWAP EAX
      ! MOV H4, EAX
    
      ! POP ESI
      ! POP EDI
    
      SHA.H0 = H0:  SHA.H1 = H1:  SHA.H2 = H2:  SHA.H3 = H3:  SHA.H4 = H4
    
    END FUNCTION
    Last edited by Wayne Diamond; 4 Jan 2015, 01:51 AM.
    -
Working...
X