adapted to openpace 0.6
git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@418 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
@@ -40,9 +40,9 @@ AC_CHECK_HEADERS(openssl/evp.h, [], [ AC_MSG_ERROR([openssl/evp.h not found, ins
|
|||||||
AC_MSG_CHECKING([for EVP_read_pw_string_min])
|
AC_MSG_CHECKING([for EVP_read_pw_string_min])
|
||||||
AC_TRY_LINK_FUNC(EVP_read_pw_string_min, [ AC_MSG_RESULT([yes]) ], [ AC_MSG_ERROR([OpenSSL not found, use ./configure OPENSSL_LIBS=...]) ])
|
AC_TRY_LINK_FUNC(EVP_read_pw_string_min, [ AC_MSG_RESULT([yes]) ], [ AC_MSG_ERROR([OpenSSL not found, use ./configure OPENSSL_LIBS=...]) ])
|
||||||
|
|
||||||
AC_CHECK_HEADERS(openssl/pace.h, [], [ AC_MSG_ERROR([openssl/pace.h not found, install OpenPACE or use ./configure OPENSSL_CFLAGS=...]) ])
|
AC_CHECK_HEADERS(openssl/eac.h, [], [ AC_MSG_ERROR([openssl/eac.h not found, install OpenPACE or use ./configure OPENSSL_CFLAGS=...]) ])
|
||||||
AC_MSG_CHECKING([for parse_ef_card_access])
|
AC_MSG_CHECKING([for EAC_CTX_init_pace])
|
||||||
AC_TRY_LINK_FUNC(parse_ef_card_access, [ AC_MSG_RESULT([yes]) ], [ AC_MSG_ERROR([OpenPACE not found, use ./configure OPENSSL_LIBS=...]) ])
|
AC_TRY_LINK_FUNC(EAC_CTX_init_pace, [ AC_MSG_RESULT([yes]) ], [ AC_MSG_ERROR([OpenPACE not found, use ./configure OPENSSL_LIBS=...]) ])
|
||||||
|
|
||||||
CPPFLAGS="$saved_CPPFLAGS"
|
CPPFLAGS="$saved_CPPFLAGS"
|
||||||
LIBS="$saved_LIBS"
|
LIBS="$saved_LIBS"
|
||||||
|
|||||||
185
npa/src/npa.c
185
npa/src/npa.c
@@ -29,7 +29,9 @@
|
|||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/objects.h>
|
#include <openssl/objects.h>
|
||||||
|
#include <openssl/eac.h>
|
||||||
#include <openssl/pace.h>
|
#include <openssl/pace.h>
|
||||||
|
#include <openssl/cv_cert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -152,12 +154,8 @@ const size_t maxresp = SC_MAX_APDU_BUFFER_SIZE - 2;
|
|||||||
struct npa_sm_ctx {
|
struct npa_sm_ctx {
|
||||||
/** Send sequence counter */
|
/** Send sequence counter */
|
||||||
BIGNUM *ssc;
|
BIGNUM *ssc;
|
||||||
/** Key for message authentication code */
|
/** EAC context */
|
||||||
const BUF_MEM *key_mac;
|
EAC_CTX *ctx;
|
||||||
/** Key for encryption and decryption */
|
|
||||||
const BUF_MEM *key_enc;
|
|
||||||
/** PACE context */
|
|
||||||
PACE_CTX *ctx;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int npa_sm_encrypt(sc_card_t *card, const struct sm_ctx *ctx,
|
static int npa_sm_encrypt(sc_card_t *card, const struct sm_ctx *ctx,
|
||||||
@@ -175,13 +173,12 @@ static int npa_sm_post_transmit(sc_card_t *card, const struct sm_ctx *ctx,
|
|||||||
sc_apdu_t *sm_apdu);
|
sc_apdu_t *sm_apdu);
|
||||||
static void npa_sm_clear_free(const struct sm_ctx *ctx);
|
static void npa_sm_clear_free(const struct sm_ctx *ctx);
|
||||||
|
|
||||||
static int increment_ssc(struct npa_sm_ctx *psmctx);
|
static int increment_ssc(struct npa_sm_ctx *eacsmctx);
|
||||||
static int decrement_ssc(struct npa_sm_ctx *psmctx);
|
static int decrement_ssc(struct npa_sm_ctx *eacsmctx);
|
||||||
static int reset_ssc(struct npa_sm_ctx *psmctx);
|
static int reset_ssc(struct npa_sm_ctx *eacsmctx);
|
||||||
|
|
||||||
static struct npa_sm_ctx *
|
static struct npa_sm_ctx *
|
||||||
npa_sm_ctx_create(const BUF_MEM *key_mac,
|
npa_sm_ctx_create(EAC_CTX *ctx)
|
||||||
const BUF_MEM *key_enc, PACE_CTX *ctx)
|
|
||||||
{
|
{
|
||||||
struct npa_sm_ctx *out = malloc(sizeof *out);
|
struct npa_sm_ctx *out = malloc(sizeof *out);
|
||||||
if (!out)
|
if (!out)
|
||||||
@@ -191,8 +188,6 @@ npa_sm_ctx_create(const BUF_MEM *key_mac,
|
|||||||
if (!out->ssc || reset_ssc(out) < 0)
|
if (!out->ssc || reset_ssc(out) < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
out->key_enc = key_enc;
|
|
||||||
out->key_mac = key_mac;
|
|
||||||
out->ctx = ctx;
|
out->ctx = ctx;
|
||||||
|
|
||||||
|
|
||||||
@@ -998,14 +993,11 @@ int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
|
|||||||
struct sm_ctx *sctx)
|
struct sm_ctx *sctx)
|
||||||
{
|
{
|
||||||
u8 *p = NULL;
|
u8 *p = NULL;
|
||||||
PACEInfo *info = NULL;
|
EAC_CTX *eac_ctx = NULL;
|
||||||
PACEDomainParameterInfo *static_dp = NULL, *eph_dp = NULL;
|
BUF_MEM *enc_nonce = NULL, *mdata = NULL, *mdata_opp = NULL,
|
||||||
BUF_MEM *enc_nonce = NULL, *nonce = NULL, *mdata = NULL, *mdata_opp = NULL,
|
*token_opp = NULL, *token = NULL, *pub = NULL, *pub_opp = NULL,
|
||||||
*k_enc = NULL, *k_mac = NULL, *token_opp = NULL,
|
*comp_pub = NULL, *comp_pub_opp = NULL, *hash_cert_desc = NULL;
|
||||||
*token = NULL, *pub = NULL, *pub_opp = NULL, *key = NULL,
|
|
||||||
*comp_pub = NULL, *comp_pub_opp = NULL, *hash_cert_desc = NULL;
|
|
||||||
PACE_SEC *sec = NULL;
|
PACE_SEC *sec = NULL;
|
||||||
PACE_CTX *pctx = NULL;
|
|
||||||
CVC_CHAT *chat = NULL;
|
CVC_CHAT *chat = NULL;
|
||||||
BIO *bio_stdout = NULL;
|
BIO *bio_stdout = NULL;
|
||||||
int r;
|
int r;
|
||||||
@@ -1057,7 +1049,7 @@ int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
hash_cert_desc = PACE_hash_certificate_description(
|
hash_cert_desc = EAC_hash_certificate_description(
|
||||||
pace_input.certificate_description,
|
pace_input.certificate_description,
|
||||||
pace_input.certificate_description_length);
|
pace_input.certificate_description_length);
|
||||||
if (!hash_cert_desc) {
|
if (!hash_cert_desc) {
|
||||||
@@ -1117,24 +1109,19 @@ int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
|
|||||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "EF.CardAccess", pace_output->ef_cardaccess,
|
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "EF.CardAccess", pace_output->ef_cardaccess,
|
||||||
pace_output->ef_cardaccess_length);
|
pace_output->ef_cardaccess_length);
|
||||||
|
|
||||||
if (!parse_ef_card_access(pace_output->ef_cardaccess,
|
eac_ctx = EAC_CTX_new();
|
||||||
pace_output->ef_cardaccess_length, &info, &static_dp)) {
|
if (!eac_ctx
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse EF.CardAccess.");
|
|| !EAC_CTX_init_ef_cardaccess(pace_output->ef_cardaccess,
|
||||||
|
pace_output->ef_cardaccess_length, eac_ctx)) {
|
||||||
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse EF.CardAccess.");
|
||||||
ssl_error(card->ctx);
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
pctx = PACE_CTX_new();
|
eac_ctx->tr_version = pace_input.tr_version;
|
||||||
if (!pctx || !PACE_init(pctx, &static_dp, info)) {
|
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not initialize PACE parameters.");
|
|
||||||
ssl_error(card->ctx);
|
|
||||||
r = SC_ERROR_INTERNAL;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
pctx->tr_version = pace_input.tr_version;
|
|
||||||
|
|
||||||
r = npa_mse_set_at(oldnpactx, card, info->protocol, pace_input.pin_id,
|
r = npa_mse_set_at(oldnpactx, card, eac_ctx->pace_ctx->protocol, pace_input.pin_id,
|
||||||
chat, &pace_output->mse_set_at_sw1, &pace_output->mse_set_at_sw2);
|
chat, &pace_output->mse_set_at_sw1, &pace_output->mse_set_at_sw2);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol proberties "
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol proberties "
|
||||||
@@ -1165,11 +1152,16 @@ int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce = PACE_STEP2_dec_nonce(sec, enc_nonce, pctx);
|
if (!PACE_STEP2_dec_nonce(eac_ctx, sec, enc_nonce)) {
|
||||||
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not decrypt MRTD's nonce.");
|
||||||
|
ssl_error(card->ctx);
|
||||||
|
r = SC_ERROR_INTERNAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
mdata_opp = BUF_MEM_new();
|
mdata_opp = BUF_MEM_new();
|
||||||
mdata = PACE_STEP3A_generate_mapping_data(static_dp, pctx);
|
mdata = PACE_STEP3A_generate_mapping_data(eac_ctx);
|
||||||
if (!nonce || !mdata || !mdata_opp) {
|
if (!mdata || !mdata_opp) {
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not generate mapping data.");
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not generate mapping data.");
|
||||||
ssl_error(card->ctx);
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
@@ -1185,10 +1177,16 @@ int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
|
|||||||
mdata_opp->max = mdata_opp->length;
|
mdata_opp->max = mdata_opp->length;
|
||||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Mapping data from MRTD", (u8 *) mdata_opp->data, mdata_opp->length);
|
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Mapping data from MRTD", (u8 *) mdata_opp->data, mdata_opp->length);
|
||||||
|
|
||||||
eph_dp = PACE_STEP3A_map_dp(static_dp, pctx, nonce, mdata_opp);
|
if (!PACE_STEP3A_map_generator(eac_ctx, mdata_opp)) {
|
||||||
pub = PACE_STEP3B_generate_ephemeral_key(eph_dp, pctx);
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not map generator.");
|
||||||
|
ssl_error(card->ctx);
|
||||||
|
r = SC_ERROR_INTERNAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub = PACE_STEP3B_generate_ephemeral_key(eac_ctx);
|
||||||
pub_opp = BUF_MEM_new();
|
pub_opp = BUF_MEM_new();
|
||||||
if (!eph_dp || !pub || !pub_opp) {
|
if (!pub || !pub_opp) {
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not generate ephemeral domain parameter or "
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not generate ephemeral domain parameter or "
|
||||||
"ephemeral key pair.");
|
"ephemeral key pair.");
|
||||||
ssl_error(card->ctx);
|
ssl_error(card->ctx);
|
||||||
@@ -1205,17 +1203,16 @@ int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
|
|||||||
pub_opp->max = pub_opp->length;
|
pub_opp->max = pub_opp->length;
|
||||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Ephemeral public key from MRTD", (u8 *) pub_opp->data, pub_opp->length);
|
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Ephemeral public key from MRTD", (u8 *) pub_opp->data, pub_opp->length);
|
||||||
|
|
||||||
key = PACE_STEP3B_compute_ephemeral_key(eph_dp, pctx, pub_opp);
|
|
||||||
if (!key ||
|
if (!PACE_STEP3B_compute_shared_secret(eac_ctx, pub_opp)
|
||||||
!PACE_STEP3C_derive_keys(key, pctx, info, &k_mac, &k_enc)) {
|
|| !PACE_STEP3C_derive_keys(eac_ctx)) {
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute ephemeral shared secret or "
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute ephemeral shared secret or "
|
||||||
"derive keys for encryption and authentication.");
|
"derive keys for encryption and authentication.");
|
||||||
ssl_error(card->ctx);
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
token = PACE_STEP3D_compute_authentication_token(pctx,
|
token = PACE_STEP3D_compute_authentication_token(eac_ctx, pub_opp);
|
||||||
eph_dp, info, pub_opp, k_mac);
|
|
||||||
token_opp = BUF_MEM_new();
|
token_opp = BUF_MEM_new();
|
||||||
if (!token || !token_opp) {
|
if (!token || !token_opp) {
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute authentication token.");
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute authentication token.");
|
||||||
@@ -1235,17 +1232,24 @@ int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
|
|||||||
}
|
}
|
||||||
token_opp->max = token_opp->length;
|
token_opp->max = token_opp->length;
|
||||||
|
|
||||||
if (!PACE_STEP3D_verify_authentication_token(pctx,
|
if (!PACE_STEP3D_verify_authentication_token(eac_ctx, token_opp)) {
|
||||||
eph_dp, info, k_mac, token_opp)) {
|
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not verify authentication token.");
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not verify authentication token.");
|
||||||
ssl_error(card->ctx);
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize secure channel */
|
||||||
|
if (!EAC_CTX_set_encryption_ctx(eac_ctx, EAC_ID_PACE)) {
|
||||||
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not initialize encryption.");
|
||||||
|
ssl_error(card->ctx);
|
||||||
|
r = SC_ERROR_INTERNAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Identifier for ICC and PCD */
|
/* Identifier for ICC and PCD */
|
||||||
comp_pub = PACE_Comp(eph_dp, pctx, pub);
|
comp_pub = EAC_Comp(eac_ctx, EAC_ID_PACE, pub);
|
||||||
comp_pub_opp = PACE_Comp(eph_dp, pctx, pub_opp);
|
comp_pub_opp = EAC_Comp(eac_ctx, EAC_ID_PACE, pub_opp);
|
||||||
if (!comp_pub || !comp_pub_opp) {
|
if (!comp_pub || !comp_pub_opp) {
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compress public keys for identification.");
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compress public keys for identification.");
|
||||||
ssl_error(card->ctx);
|
ssl_error(card->ctx);
|
||||||
@@ -1275,7 +1279,7 @@ int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
|
|||||||
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "ID PCD", pace_output->id_pcd,
|
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "ID PCD", pace_output->id_pcd,
|
||||||
pace_output->id_pcd_length);
|
pace_output->id_pcd_length);
|
||||||
|
|
||||||
sctx->priv_data = npa_sm_ctx_create(k_mac, k_enc, pctx);
|
sctx->priv_data = npa_sm_ctx_create(eac_ctx);
|
||||||
if (!sctx->priv_data) {
|
if (!sctx->priv_data) {
|
||||||
r = SC_ERROR_OUT_OF_MEMORY;
|
r = SC_ERROR_OUT_OF_MEMORY;
|
||||||
goto err;
|
goto err;
|
||||||
@@ -1288,22 +1292,12 @@ int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
|
|||||||
sctx->post_transmit = npa_sm_post_transmit;
|
sctx->post_transmit = npa_sm_post_transmit;
|
||||||
sctx->clear_free = npa_sm_clear_free;
|
sctx->clear_free = npa_sm_clear_free;
|
||||||
sctx->padding_indicator = SM_ISO_PADDING;
|
sctx->padding_indicator = SM_ISO_PADDING;
|
||||||
sctx->block_length = EVP_CIPHER_block_size(pctx->cipher);
|
sctx->block_length = EVP_CIPHER_block_size(eac_ctx->key_ctx->cipher);
|
||||||
sctx->active = 1;
|
sctx->active = 1;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (info)
|
|
||||||
PACEInfo_free(info);
|
|
||||||
if (static_dp)
|
|
||||||
PACEDomainParameterInfo_clear_free(static_dp);
|
|
||||||
if (eph_dp)
|
|
||||||
PACEDomainParameterInfo_clear_free(eph_dp);
|
|
||||||
if (enc_nonce)
|
if (enc_nonce)
|
||||||
BUF_MEM_free(enc_nonce);
|
BUF_MEM_free(enc_nonce);
|
||||||
if (nonce) {
|
|
||||||
OPENSSL_cleanse(nonce->data, nonce->length);
|
|
||||||
BUF_MEM_free(nonce);
|
|
||||||
}
|
|
||||||
if (mdata)
|
if (mdata)
|
||||||
BUF_MEM_free(mdata);
|
BUF_MEM_free(mdata);
|
||||||
if (mdata_opp)
|
if (mdata_opp)
|
||||||
@@ -1322,26 +1316,14 @@ err:
|
|||||||
BUF_MEM_free(comp_pub);
|
BUF_MEM_free(comp_pub);
|
||||||
if (hash_cert_desc)
|
if (hash_cert_desc)
|
||||||
BUF_MEM_free(hash_cert_desc);
|
BUF_MEM_free(hash_cert_desc);
|
||||||
if (key) {
|
|
||||||
OPENSSL_cleanse(key->data, key->length);
|
|
||||||
BUF_MEM_free(key);
|
|
||||||
}
|
|
||||||
if (sec)
|
if (sec)
|
||||||
PACE_SEC_clean_free(sec);
|
PACE_SEC_clean_free(sec);
|
||||||
if (bio_stdout)
|
if (bio_stdout)
|
||||||
BIO_free_all(bio_stdout);
|
BIO_free_all(bio_stdout);
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (k_enc) {
|
if (eac_ctx)
|
||||||
OPENSSL_cleanse(k_enc->data, k_enc->length);
|
EAC_CTX_clear_free(eac_ctx);
|
||||||
BUF_MEM_free(k_enc);
|
|
||||||
}
|
|
||||||
if (k_mac) {
|
|
||||||
OPENSSL_cleanse(k_mac->data, k_mac->length);
|
|
||||||
BUF_MEM_free(k_mac);
|
|
||||||
}
|
|
||||||
if (pctx)
|
|
||||||
PACE_CTX_clear_free(pctx);
|
|
||||||
if (sctx->priv_data)
|
if (sctx->priv_data)
|
||||||
npa_sm_clear_free(sctx->priv_data);
|
npa_sm_clear_free(sctx->priv_data);
|
||||||
}
|
}
|
||||||
@@ -1370,34 +1352,34 @@ const char *npa_secret_name(enum s_type pin_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
increment_ssc(struct npa_sm_ctx *psmctx)
|
increment_ssc(struct npa_sm_ctx *eacsmctx)
|
||||||
{
|
{
|
||||||
if (!psmctx)
|
if (!eacsmctx)
|
||||||
return SC_ERROR_INVALID_ARGUMENTS;
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
BN_add_word(psmctx->ssc, 1);
|
BN_add_word(eacsmctx->ssc, 1);
|
||||||
|
|
||||||
return SC_SUCCESS;
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
decrement_ssc(struct npa_sm_ctx *psmctx)
|
decrement_ssc(struct npa_sm_ctx *eacsmctx)
|
||||||
{
|
{
|
||||||
if (!psmctx)
|
if (!eacsmctx)
|
||||||
return SC_ERROR_INVALID_ARGUMENTS;
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
BN_sub_word(psmctx->ssc, 1);
|
BN_sub_word(eacsmctx->ssc, 1);
|
||||||
|
|
||||||
return SC_SUCCESS;
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
reset_ssc(struct npa_sm_ctx *psmctx)
|
reset_ssc(struct npa_sm_ctx *eacsmctx)
|
||||||
{
|
{
|
||||||
if (!psmctx)
|
if (!eacsmctx)
|
||||||
return SC_ERROR_INVALID_ARGUMENTS;
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
BN_zero(psmctx->ssc);
|
BN_zero(eacsmctx->ssc);
|
||||||
|
|
||||||
return SC_SUCCESS;
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -1414,10 +1396,10 @@ npa_sm_encrypt(sc_card_t *card, const struct sm_ctx *ctx,
|
|||||||
r = SC_ERROR_INVALID_ARGUMENTS;
|
r = SC_ERROR_INVALID_ARGUMENTS;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
struct npa_sm_ctx *psmctx = ctx->priv_data;
|
struct npa_sm_ctx *eacsmctx = ctx->priv_data;
|
||||||
|
|
||||||
databuf = BUF_MEM_create_init(data, datalen);
|
databuf = BUF_MEM_create_init(data, datalen);
|
||||||
encbuf = PACE_encrypt(psmctx->ctx, psmctx->ssc, psmctx->key_enc, databuf);
|
encbuf = EAC_encrypt(eacsmctx->ctx, eacsmctx->ssc, databuf);
|
||||||
if (!databuf || !encbuf) {
|
if (!databuf || !encbuf) {
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not encrypt data.");
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not encrypt data.");
|
||||||
ssl_error(card->ctx);
|
ssl_error(card->ctx);
|
||||||
@@ -1458,10 +1440,10 @@ npa_sm_decrypt(sc_card_t *card, const struct sm_ctx *ctx,
|
|||||||
r = SC_ERROR_INVALID_ARGUMENTS;
|
r = SC_ERROR_INVALID_ARGUMENTS;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
struct npa_sm_ctx *psmctx = ctx->priv_data;
|
struct npa_sm_ctx *eacsmctx = ctx->priv_data;
|
||||||
|
|
||||||
encbuf = BUF_MEM_create_init(enc, enclen);
|
encbuf = BUF_MEM_create_init(enc, enclen);
|
||||||
databuf = PACE_decrypt(psmctx->ctx, psmctx->ssc, psmctx->key_enc, encbuf);
|
databuf = EAC_decrypt(eacsmctx->ctx, eacsmctx->ssc, encbuf);
|
||||||
if (!encbuf || !databuf) {
|
if (!encbuf || !databuf) {
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not decrypt data.");
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not decrypt data.");
|
||||||
ssl_error(card->ctx);
|
ssl_error(card->ctx);
|
||||||
@@ -1502,10 +1484,9 @@ npa_sm_authenticate(sc_card_t *card, const struct sm_ctx *ctx,
|
|||||||
r = SC_ERROR_INVALID_ARGUMENTS;
|
r = SC_ERROR_INVALID_ARGUMENTS;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
struct npa_sm_ctx *psmctx = ctx->priv_data;
|
struct npa_sm_ctx *eacsmctx = ctx->priv_data;
|
||||||
|
|
||||||
macbuf = PACE_authenticate(psmctx->ctx, psmctx->ssc, psmctx->key_mac,
|
macbuf = EAC_authenticate(eacsmctx->ctx, eacsmctx->ssc, data, datalen);
|
||||||
data, datalen);
|
|
||||||
if (!macbuf) {
|
if (!macbuf) {
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
|
||||||
"Could not compute message authentication code (MAC).");
|
"Could not compute message authentication code (MAC).");
|
||||||
@@ -1546,10 +1527,10 @@ npa_sm_verify_authentication(sc_card_t *card, const struct sm_ctx *ctx,
|
|||||||
r = SC_ERROR_INVALID_ARGUMENTS;
|
r = SC_ERROR_INVALID_ARGUMENTS;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
struct npa_sm_ctx *psmctx = ctx->priv_data;
|
struct npa_sm_ctx *eacsmctx = ctx->priv_data;
|
||||||
|
|
||||||
my_mac = PACE_authenticate(psmctx->ctx, psmctx->ssc, psmctx->key_mac,
|
my_mac = EAC_authenticate(eacsmctx->ctx, eacsmctx->ssc, macdata,
|
||||||
macdata, macdatalen);
|
macdatalen);
|
||||||
if (!my_mac) {
|
if (!my_mac) {
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
|
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
|
||||||
"Could not compute message authentication code (MAC) for verification.");
|
"Could not compute message authentication code (MAC) for verification.");
|
||||||
@@ -1597,18 +1578,10 @@ static void
|
|||||||
npa_sm_clear_free(const struct sm_ctx *ctx)
|
npa_sm_clear_free(const struct sm_ctx *ctx)
|
||||||
{
|
{
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
struct npa_sm_ctx *psmctx = ctx->priv_data;
|
struct npa_sm_ctx *eacsmctx = ctx->priv_data;
|
||||||
if (psmctx->key_mac) {
|
PACE_CTX_clear_free(eacsmctx->ctx);
|
||||||
OPENSSL_cleanse(psmctx->key_mac->data, psmctx->key_mac->max);
|
if (eacsmctx->ssc)
|
||||||
BUF_MEM_free((BUF_MEM *) psmctx->key_mac);
|
BN_clear_free(eacsmctx->ssc);
|
||||||
}
|
free(eacsmctx);
|
||||||
if (psmctx->key_enc) {
|
|
||||||
OPENSSL_cleanse(psmctx->key_enc->data, psmctx->key_enc->max);
|
|
||||||
BUF_MEM_free((BUF_MEM *) psmctx->key_enc);
|
|
||||||
}
|
|
||||||
PACE_CTX_clear_free(psmctx->ctx);
|
|
||||||
if (psmctx->ssc)
|
|
||||||
BN_clear_free(psmctx->ssc);
|
|
||||||
free(psmctx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <npa/sm.h>
|
#include <npa/sm.h>
|
||||||
#include <libopensc/opensc.h>
|
#include <libopensc/opensc.h>
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
|
#include <openssl/eac.h>
|
||||||
#include <openssl/pace.h>
|
#include <openssl/pace.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -100,7 +101,7 @@ const char *npa_secret_name(enum s_type pin_id);
|
|||||||
*/
|
*/
|
||||||
struct establish_pace_channel_input {
|
struct establish_pace_channel_input {
|
||||||
/** Version of TR-03110 to use with PACE */
|
/** Version of TR-03110 to use with PACE */
|
||||||
enum tr_version tr_version;
|
enum eac_tr_version tr_version;
|
||||||
|
|
||||||
/** Type of secret (CAN, MRZ, PIN or PUK). You may use <tt>enum s_type</tt> from \c <openssl/pace.h> */
|
/** Type of secret (CAN, MRZ, PIN or PUK). You may use <tt>enum s_type</tt> from \c <openssl/pace.h> */
|
||||||
unsigned char pin_id;
|
unsigned char pin_id;
|
||||||
|
|||||||
Reference in New Issue
Block a user