hw_cswift.c 26.1 KB
Newer Older
1 2 3 4 5
/* crypto/engine/hw_cswift.c */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
 * project 2000.
 */
/* ====================================================================
6
 * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
 *
 * 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 <openssl/crypto.h>
#include "cryptlib.h"
#include <openssl/dso.h>
#include <openssl/engine.h>

65 66
#ifndef OPENSSL_NO_HW
#ifndef OPENSSL_NO_HW_CSWIFT
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

/* Attribution notice: Rainbow have generously allowed me to reproduce
 * the necessary definitions here from their API. This means the support
 * can build independently of whether application builders have the
 * API or hardware. This will allow developers to easily produce software
 * that has latent hardware support for any users that have accelerators
 * installed, without the developers themselves needing anything extra.
 *
 * I have only clipped the parts from the CryptoSwift header files that
 * are (or seem) relevant to the CryptoSwift support code. This is
 * simply to keep the file sizes reasonable.
 * [Geoff]
 */
#ifdef FLAT_INC
#include "cswift.h"
#else
#include "vendor_defns/cswift.h"
#endif

86 87 88
#define CSWIFT_LIB_NAME "cswift engine"
#include "hw_cswift_err.c"

89
static int cswift_destroy(ENGINE *e);
G
Geoff Thorpe 已提交
90 91 92
static int cswift_init(ENGINE *e);
static int cswift_finish(ENGINE *e);
static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
93 94

/* BIGNUM stuff */
95
static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
96
		const BIGNUM *m, BN_CTX *ctx);
97
static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
98 99 100
		const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
		const BIGNUM *iqmp, BN_CTX *ctx);

101
#ifndef OPENSSL_NO_RSA
102
/* RSA stuff */
103
static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
104
#endif
105
/* This function is aliased to mod_exp (with the mont stuff dropped). */
106
static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
107 108
		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);

109
#ifndef OPENSSL_NO_DSA
110 111 112 113
/* DSA stuff */
static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
				DSA_SIG *sig, DSA *dsa);
114
#endif
115

116
#ifndef OPENSSL_NO_DH
117 118
/* DH stuff */
/* This function is alised to mod_exp (with the DH and mont dropped). */
R
Richard Levitte 已提交
119 120
static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
		const BIGNUM *a, const BIGNUM *p,
121
		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
122
#endif
123

G
Geoff Thorpe 已提交
124 125 126 127 128 129 130 131 132
/* The definitions for control commands specific to this engine */
#define CSWIFT_CMD_SO_PATH		ENGINE_CMD_BASE
static const ENGINE_CMD_DEFN cswift_cmd_defns[] = {
	{CSWIFT_CMD_SO_PATH,
		"SO_PATH",
		"Specifies the path to the 'cswift' shared library",
		ENGINE_CMD_FLAG_STRING},
	{0, NULL, NULL, 0}
	};
133

134
#ifndef OPENSSL_NO_RSA
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
/* Our internal RSA_METHOD that we provide pointers to */
static RSA_METHOD cswift_rsa =
	{
	"CryptoSwift RSA method",
	NULL,
	NULL,
	NULL,
	NULL,
	cswift_rsa_mod_exp,
	cswift_mod_exp_mont,
	NULL,
	NULL,
	0,
	NULL,
	NULL,
	NULL
	};
152
#endif
153

154
#ifndef OPENSSL_NO_DSA
155 156 157 158 159 160 161 162 163 164 165 166 167 168
/* Our internal DSA_METHOD that we provide pointers to */
static DSA_METHOD cswift_dsa =
	{
	"CryptoSwift DSA method",
	cswift_dsa_sign,
	NULL, /* dsa_sign_setup */
	cswift_dsa_verify,
	NULL, /* dsa_mod_exp */
	NULL, /* bn_mod_exp */
	NULL, /* init */
	NULL, /* finish */
	0, /* flags */
	NULL /* app_data */
	};
169
#endif
170

171
#ifndef OPENSSL_NO_DH
172 173 174 175 176 177 178 179 180 181 182 183
/* Our internal DH_METHOD that we provide pointers to */
static DH_METHOD cswift_dh =
	{
	"CryptoSwift DH method",
	NULL,
	NULL,
	cswift_mod_exp_dh,
	NULL,
	NULL,
	0,
	NULL
	};
