7116525 OpenSSL t4 engine improvements: montgomery multiply
authorFerenc Rakoczi <Ferenc.Rakoczi@Sun.COM>
Fri, 10 Feb 2012 06:32:53 -0800
changeset 682 c6e4f94fd35d
parent 681 7c568e880861
child 683 c613b3449c36
7116525 OpenSSL t4 engine improvements: montgomery multiply
components/openssl/openssl-1.0.0/Makefile
components/openssl/openssl-1.0.0/engines/t4/eng_t4.c
components/openssl/openssl-1.0.0/engines/t4/eng_t4_bignum.h
components/openssl/openssl-1.0.0/engines/t4/eng_t4_montmul.c
components/openssl/openssl-1.0.0/patches/openssl-1.0.0d-t4-engine.sparc-patch
--- a/components/openssl/openssl-1.0.0/Makefile	Wed Feb 08 16:47:41 2012 -0800
+++ b/components/openssl/openssl-1.0.0/Makefile	Fri Feb 10 06:32:53 2012 -0800
@@ -167,8 +167,8 @@
 # We need to modify the default lint flags to include patched opensslconf.h from
 # the build directory. If we do not do that, lint will complain about md2.h
 # which is not enabled by default but it is in our opensslconf.h.
-LFLAGS_32 := -I$(BUILD_DIR_32)/include $(LINT_FLAGS)
-LFLAGS_64 := -I$(BUILD_DIR_64)/include $(LINT_FLAGS)
+LFLAGS_32 := -I$(BUILD_DIR_32)/include $(LINT_FLAGS) -lsoftcrypto
+LFLAGS_64 := -I$(BUILD_DIR_64)/include $(LINT_FLAGS) -lsoftcrypto
 
 # Set modified lint flags for our lint library targets.
 $(BUILD_DIR_32)/llib-lcrypto.ln: LINT_FLAGS="$(LFLAGS_32)"
--- a/components/openssl/openssl-1.0.0/engines/t4/eng_t4.c	Wed Feb 08 16:47:41 2012 -0800
+++ b/components/openssl/openssl-1.0.0/engines/t4/eng_t4.c	Fri Feb 10 06:32:53 2012 -0800
@@ -170,13 +170,22 @@
 static t4_cipher_id get_cipher_index_by_nid(int nid);
 #pragma inline(get_cipher_index_by_nid)
 static void t4_instructions_present(_Bool *aes_present, _Bool *des_present,
-    _Bool *digest_present);
+    _Bool *digest_present, _Bool *montmul_present);
 #pragma inline(t4_instructions_present)
 
 /* Digest registration function. Called by ENGINE_set_ciphers() */
 int t4_get_all_digests(ENGINE *e, const EVP_MD **digest,
     const int **nids, int nid);
 
+/* RSA_METHOD structure used by ENGINE_set_RSA() */
+extern RSA_METHOD *t4_RSA(void);
+
+/* DH_METHOD structure used by ENGINE_set_DH() */
+extern DH_METHOD *t4_DH(void);
+
+/* DSA_METHOD structure used by ENGINE_set_DSA() */
+extern DSA_METHOD *t4_DSA(void);
+
 #ifndef	SOLARIS_NO_AES_CTR
 /*
  * NIDs for AES counter mode that will be defined during the engine
@@ -542,13 +551,14 @@
  */
 
 /*
- * Set aes_present, des_present, and digest_present to 0 or 1 depending on
- * whether the current SPARC processor supports AES, DES, and
- * MD5/SHA1/SHA256/SHA512, respectively.
+ * Set aes_present, des_present, digest_present and montmul_present
+ * to B_FALSE or B_TRUE depending on
+ * whether the current SPARC processor supports AES, DES,
+ * MD5/SHA1/SHA256/SHA512 and MONTMUL, respectively.
  */
 static void
 t4_instructions_present(_Bool *aes_present, _Bool *des_present,
-    _Bool *digest_present)
+    _Bool *digest_present, _Bool *montmul_present)
 {
 #ifdef	OPENSSL_NO_DES
 #undef	AV_SPARC_DES
@@ -585,9 +595,10 @@
 	uint_t		ui;
 
 	(void) getisax(&ui, 1);
-	*aes_present = (ui & AV_SPARC_AES) != 0;
-	*des_present = (ui & AV_SPARC_DES) != 0;
-	*digest_present = (ui & DIGEST_MASK) == DIGEST_MASK;
+	*aes_present = ((ui & AV_SPARC_AES) != 0);
+	*des_present = ((ui & AV_SPARC_DES) != 0);
+	*digest_present = ((ui & DIGEST_MASK) == DIGEST_MASK);
+	*montmul_present = ((ui & AV_SPARC_MONT) != 0);
 }
 
 
