Add internal support for (X)EdDSA keys

This commit is contained in:
Jakub Jelen 2020-02-24 18:29:32 +01:00
parent 80f80317d1
commit caae75758c
17 changed files with 582 additions and 52 deletions

View File

@ -163,7 +163,7 @@ static void sc_card_free(sc_card_t *card)
int i;
for (i=0; i<card->algorithm_count; i++) {
struct sc_algorithm_info *info = (card->algorithms + i);
if (info->algorithm == SC_ALGORITHM_EC) {
if (info->algorithm == SC_ALGORITHM_EC) {
struct sc_ec_parameters ep = info->u._ec.params;
free(ep.named_curve);
@ -1096,16 +1096,18 @@ int _sc_card_add_symmetric_alg(sc_card_t *card, unsigned int algorithm,
return _sc_card_add_algorithm(card, &info);
}
int _sc_card_add_ec_alg(sc_card_t *card, unsigned int key_length,
static int
_sc_card_add_ec_alg_int(sc_card_t *card, unsigned int key_length,
unsigned long flags, unsigned long ext_flags,
struct sc_object_id *curve_oid)
struct sc_object_id *curve_oid,
int algorithm)
{
sc_algorithm_info_t info;
memset(&info, 0, sizeof(info));
sc_init_oid(&info.u._ec.params.id);
info.algorithm = SC_ALGORITHM_EC;
info.algorithm = algorithm;
info.key_length = key_length;
info.flags = flags;
@ -1116,6 +1118,32 @@ int _sc_card_add_ec_alg(sc_card_t *card, unsigned int key_length,
return _sc_card_add_algorithm(card, &info);
}
int _sc_card_add_ec_alg(sc_card_t *card, unsigned int key_length,
unsigned long flags, unsigned long ext_flags,
struct sc_object_id *curve_oid)
{
return _sc_card_add_ec_alg_int(card, key_length, flags, ext_flags,
curve_oid, SC_ALGORITHM_EC);
}
int _sc_card_add_eddsa_alg(sc_card_t *card, unsigned int key_length,
unsigned long flags, unsigned long ext_flags,
struct sc_object_id *curve_oid)
{
/* For simplicity, share the ec union with the curve information */
return _sc_card_add_ec_alg_int(card, key_length, flags, ext_flags,
curve_oid, SC_ALGORITHM_EDDSA);
}
int _sc_card_add_xeddsa_alg(sc_card_t *card, unsigned int key_length,
unsigned long flags, unsigned long ext_flags,
struct sc_object_id *curve_oid)
{
/* For simplicity, share the ec union with the curve information */
return _sc_card_add_ec_alg_int(card, key_length, flags, ext_flags,
curve_oid, SC_ALGORITHM_XEDDSA);
}
sc_algorithm_info_t * sc_card_find_alg(sc_card_t *card,
unsigned int algorithm, unsigned int key_length, void *param)
{
@ -1129,7 +1157,7 @@ sc_algorithm_info_t * sc_card_find_alg(sc_card_t *card,
if (info->key_length != key_length)
continue;
if (param) {
if (info->algorithm == SC_ALGORITHM_EC)
if (info->algorithm == SC_ALGORITHM_EC || info->algorithm == SC_ALGORITHM_EDDSA)
if(!sc_compare_oid((struct sc_object_id *)param, &info->u._ec.params.id))
continue;
}
@ -1144,6 +1172,18 @@ sc_algorithm_info_t * sc_card_find_ec_alg(sc_card_t *card,
return sc_card_find_alg(card, SC_ALGORITHM_EC, key_length, curve_name);
}
sc_algorithm_info_t * sc_card_find_eddsa_alg(sc_card_t *card,
unsigned int key_length, struct sc_object_id *curve_name)
{
return sc_card_find_alg(card, SC_ALGORITHM_EDDSA, key_length, curve_name);
}
sc_algorithm_info_t * sc_card_find_xeddsa_alg(sc_card_t *card,
unsigned int key_length, struct sc_object_id *curve_name)
{
return sc_card_find_alg(card, SC_ALGORITHM_XEDDSA, key_length, curve_name);
}
int _sc_card_add_rsa_alg(sc_card_t *card, unsigned int key_length,
unsigned long flags, unsigned long exponent)
{

View File

@ -974,6 +974,7 @@ typedef struct sc_cardctl_piv_genkey_info_st {
#define SC_OPENPGP_KEYALGO_RSA 0x01
#define SC_OPENPGP_KEYALGO_ECDH 0x12
#define SC_OPENPGP_KEYALGO_ECDSA 0x13
#define SC_OPENPGP_KEYALGO_EDDSA 0x16
#define SC_OPENPGP_KEYFORMAT_RSA_STD 0 /* See 4.3.3.6 Algorithm Attributes */
#define SC_OPENPGP_KEYFORMAT_RSA_STDN 1 /* OpenPGP card spec v2 */

View File

@ -153,6 +153,12 @@ int _sc_card_add_rsa_alg(struct sc_card *card, unsigned int key_length,
int _sc_card_add_ec_alg(struct sc_card *card, unsigned int key_length,
unsigned long flags, unsigned long ext_flags,
struct sc_object_id *curve_oid);
int _sc_card_add_eddsa_alg(struct sc_card *card, unsigned int key_length,
unsigned long flags, unsigned long ext_flags,
struct sc_object_id *curve_oid);
int _sc_card_add_xeddsa_alg(struct sc_card *card, unsigned int key_length,
unsigned long flags, unsigned long ext_flags,
struct sc_object_id *curve_oid);
/********************************************************************/
/* pkcs1 padding/encoding functions */

View File

@ -175,6 +175,7 @@ sc_pkcs15_encode_pubkey
sc_pkcs15_encode_pubkey_dsa
sc_pkcs15_encode_pubkey_rsa
sc_pkcs15_encode_pubkey_ec
sc_pkcs15_encode_pubkey_eddsa
sc_pkcs15_encode_pubkey_gostr3410
sc_pkcs15_encode_pubkey_as_spki
sc_pkcs15_encode_pukdf_entry

View File

@ -78,6 +78,8 @@ extern "C" {
#define SC_ALGORITHM_DSA 1
#define SC_ALGORITHM_EC 2
#define SC_ALGORITHM_GOSTR3410 3
#define SC_ALGORITHM_EDDSA 4
#define SC_ALGORITHM_XEDDSA 5
/* Symmetric algorithms */
#define SC_ALGORITHM_DES 64
@ -189,6 +191,10 @@ extern "C" {
SC_ALGORITHM_ECDSA_HASH_SHA384 | \
SC_ALGORITHM_ECDSA_HASH_SHA512)
/* EdDSA algorithms */
#define SC_ALGORITHM_EDDSA_RAW 0x00400000
#define SC_ALGORITHM_XEDDSA_RAW 0x00800000
/* define mask of all algorithms that can do raw */
#define SC_ALGORITHM_RAW_MASK (SC_ALGORITHM_RSA_RAW | \
SC_ALGORITHM_GOSTR3410_RAW | \
@ -1555,6 +1561,10 @@ struct sc_algorithm_info * sc_card_find_rsa_alg(struct sc_card *card,
unsigned int key_length);
struct sc_algorithm_info * sc_card_find_ec_alg(struct sc_card *card,
unsigned int field_length, struct sc_object_id *curve_oid);
struct sc_algorithm_info * sc_card_find_eddsa_alg(struct sc_card *card,
unsigned int field_length, struct sc_object_id *curve_oid);
struct sc_algorithm_info * sc_card_find_xeddsa_alg(struct sc_card *card,
unsigned int field_length, struct sc_object_id *curve_oid);
struct sc_algorithm_info * sc_card_find_gostr3410_alg(struct sc_card *card,
unsigned int key_length);
struct sc_algorithm_info * sc_card_find_alg(sc_card_t *card,

View File

@ -412,7 +412,6 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = {
asn1_encode_pbes2_params,
asn1_free_pbes2_params },
#endif
#ifdef SC_ALGORITHM_EC
{ SC_ALGORITHM_EC, {{ 1, 2, 840, 10045, 2, 1, -1}},
asn1_decode_ec_params,
@ -448,6 +447,14 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = {
asn1_decode_ec_params,
asn1_encode_ec_params,
asn1_free_ec_params },
#endif
#ifdef SC_ALGORITHM_EDDSA
/* aka Ed25519 */
{ SC_ALGORITHM_EDDSA, {{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, NULL, NULL, NULL },
#endif
#ifdef SC_ALGORITHM_XEDDSA
/* aka curve25519 */
{ SC_ALGORITHM_XEDDSA, {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, NULL, NULL, NULL },
#endif
{ -1, {{ -1 }}, NULL, NULL, NULL }
};

View File

@ -617,6 +617,14 @@ sc_pkcs15_free_prkey(struct sc_pkcs15_prkey *key)
if (key->u.ec.ecpointQ.value)
free(key->u.ec.ecpointQ.value);
break;
case SC_ALGORITHM_EDDSA:
free(key->u.eddsa.pubkey.value);
key->u.eddsa.pubkey.value = NULL;
key->u.eddsa.pubkey.len = 0;
free(key->u.eddsa.value.value);
key->u.eddsa.value.value = NULL;
key->u.eddsa.value.len = 0;
break;
}
}
@ -783,6 +791,13 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key)
break;
}
#endif /* !defined(OPENSSL_NO_EC) */
#ifdef EVP_PKEY_ED25519
case EVP_PKEY_ED25519: {
/* TODO */
break;
}
#endif /* EVP_PKEY_ED25519 */
default:
return SC_ERROR_NOT_SUPPORTED;
}

View File

@ -580,6 +580,12 @@ static struct sc_asn1_entry c_asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE] = {
{ NULL, 0, 0, 0, NULL, NULL }
};
#define C_ASN1_EDDSA_PUBKEY_SIZE 2
static struct sc_asn1_entry c_asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE] = {
{ "pubkey", 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,
@ -767,6 +773,47 @@ sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key,
sc_asn1_encode(ctx, asn1_ec_pointQ, buf, buflen));
}
/*
* EdDSA keys are just byte strings. For now only
* for Ed25519 keys 32B length are supported
*/
int
sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx,
struct sc_pkcs15_pubkey_eddsa *key,
const u8 *buf, size_t buflen)
{
int r;
u8 * pubkey = NULL;
size_t pubkey_len;
struct sc_asn1_entry asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE];
LOG_FUNC_CALLED(ctx);
sc_copy_asn1_entry(c_asn1_eddsa_pubkey, asn1_eddsa_pubkey);
sc_format_asn1_entry(asn1_eddsa_pubkey + 0, &pubkey, &pubkey_len, 1);
r = sc_asn1_decode(ctx, asn1_eddsa_pubkey, buf, buflen, NULL, NULL);
if (r < 0)
LOG_TEST_RET(ctx, r, "ASN.1 decoding failed");
key->pubkey.len = pubkey_len;
key->pubkey.value = pubkey;
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
int
sc_pkcs15_encode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_eddsa *key,
u8 **buf, size_t *buflen)
{
struct sc_asn1_entry asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE];
LOG_FUNC_CALLED(ctx);
sc_copy_asn1_entry(c_asn1_eddsa_pubkey, asn1_eddsa_pubkey);
sc_format_asn1_entry(asn1_eddsa_pubkey + 0, key->pubkey.value, &key->pubkey.len, 1);
LOG_FUNC_RETURN(ctx,
sc_asn1_encode(ctx, asn1_eddsa_pubkey, buf, buflen));
}
int
sc_pkcs15_encode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key,
@ -780,6 +827,9 @@ sc_pkcs15_encode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key,
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);
if (key->algorithm == SC_ALGORITHM_EDDSA ||
key->algorithm == SC_ALGORITHM_XEDDSA) /* XXX encoding is the same here */
return sc_pkcs15_encode_pubkey_eddsa(ctx, &key->u.eddsa, buf, len);
sc_log(ctx, "Encoding of public key type %u not supported", key->algorithm);
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
@ -897,6 +947,9 @@ sc_pkcs15_decode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key,
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);
if (key->algorithm == SC_ALGORITHM_EDDSA ||
key->algorithm == SC_ALGORITHM_XEDDSA)
return sc_pkcs15_decode_pubkey_eddsa(ctx, &key->u.eddsa, buf, len);
sc_log(ctx, "Decoding of public key type %u not supported", key->algorithm);
return SC_ERROR_NOT_SUPPORTED;
@ -939,6 +992,12 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_obj
case SC_PKCS15_TYPE_PUBKEY_EC:
algorithm = SC_ALGORITHM_EC;
break;
case SC_PKCS15_TYPE_PUBKEY_EDDSA:
algorithm = SC_ALGORITHM_EDDSA;
break;
case SC_PKCS15_TYPE_PUBKEY_XEDDSA:
algorithm = SC_ALGORITHM_XEDDSA;
break;
default:
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported public key type.");
}
@ -984,7 +1043,8 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_obj
r = sc_pkcs15_read_file(p15card, &info->path, &data, &len);
LOG_TEST_GOTO_ERR(ctx, r, "Failed to read public key file.");
if (algorithm == SC_ALGORITHM_EC && *data == (SC_ASN1_TAG_SEQUENCE | SC_ASN1_TAG_CONSTRUCTED))
if ((algorithm == SC_ALGORITHM_EC || algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA)
&& *data == (SC_ASN1_TAG_SEQUENCE | SC_ASN1_TAG_CONSTRUCTED))
r = sc_pkcs15_pubkey_from_spki_sequence(ctx, data, len, &pubkey);
else
r = sc_pkcs15_decode_pubkey(ctx, pubkey, data, len);
@ -1067,6 +1127,22 @@ sc_pkcs15_pubkey_from_prvkey(struct sc_context *ctx, struct sc_pkcs15_prkey *prv
}
memcpy(pubkey->u.ec.ecpointQ.value, prvkey->u.ec.ecpointQ.value, prvkey->u.ec.ecpointQ.len);
pubkey->u.ec.ecpointQ.len = prvkey->u.ec.ecpointQ.len;
break;
case SC_ALGORITHM_EDDSA:
case SC_ALGORITHM_XEDDSA:
/* Copy pubkey */
if (prvkey->u.eddsa.pubkey.value == NULL || prvkey->u.eddsa.pubkey.len <= 0) {
sc_pkcs15_free_pubkey(pubkey);
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
}
pubkey->u.eddsa.pubkey.value = malloc(prvkey->u.eddsa.pubkey.len);
if (!pubkey->u.eddsa.pubkey.value) {
sc_pkcs15_free_pubkey(pubkey);
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
}
memcpy(pubkey->u.eddsa.pubkey.value, prvkey->u.eddsa.pubkey.value, prvkey->u.eddsa.pubkey.len);
pubkey->u.eddsa.pubkey.len = prvkey->u.eddsa.pubkey.len;
break;
default:
sc_log(ctx, "Unsupported private key algorithm");
@ -1160,6 +1236,18 @@ sc_pkcs15_dup_pubkey(struct sc_context *ctx, struct sc_pkcs15_pubkey *key, struc
rv = SC_ERROR_NOT_SUPPORTED;
}
break;
case SC_ALGORITHM_EDDSA:
case SC_ALGORITHM_XEDDSA:
/* Copy pubkey */
pubkey->u.eddsa.pubkey.value = malloc(key->u.eddsa.pubkey.len);
if (!pubkey->u.eddsa.pubkey.value) {
rv = SC_ERROR_OUT_OF_MEMORY;
break;
}
memcpy(pubkey->u.eddsa.pubkey.value, key->u.eddsa.pubkey.value, key->u.eddsa.pubkey.len);
pubkey->u.eddsa.pubkey.len = key->u.eddsa.pubkey.len;
break;
default:
sc_log(ctx, "Unsupported private key algorithm");
@ -1215,6 +1303,12 @@ sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *key)
if (key->u.ec.ecpointQ.value)
free(key->u.ec.ecpointQ.value);
break;
case SC_ALGORITHM_EDDSA:
case SC_ALGORITHM_XEDDSA:
free(key->u.eddsa.pubkey.value);
key->u.eddsa.pubkey.value = NULL;
key->u.eddsa.pubkey.len = 0;
break;
}
sc_mem_clear(key, sizeof(*key));
}
@ -1413,8 +1507,7 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke
}
memcpy(pubkey->u.ec.ecpointQ.value, pk.value, pk.len);
pubkey->u.ec.ecpointQ.len = pk.len;
}
else {
} else {
/* Public key is expected to be encapsulated into BIT STRING */
r = sc_pkcs15_decode_pubkey(ctx, pubkey, pk.value, pk.len);
LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 parsing of subjectPubkeyInfo failed");
@ -1517,7 +1610,11 @@ static struct ec_curve_info {
{"secp192k1", "1.3.132.0.31", "06052B8104001F", 192},
{"secp256k1", "1.3.132.0.10", "06052B8104000A", 256},
{NULL, NULL, NULL, 0},
{"ed25519", "1.3.6.1.4.1.11591.15.1", "06092B06010401DA470F01", 255},
{"curve25519", "1.3.6.1.4.1.3029.1.5.1", "060A2B060104019755010501", 255},
{NULL, NULL, NULL, 0}, /* Do not touch this */
};
@ -1715,6 +1812,12 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key)
break;
}
#endif /* !defined(OPENSSL_NO_EC) */
#ifdef EVP_PKEY_ED25519
case EVP_PKEY_ED25519: {
/* TODO */
break;
}
#endif /* EVP_PKEY_ED25519 */
default:
return SC_ERROR_NOT_SUPPORTED;
}