184
#endif
185

G
Geoff Thorpe 已提交
186 187 188
/* Constants used when creating the ENGINE */
static const char *engine_cswift_id = "cswift";
static const char *engine_cswift_name = "CryptoSwift hardware engine support";
189

190 191 192
/* This internal function is used by ENGINE_cswift() and possibly by the
 * "dynamic" ENGINE support too */
static int bind_helper(ENGINE *e)
193
	{
194
#ifndef OPENSSL_NO_RSA
R
Richard Levitte 已提交
195
	const RSA_METHOD *meth1;
196 197
#endif
#ifndef OPENSSL_NO_DH
R
Richard Levitte 已提交
198
	const DH_METHOD *meth2;
199
#endif
200 201
	if(!ENGINE_set_id(e, engine_cswift_id) ||
			!ENGINE_set_name(e, engine_cswift_name) ||
202
#ifndef OPENSSL_NO_RSA
203
			!ENGINE_set_RSA(e, &cswift_rsa) ||
204 205
#endif
#ifndef OPENSSL_NO_DSA
206
			!ENGINE_set_DSA(e, &cswift_dsa) ||
207 208
#endif
#ifndef OPENSSL_NO_DH
209
			!ENGINE_set_DH(e, &cswift_dh) ||
210
#endif
211
			!ENGINE_set_destroy_function(e, cswift_destroy) ||
212 213 214 215 216
			!ENGINE_set_init_function(e, cswift_init) ||
			!ENGINE_set_finish_function(e, cswift_finish) ||
			!ENGINE_set_ctrl_function(e, cswift_ctrl) ||
			!ENGINE_set_cmd_defns(e, cswift_cmd_defns))
		return 0;
217

218
#ifndef OPENSSL_NO_RSA
219 220 221 222 223 224 225 226 227 228 229 230
	/* We know that the "PKCS1_SSLeay()" functions hook properly
	 * to the cswift-specific mod_exp and mod_exp_crt so we use
	 * those functions. NB: We don't use ENGINE_openssl() or
	 * anything "more generic" because something like the RSAref
	 * code may not hook properly, and if you own one of these
	 * cards then you have the right to do RSA operations on it
	 * anyway! */ 
	meth1 = RSA_PKCS1_SSLeay();
	cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
	cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
	cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
	cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
231
#endif
232

233
#ifndef OPENSSL_NO_DH
234 235 236 237
	/* Much the same for Diffie-Hellman */
	meth2 = DH_OpenSSL();
	cswift_dh.generate_key = meth2->generate_key;
	cswift_dh.compute_key = meth2->compute_key;
238
#endif
239 240

	/* Ensure the cswift error handling is set up */
241
	ERR_load_CSWIFT_strings();
242 243 244
	return 1;
	}

245
static ENGINE *engine_cswift(void)
246 247 248 249 250 251 252 253 254
	{
	ENGINE *ret = ENGINE_new();
	if(!ret)
		return NULL;
	if(!bind_helper(ret))
		{
		ENGINE_free(ret);
		return NULL;
		}
G
Geoff Thorpe 已提交
255
	return ret;
256 257
	}

258 259 260 261 262 263 264 265 266 267
void ENGINE_load_cswift(void)
	{
	/* Copied from eng_[openssl|dyn].c */
	ENGINE *toadd = engine_cswift();
	if(!toadd) return;
	ENGINE_add(toadd);
	ENGINE_free(toadd);
	ERR_clear_error();
	}

268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
/* This is a process-global DSO handle used for loading and unloading
 * the CryptoSwift library. NB: This is only set (or unset) during an
 * init() or finish() call (reference counts permitting) and they're
 * operating with global locks, so this should be thread-safe
 * implicitly. */
static DSO *cswift_dso = NULL;

/* These are the function pointers that are (un)set when the library has
 * successfully (un)loaded. */
t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL;
t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL;
t_swSimpleRequest *p_CSwift_SimpleRequest = NULL;
t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL;

/* Used in the DSO operations. */
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
static const char *CSWIFT_LIBNAME = NULL;
static const char *get_CSWIFT_LIBNAME(void)
	{
	if(CSWIFT_LIBNAME)
		return CSWIFT_LIBNAME;
	return "swift";
	}
