Fixes to key wrapping and unwrapping code: Set IV correctly in symmetric unwrap. Correctly distinguish symmetric and asymmetric operation when building APDUs. Check CKA_TOKEN from the pkcs15 object in framework_pkcs15. Updated some comments.

This commit is contained in:
Hannu Honkanen 2018-05-29 06:23:57 -07:00
parent 861d8b308b
commit 287a63c704
3 changed files with 24 additions and 11 deletions

View File

@ -869,6 +869,10 @@ static int myeid_set_security_env(struct sc_card *card,
{
tmp.algorithm_ref = 0x00;
}
if ((tmp.algorithm_flags & SC_ALGORITHM_AES_CBC_PAD) == SC_ALGORITHM_AES_CBC_PAD)
tmp.algorithm_ref |= 0x80; /* set PKCS#7 padding */
/* from this point, there's no difference to RSA SE */
return myeid_set_security_env_rsa(card, &tmp, se_num);
}
@ -1267,7 +1271,7 @@ static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen)
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x2A, 0x84, 0x00);
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
apdu.le = outlen;
apdu.le = 0;
apdu.lc = 0;
r = sc_transmit_apdu(card, &apdu);
@ -1325,7 +1329,7 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra
apdu.resplen = sizeof(rbuf);
apdu.le = crgram_len;
if (crgram_len == 256)
if (crgram_len == 256 && p2 == 0x86)
{
apdu.le = 0;
/* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */
@ -1352,10 +1356,10 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
{
if (crgram_len == 256)
if (crgram_len == 256 && p2 == 0x86) /* with symmetric crypto, we support only single apdu unwrap for now */
{
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT,
0x2A, 0x00, 0x86);
0x2A, 0x00, p2);
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
apdu.le = crgram_len;

View File

@ -426,7 +426,7 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card,
LOG_TEST_RET(ctx, r, "cannot encode security operation flags");
senv.algorithm_flags = sec_flags;
if ((sec_flags & SC_ALGORITHM_AES_CBC & SC_ALGORITHM_AES_CBC_PAD) > 0) {
if ((sec_flags & (SC_ALGORITHM_AES_CBC | SC_ALGORITHM_AES_CBC_PAD)) > 0) {
senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_IV, (u8*) param, paramlen };
LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment");
}

View File

@ -2198,12 +2198,21 @@ out: return rv;
}
/* TODO Only Session secret key objects are supported for now
/*
* Secret key objects can be stored on card, if the card supports them
*
* Session objects have CKA_TOKEN=false
*
* CKA_TOKEN = FALSE can mean two things:
* 1. If the card supports on card session objects, the object is stored on card for duration of the PKCS#11 session.
* Depending on card implementation, it can be automatically deleted during the card's reset.
* This kind of objects are not written to the PKCS#15 directory file.
* 2. If the card doesn't support on card session objects, a CKA_TOKEN = FALSE object is stored only in OpenSC's memory.
* This is used by the C_DeriveKey with ECDH to hold the
* key, and the calling application can then retrieve tha attributes as needed.
* TODO If a card can support secret key objects on the card, this
* code will need to be expanded.
* .
*/
static CK_RV
pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile,
@ -2348,10 +2357,11 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile
skey_info->data.len = args.key.data_len;
skey_info->value_len = args.value_len; /* callers preferred length */
args.key.data = NULL;
key_obj->session_object = 1;
}
else {
if(_token == FALSE)
args.session_object = 1; /* store the object on card for duration of the session. */
args.session_object = 1; /* store the object on card for duration of the session. */
rc = sc_pkcs15init_store_secret_key(fw_data->p15_card, profile, &args, &key_obj);
if (rc < 0) {
@ -4752,9 +4762,8 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session,
*(CK_OBJECT_CLASS*)attr->pValue = CKO_SECRET_KEY;
break;
case CKA_TOKEN:
/*TODO DEE change if on card skeys are supported */
check_attribute_buffer(attr, sizeof(CK_BBOOL));
*(CK_BBOOL*)attr->pValue = FALSE;
*(CK_BBOOL*)attr->pValue = skey->base.p15_object->session_object == 0;
break;
case CKA_PRIVATE:
check_attribute_buffer(attr, sizeof(CK_BBOOL));