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 10296341Sdelphij * 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 65296341Sdelphij# include <openssl/rsa.h> 66160814Ssimon#endif 67160814Ssimon#include <openssl/bn.h> 68160814Ssimon 69160814Ssimon#ifndef OPENSSL_NO_HW 70296341Sdelphij# ifndef OPENSSL_NO_HW_4758_CCA 71160814Ssimon 72296341Sdelphij# ifdef FLAT_INC 73296341Sdelphij# include "hw_4758_cca.h" 74296341Sdelphij# else 75296341Sdelphij# include "vendor_defns/hw_4758_cca.h" 76296341Sdelphij# endif 77160814Ssimon 78296341Sdelphij# 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); 83296341Sdelphijstatic int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, 84296341Sdelphij void (*f) (void)); 85160814Ssimon 86160814Ssimon/* rsa functions */ 87296341Sdelphij/* -------------*/ 88296341Sdelphij# ifndef OPENSSL_NO_RSA 89160814Ssimonstatic int cca_rsa_pub_enc(int flen, const unsigned char *from, 90296341Sdelphij unsigned char *to, RSA *rsa, int padding); 91160814Ssimonstatic int cca_rsa_priv_dec(int flen, const unsigned char *from, 92296341Sdelphij unsigned char *to, RSA *rsa, int padding); 93160814Ssimonstatic int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, 94296341Sdelphij unsigned char *sigret, unsigned int *siglen, 95296341Sdelphij const RSA *rsa); 96296341Sdelphijstatic int cca_rsa_verify(int dtype, const unsigned char *m, 97296341Sdelphij unsigned int m_len, const unsigned char *sigbuf, 98296341Sdelphij unsigned int siglen, const RSA *rsa); 99160814Ssimon 100160814Ssimon/* utility functions */ 101296341Sdelphij/* ---------------------*/ 102296341Sdelphijstatic EVP_PKEY *ibm_4758_load_privkey(ENGINE *, const char *, 103296341Sdelphij UI_METHOD *ui_method, 104296341Sdelphij void *callback_data); 105296341Sdelphijstatic EVP_PKEY *ibm_4758_load_pubkey(ENGINE *, const char *, 106296341Sdelphij UI_METHOD *ui_method, 107296341Sdelphij void *callback_data); 108160814Ssimon 109296341Sdelphijstatic int getModulusAndExponent(const unsigned char *token, 110296341Sdelphij long *exponentLength, 111296341Sdelphij unsigned char *exponent, long *modulusLength, 112296341Sdelphij long *modulusFieldLength, 113296341Sdelphij unsigned char *modulus); 114296341Sdelphij# endif 115160814Ssimon 116160814Ssimon/* RAND number functions */ 117296341Sdelphij/* ---------------------*/ 118296341Sdelphijstatic int cca_get_random_bytes(unsigned char *, int); 119160814Ssimonstatic int cca_random_status(void); 120160814Ssimon 121296341Sdelphij# ifndef OPENSSL_NO_RSA 122160814Ssimonstatic void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 123296341Sdelphij int idx, long argl, void *argp); 124296341Sdelphij# endif 125160814Ssimon 126160814Ssimon/* Function pointers for CCA verbs */ 127296341Sdelphij/* -------------------------------*/ 128296341Sdelphij# 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; 135296341Sdelphij# endif 136160814Ssimonstatic F_RANDOMNUMBERGENERATE randomNumberGenerate; 137160814Ssimon 138160814Ssimon/* static variables */ 139296341Sdelphij/* ----------------*/ 140160814Ssimonstatic const char *CCA4758_LIB_NAME = NULL; 141160814Ssimonstatic const char *get_CCA4758_LIB_NAME(void) 142296341Sdelphij{ 143296341Sdelphij if (CCA4758_LIB_NAME) 144296341Sdelphij return CCA4758_LIB_NAME; 145296341Sdelphij return CCA_LIB_NAME; 146296341Sdelphij} 147296341Sdelphij 148160814Ssimonstatic void free_CCA4758_LIB_NAME(void) 149296341Sdelphij{ 150296341Sdelphij if (CCA4758_LIB_NAME) 151296341Sdelphij OPENSSL_free((void *)CCA4758_LIB_NAME); 152296341Sdelphij CCA4758_LIB_NAME = NULL; 153296341Sdelphij} 154296341Sdelphij 155160814Ssimonstatic long set_CCA4758_LIB_NAME(const char *name) 156296341Sdelphij{ 157296341Sdelphij free_CCA4758_LIB_NAME(); 158296341Sdelphij return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0); 159296341Sdelphij} 160160814Ssimon 161296341Sdelphij# ifndef OPENSSL_NO_RSA 162296341Sdelphijstatic const char *n_keyRecordRead = CSNDKRR; 163296341Sdelphijstatic const char *n_digitalSignatureGenerate = CSNDDSG; 164296341Sdelphijstatic const char *n_digitalSignatureVerify = CSNDDSV; 165296341Sdelphijstatic const char *n_publicKeyExtract = CSNDPKX; 166296341Sdelphijstatic const char *n_pkaEncrypt = CSNDPKE; 167296341Sdelphijstatic const char *n_pkaDecrypt = CSNDPKD; 168296341Sdelphij# endif 169296341Sdelphijstatic const char *n_randomNumberGenerate = CSNBRNG; 170296341Sdelphij 171296341Sdelphij# ifndef OPENSSL_NO_RSA 172160814Ssimonstatic int hndidx = -1; 173296341Sdelphij# endif 174160814Ssimonstatic DSO *dso = NULL; 175160814Ssimon 176160814Ssimon/* openssl engine initialization structures */ 177296341Sdelphij/* ----------------------------------------*/ 178160814Ssimon 179296341Sdelphij# define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE 180296341Sdelphijstatic const ENGINE_CMD_DEFN cca4758_cmd_defns[] = { 181296341Sdelphij {CCA4758_CMD_SO_PATH, 182296341Sdelphij "SO_PATH", 183296341Sdelphij "Specifies the path to the '4758cca' shared library", 184296341Sdelphij ENGINE_CMD_FLAG_STRING}, 185296341Sdelphij {0, NULL, NULL, 0} 186296341Sdelphij}; 187160814Ssimon 188296341Sdelphij# ifndef OPENSSL_NO_RSA 189296341Sdelphijstatic RSA_METHOD ibm_4758_cca_rsa = { 190296341Sdelphij "IBM 4758 CCA RSA method", 191296341Sdelphij cca_rsa_pub_enc, 192296341Sdelphij NULL, 193296341Sdelphij NULL, 194296341Sdelphij cca_rsa_priv_dec, 195296341Sdelphij NULL, /* rsa_mod_exp, */ 196296341Sdelphij NULL, /* mod_exp_mont, */ 197296341Sdelphij NULL, /* init */ 198296341Sdelphij NULL, /* finish */ 199296341Sdelphij RSA_FLAG_SIGN_VER, /* flags */ 200296341Sdelphij NULL, /* app_data */ 201296341Sdelphij cca_rsa_sign, /* rsa_sign */ 202296341Sdelphij cca_rsa_verify, /* rsa_verify */ 203296341Sdelphij NULL /* rsa_keygen */ 204296341Sdelphij}; 205296341Sdelphij# endif 206160814Ssimon 207296341Sdelphijstatic RAND_METHOD ibm_4758_cca_rand = { 208296341Sdelphij /* "IBM 4758 RAND method", */ 209296341Sdelphij NULL, /* seed */ 210296341Sdelphij cca_get_random_bytes, /* get random bytes from the card */ 211296341Sdelphij NULL, /* cleanup */ 212296341Sdelphij NULL, /* add */ 213296341Sdelphij cca_get_random_bytes, /* pseudo rand */ 214296341Sdelphij cca_random_status, /* status */ 215296341Sdelphij}; 216160814Ssimon 217160814Ssimonstatic const char *engine_4758_cca_id = "4758cca"; 218296341Sdelphijstatic const char *engine_4758_cca_name = 219296341Sdelphij "IBM 4758 CCA hardware engine support"; 220296341Sdelphij# 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"; 223296341Sdelphij# endif 224160814Ssimon 225160814Ssimon/* engine implementation */ 226296341Sdelphij/* ---------------------*/ 227160814Ssimonstatic int bind_helper(ENGINE *e) 228296341Sdelphij{ 229296341Sdelphij if (!ENGINE_set_id(e, engine_4758_cca_id) || 230296341Sdelphij !ENGINE_set_name(e, engine_4758_cca_name) || 231296341Sdelphij# ifndef OPENSSL_NO_RSA 232296341Sdelphij !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) || 233296341Sdelphij# endif 234296341Sdelphij !ENGINE_set_RAND(e, &ibm_4758_cca_rand) || 235296341Sdelphij !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) || 236296341Sdelphij !ENGINE_set_init_function(e, ibm_4758_cca_init) || 237296341Sdelphij !ENGINE_set_finish_function(e, ibm_4758_cca_finish) || 238296341Sdelphij !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) || 239296341Sdelphij# ifndef OPENSSL_NO_RSA 240296341Sdelphij !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) || 241296341Sdelphij !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) || 242296341Sdelphij# endif 243296341Sdelphij !ENGINE_set_cmd_defns(e, cca4758_cmd_defns)) 244296341Sdelphij return 0; 245296341Sdelphij /* Ensure the error handling is set up */ 246296341Sdelphij ERR_load_CCA4758_strings(); 247296341Sdelphij return 1; 248296341Sdelphij} 249160814Ssimon 250296341Sdelphij# ifdef OPENSSL_NO_DYNAMIC_ENGINE 251160814Ssimonstatic ENGINE *engine_4758_cca(void) 252296341Sdelphij{ 253296341Sdelphij ENGINE *ret = ENGINE_new(); 254296341Sdelphij if (!ret) 255296341Sdelphij return NULL; 256296341Sdelphij if (!bind_helper(ret)) { 257296341Sdelphij ENGINE_free(ret); 258296341Sdelphij return NULL; 259296341Sdelphij } 260296341Sdelphij return ret; 261296341Sdelphij} 262160814Ssimon 263160814Ssimonvoid ENGINE_load_4758cca(void) 264296341Sdelphij{ 265296341Sdelphij ENGINE *e_4758 = engine_4758_cca(); 266296341Sdelphij if (!e_4758) 267296341Sdelphij return; 268296341Sdelphij ENGINE_add(e_4758); 269296341Sdelphij ENGINE_free(e_4758); 270296341Sdelphij ERR_clear_error(); 271296341Sdelphij} 272296341Sdelphij# endif 273160814Ssimon 274160814Ssimonstatic int ibm_4758_cca_destroy(ENGINE *e) 275296341Sdelphij{ 276296341Sdelphij ERR_unload_CCA4758_strings(); 277296341Sdelphij free_CCA4758_LIB_NAME(); 278296341Sdelphij return 1; 279296341Sdelphij} 280160814Ssimon 281160814Ssimonstatic int ibm_4758_cca_init(ENGINE *e) 282296341Sdelphij{ 283296341Sdelphij if (dso) { 284296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_ALREADY_LOADED); 285296341Sdelphij goto err; 286296341Sdelphij } 287160814Ssimon 288296341Sdelphij dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0); 289296341Sdelphij if (!dso) { 290296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); 291296341Sdelphij goto err; 292296341Sdelphij } 293296341Sdelphij# ifndef OPENSSL_NO_RSA 294296341Sdelphij if (!(keyRecordRead = (F_KEYRECORDREAD) 295296341Sdelphij DSO_bind_func(dso, n_keyRecordRead)) || 296296341Sdelphij !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 297296341Sdelphij DSO_bind_func(dso, n_randomNumberGenerate)) || 298296341Sdelphij !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 299296341Sdelphij DSO_bind_func(dso, n_digitalSignatureGenerate)) || 300296341Sdelphij !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY) 301296341Sdelphij DSO_bind_func(dso, n_digitalSignatureVerify)) || 302296341Sdelphij !(publicKeyExtract = (F_PUBLICKEYEXTRACT) 303296341Sdelphij DSO_bind_func(dso, n_publicKeyExtract)) || 304296341Sdelphij !(pkaEncrypt = (F_PKAENCRYPT) 305296341Sdelphij DSO_bind_func(dso, n_pkaEncrypt)) || !(pkaDecrypt = (F_PKADECRYPT) 306296341Sdelphij DSO_bind_func(dso, 307296341Sdelphij n_pkaDecrypt))) 308296341Sdelphij { 309296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); 310296341Sdelphij goto err; 311296341Sdelphij } 312296341Sdelphij# else 313296341Sdelphij if (!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 314296341Sdelphij DSO_bind_func(dso, n_randomNumberGenerate))) { 315296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); 316296341Sdelphij goto err; 317296341Sdelphij } 318296341Sdelphij# endif 319160814Ssimon 320296341Sdelphij# ifndef OPENSSL_NO_RSA 321296341Sdelphij hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle", 322296341Sdelphij NULL, NULL, cca_ex_free); 323296341Sdelphij# endif 324160814Ssimon 325296341Sdelphij return 1; 326296341Sdelphij err: 327296341Sdelphij if (dso) 328296341Sdelphij DSO_free(dso); 329296341Sdelphij dso = NULL; 330160814Ssimon 331296341Sdelphij# ifndef OPENSSL_NO_RSA 332296341Sdelphij keyRecordRead = (F_KEYRECORDREAD) 0; 333296341Sdelphij digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0; 334296341Sdelphij digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; 335296341Sdelphij publicKeyExtract = (F_PUBLICKEYEXTRACT)0; 336296341Sdelphij pkaEncrypt = (F_PKAENCRYPT) 0; 337296341Sdelphij pkaDecrypt = (F_PKADECRYPT) 0; 338296341Sdelphij# endif 339296341Sdelphij randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; 340296341Sdelphij return 0; 341296341Sdelphij} 342160814Ssimon 343160814Ssimonstatic int ibm_4758_cca_finish(ENGINE *e) 344296341Sdelphij{ 345296341Sdelphij free_CCA4758_LIB_NAME(); 346296341Sdelphij if (!dso) { 347296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_NOT_LOADED); 348296341Sdelphij return 0; 349296341Sdelphij } 350296341Sdelphij if (!DSO_free(dso)) { 351296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_UNIT_FAILURE); 352296341Sdelphij return 0; 353296341Sdelphij } 354296341Sdelphij dso = NULL; 355296341Sdelphij# ifndef OPENSSL_NO_RSA 356296341Sdelphij keyRecordRead = (F_KEYRECORDREAD) 0; 357296341Sdelphij randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; 358296341Sdelphij digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0; 359296341Sdelphij digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; 360296341Sdelphij publicKeyExtract = (F_PUBLICKEYEXTRACT)0; 361296341Sdelphij pkaEncrypt = (F_PKAENCRYPT) 0; 362296341Sdelphij pkaDecrypt = (F_PKADECRYPT) 0; 363296341Sdelphij# endif 364296341Sdelphij randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; 365296341Sdelphij return 1; 366296341Sdelphij} 367160814Ssimon 368296341Sdelphijstatic int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, 369296341Sdelphij void (*f) (void)) 370296341Sdelphij{ 371296341Sdelphij int initialised = ((dso == NULL) ? 0 : 1); 372296341Sdelphij switch (cmd) { 373296341Sdelphij case CCA4758_CMD_SO_PATH: 374296341Sdelphij if (p == NULL) { 375296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, 376296341Sdelphij ERR_R_PASSED_NULL_PARAMETER); 377296341Sdelphij return 0; 378296341Sdelphij } 379296341Sdelphij if (initialised) { 380296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, CCA4758_R_ALREADY_LOADED); 381296341Sdelphij return 0; 382296341Sdelphij } 383296341Sdelphij return set_CCA4758_LIB_NAME((const char *)p); 384296341Sdelphij default: 385296341Sdelphij break; 386296341Sdelphij } 387296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, 388296341Sdelphij CCA4758_R_COMMAND_NOT_IMPLEMENTED); 389296341Sdelphij return 0; 390296341Sdelphij} 391160814Ssimon 392296341Sdelphij# ifndef OPENSSL_NO_RSA 393160814Ssimon 394296341Sdelphij# define MAX_CCA_PKA_TOKEN_SIZE 2500 395160814Ssimon 396296341Sdelphijstatic EVP_PKEY *ibm_4758_load_privkey(ENGINE *e, const char *key_id, 397296341Sdelphij UI_METHOD *ui_method, 398296341Sdelphij void *callback_data) 399296341Sdelphij{ 400296341Sdelphij RSA *rtmp = NULL; 401296341Sdelphij EVP_PKEY *res = NULL; 402296341Sdelphij unsigned char *keyToken = NULL; 403296341Sdelphij unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE]; 404296341Sdelphij long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 405296341Sdelphij long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 406296341Sdelphij long returnCode; 407296341Sdelphij long reasonCode; 408296341Sdelphij long exitDataLength = 0; 409296341Sdelphij long ruleArrayLength = 0; 410296341Sdelphij unsigned char exitData[8]; 411296341Sdelphij unsigned char ruleArray[8]; 412296341Sdelphij unsigned char keyLabel[64]; 413296341Sdelphij unsigned long keyLabelLength = strlen(key_id); 414296341Sdelphij unsigned char modulus[256]; 415296341Sdelphij long modulusFieldLength = sizeof(modulus); 416296341Sdelphij long modulusLength = 0; 417296341Sdelphij unsigned char exponent[256]; 418296341Sdelphij long exponentLength = sizeof(exponent); 419160814Ssimon 420296341Sdelphij if (keyLabelLength > sizeof(keyLabel)) { 421296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 422296341Sdelphij CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 423296341Sdelphij return NULL; 424296341Sdelphij } 425160814Ssimon 426296341Sdelphij memset(keyLabel, ' ', sizeof(keyLabel)); 427296341Sdelphij memcpy(keyLabel, key_id, keyLabelLength); 428160814Ssimon 429296341Sdelphij keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); 430296341Sdelphij if (!keyToken) { 431296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); 432296341Sdelphij goto err; 433296341Sdelphij } 434160814Ssimon 435296341Sdelphij keyRecordRead(&returnCode, &reasonCode, &exitDataLength, 436296341Sdelphij exitData, &ruleArrayLength, ruleArray, keyLabel, 437296341Sdelphij &keyTokenLength, keyToken + sizeof(long)); 438160814Ssimon 439296341Sdelphij if (returnCode) { 440296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 441296341Sdelphij CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 442296341Sdelphij goto err; 443296341Sdelphij } 444160814Ssimon 445296341Sdelphij publicKeyExtract(&returnCode, &reasonCode, &exitDataLength, 446296341Sdelphij exitData, &ruleArrayLength, ruleArray, &keyTokenLength, 447296341Sdelphij keyToken + sizeof(long), &pubKeyTokenLength, 448296341Sdelphij pubKeyToken); 449160814Ssimon 450296341Sdelphij if (returnCode) { 451296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 452296341Sdelphij CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 453296341Sdelphij goto err; 454296341Sdelphij } 455160814Ssimon 456296341Sdelphij if (!getModulusAndExponent(pubKeyToken, &exponentLength, 457296341Sdelphij exponent, &modulusLength, &modulusFieldLength, 458296341Sdelphij modulus)) { 459296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, 460296341Sdelphij CCA4758_R_FAILED_LOADING_PRIVATE_KEY); 461296341Sdelphij goto err; 462296341Sdelphij } 463160814Ssimon 464296341Sdelphij (*(long *)keyToken) = keyTokenLength; 465296341Sdelphij rtmp = RSA_new_method(e); 466296341Sdelphij RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); 467160814Ssimon 468296341Sdelphij rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); 469296341Sdelphij rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); 470296341Sdelphij rtmp->flags |= RSA_FLAG_EXT_PKEY; 471160814Ssimon 472296341Sdelphij res = EVP_PKEY_new(); 473296341Sdelphij EVP_PKEY_assign_RSA(res, rtmp); 474160814Ssimon 475296341Sdelphij return res; 476296341Sdelphij err: 477296341Sdelphij if (keyToken) 478296341Sdelphij OPENSSL_free(keyToken); 479296341Sdelphij return NULL; 480296341Sdelphij} 481160814Ssimon 482296341Sdelphijstatic EVP_PKEY *ibm_4758_load_pubkey(ENGINE *e, const char *key_id, 483296341Sdelphij UI_METHOD *ui_method, 484296341Sdelphij void *callback_data) 485296341Sdelphij{ 486296341Sdelphij RSA *rtmp = NULL; 487296341Sdelphij EVP_PKEY *res = NULL; 488296341Sdelphij unsigned char *keyToken = NULL; 489296341Sdelphij long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; 490296341Sdelphij long returnCode; 491296341Sdelphij long reasonCode; 492296341Sdelphij long exitDataLength = 0; 493296341Sdelphij long ruleArrayLength = 0; 494296341Sdelphij unsigned char exitData[8]; 495296341Sdelphij unsigned char ruleArray[8]; 496296341Sdelphij unsigned char keyLabel[64]; 497296341Sdelphij unsigned long keyLabelLength = strlen(key_id); 498296341Sdelphij unsigned char modulus[512]; 499296341Sdelphij long modulusFieldLength = sizeof(modulus); 500296341Sdelphij long modulusLength = 0; 501296341Sdelphij unsigned char exponent[512]; 502296341Sdelphij long exponentLength = sizeof(exponent); 503160814Ssimon 504296341Sdelphij if (keyLabelLength > sizeof(keyLabel)) { 505296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 506296341Sdelphij CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 507296341Sdelphij return NULL; 508296341Sdelphij } 509160814Ssimon 510296341Sdelphij memset(keyLabel, ' ', sizeof(keyLabel)); 511296341Sdelphij memcpy(keyLabel, key_id, keyLabelLength); 512160814Ssimon 513296341Sdelphij keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); 514296341Sdelphij if (!keyToken) { 515296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); 516296341Sdelphij goto err; 517296341Sdelphij } 518160814Ssimon 519296341Sdelphij keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData, 520296341Sdelphij &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength, 521296341Sdelphij keyToken + sizeof(long)); 522160814Ssimon 523296341Sdelphij if (returnCode) { 524296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); 525296341Sdelphij goto err; 526296341Sdelphij } 527160814Ssimon 528296341Sdelphij if (!getModulusAndExponent(keyToken + sizeof(long), &exponentLength, 529296341Sdelphij exponent, &modulusLength, &modulusFieldLength, 530296341Sdelphij modulus)) { 531296341Sdelphij CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, 532296341Sdelphij CCA4758_R_FAILED_LOADING_PUBLIC_KEY); 533296341Sdelphij goto err; 534296341Sdelphij } 535160814Ssimon 536296341Sdelphij (*(long *)keyToken) = keyTokenLength; 537296341Sdelphij rtmp = RSA_new_method(e); 538296341Sdelphij RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); 539296341Sdelphij rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); 540296341Sdelphij rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); 541296341Sdelphij rtmp->flags |= RSA_FLAG_EXT_PKEY; 542296341Sdelphij res = EVP_PKEY_new(); 543296341Sdelphij EVP_PKEY_assign_RSA(res, rtmp); 544160814Ssimon 545296341Sdelphij return res; 546296341Sdelphij err: 547296341Sdelphij if (keyToken) 548296341Sdelphij OPENSSL_free(keyToken); 549296341Sdelphij return NULL; 550296341Sdelphij} 551160814Ssimon 552160814Ssimonstatic int cca_rsa_pub_enc(int flen, const unsigned char *from, 553296341Sdelphij unsigned char *to, RSA *rsa, int padding) 554296341Sdelphij{ 555296341Sdelphij long returnCode; 556296341Sdelphij long reasonCode; 557296341Sdelphij long lflen = flen; 558296341Sdelphij long exitDataLength = 0; 559296341Sdelphij unsigned char exitData[8]; 560296341Sdelphij long ruleArrayLength = 1; 561296341Sdelphij unsigned char ruleArray[8] = "PKCS-1.2"; 562296341Sdelphij long dataStructureLength = 0; 563296341Sdelphij unsigned char dataStructure[8]; 564296341Sdelphij long outputLength = RSA_size(rsa); 565296341Sdelphij long keyTokenLength; 566296341Sdelphij unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); 567160814Ssimon 568296341Sdelphij keyTokenLength = *(long *)keyToken; 569296341Sdelphij keyToken += sizeof(long); 570160814Ssimon 571296341Sdelphij pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData, 572296341Sdelphij &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from, 573296341Sdelphij &dataStructureLength, dataStructure, &keyTokenLength, 574296341Sdelphij keyToken, &outputLength, to); 575160814Ssimon 576296341Sdelphij if (returnCode || reasonCode) 577296341Sdelphij return -(returnCode << 16 | reasonCode); 578296341Sdelphij return outputLength; 579296341Sdelphij} 580160814Ssimon 581160814Ssimonstatic int cca_rsa_priv_dec(int flen, const unsigned char *from, 582296341Sdelphij unsigned char *to, RSA *rsa, int padding) 583296341Sdelphij{ 584296341Sdelphij long returnCode; 585296341Sdelphij long reasonCode; 586296341Sdelphij long lflen = flen; 587296341Sdelphij long exitDataLength = 0; 588296341Sdelphij unsigned char exitData[8]; 589296341Sdelphij long ruleArrayLength = 1; 590296341Sdelphij unsigned char ruleArray[8] = "PKCS-1.2"; 591296341Sdelphij long dataStructureLength = 0; 592296341Sdelphij unsigned char dataStructure[8]; 593296341Sdelphij long outputLength = RSA_size(rsa); 594296341Sdelphij long keyTokenLength; 595296341Sdelphij unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); 596160814Ssimon 597296341Sdelphij keyTokenLength = *(long *)keyToken; 598296341Sdelphij keyToken += sizeof(long); 599160814Ssimon 600296341Sdelphij pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData, 601296341Sdelphij &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from, 602296341Sdelphij &dataStructureLength, dataStructure, &keyTokenLength, 603296341Sdelphij keyToken, &outputLength, to); 604160814Ssimon 605296341Sdelphij return (returnCode | reasonCode) ? 0 : 1; 606296341Sdelphij} 607160814Ssimon 608296341Sdelphij# define SSL_SIG_LEN 36 609160814Ssimon 610296341Sdelphijstatic int cca_rsa_verify(int type, const unsigned char *m, 611296341Sdelphij unsigned int m_len, const unsigned char *sigbuf, 612296341Sdelphij unsigned int siglen, const RSA *rsa) 613296341Sdelphij{ 614296341Sdelphij long returnCode; 615296341Sdelphij long reasonCode; 616296341Sdelphij long lsiglen = siglen; 617296341Sdelphij long exitDataLength = 0; 618296341Sdelphij unsigned char exitData[8]; 619296341Sdelphij long ruleArrayLength = 1; 620296341Sdelphij unsigned char ruleArray[8] = "PKCS-1.1"; 621296341Sdelphij long keyTokenLength; 622296341Sdelphij unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); 623296341Sdelphij long length = SSL_SIG_LEN; 624296341Sdelphij long keyLength; 625296341Sdelphij unsigned char *hashBuffer = NULL; 626296341Sdelphij X509_SIG sig; 627296341Sdelphij ASN1_TYPE parameter; 628296341Sdelphij X509_ALGOR algorithm; 629296341Sdelphij ASN1_OCTET_STRING digest; 630160814Ssimon 631296341Sdelphij keyTokenLength = *(long *)keyToken; 632296341Sdelphij keyToken += sizeof(long); 633160814Ssimon 634296341Sdelphij if (type == NID_md5 || type == NID_sha1) { 635296341Sdelphij sig.algor = &algorithm; 636296341Sdelphij algorithm.algorithm = OBJ_nid2obj(type); 637160814Ssimon 638296341Sdelphij if (!algorithm.algorithm) { 639296341Sdelphij CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 640296341Sdelphij CCA4758_R_UNKNOWN_ALGORITHM_TYPE); 641296341Sdelphij return 0; 642296341Sdelphij } 643160814Ssimon 644296341Sdelphij if (!algorithm.algorithm->length) { 645296341Sdelphij CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 646296341Sdelphij CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); 647296341Sdelphij return 0; 648296341Sdelphij } 649160814Ssimon 650296341Sdelphij parameter.type = V_ASN1_NULL; 651296341Sdelphij parameter.value.ptr = NULL; 652296341Sdelphij algorithm.parameter = ¶meter; 653160814Ssimon 654296341Sdelphij sig.digest = &digest; 655296341Sdelphij sig.digest->data = (unsigned char *)m; 656296341Sdelphij sig.digest->length = m_len; 657160814Ssimon 658296341Sdelphij length = i2d_X509_SIG(&sig, NULL); 659296341Sdelphij } 660160814Ssimon 661296341Sdelphij keyLength = RSA_size(rsa); 662160814Ssimon 663296341Sdelphij if (length - RSA_PKCS1_PADDING > keyLength) { 664296341Sdelphij CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 665296341Sdelphij CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 666296341Sdelphij return 0; 667296341Sdelphij } 668160814Ssimon 669296341Sdelphij switch (type) { 670296341Sdelphij case NID_md5_sha1: 671296341Sdelphij if (m_len != SSL_SIG_LEN) { 672296341Sdelphij CCA4758err(CCA4758_F_CCA_RSA_VERIFY, 673296341Sdelphij CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 674296341Sdelphij return 0; 675296341Sdelphij } 676160814Ssimon 677296341Sdelphij hashBuffer = (unsigned char *)m; 678296341Sdelphij length = m_len; 679296341Sdelphij break; 680296341Sdelphij case NID_md5: 681296341Sdelphij { 682296341Sdelphij unsigned char *ptr; 683296341Sdelphij ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); 684296341Sdelphij if (!hashBuffer) { 685296341Sdelphij CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE); 686296341Sdelphij return 0; 687296341Sdelphij } 688160814Ssimon 689296341Sdelphij i2d_X509_SIG(&sig, &ptr); 690296341Sdelphij } 691296341Sdelphij break; 692296341Sdelphij case NID_sha1: 693296341Sdelphij { 694296341Sdelphij unsigned char *ptr; 695296341Sdelphij ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); 696296341Sdelphij if (!hashBuffer) { 697296341Sdelphij CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE); 698296341Sdelphij return 0; 699296341Sdelphij } 700296341Sdelphij i2d_X509_SIG(&sig, &ptr); 701296341Sdelphij } 702296341Sdelphij break; 703296341Sdelphij default: 704296341Sdelphij return 0; 705296341Sdelphij } 706160814Ssimon 707296341Sdelphij digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength, 708296341Sdelphij exitData, &ruleArrayLength, ruleArray, 709296341Sdelphij &keyTokenLength, keyToken, &length, hashBuffer, 710296341Sdelphij &lsiglen, (unsigned char *)sigbuf); 711160814Ssimon 712296341Sdelphij if (type == NID_sha1 || type == NID_md5) { 713296341Sdelphij OPENSSL_cleanse(hashBuffer, keyLength + 1); 714296341Sdelphij OPENSSL_free(hashBuffer); 715296341Sdelphij } 716160814Ssimon 717296341Sdelphij return ((returnCode || reasonCode) ? 0 : 1); 718296341Sdelphij} 719160814Ssimon 720296341Sdelphij# define SSL_SIG_LEN 36 721160814Ssimon 722160814Ssimonstatic int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, 723296341Sdelphij unsigned char *sigret, unsigned int *siglen, 724296341Sdelphij const RSA *rsa) 725296341Sdelphij{ 726296341Sdelphij long returnCode; 727296341Sdelphij long reasonCode; 728296341Sdelphij long exitDataLength = 0; 729296341Sdelphij unsigned char exitData[8]; 730296341Sdelphij long ruleArrayLength = 1; 731296341Sdelphij unsigned char ruleArray[8] = "PKCS-1.1"; 732296341Sdelphij long outputLength = 256; 733296341Sdelphij long outputBitLength; 734296341Sdelphij long keyTokenLength; 735296341Sdelphij unsigned char *hashBuffer = NULL; 736296341Sdelphij unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); 737296341Sdelphij long length = SSL_SIG_LEN; 738296341Sdelphij long keyLength; 739296341Sdelphij X509_SIG sig; 740296341Sdelphij ASN1_TYPE parameter; 741296341Sdelphij X509_ALGOR algorithm; 742296341Sdelphij ASN1_OCTET_STRING digest; 743160814Ssimon 744296341Sdelphij keyTokenLength = *(long *)keyToken; 745296341Sdelphij keyToken += sizeof(long); 746160814Ssimon 747296341Sdelphij if (type == NID_md5 || type == NID_sha1) { 748296341Sdelphij sig.algor = &algorithm; 749296341Sdelphij algorithm.algorithm = OBJ_nid2obj(type); 750160814Ssimon 751296341Sdelphij if (!algorithm.algorithm) { 752296341Sdelphij CCA4758err(CCA4758_F_CCA_RSA_SIGN, 753296341Sdelphij CCA4758_R_UNKNOWN_ALGORITHM_TYPE); 754296341Sdelphij return 0; 755296341Sdelphij } 756160814Ssimon 757296341Sdelphij if (!algorithm.algorithm->length) { 758296341Sdelphij CCA4758err(CCA4758_F_CCA_RSA_SIGN, 759296341Sdelphij CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); 760296341Sdelphij return 0; 761296341Sdelphij } 762160814Ssimon 763296341Sdelphij parameter.type = V_ASN1_NULL; 764296341Sdelphij parameter.value.ptr = NULL; 765296341Sdelphij algorithm.parameter = ¶meter; 766160814Ssimon 767296341Sdelphij sig.digest = &digest; 768296341Sdelphij sig.digest->data = (unsigned char *)m; 769296341Sdelphij sig.digest->length = m_len; 770160814Ssimon 771296341Sdelphij length = i2d_X509_SIG(&sig, NULL); 772296341Sdelphij } 773160814Ssimon 774296341Sdelphij keyLength = RSA_size(rsa); 775160814Ssimon 776296341Sdelphij if (length - RSA_PKCS1_PADDING > keyLength) { 777296341Sdelphij CCA4758err(CCA4758_F_CCA_RSA_SIGN, 778296341Sdelphij CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 779296341Sdelphij return 0; 780296341Sdelphij } 781160814Ssimon 782296341Sdelphij switch (type) { 783296341Sdelphij case NID_md5_sha1: 784296341Sdelphij if (m_len != SSL_SIG_LEN) { 785296341Sdelphij CCA4758err(CCA4758_F_CCA_RSA_SIGN, 786296341Sdelphij CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); 787296341Sdelphij return 0; 788296341Sdelphij } 789296341Sdelphij hashBuffer = (unsigned char *)m; 790296341Sdelphij length = m_len; 791296341Sdelphij break; 792296341Sdelphij case NID_md5: 793296341Sdelphij { 794296341Sdelphij unsigned char *ptr; 795296341Sdelphij ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); 796296341Sdelphij if (!hashBuffer) { 797296341Sdelphij CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); 798296341Sdelphij return 0; 799296341Sdelphij } 800296341Sdelphij i2d_X509_SIG(&sig, &ptr); 801296341Sdelphij } 802296341Sdelphij break; 803296341Sdelphij case NID_sha1: 804296341Sdelphij { 805296341Sdelphij unsigned char *ptr; 806296341Sdelphij ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); 807296341Sdelphij if (!hashBuffer) { 808296341Sdelphij CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); 809296341Sdelphij return 0; 810296341Sdelphij } 811296341Sdelphij i2d_X509_SIG(&sig, &ptr); 812296341Sdelphij } 813296341Sdelphij break; 814296341Sdelphij default: 815296341Sdelphij return 0; 816296341Sdelphij } 817160814Ssimon 818296341Sdelphij digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength, 819296341Sdelphij exitData, &ruleArrayLength, ruleArray, 820296341Sdelphij &keyTokenLength, keyToken, &length, hashBuffer, 821296341Sdelphij &outputLength, &outputBitLength, sigret); 822160814Ssimon 823296341Sdelphij if (type == NID_sha1 || type == NID_md5) { 824296341Sdelphij OPENSSL_cleanse(hashBuffer, keyLength + 1); 825296341Sdelphij OPENSSL_free(hashBuffer); 826296341Sdelphij } 827160814Ssimon 828296341Sdelphij *siglen = outputLength; 829160814Ssimon 830296341Sdelphij return ((returnCode || reasonCode) ? 0 : 1); 831296341Sdelphij} 832160814Ssimon 833296341Sdelphijstatic int getModulusAndExponent(const unsigned char *token, 834296341Sdelphij long *exponentLength, 835296341Sdelphij unsigned char *exponent, long *modulusLength, 836296341Sdelphij long *modulusFieldLength, 837296341Sdelphij unsigned char *modulus) 838296341Sdelphij{ 839296341Sdelphij unsigned long len; 840160814Ssimon 841296341Sdelphij if (*token++ != (char)0x1E) /* internal PKA token? */ 842296341Sdelphij return 0; 843160814Ssimon 844296341Sdelphij if (*token++) /* token version must be zero */ 845296341Sdelphij return 0; 846160814Ssimon 847296341Sdelphij len = *token++; 848296341Sdelphij len = len << 8; 849296341Sdelphij len |= (unsigned char)*token++; 850160814Ssimon 851296341Sdelphij token += 4; /* skip reserved bytes */ 852160814Ssimon 853296341Sdelphij if (*token++ == (char)0x04) { 854296341Sdelphij if (*token++) /* token version must be zero */ 855296341Sdelphij return 0; 856160814Ssimon 857296341Sdelphij len = *token++; 858296341Sdelphij len = len << 8; 859296341Sdelphij len |= (unsigned char)*token++; 860160814Ssimon 861296341Sdelphij token += 2; /* skip reserved section */ 862160814Ssimon 863296341Sdelphij len = *token++; 864296341Sdelphij len = len << 8; 865296341Sdelphij len |= (unsigned char)*token++; 866160814Ssimon 867296341Sdelphij *exponentLength = len; 868160814Ssimon 869296341Sdelphij len = *token++; 870296341Sdelphij len = len << 8; 871296341Sdelphij len |= (unsigned char)*token++; 872160814Ssimon 873296341Sdelphij *modulusLength = len; 874160814Ssimon 875296341Sdelphij len = *token++; 876296341Sdelphij len = len << 8; 877296341Sdelphij len |= (unsigned char)*token++; 878160814Ssimon 879296341Sdelphij *modulusFieldLength = len; 880160814Ssimon 881296341Sdelphij memcpy(exponent, token, *exponentLength); 882296341Sdelphij token += *exponentLength; 883160814Ssimon 884296341Sdelphij memcpy(modulus, token, *modulusFieldLength); 885296341Sdelphij return 1; 886296341Sdelphij } 887296341Sdelphij return 0; 888296341Sdelphij} 889160814Ssimon 890296341Sdelphij# endif /* OPENSSL_NO_RSA */ 891160814Ssimon 892160814Ssimonstatic int cca_random_status(void) 893296341Sdelphij{ 894296341Sdelphij return 1; 895296341Sdelphij} 896160814Ssimon 897296341Sdelphijstatic int cca_get_random_bytes(unsigned char *buf, int num) 898296341Sdelphij{ 899296341Sdelphij long ret_code; 900296341Sdelphij long reason_code; 901296341Sdelphij long exit_data_length; 902296341Sdelphij unsigned char exit_data[4]; 903296341Sdelphij unsigned char form[] = "RANDOM "; 904296341Sdelphij unsigned char rand_buf[8]; 905160814Ssimon 906296341Sdelphij while (num >= (int)sizeof(rand_buf)) { 907296341Sdelphij randomNumberGenerate(&ret_code, &reason_code, &exit_data_length, 908296341Sdelphij exit_data, form, rand_buf); 909296341Sdelphij if (ret_code) 910296341Sdelphij return 0; 911296341Sdelphij num -= sizeof(rand_buf); 912296341Sdelphij memcpy(buf, rand_buf, sizeof(rand_buf)); 913296341Sdelphij buf += sizeof(rand_buf); 914296341Sdelphij } 915160814Ssimon 916296341Sdelphij if (num) { 917296341Sdelphij randomNumberGenerate(&ret_code, &reason_code, NULL, NULL, 918296341Sdelphij form, rand_buf); 919296341Sdelphij if (ret_code) 920296341Sdelphij return 0; 921296341Sdelphij memcpy(buf, rand_buf, num); 922296341Sdelphij } 923160814Ssimon 924296341Sdelphij return 1; 925296341Sdelphij} 926160814Ssimon 927296341Sdelphij# ifndef OPENSSL_NO_RSA 928160814Ssimonstatic void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx, 929296341Sdelphij long argl, void *argp) 930296341Sdelphij{ 931296341Sdelphij if (item) 932296341Sdelphij OPENSSL_free(item); 933296341Sdelphij} 934296341Sdelphij# endif 935160814Ssimon 936160814Ssimon/* Goo to handle building as a dynamic engine */ 937296341Sdelphij# ifndef OPENSSL_NO_DYNAMIC_ENGINE 938160814Ssimonstatic int bind_fn(ENGINE *e, const char *id) 939296341Sdelphij{ 940296341Sdelphij if (id && (strcmp(id, engine_4758_cca_id) != 0) && 941296341Sdelphij (strcmp(id, engine_4758_cca_id_alt) != 0)) 942296341Sdelphij return 0; 943296341Sdelphij if (!bind_helper(e)) 944296341Sdelphij return 0; 945296341Sdelphij return 1; 946296341Sdelphij} 947296341Sdelphij 948160814SsimonIMPLEMENT_DYNAMIC_CHECK_FN() 949296341Sdelphij IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) 950296341Sdelphij# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ 951296341Sdelphij# endif /* !OPENSSL_NO_HW_4758_CCA */ 952296341Sdelphij#endif /* !OPENSSL_NO_HW */ 953