Page 5 of 5

Posted: Wed Aug 11, 2004 8:14 pm
by Shannara
Heh, no problemo, I find alot of people making that mistake :)

Anyways, I actually have fully working code in VB but not PB yet (the equivilent), but thats ok for now, I'll keep on searching.

Posted: Thu Aug 12, 2004 2:14 am
by sec
newbie,
AES*
notice: input/output is the same place
Please don't use

Code: Select all

for i = 0 to len(plain) step 16
...
AES128Encrypt(plain,..) ; notice: input/output is the same place
...

next i
insead of

Code: Select all

oldlen = len(plain) ; run once
for i = 0 to oldlen step 16
...
AES128Encrypt(plain,..) ; notice: input/output is the same place

...
next i
And yes blocksize must equal 128 bit (16byte), if size of current plaintext
less than 16 byte then you need padding (16- size of current plaintext) byte.
Shannara: These functions are extractly as desc in fips-197 :)

Posted: Thu Aug 12, 2004 3:15 am
by Shannara
sec: Please read my previous post in this thread :)

Posted: Thu Aug 12, 2004 5:34 am
by sec
Shannara: i want to talk that: this lib is not "AES hybrid" :twisted:

Posted: Thu Aug 12, 2004 11:21 am
by newbie
Sec, as I said in comments in my last code posted, when I am in the decryption procedure in my program, the program did not encrypt the buffer it has received( via network) so there is no way for it to decrypt until the length of the "oldlen" that it does not know.

So how to do that ?
And then how to do such padding, adding null characters "0" ?

Posted: Thu Aug 12, 2004 11:38 am
by sec
I am in the decryption procedure in my program, the program did not encrypt the buffer it has received( via network) so there is no way for it to decrypt until the length of the "oldlen" that it does not know.
grrrr, any example? :)

Posted: Thu Aug 12, 2004 11:43 am
by newbie
The code is too much split and huge to post it here, but I just found that in my case I always use AES to encode a cheksum which is always 32 bytes... so no pb on this side.

Anyway in case of later encryption of data not being a multiple of 16 (16, 32 ,etc...) I am working on a padding will null bytes and I think it should work.

About the code you want, just take the last onr I posted, and as stated in the comments, assume that the last lines to decrypt are in another program, and does nto have the information above.

Posted: Thu Aug 12, 2004 11:57 am
by sec
newbie wrote:The code is too much split and huge to post it here , but I just found that in my case I always use AES to encode a cheksum which is always 32 bytes... so no pb on this side.

Anyway in case of later encryption of data not being a multiple of 16 (16, 32 ,etc...) I am working on a padding will null bytes and I think it should work.
It must work :)
Some clear example for other problem?

Posted: Thu Aug 12, 2004 12:25 pm
by newbie
My other problem is that when I decrypt until the length of the encrypted buffer (and not until the length of the old plain text) it works, because It seems that my padding fails.

buffer size start = 35 bytes
encrypted size = 35 bytes
so, decrypted size = 35 bytes

my two procs :

Code: Select all

Global AESkey.s
AESkey = MD5Fingerprint("toto", 4) 

Procedure AESEncrypt(*Buffer);, *local_key)
    Static local_key1.s
    If local_key1 = ""
        local_key1 = AESkey
    EndIf
    length_buff.l = Len(PeekS(*Buffer)) ; len(plain)
    padding.l = length_buff 
    While padding >= 16
        padding - 16
    Wend
    If padding > 0
        padding = 16 - padding ; bytes missing to do a 128 bits block
    EndIf
     
    Debug "PeekS(*Buffer) = " + PeekS(*Buffer)
    Debug "Len(PeekS(*Buffer)) = " + Str(length_buff)
    Debug "PADDING = " + Str(padding)
    
    For a = 0 To length_buff Step 16
        AES256Encrypt(*Buffer + a, @local_key1)
        Debug "a = " + Str(a)
        Debug "PeekS(*Buffer) = " + PeekS(*Buffer)
    Next a
   
    If padding > 0
        Debug "ADDING " + Str(padding) + " null bytes" 
        For i = 0 To padding
            PokeB(*Buffer+a+i, $0)
        Next
    EndIf
    ProcedureReturn *Buffer
EndProcedure

Procedure AESDecrypt(*Buffer);, *local_key)
    Static local_key2.s
    If local_key2 = ""
        local_key2 = AESkey
    EndIf
    length_buff.l = Len(PeekS(*Buffer))
    
    For a = 0 To length_buff Step 16 
        AES256Decrypt(*Buffer + a, @local_key2)

    Next a
    ProcedureReturn *Buffer
EndProcedure
It seems that adding null bytes is just to "follow the FIPS standard" but in reality, that there is one or many null bytes to reach the next 128 bits block, the decryption proc anyway only read the encrypted buffer.

So the final point is : is these two procedure 100% to work with your lib ?
It seems that you don't like in the decryption procedure the " For a = 0 To length_buff Step 16 ", but as I said this procedure is in another program
which do not know the original size, and moreover it works anyway 8O

