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 10280297Sjkim * 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 65280297Sjkim# include <openssl/rsa.h> 66160814Ssimon#endif 67160814Ssimon#include <openssl/bn.h> 68160814Ssimon 69160814Ssimon#ifndef OPENSSL_NO_HW 70280297Sjkim# ifndef OPENSSL_NO_HW_4758_CCA 71160814Ssimon 72280297Sjkim# ifdef FLAT_INC 73280297Sjkim# include "hw_4758_cca.h" 74280297Sjkim# else 75280297Sjkim# include "vendor_defns/hw_4758_cca.h" 76280297Sjkim# endif 77160814Ssimon 78280297Sjkim# 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); 83280297Sjkimstatic int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, 84280297Sjkim void (*f) (void)); 85160814Ssimon 86160814Ssimon/* rsa functions */ 87280297Sjkim/* -------------*/ 88280297Sjkim# ifndef OPENSSL_NO_RSA 89160814Ssimonstatic int cca_rsa_pub_enc(int flen, const unsigned char *from, 90280297Sjkim unsigned char *to, RSA *rsa, int padding); 91160814Ssimonstatic int cca_rsa_priv_dec(int flen, const unsigned char *from, 92280297Sjkim unsigned char *to, RSA *rsa, int padding); 93160814Ssimonstatic int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, 94280297Sjkim unsigned char *sigret, unsigned int *siglen, 95280297Sjkim const RSA *rsa); 96280297Sjkimstatic int cca_rsa_verify(int dtype, const unsigned char *m, 97280297Sjkim unsigned int m_len, const unsigned char *sigbuf, 98280297Sjkim unsigned int siglen, const RSA *rsa); 99160814Ssimon 100160814Ssimon/* utility functions */ 101280297Sjkim/* ---------------------*/ 102280297Sjkimstatic EVP_PKEY *ibm_4758_load_privkey(ENGINE *, const char *, 103280297Sjkim UI_METHOD *ui_method, 104280297Sjkim void *callback_data); 105280297Sjkimstatic EVP_PKEY *ibm_4758_load_pubkey(ENGINE *, const char *, 106280297Sjkim UI_METHOD *ui_method, 107280297Sjkim void *callback_data); 108160814Ssimon 109280297Sjkimstatic int getModulusAndExponent(const unsigned char *token, 110280297Sjkim long *exponentLength, 111280297Sjkim unsigned char *exponent, long *modulusLength, 112280297Sjkim long *modulusFieldLength, 113280297Sjkim unsigned char *modulus); 114280297Sjkim# endif 115160814Ssimon 116160814Ssimon/* RAND number functions */ 117280297Sjkim/* ---------------------*/ 118280297Sjkimstatic int cca_get_random_bytes(unsigned char *, int); 119160814Ssimonstatic int cca_random_status(void); 120160814Ssimon 121280297Sjkim# ifndef OPENSSL_NO_RSA 122160814Ssimonstatic void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 123280297Sjkim int idx, long argl, void *argp); 124280297Sjkim# endif 125160814Ssimon 126160814Ssimon/* Function pointers for CCA verbs */ 127280297Sjkim/* -------------------------------*/ 128280297Sjkim# 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; 135280297Sjkim# endif 136160814Ssimonstatic F_RANDOMNUMBERGENERATE randomNumberGenerate; 137160814Ssimon 138160814Ssimon/* static variables */ 139280297Sjkim/* ----------------*/ 140160814Ssimonstatic const char *CCA4758_LIB_NAME = NULL; 141160814Ssimonstatic const char *get_CCA4758_LIB_NAME(void) 142280297Sjkim{ 143280297Sjkim if (CCA4758_LIB_NAME) 144280297Sjkim return CCA4758_LIB_NAME; 145280297Sjkim return CCA_LIB_NAME; 146280297Sjkim} 147280297Sjkim 148160814Ssimonstatic void free_CCA4758_LIB_NAME(void) 149280297Sjkim{ 150280297Sjkim if (CCA4758_LIB_NAME) 151280297Sjkim OPENSSL_free((void *)CCA4758_LIB_NAME); 152280297Sjkim CCA4758_LIB_NAME = NULL; 153280297Sjkim} 154280297Sjkim 155160814Ssimonstatic long set_CCA4758_LIB_NAME(const char *name) 156280297Sjkim{ 157280297Sjkim free_CCA4758_LIB_NAME(); 158280297Sjkim return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0); 159280297Sjkim} 160160814Ssimon 161280297Sjkim# ifndef OPENSSL_NO_RSA 162280297Sjkimstatic const char *n_keyRecordRead = CSNDKRR; 163280297Sjkimstatic const char *n_digitalSignatureGenerate = CSNDDSG; 164280297Sjkimstatic const char *n_digitalSignatureVerify = CSNDDSV; 165280297Sjkimstatic const char *n_publicKeyExtract = CSNDPKX; 166280297Sjkimstatic const char *n_pkaEncrypt = CSNDPKE; 167280297Sjkimstatic const char *n_pkaDecrypt = CSNDPKD; 168280297Sjkim# endif 169280297Sjkimstatic const char *n_randomNumberGenerate = CSNBRNG; 170280297Sjkim 171280297Sjkim# ifndef OPENSSL_NO_RSA 172160814Ssimonstatic int hndidx = -1; 173280297Sjkim# endif 174160814Ssimonstatic DSO *dso = NULL; 175160814Ssimon 176160814Ssimon/* openssl engine initialization structures */ 177280297Sjkim/* ----------------------------------------*/ 178160814Ssimon 179280297Sjkim# define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE 180280297Sjkimstatic const ENGINE_CMD_DEFN cca4758_cmd_defns[] = { 181280297Sjkim {CCA4758_CMD_SO_PATH, 182280297Sjkim "SO_PATH", 183280297Sjkim "Specifies the path to the '4758cca' shared library", 184280297Sjkim ENGINE_CMD_FLAG_STRING}, 185280297Sjkim {0, NULL, NULL, 0} 186280297Sjkim}; 187160814Ssimon 188280297Sjkim# ifndef OPENSSL_NO_RSA 189280297Sjkimstatic RSA_METHOD ibm_4758_cca_rsa = { 190280297Sjkim "IBM 4758 CCA RSA method", 191280297Sjkim cca_rsa_pub_enc, 192280297Sjkim NULL, 193280297Sjkim NULL, 194280297Sjkim cca_rsa_priv_dec, 195280297Sjkim NULL, /* rsa_mod_exp, */ 196280297Sjkim NULL, /* mod_exp_mont, */ 197280297Sjkim NULL, /* init */ 198280297Sjkim NULL, /* finish */ 199280297Sjkim RSA_FLAG_SIGN_VER, /* flags */ 200280297Sjkim NULL, /* app_data */ 201280297Sjkim cca_rsa_sign, /* rsa_sign */ 202280297Sjkim cca_rsa_verify, /* rsa_verify */ 203280297Sjkim NULL /* rsa_keygen */ 204280297Sjkim}; 205280297Sjkim# endif 206160814Ssimon 207280297Sjkimstatic RAND_METHOD ibm_4758_cca_rand = { 208280297Sjkim /* "IBM 4758 RAND method", */ 209280297Sjkim NULL, /* seed */ 210280297Sjkim cca_get_random_bytes, /* get random bytes from the card */ 211280297Sjkim NULL, /* cleanup */ 212280297Sjkim NULL, /* add */ 213280297Sjkim cca_get_random_bytes, /* pseudo rand */ 214280297Sjkim cca_random_status, /* status */ 215280297Sjkim}; 216160814Ssimon 217160814Ssimonstatic const char *engine_4758_cca_id = "4758cca"; 218280297Sjkimstatic const char *engine_4758_cca_name = 219280297Sjkim "IBM 4758 CCA hardware engine support"; 220280297Sjkim# 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"; 223280297Sjkim# endif 224160814Ssimon 225160814Ssimon/* engine implementation */ 226280297Sjkim/* ---------------------*/ 227160814Ssimonstatic int bind_helper(ENGINE *e) 228280297Sjkim{ 229280297Sjkim if (!ENGINE_set_id(e, engine_4758_cca_id) || 230280297Sjkim !ENGINE_set_name(e, engine_4758_cca_name) || 231280297Sjkim# ifndef OPENSSL_NO_RSA 232280297Sjkim !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) || 233280297Sjkim# endif 234280297Sjkim !ENGINE_set_RAND(e, &ibm_4758_cca_rand) || 235280297Sjkim !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) || 236280297Sjkim !ENGINE_set_init_function(e, ibm_4758_cca_init) || 237280297Sjkim !ENGINE_set_finish_function(e, ibm_4758_cca_finish) || 238280297Sjkim !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) || 239280297Sjkim# ifndef OPENSSL_NO_RSA 240280297Sjkim !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) || 241280297Sjkim !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) || 242280297Sjkim# endif 243280297Sjkim !ENGINE_set_cmd_defns(e, cca4758_cmd_defns)) 244280297Sjkim return 0; 245280297Sjkim /* Ensure the error handling is set up */ 246280297Sjkim ERR_load_CCA4758_strings(); 247280297Sjkim return 1; 248280297Sjkim} 249160814Ssimon 250280297Sjkim# ifdef OPENSSL_NO_DYNAMIC_ENGINE 251160814Ssimonstatic ENGINE *engine_4758_cca(void) 252280297Sjkim{ 253280297Sjkim ENGINE *ret = ENGINE_new(); 254280297Sjkim if (!ret) 255280297Sjkim return NULL; 256280297Sjkim if (!bind_helper(ret)) { 257280297Sjkim ENGINE_free(ret); 258280297Sjkim return NULL; 259280297Sjkim } 260280297Sjkim return ret; 261280297Sjkim} 262160814Ssimon 263160814Ssimonvoid ENGINE_load_4758cca(void) 264280297Sjkim{ 265280297Sjkim ENGINE *e_4758 = engine_4758_cca(); 266280297Sjkim if (!e_4758) 267280297Sjkim return; 268280297Sjkim ENGINE_add(e_4758); 269280297Sjkim ENGINE_free(e_4758); 270280297Sjkim ERR_clear_error(); 271280297Sjkim} 272280297Sjkim# endif 273160814Ssimon 274160814Ssimonstatic int ibm_4758_cca_destroy(ENGINE *e) 275280297Sjkim{ 276280297Sjkim ERR_unload_CCA4758_strings(); 277280297Sjkim free_CCA4758_LIB_NAME(); 278280297Sjkim return 1; 279280297Sjkim} 280160814Ssimon 281160814Ssimonstatic int ibm_4758_cca_init(ENGINE *e) 282280297Sjkim{ 283280297Sjkim if (dso) { 284280297Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_ALREADY_LOADED); 285280297Sjkim goto err; 286280297Sjkim } 287160814Ssimon 288280297Sjkim dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0); 289280297Sjkim if (!dso) { 290280297Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); 291280297Sjkim goto err; 292280297Sjkim } 293280297Sjkim# ifndef OPENSSL_NO_RSA 294280297Sjkim if (!(keyRecordRead = (F_KEYRECORDREAD) 295280297Sjkim DSO_bind_func(dso, n_keyRecordRead)) || 296280297Sjkim !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 297280297Sjkim DSO_bind_func(dso, n_randomNumberGenerate)) || 298280297Sjkim !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 299280297Sjkim DSO_bind_func(dso, n_digitalSignatureGenerate)) || 300280297Sjkim !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY) 301280297Sjkim DSO_bind_func(dso, n_digitalSignatureVerify)) || 302280297Sjkim !(publicKeyExtract = (F_PUBLICKEYEXTRACT) 303280297Sjkim DSO_bind_func(dso, n_publicKeyExtract)) || 304280297Sjkim !(pkaEncrypt = (F_PKAENCRYPT) 305280297Sjkim DSO_bind_func(dso, n_pkaEncrypt)) || !(pkaDecrypt = (F_PKADECRYPT) 306280297Sjkim DSO_bind_func(dso, 307280297Sjkim n_pkaDecrypt))) 308280297Sjkim { 309280297Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); 310280297Sjkim goto err; 311280297Sjkim } 312280297Sjkim# else 313280297Sjkim if (!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 314280297Sjkim DSO_bind_func(dso, n_randomNumberGenerate))) { 315280297Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); 316280297Sjkim goto err; 317280297Sjkim } 318280297Sjkim# endif 319160814Ssimon 320280297Sjkim# ifndef OPENSSL_NO_RSA 321280297Sjkim hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle", 322280297Sjkim NULL, NULL, cca_ex_free); 323280297Sjkim# endif 324160814Ssimon 325280297Sjkim return 1; 326280297Sjkim err: 327280297Sjkim if (dso) 328280297Sjkim DSO_free(dso); 329280297Sjkim dso = NULL; 330160814Ssimon 331280297Sjkim# ifndef OPENSSL_NO_RSA 332280297Sjkim keyRecordRead = (F_KEYRECORDREAD) 0; 333280297Sjkim digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0; 334280297Sjkim digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; 335280297Sjkim publicKeyExtract = (F_PUBLICKEYEXTRACT)0; 336280297Sjkim pkaEncrypt = (F_PKAENCRYPT) 0; 337280297Sjkim pkaDecrypt = (F_PKADECRYPT) 0; 338280297Sjkim# endif 339280297Sjkim randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; 340280297Sjkim return 0; 341280297Sjkim} 342160814Ssimon 343160814Ssimonstatic int ibm_4758_cca_finish(ENGINE *e) 344280297Sjkim{ 345280297Sjkim free_CCA4758_LIB_NAME(); 346280297Sjkim if (!dso) { 347280297Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_NOT_LOADED); 348280297Sjkim return 0; 349280297Sjkim } 350280297Sjkim if (!DSO_free(dso)) { 351280297Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_UNIT_FAILURE); 352280297Sjkim return 0; 353280297Sjkim } 354280297Sjkim dso = NULL; 355280297Sjkim# ifndef OPENSSL_NO_RSA 356280297Sjkim keyRecordRead = (F_KEYRECORDREAD) 0; 357280297Sjkim randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; 358280297Sjkim digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0; 359280297Sjkim digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; 360280297Sjkim publicKeyExtract = (F_PUBLICKEYEXTRACT)0; 361280297Sjkim pkaEncrypt = (F_PKAENCRYPT) 0; 362280297Sjkim pkaDecrypt = (F_PKADECRYPT) 0; 363280297Sjkim# endif 364280297Sjkim randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; 365280297Sjkim return 1; 366280297Sjkim} 367160814Ssimon 368280297Sjkimstatic int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, 369280297Sjkim void (*f) (void)) 370280297Sjkim{ 371280297Sjkim int initialised = ((dso == NULL) ? 0 : 1); 372280297Sjkim switch (cmd) { 373280297Sjkim case CCA4758_CMD_SO_PATH: 374280297Sjkim if (p == NULL) { 375280297Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, 376280297Sjkim ERR_R_PASSED_NULL_PARAMETER); 377280297Sjkim return 0; 378280297Sjkim } 379280297Sjkim if (initialised) { 380280297Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, CCA4758_R_ALREADY_LOADED); 381280297Sjkim return 0; 382280297Sjkim } 383280297Sjkim return set_CCA4758_LIB_NAME((const char *)p); 384280297Sjkim default: 385280297Sjkim break; 386280297Sjkim } 387280297Sjkim CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, 388280297Sjkim CCA4758_R_COMMAND_NOT_IMPLEMENTED); 389280297Sjkim return 0; 390280297Sjkim} 391160814Ssimon 392280297Sjkim# ifndef OPENSSL_NO_RSA 393160814Ssimon 394280297Sjkim# define MAX_CCA_PKA_TOKEN_SIZE 2500 395160814Ssimon 396280297Sjkimstatic EVP_PKEY *ibm_4758_load_privkey(ENGINE *e, const char *key_id, 397280297Sjkim UI_METHOD *ui_method, 398280297Sjkim void *callback_data) 399280297Sjkim{ 400280297Sjkim RSA *rtmp = NULL; 401280297Sjkim EVP_PKEY *res = NULL; 402280297Sjkim unsigned char *keyToken = NULL; 403280297Sjkim unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE]; 404280297Sjkim long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 405280297Sjkim long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 406280297Sjkim long returnCode; 407280297Sjkim long reasonCode; 408280297Sjkim long exitDataLength = 0; 409280297Sjkim long ruleArrayLength = 0; 410280297Sjkim unsigned char exitData[8]; 411280297Sjkim unsigned char ruleArray[8]; 412280297Sjkim unsigned char keyLabel[64]; 413280297Sjkim unsigned long keyLabelLength = strlen(key_id); 414280297Sjkim unsigned char modulus[256]; 415280297Sjkim long modulusFieldLength = sizeof(modulus); 416280297Sjkim long modulusLength = 0; 417280297Sjkim unsigned char exponent[256]; 418280297Sjkim long exponentLength = sizeof(exponent); 419160814Ssimon 420280297Sjkim if (keyLabelLength > sizeof(keyLabel)) { 421280297Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 422280297Sjkim CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 423280297Sjkim return NULL; 424280297Sjkim } 425160814Ssimon 426280297Sjkim memset(keyLabel, ' ', sizeof(keyLabel)); 427280297Sjkim memcpy(keyLabel, key_id, keyLabelLength); 428160814Ssimon 429280297Sjkim keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); 430280297Sjkim if (!keyToken) { 431280297Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); 432280297Sjkim goto err; 433280297Sjkim } 434160814Ssimon 435280297Sjkim keyRecordRead(&returnCode, &reasonCode, &exitDataLength, 436280297Sjkim exitData, &ruleArrayLength, ruleArray, keyLabel, 437280297Sjkim &keyTokenLength, keyToken + sizeof(long)); 438160814Ssimon 439280297Sjkim if (returnCode) { 440280297Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 441280297Sjkim CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 442280297Sjkim goto err; 443280297Sjkim } 444160814Ssimon 445280297Sjkim publicKeyExtract(&returnCode, &reasonCode, &exitDataLength, 446280297Sjkim exitData, &ruleArrayLength, ruleArray, &keyTokenLength, 447280297Sjkim keyToken + sizeof(long), &pubKeyTokenLength, 448280297Sjkim pubKeyToken); 449160814Ssimon 450280297Sjkim if (returnCode) { 451280297Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 452280297Sjkim CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 453280297Sjkim goto err; 454280297Sjkim } 455160814Ssimon 456280297Sjkim if (!getModulusAndExponent(pubKeyToken, &exponentLength, 457280297Sjkim exponent, &modulusLength, &modulusFieldLength, 458280297Sjkim modulus)) { 459280297Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 460280297Sjkim CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 461280297Sjkim goto err; 462280297Sjkim } 463160814Ssimon 464280297Sjkim (*(long *)keyToken) = keyTokenLength; 465280297Sjkim rtmp = RSA_new_method(e); 466306195Sjkim if (rtmp == NULL) { 467306195Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); 468306195Sjkim goto err; 469306195Sjkim } 470280297Sjkim RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); 471160814Ssimon 472280297Sjkim rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); 473280297Sjkim rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); 474280297Sjkim rtmp->flags |= RSA_FLAG_EXT_PKEY; 475160814Ssimon 476280297Sjkim res = EVP_PKEY_new(); 477280297Sjkim EVP_PKEY_assign_RSA(res, rtmp); 478160814Ssimon 479280297Sjkim return res; 480280297Sjkim err: 481280297Sjkim if (keyToken) 482280297Sjkim OPENSSL_free(keyToken); 483280297Sjkim return NULL; 484280297Sjkim} 485160814Ssimon 486280297Sjkimstatic EVP_PKEY *ibm_4758_load_pubkey(ENGINE *e, const char *key_id, 487280297Sjkim UI_METHOD *ui_method, 488280297Sjkim void *callback_data) 489280297Sjkim{ 490280297Sjkim RSA *rtmp = NULL; 491280297Sjkim EVP_PKEY *res = NULL; 492280297Sjkim unsigned char *keyToken = NULL; 493280297Sjkim long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 494280297Sjkim long returnCode; 495280297Sjkim long reasonCode; 496280297Sjkim long exitDataLength = 0; 497280297Sjkim long ruleArrayLength = 0; 498280297Sjkim unsigned char exitData[8]; 499280297Sjkim unsigned char ruleArray[8]; 500280297Sjkim unsigned char keyLabel[64]; 501280297Sjkim unsigned long keyLabelLength = strlen(key_id); 502280297Sjkim unsigned char modulus[512]; 503280297Sjkim long modulusFieldLength = sizeof(modulus); 504280297Sjkim long modulusLength = 0; 505280297Sjkim unsigned char exponent[512]; 506280297Sjkim long exponentLength = sizeof(exponent); 507160814Ssimon 508280297Sjkim if (keyLabelLength > sizeof(keyLabel)) { 509280297Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 510280297Sjkim CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 511280297Sjkim return NULL; 512280297Sjkim } 513160814Ssimon 514280297Sjkim memset(keyLabel, ' ', sizeof(keyLabel)); 515280297Sjkim memcpy(keyLabel, key_id, keyLabelLength); 516160814Ssimon 517280297Sjkim keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); 518280297Sjkim if (!keyToken) { 519280297Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); 520280297Sjkim goto err; 521280297Sjkim } 522160814Ssimon 523280297Sjkim keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData, 524280297Sjkim &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength, 525280297Sjkim keyToken + sizeof(long)); 526160814Ssimon 527280297Sjkim if (returnCode) { 528280297Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); 529280297Sjkim goto err; 530280297Sjkim } 531160814Ssimon 532280297Sjkim if (!getModulusAndExponent(keyToken + sizeof(long), &exponentLength, 533280297Sjkim exponent, &modulusLength, &modulusFieldLength, 534280297Sjkim modulus)) { 535280297Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 536280297Sjkim CCA4758_R_FAILED_LOADING_PUBLIC_KEY); 537280297Sjkim goto err; 538280297Sjkim } 539160814Ssimon 540280297Sjkim (*(long *)keyToken) = keyTokenLength; 541280297Sjkim rtmp = RSA_new_method(e); 542306195Sjkim if (rtmp == NULL) { 543306195Sjkim CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); 544306195Sjkim goto err; 545306195Sjkim } 546280297Sjkim RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); 547280297Sjkim rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); 548280297Sjkim rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); 549280297Sjkim rtmp->flags |= RSA_FLAG_EXT_PKEY; 550280297Sjkim res = EVP_PKEY_new(); 551280297Sjkim EVP_PKEY_assign_RSA(res, rtmp); 552160814Ssimon 553280297Sjkim return res; 554280297Sjkim err: 555280297Sjkim if (keyToken) 556280297Sjkim OPENSSL_free(keyToken); 557280297Sjkim return NULL; 558280297Sjkim} 559160814Ssimon 560160814Ssimonstatic int cca_rsa_pub_enc(int flen, const unsigned char *from, 561280297Sjkim unsigned char *to, RSA *rsa, int padding) 562280297Sjkim{ 563280297Sjkim long returnCode; 564280297Sjkim long reasonCode; 565280297Sjkim long lflen = flen; 566280297Sjkim long exitDataLength = 0; 567280297Sjkim unsigned char exitData[8]; 568280297Sjkim long ruleArrayLength = 1; 569280297Sjkim unsigned char ruleArray[8] = "PKCS-1.2"; 570280297Sjkim long dataStructureLength = 0; 571280297Sjkim unsigned char dataStructure[8]; 572280297Sjkim long outputLength = RSA_size(rsa); 573280297Sjkim long keyTokenLength; 574280297Sjkim unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); 575160814Ssimon 576280297Sjkim keyTokenLength = *(long *)keyToken; 577280297Sjkim keyToken += sizeof(long); 578160814Ssimon 579280297Sjkim pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData, 580280297Sjkim &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from, 581280297Sjkim &dataStructureLength, dataStructure, &keyTokenLength, 582280297Sjkim keyToken, &outputLength, to); 583160814Ssimon 584280297Sjkim if (returnCode || reasonCode) 585280297Sjkim return -(returnCode << 16 | reasonCode); 586280297Sjkim return outputLength; 587280297Sjkim} 588160814Ssimon 589160814Ssimonstatic int cca_rsa_priv_dec(int flen, const unsigned char *from, 590280297Sjkim unsigned char *to, RSA *rsa, int padding) 591280297Sjkim{ 592280297Sjkim long returnCode; 593280297Sjkim long reasonCode; 594280297Sjkim long lflen = flen; 595280297Sjkim long exitDataLength = 0; 596280297Sjkim unsigned char exitData[8]; 597280297Sjkim long ruleArrayLength = 1; 598280297Sjkim unsigned char ruleArray[8] = "PKCS-1.2"; 599280297Sjkim long dataStructureLength = 0; 600280297Sjkim unsigned char dataStructure[8]; 601280297Sjkim long outputLength = RSA_size(rsa); 602280297Sjkim long keyTokenLength; 603280297Sjkim unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); 604160814Ssimon 605280297Sjkim keyTokenLength = *(long *)keyToken; 606280297Sjkim keyToken += sizeof(long); 607160814Ssimon 608280297Sjkim pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData, 609280297Sjkim &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from, 610280297Sjkim &dataStructureLength, dataStructure, &keyTokenLength, 611280297Sjkim keyToken, &outputLength, to); 612160814Ssimon 613280297Sjkim return (returnCode | reasonCode) ? 0 : 1; 614280297Sjkim} 615160814Ssimon 616280297Sjkim# define SSL_SIG_LEN 36 617160814Ssimon 618280297Sjkimstatic int cca_rsa_verify(int type, const unsigned char *m, 619280297Sjkim unsigned int m_len, const unsigned char *sigbuf, 620280297Sjkim unsigned int siglen, const RSA *rsa) 621280297Sjkim{ 622280297Sjkim long returnCode; 623280297Sjkim long reasonCode; 624280297Sjkim long lsiglen = siglen; 625280297Sjkim long exitDataLength = 0; 626280297Sjkim unsigned char exitData[8]; 627280297Sjkim long ruleArrayLength = 1; 628280297Sjkim unsigned char ruleArray[8] = "PKCS-1.1"; 629280297Sjkim long keyTokenLength; 630280297Sjkim unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); 631280297Sjkim long length = SSL_SIG_LEN; 632280297Sjkim long keyLength; 633280297Sjkim unsigned char *hashBuffer = NULL; 634280297Sjkim X509_SIG sig; 635280297Sjkim ASN1_TYPE parameter; 636280297Sjkim X509_ALGOR algorithm; 637280297Sjkim ASN1_OCTET_STRING digest; 638160814Ssimon 639280297Sjkim keyTokenLength = *(long *)keyToken; 640280297Sjkim keyToken += sizeof(long); 641160814Ssimon 642280297Sjkim if (type == NID_md5 || type == NID_sha1) { 643280297Sjkim sig.algor = &algorithm; 644280297Sjkim algorithm.algorithm = OBJ_nid2obj(type); 645160814Ssimon 646280297Sjkim if (!algorithm.algorithm) { 647280297Sjkim CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 648280297Sjkim CCA4758_R_UNKNOWN_ALGORITHM_TYPE); 649280297Sjkim return 0; 650280297Sjkim } 651160814Ssimon 652280297Sjkim if (!algorithm.algorithm->length) { 653280297Sjkim CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 654280297Sjkim CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); 655280297Sjkim return 0; 656280297Sjkim } 657160814Ssimon 658280297Sjkim parameter.type = V_ASN1_NULL; 659280297Sjkim parameter.value.ptr = NULL; 660280297Sjkim algorithm.parameter = ¶meter; 661160814Ssimon 662280297Sjkim sig.digest = &digest; 663280297Sjkim sig.digest->data = (unsigned char *)m; 664280297Sjkim sig.digest->length = m_len; 665160814Ssimon 666280297Sjkim length = i2d_X509_SIG(&sig, NULL); 667280297Sjkim } 668160814Ssimon 669280297Sjkim keyLength = RSA_size(rsa); 670160814Ssimon 671280297Sjkim if (length - RSA_PKCS1_PADDING > keyLength) { 672280297Sjkim CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 673280297Sjkim CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 674280297Sjkim return 0; 675280297Sjkim } 676160814Ssimon 677280297Sjkim switch (type) { 678280297Sjkim case NID_md5_sha1: 679280297Sjkim if (m_len != SSL_SIG_LEN) { 680280297Sjkim CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 681280297Sjkim CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 682280297Sjkim return 0; 683280297Sjkim } 684160814Ssimon 685280297Sjkim hashBuffer = (unsigned char *)m; 686280297Sjkim length = m_len; 687280297Sjkim break; 688280297Sjkim case NID_md5: 689280297Sjkim { 690280297Sjkim unsigned char *ptr; 691280297Sjkim ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); 692280297Sjkim if (!hashBuffer) { 693280297Sjkim CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE); 694280297Sjkim return 0; 695280297Sjkim } 696160814Ssimon 697280297Sjkim i2d_X509_SIG(&sig, &ptr); 698280297Sjkim } 699280297Sjkim break; 700280297Sjkim case NID_sha1: 701280297Sjkim { 702280297Sjkim unsigned char *ptr; 703280297Sjkim ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); 704280297Sjkim if (!hashBuffer) { 705280297Sjkim CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE); 706280297Sjkim return 0; 707280297Sjkim } 708280297Sjkim i2d_X509_SIG(&sig, &ptr); 709280297Sjkim } 710280297Sjkim break; 711280297Sjkim default: 712280297Sjkim return 0; 713280297Sjkim } 714160814Ssimon 715280297Sjkim digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength, 716280297Sjkim exitData, &ruleArrayLength, ruleArray, 717280297Sjkim &keyTokenLength, keyToken, &length, hashBuffer, 718280297Sjkim &lsiglen, (unsigned char *)sigbuf); 719160814Ssimon 720280297Sjkim if (type == NID_sha1 || type == NID_md5) { 721280297Sjkim OPENSSL_cleanse(hashBuffer, keyLength + 1); 722280297Sjkim OPENSSL_free(hashBuffer); 723280297Sjkim } 724160814Ssimon 725280297Sjkim return ((returnCode || reasonCode) ? 0 : 1); 726280297Sjkim} 727160814Ssimon 728280297Sjkim# define SSL_SIG_LEN 36 729160814Ssimon 730160814Ssimonstatic int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, 731280297Sjkim unsigned char *sigret, unsigned int *siglen, 732280297Sjkim const RSA *rsa) 733280297Sjkim{ 734280297Sjkim long returnCode; 735280297Sjkim long reasonCode; 736280297Sjkim long exitDataLength = 0; 737280297Sjkim unsigned char exitData[8]; 738280297Sjkim long ruleArrayLength = 1; 739280297Sjkim unsigned char ruleArray[8] = "PKCS-1.1"; 740280297Sjkim long outputLength = 256; 741280297Sjkim long outputBitLength; 742280297Sjkim long keyTokenLength; 743280297Sjkim unsigned char *hashBuffer = NULL; 744280297Sjkim unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); 745280297Sjkim long length = SSL_SIG_LEN; 746280297Sjkim long keyLength; 747280297Sjkim X509_SIG sig; 748280297Sjkim ASN1_TYPE parameter; 749280297Sjkim X509_ALGOR algorithm; 750280297Sjkim ASN1_OCTET_STRING digest; 751160814Ssimon 752280297Sjkim keyTokenLength = *(long *)keyToken; 753280297Sjkim keyToken += sizeof(long); 754160814Ssimon 755280297Sjkim if (type == NID_md5 || type == NID_sha1) { 756280297Sjkim sig.algor = &algorithm; 757280297Sjkim algorithm.algorithm = OBJ_nid2obj(type); 758160814Ssimon 759280297Sjkim if (!algorithm.algorithm) { 760280297Sjkim CCA4758err(CCA4758_F_CCA_RSA_SIGN, 761280297Sjkim CCA4758_R_UNKNOWN_ALGORITHM_TYPE); 762280297Sjkim return 0; 763280297Sjkim } 764160814Ssimon 765280297Sjkim if (!algorithm.algorithm->length) { 766280297Sjkim CCA4758err(CCA4758_F_CCA_RSA_SIGN, 767280297Sjkim CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); 768280297Sjkim return 0; 769280297Sjkim } 770160814Ssimon 771280297Sjkim parameter.type = V_ASN1_NULL; 772280297Sjkim parameter.value.ptr = NULL; 773280297Sjkim algorithm.parameter = ¶meter; 774160814Ssimon 775280297Sjkim sig.digest = &digest; 776280297Sjkim sig.digest->data = (unsigned char *)m; 777280297Sjkim sig.digest->length = m_len; 778160814Ssimon 779280297Sjkim length = i2d_X509_SIG(&sig, NULL); 780280297Sjkim } 781160814Ssimon 782280297Sjkim keyLength = RSA_size(rsa); 783160814Ssimon 784280297Sjkim if (length - RSA_PKCS1_PADDING > keyLength) { 785280297Sjkim CCA4758err(CCA4758_F_CCA_RSA_SIGN, 786280297Sjkim CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 787280297Sjkim return 0; 788280297Sjkim } 789160814Ssimon 790280297Sjkim switch (type) { 791280297Sjkim case NID_md5_sha1: 792280297Sjkim if (m_len != SSL_SIG_LEN) { 793280297Sjkim CCA4758err(CCA4758_F_CCA_RSA_SIGN, 794280297Sjkim CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 795280297Sjkim return 0; 796280297Sjkim } 797280297Sjkim hashBuffer = (unsigned char *)m; 798280297Sjkim length = m_len; 799280297Sjkim break; 800280297Sjkim case NID_md5: 801280297Sjkim { 802280297Sjkim unsigned char *ptr; 803280297Sjkim ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); 804280297Sjkim if (!hashBuffer) { 805280297Sjkim CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); 806280297Sjkim return 0; 807280297Sjkim } 808280297Sjkim i2d_X509_SIG(&sig, &ptr); 809280297Sjkim } 810280297Sjkim break; 811280297Sjkim case NID_sha1: 812280297Sjkim { 813280297Sjkim unsigned char *ptr; 814280297Sjkim ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); 815280297Sjkim if (!hashBuffer) { 816280297Sjkim CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); 817280297Sjkim return 0; 818280297Sjkim } 819280297Sjkim i2d_X509_SIG(&sig, &ptr); 820280297Sjkim } 821280297Sjkim break; 822280297Sjkim default: 823280297Sjkim return 0; 824280297Sjkim } 825160814Ssimon 826280297Sjkim digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength, 827280297Sjkim exitData, &ruleArrayLength, ruleArray, 828280297Sjkim &keyTokenLength, keyToken, &length, hashBuffer, 829280297Sjkim &outputLength, &outputBitLength, sigret); 830160814Ssimon 831280297Sjkim if (type == NID_sha1 || type == NID_md5) { 832280297Sjkim OPENSSL_cleanse(hashBuffer, keyLength + 1); 833280297Sjkim OPENSSL_free(hashBuffer); 834280297Sjkim } 835160814Ssimon 836280297Sjkim *siglen = outputLength; 837160814Ssimon 838280297Sjkim return ((returnCode || reasonCode) ? 0 : 1); 839280297Sjkim} 840160814Ssimon 841280297Sjkimstatic int getModulusAndExponent(const unsigned char *token, 842280297Sjkim long *exponentLength, 843280297Sjkim unsigned char *exponent, long *modulusLength, 844280297Sjkim long *modulusFieldLength, 845280297Sjkim unsigned char *modulus) 846280297Sjkim{ 847280297Sjkim unsigned long len; 848160814Ssimon 849280297Sjkim if (*token++ != (char)0x1E) /* internal PKA token? */ 850280297Sjkim return 0; 851160814Ssimon 852280297Sjkim if (*token++) /* token version must be zero */ 853280297Sjkim return 0; 854160814Ssimon 855280297Sjkim len = *token++; 856280297Sjkim len = len << 8; 857280297Sjkim len |= (unsigned char)*token++; 858160814Ssimon 859280297Sjkim token += 4; /* skip reserved bytes */ 860160814Ssimon 861280297Sjkim if (*token++ == (char)0x04) { 862280297Sjkim if (*token++) /* token version must be zero */ 863280297Sjkim return 0; 864160814Ssimon 865280297Sjkim len = *token++; 866280297Sjkim len = len << 8; 867280297Sjkim len |= (unsigned char)*token++; 868160814Ssimon 869280297Sjkim token += 2; /* skip reserved section */ 870160814Ssimon 871280297Sjkim len = *token++; 872280297Sjkim len = len << 8; 873280297Sjkim len |= (unsigned char)*token++; 874160814Ssimon 875280297Sjkim *exponentLength = len; 876160814Ssimon 877280297Sjkim len = *token++; 878280297Sjkim len = len << 8; 879280297Sjkim len |= (unsigned char)*token++; 880160814Ssimon 881280297Sjkim *modulusLength = len; 882160814Ssimon 883280297Sjkim len = *token++; 884280297Sjkim len = len << 8; 885280297Sjkim len |= (unsigned char)*token++; 886160814Ssimon 887280297Sjkim *modulusFieldLength = len; 888160814Ssimon 889280297Sjkim memcpy(exponent, token, *exponentLength); 890280297Sjkim token += *exponentLength; 891160814Ssimon 892280297Sjkim memcpy(modulus, token, *modulusFieldLength); 893280297Sjkim return 1; 894280297Sjkim } 895280297Sjkim return 0; 896280297Sjkim} 897160814Ssimon 898280297Sjkim# endif /* OPENSSL_NO_RSA */ 899160814Ssimon 900160814Ssimonstatic int cca_random_status(void) 901280297Sjkim{ 902280297Sjkim return 1; 903280297Sjkim} 904160814Ssimon 905280297Sjkimstatic int cca_get_random_bytes(unsigned char *buf, int num) 906280297Sjkim{ 907280297Sjkim long ret_code; 908280297Sjkim long reason_code; 909280297Sjkim long exit_data_length; 910280297Sjkim unsigned char exit_data[4]; 911280297Sjkim unsigned char form[] = "RANDOM "; 912280297Sjkim unsigned char rand_buf[8]; 913160814Ssimon 914280297Sjkim while (num >= (int)sizeof(rand_buf)) { 915280297Sjkim randomNumberGenerate(&ret_code, &reason_code, &exit_data_length, 916280297Sjkim exit_data, form, rand_buf); 917280297Sjkim if (ret_code) 918280297Sjkim return 0; 919280297Sjkim num -= sizeof(rand_buf); 920280297Sjkim memcpy(buf, rand_buf, sizeof(rand_buf)); 921280297Sjkim buf += sizeof(rand_buf); 922280297Sjkim } 923160814Ssimon 924280297Sjkim if (num) { 925280297Sjkim randomNumberGenerate(&ret_code, &reason_code, NULL, NULL, 926280297Sjkim form, rand_buf); 927280297Sjkim if (ret_code) 928280297Sjkim return 0; 929280297Sjkim memcpy(buf, rand_buf, num); 930280297Sjkim } 931160814Ssimon 932280297Sjkim return 1; 933280297Sjkim} 934160814Ssimon 935280297Sjkim# ifndef OPENSSL_NO_RSA 936160814Ssimonstatic void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx, 937280297Sjkim long argl, void *argp) 938280297Sjkim{ 939280297Sjkim if (item) 940280297Sjkim OPENSSL_free(item); 941280297Sjkim} 942280297Sjkim# endif 943160814Ssimon 944160814Ssimon/* Goo to handle building as a dynamic engine */ 945280297Sjkim# ifndef OPENSSL_NO_DYNAMIC_ENGINE 946160814Ssimonstatic int bind_fn(ENGINE *e, const char *id) 947280297Sjkim{ 948280297Sjkim if (id && (strcmp(id, engine_4758_cca_id) != 0) && 949280297Sjkim (strcmp(id, engine_4758_cca_id_alt) != 0)) 950280297Sjkim return 0; 951280297Sjkim if (!bind_helper(e)) 952280297Sjkim return 0; 953280297Sjkim return 1; 954280297Sjkim} 955280297Sjkim 956160814SsimonIMPLEMENT_DYNAMIC_CHECK_FN() 957280297Sjkim IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) 958280297Sjkim# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ 959280297Sjkim# endif /* !OPENSSL_NO_HW_4758_CCA */ 960280297Sjkim#endif /* !OPENSSL_NO_HW */ 961