Baeh, now troubles with multiples of FileReadBufferSize fixed.
---
- Fixed trouble when the file read buffer was as big as the file itself.
- Fixed another padding hick-up (a file containing only 20 20 20 20 20 20)
These padding conditions can give a head-ache!
-----
- Fixed unsigned/signed hick-up
- Freeing memory
- Updated padding method. Now the value of the padded byte is equal to the numbers of bytes to pad. If 12 bytes are needed, the pad (hex) is "0c".
---------------
Another thought:
Trouble is with files that are multiples of 16 already _and_ contain 00 bytes at the end. The decryption unpadding tries to unpad then.
That was what I meant when saying "not sure which padding method to use"

Will switch to RFC2630 padding.
Edit: Ah, seems to be really a filesize issue; strangely, small files I tried worked, but a 3KB exe I made didn't. Will look into it. Yep, it indeed is a padding issue.
newbie wrote:Max.² wrote:newbie wrote:Thanks Max.² for the correction about the page, it is done

Dunno if you saw it, but I updated the file crypt procedure some posts ago.
Let me try it first my the Lib I use
EDIT : I tested your code Max with your last Lib (from the link within the code) and it is not correct unfortunaly :-/
When encrypting a 3Ko executable, the final decrypted is 2.98Ko, and is not runable (Windows gives an error).
I just changed the target file, and input/output files, do I need to change anything else ?
This is the latest version I am using; since yesterday, no matter which file type and file size, it worked correctly. Only thing I changed was key handling, but that shouldn't have an effect on the result.
Code: Select all
;http://www.host4scripts.de/pub/AESLIB.zip ; use just _1_ of the libs
;to make life easier, FileReadBufferSize needs to be a multiplier of 16
;Key is meant hexademical. A common way to generate a 16 byte key out of a password is to use MD5Fingerprint
;Procedure by PB / english forum
Procedure.l hex2dec(h$)
h$=UCase(h$)
For r=1 To Len(h$)
d<<4 : a$=Mid(h$,r,1)
If Asc(a$)>60
d+Asc(a$)-55
Else
d+Asc(a$)-48
EndIf
Next
ProcedureReturn d
EndProcedure
Procedure AES_Crypt_File(Mode,InFilename.s,OutFileName.s,Key.s,FileReadBufferSize)
;Mode 0 = Encrypt
;Mode 1 = Decrypt
If FileReadBufferSize % 16 = 0
#OutFile = 0
#InFile = 1
FileIn=OpenFile(#InFile,InFilename.s)
If FileIn<>0
;Key transformation
*KeyBuffer = AllocateMemory(16)
j=-1
For i=1 To Len(Key.s) Step 2
j=j+1
PokeB(*KeyBuffer+j,Hex2Dec(Mid(Key,i,2)))
Next i
KeyLengthinBits = Len(Key)*4
AES_Gen_Tabs()
If Mode = 0
Ecx.s = Space(255)
AES_Encrypt_Key(*KeyBuffer, KeyLengthinBits, @Ecx)
ElseIf Mode = 1
Dcx.s = Space(255)
AES_Decrypt_Key(*KeyBuffer, KeyLengthinBits, @Dcx)
EndIf
*InputBuffer = AllocateMemory(FileReadBufferSize)
*OutputBuffer = AllocateMemory(FileReadBufferSize)
*PlainBlock = AllocateMemory(16)
*EncryptionBlock = AllocateMemory(16)
FileLength = FileSize(InFileName)
BlocksToRead = Int(FileLength/FileReadBufferSize)
Result=CreateFile(#OutFile,OutFileName)
If Result
For Offset = 0 To BlocksToRead
If OffSet<BlocksToRead
BlockSize = FileReadBufferSize
Else
BlockSize = FileLength-Offset*FileReadBufferSize
EndIf
; get data from input file
UseFile(1)
FileSeek(OffSet*FileReadBufferSize)
Result=ReadData(*InputBuffer,BlockSize)
;Pad (make multiple of 16bytes) if needed
If BlockSize<>FileReadBufferSize And Mode = 0
Debug "Pad!"
PadBytes = (FileReadBufferSize - BlockSize) % 16
Debug "Need to pad with "+Str(PadBytes)+" bytes"
For i=0 To PadBytes-1
;Using pad method RFC2630
PokeB(*inputBuffer+Blocksize+i,PadBytes)
Next i
BlockSize = BlockSize + PadBytes
EndIf
; write data to outputfile
UseFile(0)
For EncryptionBlockOffset = 0 To FileReadBufferSize / 16
CopyMemory(*InputBuffer+EncryptionBlockOffset*16, *PlainBlock , 16)
If Mode = 0
AES_Encrypt(*PlainBlock,*EncryptionBlock,@Ecx)
ElseIf Mode = 1
AES_Decrypt(*PlainBlock,*EncryptionBlock,@Dcx)
EndIf
CopyMemory(*EncryptionBlock,*OutputBuffer+EncryptionBlockOffset*16,16)
Next EncryptionBlockOffset
FileSeek(OffSet*FileReadBufferSize)
;Strip padded bytes
If mode=1 And ((offset = BlocksToRead) Or (FileLength % FileReadBufferSize = 0))
Debug "Unpad!"
PaddedBytes=PeekB(*OutputBuffer+BlockSize-1) & $FF
Debug "Supposed # of padded bytes: "+Str(PaddedBytes)
For i=1 To PaddedBytes
If PeekB(*OutputBuffer+BlockSize-i)<>PaddedBytes
Debug "False alarm. No unpadding needed."
Break
EndIf
Next i
If i>PaddedBytes And PaddedBytes<16
BlockSize=BlockSize-PaddedBytes
Debug "Decreasing Block by "+Str(PaddedBytes)+" to get rid of padded bytes"
EndIf
EndIf
WriteData(*OutputBuffer,BlockSize)
Next Offset
CloseFile(#InFile)
CloseFile(#OutFile)
EndIf
FreeMemory(-1)
EndIf
Else
Error = 1
EndIf
EndProcedure
start = GetTickCount_()
Key.s = "00010203050607080A0B0C0D0F101112"
InFile.s = "c:\_2.mpg"
EncryptFile.s = "c:\_Encrypt.enc"
DecryptFile.s = "c:\_Decrypt.exe"
AES_Crypt_File(0,InFile.s,EncryptFile.s,Key.s,8192*2)
AES_Crypt_File(1,EncryptFile.s,DecryptFile.s,Key.s,8192*2)
Debug "Milliseconds: "+Str(GetTickCount_()-start)
If MD5FileFingerprint(InFile) = MD5FileFingerprint(DecryptFile)
Debug "ok"
Else
Debug "error"
EndIf