xref: /illumos-gate/usr/src/uts/common/gssapi/mechs/krb5/crypto/old/old_decrypt.c (revision 7c478bd95313f5f23a4c958a745db2134aa0324)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright 2001-2003 Sun Microsystems, Inc.  All rights reserved.
3*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate  */
5*7c478bd9Sstevel@tonic-gate 
6*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
7*7c478bd9Sstevel@tonic-gate 
8*7c478bd9Sstevel@tonic-gate /*
9*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1998 by the FundsXpress, INC.
10*7c478bd9Sstevel@tonic-gate  *
11*7c478bd9Sstevel@tonic-gate  * All rights reserved.
12*7c478bd9Sstevel@tonic-gate  *
13*7c478bd9Sstevel@tonic-gate  * Export of this software from the United States of America may require
14*7c478bd9Sstevel@tonic-gate  * a specific license from the United States Government.  It is the
15*7c478bd9Sstevel@tonic-gate  * responsibility of any person or organization contemplating export to
16*7c478bd9Sstevel@tonic-gate  * obtain such a license before exporting.
17*7c478bd9Sstevel@tonic-gate  *
18*7c478bd9Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
19*7c478bd9Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
20*7c478bd9Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
21*7c478bd9Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
22*7c478bd9Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
23*7c478bd9Sstevel@tonic-gate  * the name of FundsXpress. not be used in advertising or publicity pertaining
24*7c478bd9Sstevel@tonic-gate  * to distribution of the software without specific, written prior
25*7c478bd9Sstevel@tonic-gate  * permission.  FundsXpress makes no representations about the suitability of
26*7c478bd9Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
27*7c478bd9Sstevel@tonic-gate  * or implied warranty.
28*7c478bd9Sstevel@tonic-gate  *
29*7c478bd9Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
30*7c478bd9Sstevel@tonic-gate  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
31*7c478bd9Sstevel@tonic-gate  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32*7c478bd9Sstevel@tonic-gate  */
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate #include <k5-int.h>
35*7c478bd9Sstevel@tonic-gate #include <old.h>
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate #ifndef HAVE_MEMMOVE
38*7c478bd9Sstevel@tonic-gate #ifdef HAVE_BCOPY
39*7c478bd9Sstevel@tonic-gate #define memmove(dst,src,size) bcopy(src,dst,size)
40*7c478bd9Sstevel@tonic-gate #endif
41*7c478bd9Sstevel@tonic-gate #endif
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
44*7c478bd9Sstevel@tonic-gate krb5_error_code
45*7c478bd9Sstevel@tonic-gate krb5_old_decrypt(context, enc, hash, key, usage, ivec, input, arg_output)
46*7c478bd9Sstevel@tonic-gate      krb5_context context;
47*7c478bd9Sstevel@tonic-gate      krb5_const struct krb5_enc_provider *enc;
48*7c478bd9Sstevel@tonic-gate      krb5_const struct krb5_hash_provider *hash;
49*7c478bd9Sstevel@tonic-gate      krb5_const krb5_keyblock *key;
50*7c478bd9Sstevel@tonic-gate      krb5_keyusage usage;
51*7c478bd9Sstevel@tonic-gate      krb5_const krb5_data *ivec;
52*7c478bd9Sstevel@tonic-gate      krb5_const krb5_data *input;
53*7c478bd9Sstevel@tonic-gate      krb5_data *arg_output;
54*7c478bd9Sstevel@tonic-gate {
55*7c478bd9Sstevel@tonic-gate     krb5_error_code ret;
56*7c478bd9Sstevel@tonic-gate     size_t blocksize, hashsize, plainsize;
57*7c478bd9Sstevel@tonic-gate     unsigned char *cn;
58*7c478bd9Sstevel@tonic-gate     krb5_data output, cksum, crcivec;
59*7c478bd9Sstevel@tonic-gate     int alloced;
60*7c478bd9Sstevel@tonic-gate     unsigned char orig_cksum[128], new_cksum[128];
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate     (*(enc->block_size))(&blocksize);
63*7c478bd9Sstevel@tonic-gate     (*(hash->hash_size))(&hashsize);
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate     plainsize = input->length - blocksize - hashsize;
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate     if (arg_output->length < plainsize)
68*7c478bd9Sstevel@tonic-gate 	return(KRB5_BAD_MSIZE);
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate     if (arg_output->length < input->length) {
71*7c478bd9Sstevel@tonic-gate 	output.length = input->length;
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate 	if ((output.data = (char *) MALLOC(output.length)) == NULL) {
74*7c478bd9Sstevel@tonic-gate 	    return(ENOMEM);
75*7c478bd9Sstevel@tonic-gate 	}
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate 	alloced = 1;
78*7c478bd9Sstevel@tonic-gate     } else {
79*7c478bd9Sstevel@tonic-gate 	output.length = input->length;
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate 	output.data = arg_output->data;
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate 	alloced = 0;
84*7c478bd9Sstevel@tonic-gate     }
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate     /* decrypt it */
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate     /* save last ciphertext block in case we decrypt in place */
89*7c478bd9Sstevel@tonic-gate     if (ivec != NULL && ivec->length == blocksize) {
90*7c478bd9Sstevel@tonic-gate 	cn = MALLOC(blocksize);
91*7c478bd9Sstevel@tonic-gate 	if (cn == NULL) {
92*7c478bd9Sstevel@tonic-gate 	    ret = ENOMEM;
93*7c478bd9Sstevel@tonic-gate 	    goto cleanup;
94*7c478bd9Sstevel@tonic-gate 	}
95*7c478bd9Sstevel@tonic-gate 	(void) memcpy(cn, input->data + input->length - blocksize, blocksize);
96*7c478bd9Sstevel@tonic-gate     } else
97*7c478bd9Sstevel@tonic-gate 	cn = NULL;
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate     /* XXX this is gross, but I don't have much choice */
100*7c478bd9Sstevel@tonic-gate     if ((key->enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) {
101*7c478bd9Sstevel@tonic-gate 	crcivec.length = key->length;
102*7c478bd9Sstevel@tonic-gate 	crcivec.data = (char *) key->contents;
103*7c478bd9Sstevel@tonic-gate 	ivec = &crcivec;
104*7c478bd9Sstevel@tonic-gate     }
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate     if ((ret = ((*(enc->decrypt))(context, key, ivec, input, &output))))
107*7c478bd9Sstevel@tonic-gate 	goto cleanup;
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate     /* verify the checksum */
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate     (void) memcpy(orig_cksum, output.data+blocksize, hashsize);
112*7c478bd9Sstevel@tonic-gate     (void) memset(output.data+blocksize, 0, hashsize);
113*7c478bd9Sstevel@tonic-gate 
114*7c478bd9Sstevel@tonic-gate     cksum.length = hashsize;
115*7c478bd9Sstevel@tonic-gate     cksum.data = (char *)new_cksum;
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate     if ((ret = ((*(hash->hash))(context, 1, &output, &cksum))))
118*7c478bd9Sstevel@tonic-gate 	goto cleanup;
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate     if (memcmp(cksum.data, orig_cksum, cksum.length) != 0) {
121*7c478bd9Sstevel@tonic-gate 	ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
122*7c478bd9Sstevel@tonic-gate 	goto cleanup;
123*7c478bd9Sstevel@tonic-gate     }
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate     /* copy the plaintext around */
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate     if (alloced) {
128*7c478bd9Sstevel@tonic-gate 	(void) memcpy(arg_output->data, output.data+blocksize+hashsize,
129*7c478bd9Sstevel@tonic-gate 	       plainsize);
130*7c478bd9Sstevel@tonic-gate     } else {
131*7c478bd9Sstevel@tonic-gate 	(void) memmove(arg_output->data, arg_output->data+blocksize+hashsize,
132*7c478bd9Sstevel@tonic-gate 		plainsize);
133*7c478bd9Sstevel@tonic-gate     }
134*7c478bd9Sstevel@tonic-gate     arg_output->length = plainsize;
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate     /* update ivec */
137*7c478bd9Sstevel@tonic-gate     if (cn != NULL)
138*7c478bd9Sstevel@tonic-gate 	(void) memcpy(ivec->data, cn, blocksize);
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate     ret = 0;
141*7c478bd9Sstevel@tonic-gate 
142*7c478bd9Sstevel@tonic-gate cleanup:
143*7c478bd9Sstevel@tonic-gate     if (alloced) {
144*7c478bd9Sstevel@tonic-gate 	(void) memset(output.data, 0, output.length);
145*7c478bd9Sstevel@tonic-gate 	FREE(output.data, output.length);
146*7c478bd9Sstevel@tonic-gate     }
147*7c478bd9Sstevel@tonic-gate 
148*7c478bd9Sstevel@tonic-gate     if (cn != NULL)
149*7c478bd9Sstevel@tonic-gate 	FREE(cn, blocksize);
150*7c478bd9Sstevel@tonic-gate     (void) memset(new_cksum, 0, hashsize);
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate     return(ret);
153*7c478bd9Sstevel@tonic-gate }
154