110db1377Sgtb /*
2159d09a2SMark Phalan  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
310db1377Sgtb  * Use is subject to license terms.
410db1377Sgtb  */
510db1377Sgtb 
610db1377Sgtb 
710db1377Sgtb /*
810db1377Sgtb  * Copyright (C) 1998 by the FundsXpress, INC.
9*55fea89dSDan Cross  *
1010db1377Sgtb  * All rights reserved.
11*55fea89dSDan Cross  *
1210db1377Sgtb  * Export of this software from the United States of America may require
1310db1377Sgtb  * a specific license from the United States Government.  It is the
1410db1377Sgtb  * responsibility of any person or organization contemplating export to
1510db1377Sgtb  * obtain such a license before exporting.
16*55fea89dSDan Cross  *
1710db1377Sgtb  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
1810db1377Sgtb  * distribute this software and its documentation for any purpose and
1910db1377Sgtb  * without fee is hereby granted, provided that the above copyright
2010db1377Sgtb  * notice appear in all copies and that both that copyright notice and
2110db1377Sgtb  * this permission notice appear in supporting documentation, and that
2210db1377Sgtb  * the name of FundsXpress. not be used in advertising or publicity pertaining
2310db1377Sgtb  * to distribution of the software without specific, written prior
2410db1377Sgtb  * permission.  FundsXpress makes no representations about the suitability of
2510db1377Sgtb  * this software for any purpose.  It is provided "as is" without express
2610db1377Sgtb  * or implied warranty.
27*55fea89dSDan Cross  *
2810db1377Sgtb  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
2910db1377Sgtb  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
3010db1377Sgtb  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
3110db1377Sgtb  */
3210db1377Sgtb 
3310db1377Sgtb #include "k5-int.h"
3410db1377Sgtb 
3510db1377Sgtb /*
3610db1377Sgtb  * Solaris Kerberos
3710db1377Sgtb  * krb5_string_to_key/krb5_use_enctype are needed by Samba
3810db1377Sgtb  */
3910db1377Sgtb 
40159d09a2SMark Phalan krb5_error_code KRB5_CALLCONV
krb5_encrypt(krb5_context context,krb5_const_pointer inptr,krb5_pointer outptr,size_t size,krb5_encrypt_block * eblock,krb5_pointer ivec)41159d09a2SMark Phalan krb5_encrypt(krb5_context context, krb5_const_pointer inptr,
42159d09a2SMark Phalan 	     krb5_pointer outptr, size_t size, krb5_encrypt_block *eblock,
43159d09a2SMark Phalan 	     krb5_pointer ivec)
44159d09a2SMark Phalan {
45159d09a2SMark Phalan     krb5_data inputd, ivecd;
46159d09a2SMark Phalan     krb5_enc_data outputd;
47159d09a2SMark Phalan     size_t blocksize, outlen;
48159d09a2SMark Phalan     krb5_error_code ret;
49159d09a2SMark Phalan 
50159d09a2SMark Phalan     if (ivec) {
51159d09a2SMark Phalan 	if ((ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize)))
52159d09a2SMark Phalan 	    return(ret);
53159d09a2SMark Phalan 
54159d09a2SMark Phalan 	ivecd.length = blocksize;
55159d09a2SMark Phalan 	ivecd.data = ivec;
56159d09a2SMark Phalan     }
57159d09a2SMark Phalan 
58159d09a2SMark Phalan     /* size is the length of the input cleartext data */
59159d09a2SMark Phalan     inputd.length = size;
60159d09a2SMark Phalan     inputd.data = (char*)inptr;
61159d09a2SMark Phalan 
62159d09a2SMark Phalan     /* The size of the output buffer isn't part of the old api.  Not too
63159d09a2SMark Phalan        safe.  So, we assume here that it's big enough. */
64159d09a2SMark Phalan     if ((ret = krb5_c_encrypt_length(context, eblock->key->enctype, size,
65159d09a2SMark Phalan 				     &outlen)))
66159d09a2SMark Phalan 	return(ret);
67159d09a2SMark Phalan 
68159d09a2SMark Phalan     outputd.ciphertext.length = outlen;
69159d09a2SMark Phalan     outputd.ciphertext.data = outptr;
70159d09a2SMark Phalan 
71159d09a2SMark Phalan     return(krb5_c_encrypt(context, eblock->key, 0, ivec?&ivecd:0,
72159d09a2SMark Phalan 			  &inputd, &outputd));
73159d09a2SMark Phalan }
74159d09a2SMark Phalan 
75159d09a2SMark Phalan krb5_error_code KRB5_CALLCONV
krb5_decrypt(krb5_context context,krb5_const_pointer inptr,krb5_pointer outptr,size_t size,krb5_encrypt_block * eblock,krb5_pointer ivec)76159d09a2SMark Phalan krb5_decrypt(krb5_context context, krb5_const_pointer inptr,
77159d09a2SMark Phalan 	     krb5_pointer outptr, size_t size, krb5_encrypt_block *eblock,
78159d09a2SMark Phalan 	     krb5_pointer ivec)
79159d09a2SMark Phalan {
80159d09a2SMark Phalan     krb5_enc_data inputd;
81159d09a2SMark Phalan     krb5_data outputd, ivecd;
82159d09a2SMark Phalan     size_t blocksize;
83159d09a2SMark Phalan     krb5_error_code ret;
84159d09a2SMark Phalan 
85159d09a2SMark Phalan     if (ivec) {
86159d09a2SMark Phalan 	if ((ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize)))
87159d09a2SMark Phalan 	    return(ret);
88159d09a2SMark Phalan 
89159d09a2SMark Phalan 	ivecd.length = blocksize;
90159d09a2SMark Phalan 	ivecd.data = ivec;
91159d09a2SMark Phalan     }
92159d09a2SMark Phalan 
93159d09a2SMark Phalan     /* size is the length of the input ciphertext data */
94159d09a2SMark Phalan     inputd.enctype = eblock->key->enctype;
95159d09a2SMark Phalan     inputd.ciphertext.length = size;
96159d09a2SMark Phalan     /* Solaris Kerberos */
97159d09a2SMark Phalan     inputd.ciphertext.data = (char*)inptr;
98159d09a2SMark Phalan 
99159d09a2SMark Phalan     /* we don't really know how big this is, but the code tends to assume
100159d09a2SMark Phalan        that the output buffer size should be the same as the input
101159d09a2SMark Phalan        buffer size */
102159d09a2SMark Phalan     outputd.length = size;
103159d09a2SMark Phalan     outputd.data = outptr;
104159d09a2SMark Phalan 
105159d09a2SMark Phalan     return(krb5_c_decrypt(context, eblock->key, 0, ivec?&ivecd:0,
106159d09a2SMark Phalan 			  &inputd, &outputd));
107159d09a2SMark Phalan }
108159d09a2SMark Phalan 
109159d09a2SMark Phalan krb5_error_code KRB5_CALLCONV
krb5_process_key(krb5_context context,krb5_encrypt_block * eblock,const krb5_keyblock * key)110159d09a2SMark Phalan krb5_process_key(krb5_context context, krb5_encrypt_block *eblock,
111159d09a2SMark Phalan 		 const krb5_keyblock *key)
112159d09a2SMark Phalan {
113159d09a2SMark Phalan     eblock->key = (krb5_keyblock *) key;
114159d09a2SMark Phalan 
115159d09a2SMark Phalan     return(0);
116159d09a2SMark Phalan }
117159d09a2SMark Phalan 
118159d09a2SMark Phalan krb5_error_code KRB5_CALLCONV
krb5_finish_key(krb5_context context,krb5_encrypt_block * eblock)119159d09a2SMark Phalan krb5_finish_key(krb5_context context, krb5_encrypt_block *eblock)
120159d09a2SMark Phalan {
121159d09a2SMark Phalan     return(0);
122159d09a2SMark Phalan }
123159d09a2SMark Phalan 
12410db1377Sgtb krb5_error_code KRB5_CALLCONV
krb5_string_to_key(krb5_context context,const krb5_encrypt_block * eblock,krb5_keyblock * keyblock,const krb5_data * data,const krb5_data * salt)12510db1377Sgtb krb5_string_to_key(krb5_context context, const krb5_encrypt_block *eblock,
12610db1377Sgtb 		   krb5_keyblock *keyblock, const krb5_data *data,
12710db1377Sgtb 		   const krb5_data *salt)
12810db1377Sgtb {
12910db1377Sgtb     return(krb5_c_string_to_key(context, eblock->crypto_entry, data, salt,
13010db1377Sgtb 				keyblock));
13110db1377Sgtb }
13210db1377Sgtb 
133159d09a2SMark Phalan krb5_error_code KRB5_CALLCONV
krb5_init_random_key(krb5_context context,const krb5_encrypt_block * eblock,const krb5_keyblock * keyblock,krb5_pointer * ptr)134159d09a2SMark Phalan krb5_init_random_key(krb5_context context, const krb5_encrypt_block *eblock,
135159d09a2SMark Phalan 		     const krb5_keyblock *keyblock, krb5_pointer *ptr)
136159d09a2SMark Phalan {
137159d09a2SMark Phalan     krb5_data data;
138159d09a2SMark Phalan 
139159d09a2SMark Phalan     data.length = keyblock->length;
140159d09a2SMark Phalan     data.data = (char *) keyblock->contents;
141159d09a2SMark Phalan 
142159d09a2SMark Phalan     return(krb5_c_random_seed(context, &data));
143159d09a2SMark Phalan }
144159d09a2SMark Phalan 
145159d09a2SMark Phalan krb5_error_code KRB5_CALLCONV
krb5_finish_random_key(krb5_context context,const krb5_encrypt_block * eblock,krb5_pointer * ptr)146159d09a2SMark Phalan krb5_finish_random_key(krb5_context context, const krb5_encrypt_block *eblock,
147159d09a2SMark Phalan 		       krb5_pointer *ptr)
148159d09a2SMark Phalan {
149159d09a2SMark Phalan     return(0);
150159d09a2SMark Phalan }
151159d09a2SMark Phalan 
152159d09a2SMark Phalan krb5_error_code KRB5_CALLCONV
krb5_random_key(krb5_context context,const krb5_encrypt_block * eblock,krb5_pointer ptr,krb5_keyblock ** keyblock)153159d09a2SMark Phalan krb5_random_key(krb5_context context, const krb5_encrypt_block *eblock,
154159d09a2SMark Phalan 		krb5_pointer ptr, krb5_keyblock **keyblock)
155159d09a2SMark Phalan {
156159d09a2SMark Phalan     krb5_keyblock *key;
157159d09a2SMark Phalan     krb5_error_code ret;
158159d09a2SMark Phalan 
159159d09a2SMark Phalan     if ((key = (krb5_keyblock *) malloc(sizeof(krb5_keyblock))) == NULL)
160159d09a2SMark Phalan 	return(ENOMEM);
161159d09a2SMark Phalan 
162159d09a2SMark Phalan     if ((ret = krb5_c_make_random_key(context, eblock->crypto_entry, key)))
163159d09a2SMark Phalan 	free(key);
164159d09a2SMark Phalan 
165159d09a2SMark Phalan     *keyblock = key;
166159d09a2SMark Phalan 
167159d09a2SMark Phalan     return(ret);
168159d09a2SMark Phalan }
169159d09a2SMark Phalan 
170159d09a2SMark Phalan krb5_enctype KRB5_CALLCONV
krb5_eblock_enctype(krb5_context context,const krb5_encrypt_block * eblock)171159d09a2SMark Phalan krb5_eblock_enctype(krb5_context context, const krb5_encrypt_block *eblock)
172159d09a2SMark Phalan {
173159d09a2SMark Phalan     return(eblock->crypto_entry);
174159d09a2SMark Phalan }
175159d09a2SMark Phalan 
17610db1377Sgtb krb5_error_code KRB5_CALLCONV
krb5_use_enctype(krb5_context context,krb5_encrypt_block * eblock,krb5_enctype enctype)17710db1377Sgtb krb5_use_enctype(krb5_context context, krb5_encrypt_block *eblock,
178159d09a2SMark Phalan 		 krb5_enctype enctype)
17910db1377Sgtb {
18010db1377Sgtb     eblock->crypto_entry = enctype;
18110db1377Sgtb 
18210db1377Sgtb     return(0);
18310db1377Sgtb }
18410db1377Sgtb 
18510db1377Sgtb size_t KRB5_CALLCONV
krb5_encrypt_size(size_t length,krb5_enctype crypto)186159d09a2SMark Phalan krb5_encrypt_size(size_t length, krb5_enctype crypto)
18710db1377Sgtb {
188159d09a2SMark Phalan     size_t ret;
18910db1377Sgtb 
190159d09a2SMark Phalan     if (krb5_c_encrypt_length(/* XXX */ 0, crypto, length, &ret))
191159d09a2SMark Phalan 	return(-1); /* XXX */
19210db1377Sgtb 
193159d09a2SMark Phalan     return(ret);
19410db1377Sgtb }
195ab9b2e15Sgtb 
196ab9b2e15Sgtb size_t KRB5_CALLCONV
krb5_checksum_size(krb5_context context,krb5_cksumtype ctype)197159d09a2SMark Phalan krb5_checksum_size(krb5_context context, krb5_cksumtype ctype)
198ab9b2e15Sgtb {
199ab9b2e15Sgtb     size_t ret;
200ab9b2e15Sgtb 
201159d09a2SMark Phalan     if (krb5_c_checksum_length(context, ctype, &ret))
202159d09a2SMark Phalan 	return(-1); /* XXX */
203159d09a2SMark Phalan 
204159d09a2SMark Phalan     return(ret);
205159d09a2SMark Phalan }
206159d09a2SMark Phalan 
207159d09a2SMark Phalan krb5_error_code KRB5_CALLCONV
krb5_calculate_checksum(krb5_context context,krb5_cksumtype ctype,krb5_const_pointer in,size_t in_length,krb5_const_pointer seed,size_t seed_length,krb5_checksum * outcksum)208159d09a2SMark Phalan krb5_calculate_checksum(krb5_context context, krb5_cksumtype ctype,
209159d09a2SMark Phalan 			krb5_const_pointer in, size_t in_length,
210159d09a2SMark Phalan 			krb5_const_pointer seed, size_t seed_length,
211159d09a2SMark Phalan 			krb5_checksum *outcksum)
212159d09a2SMark Phalan {
213159d09a2SMark Phalan     krb5_data input;
214159d09a2SMark Phalan     krb5_keyblock key;
215159d09a2SMark Phalan     krb5_error_code ret;
216159d09a2SMark Phalan     krb5_checksum cksum;
217159d09a2SMark Phalan 
218159d09a2SMark Phalan     /* Solaris Kerberos */
219159d09a2SMark Phalan     input.data = (char*)in;
220159d09a2SMark Phalan     input.length = in_length;
221159d09a2SMark Phalan 
222159d09a2SMark Phalan     key.length = seed_length;
223159d09a2SMark Phalan     /* Solaris Kerberos */
224159d09a2SMark Phalan     key.contents = (unsigned char*)seed;
225159d09a2SMark Phalan 
226159d09a2SMark Phalan     if ((ret = krb5_c_make_checksum(context, ctype, &key, 0, &input, &cksum)))
227159d09a2SMark Phalan 	return(ret);
228159d09a2SMark Phalan 
229159d09a2SMark Phalan     if (outcksum->length < cksum.length) {
230159d09a2SMark Phalan 	memset(cksum.contents, 0, cksum.length);
231159d09a2SMark Phalan 	free(cksum.contents);
232159d09a2SMark Phalan 	return(KRB5_BAD_MSIZE);
233159d09a2SMark Phalan     }
234159d09a2SMark Phalan 
235159d09a2SMark Phalan     outcksum->magic = cksum.magic;
236159d09a2SMark Phalan     outcksum->checksum_type = cksum.checksum_type;
237159d09a2SMark Phalan     memcpy(outcksum->contents, cksum.contents, cksum.length);
238159d09a2SMark Phalan     outcksum->length = cksum.length;
239159d09a2SMark Phalan 
240159d09a2SMark Phalan     free(cksum.contents);
241*55fea89dSDan Cross 
242159d09a2SMark Phalan     return(0);
243159d09a2SMark Phalan }
244159d09a2SMark Phalan 
245159d09a2SMark Phalan krb5_error_code KRB5_CALLCONV
krb5_verify_checksum(krb5_context context,krb5_cksumtype ctype,const krb5_checksum * cksum,krb5_const_pointer in,size_t in_length,krb5_const_pointer seed,size_t seed_length)246159d09a2SMark Phalan krb5_verify_checksum(krb5_context context, krb5_cksumtype ctype,
247159d09a2SMark Phalan 		     const krb5_checksum *cksum, krb5_const_pointer in,
248159d09a2SMark Phalan 		     size_t in_length, krb5_const_pointer seed,
249159d09a2SMark Phalan 		     size_t seed_length)
250159d09a2SMark Phalan {
251159d09a2SMark Phalan     krb5_data input;
252159d09a2SMark Phalan     krb5_keyblock key;
253159d09a2SMark Phalan     krb5_error_code ret;
254159d09a2SMark Phalan     krb5_boolean valid;
255159d09a2SMark Phalan 
256159d09a2SMark Phalan     /* Solaris Kerberos */
257159d09a2SMark Phalan     input.data = (char*)in;
258159d09a2SMark Phalan     input.length = in_length;
259159d09a2SMark Phalan 
260159d09a2SMark Phalan     key.length = seed_length;
261159d09a2SMark Phalan     /* Solaris Kerberos */
262159d09a2SMark Phalan     key.contents = (unsigned char*)seed;
263159d09a2SMark Phalan 
264159d09a2SMark Phalan     if ((ret = krb5_c_verify_checksum(context, &key, 0, &input, cksum,
265159d09a2SMark Phalan 				      &valid)))
266159d09a2SMark Phalan 	return(ret);
267159d09a2SMark Phalan 
268159d09a2SMark Phalan     if (!valid)
269159d09a2SMark Phalan 	return(KRB5KRB_AP_ERR_BAD_INTEGRITY);
270159d09a2SMark Phalan 
271159d09a2SMark Phalan     return(0);
272159d09a2SMark Phalan }
273159d09a2SMark Phalan 
274159d09a2SMark Phalan krb5_error_code KRB5_CALLCONV
krb5_random_confounder(size_t size,krb5_pointer ptr)275159d09a2SMark Phalan krb5_random_confounder(size_t size, krb5_pointer ptr)
276159d09a2SMark Phalan {
277159d09a2SMark Phalan     krb5_data random_data;
278159d09a2SMark Phalan 
279159d09a2SMark Phalan     random_data.length = size;
280159d09a2SMark Phalan     random_data.data = ptr;
281159d09a2SMark Phalan 
282159d09a2SMark Phalan     return(krb5_c_random_make_octets(/* XXX */ 0, &random_data));
283159d09a2SMark Phalan }
284159d09a2SMark Phalan 
krb5_encrypt_data(krb5_context context,krb5_keyblock * key,krb5_pointer ivec,krb5_data * data,krb5_enc_data * enc_data)285159d09a2SMark Phalan krb5_error_code krb5_encrypt_data(krb5_context context, krb5_keyblock *key,
286159d09a2SMark Phalan 				  krb5_pointer ivec, krb5_data *data,
287159d09a2SMark Phalan 				  krb5_enc_data *enc_data)
288159d09a2SMark Phalan {
289159d09a2SMark Phalan     krb5_error_code ret;
290159d09a2SMark Phalan     size_t enclen, blocksize;
291159d09a2SMark Phalan     krb5_data ivecd;
292159d09a2SMark Phalan 
293159d09a2SMark Phalan     if ((ret = krb5_c_encrypt_length(context, key->enctype, data->length,
294159d09a2SMark Phalan 				     &enclen)))
295159d09a2SMark Phalan 	return(ret);
296159d09a2SMark Phalan 
297159d09a2SMark Phalan     if (ivec) {
298159d09a2SMark Phalan 	if ((ret = krb5_c_block_size(context, key->enctype, &blocksize)))
299159d09a2SMark Phalan 	    return(ret);
300159d09a2SMark Phalan 
301159d09a2SMark Phalan 	ivecd.length = blocksize;
302159d09a2SMark Phalan 	ivecd.data = ivec;
303159d09a2SMark Phalan     }
304159d09a2SMark Phalan 
305159d09a2SMark Phalan     enc_data->magic = KV5M_ENC_DATA;
306159d09a2SMark Phalan     enc_data->kvno = 0;
307159d09a2SMark Phalan     enc_data->enctype = key->enctype;
308159d09a2SMark Phalan     enc_data->ciphertext.length = enclen;
309159d09a2SMark Phalan     if ((enc_data->ciphertext.data = malloc(enclen)) == NULL)
310159d09a2SMark Phalan 	return(ENOMEM);
311159d09a2SMark Phalan 
312159d09a2SMark Phalan     if ((ret = krb5_c_encrypt(context, key, 0, ivec?&ivecd:0, data, enc_data)))
313159d09a2SMark Phalan 	free(enc_data->ciphertext.data);
314159d09a2SMark Phalan 
315159d09a2SMark Phalan     return(ret);
316159d09a2SMark Phalan }
317159d09a2SMark Phalan 
krb5_decrypt_data(krb5_context context,krb5_keyblock * key,krb5_pointer ivec,krb5_enc_data * enc_data,krb5_data * data)318159d09a2SMark Phalan krb5_error_code krb5_decrypt_data(krb5_context context, krb5_keyblock *key,
319159d09a2SMark Phalan 				  krb5_pointer ivec, krb5_enc_data *enc_data,
320159d09a2SMark Phalan 				  krb5_data *data)
321159d09a2SMark Phalan {
322159d09a2SMark Phalan     krb5_error_code ret;
323159d09a2SMark Phalan     krb5_data ivecd;
324159d09a2SMark Phalan     size_t blocksize;
325159d09a2SMark Phalan 
326159d09a2SMark Phalan     if (ivec) {
327159d09a2SMark Phalan 	if ((ret = krb5_c_block_size(context, key->enctype, &blocksize)))
328159d09a2SMark Phalan 	    return(ret);
329159d09a2SMark Phalan 
330159d09a2SMark Phalan 	ivecd.length = blocksize;
331159d09a2SMark Phalan 	ivecd.data = ivec;
332159d09a2SMark Phalan     }
333159d09a2SMark Phalan 
334159d09a2SMark Phalan     data->length = enc_data->ciphertext.length;
335159d09a2SMark Phalan     if ((data->data = (char *) malloc(data->length)) == NULL)
336159d09a2SMark Phalan 	return(ENOMEM);
337159d09a2SMark Phalan 
338159d09a2SMark Phalan     if ((ret = krb5_c_decrypt(context, key, 0, ivec?&ivecd:0, enc_data, data)))
339159d09a2SMark Phalan 	free(data->data);
340ab9b2e15Sgtb 
341159d09a2SMark Phalan     /* Solaris Kerberos */
342ab9b2e15Sgtb     return(ret);
343ab9b2e15Sgtb }
344