Corrections and code cleanup as requested in review. Changed value to void* in sc_sec_env_param_t, because param_type defines type of the value. Fixed handling of secret key length in framework-pkcs15 and pkcs15-lib: CKA_VALUE_LEN from PKCS#11 is in bytes, PKCS#15 objects need key length in bits. Rebased on top of upstream/master and resolved merge conflicts.

This commit is contained in:
Hannu Honkanen 2018-10-01 15:27:09 +03:00
parent 84317f4e9d
commit 90ec7123ba
8 changed files with 121 additions and 96 deletions

View File

@ -59,6 +59,9 @@
#define MYEID_CARD_CAP_GRIDPIN 0x10
#define MYEID_CARD_CAP_PIV_EMU 0x20
#define MYEID_MAX_APDU_DATA_LEN 0xFF
#define MYEID_MAX_RSA_KEY_LEN 2048
static const char *myeid_card_name = "MyEID";
static char card_name_buf[MYEID_CARD_NAME_MAX_LEN];
@ -677,25 +680,29 @@ static int myeid_set_security_env_rsa(sc_card_t *card, const sc_security_env_t *
}
for (i = 0; i < SC_SEC_ENV_MAX_PARAMS; i++)
if (env->params[i].param_type == SC_SEC_ENV_PARAM_TARGET_FILE) {
target_file = (sc_path_t*) env->params[i].value;
if (env->params[i].value_len < sizeof(sc_path_t) || target_file->len != 2) {
sc_log(card->ctx, "wrong length of target file reference.\n");
return SC_ERROR_WRONG_LENGTH;
}
*p++ = 0x83;
*p++ = 2;
memcpy(p, target_file->value, 2);
p+= 2;
break;
target_file = (sc_path_t*) env->params[i].value;
if (env->params[i].value_len < sizeof(sc_path_t) || target_file->len != 2) {
sc_log(card->ctx, "wrong length of target file reference.\n");
return SC_ERROR_WRONG_LENGTH;
}
*p++ = 0x83;
*p++ = 2;
memcpy(p, target_file->value, 2);
p+= 2;
break;
}
if (env->operation == SC_SEC_OPERATION_UNWRAP || env->operation == SC_SEC_OPERATION_WRAP) /* & SC_SEC_ENV_IV_PRESENT*/
if (env->operation == SC_SEC_OPERATION_UNWRAP || env->operation == SC_SEC_OPERATION_WRAP)
{
/* add IV if present */
for (i = 0; i < SC_SEC_ENV_MAX_PARAMS; i++)
if (env->params[i].param_type == SC_SEC_ENV_PARAM_IV) {
*p++ = 0x87;
*p++ = (unsigned char) env->params[i].value_len;
if (p + env->params[i].value_len >= sbuf + SC_MAX_APDU_BUFFER_SIZE) {
sc_log(card->ctx, "IV too long.\n");
return SC_ERROR_WRONG_LENGTH;
}
memcpy(p, env->params[i].value, env->params[i].value_len);
p+=(unsigned char) env->params[i].value_len;
break;
@ -1288,20 +1295,21 @@ static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen)
static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgram_len)
{
int r;
u8 out[512];
size_t outlen = 512;
struct sc_apdu apdu;
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
u8 p2 = 0x86;
u8 p2 = 0x86; /* init P2 for asymmetric crypto by default.*/
myeid_private_data_t* priv;
int symmetric_operation = 0;
LOG_FUNC_CALLED(card->ctx);
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL);
assert(card != NULL && crgram != NULL && out != NULL);
if (card == NULL || crgram == NULL) {
LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "One or more of required arguments was null.\n");
}
if (crgram_len > 256)
if (crgram_len > MYEID_MAX_RSA_KEY_LEN / 8)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
if (card->drv_data)
@ -1313,40 +1321,56 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra
if (priv->sec_env->algorithm == SC_ALGORITHM_AES ||
priv->sec_env->algorithm == SC_ALGORITHM_3DES ||
priv->sec_env->algorithm == SC_ALGORITHM_DES)
p2 = 0x84; /* Set correct P2 for symmetric crypto */
symmetric_operation = 1;
}
}
if (symmetric_operation)
{
p2 = 0x84; /* Set correct P2 for symmetric crypto */
if (crgram_len > MYEID_MAX_APDU_DATA_LEN)
{
LOG_TEST_RET(card->ctx, SC_ERROR_WRONG_LENGTH, "Unwrapping symmetric data longer that 255 bytes is not supported\n");
}
}
/* INS: 0x2A PERFORM SECURITY OPERATION
* P1: 0x00 Do not expect response - the deciphered data will be placed into the target key EF.
* P2: 0x86 Cmd: Padding indicator byte followed by cryptogram
* P2: 0x84 Cmd: AES/3DES Cryptogram (plain value encoded in BER-TLV DO, but not including SM DOs) */
* P2: 0x84 Cmd: AES/3DES Cryptogram (plain value encoded in BER-TLV DO, but not including SM DOs)
If crgram_len == 256 (2048 bit RSA), we split the cryptogram in two and send two APDUs.
*/
sc_format_apdu(card, &apdu,
(crgram_len < 256) ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT,
SC_APDU_CASE_3_SHORT,
0x2A, 0x00, p2);
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
apdu.le = crgram_len;
apdu.le = 0;
if (crgram_len == 256 && p2 == 0x86)
if (symmetric_operation)
{
apdu.le = 0;
/* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */
sbuf[0] = 0x81;
memcpy(sbuf + 1, crgram, crgram_len / 2);
apdu.lc = crgram_len / 2 + 1;
/* symmetric crypto, no padding indicator byte */
{
memcpy(sbuf, crgram, crgram_len);
apdu.lc = crgram_len;
}
}
else if (p2 == 0x86)
else
{
sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */
memcpy(sbuf + 1, crgram, crgram_len);
apdu.lc = crgram_len + 1;
}
else /* symmetric crypto, no padding indicator byte */
{
memcpy(sbuf, crgram, crgram_len);
apdu.lc = crgram_len;
if (crgram_len > MYEID_MAX_APDU_DATA_LEN)
{
/* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */
sbuf[0] = 0x81;
memcpy(sbuf + 1, crgram, crgram_len / 2);
apdu.lc = crgram_len / 2 + 1;
}
else
{
sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */
memcpy(sbuf + 1, crgram, crgram_len);
apdu.lc = crgram_len + 1;
}
}
apdu.datalen = apdu.lc;
@ -1356,15 +1380,15 @@ 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 && p2 == 0x86) /* with symmetric crypto, we support only single apdu unwrap for now */
if (crgram_len > MYEID_MAX_APDU_DATA_LEN)
{
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT,
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT,
0x2A, 0x00, p2);
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
apdu.le = crgram_len;
apdu.le = 0;
/* padding indicator byte,
* 0x82 = Second half of 2048 bit cryptogram */
* 0x82 = Second half of 2048 bit cryptogram */
sbuf[0] = 0x82;
memcpy(sbuf + 1, crgram + crgram_len / 2, crgram_len / 2);
apdu.lc = crgram_len / 2 + 1;
@ -1374,18 +1398,6 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra
r = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
{
LOG_FUNC_RETURN(card->ctx, r);
}
}
else
{
int len = apdu.resplen > outlen ? outlen : apdu.resplen;
memcpy(out, apdu.resp, len);
LOG_FUNC_RETURN(card->ctx, r);
}
}
LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));

