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 10160814Ssimon * 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 65160814Ssimon#include <openssl/rsa.h> 66160814Ssimon#endif 67160814Ssimon#include <openssl/bn.h> 68160814Ssimon 69160814Ssimon#ifndef OPENSSL_NO_HW 70160814Ssimon#ifndef OPENSSL_NO_HW_4758_CCA 71160814Ssimon 72160814Ssimon#ifdef FLAT_INC 73160814Ssimon#include "hw_4758_cca.h" 74160814Ssimon#else 75160814Ssimon#include "vendor_defns/hw_4758_cca.h" 76160814Ssimon#endif 77160814Ssimon 78160814Ssimon#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); 83160814Ssimonstatic int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); 84160814Ssimon 85160814Ssimon/* rsa functions */ 86160814Ssimon/*---------------*/ 87160814Ssimon#ifndef OPENSSL_NO_RSA 88160814Ssimonstatic int cca_rsa_pub_enc(int flen, const unsigned char *from, 89160814Ssimon unsigned char *to, RSA *rsa,int padding); 90160814Ssimonstatic int cca_rsa_priv_dec(int flen, const unsigned char *from, 91160814Ssimon unsigned char *to, RSA *rsa,int padding); 92160814Ssimonstatic int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, 93160814Ssimon unsigned char *sigret, unsigned int *siglen, const RSA *rsa); 94160814Ssimonstatic int cca_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len, 95238405Sjkim const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa); 96160814Ssimon 97160814Ssimon/* utility functions */ 98160814Ssimon/*-----------------------*/ 99160814Ssimonstatic EVP_PKEY *ibm_4758_load_privkey(ENGINE*, const char*, 100160814Ssimon UI_METHOD *ui_method, void *callback_data); 101160814Ssimonstatic EVP_PKEY *ibm_4758_load_pubkey(ENGINE*, const char*, 102160814Ssimon UI_METHOD *ui_method, void *callback_data); 103160814Ssimon 104160814Ssimonstatic int getModulusAndExponent(const unsigned char *token, long *exponentLength, 105160814Ssimon unsigned char *exponent, long *modulusLength, 106160814Ssimon long *modulusFieldLength, unsigned char *modulus); 107160814Ssimon#endif 108160814Ssimon 109160814Ssimon/* RAND number functions */ 110160814Ssimon/*-----------------------*/ 111238405Sjkimstatic int cca_get_random_bytes(unsigned char*, int); 112160814Ssimonstatic int cca_random_status(void); 113160814Ssimon 114160814Ssimon#ifndef OPENSSL_NO_RSA 115160814Ssimonstatic void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 116160814Ssimon int idx,long argl, void *argp); 117160814Ssimon#endif 118160814Ssimon 119160814Ssimon/* Function pointers for CCA verbs */ 120160814Ssimon/*---------------------------------*/ 121160814Ssimon#ifndef OPENSSL_NO_RSA 122160814Ssimonstatic F_KEYRECORDREAD keyRecordRead; 123160814Ssimonstatic F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate; 124160814Ssimonstatic F_DIGITALSIGNATUREVERIFY digitalSignatureVerify; 125160814Ssimonstatic F_PUBLICKEYEXTRACT publicKeyExtract; 126160814Ssimonstatic F_PKAENCRYPT pkaEncrypt; 127160814Ssimonstatic F_PKADECRYPT pkaDecrypt; 128160814Ssimon#endif 129160814Ssimonstatic F_RANDOMNUMBERGENERATE randomNumberGenerate; 130160814Ssimon 131160814Ssimon/* static variables */ 132160814Ssimon/*------------------*/ 133160814Ssimonstatic const char *CCA4758_LIB_NAME = NULL; 134160814Ssimonstatic const char *get_CCA4758_LIB_NAME(void) 135160814Ssimon { 136160814Ssimon if(CCA4758_LIB_NAME) 137160814Ssimon return CCA4758_LIB_NAME; 138160814Ssimon return CCA_LIB_NAME; 139160814Ssimon } 140160814Ssimonstatic void free_CCA4758_LIB_NAME(void) 141160814Ssimon { 142160814Ssimon if(CCA4758_LIB_NAME) 143160814Ssimon OPENSSL_free((void*)CCA4758_LIB_NAME); 144160814Ssimon CCA4758_LIB_NAME = NULL; 145160814Ssimon } 146160814Ssimonstatic long set_CCA4758_LIB_NAME(const char *name) 147160814Ssimon { 148160814Ssimon free_CCA4758_LIB_NAME(); 149160814Ssimon return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0); 150160814Ssimon } 151160814Ssimon#ifndef OPENSSL_NO_RSA 152160814Ssimonstatic const char* n_keyRecordRead = CSNDKRR; 153160814Ssimonstatic const char* n_digitalSignatureGenerate = CSNDDSG; 154160814Ssimonstatic const char* n_digitalSignatureVerify = CSNDDSV; 155160814Ssimonstatic const char* n_publicKeyExtract = CSNDPKX; 156160814Ssimonstatic const char* n_pkaEncrypt = CSNDPKE; 157160814Ssimonstatic const char* n_pkaDecrypt = CSNDPKD; 158160814Ssimon#endif 159160814Ssimonstatic const char* n_randomNumberGenerate = CSNBRNG; 160160814Ssimon 161160814Ssimon#ifndef OPENSSL_NO_RSA 162160814Ssimonstatic int hndidx = -1; 163160814Ssimon#endif 164160814Ssimonstatic DSO *dso = NULL; 165160814Ssimon 166160814Ssimon/* openssl engine initialization structures */ 167160814Ssimon/*------------------------------------------*/ 168160814Ssimon 169160814Ssimon#define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE 170160814Ssimonstatic const ENGINE_CMD_DEFN cca4758_cmd_defns[] = { 171160814Ssimon {CCA4758_CMD_SO_PATH, 172160814Ssimon "SO_PATH", 173160814Ssimon "Specifies the path to the '4758cca' shared library", 174160814Ssimon ENGINE_CMD_FLAG_STRING}, 175160814Ssimon {0, NULL, NULL, 0} 176160814Ssimon }; 177160814Ssimon 178160814Ssimon#ifndef OPENSSL_NO_RSA 179160814Ssimonstatic RSA_METHOD ibm_4758_cca_rsa = 180160814Ssimon { 181160814Ssimon "IBM 4758 CCA RSA method", 182160814Ssimon cca_rsa_pub_enc, 183160814Ssimon NULL, 184160814Ssimon NULL, 185160814Ssimon cca_rsa_priv_dec, 186160814Ssimon NULL, /*rsa_mod_exp,*/ 187160814Ssimon NULL, /*mod_exp_mont,*/ 188160814Ssimon NULL, /* init */ 189160814Ssimon NULL, /* finish */ 190160814Ssimon RSA_FLAG_SIGN_VER, /* flags */ 191160814Ssimon NULL, /* app_data */ 192160814Ssimon cca_rsa_sign, /* rsa_sign */ 193160814Ssimon cca_rsa_verify, /* rsa_verify */ 194160814Ssimon NULL /* rsa_keygen */ 195160814Ssimon }; 196160814Ssimon#endif 197160814Ssimon 198160814Ssimonstatic RAND_METHOD ibm_4758_cca_rand = 199160814Ssimon { 200160814Ssimon /* "IBM 4758 RAND method", */ 201160814Ssimon NULL, /* seed */ 202160814Ssimon cca_get_random_bytes, /* get random bytes from the card */ 203160814Ssimon NULL, /* cleanup */ 204160814Ssimon NULL, /* add */ 205160814Ssimon cca_get_random_bytes, /* pseudo rand */ 206160814Ssimon cca_random_status, /* status */ 207160814Ssimon }; 208160814Ssimon 209160814Ssimonstatic const char *engine_4758_cca_id = "4758cca"; 210160814Ssimonstatic const char *engine_4758_cca_name = "IBM 4758 CCA hardware engine support"; 211160814Ssimon#ifndef OPENSSL_NO_DYNAMIC_ENGINE 212160814Ssimon/* Compatibility hack, the dynamic library uses this form in the path */ 213160814Ssimonstatic const char *engine_4758_cca_id_alt = "4758_cca"; 214160814Ssimon#endif 215160814Ssimon 216160814Ssimon/* engine implementation */ 217160814Ssimon/*-----------------------*/ 218160814Ssimonstatic int bind_helper(ENGINE *e) 219160814Ssimon { 220160814Ssimon if(!ENGINE_set_id(e, engine_4758_cca_id) || 221160814Ssimon !ENGINE_set_name(e, engine_4758_cca_name) || 222160814Ssimon#ifndef OPENSSL_NO_RSA 223160814Ssimon !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) || 224160814Ssimon#endif 225160814Ssimon !ENGINE_set_RAND(e, &ibm_4758_cca_rand) || 226160814Ssimon !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) || 227160814Ssimon !ENGINE_set_init_function(e, ibm_4758_cca_init) || 228160814Ssimon !ENGINE_set_finish_function(e, ibm_4758_cca_finish) || 229160814Ssimon !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) || 230160814Ssimon#ifndef OPENSSL_NO_RSA 231160814Ssimon !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) || 232160814Ssimon !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) || 233160814Ssimon#endif 234160814Ssimon !ENGINE_set_cmd_defns(e, cca4758_cmd_defns)) 235160814Ssimon return 0; 236160814Ssimon /* Ensure the error handling is set up */ 237160814Ssimon ERR_load_CCA4758_strings(); 238160814Ssimon return 1; 239160814Ssimon } 240160814Ssimon 241160814Ssimon#ifdef OPENSSL_NO_DYNAMIC_ENGINE 242160814Ssimonstatic ENGINE *engine_4758_cca(void) 243160814Ssimon { 244160814Ssimon ENGINE *ret = ENGINE_new(); 245160814Ssimon if(!ret) 246160814Ssimon return NULL; 247160814Ssimon if(!bind_helper(ret)) 248160814Ssimon { 249160814Ssimon ENGINE_free(ret); 250160814Ssimon return NULL; 251160814Ssimon } 252160814Ssimon return ret; 253160814Ssimon } 254160814Ssimon 255160814Ssimonvoid ENGINE_load_4758cca(void) 256160814Ssimon { 257160814Ssimon ENGINE *e_4758 = engine_4758_cca(); 258160814Ssimon if (!e_4758) return; 259160814Ssimon ENGINE_add(e_4758); 260160814Ssimon ENGINE_free(e_4758); 261160814Ssimon ERR_clear_error(); 262160814Ssimon } 263160814Ssimon#endif 264160814Ssimon 265160814Ssimonstatic int ibm_4758_cca_destroy(ENGINE *e) 266160814Ssimon { 267160814Ssimon ERR_unload_CCA4758_strings(); 268160814Ssimon free_CCA4758_LIB_NAME(); 269160814Ssimon return 1; 270160814Ssimon } 271160814Ssimon 272160814Ssimonstatic int ibm_4758_cca_init(ENGINE *e) 273160814Ssimon { 274160814Ssimon if(dso) 275160814Ssimon { 276160814Ssimon CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_ALREADY_LOADED); 277160814Ssimon goto err; 278160814Ssimon } 279160814Ssimon 280160814Ssimon dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0); 281160814Ssimon if(!dso) 282160814Ssimon { 283160814Ssimon CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE); 284160814Ssimon goto err; 285160814Ssimon } 286160814Ssimon 287160814Ssimon#ifndef OPENSSL_NO_RSA 288160814Ssimon if(!(keyRecordRead = (F_KEYRECORDREAD) 289160814Ssimon DSO_bind_func(dso, n_keyRecordRead)) || 290160814Ssimon !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 291160814Ssimon DSO_bind_func(dso, n_randomNumberGenerate)) || 292160814Ssimon !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 293160814Ssimon DSO_bind_func(dso, n_digitalSignatureGenerate)) || 294160814Ssimon !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY) 295160814Ssimon DSO_bind_func(dso, n_digitalSignatureVerify)) || 296160814Ssimon !(publicKeyExtract = (F_PUBLICKEYEXTRACT) 297160814Ssimon DSO_bind_func(dso, n_publicKeyExtract)) || 298160814Ssimon !(pkaEncrypt = (F_PKAENCRYPT) 299160814Ssimon DSO_bind_func(dso, n_pkaEncrypt)) || 300160814Ssimon !(pkaDecrypt = (F_PKADECRYPT) 301160814Ssimon DSO_bind_func(dso, n_pkaDecrypt))) 302160814Ssimon { 303160814Ssimon CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE); 304160814Ssimon goto err; 305160814Ssimon } 306160814Ssimon#else 307160814Ssimon if(!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 308160814Ssimon DSO_bind_func(dso, n_randomNumberGenerate))) 309160814Ssimon { 310160814Ssimon CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE); 311160814Ssimon goto err; 312160814Ssimon } 313160814Ssimon#endif 314160814Ssimon 315160814Ssimon#ifndef OPENSSL_NO_RSA 316160814Ssimon hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle", 317160814Ssimon NULL, NULL, cca_ex_free); 318160814Ssimon#endif 319160814Ssimon 320160814Ssimon return 1; 321160814Ssimonerr: 322160814Ssimon if(dso) 323160814Ssimon DSO_free(dso); 324160814Ssimon dso = NULL; 325160814Ssimon 326160814Ssimon#ifndef OPENSSL_NO_RSA 327160814Ssimon keyRecordRead = (F_KEYRECORDREAD)0; 328160814Ssimon digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0; 329160814Ssimon digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; 330160814Ssimon publicKeyExtract = (F_PUBLICKEYEXTRACT)0; 331160814Ssimon pkaEncrypt = (F_PKAENCRYPT)0; 332160814Ssimon pkaDecrypt = (F_PKADECRYPT)0; 333160814Ssimon#endif 334160814Ssimon randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0; 335160814Ssimon return 0; 336160814Ssimon } 337160814Ssimon 338160814Ssimonstatic int ibm_4758_cca_finish(ENGINE *e) 339160814Ssimon { 340160814Ssimon free_CCA4758_LIB_NAME(); 341160814Ssimon if(!dso) 342160814Ssimon { 343160814Ssimon CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, 344160814Ssimon CCA4758_R_NOT_LOADED); 345160814Ssimon return 0; 346160814Ssimon } 347160814Ssimon if(!DSO_free(dso)) 348160814Ssimon { 349160814Ssimon CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, 350160814Ssimon CCA4758_R_UNIT_FAILURE); 351160814Ssimon return 0; 352160814Ssimon } 353160814Ssimon dso = NULL; 354160814Ssimon#ifndef OPENSSL_NO_RSA 355160814Ssimon keyRecordRead = (F_KEYRECORDREAD)0; 356160814Ssimon randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0; 357160814Ssimon digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0; 358160814Ssimon digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; 359160814Ssimon publicKeyExtract = (F_PUBLICKEYEXTRACT)0; 360160814Ssimon pkaEncrypt = (F_PKAENCRYPT)0; 361160814Ssimon pkaDecrypt = (F_PKADECRYPT)0; 362160814Ssimon#endif 363160814Ssimon randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0; 364160814Ssimon return 1; 365160814Ssimon } 366160814Ssimon 367160814Ssimonstatic int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) 368160814Ssimon { 369160814Ssimon int initialised = ((dso == NULL) ? 0 : 1); 370160814Ssimon switch(cmd) 371160814Ssimon { 372160814Ssimon case CCA4758_CMD_SO_PATH: 373160814Ssimon if(p == NULL) 374160814Ssimon { 375160814Ssimon CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, 376160814Ssimon ERR_R_PASSED_NULL_PARAMETER); 377160814Ssimon return 0; 378160814Ssimon } 379160814Ssimon if(initialised) 380160814Ssimon { 381160814Ssimon CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, 382160814Ssimon CCA4758_R_ALREADY_LOADED); 383160814Ssimon return 0; 384160814Ssimon } 385160814Ssimon return set_CCA4758_LIB_NAME((const char *)p); 386160814Ssimon default: 387160814Ssimon break; 388160814Ssimon } 389160814Ssimon CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, 390160814Ssimon CCA4758_R_COMMAND_NOT_IMPLEMENTED); 391160814Ssimon return 0; 392160814Ssimon } 393160814Ssimon 394160814Ssimon#ifndef OPENSSL_NO_RSA 395160814Ssimon 396160814Ssimon#define MAX_CCA_PKA_TOKEN_SIZE 2500 397160814Ssimon 398160814Ssimonstatic EVP_PKEY *ibm_4758_load_privkey(ENGINE* e, const char* key_id, 399160814Ssimon UI_METHOD *ui_method, void *callback_data) 400160814Ssimon { 401160814Ssimon RSA *rtmp = NULL; 402160814Ssimon EVP_PKEY *res = NULL; 403160814Ssimon unsigned char* keyToken = NULL; 404160814Ssimon unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE]; 405160814Ssimon long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 406160814Ssimon long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 407160814Ssimon long returnCode; 408160814Ssimon long reasonCode; 409160814Ssimon long exitDataLength = 0; 410160814Ssimon long ruleArrayLength = 0; 411160814Ssimon unsigned char exitData[8]; 412160814Ssimon unsigned char ruleArray[8]; 413160814Ssimon unsigned char keyLabel[64]; 414160814Ssimon unsigned long keyLabelLength = strlen(key_id); 415160814Ssimon unsigned char modulus[256]; 416160814Ssimon long modulusFieldLength = sizeof(modulus); 417160814Ssimon long modulusLength = 0; 418160814Ssimon unsigned char exponent[256]; 419160814Ssimon long exponentLength = sizeof(exponent); 420160814Ssimon 421160814Ssimon if (keyLabelLength > sizeof(keyLabel)) 422160814Ssimon { 423160814Ssimon CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 424160814Ssimon CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 425160814Ssimon return NULL; 426160814Ssimon } 427160814Ssimon 428160814Ssimon memset(keyLabel,' ', sizeof(keyLabel)); 429160814Ssimon memcpy(keyLabel, key_id, keyLabelLength); 430160814Ssimon 431160814Ssimon keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); 432160814Ssimon if (!keyToken) 433160814Ssimon { 434160814Ssimon CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 435160814Ssimon ERR_R_MALLOC_FAILURE); 436160814Ssimon goto err; 437160814Ssimon } 438160814Ssimon 439160814Ssimon keyRecordRead(&returnCode, &reasonCode, &exitDataLength, 440160814Ssimon exitData, &ruleArrayLength, ruleArray, keyLabel, 441160814Ssimon &keyTokenLength, keyToken+sizeof(long)); 442160814Ssimon 443160814Ssimon if (returnCode) 444160814Ssimon { 445160814Ssimon CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 446160814Ssimon CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 447160814Ssimon goto err; 448160814Ssimon } 449160814Ssimon 450160814Ssimon publicKeyExtract(&returnCode, &reasonCode, &exitDataLength, 451160814Ssimon exitData, &ruleArrayLength, ruleArray, &keyTokenLength, 452160814Ssimon keyToken+sizeof(long), &pubKeyTokenLength, pubKeyToken); 453160814Ssimon 454160814Ssimon if (returnCode) 455160814Ssimon { 456160814Ssimon CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 457160814Ssimon CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 458160814Ssimon goto err; 459160814Ssimon } 460160814Ssimon 461160814Ssimon if (!getModulusAndExponent(pubKeyToken, &exponentLength, 462160814Ssimon exponent, &modulusLength, &modulusFieldLength, 463160814Ssimon modulus)) 464160814Ssimon { 465160814Ssimon CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 466160814Ssimon CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 467160814Ssimon goto err; 468160814Ssimon } 469160814Ssimon 470160814Ssimon (*(long*)keyToken) = keyTokenLength; 471160814Ssimon rtmp = RSA_new_method(e); 472160814Ssimon RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); 473160814Ssimon 474160814Ssimon rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); 475160814Ssimon rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); 476160814Ssimon rtmp->flags |= RSA_FLAG_EXT_PKEY; 477160814Ssimon 478160814Ssimon res = EVP_PKEY_new(); 479160814Ssimon EVP_PKEY_assign_RSA(res, rtmp); 480160814Ssimon 481160814Ssimon return res; 482160814Ssimonerr: 483160814Ssimon if (keyToken) 484160814Ssimon OPENSSL_free(keyToken); 485160814Ssimon return NULL; 486160814Ssimon } 487160814Ssimon 488160814Ssimonstatic EVP_PKEY *ibm_4758_load_pubkey(ENGINE* e, const char* key_id, 489160814Ssimon UI_METHOD *ui_method, void *callback_data) 490160814Ssimon { 491160814Ssimon RSA *rtmp = NULL; 492160814Ssimon EVP_PKEY *res = NULL; 493160814Ssimon unsigned char* keyToken = NULL; 494160814Ssimon long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 495160814Ssimon long returnCode; 496160814Ssimon long reasonCode; 497160814Ssimon long exitDataLength = 0; 498160814Ssimon long ruleArrayLength = 0; 499160814Ssimon unsigned char exitData[8]; 500160814Ssimon unsigned char ruleArray[8]; 501160814Ssimon unsigned char keyLabel[64]; 502160814Ssimon unsigned long keyLabelLength = strlen(key_id); 503160814Ssimon unsigned char modulus[512]; 504160814Ssimon long modulusFieldLength = sizeof(modulus); 505160814Ssimon long modulusLength = 0; 506160814Ssimon unsigned char exponent[512]; 507160814Ssimon long exponentLength = sizeof(exponent); 508160814Ssimon 509160814Ssimon if (keyLabelLength > sizeof(keyLabel)) 510160814Ssimon { 511160814Ssimon CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 512160814Ssimon CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 513160814Ssimon return NULL; 514160814Ssimon } 515160814Ssimon 516160814Ssimon memset(keyLabel,' ', sizeof(keyLabel)); 517160814Ssimon memcpy(keyLabel, key_id, keyLabelLength); 518160814Ssimon 519160814Ssimon keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); 520160814Ssimon if (!keyToken) 521160814Ssimon { 522160814Ssimon CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 523160814Ssimon ERR_R_MALLOC_FAILURE); 524160814Ssimon goto err; 525160814Ssimon } 526160814Ssimon 527160814Ssimon keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData, 528160814Ssimon &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength, 529160814Ssimon keyToken+sizeof(long)); 530160814Ssimon 531160814Ssimon if (returnCode) 532160814Ssimon { 533160814Ssimon CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 534160814Ssimon ERR_R_MALLOC_FAILURE); 535160814Ssimon goto err; 536160814Ssimon } 537160814Ssimon 538160814Ssimon if (!getModulusAndExponent(keyToken+sizeof(long), &exponentLength, 539160814Ssimon exponent, &modulusLength, &modulusFieldLength, modulus)) 540160814Ssimon { 541160814Ssimon CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 542160814Ssimon CCA4758_R_FAILED_LOADING_PUBLIC_KEY); 543160814Ssimon goto err; 544160814Ssimon } 545160814Ssimon 546160814Ssimon (*(long*)keyToken) = keyTokenLength; 547160814Ssimon rtmp = RSA_new_method(e); 548160814Ssimon RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); 549160814Ssimon rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); 550160814Ssimon rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); 551160814Ssimon rtmp->flags |= RSA_FLAG_EXT_PKEY; 552160814Ssimon res = EVP_PKEY_new(); 553160814Ssimon EVP_PKEY_assign_RSA(res, rtmp); 554160814Ssimon 555160814Ssimon return res; 556160814Ssimonerr: 557160814Ssimon if (keyToken) 558160814Ssimon OPENSSL_free(keyToken); 559160814Ssimon return NULL; 560160814Ssimon } 561160814Ssimon 562160814Ssimonstatic int cca_rsa_pub_enc(int flen, const unsigned char *from, 563160814Ssimon unsigned char *to, RSA *rsa,int padding) 564160814Ssimon { 565160814Ssimon long returnCode; 566160814Ssimon long reasonCode; 567160814Ssimon long lflen = flen; 568160814Ssimon long exitDataLength = 0; 569160814Ssimon unsigned char exitData[8]; 570160814Ssimon long ruleArrayLength = 1; 571160814Ssimon unsigned char ruleArray[8] = "PKCS-1.2"; 572160814Ssimon long dataStructureLength = 0; 573160814Ssimon unsigned char dataStructure[8]; 574160814Ssimon long outputLength = RSA_size(rsa); 575160814Ssimon long keyTokenLength; 576160814Ssimon unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx); 577160814Ssimon 578160814Ssimon keyTokenLength = *(long*)keyToken; 579160814Ssimon keyToken+=sizeof(long); 580160814Ssimon 581160814Ssimon pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData, 582160814Ssimon &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from, 583160814Ssimon &dataStructureLength, dataStructure, &keyTokenLength, 584160814Ssimon keyToken, &outputLength, to); 585160814Ssimon 586160814Ssimon if (returnCode || reasonCode) 587160814Ssimon return -(returnCode << 16 | reasonCode); 588160814Ssimon return outputLength; 589160814Ssimon } 590160814Ssimon 591160814Ssimonstatic int cca_rsa_priv_dec(int flen, const unsigned char *from, 592160814Ssimon unsigned char *to, RSA *rsa,int padding) 593160814Ssimon { 594160814Ssimon long returnCode; 595160814Ssimon long reasonCode; 596160814Ssimon long lflen = flen; 597160814Ssimon long exitDataLength = 0; 598160814Ssimon unsigned char exitData[8]; 599160814Ssimon long ruleArrayLength = 1; 600160814Ssimon unsigned char ruleArray[8] = "PKCS-1.2"; 601160814Ssimon long dataStructureLength = 0; 602160814Ssimon unsigned char dataStructure[8]; 603160814Ssimon long outputLength = RSA_size(rsa); 604160814Ssimon long keyTokenLength; 605160814Ssimon unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx); 606160814Ssimon 607160814Ssimon keyTokenLength = *(long*)keyToken; 608160814Ssimon keyToken+=sizeof(long); 609160814Ssimon 610160814Ssimon pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData, 611160814Ssimon &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from, 612160814Ssimon &dataStructureLength, dataStructure, &keyTokenLength, 613160814Ssimon keyToken, &outputLength, to); 614160814Ssimon 615160814Ssimon return (returnCode | reasonCode) ? 0 : 1; 616160814Ssimon } 617160814Ssimon 618160814Ssimon#define SSL_SIG_LEN 36 619160814Ssimon 620160814Ssimonstatic int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len, 621238405Sjkim const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa) 622160814Ssimon { 623160814Ssimon long returnCode; 624160814Ssimon long reasonCode; 625160814Ssimon long lsiglen = siglen; 626160814Ssimon long exitDataLength = 0; 627160814Ssimon unsigned char exitData[8]; 628160814Ssimon long ruleArrayLength = 1; 629160814Ssimon unsigned char ruleArray[8] = "PKCS-1.1"; 630160814Ssimon long keyTokenLength; 631160814Ssimon unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx); 632160814Ssimon long length = SSL_SIG_LEN; 633160814Ssimon long keyLength ; 634160814Ssimon unsigned char *hashBuffer = NULL; 635160814Ssimon X509_SIG sig; 636160814Ssimon ASN1_TYPE parameter; 637160814Ssimon X509_ALGOR algorithm; 638160814Ssimon ASN1_OCTET_STRING digest; 639160814Ssimon 640160814Ssimon keyTokenLength = *(long*)keyToken; 641160814Ssimon keyToken+=sizeof(long); 642160814Ssimon 643160814Ssimon if (type == NID_md5 || type == NID_sha1) 644160814Ssimon { 645160814Ssimon sig.algor = &algorithm; 646160814Ssimon algorithm.algorithm = OBJ_nid2obj(type); 647160814Ssimon 648160814Ssimon if (!algorithm.algorithm) 649160814Ssimon { 650160814Ssimon CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 651160814Ssimon CCA4758_R_UNKNOWN_ALGORITHM_TYPE); 652160814Ssimon return 0; 653160814Ssimon } 654160814Ssimon 655160814Ssimon if (!algorithm.algorithm->length) 656160814Ssimon { 657160814Ssimon CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 658160814Ssimon CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); 659160814Ssimon return 0; 660160814Ssimon } 661160814Ssimon 662160814Ssimon parameter.type = V_ASN1_NULL; 663160814Ssimon parameter.value.ptr = NULL; 664160814Ssimon algorithm.parameter = ¶meter; 665160814Ssimon 666160814Ssimon sig.digest = &digest; 667160814Ssimon sig.digest->data = (unsigned char*)m; 668160814Ssimon sig.digest->length = m_len; 669160814Ssimon 670160814Ssimon length = i2d_X509_SIG(&sig, NULL); 671160814Ssimon } 672160814Ssimon 673160814Ssimon keyLength = RSA_size(rsa); 674160814Ssimon 675160814Ssimon if (length - RSA_PKCS1_PADDING > keyLength) 676160814Ssimon { 677160814Ssimon CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 678160814Ssimon CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 679160814Ssimon return 0; 680160814Ssimon } 681160814Ssimon 682160814Ssimon switch (type) 683160814Ssimon { 684160814Ssimon case NID_md5_sha1 : 685160814Ssimon if (m_len != SSL_SIG_LEN) 686160814Ssimon { 687160814Ssimon CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 688160814Ssimon CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 689160814Ssimon return 0; 690160814Ssimon } 691160814Ssimon 692160814Ssimon hashBuffer = (unsigned char *)m; 693160814Ssimon length = m_len; 694160814Ssimon break; 695160814Ssimon case NID_md5 : 696160814Ssimon { 697160814Ssimon unsigned char *ptr; 698160814Ssimon ptr = hashBuffer = OPENSSL_malloc( 699160814Ssimon (unsigned int)keyLength+1); 700160814Ssimon if (!hashBuffer) 701160814Ssimon { 702160814Ssimon CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 703160814Ssimon ERR_R_MALLOC_FAILURE); 704160814Ssimon return 0; 705160814Ssimon } 706160814Ssimon 707160814Ssimon i2d_X509_SIG(&sig, &ptr); 708160814Ssimon } 709160814Ssimon break; 710160814Ssimon case NID_sha1 : 711160814Ssimon { 712160814Ssimon unsigned char *ptr; 713160814Ssimon ptr = hashBuffer = OPENSSL_malloc( 714160814Ssimon (unsigned int)keyLength+1); 715160814Ssimon if (!hashBuffer) 716160814Ssimon { 717160814Ssimon CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 718160814Ssimon ERR_R_MALLOC_FAILURE); 719160814Ssimon return 0; 720160814Ssimon } 721160814Ssimon i2d_X509_SIG(&sig, &ptr); 722160814Ssimon } 723160814Ssimon break; 724160814Ssimon default: 725160814Ssimon return 0; 726160814Ssimon } 727160814Ssimon 728160814Ssimon digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength, 729160814Ssimon exitData, &ruleArrayLength, ruleArray, &keyTokenLength, 730238405Sjkim keyToken, &length, hashBuffer, &lsiglen, 731238405Sjkim (unsigned char *)sigbuf); 732160814Ssimon 733160814Ssimon if (type == NID_sha1 || type == NID_md5) 734160814Ssimon { 735160814Ssimon OPENSSL_cleanse(hashBuffer, keyLength+1); 736160814Ssimon OPENSSL_free(hashBuffer); 737160814Ssimon } 738160814Ssimon 739160814Ssimon return ((returnCode || reasonCode) ? 0 : 1); 740160814Ssimon } 741160814Ssimon 742160814Ssimon#define SSL_SIG_LEN 36 743160814Ssimon 744160814Ssimonstatic int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, 745160814Ssimon unsigned char *sigret, unsigned int *siglen, const RSA *rsa) 746160814Ssimon { 747160814Ssimon long returnCode; 748160814Ssimon long reasonCode; 749160814Ssimon long exitDataLength = 0; 750160814Ssimon unsigned char exitData[8]; 751160814Ssimon long ruleArrayLength = 1; 752160814Ssimon unsigned char ruleArray[8] = "PKCS-1.1"; 753160814Ssimon long outputLength=256; 754160814Ssimon long outputBitLength; 755160814Ssimon long keyTokenLength; 756160814Ssimon unsigned char *hashBuffer = NULL; 757160814Ssimon unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx); 758160814Ssimon long length = SSL_SIG_LEN; 759160814Ssimon long keyLength ; 760160814Ssimon X509_SIG sig; 761160814Ssimon ASN1_TYPE parameter; 762160814Ssimon X509_ALGOR algorithm; 763160814Ssimon ASN1_OCTET_STRING digest; 764160814Ssimon 765160814Ssimon keyTokenLength = *(long*)keyToken; 766160814Ssimon keyToken+=sizeof(long); 767160814Ssimon 768160814Ssimon if (type == NID_md5 || type == NID_sha1) 769160814Ssimon { 770160814Ssimon sig.algor = &algorithm; 771160814Ssimon algorithm.algorithm = OBJ_nid2obj(type); 772160814Ssimon 773160814Ssimon if (!algorithm.algorithm) 774160814Ssimon { 775160814Ssimon CCA4758err(CCA4758_F_CCA_RSA_SIGN, 776160814Ssimon CCA4758_R_UNKNOWN_ALGORITHM_TYPE); 777160814Ssimon return 0; 778160814Ssimon } 779160814Ssimon 780160814Ssimon if (!algorithm.algorithm->length) 781160814Ssimon { 782160814Ssimon CCA4758err(CCA4758_F_CCA_RSA_SIGN, 783160814Ssimon CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); 784160814Ssimon return 0; 785160814Ssimon } 786160814Ssimon 787160814Ssimon parameter.type = V_ASN1_NULL; 788160814Ssimon parameter.value.ptr = NULL; 789160814Ssimon algorithm.parameter = ¶meter; 790160814Ssimon 791160814Ssimon sig.digest = &digest; 792160814Ssimon sig.digest->data = (unsigned char*)m; 793160814Ssimon sig.digest->length = m_len; 794160814Ssimon 795160814Ssimon length = i2d_X509_SIG(&sig, NULL); 796160814Ssimon } 797160814Ssimon 798160814Ssimon keyLength = RSA_size(rsa); 799160814Ssimon 800160814Ssimon if (length - RSA_PKCS1_PADDING > keyLength) 801160814Ssimon { 802160814Ssimon CCA4758err(CCA4758_F_CCA_RSA_SIGN, 803160814Ssimon CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 804160814Ssimon return 0; 805160814Ssimon } 806160814Ssimon 807160814Ssimon switch (type) 808160814Ssimon { 809160814Ssimon case NID_md5_sha1 : 810160814Ssimon if (m_len != SSL_SIG_LEN) 811160814Ssimon { 812160814Ssimon CCA4758err(CCA4758_F_CCA_RSA_SIGN, 813160814Ssimon CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 814160814Ssimon return 0; 815160814Ssimon } 816160814Ssimon hashBuffer = (unsigned char*)m; 817160814Ssimon length = m_len; 818160814Ssimon break; 819160814Ssimon case NID_md5 : 820160814Ssimon { 821160814Ssimon unsigned char *ptr; 822160814Ssimon ptr = hashBuffer = OPENSSL_malloc( 823160814Ssimon (unsigned int)keyLength+1); 824160814Ssimon if (!hashBuffer) 825160814Ssimon { 826160814Ssimon CCA4758err(CCA4758_F_CCA_RSA_SIGN, 827160814Ssimon ERR_R_MALLOC_FAILURE); 828160814Ssimon return 0; 829160814Ssimon } 830160814Ssimon i2d_X509_SIG(&sig, &ptr); 831160814Ssimon } 832160814Ssimon break; 833160814Ssimon case NID_sha1 : 834160814Ssimon { 835160814Ssimon unsigned char *ptr; 836160814Ssimon ptr = hashBuffer = OPENSSL_malloc( 837160814Ssimon (unsigned int)keyLength+1); 838160814Ssimon if (!hashBuffer) 839160814Ssimon { 840160814Ssimon CCA4758err(CCA4758_F_CCA_RSA_SIGN, 841160814Ssimon ERR_R_MALLOC_FAILURE); 842160814Ssimon return 0; 843160814Ssimon } 844160814Ssimon i2d_X509_SIG(&sig, &ptr); 845160814Ssimon } 846160814Ssimon break; 847160814Ssimon default: 848160814Ssimon return 0; 849160814Ssimon } 850160814Ssimon 851160814Ssimon digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength, 852160814Ssimon exitData, &ruleArrayLength, ruleArray, &keyTokenLength, 853160814Ssimon keyToken, &length, hashBuffer, &outputLength, &outputBitLength, 854160814Ssimon sigret); 855160814Ssimon 856160814Ssimon if (type == NID_sha1 || type == NID_md5) 857160814Ssimon { 858160814Ssimon OPENSSL_cleanse(hashBuffer, keyLength+1); 859160814Ssimon OPENSSL_free(hashBuffer); 860160814Ssimon } 861160814Ssimon 862160814Ssimon *siglen = outputLength; 863160814Ssimon 864160814Ssimon return ((returnCode || reasonCode) ? 0 : 1); 865160814Ssimon } 866160814Ssimon 867160814Ssimonstatic int getModulusAndExponent(const unsigned char*token, long *exponentLength, 868160814Ssimon unsigned char *exponent, long *modulusLength, long *modulusFieldLength, 869160814Ssimon unsigned char *modulus) 870160814Ssimon { 871160814Ssimon unsigned long len; 872160814Ssimon 873160814Ssimon if (*token++ != (char)0x1E) /* internal PKA token? */ 874160814Ssimon return 0; 875160814Ssimon 876160814Ssimon if (*token++) /* token version must be zero */ 877160814Ssimon return 0; 878160814Ssimon 879160814Ssimon len = *token++; 880160814Ssimon len = len << 8; 881160814Ssimon len |= (unsigned char)*token++; 882160814Ssimon 883160814Ssimon token += 4; /* skip reserved bytes */ 884160814Ssimon 885160814Ssimon if (*token++ == (char)0x04) 886160814Ssimon { 887160814Ssimon if (*token++) /* token version must be zero */ 888160814Ssimon return 0; 889160814Ssimon 890160814Ssimon len = *token++; 891160814Ssimon len = len << 8; 892160814Ssimon len |= (unsigned char)*token++; 893160814Ssimon 894160814Ssimon token+=2; /* skip reserved section */ 895160814Ssimon 896160814Ssimon len = *token++; 897160814Ssimon len = len << 8; 898160814Ssimon len |= (unsigned char)*token++; 899160814Ssimon 900160814Ssimon *exponentLength = len; 901160814Ssimon 902160814Ssimon len = *token++; 903160814Ssimon len = len << 8; 904160814Ssimon len |= (unsigned char)*token++; 905160814Ssimon 906160814Ssimon *modulusLength = len; 907160814Ssimon 908160814Ssimon len = *token++; 909160814Ssimon len = len << 8; 910160814Ssimon len |= (unsigned char)*token++; 911160814Ssimon 912160814Ssimon *modulusFieldLength = len; 913160814Ssimon 914160814Ssimon memcpy(exponent, token, *exponentLength); 915160814Ssimon token+= *exponentLength; 916160814Ssimon 917160814Ssimon memcpy(modulus, token, *modulusFieldLength); 918160814Ssimon return 1; 919160814Ssimon } 920160814Ssimon return 0; 921160814Ssimon } 922160814Ssimon 923160814Ssimon#endif /* OPENSSL_NO_RSA */ 924160814Ssimon 925160814Ssimonstatic int cca_random_status(void) 926160814Ssimon { 927160814Ssimon return 1; 928160814Ssimon } 929160814Ssimon 930160814Ssimonstatic int cca_get_random_bytes(unsigned char* buf, int num) 931160814Ssimon { 932160814Ssimon long ret_code; 933160814Ssimon long reason_code; 934160814Ssimon long exit_data_length; 935160814Ssimon unsigned char exit_data[4]; 936160814Ssimon unsigned char form[] = "RANDOM "; 937160814Ssimon unsigned char rand_buf[8]; 938160814Ssimon 939160814Ssimon while(num >= (int)sizeof(rand_buf)) 940160814Ssimon { 941160814Ssimon randomNumberGenerate(&ret_code, &reason_code, &exit_data_length, 942160814Ssimon exit_data, form, rand_buf); 943160814Ssimon if (ret_code) 944160814Ssimon return 0; 945160814Ssimon num -= sizeof(rand_buf); 946160814Ssimon memcpy(buf, rand_buf, sizeof(rand_buf)); 947160814Ssimon buf += sizeof(rand_buf); 948160814Ssimon } 949160814Ssimon 950160814Ssimon if (num) 951160814Ssimon { 952160814Ssimon randomNumberGenerate(&ret_code, &reason_code, NULL, NULL, 953160814Ssimon form, rand_buf); 954160814Ssimon if (ret_code) 955160814Ssimon return 0; 956160814Ssimon memcpy(buf, rand_buf, num); 957160814Ssimon } 958160814Ssimon 959160814Ssimon return 1; 960160814Ssimon } 961160814Ssimon 962160814Ssimon#ifndef OPENSSL_NO_RSA 963160814Ssimonstatic void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx, 964160814Ssimon long argl, void *argp) 965160814Ssimon { 966160814Ssimon if (item) 967160814Ssimon OPENSSL_free(item); 968160814Ssimon } 969160814Ssimon#endif 970160814Ssimon 971160814Ssimon/* Goo to handle building as a dynamic engine */ 972160814Ssimon#ifndef OPENSSL_NO_DYNAMIC_ENGINE 973160814Ssimonstatic int bind_fn(ENGINE *e, const char *id) 974160814Ssimon { 975160814Ssimon if(id && (strcmp(id, engine_4758_cca_id) != 0) && 976160814Ssimon (strcmp(id, engine_4758_cca_id_alt) != 0)) 977160814Ssimon return 0; 978160814Ssimon if(!bind_helper(e)) 979160814Ssimon return 0; 980160814Ssimon return 1; 981160814Ssimon } 982160814SsimonIMPLEMENT_DYNAMIC_CHECK_FN() 983160814SsimonIMPLEMENT_DYNAMIC_BIND_FN(bind_fn) 984160814Ssimon#endif /* OPENSSL_NO_DYNAMIC_ENGINE */ 985160814Ssimon 986160814Ssimon#endif /* !OPENSSL_NO_HW_4758_CCA */ 987160814Ssimon#endif /* !OPENSSL_NO_HW */ 988