Page 1 of 1

Example of using TLS-Library parts for generating PRNG numbers

Posted: Thu Jul 05, 2018 4:59 pm
by floppy121
Kolibri TLS library --- GitHub repository

If you just want to get this RNG (not interested about how I got it by myself),
just scroll down to " 3) Include this RNG to your project " part of this message!

1) Extract the RNG from TLS Library
Spoiler:[*][/b] Download three files from this repository:

Code: Select all

hmac.inc  PRF.inc  SHA256.INC
and put them inside a new TLS-Library-RNG subdirectory of your project

[*][/b] Open hmac.inc, you will see this code at lines 41-42

Code: Select all

b = 64 ; block_size
l = 32 ; output length for SHA256
prf function will generate ( b + 3 * l ) random bytes, but only if ( b >= l ) - if this condition is not valid, your project will crash with exception 0E (page fault)

For example, if you want to generate 68 random bytes, you could change these values to

Code: Select all

b = 32 ; block_size
l = 12 ; output length for SHA256
, because ( 32 + 3 * 12 ) = ( 32 + 36 ) = 68

[*][/b] Open SHA256.INC and remove (or comment with ";") these six lines:

Code: Select all

Line  4 || iglobal
Line  5 || align 4
Line 26 || eng
Line 28 || uglobal
Line 29 || align 4
Line 34 || eng
, because if you don't remove these six lines - you will get the errors like undefined symbol 'sha256_start_digest'
2) Get entropy for PRNG and create the interface to it

[*][/b] Copy the source code of get_entropy function from the first post of this thread - (rus) Functions-"sources of entropy" for a quality RNG
(code hidden under a spoiler, click "Show") and put it to a new ./TLS-Library-RNG/entropy.inc file with your functions

Also, you may need to add this code to the end of get_entropy function (before the popa)

Code: Select all

    mov esi, entropy
    mov ebx, ENTROPY_SIZE
    call replace_00_with_ff
, and declare replace_00_with_ff function with this code:
Spoiler:

Code: Select all

; replace_00_with_ff:
; replace 00 with ff in a memory area
;
; IN:    ESI - pointer to a memory area
;        EBX - size of a memory area

replace_00_with_ff:

    push eax ecx

    xor ecx, ecx

    .cycle_replace_00_with_ff:

        cmp byte[esi], 0
        jne .not_00
        mov byte[esi], 0xff

    .not_00:

        inc esi
        inc ecx
        cmp ecx, ebx
        jb .cycle_replace_00_with_ff

    pop ecx eax

    ret
[*][/b] For convenience, to the same entropy.inc file we could add fill_random_buffer interface function:
Spoiler:

Code: Select all

; Prepare, then call a Pseudo Random function based on HMAC

fill_random_buffer:

    pusha

    call get_entropy
    xor ebx, ebx
    xor edx, edx
    xor eax, eax
    xor esi, esi
    stdcall prf, entropy, ENTROPY_SIZE+1, random_buffer

    popa

    ret
+1 at the ENTROPY_SIZE+1 is because the real size of entropy is +1 because of a null character

Also add there convert_random_buffer_to_ascii function - it could convert a part of random buffer to ASCII chars:
Spoiler:

Code: Select all

; convert_random_buffer_to_ascii:
; convert a part of random buffer to ASCII chars
;
; IN:       ECX = size of a part of random buffer which will be converted

convert_random_buffer_to_ascii:

    push esi edx ebx eax

    cmp ecx, 1
    jb .wrong_part_size
    cmp ecx, RANDOM_BUFFER_SIZE
    ja .wrong_part_size

    xor eax, eax
    xor ebx, ebx

    mov esi, random_buffer
    mov edx, 95

  .cycle_conversion:

    mov al, byte[esi]

    cmp al, 95
    jb .skip_division

    div dl
    mov al, ah

  .skip_division:

    add al, 32
    mov byte[esi], al

    inc ebx
    inc esi

    cmp ebx, ecx
    jne .cycle_conversion

  .wrong_part_size:

    pop eax ebx edx esi

    ret
3) Include this RNG to your project

[*][/b] Add this code to your main project file, e.g. to example.asm :

Code: Select all

include "./TLS-Library-RNG/hmac.inc"
include "./TLS-Library-RNG/PRF.inc"
include "./TLS-Library-RNG/SHA256.INC"
include "./TLS-Library-RNG/entropy.inc"

Code: Select all

RANDOM_BUFFER_SIZE = b + 3 * l ; 'b' and 'l' are defined at hmac.inc
                               ; currently, b = 32 and l = 12, so:
                               ;         RANDOM_BUFFER_SIZE = (b + 3 * l) = (32 + 3 * 12) = 68
RANDOM_BUFFER_SIZE_TO_CONVERT = 65; call convert_random_buffer_to_ascii to convert 65 random_bytes to ASCII
                               ; ^ should be smaller than or equal to RANDOM_BUFFER_SIZE
random_buffer        db RANDOM_BUFFER_SIZE dup(0)

Code: Select all

ENTROPY_SIZE = 56 ; check if there are any updates for ENTROPY_SIZE at this "sources of entropy" thread
entropy        db ENTROPY_SIZE dup(255), 0 ; http://board.kolibrios.org/viewtopic.php?f=2&t=3735
                                           ; ( code hidden under a spoiler, click "Show" )
4) Usage of PRNG

Code: Select all

        push    ecx
        call    fill_random_buffer
        mov     ecx, RANDOM_BUFFER_SIZE_TO_CONVERT
        call    convert_random_buffer_to_ascii
        pop     ecx
5) Attached files (with SHA256 checksums)

Prepared TLS-Library-RNG_with_example is attached below to save your time!

Code: Select all

b8d8c04dca25107a17ecbbc800cf4a2dfa923873e3a7bcf247aeb342b9c49ecc  ./entropy.inc
c2d36b18a460e664eec63d5373a3419f5a659379405dc942b1563dacea8f2303  ./example.asm
2a781b30ce74031e2aa37cf8d97a3a60fdf1630f04ef963023e5d20935a3015a  ./TLS-Library-RNG_with_example.zip
0ede9e511fc10f05a11b992808a893b315604b25bbccbd10759202788013cec3  ./TLS-Library-RNG.zip
Includes TLS-Library-RNG directory with four files, and example.asm which can't be compiled separately but you could borrow its' elements