static void free_CSWIFT_LIBNAME(void)
	{
	if(CSWIFT_LIBNAME)
		OPENSSL_free((void*)CSWIFT_LIBNAME);
	CSWIFT_LIBNAME = NULL;
	}
static long set_CSWIFT_LIBNAME(const char *name)
	{
	free_CSWIFT_LIBNAME();
	return (((CSWIFT_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
	}
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
static const char *CSWIFT_F1 = "swAcquireAccContext";
static const char *CSWIFT_F2 = "swAttachKeyParam";
static const char *CSWIFT_F3 = "swSimpleRequest";
static const char *CSWIFT_F4 = "swReleaseAccContext";


/* CryptoSwift library functions and mechanics - these are used by the
 * higher-level functions further down. NB: As and where there's no
 * error checking, take a look lower down where these functions are
 * called, the checking and error handling is probably down there. */

/* utility function to obtain a context */
static int get_context(SW_CONTEXT_HANDLE *hac)
	{
        SW_STATUS status;
 
        status = p_CSwift_AcquireAccContext(hac);
        if(status != SW_OK)
                return 0;
        return 1;
	}
 
/* similarly to release one. */
static void release_context(SW_CONTEXT_HANDLE hac)
	{
        p_CSwift_ReleaseAccContext(hac);
	}

329 330 331
/* Destructor (complements the "ENGINE_cswift()" constructor) */
static int cswift_destroy(ENGINE *e)
	{
332
	free_CSWIFT_LIBNAME();
333
	ERR_unload_CSWIFT_strings();
334 335 336
	return 1;
	}

337
/* (de)initialisation functions. */
G
Geoff Thorpe 已提交
338
static int cswift_init(ENGINE *e)
339 340 341 342 343 344 345 346 347
	{
        SW_CONTEXT_HANDLE hac;
        t_swAcquireAccContext *p1;
        t_swAttachKeyParam *p2;
        t_swSimpleRequest *p3;
        t_swReleaseAccContext *p4;

	if(cswift_dso != NULL)
		{
348
		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_ALREADY_LOADED);
349 350 351
		goto err;
		}
	/* Attempt to load libswift.so/swift.dll/whatever. */
352
	cswift_dso = DSO_load(NULL, get_CSWIFT_LIBNAME(), NULL, 0);
353 354
	if(cswift_dso == NULL)
		{
355
		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
356 357 358 359 360 361 362 363 364 365 366
		goto err;
		}
	if(!(p1 = (t_swAcquireAccContext *)
				DSO_bind_func(cswift_dso, CSWIFT_F1)) ||
			!(p2 = (t_swAttachKeyParam *)
				DSO_bind_func(cswift_dso, CSWIFT_F2)) ||
			!(p3 = (t_swSimpleRequest *)
				DSO_bind_func(cswift_dso, CSWIFT_F3)) ||
			!(p4 = (t_swReleaseAccContext *)
				DSO_bind_func(cswift_dso, CSWIFT_F4)))
		{
367
		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
368 369 370 371 372 373 374 375 376 377 378
		goto err;
		}
	/* Copy the pointers */
	p_CSwift_AcquireAccContext = p1;
	p_CSwift_AttachKeyParam = p2;
	p_CSwift_SimpleRequest = p3;
	p_CSwift_ReleaseAccContext = p4;
	/* Try and get a context - if not, we may have a DSO but no
	 * accelerator! */
	if(!get_context(&hac))
		{
379
		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_UNIT_FAILURE);
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
		goto err;
		}
	release_context(hac);
	/* Everything's fine. */
	return 1;
err:
	if(cswift_dso)
		DSO_free(cswift_dso);
	p_CSwift_AcquireAccContext = NULL;
	p_CSwift_AttachKeyParam = NULL;
	p_CSwift_SimpleRequest = NULL;
	p_CSwift_ReleaseAccContext = NULL;
	return 0;
	}

G
Geoff Thorpe 已提交
395
static int cswift_finish(ENGINE *e)
396
	{
397
	free_CSWIFT_LIBNAME();
398 399
	if(cswift_dso == NULL)
		{
400
		CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_NOT_LOADED);
401 402 403 404
		return 0;
		}
	if(!DSO_free(cswift_dso))
		{
405
		CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_UNIT_FAILURE);
406 407 408 409 410 411 412 413 414 415
		return 0;
		}
	cswift_dso = NULL;
	p_CSwift_AcquireAccContext = NULL;
	p_CSwift_AttachKeyParam = NULL;
	p_CSwift_SimpleRequest = NULL;
	p_CSwift_ReleaseAccContext = NULL;
	return 1;
	}

