---
 crypto.c         |   85 ++--------------------------------------------------
 crypto_backend.h |   37 +++++++++++++++++++++++
 crypto_openssl.c |   87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 crypto_openssl.h |   15 +++++++++
 ntlm.c           |    2 +-
 5 files changed, 144 insertions(+), 82 deletions(-)

diff --git a/crypto.c b/crypto.c
index ff34d5f..ea04cdd 100644
--- a/crypto.c
+++ b/crypto.c
@@ -601,83 +601,6 @@ free_key_ctx_bi (struct key_ctx_bi *ctx)
   free_key_ctx(&ctx->decrypt);
 }

-/*
- * Return number of DES cblocks for the current
- * key type or 0 if not a DES cipher.
- */
-static int
-n_DES_cblocks (const struct key_type *kt)
-{
-  int ret = 0;
-  const char *name = OBJ_nid2sn (EVP_CIPHER_nid (kt->cipher));
-  if (name)
-    {
-      if (!strncmp (name, "DES-", 4))
-       {
-         ret = EVP_CIPHER_key_length (kt->cipher) / sizeof (DES_cblock);
-       }
-      else if (!strncmp (name, "DESX-", 5))
-       {
-         ret = 1;
-       }
-    }
-  dmsg (D_CRYPTO_DEBUG, "CRYPTO INFO: n_DES_cblocks=%d", ret);
-  return ret;
-}
-
-static bool
-check_key_DES (struct key *key, const struct key_type *kt, int ndc)
-{
-  int i;
-  struct buffer b;
-
-  buf_set_read (&b, key->cipher, kt->cipher_length);
-
-  for (i = 0; i < ndc; ++i)
-    {
-      DES_cblock *dc = (DES_cblock*) buf_read_alloc (&b, sizeof (DES_cblock));
-      if (!dc)
-       {
-         msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key 
material");
-         goto err;
-       }
-      if (DES_is_weak_key(dc))
-       {
-         msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected");
-         goto err;
-       }
-      if (!DES_check_key_parity (dc))
-       {
-         msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity 
detected");
-         goto err;
-       }
-    }
-  return true;
-
- err:
-  ERR_clear_error ();
-  return false;
-}
-
-static void
-fixup_key_DES (struct key *key, const struct key_type *kt, int ndc)
-{
-  int i;
-  struct buffer b;
-
-  buf_set_read (&b, key->cipher, kt->cipher_length);
-  for (i = 0; i < ndc; ++i)
-    {
-      DES_cblock *dc = (DES_cblock*) buf_read_alloc(&b, sizeof(DES_cblock));
-      if (!dc)
-       {
-         msg (D_CRYPT_ERRORS, "CRYPTO INFO: fixup_key_DES: insufficient key 
material");
-         ERR_clear_error ();
-         return;
-       }
-      DES_set_odd_parity (dc);
-    }
-}

 static bool
 key_is_zero (struct key *key, const struct key_type *kt)
@@ -708,9 +631,9 @@ check_key (struct key *key, const struct key_type *kt)
        * Check for weak or semi-weak DES keys.
        */
       {
-       const int ndc = n_DES_cblocks (kt);
+       const int ndc = key_des_num_cblocks (kt->cipher);
        if (ndc)
-         return check_key_DES (key, kt, ndc);
+         return key_des_check (key->cipher, kt->cipher_length, ndc);
        else
          return true;
       }
@@ -735,10 +658,10 @@ fixup_key (struct key *key, const struct key_type *kt)
 #ifdef ENABLE_DEBUG
       const struct key orig = *key;
 #endif
-      const int ndc = n_DES_cblocks (kt);
+      const int ndc = key_des_num_cblocks (kt->cipher);

       if (ndc)
-       fixup_key_DES (key, kt, ndc);
+       key_des_fixup (key->cipher, kt->cipher_length, ndc);

 #ifdef ENABLE_DEBUG
       if (check_debug_level (D_CRYPTO_DEBUG))
diff --git a/crypto_backend.h b/crypto_backend.h
index 1b85dec..f0e7b18 100644
--- a/crypto_backend.h
+++ b/crypto_backend.h
@@ -91,6 +91,43 @@ int rand_bytes (uint8_t *output, int len);

 /*
  *
+ * Key functions, allow manipulation of keys.
+ *
+ */
+
+
+/**
+ * Return number of DES cblocks (1 cblock = length of a single-DES key) for the
+ * current key type or 0 if not a DES cipher.
+ *
+ * @param kt           Type of key
+ *
+ * @return             Number of DES cblocks that the key consists of, or 0.
+ */
+int key_des_num_cblocks (const cipher_kt_t *kt);
+
+/*
+ * Check the given DES key. Checks the given key's length, weakness and parity.
+ *
+ * @param key          Key to check
+ * @param key_len      Length of the key, in bytes
+ * @param ndc          Number of DES cblocks that the key is made up of.
+ *
+ * @return             \c true if the key is valid, \c false otherwise.
+ */
+bool key_des_check (uint8_t *key, int key_len, int ndc);
+
+/*
+ * Fix the given DES key, setting its parity to odd.
+ *
+ * @param key          Key to check
+ * @param key_len      Length of the key, in bytes
+ * @param ndc          Number of DES cblocks that the key is made up of.
+ */
+void key_des_fixup (uint8_t *key, int key_len, int ndc);
+
+/*
+ *
  * Generic cipher key type functions
  *
  */
diff --git a/crypto_openssl.c b/crypto_openssl.c
index 199a209..9fbbf11 100644
--- a/crypto_openssl.c
+++ b/crypto_openssl.c
@@ -58,6 +58,11 @@

 #if SSLEAY_VERSION_NUMBER < 0x00907000L

+#define DES_cblock                        des_cblock
+#define DES_is_weak_key                   des_is_weak_key
+#define DES_check_key_parity              des_check_key_parity
+#define DES_set_odd_parity                des_set_odd_parity
+
 #endif

 #if SSLEAY_VERSION_NUMBER < 0x00906000
@@ -354,3 +359,85 @@ int rand_bytes(uint8_t *output, int len)
   return RAND_bytes (output, len);
 }