So : good/ not good ?
If not good why does it work ?
And how to have both good & working example.

I know it's not necessarely clear ... :roll:

EDIT : just imagine that the decryption procedure just receive in argument the encrypted buffer, and does not know the original plain text size.

EDIT 2 :
I noticed that you shouldn't encrypt/decrypt until the size, but until the size-16.
Indeed, let's say our buffer is 32 bytes, a = 0, so bytes 1 to 16 are encrypted, then a = a + 16, and bytes from 16 to 32 are encrypted, no need to do again a = a + 16 !
Am i right ?

here is what I mean :

Code: Select all


#CHECKSUM_SIZE = 32

Procedure AESEncryptMD5(*Buffer);, *local_key)
    Static local_key1.s
    If local_key1 = ""
        local_key1 = AESkey
    EndIf
    length_buff.l = #CHECKSUM_SIZE-16
    
    ;Debug "AESEncrypt() AESkey = " + local_key1
    Debug "PeekS(*Buffer) = " + PeekS(*Buffer)
    Debug "Len(PeekS(*Buffer)) = " + Str(length_buff)
    For a = 0 To length_buff Step 16
        AES256Encrypt(*Buffer + a, @local_key1)
        Debug "a = " + Str(a)
        Debug "PeekS(*Buffer) = " + PeekS(*Buffer)
    Next a
    ProcedureReturn *Buffer
EndProcedure

Procedure AESDecryptMD5(*Buffer);, *local_key)
    Static local_key2.s
    If local_key2 = ""
        local_key2 = AESkey
    EndIf
    length_buff.l = #CHECKSUM_SIZE-16
    ; Debug "AESDecrypt AESkey = " + local_key2
    For a = 0 To length_buff Step 16 
        AES256Decrypt(*Buffer + a, @local_key2)
    Next a
    ProcedureReturn *Buffer
EndProcedure
I think that these two one are perfect ^^
My problems is for the two above for padding.

EDIT 3 :
As soon as the "MD5 encrypt/decrypt" (32 bytes) are SEC certified, and as soon as the normal one (to encrypt/encrypt data from any size) are SEC certified, I would want to make another post in General or Windows, as "AES" to make things more simple, and where people would grab SEC's lib and the procedures to use it.

Posted: Thu Aug 12, 2004 3:31 pm
by sec
I think what you would do

Code: Select all

Encrypt proc::
d = _size of buffer to encrypt  (use: len(), filesize(), globalsize_() ..)
m = d % 16 (d modulo 16)
k = _size of keybuffer (use: len(), filesize(), globalsize_() ..)

m = 0
if m >0 
padding (16 - (d % 16)) bytes to buffer to encrypt
d = d+(16 - (d % 16))
endif

process(keybuffer and k) 
while d <>0
d = d - 16 
select k:
case 16: ;k = 16
to call AES128Encrypt

case 24: ;k = 24
to call AES192Encrypt

case 32: ; k =32
to call AES256Encrypt

endselect
wend
Edit: d = d -16 (not d/16)

Posted: Thu Aug 12, 2004 5:16 pm
by newbie
Thanks for the explanations and for your wonderfull lib !
If you take a look at the dates of the other threads, you will see that it is a long awaited Lib :D

EDIT :
If I dare one more question, do I have to do padding too with Blowfish ?
So I guess it is this time for 64 bits blocks ?

EDIT 2 : I answer myself : yes !
Just do two padding functions, one for Blowfish (64 bits blocks) and the other for AES (128 bits blocks), allocate memory regarding the size required, and all works fine ;)

Posted: Thu Aug 12, 2004 9:41 pm
by CherokeeStalker
newbie wrote:ok Sec, I have managed to code a complete example to use your lib, which works without any errors :

Code: Select all

Procedure AESEncrypt(*Buffer, *Key)
    For a = 0 To Len(PeekS(*Buffer)) Step 16
        AES256Encrypt(*Buffer + a, *Key)
    Next a
    ProcedureReturn *Buffer
EndProcedure

Procedure AESDecrypt(*Buffer, *Key)
    For a = 0 To Len(PeekS(*Buffer)) Step 16 
        AES256Decrypt(*Buffer + a, *Key)
    Next a
    ProcedureReturn *Buffer
EndProcedure


plain.s = "I am a fan of SEC now :-) lololoLOL" ; our plain text
key.s = MD5Fingerprint("toto", 4)               ; creating an AES key of 256 bits

Debug "clear = " + plain                        
Debug "len(clear) = " + Str(Len(plain))
Debug "key = " + key

length_required.l = Len(plain)                  ; length required for the buffer
Debug "length_required = " + Str(length_required)
    
*cypher_text = AllocateMemory(length_required)  ; creating the buffer to the right input/output size
PokeS(*cypher_text, plain, length_required)     ; copying our plain text into the buffer
Debug "LEN *cypher_text = " + Str(Len(PeekS(*cypher_text)))

