xref: /freebsd/crypto/krb5/src/lib/crypto/krb/old_api_glue.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  * Copyright (C) 1998 by the FundsXpress, INC.
4  *
5  * All rights reserved.
6  *
7  * Export of this software from the United States of America may require
8  * a specific license from the United States Government.  It is the
9  * responsibility of any person or organization contemplating export to
10  * obtain such a license before exporting.
11  *
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of FundsXpress. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  FundsXpress makes no representations about the suitability of
20  * this software for any purpose.  It is provided "as is" without express
21  * or implied warranty.
22  *
23  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
25  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26  */
27 
28 #include "crypto_int.h"
29 
30 /*
31  * The following functions were removed from the API in krb5 1.3 but
32  * still need to be exported for ABI compatibility.  The other
33  * functions defined in this file are still in the API (and thus
34  * prototyped in krb5.hin) but are deprecated.
35  */
36 krb5_boolean KRB5_CALLCONV valid_enctype(krb5_enctype ktype);
37 krb5_boolean KRB5_CALLCONV valid_cksumtype(krb5_cksumtype ctype);
38 krb5_boolean KRB5_CALLCONV is_coll_proof_cksum(krb5_cksumtype ctype);
39 krb5_boolean KRB5_CALLCONV is_keyed_cksum(krb5_cksumtype ctype);
40 krb5_error_code KRB5_CALLCONV krb5_random_confounder(size_t, krb5_pointer);
41 krb5_error_code krb5_encrypt_data(krb5_context context, krb5_keyblock *key,
42                                   krb5_pointer ivec, krb5_data *data,
43                                   krb5_enc_data *enc_data);
44 krb5_error_code krb5_decrypt_data(krb5_context context, krb5_keyblock *key,
45                                   krb5_pointer ivec, krb5_enc_data *data,
46                                   krb5_data *enc_data);
47 
48 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)49 krb5_encrypt(krb5_context context, krb5_const_pointer inptr,
50              krb5_pointer outptr, size_t size, krb5_encrypt_block *eblock,
51              krb5_pointer ivec)
52 {
53     krb5_data inputd, ivecd;
54     krb5_enc_data outputd;
55     size_t blocksize, outlen;
56     krb5_error_code ret;
57 
58     if (ivec) {
59         ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize);
60         if (ret)
61             return ret;
62 
63         ivecd = make_data(ivec, blocksize);
64     }
65 
66     /* size is the length of the input cleartext data. */
67     inputd = make_data((void *) inptr, size);
68 
69     /*
70      * The size of the output buffer isn't part of the old api.  Not too
71      * safe.  So, we assume here that it's big enough.
72      */
73     ret = krb5_c_encrypt_length(context, eblock->key->enctype, size, &outlen);
74     if (ret)
75         return ret;
76 
77     outputd.ciphertext = make_data(outptr, outlen);
78 
79     return krb5_c_encrypt(context, eblock->key, 0, ivec ? &ivecd : 0,
80                           &inputd, &outputd);
81 }
82 
83 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)84 krb5_decrypt(krb5_context context, krb5_const_pointer inptr,
85              krb5_pointer outptr, size_t size, krb5_encrypt_block *eblock,
86              krb5_pointer ivec)
87 {
88     krb5_enc_data inputd;
89     krb5_data outputd, ivecd;
90     size_t blocksize;
91     krb5_error_code ret;
92 
93     if (ivec) {
94         ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize);
95         if (ret)
96             return ret;
97 
98         ivecd = make_data(ivec, blocksize);
99     }
100 
101     /* size is the length of the input ciphertext data */
102     inputd.enctype = eblock->key->enctype;
103     inputd.ciphertext = make_data((void *) inptr, size);
104 
105     /* we don't really know how big this is, but the code tends to assume
106        that the output buffer size should be the same as the input
107        buffer size */
108     outputd = make_data(outptr, size);
109 
110     return krb5_c_decrypt(context, eblock->key, 0, ivec ? &ivecd : 0,
111                           &inputd, &outputd);
112 }
113 
114 krb5_error_code KRB5_CALLCONV
krb5_process_key(krb5_context context,krb5_encrypt_block * eblock,const krb5_keyblock * key)115 krb5_process_key(krb5_context context, krb5_encrypt_block *eblock,
116                  const krb5_keyblock *key)
117 {
118     eblock->key = (krb5_keyblock *) key;
119 
120     return 0;
121 }
122 
123 krb5_error_code KRB5_CALLCONV
krb5_finish_key(krb5_context context,krb5_encrypt_block * eblock)124 krb5_finish_key(krb5_context context, krb5_encrypt_block *eblock)
125 {
126     return 0;
127 }
128 
129 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)130 krb5_string_to_key(krb5_context context, const krb5_encrypt_block *eblock,
131                    krb5_keyblock *keyblock, const krb5_data *data,
132                    const krb5_data *salt)
133 {
134     return krb5_c_string_to_key(context, eblock->crypto_entry, data, salt,
135                                 keyblock);
136 }
137 
138 krb5_error_code KRB5_CALLCONV
krb5_init_random_key(krb5_context context,const krb5_encrypt_block * eblock,const krb5_keyblock * keyblock,krb5_pointer * ptr)139 krb5_init_random_key(krb5_context context, const krb5_encrypt_block *eblock,
140                      const krb5_keyblock *keyblock, krb5_pointer *ptr)
141 {
142     krb5_data data = make_data(keyblock->contents, keyblock->length);
143 
144     return krb5_c_random_seed(context, &data);
145 }
146 
147 krb5_error_code KRB5_CALLCONV
krb5_finish_random_key(krb5_context context,const krb5_encrypt_block * eblock,krb5_pointer * ptr)148 krb5_finish_random_key(krb5_context context, const krb5_encrypt_block *eblock,
149                        krb5_pointer *ptr)
150 {
151     return 0;
152 }
153 
154 krb5_error_code KRB5_CALLCONV
krb5_random_key(krb5_context context,const krb5_encrypt_block * eblock,krb5_pointer ptr,krb5_keyblock ** keyblock)155 krb5_random_key(krb5_context context, const krb5_encrypt_block *eblock,
156                 krb5_pointer ptr, krb5_keyblock **keyblock)
157 {
158     krb5_keyblock *key;
159     krb5_error_code ret;
160 
161     *keyblock = NULL;
162 
163     key = malloc(sizeof(krb5_keyblock));
164     if (key == NULL)
165         return ENOMEM;
166 
167     ret = krb5_c_make_random_key(context, eblock->crypto_entry, key);
168     if (ret) {
169         free(key);
170         return ret;
171     }
172 
173     *keyblock = key;
174     return(ret);
175 }
176 
177 krb5_enctype KRB5_CALLCONV
krb5_eblock_enctype(krb5_context context,const krb5_encrypt_block * eblock)178 krb5_eblock_enctype(krb5_context context, const krb5_encrypt_block *eblock)
179 {
180     return eblock->crypto_entry;
181 }
182 
183 krb5_error_code KRB5_CALLCONV
krb5_use_enctype(krb5_context context,krb5_encrypt_block * eblock,krb5_enctype enctype)184 krb5_use_enctype(krb5_context context, krb5_encrypt_block *eblock,
185                  krb5_enctype enctype)
186 {
187     eblock->crypto_entry = enctype;
188 
189     return 0;
190 }
191 
192 size_t KRB5_CALLCONV
krb5_encrypt_size(size_t length,krb5_enctype crypto)193 krb5_encrypt_size(size_t length, krb5_enctype crypto)
194 {
195     size_t ret;
196 
197     if (krb5_c_encrypt_length(NULL, crypto, length, &ret))
198         return (size_t) -1; /* XXX */
199 
200     return ret;
201 }
202 
203 size_t KRB5_CALLCONV
krb5_checksum_size(krb5_context context,krb5_cksumtype ctype)204 krb5_checksum_size(krb5_context context, krb5_cksumtype ctype)
205 {
206     size_t ret;
207 
208     if (krb5_c_checksum_length(context, ctype, &ret))
209         return (size_t) -1; /* XXX */
210 
211     return ret;
212 }
213 
214 /* Guess the enctype for an untyped key used with checksum type ctype. */
215 static krb5_enctype
guess_enctype(krb5_cksumtype ctype)216 guess_enctype(krb5_cksumtype ctype)
217 {
218     const struct krb5_cksumtypes *ctp;
219     int i;
220 
221     if (ctype == CKSUMTYPE_HMAC_MD5_ARCFOUR)
222         return ENCTYPE_ARCFOUR_HMAC;
223     ctp = find_cksumtype(ctype);
224     if (ctp == NULL || ctp->enc == NULL)
225         return 0;
226     for (i = 0; i < krb5int_enctypes_length; i++) {
227         if (krb5int_enctypes_list[i].enc == ctp->enc)
228             return i;
229     }
230     return 0;
231 }
232 
233 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)234 krb5_calculate_checksum(krb5_context context, krb5_cksumtype ctype,
235                         krb5_const_pointer in, size_t in_length,
236                         krb5_const_pointer seed, size_t seed_length,
237                         krb5_checksum *outcksum)
238 {
239     krb5_data input = make_data((void *) in, in_length);
240     krb5_keyblock keyblock, *kptr = NULL;
241     krb5_error_code ret;
242     krb5_checksum cksum;
243 
244     if (seed != NULL) {
245         keyblock.enctype = guess_enctype(ctype);
246         keyblock.length = seed_length;
247         keyblock.contents = (unsigned char *) seed;
248         kptr = &keyblock;
249     }
250 
251     ret = krb5_c_make_checksum(context, ctype, kptr, 0, &input, &cksum);
252     if (ret)
253         return ret;
254 
255     if (outcksum->length < cksum.length) {
256         memset(cksum.contents, 0, cksum.length);
257         free(cksum.contents);
258         return KRB5_BAD_MSIZE;
259     }
260 
261     outcksum->magic = cksum.magic;
262     outcksum->checksum_type = cksum.checksum_type;
263     memcpy(outcksum->contents, cksum.contents, cksum.length);
264     outcksum->length = cksum.length;
265 
266     free(cksum.contents);
267 
268     return(0);
269 }
270 
271 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)272 krb5_verify_checksum(krb5_context context, krb5_cksumtype ctype,
273                      const krb5_checksum *cksum, krb5_const_pointer in,
274                      size_t in_length, krb5_const_pointer seed,
275                      size_t seed_length)
276 {
277     krb5_data input = make_data((void *) in, in_length);
278     krb5_keyblock keyblock, *kptr = NULL;
279     krb5_error_code ret;
280     krb5_boolean valid;
281 
282     if (seed != NULL) {
283         keyblock.enctype = guess_enctype(ctype);
284         keyblock.length = seed_length;
285         keyblock.contents = (unsigned char *) seed;
286         kptr = &keyblock;
287     }
288 
289     ret = krb5_c_verify_checksum(context, kptr, 0, &input, cksum, &valid);
290     if (ret)
291         return ret;
292 
293     if (!valid)
294         return KRB5KRB_AP_ERR_BAD_INTEGRITY;
295 
296     return 0;
297 }
298 
299 krb5_error_code KRB5_CALLCONV
krb5_random_confounder(size_t size,krb5_pointer ptr)300 krb5_random_confounder(size_t size, krb5_pointer ptr)
301 {
302     krb5_data random_data = make_data(ptr, size);
303 
304     return krb5_c_random_make_octets(NULL, &random_data);
305 }
306 
krb5_encrypt_data(krb5_context context,krb5_keyblock * key,krb5_pointer ivec,krb5_data * data,krb5_enc_data * enc_data)307 krb5_error_code krb5_encrypt_data(krb5_context context, krb5_keyblock *key,
308                                   krb5_pointer ivec, krb5_data *data,
309                                   krb5_enc_data *enc_data)
310 {
311     krb5_error_code ret;
312     size_t enclen, blocksize;
313     krb5_data ivecd;
314 
315     ret = krb5_c_encrypt_length(context, key->enctype, data->length, &enclen);
316     if (ret)
317         return ret;
318 
319     if (ivec) {
320         ret = krb5_c_block_size(context, key->enctype, &blocksize);
321         if (ret)
322             return ret;
323 
324         ivecd = make_data(ivec, blocksize);
325     }
326 
327     enc_data->magic = KV5M_ENC_DATA;
328     enc_data->kvno = 0;
329     enc_data->enctype = key->enctype;
330     ret = alloc_data(&enc_data->ciphertext, enclen);
331     if (ret)
332         return ret;
333 
334     ret = krb5_c_encrypt(context, key, 0, ivec ? &ivecd : 0, data, enc_data);
335     if (ret)
336         free(enc_data->ciphertext.data);
337 
338     return ret;
339 }
340 
krb5_decrypt_data(krb5_context context,krb5_keyblock * key,krb5_pointer ivec,krb5_enc_data * enc_data,krb5_data * data)341 krb5_error_code krb5_decrypt_data(krb5_context context, krb5_keyblock *key,
342                                   krb5_pointer ivec, krb5_enc_data *enc_data,
343                                   krb5_data *data)
344 {
345     krb5_error_code ret;
346     krb5_data ivecd;
347     size_t blocksize;
348 
349     if (ivec) {
350         ret = krb5_c_block_size(context, key->enctype, &blocksize);
351         if (ret)
352             return ret;
353 
354         ivecd = make_data(ivec, blocksize);
355     }
356 
357     ret = alloc_data(data, enc_data->ciphertext.length);
358     if (ret)
359         return ret;
360 
361     ret = krb5_c_decrypt(context, key, 0, ivec ? &ivecd : 0, enc_data, data);
362     if (ret)
363         free(data->data);
364 
365     return 0;
366 }
367 
368 krb5_boolean KRB5_CALLCONV
valid_cksumtype(krb5_cksumtype ctype)369 valid_cksumtype(krb5_cksumtype ctype)
370 {
371     return krb5_c_valid_cksumtype(ctype);
372 }
373 
374 krb5_boolean KRB5_CALLCONV
is_keyed_cksum(krb5_cksumtype ctype)375 is_keyed_cksum(krb5_cksumtype ctype)
376 {
377     return krb5_c_is_keyed_cksum(ctype);
378 }
379 
380 krb5_boolean KRB5_CALLCONV
is_coll_proof_cksum(krb5_cksumtype ctype)381 is_coll_proof_cksum(krb5_cksumtype ctype)
382 {
383     return krb5_c_is_coll_proof_cksum(ctype);
384 }
385 
386 krb5_boolean KRB5_CALLCONV
valid_enctype(krb5_enctype etype)387 valid_enctype(krb5_enctype etype)
388 {
389     return krb5_c_valid_enctype(etype);
390 }
391