Re: [strongSwan] Strongswan 4.2.14 broken on ARM ?

2009-05-20 Thread Graham Hudspith
> I've removed any reads to unaligned integers in the parser code [1],
generator looks OK so far. I don't have an ARM box, so any feedback is
very welcome.
>
> Thanks
> Martin
>
> [1]http://wiki.strongswan.org/repositories/diff/strongswan?rev=42748858
>
>

Martin,

Thanks for that patch.

With a small bit of adjustment, I managed to apply the patch to my
copy of the 4.2.14 code, :-), and rebuild.

It seems to work fine, so far.

I did have a small problem the first time I brought the ARM up, in
that the initial SA came up fine but then something started creating LOTS
of child SAs. I pulled the plug on the ARM box after we got to 100 child
SAs. Unfortunately, I did not have any charon logging turned on, so had no
logs to comb through.

Since then, restarting the ARM box and bringing up the connection has
exhibited no problems (and no unwanted child SAs).

So, looking good (but feeling slightly nervous about it needing wider
testing).

Regards,

Graham.







___
Users mailing list
Users@lists.strongswan.org
https://lists.strongswan.org/mailman/listinfo/users


Re: [strongSwan] Strongswan 4.2.14 broken on ARM ?

2009-05-18 Thread Martin Willi
Hi,

> Whenever the byte in memory is half-word-aligned, reading it as a uint16
> works as expected. The other half of the time, the compiler is adjusting
> the pointer (back one) to make it half-word-aligned before reading the two
> bytes as a uint16.

Yes, it seems that some ARM CPUs don't like unaligned (half-)word reads.

> I can find at least 26 occasions in the strongSwan code where this
> reading-a-byte-pointer-as-a-uint16-pointer idiom occurs.

I think not all of them are problematic. GCC should align struct members
properly, so read/write to struct members shouldn't be a problem (except
__packed__ ones, I'll review those).

I've removed any reads to unaligned integers in the parser code [1],
generator looks OK so far. I don't have an ARM box, so any feedback is
very welcome.

Thanks
Martin

[1]http://wiki.strongswan.org/repositories/diff/strongswan?rev=42748858

___
Users mailing list
Users@lists.strongswan.org
https://lists.strongswan.org/mailman/listinfo/users


Re: [strongSwan] Strongswan 4.2.14 broken on ARM ?

2009-05-15 Thread Graham Hudspith
> Hi,
>
> I wonder if anyone can please help me with a problem I'm having getting
> strongSwan (4.2.14) running on the ARM ?
>
> I've played about getting strongSwan working on x86 setting up a tunnel to
> a server. I then compiled strongSwan for ARM and copied across the config
> files I used on x86.
>
> The ARM version fails to set up the tunnel.
>

I hate replying to my own email, but I've been playing around with the ARM
compiler.

>
> Can anyone explain this and how to fix it easily ?
>

It seems that there is a word (or, half-word) alignment thing going on here.

I've written another test program which iterates through the array of 6
bytes, converting each one to a uint16.

The array is:

   0x27, 0xff, 0x03, 0xFA, 0x04, 0x30

On the x86, the output is:

   => 0x27ff
bytes = 0xbfc8bffe, byte_pos = 0xbfc8bffe, &bytes[0] = 0xbfc8bffe
*byte_pos = 0x27
*((u_int16_t*) byte_pos) = 65319 = 0xff27
ntohs(*((u_int16_t*) byte_pos)) = 10239 = 0x27ff


   => 0xff03
bytes = 0xbfc8bffe, byte_pos = 0xbfc8bfff, &bytes[1] = 0xbfc8bfff
*byte_pos = 0xff
*((u_int16_t*) byte_pos) = 1023 = 0x03ff
ntohs(*((u_int16_t*) byte_pos)) = 65283 = 0xff03


   => 0x03fa
bytes = 0xbfc8bffe, byte_pos = 0xbfc8c000, &bytes[2] = 0xbfc8c000
*byte_pos = 0x03
*((u_int16_t*) byte_pos) = 64003 = 0xfa03
ntohs(*((u_int16_t*) byte_pos)) = 1018 = 0x03fa


   => 0xfa04
bytes = 0xbfc8bffe, byte_pos = 0xbfc8c001, &bytes[3] = 0xbfc8c001
*byte_pos = 0xfa
*((u_int16_t*) byte_pos) = 1274 = 0x04fa
ntohs(*((u_int16_t*) byte_pos)) = 64004 = 0xfa04


   => 0x0430
bytes = 0xbfc8bffe, byte_pos = 0xbfc8c002, &bytes[4] = 0xbfc8c002
*byte_pos = 0x04
*((u_int16_t*) byte_pos) = 12292 = 0x3004
ntohs(*((u_int16_t*) byte_pos)) = 1072 = 0x0430

