Path: blob/main/crypto/heimdal/lib/gssapi/mech/gss_aeap.c
34914 views
/*1* AEAD support2*/34#include "mech_locl.h"56/**7* Encrypts or sign the data.8*9* This is a more complicated version of gss_wrap(), it allows the10* caller to use AEAD data (signed header/trailer) and allow greater11* controll over where the encrypted data is placed.12*13* The maximum packet size is gss_context_stream_sizes.max_msg_size.14*15* The caller needs provide the folloing buffers when using in conf_req_flag=1 mode:16*17* - HEADER (of size gss_context_stream_sizes.header)18* { DATA or SIGN_ONLY } (optional, zero or more)19* PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted)20* TRAILER (of size gss_context_stream_sizes.trailer)21*22* - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the23* DATA elements is padded to a block bountry and header is of at24* least size gss_context_stream_sizes.header + gss_context_stream_sizes.trailer.25*26* HEADER, PADDING, TRAILER will be shrunken to the size required to transmit any of them too large.27*28* To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER29*30* When used in conf_req_flag=0,31*32* - HEADER (of size gss_context_stream_sizes.header)33* { DATA or SIGN_ONLY } (optional, zero or more)34* PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted)35* TRAILER (of size gss_context_stream_sizes.trailer)36*37*38* The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or39* gss_context_query_attributes().40*41* @ingroup gssapi42*/434445GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL46gss_wrap_iov(OM_uint32 * minor_status,47gss_ctx_id_t context_handle,48int conf_req_flag,49gss_qop_t qop_req,50int * conf_state,51gss_iov_buffer_desc *iov,52int iov_count)53{54struct _gss_context *ctx = (struct _gss_context *) context_handle;55gssapi_mech_interface m;5657if (minor_status)58*minor_status = 0;59if (conf_state)60*conf_state = 0;61if (ctx == NULL)62return GSS_S_NO_CONTEXT;63if (iov == NULL && iov_count != 0)64return GSS_S_CALL_INACCESSIBLE_READ;6566m = ctx->gc_mech;6768if (m->gm_wrap_iov == NULL)69return GSS_S_UNAVAILABLE;7071return (m->gm_wrap_iov)(minor_status, ctx->gc_ctx,72conf_req_flag, qop_req, conf_state,73iov, iov_count);74}7576/**77* Decrypt or verifies the signature on the data.78*79*80* @ingroup gssapi81*/8283GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL84gss_unwrap_iov(OM_uint32 *minor_status,85gss_ctx_id_t context_handle,86int *conf_state,87gss_qop_t *qop_state,88gss_iov_buffer_desc *iov,89int iov_count)90{91struct _gss_context *ctx = (struct _gss_context *) context_handle;92gssapi_mech_interface m;9394if (minor_status)95*minor_status = 0;96if (conf_state)97*conf_state = 0;98if (qop_state)99*qop_state = 0;100if (ctx == NULL)101return GSS_S_NO_CONTEXT;102if (iov == NULL && iov_count != 0)103return GSS_S_CALL_INACCESSIBLE_READ;104105m = ctx->gc_mech;106107if (m->gm_unwrap_iov == NULL)108return GSS_S_UNAVAILABLE;109110return (m->gm_unwrap_iov)(minor_status, ctx->gc_ctx,111conf_state, qop_state,112iov, iov_count);113}114115/**116* Update the length fields in iov buffer for the types:117* - GSS_IOV_BUFFER_TYPE_HEADER118* - GSS_IOV_BUFFER_TYPE_PADDING119* - GSS_IOV_BUFFER_TYPE_TRAILER120*121* Consider using gss_context_query_attributes() to fetch the data instead.122*123* @ingroup gssapi124*/125126GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL127gss_wrap_iov_length(OM_uint32 * minor_status,128gss_ctx_id_t context_handle,129int conf_req_flag,130gss_qop_t qop_req,131int *conf_state,132gss_iov_buffer_desc *iov,133int iov_count)134{135struct _gss_context *ctx = (struct _gss_context *) context_handle;136gssapi_mech_interface m;137138if (minor_status)139*minor_status = 0;140if (conf_state)141*conf_state = 0;142if (ctx == NULL)143return GSS_S_NO_CONTEXT;144if (iov == NULL && iov_count != 0)145return GSS_S_CALL_INACCESSIBLE_READ;146147m = ctx->gc_mech;148149if (m->gm_wrap_iov_length == NULL)150return GSS_S_UNAVAILABLE;151152return (m->gm_wrap_iov_length)(minor_status, ctx->gc_ctx,153conf_req_flag, qop_req, conf_state,154iov, iov_count);155}156157/**158* Free all buffer allocated by gss_wrap_iov() or gss_unwrap_iov() by159* looking at the GSS_IOV_BUFFER_FLAG_ALLOCATED flag.160*161* @ingroup gssapi162*/163164GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL165gss_release_iov_buffer(OM_uint32 *minor_status,166gss_iov_buffer_desc *iov,167int iov_count)168{169OM_uint32 junk;170int i;171172if (minor_status)173*minor_status = 0;174if (iov == NULL && iov_count != 0)175return GSS_S_CALL_INACCESSIBLE_READ;176177for (i = 0; i < iov_count; i++) {178if ((iov[i].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) == 0)179continue;180gss_release_buffer(&junk, &iov[i].buffer);181iov[i].type &= ~GSS_IOV_BUFFER_FLAG_ALLOCATED;182}183return GSS_S_COMPLETE;184}185186/**187* Query the context for parameters.188*189* SSPI equivalent if this function is QueryContextAttributes.190*191* - GSS_C_ATTR_STREAM_SIZES data is a gss_context_stream_sizes.192*193* @ingroup gssapi194*/195196gss_OID_desc GSSAPI_LIB_FUNCTION __gss_c_attr_stream_sizes_oid_desc =197{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03")};198199GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL200gss_context_query_attributes(OM_uint32 *minor_status,201const gss_ctx_id_t context_handle,202const gss_OID attribute,203void *data,204size_t len)205{206if (minor_status)207*minor_status = 0;208209if (gss_oid_equal(GSS_C_ATTR_STREAM_SIZES, attribute)) {210memset(data, 0, len);211return GSS_S_COMPLETE;212}213214return GSS_S_FAILURE;215}216217218