Skip to content

Commit

Permalink
Use OpenSSL versions OpenSSL-0.9.7 to 1.1.0a for OpenSC
Browse files Browse the repository at this point in the history
OpenSSL-1.1.0 was released 8/25/2016
OpenSSL-1.1.0a was released 9/22/2016

  https://www.openssl.org/news/openssl-1.1.0-notes.html

Changes to allow the OpenSC code base to work with OpenSSL versions from
0.9.7 to 1.1.0 with few changes.

This is an update and rebased version of my prep-openssl-1.1.0-pre6 branch.

No attempt was made to back port any OpenSSL features. These changes
just allow an updated OpenSC code base to use what is in the various OpenSSL
releases.

A new header libopensc/sc-ossl-compat.h contains extra defines
to reduce the need for so many #if OPENSSL_VERSION_NUMBER statements
in the source code.

The OpenSC source can now use the OpenSSL 1.1 API. The libopensc/sc-ossl-compat.h
has defines for the new API for use with older versions of OpenSSL.

sc-ossl-compat.h is included by libopensc/internal.h so all OpenSC
library routines can take advantage of it. For the tools, which do not use
libopensc/internal.h, libopensc/sc-ossl-compat.h is included by the tools.

The OpenSC source has been modified to use OpenSSL functions to access
hidden structures, such X509, BIGNUM, EVP_CIPHER_CTX, and use XXX_new
functions to allocate structures which must use pointer such as
BIGNUM and EVP_CIPHER_CTX.

For backward compatability sc-ossl-compat.h now defines inline routines
to emulate the RSA and DSA  access routines in OpenSSL-1.1.0. Thus
the same OpenSC source code can be used with openSSL versions from
0.9.7 to 1.1.0.

Inline routines were chosen, because using macros does not work on all platforms.
Having OpenSC versions of these routines in libopensc would be a posibility,
but they are only used for older version of OpenSSL, and could be removed in
the future.
 Changes to be committed:
	modified:   src/libopensc/card-entersafe.c
	modified:   src/libopensc/card-epass2003.c
	modified:   src/libopensc/card-gids.c
	modified:   src/libopensc/card-gpk.c
	modified:   src/libopensc/card-oberthur.c
	modified:   src/libopensc/card-piv.c
	modified:   src/libopensc/card-westcos.c
	modified:   src/libopensc/cwa-dnie.c
	modified:   src/libopensc/cwa14890.c
	modified:   src/libopensc/internal.h
	modified:   src/libopensc/p15card-helper.c
	modified:   src/libopensc/pkcs15-itacns.c
	modified:   src/libopensc/pkcs15-prkey.c
	modified:   src/libopensc/pkcs15-pubkey.c
	new file:   src/libopensc/sc-ossl-compat.h
	modified:   src/pkcs11/openssl.c
	modified:   src/pkcs15init/pkcs15-lib.c
	modified:   src/pkcs15init/pkcs15-oberthur-awp.c
	modified:   src/pkcs15init/pkcs15-oberthur.c
	modified:   src/pkcs15init/pkcs15-oberthur.h
	modified:   src/pkcs15init/pkcs15-westcos.c
	modified:   src/tools/cryptoflex-tool.c
	modified:   src/tools/gids-tool.c
	modified:   src/tools/netkey-tool.c
	modified:   src/tools/piv-tool.c
	modified:   src/tools/pkcs11-tool.c
	modified:   src/tools/pkcs15-init.c
	modified:   src/tools/sc-hsm-tool.c
	modified:   src/tools/westcos-tool.c
  • Loading branch information
dengert committed Oct 8, 2016
1 parent 44694a0 commit 5fb4db6
Show file tree
Hide file tree
Showing 29 changed files with 953 additions and 400 deletions.
46 changes: 23 additions & 23 deletions src/libopensc/card-entersafe.c
Expand Up @@ -194,7 +194,7 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu,
u8 *key, size_t keylen,
u8 *buff, size_t buffsize)
{
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX * ctx = NULL;
u8 iv[8]={0};
int len;

Expand All @@ -211,27 +211,26 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu,
memcpy(buff+1,apdu->data,apdu->lc);
buff[apdu->lc+1]=0x80;

EVP_CIPHER_CTX_init(&ctx);
EVP_CIPHER_CTX_set_padding(&ctx,0);
ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL)
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
EVP_CIPHER_CTX_set_padding(ctx,0);

if(keylen == 8)
EVP_EncryptInit_ex(&ctx, EVP_des_ecb(), NULL, key, iv);
EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, key, iv);
else if (keylen == 16)
EVP_EncryptInit_ex(&ctx, EVP_des_ede(), NULL, key, iv);
EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, key, iv);
else
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);

