summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/krb5
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2010-11-12 15:27:43 +1100
committerAndrew Bartlett <abartlet@samba.org>2010-11-15 01:25:06 +0000
commit6a27fbbfc4c51ae1635b8a5fa51c470ebc9f01e2 (patch)
tree67429e7173cb2e524bcb340e233008b33241dc77 /source4/heimdal/lib/krb5
parent192a555c9ab425fa8e18ee5bed84a8c2fd527200 (diff)
downloadsamba-6a27fbbfc4c51ae1635b8a5fa51c470ebc9f01e2.tar.gz
samba-6a27fbbfc4c51ae1635b8a5fa51c470ebc9f01e2.tar.bz2
samba-6a27fbbfc4c51ae1635b8a5fa51c470ebc9f01e2.zip
heimdal Extra files required for merge up to current heimdal
Diffstat (limited to 'source4/heimdal/lib/krb5')
-rw-r--r--source4/heimdal/lib/krb5/crypto-aes.c170
-rw-r--r--source4/heimdal/lib/krb5/crypto-algs.c87
-rw-r--r--source4/heimdal/lib/krb5/crypto-arcfour.c325
-rw-r--r--source4/heimdal/lib/krb5/crypto-des-common.c152
-rw-r--r--source4/heimdal/lib/krb5/crypto-des.c375
-rw-r--r--source4/heimdal/lib/krb5/crypto-des3.c226
-rw-r--r--source4/heimdal/lib/krb5/crypto-evp.c182
-rw-r--r--source4/heimdal/lib/krb5/crypto-null.c97
-rw-r--r--source4/heimdal/lib/krb5/crypto-pk.c292
-rw-r--r--source4/heimdal/lib/krb5/crypto-rand.c109
-rw-r--r--source4/heimdal/lib/krb5/crypto-stubs.c102
-rw-r--r--source4/heimdal/lib/krb5/crypto.h182
-rw-r--r--source4/heimdal/lib/krb5/salt-aes.c103
-rw-r--r--source4/heimdal/lib/krb5/salt-arcfour.c112
-rw-r--r--source4/heimdal/lib/krb5/salt-des.c224
-rw-r--r--source4/heimdal/lib/krb5/salt-des3.c150
-rw-r--r--source4/heimdal/lib/krb5/store-int.c58
17 files changed, 2946 insertions, 0 deletions
diff --git a/source4/heimdal/lib/krb5/crypto-aes.c b/source4/heimdal/lib/krb5/crypto-aes.c
new file mode 100644
index 0000000000..25c675c900
--- /dev/null
+++ b/source4/heimdal/lib/krb5/crypto-aes.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+/*
+ * AES
+ */
+
+static struct key_type keytype_aes128 = {
+ KEYTYPE_AES128,
+ "aes-128",
+ 128,
+ 16,
+ sizeof(struct evp_schedule),
+ NULL,
+ _krb5_evp_schedule,
+ _krb5_AES_salt,
+ NULL,
+ _krb5_evp_cleanup,
+ EVP_aes_128_cbc
+};
+
+static struct key_type keytype_aes256 = {
+ KEYTYPE_AES256,
+ "aes-256",
+ 256,
+ 32,
+ sizeof(struct evp_schedule),
+ NULL,
+ _krb5_evp_schedule,
+ _krb5_AES_salt,
+ NULL,
+ _krb5_evp_cleanup,
+ EVP_aes_256_cbc
+};
+
+struct checksum_type _krb5_checksum_hmac_sha1_aes128 = {
+ CKSUMTYPE_HMAC_SHA1_96_AES_128,
+ "hmac-sha1-96-aes128",
+ 64,
+ 12,
+ F_KEYED | F_CPROOF | F_DERIVED,
+ _krb5_SP_HMAC_SHA1_checksum,
+ NULL
+};
+
+struct checksum_type _krb5_checksum_hmac_sha1_aes256 = {
+ CKSUMTYPE_HMAC_SHA1_96_AES_256,
+ "hmac-sha1-96-aes256",
+ 64,
+ 12,
+ F_KEYED | F_CPROOF | F_DERIVED,
+ _krb5_SP_HMAC_SHA1_checksum,
+ NULL
+};
+
+static krb5_error_code
+AES_PRF(krb5_context context,
+ krb5_crypto crypto,
+ const krb5_data *in,
+ krb5_data *out)
+{
+ struct checksum_type *ct = crypto->et->checksum;
+ krb5_error_code ret;
+ Checksum result;
+ krb5_keyblock *derived;
+
+ result.cksumtype = ct->type;
+ ret = krb5_data_alloc(&result.checksum, ct->checksumsize);
+ if (ret) {
+ krb5_set_error_message(context, ret, N_("malloc: out memory", ""));
+ return ret;
+ }
+
+ ret = (*ct->checksum)(context, NULL, in->data, in->length, 0, &result);
+ if (ret) {
+ krb5_data_free(&result.checksum);
+ return ret;
+ }
+
+ if (result.checksum.length < crypto->et->blocksize)
+ krb5_abortx(context, "internal prf error");
+
+ derived = NULL;
+ ret = krb5_derive_key(context, crypto->key.key,
+ crypto->et->type, "prf", 3, &derived);
+ if (ret)
+ krb5_abortx(context, "krb5_derive_key");
+
+ ret = krb5_data_alloc(out, crypto->et->blocksize);
+ if (ret)
+ krb5_abortx(context, "malloc failed");
+
+ {
+ const EVP_CIPHER *c = (*crypto->et->keytype->evp)();
+ EVP_CIPHER_CTX ctx;
+
+ EVP_CIPHER_CTX_init(&ctx); /* ivec all zero */
+ EVP_CipherInit_ex(&ctx, c, NULL, derived->keyvalue.data, NULL, 1);
+ EVP_Cipher(&ctx, out->data, result.checksum.data,
+ crypto->et->blocksize);
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ }
+
+ krb5_data_free(&result.checksum);
+ krb5_free_keyblock(context, derived);
+
+ return ret;
+}
+
+struct encryption_type _krb5_enctype_aes128_cts_hmac_sha1 = {
+ ETYPE_AES128_CTS_HMAC_SHA1_96,
+ "aes128-cts-hmac-sha1-96",
+ 16,
+ 1,
+ 16,
+ &keytype_aes128,
+ &_krb5_checksum_sha1,
+ &_krb5_checksum_hmac_sha1_aes128,
+ F_DERIVED,
+ _krb5_evp_encrypt_cts,
+ 16,
+ AES_PRF
+};
+
+struct encryption_type _krb5_enctype_aes256_cts_hmac_sha1 = {
+ ETYPE_AES256_CTS_HMAC_SHA1_96,
+ "aes256-cts-hmac-sha1-96",
+ 16,
+ 1,
+ 16,
+ &keytype_aes256,
+ &_krb5_checksum_sha1,
+ &_krb5_checksum_hmac_sha1_aes256,
+ F_DERIVED,
+ _krb5_evp_encrypt_cts,
+ 16,
+ AES_PRF
+};
diff --git a/source4/heimdal/lib/krb5/crypto-algs.c b/source4/heimdal/lib/krb5/crypto-algs.c
new file mode 100644
index 0000000000..5bd14ce09d
--- /dev/null
+++ b/source4/heimdal/lib/krb5/crypto-algs.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+#ifndef HEIMDAL_SMALLER
+#define DES3_OLD_ENCTYPE 1
+#endif
+
+struct checksum_type *_krb5_checksum_types[] = {
+ &_krb5_checksum_none,
+#ifdef HEIM_WEAK_CRYPTO
+ &_krb5_checksum_crc32,
+ &_krb5_checksum_rsa_md4,
+ &_krb5_checksum_rsa_md4_des,
+ &_krb5_checksum_rsa_md5_des,
+#endif
+#ifdef DES3_OLD_ENCTYPE
+ &_krb5_checksum_rsa_md5_des3,
+#endif
+ &_krb5_checksum_rsa_md5,
+ &_krb5_checksum_sha1,
+ &_krb5_checksum_hmac_sha1_des3,
+ &_krb5_checksum_hmac_sha1_aes128,
+ &_krb5_checksum_hmac_sha1_aes256,
+ &_krb5_checksum_hmac_md5
+};
+
+int _krb5_num_checksums
+ = sizeof(_krb5_checksum_types) / sizeof(_krb5_checksum_types[0]);
+
+/*
+ * these should currently be in reverse preference order.
+ * (only relevant for !F_PSEUDO) */
+
+struct encryption_type *_krb5_etypes[] = {
+ &_krb5_enctype_aes256_cts_hmac_sha1,
+ &_krb5_enctype_aes128_cts_hmac_sha1,
+ &_krb5_enctype_des3_cbc_sha1,
+ &_krb5_enctype_des3_cbc_none, /* used by the gss-api mech */
+ &_krb5_enctype_arcfour_hmac_md5,
+#ifdef DES3_OLD_ENCTYPE
+ &_krb5_enctype_des3_cbc_md5,
+ &_krb5_enctype_old_des3_cbc_sha1,
+#endif
+#ifdef HEIM_WEAK_CRYPTO
+ &_krb5_enctype_des_cbc_crc,
+ &_krb5_enctype_des_cbc_md4,
+ &_krb5_enctype_des_cbc_md5,
+ &_krb5_enctype_des_cbc_none,
+ &_krb5_enctype_des_cfb64_none,
+ &_krb5_enctype_des_pcbc_none,
+#endif
+ &_krb5_enctype_null
+};
+
+int _krb5_num_etypes = sizeof(_krb5_etypes) / sizeof(_krb5_etypes[0]);
diff --git a/source4/heimdal/lib/krb5/crypto-arcfour.c b/source4/heimdal/lib/krb5/crypto-arcfour.c
new file mode 100644
index 0000000000..d098561474
--- /dev/null
+++ b/source4/heimdal/lib/krb5/crypto-arcfour.c
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * ARCFOUR
+ */
+
+#include "krb5_locl.h"
+
+static struct key_type keytype_arcfour = {
+ KEYTYPE_ARCFOUR,
+ "arcfour",
+ 128,
+ 16,
+ sizeof(struct evp_schedule),
+ NULL,
+ _krb5_evp_schedule,
+ _krb5_arcfour_salt,
+ NULL,
+ _krb5_evp_cleanup,
+ EVP_rc4
+};
+
+/*
+ * checksum according to section 5. of draft-brezak-win2k-krb-rc4-hmac-03.txt
+ */
+
+krb5_error_code
+_krb5_HMAC_MD5_checksum(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *result)
+{
+ EVP_MD_CTX *m;
+ struct checksum_type *c = _krb5_find_checksum (CKSUMTYPE_RSA_MD5);
+ const char signature[] = "signaturekey";
+ Checksum ksign_c;
+ struct key_data ksign;
+ krb5_keyblock kb;
+ unsigned char t[4];
+ unsigned char tmp[16];
+ unsigned char ksign_c_data[16];
+ krb5_error_code ret;
+
+ m = EVP_MD_CTX_create();
+ if (m == NULL) {
+ krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+ ksign_c.checksum.length = sizeof(ksign_c_data);
+ ksign_c.checksum.data = ksign_c_data;
+ ret = _krb5_internal_hmac(context, c, signature, sizeof(signature),
+ 0, key, &ksign_c);
+ if (ret) {
+ EVP_MD_CTX_destroy(m);
+ return ret;
+ }
+ ksign.key = &kb;
+ kb.keyvalue = ksign_c.checksum;
+ EVP_DigestInit_ex(m, EVP_md5(), NULL);
+ t[0] = (usage >> 0) & 0xFF;
+ t[1] = (usage >> 8) & 0xFF;
+ t[2] = (usage >> 16) & 0xFF;
+ t[3] = (usage >> 24) & 0xFF;
+ EVP_DigestUpdate(m, t, 4);
+ EVP_DigestUpdate(m, data, len);
+ EVP_DigestFinal_ex (m, tmp, NULL);
+ EVP_MD_CTX_destroy(m);
+
+ ret = _krb5_internal_hmac(context, c, tmp, sizeof(tmp), 0, &ksign, result);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+struct checksum_type _krb5_checksum_hmac_md5 = {
+ CKSUMTYPE_HMAC_MD5,
+ "hmac-md5",
+ 64,
+ 16,
+ F_KEYED | F_CPROOF,
+ _krb5_HMAC_MD5_checksum,
+ NULL
+};
+
+/*
+ * section 6 of draft-brezak-win2k-krb-rc4-hmac-03
+ *
+ * warning: not for small children
+ */
+
+static krb5_error_code
+ARCFOUR_subencrypt(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ unsigned usage,
+ void *ivec)
+{
+ EVP_CIPHER_CTX ctx;
+ struct checksum_type *c = _krb5_find_checksum (CKSUMTYPE_RSA_MD5);
+ Checksum k1_c, k2_c, k3_c, cksum;
+ struct key_data ke;
+ krb5_keyblock kb;
+ unsigned char t[4];
+ unsigned char *cdata = data;
+ unsigned char k1_c_data[16], k2_c_data[16], k3_c_data[16];
+ krb5_error_code ret;
+
+ t[0] = (usage >> 0) & 0xFF;
+ t[1] = (usage >> 8) & 0xFF;
+ t[2] = (usage >> 16) & 0xFF;
+ t[3] = (usage >> 24) & 0xFF;
+
+ k1_c.checksum.length = sizeof(k1_c_data);
+ k1_c.checksum.data = k1_c_data;
+
+ ret = _krb5_internal_hmac(NULL, c, t, sizeof(t), 0, key, &k1_c);
+ if (ret)
+ krb5_abortx(context, "hmac failed");
+
+ memcpy (k2_c_data, k1_c_data, sizeof(k1_c_data));
+
+ k2_c.checksum.length = sizeof(k2_c_data);
+ k2_c.checksum.data = k2_c_data;
+
+ ke.key = &kb;
+ kb.keyvalue = k2_c.checksum;
+
+ cksum.checksum.length = 16;
+ cksum.checksum.data = data;
+
+ ret = _krb5_internal_hmac(NULL, c, cdata + 16, len - 16, 0, &ke, &cksum);
+ if (ret)
+ krb5_abortx(context, "hmac failed");
+
+ ke.key = &kb;
+ kb.keyvalue = k1_c.checksum;
+
+ k3_c.checksum.length = sizeof(k3_c_data);
+ k3_c.checksum.data = k3_c_data;
+
+ ret = _krb5_internal_hmac(NULL, c, data, 16, 0, &ke, &k3_c);
+ if (ret)
+ krb5_abortx(context, "hmac failed");
+
+ EVP_CIPHER_CTX_init(&ctx);
+
+ EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, k3_c.checksum.data, NULL, 1);
+ EVP_Cipher(&ctx, cdata + 16, cdata + 16, len - 16);
+ EVP_CIPHER_CTX_cleanup(&ctx);
+
+ memset (k1_c_data, 0, sizeof(k1_c_data));
+ memset (k2_c_data, 0, sizeof(k2_c_data));
+ memset (k3_c_data, 0, sizeof(k3_c_data));
+ return 0;
+}
+
+static krb5_error_code
+ARCFOUR_subdecrypt(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ unsigned usage,
+ void *ivec)
+{
+ EVP_CIPHER_CTX ctx;
+ struct checksum_type *c = _krb5_find_checksum (CKSUMTYPE_RSA_MD5);
+ Checksum k1_c, k2_c, k3_c, cksum;
+ struct key_data ke;
+ krb5_keyblock kb;
+ unsigned char t[4];
+ unsigned char *cdata = data;
+ unsigned char k1_c_data[16], k2_c_data[16], k3_c_data[16];
+ unsigned char cksum_data[16];
+ krb5_error_code ret;
+
+ t[0] = (usage >> 0) & 0xFF;
+ t[1] = (usage >> 8) & 0xFF;
+ t[2] = (usage >> 16) & 0xFF;
+ t[3] = (usage >> 24) & 0xFF;
+
+ k1_c.checksum.length = sizeof(k1_c_data);
+ k1_c.checksum.data = k1_c_data;
+
+ ret = _krb5_internal_hmac(NULL, c, t, sizeof(t), 0, key, &k1_c);
+ if (ret)
+ krb5_abortx(context, "hmac failed");
+
+ memcpy (k2_c_data, k1_c_data, sizeof(k1_c_data));
+
+ k2_c.checksum.length = sizeof(k2_c_data);
+ k2_c.checksum.data = k2_c_data;
+
+ ke.key = &kb;
+ kb.keyvalue = k1_c.checksum;
+
+ k3_c.checksum.length = sizeof(k3_c_data);
+ k3_c.checksum.data = k3_c_data;
+
+ ret = _krb5_internal_hmac(NULL, c, cdata, 16, 0, &ke, &k3_c);
+ if (ret)
+ krb5_abortx(context, "hmac failed");
+
+ EVP_CIPHER_CTX_init(&ctx);
+ EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, k3_c.checksum.data, NULL, 0);
+ EVP_Cipher(&ctx, cdata + 16, cdata + 16, len - 16);
+ EVP_CIPHER_CTX_cleanup(&ctx);
+
+ ke.key = &kb;
+ kb.keyvalue = k2_c.checksum;
+
+ cksum.checksum.length = 16;
+ cksum.checksum.data = cksum_data;
+
+ ret = _krb5_internal_hmac(NULL, c, cdata + 16, len - 16, 0, &ke, &cksum);
+ if (ret)
+ krb5_abortx(context, "hmac failed");
+
+ memset (k1_c_data, 0, sizeof(k1_c_data));
+ memset (k2_c_data, 0, sizeof(k2_c_data));
+ memset (k3_c_data, 0, sizeof(k3_c_data));
+
+ if (ct_memcmp (cksum.checksum.data, data, 16) != 0) {
+ krb5_clear_error_message (context);
+ return KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * convert the usage numbers used in
+ * draft-ietf-cat-kerb-key-derivation-00.txt to the ones in
+ * draft-brezak-win2k-krb-rc4-hmac-04.txt
+ */
+
+krb5_error_code
+_krb5_usage2arcfour(krb5_context context, unsigned *usage)
+{
+ switch (*usage) {
+ case KRB5_KU_AS_REP_ENC_PART : /* 3 */
+ *usage = 8;
+ return 0;
+ case KRB5_KU_USAGE_SEAL : /* 22 */
+ *usage = 13;
+ return 0;
+ case KRB5_KU_USAGE_SIGN : /* 23 */
+ *usage = 15;
+ return 0;
+ case KRB5_KU_USAGE_SEQ: /* 24 */
+ *usage = 0;
+ return 0;
+ default :
+ return 0;
+ }
+}
+
+static krb5_error_code
+ARCFOUR_encrypt(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encryptp,
+ int usage,
+ void *ivec)
+{
+ krb5_error_code ret;
+ unsigned keyusage = usage;
+
+ if((ret = _krb5_usage2arcfour (context, &keyusage)) != 0)
+ return ret;
+
+ if (encryptp)
+ return ARCFOUR_subencrypt (context, key, data, len, keyusage, ivec);
+ else
+ return ARCFOUR_subdecrypt (context, key, data, len, keyusage, ivec);
+}
+
+struct encryption_type _krb5_enctype_arcfour_hmac_md5 = {
+ ETYPE_ARCFOUR_HMAC_MD5,
+ "arcfour-hmac-md5",
+ 1,
+ 1,
+ 8,
+ &keytype_arcfour,
+ &_krb5_checksum_hmac_md5,
+ NULL,
+ F_SPECIAL,
+ ARCFOUR_encrypt,
+ 0,
+ NULL
+};
diff --git a/source4/heimdal/lib/krb5/crypto-des-common.c b/source4/heimdal/lib/krb5/crypto-des-common.c
new file mode 100644
index 0000000000..82d344f28f
--- /dev/null
+++ b/source4/heimdal/lib/krb5/crypto-des-common.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Functions which are used by both single and triple DES enctypes */
+
+#include "krb5_locl.h"
+
+/*
+ * A = A xor B. A & B are 8 bytes.
+ */
+
+void
+_krb5_xor (DES_cblock *key, const unsigned char *b)
+{
+ unsigned char *a = (unsigned char*)key;
+ a[0] ^= b[0];
+ a[1] ^= b[1];
+ a[2] ^= b[2];
+ a[3] ^= b[3];
+ a[4] ^= b[4];
+ a[5] ^= b[5];
+ a[6] ^= b[6];
+ a[7] ^= b[7];
+}
+
+#if defined(DES3_OLD_ENCTYPE) || defined(HEIM_WEAK_CRYPTO)
+krb5_error_code
+_krb5_des_checksum(krb5_context context,
+ const EVP_MD *evp_md,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ Checksum *cksum)
+{
+ struct evp_schedule *ctx = key->schedule->data;
+ EVP_MD_CTX *m;
+ DES_cblock ivec;
+ unsigned char *p = cksum->checksum.data;
+
+ krb5_generate_random_block(p, 8);
+
+ m = EVP_MD_CTX_create();
+ if (m == NULL) {
+ krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+
+ EVP_DigestInit_ex(m, evp_md, NULL);
+ EVP_DigestUpdate(m, p, 8);
+ EVP_DigestUpdate(m, data, len);
+ EVP_DigestFinal_ex (m, p + 8, NULL);
+ EVP_MD_CTX_destroy(m);
+ memset (&ivec, 0, sizeof(ivec));
+ EVP_CipherInit_ex(&ctx->ectx, NULL, NULL, NULL, (void *)&ivec, -1);
+ EVP_Cipher(&ctx->ectx, p, p, 24);
+
+ return 0;
+}
+
+krb5_error_code
+_krb5_des_verify(krb5_context context,
+ const EVP_MD *evp_md,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ Checksum *C)
+{
+ struct evp_schedule *ctx = key->schedule->data;
+ EVP_MD_CTX *m;
+ unsigned char tmp[24];
+ unsigned char res[16];
+ DES_cblock ivec;
+ krb5_error_code ret = 0;
+
+ m = EVP_MD_CTX_create();
+ if (m == NULL) {
+ krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+
+ memset(&ivec, 0, sizeof(ivec));
+ EVP_CipherInit_ex(&ctx->dctx, NULL, NULL, NULL, (void *)&ivec, -1);
+ EVP_Cipher(&ctx->dctx, tmp, C->checksum.data, 24);
+
+ EVP_DigestInit_ex(m, evp_md, NULL);
+ EVP_DigestUpdate(m, tmp, 8); /* confounder */
+ EVP_DigestUpdate(m, data, len);
+ EVP_DigestFinal_ex (m, res, NULL);
+ EVP_MD_CTX_destroy(m);
+ if(ct_memcmp(res, tmp + 8, sizeof(res)) != 0) {
+ krb5_clear_error_message (context);
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ }
+ memset(tmp, 0, sizeof(tmp));
+ memset(res, 0, sizeof(res));
+ return ret;
+}
+
+#endif
+
+static krb5_error_code
+RSA_MD5_checksum(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *C)
+{
+ if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md5(), NULL) != 1)
+ krb5_abortx(context, "md5 checksum failed");
+ return 0;
+}
+
+struct checksum_type _krb5_checksum_rsa_md5 = {
+ CKSUMTYPE_RSA_MD5,
+ "rsa-md5",
+ 64,
+ 16,
+ F_CPROOF,
+ RSA_MD5_checksum,
+ NULL
+};
diff --git a/source4/heimdal/lib/krb5/crypto-des.c b/source4/heimdal/lib/krb5/crypto-des.c
new file mode 100644
index 0000000000..f6c09ba40c
--- /dev/null
+++ b/source4/heimdal/lib/krb5/crypto-des.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+#ifdef HEIM_WEAK_CRYPTO
+
+
+static void
+krb5_DES_random_key(krb5_context context,
+ krb5_keyblock *key)
+{
+ DES_cblock *k = key->keyvalue.data;
+ do {
+ krb5_generate_random_block(k, sizeof(DES_cblock));
+ DES_set_odd_parity(k);
+ } while(DES_is_weak_key(k));
+}
+
+static void
+krb5_DES_schedule_old(krb5_context context,
+ struct key_type *kt,
+ struct key_data *key)
+{
+ DES_set_key_unchecked(key->key->keyvalue.data, key->schedule->data);
+}
+
+static void
+krb5_DES_random_to_key(krb5_context context,
+ krb5_keyblock *key,
+ const void *data,
+ size_t size)
+{
+ DES_cblock *k = key->keyvalue.data;
+ memcpy(k, data, key->keyvalue.length);
+ DES_set_odd_parity(k);
+ if(DES_is_weak_key(k))
+ _krb5_xor(k, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
+}
+
+static struct key_type keytype_des_old = {
+ KEYTYPE_DES,
+ "des-old",
+ 56,
+ 8,
+ sizeof(DES_key_schedule),
+ krb5_DES_random_key,
+ krb5_DES_schedule_old,
+ _krb5_des_salt,
+ krb5_DES_random_to_key
+};
+
+static struct key_type keytype_des = {
+ KEYTYPE_DES,
+ "des",
+ 56,
+ 8,
+ sizeof(struct evp_schedule),
+ krb5_DES_random_key,
+ _krb5_evp_schedule,
+ _krb5_des_salt,
+ krb5_DES_random_to_key,
+ _krb5_evp_cleanup,
+ EVP_des_cbc
+};
+
+static krb5_error_code
+CRC32_checksum(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *C)
+{
+ uint32_t crc;
+ unsigned char *r = C->checksum.data;
+ _krb5_crc_init_table ();
+ crc = _krb5_crc_update (data, len, 0);
+ r[0] = crc & 0xff;
+ r[1] = (crc >> 8) & 0xff;
+ r[2] = (crc >> 16) & 0xff;
+ r[3] = (crc >> 24) & 0xff;
+ return 0;
+}
+
+static krb5_error_code
+RSA_MD4_checksum(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *C)
+{
+ if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md4(), NULL) != 1)
+ krb5_abortx(context, "md4 checksum failed");
+ return 0;
+}
+
+static krb5_error_code
+RSA_MD4_DES_checksum(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *cksum)
+{
+ return _krb5_des_checksum(context, EVP_md4(), key, data, len, cksum);
+}
+
+static krb5_error_code
+RSA_MD4_DES_verify(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *C)
+{
+ return _krb5_des_verify(context, EVP_md4(), key, data, len, C);
+}
+
+static krb5_error_code
+RSA_MD5_DES_checksum(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *C)
+{
+ return _krb5_des_checksum(context, EVP_md5(), key, data, len, C);
+}
+
+static krb5_error_code
+RSA_MD5_DES_verify(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *C)
+{
+ return _krb5_des_verify(context, EVP_md5(), key, data, len, C);
+}
+
+struct checksum_type _krb5_checksum_crc32 = {
+ CKSUMTYPE_CRC32,
+ "crc32",
+ 1,
+ 4,
+ 0,
+ CRC32_checksum,
+ NULL
+};
+
+struct checksum_type _krb5_checksum_rsa_md4 = {
+ CKSUMTYPE_RSA_MD4,
+ "rsa-md4",
+ 64,
+ 16,
+ F_CPROOF,
+ RSA_MD4_checksum,
+ NULL
+};
+
+struct checksum_type _krb5_checksum_rsa_md4_des = {
+ CKSUMTYPE_RSA_MD4_DES,
+ "rsa-md4-des",
+ 64,
+ 24,
+ F_KEYED | F_CPROOF | F_VARIANT,
+ RSA_MD4_DES_checksum,
+ RSA_MD4_DES_verify
+};
+
+struct checksum_type _krb5_checksum_rsa_md5_des = {
+ CKSUMTYPE_RSA_MD5_DES,
+ "rsa-md5-des",
+ 64,
+ 24,
+ F_KEYED | F_CPROOF | F_VARIANT,
+ RSA_MD5_DES_checksum,
+ RSA_MD5_DES_verify
+};
+
+static krb5_error_code
+evp_des_encrypt_null_ivec(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encryptp,
+ int usage,
+ void *ignore_ivec)
+{
+ struct evp_schedule *ctx = key->schedule->data;
+ EVP_CIPHER_CTX *c;
+ DES_cblock ivec;
+ memset(&ivec, 0, sizeof(ivec));
+ c = encryptp ? &ctx->ectx : &ctx->dctx;
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, (void *)&ivec, -1);
+ EVP_Cipher(c, data, data, len);
+ return 0;
+}
+
+static krb5_error_code
+evp_des_encrypt_key_ivec(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encryptp,
+ int usage,
+ void *ignore_ivec)
+{
+ struct evp_schedule *ctx = key->schedule->data;
+ EVP_CIPHER_CTX *c;
+ DES_cblock ivec;
+ memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
+ c = encryptp ? &ctx->ectx : &ctx->dctx;
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, (void *)&ivec, -1);
+ EVP_Cipher(c, data, data, len);
+ return 0;
+}
+
+static krb5_error_code
+DES_CFB64_encrypt_null_ivec(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encryptp,
+ int usage,
+ void *ignore_ivec)
+{
+ DES_cblock ivec;
+ int num = 0;
+ DES_key_schedule *s = key->schedule->data;
+ memset(&ivec, 0, sizeof(ivec));
+
+ DES_cfb64_encrypt(data, data, len, s, &ivec, &num, encryptp);
+ return 0;
+}
+
+static krb5_error_code
+DES_PCBC_encrypt_key_ivec(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encryptp,
+ int usage,
+ void *ignore_ivec)
+{
+ DES_cblock ivec;
+ DES_key_schedule *s = key->schedule->data;
+ memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
+
+ DES_pcbc_encrypt(data, data, len, s, &ivec, encryptp);
+ return 0;
+}
+
+struct encryption_type _krb5_enctype_des_cbc_crc = {
+ ETYPE_DES_CBC_CRC,
+ "des-cbc-crc",
+ 8,
+ 8,
+ 8,
+ &keytype_des,
+ &_krb5_checksum_crc32,
+ NULL,
+ F_DISABLED|F_WEAK,
+ evp_des_encrypt_key_ivec,
+ 0,
+ NULL
+};
+
+struct encryption_type _krb5_enctype_des_cbc_md4 = {
+ ETYPE_DES_CBC_MD4,
+ "des-cbc-md4",
+ 8,
+ 8,
+ 8,
+ &keytype_des,
+ &_krb5_checksum_rsa_md4,
+ &_krb5_checksum_rsa_md4_des,
+ F_DISABLED|F_WEAK,
+ evp_des_encrypt_null_ivec,
+ 0,
+ NULL
+};
+
+struct encryption_type _krb5_enctype_des_cbc_md5 = {
+ ETYPE_DES_CBC_MD5,
+ "des-cbc-md5",
+ 8,
+ 8,
+ 8,
+ &keytype_des,
+ &_krb5_checksum_rsa_md5,
+ &_krb5_checksum_rsa_md5_des,
+ F_DISABLED|F_WEAK,
+ evp_des_encrypt_null_ivec,
+ 0,
+ NULL
+};
+
+struct encryption_type _krb5_enctype_des_cbc_none = {
+ ETYPE_DES_CBC_NONE,
+ "des-cbc-none",
+ 8,
+ 8,
+ 0,
+ &keytype_des,
+ &_krb5_checksum_none,
+ NULL,
+ F_PSEUDO|F_DISABLED|F_WEAK,
+ evp_des_encrypt_null_ivec,
+ 0,
+ NULL
+};
+
+struct encryption_type _krb5_enctype_des_cfb64_none = {
+ ETYPE_DES_CFB64_NONE,
+ "des-cfb64-none",
+ 1,
+ 1,
+ 0,
+ &keytype_des_old,
+ &_krb5_checksum_none,
+ NULL,
+ F_PSEUDO|F_DISABLED|F_WEAK,
+ DES_CFB64_encrypt_null_ivec,
+ 0,
+ NULL
+};
+
+struct encryption_type _krb5_enctype_des_pcbc_none = {
+ ETYPE_DES_PCBC_NONE,
+ "des-pcbc-none",
+ 8,
+ 8,
+ 0,
+ &keytype_des_old,
+ &_krb5_checksum_none,
+ NULL,
+ F_PSEUDO|F_DISABLED|F_WEAK,
+ DES_PCBC_encrypt_key_ivec,
+ 0,
+ NULL
+};
+#endif /* HEIM_WEAK_CRYPTO */
diff --git a/source4/heimdal/lib/krb5/crypto-des3.c b/source4/heimdal/lib/krb5/crypto-des3.c
new file mode 100644
index 0000000000..1ff692b520
--- /dev/null
+++ b/source4/heimdal/lib/krb5/crypto-des3.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+/*
+ *
+ */
+
+static void
+DES3_random_key(krb5_context context,
+ krb5_keyblock *key)
+{
+ DES_cblock *k = key->keyvalue.data;
+ do {
+ krb5_generate_random_block(k, 3 * sizeof(DES_cblock));
+ DES_set_odd_parity(&k[0]);
+ DES_set_odd_parity(&k[1]);
+ DES_set_odd_parity(&k[2]);
+ } while(DES_is_weak_key(&k[0]) ||
+ DES_is_weak_key(&k[1]) ||
+ DES_is_weak_key(&k[2]));
+}
+
+
+#ifdef DES3_OLD_ENCTYPE
+static struct key_type keytype_des3 = {
+ KEYTYPE_DES3,
+ "des3",
+ 168,
+ 24,
+ sizeof(struct evp_schedule),
+ DES3_random_key,
+ _krb5_evp_schedule,
+ _krb5_des3_salt,
+ _krb5_DES3_random_to_key,
+ _krb5_evp_cleanup,
+ EVP_des_ede3_cbc
+};
+#endif
+
+static struct key_type keytype_des3_derived = {
+ KEYTYPE_DES3,
+ "des3",
+ 168,
+ 24,
+ sizeof(struct evp_schedule),
+ DES3_random_key,
+ _krb5_evp_schedule,
+ _krb5_des3_salt_derived,
+ _krb5_DES3_random_to_key,
+ _krb5_evp_cleanup,
+ EVP_des_ede3_cbc
+};
+
+#ifdef DES3_OLD_ENCTYPE
+static krb5_error_code
+RSA_MD5_DES3_checksum(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *C)
+{
+ return _krb5_des_checksum(context, EVP_md5(), key, data, len, C);
+}
+
+static krb5_error_code
+RSA_MD5_DES3_verify(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *C)
+{
+ return _krb5_des_verify(context, EVP_md5(), key, data, len, C);
+}
+
+struct checksum_type _krb5_checksum_rsa_md5_des3 = {
+ CKSUMTYPE_RSA_MD5_DES3,
+ "rsa-md5-des3",
+ 64,
+ 24,
+ F_KEYED | F_CPROOF | F_VARIANT,
+ RSA_MD5_DES3_checksum,
+ RSA_MD5_DES3_verify
+};
+#endif
+
+struct checksum_type _krb5_checksum_hmac_sha1_des3 = {
+ CKSUMTYPE_HMAC_SHA1_DES3,
+ "hmac-sha1-des3",
+ 64,
+ 20,
+ F_KEYED | F_CPROOF | F_DERIVED,
+ _krb5_SP_HMAC_SHA1_checksum,
+ NULL
+};
+
+#ifdef DES3_OLD_ENCTYPE
+struct encryption_type _krb5_enctype_des3_cbc_md5 = {
+ ETYPE_DES3_CBC_MD5,
+ "des3-cbc-md5",
+ 8,
+ 8,
+ 8,
+ &keytype_des3,
+ &_krb5_checksum_rsa_md5,
+ &_krb5_checksum_rsa_md5_des3,
+ 0,
+ _krb5_evp_encrypt,
+ 0,
+ NULL
+};
+#endif
+
+struct encryption_type _krb5_enctype_des3_cbc_sha1 = {
+ ETYPE_DES3_CBC_SHA1,
+ "des3-cbc-sha1",
+ 8,
+ 8,
+ 8,
+ &keytype_des3_derived,
+ &_krb5_checksum_sha1,
+ &_krb5_checksum_hmac_sha1_des3,
+ F_DERIVED,
+ _krb5_evp_encrypt,
+ 0,
+ NULL
+};
+
+#ifdef DES3_OLD_ENCTYPE
+struct encryption_type _krb5_enctype_old_des3_cbc_sha1 = {
+ ETYPE_OLD_DES3_CBC_SHA1,
+ "old-des3-cbc-sha1",
+ 8,
+ 8,
+ 8,
+ &keytype_des3,
+ &_krb5_checksum_sha1,
+ &_krb5_checksum_hmac_sha1_des3,
+ 0,
+ _krb5_evp_encrypt,
+ 0,
+ NULL
+};
+#endif
+
+struct encryption_type _krb5_enctype_des3_cbc_none = {
+ ETYPE_DES3_CBC_NONE,
+ "des3-cbc-none",
+ 8,
+ 8,
+ 0,
+ &keytype_des3_derived,
+ &_krb5_checksum_none,
+ NULL,
+ F_PSEUDO,
+ _krb5_evp_encrypt,
+ 0,
+ NULL
+};
+
+void
+_krb5_DES3_random_to_key(krb5_context context,
+ krb5_keyblock *key,
+ const void *data,
+ size_t size)
+{
+ unsigned char *x = key->keyvalue.data;
+ const u_char *q = data;
+ DES_cblock *k;
+ int i, j;
+
+ memset(x, 0, sizeof(x));
+ for (i = 0; i < 3; ++i) {
+ unsigned char foo;
+ for (j = 0; j < 7; ++j) {
+ unsigned char b = q[7 * i + j];
+
+ x[8 * i + j] = b;
+ }
+ foo = 0;
+ for (j = 6; j >= 0; --j) {
+ foo |= q[7 * i + j] & 1;
+ foo <<= 1;
+ }
+ x[8 * i + 7] = foo;
+ }
+ k = key->keyvalue.data;
+ for (i = 0; i < 3; i++) {
+ DES_set_odd_parity(&k[i]);
+ if(DES_is_weak_key(&k[i]))
+ _krb5_xor(&k[i], (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
+ }
+}
diff --git a/source4/heimdal/lib/krb5/crypto-evp.c b/source4/heimdal/lib/krb5/crypto-evp.c
new file mode 100644
index 0000000000..69d1e2679d
--- /dev/null
+++ b/source4/heimdal/lib/krb5/crypto-evp.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+void
+_krb5_evp_schedule(krb5_context context,
+ struct key_type *kt,
+ struct key_data *kd)
+{
+ struct evp_schedule *key = kd->schedule->data;
+ const EVP_CIPHER *c = (*kt->evp)();
+
+ EVP_CIPHER_CTX_init(&key->ectx);
+ EVP_CIPHER_CTX_init(&key->dctx);
+
+ EVP_CipherInit_ex(&key->ectx, c, NULL, kd->key->keyvalue.data, NULL, 1);
+ EVP_CipherInit_ex(&key->dctx, c, NULL, kd->key->keyvalue.data, NULL, 0);
+}
+
+void
+_krb5_evp_cleanup(krb5_context context, struct key_data *kd)
+{
+ struct evp_schedule *key = kd->schedule->data;
+ EVP_CIPHER_CTX_cleanup(&key->ectx);
+ EVP_CIPHER_CTX_cleanup(&key->dctx);
+}
+
+krb5_error_code
+_krb5_evp_encrypt(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encryptp,
+ int usage,
+ void *ivec)
+{
+ struct evp_schedule *ctx = key->schedule->data;
+ EVP_CIPHER_CTX *c;
+ c = encryptp ? &ctx->ectx : &ctx->dctx;
+ if (ivec == NULL) {
+ /* alloca ? */
+ size_t len2 = EVP_CIPHER_CTX_iv_length(c);
+ void *loiv = malloc(len2);
+ if (loiv == NULL) {
+ krb5_clear_error_message(context);
+ return ENOMEM;
+ }
+ memset(loiv, 0, len2);
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, loiv, -1);
+ free(loiv);
+ } else
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, ivec, -1);
+ EVP_Cipher(c, data, data, len);
+ return 0;
+}
+
+static const unsigned char zero_ivec[EVP_MAX_BLOCK_LENGTH] = { 0 };
+
+krb5_error_code
+_krb5_evp_encrypt_cts(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encryptp,
+ int usage,
+ void *ivec)
+{
+ size_t i, blocksize;
+ struct evp_schedule *ctx = key->schedule->data;
+ char tmp[EVP_MAX_BLOCK_LENGTH], ivec2[EVP_MAX_BLOCK_LENGTH];
+ EVP_CIPHER_CTX *c;
+ unsigned char *p;
+
+ c = encryptp ? &ctx->ectx : &ctx->dctx;
+
+ blocksize = EVP_CIPHER_CTX_block_size(c);
+
+ if (len < blocksize) {
+ krb5_set_error_message(context, EINVAL,
+ "message block too short");
+ return EINVAL;
+ } else if (len == blocksize) {
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
+ EVP_Cipher(c, data, data, len);
+ return 0;
+ }
+
+ if (ivec)
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, ivec, -1);
+ else
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
+
+ if (encryptp) {
+
+ p = data;
+ i = ((len - 1) / blocksize) * blocksize;
+ EVP_Cipher(c, p, p, i);
+ p += i - blocksize;
+ len -= i;
+ memcpy(ivec2, p, blocksize);
+
+ for (i = 0; i < len; i++)
+ tmp[i] = p[i + blocksize] ^ ivec2[i];
+ for (; i < blocksize; i++)
+ tmp[i] = 0 ^ ivec2[i];
+
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
+ EVP_Cipher(c, p, tmp, blocksize);
+
+ memcpy(p + blocksize, ivec2, len);
+ if (ivec)
+ memcpy(ivec, p, blocksize);
+ } else {
+ char tmp2[EVP_MAX_BLOCK_LENGTH], tmp3[EVP_MAX_BLOCK_LENGTH];
+
+ p = data;
+ if (len > blocksize * 2) {
+ /* remove last two blocks and round up, decrypt this with cbc, then do cts dance */
+ i = ((((len - blocksize * 2) + blocksize - 1) / blocksize) * blocksize);
+ memcpy(ivec2, p + i - blocksize, blocksize);
+ EVP_Cipher(c, p, p, i);
+ p += i;
+ len -= i + blocksize;
+ } else {
+ if (ivec)
+ memcpy(ivec2, ivec, blocksize);
+ else
+ memcpy(ivec2, zero_ivec, blocksize);
+ len -= blocksize;
+ }
+
+ memcpy(tmp, p, blocksize);
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
+ EVP_Cipher(c, tmp2, p, blocksize);
+
+ memcpy(tmp3, p + blocksize, len);
+ memcpy(tmp3 + len, tmp2 + len, blocksize - len); /* xor 0 */
+
+ for (i = 0; i < len; i++)
+ p[i + blocksize] = tmp2[i] ^ tmp3[i];
+
+ EVP_CipherInit_ex(c, NULL, NULL, NULL, zero_ivec, -1);
+ EVP_Cipher(c, p, tmp3, blocksize);
+
+ for (i = 0; i < blocksize; i++)
+ p[i] ^= ivec2[i];
+ if (ivec)
+ memcpy(ivec, tmp, blocksize);
+ }
+ return 0;
+}
diff --git a/source4/heimdal/lib/krb5/crypto-null.c b/source4/heimdal/lib/krb5/crypto-null.c
new file mode 100644
index 0000000000..3a5c6b6cb3
--- /dev/null
+++ b/source4/heimdal/lib/krb5/crypto-null.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+#ifndef HEIMDAL_SMALLER
+#define DES3_OLD_ENCTYPE 1
+#endif
+
+static struct key_type keytype_null = {
+ KEYTYPE_NULL,
+ "null",
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL
+};
+
+static krb5_error_code
+NONE_checksum(krb5_context context,
+ struct key_data *key,
+ const void *data,
+ size_t len,
+ unsigned usage,
+ Checksum *C)
+{
+ return 0;
+}
+
+struct checksum_type _krb5_checksum_none = {
+ CKSUMTYPE_NONE,
+ "none",
+ 1,
+ 0,
+ 0,
+ NONE_checksum,
+ NULL
+};
+
+static krb5_error_code
+NULL_encrypt(krb5_context context,
+ struct key_data *key,
+ void *data,
+ size_t len,
+ krb5_boolean encryptp,
+ int usage,
+ void *ivec)
+{
+ return 0;
+}
+
+struct encryption_type _krb5_enctype_null = {
+ ETYPE_NULL,
+ "null",
+ 1,
+ 1,
+ 0,
+ &keytype_null,
+ &_krb5_checksum_none,
+ NULL,
+ F_DISABLED,
+ NULL_encrypt,
+ 0,
+ NULL
+};
diff --git a/source4/heimdal/lib/krb5/crypto-pk.c b/source4/heimdal/lib/krb5/crypto-pk.c
new file mode 100644
index 0000000000..21e729c9e1
--- /dev/null
+++ b/source4/heimdal/lib/krb5/crypto-pk.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+#include <pkinit_asn1.h>
+
+krb5_error_code
+_krb5_pk_octetstring2key(krb5_context context,
+ krb5_enctype type,
+ const void *dhdata,
+ size_t dhsize,
+ const heim_octet_string *c_n,
+ const heim_octet_string *k_n,
+ krb5_keyblock *key)
+{
+ struct encryption_type *et = _krb5_find_enctype(type);
+ krb5_error_code ret;
+ size_t keylen, offset;
+ void *keydata;
+ unsigned char counter;
+ unsigned char shaoutput[SHA_DIGEST_LENGTH];
+ EVP_MD_CTX *m;
+
+ if(et == NULL) {
+ krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+ N_("encryption type %d not supported", ""),
+ type);
+ return KRB5_PROG_ETYPE_NOSUPP;
+ }
+ keylen = (et->keytype->bits + 7) / 8;
+
+ keydata = malloc(keylen);
+ if (keydata == NULL) {
+ krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+
+ m = EVP_MD_CTX_create();
+ if (m == NULL) {
+ free(keydata);
+ krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+
+ counter = 0;
+ offset = 0;
+ do {
+
+ EVP_DigestInit_ex(m, EVP_sha1(), NULL);
+ EVP_DigestUpdate(m, &counter, 1);
+ EVP_DigestUpdate(m, dhdata, dhsize);
+
+ if (c_n)
+ EVP_DigestUpdate(m, c_n->data, c_n->length);
+ if (k_n)
+ EVP_DigestUpdate(m, k_n->data, k_n->length);
+
+ EVP_DigestFinal_ex(m, shaoutput, NULL);
+
+ memcpy((unsigned char *)keydata + offset,
+ shaoutput,
+ min(keylen - offset, sizeof(shaoutput)));
+
+ offset += sizeof(shaoutput);
+ counter++;
+ } while(offset < keylen);
+ memset(shaoutput, 0, sizeof(shaoutput));
+
+ EVP_MD_CTX_destroy(m);
+
+ ret = krb5_random_to_key(context, type, keydata, keylen, key);
+ memset(keydata, 0, sizeof(keylen));
+ free(keydata);
+ return ret;
+}
+
+static krb5_error_code
+encode_uvinfo(krb5_context context, krb5_const_principal p, krb5_data *data)
+{
+ KRB5PrincipalName pn;
+ krb5_error_code ret;
+ size_t size;
+
+ pn.principalName = p->name;
+ pn.realm = p->realm;
+
+ ASN1_MALLOC_ENCODE(KRB5PrincipalName, data->data, data->length,
+ &pn, &size, ret);
+ if (ret) {
+ krb5_data_zero(data);
+ krb5_set_error_message(context, ret,
+ N_("Failed to encode KRB5PrincipalName", ""));
+ return ret;
+ }
+ if (data->length != size)
+ krb5_abortx(context, "asn1 compiler internal error");
+ return 0;
+}
+
+static krb5_error_code
+encode_otherinfo(krb5_context context,
+ const AlgorithmIdentifier *ai,
+ krb5_const_principal client,
+ krb5_const_principal server,
+ krb5_enctype enctype,
+ const krb5_data *as_req,
+ const krb5_data *pk_as_rep,
+ const Ticket *ticket,
+ krb5_data *other)
+{
+ PkinitSP80056AOtherInfo otherinfo;
+ PkinitSuppPubInfo pubinfo;
+ krb5_error_code ret;
+ krb5_data pub;
+ size_t size;
+
+ krb5_data_zero(other);
+ memset(&otherinfo, 0, sizeof(otherinfo));
+ memset(&pubinfo, 0, sizeof(pubinfo));
+
+ pubinfo.enctype = enctype;
+ pubinfo.as_REQ = *as_req;
+ pubinfo.pk_as_rep = *pk_as_rep;
+ pubinfo.ticket = *ticket;
+ ASN1_MALLOC_ENCODE(PkinitSuppPubInfo, pub.data, pub.length,
+ &pubinfo, &size, ret);
+ if (ret) {
+ krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+ return ret;
+ }
+ if (pub.length != size)
+ krb5_abortx(context, "asn1 compiler internal error");
+
+ ret = encode_uvinfo(context, client, &otherinfo.partyUInfo);
+ if (ret) {
+ free(pub.data);
+ return ret;
+ }
+ ret = encode_uvinfo(context, server, &otherinfo.partyVInfo);
+ if (ret) {
+ free(otherinfo.partyUInfo.data);
+ free(pub.data);
+ return ret;
+ }
+
+ otherinfo.algorithmID = *ai;
+ otherinfo.suppPubInfo = &pub;
+
+ ASN1_MALLOC_ENCODE(PkinitSP80056AOtherInfo, other->data, other->length,
+ &otherinfo, &size, ret);
+ free(otherinfo.partyUInfo.data);
+ free(otherinfo.partyVInfo.data);
+ free(pub.data);
+ if (ret) {
+ krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+ return ret;
+ }
+ if (other->length != size)
+ krb5_abortx(context, "asn1 compiler internal error");
+
+ return 0;
+}
+
+krb5_error_code
+_krb5_pk_kdf(krb5_context context,
+ const struct AlgorithmIdentifier *ai,
+ const void *dhdata,
+ size_t dhsize,
+ krb5_const_principal client,
+ krb5_const_principal server,
+ krb5_enctype enctype,
+ const krb5_data *as_req,
+ const krb5_data *pk_as_rep,
+ const Ticket *ticket,
+ krb5_keyblock *key)
+{
+ struct encryption_type *et;
+ krb5_error_code ret;
+ krb5_data other;
+ size_t keylen, offset;
+ uint32_t counter;
+ unsigned char *keydata;
+ unsigned char shaoutput[SHA_DIGEST_LENGTH];
+ EVP_MD_CTX *m;
+
+ if (der_heim_oid_cmp(&asn1_oid_id_pkinit_kdf_ah_sha1, &ai->algorithm) != 0) {
+ krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+ N_("KDF not supported", ""));
+ return KRB5_PROG_ETYPE_NOSUPP;
+ }
+ if (ai->parameters != NULL &&
+ (ai->parameters->length != 2 ||
+ memcmp(ai->parameters->data, "\x05\x00", 2) != 0))
+ {
+ krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+ N_("kdf params not NULL or the NULL-type",
+ ""));
+ return KRB5_PROG_ETYPE_NOSUPP;
+ }
+
+ et = _krb5_find_enctype(enctype);
+ if(et == NULL) {
+ krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
+ N_("encryption type %d not supported", ""),
+ enctype);
+ return KRB5_PROG_ETYPE_NOSUPP;
+ }
+ keylen = (et->keytype->bits + 7) / 8;
+
+ keydata = malloc(keylen);
+ if (keydata == NULL) {
+ krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+
+ ret = encode_otherinfo(context, ai, client, server,
+ enctype, as_req, pk_as_rep, ticket, &other);
+ if (ret) {
+ free(keydata);
+ return ret;
+ }
+
+ m = EVP_MD_CTX_create();
+ if (m == NULL) {
+ free(keydata);
+ free(other.data);
+ krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+
+ offset = 0;
+ counter = 1;
+ do {
+ unsigned char cdata[4];
+
+ EVP_DigestInit_ex(m, EVP_sha1(), NULL);
+ _krb5_put_int(cdata, counter, 4);
+ EVP_DigestUpdate(m, cdata, 4);
+ EVP_DigestUpdate(m, dhdata, dhsize);
+ EVP_DigestUpdate(m, other.data, other.length);
+
+ EVP_DigestFinal_ex(m, shaoutput, NULL);
+
+ memcpy((unsigned char *)keydata + offset,
+ shaoutput,
+ min(keylen - offset, sizeof(shaoutput)));
+
+ offset += sizeof(shaoutput);
+ counter++;
+ } while(offset < keylen);
+ memset(shaoutput, 0, sizeof(shaoutput));
+
+ EVP_MD_CTX_destroy(m);
+ free(other.data);
+
+ ret = krb5_random_to_key(context, enctype, keydata, keylen, key);
+ memset(keydata, 0, sizeof(keylen));
+ free(keydata);
+
+ return ret;
+}
diff --git a/source4/heimdal/lib/krb5/crypto-rand.c b/source4/heimdal/lib/krb5/crypto-rand.c
new file mode 100644
index 0000000000..49bd679362
--- /dev/null
+++ b/source4/heimdal/lib/krb5/crypto-rand.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+#define ENTROPY_NEEDED 128
+
+static HEIMDAL_MUTEX crypto_mutex = HEIMDAL_MUTEX_INITIALIZER;
+
+static int
+seed_something(void)
+{
+ char buf[1024], seedfile[256];
+
+ /* If there is a seed file, load it. But such a file cannot be trusted,
+ so use 0 for the entropy estimate */
+ if (RAND_file_name(seedfile, sizeof(seedfile))) {
+ int fd;
+ fd = open(seedfile, O_RDONLY | O_BINARY | O_CLOEXEC);
+ if (fd >= 0) {
+ ssize_t ret;
+ rk_cloexec(fd);
+ ret = read(fd, buf, sizeof(buf));
+ if (ret > 0)
+ RAND_add(buf, ret, 0.0);
+ close(fd);
+ } else
+ seedfile[0] = '\0';
+ } else
+ seedfile[0] = '\0';
+
+ /* Calling RAND_status() will try to use /dev/urandom if it exists so
+ we do not have to deal with it. */
+ if (RAND_status() != 1) {
+#ifndef _WIN32
+ krb5_context context;
+ const char *p;
+
+ /* Try using egd */
+ if (!krb5_init_context(&context)) {
+ p = krb5_config_get_string(context, NULL, "libdefaults",
+ "egd_socket", NULL);
+ if (p != NULL)
+ RAND_egd_bytes(p, ENTROPY_NEEDED);
+ krb5_free_context(context);
+ }
+#else
+ /* TODO: Once a Windows CryptoAPI RAND method is defined, we
+ can use that and failover to another method. */
+#endif
+ }
+
+ if (RAND_status() == 1) {
+ /* Update the seed file */
+ if (seedfile[0])
+ RAND_write_file(seedfile);
+
+ return 0;
+ } else
+ return -1;
+}
+
+KRB5_LIB_FUNCTION void KRB5_LIB_CALL
+krb5_generate_random_block(void *buf, size_t len)
+{
+ static int rng_initialized = 0;
+
+ HEIMDAL_MUTEX_lock(&crypto_mutex);
+ if (!rng_initialized) {
+ if (seed_something())
+ krb5_abortx(NULL, "Fatal: could not seed the "
+ "random number generator");
+
+ rng_initialized = 1;
+ }
+ HEIMDAL_MUTEX_unlock(&crypto_mutex);
+ if (RAND_bytes(buf, len) <= 0)
+ krb5_abortx(NULL, "Failed to generate random block");
+}
diff --git a/source4/heimdal/lib/krb5/crypto-stubs.c b/source4/heimdal/lib/krb5/crypto-stubs.c
new file mode 100644
index 0000000000..b462680643
--- /dev/null
+++ b/source4/heimdal/lib/krb5/crypto-stubs.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <krb5_locl.h>
+
+/* These are stub functions for the standalone RFC3961 crypto library */
+
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_init_context(krb5_context *context)
+{
+ krb5_context p;
+
+ *context = NULL;
+
+ /* should have a run_once */
+ bindtextdomain(HEIMDAL_TEXTDOMAIN, HEIMDAL_LOCALEDIR);
+
+ p = calloc(1, sizeof(*p));
+ if(!p)
+ return ENOMEM;
+
+ p->mutex = malloc(sizeof(HEIMDAL_MUTEX));
+ if (p->mutex == NULL) {
+ free(p);
+ return ENOMEM;
+ }
+ HEIMDAL_MUTEX_init(p->mutex);
+
+ *context = p;
+ return 0;
+}
+
+KRB5_LIB_FUNCTION void KRB5_LIB_CALL
+krb5_free_context(krb5_context context)
+{
+ krb5_clear_error_message(context);
+
+ HEIMDAL_MUTEX_destroy(context->mutex);
+ free(context->mutex);
+ if (context->flags & KRB5_CTX_F_SOCKETS_INITIALIZED) {
+ rk_SOCK_EXIT();
+ }
+
+ memset(context, 0, sizeof(*context));
+ free(context);
+}
+
+krb5_boolean
+_krb5_homedir_access(krb5_context context) {
+ return 0;
+}
+
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_log(krb5_context context,
+ krb5_log_facility *fac,
+ int level,
+ const char *fmt,
+ ...)
+{
+ return 0;
+}
+
+/* This function is currently just used to get the location of the EGD
+ * socket. If we're not using an EGD, then we can just return NULL */
+
+KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL
+krb5_config_get_string (krb5_context context,
+ const krb5_config_section *c,
+ ...)
+{
+ return NULL;
+}
diff --git a/source4/heimdal/lib/krb5/crypto.h b/source4/heimdal/lib/krb5/crypto.h
new file mode 100644
index 0000000000..c57221b1e6
--- /dev/null
+++ b/source4/heimdal/lib/krb5/crypto.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef HEIMDAL_SMALLER
+#define DES3_OLD_ENCTYPE 1
+#endif
+
+struct key_data {
+ krb5_keyblock *key;
+ krb5_data *schedule;
+};
+
+struct key_usage {
+ unsigned usage;
+ struct key_data key;
+};
+
+struct krb5_crypto_data {
+ struct encryption_type *et;
+ struct key_data key;
+ int num_key_usage;
+ struct key_usage *key_usage;
+};
+
+#define CRYPTO_ETYPE(C) ((C)->et->type)
+
+/* bits for `flags' below */
+#define F_KEYED 1 /* checksum is keyed */
+#define F_CPROOF 2 /* checksum is collision proof */
+#define F_DERIVED 4 /* uses derived keys */
+#define F_VARIANT 8 /* uses `variant' keys (6.4.3) */
+#define F_PSEUDO 16 /* not a real protocol type */
+#define F_SPECIAL 32 /* backwards */
+#define F_DISABLED 64 /* enctype/checksum disabled */
+#define F_WEAK 128 /* enctype is considered weak */
+
+struct salt_type {
+ krb5_salttype type;
+ const char *name;
+ krb5_error_code (*string_to_key)(krb5_context, krb5_enctype, krb5_data,
+ krb5_salt, krb5_data, krb5_keyblock*);
+};
+
+struct key_type {
+ krb5_keytype type; /* XXX */
+ const char *name;
+ size_t bits;
+ size_t size;
+ size_t schedule_size;
+ void (*random_key)(krb5_context, krb5_keyblock*);
+ void (*schedule)(krb5_context, struct key_type *, struct key_data *);
+ struct salt_type *string_to_key;
+ void (*random_to_key)(krb5_context, krb5_keyblock*, const void*, size_t);
+ void (*cleanup)(krb5_context, struct key_data *);
+ const EVP_CIPHER *(*evp)(void);
+};
+
+struct checksum_type {
+ krb5_cksumtype type;
+ const char *name;
+ size_t blocksize;
+ size_t checksumsize;
+ unsigned flags;
+ krb5_error_code (*checksum)(krb5_context context,
+ struct key_data *key,
+ const void *buf, size_t len,
+ unsigned usage,
+ Checksum *csum);
+ krb5_error_code (*verify)(krb5_context context,
+ struct key_data *key,
+ const void *buf, size_t len,
+ unsigned usage,
+ Checksum *csum);
+};
+
+struct encryption_type {
+ krb5_enctype type;
+ const char *name;
+ size_t blocksize;
+ size_t padsize;
+ size_t confoundersize;
+ struct key_type *keytype;
+ struct checksum_type *checksum;
+ struct checksum_type *keyed_checksum;
+ unsigned flags;
+ krb5_error_code (*encrypt)(krb5_context context,
+ struct key_data *key,
+ void *data, size_t len,
+ krb5_boolean encryptp,
+ int usage,
+ void *ivec);
+ size_t prf_length;
+ krb5_error_code (*prf)(krb5_context,
+ krb5_crypto, const krb5_data *, krb5_data *);
+};
+
+#define ENCRYPTION_USAGE(U) (((U) << 8) | 0xAA)
+#define INTEGRITY_USAGE(U) (((U) << 8) | 0x55)
+#define CHECKSUM_USAGE(U) (((U) << 8) | 0x99)
+
+/* Checksums */
+
+extern struct checksum_type _krb5_checksum_none;
+extern struct checksum_type _krb5_checksum_crc32;
+extern struct checksum_type _krb5_checksum_rsa_md4;
+extern struct checksum_type _krb5_checksum_rsa_md4_des;
+extern struct checksum_type _krb5_checksum_rsa_md5_des;
+extern struct checksum_type _krb5_checksum_rsa_md5_des3;
+extern struct checksum_type _krb5_checksum_rsa_md5;
+extern struct checksum_type _krb5_checksum_hmac_sha1_des3;
+extern struct checksum_type _krb5_checksum_hmac_sha1_aes128;
+extern struct checksum_type _krb5_checksum_hmac_sha1_aes256;
+extern struct checksum_type _krb5_checksum_hmac_md5;
+extern struct checksum_type _krb5_checksum_sha1;
+
+extern struct checksum_type *_krb5_checksum_types[];
+extern int _krb5_num_checksums;
+
+/* Salts */
+
+extern struct salt_type _krb5_AES_salt[];
+extern struct salt_type _krb5_arcfour_salt[];
+extern struct salt_type _krb5_des_salt[];
+extern struct salt_type _krb5_des3_salt[];
+extern struct salt_type _krb5_des3_salt_derived[];
+
+/* Encryption types */
+
+extern struct encryption_type _krb5_enctype_aes256_cts_hmac_sha1;
+extern struct encryption_type _krb5_enctype_aes128_cts_hmac_sha1;
+extern struct encryption_type _krb5_enctype_des3_cbc_sha1;
+extern struct encryption_type _krb5_enctype_des3_cbc_md5;
+extern struct encryption_type _krb5_enctype_des3_cbc_none;
+extern struct encryption_type _krb5_enctype_arcfour_hmac_md5;
+extern struct encryption_type _krb5_enctype_des_cbc_md5;
+extern struct encryption_type _krb5_enctype_old_des3_cbc_sha1;
+extern struct encryption_type _krb5_enctype_des_cbc_crc;
+extern struct encryption_type _krb5_enctype_des_cbc_md4;
+extern struct encryption_type _krb5_enctype_des_cbc_md5;
+extern struct encryption_type _krb5_enctype_des_cbc_none;
+extern struct encryption_type _krb5_enctype_des_cfb64_none;
+extern struct encryption_type _krb5_enctype_des_pcbc_none;
+extern struct encryption_type _krb5_enctype_null;
+
+extern struct encryption_type *_krb5_etypes[];
+extern int _krb5_num_etypes;
+
+/* Interface to the EVP crypto layer provided by hcrypto */
+struct evp_schedule {
+ EVP_CIPHER_CTX ectx;
+ EVP_CIPHER_CTX dctx;
+};
diff --git a/source4/heimdal/lib/krb5/salt-aes.c b/source4/heimdal/lib/krb5/salt-aes.c
new file mode 100644
index 0000000000..1c40b54f6b
--- /dev/null
+++ b/source4/heimdal/lib/krb5/salt-aes.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+int _krb5_AES_string_to_default_iterator = 4096;
+
+static krb5_error_code
+AES_string_to_key(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_data opaque,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ uint32_t iter;
+ struct encryption_type *et;
+ struct key_data kd;
+
+ if (opaque.length == 0)
+ iter = _krb5_AES_string_to_default_iterator;
+ else if (opaque.length == 4) {
+ unsigned long v;
+ _krb5_get_int(opaque.data, &v, 4);
+ iter = ((uint32_t)v);
+ } else
+ return KRB5_PROG_KEYTYPE_NOSUPP; /* XXX */
+
+ et = _krb5_find_enctype(enctype);
+ if (et == NULL)
+ return KRB5_PROG_KEYTYPE_NOSUPP;
+
+ kd.schedule = NULL;
+ ALLOC(kd.key, 1);
+ if(kd.key == NULL) {
+ krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+ kd.key->keytype = enctype;
+ ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size);
+ if (ret) {
+ krb5_set_error_message (context, ret, N_("malloc: out of memory", ""));
+ return ret;
+ }
+
+ ret = PKCS5_PBKDF2_HMAC_SHA1(password.data, password.length,
+ salt.saltvalue.data, salt.saltvalue.length,
+ iter,
+ et->keytype->size, kd.key->keyvalue.data);
+ if (ret != 1) {
+ _krb5_free_key_data(context, &kd, et);
+ krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP,
+ "Error calculating s2k");
+ return KRB5_PROG_KEYTYPE_NOSUPP;
+ }
+
+ ret = _krb5_derive_key(context, et, &kd, "kerberos", strlen("kerberos"));
+ if (ret == 0)
+ ret = krb5_copy_keyblock_contents(context, kd.key, key);
+ _krb5_free_key_data(context, &kd, et);
+
+ return ret;
+}
+
+struct salt_type _krb5_AES_salt[] = {
+ {
+ KRB5_PW_SALT,
+ "pw-salt",
+ AES_string_to_key
+ },
+ { 0 }
+};
diff --git a/source4/heimdal/lib/krb5/salt-arcfour.c b/source4/heimdal/lib/krb5/salt-arcfour.c
new file mode 100644
index 0000000000..b222b47e16
--- /dev/null
+++ b/source4/heimdal/lib/krb5/salt-arcfour.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+static krb5_error_code
+ARCFOUR_string_to_key(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_data opaque,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ uint16_t *s = NULL;
+ size_t len, i;
+ EVP_MD_CTX *m;
+
+ m = EVP_MD_CTX_create();
+ if (m == NULL) {
+ ret = ENOMEM;
+ krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+ goto out;
+ }
+
+ EVP_DigestInit_ex(m, EVP_md4(), NULL);
+
+ ret = wind_utf8ucs2_length(password.data, &len);
+ if (ret) {
+ krb5_set_error_message (context, ret,
+ N_("Password not an UCS2 string", ""));
+ goto out;
+ }
+
+ s = malloc (len * sizeof(s[0]));
+ if (len != 0 && s == NULL) {
+ krb5_set_error_message (context, ENOMEM,
+ N_("malloc: out of memory", ""));
+ ret = ENOMEM;
+ goto out;
+ }
+
+ ret = wind_utf8ucs2(password.data, s, &len);
+ if (ret) {
+ krb5_set_error_message (context, ret,
+ N_("Password not an UCS2 string", ""));
+ goto out;
+ }
+
+ /* LE encoding */
+ for (i = 0; i < len; i++) {
+ unsigned char p;
+ p = (s[i] & 0xff);
+ EVP_DigestUpdate (m, &p, 1);
+ p = (s[i] >> 8) & 0xff;
+ EVP_DigestUpdate (m, &p, 1);
+ }
+
+ key->keytype = enctype;
+ ret = krb5_data_alloc (&key->keyvalue, 16);
+ if (ret) {
+ krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
+ goto out;
+ }
+ EVP_DigestFinal_ex (m, key->keyvalue.data, NULL);
+
+ out:
+ EVP_MD_CTX_destroy(m);
+ if (s)
+ memset (s, 0, len);
+ free (s);
+ return ret;
+}
+
+struct salt_type _krb5_arcfour_salt[] = {
+ {
+ KRB5_PW_SALT,
+ "pw-salt",
+ ARCFOUR_string_to_key
+ },
+ { 0 }
+};
diff --git a/source4/heimdal/lib/krb5/salt-des.c b/source4/heimdal/lib/krb5/salt-des.c
new file mode 100644
index 0000000000..6939b6b50b
--- /dev/null
+++ b/source4/heimdal/lib/krb5/salt-des.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+#ifdef HEIM_WEAK_CRYPTO
+
+#ifdef ENABLE_AFS_STRING_TO_KEY
+
+/* This defines the Andrew string_to_key function. It accepts a password
+ * string as input and converts it via a one-way encryption algorithm to a DES
+ * encryption key. It is compatible with the original Andrew authentication
+ * service password database.
+ */
+
+/*
+ * Short passwords, i.e 8 characters or less.
+ */
+static void
+krb5_DES_AFS3_CMU_string_to_key (krb5_data pw,
+ krb5_data cell,
+ DES_cblock *key)
+{
+ char password[8+1]; /* crypt is limited to 8 chars anyway */
+ int i;
+
+ for(i = 0; i < 8; i++) {
+ char c = ((i < pw.length) ? ((char*)pw.data)[i] : 0) ^
+ ((i < cell.length) ?
+ tolower(((unsigned char*)cell.data)[i]) : 0);
+ password[i] = c ? c : 'X';
+ }
+ password[8] = '\0';
+
+ memcpy(key, crypt(password, "p1") + 2, sizeof(DES_cblock));
+
+ /* parity is inserted into the LSB so left shift each byte up one
+ bit. This allows ascii characters with a zero MSB to retain as
+ much significance as possible. */
+ for (i = 0; i < sizeof(DES_cblock); i++)
+ ((unsigned char*)key)[i] <<= 1;
+ DES_set_odd_parity (key);
+}
+
+/*
+ * Long passwords, i.e 9 characters or more.
+ */
+static void
+krb5_DES_AFS3_Transarc_string_to_key (krb5_data pw,
+ krb5_data cell,
+ DES_cblock *key)
+{
+ DES_key_schedule schedule;
+ DES_cblock temp_key;
+ DES_cblock ivec;
+ char password[512];
+ size_t passlen;
+
+ memcpy(password, pw.data, min(pw.length, sizeof(password)));
+ if(pw.length < sizeof(password)) {
+ int len = min(cell.length, sizeof(password) - pw.length);
+ int i;
+
+ memcpy(password + pw.length, cell.data, len);
+ for (i = pw.length; i < pw.length + len; ++i)
+ password[i] = tolower((unsigned char)password[i]);
+ }
+ passlen = min(sizeof(password), pw.length + cell.length);
+ memcpy(&ivec, "kerberos", 8);
+ memcpy(&temp_key, "kerberos", 8);
+ DES_set_odd_parity (&temp_key);
+ DES_set_key_unchecked (&temp_key, &schedule);
+ DES_cbc_cksum ((void*)password, &ivec, passlen, &schedule, &ivec);
+
+ memcpy(&temp_key, &ivec, 8);
+ DES_set_odd_parity (&temp_key);
+ DES_set_key_unchecked (&temp_key, &schedule);
+ DES_cbc_cksum ((void*)password, key, passlen, &schedule, &ivec);
+ memset(&schedule, 0, sizeof(schedule));
+ memset(&temp_key, 0, sizeof(temp_key));
+ memset(&ivec, 0, sizeof(ivec));
+ memset(password, 0, sizeof(password));
+
+ DES_set_odd_parity (key);
+}
+
+static krb5_error_code
+DES_AFS3_string_to_key(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_data opaque,
+ krb5_keyblock *key)
+{
+ DES_cblock tmp;
+ if(password.length > 8)
+ krb5_DES_AFS3_Transarc_string_to_key(password, salt.saltvalue, &tmp);
+ else
+ krb5_DES_AFS3_CMU_string_to_key(password, salt.saltvalue, &tmp);
+ key->keytype = enctype;
+ krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp));
+ memset(&key, 0, sizeof(key));
+ return 0;
+}
+#endif /* ENABLE_AFS_STRING_TO_KEY */
+
+static void
+DES_string_to_key_int(unsigned char *data, size_t length, DES_cblock *key)
+{
+ DES_key_schedule schedule;
+ int i;
+ int reverse = 0;
+ unsigned char *p;
+
+ unsigned char swap[] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
+ 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf };
+ memset(key, 0, 8);
+
+ p = (unsigned char*)key;
+ for (i = 0; i < length; i++) {
+ unsigned char tmp = data[i];
+ if (!reverse)
+ *p++ ^= (tmp << 1);
+ else
+ *--p ^= (swap[tmp & 0xf] << 4) | swap[(tmp & 0xf0) >> 4];
+ if((i % 8) == 7)
+ reverse = !reverse;
+ }
+ DES_set_odd_parity(key);
+ if(DES_is_weak_key(key))
+ (*key)[7] ^= 0xF0;
+ DES_set_key_unchecked(key, &schedule);
+ DES_cbc_cksum((void*)data, key, length, &schedule, key);
+ memset(&schedule, 0, sizeof(schedule));
+ DES_set_odd_parity(key);
+ if(DES_is_weak_key(key))
+ (*key)[7] ^= 0xF0;
+}
+
+static krb5_error_code
+krb5_DES_string_to_key(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_data opaque,
+ krb5_keyblock *key)
+{
+ unsigned char *s;
+ size_t len;
+ DES_cblock tmp;
+
+#ifdef ENABLE_AFS_STRING_TO_KEY
+ if (opaque.length == 1) {
+ unsigned long v;
+ _krb5_get_int(opaque.data, &v, 1);
+ if (v == 1)
+ return DES_AFS3_string_to_key(context, enctype, password,
+ salt, opaque, key);
+ }
+#endif
+
+ len = password.length + salt.saltvalue.length;
+ s = malloc(len);
+ if(len > 0 && s == NULL) {
+ krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+ memcpy(s, password.data, password.length);
+ memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length);
+ DES_string_to_key_int(s, len, &tmp);
+ key->keytype = enctype;
+ krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp));
+ memset(&tmp, 0, sizeof(tmp));
+ memset(s, 0, len);
+ free(s);
+ return 0;
+}
+
+struct salt_type _krb5_des_salt[] = {
+ {
+ KRB5_PW_SALT,
+ "pw-salt",
+ krb5_DES_string_to_key
+ },
+#ifdef ENABLE_AFS_STRING_TO_KEY
+ {
+ KRB5_AFS3_SALT,
+ "afs3-salt",
+ DES_AFS3_string_to_key
+ },
+#endif
+ { 0 }
+};
+#endif
diff --git a/source4/heimdal/lib/krb5/salt-des3.c b/source4/heimdal/lib/krb5/salt-des3.c
new file mode 100644
index 0000000000..79140a274f
--- /dev/null
+++ b/source4/heimdal/lib/krb5/salt-des3.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+#ifdef DES3_OLD_ENCTYPE
+static krb5_error_code
+DES3_string_to_key(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_data opaque,
+ krb5_keyblock *key)
+{
+ char *str;
+ size_t len;
+ unsigned char tmp[24];
+ DES_cblock keys[3];
+ krb5_error_code ret;
+
+ len = password.length + salt.saltvalue.length;
+ str = malloc(len);
+ if(len != 0 && str == NULL) {
+ krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+ memcpy(str, password.data, password.length);
+ memcpy(str + password.length, salt.saltvalue.data, salt.saltvalue.length);
+ {
+ DES_cblock ivec;
+ DES_key_schedule s[3];
+ int i;
+
+ ret = _krb5_n_fold(str, len, tmp, 24);
+ if (ret) {
+ memset(str, 0, len);
+ free(str);
+ krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
+ return ret;
+ }
+
+ for(i = 0; i < 3; i++){
+ memcpy(keys + i, tmp + i * 8, sizeof(keys[i]));
+ DES_set_odd_parity(keys + i);
+ if(DES_is_weak_key(keys + i))
+ _krb5_xor(keys + i, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
+ DES_set_key_unchecked(keys + i, &s[i]);
+ }
+ memset(&ivec, 0, sizeof(ivec));
+ DES_ede3_cbc_encrypt(tmp,
+ tmp, sizeof(tmp),
+ &s[0], &s[1], &s[2], &ivec, DES_ENCRYPT);
+ memset(s, 0, sizeof(s));
+ memset(&ivec, 0, sizeof(ivec));
+ for(i = 0; i < 3; i++){
+ memcpy(keys + i, tmp + i * 8, sizeof(keys[i]));
+ DES_set_odd_parity(keys + i);
+ if(DES_is_weak_key(keys + i))
+ _krb5_xor(keys + i, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
+ }
+ memset(tmp, 0, sizeof(tmp));
+ }
+ key->keytype = enctype;
+ krb5_data_copy(&key->keyvalue, keys, sizeof(keys));
+ memset(keys, 0, sizeof(keys));
+ memset(str, 0, len);
+ free(str);
+ return 0;
+}
+#endif
+
+static krb5_error_code
+DES3_string_to_key_derived(krb5_context context,
+ krb5_enctype enctype,
+ krb5_data password,
+ krb5_salt salt,
+ krb5_data opaque,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ size_t len = password.length + salt.saltvalue.length;
+ char *s;
+
+ s = malloc(len);
+ if(len != 0 && s == NULL) {
+ krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
+ return ENOMEM;
+ }
+ memcpy(s, password.data, password.length);
+ memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length);
+ ret = krb5_string_to_key_derived(context,
+ s,
+ len,
+ enctype,
+ key);
+ memset(s, 0, len);
+ free(s);
+ return ret;
+}
+
+
+#ifdef DES3_OLD_ENCTYPE
+struct salt_type _krb5_des3_salt[] = {
+ {
+ KRB5_PW_SALT,
+ "pw-salt",
+ DES3_string_to_key
+ },
+ { 0 }
+};
+#endif
+
+struct salt_type _krb5_des3_salt_derived[] = {
+ {
+ KRB5_PW_SALT,
+ "pw-salt",
+ DES3_string_to_key_derived
+ },
+ { 0 }
+};
diff --git a/source4/heimdal/lib/krb5/store-int.c b/source4/heimdal/lib/krb5/store-int.c
new file mode 100644
index 0000000000..0a18d0dddf
--- /dev/null
+++ b/source4/heimdal/lib/krb5/store-int.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997-2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb5_locl.h"
+
+KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
+_krb5_put_int(void *buffer, unsigned long value, size_t size)
+{
+ unsigned char *p = buffer;
+ int i;
+ for (i = size - 1; i >= 0; i--) {
+ p[i] = value & 0xff;
+ value >>= 8;
+ }
+ return size;
+}
+
+KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
+_krb5_get_int(void *buffer, unsigned long *value, size_t size)
+{
+ unsigned char *p = buffer;
+ unsigned long v = 0;
+ int i;
+ for (i = 0; i < size; i++)
+ v = (v << 8) + p[i];
+ *value = v;
+ return size;
+}