components/openssl/openssl-1.0.0/engines/t4/eng_t4_montmul.c
branchs11-update
changeset 2593 b92e6df5eaf0
parent 2592 a7d8d41eeab2
child 2594 27f414f634e9
equal deleted inserted replaced
2592:a7d8d41eeab2 2593:b92e6df5eaf0
     1 /*
       
     2  * This product includes cryptographic software developed by the OpenSSL
       
     3  * Project for use in the OpenSSL Toolkit (http://www.openssl.org/).
       
     4  */
       
     5 
       
     6 /*
       
     7  * ====================================================================
       
     8  * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
       
     9  *
       
    10  * Redistribution and use in source and binary forms, with or without
       
    11  * modification, are permitted provided that the following conditions
       
    12  * are met:
       
    13  *
       
    14  * 1. Redistributions of source code must retain the above copyright
       
    15  *    notice, this list of conditions and the following disclaimer.
       
    16  *
       
    17  * 2. Redistributions in binary form must reproduce the above copyright
       
    18  *    notice, this list of conditions and the following disclaimer in
       
    19  *    the documentation and/or other materials provided with the
       
    20  *    distribution.
       
    21  *
       
    22  * 3. All advertising materials mentioning features or use of this
       
    23  *    software must display the following acknowledgment:
       
    24  *    "This product includes software developed by the OpenSSL Project
       
    25  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
       
    26  *
       
    27  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
       
    28  *    endorse or promote products derived from this software without
       
    29  *    prior written permission. For written permission, please contact
       
    30  *    [email protected].
       
    31  *
       
    32  * 5. Products derived from this software may not be called "OpenSSL"
       
    33  *    nor may "OpenSSL" appear in their names without prior written
       
    34  *    permission of the OpenSSL Project.
       
    35  *
       
    36  * 6. Redistributions of any form whatsoever must retain the following
       
    37  *    acknowledgment:
       
    38  *    "This product includes software developed by the OpenSSL Project
       
    39  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
       
    40  *
       
    41  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
       
    42  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    44  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
       
    45  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    46  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
       
    47  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    48  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
       
    49  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
       
    50  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
       
    51  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
       
    52  * OF THE POSSIBILITY OF SUCH DAMAGE.
       
    53  * ====================================================================
       
    54  */
       
    55 
       
    56 /*
       
    57  * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
       
    58  */
       
    59 
       
    60 /*
       
    61  * This engine supports SPARC microprocessors that provide AES and other
       
    62  * cipher and hash instructions, such as the T4 microprocessor.
       
    63  *
       
    64  * This file implements the RSA, DSA, and DH operations.
       
    65  */
       
    66 
       
    67 #include <openssl/opensslconf.h>
       
    68 
       
    69 #define	BIGNUM SOLARIS_BIGNUM
       
    70 #include "eng_t4_bignum.h"
       
    71 #undef BIGNUM
       
    72 
       
    73 
       
    74 #if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_MONTMUL_T4)
       
    75 #include <sys/types.h>
       
    76 #include <sys/auxv.h>		/* getisax() */
       
    77 #include <sys/sysmacros.h>	/* IS_P2ALIGNED() */
       
    78 #include <sys/byteorder.h>	/* htonl() and friends */
       
    79 #include <stdlib.h>
       
    80 #include <string.h>
       
    81 #include <stdio.h>
       
    82 #include <errno.h>
       
    83 
       
    84 #ifndef OPENSSL_NO_RSA
       
    85 #include <openssl/rsa.h>
       
    86 #endif	/* !OPENSSL_NO_RSA */
       
    87 
       
    88 #ifndef OPENSSL_NO_DSA
       
    89 #include <openssl/dsa.h>
       
    90 #endif	/* !OPENSSL_NO_DSA */
       
    91 
       
    92 #ifndef OPENSSL_NO_DH
       
    93 #include <openssl/dh.h>
       
    94 #endif	/* !OPENSSL_NO_DH */
       
    95 
       
    96 #include <openssl/bio.h>
       
    97 #include <openssl/aes.h>
       
    98 #include <openssl/engine.h>
       
    99 
       
   100 #if (defined(sun4v) || defined(__sparcv9) || defined(__sparcv8plus) || \
       
   101 	defined(__sparcv8)) && !defined(OPENSSL_NO_ASM)
       
   102 #define	COMPILE_HW_T4
       
   103 #endif
       
   104 
       
   105 #ifdef	COMPILE_HW_T4
       
   106 
       
   107 #if !(defined(OPENSSL_NO_RSA) && defined(OPENSSL_NO_DSA) && \
       
   108 	defined(OPENSSL_NO_DH))
       
   109 
       
   110 
       
   111 /*
       
   112  * Convert OpenSSL's BIGNUM to Solaris's BIGNUM....
       
   113  * It assumes that the Solaris BIGNUM has enough space
       
   114  */
       
   115 static void
       
   116 bn2solbn(const BIGNUM *src, SOLARIS_BIGNUM *dst)
       
   117 {
       
   118 	int	i, j;
       
   119 
       
   120 	if (BN_BITS2 < BIG_CHUNK_SIZE) {
       
   121 		for (i = 0, j = 0; i < src->top; i++) {
       
   122 			if ((i & 1) == 0) {
       
   123 				dst->value[j] = src->d[i];
       
   124 			} else {
       
   125 				dst->value[j] += ((uint64_t)(src->d[i])) << 32;
       
   126 				j++;
       
   127 			}
       
   128 		}
       
   129 		dst->len = (src->top + 1) / 2;
       
   130 		dst->sign = (src->neg == 1) ? -1 : 1;
       
   131 	} else if (BN_BITS2 == BIG_CHUNK_SIZE) {
       
   132 		(void) memcpy(dst->value, src->d, src->top);
       
   133 		dst->len = src->top;
       
   134 		dst->sign = (src->neg == 1) ? -1 : 1;
       
   135 	} else { /* BN_BITS2 > BIG_CHUNK_SIZE */
       
   136 		for (i = 0, j = 0; i < src->top; i++) {
       
   137 			dst->value[j++] = src->d[i] & 0xffffffffULL;
       
   138 			dst->value[j++] = ((uint64_t)(src->d[i])) >> 32;
       
   139 		}
       
   140 		dst->len = src->top * 2;
       
   141 		if (dst->value[dst->len - 1] == 0) {
       
   142 			dst->len--;
       
   143 		}
       
   144 		dst->sign = (src->neg == 1) ? -1 : 1;
       
   145 	}
       
   146 }
       
   147 
       
   148 /*
       
   149  * It assumes that OpenSSL's BIGNUM has enough space.
       
   150  */
       
   151 static void
       
   152 solbn2bn(const SOLARIS_BIGNUM *src, BIGNUM *dst)
       
   153 {
       
   154 	int	i, j;
       
   155 
       
   156 	if (BN_BITS2 < BIG_CHUNK_SIZE) {
       
   157 		for (i = 0, j = 0; i < src->len; i++) {
       
   158 			dst->d[j++] = src->value[i] & 0xffffffffULL;
       
   159 			dst->d[j++] = ((uint64_t)(src->value[i])) >> 32;
       
   160 		}
       
   161 		dst->top = src->len * 2;
       
   162 		if (dst->d[dst->top - 1] == 0) {
       
   163 			dst->top--;
       
   164 		}
       
   165 		dst->neg = (src->sign == -1) ? 1 : 0;
       
   166 	} else if (BN_BITS2 == BIG_CHUNK_SIZE) {
       
   167 		(void) memcpy(src->value, dst->d, src->len);
       
   168 		dst->top = src->len;
       
   169 		dst->neg = (src->sign == -1) ? 1 : 0;
       
   170 	} else { /* BN_BITS2 > BIG_CHUNK_SIZE */
       
   171 		for (i = 0, j = 0; i < src->len; i++) {
       
   172 			if ((i & 1) == 0) {
       
   173 				dst->d[j] = src->value[i];
       
   174 			} else {
       
   175 				dst->d[j] += ((uint64_t)(src->value[i])) << 32;
       
   176 				j++;
       
   177 			}
       
   178 		}
       
   179 		dst->top = (src->len + 1) / 2;
       
   180 		dst->neg =  (src->sign == -1) ? 1 : 0;
       
   181 	}
       
   182 }
       
   183 
       
   184 
       
   185 
       
   186 static int
       
   187 t4_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
       
   188     BN_CTX *ctx, BN_MONT_CTX *m_ctx)
       
   189 {
       
   190 	int		rv = 0;
       
   191 	SOLARIS_BIGNUM	sol_r = {0};
       
   192 	SOLARIS_BIGNUM	sol_a = {0};
       
   193 	SOLARIS_BIGNUM	sol_p = {0};
       
   194 	SOLARIS_BIGNUM	sol_m = {0};
       
   195 
       
   196 	if (big_init(&sol_r, (m->top + 3) * BN_BITS2 / BIG_CHUNK_SIZE) !=
       
   197 	    BIG_OK) {
       
   198 		goto cleanup;
       
   199 	}
       
   200 	if (big_init(&sol_a, (a->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
       
   201 	    BIG_OK) {
       
   202 		goto cleanup;
       
   203 	}
       
   204 	if (big_init(&sol_p, (p->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
       
   205 	    BIG_OK) {
       
   206 		goto cleanup;
       
   207 	}
       
   208 	if (big_init(&sol_m, (m->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
       
   209 	    BIG_OK) {
       
   210 		goto cleanup;
       
   211 	}
       
   212 
       
   213 	bn2solbn(a, &sol_a);
       
   214 	bn2solbn(p, &sol_p);
       
   215 	bn2solbn(m, &sol_m);
       
   216 
       
   217 	/* calls libsoftcrypto's big_modexp() routine */
       
   218 	if (big_modexp(&sol_r, &sol_a, &sol_p, &sol_m, NULL) != BIG_OK) {
       
   219 		goto cleanup;
       
   220 	}
       
   221 
       
   222 	if (bn_wexpand(r, m->top + 2) == NULL) {
       
   223 		goto cleanup;
       
   224 	}
       
   225 	solbn2bn(&sol_r, r);
       
   226 
       
   227 	rv = 1;
       
   228 
       
   229 cleanup:
       
   230 
       
   231 	big_finish(&sol_m);
       
   232 	big_finish(&sol_p);
       
   233 	big_finish(&sol_a);
       
   234 	big_finish(&sol_r);
       
   235 
       
   236 	return (rv);
       
   237 }
       
   238 
       
   239 #endif	/* !(OPENSSL_NO_RSA && OPENSSL_NO_DSA) */
       
   240 
       
   241 #ifndef OPENSSL_NO_RSA
       
   242 
       
   243 /* Our internal RSA_METHOD that we provide pointers to */
       
   244 static RSA_METHOD t4_rsa =
       
   245 {
       
   246 	"Oracle T4 RSA method",
       
   247 	NULL,			/* rsa_pub_encrypt */
       
   248 	NULL,			/* rsa_pub_decrypt */
       
   249 	NULL,			/* rsa_priv_encrypt */
       
   250 	NULL,			/* rsa_priv_decrypt */
       
   251 	NULL,			/* rsa_mod_exp */
       
   252 	t4_bn_mod_exp,		/* bn_mod_exp */
       
   253 	NULL,			/* init */
       
   254 	NULL,			/* finish */
       
   255 	RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE | RSA_FLAG_NO_BLINDING,
       
   256 				/* flags  */
       
   257 	NULL,			/* app_data */
       
   258 	NULL,			/* rsa_sign */
       
   259 	NULL,			/* rsa_verify */
       
   260 	/* Internal rsa_keygen will be used if this is NULL. */
       
   261 	NULL			/* rsa_keygen */
       
   262 };
       
   263 
       
   264 RSA_METHOD *
       
   265 t4_RSA(void)
       
   266 {
       
   267 	const RSA_METHOD *meth1;
       
   268 
       
   269 	meth1 = RSA_PKCS1_SSLeay();
       
   270 	t4_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
       
   271 	t4_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
       
   272 	t4_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
       
   273 	t4_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
       
   274 	t4_rsa.rsa_mod_exp = meth1->rsa_mod_exp;
       
   275 	t4_rsa.finish = meth1->finish;
       
   276 
       
   277 	return (&t4_rsa);
       
   278 }
       
   279 
       
   280 #endif /* !OPENSSL_NO_RSA */
       
   281 
       
   282 
       
   283 #ifndef OPENSSL_NO_DSA
       
   284 
       
   285 static int
       
   286 t4_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
       
   287     const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
       
   288 {
       
   289 	return (t4_bn_mod_exp(r, a, p, m, ctx, m_ctx));
       
   290 }
       
   291 
       
   292 
       
   293 static int
       
   294 t4_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
       
   295     BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
       
   296 {
       
   297 	int		rv = 0;
       
   298 	SOLARIS_BIGNUM	sol_rr = {0};
       
   299 	SOLARIS_BIGNUM	sol_a1 = {0};
       
   300 	SOLARIS_BIGNUM	sol_p1 = {0};
       
   301 	SOLARIS_BIGNUM	sol_a2 = {0};
       
   302 	SOLARIS_BIGNUM	sol_p2 = {0};
       
   303 	SOLARIS_BIGNUM	sol_m = {0};
       
   304 	SOLARIS_BIGNUM	sol_tmp = {0};
       
   305 
       
   306 	if (big_init(&sol_rr, (m->top + 3) * BN_BITS2 / BIG_CHUNK_SIZE) !=
       
   307 	    BIG_OK) {
       
   308 		goto cleanup;
       
   309 	}
       
   310 	if (big_init(&sol_a1, (a1->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
       
   311 	    BIG_OK) {
       
   312 		goto cleanup;
       
   313 	}
       
   314 	if (big_init(&sol_p1, (p1->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
       
   315 	    BIG_OK) {
       
   316 		goto cleanup;
       
   317 	}
       
   318 	if (big_init(&sol_a2, (a2->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
       
   319 	    BIG_OK) {
       
   320 		goto cleanup;
       
   321 	}
       
   322 	if (big_init(&sol_p2, (p2->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
       
   323 	    BIG_OK) {
       
   324 		goto cleanup;
       
   325 	}
       
   326 	if (big_init(&sol_m, (m->top + 1) * BN_BITS2 / BIG_CHUNK_SIZE) !=
       
   327 	    BIG_OK) {
       
   328 		goto cleanup;
       
   329 	}
       
   330 	if (big_init(&sol_tmp, 2 * sol_m.len + 1) != BIG_OK) {
       
   331 		goto cleanup;
       
   332 	}
       
   333 
       
   334 	if (big_init(&sol_tmp, 2 * sol_m.len + 1) != BIG_OK) {
       
   335 		goto cleanup;
       
   336 	}
       
   337 
       
   338 	bn2solbn(a1, &sol_a1);
       
   339 	bn2solbn(p1, &sol_p1);
       
   340 	bn2solbn(a2, &sol_a2);
       
   341 	bn2solbn(p2, &sol_p2);
       
   342 	bn2solbn(m, &sol_m);
       
   343 
       
   344 
       
   345 	/* calls libsoftcrypto's big_modexp() routine */
       
   346 	if (big_modexp(&sol_rr, &sol_a1, &sol_p1, &sol_m, NULL) !=
       
   347 	    BIG_OK) {
       
   348 		goto cleanup;
       
   349 	}
       
   350 
       
   351 	if (big_modexp(&sol_tmp, &sol_a2, &sol_p2, &sol_m, NULL) !=
       
   352 	    BIG_OK) {
       
   353 		goto cleanup;
       
   354 	}
       
   355 
       
   356 	if (big_mul(&sol_tmp, &sol_rr, &sol_tmp) != BIG_OK) {
       
   357 		goto cleanup;
       
   358 	}
       
   359 
       
   360 	if (big_div_pos(NULL, &sol_rr, &sol_tmp, &sol_m) != BIG_OK) {
       
   361 		goto cleanup;
       
   362 	}
       
   363 
       
   364 	if (bn_wexpand(rr, m->top + 2) == NULL) {
       
   365 		goto cleanup;
       
   366 	}
       
   367 	solbn2bn(&sol_rr, rr);
       
   368 
       
   369 	rv = 1;
       
   370 
       
   371 cleanup:
       
   372 
       
   373 	big_finish(&sol_tmp);
       
   374 	big_finish(&sol_m);
       
   375 	big_finish(&sol_p2);
       
   376 	big_finish(&sol_a2);
       
   377 	big_finish(&sol_p1);
       
   378 	big_finish(&sol_a1);
       
   379 	big_finish(&sol_rr);
       
   380 
       
   381 	return (rv);
       
   382 }
       
   383 
       
   384 /* Our internal DSA_METHOD that we provide pointers to */
       
   385 static DSA_METHOD t4_dsa =
       
   386 {
       
   387 	"Oracle T4 DSA method",	/* name */
       
   388 	NULL,			/* dsa_do_sign */
       
   389 	NULL,			/* dsa_sign_setup */
       
   390 	NULL,			/* dsa_do_verify */
       
   391 	t4_dsa_mod_exp,		/* dsa_mod_exp, */
       
   392 	t4_dsa_bn_mod_exp,	/* bn_mod_exp, */
       
   393 	NULL,			/* init */
       
   394 	NULL,			/* finish */
       
   395 	NULL,			/* flags */
       
   396 	NULL,			/* app_data */
       
   397 	NULL,			/* dsa_paramgen */
       
   398 	NULL			/* dsa_keygen */
       
   399 };
       
   400 
       
   401 DSA_METHOD *
       
   402 t4_DSA(void)
       
   403 {
       
   404 	const DSA_METHOD *meth1;
       
   405 
       
   406 	meth1 = DSA_OpenSSL();
       
   407 	t4_dsa.dsa_do_sign = meth1->dsa_do_sign;
       
   408 	t4_dsa.dsa_sign_setup = meth1->dsa_sign_setup;
       
   409 	t4_dsa.dsa_do_verify = meth1->dsa_do_verify;
       
   410 	t4_dsa.finish = meth1->finish;
       
   411 
       
   412 	return (&t4_dsa);
       
   413 }
       
   414 
       
   415 #endif /* !OPENSSL_NO_DSA */
       
   416 
       
   417 
       
   418 #ifndef OPENSSL_NO_DH
       
   419 
       
   420 static int
       
   421 t4_dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
       
   422     const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
       
   423 {
       
   424 	return (t4_bn_mod_exp(r, a, p, m, ctx, m_ctx));
       
   425 }
       
   426 
       
   427 
       
   428 
       
   429 /* Our internal DH_METHOD that we provide pointers to */
       
   430 static DH_METHOD t4_dh =
       
   431 {
       
   432 	"Oracle T4 DH method",	/* name */
       
   433 	NULL,			/* generate_key */
       
   434 	NULL,			/* compute_key */
       
   435 	t4_dh_bn_mod_exp,	/* bn_mod_exp, */
       
   436 	NULL,			/* init */
       
   437 	NULL,			/* finish */
       
   438 	NULL,			/* flags */
       
   439 	NULL			/* app_data */
       
   440 };
       
   441 
       
   442 DH_METHOD *
       
   443 t4_DH(void)
       
   444 {
       
   445 	const DH_METHOD *meth1;
       
   446 
       
   447 	meth1 = DH_OpenSSL();
       
   448 	t4_dh.generate_key = meth1->generate_key;
       
   449 	t4_dh.compute_key = meth1->compute_key;
       
   450 	t4_dh.finish = meth1->finish;
       
   451 
       
   452 	return (&t4_dh);
       
   453 }
       
   454 
       
   455 #endif /* !OPENSSL_NO_DH */
       
   456 
       
   457 #endif	/* COMPILE_HW_T4 */
       
   458 
       
   459 #endif	/* !OPENSSL_NO_HW && !OPENSSL_NO_HW_MONTMUL_T4 */