Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libkstream Cygnus's libkstream, from cryptosrc-us.
details: https://anonhg.NetBSD.org/src/rev/8793be4ec1f2
branches: trunk
changeset: 488052:8793be4ec1f2
user: thorpej <thorpej%NetBSD.org@localhost>
date: Sat Jun 17 06:24:28 2000 +0000
description:
Cygnus's libkstream, from cryptosrc-us.
diffstat:
lib/libkstream/Makefile | 12 +
lib/libkstream/kstream-des.c | 339 ++++++++++++++++++++++++++++++++++++++
lib/libkstream/kstream.c | 377 +++++++++++++++++++++++++++++++++++++++++++
lib/libkstream/kstream.h | 100 +++++++++++
4 files changed, 828 insertions(+), 0 deletions(-)
diffs (truncated from 844 to 300 lines):
diff -r ef205e186613 -r 8793be4ec1f2 lib/libkstream/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libkstream/Makefile Sat Jun 17 06:24:28 2000 +0000
@@ -0,0 +1,12 @@
+# $NetBSD: Makefile,v 1.1.1.1 2000/06/17 06:24:28 thorpej Exp $
+
+LIB= kstream
+
+SRCS= kstream.c kstream-des.c
+
+COPTS+= -g
+
+SHLIB_MAJOR?= 1
+SHLIB_MINOR?= 0
+
+.include <bsd.lib.mk>
diff -r ef205e186613 -r 8793be4ec1f2 lib/libkstream/kstream-des.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libkstream/kstream-des.c Sat Jun 17 06:24:28 2000 +0000
@@ -0,0 +1,339 @@
+/* $NetBSD: kstream-des.c,v 1.1.1.1 2000/06/17 06:24:28 thorpej Exp $ */
+
+/* DES-encrypted-stream implementation for MIT Kerberos.
+ Written by Ken Raeburn (Raeburn%Cygnus.COM@localhost), based on algorithms
+ in the original MIT Kerberos code.
+ Copyright (C) 1991, 1992 by Cygnus Support.
+
+ This file is distributed under the same terms as Kerberos.
+ For copying and distribution information, please see the file
+ <kerberosIV/mit-copyright.h>.
+
+ from: kstream-des.c,v 1.9 1996/06/02 07:37:27 ghudson Exp $
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <des.h>
+#include <kerberosIV/kstream.h>
+
+typedef struct {
+ union {
+ long align_me;
+ double align_me_harder;
+ Key_schedule sched;
+ } u;
+ des_cblock ivec;
+} kstream_des_init_block;
+
+typedef struct {
+ kstream_des_init_block x;
+ int no_right_justify;
+ int protect_rlogin_oob;
+ char *buf1, *buf2;
+ size_t len1, len2;
+} priv;
+
+typedef struct kstream_data_block ksdb;
+
+/* The data stream consists of four bytes representing a net-order
+ integer, followed by enough data to produce that many
+ cleartext bytes. This means the size of that data must be rounded
+ up to a multiple of 8, even though the cleartext may only be one
+ byte. For blocks of less than eight bytes, most software (well,
+ exactly half of the two already-existing programs, and all of the
+ ones we write using this library :-) pads on the *left* with
+ random values.
+
+ Some existing software that we have to be compatible with may send
+ blocks of data that decrypt to more than 8 bytes, but not an exact
+ multiple. In that case, the padding is on the right, as would be
+ considered "normal". This software currently will not generate such
+ a sequence, but a future version could. Don't break compatibility
+ with that mode. */
+
+#ifdef sun
+static kstream_ptr losing_realloc (old_ptr, new_size)
+ kstream_ptr old_ptr;
+ size_t new_size;
+{
+ return old_ptr ? realloc (old_ptr, new_size) : malloc (new_size);
+}
+#define realloc losing_realloc
+#endif
+
+/* Do the actual encryption work. This routine will handle chunks of
+ any size up to 16 bytes, or any multiple of 8 over that. It makes
+ the padding a little easier to write it this way. Handling sizes
+ between 8 and 16 is an annoyance, but rlogin actually relies on being
+ able to send 12 bytes in one chunk. Bleah! */
+static void
+do_encrypt (out, inp, p)
+ ksdb *out;
+ ksdb *inp;
+ priv *p;
+{
+ union {
+ char buf[16];
+ int junk[16 / sizeof (int)];
+ } u;
+ ksdb in;
+ char *ptr;
+ static int seeded;
+
+ if (!seeded) {
+ srandom ((int) time ((time_t *) 0));
+ seeded = 1;
+ }
+
+ in = *inp;
+ if (in.length < 8)
+ {
+ if (! p->no_right_justify)
+ {
+ u.junk[0] = random ();
+ memcpy (u.buf + 8 - in.length, in.ptr, in.length);
+ }
+ else
+ {
+ u.junk[(sizeof (u.junk[0]) + 7) / sizeof (u.junk[0]) - 1] = random ();
+ memcpy (u.buf, in.ptr, in.length);
+ }
+ in.ptr = u.buf;
+ in.length = 8;
+ }
+ else if (in.length == 8)
+ {
+ memcpy (u.buf, in.ptr, 8);
+ in.ptr = u.buf;
+ }
+ else if (in.length < sizeof (u.buf))
+ {
+ if (in.length % 8 == 0)
+ abort ();
+ u.junk[(sizeof (u.junk) / sizeof (u.junk[0])) - 1] = random ();
+ memcpy (u.buf, in.ptr, in.length);
+ in.ptr = u.buf;
+ }
+ else if (in.length % 8 != 0)
+ abort ();
+ {
+ unsigned long x;
+ x = inp->length; /* not in.length! */
+ ptr = (char *) out->ptr;
+ ptr[3] = x & 0xff; x >>= 8;
+ ptr[2] = x & 0xff; x >>= 8;
+ ptr[1] = x & 0xff; x >>= 8;
+ ptr[0] = x & 0xff; x >>= 8;
+ ptr += 4;
+ if (x)
+ abort ();
+ }
+ des_pcbc_encrypt ((des_cblock *)in.ptr, (des_cblock *)ptr, in.length,
+ p->x.u.sched, (des_cblock *)p->x.ivec, ENCRYPT);
+ out->ptr = ptr + ((in.length + 7) & ~7);
+}
+
+static int
+encrypt (outp, inp, k)
+ ksdb *outp;
+ ksdb *inp;
+ kstream k;
+{
+ const int small_block_size = 16;
+ priv *p = (priv *) k->data;
+
+ if (inp->length > small_block_size && inp->length % 8 != 0)
+ {
+ /* do two */
+ ksdb in, out;
+ size_t sz;
+
+ in.ptr = inp->ptr;
+ in.length = inp->length & ~7;
+ sz = in.length + 4; /* first block */
+ sz += 8 + 4; /* second block */
+ outp->length = sz;
+ out.ptr = outp->ptr = p->buf1 = realloc (p->buf1, sz);
+ out.length = sz;
+ assert (out.ptr != 0 || out.length == 0);
+ do_encrypt (&out, &in, p);
+ in.ptr = (char *) in.ptr + in.length;
+ in.length = inp->length - in.length;
+ do_encrypt (&out, &in, p);
+ return inp->length;
+ }
+ else
+ {
+ size_t sz = (inp->length + 7) & ~7;
+ sz += 4;
+ outp->length = sz;
+ outp->ptr = p->buf1 = realloc (p->buf1, sz);
+ assert (outp->ptr != 0 || outp->length == 0);
+ do_encrypt (outp, inp, p);
+ outp->ptr = p->buf1;
+ return inp->length;
+ }
+}
+
+int _kstream_des_debug_OOB = 0;
+
+static int
+decrypt (outp, inp, k)
+ ksdb *outp;
+ ksdb *inp;
+ kstream k;
+{
+ char *ptr = inp->ptr;
+ unsigned long x = 0;
+ int error_count = 0;
+ size_t sz;
+ priv *p = (priv *) k->data;
+
+ if(inp->length < 1) return -12; /* make sure we have at least one byte */
+ if (p->protect_rlogin_oob) {
+ /* here's where we handle an attack. The first byte ends up being the
+ highest. If it's not zero, skip it. If it is zero, we can't detect it,
+ and we still lose... */
+ x = *ptr & 0xff; /* get the first char */
+ while (x) {
+ if(_kstream_des_debug_OOB) fprintf(stderr,"BAD BYTE %02x\n\r", x);
+ error_count++; /* count the bad byte */
+ ptr++; /* and skip it */
+ if(inp->length == error_count) {
+ return -12; /* we've used up all of the input */
+ }
+ x = *ptr & 0xff; /* get the next potentially first char */
+ }
+ ptr++;
+ } else {
+ x <<= 8; x += *ptr++ & 0xff;
+ }
+
+
+ /* If we've got four bytes, we can at least determine the correct
+ amount that still needs to be read. If not, we can assume a
+ minimum of 12 good bytes (4-byte length plus one 8-byte block)
+ and we know how many of the ones we've got are bad. */
+ if (inp->length < 4 + error_count)
+ return inp->length - error_count - 12;
+
+/* x <<= 8; x += *ptr++ & 0xff; */ /* x already has first byte loaded */
+ x <<= 8; x += *ptr++ & 0xff;
+ x <<= 8; x += *ptr++ & 0xff;
+ x <<= 8; x += *ptr++ & 0xff;
+ sz = (x + 7) & ~7;
+ if (inp->length < sz + 4 + error_count)
+ return - (sz + 4 + error_count - inp->length);
+ assert (sz <= sizeof (k->in_crypt.data));
+
+ if (p->buf1)
+ p->buf1 = realloc (p->buf1, sz);
+ else
+ p->buf1 = malloc (sz);
+ assert (p->buf1 != 0 || sz == 0);
+ outp->ptr = p->buf1;
+ outp->length = x;
+ pcbc_encrypt ((des_cblock *)ptr, (des_cblock *)outp->ptr, sz, p->x.u.sched,
+ (des_cblock *)p->x.ivec, DECRYPT);
+ if (p->no_right_justify == 0
+ && x < 8)
+ outp->ptr = p->buf1 + 8 - x;
+ return sz + 4 + error_count;
+}
+
+static int
+init (k, data)
+ kstream k;
+ void *data;
+{
+ priv *p;
+
+ p = (priv *) malloc (sizeof (priv));
+ k->data = (kstream_ptr) p;
+ if (!p)
+ return errno;
+ p->buf1 = p->buf2 = 0;
+ p->len1 = p->len2 = 0;
+ p->no_right_justify = 0;
+ p->protect_rlogin_oob = 0;
+ p->x = * (kstream_des_init_block *) data;
+ return 0;
+}
+
+static int
+rcp_init (k, data)
+ kstream k;
+ void *data;
+{
+ int x = init (k, data);
+ ((priv *)(k->data))->no_right_justify = 1;
+ return x;
+}
+
+static int
+rlogin_init (k, data)
Home |
Main Index |
Thread Index |
Old Index