xref: /freebsd/crypto/krb5/src/lib/gssapi/mechglue/g_unwrap_aead.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* #pragma ident	"@(#)g_seal.c	1.19	98/04/21 SMI" */
2 
3 /*
4  * Copyright 1996 by Sun Microsystems, Inc.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software
7  * and its documentation for any purpose is hereby granted without fee,
8  * provided that the above copyright notice appears in all copies and
9  * that both that copyright notice and this permission notice appear in
10  * supporting documentation, and that the name of Sun Microsystems not be used
11  * in advertising or publicity pertaining to distribution of the software
12  * without specific, written prior permission. Sun Microsystems makes no
13  * representations about the suitability of this software for any
14  * purpose.  It is provided "as is" without express or implied warranty.
15  *
16  * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18  * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
20  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22  * PERFORMANCE OF THIS SOFTWARE.
23  */
24 
25 /*
26  *  glue routine for gss_unwrap_aead
27  */
28 
29 #include "mglueP.h"
30 
31 static OM_uint32
val_unwrap_aead_args(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)32 val_unwrap_aead_args(
33     OM_uint32 *minor_status,
34     gss_ctx_id_t context_handle,
35     gss_buffer_t input_message_buffer,
36     gss_buffer_t input_assoc_buffer,
37     gss_buffer_t output_payload_buffer,
38     int *conf_state,
39     gss_qop_t *qop_state)
40 {
41 
42     /* Initialize outputs. */
43 
44     if (minor_status != NULL)
45 	*minor_status = 0;
46 
47     /* Validate arguments. */
48 
49     if (minor_status == NULL)
50 	return (GSS_S_CALL_INACCESSIBLE_WRITE);
51 
52     if (context_handle == GSS_C_NO_CONTEXT)
53 	return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
54 
55     if (input_message_buffer == GSS_C_NO_BUFFER)
56 	return (GSS_S_CALL_INACCESSIBLE_READ);
57 
58     if (output_payload_buffer == GSS_C_NO_BUFFER)
59 	return (GSS_S_CALL_INACCESSIBLE_WRITE);
60 
61     return (GSS_S_COMPLETE);
62 }
63 
64 static OM_uint32
gssint_unwrap_aead_iov_shim(gss_mechanism mech,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)65 gssint_unwrap_aead_iov_shim(gss_mechanism mech,
66 			    OM_uint32 *minor_status,
67 			    gss_ctx_id_t context_handle,
68 			    gss_buffer_t input_message_buffer,
69 			    gss_buffer_t input_assoc_buffer,
70 			    gss_buffer_t output_payload_buffer,
71 			    int *conf_state,
72 			    gss_qop_t *qop_state)
73 {
74     OM_uint32		    status;
75     gss_iov_buffer_desc	    iov[3];
76     int			    i = 0;
77 
78     iov[i].type = GSS_IOV_BUFFER_TYPE_STREAM;
79     iov[i].buffer = *input_message_buffer;
80     i++;
81 
82     if (input_assoc_buffer != NULL) {
83 	iov[i].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
84 	iov[i].buffer = *input_assoc_buffer;
85 	i++;
86     }
87 
88     iov[i].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE;
89     iov[i].buffer.value = NULL;
90     iov[i].buffer.length = 0;
91     i++;
92 
93     assert(mech->gss_unwrap_iov);
94 
95     status = mech->gss_unwrap_iov(minor_status, context_handle, conf_state,
96 				  qop_state, iov, i);
97     if (status == GSS_S_COMPLETE) {
98 	*output_payload_buffer = iov[i - 1].buffer;
99     } else {
100 	OM_uint32 minor;
101 
102 	map_error(minor_status, mech);
103 
104 	if (iov[i - 1].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) {
105 	    gss_release_buffer(&minor, &iov[i - 1].buffer);
106 	    iov[i - 1].type &= ~(GSS_IOV_BUFFER_FLAG_ALLOCATED);
107 	}
108     }
109 
110     return status;
111 }
112 
113 OM_uint32
gssint_unwrap_aead(gss_mechanism mech,OM_uint32 * minor_status,gss_union_ctx_id_t ctx,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)114 gssint_unwrap_aead (gss_mechanism mech,
115 		    OM_uint32 *minor_status,
116 		    gss_union_ctx_id_t ctx,
117 		    gss_buffer_t input_message_buffer,
118 		    gss_buffer_t input_assoc_buffer,
119 		    gss_buffer_t output_payload_buffer,
120 		    int *conf_state,
121 		    gss_qop_t *qop_state)
122 {
123     OM_uint32		    status;
124 
125     assert(mech != NULL);
126     assert(ctx != NULL);
127 
128  /* EXPORT DELETE START */
129 
130     if (mech->gss_unwrap_aead) {
131 	status = mech->gss_unwrap_aead(minor_status,
132 				       ctx->internal_ctx_id,
133 				       input_message_buffer,
134 				       input_assoc_buffer,
135 				       output_payload_buffer,
136 				       conf_state,
137 				       qop_state);
138 	if (status != GSS_S_COMPLETE)
139 	    map_error(minor_status, mech);
140     } else if (mech->gss_unwrap_iov) {
141 	status = gssint_unwrap_aead_iov_shim(mech,
142 					     minor_status,
143 					     ctx->internal_ctx_id,
144 					     input_message_buffer,
145 					     input_assoc_buffer,
146 					     output_payload_buffer,
147 					     conf_state,
148 					     qop_state);
149     } else
150 	status = GSS_S_UNAVAILABLE;
151  /* EXPORT DELETE END */
152 
153     return (status);
154 }
155 
156 OM_uint32 KRB5_CALLCONV
gss_unwrap_aead(minor_status,context_handle,input_message_buffer,input_assoc_buffer,output_payload_buffer,conf_state,qop_state)157 gss_unwrap_aead (minor_status,
158                  context_handle,
159 		 input_message_buffer,
160 		 input_assoc_buffer,
161 		 output_payload_buffer,
162                  conf_state,
163                  qop_state)
164 OM_uint32 *		minor_status;
165 gss_ctx_id_t		context_handle;
166 gss_buffer_t		input_message_buffer;
167 gss_buffer_t		input_assoc_buffer;
168 gss_buffer_t		output_payload_buffer;
169 int 			*conf_state;
170 gss_qop_t		*qop_state;
171 {
172 
173     OM_uint32		status;
174     gss_union_ctx_id_t	ctx;
175     gss_mechanism	mech;
176 
177     status = val_unwrap_aead_args(minor_status, context_handle,
178 				  input_message_buffer, input_assoc_buffer,
179 				  output_payload_buffer,
180 				  conf_state, qop_state);
181     if (status != GSS_S_COMPLETE)
182 	return (status);
183 
184     /*
185      * select the approprate underlying mechanism routine and
186      * call it.
187      */
188     ctx = (gss_union_ctx_id_t) context_handle;
189     if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT)
190 	return (GSS_S_NO_CONTEXT);
191     mech = gssint_get_mechanism (ctx->mech_type);
192 
193     if (!mech)
194 	return (GSS_S_BAD_MECH);
195 
196     return gssint_unwrap_aead(mech, minor_status, ctx,
197 			      input_message_buffer, input_assoc_buffer,
198 			      output_payload_buffer, conf_state, qop_state);
199 }
200