GDOI Reference Implementation Primer ------------------------------------ A. Introduction The purpose of this reference implementation is to provide a base vehicle for testing the GDOI group key management protocol (RFC 3547). This primer shows the very basics of configuring GDOI on a pair of systems with known-working configurations. GDOI is a key management system for groups. It is primarily designed for use with secure broadcast applications, but many other types of applications can take advantage of GDOI as well for their keying. B. System Requirements You will need two Linux or OpenBSD systems. This code was developed on Linux and OpenBSD. The following releases have been tested and are safe to use: Linux: Red Hat (6.1, 7.1, 8.0), SUSE 8.2 OpenBSD: 2.9, 3.2 FreeBSD: 4.8 Familiarity with the isakmpd package is helpful. For help with gdoid configuration,see gdoid.conf.5. Note that the page must be formated with "nroff -mandoc" macros. C. System Roles It is most efficient for many group applications to have a rendezvous point where group members can get keys. With that in mind, GDOI was developed to have two distinct roles in the protocol: the role of a key server, and the role of a group member. C.1 Key Server A GDOI key server has the responsibility of keeping keys for the group, and releasing them on demand to authenticated and authorized group members. GDOI authenticates group members using the definition of an IKE Phase 1 exchange (see RFC 2409). The GDOI registration exchange follows the IKE Phase 1 exchange. It contains liveliness checks, confidentiality, and authorization checks. This GDOI reference implementation does not provide any level of authorization check. As long as the group member passes the IKE Phase 1 authentication he is granted access to whatever groups are available on the key server. The key server does support the GDOI "push" (or rekey) message by which a key server can update the keys and policy for the entire group. An IP multicast message is used for this purpose. C.2 Group Member A group member is a host which is running some application which needs keys. There are two different models that applications can use GDOI: directly to get Secure RTP (SRTP) policy and keys, or transparently using IPSec. C.2.1 IPSec Applications are not aware of IPSec protecting applications; it's all done transparently in the kernel. In this reference implementation the GDOI group member code is pre-configured with which groups to join, and it contacts the key server at startup time. This ensures that the SAs will be loaded into the kernel when the application is started. If you want to really test the crypto system, you'll need to do that on OpenBSD. I have demonstrated that the kernel will accept SAs for multicast destinations and match incoming and outgoing packets against them. However, a small kernel patch is required. It is included later in this document. Ciphers 3DES and AES have been validated to work with OpenBSD. Unfortunately the Linux FreeS/WAN IPSec code doesn't support multicast, so while you can push SAs to Linux systems you won't be able to actually use them for IPSec. C.2.2 Secure RTP The Secure RTP (SRTP) protocol is an application level encryption system. The SRTP application directly requests a local GDOI group member daemon for keys, which in turn causes the GDOI group member to contact the GDOI key server. This reference implementation includes an IPC mechanism via a UNIX socket which the SRTP application can use to request keys. It also includes a sample program which "pings" the GDOI client daemon. When the GDOI client daemon receives the request for keys it starts an IKE Phase 1 with the key server. Once that successfully completes it initiates the GDOI protocol exchange with the key server. At the end of of that exchange he has the policy and keys necessary for the application, and returns them via a UNIX socket to the application. NOTE: The SRTP support code in this version is based on an earlier version of SRTP, so neither the GDOI code nor the client daemon are generally useful in their present state. D. Initial Setup Choose which system will be your key server, and which system will be your group member and note their IP addresses. D.1 Key Server Setup It would be best of find sample configurations in the samples document and use one of them. To test between two or three systems use the samples in the "three-clients" sample directory. To setup the key server, copy the "gdoi_ks.conf" file and change the IP addresses in the following lines: Listen-on= = GDOI-group-member-1 [GDOI-group-member-1] Local-address= Address= (You can ignore the configuration lines for GDOI-group-member-2 and GDOI-group-member-3 until you're ready to test with those systems.) That's it! The rest of the policy defines the IKE Phase 1 policy, and one group which contains two IPSec SAs. You can leave those as is. D.2 Group Member Setup Edit gdoi_client1.conf and change the IP addresses in these configuration statements: Listen-on= = GDOI-key-server [GDOI-key-server] Local-address= Address= E. Using the sample configuration Start the test by completing the following steps: E.1. On the key server, become "root". Be sure the gdoi_gcks.conf file is owned by root and has a mode of 600. Then start isakmpd as follows: # ./START_KS This prepares the key server to accept requests from GDOI group members. You will see some debug messages. E.2. On the group member, become "root". Be sure the gdoi_client1.conf file is owned by root and has a mode of 600. Then start isakmpd as follows: # ./START_CLIENT1 This causes the group member to initiate a GDOI exchange to the key server. You will see some debug messages. If you are on an OpenBSD system and wish to load SAs into the kernel, remove the "-n" flag from the call to isakmpd in START_CLIENT1. E.3. The exchange is successful if you see the following string near the end of the debugging statements on both systems: DONE WITH PHASE 2!!! You can compare your output to two sample output scripts in the "three-clients" directory. E.4. If you are on OpenBSD systems, you can check if the SAs were loaded into the kernel with this command: # cat /kern/ipsec E.5 If you are on a BSD based system and want to use the IPSec SAs, you may need to apply a couple of simple kernel hacks. E.5.1 Tunnel Decapsulation The issue is not with the IPSec subsystem, but to make sure the kernel deals appropriately with multicast packets which are decapsulated from IPSec. *** ORIGnetinet/ip_input.c Tue Apr 3 13:45:06 2001 --- netinet/ip_input.c Tue Apr 30 18:24:13 2002 *************** *** 480,485 **** --- 480,494 ---- */ IN_LOOKUP_MULTI(ip->ip_dst, m->m_pkthdr.rcvif, inm); if (inm == NULL) { + #ifndef MROUTING + /* + * XXX Hack! Assume it's our packet. The problem + * is that after decryption the input interface is + * the "enc0" virtual interface rather than the + * actual media interface. + */ + goto ours; + #endif /* MROUTING */ ipstat.ips_cantforward++; m_freem(m); return; E.5.2 Multicast TTL Multicast packets encapsualated with IPsec lose their TTL value. By default, it is '1', which restricts multicast packets to the local LAN. Use the following hack to allow encapsulated IPsec packets to travel through a multicast routed network. diff -rc ORIGnetinet/ip_output.c netinet/ip_output.c *** ORIGnetinet/ip_output.c Sat Apr 14 18:19:02 2001 --- netinet/ip_output.c Thu Jul 24 10:08:42 2003 *************** *** 422,429 **** ip->ip_ttl = imo->imo_multicast_ttl; if (imo->imo_multicast_ifp != NULL) ifp = imo->imo_multicast_ifp; ! } else ! ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL; /* * Confirm that the outgoing interface supports multicast, --- 422,436 ---- ip->ip_ttl = imo->imo_multicast_ttl; if (imo->imo_multicast_ifp != NULL) ifp = imo->imo_multicast_ifp; ! } else { ! /* ! * XXX Hack! The default TTL multicast restricts packets ! * to a LAN. The TTL from the original packet should be ! * used, but that isn't available. Hard code the TTL ! * to something more useful. ! */ ! ip->ip_ttl = 10 /* was IP_DEFAULT_MULTICAST_TTL */; ! } /* * Confirm that the outgoing interface supports multicast, F. IKE Phase 1 Configuration Statements. The following examples are taken from the accompanying sample configurations. F.1. In IKE Phase 1, define the DOI to be "GROUP". This must be done on both the key server and the group member. EXAMPLE ------- [Default-main-mode] DOI= GROUP EXCHANGE_TYPE= ID_PROT Transforms= 3DES-SHA F.2. For the GDOI exchange, define a Group-ID which is an IKE Phase 2 identity type. Only KEY_ID is supported at the moment. For more information on the IKE Phase 1 configuration see isakmpd.conf.5. G. GDOI Configuration Statements. To run the GDOI functionality, the following configuration is needed in the configuration files. These examples are taken from the accompanying sample configurations. For more information, see the gdoid.conf(5) manual page included in this distribution. Other example configurations can be found in the samples directory. G.1 Key Server The key server stores the crypto policy and keys for a group. In this reference implementation all keys and policy are static. Dynamic changing of keys is not available. The key server must define a security policy for the group. EXAMPLE 1 shows the base policy definition to define group "1234". It defines the peer (GDOI-group-member) and exact group policy (Default-group-mode) by reference. EXAMPLE 1 --------- [IPsec-group-policy] Phase= 2 ISAKMP-peer= GDOI-group-member Configuration= Default-group-mode Group-ID= Group-1 [Group-1] ID-type= KEY_ID Key-value= 1234 The actual policy for Default-group-mode is shown in EXAMPLE 2. It defines the Exchange to be a PULL_MODE (which is exchange number 32, see RFC 3547). It also lists two Traffic Encryption Key policy groups to be part of this group. (If this were keying a real application, perhaps one TEK would be the audio stream and one the video stream). EXAMPLE 2 --------- [Default-group-mode] DOI= GROUP EXCHANGE_TYPE= PULL_MODE SA-TEKS= GROUP1-TEK1, GROUP1-TEK2 Finally, policy must be specified for each TEK. EXAMPLE 3 shows the policy for GROUP1-TEK1. This defines a subset of the ESP policy information required. EXAMPLE 3 --------- [GROUP1-TEK1] Crypto-protocol= PROTO_IPSEC_ESP Src-ID= Group-tek1-src Dst-ID= Group-tek1-dst # SPI is 0x1122aabb SPI= 287484603 TEK_Suite= GDOI-ESP-3DES-SHA-SUITE DES_KEY1= ABCDEFGH DES_KEY2= IJKLMNOP DES_KEY3= QRSTUVWX SHA_KEY= 12345678901234567890 [Group-tek1-src] ID-type= IPV4_ADDR Address= 172.19.193.37 Port= 1024 [Group-tek1-dst] ID-type= IPV4_ADDR Address= 239.192.1.1 Port= 1024 G.2 Group Member On the group member side, the following configuration needs to be setup: First, a policy must be defined based on the group name as shown in EXAMPLE 4. This special naming allows the GDOI group member to find the appropriate IKE Phase 1 policy when the crypto system gives it a group number. EXAMPLE 4 --------- [Group-1234] Phase= 2 ISAKMP-peer= ISAKMP-peer-gcks Configuration= Default-group-mode Group-ID= Group-1 [Group-1] ID-type= KEY_ID Key-value= 1234 The policy for Default-group-mode is shown in EXAMPLE 5. EXAMPLE 5 --------- [Default-group-mode] DOI= GROUP EXCHANGE_TYPE= PULL_MODE Suites= GM-ESP H. Hints Here are some things to keep in mind using this package. 1. The configuration (*.conf) files that you use MUST be owned by root and have a mode of 600. If not, isakmpd will quickly abort. The configuration files included in the samples directory may not be set correctly -- that depends on how you extracted the files, 2. If the IKE Phase 1 connections don't seem to be working, restart both isakmpd daemons and try again. That usually eliminates any confusion between them. 3. There are no known bugs. However, the best advice is to not vary too far from the samples. I. Generating and using RSA Public Keys with OpenSSL To create an RSA keypair to use with the rekey messages, follow the following steps. 1. Generate a keypair of at least 1024 bits. openssl genrsa 1024 > rsakeys.pem 2. The keys are generated in PEM format, and GDOI would like them to be in DER format, so they must be converted openssl rsa -in rsakeys.pem -outform DER -out rsakeys.der NOTE: The keys are not in a displayable format. I. Acknowledgments Thanks to the following individuals for contributing to gdoid: Sebastien.Josset at space.alcatel.fr contributed code which enabled GDOI to support AES as an IPsec transform, and the new OpenBSD PF_KEY extensions.