The MASM Forum

General => The Campus => Topic started by: JK on March 16, 2021, 04:58:03 AM

Title: C header translation
Post by: JK on March 16, 2021, 04:58:03 AM
How would i translate this C struct (wincrypt.h) to ASM

typedef struct _CRYPT_AES_256_KEY_STATE {
  unsigned char Key[32];
  unsigned char IV[16];
  unsigned char EncryptionState[15][16];
  unsigned char DecryptionState[15][16];
  unsigned char Feedback[16];
} CRYPT_AES_256_KEY_STATE, *PCRYPT_AES_256_KEY_STATE;


and what would be a valid syntax for reading or writing EncryptionState[2][3] or EncryptionState[i1][i2] (where i1 and i2 are local variables)?


JK
Title: Re: C header translation
Post by: jj2007 on March 16, 2021, 04:58:51 AM
Not tested:
CRYPT_AES_256_KEY_STATE STRUCT
Key        char 32 dup(?)
IV        char 16 dup(?)
EncryptionState char 15 dup(?)
DecryptionState char 15 dup(?)
Feedback  char 16 dup(?)
CRYPT_AES_256_KEY_STATE ENDS

PCRYPT_AES_256_KEY_STATE typedef ptr CRYPT_AES_256_KEY_STATE


Gcc chokes on this one:
#include <stdio.h> // template for a simple C console app
#include <windows.h> // needs Gcc or Visual C and the Compile plugin
#include <WinCrypt.h>
int main() {
  long long q=1234567890123456789;
  CRYPT_AES_256_KEY_STATE cstate;
}
Title: Re: C header translation
Post by: JK on March 16, 2021, 07:21:26 AM
FreeBASIC defines it (two-dimensional) as:

    type _CRYPT_AES_256_KEY_STATE
        Key(0 to 31) as ubyte
        IV(0 to 15) as ubyte
        EncryptionState(0 to 14, 0 to 15) as ubyte
        DecryptionState(0 to 14, 0 to 15) as ubyte
        Feedback(0 to 15) as ubyte
    end type


my point here is, it is a two-dimensional array for EncryptionState and DecryptionState so the total number of elements would be 240 (15 x 16), so one-dimensional it must be:

... 240 dup (?)

but is there an assembler syntax supporting two dimensions as well?

And, if yes - what would be a valid syntax for reading or writing EncryptionState[2][3] or EncryptionState[i1][i2] (where i1 and i2 are local variables)?
Title: Re: C header translation
Post by: Greenhorn on March 16, 2021, 07:22:46 AM
Members EncryptionState and DecryptionState are two-dimensional arrays.

Should be like this:

CRYPT_AES_256_KEY_STATE STRUCT
Key            byte 32 dup(?)
IV            byte 16 dup(?)
EncryptionState   byte 15 dup(16 dup(?))
DecryptionState   byte 15 dup(16 dup(?))
Feedback         byte 16 dup(?)
CRYPT_AES_256_KEY_STATE ENDS

PCRYPT_AES_256_KEY_STATE typedef ptr CRYPT_AES_256_KEY_STATE

...
LOCAL ca2ks:    CRYPT_AES_256_KEY_STATE

...
mov  al, ca2ks.EncryptionState[2  *16*sizeof(byte)]    ;// same as ca2ks.EncryptionState[2][0] in C lang
mov  al, ca2ks.EncryptionState[14*16*sizeof(byte)]    ;// same as ca2ks.EncryptionState[14][0] in C lang


The sizeof(byte) is not necessary here, it's just to show how it works with array element sizes.


Kind regards
Greenhorn
Title: Re: C header translation
Post by: JK on March 16, 2021, 07:48:56 AM
So there is no such syntax?

mov  al, ca2ks.EncryptionState[2, 0]

In my case i must always CALCULATE the one-dimensional index from the two indices for this two-dimensional array, i cannot let the assembler resolve it for me - is this true?


Thanks for your help!
Title: Re: C header translation
Post by: jj2007 on March 16, 2021, 07:50:56 AM
Quote from: JK on March 16, 2021, 07:48:56 AM
So there is no such syntax?

No, but you can use (if both are immediates)
index=rows*xsize+column
mov  al, ca2ks.EncryptionState[index]
Title: Re: C header translation
Post by: Greenhorn on March 16, 2021, 08:11:23 AM
Quote from: JK on March 16, 2021, 07:48:56 AM
In my case i must always CALCULATE the one-dimensional index from the two indices for this two-dimensional array, i cannot let the assembler resolve it for me - is this true?

True.

ca2ks.EncryptionState[2, 0]
This is high level programming language. That means, the compiler is doing the calculation for you.
In Assembly language you are on the lowest (machine) level and all memory access is on a byte basis.

