/*
* Support for VIA PadLock Advanced Cryptography Engine (ACE)
* Written by Michal Ludvig <michal@logix.cz>
* http://www.logix.cz/michal
*
* Big thanks to Andy Polyakov for a help with optimization,
* assembler fixes, port to MS Windows and a lot of other
* valuable work on this engine!
*/
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED 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 OpenSSL PROJECT OR
* ITS 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.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
#include <openssl/crypto.h>
#include <openssl/dso.h>
#include <openssl/engine.h>
#include <openssl/evp.h>
#ifndef OPENSSL_NO_AES
#include <openssl/aes.h>
#endif
#include <openssl/rand.h>
#include <openssl/err.h>
#ifndef OPENSSL_NO_HW
#ifndef OPENSSL_NO_HW_PADLOCK
/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
#if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
# ifndef OPENSSL_NO_DYNAMIC_ENGINE
# define DYNAMIC_ENGINE
# endif
#elif (OPENSSL_VERSION_NUMBER >= 0x00907000L)
# ifdef ENGINE_DYNAMIC_SUPPORT
# define DYNAMIC_ENGINE
# endif
#else
# error "Only OpenSSL >= 0.9.7 is supported"
#endif
/* VIA PadLock AES is available *ONLY* on some x86 CPUs.
Not only that it doesn't exist elsewhere, but it
even can't be compiled on other platforms!
In addition, because of the heavy use of inline assembler,
compiler choice is limited to GCC and Microsoft C. */
#undef COMPILE_HW_PADLOCK
#if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM)
# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \
(defined(_MSC_VER) && defined(_M_IX86))
# define COMPILE_HW_PADLOCK
static ENGINE *ENGINE_padlock (void);
# endif
#endif
void ENGINE_load_padlock (void)
{
/* On non-x86 CPUs it just returns. */
#ifdef COMPILE_HW_PADLOCK
ENGINE *toadd = ENGINE_padlock ();
if (!toadd) return;
ENGINE_add (toadd);
ENGINE_free (toadd);
ERR_clear_error ();
#endif
}
#ifdef COMPILE_HW_PADLOCK
/* We do these includes here to avoid header problems on platforms that
do not have the VIA padlock anyway... */
#ifdef _WIN32
# include <malloc.h>
# ifndef alloca
# define alloca _alloca
# endif
#elif defined(NETWARE_CLIB) && defined(__GNUC__)
void *alloca(size_t);
# define alloca(s) __builtin_alloca(s)
#else
# include <stdlib.h>
#endif
/* Function for ENGINE detection and control */
static int padlock_available(void);
static int padlock_init(ENGINE *e);
/* RNG Stuff */
static RAND_METHOD padlock_rand;
/* Cipher Stuff */
#ifndef OPENSSL_NO_AES
static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
#endif
/* Engine names */
static const char *padlock_id = "padlock";
static char padlock_name[100];
/* Available features */
static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
static int padlock_use_rng = 0; /* Random Number Generator */
#ifndef OPENSSL_NO_AES
static int padlock_aes_align_required