put reasonable SCCS headers on
[unix-history] / usr / src / usr.bin / rlogin / des_rw.c
CommitLineData
86dc635c 1/*-
ec5b20ff
KF
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
6d936b27 5 * %sccs.include.redist.c%
ec5b20ff
KF
6 */
7
ec5b20ff 8#ifndef lint
86dc635c 9static char sccsid[] = "@(#)des_rw.c 5.5 (Berkeley) %G%";
ec5b20ff
KF
10#endif /* not lint */
11
ec5b20ff 12#include <sys/param.h>
63fc53d2 13#include <kerberosIV/des.h>
4f10ae0d 14#include <kerberosIV/krb.h>
ec5b20ff
KF
15
16extern long random();
17static unsigned char des_inbuf[10240], storage[10240], *store_ptr;
18static bit_64 *key;
19static u_char *key_schedule;
20
21/*
22 * NB: These routines will not function properly if NBIO
23 * is set
24 */
25
26/*
27 * des_set_key
28 *
29 * Set des encryption/decryption key for use by the des_read and
30 * des_write routines
31 *
32 * The inkey parameter is actually the DES initial vector,
33 * and the insched is the DES Key unwrapped for faster decryption
34 */
35
36void
37des_set_key(inkey, insched)
38 bit_64 *inkey;
39 u_char *insched;
40{
41 key = inkey;
42 key_schedule = insched;
43}
44
45void
46des_clear_key()
47{
48 bzero((char *) key, sizeof(C_Block));
49 bzero((char *) key_schedule, sizeof(Key_schedule));
50}
51
52
53int
54des_read(fd, buf, len)
55 int fd;
56 register char *buf;
57 int len;
58{
59 int nreturned = 0;
60 long net_len, rd_len;
61 int nstored = 0;
62
63 if (nstored >= len) {
64 (void) bcopy(store_ptr, buf, len);
65 store_ptr += len;
66 nstored -= len;
67 return(len);
68 } else if (nstored) {
69 (void) bcopy(store_ptr, buf, nstored);
70 nreturned += nstored;
71 buf += nstored;
72 len -= nstored;
73 nstored = 0;
74 }
75
76 if (krb_net_read(fd, &net_len, sizeof(net_len)) != sizeof(net_len)) {
77 /* XXX can't read enough, pipe
78 must have closed */
79 return(0);
80 }
81 net_len = ntohl(net_len);
82 if (net_len <= 0 || net_len > sizeof(des_inbuf)) {
83 /* preposterous length; assume out-of-sync; only
84 recourse is to close connection, so return 0 */
85 return(0);
86 }
87 /* the writer tells us how much real data we are getting, but
88 we need to read the pad bytes (8-byte boundary) */
89 rd_len = roundup(net_len, 8);
90 if (krb_net_read(fd, des_inbuf, rd_len) != rd_len) {
91 /* pipe must have closed, return 0 */
92 return(0);
93 }
94 (void) des_pcbc_encrypt(des_inbuf, /* inbuf */
95 storage, /* outbuf */
96 net_len, /* length */
97 key_schedule, /* DES key */
98 key, /* IV */
99 DECRYPT); /* direction */
100
101 if(net_len < 8)
102 store_ptr = storage + 8 - net_len;
103 else
104 store_ptr = storage;
105
106 nstored = net_len;
107 if (nstored > len) {
108 (void) bcopy(store_ptr, buf, len);
109 nreturned += len;
110 store_ptr += len;
111 nstored -= len;
112 } else {
113 (void) bcopy(store_ptr, buf, nstored);
114 nreturned += nstored;
115 nstored = 0;
116 }
117
118 return(nreturned);
119}
120
121static unsigned char des_outbuf[10240]; /* > longest write */
122
123int
124des_write(fd, buf, len)
125 int fd;
126 char *buf;
127 int len;
128{
129 static int seeded = 0;
130 static char garbage_buf[8];
131 long net_len, garbage;
132
133 if(len < 8) {
134 if(!seeded) {
135 seeded = 1;
136 srandom((int) time((long *)0));
137 }
138 garbage = random();
139 /* insert random garbage */
140 (void) bcopy(&garbage, garbage_buf, MIN(sizeof(long),8));
141 /* this "right-justifies" the data in the buffer */
142 (void) bcopy(buf, garbage_buf + 8 - len, len);
143 }
144 /* pcbc_encrypt outputs in 8-byte (64 bit) increments */
145
146 (void) des_pcbc_encrypt((len < 8) ? garbage_buf : buf,
147 des_outbuf,
148 (len < 8) ? 8 : len,
149 key_schedule, /* DES key */
150 key, /* IV */
151 ENCRYPT);
152
153 /* tell the other end the real amount, but send an 8-byte padded
154 packet */
155 net_len = htonl(len);
156 (void) write(fd, &net_len, sizeof(net_len));
157 (void) write(fd, des_outbuf, roundup(len,8));
158 return(len);
159}