1/* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights 7 * Reserved. This file contains Original Code and/or Modifications of 8 * Original Code as defined in and that are subject to the Apple Public 9 * Source License Version 1.0 (the 'License'). You may not use this file 10 * except in compliance with the License. Please obtain a copy of the 11 * License at http://www.apple.com/publicsource and read it before using 12 * this file. 13 * 14 * The Original Code and all software distributed under the License are 15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 19 * License for the specific language governing rights and limitations 20 * under the License." 21 * 22 * @APPLE_LICENSE_HEADER_END@ 23 */ 24/*- 25 * Copyright (c) 1989, 1993 26 * The Regents of the University of California. All rights reserved. 27 * 28 * Redistribution and use in source and binary forms, with or without 29 * modification, are permitted provided that the following conditions 30 * are met: 31 * 1. Redistributions of source code must retain the above copyright 32 * notice, this list of conditions and the following disclaimer. 33 * 2. Redistributions in binary form must reproduce the above copyright 34 * notice, this list of conditions and the following disclaimer in the 35 * documentation and/or other materials provided with the distribution. 36 * 3. All advertising materials mentioning features or use of this software 37 * must display the following acknowledgement: 38 * This product includes software developed by the University of 39 * California, Berkeley and its contributors. 40 * 4. Neither the name of the University nor the names of its contributors 41 * may be used to endorse or promote products derived from this software 42 * without specific prior written permission. 43 * 44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 54 * SUCH DAMAGE. 55 */ 56 57#include <sys/cdefs.h> 58#ifndef lint 59__unused static char sccsid[] = "@(#)des_rw.c 8.1 (Berkeley) 6/6/93"; 60#endif /* not lint */ 61 62#ifdef CRYPT 63#ifdef KERBEROS 64#include <sys/param.h> 65 66#include <kerberosIV/des.h> 67#include <kerberosIV/krb.h> 68 69#include <stdlib.h> 70#include <string.h> 71#include <time.h> 72#include <unistd.h> 73 74static unsigned char des_inbuf[10240], storage[10240], *store_ptr; 75static bit_64 *key; 76static u_char *key_schedule; 77 78/* XXX these should be in a kerberos include file */ 79int krb_net_read __P((int, char *, int)); 80#ifdef notdef 81/* XXX too hard to make this work */ 82int des_pcbc_encrypt __P((des_cblock *, des_cblock *, long, 83 des_key_schedule, des_cblock *, int)); 84#endif 85 86/* 87 * NB: These routines will not function properly if NBIO 88 * is set 89 */ 90 91/* 92 * des_set_key 93 * 94 * Set des encryption/decryption key for use by the des_read and 95 * des_write routines 96 * 97 * The inkey parameter is actually the DES initial vector, 98 * and the insched is the DES Key unwrapped for faster decryption 99 */ 100 101void 102des_set_key(inkey, insched) 103 bit_64 *inkey; 104 u_char *insched; 105{ 106 key = inkey; 107 key_schedule = insched; 108} 109 110void 111des_clear_key() 112{ 113 bzero((char *) key, sizeof(C_Block)); 114 bzero((char *) key_schedule, sizeof(Key_schedule)); 115} 116 117 118int 119des_read(fd, buf, len) 120 int fd; 121 register char *buf; 122 int len; 123{ 124 int nreturned = 0; 125 long net_len, rd_len; 126 int nstored = 0; 127 128 if (nstored >= len) { 129 (void) bcopy(store_ptr, buf, len); 130 store_ptr += len; 131 nstored -= len; 132 return(len); 133 } else if (nstored) { 134 (void) bcopy(store_ptr, buf, nstored); 135 nreturned += nstored; 136 buf += nstored; 137 len -= nstored; 138 nstored = 0; 139 } 140 141 if (krb_net_read(fd, (char *)&net_len, sizeof(net_len)) != 142 sizeof(net_len)) { 143 /* XXX can't read enough, pipe 144 must have closed */ 145 return(0); 146 } 147 net_len = ntohl(net_len); 148 if (net_len <= 0 || net_len > sizeof(des_inbuf)) { 149 /* preposterous length; assume out-of-sync; only 150 recourse is to close connection, so return 0 */ 151 return(0); 152 } 153 /* the writer tells us how much real data we are getting, but 154 we need to read the pad bytes (8-byte boundary) */ 155 rd_len = roundup(net_len, 8); 156 if (krb_net_read(fd, (char *)des_inbuf, rd_len) != rd_len) { 157 /* pipe must have closed, return 0 */ 158 return(0); 159 } 160 (void) des_pcbc_encrypt(des_inbuf, /* inbuf */ 161 storage, /* outbuf */ 162 net_len, /* length */ 163 key_schedule, /* DES key */ 164 key, /* IV */ 165 DECRYPT); /* direction */ 166 167 if(net_len < 8) 168 store_ptr = storage + 8 - net_len; 169 else 170 store_ptr = storage; 171 172 nstored = net_len; 173 if (nstored > len) { 174 (void) bcopy(store_ptr, buf, len); 175 nreturned += len; 176 store_ptr += len; 177 nstored -= len; 178 } else { 179 (void) bcopy(store_ptr, buf, nstored); 180 nreturned += nstored; 181 nstored = 0; 182 } 183 184 return(nreturned); 185} 186 187static unsigned char des_outbuf[10240]; /* > longest write */ 188 189int 190des_write(fd, buf, len) 191 int fd; 192 char *buf; 193 int len; 194{ 195 static int seeded = 0; 196 static char garbage_buf[8]; 197 long net_len, garbage; 198 199 if(len < 8) { 200 if(!seeded) { 201 seeded = 1; 202 srandom((int) time((long *)0)); 203 } 204 garbage = random(); 205 /* insert random garbage */ 206 (void) bcopy(&garbage, garbage_buf, MIN(sizeof(long),8)); 207 /* this "right-justifies" the data in the buffer */ 208 (void) bcopy(buf, garbage_buf + 8 - len, len); 209 } 210 /* pcbc_encrypt outputs in 8-byte (64 bit) increments */ 211 212 (void) des_pcbc_encrypt((len < 8) ? garbage_buf : buf, 213 des_outbuf, 214 (len < 8) ? 8 : len, 215 key_schedule, /* DES key */ 216 key, /* IV */ 217 ENCRYPT); 218 219 /* tell the other end the real amount, but send an 8-byte padded 220 packet */ 221 net_len = htonl(len); 222 (void) write(fd, &net_len, sizeof(net_len)); 223 (void) write(fd, des_outbuf, roundup(len,8)); 224 return(len); 225} 226#endif /* KERBEROS */ 227#endif /* CRYPT */ 228