checked in for Kevin Fall
[unix-history] / usr / src / usr.bin / rlogin / des_rw.c
CommitLineData
ec5b20ff
KF
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 */
17
18
19/*
20 * $Source:$
21 * $Header:$
22 */
23
24
25#ifndef lint
26static char sccsid[] = "@(#)des_rw.c 1.7 (Berkeley) 2/6/89";
27#endif /* not lint */
28
ec5b20ff 29#include <sys/param.h>
63fc53d2
KB
30#include <kerberosIV/krb.h>
31#include <kerberosIV/des.h>
ec5b20ff
KF
32
33extern long random();
34static unsigned char des_inbuf[10240], storage[10240], *store_ptr;
35static bit_64 *key;
36static u_char *key_schedule;
37
38/*
39 * NB: These routines will not function properly if NBIO
40 * is set
41 */
42
43/*
44 * des_set_key
45 *
46 * Set des encryption/decryption key for use by the des_read and
47 * des_write routines
48 *
49 * The inkey parameter is actually the DES initial vector,
50 * and the insched is the DES Key unwrapped for faster decryption
51 */
52
53void
54des_set_key(inkey, insched)
55 bit_64 *inkey;
56 u_char *insched;
57{
58 key = inkey;
59 key_schedule = insched;
60}
61
62void
63des_clear_key()
64{
65 bzero((char *) key, sizeof(C_Block));
66 bzero((char *) key_schedule, sizeof(Key_schedule));
67}
68
69
70int
71des_read(fd, buf, len)
72 int fd;
73 register char *buf;
74 int len;
75{
76 int nreturned = 0;
77 long net_len, rd_len;
78 int nstored = 0;
79
80 if (nstored >= len) {
81 (void) bcopy(store_ptr, buf, len);
82 store_ptr += len;
83 nstored -= len;
84 return(len);
85 } else if (nstored) {
86 (void) bcopy(store_ptr, buf, nstored);
87 nreturned += nstored;
88 buf += nstored;
89 len -= nstored;
90 nstored = 0;
91 }
92
93 if (krb_net_read(fd, &net_len, sizeof(net_len)) != sizeof(net_len)) {
94 /* XXX can't read enough, pipe
95 must have closed */
96 return(0);
97 }
98 net_len = ntohl(net_len);
99 if (net_len <= 0 || net_len > sizeof(des_inbuf)) {
100 /* preposterous length; assume out-of-sync; only
101 recourse is to close connection, so return 0 */
102 return(0);
103 }
104 /* the writer tells us how much real data we are getting, but
105 we need to read the pad bytes (8-byte boundary) */
106 rd_len = roundup(net_len, 8);
107 if (krb_net_read(fd, des_inbuf, rd_len) != rd_len) {
108 /* pipe must have closed, return 0 */
109 return(0);
110 }
111 (void) des_pcbc_encrypt(des_inbuf, /* inbuf */
112 storage, /* outbuf */
113 net_len, /* length */
114 key_schedule, /* DES key */
115 key, /* IV */
116 DECRYPT); /* direction */
117
118 if(net_len < 8)
119 store_ptr = storage + 8 - net_len;
120 else
121 store_ptr = storage;
122
123 nstored = net_len;
124 if (nstored > len) {
125 (void) bcopy(store_ptr, buf, len);
126 nreturned += len;
127 store_ptr += len;
128 nstored -= len;
129 } else {
130 (void) bcopy(store_ptr, buf, nstored);
131 nreturned += nstored;
132 nstored = 0;
133 }
134
135 return(nreturned);
136}
137
138static unsigned char des_outbuf[10240]; /* > longest write */
139
140int
141des_write(fd, buf, len)
142 int fd;
143 char *buf;
144 int len;
145{
146 static int seeded = 0;
147 static char garbage_buf[8];
148 long net_len, garbage;
149
150 if(len < 8) {
151 if(!seeded) {
152 seeded = 1;
153 srandom((int) time((long *)0));
154 }
155 garbage = random();
156 /* insert random garbage */
157 (void) bcopy(&garbage, garbage_buf, MIN(sizeof(long),8));
158 /* this "right-justifies" the data in the buffer */
159 (void) bcopy(buf, garbage_buf + 8 - len, len);
160 }
161 /* pcbc_encrypt outputs in 8-byte (64 bit) increments */
162
163 (void) des_pcbc_encrypt((len < 8) ? garbage_buf : buf,
164 des_outbuf,
165 (len < 8) ? 8 : len,
166 key_schedule, /* DES key */
167 key, /* IV */
168 ENCRYPT);
169
170 /* tell the other end the real amount, but send an 8-byte padded
171 packet */
172 net_len = htonl(len);
173 (void) write(fd, &net_len, sizeof(net_len));
174 (void) write(fd, des_outbuf, roundup(len,8));
175 return(len);
176}