hw_4758_cca.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/* Author: Maurice Gittens <maurice@gittens.nl> */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#ifndef OPENSSL_NO_HW
#ifndef OPENSSL_NO_HW_4758_CCA
#ifdef FLAT_INC
#include "hw_4758_cca.h"
#else
#include "vendor_defns/hw_4758_cca.h"
#endif
#include "hw_4758_cca_err.c"
static int ibm_4758_cca_destroy(ENGINE *e);
static int ibm_4758_cca_init(ENGINE *e);
static int ibm_4758_cca_finish(ENGINE *e);
/* rsa functions */
/*---------------*/
#ifndef OPENSSL_NO_RSA
/* utility functions */
/*-----------------------*/
unsigned char *exponent, long *modulusLength,
long *modulusFieldLength, unsigned char *modulus);
#endif
/* RAND number functions */
/*-----------------------*/
static int cca_get_random_bytes(unsigned char*, int );
static int cca_random_status(void);
/* Function pointers for CCA verbs */
/*---------------------------------*/
#ifndef OPENSSL_NO_RSA
static F_KEYRECORDREAD keyRecordRead;
static F_PUBLICKEYEXTRACT publicKeyExtract;
static F_PKAENCRYPT pkaEncrypt;
static F_PKADECRYPT pkaDecrypt;
#endif
/* static variables */
/*------------------*/
static const char *CCA4758_LIB_NAME = NULL;
static const char *get_CCA4758_LIB_NAME(void)
{
if(CCA4758_LIB_NAME)
return CCA4758_LIB_NAME;
return CCA_LIB_NAME;
}
static void free_CCA4758_LIB_NAME(void)
{
if(CCA4758_LIB_NAME)
OPENSSL_free((void*)CCA4758_LIB_NAME);
}
static long set_CCA4758_LIB_NAME(const char *name)
{
}
#ifndef OPENSSL_NO_RSA
static const char* n_keyRecordRead = CSNDKRR;
static const char* n_digitalSignatureGenerate = CSNDDSG;
static const char* n_digitalSignatureVerify = CSNDDSV;
static const char* n_publicKeyExtract = CSNDPKX;
static const char* n_pkaEncrypt = CSNDPKE;
static const char* n_pkaDecrypt = CSNDPKD;
#endif
static const char* n_randomNumberGenerate = CSNBRNG;
static int hndidx = -1;
/* openssl engine initialization structures */
/*------------------------------------------*/
#define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE
static const ENGINE_CMD_DEFN cca4758_cmd_defns[] = {
"SO_PATH",
"Specifies the path to the '4758cca' shared library",
};
#ifndef OPENSSL_NO_RSA
static RSA_METHOD ibm_4758_cca_rsa =
{
"IBM 4758 CCA RSA method",
NULL,
NULL,
NULL, /*rsa_mod_exp,*/
NULL, /*mod_exp_mont,*/
NULL, /* init */
NULL, /* finish */
RSA_FLAG_SIGN_VER, /* flags */
NULL, /* app_data */
cca_rsa_sign, /* rsa_sign */
cca_rsa_verify /* rsa_verify */
};
#endif
static RAND_METHOD ibm_4758_cca_rand =
{
/* "IBM 4758 RAND method", */
NULL, /* seed */
cca_get_random_bytes, /* get random bytes from the card */
NULL, /* cleanup */
NULL, /* add */
cca_get_random_bytes, /* pseudo rand */
cca_random_status, /* status */
};
static const char *engine_4758_cca_id = "4758cca";
static const char *engine_4758_cca_name = "IBM 4758 CCA hardware engine support";
/* engine implementation */
/*-----------------------*/
static int bind_helper(ENGINE *e)
{
if(!ENGINE_set_id(e, engine_4758_cca_id) ||
!ENGINE_set_name(e, engine_4758_cca_name) ||
#ifndef OPENSSL_NO_RSA
!ENGINE_set_RSA(e, &ibm_4758_cca_rsa) ||
#endif
!ENGINE_set_RAND(e, &ibm_4758_cca_rand) ||
return 0;
/* Ensure the error handling is set up */
return 1;
}
#ifndef ENGINE_DYNAMIC_SUPPORT
static ENGINE *engine_4758_cca(void)
{
if(!ret)
return NULL;
if(!bind_helper(ret))
{
return NULL;
}
return ret;
}
void ENGINE_load_4758cca(void)
{
if (!e_4758) return;
}
#endif
static int ibm_4758_cca_destroy(ENGINE *e)
{
return 1;
}
static int ibm_4758_cca_init(ENGINE *e)
{
if(dso)
{
goto err;
}
if(!dso)
{
goto err;
}
#ifndef OPENSSL_NO_RSA
if(!(keyRecordRead = (F_KEYRECORDREAD)
!(pkaEncrypt = (F_PKAENCRYPT)
!(pkaDecrypt = (F_PKADECRYPT)
{
goto err;
}
#else
{
goto err;
}
#endif
return 1;
err:
if(dso)
keyRecordRead = (F_KEYRECORDREAD)0;
pkaEncrypt = (F_PKAENCRYPT)0;
pkaDecrypt = (F_PKADECRYPT)0;
return 0;
}
static int ibm_4758_cca_finish(ENGINE *e)
{
if(!dso)
{
return 0;
}
{
return 0;
}
keyRecordRead = (F_KEYRECORDREAD)0;
pkaEncrypt = (F_PKAENCRYPT)0;
pkaDecrypt = (F_PKADECRYPT)0;
return 1;
}
{
switch(cmd)
{
case CCA4758_CMD_SO_PATH:
if(p == NULL)
{
return 0;
}
if(initialised)
{
return 0;
}
return set_CCA4758_LIB_NAME((const char *)p);
default:
break;
}
return 0;
}
#ifndef OPENSSL_NO_RSA
#define MAX_CCA_PKA_TOKEN_SIZE 2500
{
unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE];
long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
long returnCode;
long reasonCode;
long exitDataLength = 0;
long ruleArrayLength = 0;
unsigned char exitData[8];
unsigned char ruleArray[8];
unsigned char keyLabel[64];
unsigned char modulus[256];
long modulusFieldLength = sizeof(modulus);
long modulusLength = 0;
unsigned char exponent[256];
long exponentLength = sizeof(exponent);
if (keyLabelLength > sizeof(keyLabel))
{
return NULL;
}
if (!keyToken)
{
goto err;
}
&keyTokenLength, keyToken+sizeof(long));
if (returnCode)
{
goto err;
}
if (returnCode)
{
goto err;
}
modulus))
{
goto err;
}
(*(long*)keyToken) = keyTokenLength;
rtmp = RSA_new_method(e);
res = EVP_PKEY_new();
return res;
err:
if (keyToken)
if (res)
if (rtmp)
return NULL;
}
{
long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
long returnCode;
long reasonCode;
long exitDataLength = 0;
long ruleArrayLength = 0;
unsigned char exitData[8];
unsigned char ruleArray[8];
unsigned char keyLabel[64];
unsigned char modulus[512];
long modulusFieldLength = sizeof(modulus);
long modulusLength = 0;
unsigned char exponent[512];
long exponentLength = sizeof(exponent);
if (keyLabelLength > sizeof(keyLabel))
{
return NULL;
}
if (!keyToken)
{
goto err;
}
keyToken+sizeof(long));
if (returnCode)
{
goto err;
}
{
goto err;
}
(*(long*)keyToken) = keyTokenLength;
rtmp = RSA_new_method(e);
res = EVP_PKEY_new();
return res;
err:
if (keyToken)
if (res)
if (rtmp)
return NULL;
}
{
long returnCode;
long reasonCode;
long exitDataLength = 0;
unsigned char exitData[8];
long ruleArrayLength = 1;
long dataStructureLength = 0;
unsigned char dataStructure[8];
long keyTokenLength;
keyTokenLength = *(long*)keyToken;
keyToken+=sizeof(long);
if (returnCode || reasonCode)
return outputLength;
}
{
long returnCode;
long reasonCode;
long exitDataLength = 0;
unsigned char exitData[8];
long ruleArrayLength = 1;
long dataStructureLength = 0;
unsigned char dataStructure[8];
long keyTokenLength;
keyTokenLength = *(long*)keyToken;
keyToken+=sizeof(long);
}
#define SSL_SIG_LEN 36
{
long returnCode;
long reasonCode;
long exitDataLength = 0;
unsigned char exitData[8];
long ruleArrayLength = 1;
long keyTokenLength;
long length = SSL_SIG_LEN;
long keyLength ;
unsigned char *hashBuffer = NULL;
keyTokenLength = *(long*)keyToken;
keyToken+=sizeof(long);
{
{
return 0;
}
{
return 0;
}
}
{
return 0;
}
switch (type)
{
case NID_md5_sha1 :
if (m_len != SSL_SIG_LEN)
{
return 0;
}
hashBuffer = (unsigned char *)m;
break;
case NID_md5 :
{
unsigned char *ptr;
(unsigned int)keyLength+1);
if (!hashBuffer)
{
return 0;
}
}
break;
case NID_sha1 :
{
unsigned char *ptr;
(unsigned int)keyLength+1);
if (!hashBuffer)
{
return 0;
}
}
break;
default:
return 0;
}
{
}
}
#define SSL_SIG_LEN 36
{
long returnCode;
long reasonCode;
long exitDataLength = 0;
unsigned char exitData[8];
long ruleArrayLength = 1;
long outputLength=256;
long outputBitLength;
long keyTokenLength;
unsigned char *hashBuffer = NULL;
long length = SSL_SIG_LEN;
long keyLength ;
keyTokenLength = *(long*)keyToken;
keyToken+=sizeof(long);
{
{
return 0;
}
{
return 0;
}
}
{
return 0;
}
switch (type)
{
case NID_md5_sha1 :
if (m_len != SSL_SIG_LEN)
{
return 0;
}
hashBuffer = (unsigned char*)m;
break;
case NID_md5 :
{
unsigned char *ptr;
(unsigned int)keyLength+1);
if (!hashBuffer)
{
return 0;
}
}
break;
case NID_sha1 :
{
unsigned char *ptr;
(unsigned int)keyLength+1);
if (!hashBuffer)
{
return 0;
}
}
break;
default:
return 0;
}
sigret);
{
}
*siglen = outputLength;
}
unsigned char *modulus)
{
unsigned long len;
return 0;
if (*token++) /* token version must be zero */
return 0;
if (*token++ == (char)0x04)
{
if (*token++) /* token version must be zero */
return 0;
*exponentLength = len;
*modulusLength = len;
token+= *exponentLength;
return 1;
}
return 0;
}
#endif /* OPENSSL_NO_RSA */
static int cca_random_status(void)
{
return 1;
}
{
long ret_code;
long reason_code;
long exit_data_length;
unsigned char exit_data[4];
unsigned char form[] = "RANDOM ";
unsigned char rand_buf[8];
{
if (ret_code)
return 0;
}
if (num)
{
if (ret_code)
return 0;
}
return 1;
}
{
if (item)
}
/* Goo to handle building as a dynamic engine */
#ifdef ENGINE_DYNAMIC_SUPPORT
{
return 0;
if(!bind_helper(e))
return 0;
return 1;
}
#endif /* ENGINE_DYNAMIC_SUPPORT */
#endif /* !OPENSSL_NO_HW_4758_CCA */
#endif /* !OPENSSL_NO_HW */