@@ -1085,9 +1096,10 @@
 static int
 t4_bind(ENGINE *e)
 {
-	_Bool aes_engage, digest_engage, des_engage;
+	_Bool aes_engage, digest_engage, des_engage, montmul_engage;
 
-	t4_instructions_present(&aes_engage, &des_engage, &digest_engage);
+	t4_instructions_present(&aes_engage, &des_engage, &digest_engage,
+	    &montmul_engage);
 #ifdef	DEBUG_T4
 	(void) fprintf(stderr,
 	    "t4_bind: engage aes=%d, des=%d, digest=%d\n",
@@ -1128,6 +1140,15 @@
 	    !ENGINE_set_init_function(e, t4_init) ||
 	    (aes_engage && !ENGINE_set_ciphers(e, t4_get_all_ciphers)) ||
 	    (digest_engage && !ENGINE_set_digests(e, t4_get_all_digests)) ||
+#ifndef OPENSSL_NO_RSA
+	    (montmul_engage && !ENGINE_set_RSA(e, t4_RSA())) ||
+#endif	/* OPENSSL_NO_RSA */
+#ifndef OPENSSL_NO_DH
+	    (montmul_engage && !ENGINE_set_DH(e, t4_DH())) ||
+#endif	/* OPENSSL_NO_DH */
+#ifndef OPENSSL_NO_DSA
+	    (montmul_engage && !ENGINE_set_DSA(e, t4_DSA())) ||
+#endif	/* OPENSSL_NO_DSA */
 	    !ENGINE_set_destroy_function(e, t4_destroy)) {
 		T4_FREE_AES_CTR_NIDS;
 		return (0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-1.0.0/engines/t4/eng_t4_bignum.h	Fri Feb 10 06:32:53 2012 -0800
@@ -0,0 +1,287 @@
+/*
+ * This product includes cryptographic software developed by the OpenSSL
+ * Project for use in the OpenSSL Toolkit (http://www.openssl.org/).
+ */
+
+/*
+ * ====================================================================
+ * Copyright (c) 1999-2011 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
+ *    [email protected].
+ *
+ * 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.
+ * ====================================================================
+ */
+
+/*
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * This file is a copy of the ON gate's usr/src/common/bignum/bignum.h file
+ */
+
+#ifndef _BIGNUM_H
+#define	_BIGNUM_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+
+#if defined(__sparcv9) || defined(__amd64) || defined(__sparc)
+						/* 64-bit chunk size */
+#ifndef UMUL64
+#define	UMUL64	/* 64-bit multiplication results are supported */
+#endif
+#else
+#define	BIGNUM_CHUNK_32
+#endif
+
+
+#define	BITSINBYTE	8
+
+/* Bignum "digits" (aka "chunks" or "words") are either 32- or 64-bits */
+#ifdef BIGNUM_CHUNK_32
+#define	BIG_CHUNK_SIZE		32
+#define	BIG_CHUNK_TYPE		uint32_t
+#define	BIG_CHUNK_TYPE_SIGNED	int32_t
+#define	BIG_CHUNK_HIGHBIT	0x80000000
+#define	BIG_CHUNK_ALLBITS	0xffffffff
+#define	BIG_CHUNK_LOWHALFBITS	0xffff
+#define	BIG_CHUNK_HALF_HIGHBIT	0x8000
+
+#else
+#define	BIG_CHUNK_SIZE		64
+#define	BIG_CHUNK_TYPE		uint64_t
+#define	BIG_CHUNK_TYPE_SIGNED	int64_t
+#define	BIG_CHUNK_HIGHBIT	0x8000000000000000ULL
+#define	BIG_CHUNK_ALLBITS	0xffffffffffffffffULL
+#define	BIG_CHUNK_LOWHALFBITS	0xffffffffULL
+#define	BIG_CHUNK_HALF_HIGHBIT	0x80000000ULL
+#endif
+
+#define	BITLEN2BIGNUMLEN(x)	((x) > 0 ? \
+				((((x) - 1) / BIG_CHUNK_SIZE) + 1) : 0)
+#define	CHARLEN2BIGNUMLEN(x)	((x) > 0 ? \
+				((((x) - 1) / sizeof (BIG_CHUNK_TYPE)) + 1) : 0)
+
+#define	BIGNUM_WORDSIZE	(BIG_CHUNK_SIZE / BITSINBYTE)  /* word size in bytes */
+#define	BIG_CHUNKS_FOR_160BITS	BITLEN2BIGNUMLEN(160)
+
+
+/*
+ * leading 0's are permitted
+ * 0 should be represented by size>=1, size>=len>=1, sign=1,
+ * value[i]=0 for 0<i<len
+ */
+typedef struct {
+	/* size and len in units of BIG_CHUNK_TYPE words  */
+	uint32_t	size;	/* size of memory allocated for value  */
+	uint32_t	len;	/* number of valid data words in value */
+	int		sign;	/* 1 for nonnegative, -1 for negative  */
+	int		malloced; /* 1 if value was malloced, 0 if not */
+	BIG_CHUNK_TYPE *value;
+} BIGNUM;
+
+#define	BIGTMPSIZE 65
+
+#define	BIG_TRUE 1
+#define	BIG_FALSE 0
+
+typedef int BIG_ERR_CODE;
+
+/* error codes */
+#define	BIG_OK 0
+#define	BIG_NO_MEM -1
+#define	BIG_INVALID_ARGS -2
+#define	BIG_DIV_BY_0 -3
+#define	BIG_NO_RANDOM -4
+#define	BIG_GENERAL_ERR	-5
+#define	BIG_TEST_FAILED -6
+#define	BIG_BUFFER_TOO_SMALL -7
+
+/*
+ * this is not an error code, but should be different from possible error codes
+ */
+#define	RND_TEST_VALUE_SUPPLIED	-8
+
+
+#define	arraysize(x) (sizeof (x) / sizeof (x[0]))
+
+typedef BIG_ERR_CODE (*big_modexp_ncp_func_ptr)(BIGNUM *result,
+    BIGNUM *ma, BIGNUM *e, BIGNUM *n,
+    BIGNUM *tmp, BIG_CHUNK_TYPE n0, void *ncp, void *req);
+
+typedef struct {
+	big_modexp_ncp_func_ptr	func;
+	void			*ncp;
+	void 			*reqp;
+} big_modexp_ncp_info_t;
+
+#ifdef YF_MODEXP
+BIG_ERR_CODE big_modexp_ncp_yf(BIGNUM *result, BIGNUM *ma, BIGNUM *e, BIGNUM *n,
+    BIGNUM *tmp, BIG_CHUNK_TYPE n0);
+#endif
+
+#ifdef YF_MONTMUL
+BIG_ERR_CODE big_mont_mul_yf(BIGNUM *ret,
+    BIGNUM *a, BIGNUM *b, BIGNUM *n, BIG_CHUNK_TYPE n0);
+#endif
+
+#ifdef YF_MPMUL
+BIG_ERR_CODE big_mp_mul_yf(BIGNUM *ret, BIGNUM *a, BIGNUM *b);
+void mpmul_arr_yf(uint64_t *res, uint64_t *m1, uint64_t *m2, int len);
+#endif
+
+#ifdef USE_FLOATING_POINT
+void conv_d16_to_i32(uint32_t *i32, double *d16, int64_t *tmp, int ilen);
+void conv_i32_to_d32(double *d32, uint32_t *i32, int len);
+void conv_i32_to_d16(double *d16, uint32_t *i32, int len);
+void conv_i32_to_d32_and_d16(double *d32, double *d16,
+    uint32_t *i32, int len);
+void mont_mulf_noconv(uint32_t *result, double *dm1, double *dm2, double *dt,
+    double *dn, uint32_t *nint, int nlen, double dn0);
+#endif /* USE_FLOATING_POINT */
+
+extern BIGNUM big_One;
+extern BIGNUM big_Two;
+
+void printbignum(char *aname, BIGNUM *a);
+
+BIG_ERR_CODE big_init(BIGNUM *number, int size);
+BIG_ERR_CODE big_extend(BIGNUM *number, int size);
+void big_finish(BIGNUM *number);
+void bytestring2bignum(BIGNUM *bn, uchar_t *kn, size_t len);
+void bignum2bytestring(uchar_t *kn, BIGNUM *bn, size_t len);
+BIG_ERR_CODE big_mont_rr(BIGNUM *result, BIGNUM *n);
+BIG_ERR_CODE big_modexp(BIGNUM *result, BIGNUM *a, BIGNUM *e,
+    BIGNUM *n, BIGNUM *n_rr);
+BIG_ERR_CODE big_modexp_ext(BIGNUM *result, BIGNUM *a, BIGNUM *e,
+    BIGNUM *n, BIGNUM *n_rr, big_modexp_ncp_info_t *info);
+BIG_ERR_CODE big_modexp_crt(BIGNUM *result, BIGNUM *a, BIGNUM *dmodpminus1,
+    BIGNUM *dmodqminus1, BIGNUM *p, BIGNUM *q, BIGNUM *pinvmodq,
+    BIGNUM *p_rr, BIGNUM *q_rr);
+BIG_ERR_CODE big_modexp_crt_ext(BIGNUM *result, BIGNUM *a, BIGNUM *dmodpminus1,
+    BIGNUM *dmodqminus1, BIGNUM *p, BIGNUM *q, BIGNUM *pinvmodq,
+    BIGNUM *p_rr, BIGNUM *q_rr, big_modexp_ncp_info_t *info);
+int big_cmp_abs(BIGNUM *a, BIGNUM *b);
+BIG_ERR_CODE big_random(BIGNUM *r, size_t length,
+    int (*rfunc)(void *, size_t), boolean_t precise);
+BIG_ERR_CODE big_div_pos(BIGNUM *result, BIGNUM *remainder,
+    BIGNUM *aa, BIGNUM *bb);
+BIG_ERR_CODE big_ext_gcd_pos(BIGNUM *gcd, BIGNUM *cm, BIGNUM *ce,
+    BIGNUM *m, BIGNUM *e);
+BIG_ERR_CODE big_add(BIGNUM *result, BIGNUM *aa, BIGNUM *bb);
+BIG_ERR_CODE big_add_abs(BIGNUM *result, BIGNUM *aa, BIGNUM *bb);
+void big_mul_arr_64(uint64_t *result, uint64_t *a, uint64_t *b, int alen);
+BIG_ERR_CODE big_mul(BIGNUM *result, BIGNUM *aa, BIGNUM *bb);
+void big_shiftright(BIGNUM *result, BIGNUM *aa, int offs);
+BIG_ERR_CODE big_nextprime_pos(BIGNUM *result, BIGNUM *n);
+BIG_ERR_CODE big_nextprime_pos_ext(BIGNUM *result, BIGNUM *n,
+    big_modexp_ncp_info_t *info);
+BIG_ERR_CODE big_sub_pos(BIGNUM *result, BIGNUM *aa, BIGNUM *bb);
+BIG_ERR_CODE big_copy(BIGNUM *dest, BIGNUM *src);
+BIG_ERR_CODE big_sub(BIGNUM *result, BIGNUM *aa, BIGNUM *bb);
+int big_bitlength(BIGNUM *n);
+BIG_ERR_CODE big_init1(BIGNUM *number, int size,
+    BIG_CHUNK_TYPE *buf, int bufsize);
+BIG_ERR_CODE big_mont_mul(BIGNUM *ret,
+    BIGNUM *a, BIGNUM *b, BIGNUM *n, BIG_CHUNK_TYPE n0);
+int big_is_zero(BIGNUM *n);
+BIG_CHUNK_TYPE big_n0(BIG_CHUNK_TYPE n);
+
+
+/*
+ * Kernel bignum module: module integrity test
+ */
+extern int	bignum_fips_check(void);
+
+#if defined(HWCAP)
+
+#if (BIG_CHUNK_SIZE != 32)
+#error HWCAP works only with 32-bit bignum chunks
+#endif
+
+#define	BIG_MUL_SET_VEC(r, a, len, digit) \
+	(*big_mul_set_vec_impl)(r, a, len, digit)
+#define	BIG_MUL_ADD_VEC(r, a, len, digit) \
+	(*big_mul_add_vec_impl)(r, a, len, digit)
+#define	BIG_MUL_VEC(r, a, alen, b, blen) \
+	(*big_mul_vec_impl)(r, a, alen, b, blen)
+#define	BIG_SQR_VEC(r, a, len) \
+	(*big_sqr_vec_impl)(r, a, len)
+
+extern BIG_CHUNK_TYPE (*big_mul_set_vec_impl)
+	(BIG_CHUNK_TYPE *r, BIG_CHUNK_TYPE *a, int len, BIG_CHUNK_TYPE digit);
+extern BIG_CHUNK_TYPE (*big_mul_add_vec_impl)
+	(BIG_CHUNK_TYPE *r, BIG_CHUNK_TYPE *a, int len, BIG_CHUNK_TYPE digit);
+extern void (*big_mul_vec_impl)
+	(BIG_CHUNK_TYPE *r, BIG_CHUNK_TYPE *a, int alen, BIG_CHUNK_TYPE *b,
+	    int blen);
+extern void (*big_sqr_vec_impl)
+	(BIG_CHUNK_TYPE *r, BIG_CHUNK_TYPE *a, int len);
+
+#else /* ! HWCAP */
+
+#define	BIG_MUL_SET_VEC(r, a, len, digit) big_mul_set_vec(r, a, len, digit)
+#define	BIG_MUL_ADD_VEC(r, a, len, digit) big_mul_add_vec(r, a, len, digit)
+#define	BIG_MUL_VEC(r, a, alen, b, blen) big_mul_vec(r, a, alen, b, blen)
+#define	BIG_SQR_VEC(r, a, len) big_sqr_vec(r, a, len)
+
+extern BIG_CHUNK_TYPE big_mul_set_vec(BIG_CHUNK_TYPE *r, BIG_CHUNK_TYPE *a,
+    int len, BIG_CHUNK_TYPE d);
+extern BIG_CHUNK_TYPE big_mul_add_vec(BIG_CHUNK_TYPE *r,
+    BIG_CHUNK_TYPE *a, int len, BIG_CHUNK_TYPE d);
+extern void big_mul_vec(BIG_CHUNK_TYPE *r, BIG_CHUNK_TYPE *a, int alen,
+    BIG_CHUNK_TYPE *b, int blen);
+extern void big_sqr_vec(BIG_CHUNK_TYPE *r, BIG_CHUNK_TYPE *a, int len);
+
+#endif /* HWCAP */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _BIGNUM_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-1.0.0/engines/t4/eng_t4_montmul.c	Fri Feb 10 06:32:53 2012 -0800
@@ -0,0 +1,459 @@
+/*
+ * This product includes cryptographic software developed by the OpenSSL
+ * Project for use in the OpenSSL Toolkit (http://www.openssl.org/).
+ */
+
+/*
+ * ====================================================================
+ * Copyright (c) 1999-2011 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
+ *    [email protected].
+ *
+ * 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.
+ * ====================================================================
+ */
+
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * This engine supports SPARC microprocessors that provide AES and other
+ * cipher and hash instructions, such as the T4 microprocessor.
+ *
+ * This file implements the RSA, DSA, and DH operations.
+ */
+
+#include <openssl/opensslconf.h>
+
+#define	BIGNUM SOLARIS_BIGNUM
+#include "eng_t4_bignum.h"
+#undef BIGNUM
+
+
+#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_MONTMUL_T4)
+#include <sys/types.h>
+#include <sys/auxv.h>		/* getisax() */
+#include <sys/sysmacros.h>	/* IS_P2ALIGNED() */
+#include <sys/byteorder.h>	/* htonl() and friends */
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif	/* !OPENSSL_NO_RSA */
+
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif	/* !OPENSSL_NO_DSA */
+
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif	/* !OPENSSL_NO_DH */
+
+#include <openssl/bio.h>
+#include <openssl/aes.h>
+#include <openssl/engine.h>
+
+#if (defined(sun4v) || defined(__sparcv9) || defined(__sparcv8plus) || \
+	defined(__sparcv8)) && !defined(OPENSSL_NO_ASM)
+#define	COMPILE_HW_T4
+#endif
+
+#ifdef	COMPILE_HW_T4
+
+#if !(defined(OPENSSL_NO_RSA) && defined(OPENSSL_NO_DSA) && \
+	defined(OPENSSL_NO_DH))
+
+
+/*
+ * Convert OpenSSL's BIGNUM to Solaris's BIGNUM....
+ * It assumes that the Solaris BIGNUM has enough space
+ */
+static void
+bn2solbn(const BIGNUM *src, SOLARIS_BIGNUM *dst)
+{
+	int	i, j;
+
+	if (BN_BITS2 < BIG_CHUNK_SIZE) {
+		for (i = 0, j = 0; i < src->top; i++) {
+			if ((i & 1) == 0) {
+				dst->value[j] = src->d[i];
+			} else {
+				dst->value[j] += ((uint64_t)(src->d[i])) << 32;
+				j++;
+			}
+		}
+		dst->len = (src->top + 1) / 2;
+		dst->sign = (src->neg == 1) ? -1 : 1;
+	} else if (BN_BITS2 == BIG_CHUNK_SIZE) {
+		(void) memcpy(dst->value, src->d, src->top);
+		dst->len = src->top;
+		dst->sign = (src->neg == 1) ? -1 : 1;
+	} else { /* BN_BITS2 > BIG_CHUNK_SIZE */
+		for (i = 0, j = 0; i < src->top; i++) {
+			dst->value[j++] = src->d[i] & 0xffffffffULL;
+			dst->value[j++] = ((uint64_t)(src->d[i])) >> 32;
+		}
+		dst->len = src->top * 2;
+		if (dst->value[dst->len - 1] == 0) {
+			dst->len--;
+		}
+		dst->sign = (src->neg == 1) ? -1 : 1;
+	}
+}
+
+/*
+ * It assumes that OpenSSL's BIGNUM has enough space.
+ */
+static void
+solbn2bn(const SOLARIS_BIGNUM *src, BIGNUM *dst)
+{
+	int	i, j;
+
+	if (BN_BITS2 < BIG_CHUNK_SIZE) {
+		for (i = 0, j = 0; i < src->len; i++) {
+			dst->d[j++] = src->value[i] & 0xffffffffULL;
+			dst->d[j++] = ((uint64_t)(src->value[i])) >> 32;
+		}
+		dst->top = src->len * 2;
+		if (dst->d[dst->top - 1] == 0) {
+			dst->top--;
+		}
+		dst->neg = (src->sign == -1) ? 1 : 0;
+	} else if (BN_BITS2 == BIG_CHUNK_SIZE) {
+		(void) memcpy(src->value, dst->d, src->len);
+		dst->top = src->len;
+		dst->neg = (src->sign == -1) ? 1 : 0;
+	} else { /* BN_BITS2 > BIG_CHUNK_SIZE */
+		for (i = 0, j = 0; i < src->len; i++) {
+			if ((i & 1) == 0) {
+				dst->d[j] = src->value[i];
+			} else {
+				dst->d[j] += ((uint64_t)(src->value[i])) << 32;
+				j++;
+			}
+		}
+		dst->top = (src->len + 1) / 2;
+		dst->neg =  (src->sign == -1) ? 1 : 0;
+	}
+}
+
+
+
+static int
+t4_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+    BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+	int		rv = 0;
+	SOLARIS_BIGNUM	sol_r = {0};
+	SOLARIS_BIGNUM	sol_a = {0};
+	SOLARIS_BIGNUM	sol_p = {0};
+	SOLARIS_BIGNUM	sol_m = {0};
+
+	if (big_init(&sol_r, (m->top + 3) * BN_BITS2 / BIG_CHUNK_SIZE) !=
+	    BIG_OK) {
+		goto cleanup;
+	}
+	if (big_init(&sol_a, (a->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
+	    BIG_OK) {
+		goto cleanup;
+	}
+	if (big_init(&sol_p, (p->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
+	    BIG_OK) {
+		goto cleanup;
+	}
+	if (big_init(&sol_m, (m->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
+	    BIG_OK) {
+		goto cleanup;
+	}
+
+	bn2solbn(a, &sol_a);
+	bn2solbn(p, &sol_p);
+	bn2solbn(m, &sol_m);
+
+	/* calls libsoftcrypto's big_modexp() routine */
+	if (big_modexp(&sol_r, &sol_a, &sol_p, &sol_m, NULL) != BIG_OK) {
+		goto cleanup;
+	}
+
+	if (bn_wexpand(r, m->top + 2) == NULL) {
+		goto cleanup;
+	}
+	solbn2bn(&sol_r, r);
+
+	rv = 1;
+
+cleanup:
+
+	big_finish(&sol_m);
+	big_finish(&sol_p);
+	big_finish(&sol_a);
+	big_finish(&sol_r);
+
+	return (rv);
+}
+
+#endif	/* !(OPENSSL_NO_RSA && OPENSSL_NO_DSA) */
+
+#ifndef OPENSSL_NO_RSA
+
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD t4_rsa =
+{
+	"Oracle T4 RSA method",
+	NULL,			/* rsa_pub_encrypt */
+	NULL,			/* rsa_pub_decrypt */
+	NULL,			/* rsa_priv_encrypt */
+	NULL,			/* rsa_priv_decrypt */
+	NULL,			/* rsa_mod_exp */
+	t4_bn_mod_exp,		/* bn_mod_exp */
+	NULL,			/* init */
+	NULL,			/* finish */
+	RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE | RSA_FLAG_NO_BLINDING,
+				/* flags  */
+	NULL,			/* app_data */
+	NULL,			/* rsa_sign */
+	NULL,			/* rsa_verify */
+	/* Internal rsa_keygen will be used if this is NULL. */
+	NULL			/* rsa_keygen */
+};
+
+RSA_METHOD *
+t4_RSA(void)
+{
+	const RSA_METHOD *meth1;
+
+	meth1 = RSA_PKCS1_SSLeay();
+	t4_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+	t4_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+	t4_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+	t4_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+	t4_rsa.rsa_mod_exp = meth1->rsa_mod_exp;
+	t4_rsa.finish = meth1->finish;
+
+	return (&t4_rsa);
+}
+
+#endif /* !OPENSSL_NO_RSA */
+
+
+#ifndef OPENSSL_NO_DSA
+
+static int
+t4_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+	return (t4_bn_mod_exp(r, a, p, m, ctx, m_ctx));
+}
+
+
+static int
+t4_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
+    BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+	int		rv = 0;
+	SOLARIS_BIGNUM	sol_rr = {0};
+	SOLARIS_BIGNUM	sol_a1 = {0};
+	SOLARIS_BIGNUM	sol_p1 = {0};
+	SOLARIS_BIGNUM	sol_a2 = {0};
+	SOLARIS_BIGNUM	sol_p2 = {0};
+	SOLARIS_BIGNUM	sol_m = {0};
+	SOLARIS_BIGNUM	sol_tmp = {0};
+
+	if (big_init(&sol_rr, (m->top + 3) * BN_BITS2 / BIG_CHUNK_SIZE) !=
+	    BIG_OK) {
+		goto cleanup;
+	}
+	if (big_init(&sol_a1, (a1->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
+	    BIG_OK) {
+		goto cleanup;
+	}
+	if (big_init(&sol_p1, (p1->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
+	    BIG_OK) {
+		goto cleanup;
+	}
+	if (big_init(&sol_a2, (a2->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
+	    BIG_OK) {
+		goto cleanup;
+	}
+	if (big_init(&sol_p2, (p2->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
+	    BIG_OK) {
+		goto cleanup;
+	}
+	if (big_init(&sol_m, (m->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
+	    BIG_OK) {
+		goto cleanup;
+	}
+	if (big_init(&sol_tmp, 2 * sol_m.len + 1) != BIG_OK) {
+		goto cleanup;
+	}
+
+	if (big_init(&sol_tmp, 2 * sol_m.len + 1) != BIG_OK) {
+		goto cleanup;
+	}
+
+	bn2solbn(a1, &sol_a1);
+	bn2solbn(p1, &sol_p1);
+	bn2solbn(a2, &sol_a2);
+	bn2solbn(p2, &sol_p2);
+	bn2solbn(m, &sol_m);
+
+
+	/* calls libsoftcrypto's big_modexp() routine */
+	if (big_modexp(&sol_rr, &sol_a1, &sol_p1, &sol_m, NULL) !=
+	    BIG_OK) {
+		goto cleanup;
+	}
+
+	if (big_modexp(&sol_tmp, &sol_a2, &sol_p2, &sol_m, NULL) !=
+	    BIG_OK) {
+		goto cleanup;
+	}
+
+	if (big_mul(&sol_tmp, &sol_rr, &sol_tmp) != BIG_OK) {
+		goto cleanup;
+	}
+
+	if (big_div_pos(NULL, &sol_rr, &sol_tmp, &sol_m) != BIG_OK) {
+		goto cleanup;
+	}
+
+	if (bn_wexpand(rr, m->top + 2) == NULL) {
+		goto cleanup;
+	}
+	solbn2bn(&sol_rr, rr);
+
+	rv = 1;
+
+cleanup:
+
+	big_finish(&sol_tmp);
+	big_finish(&sol_m);
+	big_finish(&sol_p2);
+	big_finish(&sol_a2);
+	big_finish(&sol_p1);
+	big_finish(&sol_a1);
+	big_finish(&sol_rr);
+
+	return (rv);
+}
+
+/* Our internal DSA_METHOD that we provide pointers to */
+static DSA_METHOD t4_dsa =
+{
+	"Oracle T4 DSA method",	/* name */
+	NULL,			/* dsa_do_sign */
+	NULL,			/* dsa_sign_setup */
+	NULL,			/* dsa_do_verify */
+	t4_dsa_mod_exp,		/* dsa_mod_exp, */
+	t4_dsa_bn_mod_exp,	/* bn_mod_exp, */
+	NULL,			/* init */
+	NULL,			/* finish */
+	NULL,			/* flags */
+	NULL,			/* app_data */
+	NULL,			/* dsa_paramgen */
+	NULL			/* dsa_keygen */
+};
+
+DSA_METHOD *
+t4_DSA(void)
+{
+	const DSA_METHOD *meth1;
+
+	meth1 = DSA_OpenSSL();
+	t4_dsa.dsa_do_sign = meth1->dsa_do_sign;
+	t4_dsa.dsa_sign_setup = meth1->dsa_sign_setup;
+	t4_dsa.dsa_do_verify = meth1->dsa_do_verify;
+	t4_dsa.finish = meth1->finish;
+
+	return (&t4_dsa);
+}
+
+#endif /* !OPENSSL_NO_DSA */
+
+
+#ifndef OPENSSL_NO_DH
+
+static int
+t4_dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+	return (t4_bn_mod_exp(r, a, p, m, ctx, m_ctx));
+}
+
+
+
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD t4_dh =
+{
+	"Oracle T4 DH method",	/* name */
+	NULL,			/* generate_key */
+	NULL,			/* compute_key */
+	t4_dh_bn_mod_exp,	/* bn_mod_exp, */
+	NULL,			/* init */
+	NULL,			/* finish */
+	NULL,			/* flags */
+	NULL			/* app_data */
+};
+
+DH_METHOD *
+t4_DH(void)
+{
+	const DH_METHOD *meth1;
+
+	meth1 = DH_OpenSSL();
+	t4_dh.generate_key = meth1->generate_key;
+	t4_dh.compute_key = meth1->compute_key;
+	t4_dh.finish = meth1->finish;
+
+	return (&t4_dh);
+}
+
+#endif /* !OPENSSL_NO_DH */
+
+#endif	/* COMPILE_HW_T4 */
+
+#endif	/* !OPENSSL_NO_HW && !OPENSSL_NO_HW_MONTMUL_T4 */
--- a/components/openssl/openssl-1.0.0/patches/openssl-1.0.0d-t4-engine.sparc-patch	Wed Feb 08 16:47:41 2012 -0800
+++ b/components/openssl/openssl-1.0.0/patches/openssl-1.0.0d-t4-engine.sparc-patch	Fri Feb 10 06:32:53 2012 -0800
@@ -18,6 +18,18 @@
  my $alpha_asm="alphacpuid.o:bn_asm.o alpha-mont.o::::::::::::void";
  my $mips3_asm=":bn-mips3.o::::::::::::void";
  my $s390x_asm="s390xcap.o s390xcpuid.o:bn-s390x.o s390x-mont.o::aes-s390x.o:::sha1-s390x.o sha256-s390x.o sha512-s390x.o::rc4-s390x.o:::::void";
+@@ -256,9 +256,9 @@
+ #
+ "solaris64-x86_64-cc-sunw","cc:-xO3 -m64 -xstrconst -Xa -DL_ENDIAN::-D_REENTRANT::-lsocket -lnsl -lc:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR DES_PTR DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign -M/usr/lib/ld/map.noexdata:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+ #
+-"solaris-sparcv9-cc-sunw","cc:-xtarget=ultra -m32 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -lc:BN_LLONG RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m32 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
++"solaris-sparcv9-cc-sunw","cc:-xtarget=ultra -m32 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -lc -lsoftcrypto:BN_LLONG RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m32 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+ #
+-"solaris64-sparcv9-cc-sunw","cc:-xtarget=ultra -m64 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -xspace -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -lc:BN_LLONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):/usr/ccs/bin/ar rs::/64",
++"solaris64-sparcv9-cc-sunw","cc:-xtarget=ultra -m64 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -xspace -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -lc -lsoftcrypto:BN_LLONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):/usr/ccs/bin/ar rs::/64",
+ 
+ #### IRIX 5.x configs
+ # -mips2 flag is added by ./config when appropriate.
 Index: crypto/aes/Makefile
 ===================================================================
 diff -ru openssl-1.0.0d/crypto/aes/ openssl-1.0.0d/crypto/aes/Makefile
@@ -82,7 +94,7 @@
  	tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c \
  	eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c \
 +	eng_t4.c eng_t4_des.c eng_t4_md5.c \
-+	eng_t4_sha1.c eng_t4_sha256.c eng_t4_sha512.c \
++	eng_t4_sha1.c eng_t4_sha256.c eng_t4_sha512.c eng_t4_montmul.c \
  	hw_pk11.c hw_pk11_pub.c hw_pk11_uri.c
  LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
  	eng_table.o eng_pkey.o eng_fat.o eng_all.o \
@@ -90,7 +102,7 @@
  	tb_cipher.o tb_digest.o tb_pkmeth.o tb_asnmth.o \
  	eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o \
 +	eng_t4.o eng_t4_des.o eng_t4_md5.o \
-+	eng_t4_sha1.o eng_t4_sha256.o eng_t4_sha512.o \
++	eng_t4_sha1.o eng_t4_sha256.o eng_t4_sha512.o eng_t4_montmul.o \
  	hw_pk11.o hw_pk11_pub.o hw_pk11_uri.o
  
  SRC= $(LIBSRC)