svn rev #24699: trunk/src/lib/crypto/ builtin/des/ crypto_tests/ krb/ nss/des/ ...
ghudson@MIT.EDU
ghudson at MIT.EDU
Thu Mar 10 23:20:17 EST 2011
http://src.mit.edu/fisheye/changelog/krb5/?cs=24699
Commit By: ghudson
Log Message:
Move the des and AFS string-to-key implementations into lib/crypto/krb,
since they aren't standard crypto primitives. Revise the module SPI
accordingly. Add tests for AFS string-to-key to t_str2key.c to replace
the ones in the (now defunct) t_afss2k.c.
Changed Files:
U trunk/src/lib/crypto/builtin/des/Makefile.in
D trunk/src/lib/crypto/builtin/des/afsstring2key.c
U trunk/src/lib/crypto/builtin/des/des_int.h
A trunk/src/lib/crypto/builtin/des/des_keys.c
U trunk/src/lib/crypto/builtin/des/f_parity.c
D trunk/src/lib/crypto/builtin/des/string2key.c
D trunk/src/lib/crypto/builtin/des/t_afss2k.c
U trunk/src/lib/crypto/crypto_tests/t_str2key.c
U trunk/src/lib/crypto/krb/crypto_int.h
U trunk/src/lib/crypto/krb/random_to_key.c
U trunk/src/lib/crypto/krb/s2k_des.c
U trunk/src/lib/crypto/nss/des/Makefile.in
A trunk/src/lib/crypto/nss/des/des_keys.c
D trunk/src/lib/crypto/nss/des/des_oldapis.c
D trunk/src/lib/crypto/nss/des/f_parity.c
D trunk/src/lib/crypto/nss/des/string2key.c
U trunk/src/lib/crypto/nss/enc_provider/des.c
U trunk/src/lib/crypto/nss/enc_provider/enc_gen.c
U trunk/src/lib/crypto/openssl/des/Makefile.in
A trunk/src/lib/crypto/openssl/des/des_keys.c
D trunk/src/lib/crypto/openssl/des/des_oldapis.c
D trunk/src/lib/crypto/openssl/des/f_parity.c
D trunk/src/lib/crypto/openssl/des/string2key.c
U trunk/src/lib/crypto/openssl/enc_provider/des.c
Modified: trunk/src/lib/crypto/builtin/des/Makefile.in
===================================================================
--- trunk/src/lib/crypto/builtin/des/Makefile.in 2011-03-11 04:17:42 UTC (rev 24698)
+++ trunk/src/lib/crypto/builtin/des/Makefile.in 2011-03-11 04:20:17 UTC (rev 24699)
@@ -13,41 +13,38 @@
STLIBOBJS=\
- afsstring2key.o \
d3_aead.o \
d3_kysched.o \
+ des_keys.o \
f_aead.o \
f_cksum.o \
f_parity.o \
f_sched.o \
f_tables.o \
key_sched.o \
- string2key.o \
weak_key.o
-OBJS= $(OUTPRE)afsstring2key.$(OBJEXT) \
- $(OUTPRE)d3_aead.$(OBJEXT) \
+OBJS= $(OUTPRE)d3_aead.$(OBJEXT) \
$(OUTPRE)d3_kysched.$(OBJEXT) \
+ $(OUTPRE)des_keys.c.$(OBJEXT) \
$(OUTPRE)f_aead.$(OBJEXT) \
$(OUTPRE)f_cksum.$(OBJEXT) \
$(OUTPRE)f_parity.$(OBJEXT) \
$(OUTPRE)f_sched.$(OBJEXT) \
$(OUTPRE)f_tables.$(OBJEXT) \
$(OUTPRE)key_sched.$(OBJEXT) \
- $(OUTPRE)string2key.$(OBJEXT) \
$(OUTPRE)weak_key.$(OBJEXT)
-SRCS= $(srcdir)/afsstring2key.c \
- $(srcdir)/d3_aead.c \
+SRCS= $(srcdir)/d3_aead.c \
$(srcdir)/d3_kysched.c \
+ $(srcdir)/des_keys.c \
$(srcdir)/f_aead.c \
$(srcdir)/f_cksum.c \
$(srcdir)/f_parity.c \
$(srcdir)/f_sched.c \
$(srcdir)/f_tables.c \
$(srcdir)/key_sched.c \
- $(srcdir)/weak_key.c \
- $(srcdir)/string2key.c
+ $(srcdir)/weak_key.c
EXTRADEPSRCS = $(srcdir)/destest.c $(srcdir)/f_cbc.c $(srcdir)/t_verify.c
@@ -67,19 +64,11 @@
all-unix:: all-libobjs
-TAFSS2KOBJS = \
- t_afss2k.$(OBJEXT) $(TOBJS) \
- afsstring2key.$(OBJEXT) f_parity.$(OBJEXT) weak_key.$(OBJEXT)
-
-t_afss2k$(EXEEXT): $(TAFSS2KOBJS) $(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB)
- $(CC_LINK) -o $@ $(TAFSS2KOBJS) -lcom_err $(SUPPORT_LIB)
-
-check-unix:: verify destest t_afss2k
+check-unix:: verify destest
$(RUN_SETUP) $(VALGRIND) ./verify -z
$(RUN_SETUP) $(VALGRIND) ./verify -m
$(RUN_SETUP) $(VALGRIND) ./verify
$(RUN_SETUP) $(VALGRIND) ./destest < $(srcdir)/keytest.data
- $(RUN_SETUP) $(VALGRIND) ./t_afss2k
includes:: depend
@@ -89,7 +78,7 @@
clean::
$(RM) destest.$(OBJEXT) destest$(EXEEXT) verify$(EXEEXT) \
- t_verify.$(OBJEXT) t_afss2k.$(OBJEXT) t_afss2k$(EXEEXT) $(TOBJS)
+ t_verify.$(OBJEXT) $(TOBJS)
clean-unix:: clean-libobjs
Modified: trunk/src/lib/crypto/builtin/des/des_int.h
===================================================================
--- trunk/src/lib/crypto/builtin/des/des_int.h 2011-03-11 04:17:42 UTC (rev 24698)
+++ trunk/src/lib/crypto/builtin/des/des_int.h 2011-03-11 04:20:17 UTC (rev 24699)
@@ -184,6 +184,7 @@
krb5_pointer *);
/* key_parity.c */
+void mit_des_fixup_key_parity(mit_des_cblock);
int mit_des_check_key_parity(mit_des_cblock);
/* key_sched.c */
Added: trunk/src/lib/crypto/builtin/des/des_keys.c
===================================================================
--- trunk/src/lib/crypto/builtin/des/des_keys.c (rev 0)
+++ trunk/src/lib/crypto/builtin/des/des_keys.c 2011-03-11 04:20:17 UTC (rev 24699)
@@ -0,0 +1,40 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/des/des_keys.c - Key functions used by Kerberos code */
+/*
+ * Copyright (C) 2011 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "crypto_int.h"
+#include "des_int.h"
+
+void
+k5_des_fixup_key_parity(unsigned char *keybits)
+{
+ mit_des_fixup_key_parity(keybits);
+}
+
+krb5_boolean
+k5_des_is_weak_key(unsigned char *keybits)
+{
+ return mit_des_is_weak_key(keybits);
+}
Modified: trunk/src/lib/crypto/builtin/des/f_parity.c
===================================================================
--- trunk/src/lib/crypto/builtin/des/f_parity.c 2011-03-11 04:17:42 UTC (rev 24698)
+++ trunk/src/lib/crypto/builtin/des/f_parity.c 2011-03-11 04:20:17 UTC (rev 24699)
@@ -9,7 +9,7 @@
* Mark Eichin -- Cygnus Support
*/
-#include "crypto_int.h"
+
#include "des_int.h"
/*
@@ -22,10 +22,10 @@
#define parity_char(x) pstep(pstep(pstep((x),4),2),1)
void
-mit_des_fixup_key_parity(unsigned char *key)
+mit_des_fixup_key_parity(mit_des_cblock key)
{
unsigned int i;
- for (i=0; i<8; i++)
+ for (i=0; i<sizeof(mit_des_cblock); i++)
{
key[i] &= 0xfe;
key[i] |= 1^parity_char(key[i]);
Modified: trunk/src/lib/crypto/crypto_tests/t_str2key.c
===================================================================
--- trunk/src/lib/crypto/crypto_tests/t_str2key.c 2011-03-11 04:17:42 UTC (rev 24698)
+++ trunk/src/lib/crypto/crypto_tests/t_str2key.c 2011-03-11 04:20:17 UTC (rev 24699)
@@ -1,5 +1,5 @@
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/* lib/crypto/crypto_tests/t_str2key.c */
+/* lib/crypto/crypto_tests/t_str2key.c - String-to-key test vectors */
/*
* Copyright (C) 2010 by the Massachusetts Institute of Technology.
* All rights reserved.
@@ -24,11 +24,6 @@
* or implied warranty.
*/
-/*
- *
- * String-to-key test vectors
- */
-
#include "k5-int.h"
struct test {
@@ -38,6 +33,176 @@
krb5_data params;
krb5_data expected_key;
} test_cases[] = {
+ /* AFS string-to-key tests from old t_afss2k.c. */
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "",
+ "Sodium Chloride",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xA4\xD0\xD0\x9B\x86\x92\xB0\xC2" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "M",
+ "Sodium Chloride",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xF1\xF2\x9E\xAB\xD0\xEF\xDF\x73" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My",
+ "Sodium Chloride",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xD6\x85\x61\xC4\xF2\x94\xF4\xA1" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My ",
+ "Sodium Chloride",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xD0\xE3\xA7\x83\x94\x61\xE0\xD0" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My P",
+ "Sodium Chloride",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xD5\x62\xCD\x94\x61\xCB\x97\xDF" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Pa",
+ "Sodium Chloride",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\x9E\xA2\xA2\xEC\xA8\x8C\x6B\x8F" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Pas",
+ "Sodium Chloride",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xE3\x91\x6D\xD3\x85\xF1\x67\xC4" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Pass",
+ "Sodium Chloride",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xF4\xC4\x73\xC8\x8A\xE9\x94\x6D" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Passw",
+ "Sodium Chloride",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xA1\x9E\xB3\xAD\x6B\xE3\xAB\xD9" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Passwo",
+ "Sodium Chloride",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xAD\xA1\xCE\x10\x37\x83\xA7\x8C" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Passwor",
+ "Sodium Chloride",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xD3\x01\xD0\xF7\x3E\x7A\x49\x0B" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Password",
+ "Sodium Chloride",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xB6\x2A\x4A\xEC\x9D\x4C\x68\xDF" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "",
+ "NaCl",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\x61\xEF\xE6\x83\xE5\x8A\x6B\x98" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "M",
+ "NaCl",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\x68\xCD\x68\xAD\xC4\x86\xCD\xE5" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My",
+ "NaCl",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\x83\xA1\xC8\x86\x8F\x67\xD0\x62" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My ",
+ "NaCl",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\x9E\xC7\x8F\xA4\xA4\xB3\xE0\xD5" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My P",
+ "NaCl",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xD9\x92\x86\x8F\x9D\x8C\x85\xE6" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Pa",
+ "NaCl",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xDA\xF2\x92\x83\xF4\x9B\xA7\xAD" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Pas",
+ "NaCl",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\x91\xCD\xAD\xEF\x86\xDF\xD3\xA2" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Pass",
+ "NaCl",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\x73\xD3\x67\x68\x8F\x6E\xE3\x73" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Passw",
+ "NaCl",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xC4\x61\x85\x9D\xAD\xF4\xDC\xB0" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Passwo",
+ "NaCl",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\xE9\x02\x83\x16\x2C\xEC\xE0\x08" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Passwor",
+ "NaCl",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\x61\xC8\x26\x29\xD9\x73\x6E\xB6" }
+ },
+ {
+ ENCTYPE_DES_CBC_CRC,
+ "My Password",
+ "NaCl",
+ { KV5M_DATA, 1, "\1" },
+ { KV5M_DATA, 8, "\x8C\xA8\x9E\xC4\xA8\xDC\x31\x73" }
+ },
+
/* Test vectors from RFC 3961 appendix A.2. */
{
ENCTYPE_DES_CBC_CRC,
Modified: trunk/src/lib/crypto/krb/crypto_int.h
===================================================================
--- trunk/src/lib/crypto/krb/crypto_int.h 2011-03-11 04:17:42 UTC (rev 24698)
+++ trunk/src/lib/crypto/krb/crypto_int.h 2011-03-11 04:20:17 UTC (rev 24699)
@@ -432,16 +432,11 @@
/* Modules must implement the following functions. */
-/* Set the parity bits in a DES key. */
-void mit_des_fixup_key_parity(unsigned char *key);
+/* Set the parity bits to the correct values in keybits. */
+void k5_des_fixup_key_parity(unsigned char *keybits);
-/* Convert a password to a DES key (see RFC 3961). */
-krb5_error_code mit_afs_string_to_key(krb5_keyblock *keyblock,
- const krb5_data *password,
- const krb5_data *salt);
-krb5_error_code mit_des_string_to_key_int(krb5_keyblock *key,
- const krb5_data *password,
- const krb5_data *salt);
+/* Return true if keybits is a weak or semi-weak DES key. */
+krb5_boolean k5_des_is_weak_key(unsigned char *keybits);
/* Compute an HMAC using the provided hash function, key, and data, storing the
* result into output (caller-allocated). */
Modified: trunk/src/lib/crypto/krb/random_to_key.c
===================================================================
--- trunk/src/lib/crypto/krb/random_to_key.c 2011-03-11 04:17:42 UTC (rev 24698)
+++ trunk/src/lib/crypto/krb/random_to_key.c 2011-03-11 04:20:17 UTC (rev 24699)
@@ -92,7 +92,7 @@
* 8 key bytes, then compute the parity bits. */
memcpy(keyblock->contents, randombits->data, randombits->length);
eighth_byte(keyblock->contents);
- mit_des_fixup_key_parity(keyblock->contents);
+ k5_des_fixup_key_parity(keyblock->contents);
return 0;
}
@@ -112,7 +112,7 @@
for (i = 0; i < 3; i++) {
memcpy(&keyblock->contents[i * 8], &randombits->data[i * 7], 7);
eighth_byte(&keyblock->contents[i * 8]);
- mit_des_fixup_key_parity(&keyblock->contents[i * 8]);
+ k5_des_fixup_key_parity(&keyblock->contents[i * 8]);
}
return 0;
}
Modified: trunk/src/lib/crypto/krb/s2k_des.c
===================================================================
--- trunk/src/lib/crypto/krb/s2k_des.c 2011-03-11 04:17:42 UTC (rev 24698)
+++ trunk/src/lib/crypto/krb/s2k_des.c 2011-03-11 04:20:17 UTC (rev 24699)
@@ -25,26 +25,672 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+/*
+ * RFC 3961 and AFS string to key. These are not standard crypto primitives
+ * (RFC 3961 string-to-key is implemented in OpenSSL for historical reasons but
+ * it doesn't get weak keys right), so we have to implement them here.
+ */
+
+#include <ctype.h>
#include "crypto_int.h"
+#undef min
+#define min(a,b) ((a)>(b)?(b):(a))
+
+/* Compute a CBC checksum of in (with length len) using the specified key and
+ * ivec. The result is written into out. */
+static krb5_error_code
+des_cbc_mac(const unsigned char *keybits, const unsigned char *ivec,
+ const unsigned char *in, size_t len, unsigned char *out)
+{
+ krb5_error_code ret;
+ krb5_keyblock kb;
+ krb5_key key;
+ krb5_crypto_iov iov[2];
+ unsigned char zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ krb5_data outd, ivecd;
+
+ /* Make a key from keybits. */
+ kb.magic = KV5M_KEYBLOCK;
+ kb.enctype = ENCTYPE_DES_CBC_CRC;
+ kb.length = 8;
+ kb.contents = (unsigned char *)keybits;
+ ret = krb5_k_create_key(NULL, &kb, &key);
+ if (ret)
+ return ret;
+
+ /* Make iovs for the input data, padding it out to the block size. */
+ iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[0].data = make_data((unsigned char *)in, len);
+ iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[1].data = make_data(zero, krb5_roundup(len, 8) - len);
+
+ /* Make krb5_data structures for the ivec and output. */
+ ivecd = make_data((unsigned char *)ivec, 8);
+ outd = make_data(out, 8);
+
+ /* Call the cbc_mac operation of the module's DES enc-provider. */
+ ret = krb5int_enc_des.cbc_mac(key, iov, 2, &ivecd, &outd);
+ krb5_k_free_key(NULL, key);
+ return ret;
+}
+
+/*** AFS string-to-key constants ***/
+
+/* Initial permutation */
+static const char IP[] = {
+ 58,50,42,34,26,18,10, 2,
+ 60,52,44,36,28,20,12, 4,
+ 62,54,46,38,30,22,14, 6,
+ 64,56,48,40,32,24,16, 8,
+ 57,49,41,33,25,17, 9, 1,
+ 59,51,43,35,27,19,11, 3,
+ 61,53,45,37,29,21,13, 5,
+ 63,55,47,39,31,23,15, 7,
+};
+
+/* Final permutation, FP = IP^(-1) */
+static const char FP[] = {
+ 40, 8,48,16,56,24,64,32,
+ 39, 7,47,15,55,23,63,31,
+ 38, 6,46,14,54,22,62,30,
+ 37, 5,45,13,53,21,61,29,
+ 36, 4,44,12,52,20,60,28,
+ 35, 3,43,11,51,19,59,27,
+ 34, 2,42,10,50,18,58,26,
+ 33, 1,41, 9,49,17,57,25,
+};
+
+/*
+ * Permuted-choice 1 from the key bits to yield C and D.
+ * Note that bits 8,16... are left out: They are intended for a parity check.
+ */
+static const char PC1_C[] = {
+ 57,49,41,33,25,17, 9,
+ 1,58,50,42,34,26,18,
+ 10, 2,59,51,43,35,27,
+ 19,11, 3,60,52,44,36,
+};
+
+static const char PC1_D[] = {
+ 63,55,47,39,31,23,15,
+ 7,62,54,46,38,30,22,
+ 14, 6,61,53,45,37,29,
+ 21,13, 5,28,20,12, 4,
+};
+
+/* Sequence of shifts used for the key schedule */
+static const char shifts[] = {
+ 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
+};
+
+/* Permuted-choice 2, to pick out the bits from the CD array that generate the
+ * key schedule */
+static const char PC2_C[] = {
+ 14,17,11,24, 1, 5,
+ 3,28,15, 6,21,10,
+ 23,19,12, 4,26, 8,
+ 16, 7,27,20,13, 2,
+};
+
+static const char PC2_D[] = {
+ 41,52,31,37,47,55,
+ 30,40,51,45,33,48,
+ 44,49,39,56,34,53,
+ 46,42,50,36,29,32,
+};
+
+/* The E bit-selection table */
+static const char e[] = {
+ 32, 1, 2, 3, 4, 5,
+ 4, 5, 6, 7, 8, 9,
+ 8, 9,10,11,12,13,
+ 12,13,14,15,16,17,
+ 16,17,18,19,20,21,
+ 20,21,22,23,24,25,
+ 24,25,26,27,28,29,
+ 28,29,30,31,32, 1,
+};
+
+/* P is a permutation on the selected combination of the current L and key. */
+static const char P[] = {
+ 16, 7,20,21,
+ 29,12,28,17,
+ 1,15,23,26,
+ 5,18,31,10,
+ 2, 8,24,14,
+ 32,27, 3, 9,
+ 19,13,30, 6,
+ 22,11, 4,25,
+};
+
+/*
+ * The 8 selection functions.
+ * For some reason, they give a 0-origin
+ * index, unlike everything else.
+ */
+static const char S[8][64] = {
+ {14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
+ 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
+ 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
+ 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13},
+
+ {15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
+ 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
+ 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
+ 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9},
+
+ {10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
+ 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
+ 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
+ 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12},
+
+ { 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
+ 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
+ 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
+ 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14},
+
+ { 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
+ 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
+ 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
+ 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3},
+
+ {12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
+ 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
+ 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
+ 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13},
+
+ { 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
+ 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
+ 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
+ 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12},
+
+ {13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
+ 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
+ 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
+ 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11},
+};
+
+
+/* Set up the key schedule from the key. */
+static void
+afs_crypt_setkey(char *key, char *E, char (*KS)[48])
+{
+ int i, j, k, t;
+ char C[28], D[28]; /* Used to calculate key schedule. */
+
+ /*
+ * First, generate C and D by permuting
+ * the key. The low order bit of each
+ * 8-bit char is not used, so C and D are only 28
+ * bits apiece.
+ */
+ for (i = 0; i < 28; i++) {
+ C[i] = key[PC1_C[i] - 1];
+ D[i] = key[PC1_D[i] - 1];
+ }
+ /*
+ * To generate Ki, rotate C and D according
+ * to schedule and pick up a permutation
+ * using PC2.
+ */
+ for (i = 0; i < 16; i++) {
+ /* Rotate. */
+ for (k = 0; k < shifts[i]; k++) {
+ t = C[0];
+ for (j = 0; j < 28 - 1; j++)
+ C[j] = C[j + 1];
+ C[27] = t;
+ t = D[0];
+ for (j = 0; j < 28 - 1; j++)
+ D[j] = D[j + 1];
+ D[27] = t;
+ }
+ /* Get Ki. Note C and D are concatenated. */
+ for (j = 0; j < 24; j++) {
+ KS[i][j] = C[PC2_C[j]-1];
+ KS[i][j+24] = D[PC2_D[j]-28-1];
+ }
+ }
+
+ memcpy(E, e, 48);
+}
+
+/*
+ * The payoff: encrypt a block.
+ */
+
+static void
+afs_encrypt_block(char *block, char *E, char (*KS)[48])
+{
+ const long edflag = 0;
+ int i, ii;
+ int t, j, k;
+ char tempL[32];
+ char f[32];
+ char L[64]; /* Current block divided into two halves */
+ char *const R = &L[32];
+ /* The combination of the key and the input, before selection. */
+ char preS[48];
+
+ /* First, permute the bits in the input. */
+ for (j = 0; j < 64; j++)
+ L[j] = block[IP[j] - 1];
+ /* Perform an encryption operation 16 times. */
+ for (ii = 0; ii < 16; ii++) {
+ /* Set direction. */
+ i = (edflag) ? 15 - ii : ii;
+ /* Save the R array, which will be the new L. */
+ memcpy(tempL, R, 32);
+ /* Expand R to 48 bits using the E selector; exclusive-or with the
+ * current key bits. */
+ for (j = 0; j < 48; j++)
+ preS[j] = R[E[j] - 1] ^ KS[i][j];
+ /*
+ * The pre-select bits are now considered in 8 groups of 6 bits each.
+ * The 8 selection functions map these 6-bit quantities into 4-bit
+ * quantities and the results permuted to make an f(R, K). The
+ * indexing into the selection functions is peculiar; it could be
+ * simplified by rewriting the tables.
+ */
+ for (j = 0; j < 8; j++) {
+ t = 6 * j;
+ k = S[j][(preS[t + 0] << 5) +
+ (preS[t + 1] << 3) +
+ (preS[t + 2] << 2) +
+ (preS[t + 3] << 1) +
+ (preS[t + 4] << 0) +
+ (preS[t + 5] << 4)];
+ t = 4 * j;
+ f[t + 0] = (k >> 3) & 1;
+ f[t + 1] = (k >> 2) & 1;
+ f[t + 2] = (k >> 1) & 1;
+ f[t + 3] = (k >> 0) & 1;
+ }
+ /* The new R is L ^ f(R, K). The f here has to be permuted first,
+ * though. */
+ for (j = 0; j < 32; j++)
+ R[j] = L[j] ^ f[P[j] - 1];
+ /* Finally, the new L (the original R) is copied back. */
+ memcpy(L, tempL, 32);
+ }
+ /* The output L and R are reversed. */
+ for (j = 0; j < 32; j++) {
+ t = L[j];
+ L[j] = R[j];
+ R[j] = t;
+ }
+ /* The final output gets the inverse permutation of the very original. */
+ for (j = 0; j < 64; j++)
+ block[j] = L[FP[j] - 1];
+}
+
+/* iobuf must be at least 16 bytes */
+static char *
+afs_crypt(const char *pw, const char *salt, char *iobuf)
+{
+ int i, j, c;
+ int temp;
+ char block[66];
+ char E[48];
+ char KS[16][48]; /* Key schedule, generated from key */
+
+ for (i = 0; i < 66; i++)
+ block[i] = 0;
+ for (i = 0; (c = *pw) != '\0' && i < 64; pw++){
+ for(j = 0; j < 7; j++, i++)
+ block[i] = (c >> (6 - j)) & 01;
+ i++;
+ }
+
+ afs_crypt_setkey(block, E, KS);
+
+ for (i = 0; i < 66; i++)
+ block[i] = 0;
+
+ for (i = 0; i < 2; i++) {
+ c = *salt++;
+ iobuf[i] = c;
+ if (c > 'Z')
+ c -= 6;
+ if (c > '9')
+ c -= 7;
+ c -= '.';
+ for (j = 0; j < 6; j++) {
+ if ((c >> j) & 01) {
+ temp = E[6 * i + j];
+ E[6 * i + j] = E[6 * i + j + 24];
+ E[6 * i + j + 24] = temp;
+ }
+ }
+ }
+
+ for (i = 0; i < 25; i++)
+ afs_encrypt_block(block, E, KS);
+
+ for (i = 0; i < 11; i++) {
+ c = 0;
+ for (j = 0; j < 6; j++) {
+ c <<= 1;
+ c |= block[6 * i + j];
+ }
+ c += '.';
+ if (c > '9')
+ c += 7;
+ if (c > 'Z')
+ c += 6;
+ iobuf[i + 2] = c;
+ }
+ iobuf[i + 2] = 0;
+ if (iobuf[1] == 0)
+ iobuf[1] = iobuf[0];
+ return iobuf;
+}
+
+static krb5_error_code
+afs_s2k_oneblock(const krb5_data *data, const krb5_data *salt,
+ unsigned char *key_out)
+{
+ unsigned int i;
+ unsigned char password[9]; /* trailing nul for crypt() */
+ char afs_crypt_buf[16];
+
+ /*
+ * Run afs_crypt and use the first eight returned bytes after the copy of
+ * the (fixed) salt.
+ *
+ * Since the returned bytes are alphanumeric, the output is limited to
+ * 2**48 possibilities; for each byte, only 64 possible values can be used.
+ */
+
+ memset(password, 0, sizeof(password));
+ memcpy(password, salt->data, min(salt->length, 8));
+ for (i = 0; i < 8; i++) {
+ if (isupper(password[i]))
+ password[i] = tolower(password[i]);
+ }
+ for (i = 0; i < data->length; i++)
+ password[i] ^= data->data[i];
+ for (i = 0; i < 8; i++) {
+ if (password[i] == '\0')
+ password[i] = 'X';
+ }
+ password[8] = '\0';
+ /* Out-of-bounds salt characters are equivalent to a salt string
+ * of "p1". */
+ strncpy((char *)key_out,
+ (char *)afs_crypt((char *)password, "#~", afs_crypt_buf) + 2, 8);
+ for (i = 0; i < 8; i++)
+ key_out[i] <<= 1;
+ /* Fix up key parity again. */
+ k5_des_fixup_key_parity(key_out);
+ zap(password, sizeof(password));
+ return 0;
+}
+
+static krb5_error_code
+afs_s2k_multiblock(const krb5_data *data, const krb5_data *salt,
+ unsigned char *key_out)
+{
+ krb5_error_code ret;
+ unsigned char ivec[8], tkey[8], *password;
+ size_t pw_len = salt->length + data->length;
+ unsigned int i, j;
+
+ /* Do a CBC checksum, twice, and use the result as the new key. */
+
+ password = malloc(pw_len);
+ if (!password)
+ return ENOMEM;
+
+ memcpy(password, data->data, data->length);
+ for (i = data->length, j = 0; j < salt->length; i++, j++) {
+ password[i] = salt->data[j];
+ if (isupper(password[i]))
+ password[i] = tolower(password[i]);
+ }
+
+ memcpy(ivec, "kerberos", sizeof(ivec));
+ memcpy(tkey, ivec, sizeof(tkey));
+ k5_des_fixup_key_parity(tkey);
+ ret = des_cbc_mac(tkey, ivec, password, pw_len, tkey);
+ if (ret)
+ goto cleanup;
+
+ memcpy(ivec, tkey, sizeof(ivec));
+ k5_des_fixup_key_parity(tkey);
+ ret = des_cbc_mac(tkey, ivec, password, pw_len, key_out);
+ if (ret)
+ goto cleanup;
+ k5_des_fixup_key_parity(key_out);
+
+cleanup:
+ zapfree(password, pw_len);
+ return ret;
+}
+
+static krb5_error_code
+afs_s2k(const krb5_data *data, const krb5_data *salt, unsigned char *key_out)
+{
+ if (data->length <= 8)
+ return afs_s2k_oneblock(data, salt, key_out);
+ else
+ return afs_s2k_multiblock(data, salt, key_out);
+}
+
+static krb5_error_code
+des_s2k(const krb5_data *pw, const krb5_data *salt, unsigned char *key_out)
+{
+ union {
+ /* 8 "forward" bytes, 8 "reverse" bytes */
+ unsigned char uc[16];
+ krb5_ui_4 ui[4];
+ } temp;
+ unsigned int i;
+ krb5_ui_4 x, y, z;
+ unsigned char *p, *copy;
+ size_t copylen;
+ krb5_error_code ret;
+
+ /* As long as the architecture is big-endian or little-endian, it
+ doesn't matter which it is. Think of it as reversing the
+ bytes, and also reversing the bits within each byte. But this
+ current algorithm is dependent on having four 8-bit char values
+ exactly overlay a 32-bit integral type. */
+ if (sizeof(temp.uc) != sizeof(temp.ui)
+ || (unsigned char)~0 != 0xFF
+ || (krb5_ui_4)~(krb5_ui_4)0 != 0xFFFFFFFF
+ || (temp.uc[0] = 1, temp.uc[1] = 2, temp.uc[2] = 3, temp.uc[3] = 4,
+ !(temp.ui[0] == 0x01020304
+ || temp.ui[0] == 0x04030201)))
+ abort();
+#define FETCH4(VAR, IDX) VAR = temp.ui[IDX/4]
+#define PUT4(VAR, IDX) temp.ui[IDX/4] = VAR
+
+ copylen = pw->length + (salt ? salt->length : 0);
+ /* Don't need NUL termination, at this point we're treating it as
+ a byte array, not a string. */
+ copy = malloc(copylen);
+ if (copy == NULL)
+ return ENOMEM;
+ memcpy(copy, pw->data, pw->length);
+ if (salt)
+ memcpy(copy + pw->length, salt->data, salt->length);
+
+ memset(&temp, 0, sizeof(temp));
+ p = temp.uc;
+ /* Handle the fan-fold xor operation by splitting the data into
+ forward and reverse sections, and combine them later, rather
+ than having to do the reversal over and over again. */
+ for (i = 0; i < copylen; i++) {
+ *p++ ^= copy[i];
+ if (p == temp.uc+16) {
+ p = temp.uc;
+#ifdef PRINT_TEST_VECTORS
+ {
+ int j;
+ printf("after %d input bytes:\nforward block:\t", i+1);
+ for (j = 0; j < 8; j++)
+ printf(" %02x", temp.uc[j] & 0xff);
+ printf("\nreverse block:\t");
+ for (j = 8; j < 16; j++)
+ printf(" %02x", temp.uc[j] & 0xff);
+ printf("\n");
+ }
+#endif
+ }
+ }
+
+#ifdef PRINT_TEST_VECTORS
+ if (p != temp.uc) {
+ int j;
+ printf("at end, after %d input bytes:\nforward block:\t", i);
+ for (j = 0; j < 8; j++)
+ printf(" %02x", temp.uc[j] & 0xff);
+ printf("\nreverse block:\t");
+ for (j = 8; j < 16; j++)
+ printf(" %02x", temp.uc[j] & 0xff);
+ printf("\n");
+ }
+#endif
+#define REVERSE(VAR) \
+ { \
+ krb5_ui_4 old = VAR, temp1 = 0; \
+ int j; \
+ for (j = 0; j < 32; j++) { \
+ temp1 = (temp1 << 1) | (old & 1); \
+ old >>= 1; \
+ } \
+ VAR = temp1; \
+ }
+
+ FETCH4 (x, 8);
+ FETCH4 (y, 12);
+ /* Ignore high bits of each input byte. */
+ x &= 0x7F7F7F7F;
+ y &= 0x7F7F7F7F;
+ /* Reverse the bit strings -- after this, y is "before" x. */
+ REVERSE (x);
+ REVERSE (y);
+#ifdef PRINT_TEST_VECTORS
+ {
+ int j;
+ union { unsigned char uc[4]; krb5_ui_4 ui; } t2;
+ printf("after reversal, reversed block:\n\t\t");
+ t2.ui = y;
+ for (j = 0; j < 4; j++)
+ printf(" %02x", t2.uc[j] & 0xff);
+ t2.ui = x;
+ for (j = 0; j < 4; j++)
+ printf(" %02x", t2.uc[j] & 0xff);
+ printf("\n");
+ }
+#endif
+ /* Ignored bits are now at the bottom of each byte, where we'll
+ * put the parity bits. Good. */
+ FETCH4 (z, 0);
+ z &= 0x7F7F7F7F;
+ /* Ignored bits for z are at the top of each byte; fix that. */
+ z <<= 1;
+ /* Finish the fan-fold xor for these four bytes. */
+ z ^= y;
+ PUT4 (z, 0);
+ /* Now do the second four bytes. */
+ FETCH4 (z, 4);
+ z &= 0x7F7F7F7F;
+ /* Ignored bits for z are at the top of each byte; fix that. */
+ z <<= 1;
+ /* Finish the fan-fold xor for these four bytes. */
+ z ^= x;
+ PUT4 (z, 4);
+
+#ifdef PRINT_TEST_VECTORS
+ {
+ int j;
+ printf("after reversal, combined block:\n\t\t");
+ for (j = 0; j < 8; j++)
+ printf(" %02x", temp.uc[j] & 0xff);
+ printf("\n");
+ }
+#endif
+
+#define FIXUP(k) (k5_des_fixup_key_parity(k), \
+ k5_des_is_weak_key(k) ? (k[7] ^= 0xF0) : 0)
+
+ /* Now temp.cb is the temporary key, with invalid parity. */
+ FIXUP(temp.uc);
+
+#ifdef PRINT_TEST_VECTORS
+ {
+ int j;
+ printf("after fixing parity and weak keys:\n\t\t");
+ for (j = 0; j < 8; j++)
+ printf(" %02x", temp.uc[j] & 0xff);
+ printf("\n");
+ }
+#endif
+
+ ret = des_cbc_mac(temp.uc, temp.uc, copy, copylen, temp.uc);
+ if (ret)
+ goto cleanup;
+
+#ifdef PRINT_TEST_VECTORS
+ {
+ int j;
+ printf("cbc checksum:\n\t\t");
+ for (j = 0; j < 8; j++)
+ printf(" %02x", temp.uc[j] & 0xff);
+ printf("\n");
+ }
+#endif
+
+ FIXUP(temp.uc);
+
+#ifdef PRINT_TEST_VECTORS
+ {
+ int j;
+ printf("after fixing parity and weak keys:\n\t\t");
+ for (j = 0; j < 8; j++)
+ printf(" %02x", temp.uc[j] & 0xff);
+ printf("\n");
+ }
+#endif
+
+ memcpy(key_out, temp.uc, 8);
+
+cleanup:
+ zap(&temp, sizeof(temp));
+ zapfree(copy, copylen);
+ return ret;
+}
+
krb5_error_code
krb5int_des_string_to_key(const struct krb5_keytypes *ktp,
const krb5_data *string, const krb5_data *salt,
- const krb5_data *parm, krb5_keyblock *key)
+ const krb5_data *parm, krb5_keyblock *keyblock)
{
int type;
- if (parm) {
+ krb5_data afssalt;
+
+ if (parm != NULL) {
if (parm->length != 1)
return KRB5_ERR_BAD_S2K_PARAMS;
type = parm->data[0];
+ if (type != 0 && type != 1)
+ return KRB5_ERR_BAD_S2K_PARAMS;
+ } else
+ type = 0;
+
+ /* Use AFS string to key if we were told to. */
+ if (type == 1)
+ return afs_s2k(string, salt, keyblock->contents);
+
+ /* Also use AFS string to key if the salt indicates it. */
+ if (salt != NULL && (salt->length == SALT_TYPE_AFS_LENGTH
+ || salt->length == (unsigned)-1)) {
+ afssalt = make_data(salt->data, strcspn(salt->data, "@"));
+ return afs_s2k(string, &afssalt, keyblock->contents);
}
- else type = 0;
- switch(type) {
- case 0:
- return(mit_des_string_to_key_int(key, string, salt));
- case 1:
- return mit_afs_string_to_key(key, string, salt);
- default:
- return KRB5_ERR_BAD_S2K_PARAMS;
- }
+
+ return des_s2k(string, salt, keyblock->contents);
}
Modified: trunk/src/lib/crypto/nss/des/Makefile.in
===================================================================
--- trunk/src/lib/crypto/nss/des/Makefile.in 2011-03-11 04:17:42 UTC (rev 24698)
+++ trunk/src/lib/crypto/nss/des/Makefile.in 2011-03-11 04:20:17 UTC (rev 24699)
@@ -9,17 +9,11 @@
PROG_LIBPATH=-L$(TOPLIBD)
PROG_RPATH=$(KRB5_LIBDIR)
-STLIBOBJS= des_oldapis.o \
- f_parity.o \
- string2key.o
+STLIBOBJS= des_keys.o
-OBJS= $(OUTPRE)f_parity.$(OBJEXT) \
- $(OUTPRE)des_oldapis.$(OBJEXT) \
- $(OUTPRE)string2key.$(OBJEXT)
+OBJS= $(OUTPRE)des_keys.$(OBJEXT)
-SRCS= $(srcdir)/f_parity.c \
- $(srcdir)/des_oldapis.c \
- $(srcdir)/string2key.c
+SRCS= $(srcdir)/des_keys.c
all-unix:: all-libobjs
Added: trunk/src/lib/crypto/nss/des/des_keys.c
===================================================================
--- trunk/src/lib/crypto/nss/des/des_keys.c (rev 0)
+++ trunk/src/lib/crypto/nss/des/des_keys.c 2011-03-11 04:20:17 UTC (rev 24699)
@@ -0,0 +1,87 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/nss/des/des_keys.c - Key functions used by Kerberos code */
+/*
+ * Copyright (C) 2011 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "crypto_int.h"
+
+/*
+ * des_fixup_key_parity: Forces odd parity per byte; parity is bits
+ * 8,16,...64 in des order, implies 0, 8, 16, ...
+ * vax order.
+ */
+#define smask(step) ((1<<step)-1)
+#define pstep(x,step) (((x)&smask(step))^(((x)>>step)&smask(step)))
+#define parity_char(x) pstep(pstep(pstep((x),4),2),1)
+
+void
+k5_des_fixup_key_parity(unsigned char *keybits)
+{
+ unsigned int i;
+
+ for (i = 0; i < 8; i++) {
+ keybits[i] &= 0xfe;
+ keybits[i] |= 1^parity_char(keybits[i]);
+ }
+}
+
+/* The following are the weak DES keys: */
+static const unsigned char weak[16][8] = {
+ /* Weak keys */
+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+ {0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe},
+ {0x1f,0x1f,0x1f,0x1f,0x0e,0x0e,0x0e,0x0e},
+ {0xe0,0xe0,0xe0,0xe0,0xf1,0xf1,0xf1,0xf1},
+
+ /* Semi-weak */
+ {0x01,0xfe,0x01,0xfe,0x01,0xfe,0x01,0xfe},
+ {0xfe,0x01,0xfe,0x01,0xfe,0x01,0xfe,0x01},
+
+ {0x1f,0xe0,0x1f,0xe0,0x0e,0xf1,0x0e,0xf1},
+ {0xe0,0x1f,0xe0,0x1f,0xf1,0x0e,0xf1,0x0e},
+
+ {0x01,0xe0,0x01,0xe0,0x01,0xf1,0x01,0xf1},
+ {0xe0,0x01,0xe0,0x01,0xf1,0x01,0xf1,0x01},
+
+ {0x1f,0xfe,0x1f,0xfe,0x0e,0xfe,0x0e,0xfe},
+ {0xfe,0x1f,0xfe,0x1f,0xfe,0x0e,0xfe,0x0e},
+
+ {0x01,0x1f,0x01,0x1f,0x01,0x0e,0x01,0x0e},
+ {0x1f,0x01,0x1f,0x01,0x0e,0x01,0x0e,0x01},
+
+ {0xe0,0xfe,0xe0,0xfe,0xf1,0xfe,0xf1,0xfe},
+ {0xfe,0xe0,0xfe,0xe0,0xfe,0xf1,0xfe,0xf1}
+};
+
+krb5_boolean
+k5_des_is_weak_key(unsigned char *keybits)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(weak) / 8; i++) {
+ if (memcmp(weak[i], keybits, 8) == 0)
+ return TRUE;
+ }
+ return FALSE;
+}
Modified: trunk/src/lib/crypto/nss/enc_provider/des.c
===================================================================
--- trunk/src/lib/crypto/nss/enc_provider/des.c 2011-03-11 04:17:42 UTC (rev 24698)
+++ trunk/src/lib/crypto/nss/enc_provider/des.c 2011-03-11 04:20:17 UTC (rev 24699)
@@ -57,19 +57,32 @@
{
krb5_error_code ret;
- ret = k5_nss_gen_import(key, CKM_DES_CBC, CKA_ENCRYPT);
+ ret = k5_nss_gen_import(key, CKM_DES_CBC, CKA_DECRYPT);
if (ret != 0)
return ret;
return k5_nss_gen_block_iov(key, CKM_DES_CBC, CKA_DECRYPT,
ivec, data, num_data);
}
+static krb5_error_code
+k5_des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data,
+ const krb5_data *ivec, krb5_data *output)
+{
+ krb5_error_code ret;
+
+ ret = k5_nss_gen_import(key, CKM_DES_CBC, CKA_ENCRYPT);
+ if (ret != 0)
+ return ret;
+ return k5_nss_gen_cbcmac_iov(key, CKM_DES_CBC, ivec, data, num_data,
+ output);
+}
+
const struct krb5_enc_provider krb5int_enc_des = {
8,
7, KRB5_MIT_DES_KEYSIZE,
k5_des_encrypt_iov,
k5_des_decrypt_iov,
- NULL,
+ k5_des_cbc_mac,
krb5int_des_init_state,
krb5int_default_free_state,
k5_nss_gen_cleanup
Modified: trunk/src/lib/crypto/nss/enc_provider/enc_gen.c
===================================================================
--- trunk/src/lib/crypto/nss/enc_provider/enc_gen.c 2011-03-11 04:17:42 UTC (rev 24698)
+++ trunk/src/lib/crypto/nss/enc_provider/enc_gen.c 2011-03-11 04:20:17 UTC (rev 24699)
@@ -545,9 +545,8 @@
SECStatus rv;
SECItem *param = NULL;
struct iov_block_state input_pos, output_pos;
- unsigned char storage[MAX_BLOCK_SIZE];
+ unsigned char block[MAX_BLOCK_SIZE], *lastblock;
unsigned char iv0[MAX_BLOCK_SIZE];
- unsigned char *ptr = NULL, *lastptr = NULL;
SECItem iv;
size_t blocksize;
int length = 0;
@@ -557,7 +556,7 @@
IOV_BLOCK_STATE_INIT(&output_pos);
blocksize = PK11_GetBlockSize(mech, NULL);
- assert(blocksize <= sizeof(storage));
+ assert(blocksize <= sizeof(block));
if (output->length < blocksize)
return KRB5_BAD_MSIZE;
@@ -577,23 +576,19 @@
goto done;
}
- lastptr = iv.data;
+ lastblock = iv.data;
for (currentblock = 0;;currentblock++) {
- if (!krb5int_c_iov_get_block_nocopy(storage, blocksize, data, num_data,
- &input_pos, &ptr))
+ if (!krb5int_c_iov_get_block(block, blocksize, data, num_data,
+ &input_pos))
break;
-
- lastptr = NULL;
-
- rv = PK11_CipherOp(ctx, ptr, &length, blocksize, ptr, blocksize);
+ rv = PK11_CipherOp(ctx, block, &length, blocksize, block, blocksize);
if (rv != SECSuccess) {
ret = k5_nss_map_last_error();
goto done;
}
-
- lastptr = ptr;
+ lastblock = block;
}
- memcpy(output->data, lastptr, blocksize);
+ memcpy(output->data, lastblock, blocksize);
done:
if (ctx) {
Modified: trunk/src/lib/crypto/openssl/des/Makefile.in
===================================================================
--- trunk/src/lib/crypto/openssl/des/Makefile.in 2011-03-11 04:17:42 UTC (rev 24698)
+++ trunk/src/lib/crypto/openssl/des/Makefile.in 2011-03-11 04:20:17 UTC (rev 24699)
@@ -7,19 +7,12 @@
PROG_LIBPATH=-L$(TOPLIBD)
PROG_RPATH=$(KRB5_LIBDIR)
+STLIBOBJS= des_keys.o
-STLIBOBJS= des_oldapis.o \
- f_parity.o \
- string2key.o
+OBJS= $(OUTPRE)des_keys.$(OBJEXT)
-OBJS= $(OUTPRE)f_parity.$(OBJEXT) \
- $(OUTPRE)des_oldapis.$(OBJEXT) \
- $(OUTPRE)string2key.$(OBJEXT)
+SRCS= $(srcdir)/des_keys.c
-SRCS= $(srcdir)/f_parity.c \
- $(srcdir)/des_oldapis.c \
- $(srcdir)/string2key.c
-
all-unix:: all-libobjs
includes:: depend
Added: trunk/src/lib/crypto/openssl/des/des_keys.c
===================================================================
--- trunk/src/lib/crypto/openssl/des/des_keys.c (rev 0)
+++ trunk/src/lib/crypto/openssl/des/des_keys.c 2011-03-11 04:20:17 UTC (rev 24699)
@@ -0,0 +1,40 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/openssl/des/des_keys.c - Key functions used by Kerberos code */
+/*
+ * Copyright (C) 2011 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "crypto_int.h"
+#include <openssl/des.h>
+
+void
+k5_des_fixup_key_parity(unsigned char *keybits)
+{
+ DES_set_odd_parity((DES_cblock *)keybits);
+}
+
+krb5_boolean
+k5_des_is_weak_key(unsigned char *keybits)
+{
+ return DES_is_weak_key((DES_cblock *)keybits);
+}
Modified: trunk/src/lib/crypto/openssl/enc_provider/des.c
===================================================================
--- trunk/src/lib/crypto/openssl/enc_provider/des.c 2011-03-11 04:17:42 UTC (rev 24698)
+++ trunk/src/lib/crypto/openssl/enc_provider/des.c 2011-03-11 04:20:17 UTC (rev 24699)
@@ -52,6 +52,7 @@
#include "crypto_int.h"
#include <openssl/evp.h>
+#include <openssl/des.h>
#define DES_BLOCK_SIZE 8
#define DES_KEY_SIZE 8
@@ -188,12 +189,50 @@
return 0;
}
+static krb5_error_code
+k5_des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data,
+ const krb5_data *ivec, krb5_data *output)
+{
+ int ret;
+ struct iov_block_state iov_state;
+ DES_cblock blockY, blockB;
+ DES_key_schedule sched;
+ krb5_boolean empty;
+
+ ret = validate(key, ivec, data, num_data, &empty);
+ if (ret != 0)
+ return ret;
+
+ if (output->length != DES_BLOCK_SIZE)
+ return KRB5_BAD_MSIZE;
+
+ if (DES_set_key((DES_cblock *)key->keyblock.contents, &sched) != 0)
+ return KRB5_CRYPTO_INTERNAL;
+
+ if (ivec != NULL)
+ memcpy(blockY, ivec->data, DES_BLOCK_SIZE);
+ else
+ memset(blockY, 0, DES_BLOCK_SIZE);
+
+ IOV_BLOCK_STATE_INIT(&iov_state);
+ for (;;) {
+ if (!krb5int_c_iov_get_block(blockB, DES_BLOCK_SIZE, data, num_data,
+ &iov_state))
+ break;
+ store_64_n(load_64_n(blockB) ^ load_64_n(blockY), blockB);
+ DES_ecb_encrypt(&blockB, &blockY, &sched, 1);
+ }
+
+ memcpy(output->data, blockY, DES_BLOCK_SIZE);
+ return 0;
+}
+
const struct krb5_enc_provider krb5int_enc_des = {
DES_BLOCK_SIZE,
DES_KEY_BYTES, DES_KEY_SIZE,
k5_des_encrypt,
k5_des_decrypt,
- NULL,
+ k5_des_cbc_mac,
krb5int_des_init_state,
krb5int_default_free_state
};
More information about the cvs-krb5
mailing list