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.
Blowfish Encryption Componet
-
sec
- Enthusiast

- Posts: 792
- Joined: Sat Aug 09, 2003 3:13 am
- Location: 90-61-92 // EU or ASIA
- Contact:
newbie,
AES*
notice: input/output is the same place
Please don't use
insead of
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
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 iCode: Select all
oldlen = len(plain) ; run once
for i = 0 to oldlen step 16
...
AES128Encrypt(plain,..) ; notice: input/output is the same place
...
next iless than 16 byte then you need padding (16- size of current plaintext) byte.
Shannara: These functions are extractly as desc in fips-197
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" ?
So how to do that ?
And then how to do such padding, adding null characters "0" ?
- Registered PB user -
Using PB 4.00
Using PB 4.00
-
sec
- Enthusiast

- Posts: 792
- Joined: Sat Aug 09, 2003 3:13 am
- Location: 90-61-92 // EU or ASIA
- Contact:
grrrr, any example?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.
Last edited by sec on Thu Aug 12, 2004 11:47 am, edited 1 time in total.
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.
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.
- Registered PB user -
Using PB 4.00
Using PB 4.00
-
sec
- Enthusiast

- Posts: 792
- Joined: Sat Aug 09, 2003 3:13 am
- Location: 90-61-92 // EU or ASIA
- Contact:
It must worknewbie 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.
Some clear example for other problem?
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 :
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 :
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.
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
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
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.
- Registered PB user -
Using PB 4.00
Using PB 4.00
-
sec
- Enthusiast

- Posts: 792
- Joined: Sat Aug 09, 2003 3:13 am
- Location: 90-61-92 // EU or ASIA
- Contact:
I think what you would do
Edit: d = d -16 (not d/16)
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
Last edited by sec on Fri Aug 13, 2004 1:54 am, edited 1 time in total.
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
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
If you take a look at the dates of the other threads, you will see that it is a long awaited Lib
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
- Registered PB user -
Using PB 4.00
Using PB 4.00
-
CherokeeStalker
- User

- Posts: 66
- Joined: Fri Oct 17, 2003 2:42 am
newbie wrote:ok Sec, I have managed to code a complete example to use your lib, which works without any errors :
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 :)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)))
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)))
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
(i'll post it when i will be 100% sure it is ok)
EDIT :
viewtopic.php?p=66818#66818
- Registered PB user -
Using PB 4.00
Using PB 4.00
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.
