summaryrefslogtreecommitdiffstats
path: root/src/lib/des425
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/des425')
-rw-r--r--src/lib/des425/ChangeLog7
-rw-r--r--src/lib/des425/Makefile.in2
-rw-r--r--src/lib/des425/pcbc_encrypt.c471
3 files changed, 239 insertions, 241 deletions
diff --git a/src/lib/des425/ChangeLog b/src/lib/des425/ChangeLog
index d2fc93f3db..cf76d76372 100644
--- a/src/lib/des425/ChangeLog
+++ b/src/lib/des425/ChangeLog
@@ -1,3 +1,10 @@
+Thu Nov 3 18:29:10 1994 Mark Eichin (eichin@cygnus.com)
+
+ * pcbc_encrypt.c: moved from f_pcbc.c in lib/crypto/des, and
+ inlined proper des.h to avoid confusion in names.
+ * Makefile.in: add -I to CFLAGS to get f_tables.h from
+ lib/crypto/des as well.
+
Wed Oct 26 14:23:36 1994 (tytso@rsx-11)
* Makefile.in (check):
diff --git a/src/lib/des425/Makefile.in b/src/lib/des425/Makefile.in
index 389a379a7b..650c8dded2 100644
--- a/src/lib/des425/Makefile.in
+++ b/src/lib/des425/Makefile.in
@@ -1,4 +1,4 @@
-CFLAGS = $(CCOPTS) $(DEFS)
+CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../crypto/des
LDFLAGS = -g
all:: $(OBJS)
diff --git a/src/lib/des425/pcbc_encrypt.c b/src/lib/des425/pcbc_encrypt.c
index 00d9644ee1..45de20bc05 100644
--- a/src/lib/des425/pcbc_encrypt.c
+++ b/src/lib/des425/pcbc_encrypt.c
@@ -1,261 +1,252 @@
/*
* lib/des425/pcbc_encrypt.c
- *
- * Copyright 1985, 1986, 1987, 1988,1990 by the Massachusetts Institute
- * of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. 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.
- *
- *
- * These routines perform encryption and decryption using the DES
- * private key algorithm, or else a subset of it-- fewer inner loops.
- * ( AUTH_DES_ITER defaults to 16, may be less)
- *
- * Under U.S. law, this software may not be exported outside the US
- * without license from the U.S. Commerce department.
- *
- * The key schedule is passed as an arg, as well as the cleartext or
- * ciphertext. The cleartext and ciphertext should be in host order.
- *
- * These routines form the library interface to the des facilities.
- *
- * spm 8/85 MIT project athena
*/
-
-#include <stdio.h>
-#include "des.h"
-
-extern int mit_des_debug;
-extern int mit_des_debug_print();
-
/*
- * pcbc_encrypt is an "error propagation chaining" encrypt operation
- * for DES, similar to CBC, but that, on encryption, "xor"s the
- * plaintext of block N with the ciphertext resulting from block N,
- * then "xor"s that result with the plaintext of block N+1 prior to
- * encrypting block N+1. (decryption the appropriate inverse. This
- * "pcbc" mode propagates a single bit error anywhere in either the
- * cleartext or ciphertext chain all the way through to the end. In
- * contrast, CBC mode limits a single bit error in the ciphertext to
- * affect only the current (8byte) block and the subsequent block.
- *
- * performs pcbc error-propagation chaining operation by xor-ing block
- * N+1 with both the plaintext (block N) and the ciphertext from block
- * N. Either encrypts from cleartext to ciphertext, if encrypt != 0
- * or decrypts from ciphertext to cleartext, if encrypt == 0
- *
- * NOTE-- the output is ALWAYS an multiple of 8 bytes long. If not
- * enough space was provided, your program will get trashed.
- *
- * For encryption, the cleartext string is null padded, at the end, to
- * an integral multiple of eight bytes.
- *
- * For decryption, the ciphertext will be used in integral multiples
- * of 8 bytes, but only the first "length" bytes returned into the
- * cleartext.
- *
- * This is NOT a standard mode of operation.
+ * Copyright (c) 1990 Dennis Ferguson. All rights reserved.
*
+ * Commercial use is permitted only if products which are derived from
+ * or include this software are made available for purchase and/or use
+ * in Canada. Otherwise, redistribution and use in source and binary
+ * forms are permitted.
*/
-int
-des_pcbc_encrypt(in,out,length,key,iv,encrypt)
- mit_des_cblock *in; /* >= length bytes of inputtext */
- mit_des_cblock *out; /* >= length bytes of outputtext */
- register long length; /* in bytes */
- int encrypt; /* 0 ==> decrypt, else encrypt */
- des_key_schedule key; /* precomputed key schedule */
- mit_des_cblock *iv; /* 8 bytes of ivec */
-{
- register unsigned long *input = (unsigned long *) in;
- register unsigned long *output = (unsigned long *) out;
- register unsigned long *ivec = (unsigned long *) iv;
+/*
+ * des_pcbc_encrypt.c - encrypt a string of characters in error propagation mode
+ */
- unsigned long i,j;
- static unsigned long t_input[2];
- static unsigned long t_output[2];
- static unsigned char *t_in_p;
- static unsigned long xor_0, xor_1;
+/*
+ * copy of include/des.h to avoid collision with local one
+ */
+#include <kerberosIV/mit-copyright.h>
+#include <krb5/osconf.h>
- t_in_p = (unsigned char *) t_input;
- if (encrypt) {
-#ifdef MUSTALIGN
- if ((long) ivec & 3) {
- memcpy((char *)&xor_0, (char *)ivec++,sizeof(xor_0));
- memcpy((char *)&xor_1, (char *)ivec, sizeof(xor_1));
- }
- else
+#ifndef KRB_INT32
+#define KRB_INT32 long
#endif
- {
- xor_0 = *ivec++;
- xor_1 = *ivec;
- }
-
- for (i = 0; length > 0; i++, length -= 8) {
- /* get input */
-#ifdef MUSTALIGN
- if ((long) input & 3) {
- memcpy((char *)&t_input[0], (char *)input, sizeof(t_input[0]));
- memcpy((char *)&t_input[1], (char *)(input+1),sizeof(t_input[1]));
- }
- else
+#ifndef KRB_UINT32
+#define KRB_UINT32 unsigned KRB_INT32
#endif
- {
- t_input[0] = *input;
- t_input[1] = *(input+1);
- }
-
- /* zero pad */
- if (length < 8) {
- for (j = length; j <= 7; j++)
- *(t_in_p+j)= 0;
- }
-#ifdef DEBUG
- if (mit_des_debug)
- mit_des_debug_print("clear",length,t_input[0],t_input[1]);
+typedef unsigned char des_cblock[8]; /* crypto-block size */
+/* Key schedule */
+typedef struct des_ks_struct { union { KRB_INT32 pad; des_cblock _;} __; } des_key_schedule[16];
+
+#define DES_KEY_SZ (sizeof(des_cblock))
+#define DES_ENCRYPT 1
+#define DES_DECRYPT 0
+
+#ifndef NCOMPAT
+#define C_Block des_cblock
+#define Key_schedule des_key_schedule
+#define ENCRYPT DES_ENCRYPT
+#define DECRYPT DES_DECRYPT
+#define KEY_SZ DES_KEY_SZ
+#define string_to_key des_string_to_key
+#define read_pw_string des_read_pw_string
+#define random_key des_random_key
+#define pcbc_encrypt des_pcbc_encrypt
+#define key_sched des_key_sched
+#define cbc_encrypt des_cbc_encrypt
+#define cbc_cksum des_cbc_cksum
+#define C_Block_print des_cblock_print
+#define quad_cksum des_quad_cksum
+typedef struct des_ks_struct bit_64;
#endif
- /* do the xor for cbc into the temp */
- t_input[0] ^= xor_0 ;
- t_input[1] ^= xor_1 ;
- /* encrypt */
- (void) des_ecb_encrypt(t_input,t_output,key,encrypt);
- /*
- * We want to XOR with both the plaintext and ciphertext
- * of the previous block, before we write the output, in
- * case both input and output are the same space.
- */
-#ifdef MUSTALIGN
- if ((long) input & 3) {
- memcpy((char *)&xor_0, (char *)input++, sizeof(xor_0));
- xor_0 ^= t_output[0];
- memcpy((char *)&xor_1, (char *)input++, sizeof(xor_1));
- xor_1 ^= t_output[1];
- }
- else
-#endif
- {
- xor_0 = *input++ ^ t_output[0];
- xor_1 = *input++ ^ t_output[1];
- }
-
-
- /* copy temp output and save it for cbc */
-#ifdef MUSTALIGN
- if ((long) output & 3) {
- memcpy((char *)output++, (char *)&t_output[0],
- sizeof(t_output[0]));
- memcpy((char *)output++, (char *)&t_output[1],
- sizeof(t_output[1]));
- }
- else
-#endif
- {
- *output++ = t_output[0];
- *output++ = t_output[1];
- }
+#define des_cblock_print(x) des_cblock_print_file(x, stdout)
-#ifdef DEBUG
- if (mit_des_debug) {
- mit_des_debug_print("xor'ed",i,t_input[0],t_input[1]);
- mit_des_debug_print("cipher",i,t_output[0],t_output[1]);
- }
-#endif
- }
- t_output[0] = 0;
- t_output[1] = 0;
- xor_0 = 0;
- xor_1 = 0;
- return 0;
- }
+#include "f_tables.h"
- else {
- /* decrypt */
-#ifdef MUSTALIGN
- if ((long) ivec & 3) {
- memcpy((char *)&xor_0, (char *)ivec++,sizeof(xor_0));
- memcpy((char *)&xor_1, (char *)ivec, sizeof(xor_1));
- }
- else
-#endif
- {
- xor_0 = *ivec++;
- xor_1 = *ivec;
+/*
+ * des_pcbc_encrypt - {en,de}crypt a stream in PCBC mode
+ */
+int
+des_pcbc_encrypt(in, out, length, schedule, ivec, encrypt)
+ des_cblock *in;
+ des_cblock *out;
+ long length;
+ des_key_schedule schedule;
+ des_cblock ivec;
+ int encrypt;
+{
+ register unsigned KRB_INT32 left, right;
+ register unsigned KRB_INT32 temp;
+ register unsigned KRB_INT32 *kp;
+ register unsigned char *ip, *op;
+
+ /*
+ * Copy the key pointer, just once
+ */
+ kp = (unsigned KRB_INT32 *)schedule;
+
+ /*
+ * Deal with encryption and decryption separately.
+ */
+ if (encrypt) {
+ register unsigned KRB_INT32 plainl;
+ register unsigned KRB_INT32 plainr;
+
+ /*
+ * Initialize left and right with the contents of the initial
+ * vector.
+ */
+ ip = (unsigned char *)ivec;
+ GET_HALF_BLOCK(left, ip);
+ GET_HALF_BLOCK(right, ip);
+
+ /*
+ * Suitably initialized, now work the length down 8 bytes
+ * at a time.
+ */
+ ip = (unsigned char *)in;
+ op = (unsigned char *)out;
+ while (length > 0) {
+ /*
+ * Get block of input. If the length is
+ * greater than 8 this is straight
+ * forward. Otherwise we have to fart around.
+ */
+ if (length > 8) {
+ GET_HALF_BLOCK(plainl, ip);
+ GET_HALF_BLOCK(plainr, ip);
+ left ^= plainl;
+ right ^= plainr;
+ length -= 8;
+ } else {
+ /*
+ * Oh, shoot. We need to pad the
+ * end with zeroes. Work backwards
+ * to do this. We know this is the
+ * last block, though, so we don't have
+ * to save the plain text.
+ */
+ ip += (int) length;
+ switch(length) {
+ case 8:
+ right ^= *(--ip) & 0xff;
+ case 7:
+ right ^= (*(--ip) & 0xff) << 8;
+ case 6:
+ right ^= (*(--ip) & 0xff) << 16;
+ case 5:
+ right ^= (*(--ip) & 0xff) << 24;
+ case 4:
+ left ^= *(--ip) & 0xff;
+ case 3:
+ left ^= (*(--ip) & 0xff) << 8;
+ case 2:
+ left ^= (*(--ip) & 0xff) << 16;
+ case 1:
+ left ^= (*(--ip) & 0xff) << 24;
+ break;
+ }
+ length = 0;
+ }
+
+ /*
+ * Encrypt what we have
+ */
+ DES_DO_ENCRYPT(left, right, temp, kp);
+
+ /*
+ * Copy the results out
+ */
+ PUT_HALF_BLOCK(left, op);
+ PUT_HALF_BLOCK(right, op);
+
+ /*
+ * Xor with the old plain text
+ */
+ left ^= plainl;
+ right ^= plainr;
+ }
+ } else {
+ /*
+ * Decrypting is harder than encrypting because of
+ * the necessity of remembering a lot more things.
+ * Should think about this a little more...
+ */
+ unsigned KRB_INT32 ocipherl, ocipherr;
+ unsigned KRB_INT32 cipherl, cipherr;
+
+ if (length <= 0)
+ return 0;
+
+ /*
+ * Prime the old cipher with ivec.
+ */
+ ip = (unsigned char *)ivec;
+ GET_HALF_BLOCK(ocipherl, ip);
+ GET_HALF_BLOCK(ocipherr, ip);
+
+ /*
+ * Now do this in earnest until we run out of length.
+ */
+ ip = (unsigned char *)in;
+ op = (unsigned char *)out;
+ for (;;) { /* check done inside loop */
+ /*
+ * Read a block from the input into left and
+ * right. Save this cipher block for later.
+ */
+ GET_HALF_BLOCK(left, ip);
+ GET_HALF_BLOCK(right, ip);
+ cipherl = left;
+ cipherr = right;
+
+ /*
+ * Decrypt this.
+ */
+ DES_DO_DECRYPT(left, right, temp, kp);
+
+ /*
+ * Xor with the old cipher to get plain
+ * text. Output 8 or less bytes of this.
+ */
+ left ^= ocipherl;
+ right ^= ocipherr;
+ if (length > 8) {
+ length -= 8;
+ PUT_HALF_BLOCK(left, op);
+ PUT_HALF_BLOCK(right, op);
+ /*
+ * Save current cipher block here
+ */
+ ocipherl = cipherl ^ left;
+ ocipherr = cipherr ^ right;
+ } else {
+ /*
+ * Trouble here. Start at end of output,
+ * work backwards.
+ */
+ op += (int) length;
+ switch(length) {
+ case 8:
+ *(--op) = right & 0xff;
+ case 7:
+ *(--op) = (right >> 8) & 0xff;
+ case 6:
+ *(--op) = (right >> 16) & 0xff;
+ case 5:
+ *(--op) = (right >> 24) & 0xff;
+ case 4:
+ *(--op) = left & 0xff;
+ case 3:
+ *(--op) = (left >> 8) & 0xff;
+ case 2:
+ *(--op) = (left >> 16) & 0xff;
+ case 1:
+ *(--op) = (left >> 24) & 0xff;
+ break;
+ }
+ break; /* we're done */
+ }
+ }
}
- for (i = 0; length > 0; i++, length -= 8) {
- /* get input */
-#ifdef MUSTALIGN
- if ((long) input & 3) {
- memcpy((char *)&t_input[0],(char *)input++,sizeof(t_input[0]));
- memcpy((char *)&t_input[1],(char *)input++,sizeof(t_input[1]));
- }
- else
-#endif
- {
- t_input[0] = *input++;
- t_input[1] = *input++;
- }
-
- /* no padding for decrypt */
-#ifdef DEBUG
- if (mit_des_debug)
- mit_des_debug_print("cipher",i,t_input[0],t_input[1]);
-#else
-#ifdef lint
- i = i;
-#endif
-#endif
- /* encrypt */
- (void) des_ecb_encrypt(t_input,t_output,key,encrypt);
-#ifdef DEBUG
- if (mit_des_debug)
- mit_des_debug_print("out pre xor",i,t_output[0],t_output[1]);
-#endif
- /* do the xor for cbc into the output */
- t_output[0] ^= xor_0 ;
- t_output[1] ^= xor_1 ;
- /* copy temp output */
-#ifdef MUSTALIGN
- if ((long) output & 3) {
- memcpy((char *)output++, (char *)&t_output[0],
- sizeof(t_output[0]));
- memcpy((char *)output++, (char *)&t_output[1],
- sizeof(t_output[1]));
- }
- else
-#endif
- {
- *output++ = t_output[0];
- *output++ = t_output[1];
- }
-
- /* save xor value for next round */
- xor_0 = t_output[0] ^ t_input[0];
- xor_1 = t_output[1] ^ t_input[1];
-
-#ifdef DEBUG
- if (mit_des_debug)
- mit_des_debug_print("clear",i,t_output[0],t_output[1]);
-#endif
- }
+ /*
+ * Done, return nothing.
+ */
return 0;
- }
}