0

Presently I am trying to port an encryption library written in C to Delphi. It is almost finished, however the C source code consists of the following instructions that I have not been able to cope with so far.

unsigned char one_block[16];
unsigned char * iv
((unsigned int *)one_block)[3] = ((unsigned int *) iv)[3];

...

I tried to convert it even as

var
  one_block: Array[0..15] of Byte;
  iv : PByte;
begin
  PDWord(one_block[3]):= PDWord(iv[3]);
  ...
end; 

but it obviously fails to compile, because the left side of the expression cannot be assigned.

Can anyone with more practice in porting give me a hint on how to solve this problem? Thank you in advance.

2
  • You've used one_block in both of your code snippets, with no indication of what it might be. You've also not assigned any value to iv before trying to access iv[3]. It's pretty difficult to try to port code when you haven't included the major parts. Commented Jul 26, 2014 at 15:01
  • Sorry Ken. You absolutely are right. They are mistyping in both cases. 'one_block' should have been 'block' as in the declaration parts. Commented Jul 26, 2014 at 15:08

2 Answers 2

4

Try the following:

{$POINTERMATH ON}
PCardinal(@one_block)[3] := PCardinal(iv)[3]; // fills bytes 12..15 of one_block

As the comments say, I assume that the C code somehow initializes iv, and also sets the other parts of one_block. You did not show that.

Now, if your version of Delphi does not support $POINTERMATH, you'll have to do:

type
  PCardinalArray = ^TCardinalArray;
  TCardinalArray = array[0..3] of Cardinal;

  ...

  PCardinalArray(@one_block)^[3] := PCardinalArray(iv)^[3];
Sign up to request clarification or add additional context in comments.

6 Comments

This one seems to work at first glace but I need to check the whole procedure.
It should work. But if you like it, don't hesitate to upvote it.
Note that, as I commented, PCardinal(@x)^[3] accesses x as if it were an array of Cardinals (or DWORDs), so its sets the third Cardinal, or bytes 12..15 of the array.
FWIW, my obligatory recommendation: Addressing pointers.
My only suggestion is to not use PCardinal, since it is a generic type that could change size in a future release (it already has once before). PDWord or PUint32 is more appropriate and matches the C code.
|
1
PDWord(one_block)[3] := PDWord(iv)[3]; 

...if Pascal/Delphi can use PDWord as array.
1. Cast (change type of the array).
2. Acces the array (of ints/dwords).

EDIT:

Well, IV and BLOCK should be used as

array[0..3] of Integer (or DWord)

...as it seems you are using AES-128

so, you should declare

TBlock = array[0..3] of Integer/Dword
PBlock = ^TBlock

and cast it this way

PBlock(@block)^[3] = PBlock(@iv)^[3]

or maybe directly

TBlock(block)[3] = TBlock(iv)[3]

...I am sorry but it has been 10 years I was working with Delphi

3 Comments

Thank you, but I already tried this solution without success. In Delphi, the left side of an expression like this can't be assigned to.
try casting to ^array of integers - see stackoverflow.com/questions/8508783/…
Not quite correct. iv is already a pointer, so should not be referenced: PBlock(@one_block)^[3] := PBlock(iv)^[3];. That was my solution too. <g>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.