Support for ECC keys (part 1) header files and

support routines. Add definitions for EC keys,
parameters and extensions to structures. 
Add the sc_card_find_ec_alg, sc_pkcs15_decode_pubkey_ec,
sc_pkcs15_encode_pubkey_ec, sc_pkcs15emu_add_ec_prkey,
sc_pkcs15emu_add_ec_pubkey routines. 
Only EC named curves are currently supported. 



git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@4902 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
dengert 2010-11-30 19:13:48 +00:00
parent 137a7282ad
commit c34caeb662
6 changed files with 221 additions and 12 deletions

View File

@ -110,6 +110,8 @@ int _sc_match_atr(struct sc_card *card, struct sc_atr_table *table, int *type_ou
int _sc_card_add_algorithm(struct sc_card *card, const struct sc_algorithm_info *info);
int _sc_card_add_rsa_alg(struct sc_card *card, unsigned int key_length,
unsigned long flags, unsigned long exponent);
int _sc_card_add_ec_alg(struct sc_card *card, unsigned int key_length,
unsigned long flags, unsigned long ext_flags);
int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out,
unsigned int *tag_out, size_t *taglen);

View File

@ -78,7 +78,7 @@ extern "C" {
#define SC_ALGORITHM_ONBOARD_KEY_GEN 0x80000000
/* need usage = either sign or decrypt. keys with both? decrypt, emulate sign */
#define SC_ALGORITHM_NEED_USAGE 0x40000000
#define SC_ALGORITHM_SPECIFIC_FLAGS 0x0000FFFF
#define SC_ALGORITHM_SPECIFIC_FLAGS 0x0001FFFF
#define SC_ALGORITHM_RSA_RAW 0x00000001
/* If the card is willing to produce a cryptogram padded with the following
@ -106,6 +106,36 @@ extern "C" {
#define SC_ALGORITHM_GOSTR3410_HASH_NONE 0x00004000
#define SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411 0x00008000
#define SC_ALGORITHM_GOSTR3410_HASHES 0x00008000
/*TODO: -DEE Should the above be 0x0000E000 */
/* Or should the HASH_NONE be 0x00000010 and HASHES be 0x00008010 */
/* May need more bits if card can do more hashes */
/* TODO: -DEE Will overload RSA_HASHES with EC_HASHES */
/* Not clear if these need their own bits or not */
/* The PIV card does not support and hashes */
#define SC_ALGORITHM_ECDSA_RAW 0x00010000
#define SC_ALGORITHM_ECDSA_HASH_NONE SC_ALGORITHM_RSA_HASH_NONE
#define SC_ALGORITHM_ECDSA_HASH_SHA1 SC_ALGORITHM_RSA_HASH_SHA1
#define SC_ALGORITHM_ECDSA_HASH_SHA224 SC_ALGORITHM_RSA_HASH_SHA224
#define SC_ALGORITHM_ECDSA_HASH_SHA256 SC_ALGORITHM_RSA_HASH_SHA256
#define SC_ALGORITHM_ECDSA_HASH_SHA384 SC_ALGORITHM_RSA_HASH_SHA384
#define SC_ALGORITHM_ECDSA_HASH_SHA512 SC_ALGORITHM_RSA_HASH_SHA512
#define SC_ALGORITHM_ECDSA_HASHES (SC_ALGORITHM_ECDSA_HASH_SHA1 | \
SC_ALGORITHM_ECDSA_HASH_SHA224 | \
SC_ALGORITHM_ECDSA_HASH_SHA256 | \
SC_ALGORITHM_ECDSA_HASH_SHA384 | \
SC_ALGORITHM_ECDSA_HASH_SHA512)
/* define mask of all algorithms that can do raw */
#define SC_ALGORITHM_RAW_MASK (SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_GOSTR3410_RAW | SC_ALGORITHM_ECDSA_RAW)
/* extened algorithm bits for selected mechs */
#define SC_ALGORITHM_EXT_EC_F_P 0x00000001
#define SC_ALGORITHM_EXT_EC_F_2M 0x00000002
#define SC_ALGORITHM_EXT_EC_ECPARAMETERS 0x00000004
#define SC_ALGORITHM_EXT_EC_NAMEDCURVE 0x00000008
#define SC_ALGORITHM_EXT_EC_UNCOMPRESES 0x00000010
#define SC_ALGORITHM_EXT_EC_COMPRESS 0x00000020
/* Event masks for sc_wait_for_event() */
#define SC_EVENT_CARD_INSERTED 0x0001
@ -155,6 +185,12 @@ struct sc_pbes2_params {
struct sc_algorithm_id key_encr_alg;
};
struct sc_ec_params {
int type;
u8 * der;
size_t der_len;
};
typedef struct sc_algorithm_info {
unsigned int algorithm;
unsigned int key_length;
@ -164,6 +200,9 @@ typedef struct sc_algorithm_info {
struct sc_rsa_info {
unsigned long exponent;
} _rsa;
struct sc_ec_info {
unsigned ext_flags;
} _ec;
} u;
} sc_algorithm_info_t;
@ -1068,6 +1107,8 @@ int sc_update_dir(sc_card_t *card, sc_app_info_t *app);
struct sc_algorithm_info * sc_card_find_rsa_alg(sc_card_t *card,
unsigned int key_length);
struct sc_algorithm_info * sc_card_find_ec_alg(sc_card_t *card,
unsigned int field_length);
struct sc_card_error {

View File

@ -89,6 +89,7 @@ static const struct sc_asn1_entry c_asn1_pubkey_choice[] = {
{ "publicRSAKey", SC_ASN1_PKCS15_OBJECT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
{ "publicDSAKey", SC_ASN1_PKCS15_OBJECT, 2 | SC_ASN1_CTX | SC_ASN1_CONS, 0, NULL, NULL },
{ "publicGOSTR3410Key", SC_ASN1_PKCS15_OBJECT, 3 | SC_ASN1_CTX | SC_ASN1_CONS, 0, NULL, NULL },
/*TODO: -DEE not clear EC is needed here as look like it is for pukdf */
{ NULL, 0, 0, 0, NULL, NULL }
};
@ -287,6 +288,7 @@ int sc_pkcs15_encode_pukdf_entry(sc_context_t *ctx,
}
break;
default:
/* TODO: -DEE Should add ECC but dont have PKCS15 card with ECC */
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unsupported public key type: %X\n", obj->type);
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
break;
@ -336,6 +338,11 @@ static struct sc_asn1_entry c_asn1_gostr3410_pub_coefficients[2] = {
{ NULL, 0, 0, 0, NULL, NULL }
};
static struct sc_asn1_entry c_asn1_ec_pointQ[2] = {
{ "ecpointQ", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_ALLOC, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};
int
sc_pkcs15_decode_pubkey_rsa(sc_context_t *ctx,
struct sc_pkcs15_pubkey_rsa *key,
@ -475,6 +482,64 @@ sc_pkcs15_encode_pubkey_gostr3410(sc_context_t *ctx,
return 0;
}
/*
* We are storing the ec_pointQ as a octet string.
* Thus we will just copy the string.
* But to get the field length we decode it.
*/
int
sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx,
struct sc_pkcs15_pubkey_ec *key,
const u8 *buf, size_t buflen)
{
int r;
u8 * ecpoint_data;
size_t ecpoint_len;
struct sc_asn1_entry asn1_ec_pointQ[2];
sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ);
sc_format_asn1_entry(asn1_ec_pointQ + 0, &ecpoint_data, &ecpoint_len, 1);
r = sc_asn1_decode(ctx, asn1_ec_pointQ, buf, buflen, NULL, NULL);
if (r < 0)
SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 encoding failed");
sc_debug(ctx, SC_LOG_DEBUG_NORMAL,"DEE-EC key=%p, buf=%p, buflen=%d", key, buf, buflen);
key->ecpointQ.value = malloc(buflen);
if (key->ecpointQ.value == NULL)
return SC_ERROR_OUT_OF_MEMORY;
key->ecpointQ.len = buflen;
memcpy(key->ecpointQ.value, buf, buflen);
/* An uncompressed ecpoint is of the form 04||x||y
* The 04 indicates uncompressed
* x and y are same size, and field_length = sizeof(x) in bits. */
/* TODO: -DEE support more then uncompressed */
key->field_length = (ecpoint_len - 1)/2 * 8;
if (ecpoint_data);
free (ecpoint_data);
return r;
}
int sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx,
struct sc_pkcs15_pubkey_ec *key,
u8 **buf, size_t *buflen)
{
*buf = malloc(key->ecpointQ.len);
if (*buf == NULL)
return SC_ERROR_OUT_OF_MEMORY;
memcpy(*buf, key->ecpointQ.value, key->ecpointQ.len);
*buflen = key->ecpointQ.len;
sc_debug(ctx, SC_LOG_DEBUG_NORMAL,"DEE-EC key->ecpointQ=%p:%d *buf=%p:%d",
key->ecpointQ.value, key->ecpointQ.len, *buf, *buflen);
return 0;
}
int
sc_pkcs15_encode_pubkey(sc_context_t *ctx,
struct sc_pkcs15_pubkey *key,
@ -487,6 +552,8 @@ sc_pkcs15_encode_pubkey(sc_context_t *ctx,
if (key->algorithm == SC_ALGORITHM_GOSTR3410)
return sc_pkcs15_encode_pubkey_gostr3410(ctx,
&key->u.gostr3410, buf, len);
if (key->algorithm == SC_ALGORITHM_EC)
return sc_pkcs15_encode_pubkey_ec(ctx, &key->u.ec, buf, len);
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Encoding of public key type %u not supported\n",
key->algorithm);
return SC_ERROR_NOT_SUPPORTED;
@ -504,6 +571,8 @@ sc_pkcs15_decode_pubkey(sc_context_t *ctx,
if (key->algorithm == SC_ALGORITHM_GOSTR3410)
return sc_pkcs15_decode_pubkey_gostr3410(ctx,
&key->u.gostr3410, buf, len);
if (key->algorithm == SC_ALGORITHM_EC)
return sc_pkcs15_decode_pubkey_ec(ctx, &key->u.ec, buf, len);
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Decoding of public key type %u not supported\n",
key->algorithm);
return SC_ERROR_NOT_SUPPORTED;
@ -536,6 +605,9 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card,
case SC_PKCS15_TYPE_PUBKEY_GOSTR3410:
algorithm = SC_ALGORITHM_GOSTR3410;
break;
case SC_PKCS15_TYPE_PUBKEY_EC:
algorithm = SC_ALGORITHM_EC;
break;
default:
sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported public key type.");
return SC_ERROR_NOT_SUPPORTED;
@ -654,6 +726,12 @@ void sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *key)
if (key->u.gostr3410.xy.data)
free(key->u.gostr3410.xy.data);
break;
case SC_ALGORITHM_EC:
if (key->u.ec.ecparameters.value)
free(key->u.ec.ecparameters.value);
if (key->u.ec.ecpointQ.value)
free(key->u.ec.ecpointQ.value);
break;
}
if (key->data.value)
free(key->data.value);
@ -752,7 +830,8 @@ int sc_pkcs15_pubkey_from_spki(sc_context_t *ctx, sc_pkcs15_pubkey_t ** outpubke
sc_pkcs15_der_t pk = { NULL, 0 };
struct sc_algorithm_id pk_alg;
struct sc_asn1_entry asn1_pkinfo[3];
struct sc_asn1_entry asn1_ec_pointQ[2];
sc_debug(ctx,SC_LOG_DEBUG_NORMAL,"sc_pkcs15_pubkey_from_spki %p:%d", buf, buflen);
memset(&pk_alg, 0, sizeof(pk_alg));
@ -778,15 +857,40 @@ int sc_pkcs15_pubkey_from_spki(sc_context_t *ctx, sc_pkcs15_pubkey_t ** outpubke
memcpy(pubkey->alg_id, &pk_alg, sizeof(struct sc_algorithm_id));
pubkey->algorithm = pk_alg.algorithm;
pk.len >>= 3; /* convert number of bits to bytes */
pubkey->data = pk; /* save in publey */
pk.value = NULL;
/* Now decode what every is in pk as it depends on the key algorthim */
sc_debug(ctx,SC_LOG_DEBUG_NORMAL,"DEE pk_alg.algorithm=%d",pk_alg.algorithm);
r = sc_pkcs15_decode_pubkey(ctx, pubkey, pubkey->data.value, pubkey->data.len);
if (r < 0)
goto err;
/* pk.len is in bits at this point */
switch (pk_alg.algorithm) {
case SC_ALGORITHM_EC:
/*
* For most keys, the above ASN.1 parsing of a key works, but for EC keys,
* the ec_pointQ in a certificate is stored in a bitstring, but
* in PKCS#11 it is an octet string and we just decoded its
* contents from the bitstring in the certificate. So we need to encode it
* back to an octet string so we can store it as an octet string.
*/
pk.len >>= 3; /* Assume it is multiple of 8 */
// pubkey->u.ec.field_length = (pk.len - 1)/2 * 8;
sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ);
sc_format_asn1_entry(&asn1_ec_pointQ[0], pk.value, &pk.len, 1);
r = sc_asn1_encode(ctx, asn1_ec_pointQ,
&pubkey->data.value, &pubkey->data.len);
sc_debug(ctx,SC_LOG_DEBUG_NORMAL,"DEE r=%d data=%p:%d",
r,pubkey->data.value, pubkey->data.len);
break;
default:
pk.len >>= 3; /* convert number of bits to bytes */
pubkey->data = pk; /* save in publey */
pk.value = NULL;
break;
}
/* Now decode what every is in pk as it depends on the key algorthim */
r = sc_pkcs15_decode_pubkey(ctx, pubkey, pubkey->data.value, pubkey->data.len);
if (r < 0)
goto err;
*outpubkey = pubkey;
pubkey = NULL;

View File

@ -359,6 +359,30 @@ int sc_pkcs15emu_add_rsa_pubkey(sc_pkcs15_card_t *p15card,
return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_RSA, obj, &key);
}
int sc_pkcs15emu_add_ec_prkey(sc_pkcs15_card_t *p15card,
const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
{
sc_pkcs15_prkey_info_t key = *in_key;
if (key.access_flags == 0)
key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
| SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
| SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
| SC_PKCS15_PRKEY_ACCESS_LOCAL;
return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_EC, obj, &key);
}
int sc_pkcs15emu_add_ec_pubkey(sc_pkcs15_card_t *p15card,
const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
{
sc_pkcs15_pubkey_info_t key = *in_key;
if (key.access_flags == 0)
key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_EC, obj, &key);
}
int sc_pkcs15emu_add_x509_cert(sc_pkcs15_card_t *p15card,
const sc_pkcs15_object_t *obj, const sc_pkcs15_cert_info_t *cert)
{

View File

@ -149,6 +149,21 @@ struct sc_pkcs15_prkey_dsa {
sc_pkcs15_bignum_t priv;
};
/* The ecParameters are kept in DER format
* as certificates, and pkcs11 process them as DER
* If needed, they can be parsed
*/
struct sc_pkcs15_pubkey_ec {
sc_pkcs15_der_t ecparameters;
sc_pkcs15_der_t ecpointQ; /* note this is der */
size_t field_length; /* in bits */
};
struct sc_pkcs15_prkey_ec {
sc_pkcs15_der_t ecparameters;
sc_pkcs15_bignum_t privateD; /* note this is bignum */
};
struct sc_pkcs15_pubkey_gostr3410 {
sc_pkcs15_bignum_t xy;
};
@ -166,6 +181,7 @@ struct sc_pkcs15_pubkey {
union {
struct sc_pkcs15_pubkey_rsa rsa;
struct sc_pkcs15_pubkey_dsa dsa;
struct sc_pkcs15_pubkey_ec ec;
struct sc_pkcs15_pubkey_gostr3410 gostr3410;
} u;
@ -181,6 +197,7 @@ struct sc_pkcs15_prkey {
union {
struct sc_pkcs15_prkey_rsa rsa;
struct sc_pkcs15_prkey_dsa dsa;
struct sc_pkcs15_prkey_ec ec;
struct sc_pkcs15_prkey_gostr3410 gostr3410;
} u;
};
@ -298,7 +315,9 @@ struct sc_pkcs15_prkey_info {
struct sc_pkcs15_id id; /* correlates to public certificate id */
unsigned int usage, access_flags;
int native, key_reference;
size_t modulus_length;
/* convert to union if other types are supported */
size_t modulus_length; /* RSA */
size_t field_length; /* EC in bits */
struct sc_pkcs15_der subject;
@ -313,7 +332,9 @@ struct sc_pkcs15_pubkey_info {
struct sc_pkcs15_id id; /* correlates to private key id */
unsigned int usage, access_flags;
int native, key_reference;
size_t modulus_length;
/* convert to union if other types are supported */
size_t modulus_length; /* RSA */
size_t field_length; /* EC in bits */
struct sc_pkcs15_der subject;
@ -330,11 +351,13 @@ typedef struct sc_pkcs15_pubkey_info sc_pkcs15_pubkey_info_t;
#define SC_PKCS15_TYPE_PRKEY_RSA 0x101
#define SC_PKCS15_TYPE_PRKEY_DSA 0x102
#define SC_PKCS15_TYPE_PRKEY_GOSTR3410 0x103
#define SC_PKCS15_TYPE_PRKEY_EC 0x104
#define SC_PKCS15_TYPE_PUBKEY 0x200
#define SC_PKCS15_TYPE_PUBKEY_RSA 0x201
#define SC_PKCS15_TYPE_PUBKEY_DSA 0x202
#define SC_PKCS15_TYPE_PUBKEY_GOSTR3410 0x203
#define SC_PKCS15_TYPE_PUBKEY_EC 0x204
#define SC_PKCS15_TYPE_CERT 0x400
#define SC_PKCS15_TYPE_CERT_X509 0x401
@ -368,6 +391,7 @@ struct sc_pkcs15_object {
/* emulated object pointer */
void *emulated;
struct sc_pkcs15_df *df; /* can be NULL, if object is 'floating' */
struct sc_pkcs15_object *next, *prev; /* used only internally */
@ -526,6 +550,10 @@ int sc_pkcs15_decode_pubkey_gostr3410(sc_context_t *,
struct sc_pkcs15_pubkey_gostr3410 *, const u8 *, size_t);
int sc_pkcs15_encode_pubkey_gostr3410(sc_context_t *,
struct sc_pkcs15_pubkey_gostr3410 *, u8 **, size_t *);
int sc_pkcs15_decode_pubkey_ec(struct sc_context *,
struct sc_pkcs15_pubkey_ec *, const u8 *, size_t);
int sc_pkcs15_encode_pubkey_ec(struct sc_context *,
struct sc_pkcs15_pubkey_ec *, u8 **, size_t *);
int sc_pkcs15_decode_pubkey(struct sc_context *,
struct sc_pkcs15_pubkey *, const u8 *, size_t);
int sc_pkcs15_encode_pubkey(struct sc_context *,
@ -793,6 +821,10 @@ int sc_pkcs15emu_add_rsa_prkey(sc_pkcs15_card_t *,
const sc_pkcs15_object_t *, const sc_pkcs15_prkey_info_t *);
int sc_pkcs15emu_add_rsa_pubkey(sc_pkcs15_card_t *,
const sc_pkcs15_object_t *, const sc_pkcs15_pubkey_info_t *);
int sc_pkcs15emu_add_ec_prkey(sc_pkcs15_card_t *,
const sc_pkcs15_object_t *, const sc_pkcs15_prkey_info_t *);
int sc_pkcs15emu_add_ec_pubkey(sc_pkcs15_card_t *,
const sc_pkcs15_object_t *, const sc_pkcs15_pubkey_info_t *);
int sc_pkcs15emu_add_x509_cert(sc_pkcs15_card_t *,
const sc_pkcs15_object_t *, const sc_pkcs15_cert_info_t *);
int sc_pkcs15emu_add_data_object(sc_pkcs15_card_t *,

View File

@ -711,6 +711,12 @@ struct ck_mechanism_info
#define CKF_DERIVE (1UL << 19)
#define CKF_EXTENSION (1UL << 31)
#define CKF_EC_F_P (1UL << 20)
#define CKF_EC_F_2M (1UL << 21)
#define CKF_EC_ECPARAMETERS (1UL << 22)
#define CKF_EC_NAMEDCURVE (1UL << 23)
#define CKF_EC_UNCOMPRESES (1UL << 24)
#define CKF_EC_COMPRESS (1UL << 25)
/* Flags for C_WaitForSlotEvent. */
#define CKF_DONT_BLOCK (1UL)