*** empty log message ***
[heimdal.git] / lib / gssapi / krb5 / wrap.c
blob7d1408c4a07991247900b3ed46733d540954dec3
1 /*
2 * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Kungliga Tekniska
20 * Högskolan and its contributors.
22 * 4. Neither the name of the Institute nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
39 #include "gssapi_locl.h"
41 RCSID("$Id$");
43 OM_uint32 gss_wrap_size_limit (
44 OM_uint32 * minor_status,
45 const gss_ctx_id_t context_handle,
46 int conf_req_flag,
47 gss_qop_t qop_req,
48 OM_uint32 req_output_size,
49 OM_uint32 * max_input_size
52 size_t len, total_len, padlength;
53 padlength = 8 - (req_output_size % 8);
54 len = req_output_size + 8 + padlength + 22;
55 gssapi_krb5_encap_length(len, &len, &total_len);
56 *max_input_size = (OM_uint32)total_len;
57 return GSS_S_COMPLETE;
60 OM_uint32 gss_wrap
61 (OM_uint32 * minor_status,
62 const gss_ctx_id_t context_handle,
63 int conf_req_flag,
64 gss_qop_t qop_req,
65 const gss_buffer_t input_message_buffer,
66 int * conf_state,
67 gss_buffer_t output_message_buffer
70 u_char *p;
71 struct md5 md5;
72 u_char hash[16];
73 des_key_schedule schedule;
74 des_cblock key;
75 des_cblock zero;
76 int i;
77 int32_t seq_number;
78 size_t len, total_len, padlength;
80 padlength = 8 - (input_message_buffer->length % 8);
81 len = input_message_buffer->length + 8 + padlength + 22;
82 gssapi_krb5_encap_length (len, &len, &total_len);
84 output_message_buffer->length = total_len;
85 output_message_buffer->value = malloc (total_len);
86 if (output_message_buffer->value == NULL)
87 return GSS_S_FAILURE;
89 p = gssapi_krb5_make_header(output_message_buffer->value,
90 len,
91 "\x02\x01");
94 /* SGN_ALG */
95 memcpy (p, "\x00\x00", 2);
96 p += 2;
97 /* SEAL_ALG */
98 if(conf_req_flag)
99 memcpy (p, "\x00\x00", 2);
100 else
101 memcpy (p, "\xff\xff", 2);
102 p += 2;
103 /* Filler */
104 memcpy (p, "\xff\xff", 2);
105 p += 2;
107 /* fill in later */
108 memset (p, 0, 16);
109 p += 16;
111 /* confounder + data + pad */
112 des_new_random_key((des_cblock*)p);
113 memcpy (p + 8, input_message_buffer->value,
114 input_message_buffer->length);
115 memset (p + 8 + input_message_buffer->length, padlength, padlength);
117 /* checksum */
118 md5_init (&md5);
119 md5_update (&md5, p - 24, 8);
120 md5_update (&md5, p, input_message_buffer->length + padlength + 8);
121 md5_finito (&md5, hash);
123 memset (&zero, 0, sizeof(zero));
124 gss_krb5_getsomekey(context_handle, &key);
125 des_set_key (&key, schedule);
126 des_cbc_cksum ((des_cblock *)hash,
127 (des_cblock *)hash, sizeof(hash), schedule, &zero);
128 memcpy (p - 8, hash, 8);
130 /* sequence number */
131 krb5_auth_getlocalseqnumber (gssapi_krb5_context,
132 context_handle->auth_context,
133 &seq_number);
135 p -= 16;
136 p[0] = (seq_number >> 0) & 0xFF;
137 p[1] = (seq_number >> 8) & 0xFF;
138 p[2] = (seq_number >> 16) & 0xFF;
139 p[3] = (seq_number >> 24) & 0xFF;
140 memset (p + 4,
141 (context_handle->more_flags & LOCAL) ? 0 : 0xFF,
144 des_set_key (&key, schedule);
145 des_cbc_encrypt ((des_cblock *)p, (des_cblock *)p, 8,
146 schedule, (des_cblock *)(p + 8), DES_ENCRYPT);
148 krb5_auth_setlocalseqnumber (gssapi_krb5_context,
149 context_handle->auth_context,
150 ++seq_number);
152 /* encrypt the data */
153 p += 16;
155 if(conf_req_flag) {
156 gss_krb5_getsomekey(context_handle, &key);
157 for (i = 0; i < sizeof(key); ++i)
158 key[i] ^= 0xf0;
159 des_set_key (&key, schedule);
160 memset (&zero, 0, sizeof(zero));
161 des_cbc_encrypt ((des_cblock *)p,
162 (des_cblock *)p,
163 8 + input_message_buffer->length + padlength,
164 schedule,
165 &zero,
166 DES_ENCRYPT);
168 memset (key, 0, sizeof(key));
169 memset (schedule, 0, sizeof(schedule));
171 if(conf_state != NULL)
172 *conf_state = conf_req_flag;
173 return GSS_S_COMPLETE;