1160814Ssimon/* Author: Maurice Gittens <maurice@gittens.nl> */ 2160814Ssimon/* ==================================================================== 3160814Ssimon * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 4160814Ssimon * 5160814Ssimon * Redistribution and use in source and binary forms, with or without 6160814Ssimon * modification, are permitted provided that the following conditions 7160814Ssimon * are met: 8160814Ssimon * 9160814Ssimon * 1. Redistributions of source code must retain the above copyright 10280304Sjkim * notice, this list of conditions and the following disclaimer. 11160814Ssimon * 12160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 13160814Ssimon * notice, this list of conditions and the following disclaimer in 14160814Ssimon * the documentation and/or other materials provided with the 15160814Ssimon * distribution. 16160814Ssimon * 17160814Ssimon * 3. All advertising materials mentioning features or use of this 18160814Ssimon * software must display the following acknowledgment: 19160814Ssimon * "This product includes software developed by the OpenSSL Project 20160814Ssimon * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 21160814Ssimon * 22160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23160814Ssimon * endorse or promote products derived from this software without 24160814Ssimon * prior written permission. For written permission, please contact 25160814Ssimon * licensing@OpenSSL.org. 26160814Ssimon * 27160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 28160814Ssimon * nor may "OpenSSL" appear in their names without prior written 29160814Ssimon * permission of the OpenSSL Project. 30160814Ssimon * 31160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 32160814Ssimon * acknowledgment: 33160814Ssimon * "This product includes software developed by the OpenSSL Project 34160814Ssimon * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 35160814Ssimon * 36160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 48160814Ssimon * ==================================================================== 49160814Ssimon * 50160814Ssimon * This product includes cryptographic software written by Eric Young 51160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 52160814Ssimon * Hudson (tjh@cryptsoft.com). 53160814Ssimon * 54160814Ssimon */ 55160814Ssimon 56160814Ssimon#include <stdio.h> 57160814Ssimon#include <string.h> 58160814Ssimon#include <openssl/crypto.h> 59160814Ssimon#include <openssl/dso.h> 60160814Ssimon#include <openssl/x509.h> 61160814Ssimon#include <openssl/objects.h> 62160814Ssimon#include <openssl/engine.h> 63160814Ssimon#include <openssl/rand.h> 64160814Ssimon#ifndef OPENSSL_NO_RSA 65280304Sjkim# include <openssl/rsa.h> 66160814Ssimon#endif 67160814Ssimon#include <openssl/bn.h> 68160814Ssimon 69160814Ssimon#ifndef OPENSSL_NO_HW 70280304Sjkim# ifndef OPENSSL_NO_HW_4758_CCA 71160814Ssimon 72280304Sjkim# ifdef FLAT_INC 73280304Sjkim# include "hw_4758_cca.h" 74280304Sjkim# else 75280304Sjkim# include "vendor_defns/hw_4758_cca.h" 76280304Sjkim# endif 77160814Ssimon 78280304Sjkim# include "e_4758cca_err.c" 79160814Ssimon 80160814Ssimonstatic int ibm_4758_cca_destroy(ENGINE *e); 81160814Ssimonstatic int ibm_4758_cca_init(ENGINE *e); 82160814Ssimonstatic int ibm_4758_cca_finish(ENGINE *e); 83280304Sjkimstatic int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, 84280304Sjkim void (*f) (void)); 85160814Ssimon 86160814Ssimon/* rsa functions */ 87280304Sjkim/* -------------*/ 88280304Sjkim# ifndef OPENSSL_NO_RSA 89160814Ssimonstatic int cca_rsa_pub_enc(int flen, const unsigned char *from, 90280304Sjkim unsigned char *to, RSA *rsa, int padding); 91160814Ssimonstatic int cca_rsa_priv_dec(int flen, const unsigned char *from, 92280304Sjkim unsigned char *to, RSA *rsa, int padding); 93160814Ssimonstatic int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, 94280304Sjkim unsigned char *sigret, unsigned int *siglen, 95280304Sjkim const RSA *rsa); 96280304Sjkimstatic int cca_rsa_verify(int dtype, const unsigned char *m, 97280304Sjkim unsigned int m_len, const unsigned char *sigbuf, 98280304Sjkim unsigned int siglen, const RSA *rsa); 99160814Ssimon 100160814Ssimon/* utility functions */ 101280304Sjkim/* ---------------------*/ 102280304Sjkimstatic EVP_PKEY *ibm_4758_load_privkey(ENGINE *, const char *, 103280304Sjkim UI_METHOD *ui_method, 104280304Sjkim void *callback_data); 105280304Sjkimstatic EVP_PKEY *ibm_4758_load_pubkey(ENGINE *, const char *, 106280304Sjkim UI_METHOD *ui_method, 107280304Sjkim void *callback_data); 108160814Ssimon 109280304Sjkimstatic int getModulusAndExponent(const unsigned char *token, 110280304Sjkim long *exponentLength, 111280304Sjkim unsigned char *exponent, long *modulusLength, 112280304Sjkim long *modulusFieldLength, 113280304Sjkim unsigned char *modulus); 114280304Sjkim# endif 115160814Ssimon 116160814Ssimon/* RAND number functions */ 117280304Sjkim/* ---------------------*/ 118280304Sjkimstatic int cca_get_random_bytes(unsigned char *, int); 119160814Ssimonstatic int cca_random_status(void); 120160814Ssimon 121280304Sjkim# ifndef OPENSSL_NO_RSA 122160814Ssimonstatic void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 123280304Sjkim int idx, long argl, void *argp); 124280304Sjkim# endif 125160814Ssimon 126160814Ssimon/* Function pointers for CCA verbs */ 127280304Sjkim/* -------------------------------*/ 128280304Sjkim# ifndef OPENSSL_NO_RSA 129160814Ssimonstatic F_KEYRECORDREAD keyRecordRead; 130160814Ssimonstatic F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate; 131160814Ssimonstatic F_DIGITALSIGNATUREVERIFY digitalSignatureVerify; 132160814Ssimonstatic F_PUBLICKEYEXTRACT publicKeyExtract; 133160814Ssimonstatic F_PKAENCRYPT pkaEncrypt; 134160814Ssimonstatic F_PKADECRYPT pkaDecrypt; 135280304Sjkim# endif 136160814Ssimonstatic F_RANDOMNUMBERGENERATE randomNumberGenerate; 137160814Ssimon 138160814Ssimon/* static variables */ 139280304Sjkim/* ----------------*/ 140160814Ssimonstatic const char *CCA4758_LIB_NAME = NULL; 141160814Ssimonstatic const char *get_CCA4758_LIB_NAME(void) 142280304Sjkim{ 143280304Sjkim if (CCA4758_LIB_NAME) 144280304Sjkim return CCA4758_LIB_NAME; 145280304Sjkim return CCA_LIB_NAME; 146280304Sjkim} 147280304Sjkim 148160814Ssimonstatic void free_CCA4758_LIB_NAME(void) 149280304Sjkim{ 150280304Sjkim if (CCA4758_LIB_NAME) 151280304Sjkim OPENSSL_free((void *)CCA4758_LIB_NAME); 152280304Sjkim CCA4758_LIB_NAME = NULL; 153280304Sjkim} 154280304Sjkim 155160814Ssimonstatic long set_CCA4758_LIB_NAME(const char *name) 156280304Sjkim{ 157280304Sjkim free_CCA4758_LIB_NAME(); 158280304Sjkim return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0); 159280304Sjkim} 160160814Ssimon 161280304Sjkim# ifndef OPENSSL_NO_RSA 162280304Sjkimstatic const char *n_keyRecordRead = CSNDKRR; 163280304Sjkimstatic const char *n_digitalSignatureGenerate = CSNDDSG; 164280304Sjkimstatic const char *n_digitalSignatureVerify = CSNDDSV; 165280304Sjkimstatic const char *n_publicKeyExtract = CSNDPKX; 166280304Sjkimstatic const char *n_pkaEncrypt = CSNDPKE; 167280304Sjkimstatic const char *n_pkaDecrypt = CSNDPKD; 168280304Sjkim# endif 169280304Sjkimstatic const char *n_randomNumberGenerate = CSNBRNG; 170280304Sjkim 171280304Sjkim# ifndef OPENSSL_NO_RSA 172160814Ssimonstatic int hndidx = -1; 173280304Sjkim# endif 174160814Ssimonstatic DSO *dso = NULL; 175160814Ssimon 176160814Ssimon/* openssl engine initialization structures */ 177280304Sjkim/* ----------------------------------------*/ 178160814Ssimon 179280304Sjkim# define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE 180280304Sjkimstatic const ENGINE_CMD_DEFN cca4758_cmd_defns[] = { 181280304Sjkim {CCA4758_CMD_SO_PATH, 182280304Sjkim "SO_PATH", 183280304Sjkim "Specifies the path to the '4758cca' shared library", 184280304Sjkim ENGINE_CMD_FLAG_STRING}, 185280304Sjkim {0, NULL, NULL, 0} 186280304Sjkim}; 187160814Ssimon 188280304Sjkim# ifndef OPENSSL_NO_RSA 189280304Sjkimstatic RSA_METHOD ibm_4758_cca_rsa = { 190280304Sjkim "IBM 4758 CCA RSA method", 191280304Sjkim cca_rsa_pub_enc, 192280304Sjkim NULL, 193280304Sjkim NULL, 194280304Sjkim cca_rsa_priv_dec, 195280304Sjkim NULL, /* rsa_mod_exp, */ 196280304Sjkim NULL, /* mod_exp_mont, */ 197280304Sjkim NULL, /* init */ 198280304Sjkim NULL, /* finish */ 199280304Sjkim RSA_FLAG_SIGN_VER, /* flags */ 200280304Sjkim NULL, /* app_data */ 201280304Sjkim cca_rsa_sign, /* rsa_sign */ 202280304Sjkim cca_rsa_verify, /* rsa_verify */ 203280304Sjkim NULL /* rsa_keygen */ 204280304Sjkim}; 205280304Sjkim# endif 206160814Ssimon 207280304Sjkimstatic RAND_METHOD ibm_4758_cca_rand = { 208280304Sjkim /* "IBM 4758 RAND method", */ 209280304Sjkim NULL, /* seed */ 210280304Sjkim cca_get_random_bytes, /* get random bytes from the card */ 211280304Sjkim NULL, /* cleanup */ 212280304Sjkim NULL, /* add */ 213280304Sjkim cca_get_random_bytes, /* pseudo rand */ 214280304Sjkim cca_random_status, /* status */ 215280304Sjkim}; 216160814Ssimon 217160814Ssimonstatic const char *engine_4758_cca_id = "4758cca"; 218280304Sjkimstatic const char *engine_4758_cca_name = 219280304Sjkim "IBM 4758 CCA hardware engine support"; 220280304Sjkim# ifndef OPENSSL_NO_DYNAMIC_ENGINE 221160814Ssimon/* Compatibility hack, the dynamic library uses this form in the path */ 222160814Ssimonstatic const char *engine_4758_cca_id_alt = "4758_cca"; 223280304Sjkim# endif 224160814Ssimon 225160814Ssimon/* engine implementation */ 226280304Sjkim/* ---------------------*/ 227160814Ssimonstatic int bind_helper(ENGINE *e) 228280304Sjkim{ 229280304Sjkim if (!ENGINE_set_id(e, engine_4758_cca_id) || 230280304Sjkim !ENGINE_set_name(e, engine_4758_cca_name) || 231280304Sjkim# ifndef OPENSSL_NO_RSA 232280304Sjkim !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) || 233280304Sjkim# endif 234280304Sjkim !ENGINE_set_RAND(e, &ibm_4758_cca_rand) || 235280304Sjkim !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) || 236280304Sjkim !ENGINE_set_init_function(e, ibm_4758_cca_init) || 237280304Sjkim !ENGINE_set_finish_function(e, ibm_4758_cca_finish) || 238280304Sjkim !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) || 239280304Sjkim# ifndef OPENSSL_NO_RSA 240280304Sjkim !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) || 241280304Sjkim !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) || 242280304Sjkim# endif 243280304Sjkim !ENGINE_set_cmd_defns(e, cca4758_cmd_defns)) 244280304Sjkim return 0; 245280304Sjkim /* Ensure the error handling is set up */ 246280304Sjkim ERR_load_CCA4758_strings(); 247280304Sjkim return 1; 248280304Sjkim} 249160814Ssimon 250280304Sjkim# ifdef OPENSSL_NO_DYNAMIC_ENGINE 251160814Ssimonstatic ENGINE *engine_4758_cca(void) 252280304Sjkim{ 253280304Sjkim ENGINE *ret = ENGINE_new(); 254280304Sjkim if (!ret) 255280304Sjkim return NULL; 256280304Sjkim if (!bind_helper(ret)) { 257280304Sjkim ENGINE_free(ret); 258280304Sjkim return NULL; 259280304Sjkim } 260280304Sjkim return ret; 261280304Sjkim} 262160814Ssimon 263160814Ssimonvoid ENGINE_load_4758cca(void) 264280304Sjkim{ 265280304Sjkim ENGINE *e_4758 = engine_4758_cca(); 266280304Sjkim if (!e_4758) 267280304Sjkim return; 268280304Sjkim ENGINE_add(e_4758); 269280304Sjkim ENGINE_free(e_4758); 270280304Sjkim ERR_clear_error(); 271280304Sjkim} 272280304Sjkim# endif 273160814Ssimon 274160814Ssimonstatic int ibm_4758_cca_destroy(ENGINE *e) 275280304Sjkim{ 276280304Sjkim ERR_unload_CCA4758_strings(); 277280304Sjkim free_CCA4758_LIB_NAME(); 278280304Sjkim return 1; 279280304Sjkim} 280160814Ssimon 281160814Ssimonstatic int ibm_4758_cca_init(ENGINE *e) 282280304Sjkim{ 283280304Sjkim if (dso) { 284280304Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_ALREADY_LOADED); 285280304Sjkim goto err; 286280304Sjkim } 287160814Ssimon 288280304Sjkim dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0); 289280304Sjkim if (!dso) { 290280304Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); 291280304Sjkim goto err; 292280304Sjkim } 293280304Sjkim# ifndef OPENSSL_NO_RSA 294280304Sjkim if (!(keyRecordRead = (F_KEYRECORDREAD) 295280304Sjkim DSO_bind_func(dso, n_keyRecordRead)) || 296280304Sjkim !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 297280304Sjkim DSO_bind_func(dso, n_randomNumberGenerate)) || 298280304Sjkim !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 299280304Sjkim DSO_bind_func(dso, n_digitalSignatureGenerate)) || 300280304Sjkim !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY) 301280304Sjkim DSO_bind_func(dso, n_digitalSignatureVerify)) || 302280304Sjkim !(publicKeyExtract = (F_PUBLICKEYEXTRACT) 303280304Sjkim DSO_bind_func(dso, n_publicKeyExtract)) || 304280304Sjkim !(pkaEncrypt = (F_PKAENCRYPT) 305280304Sjkim DSO_bind_func(dso, n_pkaEncrypt)) || !(pkaDecrypt = (F_PKADECRYPT) 306280304Sjkim DSO_bind_func(dso, 307280304Sjkim n_pkaDecrypt))) 308280304Sjkim { 309280304Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); 310280304Sjkim goto err; 311280304Sjkim } 312280304Sjkim# else 313280304Sjkim if (!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 314280304Sjkim DSO_bind_func(dso, n_randomNumberGenerate))) { 315280304Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); 316280304Sjkim goto err; 317280304Sjkim } 318280304Sjkim# endif 319160814Ssimon 320280304Sjkim# ifndef OPENSSL_NO_RSA 321280304Sjkim hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle", 322280304Sjkim NULL, NULL, cca_ex_free); 323280304Sjkim# endif 324160814Ssimon 325280304Sjkim return 1; 326280304Sjkim err: 327280304Sjkim if (dso) 328280304Sjkim DSO_free(dso); 329280304Sjkim dso = NULL; 330160814Ssimon 331280304Sjkim# ifndef OPENSSL_NO_RSA 332280304Sjkim keyRecordRead = (F_KEYRECORDREAD) 0; 333280304Sjkim digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0; 334280304Sjkim digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; 335280304Sjkim publicKeyExtract = (F_PUBLICKEYEXTRACT)0; 336280304Sjkim pkaEncrypt = (F_PKAENCRYPT) 0; 337280304Sjkim pkaDecrypt = (F_PKADECRYPT) 0; 338280304Sjkim# endif 339280304Sjkim randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; 340280304Sjkim return 0; 341280304Sjkim} 342160814Ssimon 343160814Ssimonstatic int ibm_4758_cca_finish(ENGINE *e) 344280304Sjkim{ 345280304Sjkim free_CCA4758_LIB_NAME(); 346280304Sjkim if (!dso) { 347280304Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_NOT_LOADED); 348280304Sjkim return 0; 349280304Sjkim } 350280304Sjkim if (!DSO_free(dso)) { 351280304Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_UNIT_FAILURE); 352280304Sjkim return 0; 353280304Sjkim } 354280304Sjkim dso = NULL; 355280304Sjkim# ifndef OPENSSL_NO_RSA 356280304Sjkim keyRecordRead = (F_KEYRECORDREAD) 0; 357280304Sjkim randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; 358280304Sjkim digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0; 359280304Sjkim digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; 360280304Sjkim publicKeyExtract = (F_PUBLICKEYEXTRACT)0; 361280304Sjkim pkaEncrypt = (F_PKAENCRYPT) 0; 362280304Sjkim pkaDecrypt = (F_PKADECRYPT) 0; 363280304Sjkim# endif 364280304Sjkim randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; 365280304Sjkim return 1; 366280304Sjkim} 367160814Ssimon 368280304Sjkimstatic int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, 369280304Sjkim void (*f) (void)) 370280304Sjkim{ 371280304Sjkim int initialised = ((dso == NULL) ? 0 : 1); 372280304Sjkim switch (cmd) { 373280304Sjkim case CCA4758_CMD_SO_PATH: 374280304Sjkim if (p == NULL) { 375280304Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, 376280304Sjkim ERR_R_PASSED_NULL_PARAMETER); 377280304Sjkim return 0; 378280304Sjkim } 379280304Sjkim if (initialised) { 380280304Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, CCA4758_R_ALREADY_LOADED); 381280304Sjkim return 0; 382280304Sjkim } 383280304Sjkim return set_CCA4758_LIB_NAME((const char *)p); 384280304Sjkim default: 385280304Sjkim break; 386280304Sjkim } 387280304Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, 388280304Sjkim CCA4758_R_COMMAND_NOT_IMPLEMENTED); 389280304Sjkim return 0; 390280304Sjkim} 391160814Ssimon 392280304Sjkim# ifndef OPENSSL_NO_RSA 393160814Ssimon 394280304Sjkim# define MAX_CCA_PKA_TOKEN_SIZE 2500 395160814Ssimon 396280304Sjkimstatic EVP_PKEY *ibm_4758_load_privkey(ENGINE *e, const char *key_id, 397280304Sjkim UI_METHOD *ui_method, 398280304Sjkim void *callback_data) 399280304Sjkim{ 400280304Sjkim RSA *rtmp = NULL; 401280304Sjkim EVP_PKEY *res = NULL; 402280304Sjkim unsigned char *keyToken = NULL; 403280304Sjkim unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE]; 404280304Sjkim long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 405280304Sjkim long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 406280304Sjkim long returnCode; 407280304Sjkim long reasonCode; 408280304Sjkim long exitDataLength = 0; 409280304Sjkim long ruleArrayLength = 0; 410280304Sjkim unsigned char exitData[8]; 411280304Sjkim unsigned char ruleArray[8]; 412280304Sjkim unsigned char keyLabel[64]; 413280304Sjkim unsigned long keyLabelLength = strlen(key_id); 414280304Sjkim unsigned char modulus[256]; 415280304Sjkim long modulusFieldLength = sizeof(modulus); 416280304Sjkim long modulusLength = 0; 417280304Sjkim unsigned char exponent[256]; 418280304Sjkim long exponentLength = sizeof(exponent); 419160814Ssimon 420280304Sjkim if (keyLabelLength > sizeof(keyLabel)) { 421280304Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 422280304Sjkim CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 423280304Sjkim return NULL; 424280304Sjkim } 425160814Ssimon 426280304Sjkim memset(keyLabel, ' ', sizeof(keyLabel)); 427280304Sjkim memcpy(keyLabel, key_id, keyLabelLength); 428160814Ssimon 429280304Sjkim keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); 430280304Sjkim if (!keyToken) { 431280304Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); 432280304Sjkim goto err; 433280304Sjkim } 434160814Ssimon 435280304Sjkim keyRecordRead(&returnCode, &reasonCode, &exitDataLength, 436280304Sjkim exitData, &ruleArrayLength, ruleArray, keyLabel, 437280304Sjkim &keyTokenLength, keyToken + sizeof(long)); 438160814Ssimon 439280304Sjkim if (returnCode) { 440280304Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 441280304Sjkim CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 442280304Sjkim goto err; 443280304Sjkim } 444160814Ssimon 445280304Sjkim publicKeyExtract(&returnCode, &reasonCode, &exitDataLength, 446280304Sjkim exitData, &ruleArrayLength, ruleArray, &keyTokenLength, 447280304Sjkim keyToken + sizeof(long), &pubKeyTokenLength, 448280304Sjkim pubKeyToken); 449160814Ssimon 450280304Sjkim if (returnCode) { 451280304Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 452280304Sjkim CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 453280304Sjkim goto err; 454280304Sjkim } 455160814Ssimon 456280304Sjkim if (!getModulusAndExponent(pubKeyToken, &exponentLength, 457280304Sjkim exponent, &modulusLength, &modulusFieldLength, 458280304Sjkim modulus)) { 459280304Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 460280304Sjkim CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 461280304Sjkim goto err; 462280304Sjkim } 463160814Ssimon 464280304Sjkim (*(long *)keyToken) = keyTokenLength; 465280304Sjkim rtmp = RSA_new_method(e); 466280304Sjkim RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); 467160814Ssimon 468280304Sjkim rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); 469280304Sjkim rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); 470280304Sjkim rtmp->flags |= RSA_FLAG_EXT_PKEY; 471160814Ssimon 472280304Sjkim res = EVP_PKEY_new(); 473280304Sjkim EVP_PKEY_assign_RSA(res, rtmp); 474160814Ssimon 475280304Sjkim return res; 476280304Sjkim err: 477280304Sjkim if (keyToken) 478280304Sjkim OPENSSL_free(keyToken); 479280304Sjkim return NULL; 480280304Sjkim} 481160814Ssimon 482280304Sjkimstatic EVP_PKEY *ibm_4758_load_pubkey(ENGINE *e, const char *key_id, 483280304Sjkim UI_METHOD *ui_method, 484280304Sjkim void *callback_data) 485280304Sjkim{ 486280304Sjkim RSA *rtmp = NULL; 487280304Sjkim EVP_PKEY *res = NULL; 488280304Sjkim unsigned char *keyToken = NULL; 489280304Sjkim long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 490280304Sjkim long returnCode; 491280304Sjkim long reasonCode; 492280304Sjkim long exitDataLength = 0; 493280304Sjkim long ruleArrayLength = 0; 494280304Sjkim unsigned char exitData[8]; 495280304Sjkim unsigned char ruleArray[8]; 496280304Sjkim unsigned char keyLabel[64]; 497280304Sjkim unsigned long keyLabelLength = strlen(key_id); 498280304Sjkim unsigned char modulus[512]; 499280304Sjkim long modulusFieldLength = sizeof(modulus); 500280304Sjkim long modulusLength = 0; 501280304Sjkim unsigned char exponent[512]; 502280304Sjkim long exponentLength = sizeof(exponent); 503160814Ssimon 504280304Sjkim if (keyLabelLength > sizeof(keyLabel)) { 505280304Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 506280304Sjkim CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 507280304Sjkim return NULL; 508280304Sjkim } 509160814Ssimon 510280304Sjkim memset(keyLabel, ' ', sizeof(keyLabel)); 511280304Sjkim memcpy(keyLabel, key_id, keyLabelLength); 512160814Ssimon 513280304Sjkim keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); 514280304Sjkim if (!keyToken) { 515280304Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); 516280304Sjkim goto err; 517280304Sjkim } 518160814Ssimon 519280304Sjkim keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData, 520280304Sjkim &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength, 521280304Sjkim keyToken + sizeof(long)); 522160814Ssimon 523280304Sjkim if (returnCode) { 524280304Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); 525280304Sjkim goto err; 526280304Sjkim } 527160814Ssimon 528280304Sjkim if (!getModulusAndExponent(keyToken + sizeof(long), &exponentLength, 529280304Sjkim exponent, &modulusLength, &modulusFieldLength, 530280304Sjkim modulus)) { 531280304Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 532280304Sjkim CCA4758_R_FAILED_LOADING_PUBLIC_KEY); 533280304Sjkim goto err; 534280304Sjkim } 535160814Ssimon 536280304Sjkim (*(long *)keyToken) = keyTokenLength; 537280304Sjkim rtmp = RSA_new_method(e); 538280304Sjkim RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); 539280304Sjkim rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); 540280304Sjkim rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); 541280304Sjkim rtmp->flags |= RSA_FLAG_EXT_PKEY; 542280304Sjkim res = EVP_PKEY_new(); 543280304Sjkim EVP_PKEY_assign_RSA(res, rtmp); 544160814Ssimon 545280304Sjkim return res; 546280304Sjkim err: 547280304Sjkim if (keyToken) 548280304Sjkim OPENSSL_free(keyToken); 549280304Sjkim return NULL; 550280304Sjkim} 551160814Ssimon 552160814Ssimonstatic int cca_rsa_pub_enc(int flen, const unsigned char *from, 553280304Sjkim unsigned char *to, RSA *rsa, int padding) 554280304Sjkim{ 555280304Sjkim long returnCode; 556280304Sjkim long reasonCode; 557280304Sjkim long lflen = flen; 558280304Sjkim long exitDataLength = 0; 559280304Sjkim unsigned char exitData[8]; 560280304Sjkim long ruleArrayLength = 1; 561280304Sjkim unsigned char ruleArray[8] = "PKCS-1.2"; 562280304Sjkim long dataStructureLength = 0; 563280304Sjkim unsigned char dataStructure[8]; 564280304Sjkim long outputLength = RSA_size(rsa); 565280304Sjkim long keyTokenLength; 566280304Sjkim unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); 567160814Ssimon 568280304Sjkim keyTokenLength = *(long *)keyToken; 569280304Sjkim keyToken += sizeof(long); 570160814Ssimon 571280304Sjkim pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData, 572280304Sjkim &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from, 573280304Sjkim &dataStructureLength, dataStructure, &keyTokenLength, 574280304Sjkim keyToken, &outputLength, to); 575160814Ssimon 576280304Sjkim if (returnCode || reasonCode) 577280304Sjkim return -(returnCode << 16 | reasonCode); 578280304Sjkim return outputLength; 579280304Sjkim} 580160814Ssimon 581160814Ssimonstatic int cca_rsa_priv_dec(int flen, const unsigned char *from, 582280304Sjkim unsigned char *to, RSA *rsa, int padding) 583280304Sjkim{ 584280304Sjkim long returnCode; 585280304Sjkim long reasonCode; 586280304Sjkim long lflen = flen; 587280304Sjkim long exitDataLength = 0; 588280304Sjkim unsigned char exitData[8]; 589280304Sjkim long ruleArrayLength = 1; 590280304Sjkim unsigned char ruleArray[8] = "PKCS-1.2"; 591280304Sjkim long dataStructureLength = 0; 592280304Sjkim unsigned char dataStructure[8]; 593280304Sjkim long outputLength = RSA_size(rsa); 594280304Sjkim long keyTokenLength; 595280304Sjkim unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); 596160814Ssimon 597280304Sjkim keyTokenLength = *(long *)keyToken; 598280304Sjkim keyToken += sizeof(long); 599160814Ssimon 600280304Sjkim pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData, 601280304Sjkim &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from, 602280304Sjkim &dataStructureLength, dataStructure, &keyTokenLength, 603280304Sjkim keyToken, &outputLength, to); 604160814Ssimon 605280304Sjkim return (returnCode | reasonCode) ? 0 : 1; 606280304Sjkim} 607160814Ssimon 608280304Sjkim# define SSL_SIG_LEN 36 609160814Ssimon 610280304Sjkimstatic int cca_rsa_verify(int type, const unsigned char *m, 611280304Sjkim unsigned int m_len, const unsigned char *sigbuf, 612280304Sjkim unsigned int siglen, const RSA *rsa) 613280304Sjkim{ 614280304Sjkim long returnCode; 615280304Sjkim long reasonCode; 616280304Sjkim long lsiglen = siglen; 617280304Sjkim long exitDataLength = 0; 618280304Sjkim unsigned char exitData[8]; 619280304Sjkim long ruleArrayLength = 1; 620280304Sjkim unsigned char ruleArray[8] = "PKCS-1.1"; 621280304Sjkim long keyTokenLength; 622280304Sjkim unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); 623280304Sjkim long length = SSL_SIG_LEN; 624280304Sjkim long keyLength; 625280304Sjkim unsigned char *hashBuffer = NULL; 626280304Sjkim X509_SIG sig; 627280304Sjkim ASN1_TYPE parameter; 628280304Sjkim X509_ALGOR algorithm; 629280304Sjkim ASN1_OCTET_STRING digest; 630160814Ssimon 631280304Sjkim keyTokenLength = *(long *)keyToken; 632280304Sjkim keyToken += sizeof(long); 633160814Ssimon 634280304Sjkim if (type == NID_md5 || type == NID_sha1) { 635280304Sjkim sig.algor = &algorithm; 636280304Sjkim algorithm.algorithm = OBJ_nid2obj(type); 637160814Ssimon 638280304Sjkim if (!algorithm.algorithm) { 639280304Sjkim CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 640280304Sjkim CCA4758_R_UNKNOWN_ALGORITHM_TYPE); 641280304Sjkim return 0; 642280304Sjkim } 643160814Ssimon 644280304Sjkim if (!algorithm.algorithm->length) { 645280304Sjkim CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 646280304Sjkim CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); 647280304Sjkim return 0; 648280304Sjkim } 649160814Ssimon 650280304Sjkim parameter.type = V_ASN1_NULL; 651280304Sjkim parameter.value.ptr = NULL; 652280304Sjkim algorithm.parameter = ¶meter; 653160814Ssimon 654280304Sjkim sig.digest = &digest; 655280304Sjkim sig.digest->data = (unsigned char *)m; 656280304Sjkim sig.digest->length = m_len; 657160814Ssimon 658280304Sjkim length = i2d_X509_SIG(&sig, NULL); 659280304Sjkim } 660160814Ssimon 661280304Sjkim keyLength = RSA_size(rsa); 662160814Ssimon 663280304Sjkim if (length - RSA_PKCS1_PADDING > keyLength) { 664280304Sjkim CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 665280304Sjkim CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 666280304Sjkim return 0; 667280304Sjkim } 668160814Ssimon 669280304Sjkim switch (type) { 670280304Sjkim case NID_md5_sha1: 671280304Sjkim if (m_len != SSL_SIG_LEN) { 672280304Sjkim CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 673280304Sjkim CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 674280304Sjkim return 0; 675280304Sjkim } 676160814Ssimon 677280304Sjkim hashBuffer = (unsigned char *)m; 678280304Sjkim length = m_len; 679280304Sjkim break; 680280304Sjkim case NID_md5: 681280304Sjkim { 682280304Sjkim unsigned char *ptr; 683280304Sjkim ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); 684280304Sjkim if (!hashBuffer) { 685280304Sjkim CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE); 686280304Sjkim return 0; 687280304Sjkim } 688160814Ssimon 689280304Sjkim i2d_X509_SIG(&sig, &ptr); 690280304Sjkim } 691280304Sjkim break; 692280304Sjkim case NID_sha1: 693280304Sjkim { 694280304Sjkim unsigned char *ptr; 695280304Sjkim ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); 696280304Sjkim if (!hashBuffer) { 697280304Sjkim CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE); 698280304Sjkim return 0; 699280304Sjkim } 700280304Sjkim i2d_X509_SIG(&sig, &ptr); 701280304Sjkim } 702280304Sjkim break; 703280304Sjkim default: 704280304Sjkim return 0; 705280304Sjkim } 706160814Ssimon 707280304Sjkim digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength, 708280304Sjkim exitData, &ruleArrayLength, ruleArray, 709280304Sjkim &keyTokenLength, keyToken, &length, hashBuffer, 710280304Sjkim &lsiglen, (unsigned char *)sigbuf); 711160814Ssimon 712280304Sjkim if (type == NID_sha1 || type == NID_md5) { 713280304Sjkim OPENSSL_cleanse(hashBuffer, keyLength + 1); 714280304Sjkim OPENSSL_free(hashBuffer); 715280304Sjkim } 716160814Ssimon 717280304Sjkim return ((returnCode || reasonCode) ? 0 : 1); 718280304Sjkim} 719160814Ssimon 720280304Sjkim# define SSL_SIG_LEN 36 721160814Ssimon 722160814Ssimonstatic int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, 723280304Sjkim unsigned char *sigret, unsigned int *siglen, 724280304Sjkim const RSA *rsa) 725280304Sjkim{ 726280304Sjkim long returnCode; 727280304Sjkim long reasonCode; 728280304Sjkim long exitDataLength = 0; 729280304Sjkim unsigned char exitData[8]; 730280304Sjkim long ruleArrayLength = 1; 731280304Sjkim unsigned char ruleArray[8] = "PKCS-1.1"; 732280304Sjkim long outputLength = 256; 733280304Sjkim long outputBitLength; 734280304Sjkim long keyTokenLength; 735280304Sjkim unsigned char *hashBuffer = NULL; 736280304Sjkim unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); 737280304Sjkim long length = SSL_SIG_LEN; 738280304Sjkim long keyLength; 739280304Sjkim X509_SIG sig; 740280304Sjkim ASN1_TYPE parameter; 741280304Sjkim X509_ALGOR algorithm; 742280304Sjkim ASN1_OCTET_STRING digest; 743160814Ssimon 744280304Sjkim keyTokenLength = *(long *)keyToken; 745280304Sjkim keyToken += sizeof(long); 746160814Ssimon 747280304Sjkim if (type == NID_md5 || type == NID_sha1) { 748280304Sjkim sig.algor = &algorithm; 749280304Sjkim algorithm.algorithm = OBJ_nid2obj(type); 750160814Ssimon 751280304Sjkim if (!algorithm.algorithm) { 752280304Sjkim CCA4758err(CCA4758_F_CCA_RSA_SIGN, 753280304Sjkim CCA4758_R_UNKNOWN_ALGORITHM_TYPE); 754280304Sjkim return 0; 755280304Sjkim } 756160814Ssimon 757280304Sjkim if (!algorithm.algorithm->length) { 758280304Sjkim CCA4758err(CCA4758_F_CCA_RSA_SIGN, 759280304Sjkim CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); 760280304Sjkim return 0; 761280304Sjkim } 762160814Ssimon 763280304Sjkim parameter.type = V_ASN1_NULL; 764280304Sjkim parameter.value.ptr = NULL; 765280304Sjkim algorithm.parameter = ¶meter; 766160814Ssimon 767280304Sjkim sig.digest = &digest; 768280304Sjkim sig.digest->data = (unsigned char *)m; 769280304Sjkim sig.digest->length = m_len; 770160814Ssimon 771280304Sjkim length = i2d_X509_SIG(&sig, NULL); 772280304Sjkim } 773160814Ssimon 774280304Sjkim keyLength = RSA_size(rsa); 775160814Ssimon 776280304Sjkim if (length - RSA_PKCS1_PADDING > keyLength) { 777280304Sjkim CCA4758err(CCA4758_F_CCA_RSA_SIGN, 778280304Sjkim CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 779280304Sjkim return 0; 780280304Sjkim } 781160814Ssimon 782280304Sjkim switch (type) { 783280304Sjkim case NID_md5_sha1: 784280304Sjkim if (m_len != SSL_SIG_LEN) { 785280304Sjkim CCA4758err(CCA4758_F_CCA_RSA_SIGN, 786280304Sjkim CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 787280304Sjkim return 0; 788280304Sjkim } 789280304Sjkim hashBuffer = (unsigned char *)m; 790280304Sjkim length = m_len; 791280304Sjkim break; 792280304Sjkim case NID_md5: 793280304Sjkim { 794280304Sjkim unsigned char *ptr; 795280304Sjkim ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); 796280304Sjkim if (!hashBuffer) { 797280304Sjkim CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); 798280304Sjkim return 0; 799280304Sjkim } 800280304Sjkim i2d_X509_SIG(&sig, &ptr); 801280304Sjkim } 802280304Sjkim break; 803280304Sjkim case NID_sha1: 804280304Sjkim { 805280304Sjkim unsigned char *ptr; 806280304Sjkim ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); 807280304Sjkim if (!hashBuffer) { 808280304Sjkim CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); 809280304Sjkim return 0; 810280304Sjkim } 811280304Sjkim i2d_X509_SIG(&sig, &ptr); 812280304Sjkim } 813280304Sjkim break; 814280304Sjkim default: 815280304Sjkim return 0; 816280304Sjkim } 817160814Ssimon 818280304Sjkim digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength, 819280304Sjkim exitData, &ruleArrayLength, ruleArray, 820280304Sjkim &keyTokenLength, keyToken, &length, hashBuffer, 821280304Sjkim &outputLength, &outputBitLength, sigret); 822160814Ssimon 823280304Sjkim if (type == NID_sha1 || type == NID_md5) { 824280304Sjkim OPENSSL_cleanse(hashBuffer, keyLength + 1); 825280304Sjkim OPENSSL_free(hashBuffer); 826280304Sjkim } 827160814Ssimon 828280304Sjkim *siglen = outputLength; 829160814Ssimon 830280304Sjkim return ((returnCode || reasonCode) ? 0 : 1); 831280304Sjkim} 832160814Ssimon 833280304Sjkimstatic int getModulusAndExponent(const unsigned char *token, 834280304Sjkim long *exponentLength, 835280304Sjkim unsigned char *exponent, long *modulusLength, 836280304Sjkim long *modulusFieldLength, 837280304Sjkim unsigned char *modulus) 838280304Sjkim{ 839280304Sjkim unsigned long len; 840160814Ssimon 841280304Sjkim if (*token++ != (char)0x1E) /* internal PKA token? */ 842280304Sjkim return 0; 843160814Ssimon 844280304Sjkim if (*token++) /* token version must be zero */ 845280304Sjkim return 0; 846160814Ssimon 847280304Sjkim len = *token++; 848280304Sjkim len = len << 8; 849280304Sjkim len |= (unsigned char)*token++; 850160814Ssimon 851280304Sjkim token += 4; /* skip reserved bytes */ 852160814Ssimon 853280304Sjkim if (*token++ == (char)0x04) { 854280304Sjkim if (*token++) /* token version must be zero */ 855280304Sjkim return 0; 856160814Ssimon 857280304Sjkim len = *token++; 858280304Sjkim len = len << 8; 859280304Sjkim len |= (unsigned char)*token++; 860160814Ssimon 861280304Sjkim token += 2; /* skip reserved section */ 862160814Ssimon 863280304Sjkim len = *token++; 864280304Sjkim len = len << 8; 865280304Sjkim len |= (unsigned char)*token++; 866160814Ssimon 867280304Sjkim *exponentLength = len; 868160814Ssimon 869280304Sjkim len = *token++; 870280304Sjkim len = len << 8; 871280304Sjkim len |= (unsigned char)*token++; 872160814Ssimon 873280304Sjkim *modulusLength = len; 874160814Ssimon 875280304Sjkim len = *token++; 876280304Sjkim len = len << 8; 877280304Sjkim len |= (unsigned char)*token++; 878160814Ssimon 879280304Sjkim *modulusFieldLength = len; 880160814Ssimon 881280304Sjkim memcpy(exponent, token, *exponentLength); 882280304Sjkim token += *exponentLength; 883160814Ssimon 884280304Sjkim memcpy(modulus, token, *modulusFieldLength); 885280304Sjkim return 1; 886280304Sjkim } 887280304Sjkim return 0; 888280304Sjkim} 889160814Ssimon 890280304Sjkim# endif /* OPENSSL_NO_RSA */ 891160814Ssimon 892160814Ssimonstatic int cca_random_status(void) 893280304Sjkim{ 894280304Sjkim return 1; 895280304Sjkim} 896160814Ssimon 897280304Sjkimstatic int cca_get_random_bytes(unsigned char *buf, int num) 898280304Sjkim{ 899280304Sjkim long ret_code; 900280304Sjkim long reason_code; 901280304Sjkim long exit_data_length; 902280304Sjkim unsigned char exit_data[4]; 903280304Sjkim unsigned char form[] = "RANDOM "; 904280304Sjkim unsigned char rand_buf[8]; 905160814Ssimon 906280304Sjkim while (num >= (int)sizeof(rand_buf)) { 907280304Sjkim randomNumberGenerate(&ret_code, &reason_code, &exit_data_length, 908280304Sjkim exit_data, form, rand_buf); 909280304Sjkim if (ret_code) 910280304Sjkim return 0; 911280304Sjkim num -= sizeof(rand_buf); 912280304Sjkim memcpy(buf, rand_buf, sizeof(rand_buf)); 913280304Sjkim buf += sizeof(rand_buf); 914280304Sjkim } 915160814Ssimon 916280304Sjkim if (num) { 917280304Sjkim randomNumberGenerate(&ret_code, &reason_code, NULL, NULL, 918280304Sjkim form, rand_buf); 919280304Sjkim if (ret_code) 920280304Sjkim return 0; 921280304Sjkim memcpy(buf, rand_buf, num); 922280304Sjkim } 923160814Ssimon 924280304Sjkim return 1; 925280304Sjkim} 926160814Ssimon 927280304Sjkim# ifndef OPENSSL_NO_RSA 928160814Ssimonstatic void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx, 929280304Sjkim long argl, void *argp) 930280304Sjkim{ 931280304Sjkim if (item) 932280304Sjkim OPENSSL_free(item); 933280304Sjkim} 934280304Sjkim# endif 935160814Ssimon 936160814Ssimon/* Goo to handle building as a dynamic engine */ 937280304Sjkim# ifndef OPENSSL_NO_DYNAMIC_ENGINE 938160814Ssimonstatic int bind_fn(ENGINE *e, const char *id) 939280304Sjkim{ 940280304Sjkim if (id && (strcmp(id, engine_4758_cca_id) != 0) && 941280304Sjkim (strcmp(id, engine_4758_cca_id_alt) != 0)) 942280304Sjkim return 0; 943280304Sjkim if (!bind_helper(e)) 944280304Sjkim return 0; 945280304Sjkim return 1; 946280304Sjkim} 947280304Sjkim 948160814SsimonIMPLEMENT_DYNAMIC_CHECK_FN() 949280304Sjkim IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) 950280304Sjkim# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ 951280304Sjkim# endif /* !OPENSSL_NO_HW_4758_CCA */ 952280304Sjkim#endif /* !OPENSSL_NO_HW */ 953