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