You can see that the bytes are bring read correctly (e.g. 0x27ff, 0xff03,
0x03fa, etc.).

On the ARM, the output is:

   => 0xe427
bytes = 0xbedcebfd, byte_pos = 0xbedcebfd, &bytes[0] = 0xbedcebfd
*byte_pos = 0x27
*((u_int16_t*) byte_pos) = 10212 = 0x27e4
ntohs(*((u_int16_t*) byte_pos)) = 58407 = 0xe427


   => 0xff03
bytes = 0xbedcebfd, byte_pos = 0xbedcebfe, &bytes[1] = 0xbedcebfe
*byte_pos = 0xff
*((u_int16_t*) byte_pos) = 1023 = 0x03ff
ntohs(*((u_int16_t*) byte_pos)) = 65283 = 0xff03


   => 0xff03
bytes = 0xbedcebfd, byte_pos = 0xbedcebff, &bytes[2] = 0xbedcebff
*byte_pos = 0x03
*((u_int16_t*) byte_pos) = 1023 = 0x03ff
ntohs(*((u_int16_t*) byte_pos)) = 65283 = 0xff03


   => 0xfa04
bytes = 0xbedcebfd, byte_pos = 0xbedcec00, &bytes[3] = 0xbedcec00
*byte_pos = 0xfa
*((u_int16_t*) byte_pos) = 1274 = 0x04fa
ntohs(*((u_int16_t*) byte_pos)) = 64004 = 0xfa04


   => 0xfa04
bytes = 0xbedcebfd, byte_pos = 0xbedcec01, &bytes[4] = 0xbedcec01
*byte_pos = 0x04
*((u_int16_t*) byte_pos) = 1274 = 0x04fa
ntohs(*((u_int16_t*) byte_pos)) = 64004 = 0xfa04

Which is plain wrong.

Whenever the byte in memory is half-word-aligned, reading it as a uint16
works as expected. The other half of the time, the compiler is adjusting
the pointer (back one) to make it half-word-aligned before reading the two
bytes as a uint16.

I can find at least 26 occasions in the strongSwan code where this
reading-a-byte-pointer-as-a-uint16-pointer idiom occurs.

I have not searched for the byte-pointer->uint32-pointer case yet :-(

Graham.
#include 
#include 

#define MORE_TRACING

int main()
{
u_int8_t bytes[] =
{
0x27, 0xff, 0x03, 0xFA, 0x04, 0x30
};

u_int8_t bit_pos;

u_int8_t* byte_pos;

byte_pos = bytes;

int i;

for(i = 0; i < 5; ++i)
{
u_int16_t output_pos;

// u_int16_t intermediate = *(byte_pos + 1) << 8 | *(byte_pos + 0);

// output_pos = ntohs(intermediate);

output_pos = ntohs(*((u_int16_t*) byte_pos));

printf("   => 0x%04x\n", output_pos);

#ifdef MORE_TRACING
printf("\tbytes = 0x%x, byte_pos = 0x%x, &bytes[%d] = 0x%x\n",
(unsigned int) bytes,
(unsigned int) byte_pos,
i,
(unsigned int) &bytes[i]);

printf("\t*byte_pos = 0x%02x\n", *byte_pos);
printf("\t*((u_int16_t*) byte_pos) = %d = 0x%04x\n",
*((u_int16_t*) byte_pos), *((u_int16_t*) byte_pos));
printf("\tntohs(*((u_int16_t*) byte_pos)) = %d = 0x%04x\n",
ntohs(*((u_int16_t*) byte_pos)), ntohs(*((u_int16_t*) byte_pos)));

printf("\n\n");
#endif /* MORE_TRACING */

byte_pos++;
}

return 0;
}___
Users mailing list
Users@lists.strongswan.org
https://lists.strongswan.org/mailman/listinfo/users


[strongSwan] Strongswan 4.2.14 broken on ARM ?

2009-05-15 Thread Graham Hudspith
Hi,

I wonder if anyone can please help me with a problem I'm having getting
strongSwan (4.2.14) running on the ARM ?

I've played about getting strongSwan working on x86 setting up a tunnel to
a server. I then compiled strongSwan for ARM and copied across the config
files I used on x86.

The ARM version fails to set up the tunnel.

Turning on tracing to level 3 everywhere gets me the following line in the
client (left?) /var/log/messages:

charon: 08[MGR] checkout IKE_SA
charon: 13[ENC]   parsing rule 0 U_INT_8
charon: 13[ENC]=> 39
charon: 13[ENC]   parsing rule 1 FLAG
charon: 13[ENC]=> 0
charon: 13[ENC]   parsing rule 2 RESERVED_BIT
charon: 13[ENC]   parsing rule 3 RESERVED_BIT
charon: 13[ENC]   parsing rule 4 RESERVED_BIT
charon: 13[ENC]   parsing rule 5 RESERVED_BIT
charon: 13[ENC]   parsing rule 6 RESERVED_BIT
charon: 13[ENC]   parsing rule 7 RESERVED_BIT
charon: 13[ENC]   parsing rule 8 RESERVED_BIT
charon: 13[ENC]   parsing rule 9 PAYLOAD_LENGTH
charon: 13[ENC]=> 3
charon: 13[ENC] encrypted payload could not be decrypted and parsed
charon: 13[ENC] could not decrypt payloads
charon: 13[IKE] IKE_AUTH response with message ID 1 processing failed

The client is trying to use ike=aes128-sha-modp1024!, esp=aes128-sha1,
3des-md5 and EAP-SIM.

The client has sent out the initial IKE_SA_INIT request and been happy
with the IKE_SA_INIT response. The client has then sent out the first
IKE_AUTH request and has then had trouble processing the first IKE_AUTH
response.

Working back from the "encrypted payload could not be decrypted and
parsed" error in the code, I can see that message.c:decrypt_payloads() has
managed to decrypt and parse one payload (the ID_RESPONDER one) and has
started on the CERTIFICATE payload.

The code manages to decrypt this payload okay and starts to parse it (see
parser.c:parse_payload()).

The payload starts with the following bytes:

0x27, 0x00, 0x03, 0xFA, 0x04, 0x30

On the x86, the code parses the first byte as one uint_8 = 39 decimal (27
hex), 8 1-bit fields and a uint_16 payload-length = 1018 decimal (03FA
hex).

On the ARM, the code parses the first byte as one uint_8 = 39 (decimal), 8
1-bit fields and a uint_16 payload-length = 3 decimal (0003 hex) !!

The code, rightly, thinks this is rubbish and fails the rest of the parse.

I've worked my way through the code in parser.c (e.g. parse_payload(),
parse_uint8(), parse_bit() and parse_uint16()) and managed to reduce them
to a small test program (hopefully attached).

