Moving signature calls outside.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -1058,6 +1058,86 @@ static int cmd_keypair_gen() {
|
|||||||
return SW_INCORRECT_P1P2();
|
return SW_INCORRECT_P1P2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rsa_sign(mbedtls_rsa_context *ctx, const uint8_t *data, size_t data_len, uint8_t *out, size_t *out_len) {
|
||||||
|
uint8_t *d = (uint8_t *)data, *end = d+data_len, *hsh = NULL;
|
||||||
|
size_t seq_len = 0, hash_len = 0;
|
||||||
|
int key_size = ctx->len, r = 0;
|
||||||
|
mbedtls_md_type_t md = MBEDTLS_MD_SHA256;
|
||||||
|
if (mbedtls_asn1_get_tag(&d, end, &seq_len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) == 0) {
|
||||||
|
mbedtls_asn1_buf mdb;
|
||||||
|
r = mbedtls_asn1_get_alg_null(&d, end, &mdb);
|
||||||
|
if (r == 0) {
|
||||||
|
if (mbedtls_asn1_get_tag(&d, end, &hash_len, MBEDTLS_ASN1_OCTET_STRING) == 0) {
|
||||||
|
if (memcmp(mdb.p, "\x2B\x0E\x03\x02\x1A", 5) == 0)
|
||||||
|
md = MBEDTLS_MD_SHA1;
|
||||||
|
else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x04", 9) == 0)
|
||||||
|
md = MBEDTLS_MD_SHA224;
|
||||||
|
else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x01", 9) == 0)
|
||||||
|
md = MBEDTLS_MD_SHA256;
|
||||||
|
else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x02", 9) == 0)
|
||||||
|
md = MBEDTLS_MD_SHA384;
|
||||||
|
else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x03", 9) == 0)
|
||||||
|
md = MBEDTLS_MD_SHA512;
|
||||||
|
hsh = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (md == MBEDTLS_MD_NONE) {
|
||||||
|
if (data_len == 32)
|
||||||
|
md = MBEDTLS_MD_SHA256;
|
||||||
|
else if (data_len == 20)
|
||||||
|
md = MBEDTLS_MD_SHA1;
|
||||||
|
else if (data_len == 28)
|
||||||
|
md = MBEDTLS_MD_SHA224;
|
||||||
|
else if (data_len == 48)
|
||||||
|
md = MBEDTLS_MD_SHA384;
|
||||||
|
else if (data_len == 64)
|
||||||
|
md = MBEDTLS_MD_SHA512;
|
||||||
|
hash_len = data_len;
|
||||||
|
hsh = (uint8_t *)data;
|
||||||
|
}
|
||||||
|
if (md == MBEDTLS_MD_NONE) {
|
||||||
|
if (data_len < key_size) //needs padding
|
||||||
|
memset((uint8_t *)data+data_len, 0, key_size-data_len);
|
||||||
|
r = mbedtls_rsa_private(ctx, random_gen, NULL, data, out);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint8_t *signature = (uint8_t *)calloc(key_size, sizeof(uint8_t));
|
||||||
|
r = mbedtls_rsa_pkcs1_sign(ctx, random_gen, NULL, md, hash_len, hsh, signature);
|
||||||
|
memcpy(out, signature, key_size);
|
||||||
|
free(signature);
|
||||||
|
}
|
||||||
|
*out_len = key_size;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ecdsa_sign(mbedtls_ecdsa_context *ctx, const uint8_t *data, size_t data_len, uint8_t *out, size_t *out_len) {
|
||||||
|
mbedtls_md_type_t md = MBEDTLS_MD_SHA256;
|
||||||
|
if (data_len == 32)
|
||||||
|
md = MBEDTLS_MD_SHA256;
|
||||||
|
else if (data_len == 20)
|
||||||
|
md = MBEDTLS_MD_SHA1;
|
||||||
|
else if (data_len == 28)
|
||||||
|
md = MBEDTLS_MD_SHA224;
|
||||||
|
else if (data_len == 48)
|
||||||
|
md = MBEDTLS_MD_SHA384;
|
||||||
|
else if (data_len == 64)
|
||||||
|
md = MBEDTLS_MD_SHA512;
|
||||||
|
mbedtls_mpi ri, si;
|
||||||
|
mbedtls_mpi_init(&ri);
|
||||||
|
mbedtls_mpi_init(&si);
|
||||||
|
int r = mbedtls_ecdsa_sign(&ctx->grp, &ri, &si, &ctx->d, data, data_len, random_gen, NULL);
|
||||||
|
if (r == 0) {
|
||||||
|
mbedtls_mpi_write_binary(&ri, out, mbedtls_mpi_size(&ri));
|
||||||
|
*out_len = mbedtls_mpi_size(&ri);
|
||||||
|
mbedtls_mpi_write_binary(&si, out+*out_len, mbedtls_mpi_size(&si));
|
||||||
|
*out_len += mbedtls_mpi_size(&si);
|
||||||
|
}
|
||||||
|
mbedtls_mpi_free(&ri);
|
||||||
|
mbedtls_mpi_free(&si);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static int cmd_pso() {
|
static int cmd_pso() {
|
||||||
uint16_t algo_fid = 0x0, pk_fid = 0x0;
|
uint16_t algo_fid = 0x0, pk_fid = 0x0;
|
||||||
if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) {
|
if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) {
|
||||||
@@ -1091,30 +1171,12 @@ static int cmd_pso() {
|
|||||||
if (r != CCID_OK)
|
if (r != CCID_OK)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) {
|
if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) {
|
||||||
mbedtls_md_type_t md = MBEDTLS_MD_NONE;
|
size_t olen = 0;
|
||||||
if (memcmp(apdu.cmd_apdu_data, "\x30\x51\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00",17))
|
r = rsa_sign(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, res_APDU, &olen);
|
||||||
md = MBEDTLS_MD_SHA256;
|
|
||||||
else if (memcmp(apdu.cmd_apdu_data, "\x30\x51\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00",17))
|
|
||||||
md = MBEDTLS_MD_SHA384;
|
|
||||||
else if (memcmp(apdu.cmd_apdu_data, "\x30\x51\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00",17))
|
|
||||||
md = MBEDTLS_MD_SHA512;
|
|
||||||
uint8_t hash_len = apdu.cmd_apdu_data[18];
|
|
||||||
if (md == MBEDTLS_MD_SHA256 && hash_len != 32)
|
|
||||||
return SW_WRONG_DATA();
|
|
||||||
else if (md == MBEDTLS_MD_SHA384 && hash_len != 48)
|
|
||||||
return SW_WRONG_DATA();
|
|
||||||
else if (md == MBEDTLS_MD_SHA512 && hash_len != 64)
|
|
||||||
return SW_WRONG_DATA();
|
|
||||||
const uint8_t *hash = apdu.cmd_apdu_data+19;
|
|
||||||
uint8_t *signature = calloc( 1, ctx.len );
|
|
||||||
r = mbedtls_rsa_pkcs1_sign(&ctx, random_gen, NULL, md, hash_len, hash, signature);
|
|
||||||
memcpy(res_APDU, signature, key_size);
|
|
||||||
free(signature);
|
|
||||||
mbedtls_rsa_free(&ctx);
|
mbedtls_rsa_free(&ctx);
|
||||||
if (r != 0) {
|
if (r != 0)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
res_APDU_size = olen;
|
||||||
res_APDU_size = key_size;
|
|
||||||
//apdu.expected_res_size = key_size;
|
//apdu.expected_res_size = key_size;
|
||||||
}
|
}
|
||||||
else if (P1(apdu) == 0x80 && P2(apdu) == 0x86) {
|
else if (P1(apdu) == 0x80 && P2(apdu) == 0x86) {
|
||||||
@@ -1122,51 +1184,26 @@ static int cmd_pso() {
|
|||||||
memset(apdu.cmd_apdu_data+apdu.cmd_apdu_data_len, 0, key_size-apdu.cmd_apdu_data_len);
|
memset(apdu.cmd_apdu_data+apdu.cmd_apdu_data_len, 0, key_size-apdu.cmd_apdu_data_len);
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
r = mbedtls_rsa_pkcs1_decrypt(&ctx, random_gen, NULL, &olen, apdu.cmd_apdu_data+1, res_APDU, key_size);
|
r = mbedtls_rsa_pkcs1_decrypt(&ctx, random_gen, NULL, &olen, apdu.cmd_apdu_data+1, res_APDU, key_size);
|
||||||
if (r != 0) {
|
|
||||||
mbedtls_rsa_free(&ctx);
|
mbedtls_rsa_free(&ctx);
|
||||||
|
if (r != 0) {
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
res_APDU_size = olen;
|
res_APDU_size = olen;
|
||||||
mbedtls_rsa_free(&ctx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) {
|
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) {
|
||||||
if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) {
|
if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) {
|
||||||
mbedtls_ecdsa_context ctx;
|
mbedtls_ecdsa_context ctx;
|
||||||
mbedtls_ecdsa_init(&ctx);
|
mbedtls_ecdsa_init(&ctx);
|
||||||
mbedtls_md_type_t md = MBEDTLS_MD_SHA256;
|
|
||||||
if (apdu.cmd_apdu_data_len == 32)
|
|
||||||
md = MBEDTLS_MD_SHA256;
|
|
||||||
else if (apdu.cmd_apdu_data_len == 20)
|
|
||||||
md = MBEDTLS_MD_SHA1;
|
|
||||||
else if (apdu.cmd_apdu_data_len == 28)
|
|
||||||
md = MBEDTLS_MD_SHA224;
|
|
||||||
else if (apdu.cmd_apdu_data_len == 48)
|
|
||||||
md = MBEDTLS_MD_SHA384;
|
|
||||||
else if (apdu.cmd_apdu_data_len == 64)
|
|
||||||
md = MBEDTLS_MD_SHA512;
|
|
||||||
r = load_private_key_ecdsa(&ctx, ef);
|
r = load_private_key_ecdsa(&ctx, ef);
|
||||||
if (r != CCID_OK)
|
if (r != CCID_OK)
|
||||||
return SW_CONDITIONS_NOT_SATISFIED();
|
return SW_CONDITIONS_NOT_SATISFIED();
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
uint8_t buf[MBEDTLS_ECDSA_MAX_LEN];
|
r = ecdsa_sign(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, res_APDU, &olen);
|
||||||
mbedtls_mpi ri, si;
|
|
||||||
mbedtls_mpi_init(&ri);
|
|
||||||
mbedtls_mpi_init(&si);
|
|
||||||
r = mbedtls_ecdsa_sign(&ctx.grp, &ri, &si, &ctx.d, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, random_gen, NULL);
|
|
||||||
if (r != 0) {
|
|
||||||
mbedtls_mpi_free(&ri);
|
|
||||||
mbedtls_mpi_free(&si);
|
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecdsa_free(&ctx);
|
||||||
|
if (r != 0)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
res_APDU_size = olen;
|
||||||
mbedtls_mpi_write_binary(&ri, res_APDU, mbedtls_mpi_size(&ri));
|
|
||||||
res_APDU_size = mbedtls_mpi_size(&ri);
|
|
||||||
mbedtls_mpi_write_binary(&si, res_APDU+res_APDU_size, mbedtls_mpi_size(&si));
|
|
||||||
res_APDU_size += mbedtls_mpi_size(&si);
|
|
||||||
mbedtls_mpi_free(&ri);
|
|
||||||
mbedtls_mpi_free(&si);
|
|
||||||
mbedtls_ecdsa_free(&ctx);
|
|
||||||
}
|
}
|
||||||
else if (P1(apdu) == 0x80 && P2(apdu) == 0x86) {
|
else if (P1(apdu) == 0x80 && P2(apdu) == 0x86) {
|
||||||
mbedtls_ecdh_context ctx;
|
mbedtls_ecdh_context ctx;
|
||||||
@@ -1261,104 +1298,31 @@ static int cmd_internal_aut() {
|
|||||||
if (!ef)
|
if (!ef)
|
||||||
return SW_FILE_NOT_FOUND();
|
return SW_FILE_NOT_FOUND();
|
||||||
int r = CCID_OK;
|
int r = CCID_OK;
|
||||||
int key_size = file_read_uint16(ef->data);
|
|
||||||
mbedtls_md_type_t md = MBEDTLS_MD_NONE;
|
|
||||||
if (algo[0] == ALGO_RSA) {
|
if (algo[0] == ALGO_RSA) {
|
||||||
mbedtls_rsa_context ctx;
|
mbedtls_rsa_context ctx;
|
||||||
mbedtls_rsa_init(&ctx);
|
mbedtls_rsa_init(&ctx);
|
||||||
r = load_private_key_rsa(&ctx, ef);
|
r = load_private_key_rsa(&ctx, ef);
|
||||||
if (r != CCID_OK)
|
if (r != CCID_OK)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
uint8_t *d = apdu.cmd_apdu_data, *end = d+apdu.cmd_apdu_data_len, *hsh = NULL;
|
size_t olen = 0;
|
||||||
size_t seq_len = 0, hash_len = 0;
|
r = rsa_sign(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, res_APDU, &olen);
|
||||||
if (mbedtls_asn1_get_tag(&d, end, &seq_len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) == 0) {
|
|
||||||
mbedtls_asn1_buf mdb;
|
|
||||||
int r = mbedtls_asn1_get_alg_null(&d, end, &mdb);
|
|
||||||
if (r == 0) {
|
|
||||||
if (mbedtls_asn1_get_tag(&d, end, &hash_len, MBEDTLS_ASN1_OCTET_STRING) == 0) {
|
|
||||||
if (memcmp(mdb.p, "\x2B\x0E\x03\x02\x1A", 5) == 0)
|
|
||||||
md = MBEDTLS_MD_SHA1;
|
|
||||||
else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x04", 9) == 0)
|
|
||||||
md = MBEDTLS_MD_SHA224;
|
|
||||||
else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x01", 9) == 0)
|
|
||||||
md = MBEDTLS_MD_SHA256;
|
|
||||||
else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x02", 9) == 0)
|
|
||||||
md = MBEDTLS_MD_SHA384;
|
|
||||||
else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x03", 9) == 0)
|
|
||||||
md = MBEDTLS_MD_SHA512;
|
|
||||||
hsh = d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (md == MBEDTLS_MD_NONE) {
|
|
||||||
if (apdu.cmd_apdu_data_len == 32)
|
|
||||||
md = MBEDTLS_MD_SHA256;
|
|
||||||
else if (apdu.cmd_apdu_data_len == 20)
|
|
||||||
md = MBEDTLS_MD_SHA1;
|
|
||||||
else if (apdu.cmd_apdu_data_len == 28)
|
|
||||||
md = MBEDTLS_MD_SHA224;
|
|
||||||
else if (apdu.cmd_apdu_data_len == 48)
|
|
||||||
md = MBEDTLS_MD_SHA384;
|
|
||||||
else if (apdu.cmd_apdu_data_len == 64)
|
|
||||||
md = MBEDTLS_MD_SHA512;
|
|
||||||
hash_len = apdu.cmd_apdu_data_len;
|
|
||||||
hsh = apdu.cmd_apdu_data;
|
|
||||||
}
|
|
||||||
if (md == MBEDTLS_MD_NONE) {
|
|
||||||
if (apdu.cmd_apdu_data_len < key_size) //needs padding
|
|
||||||
memset(apdu.cmd_apdu_data+apdu.cmd_apdu_data_len, 0, key_size-apdu.cmd_apdu_data_len);
|
|
||||||
r = mbedtls_rsa_private(&ctx, random_gen, NULL, apdu.cmd_apdu_data, res_APDU);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
uint8_t *signature = (uint8_t *)calloc(key_size, sizeof(uint8_t));
|
|
||||||
r = mbedtls_rsa_pkcs1_sign(&ctx, random_gen, NULL, md, hash_len, hsh, signature);
|
|
||||||
memcpy(res_APDU, signature, key_size);
|
|
||||||
free(signature);
|
|
||||||
}
|
|
||||||
if (r != 0) {
|
|
||||||
mbedtls_rsa_free(&ctx);
|
mbedtls_rsa_free(&ctx);
|
||||||
|
if (r != 0)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
res_APDU_size = olen;
|
||||||
res_APDU_size = key_size;
|
|
||||||
apdu.expected_res_size = key_size;
|
|
||||||
mbedtls_rsa_free(&ctx);
|
|
||||||
}
|
}
|
||||||
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) {
|
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) {
|
||||||
mbedtls_ecdsa_context ctx;
|
mbedtls_ecdsa_context ctx;
|
||||||
mbedtls_ecdsa_init(&ctx);
|
mbedtls_ecdsa_init(&ctx);
|
||||||
md = MBEDTLS_MD_SHA256;
|
|
||||||
if (apdu.cmd_apdu_data_len == 32)
|
|
||||||
md = MBEDTLS_MD_SHA256;
|
|
||||||
else if (apdu.cmd_apdu_data_len == 20)
|
|
||||||
md = MBEDTLS_MD_SHA1;
|
|
||||||
else if (apdu.cmd_apdu_data_len == 28)
|
|
||||||
md = MBEDTLS_MD_SHA224;
|
|
||||||
else if (apdu.cmd_apdu_data_len == 48)
|
|
||||||
md = MBEDTLS_MD_SHA384;
|
|
||||||
else if (apdu.cmd_apdu_data_len == 64)
|
|
||||||
md = MBEDTLS_MD_SHA512;
|
|
||||||
r = load_private_key_ecdsa(&ctx, ef);
|
r = load_private_key_ecdsa(&ctx, ef);
|
||||||
if (r != CCID_OK)
|
if (r != CCID_OK)
|
||||||
return SW_CONDITIONS_NOT_SATISFIED();
|
return SW_CONDITIONS_NOT_SATISFIED();
|
||||||
size_t olen = 0;
|
size_t olen = 0;
|
||||||
uint8_t buf[MBEDTLS_ECDSA_MAX_LEN];
|
r = ecdsa_sign(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, res_APDU, &olen);
|
||||||
mbedtls_mpi ri, si;
|
|
||||||
mbedtls_mpi_init(&ri);
|
|
||||||
mbedtls_mpi_init(&si);
|
|
||||||
r = mbedtls_ecdsa_sign(&ctx.grp, &ri, &si, &ctx.d, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, random_gen, NULL);
|
|
||||||
if (r != 0) {
|
|
||||||
mbedtls_mpi_free(&ri);
|
|
||||||
mbedtls_mpi_free(&si);
|
|
||||||
mbedtls_ecdsa_free(&ctx);
|
mbedtls_ecdsa_free(&ctx);
|
||||||
|
if (r != 0)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
res_APDU_size = olen;
|
||||||
mbedtls_mpi_write_binary(&ri, res_APDU, mbedtls_mpi_size(&ri));
|
|
||||||
res_APDU_size = mbedtls_mpi_size(&ri);
|
|
||||||
mbedtls_mpi_write_binary(&si, res_APDU+res_APDU_size, mbedtls_mpi_size(&si));
|
|
||||||
res_APDU_size += mbedtls_mpi_size(&si);
|
|
||||||
mbedtls_mpi_free(&ri);
|
|
||||||
mbedtls_mpi_free(&si);
|
|
||||||
mbedtls_ecdsa_free(&ctx);
|
|
||||||
}
|
}
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user