1226031Sstas/* 2226031Sstas * AEAD support 3226031Sstas */ 4226031Sstas 5226031Sstas#include "mech_locl.h" 6226031Sstas 7226031Sstas/** 8226031Sstas * Encrypts or sign the data. 9226031Sstas * 10226031Sstas * This is a more complicated version of gss_wrap(), it allows the 11226031Sstas * caller to use AEAD data (signed header/trailer) and allow greater 12226031Sstas * controll over where the encrypted data is placed. 13226031Sstas * 14226031Sstas * The maximum packet size is gss_context_stream_sizes.max_msg_size. 15226031Sstas * 16226031Sstas * The caller needs provide the folloing buffers when using in conf_req_flag=1 mode: 17226031Sstas * 18226031Sstas * - HEADER (of size gss_context_stream_sizes.header) 19226031Sstas * { DATA or SIGN_ONLY } (optional, zero or more) 20226031Sstas * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted) 21226031Sstas * TRAILER (of size gss_context_stream_sizes.trailer) 22226031Sstas * 23226031Sstas * - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the 24226031Sstas * DATA elements is padded to a block bountry and header is of at 25226031Sstas * least size gss_context_stream_sizes.header + gss_context_stream_sizes.trailer. 26226031Sstas * 27226031Sstas * HEADER, PADDING, TRAILER will be shrunken to the size required to transmit any of them too large. 28226031Sstas * 29226031Sstas * To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER 30226031Sstas * 31226031Sstas * When used in conf_req_flag=0, 32226031Sstas * 33226031Sstas * - HEADER (of size gss_context_stream_sizes.header) 34226031Sstas * { DATA or SIGN_ONLY } (optional, zero or more) 35226031Sstas * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted) 36226031Sstas * TRAILER (of size gss_context_stream_sizes.trailer) 37226031Sstas * 38226031Sstas * 39226031Sstas * The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or 40226031Sstas * gss_context_query_attributes(). 41226031Sstas * 42226031Sstas * @ingroup gssapi 43226031Sstas */ 44226031Sstas 45226031Sstas 46226031SstasGSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 47226031Sstasgss_wrap_iov(OM_uint32 * minor_status, 48226031Sstas gss_ctx_id_t context_handle, 49226031Sstas int conf_req_flag, 50226031Sstas gss_qop_t qop_req, 51226031Sstas int * conf_state, 52226031Sstas gss_iov_buffer_desc *iov, 53226031Sstas int iov_count) 54226031Sstas{ 55226031Sstas struct _gss_context *ctx = (struct _gss_context *) context_handle; 56226031Sstas gssapi_mech_interface m; 57226031Sstas 58226031Sstas if (minor_status) 59226031Sstas *minor_status = 0; 60226031Sstas if (conf_state) 61226031Sstas *conf_state = 0; 62226031Sstas if (ctx == NULL) 63226031Sstas return GSS_S_NO_CONTEXT; 64226031Sstas if (iov == NULL && iov_count != 0) 65226031Sstas return GSS_S_CALL_INACCESSIBLE_READ; 66226031Sstas 67226031Sstas m = ctx->gc_mech; 68226031Sstas 69226031Sstas if (m->gm_wrap_iov == NULL) 70226031Sstas return GSS_S_UNAVAILABLE; 71226031Sstas 72226031Sstas return (m->gm_wrap_iov)(minor_status, ctx->gc_ctx, 73226031Sstas conf_req_flag, qop_req, conf_state, 74226031Sstas iov, iov_count); 75226031Sstas} 76226031Sstas 77226031Sstas/** 78226031Sstas * Decrypt or verifies the signature on the data. 79226031Sstas * 80226031Sstas * 81226031Sstas * @ingroup gssapi 82226031Sstas */ 83226031Sstas 84226031SstasGSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 85226031Sstasgss_unwrap_iov(OM_uint32 *minor_status, 86226031Sstas gss_ctx_id_t context_handle, 87226031Sstas int *conf_state, 88226031Sstas gss_qop_t *qop_state, 89226031Sstas gss_iov_buffer_desc *iov, 90226031Sstas int iov_count) 91226031Sstas{ 92226031Sstas struct _gss_context *ctx = (struct _gss_context *) context_handle; 93226031Sstas gssapi_mech_interface m; 94226031Sstas 95226031Sstas if (minor_status) 96226031Sstas *minor_status = 0; 97226031Sstas if (conf_state) 98226031Sstas *conf_state = 0; 99226031Sstas if (qop_state) 100226031Sstas *qop_state = 0; 101226031Sstas if (ctx == NULL) 102226031Sstas return GSS_S_NO_CONTEXT; 103226031Sstas if (iov == NULL && iov_count != 0) 104226031Sstas return GSS_S_CALL_INACCESSIBLE_READ; 105226031Sstas 106226031Sstas m = ctx->gc_mech; 107226031Sstas 108226031Sstas if (m->gm_unwrap_iov == NULL) 109226031Sstas return GSS_S_UNAVAILABLE; 110226031Sstas 111226031Sstas return (m->gm_unwrap_iov)(minor_status, ctx->gc_ctx, 112226031Sstas conf_state, qop_state, 113226031Sstas iov, iov_count); 114226031Sstas} 115226031Sstas 116226031Sstas/** 117226031Sstas * Update the length fields in iov buffer for the types: 118226031Sstas * - GSS_IOV_BUFFER_TYPE_HEADER 119226031Sstas * - GSS_IOV_BUFFER_TYPE_PADDING 120226031Sstas * - GSS_IOV_BUFFER_TYPE_TRAILER 121226031Sstas * 122226031Sstas * Consider using gss_context_query_attributes() to fetch the data instead. 123226031Sstas * 124226031Sstas * @ingroup gssapi 125226031Sstas */ 126226031Sstas 127226031SstasGSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 128226031Sstasgss_wrap_iov_length(OM_uint32 * minor_status, 129226031Sstas gss_ctx_id_t context_handle, 130226031Sstas int conf_req_flag, 131226031Sstas gss_qop_t qop_req, 132226031Sstas int *conf_state, 133226031Sstas gss_iov_buffer_desc *iov, 134226031Sstas int iov_count) 135226031Sstas{ 136226031Sstas struct _gss_context *ctx = (struct _gss_context *) context_handle; 137226031Sstas gssapi_mech_interface m; 138226031Sstas 139226031Sstas if (minor_status) 140226031Sstas *minor_status = 0; 141226031Sstas if (conf_state) 142226031Sstas *conf_state = 0; 143226031Sstas if (ctx == NULL) 144226031Sstas return GSS_S_NO_CONTEXT; 145226031Sstas if (iov == NULL && iov_count != 0) 146226031Sstas return GSS_S_CALL_INACCESSIBLE_READ; 147226031Sstas 148226031Sstas m = ctx->gc_mech; 149226031Sstas 150226031Sstas if (m->gm_wrap_iov_length == NULL) 151226031Sstas return GSS_S_UNAVAILABLE; 152226031Sstas 153226031Sstas return (m->gm_wrap_iov_length)(minor_status, ctx->gc_ctx, 154226031Sstas conf_req_flag, qop_req, conf_state, 155226031Sstas iov, iov_count); 156226031Sstas} 157226031Sstas 158226031Sstas/** 159226031Sstas * Free all buffer allocated by gss_wrap_iov() or gss_unwrap_iov() by 160226031Sstas * looking at the GSS_IOV_BUFFER_FLAG_ALLOCATED flag. 161226031Sstas * 162226031Sstas * @ingroup gssapi 163226031Sstas */ 164226031Sstas 165226031SstasGSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 166226031Sstasgss_release_iov_buffer(OM_uint32 *minor_status, 167226031Sstas gss_iov_buffer_desc *iov, 168226031Sstas int iov_count) 169226031Sstas{ 170226031Sstas OM_uint32 junk; 171226031Sstas int i; 172226031Sstas 173226031Sstas if (minor_status) 174226031Sstas *minor_status = 0; 175226031Sstas if (iov == NULL && iov_count != 0) 176226031Sstas return GSS_S_CALL_INACCESSIBLE_READ; 177226031Sstas 178226031Sstas for (i = 0; i < iov_count; i++) { 179226031Sstas if ((iov[i].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) == 0) 180226031Sstas continue; 181226031Sstas gss_release_buffer(&junk, &iov[i].buffer); 182226031Sstas iov[i].type &= ~GSS_IOV_BUFFER_FLAG_ALLOCATED; 183226031Sstas } 184226031Sstas return GSS_S_COMPLETE; 185226031Sstas} 186226031Sstas 187226031Sstas/** 188226031Sstas * Query the context for parameters. 189226031Sstas * 190226031Sstas * SSPI equivalent if this function is QueryContextAttributes. 191226031Sstas * 192226031Sstas * - GSS_C_ATTR_STREAM_SIZES data is a gss_context_stream_sizes. 193226031Sstas * 194226031Sstas * @ingroup gssapi 195226031Sstas */ 196226031Sstas 197226031Sstasgss_OID_desc GSSAPI_LIB_FUNCTION __gss_c_attr_stream_sizes_oid_desc = 198226031Sstas {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03")}; 199226031Sstas 200226031SstasGSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 201226031Sstasgss_context_query_attributes(OM_uint32 *minor_status, 202226031Sstas const gss_ctx_id_t context_handle, 203226031Sstas const gss_OID attribute, 204226031Sstas void *data, 205226031Sstas size_t len) 206226031Sstas{ 207226031Sstas if (minor_status) 208226031Sstas *minor_status = 0; 209226031Sstas 210226031Sstas if (gss_oid_equal(GSS_C_ATTR_STREAM_SIZES, attribute)) { 211226031Sstas memset(data, 0, len); 212226031Sstas return GSS_S_COMPLETE; 213226031Sstas } 214226031Sstas 215226031Sstas return GSS_S_FAILURE; 216226031Sstas} 217