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