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