View File

@ -213,6 +213,28 @@ static int format_senv(struct sc_pkcs15_card *p15card,
senv_out->algorithm = SC_ALGORITHM_GOSTR3410;
break;
case SC_PKCS15_TYPE_PRKEY_EDDSA:
*alg_info_out = sc_card_find_eddsa_alg(p15card->card, prkey->field_length, NULL);
if (*alg_info_out == NULL) {
sc_log(ctx,
"Card does not support EDDSA with field_size %"SC_FORMAT_LEN_SIZE_T"u",
prkey->field_length);
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
}
senv_out->algorithm = SC_ALGORITHM_EDDSA;
break;
case SC_PKCS15_TYPE_PRKEY_XEDDSA:
*alg_info_out = sc_card_find_xeddsa_alg(p15card->card, prkey->field_length, NULL);
if (*alg_info_out == NULL) {
sc_log(ctx,
"Card does not support XEDDSA with field_size %"SC_FORMAT_LEN_SIZE_T"u",
prkey->field_length);
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
}
senv_out->algorithm = SC_ALGORITHM_XEDDSA;
break;
case SC_PKCS15_TYPE_PRKEY_EC:
*alg_info_out = sc_card_find_ec_alg(p15card->card, prkey->field_length, NULL);
if (*alg_info_out == NULL) {
@ -320,6 +342,7 @@ int sc_pkcs15_derive(struct sc_pkcs15_card *p15card,
switch (obj->type) {
case SC_PKCS15_TYPE_PRKEY_EC:
case SC_PKCS15_TYPE_PRKEY_XEDDSA:
if (out == NULL || *poutlen < (prkey->field_length + 7) / 8) {
*poutlen = (prkey->field_length + 7) / 8;
r = 0; /* say no data to return */
@ -580,7 +603,9 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
modlen = (prkey->modulus_length + 7) / 8 * 2;
break;
case SC_PKCS15_TYPE_PRKEY_EC:
modlen = ((prkey->field_length +7) / 8) * 2; /* 2*nLen */
case SC_PKCS15_TYPE_PRKEY_EDDSA:
case SC_PKCS15_TYPE_PRKEY_XEDDSA:
modlen = ((prkey->field_length +7) / 8) * 2; /* 2*nLen */
break;
default:
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key type not supported");

View File

@ -364,6 +364,7 @@ int sc_pkcs15emu_add_ec_prkey(sc_pkcs15_card_t *p15card,
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)
{
@ -375,6 +376,56 @@ int sc_pkcs15emu_add_ec_pubkey(sc_pkcs15_card_t *p15card,
return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_EC, obj, &key);
}
int sc_pkcs15emu_add_eddsa_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_EDDSA, obj, &key);
}
int sc_pkcs15emu_add_eddsa_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_EDDSA, obj, &key);
}
int sc_pkcs15emu_add_xeddsa_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_XEDDSA, obj, &key);
}
int sc_pkcs15emu_add_xeddsa_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_XEDDSA, 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

