POSIX signals
[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
29#include <sys/types.h>
30#include <sys/param.h>
31#include <krb.h>
32#include <des.h>
33
34extern long random();
35static unsigned char des_inbuf[10240], storage[10240], *store_ptr;
36static bit_64 *key;
37static u_char *key_schedule;
38
39/*
40 * NB: These routines will not function properly if NBIO
41 * is set
42 */
43
44/*
45 * des_set_key
46 *
47 * Set des encryption/decryption key for use by the des_read and
48 * des_write routines
49 *
50 * The inkey parameter is actually the DES initial vector,
51 * and the insched is the DES Key unwrapped for faster decryption
52 */
53
54void
55des_set_key(inkey, insched)
56 bit_64 *inkey;
57 u_char *insched;
58{
59 key = inkey;
60 key_schedule = insched;
61}
62
63void
64des_clear_key()
65{
66 bzero((char *) key, sizeof(C_Block));
67 bzero((char *) key_schedule, sizeof(Key_schedule));
68}
69
70
71int
72des_read(fd, buf, len)
73 int fd;
74 register char *buf;
75 int len;
76{
77 int nreturned = 0;
78 long net_len, rd_len;
79 int nstored = 0;
80
81 if (nstored >= len) {
82 (void) bcopy(store_ptr, buf, len);
83 store_ptr += len;
84 nstored -= len;
85 return(len);
86 } else if (nstored) {
87 (void) bcopy(store_ptr, buf, nstored);
88 nreturned += nstored;
89 buf += nstored;
90 len -= nstored;
91 nstored = 0;
92 }
93
94 if (krb_net_read(fd, &net_len, sizeof(net_len)) != sizeof(net_len)) {
95 /* XXX can't read enough, pipe
96 must have closed */
97 return(0);
98 }
99 net_len = ntohl(net_len);
100 if (net_len <= 0 || net_len > sizeof(des_inbuf)) {
101 /* preposterous length; assume out-of-sync; only
102 recourse is to close connection, so return 0 */
103 return(0);
104 }
105 /* the writer tells us how much real data we are getting, but
106 we need to read the pad bytes (8-byte boundary) */
107 rd_len = roundup(net_len, 8);
108 if (krb_net_read(fd, des_inbuf, rd_len) != rd_len) {
109 /* pipe must have closed, return 0 */
110 return(0);
111 }
112 (void) des_pcbc_encrypt(des_inbuf, /* inbuf */
113 storage, /* outbuf */
114 net_len, /* length */
115 key_schedule, /* DES key */
116 key, /* IV */
117 DECRYPT); /* direction */
118
119 if(net_len < 8)
120 store_ptr = storage + 8 - net_len;
121 else
122 store_ptr = storage;
123
124 nstored = net_len;
125 if (nstored > len) {
126 (void) bcopy(store_ptr, buf, len);
127 nreturned += len;
128 store_ptr += len;
129 nstored -= len;
130 } else {
131 (void) bcopy(store_ptr, buf, nstored);
132 nreturned += nstored;
133 nstored = 0;
134 }
135
136 return(nreturned);
137}
138
139static unsigned char des_outbuf[10240]; /* > longest write */
140
141int
142des_write(fd, buf, len)
143 int fd;
144 char *buf;
145 int len;
146{
147 static int seeded = 0;
148 static char garbage_buf[8];
149 long net_len, garbage;
150
151 if(len < 8) {
152 if(!seeded) {
153 seeded = 1;
154 srandom((int) time((long *)0));
155 }
156 garbage = random();
157 /* insert random garbage */
158 (void) bcopy(&garbage, garbage_buf, MIN(sizeof(long),8));
159 /* this "right-justifies" the data in the buffer */
160 (void) bcopy(buf, garbage_buf + 8 - len, len);
161 }
162 /* pcbc_encrypt outputs in 8-byte (64 bit) increments */
163
164 (void) des_pcbc_encrypt((len < 8) ? garbage_buf : buf,
165 des_outbuf,
166 (len < 8) ? 8 : len,
167 key_schedule, /* DES key */
168 key, /* IV */
169 ENCRYPT);
170
171 /* tell the other end the real amount, but send an 8-byte padded
172 packet */
173 net_len = htonl(len);
174 (void) write(fd, &net_len, sizeof(net_len));
175 (void) write(fd, des_outbuf, roundup(len,8));
176 return(len);
177}