static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) { int initialised = ((dso == NULL) ? 0 : 1); switch(cmd) { case CCA4758_CMD_SO_PATH: if(p == NULL) { CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, ERR_R_PASSED_NULL_PARAMETER); return 0; } if(initialised) { CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, CCA4758_R_ALREADY_LOADED); return 0; } return set_CCA4758_LIB_NAME((const char *)p); default: break; } CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, CCA4758_R_COMMAND_NOT_IMPLEMENTED); return 0; }
static int ibm_4758_cca_finish(ENGINE *e) { free_CCA4758_LIB_NAME(); if(!dso) { CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_NOT_LOADED); return 0; } if(!DSO_free(dso)) { CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_UNIT_FAILURE); return 0; } dso = NULL; #ifndef OPENSSL_NO_RSA keyRecordRead = (F_KEYRECORDREAD)0; randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0; digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0; digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; publicKeyExtract = (F_PUBLICKEYEXTRACT)0; pkaEncrypt = (F_PKAENCRYPT)0; pkaDecrypt = (F_PKADECRYPT)0; #endif randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0; return 1; }
static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, const RSA *rsa) { long returnCode; long reasonCode; long exitDataLength = 0; unsigned char exitData[8]; long ruleArrayLength = 1; unsigned char ruleArray[8] = "PKCS-1.1"; long outputLength = 256; long outputBitLength; long keyTokenLength; unsigned char *hashBuffer = NULL; unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); long length = SSL_SIG_LEN; long keyLength; X509_SIG sig; ASN1_TYPE parameter; X509_ALGOR algorithm; ASN1_OCTET_STRING digest; keyTokenLength = *(long *)keyToken; keyToken += sizeof(long); if (type == NID_md5 || type == NID_sha1) { sig.algor = &algorithm; algorithm.algorithm = OBJ_nid2obj(type); if (!algorithm.algorithm) { CCA4758err(CCA4758_F_CCA_RSA_SIGN, CCA4758_R_UNKNOWN_ALGORITHM_TYPE); return 0; } if (!algorithm.algorithm->length) { CCA4758err(CCA4758_F_CCA_RSA_SIGN, CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); return 0; } parameter.type = V_ASN1_NULL; parameter.value.ptr = NULL; algorithm.parameter = ¶meter; sig.digest = &digest; sig.digest->data = (unsigned char *)m; sig.digest->length = m_len; length = i2d_X509_SIG(&sig, NULL); } keyLength = RSA_size(rsa); if (length - RSA_PKCS1_PADDING > keyLength) { CCA4758err(CCA4758_F_CCA_RSA_SIGN, CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); return 0; } switch (type) { case NID_md5_sha1: if (m_len != SSL_SIG_LEN) { CCA4758err(CCA4758_F_CCA_RSA_SIGN, CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); return 0; } hashBuffer = (unsigned char *)m; length = m_len; break; case NID_md5: { unsigned char *ptr; ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); if (!hashBuffer) { CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); return 0; } i2d_X509_SIG(&sig, &ptr); } break; case NID_sha1: { unsigned char *ptr; ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); if (!hashBuffer) { CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); return 0; } i2d_X509_SIG(&sig, &ptr); } break; default: return 0; } digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength, exitData, &ruleArrayLength, ruleArray, &keyTokenLength, keyToken, &length, hashBuffer, &outputLength, &outputBitLength, sigret); if (type == NID_sha1 || type == NID_md5) { OPENSSL_cleanse(hashBuffer, keyLength + 1); OPENSSL_free(hashBuffer); } *siglen = outputLength; return ((returnCode || reasonCode) ? 0 : 1); }
static EVP_PKEY *ibm_4758_load_pubkey(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data) { RSA *rtmp = NULL; EVP_PKEY *res = NULL; unsigned char *keyToken = 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 long keyLabelLength = strlen(key_id); unsigned char modulus[512]; long modulusFieldLength = sizeof(modulus); long modulusLength = 0; unsigned char exponent[512]; long exponentLength = sizeof(exponent); if (keyLabelLength > sizeof(keyLabel)) { CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); return NULL; } memset(keyLabel, ' ', sizeof(keyLabel)); memcpy(keyLabel, key_id, keyLabelLength); keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); if (!keyToken) { CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); goto err; } keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData, &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength, keyToken + sizeof(long)); if (returnCode) { CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); goto err; } if (!getModulusAndExponent(keyToken + sizeof(long), &exponentLength, exponent, &modulusLength, &modulusFieldLength, modulus)) { CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, CCA4758_R_FAILED_LOADING_PUBLIC_KEY); goto err; } (*(long *)keyToken) = keyTokenLength; rtmp = RSA_new_method(e); RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); rtmp->flags |= RSA_FLAG_EXT_PKEY; res = EVP_PKEY_new(); EVP_PKEY_assign_RSA(res, rtmp); return res; err: if (keyToken) OPENSSL_free(keyToken); return NULL; }
static int ibm_4758_cca_init(ENGINE *e) { if (dso) { CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_ALREADY_LOADED); goto err; } dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0); if (!dso) { CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); goto err; } # ifndef OPENSSL_NO_RSA if (!(keyRecordRead = (F_KEYRECORDREAD) DSO_bind_func(dso, n_keyRecordRead)) || !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) DSO_bind_func(dso, n_randomNumberGenerate)) || !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) DSO_bind_func(dso, n_digitalSignatureGenerate)) || !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY) DSO_bind_func(dso, n_digitalSignatureVerify)) || !(publicKeyExtract = (F_PUBLICKEYEXTRACT) DSO_bind_func(dso, n_publicKeyExtract)) || !(pkaEncrypt = (F_PKAENCRYPT) DSO_bind_func(dso, n_pkaEncrypt)) || !(pkaDecrypt = (F_PKADECRYPT) DSO_bind_func(dso, n_pkaDecrypt))) { CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); goto err; } # else if (!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) DSO_bind_func(dso, n_randomNumberGenerate))) { CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); goto err; } # endif # ifndef OPENSSL_NO_RSA hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle", NULL, NULL, cca_ex_free); # endif return 1; err: if (dso) DSO_free(dso); dso = NULL; # ifndef OPENSSL_NO_RSA keyRecordRead = (F_KEYRECORDREAD) 0; digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0; digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; publicKeyExtract = (F_PUBLICKEYEXTRACT)0; pkaEncrypt = (F_PKAENCRYPT) 0; pkaDecrypt = (F_PKADECRYPT) 0; # endif randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; return 0; }