G
Geoff Thorpe 已提交
416 417 418 419 420 421 422 423
static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
	{
	int initialised = ((cswift_dso == NULL) ? 0 : 1);
	switch(cmd)
		{
	case CSWIFT_CMD_SO_PATH:
		if(p == NULL)
			{
424
			CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,ERR_R_PASSED_NULL_PARAMETER);
G
Geoff Thorpe 已提交
425 426 427 428
			return 0;
			}
		if(initialised)
			{
429
			CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_ALREADY_LOADED);
G
Geoff Thorpe 已提交
430 431
			return 0;
			}
432
		return set_CSWIFT_LIBNAME((const char *)p);
G
Geoff Thorpe 已提交
433 434 435
	default:
		break;
		}
436
	CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED);
G
Geoff Thorpe 已提交
437 438 439
	return 0;
	}

440
/* Un petit mod_exp */
441
static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
			const BIGNUM *m, BN_CTX *ctx)
	{
	/* I need somewhere to store temporary serialised values for
	 * use with the CryptoSwift API calls. A neat cheat - I'll use
	 * BIGNUMs from the BN_CTX but access their arrays directly as
	 * byte arrays <grin>. This way I don't have to clean anything
	 * up. */
	BIGNUM *modulus;
	BIGNUM *exponent;
	BIGNUM *argument;
	BIGNUM *result;
	SW_STATUS sw_status;
	SW_LARGENUMBER arg, res;
	SW_PARAM sw_param;
	SW_CONTEXT_HANDLE hac;
	int to_return, acquired;
 
	modulus = exponent = argument = result = NULL;
	to_return = 0; /* expect failure */
	acquired = 0;
 
	if(!get_context(&hac))
		{
465
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_UNIT_FAILURE);
466 467 468 469
		goto err;
		}
	acquired = 1;
	/* Prepare the params */
B
Bodo Möller 已提交
470
	BN_CTX_start(ctx);
471 472 473 474
	modulus = BN_CTX_get(ctx);
	exponent = BN_CTX_get(ctx);
	argument = BN_CTX_get(ctx);
	result = BN_CTX_get(ctx);
B
Bodo Möller 已提交
475
	if(!result)
476
		{
477
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_CTX_FULL);
478 479 480 481 482
		goto err;
		}
	if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) ||
		!bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top))
		{
483
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_EXPAND_FAIL);
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
		goto err;
		}
	sw_param.type = SW_ALG_EXP;
	sw_param.up.exp.modulus.nbytes = BN_bn2bin(m,
		(unsigned char *)modulus->d);
	sw_param.up.exp.modulus.value = (unsigned char *)modulus->d;
	sw_param.up.exp.exponent.nbytes = BN_bn2bin(p,
		(unsigned char *)exponent->d);
	sw_param.up.exp.exponent.value = (unsigned char *)exponent->d;
	/* Attach the key params */
	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
	switch(sw_status)
		{
	case SW_OK:
		break;
	case SW_ERR_INPUT_SIZE:
500
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BAD_KEY_SIZE);
501 502 503 504
		goto err;
	default:
		{
		char tmpbuf[20];
505
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		}
		goto err;
		}
	/* Prepare the argument and response */
	arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
	arg.value = (unsigned char *)argument->d;
	res.nbytes = BN_num_bytes(m);
	memset(result->d, 0, res.nbytes);
	res.value = (unsigned char *)result->d;
	/* Perform the operation */
	if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1,
		&res, 1)) != SW_OK)
		{
		char tmpbuf[20];
522
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
523 524 525 526 527 528 529 530 531 532
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		goto err;
		}
	/* Convert the response */
	BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
	to_return = 1;
err:
	if(acquired)
		release_context(hac);
B
Bodo Möller 已提交
533
	BN_CTX_end(ctx);
534 535 536 537
	return to_return;
	}

