Projects/GSSAPI DCE
The GSS-API DCE project proposes to add functionality found in SSPI to MIT Kerberos; this functionality includes support for AEAD and support sufficient to implement DCE RPC on top of MIT Kerberos. This project depends on and is a companion to Projects/AEAD encryption API.
Contents
Background
SSPI architecture
The SSPI for connection-oriented contexts provides the following service model for per-message protection:
- Security mechanisms may add small fixed-size padding (less than 8 bytes) to a message.
- Security mechanisms add fixed size mechanism-specific tokens to messages.
- Messages may contain data chunks that are encrypted and read_only chunks that are integrity protected but not encrypted.
- So a message looks like (data+ readonly* pad token), although all the components can be reordered. In particular, when interoperating with GSS-API the token comes at the front.
- The application gets to control the placement of token, data, read_only and pad chunks both in the input and output; chunks cannot change size.
GSS-API architecture
- Application passes in a token for per-message protection
- Gss-API returns a token, typically of a different size.
- No support for AEAD
- The application does not control placement or order of chunks.
Supporting DCE RPC
We want to make it easy to implement DCE-RPC against MIT Kerberos:
- DCE RPC separates the security token information from the confidentiality protected information and places it elsewhere in the network PDU
- DCE uses AEAD to integrity protect parts of the message that are not confidentiality protected.
- DCE requires two separate AEAD buffers.
- DCE manages its own padding.
There are also changes to the context establishment procedure signaled by a DCE_STYLE flag; RFC 4757 briefly describes these changes.
AEAD support
DCE requires adding AEAD support to the GSS mechanism. However an application implementing DCE RPC will typically want in-place encryption APIs that expose significant detail about the structure of the GSS token. For some classes of application, this is desirable. However it is highly undesirable to force an application to pay attention to the details of GSS tokens in order to take advantage of features like AEAD. Doing so increases the probability that the application will depend on some semantic of the token and thus will not be portable across mechanisms.
Basic approach
Two new sets of APIs will be introduced. The first, the gss_iov API is similar to the AEAD encryption API and to SSPI. The second adds support for AEAD while minimizing differences with the original GSS-API.
gss_iov
A new structure is introduced:
typedef struct gss_iov_buffer_desc_struct { OM_uint32 type; gss_buffer_desc buffer; } gss_iov_buffer_desc, *gss_iov_buffer_t; #define GSS_C_NO_IOV_BUFFER ((gss_iov_buffer_t)0) #define GSS_IOV_BUFFER_TYPE_EMPTY 0 #define GSS_IOV_BUFFER_TYPE_DATA 1 /* Packet data */ #define GSS_IOV_BUFFER_TYPE_HEADER 2 /* Mechanism header */ #define GSS_IOV_BUFFER_TYPE_MECH_PARAMS 3 /* Mechanism specific parameters */ #define GSS_IOV_BUFFER_TYPE_TRAILER 7 /* Mechanism trailer */ #define GSS_IOV_BUFFER_TYPE_PADDING 9 /* Padding */ #define GSS_IOV_BUFFER_TYPE_STREAM 10 /* Complete wrap token */ #define GSS_IOV_BUFFER_TYPE_SIGN_ONLY 11 /* Sign only packet data */ #define GSS_IOV_BUFFER_FLAG_MASK 0xFFFF0000 #define GSS_IOV_BUFFER_FLAG_ALLOCATE 0x00010000 /* indicates GSS should allocate */ #define GSS_IOV_BUFFER_FLAG_ALLOCATED 0x00020000 /* indicates caller should free */
A set of APIs is created that takes an array of gss_iov_buffer_desc structures for per-message operations. Several types of buffers are defined. The header buffer represents mechanism-specific headers added to a security token. In SSPI, this buffer is called the token. The trailer buffer is mechanism-specific security information added to the end of application data; this buffer typically does not exist in SSPI applications. The padding buffer contains padding bytes necessary for block-cipher alignment. Data buffers contain application data to be integrity or confidentiality protected. The sign_only buffer type represents associated data that will be integrity protected but even when data buffers are confidentiality protected, the sign_only buffers will not be integrity protected. Also, If the header, data buffers, padding and trailer buffers are concatenated in that order, the resulting token should be a valid input to gss_unwrap.
The SIGN_ONLY flag indicates that a particular data buffer is integrity protected but not encrypted. This buffer can be sent over the wire, or reconstructed by the remote application.
SSPI compatible applications will typically be unable to pass in a trailer buffer. Mechanisms should try to function even when no trailer is available. The Kerberos mechanism can always produce valid output without a trailer, although if a trailer is provided, it may be used.
DCE-RPC is expected to pass in a header, a sign_only buffer, a data buffer, a sign_only buffer, and potentially padding.
Where possible, applications can use a stream buffer on unwrap. The stream buffer points to a wrap token received from the other side. This is the concatenated output of the header buffer, the data buffers, the padding buffer and the trailer buffer. When using a stream buffer, a data buffer should be passed in; this data buffer will be replaced with a pointer to the data. Note that sign_only buffer contents are not part of the stream buffer and must explicitly be passed in if a stream buffer is used.
The allocate flag may be used on wrap for the header, trailer and pad buffer. If this flag is set, the wrap call will allocate space for these buffers. If a stream buffer is used on unwrap, the allocate flag may be set on the data buffer to indicate that the data should be copied rather than pointing the data buffer into the decrypted-in-place contents of the stream. The allocated flag is used by the library to indicate that space has already been allocated for a buffer.
Applications will typically set up their data buffers along with placeholder entries for the other buffers they need and then call gss_wrap_iov_length.
gss_*_aead
In addition there will be APIs that take a single associated data buffer and produce/consume wrap tokens. The intent of these APIs is to make AEAD available without exposing token details.
API details
/* * Sign and optionally encrypt a sequence of buffers. The buffers * shall be ordered HEADER | DATA | PADDING | TRAILER. Suitable * space for the header, padding and trailer should be provided * by calling gss_wrap_iov_length(), or the ALLOCATE flag should * be set on those buffers. * * Encryption is in-place. SIGN_ONLY buffers are untouched. Only * a single PADDING buffer should be provided. The order of the * buffers in memory does not matter. Buffers in the IOV should * be arranged in the order above, and in the case of multiple * DATA buffers the sender and receiver should agree on the * order. * * With GSS_C_DCE_STYLE it is acceptable to not provide PADDING * and TRAILER, but the caller must guarantee the plaintext data * being encrypted is correctly padded, otherwise an error will * be returned. * While applications that have knowledge of the underlying * cryptosystem may request a specific configuration of data * buffers, the only generally supported configurations are: * * HEADER | DATA | PADDING | TRAILER * * which will emit GSS_Wrap() compatible tokens, and: * * HEADER | SIGN_ONLY_DATA | DATA | PADDING | TRAILER * * for AEAD. * * The typical (special cased) usage for DCE is as follows: * * HEADER | SIGN_ONLY_DATA_1 | DATA | SIGN_ONLY_DATA_2 */ OM_uint32 KRB5_CALLCONV gss_wrap_iov ( OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ int, /* conf_req_flag */ gss_qop_t, /* qop_req */ int *, /* conf_state */ size_t, /* iov_count */ gss_iov_buffer_desc *); /* iov */ /* * Verify and optionally decrypt a sequence of buffers. To process * a GSS-API message without separate buffer, pass STREAM | DATA. * Upon return DATA will contain the decrypted or integrity * protected message. Only a single DATA buffer may be provided * with this usage. DATA by default will point into STREAM, but if * the ALLOCATE flag is set a copy will be returned. * * Otherwise, decryption is in-place. SIGN_ONLY buffers are * untouched. */ OM_uint32 KRB5_CALLCONV gss_unwrap_iov ( OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ int *, /* conf_state */ gss_qop_t *, /* qop_state */ size_t, /* iov_count */ gss_iov_buffer_desc *); /* iov */ /* * Query HEADER, PADDING and TRAILER buffer lengths. DATA buffers * should be provided so the correct padding length can be determined. */ OM_uint32 KRB5_CALLCONV gss_wrap_iov_length ( OM_uint32 *, /* minor_status */ gss_ctx_id_t, /* context_handle */ int, /* conf_req_flag */ gss_qop_t, /* qop_req */ int *, /* conf_state */ size_t, /* iov_count */ gss_iov_buffer_desc *); /* iov */ /* * Release buffers that have the ALLOCATED flag set. */ OM_uint32 KRB5_CALLCONV gss_release_iov_buffer ( OM_uint32 *, /* minor_status */ size_t, /* iov_count */ gss_iov_buffer_desc *); /* iov */ OM_uint32 gss_wrap_aead( OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, gss_qop_t qop_req, gss_buffer_t input_assoc_buffer, gss_buffer_t input_payload_buffer, int *conf_state, gss_buffer_t output_message_buffer); OM_uint32 gss_unwrap_aead( OM_uint32 *minor_status, gss_ctx_Id_t context_handle, gss_buffer_t input_message_buffer, gss_buffer_t input_assoc_buffer, gss_buffer_t output_payload_buffer, int *conf_state, gss_qop_t *qop_state);
Testing plan
The Gss-sample application will be expanded to support sending IOV messages with the same layout as DCE style wrap tokens (assoc_data|data|assoc_data). These changes will be made both to the GSS and SSP ports of the sample application.
Review
This section documents the review of the project according to Project policy. It is divided into multiple sections. First, approvals should be listed. To list an approval type
- #~~~~
on its own line. The next section is for discussion. Use standard talk page conventions. In particular, sign comments with
- --~~~~
and indent replies.
Members of Krbcore raising Blocking objections should preface their comment with {{project-block}}. The member who raised the objection should remove this markup when their objection is handled.
Approvals
- TomYu 10:59, 24 December 2008 (EST)
Discussion
Ken Raeburn would prefer a different name than gss_wrap_aead because he believes AEAD focuses on the implementation rather than the abstract functionality. --SamHartman 10:10, 1 December 2008 (EST)
- No alternative name was suggested; no change made. SamHartman 13:54, 22 December 2008 (EST)
Love wants us to identify what types a given flag can be used with. --SamHartman 14:53, 1 December 2008 (EST)