;-encryption
*cypher_text = AESEncrypt(*cypher_text, @key)   ; encrypting our plain text

Debug "encrypted = " + PeekS(*cypher_text, length_required)
Debug "LEN encrypted = " + Str(Len(PeekS(*cypher_text, length_required)))

;- decryption
;let's assume that this is a break in the code, like for instance an encrypted file that we did not encrypt
;or any encrypted data for which we do not know the size of the plain text

;*cypher_text would be @plain_text$ for instance

*plain_text = AESDecrypt(*cypher_text, @key)    ; decrypting the cypher text

Debug "clear = " + PeekS(*plain_text);, length_required)
Debug "LEN clear = " + Str(Len(PeekS(*plain_text)))
These two functions can be easily combined with your libs, it's more convenient. If you have any correction to do, feel free to do it of course, I whish to learn :)

Even if this code works perfectly, I do not understand something.
From the FIPS PDF document about AES, the output cypher text size depends on the size of the plain text size, as follow :

0 <= Len(plain_text) <= 16 -> output size of 128 bits
( '<=' means less or equal)

So obviously, a 32 bytes string will have a 256 bits output.
But so, shouldn't a 33 bytes string have a 256 + 128 = 348 bits output ??
In the code, the plain text example is 35 bytes (280 bits), So if you take
the first 32 bytes, you need 256 bits of buffer + another 128 bits buffer for the remaining 3 bytes.
However in the code above, I only give 35 bytes of buffer (instead of 48 which crash ?!) and it works just fine.

I need to know if the code above is right and reliable (you know you can do a perfect lib, if it's not used right, especially for encryption, it will give BS and won't have the security level expected), and to understand what is
the problem with my understanding of the buffer encoding size.

Anyway, that's a _very_ great job from Sec, and I hope to know soon if Shannara has found what she was looking at for some time now :)

NO - the code above is not reliable (or the LIB is flawed) !
Change the code as below . . . it does not work !

Procedure AESEncrypt(*Buffer, *Key)
For a = 0 To Len(PeekS(*Buffer)) Step 16
AES256Encrypt(*Buffer + a, *Key)
Next a
ProcedureReturn *Buffer
EndProcedure

Procedure AESDecrypt(*Buffer, *Key)
For a = 0 To Len(PeekS(*Buffer)) Step 16
AES256Decrypt(*Buffer + a, *Key)
Next a
ProcedureReturn *Buffer
EndProcedure

; plain.s = "I am a fan of SEC now :-) lololoLOL" <---- This works
plain.s = "I am a fan of SEC now :-) lololoLOa" ; <----- This Doesn't Work
key.s = MD5Fingerprint("toto", 4) ; creating an AES key of 256 bits

Debug "clear = " + plain
Debug "len(clear) = " + Str(Len(plain))
Debug "key = " + key

length_required.l = Len(plain) ; length required for the buffer
Debug "length_required = " + Str(length_required)

*cypher_text = AllocateMemory(length_required) ; creating the buffer to the right input/output size
PokeS(*cypher_text, plain, length_required) ; copying our plain text into the buffer
Debug "LEN *cypher_text = " + Str(Len(PeekS(*cypher_text)))

;-encryption
*cypher_text = AESEncrypt(*cypher_text, @key) ; encrypting our plain text

Debug "encrypted = " + PeekS(*cypher_text, length_required)
Debug "LEN encrypted = " + Str(Len(PeekS(*cypher_text, length_required)))

;- decryption
;let's assume that this is a break in the code, like for instance an encrypted file that we did not encrypt
;or any encrypted data for which we do not know the size of the plain text

;*cypher_text would be @plain_text$ for instance

*plain_text = AESDecrypt(*cypher_text, @key) ; decrypting the cypher text

Debug "clear = " + PeekS(*plain_text);, length_required)
Debug "LEN clear = " + Str(Len(PeekS(*plain_text)))

Posted: Thu Aug 12, 2004 9:47 pm
by newbie
the post was "old", since the code has changed ;)

(i'll post it when i will be 100% sure it is ok)

EDIT :
viewtopic.php?p=66818#66818

Posted: Tue Aug 24, 2004 5:17 pm
by kake26
Okay, a bit of rant here. I tried to do something nice and all you people care about are PureLibs, okay. And some has bitched about my thing not being compatable with other blowfish stuff. I told you before I use a SHA512 hash to ensure a consistant 448 bit and thats why he encountered that. I can't believe some people are so narrow minded about DLLs. Excuse me for thinking on scale larger than just PB, its easier to use a lib in other languages than a PureLib you know. Anyhow I though I'd share it with you people. I'm not out to bash PB here, I just ended up like feeling my attempt to contribute was a waste.

Posted: Tue Aug 24, 2004 5:30 pm
by newbie
wow, i'm surprised you take it like that 8O

*I* _prefer_ to not use DLL, it's a personal preference, not a narrow minded
general DLL bashing.

Take it easy.