This is a good read for beginners in MASM: MASM Programmer's Guide (http://masm32.com/board/index.php?topic=3445.0)
Title: Re: C header translation
Post by: Greenhorn on March 16, 2021, 08:18:15 AM
And these books are also very good:
Write Great Code, Volume 1, 2nd Edition (https://nostarch.com/writegreatcode1_2e)
Write Great Code, Volume 2, 2nd Edition (https://nostarch.com/writegreatcode2_2)
Title: Re: C header translation
Post by: JK on March 16, 2021, 09:08:21 AM
testing with UASM this code is accepted,

mov al, ca2ks.EncryptionState[14*16*sizeof(byte)][3*sizeof(byte)][5]

all [...] get added to a final index.
Title: Re: C header translation
Post by: jj2007 on March 16, 2021, 09:24:24 AM
Quote from: jj2007 on March 16, 2021, 07:50:56 AMyou can use (if both are immediates)
index=rows*xsize+column
mov  al, ca2ks.EncryptionState[index]

Yes indeed, but only with immediates. If your rows and columns are in registers or in variables, use e.g.
imul eax, row, sizeof row
add eax, column
mov  al, ca2ks.EncryptionState[eax]
Title: Re: C header translation
Post by: HSE on March 16, 2021, 10:35:21 AM
You can define:

"if you are using ANSI srintrings:"
    char textequ <byte>
"elseif you are using WIDE strings:"
    char textequ <word>

CRYPT_AES_256_KEY_STATE STRUCT
  ···
EncryptionState char 15*16 dup(?)
  ···
CRYPT_AES_256_KEY_STATE ENDS


Title: Re: C header translation
Post by: TouEnMasm on March 17, 2021, 01:09:02 AM
Quote
CRYPT_AES_256_KEY_STATE   STRUCT DEFALIGNMASM
   Key BYTE 32 dup (?)
   IV BYTE 16 dup (?)
   EncryptionState BYTE 15 dup (?)
   DecryptionState BYTE 15 dup (?)
   Feedback BYTE 16 dup (?)
CRYPT_AES_256_KEY_STATE      ENDS


it is in wincrypt.sdk here http://luce.yves.pagesperso-orange.fr/header.htm (http://luce.yves.pagesperso-orange.fr/header.htm)
Title: Re: C header translation
Post by: HSE on March 17, 2021, 01:49:28 AM
Hi Yves!

Quote from: TouEnMasm on March 17, 2021, 01:09:02 AM
Quote
CRYPT_AES_256_KEY_STATE   STRUCT DEFALIGNMASM
   Key BYTE 32 dup (?)
   IV BYTE 16 dup (?)
   EncryptionState BYTE 15 dup (?)
   DecryptionState BYTE 15 dup (?)
   Feedback BYTE 16 dup (?)
CRYPT_AES_256_KEY_STATE      ENDS


it is in wincrypt.sdk here http://luce.yves.pagesperso-orange.fr/header.htm (http://luce.yves.pagesperso-orange.fr/header.htm)
Your CRYPT_AES_256_KEY_STATE is wrong.
Also CRYPT_AES_128_KEY_STATE is wrong in your sdk.
For sure your translator don't understand this arrays, only take first index.

Very interesting also ObjAsm sdk is wrong but it's a different translator, and take last index!
Title: Re: C header translation
Post by: TouEnMasm on March 17, 2021, 03:08:30 AM
Last SDK
Quote
typedef struct _CRYPT_AES_256_KEY_STATE {
    unsigned char Key[32];
    unsigned char IV[16];
    unsigned char EncryptionState[15][16];      // 14 rounds + 1
    unsigned char DecryptionState[15][16];
    unsigned char Feedback[16];
} CRYPT_AES_256_KEY_STATE, *PCRYPT_AES_256_KEY_STATE;

char EncryptionState[15][16]; is what is bad translated,not really very current
need to know exactly if it is a 15 * 16 bytes  or a 16 * 15 ,adressing is not the same
The comment  // 14 rounds + 1 seem to say it is a 15 * 16     


Title: Re: C header translation
Post by: HSE on March 17, 2021, 03:43:08 AM
Quote from: TouEnMasm on March 17, 2021, 03:08:30 AM
need to know exactly if it is a 15 * 16 bytes  or a 16 * 15 ,adressing is not the same
For sure say 15*16

Other vectors in structure have 16 char, then you can guess:

     y*16+x

just like Greenhorn posted before.

Regards. HSE
Title: Re: C header translation
Post by: TouEnMasm on March 17, 2021, 03:53:15 AM
Ok,the one posted by Greenhorn seems to work:
Quote
.const
CRYPT_AES_256_KEY_STATE STRUCT
Key            byte 32 dup(?)
IV            byte 16 dup(?)
EncryptionState   byte 15 dup(16 dup(?))
DecryptionState   byte 15 dup(16 dup(?))
Feedback         byte 16 dup(?)
CRYPT_AES_256_KEY_STATE ENDS
.data
truc CRYPT_AES_256_KEY_STATE <>


Quote
mov al,byte ptr truc.EncryptionState [2  *16*sizeof(byte)]
OK

work also
Quote
   lea rbx,truc.EncryptionState
   mov r11,10   ;row  data
   shl r11,4 ;* 16                       [rbx + r11 * 16] 16 scale factor not allowed 1,2,4,8
   movq xmm0, [rbx + r11 ]
   mov rax ,sizeof truc