summaryrefslogtreecommitdiff
path: root/src/openvpn/crypto_polarssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn/crypto_polarssl.c')
-rw-r--r--src/openvpn/crypto_polarssl.c712
1 files changed, 0 insertions, 712 deletions
diff --git a/src/openvpn/crypto_polarssl.c b/src/openvpn/crypto_polarssl.c
deleted file mode 100644
index 92fdb78..0000000
--- a/src/openvpn/crypto_polarssl.c
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
- * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/**
- * @file Data Channel Cryptography PolarSSL-specific backend interface
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#elif defined(_MSC_VER)
-#include "config-msvc.h"
-#endif
-
-#include "syshead.h"
-
-#if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_POLARSSL)
-
-#include "errlevel.h"
-#include "basic.h"
-#include "buffer.h"
-#include "integer.h"
-#include "crypto_backend.h"
-#include "otime.h"
-#include "misc.h"
-
-#include <polarssl/des.h>
-#include <polarssl/error.h>
-#include <polarssl/md5.h>
-#include <polarssl/cipher.h>
-#include <polarssl/havege.h>
-
-#include <polarssl/entropy.h>
-
-/*
- *
- * Hardware engine support. Allows loading/unloading of engines.
- *
- */
-
-void
-crypto_init_lib_engine (const char *engine_name)
-{
- msg (M_WARN, "Note: PolarSSL hardware crypto engine functionality is not "
- "available");
-}
-
-/*
- *
- * Functions related to the core crypto library
- *
- */
-
-void
-crypto_init_lib (void)
-{
-}
-
-void
-crypto_uninit_lib (void)
-{
-}
-
-void
-crypto_clear_error (void)
-{
-}
-
-bool polar_log_err(unsigned int flags, int errval, const char *prefix)
-{
- if (0 != errval)
- {
- char errstr[256];
- polarssl_strerror(errval, errstr, sizeof(errstr));
-
- if (NULL == prefix) prefix = "PolarSSL error";
- msg (flags, "%s: %s", prefix, errstr);
- }
-
- return 0 == errval;
-}
-
-bool polar_log_func_line(unsigned int flags, int errval, const char *func,
- int line)
-{
- char prefix[256];
-
- if (!openvpn_snprintf(prefix, sizeof(prefix), "%s:%d", func, line))
- return polar_log_err(flags, errval, func);
-
- return polar_log_err(flags, errval, prefix);
-}
-
-
-#ifdef DMALLOC
-void
-crypto_init_dmalloc (void)
-{
- msg (M_ERR, "Error: dmalloc support is not available for PolarSSL.");
-}
-#endif /* DMALLOC */
-
-typedef struct { const char * openvpn_name; const char * polarssl_name; } cipher_name_pair;
-cipher_name_pair cipher_name_translation_table[] = {
- { "BF-CBC", "BLOWFISH-CBC" },
- { "BF-CFB", "BLOWFISH-CFB64" },
- { "CAMELLIA-128-CFB", "CAMELLIA-128-CFB128" },
- { "CAMELLIA-192-CFB", "CAMELLIA-192-CFB128" },
- { "CAMELLIA-256-CFB", "CAMELLIA-256-CFB128" }
-};
-
-const cipher_name_pair *
-get_cipher_name_pair(const char *cipher_name) {
- cipher_name_pair *pair;
- size_t i = 0;
-
- /* Search for a cipher name translation */
- for (; i < sizeof (cipher_name_translation_table) / sizeof (*cipher_name_translation_table); i++)
- {
- pair = &cipher_name_translation_table[i];
- if (0 == strcmp (cipher_name, pair->openvpn_name) ||
- 0 == strcmp (cipher_name, pair->polarssl_name))
- return pair;
- }
-
- /* Nothing found, return null */
- return NULL;
-}
-
-const char *
-translate_cipher_name_from_openvpn (const char *cipher_name) {
- const cipher_name_pair *pair = get_cipher_name_pair(cipher_name);
-
- if (NULL == pair)
- return cipher_name;
-
- return pair->polarssl_name;
-}
-
-const char *
-translate_cipher_name_to_openvpn (const char *cipher_name) {
- const cipher_name_pair *pair = get_cipher_name_pair(cipher_name);
-
- if (NULL == pair)
- return cipher_name;
-
- return pair->openvpn_name;
-}
-
-void
-show_available_ciphers ()
-{
- const int *ciphers = cipher_list();
-
-#ifndef ENABLE_SMALL
- printf ("The following ciphers and cipher modes are available\n"
- "for use with " PACKAGE_NAME ". Each cipher shown below may be\n"
- "used as a parameter to the --cipher option. The default\n"
- "key size is shown as well as whether or not it can be\n"
- "changed with the --keysize directive. Using a CBC mode\n"
- "is recommended.\n\n");
-#endif
-
- while (*ciphers != 0)
- {
- const cipher_info_t *info = cipher_info_from_type(*ciphers);
-
- if (info && info->mode == POLARSSL_MODE_CBC)
- printf ("%s %d bit default key\n",
- cipher_kt_name(info), cipher_kt_key_size(info) * 8);
-
- ciphers++;
- }
- printf ("\n");
-}
-
-void
-show_available_digests ()
-{
- const int *digests = md_list();
-
-#ifndef ENABLE_SMALL
- printf ("The following message digests are available for use with\n"
- PACKAGE_NAME ". A message digest is used in conjunction with\n"
- "the HMAC function, to authenticate received packets.\n"
- "You can specify a message digest as parameter to\n"
- "the --auth option.\n\n");
-#endif
-
- while (*digests != 0)
- {
- const md_info_t *info = md_info_from_type(*digests);
-
- if (info)
- printf ("%s %d bit default key\n",
- info->name, info->size * 8);
- digests++;
- }
- printf ("\n");
-}
-
-void
-show_available_engines ()
-{
- printf ("Sorry, PolarSSL hardware crypto engine functionality is not "
- "available\n");
-}
-
-/*
- *
- * Random number functions, used in cases where we want
- * reasonably strong cryptographic random number generation
- * without depleting our entropy pool. Used for random
- * IV values and a number of other miscellaneous tasks.
- *
- */
-
-/*
- * Initialise the given ctr_drbg context, using a personalisation string and an
- * entropy gathering function.
- */
-ctr_drbg_context * rand_ctx_get()
-{
- static entropy_context ec = {0};
- static ctr_drbg_context cd_ctx = {0};
- static bool rand_initialised = false;
-
- if (!rand_initialised)
- {
- struct gc_arena gc = gc_new();
- struct buffer pers_string = alloc_buf_gc(100, &gc);
-
- /*
- * Personalisation string, should be as unique as possible (see NIST
- * 800-90 section 8.7.1). We have very little information at this stage.
- * Include Program Name, memory address of the context and PID.
- */
- buf_printf(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), &cd_ctx, time_string(0, 0, 0, &gc));
-
- /* Initialise PolarSSL RNG, and built-in entropy sources */
- entropy_init(&ec);
-
- if (!polar_ok(ctr_drbg_init(&cd_ctx, entropy_func, &ec,
- BPTR(&pers_string), BLEN(&pers_string))))
- msg (M_FATAL, "Failed to initialize random generator");
-
- gc_free(&gc);
- rand_initialised = true;
- }
-
- return &cd_ctx;
-}
-
-#ifdef ENABLE_PREDICTION_RESISTANCE
-void rand_ctx_enable_prediction_resistance()
-{
- ctr_drbg_context *cd_ctx = rand_ctx_get();
-
- ctr_drbg_set_prediction_resistance(cd_ctx, 1);
-}
-#endif /* ENABLE_PREDICTION_RESISTANCE */
-
-int
-rand_bytes (uint8_t *output, int len)
-{
- ctr_drbg_context *rng_ctx = rand_ctx_get();
-
- while (len > 0)
- {
- const size_t blen = min_int (len, CTR_DRBG_MAX_REQUEST);
- if (0 != ctr_drbg_random(rng_ctx, output, blen))
- return 0;
-
- output += blen;
- len -= blen;
- }
-
- return 1;
-}
-
-/*
- *
- * Key functions, allow manipulation of keys.
- *
- */
-
-
-int
-key_des_num_cblocks (const cipher_info_t *kt)
-{
- int ret = 0;
- if (kt->type == POLARSSL_CIPHER_DES_CBC)
- ret = 1;
- if (kt->type == POLARSSL_CIPHER_DES_EDE_CBC)
- ret = 2;
- if (kt->type == POLARSSL_CIPHER_DES_EDE3_CBC)
- ret = 3;
-
- 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)
- {
- unsigned char *key = buf_read_alloc(&b, DES_KEY_SIZE);
- if (!key)
- {
- msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material");
- goto err;
- }
- if (0 != des_key_check_weak(key))
- {
- msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected");
- goto err;
- }
- if (0 != des_key_check_key_parity(key))
- {
- msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected");
- goto err;
- }
- }
- return true;
-
- err:
- 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)
- {
- unsigned char *key = buf_read_alloc(&b, DES_KEY_SIZE);
- if (!key)
- {
- msg (D_CRYPT_ERRORS, "CRYPTO INFO: fixup_key_DES: insufficient key material");
- return;
- }
- des_key_set_parity(key);
- }
-}
-
-/*
- *
- * Generic cipher key type functions
- *
- */
-
-
-const cipher_info_t *
-cipher_kt_get (const char *ciphername)
-{
- const cipher_info_t *cipher = NULL;
-
- ASSERT (ciphername);
-
- cipher = cipher_info_from_string(ciphername);
-
- if (NULL == cipher)
- msg (M_FATAL, "Cipher algorithm '%s' not found", ciphername);
-
- if (cipher->key_length/8 > MAX_CIPHER_KEY_LENGTH)
- msg (M_FATAL, "Cipher algorithm '%s' uses a default key size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum key size (%d bytes)",
- ciphername,
- cipher->key_length/8,
- MAX_CIPHER_KEY_LENGTH);
-
- return cipher;
-}
-
-const char *
-cipher_kt_name (const cipher_info_t *cipher_kt)
-{
- if (NULL == cipher_kt)
- return "[null-cipher]";
-
- return translate_cipher_name_to_openvpn(cipher_kt->name);
-}
-
-int
-cipher_kt_key_size (const cipher_info_t *cipher_kt)
-{
- if (NULL == cipher_kt)
- return 0;
- if (POLARSSL_CIPHER_ID_BLOWFISH == cipher_kt->base->cipher)
- return 128/8; /* Override PolarSSL 32 bit default key size with sane 128 bit default */
-
- return cipher_kt->key_length/8;
-}
-
-int
-cipher_kt_iv_size (const cipher_info_t *cipher_kt)
-{
- if (NULL == cipher_kt)
- return 0;
- return cipher_kt->iv_size;
-}
-
-int
-cipher_kt_block_size (const cipher_info_t *cipher_kt)
-{
- if (NULL == cipher_kt)
- return 0;
- return cipher_kt->block_size;
-}
-
-int
-cipher_kt_mode (const cipher_info_t *cipher_kt)
-{
- ASSERT(NULL != cipher_kt);
- return cipher_kt->mode;
-}
-
-bool
-cipher_kt_mode_cbc(const cipher_kt_t *cipher)
-{
- return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_CBC;
-}
-
-bool
-cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
-{
- return cipher && (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB ||
- cipher_kt_mode(cipher) == OPENVPN_MODE_CFB);
-}
-
-
-/*
- *
- * Generic cipher context functions
- *
- */
-
-
-void
-cipher_ctx_init (cipher_context_t *ctx, uint8_t *key, int key_len,
- const cipher_info_t *kt, int enc)
-{
- ASSERT(NULL != kt && NULL != ctx);
-
- CLEAR (*ctx);
-
- if (!polar_ok(cipher_init_ctx(ctx, kt)))
- msg (M_FATAL, "PolarSSL cipher context init #1");
-
- if (!polar_ok(cipher_setkey(ctx, key, key_len*8, enc)))
- msg (M_FATAL, "PolarSSL cipher set key");
-
- /* make sure we used a big enough key */
- ASSERT (ctx->key_length <= key_len*8);
-}
-
-void cipher_ctx_cleanup (cipher_context_t *ctx)
-{
- cipher_free(ctx);
-}
-
-int cipher_ctx_iv_length (const cipher_context_t *ctx)
-{
- return cipher_get_iv_size(ctx);
-}
-
-int cipher_ctx_block_size(const cipher_context_t *ctx)
-{
- return cipher_get_block_size(ctx);
-}
-
-int cipher_ctx_mode (const cipher_context_t *ctx)
-{
- ASSERT(NULL != ctx);
-
- return cipher_kt_mode(ctx->cipher_info);
-}
-
-const cipher_kt_t *
-cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
-{
- ASSERT(NULL != ctx);
-
- return ctx->cipher_info;
-}
-
-int cipher_ctx_reset (cipher_context_t *ctx, uint8_t *iv_buf)
-{
- if (!polar_ok(cipher_reset(ctx)))
- return 0;
-
- if (!polar_ok(cipher_set_iv(ctx, iv_buf, ctx->cipher_info->iv_size)))
- return 0;
-
- return 1;
-}
-
-int cipher_ctx_update (cipher_context_t *ctx, uint8_t *dst, int *dst_len,
- uint8_t *src, int src_len)
-{
- size_t s_dst_len = *dst_len;
-
- if (!polar_ok(cipher_update(ctx, src, (size_t)src_len, dst, &s_dst_len)))
- return 0;
-
- *dst_len = s_dst_len;
-
- return 1;
-}
-
-int cipher_ctx_final (cipher_context_t *ctx, uint8_t *dst, int *dst_len)
-{
- size_t s_dst_len = *dst_len;
-
- if (!polar_ok(cipher_finish(ctx, dst, &s_dst_len)))
- return 0;
-
- *dst_len = s_dst_len;
-
- return 1;
-}
-
-void
-cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH],
- unsigned char *src,
- unsigned char *dst)
-{
- des_context ctx;
-
- ASSERT (polar_ok(des_setkey_enc(&ctx, key)));
- ASSERT (polar_ok(des_crypt_ecb(&ctx, src, dst)));
-}
-
-
-
-/*
- *
- * Generic message digest information functions
- *
- */
-
-
-const md_info_t *
-md_kt_get (const char *digest)
-{
- const md_info_t *md = NULL;
- ASSERT (digest);
-
- md = md_info_from_string(digest);
- if (!md)
- msg (M_FATAL, "Message hash algorithm '%s' not found", digest);
- if (md->size > MAX_HMAC_KEY_LENGTH)
- msg (M_FATAL, "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum hash size (%d bytes)",
- digest,
- md->size,
- MAX_HMAC_KEY_LENGTH);
- return md;
-}
-
-const char *
-md_kt_name (const md_info_t *kt)
-{
- if (NULL == kt)
- return "[null-digest]";
- return md_get_name (kt);
-}
-
-int
-md_kt_size (const md_info_t *kt)
-{
- if (NULL == kt)
- return 0;
- return md_get_size(kt);
-}
-
-/*
- *
- * Generic message digest functions
- *
- */
-
-int
-md_full (const md_kt_t *kt, const uint8_t *src, int src_len, uint8_t *dst)
-{
- return 0 == md(kt, src, src_len, dst);
-}
-
-
-void
-md_ctx_init (md_context_t *ctx, const md_info_t *kt)
-{
- ASSERT(NULL != ctx && NULL != kt);
-
- CLEAR(*ctx);
-
- ASSERT(0 == md_init_ctx(ctx, kt));
- ASSERT(0 == md_starts(ctx));
-}
-
-void
-md_ctx_cleanup(md_context_t *ctx)
-{
-}
-
-int
-md_ctx_size (const md_context_t *ctx)
-{
- if (NULL == ctx)
- return 0;
- return md_get_size(ctx->md_info);
-}
-
-void
-md_ctx_update (md_context_t *ctx, const uint8_t *src, int src_len)
-{
- ASSERT(0 == md_update(ctx, src, src_len));
-}
-
-void
-md_ctx_final (md_context_t *ctx, uint8_t *dst)
-{
- ASSERT(0 == md_finish(ctx, dst));
- md_free(ctx);
-}
-
-
-/*
- *
- * Generic HMAC functions
- *
- */
-
-
-/*
- * TODO: re-enable dmsg for crypto debug
- */
-void
-hmac_ctx_init (md_context_t *ctx, const uint8_t *key, int key_len, const md_info_t *kt)
-{
- ASSERT(NULL != kt && NULL != ctx);
-
- CLEAR(*ctx);
-
- ASSERT(0 == md_init_ctx(ctx, kt));
- ASSERT(0 == md_hmac_starts(ctx, key, key_len));
-
- /* make sure we used a big enough key */
- ASSERT (md_get_size(kt) <= key_len);
-}
-
-void
-hmac_ctx_cleanup(md_context_t *ctx)
-{
- md_free(ctx);
-}
-
-int
-hmac_ctx_size (const md_context_t *ctx)
-{
- if (NULL == ctx)
- return 0;
- return md_get_size(ctx->md_info);
-}
-
-void
-hmac_ctx_reset (md_context_t *ctx)
-{
- ASSERT(0 == md_hmac_reset(ctx));
-}
-
-void
-hmac_ctx_update (md_context_t *ctx, const uint8_t *src, int src_len)
-{
- ASSERT(0 == md_hmac_update(ctx, src, src_len));
-}
-
-void
-hmac_ctx_final (md_context_t *ctx, uint8_t *dst)
-{
- ASSERT(0 == md_hmac_finish(ctx, dst));
-}
-
-#endif /* ENABLE_CRYPTO && ENABLE_CRYPTO_POLARSSL */