xref: /illumos-gate/usr/src/uts/common/gssapi/mechs/krb5/crypto/old/old_decrypt.c (revision 505d05c73a6e56769f263d4803b22eddd168ee24)
17c478bd9Sstevel@tonic-gate /*
2*505d05c7Sgtb  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
77c478bd9Sstevel@tonic-gate 
87c478bd9Sstevel@tonic-gate /*
97c478bd9Sstevel@tonic-gate  * Copyright (C) 1998 by the FundsXpress, INC.
107c478bd9Sstevel@tonic-gate  *
117c478bd9Sstevel@tonic-gate  * All rights reserved.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * Export of this software from the United States of America may require
147c478bd9Sstevel@tonic-gate  * a specific license from the United States Government.  It is the
157c478bd9Sstevel@tonic-gate  * responsibility of any person or organization contemplating export to
167c478bd9Sstevel@tonic-gate  * obtain such a license before exporting.
177c478bd9Sstevel@tonic-gate  *
187c478bd9Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
197c478bd9Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
207c478bd9Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
217c478bd9Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
227c478bd9Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
237c478bd9Sstevel@tonic-gate  * the name of FundsXpress. not be used in advertising or publicity pertaining
247c478bd9Sstevel@tonic-gate  * to distribution of the software without specific, written prior
257c478bd9Sstevel@tonic-gate  * permission.  FundsXpress makes no representations about the suitability of
267c478bd9Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
277c478bd9Sstevel@tonic-gate  * or implied warranty.
287c478bd9Sstevel@tonic-gate  *
297c478bd9Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
307c478bd9Sstevel@tonic-gate  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
317c478bd9Sstevel@tonic-gate  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
327c478bd9Sstevel@tonic-gate  */
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #include <k5-int.h>
357c478bd9Sstevel@tonic-gate #include <old.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate /*ARGSUSED*/
387c478bd9Sstevel@tonic-gate krb5_error_code
39*505d05c7Sgtb krb5_old_decrypt(krb5_context context,
40*505d05c7Sgtb 		krb5_const struct krb5_enc_provider *enc,
41*505d05c7Sgtb 		krb5_const struct krb5_hash_provider *hash,
42*505d05c7Sgtb 		krb5_const krb5_keyblock *key,
43*505d05c7Sgtb 		krb5_keyusage usage,
44*505d05c7Sgtb 		krb5_const krb5_data *ivec,
45*505d05c7Sgtb 		krb5_const krb5_data *input,
46*505d05c7Sgtb 		krb5_data *arg_output)
477c478bd9Sstevel@tonic-gate {
487c478bd9Sstevel@tonic-gate     krb5_error_code ret;
497c478bd9Sstevel@tonic-gate     size_t blocksize, hashsize, plainsize;
507c478bd9Sstevel@tonic-gate     unsigned char *cn;
517c478bd9Sstevel@tonic-gate     krb5_data output, cksum, crcivec;
527c478bd9Sstevel@tonic-gate     int alloced;
537c478bd9Sstevel@tonic-gate     unsigned char orig_cksum[128], new_cksum[128];
547c478bd9Sstevel@tonic-gate 
55*505d05c7Sgtb 
56*505d05c7Sgtb     blocksize = enc->block_size;
57*505d05c7Sgtb     hashsize = hash->hashsize;
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate     plainsize = input->length - blocksize - hashsize;
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate     if (arg_output->length < plainsize)
627c478bd9Sstevel@tonic-gate 	return(KRB5_BAD_MSIZE);
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate     if (arg_output->length < input->length) {
657c478bd9Sstevel@tonic-gate 	output.length = input->length;
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate 	if ((output.data = (char *) MALLOC(output.length)) == NULL) {
687c478bd9Sstevel@tonic-gate 	    return(ENOMEM);
697c478bd9Sstevel@tonic-gate 	}
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate 	alloced = 1;
727c478bd9Sstevel@tonic-gate     } else {
737c478bd9Sstevel@tonic-gate 	output.length = input->length;
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	output.data = arg_output->data;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 	alloced = 0;
787c478bd9Sstevel@tonic-gate     }
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate     /* decrypt it */
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate     /* save last ciphertext block in case we decrypt in place */
837c478bd9Sstevel@tonic-gate     if (ivec != NULL && ivec->length == blocksize) {
847c478bd9Sstevel@tonic-gate 	cn = MALLOC(blocksize);
857c478bd9Sstevel@tonic-gate 	if (cn == NULL) {
867c478bd9Sstevel@tonic-gate 	    ret = ENOMEM;
877c478bd9Sstevel@tonic-gate 	    goto cleanup;
887c478bd9Sstevel@tonic-gate 	}
897c478bd9Sstevel@tonic-gate 	(void) memcpy(cn, input->data + input->length - blocksize, blocksize);
907c478bd9Sstevel@tonic-gate     } else
917c478bd9Sstevel@tonic-gate 	cn = NULL;
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate     /* XXX this is gross, but I don't have much choice */
947c478bd9Sstevel@tonic-gate     if ((key->enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) {
957c478bd9Sstevel@tonic-gate 	crcivec.length = key->length;
967c478bd9Sstevel@tonic-gate 	crcivec.data = (char *) key->contents;
977c478bd9Sstevel@tonic-gate 	ivec = &crcivec;
987c478bd9Sstevel@tonic-gate     }
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate     if ((ret = ((*(enc->decrypt))(context, key, ivec, input, &output))))
1017c478bd9Sstevel@tonic-gate 	goto cleanup;
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate     /* verify the checksum */
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate     (void) memcpy(orig_cksum, output.data+blocksize, hashsize);
1067c478bd9Sstevel@tonic-gate     (void) memset(output.data+blocksize, 0, hashsize);
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate     cksum.length = hashsize;
1097c478bd9Sstevel@tonic-gate     cksum.data = (char *)new_cksum;
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate     if ((ret = ((*(hash->hash))(context, 1, &output, &cksum))))
1127c478bd9Sstevel@tonic-gate 	goto cleanup;
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate     if (memcmp(cksum.data, orig_cksum, cksum.length) != 0) {
1157c478bd9Sstevel@tonic-gate 	ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
1167c478bd9Sstevel@tonic-gate 	goto cleanup;
1177c478bd9Sstevel@tonic-gate     }
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate     /* copy the plaintext around */
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate     if (alloced) {
1227c478bd9Sstevel@tonic-gate 	(void) memcpy(arg_output->data, output.data+blocksize+hashsize,
1237c478bd9Sstevel@tonic-gate 	       plainsize);
1247c478bd9Sstevel@tonic-gate     } else {
1257c478bd9Sstevel@tonic-gate 	(void) memmove(arg_output->data, arg_output->data+blocksize+hashsize,
1267c478bd9Sstevel@tonic-gate 		plainsize);
1277c478bd9Sstevel@tonic-gate     }
1287c478bd9Sstevel@tonic-gate     arg_output->length = plainsize;
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate     /* update ivec */
1317c478bd9Sstevel@tonic-gate     if (cn != NULL)
1327c478bd9Sstevel@tonic-gate 	(void) memcpy(ivec->data, cn, blocksize);
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate     ret = 0;
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate cleanup:
1377c478bd9Sstevel@tonic-gate     if (alloced) {
1387c478bd9Sstevel@tonic-gate 	(void) memset(output.data, 0, output.length);
1397c478bd9Sstevel@tonic-gate 	FREE(output.data, output.length);
1407c478bd9Sstevel@tonic-gate     }
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate     if (cn != NULL)
1437c478bd9Sstevel@tonic-gate 	FREE(cn, blocksize);
1447c478bd9Sstevel@tonic-gate     (void) memset(new_cksum, 0, hashsize);
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate     return(ret);
1477c478bd9Sstevel@tonic-gate }
148