len = apdu->lc;
if(!EVP_EncryptUpdate(&ctx, buff, &len, buff, buffsize)){
if(!EVP_EncryptUpdate(ctx, buff, &len, buff, buffsize)){
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "entersafe encryption error.");
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
}
apdu->lc = len;

if (!EVP_CIPHER_CTX_cleanup(&ctx)){
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "entersafe encryption error.");
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
}
EVP_CIPHER_CTX_free(ctx);

if(apdu->lc!=buffsize)
{
Expand All @@ -254,7 +253,7 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu,
u8 *tmp=0,*tmp_rounded=NULL;
size_t tmpsize=0,tmpsize_rounded=0;
int outl=0;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX * ctx = NULL;

SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

Expand Down Expand Up @@ -292,38 +291,37 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu,
tmp_rounded[tmpsize]=0x80;

/* block_size-1 blocks*/
EVP_CIPHER_CTX_init(&ctx);
EVP_CIPHER_CTX_set_padding(&ctx,0);
EVP_EncryptInit_ex(&ctx, EVP_des_cbc(), NULL, key, iv);
ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL) {
r = SC_ERROR_OUT_OF_MEMORY;
goto out;
}
EVP_CIPHER_CTX_set_padding(ctx,0);
EVP_EncryptInit_ex(ctx, EVP_des_cbc(), NULL, key, iv);

if(tmpsize_rounded>8){
if(!EVP_EncryptUpdate(&ctx,tmp_rounded,&outl,tmp_rounded,tmpsize_rounded-8)){
if(!EVP_EncryptUpdate(ctx,tmp_rounded,&outl,tmp_rounded,tmpsize_rounded-8)){
r = SC_ERROR_INTERNAL;
goto out;
}
}
/* last block */
if(keylen==8)
{
if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
if(!EVP_EncryptUpdate(ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
r = SC_ERROR_INTERNAL;
goto out;
}
}
else
{
EVP_EncryptInit_ex(&ctx, EVP_des_ede_cbc(), NULL, key,tmp_rounded+outl-8);
if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, key,tmp_rounded+outl-8);
if(!EVP_EncryptUpdate(ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
r = SC_ERROR_INTERNAL;
goto out;
}
}

if (!EVP_CIPHER_CTX_cleanup(&ctx)){
r = SC_ERROR_INTERNAL;
goto out;
}

memcpy(buff,apdu->data,apdu->lc);
/* use first 4 bytes of last block as mac value*/
memcpy(buff+apdu->lc,tmp_rounded+tmpsize_rounded-8,4);
Expand All @@ -336,6 +334,8 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu,
free(tmp);
if(tmp_rounded)
free(tmp_rounded);
if (ctx)
EVP_CIPHER_CTX_free(ctx);

SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
}
Expand Down
68 changes: 41 additions & 27 deletions src/libopensc/card-epass2003.c
Expand Up @@ -127,27 +127,28 @@ openssl_enc(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned
const unsigned char *input, size_t length, unsigned char *output)
{
int r = SC_ERROR_INTERNAL;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX * ctx = NULL;
int outl = 0;
int outl_tmp = 0;
unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = { 0 };

memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH);
EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit_ex(&ctx, cipher, NULL, key, iv_tmp);
EVP_CIPHER_CTX_set_padding(&ctx, 0);

if (!EVP_EncryptUpdate(&ctx, output, &outl, input, length))
ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL)
goto out;
EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv_tmp);
EVP_CIPHER_CTX_set_padding(ctx, 0);

if (!EVP_EncryptFinal_ex(&ctx, output + outl, &outl_tmp))
if (!EVP_EncryptUpdate(ctx, output, &outl, input, length))
goto out;

if (!EVP_CIPHER_CTX_cleanup(&ctx))
if (!EVP_EncryptFinal_ex(ctx, output + outl, &outl_tmp))
goto out;

r = SC_SUCCESS;
out:
if (ctx)
EVP_CIPHER_CTX_free(ctx);
return r;
}

Expand All @@ -156,27 +157,28 @@ openssl_dec(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned
const unsigned char *input, size_t length, unsigned char *output)
{
int r = SC_ERROR_INTERNAL;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX * ctx = NULL;
int outl = 0;
int outl_tmp = 0;
unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = { 0 };

memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH);
EVP_CIPHER_CTX_init(&ctx);
EVP_DecryptInit_ex(&ctx, cipher, NULL, key, iv_tmp);
EVP_CIPHER_CTX_set_padding(&ctx, 0);