If I compile and run this on the x86, I get:

  parsing rule 0 U_INT_8
   => 39
  skipping rules 1 FLAG ... 8 RESERVED_BIT
  parsing rule 9 PAYLOAD_LENGTH
   => 1018

output. On the ARM, I get:

  parsing rule 0 U_INT_8
   => 39
  skipping rules 1 FLAG ... 8 RESERVED_BIT
  parsing rule 9 PAYLOAD_LENGTH
   => 65283

To make things more clear what it going on, I have changed the second byte
of the message from 0x00 to 0xff in my test program.

If I replace the line:

output_pos = ntohs(*((u_int16_t*) byte_pos));

by:

u_int16_t intermediate = *(byte_pos + 1) << 8 | *(byte_pos + 0);
output_pos = ntohs(intermediate);

everything works as expected on both x86 and ARM.

Also found that something like the following works on both x86 and ARM:

u_int16_t intermediate;

u_int8_t* intermediate_bytes = (u_int8_t*) &intermediate;

intermediate_bytes[0] = byte_pos[0];

intermediate_bytes[1] = byte_pos[1];

output_pos = ntohs(intermediate);

Can anyone explain this and how to fix it easily ?

I'm hoping that someone will say that this is fixed by a command-line flag
on the ARM version of gcc ;-}

Version of ARM gcc in use is 4.1.1.

If this does mean a strongSwan code fix, will it just be to parse_uint16() ?

Or parse_uint32() too ?

Or is this idiom endemic throughout the strongSwan code ?

Thanks for any help,

Graham.

#include 
#include 

int main()
{
u_int8_t bytes[] =
{
0x27, 0xff, 0x03, 0xFA, 0x04, 0x30
};

u_int8_t bit_pos;

u_int8_t* byte_pos;

byte_pos = bytes;

printf("  parsing rule 0 U_INT_8\n");

{
u_int8_t output_pos;

output_pos = *(byte_pos);

printf("   => %d\n", output_pos);
}

byte_pos++;

printf("  skipping rules 1 FLAG ... 8 RESERVED_BIT\n");

byte_pos++;

printf("  parsing rule 9 PAYLOAD_LENGTH\n");

{
u_int16_t output_pos;

// u_int16_t intermediate = *(byte_pos + 1) << 8 | *(byte_pos + 0);

// output_pos = ntohs(intermediate);

output_pos = ntohs(*((u_int16_t*) byte_pos));

printf("   => %d\n", output_pos);

#ifdef MORE_TRACING
printf("bytes = 0x%x, byte_pos = 0x%x, bytes + 2 = 0x%x\n",
(unsigned int) bytes,
(unsigned int) byte_pos,
(unsigned int) (bytes + 2));

printf("*byte_pos = %d\n", *byte_pos);
printf("*((u_int16_t*) byte_pos) = %d = 0x%x\n",
*((u_int16_t*) byte_pos), *((u_int16_t*) byte_pos));
printf