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)
* 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;
}
#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))
*/
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
#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
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);
+ }
+}
#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
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