Dies ist natürlich kein triviales Thema, deshalb nachfolgend ein Anwendungs-Beispiel mit dem AES-NI-Instruction-Set.
, Key und Init-Vector sind in der DataSection fest vorgegeben. Kann natürlich jeder ändern/abfragen.
Als Datenquelle kann ein x-beliebiges File ausgewählt werden (Mindest-Länge 16 Bytes). Gezeigt werden soll der Speed-Vorteil.
Code: Alles auswählen
;EBC/CBC, KeySize 128/192/256 Bit
;Windows 64-Bit, CPU mit AES-NI (NI=New Instructions, wurde von Intel mal so genannt)
;PureBasic 5.73 LTS (x64)
;--------------------- Key_Expansion_Encrypt AES_128 ---------------------
Procedure Make_Roundkey_AES_128()
!pshufd xmm2,xmm2,255
!movdqa xmm3,xmm1
!pslldq xmm3,4
!pxor xmm1,xmm3
!pslldq xmm3,4
!pxor xmm1,xmm3
!pslldq xmm3,4
!pxor xmm1,xmm3
!pxor xmm1,xmm2
!add r11,16
!movdqa [r11],xmm1
EndProcedure
Procedure AES_128_Key_Expansion_Encrypt(Userkey, Key_Schedule_E)
!mov r10,[p.v_Userkey] ;oder hier rcx/rdx und die Übergabe-Register direkt verwenden. Gilt generell!
!mov r11,[p.v_Key_Schedule_E]
!movdqa xmm1,[r10]
!movdqa [r11],xmm1
!aeskeygenassist xmm2,xmm1,1
Make_Roundkey_AES_128() ;kann auch als Macro mal getestet werden; generell
!aeskeygenassist xmm2,xmm1,2
Make_Roundkey_AES_128()
!aeskeygenassist xmm2,xmm1,4
Make_Roundkey_AES_128()
!aeskeygenassist xmm2,xmm1,8
Make_Roundkey_AES_128()
!aeskeygenassist xmm2,xmm1,16
Make_Roundkey_AES_128()
!aeskeygenassist xmm2,xmm1,32
Make_Roundkey_AES_128()
!aeskeygenassist xmm2,xmm1,64
Make_Roundkey_AES_128()
!aeskeygenassist xmm2,xmm1,128
Make_Roundkey_AES_128()
!aeskeygenassist xmm2,xmm1,27
Make_Roundkey_AES_128()
!aeskeygenassist xmm2,xmm1,54
Make_Roundkey_AES_128()
EndProcedure
;-------------------------------------------------------------------------
;--------------------- Key_Expansion_Encrypt AES_192 ---------------------
Procedure Make_Roundkey_AES_192_a()
!pshufd xmm2,xmm2,85
!movdqa xmm4,xmm1
!pslldq xmm4,4
!pxor xmm1,xmm4
!pslldq xmm4,4
!pxor xmm1,xmm4
!pslldq xmm4,4
!pxor xmm1,xmm4
!pxor xmm1,xmm2
!pshufd xmm2,xmm1,255
!movdqa xmm4,xmm3
!pslldq xmm4,4
!pxor xmm3,xmm4
!pxor xmm3,xmm2
!add r11,16
!shufpd xmm5,xmm1,0
!movdqa [r11],xmm5
!movdqa xmm6,xmm1
!shufpd xmm6,xmm3,1
!add r11,16
!movdqa [r11],xmm6
EndProcedure
Procedure Make_Roundkey_AES_192_b()
!pshufd xmm2,xmm2,85
!movdqa xmm4,xmm1
!pslldq xmm4,4
!pxor xmm1,xmm4
!pslldq xmm4,4
!pxor xmm1,xmm4
!pslldq xmm4,4
!pxor xmm1,xmm4
!pxor xmm1,xmm2
!pshufd xmm2,xmm1,255
!movdqa xmm4,xmm3
!pslldq xmm4,4
!pxor xmm3,xmm4
!pxor xmm3,xmm2
!add r11,16
!movdqa [r11],xmm1
!movdqa xmm5,xmm3
EndProcedure
Procedure AES_192_Key_Expansion_Encrypt(Userkey, Key_Schedule_E)
!mov r10,[p.v_Userkey]
!mov r11,[p.v_Key_Schedule_E]
!movdqa xmm1,[r10]
!movdqa xmm3,[r10+16]
!movdqa [r11],xmm1
!movdqa xmm5,xmm3
!aeskeygenassist xmm2,xmm3,1
Make_Roundkey_AES_192_a()
!aeskeygenassist xmm2,xmm3,2
Make_Roundkey_AES_192_b()
!aeskeygenassist xmm2,xmm3,4
Make_Roundkey_AES_192_a()
!aeskeygenassist xmm2,xmm3,8
Make_Roundkey_AES_192_b()
!aeskeygenassist xmm2,xmm3,16
Make_Roundkey_AES_192_a()
!aeskeygenassist xmm2,xmm3,32
Make_Roundkey_AES_192_b()
!aeskeygenassist xmm2,xmm3,64
Make_Roundkey_AES_192_a()
!aeskeygenassist xmm2,xmm3,128
Make_Roundkey_AES_192_b()
!movdqa [r11+16],xmm3
EndProcedure
;-------------------------------------------------------------------------
;--------------------- Key_Expansion_Encrypt AES_256 ---------------------
Procedure Make_Roundkey_AES_256_a()
!pshufd xmm2,xmm2,255
!movdqa xmm4,xmm1
!pslldq xmm4,4
!pxor xmm1,xmm4
!pslldq xmm4,4
!pxor xmm1,xmm4
!pslldq xmm4,4
!pxor xmm1,xmm4
!pxor xmm1,xmm2
!add r11,16
!movdqa [r11],xmm1
EndProcedure
Procedure Make_Roundkey_AES_256_b()
!pshufd xmm2,xmm2,170
!movdqa xmm4,xmm3
!pslldq xmm4,4
!pxor xmm3,xmm4
!pslldq xmm4,4
!pxor xmm3,xmm4
!pslldq xmm4,4
!pxor xmm3,xmm4
!pxor xmm3,xmm2
!add r11,16
!movdqa [r11],xmm3
EndProcedure
Procedure AES_256_Key_Expansion_Encrypt(Userkey, Key_Schedule_E)
!mov r10,[p.v_Userkey]
!mov r11,[p.v_Key_Schedule_E]
!movdqa xmm1,[r10]
!movdqa xmm3,[r10+16]
!movdqa [r11],xmm1
!add r11,16
!movdqa [r11],xmm3
!aeskeygenassist xmm2,xmm3,1
Make_Roundkey_AES_256_a()
!aeskeygenassist xmm2,xmm1,0
Make_Roundkey_AES_256_b()
!aeskeygenassist xmm2,xmm3,2
Make_Roundkey_AES_256_a()
!aeskeygenassist xmm2,xmm1,0
Make_Roundkey_AES_256_b()
!aeskeygenassist xmm2,xmm3,4
Make_Roundkey_AES_256_a()
!aeskeygenassist xmm2,xmm1,0
Make_Roundkey_AES_256_b()
!aeskeygenassist xmm2,xmm3,8
Make_Roundkey_AES_256_a()
!aeskeygenassist xmm2,xmm1,0
Make_Roundkey_AES_256_b()
!aeskeygenassist xmm2,xmm3,16
Make_Roundkey_AES_256_a()
!aeskeygenassist xmm2,xmm1,0
Make_Roundkey_AES_256_b()
!aeskeygenassist xmm2,xmm3,32
Make_Roundkey_AES_256_a()
!aeskeygenassist xmm2,xmm1,0
Make_Roundkey_AES_256_b()
!aeskeygenassist xmm2,xmm3,64
Make_Roundkey_AES_256_a()
EndProcedure
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
Procedure AES_ECB_Encrypt_1Block(Plain, Cipher, Key_Schedule_E, Rounds)
!mov r8,[p.v_Plain]
!mov r9,[p.v_Cipher]
!mov rcx,[p.v_Key_Schedule_E]
!mov r11,[p.v_Rounds]
!movdqa xmm1,[r8]
!movdqa xmm9,[rcx]
!movdqa xmm10,[rcx+16]
!movdqa xmm11,[rcx+32]
!movdqa xmm12,[rcx+48]
!pxor xmm1,xmm9
!aesenc xmm1,xmm10
!aesenc xmm1,xmm11
!aesenc xmm1,xmm12
!movdqa xmm9,[rcx+64]
!movdqa xmm10,[rcx+80]
!movdqa xmm11,[rcx+96]
!movdqa xmm12,[rcx+112]
!aesenc xmm1,xmm9
!aesenc xmm1,xmm10
!aesenc xmm1,xmm11
!aesenc xmm1,xmm12
!movdqa xmm9,[rcx+128]
!movdqa xmm10,[rcx+144]
!movdqa xmm11,[rcx+160]
!cmp r11,12
!aesenc xmm1,xmm9
!aesenc xmm1,xmm10
!jb .E_LAST_1_ECB ;Rounds=10
!movdqa xmm9,[rcx+160]
!movdqa xmm10,[rcx+176]
!movdqa xmm11,[rcx+192]
!cmp r11,14
!aesenc xmm1,xmm9
!aesenc xmm1,xmm10
!jb .E_LAST_1_ECB ;Rounds=12
!movdqa xmm9,[rcx+192]
!movdqa xmm10,[rcx+208]
!movdqa xmm11,[rcx+224]
!aesenc xmm1,xmm9
!aesenc xmm1,xmm10
!.E_LAST_1_ECB:
!aesenclast xmm1,xmm11
!movdqa [r9],xmm1
EndProcedure
Procedure AES_ECB_Encrypt_2Blocks(Plain, Cipher, Key_Schedule_E, Rounds)
!mov r8,[p.v_Plain]
!mov r9,[p.v_Cipher]
!mov rcx,[p.v_Key_Schedule_E]
!mov r11,[p.v_Rounds]
!movdqa xmm1,[r8]
!movdqa xmm2,[r8+16]
!movdqa xmm9,[rcx]
!movdqa xmm10,[rcx+16]
!movdqa xmm11,[rcx+32]
!movdqa xmm12,[rcx+48]
!pxor xmm1,xmm9
!pxor xmm2,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!aesenc xmm1,xmm11
!aesenc xmm2,xmm11
!aesenc xmm1,xmm12
!aesenc xmm2,xmm12
!movdqa xmm9,[rcx+64]
!movdqa xmm10,[rcx+80]
!movdqa xmm11,[rcx+96]
!movdqa xmm12,[rcx+112]
!aesenc xmm1,xmm9
!aesenc xmm2,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!aesenc xmm1,xmm11
!aesenc xmm2,xmm11
!aesenc xmm1,xmm12
!aesenc xmm2,xmm12
!movdqa xmm9,[rcx+128]
!movdqa xmm10,[rcx+144]
!movdqa xmm11,[rcx+160]
!cmp r11,12
!aesenc xmm1,xmm9
!aesenc xmm2,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!jb .E_LAST_2_ECB ;Rounds=10
!movdqa xmm9,[rcx+160]
!movdqa xmm10,[rcx+176]
!movdqa xmm11,[rcx+192]
!cmp r11,14
!aesenc xmm1,xmm9
!aesenc xmm2,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!jb .E_LAST_2_ECB ;Rounds=12
!movdqa xmm9,[rcx+192]
!movdqa xmm10,[rcx+208]
!movdqa xmm11,[rcx+224]
!aesenc xmm1,xmm9
!aesenc xmm2,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!.E_LAST_2_ECB:
!aesenclast xmm1,xmm11
!aesenclast xmm2,xmm11
!movdqa [r9],xmm1
!movdqa [r9+16],xmm2
EndProcedure
Procedure AES_ECB_Encrypt_3Blocks(Plain, Cipher, Key_Schedule_E, Rounds)
!mov r8,[p.v_Plain]
!mov r9,[p.v_Cipher]
!mov rcx,[p.v_Key_Schedule_E]
!mov r11,[p.v_Rounds]
!movdqa xmm1,[r8]
!movdqa xmm2,[r8+16]
!movdqa xmm3,[r8+32]
!movdqa xmm9,[rcx]
!movdqa xmm10,[rcx+16]
!movdqa xmm11,[rcx+32]
!movdqa xmm12,[rcx+48]
!pxor xmm1,xmm9
!pxor xmm2,xmm9
!pxor xmm3,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!aesenc xmm3,xmm10
!aesenc xmm1,xmm11
!aesenc xmm2,xmm11
!aesenc xmm3,xmm11
!aesenc xmm1,xmm12
!aesenc xmm2,xmm12
!aesenc xmm3,xmm12
!movdqa xmm9,[rcx+64]
!movdqa xmm10,[rcx+80]
!movdqa xmm11,[rcx+96]
!movdqa xmm12,[rcx+112]
!aesenc xmm1,xmm9
!aesenc xmm2,xmm9
!aesenc xmm3,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!aesenc xmm3,xmm10
!aesenc xmm1,xmm11
!aesenc xmm2,xmm11
!aesenc xmm3,xmm11
!aesenc xmm1,xmm12
!aesenc xmm2,xmm12
!aesenc xmm3,xmm12
!movdqa xmm9,[rcx+128]
!movdqa xmm10,[rcx+144]
!movdqa xmm11,[rcx+160]
!cmp r11,12
!aesenc xmm1,xmm9
!aesenc xmm2,xmm9
!aesenc xmm3,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!aesenc xmm3,xmm10
!jb .E_LAST_3_ECB ;Rounds=10
!movdqa xmm9,[rcx+160]
!movdqa xmm10,[rcx+176]
!movdqa xmm11,[rcx+192]
!cmp r11,14
!aesenc xmm1,xmm9
!aesenc xmm2,xmm9
!aesenc xmm3,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!aesenc xmm3,xmm10
!jb .E_LAST_3_ECB ;Rounds=12
!movdqa xmm9,[rcx+192]
!movdqa xmm10,[rcx+208]
!movdqa xmm11,[rcx+224]
!aesenc xmm1,xmm9
!aesenc xmm2,xmm9
!aesenc xmm3,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!aesenc xmm3,xmm10
!.E_LAST_3_ECB:
!aesenclast xmm1,xmm11
!aesenclast xmm2,xmm11
!aesenclast xmm3,xmm11
!movdqa [r9],xmm1
!movdqa [r9+16],xmm2
!movdqa [r9+32],xmm3
EndProcedure
Procedure AES_ECB_Encrypt_4Blocks(Plain, Cipher, Length, Key_Schedule_E, Rounds)
!mov r8,[p.v_Plain]
!mov r9,[p.v_Cipher]
!mov rdx,[p.v_Length]
!mov rcx,[p.v_Key_Schedule_E]
!mov r11,[p.v_Rounds]
!shr rdx,6 ;/64
!sub r9,64
!.E_LOOP_4_ECB:
!movdqa xmm1,[r8]
!movdqa xmm2,[r8+16]
!movdqa xmm3,[r8+32]
!movdqa xmm4,[r8+48]
!movdqa xmm9,[rcx]
!movdqa xmm10,[rcx+16]
!movdqa xmm11,[rcx+32]
!movdqa xmm12,[rcx+48]
!pxor xmm1,xmm9
!pxor xmm2,xmm9
!pxor xmm3,xmm9
!pxor xmm4,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!aesenc xmm3,xmm10
!aesenc xmm4,xmm10
!aesenc xmm1,xmm11
!aesenc xmm2,xmm11
!aesenc xmm3,xmm11
!aesenc xmm4,xmm11
!aesenc xmm1,xmm12
!aesenc xmm2,xmm12
!aesenc xmm3,xmm12
!aesenc xmm4,xmm12
!movdqa xmm9,[rcx+64]
!movdqa xmm10,[rcx+80]
!movdqa xmm11,[rcx+96]
!movdqa xmm12,[rcx+112]
!aesenc xmm1,xmm9
!aesenc xmm2,xmm9
!aesenc xmm3,xmm9
!aesenc xmm4,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!aesenc xmm3,xmm10
!aesenc xmm4,xmm10
!aesenc xmm1,xmm11
!aesenc xmm2,xmm11
!aesenc xmm3,xmm11
!aesenc xmm4,xmm11
!aesenc xmm1,xmm12
!aesenc xmm2,xmm12
!aesenc xmm3,xmm12
!aesenc xmm4,xmm12
!movdqa xmm9,[rcx+128]
!movdqa xmm10,[rcx+144]
!movdqa xmm11,[rcx+160]
!cmp r11,12
!aesenc xmm1,xmm9
!aesenc xmm2,xmm9
!aesenc xmm3,xmm9
!aesenc xmm4,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!aesenc xmm3,xmm10
!aesenc xmm4,xmm10
!jb .E_LAST_4_ECB
!movdqa xmm9,[rcx+160]
!movdqa xmm10,[rcx+176]
!movdqa xmm11,[rcx+192]
!cmp r11,14
!aesenc xmm1,xmm9
!aesenc xmm2,xmm9
!aesenc xmm3,xmm9
!aesenc xmm4,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!aesenc xmm3,xmm10
!aesenc xmm4,xmm10
!jb .E_LAST_4_ECB
!movdqa xmm9,[rcx+192]
!movdqa xmm10,[rcx+208]
!movdqa xmm11,[rcx+224]
!aesenc xmm1,xmm9
!aesenc xmm2,xmm9
!aesenc xmm3,xmm9
!aesenc xmm4,xmm9
!aesenc xmm1,xmm10
!aesenc xmm2,xmm10
!aesenc xmm3,xmm10
!aesenc xmm4,xmm10
!.E_LAST_4_ECB:
!add r8,64
!add r9,64
!dec rdx
!aesenclast xmm1,xmm11
!aesenclast xmm2,xmm11
!aesenclast xmm3,xmm11
!aesenclast xmm4,xmm11
!movdqa [r9],xmm1
!movdqa [r9+16],xmm2
!movdqa [r9+32],xmm3
!movdqa [r9+48],xmm4
!jnz .E_LOOP_4_ECB
EndProcedure
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
Procedure AES_CBC_Encrypt_1Block(Plain, Cipher, Length, IVec, Key_Schedule_E, Rounds)
!mov r10,[p.v_Plain]
!mov r11,[p.v_Cipher]
!mov rcx,[p.v_Length]
!mov rdx,[p.v_IVec]
!mov r8,[p.v_Key_Schedule_E]
!mov r9,[p.v_Rounds]
!shr rcx,4
!sub r11,16
!movdqa xmm1,[rdx]
!.E_LOOP_CBC:
!pxor xmm1,[r10]
!pxor xmm1,[r8]
!add r10,16
!add r11,16
!cmp r9,12
!aesenc xmm1,[r8+16]
!aesenc xmm1,[r8+32]
!aesenc xmm1,[r8+48]
!aesenc xmm1,[r8+64]
!aesenc xmm1,[r8+80]
!aesenc xmm1,[r8+96]
!aesenc xmm1,[r8+112]
!aesenc xmm1,[r8+128]
!aesenc xmm1,[r8+144]
!movdqa xmm2,[r8+160]
!jb .E_LAST_CBC
!cmp r9,14
!aesenc xmm1,[r8+160]
!aesenc xmm1,[r8+176]
!movdqa xmm2,[r8+192]
!jb .E_LAST_CBC
!aesenc xmm1,[r8+192]
!aesenc xmm1,[r8+208]
!movdqa xmm2,[r8+224]
!.E_LAST_CBC:
!dec rcx
!aesenclast xmm1,xmm2
!movdqa [r11],xmm1
!jnz .E_LOOP_CBC
EndProcedure
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
Procedure AES_Key_Expansion_Decrypt(Key_Schedule_E, Key_Schedule_D, Rounds)
!mov r10,[p.v_Key_Schedule_E]
!mov r11,[p.v_Key_Schedule_D]
!mov rdx,[p.v_Rounds]
!mov rax,rdx
!shl rax,4
!mov rcx,rax
!add rcx,r10
!movdqa xmm0,[rcx]
!movdqa [r11],xmm0
!sub rcx,208
!cmp rdx,10
!aesimc xmm1,[rcx+192]
!aesimc xmm2,[rcx+176]
!aesimc xmm3,[rcx+160]
!aesimc xmm4,[rcx+144]
!movdqa [r11+16],xmm1
!movdqa [r11+32],xmm2
!movdqa [r11+48],xmm3
!movdqa [r11+64],xmm4
!aesimc xmm5,[rcx+128]
!aesimc xmm6,[rcx+112]
!aesimc xmm7,[rcx+96]
!aesimc xmm8,[rcx+80]
!movdqa [r11+80],xmm5
!movdqa [r11+96],xmm6
!movdqa [r11+112],xmm7
!movdqa [r11+128],xmm8
!aesimc xmm9,[rcx+64]
!movdqa [r11+144],xmm9
!jle .END_DEC
!cmp rdx,12
!aesimc xmm0,[rcx+48]
!aesimc xmm1,[rcx+32]
!movdqa [r11+160],xmm0
!movdqa [r11+176],xmm1
!jle .END_DEC
!aesimc xmm0,[rcx+16]
!aesimc xmm1,[rcx]
!movdqa [r11+192],xmm0
!movdqa [r11+208],xmm1
!.END_DEC:
!movdqa xmm0,[r10]
!add r11,rax
!movdqa [r11],xmm0
EndProcedure
Procedure AES_ECB_Decrypt_1Block(Cipher, Decipher, Key_Schedule_D, Rounds)
!mov r8,[p.v_Cipher]
!mov r9,[p.v_Decipher]
!mov rcx,[p.v_Key_Schedule_D]
!mov r11,[p.v_Rounds]
!movdqa xmm1,[r8]
!movdqa xmm9,[rcx]
!movdqa xmm10,[rcx+16]
!movdqa xmm11,[rcx+32]
!movdqa xmm12,[rcx+48]
!pxor xmm1,xmm9
!aesdec xmm1,xmm10
!aesdec xmm1,xmm11
!aesdec xmm1,xmm12
!movdqa xmm9,[rcx+64]
!movdqa xmm10,[rcx+80]
!movdqa xmm11,[rcx+96]
!movdqa xmm12,[rcx+112]
!aesdec xmm1,xmm9
!aesdec xmm1,xmm10
!aesdec xmm1,xmm11
!aesdec xmm1,xmm12
!movdqa xmm9,[rcx+128]
!movdqa xmm10,[rcx+144]
!movdqa xmm11,[rcx+160]
!cmp r11,12 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm1,xmm10
!jb .D_LAST_1_ECB
!movdqa xmm9,[rcx+160]
!movdqa xmm10,[rcx+176]
!movdqa xmm11,[rcx+192]
!cmp r11,14 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm1,xmm10
!jb .D_LAST_1_ECB
!movdqa xmm9,[rcx+192]
!movdqa xmm10,[rcx+208]
!movdqa xmm11,[rcx+224]
!aesdec xmm1,xmm9
!aesdec xmm1,xmm10
!.D_LAST_1_ECB:
!aesdeclast xmm1,xmm11
!movdqa [r9],xmm1
EndProcedure
Procedure AES_ECB_Decrypt_2Blocks(Cipher, Decipher, Key_Schedule_D, Rounds)
!mov r8,[p.v_Cipher]
!mov r9,[p.v_Decipher]
!mov rcx,[p.v_Key_Schedule_D]
!mov r11,[p.v_Rounds]
!movdqa xmm1,[r8]
!movdqa xmm2,[r8+16]
!movdqa xmm9,[rcx]
!movdqa xmm10,[rcx+16]
!movdqa xmm11,[rcx+32]
!movdqa xmm12,[rcx+48]
!pxor xmm1,xmm9
!pxor xmm2,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm1,xmm11
!aesdec xmm2,xmm11
!aesdec xmm1,xmm12
!aesdec xmm2,xmm12
!movdqa xmm9,[rcx+64]
!movdqa xmm10,[rcx+80]
!movdqa xmm11,[rcx+96]
!movdqa xmm12,[rcx+112]
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm1,xmm11
!aesdec xmm2,xmm11
!aesdec xmm1,xmm12
!aesdec xmm2,xmm12
!movdqa xmm9,[rcx+128]
!movdqa xmm10,[rcx+144]
!movdqa xmm11,[rcx+160]
!cmp r11,12 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!jb .D_LAST_2_ECB
!movdqa xmm9,[rcx+160]
!movdqa xmm10,[rcx+176]
!movdqa xmm11,[rcx+192]
!cmp r11,14 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!jb .D_LAST_2_ECB
!movdqa xmm9,[rcx+192]
!movdqa xmm10,[rcx+208]
!movdqa xmm11,[rcx+224]
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!.D_LAST_2_ECB:
!aesdeclast xmm1,xmm11
!aesdeclast xmm2,xmm11
!movdqa [r9],xmm1
!movdqa [r9+16],xmm2
EndProcedure
Procedure AES_ECB_Decrypt_3Blocks(Cipher, Decipher, Key_Schedule_D, Rounds)
!mov r8,[p.v_Cipher]
!mov r9,[p.v_Decipher]
!mov rcx,[p.v_Key_Schedule_D]
!mov r11,[p.v_Rounds]
!movdqa xmm1,[r8]
!movdqa xmm2,[r8+16]
!movdqa xmm3,[r8+32]
!movdqa xmm9,[rcx]
!movdqa xmm10,[rcx+16]
!movdqa xmm11,[rcx+32]
!movdqa xmm12,[rcx+48]
!pxor xmm1,xmm9
!pxor xmm2,xmm9
!pxor xmm3,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm1,xmm11
!aesdec xmm2,xmm11
!aesdec xmm3,xmm11
!aesdec xmm1,xmm12
!aesdec xmm2,xmm12
!aesdec xmm3,xmm12
!movdqa xmm9,[rcx+64]
!movdqa xmm10,[rcx+80]
!movdqa xmm11,[rcx+96]
!movdqa xmm12,[rcx+112]
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm1,xmm11
!aesdec xmm2,xmm11
!aesdec xmm3,xmm11
!aesdec xmm1,xmm12
!aesdec xmm2,xmm12
!aesdec xmm3,xmm12
!movdqa xmm9,[rcx+128]
!movdqa xmm10,[rcx+144]
!movdqa xmm11,[rcx+160]
!cmp r11,12 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!jb .D_LAST_3_ECB
!movdqa xmm9,[rcx+160]
!movdqa xmm10,[rcx+176]
!movdqa xmm11,[rcx+192]
!cmp r11,14 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!jb .D_LAST_3_ECB
!movdqa xmm9,[rcx+192]
!movdqa xmm10,[rcx+208]
!movdqa xmm11,[rcx+224]
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!.D_LAST_3_ECB:
!aesdeclast xmm1,xmm11
!aesdeclast xmm2,xmm11
!aesdeclast xmm3,xmm11
!movdqa [r9],xmm1
!movdqa [r9+16],xmm2
!movdqa [r9+32],xmm3
EndProcedure
Procedure AES_ECB_Decrypt_4Blocks(Cipher, Decipher, Length, Key_Schedule_D, Rounds)
!mov r8,[p.v_Cipher]
!mov r9,[p.v_Decipher]
!mov rdx,[p.v_Length]
!mov rcx,[p.v_Key_Schedule_D]
!mov r11,[p.v_Rounds]
!shr rdx,6
!sub r9,64
!.D_LOOP_4_ECB:
!movdqa xmm1,[r8]
!movdqa xmm2,[r8+16]
!movdqa xmm3,[r8+32]
!movdqa xmm4,[r8+48]
!movdqa xmm9,[rcx]
!movdqa xmm10,[rcx+16]
!movdqa xmm11,[rcx+32]
!movdqa xmm12,[rcx+48]
!pxor xmm1,xmm9
!pxor xmm2,xmm9
!pxor xmm3,xmm9
!pxor xmm4,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm4,xmm10
!aesdec xmm1,xmm11
!aesdec xmm2,xmm11
!aesdec xmm3,xmm11
!aesdec xmm4,xmm11
!aesdec xmm1,xmm12
!aesdec xmm2,xmm12
!aesdec xmm3,xmm12
!aesdec xmm4,xmm12
!movdqa xmm9,[rcx+64]
!movdqa xmm10,[rcx+80]
!movdqa xmm11,[rcx+96]
!movdqa xmm12,[rcx+112]
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm4,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm4,xmm10
!aesdec xmm1,xmm11
!aesdec xmm2,xmm11
!aesdec xmm3,xmm11
!aesdec xmm4,xmm11
!aesdec xmm1,xmm12
!aesdec xmm2,xmm12
!aesdec xmm3,xmm12
!aesdec xmm4,xmm12
!movdqa xmm9,[rcx+128]
!movdqa xmm10,[rcx+144]
!movdqa xmm11,[rcx+160]
!cmp r11,12 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm4,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm4,xmm10
!jb .D_LAST_4_ECB
!movdqa xmm9,[rcx+160]
!movdqa xmm10,[rcx+176]
!movdqa xmm11,[rcx+192]
!cmp r11,14 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm4,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm4,xmm10
!jb .D_LAST_4_ECB
!movdqa xmm9,[rcx+192]
!movdqa xmm10,[rcx+208]
!movdqa xmm11,[rcx+224]
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm4,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm4,xmm10
!.D_LAST_4_ECB:
!add r8,64
!add r9,64
!dec rdx
!aesdeclast xmm1,xmm11
!aesdeclast xmm2,xmm11
!aesdeclast xmm3,xmm11
!aesdeclast xmm4,xmm11
!movdqa [r9],xmm1
!movdqa [r9+16],xmm2
!movdqa [r9+32],xmm3
!movdqa [r9+48],xmm4
!jnz .D_LOOP_4_ECB
EndProcedure
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
Procedure AES_CBC_Decrypt_1Block(Cipher, Decipher, IVec, Key_Schedule_D, Rounds)
!mov r10,[p.v_Cipher]
!mov r11,[p.v_Decipher]
!mov rdx,[p.v_IVec]
!mov r8,[p.v_Key_Schedule_D]
!mov r9,[p.v_Rounds]
!movdqa xmm5,[rdx]
!movdqa xmm1,[r10]
!movdqa xmm6,xmm1
!movdqa xmm9,[r8]
!movdqa xmm10,[r8+16]
!movdqa xmm11,[r8+32]
!movdqa xmm12,[r8+48]
!pxor xmm1,xmm9
!aesdec xmm1,xmm10
!aesdec xmm1,xmm11
!aesdec xmm1,xmm12
!movdqa xmm9,[r8+64]
!movdqa xmm10,[r8+80]
!movdqa xmm11,[r8+96]
!movdqa xmm12,[r8+112]
!aesdec xmm1,xmm9
!aesdec xmm1,xmm10
!aesdec xmm1,xmm11
!aesdec xmm1,xmm12
!movdqa xmm9,[r8+128]
!movdqa xmm10,[r8+144]
!movdqa xmm11,[r8+160]
!cmp r9,12 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm1,xmm10
!jb .D_LAST_1_CBC
!movdqa xmm9,[r8+160]
!movdqa xmm10,[r8+176]
!movdqa xmm11,[r8+192]
!cmp r9,14 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm1,xmm10
!jb .D_LAST_1_CBC
!movdqa xmm9,[r8+192]
!movdqa xmm10,[r8+208]
!movdqa xmm11,[r8+224]
!aesdec xmm1,xmm9
!aesdec xmm1,xmm10
!.D_LAST_1_CBC:
!aesdeclast xmm1,xmm11
!pxor xmm1,xmm5
!movdqa [r11],xmm1
EndProcedure
Procedure AES_CBC_Decrypt_2Blocks(Cipher, Decipher, IVec, Key_Schedule_D, Rounds)
!mov r10,[p.v_Cipher]
!mov r11,[p.v_Decipher]
!mov rdx,[p.v_IVec]
!mov r8,[p.v_Key_Schedule_D]
!mov r9,[p.v_Rounds]
!movdqa xmm5,[rdx]
!movdqa xmm1,[r10]
!movdqa xmm2,[r10+16]
!movdqa xmm6,xmm1
!movdqa xmm7,xmm2
!movdqa xmm9,[r8]
!movdqa xmm10,[r8+16]
!movdqa xmm11,[r8+32]
!movdqa xmm12,[r8+48]
!pxor xmm1,xmm9
!pxor xmm2,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm1,xmm11
!aesdec xmm2,xmm11
!aesdec xmm1,xmm12
!aesdec xmm2,xmm12
!movdqa xmm9,[r8+64]
!movdqa xmm10,[r8+80]
!movdqa xmm11,[r8+96]
!movdqa xmm12,[r8+112]
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm1,xmm11
!aesdec xmm2,xmm11
!aesdec xmm1,xmm12
!aesdec xmm2,xmm12
!movdqa xmm9,[r8+128]
!movdqa xmm10,[r8+144]
!movdqa xmm11,[r8+160]
!cmp r9,12 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!jb .D_LAST_2_CBC
!movdqa xmm9,[r8+160]
!movdqa xmm10,[r8+176]
!movdqa xmm11,[r8+192]
!cmp r9,14 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!jb .D_LAST_2_CBC
!movdqa xmm9,[r8+192]
!movdqa xmm10,[r8+208]
!movdqa xmm11,[r8+224]
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!.D_LAST_2_CBC:
!aesdeclast xmm1,xmm11
!aesdeclast xmm2,xmm11
!pxor xmm1,xmm5
!pxor xmm2,xmm6
!movdqa [r11],xmm1
!movdqa [r11+16],xmm2
EndProcedure
Procedure AES_CBC_Decrypt_3Blocks(Cipher, Decipher, IVec, Key_Schedule_D, Rounds)
!mov r10,[p.v_Cipher]
!mov r11,[p.v_Decipher]
!mov rdx,[p.v_IVec]
!mov r8,[p.v_Key_Schedule_D]
!mov r9,[p.v_Rounds]
!movdqa xmm5,[rdx]
!movdqa xmm1,[r10]
!movdqa xmm2,[r10+16]
!movdqa xmm3,[r10+32]
!movdqa xmm6,xmm1
!movdqa xmm7,xmm2
!movdqa xmm8,xmm3
!movdqa xmm9,[r8]
!movdqa xmm10,[r8+16]
!movdqa xmm11,[r8+32]
!movdqa xmm12,[r8+48]
!pxor xmm1,xmm9
!pxor xmm2,xmm9
!pxor xmm3,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm1,xmm11
!aesdec xmm2,xmm11
!aesdec xmm3,xmm11
!aesdec xmm1,xmm12
!aesdec xmm2,xmm12
!aesdec xmm3,xmm12
!movdqa xmm9,[r8+64]
!movdqa xmm10,[r8+80]
!movdqa xmm11,[r8+96]
!movdqa xmm12,[r8+112]
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm1,xmm11
!aesdec xmm2,xmm11
!aesdec xmm3,xmm11
!aesdec xmm1,xmm12
!aesdec xmm2,xmm12
!aesdec xmm3,xmm12
!movdqa xmm9,[r8+128]
!movdqa xmm10,[r8+144]
!movdqa xmm11,[r8+160]
!cmp r9,12 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!jb .D_LAST_3_CBC
!movdqa xmm9,[r8+160]
!movdqa xmm10,[r8+176]
!movdqa xmm11,[r8+192]
!cmp r9,14 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!jb .D_LAST_3_CBC
!movdqa xmm9,[r8+192]
!movdqa xmm10,[r8+208]
!movdqa xmm11,[r8+224]
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!.D_LAST_3_CBC:
!aesdeclast xmm1,xmm11
!aesdeclast xmm2,xmm11
!aesdeclast xmm3,xmm11
!pxor xmm1,xmm5
!pxor xmm2,xmm6
!pxor xmm3,xmm7
!movdqa [r11],xmm1
!movdqa [r11+16],xmm2
!movdqa [r11+32],xmm3
EndProcedure
Procedure AES_CBC_Decrypt_4Blocks(Cipher, Decipher, IVec, Length, Key_Schedule_D, Rounds)
!mov r10,[p.v_Cipher]
!mov r11,[p.v_Decipher]
!mov rdx,[p.v_IVec]
!mov rcx,[p.v_Length]
!mov r8,[p.v_Key_Schedule_D]
!mov r9,[p.v_Rounds]
!shr rcx,6
!movdqa xmm5,[rdx]
!sub r11,64
!.D_LOOP_4_CBC:
!movdqa xmm1,[r10]
!movdqa xmm2,[r10+16]
!movdqa xmm3,[r10+32]
!movdqa xmm4,[r10+48]
!movdqa xmm6,xmm1
!movdqa xmm7,xmm2
!movdqa xmm8,xmm3
!movdqa xmm15,xmm4
!movdqa xmm9,[r8]
!movdqa xmm10,[r8+16]
!movdqa xmm11,[r8+32]
!movdqa xmm12,[r8+48]
!pxor xmm1,xmm9
!pxor xmm2,xmm9
!pxor xmm3,xmm9
!pxor xmm4,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm4,xmm10
!aesdec xmm1,xmm11
!aesdec xmm2,xmm11
!aesdec xmm3,xmm11
!aesdec xmm4,xmm11
!aesdec xmm1,xmm12
!aesdec xmm2,xmm12
!aesdec xmm3,xmm12
!aesdec xmm4,xmm12
!movdqa xmm9,[r8+64]
!movdqa xmm10,[r8+80]
!movdqa xmm11,[r8+96]
!movdqa xmm12,[r8+112]
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm4,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm4,xmm10
!aesdec xmm1,xmm11
!aesdec xmm2,xmm11
!aesdec xmm3,xmm11
!aesdec xmm4,xmm11
!aesdec xmm1,xmm12
!aesdec xmm2,xmm12
!aesdec xmm3,xmm12
!aesdec xmm4,xmm12
!movdqa xmm9,[r8+128]
!movdqa xmm10,[r8+144]
!movdqa xmm11,[r8+160]
!cmp r9,12 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm4,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm4,xmm10
!jb .D_LAST_4_CBC
!movdqa xmm9,[r8+160]
!movdqa xmm10,[r8+176]
!movdqa xmm11,[r8+192]
!cmp r9,14 ;Runden
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm4,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm4,xmm10
!jb .D_LAST_4_CBC
!movdqa xmm9,[r8+192]
!movdqa xmm10,[r8+208]
!movdqa xmm11,[r8+224]
!aesdec xmm1,xmm9
!aesdec xmm2,xmm9
!aesdec xmm3,xmm9
!aesdec xmm4,xmm9
!aesdec xmm1,xmm10
!aesdec xmm2,xmm10
!aesdec xmm3,xmm10
!aesdec xmm4,xmm10
!.D_LAST_4_CBC:
!add r10,64
!add r11,64
!dec rcx
!aesdeclast xmm1,xmm11
!aesdeclast xmm2,xmm11
!aesdeclast xmm3,xmm11
!aesdeclast xmm4,xmm11
!pxor xmm1,xmm5
!pxor xmm2,xmm6
!pxor xmm3,xmm7
!pxor xmm4,xmm8
!movdqa [r11],xmm1
!movdqa [r11+16],xmm2
!movdqa [r11+32],xmm3
!movdqa [r11+48],xmm4
!movdqa xmm5,xmm15
!jnz .D_LOOP_4_CBC
EndProcedure
;Test, ob CPU AES unterstützt, CPUID-Verfügbarkeit wird vorausgesetzt
!mov eax,1h
!cpuid
!test ecx,2000000h
!jnz @f
MessageRequester("Error!", "No AES-NI-CPU!")
End
!@@:
;Vorgaben:
Cipher = #PB_Cipher_ECB : Cipher$ = "ECB" ;ECB in PB: InitializationVector wird ignoriert und ist nur ein Platzhalter!
KeySize = 128
Encryption = 1 : Mode$ = "Encryption, "
Decryption = 0
OpenWindow(0, 0, 0, 400, 400, "AES-NI for File", #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
StickyWindow(0, 1)
;LoadFont(0, "Arial Fett", 9)
LoadFont(0, "Trebuchet MS Fett", 9)
SetGadgetFont(#PB_Default, FontID(0))
SelFile$ = OpenFileRequester("Select File:", "", "", 0)
If SelFile$
TextGadget(0, 10, 10, 380, 20, "File:")
EditorGadget(1, 10, 30, 380, 60, #PB_Editor_ReadOnly | #PB_Editor_WordWrap)
SetGadgetText(1, SelFile$)
Else
MessageRequester("Error!", "File?")
End
EndIf
TextGadget(2, 10, 100, 100, 20, "Mode:")
OptionGadget(3, 150, 100, 75, 20, "Encrypt")
OptionGadget(4, 240, 100, 75, 20, "Decrypt")
SetGadgetState(3, 1)
TextGadget(5, 10, 125, 100, 20, "Cipher-Mode:")
OptionGadget(6, 150, 125, 60, 20, "ECB")
OptionGadget(7, 240, 125, 60, 20, "CBC")
SetGadgetState(6, 1)
TextGadget(8, 10, 150, 100, 20, "Key-Size:")
OptionGadget(9, 150, 150, 60, 20, "128")
OptionGadget(10, 240, 150, 60, 20, "192")
OptionGadget(11, 330, 150, 60, 20, "256")
SetGadgetState(9, 1)
ButtonGadget(12, 100, 200, 200, 20, "S T A R T")
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
If Event = #PB_Event_Gadget
Select EventGadget()
Case 3
Encryption = 1 : Decryption = 0 : Mode$ = "Encryption, "
Case 4
Encryption = 0 : Decryption = 1 : Mode$ = "Decryption, "
Case 6
Cipher = #PB_Cipher_ECB : Cipher$ = "ECB"
Case 7
Cipher = #PB_Cipher_CBC : Cipher$ = "CBC"
Case 9
KeySize = 128
Case 10
KeySize = 192
Case 11
KeySize = 256
Case 12
Break
EndSelect
EndIf
ForEver
For i = 0 To 12
FreeGadget(i)
Next
TextGadget(0, 10, 10, 100, 20, "I N F O S :")
TextGadget(1, 10, 30, 380, 20, "File:")
EditorGadget(2, 10, 50, 380, 60, #PB_Editor_ReadOnly | #PB_Editor_WordWrap)
SetGadgetText(2, SelFile$)
While WaitWindowEvent(0) : Wend ;Time for displaying File
ReadFile(0, SelFile$)
InputLen = Lof(0)
TextGadget(3, 10, 115, 380, 20, "Input-Bytes: " + Str(InputLen))
TestMode$ = "Mode: " + Mode$ + Cipher$ + ", KeySize " + Str(KeySize) + " Bit"
TextGadget(4, 10, 135, 380, 20, TestMode$)
WorkingBuffer = AllocateMemory(InputLen + 1088, #PB_Memory_NoClear)
WorkingBufferA64 = (WorkingBuffer & $FFFFFFFFFFFFFFC0) + 64
;Memory-Zuweisung, Vielfache von 64 z.B. wegen Cache-Line
;000-063: Key
;064-127: InitializationVector
;128-383: Key_Schedule_Encrypt Enc, Dec
;384-639: Key_Schedule_Decrypt Dec
;640-703: BufferPad Enc, Dec
;704-767: LastIV Enc
;768-831: Last2Blocks Dec
;832-895: LastBlock16 Dec
;896-...: CipheredOutput, DecipheredOutput
;1024-...: InputBytes
CopyMemory(?UserKey, WorkingBufferA64, 32)
Key = WorkingBufferA64
CopyMemory(?UserInitializationVector, WorkingBufferA64 + 64, 16)
InitializationVector = WorkingBufferA64 + 64
Key_Schedule_Encrypt = WorkingBufferA64 + 128
BufferPad = WorkingBufferA64 + 640
InputBytes = WorkingBufferA64 + 1024
Cluster = 1024 * 1024;*1024 ;interessante Größe für PBs Read-Write-Data!
Chunks = InputLen / Cluster
RestBytes = InputLen - (Chunks * Cluster)
TA = ElapsedMilliseconds()
For i = 0 To Chunks - 1
BytesCopy = ReadData(0, InputBytes + (i * Cluster), Cluster)
;CopyGes + BytesCopy ;nur für Kontrolle
Next
Rest = ReadData(0, InputBytes + (Chunks * Cluster), RestBytes)
;Debug "Anzahl der kopierten Bytes: " + StrU(CopyGes + Rest)
TE = ElapsedMilliseconds() - TA
TextGadget(5, 10, 155, 380, 20, "Time Copy File HD/SSD -> Memory: " + Str(TE) + " ms")
CloseFile(0)
Blocks16 = InputLen >> 4 ;/16
AddrPad = (Blocks16 - 1) << 4 ;Adresse der letzten/einzigen 2 Blocks (1x16 Bytes, 1x16-LenPad)
LenPad = (16 - (InputLen % 16)) & %1111 ;liegt zwischen 0 und 15
TextGadget(6, 10, 175, 380, 20, "Blocks16: " + Str(Blocks16))
TextGadget(7, 10, 195, 380, 20, "Padding-Bytes: " + Str(LenPad))
;-------------------------------------------------------------------------
If Encryption
TA = ElapsedMilliseconds()
Select KeySize
Case 128
AES_128_Key_Expansion_Encrypt(Key, Key_Schedule_Encrypt)
Rounds = 10
Case 192
AES_192_Key_Expansion_Encrypt(Key, Key_Schedule_Encrypt)
Rounds = 12
Default ;256
AES_256_Key_Expansion_Encrypt(Key, Key_Schedule_Encrypt)
Rounds = 14
EndSelect
LastIV = WorkingBufferA64 + 704
CipheredOutput = WorkingBufferA64 + 896
If Cipher = #PB_Cipher_ECB
n = Blocks16 & 3
Select n
Case 0
AES_ECB_Encrypt_4Blocks(InputBytes, CipheredOutput, Blocks16 << 4, Key_Schedule_Encrypt, Rounds)
Case 1
AES_ECB_Encrypt_1Block(InputBytes, CipheredOutput, Key_Schedule_Encrypt, Rounds)
Case 2
AES_ECB_Encrypt_2Blocks(InputBytes, CipheredOutput, Key_Schedule_Encrypt, Rounds)
Case 3
AES_ECB_Encrypt_3Blocks(InputBytes, CipheredOutput, Key_Schedule_Encrypt, Rounds)
EndSelect
If n > 0 And Blocks16 > 3
AES_ECB_Encrypt_4Blocks(InputBytes + (n << 4), CipheredOutput + (n << 4), (Blocks16 - n) << 4, Key_Schedule_Encrypt, Rounds)
EndIf
If LenPad ;Padding Encryption
CopyMemory(CipheredOutput + AddrPad, CipheredOutput + 16 + AddrPad, 16 - LenPad)
CopyMemory(InputBytes + 16 + AddrPad, BufferPad, 16 - LenPad)
CopyMemory(CipheredOutput + 16 + AddrPad - LenPad, BufferPad + 16 - LenPad, LenPad)
AES_ECB_Encrypt_1Block(BufferPad, CipheredOutput + AddrPad, Key_Schedule_Encrypt, Rounds)
EndIf ;Padding Encryption
Else ;#PB_Cipher_CBC, Encrypt-CBC nur seriell!
AES_CBC_Encrypt_1Block(InputBytes, CipheredOutput, Blocks16 << 4, InitializationVector, Key_Schedule_Encrypt, Rounds)
If LenPad ;Padding Encryption
CopyMemory(CipheredOutput + AddrPad, CipheredOutput + 16 + AddrPad, 16 - LenPad)
CopyMemory(CipheredOutput + AddrPad, LastIV, 16 - LenPad)
CopyMemory(InputBytes + 16 + AddrPad, BufferPad, 16 - LenPad)
CopyMemory(CipheredOutput + 16 + AddrPad - LenPad, BufferPad + 16 - LenPad, LenPad)
AES_CBC_Encrypt_1Block(BufferPad, CipheredOutput + AddrPad, 16, LastIV, Key_Schedule_Encrypt, Rounds)
EndIf ;Padding Encryption
EndIf
TE = ElapsedMilliseconds() - TA
TextGadget(8, 10, 215, 380, 20, "Time Encrypt NI: " + Str(TE) + " ms")
SaveFile$ = GetFilePart(SelFile$) + ".NIenc"
Source = CipheredOutput
EndIf ;Encryption
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
If Decryption
TA = ElapsedMilliseconds()
;für Decrypt hier nochmal Encrypt nötig!
Select KeySize
Case 128
AES_128_Key_Expansion_Encrypt(Key, Key_Schedule_Encrypt)
Rounds = 10
Case 192
AES_192_Key_Expansion_Encrypt(Key, Key_Schedule_Encrypt)
Rounds = 12
Default ;256
AES_256_Key_Expansion_Encrypt(Key, Key_Schedule_Encrypt)
Rounds = 14
EndSelect
Key_Schedule_Decrypt = WorkingBufferA64 + 384
DecipheredOutput = WorkingBufferA64 + 896
AES_Key_Expansion_Decrypt(Key_Schedule_Encrypt, Key_Schedule_Decrypt, Rounds)
;-------------------------------------------------------------------------
If Cipher = #PB_Cipher_ECB
n = Blocks16 & 3
Select n
Case 0
AES_ECB_Decrypt_4Blocks(InputBytes, DecipheredOutput, Blocks16 << 4, Key_Schedule_Decrypt, Rounds)
Case 1
AES_ECB_Decrypt_1Block(InputBytes, DecipheredOutput, Key_Schedule_Decrypt, Rounds)
Case 2
AES_ECB_Decrypt_2Blocks(InputBytes, DecipheredOutput, Key_Schedule_Decrypt, Rounds)
Case 3
AES_ECB_Decrypt_3Blocks(InputBytes, DecipheredOutput, Key_Schedule_Decrypt, Rounds)
EndSelect
If n > 0 And Blocks16 > 3
AES_ECB_Decrypt_4Blocks(InputBytes + (n << 4), DecipheredOutput + (n << 4), (Blocks16 - n) << 4, Key_Schedule_Decrypt, Rounds)
EndIf
Else ;CBC, hier könnte wohl auch mit einem Block weniger angefangen werden, bringt aber wohl nichts
n = Blocks16 & 3
Select n
Case 0
AES_CBC_Decrypt_4Blocks(InputBytes, DecipheredOutput, InitializationVector, Blocks16 << 4, Key_Schedule_Decrypt, Rounds)
Case 1
AES_CBC_Decrypt_1Block(InputBytes, DecipheredOutput, InitializationVector, Key_Schedule_Decrypt, Rounds)
Case 2
AES_CBC_Decrypt_2Blocks(InputBytes, DecipheredOutput, InitializationVector, Key_Schedule_Decrypt, Rounds)
Case 3
AES_CBC_Decrypt_3Blocks(InputBytes, DecipheredOutput, InitializationVector, Key_Schedule_Decrypt, Rounds)
EndSelect
If n > 0 And Blocks16 > 3
AES_CBC_Decrypt_4Blocks(InputBytes + (n << 4), DecipheredOutput + (n << 4), InputBytes + ((n - 1) << 4), (Blocks16 - n) << 4, Key_Schedule_Decrypt, Rounds)
EndIf
EndIf ;Cipher
If LenPad ;Padding Decryption
If Cipher = #PB_Cipher_CBC
Last2Blocks = WorkingBufferA64 + 768
LastBlock16 = WorkingBufferA64 + 832
CopyMemory(InputBytes + (Blocks16 << 4), Last2Blocks, 16 - LenPad)
AES_ECB_Decrypt_1Block(InputBytes + AddrPad, LastBlock16, Key_Schedule_Decrypt, Rounds)
CopyMemory(LastBlock16 + 16 - LenPad, Last2Blocks + 16 - LenPad, LenPad)
CopyMemory(InputBytes + AddrPad, Last2Blocks + 16, 16)
If Blocks16 > 1
LastIV = InputBytes + ((Blocks16 - 2) << 4)
Else
LastIV = InitializationVector
EndIf
AES_CBC_Decrypt_2Blocks(Last2Blocks, BufferPad, LastIV, Key_Schedule_Decrypt, Rounds)
CopyMemory(BufferPad, DecipheredOutput + AddrPad, 32 - LenPad)
Else ;ElseIf; #PB_Cipher_ECB
For i = 0 To 15 - LenPad
PA.a = PeekA(DecipheredOutput + i + AddrPad)
PokeA(DecipheredOutput + 16 + i + AddrPad, PA)
Next
CopyMemory(InputBytes + 16 + AddrPad, BufferPad, 16 - LenPad)
CopyMemory(DecipheredOutput + 16 + AddrPad - LenPad, BufferPad + 16 - LenPad, LenPad)
AES_ECB_Decrypt_1Block(BufferPad, DecipheredOutput + AddrPad, Key_Schedule_Decrypt, Rounds)
EndIf
EndIf ;Padding Decryption
TE = ElapsedMilliseconds() - TA
TextGadget(8, 10, 215, 380, 20, "Time Decrypt NI: " + Str(TE) + " ms")
SaveFile$ = GetFilePart(SelFile$, #PB_FileSystem_NoExtension) + ".NIdec." + GetExtensionPart(GetFilePart(SelFile$, #PB_FileSystem_NoExtension))
Source = DecipheredOutput
EndIf ;Decryption
;-------------------------------------------------------------------------
TA = ElapsedMilliseconds()
CreateFile(1, SaveFile$)
For i = 0 To Chunks - 1
BytesWrite + WriteData(1, Source + (i * Cluster), Cluster)
Next
Rest = WriteData(1, Source + (Chunks * Cluster), RestBytes)
CloseFile(1)
TE = ElapsedMilliseconds() - TA
TextGadget(9, 10, 235, 380, 20, "Output-Bytes: " + StrU(BytesWrite + Rest))
TextGadget(10, 10, 255, 380, 20, "Time Copy File Memory -> HD/SSD: " + Str(TE) + " ms")
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
;Test/Vergleich mit PB:
TextGadget(11, 10, 290, 380, 20, "Test PB:")
ReadFile(0, SelFile$)
InputLen = Lof(0)
*PB_Eingabe = AllocateMemory(InputLen, #PB_Memory_NoClear) ;If... sonst splitten
*PB_Ausgabe = AllocateMemory(InputLen, #PB_Memory_NoClear) ;If...
For i = 0 To Chunks - 1
ReadData(0, *PB_Eingabe + (i * Cluster), Cluster)
Next
ReadData(0, *PB_Eingabe + (Chunks * Cluster), RestBytes)
Gibi = 1024 * 1024 * 1024
GibiM64 = Gibi - 64 ;damit vernünftiger Rest bleibt
LenVar = InputLen
PoiVar = 0
TA_PB = ElapsedMilliseconds()
If Encryption
Cipher_PB = Cipher | #PB_Cipher_Encode
NI_Output = CipheredOutput
Enc_Dec_PB$ = "Time Encrypt PB: "
Else ;Decryption
Cipher_PB = Cipher | #PB_Cipher_Decode
NI_Output = DecipheredOutput
Enc_Dec_PB$ = "Time Decrypt PB: "
EndIf
StartAESCipher(0, ?UserKey, KeySize, ?UserInitializationVector, Cipher_PB)
Repeat
If LenVar > Gibi
AddCipherBuffer(0, *PB_Eingabe + PoiVar, *PB_Ausgabe + PoiVar, GibiM64)
PoiVar + GibiM64
Else
AddCipherBuffer(0, *PB_Eingabe + PoiVar, *PB_Ausgabe + PoiVar, LenVar) ;Rest
Break
EndIf
LenVar - GibiM64
ForEver
FinishCipher(0)
TE_PB = ElapsedMilliseconds() - TA
TextGadget(12, 10, 310, 380, 20, Enc_Dec_PB$ + Str(TE_PB) + " ms")
TextGadget(13, 10, 330, 380, 20, "Compare Output NI-PB: " + Str(CompareMemory(NI_Output, *PB_Ausgabe, InputLen)))
;Für Tests kann auch noch Deciphered mit dem Original verglichen werden
FreeMemory(*PB_Eingabe)
TextGadget(14, 10, 350, 100, 20, "Save PB-File ?")
ButtonGadget(15, 110, 350, 50, 20, "Yes")
ButtonGadget(16, 180, 350, 50, 20, "No")
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
Until EventGadget() = 15 Or EventGadget() = 16
If EventGadget() = 15
If Encryption
SaveFile$ = GetFilePart(SelFile$) + ".PBenc"
Else ;Decryption
SaveFile$ = GetFilePart(SelFile$, #PB_FileSystem_NoExtension) + ".PBdec." + GetExtensionPart(GetFilePart(SelFile$, #PB_FileSystem_NoExtension))
EndIf
CreateFile(1, SaveFile$)
For i = 0 To Chunks - 1
WriteData(1, *PB_Ausgabe + (i * Cluster), Cluster)
Next
WriteData(1, *PB_Ausgabe + (Chunks * Cluster), RestBytes)
CloseFile(1)
EndIf
FreeMemory(*PB_Ausgabe)
CloseFile(0)
;-------------------------------------------------------------------------
TextGadget(20, 10, 380, 100, 20, "D O N E !")
FreeMemory(WorkingBuffer)
;FreeGadget... etc.
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
End
;-------------------------------------------------------------------------
DataSection ;Werte sind natürlich frei wählbar!
UserKey:
Data.b $8C, $15, $51, $2C, $0C, $8A, $0A, $D8, $07, $E4, $21, $A2, $8E, $83, $A3, $88 ;0-15: 128-Bit
Data.b $8A, $CA, $FB, $E1, $7B, $A3, $6B, $D6, $BC, $F7, $E6 ,$CD, $FE, $B5, $D7, $B3 ;0-23: 192-Bit, 0-31: 256-Bit
UserInitializationVector:
Data.b $08, $0C, $96, $48, $33, $51, $35, $80, $0C, $A9, $42, $1E, $11, $E0, $83, $C7
EndDataSection