+/*
+ *
+ * Key functions, allow manipulation of keys.
+ *
+ */
+
+
+int
+key_des_num_cblocks (const EVP_CIPHER *kt)
+{
+  int ret = 0;
+  const char *name = OBJ_nid2sn (EVP_CIPHER_nid (kt));
+  if (name)
+    {
+      if (!strncmp (name, "DES-", 4))
+       {
+         ret = EVP_CIPHER_key_length (kt) / sizeof (DES_cblock);
+       }
+      else if (!strncmp (name, "DESX-", 5))
+       {
+         ret = 1;
+       }
+    }
+  dmsg (D_CRYPTO_DEBUG, "CRYPTO INFO: n_DES_cblocks=%d", ret);
+  return ret;
+}
+
+bool
+key_des_check (uint8_t *key, int key_len, int ndc)
+{
+  int i;
+  struct buffer b;
+
+  buf_set_read (&b, key, key_len);
+
+  for (i = 0; i < ndc; ++i)
+    {
+      DES_cblock *dc = (DES_cblock*) buf_read_alloc (&b, sizeof (DES_cblock));
+      if (!dc)
+       {
+         msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key 
material");
+         goto err;
+       }
+      if (DES_is_weak_key(dc))
+       {
+         msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected");
+         goto err;
+       }
+      if (!DES_check_key_parity (dc))
+       {
+         msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity 
detected");
+         goto err;
+       }
+    }
+  return true;
+
+ err:
+  ERR_clear_error ();
+  return false;
+}
+
+void
+key_des_fixup (uint8_t *key, int key_len, int ndc)
+{
+  int i;
+  struct buffer b;
+
+  buf_set_read (&b, key, key_len);
+  for (i = 0; i < ndc; ++i)
+    {
+      DES_cblock *dc = (DES_cblock*) buf_read_alloc(&b, sizeof(DES_cblock));
+      if (!dc)
+       {
+         msg (D_CRYPT_ERRORS, "CRYPTO INFO: fixup_key_DES: insufficient key 
material");
+         ERR_clear_error ();
+         return;
+       }
+      DES_set_odd_parity (dc);
+    }
+}
+
+
diff --git a/crypto_openssl.h b/crypto_openssl.h
index ea3601e..9bc106a 100644
--- a/crypto_openssl.h
+++ b/crypto_openssl.h
@@ -34,6 +34,21 @@
 #include <openssl/hmac.h>
 #include <openssl/md5.h>

+/** Generic cipher key type %context. */
+typedef EVP_CIPHER cipher_kt_t;
+
+/** Generic message digest key type %context. */
+typedef EVP_MD md_kt_t;
+
+/** Generic cipher %context. */
+typedef EVP_CIPHER_CTX cipher_ctx_t;
+
+/** Generic message digest %context. */
+typedef EVP_MD_CTX md_ctx_t;
+
+/** Generic HMAC %context. */
+typedef HMAC_CTX hmac_ctx_t;
+
 /** Maximum length of an IV */
 #define OPENVPN_MAX_IV_LENGTH  EVP_MAX_IV_LENGTH

diff --git a/ntlm.c b/ntlm.c
index 4dfeed3..3440c12 100644
--- a/ntlm.c
+++ b/ntlm.c
@@ -63,7 +63,7 @@ create_des_keys(const unsigned char *hash, unsigned char *key)
   key[5] = ((hash[4]&31)<<3)|(hash[5]>>5);
   key[6] = ((hash[5]&63)<<2)|(hash[6]>>6);
   key[7] = ((hash[6]&127)<<1);
-  des_set_odd_parity((des_cblock *)key);
+  key_des_fixup(key, 8, 1);
 }

 static void
-- 
1.7.4.1


Reply via email to