Network Working Group D. McDonald INTERNET-DRAFT NRL draft-mcdonald-ipv6-sec-api-00.txt 30 January 1995 IPv6 Security API for BSD Sockets Status of this Memo Internet Drafts are working documents of the Internet Engineering Task Force (IETF), its Areas, and its Working Groups. Note that other groups may also distribute working documents as Internet Drafts. Internet Drafts are draft documents valid for a maximum of six months. This Internet Draft expires on July 30, 1995. Internet Drafts may be updated, replaced, or obsoleted by other documents at any time. It is not appropriate to use Internet Drafts as reference material or to cite them other than as a "working draft" or "work in progress." Please check the I-D abstract listing contained in each Internet Draft directory to learn the current status of this or any other Internet Draft. Distribution of this memo is unlimited. Introduction One of the most desirable new features of IPv6 is the security architecture [Atk94a]. The architecture has two main components, authentication [Atk94b] and encapsulating security payload [Atk94c]. Unlike other parts of IPv6, the security architecture has no counterpart in IPv4. These new features generated a need for mechanisms to allow the application to set security parameters, as well as mechanisms to allow the application to be aware of security problems. The BSD sockets interface [LMKQ89] is a commonly used Application Program Interface (API) to Internet protocols. Gilligan, et. al. have shown how sockets can be used with IPv6 [GTB94]. Security needs to be a part of any API for IPv6, and this document attempts to illustrate how sockets might enable security features. This draft is by no means a standards-track document, nor is it even a final word on the way security should be implemented at the API level. This document is intended to spark discussion, and suggest a possible way for implementors to approach the integration of security McDonald [Page 1] INTERNET-DRAFT IPv6 Security API 30 January 1995 into a BSD sockets API. Security Concepts Following this are explanations of three important concepts: security association, authentication, and encryption. These explanations are included for completeness, and for implementors who have not read the IPv6 Security Architecture documents. The IPv6 security architecture documents should be read in addition to this section. Security Association A security association exists from one endpoint to another endpoint. A security association contains several attributes, such as: * Key(s) * Source address * Destination address * Algorithm used (including algorithm mode) * Replay prevention parameters (if needed) * Security association identifier (SAID) Security associations are set up either manually, or through use of a key management protocol. Key management is beyond the scope of this document. It is hard to create and maintain a large security association table with manual key management. Ideally, there should be a separate security association per user-level socket, but this cannot always happen, and even if it does, security associations lie below the transport (e.g. TCP or UDP) level, and must be mapped into sockets in a transport-independent way. Especially in cases of manual key management, two separate user-level sockets might have their data encrypted with the same key, algorithm, and therefore, the same SAID. If more than one user's data is encrypted with the same key, then user-level security is not provided, but system level security is. At send time, if a security mechanism has been enabled (either by setting some socket option or by the system-wide security setting from the sys admin) for the sending socket, then the source userid and destination address are used to select an appropriate security association. It is possible that all users on the sending system McDonald [Page 2] INTERNET-DRAFT IPv6 Security API 30 January 1995 would share a single security association with the specific destination. If more than one security association exists for a single source userid/ destination address pair, it isn't clear how the implementation would select from among multiple such security associations. The security association will then provide the information on algorithm being used, algorithm mode, key to use, and any other parameters necessary for providing security for the outgoing datagram. At receive time, the IP layer demultiplexes a packet to the appropriate authentication or decryption mechanism on the security association identifier (SAID) and the destination address. No TCP or UDP port numbers or mechanisms are involved in determining which algorithms or keys are used for received datagrams. SAIDs are unidirectional. Ideally each source/destination port/address pair will have unique SAID's going each way, but this is only feasible in the presence of good automated key management. Authentication Authentication is proof that a datagram is entirely accurate, including verifying that a datagram originated with the reported sender. Without authentication, a datagram can be easily forged as to conceal its true origins. Any higher-level protocol (e.g. rlogin) that depends on an accurate source addresses should use some form of authentication. Authentication in IPv6 is achieved through the use of the Authentication Header. The authentication header contains a SAID, data associated with the authentication (such as the result of an MD5 computation), and other mundane header fields. Encryption Encryption scrambles data in such a way that if it was intercepted, no sense could be made of it. Ideally, only the intended recipient of the data knows how to unscramble (decrypt) the data. Without encryption, packets intercepted during intermediate hops in the network can be viewed by undesirable parties. If two communicating parties do not wish to have their exchanged data viewed by others, they should use encryption. Encryption is offered in IPv6 through the Encapsulating Security Payload (ESP) header. The ESP header has two parts, an unencrypted part which contains an SAID and synchronization fields, and an encrypted part which contains other mundane header fields. An Approach for Implementing Security with BSD Sockets McDonald [Page 3] INTERNET-DRAFT IPv6 Security API 30 January 1995 The remainder of this document discusses adding security to the BSD socket interface. Some of the following concepts are easily moved to non-BSD socket API's, such as Winsock. Others are very BSD specific. Some of the following concepts will no doubt spark controversy. As mentioned before, the point of this document is to set in motion discussion, and eventually implementation. Systemwide Network Security Level Each machine, or group of machines, on an IPv6 internet will have a system-wide security level. This security level will be the default security level for newly created AF_INET6 sockets. The security level of a machine has several parameters that need to be set. Each parameter is dependent on there being a security association that supports the parameter. The parameters are (in order of least secure to most secure): AUTHENTICATION (3 settings) * No authentication * Authentication of security-critical packets (e.g. TCP SYN segment) * Authentication of all outbound packets ENCRYPTION (4 settings) * No encryption * Encryption of each outbound packet's payload * Encryption of each entire outbound packet inside another packet * First authenticate each outbound packet, then encrypt the entire authenticated outbound packet Again, it is important to note that the system's default security level is meaningless, or weakened, in absence of the appropriate security associations. This means that if the system default has both authentication and encryption turned on, but to a certain machine only an authentication security association exists, then only authentication will be performed between those two machines. How to set a system's security level is beyond the scope of this McDonald [Page 4] INTERNET-DRAFT IPv6 Security API 30 January 1995 document. The facilities that provide access to a machine's security association table would probably be the ideal place to put mechanisms to set the systemwide security level. Security Aware Applications Before continuing, an type of application has to be defined. A _security aware_ application is one that is aware that the Internet services below it are using security. _Security unaware_ applications are not aware of underlying security services. This distinction is made because many naive applications, as well as proverbial "quick-and-dirty" ports of older applications, will not expect lack of security to be a problem. A security unaware application should continue to function identically in both secure and insecure environments. Security aware applications, on the other hand, are expected to react intelligently if security problems are encountered. Per Socket Security Level At each socket, the user should have the ability to set his or her security level beyond what the system mandates, provided there are the appropriate security associations. The parameters the user can set are identical to the ones above. If an application makes security requests, even to inspect security values, an application is henceforth treated as a security aware application. Likewise, if an application makes no security requests, it is treated as a security unaware application. For security aware applications, the level of error reporting can be determined by the user application. No security errors are reported to security unaware applications. Security aware applications will have errors reported to them by default. The error reporting parameters, and their default values are below: ERROR REPORTING * Report failure packets? (yes/no) For example: Packets that have authentication headers, but fail authentication * Default for security unaware: NO * Default for security aware: YES * Report naked packets? (yes/no) For example: Packets that are supposed to be either authenticated or encrypted, but aren't. * Default for security unaware: NO * Default for security aware: YES McDonald [Page 5] INTERNET-DRAFT IPv6 Security API 30 January 1995 * Report paranoid packets? (yes/no) For example: An authenticated packet arrives with an unknown SAID. * Default for security unaware: NO * Default for security aware: YES * Pass up paranoid packets? (yes/no) For example: Should the previous authenticated packet be passed up? * Default for security unaware: NO * Default for security aware: NO The systemwide security level, if more secure, supersedes whatever the user-level socket requests. For example, assume the systemwide security level is set to encrypt packets. If an application requests authentication to a destination that has security associations for both authentication and encryption, then the application's packets will be both authenticated and encrypted. Unlike the systemwide security level, if a socket requests a security service that is unavailable, it will be notified via an error return from one of the socket calls. A security request can be made on a socket before the destination is known. If that happens, then subsequent connect() or sendto() calls may return with an error indicating what kind of security failure occured. (For example, connect() returning with errno set to ENOSAID, indicating no security association exists.) Likewise, if a security request is made on an already connected socket, the request will immediately indicate if there is a problem with the requested security level. Finally, for security unaware applications, the socket's level will default to the system's security level. This allows older applications to be moved to IPv6 with a minimum effort. There is a danger that an insecure systemwide security level will render ignorant applications insecure, but as more applications become security aware, or as more systems turn on security by default, this danger will fade. Extensions to the BSD Socket Interface The extensions allowing per socket security take three forms. The first is new socket options which are used by the getsockopt() and setsockopt() calls. The second is new error codes to familiar calls such as connect() and sendto(). The third is using a BSD signal to notify a process of security problems. New Socket Options As in the BSD include file , socket options are McDonald [Page 6] INTERNET-DRAFT IPv6 Security API 30 January 1995 #defined to be integers. The comments include the data type expected to be passed in. #define IP_SECLEVEL 0x20 /* int; get/set security level. */ IP_SECLEVEL sets or obtains the security level for a socket. The integer argument is a bitmask of possible values. The low two bits of the integer are for authentication levels. The two bits above the authentication bits indicate what parts of datagrams should be encapsulated in an ESP. The following bitmask values correspond to the settings in the systemwide security section: /* AUTHENTICATION values. */ #define IPSEC_AUTHNONE 0x0 #define IPSEC_AUTHCRIT 0x1 #define IPSEC_AUTHALL 0x2 #define IPSEC_AUTHUNUSED 0x3 /* Unused bit combination. May be used later. */ /* ENCAPSULATING SECURITY values. */ #define IPSEC_ESPNONE 0x0 #define IPSEC_ESPPAYLOAD 0x4 #define IPSEC_ESPPACKET 0x8 #define IPSEC_ESPAUTHPACKET 0xC If the IP_SECLEVEL socket option is set, error reporting will be turned on. #define IP_SECERR 0x21 /* int; get/set error reporting. */ IP_SECERR sets or obtains the security error reporting properties of a given socket. The integer argument is a bitmask, with the low four bits answering the yes/no questions posed in the per socket security section. The bitmask values are: /* ERROR REPORTING values */ #define IPSECERR_REPFAIL 0x1 #define IPSECERR_REPNAKED 0x2 #define IPSECERR_REPPARANOID 0x4 #define IPSECERR_PASSPARANOID 0x8 New Error Codes For security aware applications, several new error codes are available. These error codes affect various system calls, and a list McDonald [Page 7] INTERNET-DRAFT IPv6 Security API 30 January 1995 of calls that might generate that error code follows each error code. [NB. Early versions of this draft were criticized for suggesting actual error codes by name. Despite the nature of the presentation, this section presents security error conditions that may be reported to a user. IEEE P1003.12 is where, I believe, errno values are defined, and where actual errno names should be added.] ENOKEY -- No key/security association exists Affects: setsockopt() For security aware applications: accept(), bind(), connect(), sendto(), sendmsg(), recvfrom(), recvmsg() ENOKEY indicates that a level of security cannot be granted because no security association, hence no key, exists for that level of security. For example, an application requests authentication, then does a connect() to a host which has no authentication security assocation. ENOKEY is returned if the FULL REQUESTED security level cannot be met. It is currently undefined whether or not partially fufilled requests are granted if ENOKEY is returned. It is also currently undefined whether or not a connection is broken if ENOKEY is returned. EKEYEXP -- Key lifetime has expired Affects: accept(), bind(), connect(), read(), readv(), recv(), recvfrom(), recvmsg(), select(), send(), sendto(), sendmsg(), write(), writev() EKEYEXP indicates that the key for the security association has expired. Keys often have finite lifetimes, because indefinite use of a key allows an adversary an indefinite amount of time to break the cryptosystem that key is a part of. Instant Security Violation Notification [NB. This is a controversial section. These could be done in error codes instead, but would be less "up-to-date". Also the IP_SECEXCEP and IP_SECMSG options could be moved to the socket options section. Other suggestions specifically for BSD have included using the exception descriptor vector in select(2) to indicate such activity.] In earlier sections, several error conditions, and mechanisms to enable error reporting, were defined. This section discusses the method for implementing error reporting. McDonald [Page 8] INTERNET-DRAFT IPv6 Security API 30 January 1995 A UNIX signal, SIGURG, will be sent to the owning process of a socket that has a security error occur. To determine which of the three possible error sources, failure packets, naked packets, or paranoid packets, generated the signal, another (read-only) socket option must be implemented. This socket option is IP_SECEXCEPT. #define IP_SECEXCEPT 0x22 /* int; get cause of SIGURG. */ IP_SECEXCEPT allows a process to determine if a security violation caused a SIGURG to be sent to it. The integer returned will contain a code indicating the cause, and possibly suggesting further action. The codes are: /* SECURITY EXCEPTION values */ #define IPSECEXC_NONE 0x0 /* Check for other causes of SIGURG */ #define IPSECEXC_FAIL 0x1 /* Failed auth., use IP_SECMSG */ #define IPSECEXC_NAKED 0x2 /* Naked packet, use IP_SECMSG */ #define IPSECEXC_PARANOID 0x3 /* Paranoid packet, use IP_SECMSG */ The first return value indicates that something other than security caused the SIGURG to be sent. Often this is the TCP out-of-band data mechanism. The remaining return values indicate that a retrievable security violation has occured. An example of an unretrievable security violation is an decryption failure. It is assumed a machine's operating system will log all security problems, whether they can be reported to a user or not (see Security Considerations). Retrieving additional information about a security violation is possible through the IP_SECMSG socket option. Like IP_SECEXCEPT, IP_SECMSG is a read-only socket option. #define IP_SECMSG 0x23 /* ipv6_secinfo; Get info on sec. violation */ IP_SEGMSG fills in an ipv6_secinfo structure, which contains information on the datagram. struct ipv6_secinfo /* Assume sizeof(u_long) == 4 bytes sizeof(u_short) == 2 bytes sizeof(u_char) == 1 byte Network order unless otherwise stated */ { u_short isi_attributes; /* Bitmask of message attributes (host order): McDonald [Page 9] INTERNET-DRAFT IPv6 Security API 30 January 1995 0x1 --> Authentication of datagram 0x2 --> Encapsulation of payload 0x4 --> Encapsulation of datagram 0x8 --> Encapsulation of authenticated datagram */ u_char isi_redsrlen; /* Length of red source route */ u_char isi_blksrlen; /* Length of black source route */ /* BLACK information is for a datagram that is INSIDE an encapsulating security payload. */ u_long isi_blkflowid; /* Black flow id */ struct ipv6_addr isi_blksrc; /* Black source address */ struct ipv6_addr isi_blkdst; /* Black destination address */ u_long isi_blksaid; /* Black SAID (for auth.) */ /* RED infromation is the outlying datagram itself. */ u_long isi_redflowid; /* Red flow id */ struct ipv6_addr isi_blksrc; /* Red source address */ struct ipv6_addr isi_blkdst; /* Red destination address */ u_long isi_redsaid; /* Red source address */ u_long isi_nexthdr; /* Next header id. Put in u_long for padding purposes. Host order. */ struct ipv6_addr isi_srcrtes[1]; /* Red source route, followed by black, if user supplies enough room. Sizes given in fields above. */ }; For all address fields, the address 0000::0000 (unspecified according to [Hin94] indicates an unknown value or a value that does not exist. Likewise, all flow ids are 0 if they are unknown or do not exist. The passed-in structure should have room for source routes, if source routes are anticipated. It is currently undefined what happens if there is not enough room to place source routes at the end of the structure. Open Questions * Any sentence with the word undefined in it needs to be fixed. * If a socket can use one of many available security associations, which one does it use? Where is the selection made? (Kernel? Yet McDonald [Page 10] INTERNET-DRAFT IPv6 Security API 30 January 1995 another sockopt?) * On the same subject, how does a user obtain his/her SAID? Should a user be able to do this at all? * What if I want "the best available security"? This is important for a program like inetd, which dispatches new sockets to other programs. * What about Winsock and other API's? How applicable is this stuff. Security Considerations It is assumed that the operating system will keep an audit log of ALL IPv6 security problems. Many IPv6 security problems cannot be reported to a particular socket, failed decryption being the best example. Comprehensive audit trails is the only way to make sure all security violations are reported. Setting the systemwide security level should have proper protections, so random users cannot downgrade the systems level to a point where unwanted packets can reach a system. If two sockets happen to use the same security association, it is possible for one socket to engage in attempts at chosen-plaintext crypanalytic attacks on other sockets' traffic that use the same security association. Acknowledgements Thanks to Ran Atkinson for hearing and answering many questions that came up during the writing of this document. Thanks to Sean O'Malley for asking some very tough questions during the early stages of this draft. Thanks to Bao Phan and Brian Adamson for useful input during the early stages of this draft. Thanks to Jim Bound for making me realize BSD isn't the whole world. References [Atk94a] Atkinson, Randall, "IPv6 Security Architecture", Internet Draft. [Atk94b] Atkinson, Randall, "IPv6 Authentication Header", Internet Draft. [Atk94c] Atkinson, Randall, "IPv6 Encapsulating Security Payload", Internet Draft. McDonald [Page 11] INTERNET-DRAFT IPv6 Security API 30 January 1995 [Hin94] Hinden, Bob (Editor), "IPv6 Routing and Addressing", Internet Draft. [GTB94] Gilligan, Robert E., Thomson, Susan, and Bound, Jim, "IPv6 Program Interfaces for BSD Systems", Internet Draft [LMKQ89] Leffler, Samuel J., McKusick, Marshall Kirk, Karels, Michael J., and Quarterman, John S., "The Design and Implementation of the 4.3BSD UNIX Operating System", Addison-Wesley, 1989. Author's Address Daniel L. McDonald United States Naval Research Laboratory Code 5544 4555 Overlook Ave. SW Washington, DC 20375 Phone: (202) 404-7122 E-mail: danmcd@itd.nrl.navy.mil McDonald [Page 12]