From 29e7d86639c0f939b3b0f84286a3ea2d551a976a Mon Sep 17 00:00:00 2001 From: Tom Yu Date: Mon, 2 Nov 1998 20:40:55 +0000 Subject: [PATCH] ressurect files missed by merge git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@11006 dc483132-0cff-0310-8789-dd5450dbe970 --- src/clients/kvno/ChangeLog | 4 + src/clients/kvno/Makefile.in | 34 ++ src/clients/kvno/kvno.M | 55 +++ src/clients/kvno/kvno.c | 169 ++++++++ src/lib/crypto/dk/Makefile.in | 44 ++ src/lib/crypto/dk/checksum.c | 104 +++++ src/lib/crypto/dk/decrypt.c | 151 +++++++ src/lib/crypto/dk/derive.c | 114 +++++ src/lib/crypto/dk/dk.h | 61 +++ src/lib/crypto/dk/encrypt.c | 167 ++++++++ src/lib/crypto/dk/stringtokey.c | 97 +++++ src/lib/crypto/enc_provider/Makefile.in | 29 ++ src/lib/crypto/enc_provider/des.c | 128 ++++++ src/lib/crypto/enc_provider/des3.c | 136 ++++++ src/lib/crypto/enc_provider/enc_provider.h | 32 ++ src/lib/crypto/hash_provider/Makefile.in | 30 ++ src/lib/crypto/hash_provider/crc32.c | 71 ++++ src/lib/crypto/hash_provider/hash_provider.h | 32 ++ src/lib/crypto/hash_provider/md4.c | 67 +++ src/lib/crypto/hash_provider/md5.c | 67 +++ src/lib/crypto/hash_provider/sha1.c | 72 ++++ src/lib/crypto/keyhash_provider/Makefile.in | 50 +++ src/lib/crypto/keyhash_provider/descbc.c | 76 ++++ src/lib/crypto/keyhash_provider/k5_md4des.c | 197 +++++++++ src/lib/crypto/keyhash_provider/k5_md5des.c | 195 +++++++++ .../keyhash_provider/keyhash_provider.h | 31 ++ src/lib/crypto/keyhash_provider/t_cksum.c | 136 ++++++ src/lib/crypto/old/Makefile.in | 29 ++ src/lib/crypto/old/decrypt.c | 121 ++++++ src/lib/crypto/old/des_stringtokey.c | 38 ++ src/lib/crypto/old/encrypt.c | 105 +++++ src/lib/crypto/old/old.h | 51 +++ src/lib/crypto/raw/Makefile.in | 29 ++ src/lib/crypto/raw/decrypt.c | 41 ++ src/lib/crypto/raw/encrypt.c | 55 +++ src/lib/crypto/raw/raw.h | 46 ++ src/lib/crypto/sha1/Makefile.in | 44 ++ src/lib/crypto/sha1/shs.c | 400 ++++++++++++++++++ src/lib/crypto/sha1/shs.h | 59 +++ src/lib/crypto/sha1/t_shs.c | 132 ++++++ 40 files changed, 3499 insertions(+) create mode 100644 src/clients/kvno/ChangeLog create mode 100644 src/clients/kvno/Makefile.in create mode 100644 src/clients/kvno/kvno.M create mode 100644 src/clients/kvno/kvno.c create mode 100644 src/lib/crypto/dk/Makefile.in create mode 100644 src/lib/crypto/dk/checksum.c create mode 100644 src/lib/crypto/dk/decrypt.c create mode 100644 src/lib/crypto/dk/derive.c create mode 100644 src/lib/crypto/dk/dk.h create mode 100644 src/lib/crypto/dk/encrypt.c create mode 100644 src/lib/crypto/dk/stringtokey.c create mode 100644 src/lib/crypto/enc_provider/Makefile.in create mode 100644 src/lib/crypto/enc_provider/des.c create mode 100644 src/lib/crypto/enc_provider/des3.c create mode 100644 src/lib/crypto/enc_provider/enc_provider.h create mode 100644 src/lib/crypto/hash_provider/Makefile.in create mode 100644 src/lib/crypto/hash_provider/crc32.c create mode 100644 src/lib/crypto/hash_provider/hash_provider.h create mode 100644 src/lib/crypto/hash_provider/md4.c create mode 100644 src/lib/crypto/hash_provider/md5.c create mode 100644 src/lib/crypto/hash_provider/sha1.c create mode 100644 src/lib/crypto/keyhash_provider/Makefile.in create mode 100644 src/lib/crypto/keyhash_provider/descbc.c create mode 100644 src/lib/crypto/keyhash_provider/k5_md4des.c create mode 100644 src/lib/crypto/keyhash_provider/k5_md5des.c create mode 100644 src/lib/crypto/keyhash_provider/keyhash_provider.h create mode 100644 src/lib/crypto/keyhash_provider/t_cksum.c create mode 100644 src/lib/crypto/old/Makefile.in create mode 100644 src/lib/crypto/old/decrypt.c create mode 100644 src/lib/crypto/old/des_stringtokey.c create mode 100644 src/lib/crypto/old/encrypt.c create mode 100644 src/lib/crypto/old/old.h create mode 100644 src/lib/crypto/raw/Makefile.in create mode 100644 src/lib/crypto/raw/decrypt.c create mode 100644 src/lib/crypto/raw/encrypt.c create mode 100644 src/lib/crypto/raw/raw.h create mode 100644 src/lib/crypto/sha1/Makefile.in create mode 100644 src/lib/crypto/sha1/shs.c create mode 100644 src/lib/crypto/sha1/shs.h create mode 100644 src/lib/crypto/sha1/t_shs.c diff --git a/src/clients/kvno/ChangeLog b/src/clients/kvno/ChangeLog new file mode 100644 index 000000000..24ad575df --- /dev/null +++ b/src/clients/kvno/ChangeLog @@ -0,0 +1,4 @@ +1998-10-27 Marc Horowitz + + * kvno.c, kvno.M: Create a new application. + diff --git a/src/clients/kvno/Makefile.in b/src/clients/kvno/Makefile.in new file mode 100644 index 000000000..74146e506 --- /dev/null +++ b/src/clients/kvno/Makefile.in @@ -0,0 +1,34 @@ +thisconfigdir=./.. +BUILDTOP=$(REL)$(U)$(S)$(U) +##DOS##BUILDTOP=..\.. + +CFLAGS = $(CCOPTS) $(DEFS) $(LOCALINCLUDE) +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +all-unix:: kvno +all-windows:: +all-mac:: + +kvno: kvno.o $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o $@ kvno.o $(KRB5_BASE_LIBS) + + +##WIN32##INCLUDES = /I$(BUILDTOP)\include /I$(BUILDTOP)\include\krb5 +##WIN32##CFLAGS = $(CCOPTS2) $(INCLUDES) + +##WIN32##all-windows:: kvno.exe +##WIN32##kvno.exe: kvno.obj $(BUILDTOP)\util\windows\getopt.obj $(KLIB) $(CLIB) +##WIN32## link /nologo /out:$@ $** + + +clean-unix:: + $(RM) kvno.o kvno + +install-unix:: + for f in kvno; do \ + $(INSTALL_PROGRAM) $$f \ + $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'`; \ + $(INSTALL_DATA) $(srcdir)/$$f.M \ + $(DESTDIR)$(CLIENT_MANDIR)/`echo $$f|sed '$(transform)'`.1; \ + done diff --git a/src/clients/kvno/kvno.M b/src/clients/kvno/kvno.M new file mode 100644 index 000000000..b89f751ea --- /dev/null +++ b/src/clients/kvno/kvno.M @@ -0,0 +1,55 @@ +.\" Copyright (C) 1998 by the FundsXpress, INC. +.\" +.\" 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 FundsXpress. not be used in advertising or publicity pertaining +.\" to distribution of the software without specific, written prior +.\" permission. FundsXpress makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" without express +.\" or implied warranty. +.\" +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" clients/kvnol/kvno.M +.\" " +.TH KVNO 1 +.SH NAME +kvno \- print key version numbers of Kerberos principals +.SH SYNOPSIS +\fBklist\fP [\fB\-e etype\fP] \fBservice1\fP \fBservice2\fP \fB...\fP +.br +.SH DESCRIPTION +.I Kvno +acquires a service ticket for the specified Kerberos principals and +prints out the key version numbers of each. +.SH OPTIONS +.TP +.B \-e +specifies the enctype which will be requested for the session key of +all the services named on the command line. This is useful in certain +backward compatibility situations. +.SH ENVIRONMENT +.B Kvno +uses the following environment variable: +.TP "\w'.SM KRB5CCNAME\ \ 'u" +.SM KRB5CCNAME +Location of the credentials (ticket) cache. +.SH FILES +.TP "\w'/tmp/krb5cc_[uid]\ \ 'u" +/tmp/krb5cc_[uid] +default location of the credentials cache ([uid] is the decimal UID of +the user). +.SH SEE ALSO +kinit(1), kdestroy(1), krb5(3) diff --git a/src/clients/kvno/kvno.c b/src/clients/kvno/kvno.c new file mode 100644 index 000000000..d94fd0bc5 --- /dev/null +++ b/src/clients/kvno/kvno.c @@ -0,0 +1,169 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include +#include +#include + +extern int optind; +extern char *optarg; + +void usage(char *argv0) +{ + char *cmd; + + cmd = strrchr(argv0, '/'); + cmd = cmd?(cmd+1):argv0; + + fprintf(stderr, "usage: %s [-e etype] service1 service2 ...\n", cmd); + + exit(1); +} + +int main(int argc, char *argv[]) +{ + krb5_context context; + krb5_error_code ret; + int option, i, errors; + char *etypestr = 0; + int quiet = 0; + krb5_enctype etype; + krb5_ccache ccache; + krb5_principal me; + krb5_creds in_creds, *out_creds; + krb5_ticket *ticket; + char *princ; + + if (ret = krb5_init_context(&context)) { + com_err(argv[0], ret, "while initializing krb5 library"); + exit(1); + } + + while ((option = getopt(argc, argv, "e:hq")) != -1) { + switch (option) { + case 'e': + etypestr = optarg; + break; + case 'h': + usage(argv[0]); + break; + case 'q': + quiet = 1; + break; + default: + usage(argv[0]); + break; + } + } + + if ((argc - optind) < 1) + usage(argv[0]); + + if (etypestr) { + if (ret = krb5_string_to_enctype(etypestr, &etype)) { + com_err(argv[0], ret, "while converting etype"); + exit(1); + } + } else { + etype = 0; + } + + if (ret = krb5_cc_default(context, &ccache)) { + com_err(argv[0], ret, "while opening ccache"); + exit(1); + } + + if (ret = krb5_cc_get_principal(context, ccache, &me)) { + com_err(argv[0], ret, "while getting client principal name"); + exit(1); + } + + errors = 0; + + for (i = optind; i < argc; i++) { + memset(&in_creds, 0, sizeof(in_creds)); + + in_creds.client = me; + + if (ret = krb5_parse_name(context, argv[i], &in_creds.server)) { + if (!quiet) + fprintf(stderr, "%s: %s while parsing principal name\n", + argv[i], error_message(ret)); + errors++; + continue; + } + + if (ret = krb5_unparse_name(context, in_creds.server, &princ)) { + fprintf(stderr, "%s: %s while printing principal name\n", + argv[i], error_message(ret)); + errors++; + continue; + } + + in_creds.keyblock.enctype = etype; + + ret = krb5_get_credentials(context, 0, ccache, &in_creds, &out_creds); + + krb5_free_principal(context, in_creds.server); + + if (ret) { + fprintf(stderr, "%s: %s while getting credentials\n", + princ, error_message(ret)); + + free(princ); + + errors++; + continue; + } + + /* we need a native ticket */ + if (ret = decode_krb5_ticket(&out_creds->ticket, &ticket)) { + fprintf(stderr, "%s: %s while decoding ticket\n", + princ, error_message(ret)); + + krb5_free_creds(context, out_creds); + free(princ); + + errors++; + continue; + } + + if (!quiet) + printf("%s: kvno = %d\n", princ, ticket->enc_part.kvno); + + krb5_free_ticket(context, ticket); + krb5_free_creds(context, out_creds); + free(princ); + } + + krb5_free_principal(context, me); + krb5_cc_close(context, ccache); + + if (errors) + exit(1); + + exit(0); +} diff --git a/src/lib/crypto/dk/Makefile.in b/src/lib/crypto/dk/Makefile.in new file mode 100644 index 000000000..076b0dd66 --- /dev/null +++ b/src/lib/crypto/dk/Makefile.in @@ -0,0 +1,44 @@ +thisconfigdir=./.. +BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) +CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/.. + +##DOS##BUILDTOP = ..\..\.. +##DOS##PREFIXDIR=dk +##DOS##OBJFILE=..\dk.lst +##WIN16##LIBNAME=..\crypto.lib + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf + +STLIBOBJS=\ + checksum.o \ + decrypt.o \ + derive.o \ + encrypt.o \ + stringtokey.o + +OBJS=\ + checksum.$(OBJEXT) \ + decrypt.$(OBJEXT) \ + derive.$(OBJEXT) \ + encrypt.$(OBJEXT) \ + stringtokey.$(OBJEXT) + +SRCS=\ + $(srcdir)/checksum.c \ + $(srcdir)/decrypt.c \ + $(srcdir)/derive.c \ + $(srcdir)/encrypt.c \ + $(srcdir)/stringtokey.c + +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs + +includes:: depend + +depend:: $(SRCS) + +clean-unix:: clean-libobjs diff --git a/src/lib/crypto/dk/checksum.c b/src/lib/crypto/dk/checksum.c new file mode 100644 index 000000000..db64e6cb6 --- /dev/null +++ b/src/lib/crypto/dk/checksum.c @@ -0,0 +1,104 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "etypes.h" +#include "dk.h" + +#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */ + +krb5_error_code +krb5_dk_make_checksum(hash, key, usage, input, output) + krb5_const struct krb5_hash_provider *hash; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *input; + krb5_data *output; +{ + int i; + struct krb5_enc_provider *enc; + size_t blocksize, keybytes, keylength; + krb5_error_code ret; + unsigned char constantdata[K5CLENGTH]; + krb5_data datain; + unsigned char *kcdata; + krb5_keyblock kc; + + for (i=0; ienctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + enc = krb5_enctypes_list[i].enc; + + /* allocate and set to-be-derived keys */ + + (*(enc->block_size))(&blocksize); + (*(enc->keysize))(&keybytes, &keylength); + + /* key->length will be tested in enc->encrypt + output->length will be tested in krb5_hmac */ + + if ((kcdata = (unsigned char *) malloc(keylength)) == NULL) + return(ENOMEM); + + kc.contents = kcdata; + kc.length = keylength; + + /* derive the key */ + + datain.data = constantdata; + datain.length = K5CLENGTH; + + datain.data[0] = (usage>>24)&0xff; + datain.data[1] = (usage>>16)&0xff; + datain.data[2] = (usage>>8)&0xff; + datain.data[3] = usage&0xff; + + datain.data[4] = 0x99; + + if (ret = krb5_derive_key(enc, key, &kc, &datain)) + goto cleanup; + + /* hash the data */ + + datain = *input; + + if (ret = krb5_hmac(hash, &kc, 1, &datain, output)) + memset(output->data, 0, output->length); + + /* ret is set correctly by the prior call */ + +cleanup: + memset(kcdata, 0, keylength); + + free(kcdata); + + return(ret); +} diff --git a/src/lib/crypto/dk/decrypt.c b/src/lib/crypto/dk/decrypt.c new file mode 100644 index 000000000..9fedffbc0 --- /dev/null +++ b/src/lib/crypto/dk/decrypt.c @@ -0,0 +1,151 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "dk.h" + +#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */ + +krb5_error_code +krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output) + krb5_const struct krb5_enc_provider *enc; + krb5_const struct krb5_hash_provider *hash; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *ivec; + krb5_const krb5_data *input; + krb5_data *output; +{ + krb5_error_code ret; + size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen; + unsigned char *plaindata, *kedata, *kidata, *cksum; + krb5_keyblock ke, ki; + krb5_data d1, d2; + unsigned char constantdata[K5CLENGTH]; + + /* allocate and set up ciphertext and to-be-derived keys */ + + (*(hash->hash_size))(&hashsize); + (*(enc->block_size))(&blocksize); + (*(enc->keysize))(&keybytes, &keylength); + + enclen = input->length - hashsize; + + if ((kedata = (unsigned char *) malloc(keylength)) == NULL) + return(ENOMEM); + if ((kidata = (unsigned char *) malloc(keylength)) == NULL) { + free(kedata); + return(ENOMEM); + } + if ((plaindata = (unsigned char *) malloc(enclen)) == NULL) { + free(kidata); + free(kedata); + return(ENOMEM); + } + if ((cksum = (unsigned char *) malloc(hashsize)) == NULL) { + free(plaindata); + free(kidata); + free(kedata); + return(ENOMEM); + } + + ke.contents = kedata; + ke.length = keylength; + ki.contents = kidata; + ki.length = keylength; + + /* derive the keys */ + + d1.data = constantdata; + d1.length = K5CLENGTH; + + d1.data[0] = (usage>>24)&0xff; + d1.data[1] = (usage>>16)&0xff; + d1.data[2] = (usage>>8)&0xff; + d1.data[3] = usage&0xff; + + d1.data[4] = 0xAA; + + if (ret = krb5_derive_key(enc, key, &ke, &d1)) + goto cleanup; + + d1.data[4] = 0x55; + + if (ret = krb5_derive_key(enc, key, &ki, &d1)) + goto cleanup; + + /* decrypt the ciphertext */ + + d1.length = enclen; + d1.data = input->data; + + d2.length = enclen; + d2.data = plaindata; + + if (ret = ((*(enc->decrypt))(&ke, ivec, &d1, &d2))) + goto cleanup; + + /* verify the hash */ + + d1.length = hashsize; + d1.data = cksum; + + if (ret = krb5_hmac(hash, &ki, 1, &d2, &d1)) + goto cleanup; + + if (memcmp(cksum, input->data+enclen, hashsize) != 0) { + ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto cleanup; + } + + /* because this encoding isn't self-describing wrt length, the + best we can do here is to compute the length minus the + confounder. */ + + plainlen = enclen - blocksize; + + if (output->length < plainlen) + return(KRB5_BAD_MSIZE); + + output->length = plainlen; + + memcpy(output->data, d2.data+blocksize, output->length); + + ret = 0; + +cleanup: + memset(kedata, 0, keylength); + memset(kidata, 0, keylength); + memset(plaindata, 0, enclen); + memset(cksum, 0, hashsize); + + free(cksum); + free(plaindata); + free(kidata); + free(kedata); + + return(ret); +} diff --git a/src/lib/crypto/dk/derive.c b/src/lib/crypto/dk/derive.c new file mode 100644 index 000000000..8765605fb --- /dev/null +++ b/src/lib/crypto/dk/derive.c @@ -0,0 +1,114 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "dk.h" + +krb5_error_code +krb5_derive_key(enc, inkey, outkey, in_constant) + krb5_const struct krb5_enc_provider *enc; + krb5_const krb5_keyblock *inkey; + krb5_keyblock *outkey; + krb5_const krb5_data *in_constant; +{ + size_t blocksize, keybytes, keylength, n; + unsigned char *inblockdata, *outblockdata, *rawkey; + krb5_data inblock, outblock; + + (*(enc->block_size))(&blocksize); + (*(enc->keysize))(&keybytes, &keylength); + + if ((inkey->length != keylength) || + (outkey->length != keylength)) + return(KRB5_CRYPTO_INTERNAL); + + /* allocate and set up buffers */ + + if ((inblockdata = (unsigned char *) malloc(blocksize)) == NULL) + return(ENOMEM); + + if ((outblockdata = (unsigned char *) malloc(blocksize)) == NULL) { + return(ENOMEM); + free(inblockdata); + } + + if ((rawkey = (unsigned char *) malloc(keybytes)) == NULL) { + return(ENOMEM); + free(outblockdata); + free(inblockdata); + } + + inblock.data = inblockdata; + inblock.length = blocksize; + + outblock.data = outblockdata; + outblock.length = blocksize; + + /* initialize the input block */ + + if (in_constant->length == inblock.length) { + memcpy(inblock.data, in_constant->data, inblock.length); + } else { + krb5_nfold(in_constant->length*8, in_constant->data, + inblock.length*8, inblock.data); + } + + /* loop encrypting the blocks until enough key bytes are generated */ + + n = 0; + while (n < keybytes) { + (*(enc->encrypt))(inkey, 0, &inblock, &outblock); + + if ((keybytes - n) <= outblock.length) { + memcpy(rawkey+n, outblock.data, (keybytes - n)); + break; + } + + memcpy(rawkey+n, outblock.data, outblock.length); + memcpy(inblock.data, outblock.data, outblock.length); + n += outblock.length; + } + + /* postprocess the key */ + + inblock.data = rawkey; + inblock.length = keybytes; + + (*(enc->make_key))(&inblock, outkey); + + /* clean memory, free resources and exit */ + + memset(inblockdata, 0, blocksize); + memset(outblockdata, 0, blocksize); + memset(rawkey, 0, keybytes); + + free(rawkey); + free(outblockdata); + free(inblockdata); + + return(0); +} + diff --git a/src/lib/crypto/dk/dk.h b/src/lib/crypto/dk/dk.h new file mode 100644 index 000000000..e4acddabc --- /dev/null +++ b/src/lib/crypto/dk/dk.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" + +void krb5_dk_encrypt_length +KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc, + krb5_const struct krb5_hash_provider *hash, + size_t input, size_t *length)); + +krb5_error_code krb5_dk_encrypt +KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc, + krb5_const struct krb5_hash_provider *hash, + krb5_const krb5_keyblock *key, krb5_keyusage usage, + krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output)); + +krb5_error_code krb5_dk_decrypt +KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc, + krb5_const struct krb5_hash_provider *hash, + krb5_const krb5_keyblock *key, krb5_keyusage usage, + krb5_const krb5_data *ivec, krb5_const krb5_data *input, + krb5_data *arg_output)); + +krb5_error_code krb5_dk_string_to_key +KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc, + krb5_const krb5_data *string, krb5_const krb5_data *salt, + krb5_keyblock *key)); + +krb5_error_code krb5_derive_key +KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc, + krb5_const krb5_keyblock *inkey, + krb5_keyblock *outkey, krb5_const krb5_data *in_constant)); + +krb5_error_code krb5_dk_make_checksum +KRB5_PROTOTYPE((krb5_const struct krb5_hash_provider *hash, + krb5_const krb5_keyblock *key, krb5_keyusage usage, + krb5_const krb5_data *input, krb5_data *output)); diff --git a/src/lib/crypto/dk/encrypt.c b/src/lib/crypto/dk/encrypt.c new file mode 100644 index 000000000..4a3a00b30 --- /dev/null +++ b/src/lib/crypto/dk/encrypt.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "dk.h" + +#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */ + +/* the spec says that the confounder size and padding are specific to + the encryption algorithm. This code (dk_encrypt_length and + dk_encrypt) assume the confounder is always the blocksize, and the + padding is always zero bytes up to the blocksize. If these + assumptions ever fails, the keytype table should be extended to + include these bits of info. */ + +void +krb5_dk_encrypt_length(enc, hash, inputlen, length) + krb5_const struct krb5_enc_provider *enc; + krb5_const struct krb5_hash_provider *hash; + size_t inputlen; + size_t *length; +{ + size_t blocksize, hashsize; + + (*(enc->block_size))(&blocksize); + (*(hash->hash_size))(&hashsize); + + *length = krb5_roundup(blocksize+inputlen, blocksize) + hashsize; +} + +krb5_error_code +krb5_dk_encrypt(enc, hash, key, usage, ivec, input, output) + krb5_const struct krb5_enc_provider *enc; + krb5_const struct krb5_hash_provider *hash; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *ivec; + krb5_const krb5_data *input; + krb5_data *output; +{ + size_t blocksize, keybytes, keylength, plainlen, enclen; + krb5_error_code ret; + unsigned char constantdata[K5CLENGTH]; + krb5_data d1, d2; + unsigned char *plaintext, *kedata, *kidata; + krb5_keyblock ke, ki; + + /* allocate and set up plaintext and to-be-derived keys */ + + (*(enc->block_size))(&blocksize); + (*(enc->keysize))(&keybytes, &keylength); + plainlen = krb5_roundup(blocksize+input->length, blocksize); + + krb5_dk_encrypt_length(enc, hash, input->length, &enclen); + + /* key->length, ivec will be tested in enc->encrypt */ + + if (output->length < enclen) + return(KRB5_BAD_MSIZE); + + if ((kedata = (unsigned char *) malloc(keylength)) == NULL) + return(ENOMEM); + if ((kidata = (unsigned char *) malloc(keylength)) == NULL) { + free(kedata); + return(ENOMEM); + } + if ((plaintext = (unsigned char *) malloc(plainlen)) == NULL) { + free(kidata); + free(kedata); + return(ENOMEM); + } + + ke.contents = kedata; + ke.length = keylength; + ki.contents = kidata; + ki.length = keylength; + + /* derive the keys */ + + d1.data = constantdata; + d1.length = K5CLENGTH; + + d1.data[0] = (usage>>24)&0xff; + d1.data[1] = (usage>>16)&0xff; + d1.data[2] = (usage>>8)&0xff; + d1.data[3] = usage&0xff; + + d1.data[4] = 0xAA; + + if (ret = krb5_derive_key(enc, key, &ke, &d1)) + goto cleanup; + + d1.data[4] = 0x55; + + if (ret = krb5_derive_key(enc, key, &ki, &d1)) + goto cleanup; + + /* put together the plaintext */ + + d1.length = blocksize; + d1.data = plaintext; + + if (ret = krb5_c_random_make_octets(/* XXX */ 0, &d1)) + goto cleanup; + + memcpy(plaintext+blocksize, input->data, input->length); + + memset(plaintext+blocksize+input->length, 0, + plainlen - (blocksize+input->length)); + + /* encrypt the plaintext */ + + d1.length = plainlen; + d1.data = plaintext; + + d2.length = plainlen; + d2.data = output->data; + + if (ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2))) + goto cleanup; + + /* hash the plaintext */ + + d2.length = enclen - plainlen; + d2.data = output->data+plainlen; + + output->length = enclen; + + if (ret = krb5_hmac(hash, &ki, 1, &d1, &d2)) + memset(d2.data, 0, d2.length); + + /* ret is set correctly by the prior call */ + +cleanup: + memset(kedata, 0, keylength); + memset(kidata, 0, keylength); + memset(plaintext, 0, plainlen); + + free(plaintext); + free(kidata); + free(kedata); + + return(ret); +} diff --git a/src/lib/crypto/dk/stringtokey.c b/src/lib/crypto/dk/stringtokey.c new file mode 100644 index 000000000..c033dc35a --- /dev/null +++ b/src/lib/crypto/dk/stringtokey.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" + +static unsigned char kerberos[] = "kerberos"; +#define kerberos_len (sizeof(kerberos)-1) + +krb5_error_code +krb5_dk_string_to_key(enc, string, salt, key) + krb5_const struct krb5_enc_provider *enc; + krb5_const krb5_data *string; + krb5_const krb5_data *salt; + krb5_keyblock *key; +{ + krb5_error_code ret; + size_t keybytes, keylength, concatlen; + unsigned char *concat, *foldstring, *foldkeydata; + krb5_data indata; + krb5_keyblock foldkey; + + /* key->length is checked by krb5_derive_key */ + + (*(enc->keysize))(&keybytes, &keylength); + + concatlen = string->length+(salt?salt->length:0); + + if ((concat = (unsigned char *) malloc(concatlen)) == NULL) + return(ENOMEM); + if ((foldstring = (unsigned char *) malloc(keybytes)) == NULL) { + free(concat); + return(ENOMEM); + } + if ((foldkeydata = (unsigned char *) malloc(keylength)) == NULL) { + free(foldstring); + free(concat); + return(ENOMEM); + } + + /* construct input string ( = string + salt), fold it, make_key it */ + + memcpy(concat, string->data, string->length); + if (salt) + memcpy(concat+string->length, salt->data, salt->length); + + krb5_nfold(concatlen*8, concat, keybytes*8, foldstring); + + indata.length = keybytes; + indata.data = foldstring; + foldkey.length = keylength; + foldkey.contents = foldkeydata; + + (*(enc->make_key))(&indata, &foldkey); + + /* now derive the key from this one */ + + indata.length = kerberos_len; + indata.data = kerberos; + + if (ret = krb5_derive_key(enc, &foldkey, key, &indata)) + memset(key->contents, 0, key->length); + + /* ret is set correctly by the prior call */ + + memset(concat, 0, concatlen); + memset(foldstring, 0, keybytes); + memset(foldkeydata, 0, keylength); + + free(foldkeydata); + free(foldstring); + free(concat); + + return(ret); +} diff --git a/src/lib/crypto/enc_provider/Makefile.in b/src/lib/crypto/enc_provider/Makefile.in new file mode 100644 index 000000000..ebb5f5cc5 --- /dev/null +++ b/src/lib/crypto/enc_provider/Makefile.in @@ -0,0 +1,29 @@ +thisconfigdir=./.. +BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) +CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des + +##DOS##BUILDTOP = ..\..\.. +##DOS##PREFIXDIR=enc_provider +##DOS##OBJFILE=..\enc_prov.lst +##WIN16##LIBNAME=..\crypto.lib + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf + +STLIBOBJS= des.o des3.o + +OBJS= des.$(OBJEXT) des3.$(OBJEXT) + +SRCS= $(srcdir)/des.c $(srcdir)/des3.c + +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs + +includes:: depend + +depend:: $(SRCS) + +clean-unix:: clean-libobjs diff --git a/src/lib/crypto/enc_provider/des.c b/src/lib/crypto/enc_provider/des.c new file mode 100644 index 000000000..68c4e5b13 --- /dev/null +++ b/src/lib/crypto/enc_provider/des.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "des_int.h" +#include "enc_provider.h" + +static mit_des_cblock mit_des_zeroblock[8] = {0,0,0,0,0,0,0,0}; + +static void +k5_des_block_size(size_t *blocksize) +{ + *blocksize = 8; +} + +static void +k5_des_keysize(size_t *keybytes, size_t *keylength) +{ + *keybytes = 7; + *keylength = 8; +} + +static krb5_error_code +k5_des_docrypt(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output, int encrypt) +{ + mit_des_key_schedule schedule; + int ret; + + /* key->enctype was checked by the caller */ + + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if ((input->length%8) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + if (input->length != output->length) + return(KRB5_BAD_MSIZE); + + switch (ret = mit_des_key_sched(key->contents, schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + + /* this has a return value, but the code always returns zero */ + + mit_des_cbc_encrypt((krb5_pointer) input->data, + (krb5_pointer) output->data, input->length, + schedule, ivec?ivec->data:(char *)mit_des_zeroblock, + encrypt); + + memset(schedule, 0, sizeof(schedule)); + + return(0); +} + +static krb5_error_code +k5_des_encrypt(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output) +{ + return(k5_des_docrypt(key, ivec, input, output, 1)); +} + +static krb5_error_code +k5_des_decrypt(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output) +{ + return(k5_des_docrypt(key, ivec, input, output, 0)); +} + +static krb5_error_code +k5_des_make_key(krb5_const krb5_data *randombits, krb5_keyblock *key) +{ + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if (randombits->length != 7) + return(KRB5_CRYPTO_INTERNAL); + + key->magic = KV5M_KEYBLOCK; + key->length = 8; + + /* take the seven bytes, move them around into the top 7 bits of the + 8 key bytes, then compute the parity bits */ + + memcpy(key->contents, randombits->data, randombits->length); + key->contents[7] = (((key->contents[0]&1)<<1) | ((key->contents[1]&1)<<2) | + ((key->contents[2]&1)<<3) | ((key->contents[3]&1)<<4) | + ((key->contents[4]&1)<<5) | ((key->contents[5]&1)<<6) | + ((key->contents[6]&1)<<7)); + + mit_des_fixup_key_parity(key->contents); + + return(0); +} + +struct krb5_enc_provider krb5_enc_des = { + k5_des_block_size, + k5_des_keysize, + k5_des_encrypt, + k5_des_decrypt, + k5_des_make_key +}; diff --git a/src/lib/crypto/enc_provider/des3.c b/src/lib/crypto/enc_provider/des3.c new file mode 100644 index 000000000..a27a4d414 --- /dev/null +++ b/src/lib/crypto/enc_provider/des3.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "des_int.h" + +static mit_des_cblock mit_des_zeroblock[8] = {0,0,0,0,0,0,0,0}; + +static void +k5_des3_block_size(size_t *blocksize) +{ + *blocksize = 8; +} + +static void +k5_des3_keysize(size_t *keybytes, size_t *keylength) +{ + *keybytes = 21; + *keylength = 24; +} + +static krb5_error_code +k5_des3_docrypt(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output, int encrypt) +{ + mit_des3_key_schedule schedule; + int ret; + + /* key->enctype was checked by the caller */ + + if (key->length != 24) + return(KRB5_BAD_KEYSIZE); + if ((input->length%8) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_BAD_MSIZE); + if (input->length != output->length) + return(KRB5_BAD_MSIZE); + + switch (ret = mit_des3_key_sched(*(mit_des3_cblock *)key->contents, + schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + + /* this has a return value, but the code always returns zero */ + + mit_des3_cbc_encrypt((krb5_pointer) input->data, + (krb5_pointer) output->data, input->length, + schedule[0], schedule[1], schedule[2], + ivec?ivec->data:(char *)mit_des_zeroblock, + encrypt); + + memset(schedule, 0, sizeof(schedule)); + + return(0); +} + +static krb5_error_code +k5_des3_encrypt(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output) +{ + return(k5_des3_docrypt(key, ivec, input, output, 1)); +} + +static krb5_error_code +k5_des3_decrypt(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output) +{ + return(k5_des3_docrypt(key, ivec, input, output, 0)); +} + +static krb5_error_code +k5_des3_make_key(krb5_const krb5_data *randombits, krb5_keyblock *key) +{ + int i; + + if (key->length != 24) + return(KRB5_BAD_KEYSIZE); + if (randombits->length != 21) + return(KRB5_CRYPTO_INTERNAL); + + key->magic = KV5M_KEYBLOCK; + key->length = 24; + + /* take the seven bytes, move them around into the top 7 bits of the + 8 key bytes, then compute the parity bits. Do this three times. */ + + for (i=0; i<3; i++) { + memcpy(key->contents+i*8, randombits->data+i*7, 7); + key->contents[i*8+7] = (((key->contents[i*8]&1)<<1) | + ((key->contents[i*8+1]&1)<<2) | + ((key->contents[i*8+2]&1)<<3) | + ((key->contents[i*8+3]&1)<<4) | + ((key->contents[i*8+4]&1)<<5) | + ((key->contents[i*8+5]&1)<<6) | + ((key->contents[i*8+6]&1)<<7)); + + mit_des_fixup_key_parity(key->contents+i*8); + } + + return(0); +} + +struct krb5_enc_provider krb5_enc_des3 = { + k5_des3_block_size, + k5_des3_keysize, + k5_des3_encrypt, + k5_des3_decrypt, + k5_des3_make_key +}; diff --git a/src/lib/crypto/enc_provider/enc_provider.h b/src/lib/crypto/enc_provider/enc_provider.h new file mode 100644 index 000000000..1488112ea --- /dev/null +++ b/src/lib/crypto/enc_provider/enc_provider.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" + +extern struct krb5_enc_provider krb5_enc_des; +extern struct krb5_enc_provider krb5_enc_des3; + + diff --git a/src/lib/crypto/hash_provider/Makefile.in b/src/lib/crypto/hash_provider/Makefile.in new file mode 100644 index 000000000..97f1ad423 --- /dev/null +++ b/src/lib/crypto/hash_provider/Makefile.in @@ -0,0 +1,30 @@ +thisconfigdir=./.. +BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) +CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../crc32 -I$(srcdir)/../md4 \ + -I$(srcdir)/../md5 -I$(srcdir)/../sha1 + +##DOS##BUILDTOP = ..\..\.. +##DOS##PREFIXDIR=hash_provider +##DOS##OBJFILE=..\hash_pro.lst +##WIN16##LIBNAME=..\crypto.lib + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf + +STLIBOBJS= crc32.o md4.o md5.o sha1.o + +OBJS= crc32.$(OBJEXT) md4.$(OBJEXT) md5.$(OBJEXT) sha1.$(OBJEXT) + +SRCS= $(srcdir)/crc32.c $(srcdir)/md4.c $(srcdir)/md5.c $(srcdir)/sha1.c + +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs + +includes:: depend + +depend:: $(SRCS) + +clean-unix:: clean-libobjs diff --git a/src/lib/crypto/hash_provider/crc32.c b/src/lib/crypto/hash_provider/crc32.c new file mode 100644 index 000000000..7c30b3d10 --- /dev/null +++ b/src/lib/crypto/hash_provider/crc32.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "crc-32.h" +#include "hash_provider.h" + +static void +k5_crc32_hash_size(size_t *output) +{ + *output = CRC32_CKSUM_LENGTH; +} + +static void +k5_crc32_block_size(size_t *output) +{ + *output = 1; +} + +static krb5_error_code +k5_crc32_hash(unsigned int icount, krb5_const krb5_data *input, + krb5_data *output) +{ + unsigned long c, cn; + int i; + + if (output->length != CRC32_CKSUM_LENGTH) + return(KRB5_CRYPTO_INTERNAL); + + c = 0; + for (i=0; idata[0] = c&0xff; + output->data[1] = (c>>8)&0xff; + output->data[2] = (c>>16)&0xff; + output->data[3] = (c>>24)&0xff; + + return(0); +} + +struct krb5_hash_provider krb5_hash_crc32 = { + k5_crc32_hash_size, + k5_crc32_block_size, + k5_crc32_hash +}; diff --git a/src/lib/crypto/hash_provider/hash_provider.h b/src/lib/crypto/hash_provider/hash_provider.h new file mode 100644 index 000000000..d97e3c3ce --- /dev/null +++ b/src/lib/crypto/hash_provider/hash_provider.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" + +extern struct krb5_hash_provider krb5_hash_crc32; +extern struct krb5_hash_provider krb5_hash_md4; +extern struct krb5_hash_provider krb5_hash_md5; +extern struct krb5_hash_provider krb5_hash_sha1; diff --git a/src/lib/crypto/hash_provider/md4.c b/src/lib/crypto/hash_provider/md4.c new file mode 100644 index 000000000..bfce845a4 --- /dev/null +++ b/src/lib/crypto/hash_provider/md4.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "rsa-md4.h" +#include "hash_provider.h" + +static void +k5_md4_hash_size(size_t *output) +{ + *output = RSA_MD4_CKSUM_LENGTH; +} + +static void +k5_md4_block_size(size_t *output) +{ + *output = 64; +} + +static krb5_error_code +k5_md4_hash(unsigned int icount, krb5_const krb5_data *input, + krb5_data *output) +{ + krb5_MD4_CTX ctx; + int i; + + if (output->length != RSA_MD4_CKSUM_LENGTH) + return(KRB5_CRYPTO_INTERNAL); + + krb5_MD4Init(&ctx); + for (i=0; idata, ctx.digest, RSA_MD4_CKSUM_LENGTH); + + return(0); +} + +struct krb5_hash_provider krb5_hash_md4 = { + k5_md4_hash_size, + k5_md4_block_size, + k5_md4_hash +}; diff --git a/src/lib/crypto/hash_provider/md5.c b/src/lib/crypto/hash_provider/md5.c new file mode 100644 index 000000000..98f934001 --- /dev/null +++ b/src/lib/crypto/hash_provider/md5.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "rsa-md5.h" +#include "hash_provider.h" + +static void +k5_md5_hash_size(size_t *output) +{ + *output = RSA_MD5_CKSUM_LENGTH; +} + +static void +k5_md5_block_size(size_t *output) +{ + *output = 64; +} + +static krb5_error_code +k5_md5_hash(unsigned int icount, krb5_const krb5_data *input, + krb5_data *output) +{ + krb5_MD5_CTX ctx; + int i; + + if (output->length != RSA_MD5_CKSUM_LENGTH) + return(KRB5_CRYPTO_INTERNAL); + + krb5_MD5Init(&ctx); + for (i=0; idata, ctx.digest, RSA_MD5_CKSUM_LENGTH); + + return(0); +} + +struct krb5_hash_provider krb5_hash_md5 = { + k5_md5_hash_size, + k5_md5_block_size, + k5_md5_hash +}; diff --git a/src/lib/crypto/hash_provider/sha1.c b/src/lib/crypto/hash_provider/sha1.c new file mode 100644 index 000000000..a7b886d5a --- /dev/null +++ b/src/lib/crypto/hash_provider/sha1.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "shs.h" +#include "hash_provider.h" + +static void +k5_sha1_hash_size(size_t *output) +{ + *output = SHS_DIGESTSIZE; +} + +static void +k5_sha1_block_size(size_t *output) +{ + *output = SHS_DATASIZE; +} + +static krb5_error_code +k5_sha1_hash(unsigned int icount, krb5_const krb5_data *input, + krb5_data *output) +{ + SHS_INFO ctx; + int i; + + if (output->length != SHS_DIGESTSIZE) + return(KRB5_CRYPTO_INTERNAL); + + shsInit(&ctx); + for (i=0; idata[i*4] = (ctx.digest[i]>>24)&0xff; + output->data[i*4+1] = (ctx.digest[i]>>16)&0xff; + output->data[i*4+2] = (ctx.digest[i]>>8)&0xff; + output->data[i*4+3] = ctx.digest[i]&0xff; + } + + return(0); +} + +struct krb5_hash_provider krb5_hash_sha1 = { + k5_sha1_hash_size, + k5_sha1_block_size, + k5_sha1_hash +}; diff --git a/src/lib/crypto/keyhash_provider/Makefile.in b/src/lib/crypto/keyhash_provider/Makefile.in new file mode 100644 index 000000000..86a4796cb --- /dev/null +++ b/src/lib/crypto/keyhash_provider/Makefile.in @@ -0,0 +1,50 @@ +thisconfigdir=./.. +BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) +CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des -I$(srcdir)/../md4 \ + -I$(srcdir)/../md5 + +##DOS##BUILDTOP = ..\..\.. +##DOS##PREFIXDIR=hashkey_provider +##DOS##OBJFILE=..\hk_pro.lst +##WIN16##LIBNAME=..\crypto.lib + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf + +STLIBOBJS= descbc.o k5_md4des.o k5_md5des.o + +OBJS= descbc.$(OBJEXT) k5_md4des.$(OBJEXT) k5_md5des.$(OBJEXT) + +SRCS= $(srcdir)/descbc.c $(srcdir)/k6_md4des.c $(srcdir)/k5_md5des.c + +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs + +includes:: depend + +depend:: $(SRCS) + +t_cksum4.o: t_cksum.c + $(CC) -DMD=4 $(CFLAGS) -o t_cksum4.o -c t_cksum.c + +t_cksum5.o: t_cksum.c + $(CC) -DMD=5 $(CFLAGS) -o t_cksum5.o -c t_cksum.c + +t_cksum4: t_cksum4.o $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o t_cksum4 t_cksum4.o $(KRB5_BASE_LIBS) + +t_cksum5: t_cksum5.o $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o t_cksum5 t_cksum5.o $(KRB5_BASE_LIBS) + +check-unix:: t_cksum4 t_cksum5 + $(RUN_SETUP) $(C)t_cksum4 "this is a test" + $(RUN_SETUP) $(C)t_cksum5 "this is a test" + +clean-unix:: + $(RM) t_cksum4 t_cksum4.o + $(RM) t_cksum5 t_cksum5.o + +clean-unix:: clean-libobjs diff --git a/src/lib/crypto/keyhash_provider/descbc.c b/src/lib/crypto/keyhash_provider/descbc.c new file mode 100644 index 000000000..3258cb3b4 --- /dev/null +++ b/src/lib/crypto/keyhash_provider/descbc.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "des_int.h" +#include "keyhash_provider.h" + +static mit_des_cblock mit_des_zeroblock[8] = {0,0,0,0,0,0,0,0}; + +static void +k5_descbc_hash_size(size_t *output) +{ + *output = 8; +} + +static krb5_error_code +k5_descbc_hash(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output) +{ + mit_des_key_schedule schedule; + int ret; + + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if ((input->length%8) != 0) + return(KRB5_BAD_MSIZE); + if (ivec && (ivec->length != 8)) + return(KRB5_CRYPTO_INTERNAL); + if (output->length != 8) + return(KRB5_CRYPTO_INTERNAL); + + switch (ret = mit_des_key_sched(key->contents, schedule)) { + case -1: + return(KRB5DES_BAD_KEYPAR); + case -2: + return(KRB5DES_WEAK_KEY); + } + + /* this has a return value, but it's useless to us */ + + mit_des_cbc_cksum(input->data, output->data, input->length, + schedule, ivec?ivec->data:(char *)mit_des_zeroblock); + + memset(schedule, 0, sizeof(schedule)); + + return(0); +} + +struct krb5_keyhash_provider krb5_keyhash_descbc = { + k5_descbc_hash_size, + k5_descbc_hash, + NULL +}; diff --git a/src/lib/crypto/keyhash_provider/k5_md4des.c b/src/lib/crypto/keyhash_provider/k5_md4des.c new file mode 100644 index 000000000..26e34030d --- /dev/null +++ b/src/lib/crypto/keyhash_provider/k5_md4des.c @@ -0,0 +1,197 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "des_int.h" +#include "rsa-md4.h" +#include "keyhash_provider.h" + +#define CONFLENGTH 8 + +/* Force acceptance of krb5-beta5 md4des checksum for now. */ +#define KRB5_MD4DES_BETA5_COMPAT + +static mit_des_cblock mit_des_zeroblock[8] = {0,0,0,0,0,0,0,0}; + +static void +k5_md4des_hash_size(size_t *output) +{ + *output = CONFLENGTH+RSA_MD4_CKSUM_LENGTH; +} + +/* des-cbc(xorkey, conf | rsa-md4(conf | data)) */ + +/* this could be done in terms of the md4 and des providers, but + that's less efficient, and there's no need for this to be generic */ + +static krb5_error_code +k5_md4des_hash(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output) +{ + krb5_error_code ret; + krb5_data data; + krb5_MD4_CTX ctx; + unsigned char conf[CONFLENGTH]; + unsigned char xorkey[8]; + int i; + mit_des_key_schedule schedule; + + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if (ivec) + return(KRB5_CRYPTO_INTERNAL); + if (output->length != (CONFLENGTH+RSA_MD4_CKSUM_LENGTH)) + return(KRB5_CRYPTO_INTERNAL); + + /* create the confouder */ + + data.length = CONFLENGTH; + data.data = conf; + if (ret = krb5_c_random_make_octets(/* XXX */ 0, &data)) + return(ret); + + /* create and schedule the encryption key */ + + memcpy(xorkey, key->contents, sizeof(xorkey)); + for (i=0; idata, input->length); + krb5_MD4Final(&ctx); + + /* construct the buffer to be encrypted */ + + memcpy(output->data, conf, CONFLENGTH); + memcpy(output->data+CONFLENGTH, ctx.digest, RSA_MD4_CKSUM_LENGTH); + + /* encrypt it, in place. this has a return value, but it's + always zero. */ + + mit_des_cbc_encrypt((krb5_pointer) output->data, + (krb5_pointer) output->data, output->length, + schedule, (char *) mit_des_zeroblock, 1); + + return(0); +} + +static krb5_error_code +k5_md4des_verify(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_const krb5_data *hash, + krb5_boolean *valid) +{ + krb5_error_code ret; + krb5_data data; + krb5_MD4_CTX ctx; + unsigned char plaintext[CONFLENGTH+RSA_MD4_CKSUM_LENGTH]; + unsigned char xorkey[8]; + int i; + mit_des_key_schedule schedule; + int compathash = 0; + + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if (ivec) + return(KRB5_CRYPTO_INTERNAL); + if (hash->length != (CONFLENGTH+RSA_MD4_CKSUM_LENGTH)) { +#ifdef KRB5_MD4DES_BETA5_COMPAT + if (hash->length != RSA_MD4_CKSUM_LENGTH) + return(KRB5_CRYPTO_INTERNAL); + else + compathash = 1; +#else + return(KRB5_CRYPTO_INTERNAL); +#endif + return(KRB5_CRYPTO_INTERNAL); + } + + /* create and schedule the encryption key */ + + memcpy(xorkey, key->contents, sizeof(xorkey)); + if (!compathash) { + for (i=0; idata, + (krb5_pointer) plaintext, hash->length, + schedule, (char *) mit_des_zeroblock, 0); + } else { + mit_des_cbc_encrypt((krb5_pointer) hash->data, + (krb5_pointer) plaintext, hash->length, + schedule, xorkey, 0); + } + + /* hash the confounder, then the input data */ + + krb5_MD4Init(&ctx); + if (!compathash) { + krb5_MD4Update(&ctx, plaintext, CONFLENGTH); + } + krb5_MD4Update(&ctx, input->data, input->length); + krb5_MD4Final(&ctx); + + /* compare the decrypted hash to the computed one */ + + if (!compathash) { + *valid = + (memcmp(plaintext+CONFLENGTH, ctx.digest, RSA_MD4_CKSUM_LENGTH) + == 0); + } else { + *valid = + (memcmp(plaintext, ctx.digest, RSA_MD4_CKSUM_LENGTH) == 0); + } + + memset(plaintext, 0, sizeof(plaintext)); + + return(0); +} + +struct krb5_keyhash_provider krb5_keyhash_md4des = { + k5_md4des_hash_size, + k5_md4des_hash, + k5_md4des_verify +}; diff --git a/src/lib/crypto/keyhash_provider/k5_md5des.c b/src/lib/crypto/keyhash_provider/k5_md5des.c new file mode 100644 index 000000000..d1ac65710 --- /dev/null +++ b/src/lib/crypto/keyhash_provider/k5_md5des.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "des_int.h" +#include "rsa-md5.h" +#include "keyhash_provider.h" + +#define CONFLENGTH 8 + +/* Force acceptance of krb5-beta5 md5des checksum for now. */ +#define KRB5_MD5DES_BETA5_COMPAT + +static mit_des_cblock mit_des_zeroblock[8] = {0,0,0,0,0,0,0,0}; + +static void +k5_md5des_hash_size(size_t *output) +{ + *output = CONFLENGTH+RSA_MD5_CKSUM_LENGTH; +} + +/* des-cbc(xorkey, conf | rsa-md5(conf | data)) */ + +/* this could be done in terms of the md5 and des providers, but + that's less efficient, and there's no need for this to be generic */ + +static krb5_error_code +k5_md5des_hash(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_data *output) +{ + krb5_error_code ret; + krb5_data data; + krb5_MD5_CTX ctx; + unsigned char conf[CONFLENGTH]; + unsigned char xorkey[8]; + int i; + mit_des_key_schedule schedule; + + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if (ivec) + return(KRB5_CRYPTO_INTERNAL); + if (output->length != (CONFLENGTH+RSA_MD5_CKSUM_LENGTH)) + return(KRB5_CRYPTO_INTERNAL); + + /* create the confouder */ + + data.length = CONFLENGTH; + data.data = conf; + if (ret = krb5_c_random_make_octets(/* XXX */ 0, &data)) + return(ret); + + /* create and schedule the encryption key */ + + memcpy(xorkey, key->contents, sizeof(xorkey)); + for (i=0; idata, input->length); + krb5_MD5Final(&ctx); + + /* construct the buffer to be encrypted */ + + memcpy(output->data, conf, CONFLENGTH); + memcpy(output->data+CONFLENGTH, ctx.digest, RSA_MD5_CKSUM_LENGTH); + + /* encrypt it, in place. this has a return value, but it's + always zero. */ + + mit_des_cbc_encrypt((krb5_pointer) output->data, + (krb5_pointer) output->data, output->length, + schedule, (char *) mit_des_zeroblock, 1); + + return(0); +} + +static krb5_error_code +k5_md5des_verify(krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, + krb5_const krb5_data *input, krb5_const krb5_data *hash, + krb5_boolean *valid) +{ + krb5_error_code ret; + krb5_data data; + krb5_MD5_CTX ctx; + unsigned char plaintext[CONFLENGTH+RSA_MD5_CKSUM_LENGTH]; + unsigned char xorkey[8]; + int i; + mit_des_key_schedule schedule; + int compathash = 0; + + if (key->length != 8) + return(KRB5_BAD_KEYSIZE); + if (ivec) + return(KRB5_CRYPTO_INTERNAL); + if (hash->length != (CONFLENGTH+RSA_MD5_CKSUM_LENGTH)) { +#ifdef KRB5_MD5DES_BETA5_COMPAT + if (hash->length != RSA_MD5_CKSUM_LENGTH) + return(KRB5_CRYPTO_INTERNAL); + else + compathash = 1; +#else + return(KRB5_CRYPTO_INTERNAL); +#endif + } + + /* create and schedule the encryption key */ + + memcpy(xorkey, key->contents, sizeof(xorkey)); + if (!compathash) { + for (i=0; idata, + (krb5_pointer) plaintext, hash->length, + schedule, (char *) mit_des_zeroblock, 0); + } else { + mit_des_cbc_encrypt((krb5_pointer) hash->data, + (krb5_pointer) plaintext, hash->length, + schedule, xorkey, 0); + } + + /* hash the confounder, then the input data */ + + krb5_MD5Init(&ctx); + if (!compathash) { + krb5_MD5Update(&ctx, plaintext, CONFLENGTH); + } + krb5_MD5Update(&ctx, input->data, input->length); + krb5_MD5Final(&ctx); + + /* compare the decrypted hash to the computed one */ + + if (!compathash) { + *valid = + (memcmp(plaintext+CONFLENGTH, ctx.digest, RSA_MD5_CKSUM_LENGTH) + == 0); + } else { + *valid = + (memcmp(plaintext, ctx.digest, RSA_MD5_CKSUM_LENGTH) == 0); + } + memset(plaintext, 0, sizeof(plaintext)); + + return(0); +} + +struct krb5_keyhash_provider krb5_keyhash_md5des = { + k5_md5des_hash_size, + k5_md5des_hash, + k5_md5des_verify +}; diff --git a/src/lib/crypto/keyhash_provider/keyhash_provider.h b/src/lib/crypto/keyhash_provider/keyhash_provider.h new file mode 100644 index 000000000..12ace4432 --- /dev/null +++ b/src/lib/crypto/keyhash_provider/keyhash_provider.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" + +extern struct krb5_keyhash_provider krb5_keyhash_descbc; +extern struct krb5_keyhash_provider krb5_keyhash_md4des; +extern struct krb5_keyhash_provider krb5_keyhash_md5des; diff --git a/src/lib/crypto/keyhash_provider/t_cksum.c b/src/lib/crypto/keyhash_provider/t_cksum.c new file mode 100644 index 000000000..c9eecc7ca --- /dev/null +++ b/src/lib/crypto/keyhash_provider/t_cksum.c @@ -0,0 +1,136 @@ +/* + * lib/crypto/md5/t_cksum.c + * + * Copyright 1995 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. 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. + * + */ + +/* + * t_cksum.c - Test checksum and checksum compatability for rsa-md[4,5]-des + */ + +#include "k5-int.h" + +#define MD5_K5BETA_COMPAT +#define MD4_K5BETA_COMPAT + +#if MD == 4 +extern struct krb5_keyhash_provider krb5_keyhash_md4des; +#define khp krb5_keyhash_md4des +#endif + +#if MD == 5 +extern struct krb5_keyhash_provider krb5_keyhash_md5des; +#define khp krb5_keyhash_md5des +#endif + +static void +print_checksum(text, number, message, checksum) + char *text; + int number; + char *message; + krb5_data *checksum; +{ + int i; + + printf("%s MD%d checksum(\"%s\") = ", text, number, message); + for (i=0; ilength; i++) + printf("%02x", (unsigned char) checksum->data[i]); + printf("\n"); +} + +/* + * Test the checksum verification of Old Style (tm) and correct RSA-MD[4,5]-DES + * checksums. + */ + +krb5_octet testkey[8] = { 0x45, 0x01, 0x49, 0x61, 0x58, 0x19, 0x1a, 0x3d }; + +int +main(argc, argv) + int argc; + char **argv; +{ + int msgindex; + krb5_boolean valid; + size_t length; + krb5_context kcontext; + krb5_keyblock keyblock; + krb5_error_code kret; + krb5_data plaintext, newstyle_checksum; + + /* this is a terrible seed, but that's ok for the test. */ + + plaintext.length = 8; + plaintext.data = testkey; + + krb5_c_random_seed(/* XXX */ 0, &plaintext); + + keyblock.enctype = ENCTYPE_DES_CBC_CRC; + keyblock.length = sizeof(testkey); + keyblock.contents = testkey; + + (*(khp.hash_size))(&length); + + newstyle_checksum.length = length; + + if (!(newstyle_checksum.data = (krb5_octet *) + malloc(newstyle_checksum.length))) { + printf("cannot get memory for new style checksum\n"); + return(ENOMEM); + } + for (msgindex = 1; msgindex < argc; msgindex++) { + plaintext.length = strlen(argv[msgindex]); + plaintext.data = argv[msgindex]; + + if ((kret = (*(khp.hash))(&keyblock, 0, &plaintext, &newstyle_checksum))) { + printf("krb5_calculate_checksum choked with %d\n", kret); + break; + } + print_checksum("correct", MD, argv[msgindex], &newstyle_checksum); + + if ((kret = (*(khp.verify))(&keyblock, 0, &plaintext, &newstyle_checksum, + &valid))) { + printf("verify on new checksum choked with %d\n", kret); + break; + } + if (!valid) { + printf("verify on new checksum failed\n"); + break; + } + printf("Verify succeeded for \"%s\"\n", argv[msgindex]); + + newstyle_checksum.data[0]++; + if ((kret = (*(khp.verify))(&keyblock, 0, &plaintext, &newstyle_checksum, + &valid))) { + printf("verify on new checksum choked with %d\n", kret); + break; + } + if (valid) { + printf("verify on new checksum succeeded, but shouldn't have\n"); + break; + } + printf("Verify of bad checksum OK for \"%s\"\n", argv[msgindex]); + kret = 0; + } + if (!kret) + printf("%d tests passed successfully for MD%d checksum\n", argc-1, MD); + return(kret); +} diff --git a/src/lib/crypto/old/Makefile.in b/src/lib/crypto/old/Makefile.in new file mode 100644 index 000000000..4bb754465 --- /dev/null +++ b/src/lib/crypto/old/Makefile.in @@ -0,0 +1,29 @@ +thisconfigdir=./.. +BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) +CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des + +##DOS##BUILDTOP = ..\..\.. +##DOS##PREFIXDIR=old +##DOS##OBJFILE=..\old.lst +##WIN16##LIBNAME=..\crypto.lib + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf + +STLIBOBJS= decrypt.o des_stringtokey.o encrypt.o + +OBJS= decrypt.$(OBJEXT) des_stringtokey.$(OBJEXT) encrypt.$(OBJEXT) + +SRCS= $(srcdir)/decrypt.c $(srcdir)/des_stringtokey.c $(srcdir)/encrypt.c + +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs + +includes:: depend + +depend:: $(SRCS) + +clean-unix:: clean-libobjs diff --git a/src/lib/crypto/old/decrypt.c b/src/lib/crypto/old/decrypt.c new file mode 100644 index 000000000..31fb6ce79 --- /dev/null +++ b/src/lib/crypto/old/decrypt.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "old.h" + +krb5_error_code +krb5_old_decrypt(enc, hash, key, usage, ivec, input, arg_output) + krb5_const struct krb5_enc_provider *enc; + krb5_const struct krb5_hash_provider *hash; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *ivec; + krb5_const krb5_data *input; + krb5_data *arg_output; +{ + krb5_error_code ret; + size_t blocksize, hashsize, plainsize; + unsigned char *plaintext, *cksumdata; + krb5_data output, cksum; + int alloced; + + (*(enc->block_size))(&blocksize); + (*(hash->hash_size))(&hashsize); + + plainsize = input->length - blocksize - hashsize; + + if (arg_output->length < plainsize) + return(KRB5_BAD_MSIZE); + + /* if there's enough space to work in the app buffer, use it, + otherwise allocate our own */ + + if ((cksumdata = (unsigned char *) malloc(hashsize)) == NULL) + return(ENOMEM); + + if (arg_output->length < input->length) { + output.length = input->length; + + if ((output.data = (krb5_octet *) malloc(output.length)) == NULL) { + free(cksumdata); + return(ENOMEM); + } + + alloced = 1; + } else { + output.length = input->length; + + output.data = arg_output->data; + + alloced = 0; + } + + /* decrypt it */ + + if (ret = ((*(enc->decrypt))(key, ivec, input, &output))) + goto cleanup; + + /* verify the checksum */ + + memcpy(cksumdata, output.data+blocksize, hashsize); + memset(output.data+blocksize, 0, hashsize); + + cksum.length = hashsize; + cksum.data = output.data+blocksize; + + if (ret = ((*(hash->hash))(1, &output, &cksum))) + goto cleanup; + + if (memcmp(cksum.data, output.data+blocksize, cksum.length) != 0) { + ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto cleanup; + } + + /* copy the plaintext around */ + + if (alloced) { + memcpy(arg_output->data, output.data+blocksize+hashsize, + plainsize); + } else { + memmove(arg_output->data, arg_output->data+blocksize+hashsize, + plainsize); + } + arg_output->length = plainsize; + + ret = 0; + +cleanup: + if (alloced) { + memset(output.data, 0, output.length); + free(output.data); + } + + memset(cksumdata, 0, hashsize); + free(cksumdata); + return(ret); +} + diff --git a/src/lib/crypto/old/des_stringtokey.c b/src/lib/crypto/old/des_stringtokey.c new file mode 100644 index 000000000..ed2b7339a --- /dev/null +++ b/src/lib/crypto/old/des_stringtokey.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "old.h" + +krb5_error_code +krb5_des_string_to_key(enc, string, salt, key) + krb5_const struct krb5_enc_provider *enc; + krb5_const krb5_data *string; + krb5_const krb5_data *salt; + krb5_keyblock *key; +{ + return(mit_des_string_to_key_int(key, string, salt)); +} diff --git a/src/lib/crypto/old/encrypt.c b/src/lib/crypto/old/encrypt.c new file mode 100644 index 000000000..9470d8a06 --- /dev/null +++ b/src/lib/crypto/old/encrypt.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "old.h" + +void +krb5_old_encrypt_length(enc, hash, inputlen, length) + krb5_const struct krb5_enc_provider *enc; + krb5_const struct krb5_hash_provider *hash; + size_t inputlen; + size_t *length; +{ + size_t blocksize, hashsize; + + (*(enc->block_size))(&blocksize); + (*(hash->hash_size))(&hashsize); + + *length = krb5_roundup(blocksize+hashsize+inputlen, blocksize); +} + +krb5_error_code +krb5_old_encrypt(enc, hash, key, usage, ivec, input, output) + krb5_const struct krb5_enc_provider *enc; + krb5_const struct krb5_hash_provider *hash; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *ivec; + krb5_const krb5_data *input; + krb5_data *output; +{ + krb5_error_code ret; + size_t blocksize, hashsize, enclen; + krb5_data datain, crcivec; + + (*(enc->block_size))(&blocksize); + (*(hash->hash_size))(&hashsize); + + krb5_old_encrypt_length(enc, hash, input->length, &enclen); + + if (output->length < enclen) + return(KRB5_BAD_MSIZE); + + output->length = enclen; + + /* fill in confounded, padded, plaintext buffer with zero checksum */ + + memset(output->data, 0, output->length); + + datain.length = blocksize; + datain.data = output->data; + + if (ret = krb5_c_random_make_octets(/* XXX */ 0, &datain)) + return(ret); + memcpy(output->data+blocksize+hashsize, input->data, input->length); + + /* compute the checksum */ + + datain.length = hashsize; + datain.data = output->data+blocksize; + + if (ret = ((*(hash->hash))(1, output, &datain))) + goto cleanup; + + /* encrypt it */ + + /* XXX this is gross, but I don't have much choice */ + if ((key->enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) { + crcivec.length = key->length; + crcivec.data = key->contents; + ivec = &crcivec; + } + + if (ret = ((*(enc->encrypt))(key, ivec, output, output))) + goto cleanup; + +cleanup: + if (ret) + memset(output->data, 0, output->length); + + return(ret); +} diff --git a/src/lib/crypto/old/old.h b/src/lib/crypto/old/old.h new file mode 100644 index 000000000..9c7abc2fa --- /dev/null +++ b/src/lib/crypto/old/old.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" + +void krb5_old_encrypt_length +KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc, + krb5_const struct krb5_hash_provider *hash, + size_t input, size_t *length)); + +krb5_error_code krb5_old_encrypt +KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc, + krb5_const struct krb5_hash_provider *hash, + krb5_const krb5_keyblock *key, krb5_keyusage usage, + krb5_const krb5_data *ivec, krb5_const krb5_data *input, + krb5_data *output)); + +krb5_error_code krb5_old_decrypt +KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc, + krb5_const struct krb5_hash_provider *hash, + krb5_const krb5_keyblock *key, krb5_keyusage usage, + krb5_const krb5_data *ivec, krb5_const krb5_data *input, + krb5_data *arg_output)); + +krb5_error_code krb5_des_string_to_key +KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc, + krb5_const krb5_data *string, krb5_const krb5_data *salt, + krb5_keyblock *key)); diff --git a/src/lib/crypto/raw/Makefile.in b/src/lib/crypto/raw/Makefile.in new file mode 100644 index 000000000..ebff787c1 --- /dev/null +++ b/src/lib/crypto/raw/Makefile.in @@ -0,0 +1,29 @@ +thisconfigdir=./.. +BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) +CFLAGS = $(CCOPTS) $(DEFS) + +##DOS##BUILDTOP = ..\..\.. +##DOS##PREFIXDIR=raw +##DOS##OBJFILE=..\raw.lst +##WIN16##LIBNAME=..\crypto.lib + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf + +STLIBOBJS= decrypt.o encrypt.o + +OBJS= decrypt.$(OBJEXT) encrypt.$(OBJEXT) + +SRCS= $(srcdir)/decrypt.c $(srcdir)/encrypt.c + +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs + +includes:: depend + +depend:: $(SRCS) + +clean-unix:: clean-libobjs diff --git a/src/lib/crypto/raw/decrypt.c b/src/lib/crypto/raw/decrypt.c new file mode 100644 index 000000000..2c9c2d7b6 --- /dev/null +++ b/src/lib/crypto/raw/decrypt.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "raw.h" + +krb5_error_code +krb5_raw_decrypt(enc, hash, key, usage, ivec, input, output) + krb5_const struct krb5_enc_provider *enc; + krb5_const struct krb5_hash_provider *hash; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *ivec; + krb5_const krb5_data *input; + krb5_data *output; +{ + return((*(enc->decrypt))(key, ivec, input, output)); +} diff --git a/src/lib/crypto/raw/encrypt.c b/src/lib/crypto/raw/encrypt.c new file mode 100644 index 000000000..d1a84ba8c --- /dev/null +++ b/src/lib/crypto/raw/encrypt.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "raw.h" + +void +krb5_raw_encrypt_length(enc, hash, inputlen, length) + krb5_const struct krb5_enc_provider *enc; + krb5_const struct krb5_hash_provider *hash; + size_t inputlen; + size_t *length; +{ + size_t blocksize; + + (*(enc->block_size))(&blocksize); + + *length = krb5_roundup(inputlen, blocksize); +} + +krb5_error_code +krb5_raw_encrypt(enc, hash, key, usage, ivec, input, output) + krb5_const struct krb5_enc_provider *enc; + krb5_const struct krb5_hash_provider *hash; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *ivec; + krb5_const krb5_data *input; + krb5_data *output; +{ + return((*(enc->encrypt))(key, ivec, input, output)); +} diff --git a/src/lib/crypto/raw/raw.h b/src/lib/crypto/raw/raw.h new file mode 100644 index 000000000..5cfeae67e --- /dev/null +++ b/src/lib/crypto/raw/raw.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * 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 FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" + +void krb5_raw_encrypt_length +KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc, + krb5_const struct krb5_hash_provider *hash, + size_t input, size_t *length)); + +krb5_error_code krb5_raw_encrypt +KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc, + krb5_const struct krb5_hash_provider *hash, + krb5_const krb5_keyblock *key, krb5_keyusage usage, + krb5_const krb5_data *ivec, krb5_const krb5_data *input, + krb5_data *output)); + +krb5_error_code krb5_raw_decrypt +KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc, + krb5_const struct krb5_hash_provider *hash, + krb5_const krb5_keyblock *key, krb5_keyusage usage, + krb5_const krb5_data *ivec, krb5_const krb5_data *input, + krb5_data *arg_output)); diff --git a/src/lib/crypto/sha1/Makefile.in b/src/lib/crypto/sha1/Makefile.in new file mode 100644 index 000000000..abc479366 --- /dev/null +++ b/src/lib/crypto/sha1/Makefile.in @@ -0,0 +1,44 @@ +thisconfigdir=./.. +BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) +CFLAGS = $(CCOPTS) $(DEFS) + +##DOS##BUILDTOP = ..\..\.. +##DOS##PREFIXDIR=sha1 +##DOS##OBJFILE=..\sha2.lst +##WIN16##LIBNAME=..\crypto.lib + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf + +STLIBOBJS= shs.o + +OBJS= shs.$(OBJEXT) + +SRCS= $(srcdir)/shs.c + +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs + +includes:: depend + +depend:: $(SRCS) + +t_shs: t_shs.o shs.o + $(CC) $(CFLAGS) $(LDFLAGS) -o t_shs t_shs.o shs.o + +t_shs.exe: + $(CC) $(CFLAGS2) -o t_shs.exe t_shs.c shs.c + +check-unix:: t_shs + $(C)t_shs -x + +check-windows:: t_shs$(EXEEXT) + $(C)t_shs$(EXEEXT) -x + +clean:: + $(RM) t_shs$(EXEEXT) t_shs.$(OBJEXT) + +clean-unix:: clean-libobjs diff --git a/src/lib/crypto/sha1/shs.c b/src/lib/crypto/sha1/shs.c new file mode 100644 index 000000000..a5b5a53d5 --- /dev/null +++ b/src/lib/crypto/sha1/shs.c @@ -0,0 +1,400 @@ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#include +#include "shs.h" + +/* The SHS f()-functions. The f1 and f3 functions can be optimized to + save one boolean operation each - thanks to Rich Schroeppel, + rcs@cs.arizona.edu for discovering this */ + +#define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */ +#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */ +#define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */ +#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */ + +/* The SHS Mysterious Constants */ + +#define K1 0x5A827999L /* Rounds 0-19 */ +#define K2 0x6ED9EBA1L /* Rounds 20-39 */ +#define K3 0x8F1BBCDCL /* Rounds 40-59 */ +#define K4 0xCA62C1D6L /* Rounds 60-79 */ + +/* SHS initial values */ + +#define h0init 0x67452301L +#define h1init 0xEFCDAB89L +#define h2init 0x98BADCFEL +#define h3init 0x10325476L +#define h4init 0xC3D2E1F0L + +/* Note that it may be necessary to add parentheses to these macros if they + are to be called with expressions as arguments */ + +/* 32-bit rotate left - kludged with shifts */ + +#define ROTL(n,X) (((X) << (n)) & 0xffffffff | ((X) >> (32 - n))) + +/* The initial expanding function. The hash function is defined over an + 80-word expanded input array W, where the first 16 are copies of the input + data, and the remaining 64 are defined by + + W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ] + + This implementation generates these values on the fly in a circular + buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this + optimization. + + The updated SHS changes the expanding function by adding a rotate of 1 + bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor + for this information */ + +#ifdef NEW_SHS +#define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \ + W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ))) +#else +#define expand(W,i) ( W[ i & 15 ] ^= W[ (i - 14) & 15 ] ^ \ + W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) +#endif /* NEW_SHS */ + +/* The prototype SHS sub-round. The fundamental sub-round is: + + a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data; + b' = a; + c' = ROTL( 30, b ); + d' = c; + e' = d; + + but this is implemented by unrolling the loop 5 times and renaming the + variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration. + This code is then replicated 20 times for each of the 4 functions, using + the next 20 values from the W[] array each time */ + +#define subRound(a, b, c, d, e, f, k, data) \ + ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, \ + e &= 0xffffffff, b = ROTL( 30, b ) ) + +/* Initialize the SHS values */ + +void shsInit(shsInfo) + SHS_INFO *shsInfo; +{ + /* Set the h-vars to their initial values */ + shsInfo->digest[ 0 ] = h0init; + shsInfo->digest[ 1 ] = h1init; + shsInfo->digest[ 2 ] = h2init; + shsInfo->digest[ 3 ] = h3init; + shsInfo->digest[ 4 ] = h4init; + + /* Initialise bit count */ + shsInfo->countLo = shsInfo->countHi = 0; +} + +/* Perform the SHS transformation. Note that this code, like MD5, seems to + break some optimizing compilers due to the complexity of the expressions + and the size of the basic block. It may be necessary to split it into + sections, e.g. based on the four subrounds + + Note that this corrupts the shsInfo->data area */ + +static void SHSTransform KRB5_PROTOTYPE((LONG *digest, LONG *data)); + +static +void SHSTransform(digest, data) + LONG *digest; + LONG *data; +{ + LONG A, B, C, D, E; /* Local vars */ + LONG eData[ 16 ]; /* Expanded data */ + + /* Set up first buffer and local data buffer */ + A = digest[ 0 ]; + B = digest[ 1 ]; + C = digest[ 2 ]; + D = digest[ 3 ]; + E = digest[ 4 ]; + memcpy(eData, data, sizeof (eData)); + + /* Heavy mangling, in 4 sub-rounds of 20 interations each. */ + subRound( A, B, C, D, E, f1, K1, eData[ 0 ] ); + subRound( E, A, B, C, D, f1, K1, eData[ 1 ] ); + subRound( D, E, A, B, C, f1, K1, eData[ 2 ] ); + subRound( C, D, E, A, B, f1, K1, eData[ 3 ] ); + subRound( B, C, D, E, A, f1, K1, eData[ 4 ] ); + subRound( A, B, C, D, E, f1, K1, eData[ 5 ] ); + subRound( E, A, B, C, D, f1, K1, eData[ 6 ] ); + subRound( D, E, A, B, C, f1, K1, eData[ 7 ] ); + subRound( C, D, E, A, B, f1, K1, eData[ 8 ] ); + subRound( B, C, D, E, A, f1, K1, eData[ 9 ] ); + subRound( A, B, C, D, E, f1, K1, eData[ 10 ] ); + subRound( E, A, B, C, D, f1, K1, eData[ 11 ] ); + subRound( D, E, A, B, C, f1, K1, eData[ 12 ] ); + subRound( C, D, E, A, B, f1, K1, eData[ 13 ] ); + subRound( B, C, D, E, A, f1, K1, eData[ 14 ] ); + subRound( A, B, C, D, E, f1, K1, eData[ 15 ] ); + subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) ); + subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) ); + subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) ); + subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) ); + + subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) ); + subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) ); + subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) ); + subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) ); + subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) ); + subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) ); + subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) ); + subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) ); + subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) ); + subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) ); + subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) ); + subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) ); + subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) ); + subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) ); + subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) ); + subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) ); + subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) ); + subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) ); + subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) ); + subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) ); + + subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) ); + subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) ); + subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) ); + subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) ); + subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) ); + subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) ); + subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) ); + subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) ); + subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) ); + subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) ); + subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) ); + subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) ); + subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) ); + subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) ); + subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) ); + subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) ); + subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) ); + subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) ); + subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) ); + subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) ); + + subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) ); + subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) ); + subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) ); + subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) ); + subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) ); + subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) ); + subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) ); + subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) ); + subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) ); + subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) ); + subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) ); + subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) ); + subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) ); + subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) ); + subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) ); + subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) ); + subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) ); + subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) ); + subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) ); + subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) ); + + /* Build message digest */ + digest[ 0 ] += A; + digest[ 0 ] &= 0xffffffff; + digest[ 1 ] += B; + digest[ 1 ] &= 0xffffffff; + digest[ 2 ] += C; + digest[ 2 ] &= 0xffffffff; + digest[ 3 ] += D; + digest[ 3 ] &= 0xffffffff; + digest[ 4 ] += E; + digest[ 4 ] &= 0xffffffff; +} + +/* When run on a little-endian CPU we need to perform byte reversal on an + array of longwords. It is possible to make the code endianness- + independant by fiddling around with data at the byte level, but this + makes for very slow code, so we rely on the user to sort out endianness + at compile time */ + +void longReverse( LONG *buffer, int byteCount ) +{ + LONG value; + static int init = 0; + char *cp; + + switch (init) { + case 0: + init=1; + cp = (char *) &init; + if (*cp == 1) { + init=2; + break; + } + init=1; + /* fall through - MSB */ + case 1: + return; + } + + byteCount /= sizeof( LONG ); + while( byteCount-- ) { + value = *buffer; + value = ( ( value & 0xFF00FF00L ) >> 8 ) | + ( ( value & 0x00FF00FFL ) << 8 ); + *buffer++ = ( value << 16 ) | ( value >> 16 ); + } +} + +/* Update SHS for a block of data */ + +void shsUpdate(shsInfo, buffer, count) + SHS_INFO *shsInfo; + BYTE *buffer; + int count; +{ + LONG tmp; + int dataCount, canfill; + LONG *lp; + + /* Update bitcount */ + tmp = shsInfo->countLo; + shsInfo->countLo = tmp + (((LONG) count) << 3 ); + if ((shsInfo->countLo &= 0xffffffff) < tmp) + shsInfo->countHi++; /* Carry from low to high */ + shsInfo->countHi += count >> 29; + + /* Get count of bytes already in data */ + dataCount = (int) (tmp >> 3) & 0x3F; + + /* Handle any leading odd-sized chunks */ + if (dataCount) { + lp = shsInfo->data + dataCount / 4; + canfill = (count >= dataCount); + dataCount = SHS_DATASIZE - dataCount; + + if (dataCount % 4) { + /* Fill out a full 32 bit word first if needed -- this + is not very efficient (computed shift amount), + but it shouldn't happen often. */ + while (dataCount % 4 && count > 0) { + *lp |= (LONG) *buffer++ << ((3 - dataCount++ % 4) * 8); + count--; + } + lp++; + } + while (lp < shsInfo->data + 16) { + *lp = (LONG) *buffer++ << 24; + *lp |= (LONG) *buffer++ << 16; + *lp |= (LONG) *buffer++ << 8; + *lp++ |= (LONG) *buffer++; + if ((count -= 4) < 4 && lp < shsInfo->data + 16) { + *lp = 0; + switch (count % 4) { + case 3: + *lp |= (LONG) buffer[2] << 8; + case 2: + *lp |= (LONG) buffer[1] << 16; + case 1: + *lp |= (LONG) buffer[0] << 24; + } + break; + count = 0; + } + } + if (canfill) { + SHSTransform(shsInfo->digest, shsInfo->data); + } + } + + /* Process data in SHS_DATASIZE chunks */ + while (count >= SHS_DATASIZE) { + lp = shsInfo->data; + while (lp < shsInfo->data + 16) { + *lp = ((LONG) *buffer++) << 24; + *lp |= ((LONG) *buffer++) << 16; + *lp |= ((LONG) *buffer++) << 8; + *lp++ |= (LONG) *buffer++; + } + SHSTransform(shsInfo->digest, shsInfo->data); + count -= SHS_DATASIZE; + } + + if (count > 0) { + lp = shsInfo->data; + while (count > 4) { + *lp = ((LONG) *buffer++) << 24; + *lp |= ((LONG) *buffer++) << 16; + *lp |= ((LONG) *buffer++) << 8; + *lp++ |= (LONG) *buffer++; + count -= 4; + } + *lp = 0; + switch (count % 4) { + case 0: + *lp |= ((LONG) buffer[3]); + case 3: + *lp |= ((LONG) buffer[2]) << 8; + case 2: + *lp |= ((LONG) buffer[1]) << 16; + case 1: + *lp |= ((LONG) buffer[0]) << 24; + } + } +} + +/* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern + 1 0* (64-bit count of bits processed, MSB-first) */ + +void shsFinal(shsInfo) + SHS_INFO *shsInfo; +{ + int count; + LONG *lp; + BYTE *dataPtr; + + /* Compute number of bytes mod 64 */ + count = (int) shsInfo->countLo; + count = (count >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + lp = shsInfo->data + count / 4; + switch (count % 4) { + case 3: + *lp++ |= (LONG) 0x80; + break; + case 2: + *lp++ |= (LONG) 0x80 << 8; + break; + case 1: + *lp++ |= (LONG) 0x80 << 16; + break; + case 0: + *lp++ = (LONG) 0x80 << 24; + } + + /* at this point, lp can point *past* shsInfo->data. If it points + there, just Transform and reset. If it points to the last + element, set that to zero. This pads out to 64 bytes if not + enough room for length words */ + + if (lp == shsInfo->data + 15) + *lp++ = 0; + + if (lp == shsInfo->data + 16) { + SHSTransform(shsInfo->digest, shsInfo->data); + lp = shsInfo->data; + } + + /* Pad out to 56 bytes */ + while (lp < shsInfo->data + 14) + *lp++ = 0; + + /* Append length in bits and transform */ + *lp++ = shsInfo->countHi; + *lp++ = shsInfo->countLo; + SHSTransform(shsInfo->digest, shsInfo->data); +} diff --git a/src/lib/crypto/sha1/shs.h b/src/lib/crypto/sha1/shs.h new file mode 100644 index 000000000..01acddb82 --- /dev/null +++ b/src/lib/crypto/sha1/shs.h @@ -0,0 +1,59 @@ +#ifndef _SHS_DEFINED + +#include + +#define _SHS_DEFINED + +/* Some useful types */ + +typedef krb5_octet BYTE; + +/* Old DOS/Windows compilers are case-insensitive */ +#if !defined(_MSDOS) && !defined(_WIN32) +typedef krb5_ui_4 LONG; +#endif + + +/* Define the following to use the updated SHS implementation */ +#define NEW_SHS /**/ + +/* The SHS block size and message digest sizes, in bytes */ + +#define SHS_DATASIZE 64 +#define SHS_DIGESTSIZE 20 + +/* The structure for storing SHS info */ + +typedef struct { + LONG digest[ 5 ]; /* Message digest */ + LONG countLo, countHi; /* 64-bit bit count */ + LONG data[ 16 ]; /* SHS data buffer */ + } SHS_INFO; + +/* Message digest functions (shs.c) */ +void shsInit + KRB5_PROTOTYPE((SHS_INFO *shsInfo)); +void shsUpdate + KRB5_PROTOTYPE((SHS_INFO *shsInfo, BYTE *buffer, int count)); +void shsFinal + KRB5_PROTOTYPE((SHS_INFO *shsInfo)); + + +/* Keyed Message digest functions (hmac_sha.c) */ +krb5_error_code hmac_sha + KRB5_PROTOTYPE((krb5_octet *text, + int text_len, + krb5_octet *key, + int key_len, + krb5_octet *digest)); + + +#define NIST_SHA_CKSUM_LENGTH SHS_DIGESTSIZE +#define HMAC_SHA_CKSUM_LENGTH SHS_DIGESTSIZE + + +extern krb5_checksum_entry + nist_sha_cksumtable_entry, + hmac_sha_cksumtable_entry; + +#endif /* _SHS_DEFINED */ diff --git a/src/lib/crypto/sha1/t_shs.c b/src/lib/crypto/sha1/t_shs.c new file mode 100644 index 000000000..da55992ec --- /dev/null +++ b/src/lib/crypto/sha1/t_shs.c @@ -0,0 +1,132 @@ +/**************************************************************************** +* * +* SHS Test Code * +* * +****************************************************************************/ + +#include +#include +#include +#include "shs.h" + +/* Test the SHS implementation */ + +#ifdef NEW_SHS + +static LONG shsTestResults[][ 5 ] = { + { 0xA9993E36L, 0x4706816AL, 0xBA3E2571L, 0x7850C26CL, 0x9CD0D89DL, }, + { 0x84983E44L, 0x1C3BD26EL, 0xBAAE4AA1L, 0xF95129E5L, 0xE54670F1L, }, + { 0x34AA973CL, 0xD4C4DAA4L, 0xF61EEB2BL, 0xDBAD2731L, 0x6534016FL, } + }; + +#else + +static LONG shsTestResults[][ 5 ] = { + { 0x0164B8A9L, 0x14CD2A5EL, 0x74C4F7FFL, 0x082C4D97L, 0xF1EDF880L }, + { 0xD2516EE1L, 0xACFA5BAFL, 0x33DFC1C4L, 0x71E43844L, 0x9EF134C8L }, + { 0x3232AFFAL, 0x48628A26L, 0x653B5AAAL, 0x44541FD9L, 0x0D690603L } + }; +#endif /* NEW_SHS */ + +static int compareSHSresults(shsInfo, shsTestLevel) +SHS_INFO *shsInfo; +int shsTestLevel; +{ + int i, fail = 0; + + /* Compare the returned digest and required values */ + for( i = 0; i < 5; i++ ) + if( shsInfo->digest[ i ] != shsTestResults[ shsTestLevel ][ i ] ) + fail = 1; + if (fail) { + printf("\nExpected: "); + for (i = 0; i < 5; i++) { + printf("%8.8lx ", shsTestResults[shsTestLevel][i]); + } + printf("\nGot: "); + for (i = 0; i < 5; i++) { + printf("%8.8lx ", shsInfo->digest[i]); + } + printf("\n"); + return( -1 ); + } + return( 0 ); +} + +main() +{ + SHS_INFO shsInfo; + unsigned int i; + time_t secondCount; + BYTE data[ 200 ]; + + /* Make sure we've got the endianness set right. If the machine is + big-endian (up to 64 bits) the following value will be signed, + otherwise it will be unsigned. Unfortunately we can't test for odd + things like middle-endianness without knowing the size of the data + types */ + + /* Test SHS against values given in SHS standards document */ + printf( "Running SHS test 1 ... " ); + shsInit( &shsInfo ); + shsUpdate( &shsInfo, ( BYTE * ) "abc", 3 ); + shsFinal( &shsInfo ); + if( compareSHSresults( &shsInfo, 0 ) == -1 ) + { + putchar( '\n' ); + puts( "SHS test 1 failed" ); + exit( -1 ); + } +#ifdef NEW_SHS + puts( "passed, result= A9993E364706816ABA3E25717850C26C9CD0D89D" ); +#else + puts( "passed, result= 0164B8A914CD2A5E74C4F7FF082C4D97F1EDF880" ); +#endif /* NEW_SHS */ + + printf( "Running SHS test 2 ... " ); + shsInit( &shsInfo ); + shsUpdate( &shsInfo, ( BYTE * ) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56 ); + shsFinal( &shsInfo ); + if( compareSHSresults( &shsInfo, 1 ) == -1 ) + { + putchar( '\n' ); + puts( "SHS test 2 failed" ); + exit( -1 ); + } +#ifdef NEW_SHS + puts( "passed, result= 84983E441C3BD26EBAAE4AA1F95129E5E54670F1" ); +#else + puts( "passed, result= D2516EE1ACFA5BAF33DFC1C471E438449EF134C8" ); +#endif /* NEW_SHS */ + + printf( "Running SHS test 3 ... " ); + shsInit( &shsInfo ); + for( i = 0; i < 15625; i++ ) + shsUpdate( &shsInfo, ( BYTE * ) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64 ); + shsFinal( &shsInfo ); + if( compareSHSresults( &shsInfo, 2 ) == -1 ) + { + putchar( '\n' ); + puts( "SHS test 3 failed" ); + exit( -1 ); + } +#ifdef NEW_SHS + puts( "passed, result= 34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" ); +#else + puts( "passed, result= 3232AFFA48628A26653B5AAA44541FD90D690603" ); +#endif /* NEW_SHS */ + +#if 0 + printf( "\nTesting speed for 100MB data... " ); + shsInit( &shsInfo ); + secondCount = time( NULL ); + for( i = 0; i < 500000U; i++ ) + shsUpdate( &shsInfo, data, 200 ); + secondCount = time( NULL ) - secondCount; + printf( "done. Time = %ld seconds, %ld kbytes/second.\n", \ + secondCount, 100500L / secondCount ); +#endif + + puts( "\nAll SHS tests passed" ); + exit( 0 ); +} -- 2.26.2