/* Un petit mod_exp chinois */
538
static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
			const BIGNUM *q, const BIGNUM *dmp1,
			const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
	{
	SW_STATUS sw_status;
	SW_LARGENUMBER arg, res;
	SW_PARAM sw_param;
	SW_CONTEXT_HANDLE hac;
	BIGNUM *rsa_p = NULL;
	BIGNUM *rsa_q = NULL;
	BIGNUM *rsa_dmp1 = NULL;
	BIGNUM *rsa_dmq1 = NULL;
	BIGNUM *rsa_iqmp = NULL;
	BIGNUM *argument = NULL;
	BIGNUM *result = NULL;
	int to_return = 0; /* expect failure */
	int acquired = 0;
 
	if(!get_context(&hac))
		{
558
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_UNIT_FAILURE);
559 560 561 562
		goto err;
		}
	acquired = 1;
	/* Prepare the params */
B
Bodo Möller 已提交
563
	BN_CTX_start(ctx);
564 565 566 567 568 569 570
	rsa_p = BN_CTX_get(ctx);
	rsa_q = BN_CTX_get(ctx);
	rsa_dmp1 = BN_CTX_get(ctx);
	rsa_dmq1 = BN_CTX_get(ctx);
	rsa_iqmp = BN_CTX_get(ctx);
	argument = BN_CTX_get(ctx);
	result = BN_CTX_get(ctx);
B
Bodo Möller 已提交
571
	if(!result)
572
		{
573
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_CTX_FULL);
574 575 576 577 578 579 580 581 582
		goto err;
		}
	if(!bn_wexpand(rsa_p, p->top) || !bn_wexpand(rsa_q, q->top) ||
			!bn_wexpand(rsa_dmp1, dmp1->top) ||
			!bn_wexpand(rsa_dmq1, dmq1->top) ||
			!bn_wexpand(rsa_iqmp, iqmp->top) ||
			!bn_wexpand(argument, a->top) ||
			!bn_wexpand(result, p->top + q->top))
		{
583
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
		goto err;
		}
	sw_param.type = SW_ALG_CRT;
	sw_param.up.crt.p.nbytes = BN_bn2bin(p, (unsigned char *)rsa_p->d);
	sw_param.up.crt.p.value = (unsigned char *)rsa_p->d;
	sw_param.up.crt.q.nbytes = BN_bn2bin(q, (unsigned char *)rsa_q->d);
	sw_param.up.crt.q.value = (unsigned char *)rsa_q->d;
	sw_param.up.crt.dmp1.nbytes = BN_bn2bin(dmp1,
		(unsigned char *)rsa_dmp1->d);
	sw_param.up.crt.dmp1.value = (unsigned char *)rsa_dmp1->d;
	sw_param.up.crt.dmq1.nbytes = BN_bn2bin(dmq1,
		(unsigned char *)rsa_dmq1->d);
	sw_param.up.crt.dmq1.value = (unsigned char *)rsa_dmq1->d;
	sw_param.up.crt.iqmp.nbytes = BN_bn2bin(iqmp,
		(unsigned char *)rsa_iqmp->d);
	sw_param.up.crt.iqmp.value = (unsigned char *)rsa_iqmp->d;
	/* Attach the key params */
	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
	switch(sw_status)
		{
	case SW_OK:
		break;
	case SW_ERR_INPUT_SIZE:
607
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BAD_KEY_SIZE);
608 609 610 611
		goto err;
	default:
		{
		char tmpbuf[20];
612
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		}
		goto err;
		}
	/* Prepare the argument and response */
	arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
	arg.value = (unsigned char *)argument->d;
	res.nbytes = 2 * BN_num_bytes(p);
	memset(result->d, 0, res.nbytes);
	res.value = (unsigned char *)result->d;
	/* Perform the operation */
	if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1,
		&res, 1)) != SW_OK)
		{
		char tmpbuf[20];
629
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
630 631 632 633 634 635 636 637 638 639
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		goto err;
		}
	/* Convert the response */
	BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
	to_return = 1;
err:
	if(acquired)
		release_context(hac);
B
Bodo Möller 已提交
640
	BN_CTX_end(ctx);
641 642 643
	return to_return;
	}
 
