xref: /freebsd/crypto/krb5/src/lib/gssapi/mechglue/g_wrap_aead.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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