@ -221,12 +221,21 @@ struct sc_pkcs15_pubkey_ec {
struct sc_pkcs15_u8 ecpointQ; /* This is NOT DER, just value and length */
};
struct sc_pkcs15_pubkey_eddsa {
struct sc_pkcs15_u8 pubkey;
};
struct sc_pkcs15_prkey_ec {
struct sc_ec_parameters params;
sc_pkcs15_bignum_t privateD; /* note this is bignum */
struct sc_pkcs15_u8 ecpointQ; /* This is NOT DER, just value and length */
};
struct sc_pkcs15_prkey_eddsa {
struct sc_pkcs15_u8 pubkey;
struct sc_pkcs15_u8 value;
};
struct sc_pkcs15_pubkey_gostr3410 {
struct sc_pkcs15_gost_parameters params;
sc_pkcs15_bignum_t xy;
@ -246,6 +255,7 @@ struct sc_pkcs15_pubkey {
struct sc_pkcs15_pubkey_rsa rsa;
struct sc_pkcs15_pubkey_dsa dsa;
struct sc_pkcs15_pubkey_ec ec;
struct sc_pkcs15_pubkey_eddsa eddsa;
struct sc_pkcs15_pubkey_gostr3410 gostr3410;
} u;
};
@ -259,6 +269,7 @@ struct sc_pkcs15_prkey {
struct sc_pkcs15_prkey_rsa rsa;
struct sc_pkcs15_prkey_dsa dsa;
struct sc_pkcs15_prkey_ec ec;
struct sc_pkcs15_prkey_eddsa eddsa;
struct sc_pkcs15_prkey_gostr3410 gostr3410;
struct sc_pkcs15_skey secret;
} u;
@ -440,12 +451,16 @@ typedef struct sc_pkcs15_skey_info sc_pkcs15_skey_info_t;
#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_PRKEY_EDDSA 0x105
#define SC_PKCS15_TYPE_PRKEY_XEDDSA 0x106
#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_PUBKEY_EDDSA 0x205
#define SC_PKCS15_TYPE_PUBKEY_XEDDSA 0x206
#define SC_PKCS15_TYPE_SKEY 0x300
#define SC_PKCS15_TYPE_SKEY_GENERIC 0x301
@ -705,6 +720,8 @@ 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_encode_pubkey_eddsa(struct sc_context *,
struct sc_pkcs15_pubkey_eddsa *, 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 *,
@ -1014,6 +1031,14 @@ int sc_pkcs15emu_add_ec_prkey(struct sc_pkcs15_card *,
const struct sc_pkcs15_object *, const sc_pkcs15_prkey_info_t *);
int sc_pkcs15emu_add_ec_pubkey(struct sc_pkcs15_card *,
const struct sc_pkcs15_object *, const sc_pkcs15_pubkey_info_t *);
int sc_pkcs15emu_add_eddsa_prkey(struct sc_pkcs15_card *,
const struct sc_pkcs15_object *, const sc_pkcs15_prkey_info_t *);
int sc_pkcs15emu_add_eddsa_pubkey(struct sc_pkcs15_card *,
const struct sc_pkcs15_object *, const sc_pkcs15_pubkey_info_t *);
int sc_pkcs15emu_add_xeddsa_prkey(struct sc_pkcs15_card *,
const struct sc_pkcs15_object *, const sc_pkcs15_prkey_info_t *);
int sc_pkcs15emu_add_xeddsa_pubkey(struct sc_pkcs15_card *,
const struct sc_pkcs15_object *, const sc_pkcs15_pubkey_info_t *);
int sc_pkcs15emu_add_x509_cert(struct sc_pkcs15_card *,
const struct sc_pkcs15_object *, const sc_pkcs15_cert_info_t *);
int sc_pkcs15emu_add_data_object(struct sc_pkcs15_card *,

View File

@ -79,6 +79,8 @@ static struct fmap map_CKA_KEY_TYPE[] = {
_(CKK_DH),
_(CKK_ECDSA),
_(CKK_EC),
_(CKK_EC_EDWARDS),
_(CKK_EC_MONTGOMERY),
_(CKK_RC2),
_(CKK_RC4),
_(CKK_RC5),

View File

@ -1066,6 +1066,8 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot, struct pkcs15_any_object *obj,
case SC_PKCS15_TYPE_PRKEY_RSA:
case SC_PKCS15_TYPE_PRKEY_GOSTR3410:
case SC_PKCS15_TYPE_PRKEY_EC:
case SC_PKCS15_TYPE_PRKEY_EDDSA:
case SC_PKCS15_TYPE_PRKEY_XEDDSA:
if (slot->p11card != NULL) {
pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL);
if (!slot->p11card)
@ -1256,6 +1258,26 @@ _pkcs15_create_typed_objects(struct pkcs15_fw_data *fw_data)
if (rv < 0)
return rv;
rv = pkcs15_create_pkcs11_objects(fw_data, SC_PKCS15_TYPE_PRKEY_EDDSA, "EdDSA private key",
__pkcs15_create_prkey_object);
if (rv < 0)
return rv;
rv = pkcs15_create_pkcs11_objects(fw_data, SC_PKCS15_TYPE_PUBKEY_EDDSA, "EdDSA public key",
__pkcs15_create_pubkey_object);
if (rv < 0)
return rv;
rv = pkcs15_create_pkcs11_objects(fw_data, SC_PKCS15_TYPE_PRKEY_XEDDSA, "XEdDSA private key",
__pkcs15_create_prkey_object);
if (rv < 0)
return rv;
rv = pkcs15_create_pkcs11_objects(fw_data, SC_PKCS15_TYPE_PUBKEY_XEDDSA, "XEdDSA public key",
__pkcs15_create_pubkey_object);
if (rv < 0)
return rv;
rv = pkcs15_create_pkcs11_objects(fw_data, SC_PKCS15_TYPE_PRKEY_GOSTR3410, "GOSTR3410 private key",
__pkcs15_create_prkey_object);
if (rv < 0)
@ -2206,6 +2228,14 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil
args.key.algorithm = SC_ALGORITHM_GOSTR3410;
gost = &args.key.u.gostr3410;
break;
case CKK_EC_EDWARDS:
args.key.algorithm = SC_ALGORITHM_EDDSA;
/* TODO */
return CKR_ATTRIBUTE_VALUE_INVALID;
case CKK_EC_MONTGOMERY:
args.key.algorithm = SC_ALGORITHM_XEDDSA;
/* TODO */
return CKR_ATTRIBUTE_VALUE_INVALID;
case CKK_EC:
args.key.algorithm = SC_ALGORITHM_EC;
/* TODO: -DEE Do not have PKCS15 card with EC to test this */
@ -2550,6 +2580,8 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile
rsa = &args.key.u.rsa;
break;
case CKK_EC:
case CKK_EC_EDWARDS:
case CKK_EC_MONTGOMERY:
/* TODO: -DEE Do not have real pkcs15 card with EC */
/* fall through */
default:
@ -3075,7 +3107,9 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism,
if (pMechanism->mechanism != CKM_RSA_PKCS_KEY_PAIR_GEN
&& pMechanism->mechanism != CKM_GOSTR3410_KEY_PAIR_GEN
&& pMechanism->mechanism != CKM_EC_KEY_PAIR_GEN)
&& pMechanism->mechanism != CKM_EC_KEY_PAIR_GEN
&& pMechanism->mechanism != CKM_EC_EDWARDS_KEY_PAIR_GEN
&& pMechanism->mechanism != CKM_EC_MONTGOMERY_KEY_PAIR_GEN)
return CKR_MECHANISM_INVALID;
if (!p11card)
@ -3119,6 +3153,10 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism,
keytype = CKK_RSA;
else if (rv != CKR_OK && pMechanism->mechanism == CKM_EC_KEY_PAIR_GEN)
keytype = CKK_EC;
else if (rv != CKR_OK && pMechanism->mechanism == CKM_EC_EDWARDS_KEY_PAIR_GEN)
keytype = CKK_EC_EDWARDS;
else if (rv != CKR_OK && pMechanism->mechanism == CKM_EC_MONTGOMERY_KEY_PAIR_GEN)
keytype = CKK_EC_MONTGOMERY;
else if (rv != CKR_OK && pMechanism->mechanism == CKM_GOSTR3410_KEY_PAIR_GEN)
keytype = CKK_GOSTR3410;
else if (rv != CKR_OK)
@ -3150,12 +3188,30 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism,
rv = attr_find_and_allocate_ptr(pPubTpl, ulPubCnt, CKA_EC_PARAMS, (void **)&der->value, &der->len);
if (rv != CKR_OK) {
sc_unlock(p11card->card);
return sc_to_cryptoki_error(rc, "C_GenerateKeyPair");
return sc_to_cryptoki_error(rv, "C_GenerateKeyPair");
}
keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_EC;
pub_args.key.algorithm = SC_ALGORITHM_EC;
}
else if (keytype == CKK_EC_EDWARDS) {
/* TODO Validate EC_PARAMS contains curveName "edwards25519" or "edwards448" (from RFC 8032)
* or id-Ed25519 or id-Ed448 (or equivalent OIDs in oId field) (from RFC 8410)
* otherwise return CKR_CURVE_NOT_SUPPORTED
*/
keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_EDDSA;
pub_args.key.algorithm = SC_ALGORITHM_EDDSA;
return CKR_CURVE_NOT_SUPPORTED;
}
else if (keytype == CKK_EC_MONTGOMERY) {
/* TODO Validate EC_PARAMS contains curveName "curve25519" or "curve448" (from RFC 7748)
* or id-X25519 or id-X448 (or equivalent OIDs in oId field) (from RFC 8410)
* otherwise return CKR_CURVE_NOT_SUPPORTED
*/
keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_XEDDSA;
pub_args.key.algorithm = SC_ALGORITHM_XEDDSA;
return CKR_CURVE_NOT_SUPPORTED;
}
else {
/* CKA_KEY_TYPE is set, but keytype isn't correct */
rv = CKR_ATTRIBUTE_VALUE_INVALID;
@ -3768,7 +3824,7 @@ pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session,
*/
if ((attr->type == CKA_MODULUS) || (attr->type == CKA_PUBLIC_EXPONENT) ||
((attr->type == CKA_MODULUS_BITS) && (prkey->prv_p15obj->type == SC_PKCS15_TYPE_PRKEY_EC)) ||
(attr->type == CKA_ECDSA_PARAMS)) {
(attr->type == CKA_EC_PARAMS)) {
/* First see if we have an associated public key */
if (prkey->pub_data) {
key = prkey->pub_data;
@ -3866,6 +3922,12 @@ pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session,
case SC_PKCS15_TYPE_PRKEY_GOSTR3410:
*(CK_KEY_TYPE*)attr->pValue = CKK_GOSTR3410;
break;
case SC_PKCS15_TYPE_PRKEY_EDDSA:
*(CK_KEY_TYPE*)attr->pValue = CKK_EC_EDWARDS;
break;
case SC_PKCS15_TYPE_PRKEY_XEDDSA:
*(CK_KEY_TYPE*)attr->pValue = CKK_EC_MONTGOMERY;
break;
case SC_PKCS15_TYPE_PRKEY_EC:
*(CK_KEY_TYPE*)attr->pValue = CKK_EC;
break;
@ -3897,6 +3959,11 @@ pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session,
case CKA_MODULUS_BITS:
check_attribute_buffer(attr, sizeof(CK_ULONG));
switch (prkey->prv_p15obj->type) {
case SC_PKCS15_TYPE_PRKEY_EDDSA:
case SC_PKCS15_TYPE_PRKEY_XEDDSA:
/* TODO where to get field length ? */
*(CK_ULONG *) attr->pValue = 255;
return CKR_OK;
case SC_PKCS15_TYPE_PRKEY_EC:
if (key) {
if (key->u.ec.params.field_length > 0)
@ -4113,6 +4180,12 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj,
case CKM_GOSTR3410_WITH_GOSTR3411:
flags = SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411;
break;
case CKM_EDDSA:
flags = SC_ALGORITHM_EDDSA_RAW;
break;
case CKM_XEDDSA:
flags = SC_ALGORITHM_XEDDSA_RAW;
break;
case CKM_ECDSA:
flags = SC_ALGORITHM_ECDSA_HASH_NONE;
break;
@ -4393,6 +4466,7 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj,
*/
switch (prkey->base.p15_object->type) {
case SC_PKCS15_TYPE_PRKEY_EC:
case SC_PKCS15_TYPE_PRKEY_XEDDSA:
{
CK_ECDH1_DERIVE_PARAMS * ecdh_params = (CK_ECDH1_DERIVE_PARAMS *) pParameters;
ulSeedDataLen = ecdh_params->ulPublicDataLen;
@ -4713,6 +4787,10 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_
/* even if we do not, we should not assume RSA */
if (pubkey->pub_data && pubkey->pub_data->algorithm == SC_ALGORITHM_GOSTR3410)
*(CK_KEY_TYPE*)attr->pValue = CKK_GOSTR3410;
else if (pubkey->pub_data && pubkey->pub_data->algorithm == SC_ALGORITHM_EDDSA)
*(CK_KEY_TYPE*)attr->pValue = CKK_EC_EDWARDS;
else if (pubkey->pub_data && pubkey->pub_data->algorithm == SC_ALGORITHM_XEDDSA)
*(CK_KEY_TYPE*)attr->pValue = CKK_EC_MONTGOMERY;
else if (pubkey->pub_data && pubkey->pub_data->algorithm == SC_ALGORITHM_EC)
*(CK_KEY_TYPE*)attr->pValue = CKK_EC;
else
@ -5463,6 +5541,8 @@ static CK_RV
get_ec_pubkey_params(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr)
{
struct sc_ec_parameters *ecp;
unsigned long expected_size = 0;
unsigned char *out = NULL;
if (key == NULL)
return CKR_ATTRIBUTE_TYPE_INVALID;
@ -5470,6 +5550,32 @@ get_ec_pubkey_params(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr)
return CKR_ATTRIBUTE_TYPE_INVALID;
switch (key->algorithm) {
case SC_ALGORITHM_EDDSA:
#define CURVE "edwards25519"
/* TODO key->alg_id->oid contains OID which we need to convert to curve name */
/* For now, using hardcoded curve names */
expected_size = strlen(CURVE) + 2;
check_attribute_buffer(attr, expected_size);
out = attr->pValue;
out[0] = 0x13; /* Tag PrintableString */
out[1] = strlen(CURVE);
memcpy(&out[2], CURVE, strlen(CURVE));
return CKR_OK;
#undef CURVE
case SC_ALGORITHM_XEDDSA:
#define CURVE "curve25519"
/* TODO key->alg_id->oid contains OID which we need to convert to curve name */
/* For now, using hardcoded curve names */
expected_size = strlen(CURVE) + 2;
check_attribute_buffer(attr, expected_size);
out = attr->pValue;
out[0] = 0x13; /* Tag PrintableString */
out[1] = strlen(CURVE);
memcpy(&out[2], CURVE, strlen(CURVE));
return CKR_OK;
#undef CURVE
case SC_ALGORITHM_EC:
/* TODO parms should not be in two places */
/* ec_params may be in key->alg_id or in key->u.ec */
@ -5501,6 +5607,28 @@ get_ec_pubkey_point(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr)
return CKR_ATTRIBUTE_TYPE_INVALID;
switch (key->algorithm) {
case SC_ALGORITHM_EDDSA:
case SC_ALGORITHM_XEDDSA:
rc = sc_pkcs15_encode_pubkey_eddsa(context, &key->u.eddsa, &value, &value_len);
if (rc != SC_SUCCESS)
return sc_to_cryptoki_error(rc, NULL);
if (attr->pValue == NULL_PTR) {
attr->ulValueLen = value_len;
free(value);
return CKR_OK;
}
if (attr->ulValueLen < value_len) {
attr->ulValueLen = value_len;
free(value);
return CKR_BUFFER_TOO_SMALL;
}
attr->ulValueLen = value_len;
memcpy(attr->pValue, value, value_len);
free(value);
return CKR_OK;
case SC_ALGORITHM_EC:
rc = sc_pkcs15_encode_pubkey_ec(context, &key->u.ec, &value, &value_len);
if (rc != SC_SUCCESS)
@ -5665,46 +5793,53 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags,
mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA, &mech_info, CKK_EC, NULL, NULL);
if (!mt)
return CKR_HOST_MEMORY;
rc = sc_pkcs11_register_mechanism(p11card, mt);
if (rc != CKR_OK)
return rc;
}
if (flags & SC_ALGORITHM_ECDSA_HASH_NONE) {
rc = sc_pkcs11_register_mechanism(p11card, mt);
if (rc != CKR_OK)
return rc;
}
#ifdef ENABLE_OPENSSL
/* if card supports RAW add sign_and_hash using RAW for mechs card does not support */
/* if card supports RAW add sign_and_hash using RAW for mechs card does not support */
if (flags & SC_ALGORITHM_ECDSA_RAW) {
if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA1)) {
rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_ECDSA_SHA1, CKM_SHA_1, mt);
if (rc != CKR_OK)
return rc;
}
if (flags & SC_ALGORITHM_ECDSA_RAW) {
if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA1)) {
rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card,
CKM_ECDSA_SHA1, CKM_SHA_1, mt);
if (rc != CKR_OK)
return rc;
}
if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA224)) {
rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_ECDSA_SHA224, CKM_SHA224, mt);
if (rc != CKR_OK)
return rc;
}
if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA224)) {
rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card,
CKM_ECDSA_SHA224, CKM_SHA224, mt);
if (rc != CKR_OK)
return rc;
}
if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA256)) {
rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_ECDSA_SHA256, CKM_SHA256, mt);
if (rc != CKR_OK)
return rc;
}
if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA256)) {
rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card,
CKM_ECDSA_SHA256, CKM_SHA256, mt);
if (rc != CKR_OK)
return rc;
}
if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA384)) {
rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_ECDSA_SHA384, CKM_SHA384, mt);
if (rc != CKR_OK)
return rc;
}
if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA384)) {
rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card,
CKM_ECDSA_SHA384, CKM_SHA384, mt);
if (rc != CKR_OK)
return rc;
}
if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA512)) {
rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_ECDSA_SHA512, CKM_SHA512, mt);
if (rc != CKR_OK)
return rc;
if (!(flags & SC_ALGORITHM_ECDSA_HASH_SHA512)) {
rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card,
CKM_ECDSA_SHA512, CKM_SHA512, mt);
if (rc != CKR_OK)
return rc;
}
}
}
#endif
}
if (flags & SC_ALGORITHM_ECDSA_HASH_SHA1) {
mt = sc_pkcs11_new_fw_mechanism(CKM_ECDSA_SHA1, &mech_info, CKK_EC, NULL, NULL);
@ -5753,7 +5888,7 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags,
/* ADD ECDH mechanisms */
/* The PIV uses curves where CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE produce the same results */
if(flags & SC_ALGORITHM_ECDH_CDH_RAW) {
if (flags & SC_ALGORITHM_ECDH_CDH_RAW) {
mech_info.flags &= ~(CKF_SIGN | CKF_VERIFY);
mech_info.flags |= CKF_DERIVE;
@ -5786,6 +5921,87 @@ static CK_RV register_ec_mechanisms(struct sc_pkcs11_card *p11card, int flags,
return CKR_OK;
}
static CK_RV register_eddsa_mechanisms(struct sc_pkcs11_card *p11card, int flags,
CK_ULONG min_key_size, CK_ULONG max_key_size)
{
CK_MECHANISM_INFO mech_info;
sc_pkcs11_mechanism_type_t *mt;
CK_RV rc;
mech_info.flags = CKF_HW | CKF_SIGN;
mech_info.ulMinKeySize = min_key_size;
mech_info.ulMaxKeySize = max_key_size;
if (flags & SC_ALGORITHM_EDDSA_RAW) {
mt = sc_pkcs11_new_fw_mechanism(CKM_EDDSA, &mech_info, CKK_EC_EDWARDS, NULL, NULL);
if (!mt)
return CKR_HOST_MEMORY;
rc = sc_pkcs11_register_mechanism(p11card, mt);
if (rc != CKR_OK)
return rc;
}
if (flags & SC_ALGORITHM_ONBOARD_KEY_GEN) {
mech_info.flags = CKF_HW | CKF_GENERATE_KEY_PAIR;
mt = sc_pkcs11_new_fw_mechanism(CKM_EC_EDWARDS_KEY_PAIR_GEN,
&mech_info, CKK_EC_EDWARDS, NULL, NULL);
if (!mt)
return CKR_HOST_MEMORY;
rc = sc_pkcs11_register_mechanism(p11card, mt);
if (rc != CKR_OK)
return rc;
}
return CKR_OK;
}
static CK_RV register_xeddsa_mechanisms(struct sc_pkcs11_card *p11card, int flags,
CK_ULONG min_key_size, CK_ULONG max_key_size)
{
CK_MECHANISM_INFO mech_info;
sc_pkcs11_mechanism_type_t *mt;
CK_RV rc;
mech_info.flags = CKF_HW | CKF_SIGN | CKF_DERIVE;
mech_info.ulMinKeySize = min_key_size;
mech_info.ulMaxKeySize = max_key_size;
if (flags & SC_ALGORITHM_XEDDSA_RAW) {
mt = sc_pkcs11_new_fw_mechanism(CKM_XEDDSA, &mech_info, CKK_EC_MONTGOMERY, NULL, NULL);
if (!mt)
return CKR_HOST_MEMORY;
rc = sc_pkcs11_register_mechanism(p11card, mt);
if (rc != CKR_OK)
return rc;
}
/* ADD ECDH mechanisms */
if (flags & SC_ALGORITHM_ECDH_CDH_RAW) {
mech_info.flags &= ~CKF_SIGN;
mech_info.flags |= CKF_DERIVE;
/* Montgomery curves derive function is defined only for CKM_ECDH1_DERIVE mechanism */
mt = sc_pkcs11_new_fw_mechanism(CKM_ECDH1_DERIVE, &mech_info, CKK_EC_MONTGOMERY, NULL, NULL);
if (!mt)
return CKR_HOST_MEMORY;
rc = sc_pkcs11_register_mechanism(p11card, mt);
if (rc != CKR_OK)
return rc;
}
if (flags & SC_ALGORITHM_ONBOARD_KEY_GEN) {
mech_info.flags = CKF_HW | CKF_GENERATE_KEY_PAIR;
mt = sc_pkcs11_new_fw_mechanism(CKM_EC_MONTGOMERY_KEY_PAIR_GEN, &mech_info, CKK_EC_MONTGOMERY, NULL, NULL);
if (!mt)
return CKR_HOST_MEMORY;
rc = sc_pkcs11_register_mechanism(p11card, mt);
if (rc != CKR_OK)
return rc;
}
return CKR_OK;
}
static int sc_pkcs11_register_aes_mechanisms(struct sc_pkcs11_card *p11card, int flags,
CK_ULONG min_key_size, CK_ULONG max_key_size)
{
@ -5843,8 +6059,8 @@ register_mechanisms(struct sc_pkcs11_card *p11card)
unsigned long ec_ext_flags;
sc_pkcs11_mechanism_type_t *mt;
unsigned int num;
int rsa_flags = 0, ec_flags = 0, gostr_flags = 0, aes_flags = 0;
int ec_found;
int rsa_flags = 0, ec_flags = 0, eddsa_flags = 0, xeddsa_flags = 0;
int ec_found = 0, gostr_flags = 0, aes_flags = 0;
CK_RV rc;
/* Register generic mechanisms */
@ -5864,7 +6080,6 @@ register_mechanisms(struct sc_pkcs11_card *p11card)
mech_info.ulMaxKeySize = 0;
ec_min_key_size = ~0;
ec_max_key_size = 0;
ec_found = 0;
aes_min_key_size = ~0;
aes_max_key_size = 0;
@ -5893,6 +6108,12 @@ register_mechanisms(struct sc_pkcs11_card *p11card)
ec_ext_flags |= alg_info->u._ec.ext_flags;
ec_found = 1;
break;
case SC_ALGORITHM_EDDSA:
eddsa_flags |= alg_info->flags;
break;
case SC_ALGORITHM_XEDDSA:
xeddsa_flags |= alg_info->flags;
break;
case SC_ALGORITHM_GOSTR3410:
gostr_flags |= alg_info->flags;
break;
@ -5918,6 +6139,18 @@ register_mechanisms(struct sc_pkcs11_card *p11card)
return rc;
}
if (eddsa_flags & SC_ALGORITHM_EDDSA_RAW) {
rc = register_eddsa_mechanisms(p11card, eddsa_flags, 255, 255);
if (rc != CKR_OK)
return rc;
}
if (xeddsa_flags & (SC_ALGORITHM_XEDDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW)) {
rc = register_xeddsa_mechanisms(p11card, xeddsa_flags, 255, 255);
if (rc != CKR_OK)
return rc;
}
if (gostr_flags & (SC_ALGORITHM_GOSTR3410_RAW
| SC_ALGORITHM_GOSTR3410_HASH_NONE
| SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411)) {

View File

@ -504,9 +504,12 @@ sc_pkcs11_signature_size(sc_pkcs11_operation_t *operation, CK_ULONG_PTR pLength)
*pLength = (*pLength + 7) / 8;
break;
case CKK_EC:
case CKK_EC_EDWARDS:
case CKK_EC_MONTGOMERY:
/* TODO: -DEE we should use something other then CKA_MODULUS_BITS... */
rv = key->ops->get_attribute(operation->session, key, &attr);
*pLength = ((*pLength + 7)/8) * 2 ; /* 2*nLen in bytes */
if (rv == CKR_OK)
*pLength = ((*pLength + 7)/8) * 2 ; /* 2*nLen in bytes */
break;
case CKK_GOSTR3410:
rv = key->ops->get_attribute(operation->session, key, &attr);

View File

@ -279,6 +279,8 @@ static enum_specs ck_key_s[] = {
{ CKK_DSA , "CKK_DSA " },
{ CKK_DH , "CKK_DH " },
{ CKK_EC , "CKK_EC " },
{ CKK_EC_EDWARDS , "CKK_EC_EDWARDS " },
{ CKK_EC_MONTGOMERY , "CKK_EC_MONTOGMERY " },
{ CKK_X9_42_DH , "CKK_X9_42_DH " },
{ CKK_KEA , "CKK_KEA " },
{ CKK_GENERIC_SECRET, "CKK_GENERIC_SECRET " },
@ -497,6 +499,8 @@ static enum_specs ck_mec_s[] = {
{ CKM_ECDH1_DERIVE , "CKM_ECDH1_DERIVE " },
{ CKM_ECDH1_COFACTOR_DERIVE , "CKM_ECDH1_COFACTOR_DERIVE " },
{ CKM_ECMQV_DERIVE , "CKM_ECMQV_DERIVE " },
{ CKM_EDDSA , "CKM_EDDSA " },
{ CKM_XEDDSA , "CKM_XEDDSA " },
{ CKM_JUNIPER_KEY_GEN , "CKM_JUNIPER_KEY_GEN " },
{ CKM_JUNIPER_ECB128 , "CKM_JUNIPER_ECB128 " },
{ CKM_JUNIPER_CBC128 , "CKM_JUNIPER_CBC128 " },
@ -753,8 +757,8 @@ type_spec ck_attribute_specs[] = {
{ CKA_ALWAYS_SENSITIVE , "CKA_ALWAYS_SENSITIVE ", print_boolean, NULL },
{ CKA_KEY_GEN_MECHANISM , "CKA_KEY_GEN_MECHANISM", print_boolean, NULL },
{ CKA_MODIFIABLE , "CKA_MODIFIABLE ", print_boolean, NULL },
{ CKA_ECDSA_PARAMS , "CKA_ECDSA_PARAMS ", print_generic, NULL },
{ CKA_EC_PARAMS , "CKA_EC_PARAMS ", print_generic, NULL },
{ CKA_ECDSA_PARAMS , "CKA_ECDSA_PARAMS ", print_generic, NULL },
{ CKA_EC_POINT , "CKA_EC_POINT ", print_generic, NULL },
{ CKA_SECONDARY_AUTH , "CKA_SECONDARY_AUTH ", print_generic, NULL },
{ CKA_AUTH_PIN_FLAGS , "CKA_AUTH_PIN_FLAGS ", print_generic, NULL },

View File

@ -1245,6 +1245,7 @@ CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession, /* the session's handle */
switch(key_type) {
case CKK_EC:
case CKK_EC_MONTGOMERY:
rv = sc_create_object_int(hSession, pTemplate, ulAttributeCount, phKey, 0);
if (rv != CKR_OK)

View File

@ -722,6 +722,8 @@ typedef unsigned long ck_mechanism_type_t;
#define CKM_ECDH1_DERIVE (0x1050UL)
#define CKM_ECDH1_COFACTOR_DERIVE (0x1051UL)
#define CKM_ECMQV_DERIVE (0x1052UL)
#define CKM_EC_EDWARDS_KEY_PAIR_GEN (0x1055UL)
#define CKM_EC_MONTGOMERY_KEY_PAIR_GEN (0x1056UL)
#define CKM_EDDSA (0x1057UL)
#define CKM_JUNIPER_KEY_GEN (0x1060UL)
#define CKM_JUNIPER_ECB128 (0x1061UL)
@ -1612,6 +1614,7 @@ struct ck_c_initialize_args
#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120UL)
#define CKR_RANDOM_NO_RNG (0x121UL)
#define CKR_DOMAIN_PARAMS_INVALID (0x130UL)
#define CKR_CURVE_NOT_SUPPORTED (0x140UL)
#define CKR_BUFFER_TOO_SMALL (0x150UL)
#define CKR_SAVED_STATE_INVALID (0x160UL)
#define CKR_INFORMATION_SENSITIVE (0x170UL)