if (!EVP_DecryptUpdate(&ctx, output, &outl, input, length))
ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL)
goto out;
EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv_tmp);
EVP_CIPHER_CTX_set_padding(ctx, 0);

if (!EVP_DecryptFinal_ex(&ctx, output + outl, &outl_tmp))
if (!EVP_DecryptUpdate(ctx, output, &outl, input, length))
goto out;

if (!EVP_CIPHER_CTX_cleanup(&ctx))
if (!EVP_DecryptFinal_ex(ctx, output + outl, &outl_tmp))
goto out;

r = SC_SUCCESS;
out:
if (ctx)
EVP_CIPHER_CTX_free(ctx);
return r;
}

Expand Down Expand Up @@ -280,21 +282,33 @@ static int
openssl_dig(const EVP_MD * digest, const unsigned char *input, size_t length,
unsigned char *output)
{
EVP_MD_CTX ctx;
int r = 0;
EVP_MD_CTX *ctx = NULL;
unsigned outl = 0;

EVP_MD_CTX_init(&ctx);
EVP_DigestInit_ex(&ctx, digest, NULL);
if (!EVP_DigestUpdate(&ctx, input, length))
return SC_ERROR_INTERNAL;

if (!EVP_DigestFinal_ex(&ctx, output, &outl))
return SC_ERROR_INTERNAL;
ctx = EVP_MD_CTX_create();
if (ctx == NULL) {
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}

EVP_MD_CTX_init(ctx);
EVP_DigestInit_ex(ctx, digest, NULL);
if (!EVP_DigestUpdate(ctx, input, length)) {
r = SC_ERROR_INTERNAL;
goto err;
}

if (!EVP_MD_CTX_cleanup(&ctx))
return SC_ERROR_INTERNAL;
if (!EVP_DigestFinal_ex(ctx, output, &outl)) {
r = SC_ERROR_INTERNAL;
goto err;
}
r = SC_SUCCESS;
err:
if (ctx)
EVP_MD_CTX_destroy(ctx);

return SC_SUCCESS;
return r;
}


Expand Down
27 changes: 16 additions & 11 deletions src/libopensc/card-gids.c
Expand Up @@ -1860,7 +1860,7 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) {
#ifndef ENABLE_OPENSSL
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED);
#else
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX *ctx = NULL;
int r;
u8 apduSetRandom[20] = {0x7C,0x12,0x81,0x10,0};
u8* randomR1 = apduSetRandom + 4;
Expand All @@ -1878,8 +1878,6 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) {
const EVP_CIPHER *cipher;

SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
// init crypto
EVP_CIPHER_CTX_init(&ctx);
// this is CBC instead of ECB
cipher = EVP_des_ede3_cbc();
if (!cipher) {
Expand Down Expand Up @@ -1920,21 +1918,28 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) {
memcpy(buffer, randomR2, 16);
memcpy(buffer+16, randomR1, 16);
memcpy(buffer+32, z1, sizeof(z1));
if (!EVP_EncryptInit(&ctx, cipher, key, NULL)) {
EVP_CIPHER_CTX_cleanup(&ctx);
// init crypto
ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL) {
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
}

if (!EVP_EncryptInit(ctx, cipher, key, NULL)) {
EVP_CIPHER_CTX_free(ctx);
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
}
EVP_CIPHER_CTX_set_padding(&ctx,0);
if (!EVP_EncryptUpdate(&ctx, buffer2, &buffer2size, buffer, sizeof(buffer))) {
EVP_CIPHER_CTX_cleanup(&ctx);
EVP_CIPHER_CTX_set_padding(ctx,0);
if (!EVP_EncryptUpdate(ctx, buffer2, &buffer2size, buffer, sizeof(buffer))) {
EVP_CIPHER_CTX_free(ctx);
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
}

if(!EVP_EncryptFinal(&ctx, buffer2+buffer2size, &buffer2size)) {
EVP_CIPHER_CTX_cleanup(&ctx);
if(!EVP_EncryptFinal(ctx, buffer2+buffer2size, &buffer2size)) {
EVP_CIPHER_CTX_free(ctx);
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
}
EVP_CIPHER_CTX_cleanup(&ctx);
EVP_CIPHER_CTX_free(ctx);
ctx = NULL;
// send it to the card
sc_format_apdu(card, &apdu, SC_APDU_CASE_4, INS_GENERAL_AUTHENTICATE, 0x00, 0x00);
apdu.lc = sizeof(apduSendReponse);
Expand Down

0 comments on commit 5fb4db6

Please sign in to comment.