38
38
#define PIV_ALGO_AES256 0x0c
39
39
#define PIV_ALGO_RSA1024 0x06
40
40
#define PIV_ALGO_RSA2048 0x07
41
+ #define PIV_ALGO_RSA3072 0x05
42
+ #define PIV_ALGO_RSA4096 0x16
41
43
#define PIV_ALGO_ECCP256 0x11
42
44
#define PIV_ALGO_ECCP384 0x14
43
45
#define PIV_ALGO_X25519 0xE1
@@ -1111,6 +1113,95 @@ static int cmd_attestation() {
1111
1113
return SW_OK ();
1112
1114
}
1113
1115
1116
+ static int cmd_import_asym () {
1117
+ uint8_t algo = P1 (apdu ), key_ref = P2 (apdu );
1118
+ if (key_ref != EF_PIV_KEY_AUTHENTICATION && key_ref != EF_PIV_KEY_SIGNATURE && key_ref != EF_PIV_KEY_KEYMGM && key_ref != EF_PIV_KEY_CARDAUTH && !(key_ref >= EF_PIV_KEY_RETIRED1 && key_ref <= EF_PIV_KEY_RETIRED20 )) {
1119
+ return SW_INCORRECT_P1P2 ();
1120
+ }
1121
+ asn1_ctx_t ctxi , aaa = {0 }, aab = {0 };
1122
+ asn1_ctx_init (apdu .data , (uint16_t )apdu .nc , & ctxi );
1123
+ asn1_find_tag (& ctxi , 0xAA , & aaa );
1124
+ asn1_find_tag (& ctxi , 0xAB , & aab );
1125
+ if (algo == PIV_ALGO_RSA1024 || algo == PIV_ALGO_RSA2048 || algo == PIV_ALGO_RSA3072 || algo == PIV_ALGO_RSA4096 ) {
1126
+ asn1_ctx_t a1 = { 0 }, a2 = { 0 };
1127
+ asn1_find_tag (& ctxi , 0x01 , & a1 );
1128
+ asn1_find_tag (& ctxi , 0x02 , & a2 );
1129
+ if (asn1_len (& a1 ) <= 0 || asn1_len (& a2 ) <= 0 ) {
1130
+ return SW_WRONG_DATA ();
1131
+ }
1132
+ mbedtls_rsa_context rsa ;
1133
+ mbedtls_rsa_init (& rsa );
1134
+ int r = mbedtls_mpi_read_binary (& rsa .P , a1 .data , a1 .len );
1135
+ if (r != 0 ) {
1136
+ mbedtls_rsa_free (& rsa );
1137
+ return SW_WRONG_DATA ();
1138
+ }
1139
+ r = mbedtls_mpi_read_binary (& rsa .Q , a2 .data , a2 .len );
1140
+ if (r != 0 ) {
1141
+ mbedtls_rsa_free (& rsa );
1142
+ return SW_WRONG_DATA ();
1143
+ }
1144
+ int exponent = 65537 ;
1145
+ mbedtls_mpi_lset (& rsa .E , exponent );
1146
+ r = mbedtls_rsa_import (& rsa , NULL , & rsa .P , & rsa .Q , NULL , & rsa .E );
1147
+ if (r != 0 ) {
1148
+ mbedtls_rsa_free (& rsa );
1149
+ return SW_EXEC_ERROR ();
1150
+ }
1151
+ r = mbedtls_rsa_complete (& rsa );
1152
+ if (r != 0 ) {
1153
+ mbedtls_rsa_free (& rsa );
1154
+ return SW_EXEC_ERROR ();
1155
+ }
1156
+ r = mbedtls_rsa_check_privkey (& rsa );
1157
+ if (r != 0 ) {
1158
+ mbedtls_rsa_free (& rsa );
1159
+ return SW_EXEC_ERROR ();
1160
+ }
1161
+ r = store_keys (& rsa , ALGO_RSA , key_ref , false);
1162
+ mbedtls_rsa_free (& rsa );
1163
+ if (r != 0 ) {
1164
+ return SW_EXEC_ERROR ();
1165
+ }
1166
+ }
1167
+ else if (algo == PIV_ALGO_ECCP256 || algo == PIV_ALGO_ECCP384 ) {
1168
+ asn1_ctx_t a6 = {0 };
1169
+ asn1_find_tag (& ctxi , 0x06 , & a6 );
1170
+ if (asn1_len (& a6 ) <= 0 ) {
1171
+ return SW_WRONG_DATA ();
1172
+ }
1173
+ mbedtls_ecp_group_id gid = algo == PIV_ALGO_ECCP256 ? MBEDTLS_ECP_DP_SECP256R1 : MBEDTLS_ECP_DP_SECP384R1 ;
1174
+ mbedtls_ecdsa_context ecdsa ;
1175
+ mbedtls_ecdsa_init (& ecdsa );
1176
+ int r = mbedtls_ecp_read_key (gid , & ecdsa , a6 .data , a6 .len );
1177
+ if (r != 0 ) {
1178
+ mbedtls_ecdsa_free (& ecdsa );
1179
+ return SW_EXEC_ERROR ();
1180
+ }
1181
+ r = mbedtls_ecp_mul (& ecdsa .grp , & ecdsa .Q , & ecdsa .d , & ecdsa .grp .G , random_gen , NULL );
1182
+ if (r != 0 ) {
1183
+ mbedtls_ecdsa_free (& ecdsa );
1184
+ return SW_EXEC_ERROR ();
1185
+ }
1186
+ r = mbedtls_ecp_check_pub_priv (& ecdsa , & ecdsa , random_gen , NULL );
1187
+ if (r != 0 ) {
1188
+ mbedtls_ecdsa_free (& ecdsa );
1189
+ return SW_EXEC_ERROR ();
1190
+ }
1191
+ r = store_keys (& ecdsa , ALGO_ECDSA , key_ref , false);
1192
+ mbedtls_ecdsa_free (& ecdsa );
1193
+ if (r != 0 ) {
1194
+ return SW_EXEC_ERROR ();
1195
+ }
1196
+ }
1197
+ else {
1198
+ return SW_WRONG_DATA ();
1199
+ }
1200
+ uint8_t meta [] = { algo , asn1_len (& aaa ) ? aaa .data [0 ] : PINPOLICY_ALWAYS , asn1_len (& aab ) ? aab .data [0 ] : TOUCHPOLICY_ALWAYS , ORIGIN_IMPORTED };
1201
+ meta_add (key_ref , meta , sizeof (meta ));
1202
+ return SW_OK ();
1203
+ }
1204
+
1114
1205
#define INS_VERIFY 0x20
1115
1206
#define INS_VERSION 0xFD
1116
1207
#define INS_SELECT 0xA4
@@ -1128,6 +1219,7 @@ static int cmd_attestation() {
1128
1219
#define INS_SET_RETRIES 0xFA
1129
1220
#define INS_RESET 0xFB
1130
1221
#define INS_ATTESTATION 0xF9
1222
+ #define INS_IMPORT_ASYM 0xFE
1131
1223
1132
1224
static const cmd_t cmds [] = {
1133
1225
{ INS_VERSION , cmd_version },
@@ -1146,6 +1238,7 @@ static const cmd_t cmds[] = {
1146
1238
{ INS_SET_RETRIES , cmd_set_retries },
1147
1239
{ INS_RESET , cmd_reset },
1148
1240
{ INS_ATTESTATION , cmd_attestation },
1241
+ { INS_IMPORT_ASYM , cmd_import_asym },
1149
1242
{ 0x00 , 0x0 }
1150
1243
};
1151
1244
0 commit comments