View File

@ -227,7 +227,7 @@ struct sc_supported_algo_info {
typedef struct sc_sec_env_param {
unsigned int param_type;
unsigned char* value;
void* value;
unsigned int value_len;
} sc_sec_env_param_t;

View File

@ -53,22 +53,24 @@ static int sec_env_add_param(sc_security_env_t* se, const sc_sec_env_param_t* p)
}
static sc_path_t get_file_path(const struct sc_pkcs15_object* obj)
static int get_file_path(const struct sc_pkcs15_object* obj, sc_path_t* path)
{
sc_path_t path;
if (!path)
return SC_ERROR_INCORRECT_PARAMETERS;
const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data;
const struct sc_pkcs15_skey_info *skey = (const struct sc_pkcs15_skey_info *) obj->data;
memset (&path, 0, sizeof(path));
if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY) {
path = prkey->path;
*path = prkey->path;
}
else if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_SKEY) {
path = skey->path;
*path = skey->path;
}
else
return SC_ERROR_INCORRECT_PARAMETERS;
return path;
return SC_SUCCESS;
}
@ -83,7 +85,7 @@ static int select_key_file(struct sc_pkcs15_card *p15card,
LOG_FUNC_CALLED(ctx);
orig_path = get_file_path(key);
LOG_TEST_RET(ctx, get_file_path(key, &orig_path), "Could not get key file path.");
memset(&path, 0, sizeof(sc_path_t));
memset(&file_id, 0, sizeof(sc_path_t));
@ -131,7 +133,8 @@ static int use_key(struct sc_pkcs15_card *p15card,
{
int r = SC_SUCCESS;
int revalidated_cached_pin = 0;
sc_path_t path = get_file_path(obj);
sc_path_t path;
LOG_TEST_RET(p15card->card->ctx, get_file_path(obj, &path), "Failed to get key file path.");
r = sc_lock(p15card->card);
LOG_TEST_RET(p15card->card->ctx, r, "sc_lock() failed");
@ -419,7 +422,7 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card,
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "invalid unwrapping target key path");
}
senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_TARGET_FILE, (u8*) &target_file_id, sizeof(target_file_id)};
senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_TARGET_FILE, &target_file_id, sizeof(target_file_id)};
LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add target file path to security environment");
r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags);
@ -427,7 +430,7 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card,
senv.algorithm_flags = sec_flags;
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 };
senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_IV, (void*) param, paramlen };
LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment");
}
@ -498,11 +501,11 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card,
switch (target_key->type) {
case SC_PKCS15_TYPE_PRKEY_RSA:
tkey_path = target_prkey->path;
break;
default: /* we already know it is a secret key */
tkey_path = target_skey->path;
break;
tkey_path = target_prkey->path;
break;
default: /* we already know it is a secret key */
tkey_path = target_skey->path;
break;
}
if (!tkey_path.len && tkey_path.aid.len) {
@ -523,7 +526,7 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card,
else {
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "invalid unwrapping target key path");
}
senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_TARGET_FILE, (u8*) &target_file_id, sizeof(target_file_id)};
senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_TARGET_FILE, &target_file_id, sizeof(target_file_id)};
LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add target file path to security environment");
r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags);
@ -531,7 +534,7 @@ int sc_pkcs15_wrap(struct sc_pkcs15_card *p15card,
senv.algorithm_flags = sec_flags;
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 };
senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_IV, (void*) param, paramlen };
LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment");
}