644
#ifndef OPENSSL_NO_RSA
645
static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
646 647 648 649 650 651 652 653
	{
	BN_CTX *ctx;
	int to_return = 0;

	if((ctx = BN_CTX_new()) == NULL)
		goto err;
	if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
		{
654
		CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP,CSWIFT_R_MISSING_KEY_COMPONENTS);
655 656 657 658 659 660 661 662 663
		goto err;
		}
	to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
		rsa->dmq1, rsa->iqmp, ctx);
err:
	if(ctx)
		BN_CTX_free(ctx);
	return to_return;
	}
664
#endif
665 666

/* This function is aliased to mod_exp (with the mont stuff dropped). */
667
static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
668 669 670 671 672
		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
	{
	return cswift_mod_exp(r, a, p, m, ctx);
	}

673
#ifndef OPENSSL_NO_DSA
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693
static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
	{
	SW_CONTEXT_HANDLE hac;
	SW_PARAM sw_param;
	SW_STATUS sw_status;
	SW_LARGENUMBER arg, res;
	unsigned char *ptr;
	BN_CTX *ctx;
	BIGNUM *dsa_p = NULL;
	BIGNUM *dsa_q = NULL;
	BIGNUM *dsa_g = NULL;
	BIGNUM *dsa_key = NULL;
	BIGNUM *result = NULL;
	DSA_SIG *to_return = NULL;
	int acquired = 0;

	if((ctx = BN_CTX_new()) == NULL)
		goto err;
	if(!get_context(&hac))
		{
694
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_UNIT_FAILURE);
695 696 697 698
		goto err;
		}
	acquired = 1;
	/* Prepare the params */
B
Bodo Möller 已提交
699
	BN_CTX_start(ctx);
700 701 702 703 704
	dsa_p = BN_CTX_get(ctx);
	dsa_q = BN_CTX_get(ctx);
	dsa_g = BN_CTX_get(ctx);
	dsa_key = BN_CTX_get(ctx);
	result = BN_CTX_get(ctx);
B
Bodo Möller 已提交
705
	if(!result)
706
		{
707
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_CTX_FULL);
708 709 710 711 712 713 714 715
		goto err;
		}
	if(!bn_wexpand(dsa_p, dsa->p->top) ||
			!bn_wexpand(dsa_q, dsa->q->top) ||
			!bn_wexpand(dsa_g, dsa->g->top) ||
			!bn_wexpand(dsa_key, dsa->priv_key->top) ||
			!bn_wexpand(result, dsa->p->top))
		{
716
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_EXPAND_FAIL);
717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738
		goto err;
		}
	sw_param.type = SW_ALG_DSA;
	sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
				(unsigned char *)dsa_p->d);
	sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
	sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
				(unsigned char *)dsa_q->d);
	sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
	sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
				(unsigned char *)dsa_g->d);
	sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
	sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key,
				(unsigned char *)dsa_key->d);
	sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
	/* Attach the key params */
	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
	switch(sw_status)
		{
	case SW_OK:
		break;
	case SW_ERR_INPUT_SIZE:
739
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BAD_KEY_SIZE);
740 741 742 743
		goto err;
	default:
		{
		char tmpbuf[20];
744
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		}
		goto err;
		}
	/* Prepare the argument and response */
	arg.nbytes = dlen;
	arg.value = (unsigned char *)dgst;
	res.nbytes = BN_num_bytes(dsa->p);
	memset(result->d, 0, res.nbytes);
	res.value = (unsigned char *)result->d;
	/* Perform the operation */
	sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1,
		&res, 1);
	if(sw_status != SW_OK)
		{
		char tmpbuf[20];
762
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		goto err;
		}
	/* Convert the response */
	ptr = (unsigned char *)result->d;
	if((to_return = DSA_SIG_new()) == NULL)
		goto err;
	to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL);
	to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL);

err:
	if(acquired)
		release_context(hac);
	if(ctx)
B
Bodo Möller 已提交
778 779
		{
		BN_CTX_end(ctx);
780
		BN_CTX_free(ctx);
B
Bodo Möller 已提交
781
		}
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
	return to_return;
	}

