2002-12-17 11:49:12 +00:00
|
|
|
/*
|
|
|
|
* OpenSSL helper functions, e.g. for implementing MD5 support
|
|
|
|
* et al
|
|
|
|
*
|
|
|
|
* Copyright (C) 2002 Olaf Kirch <okir@lst.de>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "sc-pkcs11.h"
|
2003-01-16 20:10:28 +00:00
|
|
|
#include "opensc/scrandom.h"
|
2002-12-17 11:49:12 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_OPENSSL
|
2003-01-06 19:52:11 +00:00
|
|
|
#include <openssl/evp.h>
|
2003-02-03 12:20:24 +00:00
|
|
|
#include <openssl/rand.h>
|
2002-12-17 11:49:12 +00:00
|
|
|
|
|
|
|
static CK_RV sc_pkcs11_openssl_md_init(sc_pkcs11_operation_t *);
|
|
|
|
static CK_RV sc_pkcs11_openssl_md_update(sc_pkcs11_operation_t *,
|
|
|
|
CK_BYTE_PTR, CK_ULONG);
|
|
|
|
static CK_RV sc_pkcs11_openssl_md_final(sc_pkcs11_operation_t *,
|
|
|
|
CK_BYTE_PTR, CK_ULONG_PTR);
|
|
|
|
static void sc_pkcs11_openssl_md_release(sc_pkcs11_operation_t *);
|
|
|
|
|
|
|
|
static sc_pkcs11_mechanism_type_t openssl_sha1_mech = {
|
|
|
|
CKM_SHA_1,
|
|
|
|
{ 0, 0, CKF_DIGEST }, 0,
|
|
|
|
sizeof(struct sc_pkcs11_operation),
|
|
|
|
sc_pkcs11_openssl_md_release,
|
|
|
|
sc_pkcs11_openssl_md_init,
|
|
|
|
sc_pkcs11_openssl_md_update,
|
|
|
|
sc_pkcs11_openssl_md_final
|
|
|
|
};
|
|
|
|
|
|
|
|
static sc_pkcs11_mechanism_type_t openssl_md5_mech = {
|
|
|
|
CKM_MD5,
|
|
|
|
{ 0, 0, CKF_DIGEST }, 0,
|
|
|
|
sizeof(struct sc_pkcs11_operation),
|
|
|
|
sc_pkcs11_openssl_md_release,
|
|
|
|
sc_pkcs11_openssl_md_init,
|
|
|
|
sc_pkcs11_openssl_md_update,
|
|
|
|
sc_pkcs11_openssl_md_final
|
|
|
|
};
|
|
|
|
|
|
|
|
static sc_pkcs11_mechanism_type_t openssl_ripemd160_mech = {
|
|
|
|
CKM_RIPEMD160,
|
|
|
|
{ 0, 0, CKF_DIGEST }, 0,
|
|
|
|
sizeof(struct sc_pkcs11_operation),
|
|
|
|
sc_pkcs11_openssl_md_release,
|
|
|
|
sc_pkcs11_openssl_md_init,
|
|
|
|
sc_pkcs11_openssl_md_update,
|
|
|
|
sc_pkcs11_openssl_md_final
|
|
|
|
};
|
|
|
|
|
|
|
|
void
|
|
|
|
sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *card)
|
|
|
|
{
|
|
|
|
openssl_sha1_mech.mech_data = EVP_sha1();
|
|
|
|
sc_pkcs11_register_mechanism(card, &openssl_sha1_mech);
|
|
|
|
openssl_md5_mech.mech_data = EVP_md5();
|
|
|
|
sc_pkcs11_register_mechanism(card, &openssl_md5_mech);
|
|
|
|
openssl_ripemd160_mech.mech_data = EVP_ripemd160();
|
|
|
|
sc_pkcs11_register_mechanism(card, &openssl_ripemd160_mech);
|
|
|
|
}
|
|
|
|
|
2003-01-16 20:10:28 +00:00
|
|
|
static int rng_seeded = 0;
|
|
|
|
|
|
|
|
|
2002-12-17 11:49:12 +00:00
|
|
|
/*
|
|
|
|
* Handle OpenSSL digest functions
|
|
|
|
*/
|
|
|
|
#define DIGEST_CTX(op) \
|
|
|
|
((EVP_MD_CTX *) (op)->priv_data)
|
|
|
|
|
|
|
|
CK_RV
|
|
|
|
sc_pkcs11_openssl_md_init(sc_pkcs11_operation_t *op)
|
|
|
|
{
|
|
|
|
sc_pkcs11_mechanism_type_t *mt;
|
|
|
|
EVP_MD_CTX *md_ctx;
|
|
|
|
EVP_MD *md;
|
|
|
|
|
|
|
|
if (!op || !(mt = op->type) || !(md = (EVP_MD *) mt->mech_data))
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
2003-01-14 19:55:45 +00:00
|
|
|
if (!(md_ctx = (EVP_MD_CTX *) calloc(1, sizeof(*md_ctx))))
|
2002-12-17 11:49:12 +00:00
|
|
|
return CKR_HOST_MEMORY;
|
|
|
|
EVP_DigestInit(md_ctx, md);
|
|
|
|
op->priv_data = md_ctx;
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV
|
|
|
|
sc_pkcs11_openssl_md_update(sc_pkcs11_operation_t *op,
|
|
|
|
CK_BYTE_PTR pData, CK_ULONG pDataLen)
|
|
|
|
{
|
|
|
|
EVP_DigestUpdate(DIGEST_CTX(op), pData, pDataLen);
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV
|
|
|
|
sc_pkcs11_openssl_md_final(sc_pkcs11_operation_t *op,
|
|
|
|
CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
|
|
|
|
{
|
|
|
|
EVP_MD_CTX *md_ctx = DIGEST_CTX(op);
|
|
|
|
unsigned int len = *pulDigestLen;
|
|
|
|
|
|
|
|
if (len < EVP_MD_CTX_size(md_ctx)) {
|
|
|
|
*pulDigestLen = EVP_MD_CTX_size(md_ctx);
|
|
|
|
return CKR_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
EVP_DigestFinal(md_ctx, pDigest, &len);
|
|
|
|
*pulDigestLen = len;
|
|
|
|
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
sc_pkcs11_openssl_md_release(sc_pkcs11_operation_t *op)
|
|
|
|
{
|
|
|
|
EVP_MD_CTX *md_ctx = DIGEST_CTX(op);
|
|
|
|
|
|
|
|
if (md_ctx)
|
|
|
|
free(md_ctx);
|
|
|
|
op->priv_data = NULL;
|
|
|
|
}
|
|
|
|
|
2003-01-16 20:10:28 +00:00
|
|
|
CK_RV
|
|
|
|
sc_pkcs11_openssl_add_seed_rand(struct sc_pkcs11_session *session,
|
|
|
|
CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
|
|
|
|
{
|
|
|
|
if (!(session->slot->card->card->caps & SC_CARD_CAP_RNG))
|
|
|
|
return CKR_RANDOM_NO_RNG;
|
|
|
|
|
|
|
|
if (pSeed == NULL || ulSeedLen == 0)
|
|
|
|
return CKR_OK;
|
|
|
|
|
|
|
|
RAND_seed(pSeed, ulSeedLen);
|
|
|
|
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV
|
|
|
|
sc_pkcs11_openssl_add_gen_rand(struct sc_pkcs11_session *session,
|
|
|
|
CK_BYTE_PTR RandomData, CK_ULONG ulRandomLen)
|
|
|
|
{
|
|
|
|
unsigned char seed[20];
|
|
|
|
int r;
|
|
|
|
|
|
|
|
if (!(session->slot->card->card->caps & SC_CARD_CAP_RNG))
|
|
|
|
return CKR_RANDOM_NO_RNG;
|
|
|
|
|
|
|
|
if (RandomData == NULL || ulRandomLen == 0)
|
|
|
|
return CKR_OK;
|
|
|
|
|
|
|
|
if (scrandom_get_data(seed, 20) == -1) {
|
|
|
|
error(context, "scrandom_get_data() failed\n");
|
|
|
|
return CKR_FUNCTION_FAILED;
|
|
|
|
}
|
|
|
|
RAND_seed(seed, 20);
|
|
|
|
|
|
|
|
if (rng_seeded == 0) {
|
|
|
|
r = sc_get_challenge(session->slot->card->card, seed, 20);
|
|
|
|
if (r != 0) {
|
|
|
|
error(context, "sc_get_challenge() returned %d\n", r);
|
|
|
|
return sc_to_cryptoki_error(r, session->slot->card->reader);
|
|
|
|
}
|
|
|
|
rng_seeded = 1;
|
|
|
|
}
|
|
|
|
RAND_seed(seed, 20);
|
|
|
|
|
|
|
|
r = RAND_bytes(RandomData, ulRandomLen);
|
|
|
|
|
|
|
|
return r == 1 ? CKR_OK : CKR_FUNCTION_FAILED;
|
|
|
|
}
|
|
|
|
|
2002-12-17 11:49:12 +00:00
|
|
|
#endif
|