View File

@ -164,10 +164,10 @@ sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj
temp_oid.value[8] = -1; /* strip off AES subtype octet*/
if (sc_compare_oid(&id_aes, &temp_oid))
if (info.key_type == 0) {
info.key_type = CKK_AES;
break;
}
if (info.key_type == 0) {
info.key_type = CKK_AES;
break;
}
}
}
}

View File

@ -2353,7 +2353,7 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile
skey_info->key_type = key_type; /* PKCS#11 CKK_* */
skey_info->data.value = args.key.data;
skey_info->data.len = args.key.data_len;
skey_info->value_len = args.value_len; /* callers preferred length */
skey_info->value_len = args.value_len * 8; /* key length comes in number of bytes, use length in bits in PKCS#15. */
args.key.data = NULL;
key_obj->session_object = 1;
}
@ -2361,7 +2361,8 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile
if(_token == FALSE)
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);
args.value_len = args.value_len * 8; /* CKA_VALUE_LEN is number of bytes, PKCS#15 needs key length in bits */
rc = sc_pkcs15init_store_secret_key(fw_data->p15_card, profile, &args, &key_obj);
if (rc < 0) {
rv = sc_to_cryptoki_error(rc, "C_CreateObject");
goto out;
@ -3521,7 +3522,7 @@ struct sc_pkcs11_object_ops pkcs15_cert_ops = {
NULL, /* decrypt */
NULL, /* derive */
NULL, /* can_do */
NULL /* init_params */
NULL, /* init_params */
NULL /* wrap_key */
};
@ -3971,11 +3972,10 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj,
if (!fw_data)
return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_UnwrapKey");
sc_log(context, "unwrapping %p %p %p %p %lu %p", session, obj,
pMechanism, pWrappedKey, ulWrappedKeyLen, targetKeyObj);
if (pMechanism == NULL || pWrappedKey == NULL || ulWrappedKeyLen == 0 || targetKeyObj == NULL)
if (pMechanism == NULL || pWrappedKey == NULL || ulWrappedKeyLen == 0 || targetKeyObj == NULL) {
sc_log(context, "One or more of mandatory arguments were NULL.");
return CKR_ARGUMENTS_BAD;
}
/* See which of the alternative keys supports unwrap */
while (prkey && !(prkey->prv_info->usage & SC_PKCS15_PRKEY_USAGE_UNWRAP))
@ -3984,6 +3984,8 @@ pkcs15_prkey_unwrap(struct sc_pkcs11_session *session, void *obj,
if (prkey == NULL)
return CKR_KEY_FUNCTION_NOT_PERMITTED;
sc_log(context, "Using mechanism %lx.", pMechanism->mechanism);
/* Select the proper padding mechanism */
switch (pMechanism->mechanism) {
case CKM_RSA_PKCS:
@ -4529,7 +4531,7 @@ struct sc_pkcs11_object_ops pkcs15_pubkey_ops = {
NULL, /* decrypt */
NULL, /* derive */
NULL, /* can_do */
NULL /* init_params */
NULL, /* init_params */
NULL /* wrap_key */
};
@ -4709,7 +4711,7 @@ struct sc_pkcs11_object_ops pkcs15_dobj_ops = {
NULL, /* decrypt */
NULL, /* derive */
NULL, /* can_do */
NULL /* init_params */
NULL, /* init_params */
NULL /* wrap_key */
};
@ -4847,11 +4849,10 @@ pkcs15_skey_unwrap(struct sc_pkcs11_session *session, void *obj,
if (!fw_data)
return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_UnwrapKey");
sc_log(context, "unwrapping %p %p %p %p %lu %p", session, obj,
pMechanism, pWrappedKey, ulWrappedKeyLen, targetKeyObj);
if (pMechanism == NULL || pWrappedKey == NULL || ulWrappedKeyLen == 0 || targetKeyObj == NULL)
return CKR_ARGUMENTS_BAD;
if (pMechanism == NULL || pWrappedKey == NULL || ulWrappedKeyLen == 0 || targetKeyObj == NULL) {
sc_log(context, "One or more of mandatory arguments were NULL.");
return CKR_ARGUMENTS_BAD;
}
/* Check whether this key supports unwrap */
if (skey && !(skey->info->usage & SC_PKCS15_PRKEY_USAGE_UNWRAP))
@ -4863,6 +4864,7 @@ pkcs15_skey_unwrap(struct sc_pkcs11_session *session, void *obj,
if (skey == NULL)
return CKR_KEY_FUNCTION_NOT_PERMITTED;
sc_log(context, "Using mechanism %lx.", pMechanism->mechanism);
/* Select the proper padding mechanism */
switch (pMechanism->mechanism) {
case CKM_AES_ECB:
@ -4920,21 +4922,21 @@ pkcs15_skey_wrap(struct sc_pkcs11_session *session, void *obj,
if (!fw_data)
return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_WrapKey");
sc_log(context, "wrapping %p %p %p %p %p %p, %lu", session, obj,
pMechanism, targetKey, pData, pulDataLen, pulDataLen == NULL ? 0 : *pulDataLen);
if (session == NULL || pMechanism == NULL || obj == NULL || targetKey == NULL)
return CKR_ARGUMENTS_BAD;
if (session == NULL || pMechanism == NULL || obj == NULL || targetKey == NULL) {
sc_log(context, "One or more of mandatory arguments were NULL.");
return CKR_ARGUMENTS_BAD;
}
/* Verify that the key supports wrapping */
if (skey && !(skey->info->usage & SC_PKCS15_PRKEY_USAGE_WRAP))
skey = NULL;
/* TODO: browse for a key that supports, like other similar funcs */
if (skey == NULL)
return CKR_KEY_FUNCTION_NOT_PERMITTED;
sc_log(context, "Using mechanism %lx.", pMechanism->mechanism);
/* Select the proper padding mechanism */
switch (pMechanism->mechanism) {
case CKM_AES_ECB:
@ -4983,7 +4985,7 @@ struct sc_pkcs11_object_ops pkcs15_skey_ops = {
NULL, /* decrypt */
NULL, /* derive */
NULL, /* can_do */
NULL /* init_params */
NULL, /* init_params */
pkcs15_skey_wrap /* wrap_key */
};

View File

@ -1097,6 +1097,9 @@ sc_pkcs11_wrap_operation(sc_pkcs11_operation_t *operation,
struct sc_pkcs11_object *targetKey,
CK_BYTE_PTR pWrappedData, CK_ULONG_PTR ulWrappedDataLen)
{
if (!operation || !wrappingKey || !wrappingKey->ops || !wrappingKey->ops->wrap_key)
return CKR_ARGUMENTS_BAD;
return wrappingKey->ops->wrap_key(operation->session,
wrappingKey,
&operation->mechanism,
@ -1110,6 +1113,9 @@ sc_pkcs11_unwrap_operation(sc_pkcs11_operation_t *operation,
CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
struct sc_pkcs11_object *targetKey)
{
if (!operation || !unwrappingKey || !unwrappingKey->ops || !unwrappingKey->ops->unwrap_key)
return CKR_ARGUMENTS_BAD;
return unwrappingKey->ops->unwrap_key(operation->session,
unwrappingKey,
&operation->mechanism,

View File

@ -83,6 +83,8 @@ static sc_pkcs11_mechanism_type_t openssl_sha224_mech = {
NULL, NULL, NULL, /* verif_* */
NULL, NULL, /* decrypt_* */
NULL, /* derive */
NULL, /* wrap */
NULL, /* unwrap */
NULL, /* mech_data */
NULL, /* free_mech_data */
};

View File

@ -1295,7 +1295,7 @@ sc_pkcs15init_init_skdf(struct sc_pkcs15_card *p15card, struct sc_profile *profi
struct sc_pkcs15_object *object = NULL;
const char *label;
unsigned int usage;
unsigned int keybits = keyargs->value_len * 8;
unsigned int keybits = keyargs->value_len;
int r = 0, key_type;
LOG_FUNC_CALLED(ctx);