11573Srgrimes/* crypto/engine/hw_cswift.c */ 21573Srgrimes/* 31573Srgrimes * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project 41573Srgrimes * 2000. 51573Srgrimes */ 61573Srgrimes/* ==================================================================== 71573Srgrimes * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. 81573Srgrimes * 91573Srgrimes * Redistribution and use in source and binary forms, with or without 101573Srgrimes * modification, are permitted provided that the following conditions 111573Srgrimes * are met: 121573Srgrimes * 131573Srgrimes * 1. Redistributions of source code must retain the above copyright 141573Srgrimes * notice, this list of conditions and the following disclaimer. 151573Srgrimes * 161573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 171573Srgrimes * notice, this list of conditions and the following disclaimer in 181573Srgrimes * the documentation and/or other materials provided with the 191573Srgrimes * distribution. 201573Srgrimes * 211573Srgrimes * 3. All advertising materials mentioning features or use of this 221573Srgrimes * software must display the following acknowledgment: 231573Srgrimes * "This product includes software developed by the OpenSSL Project 241573Srgrimes * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 251573Srgrimes * 261573Srgrimes * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 271573Srgrimes * endorse or promote products derived from this software without 281573Srgrimes * prior written permission. For written permission, please contact 291573Srgrimes * licensing@OpenSSL.org. 301573Srgrimes * 311573Srgrimes * 5. Products derived from this software may not be called "OpenSSL" 321573Srgrimes * nor may "OpenSSL" appear in their names without prior written 331573Srgrimes * permission of the OpenSSL Project. 341573Srgrimes * 351573Srgrimes * 6. Redistributions of any form whatsoever must retain the following 361573Srgrimes * acknowledgment: 371573Srgrimes * "This product includes software developed by the OpenSSL Project 3823662Speter * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 391573Srgrimes * 4092986Sobrien * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4192986Sobrien * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 421573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4391697Stegge * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 441573Srgrimes * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 451573Srgrimes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4618516Sphk * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4791697Stegge * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 481573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4991697Stegge * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 501573Srgrimes * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5191697Stegge * OF THE POSSIBILITY OF SUCH DAMAGE. 5291697Stegge * ==================================================================== 5391697Stegge * 5491697Stegge * This product includes cryptographic software written by Eric Young 5591697Stegge * (eay@cryptsoft.com). This product includes software written by Tim 5691697Stegge * Hudson (tjh@cryptsoft.com). 5791697Stegge * 5823662Speter */ 5923662Speter 601573Srgrimes#include <stdio.h> 611573Srgrimes#include <string.h> 621573Srgrimes#include <openssl/crypto.h> 631573Srgrimes#include <openssl/buffer.h> 641573Srgrimes#include <openssl/dso.h> 651573Srgrimes#include <openssl/engine.h> 661573Srgrimes#ifndef OPENSSL_NO_RSA 671573Srgrimes# include <openssl/rsa.h> 6892889Sobrien#endif 691573Srgrimes#ifndef OPENSSL_NO_DSA 7091697Stegge# include <openssl/dsa.h> 711573Srgrimes#endif 721573Srgrimes#ifndef OPENSSL_NO_DH 7391697Stegge# include <openssl/dh.h> 7491697Stegge#endif 7591697Stegge#include <openssl/rand.h> 7691697Stegge#include <openssl/bn.h> 7791697Stegge 781573Srgrimes#ifndef OPENSSL_NO_HW 7991697Stegge# ifndef OPENSSL_NO_HW_CSWIFT 8091697Stegge 8191697Stegge/* 8291697Stegge * Attribution notice: Rainbow have generously allowed me to reproduce the 8391697Stegge * necessary definitions here from their API. This means the support can 8491697Stegge * build independently of whether application builders have the API or 8591697Stegge * hardware. This will allow developers to easily produce software that has 8691697Stegge * latent hardware support for any users that have accelerators installed, 8791697Stegge * without the developers themselves needing anything extra. I have only 881573Srgrimes * clipped the parts from the CryptoSwift header files that are (or seem) 891573Srgrimes * relevant to the CryptoSwift support code. This is simply to keep the file 901573Srgrimes * sizes reasonable. [Geoff] 911573Srgrimes */ 921573Srgrimes# ifdef FLAT_INC 9391697Stegge# include "cswift.h" 941573Srgrimes# else 951573Srgrimes# include "vendor_defns/cswift.h" 96# endif 97 98# define CSWIFT_LIB_NAME "cswift engine" 99# include "e_cswift_err.c" 100 101# define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) 102 103static int cswift_destroy(ENGINE *e); 104static int cswift_init(ENGINE *e); 105static int cswift_finish(ENGINE *e); 106static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); 107# ifndef OPENSSL_NO_RSA 108static int cswift_bn_32copy(SW_LARGENUMBER *out, const BIGNUM *in); 109# endif 110 111/* BIGNUM stuff */ 112static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 113 const BIGNUM *m, BN_CTX *ctx); 114# ifndef OPENSSL_NO_RSA 115static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 116 const BIGNUM *q, const BIGNUM *dmp1, 117 const BIGNUM *dmq1, const BIGNUM *iqmp, 118 BN_CTX *ctx); 119# endif 120 121# ifndef OPENSSL_NO_RSA 122/* RSA stuff */ 123static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, 124 BN_CTX *ctx); 125/* This function is aliased to mod_exp (with the mont stuff dropped). */ 126static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 127 const BIGNUM *m, BN_CTX *ctx, 128 BN_MONT_CTX *m_ctx); 129# endif 130 131# ifndef OPENSSL_NO_DSA 132/* DSA stuff */ 133static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, 134 DSA *dsa); 135static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, 136 DSA_SIG *sig, DSA *dsa); 137# endif 138 139# ifndef OPENSSL_NO_DH 140/* DH stuff */ 141/* This function is alised to mod_exp (with the DH and mont dropped). */ 142static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r, 143 const BIGNUM *a, const BIGNUM *p, 144 const BIGNUM *m, BN_CTX *ctx, 145 BN_MONT_CTX *m_ctx); 146# endif 147 148/* RAND stuff */ 149static int cswift_rand_bytes(unsigned char *buf, int num); 150static int cswift_rand_status(void); 151 152/* The definitions for control commands specific to this engine */ 153# define CSWIFT_CMD_SO_PATH ENGINE_CMD_BASE 154static const ENGINE_CMD_DEFN cswift_cmd_defns[] = { 155 {CSWIFT_CMD_SO_PATH, 156 "SO_PATH", 157 "Specifies the path to the 'cswift' shared library", 158 ENGINE_CMD_FLAG_STRING}, 159 {0, NULL, NULL, 0} 160}; 161 162# ifndef OPENSSL_NO_RSA 163/* Our internal RSA_METHOD that we provide pointers to */ 164static RSA_METHOD cswift_rsa = { 165 "CryptoSwift RSA method", 166 NULL, 167 NULL, 168 NULL, 169 NULL, 170 cswift_rsa_mod_exp, 171 cswift_mod_exp_mont, 172 NULL, 173 NULL, 174 0, 175 NULL, 176 NULL, 177 NULL, 178 NULL 179}; 180# endif 181 182# ifndef OPENSSL_NO_DSA 183/* Our internal DSA_METHOD that we provide pointers to */ 184static DSA_METHOD cswift_dsa = { 185 "CryptoSwift DSA method", 186 cswift_dsa_sign, 187 NULL, /* dsa_sign_setup */ 188 cswift_dsa_verify, 189 NULL, /* dsa_mod_exp */ 190 NULL, /* bn_mod_exp */ 191 NULL, /* init */ 192 NULL, /* finish */ 193 0, /* flags */ 194 NULL, /* app_data */ 195 NULL, /* dsa_paramgen */ 196 NULL /* dsa_keygen */ 197}; 198# endif 199 200# ifndef OPENSSL_NO_DH 201/* Our internal DH_METHOD that we provide pointers to */ 202static DH_METHOD cswift_dh = { 203 "CryptoSwift DH method", 204 NULL, 205 NULL, 206 cswift_mod_exp_dh, 207 NULL, 208 NULL, 209 0, 210 NULL, 211 NULL 212}; 213# endif 214 215static RAND_METHOD cswift_random = { 216 /* "CryptoSwift RAND method", */ 217 NULL, 218 cswift_rand_bytes, 219 NULL, 220 NULL, 221 cswift_rand_bytes, 222 cswift_rand_status, 223}; 224 225/* Constants used when creating the ENGINE */ 226static const char *engine_cswift_id = "cswift"; 227static const char *engine_cswift_name = "CryptoSwift hardware engine support"; 228 229/* 230 * This internal function is used by ENGINE_cswift() and possibly by the 231 * "dynamic" ENGINE support too 232 */ 233static int bind_helper(ENGINE *e) 234{ 235# ifndef OPENSSL_NO_RSA 236 const RSA_METHOD *meth1; 237# endif 238# ifndef OPENSSL_NO_DH 239 const DH_METHOD *meth2; 240# endif 241 if (!ENGINE_set_id(e, engine_cswift_id) || 242 !ENGINE_set_name(e, engine_cswift_name) || 243# ifndef OPENSSL_NO_RSA 244 !ENGINE_set_RSA(e, &cswift_rsa) || 245# endif 246# ifndef OPENSSL_NO_DSA 247 !ENGINE_set_DSA(e, &cswift_dsa) || 248# endif 249# ifndef OPENSSL_NO_DH 250 !ENGINE_set_DH(e, &cswift_dh) || 251# endif 252 !ENGINE_set_RAND(e, &cswift_random) || 253 !ENGINE_set_destroy_function(e, cswift_destroy) || 254 !ENGINE_set_init_function(e, cswift_init) || 255 !ENGINE_set_finish_function(e, cswift_finish) || 256 !ENGINE_set_ctrl_function(e, cswift_ctrl) || 257 !ENGINE_set_cmd_defns(e, cswift_cmd_defns)) 258 return 0; 259 260# ifndef OPENSSL_NO_RSA 261 /* 262 * We know that the "PKCS1_SSLeay()" functions hook properly to the 263 * cswift-specific mod_exp and mod_exp_crt so we use those functions. NB: 264 * We don't use ENGINE_openssl() or anything "more generic" because 265 * something like the RSAref code may not hook properly, and if you own 266 * one of these cards then you have the right to do RSA operations on it 267 * anyway! 268 */ 269 meth1 = RSA_PKCS1_SSLeay(); 270 cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc; 271 cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec; 272 cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc; 273 cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec; 274# endif 275 276# ifndef OPENSSL_NO_DH 277 /* Much the same for Diffie-Hellman */ 278 meth2 = DH_OpenSSL(); 279 cswift_dh.generate_key = meth2->generate_key; 280 cswift_dh.compute_key = meth2->compute_key; 281# endif 282 283 /* Ensure the cswift error handling is set up */ 284 ERR_load_CSWIFT_strings(); 285 return 1; 286} 287 288# ifdef OPENSSL_NO_DYNAMIC_ENGINE 289static ENGINE *engine_cswift(void) 290{ 291 ENGINE *ret = ENGINE_new(); 292 if (!ret) 293 return NULL; 294 if (!bind_helper(ret)) { 295 ENGINE_free(ret); 296 return NULL; 297 } 298 return ret; 299} 300 301void ENGINE_load_cswift(void) 302{ 303 /* Copied from eng_[openssl|dyn].c */ 304 ENGINE *toadd = engine_cswift(); 305 if (!toadd) 306 return; 307 ENGINE_add(toadd); 308 ENGINE_free(toadd); 309 ERR_clear_error(); 310} 311# endif 312 313/* 314 * This is a process-global DSO handle used for loading and unloading the 315 * CryptoSwift library. NB: This is only set (or unset) during an init() or 316 * finish() call (reference counts permitting) and they're operating with 317 * global locks, so this should be thread-safe implicitly. 318 */ 319static DSO *cswift_dso = NULL; 320 321/* 322 * These are the function pointers that are (un)set when the library has 323 * successfully (un)loaded. 324 */ 325t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL; 326t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL; 327t_swSimpleRequest *p_CSwift_SimpleRequest = NULL; 328t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL; 329 330/* Used in the DSO operations. */ 331static const char *CSWIFT_LIBNAME = NULL; 332static const char *get_CSWIFT_LIBNAME(void) 333{ 334 if (CSWIFT_LIBNAME) 335 return CSWIFT_LIBNAME; 336 return "swift"; 337} 338 339static void free_CSWIFT_LIBNAME(void) 340{ 341 if (CSWIFT_LIBNAME) 342 OPENSSL_free((void *)CSWIFT_LIBNAME); 343 CSWIFT_LIBNAME = NULL; 344} 345 346static long set_CSWIFT_LIBNAME(const char *name) 347{ 348 free_CSWIFT_LIBNAME(); 349 return (((CSWIFT_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); 350} 351 352static const char *CSWIFT_F1 = "swAcquireAccContext"; 353static const char *CSWIFT_F2 = "swAttachKeyParam"; 354static const char *CSWIFT_F3 = "swSimpleRequest"; 355static const char *CSWIFT_F4 = "swReleaseAccContext"; 356 357/* 358 * CryptoSwift library functions and mechanics - these are used by the 359 * higher-level functions further down. NB: As and where there's no error 360 * checking, take a look lower down where these functions are called, the 361 * checking and error handling is probably down there. 362 */ 363 364/* utility function to obtain a context */ 365static int get_context(SW_CONTEXT_HANDLE *hac) 366{ 367 SW_STATUS status; 368 369 status = p_CSwift_AcquireAccContext(hac); 370 if (status != SW_OK) 371 return 0; 372 return 1; 373} 374 375/* similarly to release one. */ 376static void release_context(SW_CONTEXT_HANDLE hac) 377{ 378 p_CSwift_ReleaseAccContext(hac); 379} 380 381/* Destructor (complements the "ENGINE_cswift()" constructor) */ 382static int cswift_destroy(ENGINE *e) 383{ 384 free_CSWIFT_LIBNAME(); 385 ERR_unload_CSWIFT_strings(); 386 return 1; 387} 388 389/* (de)initialisation functions. */ 390static int cswift_init(ENGINE *e) 391{ 392 SW_CONTEXT_HANDLE hac; 393 t_swAcquireAccContext *p1; 394 t_swAttachKeyParam *p2; 395 t_swSimpleRequest *p3; 396 t_swReleaseAccContext *p4; 397 398 if (cswift_dso != NULL) { 399 CSWIFTerr(CSWIFT_F_CSWIFT_INIT, CSWIFT_R_ALREADY_LOADED); 400 goto err; 401 } 402 /* Attempt to load libswift.so/swift.dll/whatever. */ 403 cswift_dso = DSO_load(NULL, get_CSWIFT_LIBNAME(), NULL, 0); 404 if (cswift_dso == NULL) { 405 CSWIFTerr(CSWIFT_F_CSWIFT_INIT, CSWIFT_R_NOT_LOADED); 406 goto err; 407 } 408 if (!(p1 = (t_swAcquireAccContext *) 409 DSO_bind_func(cswift_dso, CSWIFT_F1)) || 410 !(p2 = (t_swAttachKeyParam *) 411 DSO_bind_func(cswift_dso, CSWIFT_F2)) || 412 !(p3 = (t_swSimpleRequest *) 413 DSO_bind_func(cswift_dso, CSWIFT_F3)) || 414 !(p4 = (t_swReleaseAccContext *) 415 DSO_bind_func(cswift_dso, CSWIFT_F4))) { 416 CSWIFTerr(CSWIFT_F_CSWIFT_INIT, CSWIFT_R_NOT_LOADED); 417 goto err; 418 } 419 /* Copy the pointers */ 420 p_CSwift_AcquireAccContext = p1; 421 p_CSwift_AttachKeyParam = p2; 422 p_CSwift_SimpleRequest = p3; 423 p_CSwift_ReleaseAccContext = p4; 424 /* 425 * Try and get a context - if not, we may have a DSO but no accelerator! 426 */ 427 if (!get_context(&hac)) { 428 CSWIFTerr(CSWIFT_F_CSWIFT_INIT, CSWIFT_R_UNIT_FAILURE); 429 goto err; 430 } 431 release_context(hac); 432 /* Everything's fine. */ 433 return 1; 434 err: 435 if (cswift_dso) { 436 DSO_free(cswift_dso); 437 cswift_dso = NULL; 438 } 439 p_CSwift_AcquireAccContext = NULL; 440 p_CSwift_AttachKeyParam = NULL; 441 p_CSwift_SimpleRequest = NULL; 442 p_CSwift_ReleaseAccContext = NULL; 443 return 0; 444} 445 446static int cswift_finish(ENGINE *e) 447{ 448 free_CSWIFT_LIBNAME(); 449 if (cswift_dso == NULL) { 450 CSWIFTerr(CSWIFT_F_CSWIFT_FINISH, CSWIFT_R_NOT_LOADED); 451 return 0; 452 } 453 if (!DSO_free(cswift_dso)) { 454 CSWIFTerr(CSWIFT_F_CSWIFT_FINISH, CSWIFT_R_UNIT_FAILURE); 455 return 0; 456 } 457 cswift_dso = NULL; 458 p_CSwift_AcquireAccContext = NULL; 459 p_CSwift_AttachKeyParam = NULL; 460 p_CSwift_SimpleRequest = NULL; 461 p_CSwift_ReleaseAccContext = NULL; 462 return 1; 463} 464 465static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) 466{ 467 int initialised = ((cswift_dso == NULL) ? 0 : 1); 468 switch (cmd) { 469 case CSWIFT_CMD_SO_PATH: 470 if (p == NULL) { 471 CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, ERR_R_PASSED_NULL_PARAMETER); 472 return 0; 473 } 474 if (initialised) { 475 CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, CSWIFT_R_ALREADY_LOADED); 476 return 0; 477 } 478 return set_CSWIFT_LIBNAME((const char *)p); 479 default: 480 break; 481 } 482 CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED); 483 return 0; 484} 485 486/* Un petit mod_exp */ 487static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 488 const BIGNUM *m, BN_CTX *ctx) 489{ 490 /* 491 * I need somewhere to store temporary serialised values for use with the 492 * CryptoSwift API calls. A neat cheat - I'll use BIGNUMs from the BN_CTX 493 * but access their arrays directly as byte arrays <grin>. This way I 494 * don't have to clean anything up. 495 */ 496 BIGNUM *modulus; 497 BIGNUM *exponent; 498 BIGNUM *argument; 499 BIGNUM *result; 500 SW_STATUS sw_status; 501 SW_LARGENUMBER arg, res; 502 SW_PARAM sw_param; 503 SW_CONTEXT_HANDLE hac; 504 int to_return, acquired; 505 506 modulus = exponent = argument = result = NULL; 507 to_return = 0; /* expect failure */ 508 acquired = 0; 509 510 if (!get_context(&hac)) { 511 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_UNIT_FAILURE); 512 goto err; 513 } 514 acquired = 1; 515 /* Prepare the params */ 516 BN_CTX_start(ctx); 517 modulus = BN_CTX_get(ctx); 518 exponent = BN_CTX_get(ctx); 519 argument = BN_CTX_get(ctx); 520 result = BN_CTX_get(ctx); 521 if (!result) { 522 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_BN_CTX_FULL); 523 goto err; 524 } 525 if (!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) || 526 !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top)) { 527 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_BN_EXPAND_FAIL); 528 goto err; 529 } 530 sw_param.type = SW_ALG_EXP; 531 sw_param.up.exp.modulus.nbytes = BN_bn2bin(m, 532 (unsigned char *)modulus->d); 533 sw_param.up.exp.modulus.value = (unsigned char *)modulus->d; 534 sw_param.up.exp.exponent.nbytes = BN_bn2bin(p, 535 (unsigned char *)exponent->d); 536 sw_param.up.exp.exponent.value = (unsigned char *)exponent->d; 537 /* Attach the key params */ 538 sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); 539 switch (sw_status) { 540 case SW_OK: 541 break; 542 case SW_ERR_INPUT_SIZE: 543 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_BAD_KEY_SIZE); 544 goto err; 545 default: 546 { 547 char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; 548 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_REQUEST_FAILED); 549 sprintf(tmpbuf, "%ld", sw_status); 550 ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); 551 } 552 goto err; 553 } 554 /* Prepare the argument and response */ 555 arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d); 556 arg.value = (unsigned char *)argument->d; 557 res.nbytes = BN_num_bytes(m); 558 memset(result->d, 0, res.nbytes); 559 res.value = (unsigned char *)result->d; 560 /* Perform the operation */ 561 if ((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1, 562 &res, 1)) != SW_OK) { 563 char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; 564 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_REQUEST_FAILED); 565 sprintf(tmpbuf, "%ld", sw_status); 566 ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); 567 goto err; 568 } 569 /* Convert the response */ 570 BN_bin2bn((unsigned char *)result->d, res.nbytes, r); 571 to_return = 1; 572 err: 573 if (acquired) 574 release_context(hac); 575 BN_CTX_end(ctx); 576 return to_return; 577} 578 579# ifndef OPENSSL_NO_RSA 580int cswift_bn_32copy(SW_LARGENUMBER *out, const BIGNUM *in) 581{ 582 int mod; 583 int numbytes = BN_num_bytes(in); 584 585 mod = 0; 586 while (((out->nbytes = (numbytes + mod)) % 32)) { 587 mod++; 588 } 589 out->value = (unsigned char *)OPENSSL_malloc(out->nbytes); 590 if (!out->value) { 591 return 0; 592 } 593 BN_bn2bin(in, &out->value[mod]); 594 if (mod) 595 memset(out->value, 0, mod); 596 597 return 1; 598} 599# endif 600 601# ifndef OPENSSL_NO_RSA 602/* Un petit mod_exp chinois */ 603static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 604 const BIGNUM *q, const BIGNUM *dmp1, 605 const BIGNUM *dmq1, const BIGNUM *iqmp, 606 BN_CTX *ctx) 607{ 608 SW_STATUS sw_status; 609 SW_LARGENUMBER arg, res; 610 SW_PARAM sw_param; 611 SW_CONTEXT_HANDLE hac; 612 BIGNUM *result = NULL; 613 BIGNUM *argument = NULL; 614 int to_return = 0; /* expect failure */ 615 int acquired = 0; 616 617 sw_param.up.crt.p.value = NULL; 618 sw_param.up.crt.q.value = NULL; 619 sw_param.up.crt.dmp1.value = NULL; 620 sw_param.up.crt.dmq1.value = NULL; 621 sw_param.up.crt.iqmp.value = NULL; 622 623 if (!get_context(&hac)) { 624 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_UNIT_FAILURE); 625 goto err; 626 } 627 acquired = 1; 628 629 /* Prepare the params */ 630 argument = BN_new(); 631 result = BN_new(); 632 if (!result || !argument) { 633 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_CTX_FULL); 634 goto err; 635 } 636 637 sw_param.type = SW_ALG_CRT; 638 /************************************************************************/ 639 /* 640 * 04/02/2003 641 */ 642 /* 643 * Modified by Frederic Giudicelli (deny-all.com) to overcome the 644 */ 645 /* 646 * limitation of cswift with values not a multiple of 32 647 */ 648 /************************************************************************/ 649 if (!cswift_bn_32copy(&sw_param.up.crt.p, p)) { 650 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); 651 goto err; 652 } 653 if (!cswift_bn_32copy(&sw_param.up.crt.q, q)) { 654 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); 655 goto err; 656 } 657 if (!cswift_bn_32copy(&sw_param.up.crt.dmp1, dmp1)) { 658 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); 659 goto err; 660 } 661 if (!cswift_bn_32copy(&sw_param.up.crt.dmq1, dmq1)) { 662 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); 663 goto err; 664 } 665 if (!cswift_bn_32copy(&sw_param.up.crt.iqmp, iqmp)) { 666 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); 667 goto err; 668 } 669 if (!bn_wexpand(argument, a->top) || !bn_wexpand(result, p->top + q->top)) { 670 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); 671 goto err; 672 } 673 674 /* Attach the key params */ 675 sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); 676 switch (sw_status) { 677 case SW_OK: 678 break; 679 case SW_ERR_INPUT_SIZE: 680 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BAD_KEY_SIZE); 681 goto err; 682 default: 683 { 684 char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; 685 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_REQUEST_FAILED); 686 sprintf(tmpbuf, "%ld", sw_status); 687 ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); 688 } 689 goto err; 690 } 691 /* Prepare the argument and response */ 692 arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d); 693 arg.value = (unsigned char *)argument->d; 694 res.nbytes = 2 * BN_num_bytes(p); 695 memset(result->d, 0, res.nbytes); 696 res.value = (unsigned char *)result->d; 697 /* Perform the operation */ 698 if ((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1, 699 &res, 1)) != SW_OK) { 700 char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; 701 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_REQUEST_FAILED); 702 sprintf(tmpbuf, "%ld", sw_status); 703 ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); 704 goto err; 705 } 706 /* Convert the response */ 707 BN_bin2bn((unsigned char *)result->d, res.nbytes, r); 708 to_return = 1; 709 err: 710 if (sw_param.up.crt.p.value) 711 OPENSSL_free(sw_param.up.crt.p.value); 712 if (sw_param.up.crt.q.value) 713 OPENSSL_free(sw_param.up.crt.q.value); 714 if (sw_param.up.crt.dmp1.value) 715 OPENSSL_free(sw_param.up.crt.dmp1.value); 716 if (sw_param.up.crt.dmq1.value) 717 OPENSSL_free(sw_param.up.crt.dmq1.value); 718 if (sw_param.up.crt.iqmp.value) 719 OPENSSL_free(sw_param.up.crt.iqmp.value); 720 if (result) 721 BN_free(result); 722 if (argument) 723 BN_free(argument); 724 if (acquired) 725 release_context(hac); 726 return to_return; 727} 728# endif 729 730# ifndef OPENSSL_NO_RSA 731static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, 732 BN_CTX *ctx) 733{ 734 int to_return = 0; 735 const RSA_METHOD *def_rsa_method; 736 737 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { 738 CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP, 739 CSWIFT_R_MISSING_KEY_COMPONENTS); 740 goto err; 741 } 742 743 /* Try the limits of RSA (2048 bits) */ 744 if (BN_num_bytes(rsa->p) > 128 || 745 BN_num_bytes(rsa->q) > 128 || 746 BN_num_bytes(rsa->dmp1) > 128 || 747 BN_num_bytes(rsa->dmq1) > 128 || BN_num_bytes(rsa->iqmp) > 128) { 748# ifdef RSA_NULL 749 def_rsa_method = RSA_null_method(); 750# else 751# if 0 752 def_rsa_method = RSA_PKCS1_RSAref(); 753# else 754 def_rsa_method = RSA_PKCS1_SSLeay(); 755# endif 756# endif 757 if (def_rsa_method) 758 return def_rsa_method->rsa_mod_exp(r0, I, rsa, ctx); 759 } 760 761 to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, 762 rsa->dmq1, rsa->iqmp, ctx); 763 err: 764 return to_return; 765} 766 767/* This function is aliased to mod_exp (with the mont stuff dropped). */ 768static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 769 const BIGNUM *m, BN_CTX *ctx, 770 BN_MONT_CTX *m_ctx) 771{ 772 const RSA_METHOD *def_rsa_method; 773 774 /* Try the limits of RSA (2048 bits) */ 775 if (BN_num_bytes(r) > 256 || 776 BN_num_bytes(a) > 256 || BN_num_bytes(m) > 256) { 777# ifdef RSA_NULL 778 def_rsa_method = RSA_null_method(); 779# else 780# if 0 781 def_rsa_method = RSA_PKCS1_RSAref(); 782# else 783 def_rsa_method = RSA_PKCS1_SSLeay(); 784# endif 785# endif 786 if (def_rsa_method) 787 return def_rsa_method->bn_mod_exp(r, a, p, m, ctx, m_ctx); 788 } 789 790 return cswift_mod_exp(r, a, p, m, ctx); 791} 792# endif /* OPENSSL_NO_RSA */ 793 794# ifndef OPENSSL_NO_DSA 795static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa) 796{ 797 SW_CONTEXT_HANDLE hac; 798 SW_PARAM sw_param; 799 SW_STATUS sw_status; 800 SW_LARGENUMBER arg, res; 801 BN_CTX *ctx; 802 BIGNUM *dsa_p = NULL; 803 BIGNUM *dsa_q = NULL; 804 BIGNUM *dsa_g = NULL; 805 BIGNUM *dsa_key = NULL; 806 BIGNUM *result = NULL; 807 DSA_SIG *to_return = NULL; 808 int acquired = 0; 809 810 if ((ctx = BN_CTX_new()) == NULL) 811 goto err; 812 if (!get_context(&hac)) { 813 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_UNIT_FAILURE); 814 goto err; 815 } 816 acquired = 1; 817 /* Prepare the params */ 818 BN_CTX_start(ctx); 819 dsa_p = BN_CTX_get(ctx); 820 dsa_q = BN_CTX_get(ctx); 821 dsa_g = BN_CTX_get(ctx); 822 dsa_key = BN_CTX_get(ctx); 823 result = BN_CTX_get(ctx); 824 if (!result) { 825 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_BN_CTX_FULL); 826 goto err; 827 } 828 if (!bn_wexpand(dsa_p, dsa->p->top) || 829 !bn_wexpand(dsa_q, dsa->q->top) || 830 !bn_wexpand(dsa_g, dsa->g->top) || 831 !bn_wexpand(dsa_key, dsa->priv_key->top) || 832 !bn_wexpand(result, dsa->p->top)) { 833 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_BN_EXPAND_FAIL); 834 goto err; 835 } 836 sw_param.type = SW_ALG_DSA; 837 sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p, (unsigned char *)dsa_p->d); 838 sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d; 839 sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q, (unsigned char *)dsa_q->d); 840 sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d; 841 sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g, (unsigned char *)dsa_g->d); 842 sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d; 843 sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key, 844 (unsigned char *)dsa_key->d); 845 sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d; 846 /* Attach the key params */ 847 sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); 848 switch (sw_status) { 849 case SW_OK: 850 break; 851 case SW_ERR_INPUT_SIZE: 852 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_BAD_KEY_SIZE); 853 goto err; 854 default: 855 { 856 char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; 857 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_REQUEST_FAILED); 858 sprintf(tmpbuf, "%ld", sw_status); 859 ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); 860 } 861 goto err; 862 } 863 /* Prepare the argument and response */ 864 arg.nbytes = dlen; 865 arg.value = (unsigned char *)dgst; 866 res.nbytes = BN_num_bytes(dsa->p); 867 memset(result->d, 0, res.nbytes); 868 res.value = (unsigned char *)result->d; 869 /* Perform the operation */ 870 sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1, 871 &res, 1); 872 if (sw_status != SW_OK) { 873 char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; 874 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_REQUEST_FAILED); 875 sprintf(tmpbuf, "%ld", sw_status); 876 ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); 877 goto err; 878 } 879 /* Convert the response */ 880 if ((to_return = DSA_SIG_new()) == NULL) 881 goto err; 882 to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL); 883 to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL); 884 885 err: 886 if (acquired) 887 release_context(hac); 888 if (ctx) { 889 BN_CTX_end(ctx); 890 BN_CTX_free(ctx); 891 } 892 return to_return; 893} 894 895static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, 896 DSA_SIG *sig, DSA *dsa) 897{ 898 SW_CONTEXT_HANDLE hac; 899 SW_PARAM sw_param; 900 SW_STATUS sw_status; 901 SW_LARGENUMBER arg[2], res; 902 unsigned long sig_result; 903 BN_CTX *ctx; 904 BIGNUM *dsa_p = NULL; 905 BIGNUM *dsa_q = NULL; 906 BIGNUM *dsa_g = NULL; 907 BIGNUM *dsa_key = NULL; 908 BIGNUM *argument = NULL; 909 int to_return = -1; 910 int acquired = 0; 911 912 if ((ctx = BN_CTX_new()) == NULL) 913 goto err; 914 if (!get_context(&hac)) { 915 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_UNIT_FAILURE); 916 goto err; 917 } 918 acquired = 1; 919 /* Prepare the params */ 920 BN_CTX_start(ctx); 921 dsa_p = BN_CTX_get(ctx); 922 dsa_q = BN_CTX_get(ctx); 923 dsa_g = BN_CTX_get(ctx); 924 dsa_key = BN_CTX_get(ctx); 925 argument = BN_CTX_get(ctx); 926 if (!argument) { 927 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_BN_CTX_FULL); 928 goto err; 929 } 930 if (!bn_wexpand(dsa_p, dsa->p->top) || 931 !bn_wexpand(dsa_q, dsa->q->top) || 932 !bn_wexpand(dsa_g, dsa->g->top) || 933 !bn_wexpand(dsa_key, dsa->pub_key->top) || 934 !bn_wexpand(argument, 40)) { 935 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_BN_EXPAND_FAIL); 936 goto err; 937 } 938 sw_param.type = SW_ALG_DSA; 939 sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p, (unsigned char *)dsa_p->d); 940 sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d; 941 sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q, (unsigned char *)dsa_q->d); 942 sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d; 943 sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g, (unsigned char *)dsa_g->d); 944 sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d; 945 sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key, 946 (unsigned char *)dsa_key->d); 947 sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d; 948 /* Attach the key params */ 949 sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); 950 switch (sw_status) { 951 case SW_OK: 952 break; 953 case SW_ERR_INPUT_SIZE: 954 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_BAD_KEY_SIZE); 955 goto err; 956 default: 957 { 958 char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; 959 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_REQUEST_FAILED); 960 sprintf(tmpbuf, "%ld", sw_status); 961 ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); 962 } 963 goto err; 964 } 965 /* Prepare the argument and response */ 966 arg[0].nbytes = dgst_len; 967 arg[0].value = (unsigned char *)dgst; 968 arg[1].nbytes = 40; 969 arg[1].value = (unsigned char *)argument->d; 970 memset(arg[1].value, 0, 40); 971 BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r)); 972 BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s)); 973 res.nbytes = 4; /* unsigned long */ 974 res.value = (unsigned char *)(&sig_result); 975 /* Perform the operation */ 976 sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2, 977 &res, 1); 978 if (sw_status != SW_OK) { 979 char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; 980 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_REQUEST_FAILED); 981 sprintf(tmpbuf, "%ld", sw_status); 982 ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); 983 goto err; 984 } 985 /* Convert the response */ 986 to_return = ((sig_result == 0) ? 0 : 1); 987 988 err: 989 if (acquired) 990 release_context(hac); 991 if (ctx) { 992 BN_CTX_end(ctx); 993 BN_CTX_free(ctx); 994 } 995 return to_return; 996} 997# endif 998 999# ifndef OPENSSL_NO_DH 1000/* This function is aliased to mod_exp (with the dh and mont dropped). */ 1001static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r, 1002 const BIGNUM *a, const BIGNUM *p, 1003 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 1004{ 1005 return cswift_mod_exp(r, a, p, m, ctx); 1006} 1007# endif 1008 1009/* Random bytes are good */ 1010static int cswift_rand_bytes(unsigned char *buf, int num) 1011{ 1012 SW_CONTEXT_HANDLE hac; 1013 SW_STATUS swrc; 1014 SW_LARGENUMBER largenum; 1015 int acquired = 0; 1016 int to_return = 0; /* assume failure */ 1017 unsigned char buf32[1024]; 1018 1019 if (!get_context(&hac)) { 1020 CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_UNIT_FAILURE); 1021 goto err; 1022 } 1023 acquired = 1; 1024 1025 /************************************************************************/ 1026 /* 1027 * 04/02/2003 1028 */ 1029 /* 1030 * Modified by Frederic Giudicelli (deny-all.com) to overcome the 1031 */ 1032 /* 1033 * limitation of cswift with values not a multiple of 32 1034 */ 1035 /************************************************************************/ 1036 1037 while (num >= (int)sizeof(buf32)) { 1038 largenum.value = buf; 1039 largenum.nbytes = sizeof(buf32); 1040 /*- 1041 * tell CryptoSwift how many bytes we want and where we want it. 1042 * Note: - CryptoSwift cannot do more than 4096 bytes at a time. 1043 * - CryptoSwift can only do multiple of 32-bits. 1044 */ 1045 swrc = 1046 p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1); 1047 if (swrc != SW_OK) { 1048 char tmpbuf[20]; 1049 CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED); 1050 sprintf(tmpbuf, "%ld", swrc); 1051 ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); 1052 goto err; 1053 } 1054 buf += sizeof(buf32); 1055 num -= sizeof(buf32); 1056 } 1057 if (num) { 1058 largenum.nbytes = sizeof(buf32); 1059 largenum.value = buf32; 1060 swrc = 1061 p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1); 1062 if (swrc != SW_OK) { 1063 char tmpbuf[20]; 1064 CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED); 1065 sprintf(tmpbuf, "%ld", swrc); 1066 ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); 1067 goto err; 1068 } 1069 memcpy(buf, largenum.value, num); 1070 } 1071 1072 to_return = 1; /* success */ 1073 err: 1074 if (acquired) 1075 release_context(hac); 1076 1077 return to_return; 1078} 1079 1080static int cswift_rand_status(void) 1081{ 1082 return 1; 1083} 1084 1085/* 1086 * This stuff is needed if this ENGINE is being compiled into a 1087 * self-contained shared-library. 1088 */ 1089# ifndef OPENSSL_NO_DYNAMIC_ENGINE 1090static int bind_fn(ENGINE *e, const char *id) 1091{ 1092 if (id && (strcmp(id, engine_cswift_id) != 0)) 1093 return 0; 1094 if (!bind_helper(e)) 1095 return 0; 1096 return 1; 1097} 1098 1099IMPLEMENT_DYNAMIC_CHECK_FN() 1100 IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) 1101# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ 1102# endif /* !OPENSSL_NO_HW_CSWIFT */ 1103#endif /* !OPENSSL_NO_HW */ 1104