Skip to contentSkip to conversation

IPsec+SCTP+IPv6 bug (was: Re: https://bugzilla.kernel.org/show_bug.cgi?id=24412)

DISCUSSION Alexey Dobriyan 2 participants 2 messages Sep 6, 2013 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

[add netdev@ to CC]

My notes and recollections are below.

Bug reporter says traffic is unecnrypted which is technically a different thing, but when I tried to reproduce absense of encryption, I couldn't even get past established TCP connection.

IPv6 case works (worked) without IPsec (setkey -F; setkey -FP). IPv4 case worked with IPsec.
IPv6 didn't work with IPsec.

setkey(8) setup:

	#!/usr/sbin/setkey -f
	flush;
	spdflush;
	add A B ah 0x42 -A hmac-sha256 0xKEY1;
	add B A ah 0x43 -A hmac-sha256 0xKEY2;
	add A B esp 0x44 -E blowfish-cbc 0xKEY3;
	add B A esp 0x45 -E blowfish-cbc 0xKEY4;
	spdadd A B any -P in ipsec esp/transport//require ah/transport//require;
	spdadd B A any -P in ipsec esp/transport//require ah/transport//require;

A, B -- IPv4 or IPv6 client/server addresses.
Client and server copy of the file should have matching keys and SPI numbers, but "opposite" addresses (A <=> B).

Keys are written in hex.
IIRC setkey is picky about key lengths (they have to match exactly those of crypto algorithms).

--------------------------------------------------------------------

IPv4 reproducer:

	socat sctp-listen:3333 -
	echo plaintext | socat - sctp-connect:IP4IP4IP4IP4:3333

IPv6 reproducer:

	socat sctp6-listen:3333 -

#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>

int main(void)

{
        struct sockaddr_in6 sa6 = {};
        int fd;

        fd = socket(PF_INET6, SOCK_STREAM, 0x84);
        sa6.sin6_family = AF_INET6;
        sa6.sin6_port = htons(3333);
        inet_pton(AF_INET6, "IP6IP6IP6IP6IP6IP6", &sa6.sin6_addr);
        sa6.sin6_scope_id = 2;	/* it depends */
        connect(fd, (struct sockaddr *)&sa6, sizeof(struct sockaddr_in6));
        write(fd, "plaintext\n", strlen("plaintext\n"));
        close(fd);
        return 0;
}