From 6c726c3d1e32e5cb24aa7337eab97f1e8f49ada8 Mon Sep 17 00:00:00 2001 From: Karl Ramm Date: Sun, 21 Dec 2008 23:54:36 +0000 Subject: Pull in our own quad_cksum so a pure-krb5 library can deal with checksums from a mixed server. --- debian/copyright | 26 ++++++++ h/internal.h | 2 + lib/Makefile.in | 2 +- lib/ZCkZAut.c | 9 ++- lib/quad_cksum.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 228 insertions(+), 6 deletions(-) create mode 100644 lib/quad_cksum.c diff --git a/debian/copyright b/debian/copyright index 5cafbf0..e675299 100644 --- a/debian/copyright +++ b/debian/copyright @@ -29,3 +29,29 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/* + * lib/quad_cksum.c + * + * Copyright 1985, 1986, 1987, 1988,1990 by the Massachusetts Institute + * of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ diff --git a/h/internal.h b/h/internal.h index b2d883e..62a467d 100644 --- a/h/internal.h +++ b/h/internal.h @@ -142,6 +142,8 @@ Code_t Z_InsertZcodeChecksum(krb5_keyblock *keyblock, ZNotice_t *notice, char *cksum_start, int cksum_len, char *cstart, char *cend, int buffer_len, int *length_ajdust); +unsigned long z_quad_cksum(const unsigned char *, krb5_ui_4 *, long, + int, unsigned char *); #endif #ifdef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE diff --git a/lib/Makefile.in b/lib/Makefile.in index 843d8cf..64e3692 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -40,7 +40,7 @@ OBJS = zephyr_err.lo ZAsyncLocate.lo ZCkAuth.lo ZCkIfNot.lo ZClosePort.lo \ ZRecvNot.lo ZRecvPkt.lo ZRetSubs.lo ZSendList.lo ZSendNot.lo \ ZSendPkt.lo ZSendRaw.lo ZSendRLst.lo ZSetDest.lo ZSetFD.lo ZSetSrv.lo \ ZSubs.lo ZVariables.lo ZWait4Not.lo Zinternal.lo ZMakeZcode.lo \ - ZReadZcode.lo ZCkZAut.lo + ZReadZcode.lo ZCkZAut.lo quad_cksum.lo .SUFFIXES: .lo diff --git a/lib/ZCkZAut.c b/lib/ZCkZAut.c index b957474..2110871 100644 --- a/lib/ZCkZAut.c +++ b/lib/ZCkZAut.c @@ -111,8 +111,8 @@ Code_t ZCheckZcodeAuthentication(ZNotice_t *notice, cksum2_base = notice->z_message; cksum2_len = notice->z_message_len; -#ifdef HAVE_KRB4 /* XXX this is probably a mistake for krb5 clients in mixed - realms? */ + /* The following code checks for old-style checksums, which will go + away once Kerberos 4 does. */ if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') && key_len == 8 && (enctype == ENCTYPE_DES_CBC_CRC || @@ -122,15 +122,14 @@ Code_t ZCheckZcodeAuthentication(ZNotice_t *notice, ZChecksum_t our_checksum; - our_checksum = des_quad_cksum((unsigned char *)cksum0_base, NULL, cksum0_len, 0, - (C_Block *)key_data); + our_checksum = z_quad_cksum((unsigned char *)cksum0_base, NULL, cksum0_len, 0, + key_data); if (our_checksum == notice->z_checksum) { krb5_free_creds(Z_krb5_ctx, creds); return ZAUTH_YES; } } /* HOLDING: creds */ -#endif cksumbuf.length = cksum0_len + cksum1_len + cksum2_len; cksumbuf.data = malloc(cksumbuf.length); diff --git a/lib/quad_cksum.c b/lib/quad_cksum.c new file mode 100644 index 0000000..5d06440 --- /dev/null +++ b/lib/quad_cksum.c @@ -0,0 +1,195 @@ +/* Lifted from the krb5 1.6 source tree and hacked slightly to fit in here + Karl Ramm 12/21/08 */ +/* + * lib/des425/quad_cksum.c + * + * Copyright 1985, 1986, 1987, 1988,1990 by the Massachusetts Institute + * of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * + * This routine does not implement: + * + * + * Quadratic Congruential Manipulation Dectection Code + * + * ref: "Message Authentication" + * R.R. Jueneman, S. M. Matyas, C.H. Meyer + * IEEE Communications Magazine, + * Sept 1985 Vol 23 No 9 p 29-40 + * + * This routine, part of the Athena DES library built for the Kerberos + * authentication system, calculates a manipulation detection code for + * a message. It is a much faster alternative to the DES-checksum + * method. No guarantees are offered for its security. + * + * Implementation for 4.2bsd + * by S.P. Miller Project Athena/MIT + */ + +/* + * Algorithm (per paper): + * define: + * message to be composed of n m-bit blocks X1,...,Xn + * optional secret seed S in block X1 + * MDC in block Xn+1 + * prime modulus N + * accumulator Z + * initial (secret) value of accumulator C + * N, C, and S are known at both ends + * C and , optionally, S, are hidden from the end users + * then + * (read array references as subscripts over time) + * Z[0] = c; + * for i = 1...n + * Z[i] = (Z[i+1] + X[i])**2 modulo N + * X[n+1] = Z[n] = MDC + * + * Then pick + * N = 2**31 -1 + * m = 16 + * iterate 4 times over plaintext, also use Zn + * from iteration j as seed for iteration j+1, + * total MDC is then a 128 bit array of the four + * Zn; + * + * return the last Zn and optionally, all + * four as output args. + * + * Modifications: + * To inhibit brute force searches of the seed space, this + * implementation is modified to have + * Z = 64 bit accumulator + * C = 64 bit C seed + * N = 2**63 - 1 + * S = S seed is not implemented here + * arithmetic is not quite real double integer precision, since we + * cant get at the carry or high order results from multiply, + * but nontheless is 64 bit arithmetic. + */ +/* + * This code purports to implement the above algorithm, but fails. + * + * First of all, there was an implicit mod 2**32 being done on the + * machines where this was developed because of their word sizes, and + * for compabitility this has to be done on machines with 64-bit + * words, so we make it explicit. + * + * Second, in the squaring operation, I really doubt the carry-over + * from the low 31-bit half of the accumulator is being done right, + * and using a modulus of 0x7fffffff on the low half of the + * accumulator seems completely wrong. And I challenge anyone to + * explain where the number 83653421 comes from. + * + * --Ken Raeburn 2001-04-06 + */ + + +/* System include files */ +#include +#include + +#include + +/* Definitions for byte swapping */ + +/* vax byte order is LSB first. This is not performance critical, and + is far more readable this way. */ +#define four_bytes_vax_to_nets(x) ((((((x[3]<<8)|x[2])<<8)|x[1])<<8)|x[0]) +#define vaxtohl(x) four_bytes_vax_to_nets(((const unsigned char *)(x))) +#define two_bytes_vax_to_nets(x) ((x[1]<<8)|x[0]) +#define vaxtohs(x) two_bytes_vax_to_nets(((const unsigned char *)(x))) + +/*** Routines ***************************************************** */ +#ifdef HAVE_KRB5 +unsigned long +z_quad_cksum(const unsigned char *in, /* input block */ + krb5_ui_4 *out, /* optional longer output */ + long length, /* original length in bytes */ + int out_count, /* number of iterations */ + unsigned char *c_seed /* secret seed, 8 bytes */ + ) +{ + + /* + * this routine both returns the low order of the final (last in + * time) 32bits of the checksum, and if "out" is not a null + * pointer, a longer version, up to entire 32 bytes of the + * checksum is written unto the address pointed to. + */ + + register krb5_ui_4 z; + register krb5_ui_4 z2; + register krb5_ui_4 x; + register krb5_ui_4 x2; + const unsigned char *p; + register krb5_int32 len; + register int i; + + /* use all 8 bytes of seed */ + + z = vaxtohl(c_seed); + z2 = vaxtohl((const char *)c_seed+4); + if (out == NULL) + out_count = 1; /* default */ + + /* This is repeated n times!! */ + for (i = 1; i <=4 && i<= out_count; i++) { + len = length; + p = in; + while (len) { + /* + * X = Z + Input ... sort of. Carry out from low half + * isn't done, so we're using all 32 bits of x now. + */ + if (len > 1) { + x = (z + vaxtohs(p)); + p += 2; + len -= 2; + } + else { + x = (z + *(const unsigned char *)p++); + len = 0; + } + x2 = z2; + /* + * I think this is supposed to be a squaring operation. + * What it really is, I haven't figured out yet. + * + * Explicit mod 2**32 is for backwards compatibility. Why + * mod 0x7fffffff and not 0x80000000 on the low half of + * the (supposed) accumulator? And where does the number + * 83653421 come from?? + */ + z = (((x * x) + (x2 * x2)) & 0xffffffff) % 0x7fffffff; + z2 = ((x * (x2+83653421)) & 0xffffffff) % 0x7fffffff; /* modulo */ + } + + if (out != NULL) { + *out++ = z; + *out++ = z2; + } + } + /* return final z value as 32 bit version of checksum */ + return z; +} +#endif -- cgit v1.2.3