1*7f2fe78bSCy Schubert /* #pragma ident "@(#)g_seal.c 1.19 98/04/21 SMI" */
2*7f2fe78bSCy Schubert
3*7f2fe78bSCy Schubert /*
4*7f2fe78bSCy Schubert * Copyright 1996 by Sun Microsystems, Inc.
5*7f2fe78bSCy Schubert *
6*7f2fe78bSCy Schubert * Permission to use, copy, modify, distribute, and sell this software
7*7f2fe78bSCy Schubert * and its documentation for any purpose is hereby granted without fee,
8*7f2fe78bSCy Schubert * provided that the above copyright notice appears in all copies and
9*7f2fe78bSCy Schubert * that both that copyright notice and this permission notice appear in
10*7f2fe78bSCy Schubert * supporting documentation, and that the name of Sun Microsystems not be used
11*7f2fe78bSCy Schubert * in advertising or publicity pertaining to distribution of the software
12*7f2fe78bSCy Schubert * without specific, written prior permission. Sun Microsystems makes no
13*7f2fe78bSCy Schubert * representations about the suitability of this software for any
14*7f2fe78bSCy Schubert * purpose. It is provided "as is" without express or implied warranty.
15*7f2fe78bSCy Schubert *
16*7f2fe78bSCy Schubert * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17*7f2fe78bSCy Schubert * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18*7f2fe78bSCy Schubert * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19*7f2fe78bSCy Schubert * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
20*7f2fe78bSCy Schubert * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21*7f2fe78bSCy Schubert * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22*7f2fe78bSCy Schubert * PERFORMANCE OF THIS SOFTWARE.
23*7f2fe78bSCy Schubert */
24*7f2fe78bSCy Schubert
25*7f2fe78bSCy Schubert /*
26*7f2fe78bSCy Schubert * glue routine for gss_wrap_aead
27*7f2fe78bSCy Schubert */
28*7f2fe78bSCy Schubert
29*7f2fe78bSCy Schubert #include "mglueP.h"
30*7f2fe78bSCy Schubert
31*7f2fe78bSCy Schubert static OM_uint32
val_wrap_aead_args(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)32*7f2fe78bSCy Schubert val_wrap_aead_args(
33*7f2fe78bSCy Schubert OM_uint32 *minor_status,
34*7f2fe78bSCy Schubert gss_ctx_id_t context_handle,
35*7f2fe78bSCy Schubert int conf_req_flag,
36*7f2fe78bSCy Schubert gss_qop_t qop_req,
37*7f2fe78bSCy Schubert gss_buffer_t input_assoc_buffer,
38*7f2fe78bSCy Schubert gss_buffer_t input_payload_buffer,
39*7f2fe78bSCy Schubert int *conf_state,
40*7f2fe78bSCy Schubert gss_buffer_t output_message_buffer)
41*7f2fe78bSCy Schubert {
42*7f2fe78bSCy Schubert
43*7f2fe78bSCy Schubert /* Initialize outputs. */
44*7f2fe78bSCy Schubert
45*7f2fe78bSCy Schubert if (minor_status != NULL)
46*7f2fe78bSCy Schubert *minor_status = 0;
47*7f2fe78bSCy Schubert
48*7f2fe78bSCy Schubert /* Validate arguments. */
49*7f2fe78bSCy Schubert
50*7f2fe78bSCy Schubert if (minor_status == NULL)
51*7f2fe78bSCy Schubert return (GSS_S_CALL_INACCESSIBLE_WRITE);
52*7f2fe78bSCy Schubert
53*7f2fe78bSCy Schubert if (context_handle == GSS_C_NO_CONTEXT)
54*7f2fe78bSCy Schubert return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
55*7f2fe78bSCy Schubert
56*7f2fe78bSCy Schubert if (input_payload_buffer == GSS_C_NO_BUFFER)
57*7f2fe78bSCy Schubert return (GSS_S_CALL_INACCESSIBLE_READ);
58*7f2fe78bSCy Schubert
59*7f2fe78bSCy Schubert if (output_message_buffer == GSS_C_NO_BUFFER)
60*7f2fe78bSCy Schubert return (GSS_S_CALL_INACCESSIBLE_WRITE);
61*7f2fe78bSCy Schubert
62*7f2fe78bSCy Schubert return (GSS_S_COMPLETE);
63*7f2fe78bSCy Schubert }
64*7f2fe78bSCy Schubert
65*7f2fe78bSCy Schubert static OM_uint32
gssint_wrap_aead_iov_shim(gss_mechanism mech,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)66*7f2fe78bSCy Schubert gssint_wrap_aead_iov_shim(gss_mechanism mech,
67*7f2fe78bSCy Schubert OM_uint32 *minor_status,
68*7f2fe78bSCy Schubert gss_ctx_id_t context_handle,
69*7f2fe78bSCy Schubert int conf_req_flag,
70*7f2fe78bSCy Schubert gss_qop_t qop_req,
71*7f2fe78bSCy Schubert gss_buffer_t input_assoc_buffer,
72*7f2fe78bSCy Schubert gss_buffer_t input_payload_buffer,
73*7f2fe78bSCy Schubert int *conf_state,
74*7f2fe78bSCy Schubert gss_buffer_t output_message_buffer)
75*7f2fe78bSCy Schubert {
76*7f2fe78bSCy Schubert gss_iov_buffer_desc iov[5];
77*7f2fe78bSCy Schubert OM_uint32 status;
78*7f2fe78bSCy Schubert size_t offset;
79*7f2fe78bSCy Schubert int i = 0, iov_count;
80*7f2fe78bSCy Schubert
81*7f2fe78bSCy Schubert /* HEADER | SIGN_ONLY_DATA | DATA | PADDING | TRAILER */
82*7f2fe78bSCy Schubert
83*7f2fe78bSCy Schubert iov[i].type = GSS_IOV_BUFFER_TYPE_HEADER;
84*7f2fe78bSCy Schubert iov[i].buffer.value = NULL;
85*7f2fe78bSCy Schubert iov[i].buffer.length = 0;
86*7f2fe78bSCy Schubert i++;
87*7f2fe78bSCy Schubert
88*7f2fe78bSCy Schubert if (input_assoc_buffer != GSS_C_NO_BUFFER) {
89*7f2fe78bSCy Schubert iov[i].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
90*7f2fe78bSCy Schubert iov[i].buffer = *input_assoc_buffer;
91*7f2fe78bSCy Schubert i++;
92*7f2fe78bSCy Schubert }
93*7f2fe78bSCy Schubert
94*7f2fe78bSCy Schubert iov[i].type = GSS_IOV_BUFFER_TYPE_DATA;
95*7f2fe78bSCy Schubert iov[i].buffer = *input_payload_buffer;
96*7f2fe78bSCy Schubert i++;
97*7f2fe78bSCy Schubert
98*7f2fe78bSCy Schubert iov[i].type = GSS_IOV_BUFFER_TYPE_PADDING;
99*7f2fe78bSCy Schubert iov[i].buffer.value = NULL;
100*7f2fe78bSCy Schubert iov[i].buffer.length = 0;
101*7f2fe78bSCy Schubert i++;
102*7f2fe78bSCy Schubert
103*7f2fe78bSCy Schubert iov[i].type = GSS_IOV_BUFFER_TYPE_TRAILER;
104*7f2fe78bSCy Schubert iov[i].buffer.value = NULL;
105*7f2fe78bSCy Schubert iov[i].buffer.length = 0;
106*7f2fe78bSCy Schubert i++;
107*7f2fe78bSCy Schubert
108*7f2fe78bSCy Schubert iov_count = i;
109*7f2fe78bSCy Schubert
110*7f2fe78bSCy Schubert assert(mech->gss_wrap_iov_length);
111*7f2fe78bSCy Schubert
112*7f2fe78bSCy Schubert status = mech->gss_wrap_iov_length(minor_status, context_handle,
113*7f2fe78bSCy Schubert conf_req_flag, qop_req,
114*7f2fe78bSCy Schubert NULL, iov, iov_count);
115*7f2fe78bSCy Schubert if (status != GSS_S_COMPLETE) {
116*7f2fe78bSCy Schubert map_error(minor_status, mech);
117*7f2fe78bSCy Schubert return status;
118*7f2fe78bSCy Schubert }
119*7f2fe78bSCy Schubert
120*7f2fe78bSCy Schubert /* Format output token (does not include associated data) */
121*7f2fe78bSCy Schubert for (i = 0, output_message_buffer->length = 0; i < iov_count; i++) {
122*7f2fe78bSCy Schubert if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_SIGN_ONLY)
123*7f2fe78bSCy Schubert continue;
124*7f2fe78bSCy Schubert
125*7f2fe78bSCy Schubert output_message_buffer->length += iov[i].buffer.length;
126*7f2fe78bSCy Schubert }
127*7f2fe78bSCy Schubert
128*7f2fe78bSCy Schubert output_message_buffer->value = gssalloc_malloc(output_message_buffer->length);
129*7f2fe78bSCy Schubert if (output_message_buffer->value == NULL) {
130*7f2fe78bSCy Schubert *minor_status = ENOMEM;
131*7f2fe78bSCy Schubert return GSS_S_FAILURE;
132*7f2fe78bSCy Schubert }
133*7f2fe78bSCy Schubert
134*7f2fe78bSCy Schubert i = 0, offset = 0;
135*7f2fe78bSCy Schubert
136*7f2fe78bSCy Schubert /* HEADER */
137*7f2fe78bSCy Schubert iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset;
138*7f2fe78bSCy Schubert offset += iov[i].buffer.length;
139*7f2fe78bSCy Schubert i++;
140*7f2fe78bSCy Schubert
141*7f2fe78bSCy Schubert /* SIGN_ONLY_DATA */
142*7f2fe78bSCy Schubert if (input_assoc_buffer != GSS_C_NO_BUFFER)
143*7f2fe78bSCy Schubert i++;
144*7f2fe78bSCy Schubert
145*7f2fe78bSCy Schubert /* DATA */
146*7f2fe78bSCy Schubert iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset;
147*7f2fe78bSCy Schubert offset += iov[i].buffer.length;
148*7f2fe78bSCy Schubert
149*7f2fe78bSCy Schubert memcpy(iov[i].buffer.value, input_payload_buffer->value, iov[i].buffer.length);
150*7f2fe78bSCy Schubert i++;
151*7f2fe78bSCy Schubert
152*7f2fe78bSCy Schubert /* PADDING */
153*7f2fe78bSCy Schubert iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset;
154*7f2fe78bSCy Schubert offset += iov[i].buffer.length;
155*7f2fe78bSCy Schubert i++;
156*7f2fe78bSCy Schubert
157*7f2fe78bSCy Schubert /* TRAILER */
158*7f2fe78bSCy Schubert iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset;
159*7f2fe78bSCy Schubert offset += iov[i].buffer.length;
160*7f2fe78bSCy Schubert i++;
161*7f2fe78bSCy Schubert
162*7f2fe78bSCy Schubert assert(offset == output_message_buffer->length);
163*7f2fe78bSCy Schubert
164*7f2fe78bSCy Schubert assert(mech->gss_wrap_iov);
165*7f2fe78bSCy Schubert
166*7f2fe78bSCy Schubert status = mech->gss_wrap_iov(minor_status, context_handle,
167*7f2fe78bSCy Schubert conf_req_flag, qop_req,
168*7f2fe78bSCy Schubert conf_state, iov, iov_count);
169*7f2fe78bSCy Schubert if (status != GSS_S_COMPLETE) {
170*7f2fe78bSCy Schubert OM_uint32 minor;
171*7f2fe78bSCy Schubert
172*7f2fe78bSCy Schubert map_error(minor_status, mech);
173*7f2fe78bSCy Schubert gss_release_buffer(&minor, output_message_buffer);
174*7f2fe78bSCy Schubert }
175*7f2fe78bSCy Schubert
176*7f2fe78bSCy Schubert return status;
177*7f2fe78bSCy Schubert }
178*7f2fe78bSCy Schubert
179*7f2fe78bSCy Schubert OM_uint32
gssint_wrap_aead(gss_mechanism mech,OM_uint32 * minor_status,gss_union_ctx_id_t ctx,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)180*7f2fe78bSCy Schubert gssint_wrap_aead (gss_mechanism mech,
181*7f2fe78bSCy Schubert OM_uint32 *minor_status,
182*7f2fe78bSCy Schubert gss_union_ctx_id_t ctx,
183*7f2fe78bSCy Schubert int conf_req_flag,
184*7f2fe78bSCy Schubert gss_qop_t qop_req,
185*7f2fe78bSCy Schubert gss_buffer_t input_assoc_buffer,
186*7f2fe78bSCy Schubert gss_buffer_t input_payload_buffer,
187*7f2fe78bSCy Schubert int *conf_state,
188*7f2fe78bSCy Schubert gss_buffer_t output_message_buffer)
189*7f2fe78bSCy Schubert {
190*7f2fe78bSCy Schubert /* EXPORT DELETE START */
191*7f2fe78bSCy Schubert OM_uint32 status;
192*7f2fe78bSCy Schubert
193*7f2fe78bSCy Schubert assert(ctx != NULL);
194*7f2fe78bSCy Schubert assert(mech != NULL);
195*7f2fe78bSCy Schubert
196*7f2fe78bSCy Schubert if (mech->gss_wrap_aead) {
197*7f2fe78bSCy Schubert status = mech->gss_wrap_aead(minor_status,
198*7f2fe78bSCy Schubert ctx->internal_ctx_id,
199*7f2fe78bSCy Schubert conf_req_flag,
200*7f2fe78bSCy Schubert qop_req,
201*7f2fe78bSCy Schubert input_assoc_buffer,
202*7f2fe78bSCy Schubert input_payload_buffer,
203*7f2fe78bSCy Schubert conf_state,
204*7f2fe78bSCy Schubert output_message_buffer);
205*7f2fe78bSCy Schubert if (status != GSS_S_COMPLETE)
206*7f2fe78bSCy Schubert map_error(minor_status, mech);
207*7f2fe78bSCy Schubert } else if (mech->gss_wrap_iov && mech->gss_wrap_iov_length) {
208*7f2fe78bSCy Schubert status = gssint_wrap_aead_iov_shim(mech,
209*7f2fe78bSCy Schubert minor_status,
210*7f2fe78bSCy Schubert ctx->internal_ctx_id,
211*7f2fe78bSCy Schubert conf_req_flag,
212*7f2fe78bSCy Schubert qop_req,
213*7f2fe78bSCy Schubert input_assoc_buffer,
214*7f2fe78bSCy Schubert input_payload_buffer,
215*7f2fe78bSCy Schubert conf_state,
216*7f2fe78bSCy Schubert output_message_buffer);
217*7f2fe78bSCy Schubert } else
218*7f2fe78bSCy Schubert status = GSS_S_UNAVAILABLE;
219*7f2fe78bSCy Schubert
220*7f2fe78bSCy Schubert /* EXPORT DELETE END */
221*7f2fe78bSCy Schubert
222*7f2fe78bSCy Schubert return status;
223*7f2fe78bSCy Schubert }
224*7f2fe78bSCy Schubert
225*7f2fe78bSCy Schubert OM_uint32 KRB5_CALLCONV
gss_wrap_aead(minor_status,context_handle,conf_req_flag,qop_req,input_assoc_buffer,input_payload_buffer,conf_state,output_message_buffer)226*7f2fe78bSCy Schubert gss_wrap_aead (minor_status,
227*7f2fe78bSCy Schubert context_handle,
228*7f2fe78bSCy Schubert conf_req_flag,
229*7f2fe78bSCy Schubert qop_req,
230*7f2fe78bSCy Schubert input_assoc_buffer,
231*7f2fe78bSCy Schubert input_payload_buffer,
232*7f2fe78bSCy Schubert conf_state,
233*7f2fe78bSCy Schubert output_message_buffer)
234*7f2fe78bSCy Schubert OM_uint32 * minor_status;
235*7f2fe78bSCy Schubert gss_ctx_id_t context_handle;
236*7f2fe78bSCy Schubert int conf_req_flag;
237*7f2fe78bSCy Schubert gss_qop_t qop_req;
238*7f2fe78bSCy Schubert gss_buffer_t input_assoc_buffer;
239*7f2fe78bSCy Schubert gss_buffer_t input_payload_buffer;
240*7f2fe78bSCy Schubert int * conf_state;
241*7f2fe78bSCy Schubert gss_buffer_t output_message_buffer;
242*7f2fe78bSCy Schubert {
243*7f2fe78bSCy Schubert OM_uint32 status;
244*7f2fe78bSCy Schubert gss_mechanism mech;
245*7f2fe78bSCy Schubert gss_union_ctx_id_t ctx;
246*7f2fe78bSCy Schubert
247*7f2fe78bSCy Schubert status = val_wrap_aead_args(minor_status, context_handle,
248*7f2fe78bSCy Schubert conf_req_flag, qop_req,
249*7f2fe78bSCy Schubert input_assoc_buffer, input_payload_buffer,
250*7f2fe78bSCy Schubert conf_state, output_message_buffer);
251*7f2fe78bSCy Schubert if (status != GSS_S_COMPLETE)
252*7f2fe78bSCy Schubert return (status);
253*7f2fe78bSCy Schubert
254*7f2fe78bSCy Schubert /*
255*7f2fe78bSCy Schubert * select the approprate underlying mechanism routine and
256*7f2fe78bSCy Schubert * call it.
257*7f2fe78bSCy Schubert */
258*7f2fe78bSCy Schubert ctx = (gss_union_ctx_id_t)context_handle;
259*7f2fe78bSCy Schubert if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
260*7f2fe78bSCy Schubert return (GSS_S_NO_CONTEXT);
261*7f2fe78bSCy Schubert mech = gssint_get_mechanism (ctx->mech_type);
262*7f2fe78bSCy Schubert if (!mech)
263*7f2fe78bSCy Schubert return (GSS_S_BAD_MECH);
264*7f2fe78bSCy Schubert
265*7f2fe78bSCy Schubert return gssint_wrap_aead(mech, minor_status, ctx,
266*7f2fe78bSCy Schubert conf_req_flag, qop_req,
267*7f2fe78bSCy Schubert input_assoc_buffer, input_payload_buffer,
268*7f2fe78bSCy Schubert conf_state, output_message_buffer);
269*7f2fe78bSCy Schubert }
270