Menu

#1 EncryptString(UnicodeString) incorrectly assumes s[1] is starting string position - which is not the case with NextGen compiler (Linux64, Mobile, etc)

1.0
open
nobody
None
2018-03-06
2017-10-16
Kent Miller
No

In the following code in the blockcipher class, (and methods like it)

{$IFDEF UNICODE}
function TDCP_blockcipher.EncryptString(const Str: UnicodeString): UnicodeString;
begin
  SetLength(Result,Length(Str));
  EncryptCFB8bit(Str[1],Result[1],Length(Str)*SizeOf(Str[1]));
  Result:= Base64EncodeStr(Result);
end;
{$ENDIF}

should be replaced with NextGen compiler 0 based string accessor compatible with Windows compiler

  EncryptCFB8bit(Str[low(str)],Result[low(result)],Length(Str)*SizeOf(Str[1]));

In addition, in order to support NextGen compiler - which don't understand the AnsiString type - they should be enclosed in $IFDEF to allow compiler to build the source
function TDCP_blockcipher.EncryptString(const Str: AnsiString): AnsiString;

{$IFNDEF NextGen}
function TDCP_blockcipher.EncryptString(const Str: AnsiString): AnsiString;
...
{$ENDIF}

Discussion

  • Lorenzo Monti

    Lorenzo Monti - 2017-10-28

    Thank you for your suggestion. I'll look at this.
    You may actively contribute to the project providing the patched source files, if you wish.

     
  • Kent Miller

    Kent Miller - 2018-03-06

    Thanks Lorenzo. I thought about doing that, but the way I had to work around stuff to compile for android was to make a new method that took a TBytes array - I wasn't aware the Delphi compiler supported RawByteString on Android, but it appears that Embarcadero did do that. All of the research on that type that I had read was that it wouldn't work on those devices without some "translation unit" that did conversions. I think someone (Nick Hodges?) also provided some sort of code/unit hack, but I wasn't about to try and use it.

    Also, I've not actually used SVN/Sourceforge before, so wasn't sure how I would go about submitting code modifications to the project.

    I am working on my first serious mobile app while needing to maintain compatibility with a Windows server that uses encryption for both the data and the transmission. I didn't realize the string offset was a problem, but couldn't understand why the data came out partially decrypted until I converted everyting over to byte arrays.

    I think the implementation you have in r16 is much cleaner than what I had done.
    I did note a couple of other differences as I was going back through what I had done so the code would build for android:

    All of the SelfTest methods for the hash classes cast their UpdateStr parameters to AnsiString - which don't compile. I'm not sure a direct cast to RawByteString works in this case either?

    Though I didn't test the result on android, I replaced those with the following (which works on Windows at least):

    B: TBytes;
    
      B:=SysUtils.TEncoding.ASCII.GetBytes('what ever test string was originally defined');
      TestHash.Update(B[0],length(B));
    

    I also noticed some other pointer problems in DCPserpent, and DCPtea - where the pointers appear to still be cast as if they are 32-bit (at least that is what I think it is doing) - Not being familiar with what the encryption code actually does, I'm not 100% certain what the intent for these instances is. (I never use pointers/pointer math in my own code)

    pdword(longword(@Indata)+ [0,4,8, or 12])^
    pdword(longword(@outdata)+ [0,4,8, or 12])^
    

    ex:
    ~~~
    b:= PDWord(longword(@InData)+4)^;
    ~~~

    instead of using the conversion PointerToInt like other units do

    pdword(PointerToInt(@Indata)+ [0,4,8, or 12])^
    pdword(PointerToInt(@outdata)+ [0,4,8, or 12])^
    

    I'm not using either one of those for my 64-bit server, so have not bothered to do anything about it.

     

    Last edit: Kent Miller 2018-03-06

Log in to post a comment.

MongoDB Logo MongoDB