static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
				DSA_SIG *sig, DSA *dsa)
	{
	SW_CONTEXT_HANDLE hac;
	SW_PARAM sw_param;
	SW_STATUS sw_status;
	SW_LARGENUMBER arg[2], res;
	unsigned long sig_result;
	BN_CTX *ctx;
	BIGNUM *dsa_p = NULL;
	BIGNUM *dsa_q = NULL;
	BIGNUM *dsa_g = NULL;
	BIGNUM *dsa_key = NULL;
	BIGNUM *argument = NULL;
	int to_return = -1;
	int acquired = 0;

	if((ctx = BN_CTX_new()) == NULL)
		goto err;
	if(!get_context(&hac))
		{
806
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_UNIT_FAILURE);
807 808 809 810
		goto err;
		}
	acquired = 1;
	/* Prepare the params */
B
Bodo Möller 已提交
811
	BN_CTX_start(ctx);
812 813 814 815 816
	dsa_p = BN_CTX_get(ctx);
	dsa_q = BN_CTX_get(ctx);
	dsa_g = BN_CTX_get(ctx);
	dsa_key = BN_CTX_get(ctx);
	argument = BN_CTX_get(ctx);
B
Bodo Möller 已提交
817
	if(!argument)
818
		{
819
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_CTX_FULL);
820 821 822 823 824 825 826 827
		goto err;
		}
	if(!bn_wexpand(dsa_p, dsa->p->top) ||
			!bn_wexpand(dsa_q, dsa->q->top) ||
			!bn_wexpand(dsa_g, dsa->g->top) ||
			!bn_wexpand(dsa_key, dsa->pub_key->top) ||
			!bn_wexpand(argument, 40))
		{
828
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_EXPAND_FAIL);
829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850
		goto err;
		}
	sw_param.type = SW_ALG_DSA;
	sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
				(unsigned char *)dsa_p->d);
	sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
	sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
				(unsigned char *)dsa_q->d);
	sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
	sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
				(unsigned char *)dsa_g->d);
	sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
	sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key,
				(unsigned char *)dsa_key->d);
	sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
	/* Attach the key params */
	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
	switch(sw_status)
		{
	case SW_OK:
		break;
	case SW_ERR_INPUT_SIZE:
851
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BAD_KEY_SIZE);
852 853 854 855
		goto err;
	default:
		{
		char tmpbuf[20];
856
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		}
		goto err;
		}
	/* Prepare the argument and response */
	arg[0].nbytes = dgst_len;
	arg[0].value = (unsigned char *)dgst;
	arg[1].nbytes = 40;
	arg[1].value = (unsigned char *)argument->d;
	memset(arg[1].value, 0, 40);
	BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r));
	BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s));
	res.nbytes = 4; /* unsigned long */
	res.value = (unsigned char *)(&sig_result);
	/* Perform the operation */
	sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2,
		&res, 1);
	if(sw_status != SW_OK)
		{
		char tmpbuf[20];
878
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
879 880 881 882 883 884 885 886 887 888 889
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		goto err;
		}
	/* Convert the response */
	to_return = ((sig_result == 0) ? 0 : 1);

err:
	if(acquired)
		release_context(hac);
	if(ctx)
B
Bodo Möller 已提交
890 891
		{
		BN_CTX_end(ctx);
892
		BN_CTX_free(ctx);
B
Bodo Möller 已提交
893
		}
894 895
	return to_return;
	}
896
#endif
897

898
#ifndef OPENSSL_NO_DH
899
/* This function is aliased to mod_exp (with the dh and mont dropped). */
R
Richard Levitte 已提交
900 901
static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
		const BIGNUM *a, const BIGNUM *p,
902 903 904 905
		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
	{
	return cswift_mod_exp(r, a, p, m, ctx);
	}
906
#endif
907

908 909 910 911 912 913 914 915 916 917 918 919 920 921 922
/* This stuff is needed if this ENGINE is being compiled into a self-contained
 * shared-library. */
#ifdef ENGINE_DYNAMIC_SUPPORT
static int bind_fn(ENGINE *e, const char *id)
	{
	if(id && (strcmp(id, engine_cswift_id) != 0))
		return 0;
	if(!bind_helper(e))
		return 0;
	return 1;
	}       
IMPLEMENT_DYNAMIC_CHECK_FN()
IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
#endif /* ENGINE_DYNAMIC_SUPPORT */

923 924
#endif /* !OPENSSL_NO_HW_CSWIFT */
#endif /* !OPENSSL_NO_HW */