Commit | Line | Data |
---|---|---|
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 | 9 | static 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 | |
16 | extern long random(); | |
17 | static unsigned char des_inbuf[10240], storage[10240], *store_ptr; | |
18 | static bit_64 *key; | |
19 | static 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 | ||
36 | void | |
37 | des_set_key(inkey, insched) | |
38 | bit_64 *inkey; | |
39 | u_char *insched; | |
40 | { | |
41 | key = inkey; | |
42 | key_schedule = insched; | |
43 | } | |
44 | ||
45 | void | |
46 | des_clear_key() | |
47 | { | |
48 | bzero((char *) key, sizeof(C_Block)); | |
49 | bzero((char *) key_schedule, sizeof(Key_schedule)); | |
50 | } | |
51 | ||
52 | ||
53 | int | |
54 | des_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 | ||
121 | static unsigned char des_outbuf[10240]; /* > longest write */ | |
122 | ||
123 | int | |
124 | des_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 | } |