3
3
* card-default.c: Support for cards with no driver
4
4
*
5
5
* Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
6
- * Copyright (C) 2005-2023 Douglas E. Engert <deengert@gmail.com>
6
+ * Copyright (C) 2005-2024 Douglas E. Engert <deengert@gmail.com>
7
7
* Copyright (C) 2006, Identity Alliance, Thomas Harning <thomas.harning@identityalliance.com>
8
8
* Copyright (C) 2007, EMC, Russell Larner <rlarner@rsa.com>
9
9
*
@@ -544,10 +544,13 @@ static const struct sc_atr_table piv_atrs[] = {
544
544
static struct piv_supported_ec_curves {
545
545
struct sc_object_id oid ;
546
546
size_t size ;
547
+ unsigned int key_type ;
547
548
} ec_curves [] = {
548
- {{{1 , 2 , 840 , 10045 , 3 , 1 , 7 , -1 }}, 256 }, /* secp256r1, nistp256, prime256v1, ansiX9p256r1 */
549
- {{{1 , 3 , 132 , 0 , 34 , -1 }}, 384 }, /* secp384r1, nistp384, prime384v1, ansiX9p384r1 */
550
- {{{-1 }}, 0 } /* This entry must not be touched. */
549
+ {{{1 , 2 , 840 , 10045 , 3 , 1 , 7 , -1 }}, 256 , SC_ALGORITHM_EC }, /* secp256r1, nistp256, prime256v1, ansiX9p256r1 */
550
+ {{{1 , 3 , 132 , 0 , 34 , -1 }}, 384 , SC_ALGORITHM_EC }, /* secp384r1, nistp384, prime384v1, ansiX9p384r1 */
551
+ {{{1 , 3 , 101 , 112 , -1 }}, 255 , SC_ALGORITHM_EDDSA }, /* RFC8410 OID equivalent to ed25519 */
552
+ {{{1 , 3 , 101 , 110 , -1 }}, 255 , SC_ALGORITHM_XEDDSA }, /* RFC8410 OID equivalent to curve25519 */
553
+ {{{-1 }}, 0 , 0 } /* This entry must not be touched. */
551
554
};
552
555
553
556
/* all have same AID */
@@ -573,6 +576,8 @@ static struct piv_aid piv_aids[] = {
573
576
#define CI_NO_RSA2048 0x00010000U /* does not have RSA 2048 */
574
577
#define CI_NO_EC384 0x00020000U /* does not have EC 384 */
575
578
#define CI_NO_EC 0x00040000U /* No EC at all */
579
+ #define CI_RSA_4096 0x00080000U /* Card supports rsa 4096 */
580
+ #define CI_25519 0x00100000U /* Card supports ED25519 and X25519 */
576
581
577
582
/*
578
583
* Flags in the piv_object:
@@ -2720,14 +2725,21 @@ static int piv_generate_key(sc_card_t *card,
2720
2725
case 0x05 : keydata -> key_bits = 3072 ; break ;
2721
2726
case 0x06 : keydata -> key_bits = 1024 ; break ;
2722
2727
case 0x07 : keydata -> key_bits = 2048 ; break ;
2728
+ case 0x16 : keydata -> key_bits = 4096 ; break ;
2723
2729
case 0x11 : keydata -> key_bits = 0 ;
2724
- keydata -> ecparam = 0 ; /* we only support prime256v1 for 11 */
2730
+ keydata -> ecparam = 0 ; /* we only support prime256v1 */
2725
2731
keydata -> ecparam_len = 0 ;
2726
2732
break ;
2727
2733
case 0x14 : keydata -> key_bits = 0 ;
2728
2734
keydata -> ecparam = 0 ; /* we only support secp384r1 */
2729
2735
keydata -> ecparam_len = 0 ;
2730
2736
break ;
2737
+ case 0xE0 :
2738
+ case 0xE1 :
2739
+ keydata -> key_bits = 0 ;
2740
+ keydata -> ecparam = 0 ;
2741
+ keydata -> ecparam_len = 0 ;
2742
+ break ;
2731
2743
default :
2732
2744
LOG_FUNC_RETURN (card -> ctx , SC_ERROR_INVALID_ARGUMENTS );
2733
2745
}
@@ -2780,8 +2792,11 @@ static int piv_generate_key(sc_card_t *card,
2780
2792
keydata -> pubkey_len = taglen ;
2781
2793
memcpy (keydata -> pubkey , tag , taglen );
2782
2794
}
2783
- }
2784
- else { /* must be EC */
2795
+ // } else if (keydata->key_algid == 0xE0 || keydata->key_algid == 0xE1) {
2796
+ // /* TODO DEE need to look at what gets returned */
2797
+ /* TODO assume same as EC with tag 86 */
2798
+
2799
+ } else { /* must be EC */
2785
2800
tag = sc_asn1_find_tag (card -> ctx , cp , in_len , 0x86 , & taglen );
2786
2801
if (tag != NULL && taglen > 0 ) {
2787
2802
keydata -> ecpoint = malloc (taglen );
@@ -2793,7 +2808,8 @@ static int piv_generate_key(sc_card_t *card,
2793
2808
}
2794
2809
2795
2810
/* TODO: -DEE Could add key to cache so could use engine to generate key,
2796
- * and sign req in single operation */
2811
+ * and sign req in single operation or write temporary selfsigned
2812
+ * certificate with new public key */
2797
2813
r = 0 ;
2798
2814
}
2799
2815
@@ -4512,6 +4528,12 @@ piv_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num)
4512
4528
}
4513
4529
} else
4514
4530
r = SC_ERROR_NO_CARD_SUPPORT ;
4531
+ } else if (env -> algorithm == SC_ALGORITHM_EDDSA ) {
4532
+ priv -> alg_id = 0xE0 ;
4533
+ priv -> key_size = 255 ;
4534
+ } else if (env -> algorithm == SC_ALGORITHM_XEDDSA ) {
4535
+ priv -> alg_id = 0xE1 ;
4536
+ priv -> key_size = 255 ;
4515
4537
} else
4516
4538
r = SC_ERROR_NO_CARD_SUPPORT ;
4517
4539
priv -> key_ref = env -> key_ref [0 ];
@@ -4541,6 +4563,7 @@ static int piv_validate_general_authentication(sc_card_t *card,
4541
4563
unsigned int cla , tag ;
4542
4564
unsigned int real_alg_id , op_tag ;
4543
4565
4566
+ /* TODO check for 4096 keys */
4544
4567
u8 sbuf [4096 ]; /* needs work. for 3072 keys, needs 384+10 or so */
4545
4568
size_t sbuflen = sizeof (sbuf );
4546
4569
u8 rbuf [4096 ];
@@ -4561,6 +4584,7 @@ static int piv_validate_general_authentication(sc_card_t *card,
4561
4584
}
4562
4585
if (priv -> operation == SC_SEC_OPERATION_DERIVE
4563
4586
&& priv -> algorithm == SC_ALGORITHM_EC ) {
4587
+ /* TODO add code for X25519 */
4564
4588
op_tag = 0x85 ;
4565
4589
} else {
4566
4590
op_tag = 0x81 ;
@@ -4583,11 +4607,12 @@ static int piv_validate_general_authentication(sc_card_t *card,
4583
4607
case 128 : real_alg_id = 0x06 ; break ;
4584
4608
case 256 : real_alg_id = 0x07 ; break ;
4585
4609
case 384 : real_alg_id = 0x05 ; break ;
4610
+ case 512 : real_alg_id = 0x16 ; break ;
4586
4611
default :
4587
4612
SC_FUNC_RETURN (card -> ctx , SC_LOG_DEBUG_VERBOSE , SC_ERROR_NO_CARD_SUPPORT );
4588
4613
}
4589
4614
}
4590
- /* EC alg_id was already set */
4615
+ /* EC and ED alg_id was already set */
4591
4616
4592
4617
r = piv_general_io (card , 0x87 , real_alg_id , priv -> key_ref ,
4593
4618
sbuf , p - sbuf , rbuf , sizeof rbuf );
@@ -4649,6 +4674,18 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen,
4649
4674
goto err ;
4650
4675
4651
4676
r = sc_asn1_decode_ecdsa_signature (card -> ctx , rbuf , r , nLen , & out , outlen );
4677
+ /* Yubikey 5.7.x supports ED25519 */
4678
+ } else if (priv -> alg_id == 0xE0 ) {
4679
+ nLen = (priv -> key_size + 7 ) / 8 ;
4680
+ if (outlen < nLen ) {
4681
+ sc_log (card -> ctx ,
4682
+ " output too small for ED signature %" SC_FORMAT_LEN_SIZE_T "u < %" SC_FORMAT_LEN_SIZE_T "u" ,
4683
+ outlen , nLen );
4684
+ r = SC_ERROR_INVALID_DATA ;
4685
+ goto err ;
4686
+ }
4687
+ r = piv_validate_general_authentication (card , data , datalen , out , outlen );
4688
+
4652
4689
} else { /* RSA is all set */
4653
4690
r = piv_validate_general_authentication (card , data , datalen , out , outlen );
4654
4691
}
@@ -5493,7 +5530,7 @@ static int piv_match_card_continued(sc_card_t *card)
5493
5530
apdu .resplen = sizeof (yubico_version_buf );
5494
5531
apdu .le = apdu .resplen ;
5495
5532
r2 = sc_transmit_apdu (card , & apdu ); /* on error yubico_version == 0 */
5496
- if (r2 > = 3 ) {
5533
+ if (apdu . resplen = = 3 ) {
5497
5534
priv -> yubico_version = (yubico_version_buf [0 ]<<16 ) | (yubico_version_buf [1 ] <<8 ) | yubico_version_buf [2 ];
5498
5535
sc_log (card -> ctx , "Yubico card->type=%d, r=0x%08x version=0x%08x" , card -> type , r , priv -> yubico_version );
5499
5536
}
@@ -5608,6 +5645,9 @@ static int piv_match_card_continued(sc_card_t *card)
5608
5645
| CI_LEAKS_FILE_NOT_FOUND ;
5609
5646
if (priv -> yubico_version < 0x00040302 )
5610
5647
priv -> card_issues |= CI_VERIFY_LC0_FAIL ;
5648
+ /* TODO may need to relocate when I get card to test */
5649
+ if (priv -> yubico_version >= 0x00050700 )
5650
+ priv -> card_issues |= CI_RSA_4096 | CI_25519 ;
5611
5651
break ;
5612
5652
5613
5653
case SC_CARD_TYPE_PIV_II_GI_DE :
@@ -5691,6 +5731,8 @@ static int piv_init(sc_card_t *card)
5691
5731
int r = 0 ;
5692
5732
piv_private_data_t * priv = PIV_DATA (card );
5693
5733
unsigned long flags ;
5734
+ unsigned long flags_eddsa ;
5735
+ unsigned long flags_xeddsa ;
5694
5736
unsigned long ext_flags ;
5695
5737
5696
5738
SC_FUNC_CALLED (card -> ctx , SC_LOG_DEBUG_VERBOSE );
@@ -5739,15 +5781,28 @@ static int piv_init(sc_card_t *card)
5739
5781
_sc_card_add_rsa_alg (card , 1024 , flags , 0 ); /* mandatory */
5740
5782
_sc_card_add_rsa_alg (card , 2048 , flags , 0 ); /* optional */
5741
5783
_sc_card_add_rsa_alg (card , 3072 , flags , 0 ); /* optional */
5784
+ if (priv -> card_issues & CI_RSA_4096 )
5785
+ _sc_card_add_rsa_alg (card , 4096 , flags , 0 ); /* some Yubikeys support this */
5742
5786
5743
5787
if (!(priv -> card_issues & CI_NO_EC )) {
5744
5788
int i ;
5745
5789
flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE ;
5746
5790
ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES ;
5791
+ flags_eddsa = SC_ALGORITHM_EDDSA_RAW ;
5792
+ flags_xeddsa = SC_ALGORITHM_XEDDSA_RAW ;
5747
5793
5748
5794
for (i = 0 ; ec_curves [i ].oid .value [0 ] >= 0 ; i ++ ) {
5749
- if (!(priv -> card_issues & CI_NO_EC384 && ec_curves [i ].size == 384 ))
5750
- _sc_card_add_ec_alg (card , ec_curves [i ].size , flags , ext_flags , & ec_curves [i ].oid );
5795
+ if (ec_curves [i ].key_type == SC_ALGORITHM_EC ) {
5796
+ if (!(priv -> card_issues & CI_NO_EC384 && ec_curves [i ].size == 384 ))
5797
+ _sc_card_add_ec_alg (card , ec_curves [i ].size , flags , ext_flags , & ec_curves [i ].oid );
5798
+
5799
+ } else if (priv -> card_issues & CI_25519 ) {
5800
+ if (ec_curves [i ].key_type == SC_ALGORITHM_EDDSA ) {
5801
+ _sc_card_add_eddsa_alg (card , ec_curves [i ].size , flags_eddsa , ext_flags , & ec_curves [i ].oid );
5802
+ } else if (ec_curves [i ].key_type == SC_ALGORITHM_XEDDSA ) {
5803
+ _sc_card_add_xeddsa_alg (card , ec_curves [i ].size , flags_xeddsa , ext_flags , & ec_curves [i ].oid );
5804
+ }
5805
+ }
5751
5806
}
5752
5807
}
5753
5808
0 commit comments