Page 2 of 2

Re: AES query...

Posted: Sun Feb 21, 2021 2:09 pm
by Helle
Padding in PB are not fix values. The last Block is internal expanded with the last Bytes of the Block before.
This is a simple example:

Code: Select all

;No Unicode!!!

String$ = "Hello this is a test for AES"
Debug String$
Debug "Len: " + Len(String$)           ;28, we need 32
*CipheredString   = AllocateMemory(Len(String$) + 1)  ;with Zero_Byte
*DecipheredString = AllocateMemory(Len(String$) + 1)  ;with Zero_Byte
  
AESEncoder(@String$, *CipheredString, Len(String$), ?KeyPB, 128, 0, #PB_Cipher_ECB)
Debug "Ciphered: "+PeekS(*CipheredString)
    
For i = 0 To Len(String$) - 1
  If i % 16 = 0
    Debug "=========================================="     ;Optik
  EndIf
  Debug Hex(PeekA(*CipheredString + i))
Next

AESDecoder(*CipheredString, *DecipheredString, Len(String$), ?KeyPB, 128, 0, #PB_Cipher_ECB)
Debug "Deciphered: " + PeekS(*DecipheredString)

Debug "=========================================="
Debug "Internal:"
String1$ = Space(32)
For i = 0 To Len(String$) - 1
  PokeA(@String1$ + i, PeekA(@String$ + i))
Next

;Length of last Block is 12 -> we need 4 Bytes
PokeA(@String1$ + 28, $5)    ;copy Bytes from the Block before last Block into last Block (see Debug-Output)
PokeA(@String1$ + 29, $31)
PokeA(@String1$ + 30, $c8)
PokeA(@String1$ + 31, $94)

*CipheredString1   = AllocateMemory(Len(String1$) + 1)     ;with Zero_Byte
*DecipheredString1 = AllocateMemory(Len(String1$) + 1)     ;with Zero_Byte

AESEncoder(@String1$, *CipheredString1, Len(String1$), ?KeyPB, 128, 0, #PB_Cipher_ECB)
;Debug "Ciphered: " + PeekS(*CipheredString1)
    
For i = 0 To Len(String1$) - 1
  If i % 16 = 0
    Debug "=========================================="
  EndIf
  Debug Hex(PeekA(*CipheredString1 + i))
Next
If i % 16 = 0
  Debug "=========================================="
EndIf

;now change the last Block with the Block before and set old Length
Buffer = AllocateMemory(32)
CopyMemory(*CipheredString1, Buffer + 16, 16)
CopyMemory(*CipheredString1 + 16, Buffer, 16)
For i = 0 To 31
  If i % 16 = 0
    Debug "=========================================="
  EndIf
  Debug Hex(PeekA(Buffer + i))
Next
If i % 16 = 0
  Debug "=========================================="
EndIf

PokeB(Buffer + 28, 0)        ;set old String-Length

For i = 0 To 27
  If i % 16 = 0
    Debug "=========================================="
  EndIf
  Debug Hex(PeekA(Buffer + i))
Next
If i % 16 = 0
  Debug "=========================================="
EndIf

AESDecoder(Buffer, *DecipheredString1, Len(String$), ?KeyPB, 128, 0, #PB_Cipher_ECB)
Debug "Deciphered: " + PeekS(*DecipheredString1)

DataSection
  KeyPB:
    Data.b $06, $a9, $21, $40, $36, $b8, $a1, $5b, $51, $2e, $03, $d5, $34, $12, $00, $06
EndDataSection


Re: AES query...

Posted: Sun Feb 21, 2021 4:07 pm
by Saki

Re: AES query...

Posted: Sun Feb 21, 2021 7:00 pm
by DoubleDutch
@Saki - that seems to be exactly what @Fred must have done - well done for figuring it out. :)

Re: AES query...

Posted: Mon Feb 22, 2021 7:52 pm
by Saki
Thanks Helle for the Code

Hi DoubleDutch
I have implemented this quickly new.

For the CBC mode I haven't looked at it yet.
Whereby it would also be helpful to know exactly how it is done in PB, otherwise it can quickly become time consuming.
Maybe someone wants to expand it, I myself do not need it.

Code: Select all

; This code demonstrates the standard decryption with PB AES - CTS of encrypted data which is not divisible by 16

; ECB Mode

EnableExplicit
Define iv$=Space(8)
Define key$=Space(8)
Define test$="Hello World, i hope you are well !" ; StringByteLength
Define ByteLength=StringByteLength(test$)
Define difference=ByteLength%16
If Bytelength<16
  MessageRequester("Hint", "PB AES supports not bytelength < 16"+#LF$+#LF$+
                           "You can fix this with a QAES module"+#LF$+
  "https://www.purebasic.fr/english/viewtopic.php?f=12&t=76780")
  End
  EndIf
AESEncoder(@test$, @test$, ByteLength, @key$, 128, @iv$, #PB_Cipher_ECB) ; We encrypt the characters

If difference
Define *buffer_0=AllocateMemory(16) ; We create a buffer for the last incomplete block
Define *buffer_1=AllocateMemory(16) ; We create a buffer for the last block
Define *buffer_2=AllocateMemory(ByteLength)

CopyMemory(@test$+ByteLength-difference, *buffer_0, difference)
CopyMemory(@test$+ByteLength-difference-16, *buffer_0, 16)

AESDecoder(*buffer_0, *buffer_0, 16, @key$, 128, @iv$, #PB_Cipher_ECB) ; Decrypt difference bytes

CopyMemory(*buffer_0+difference, *buffer_1+difference, 16-difference)
CopyMemory(@test$+ByteLength-difference, *buffer_1, difference)

AESDecoder(*buffer_1, *buffer_1, 16, @key$, 128, @iv$, #PB_Cipher_ECB) ; Decrypt the second to last block

FillMemory(*buffer_0+difference, 16-difference)

AESDecoder(@test$, @test$, Bytelength-16-difference, @key$, 128, @iv$, #PB_Cipher_ECB) ; Decrypt the second to last block
test$=Left(test$, (Bytelength-16-difference)/SizeOf(character))

Debug test$+PeekS(*buffer_1)+PeekS(*buffer_0)
Else
AESDecoder(@test$, @test$, Bytelength, @key$, 128, @iv$, #PB_Cipher_ECB) ; Decrypt the second to last block
Debug test$
EndIf