Moving signature calls outside.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2022-04-26 12:04:19 +02:00
parent b67a902eb6
commit 77842f23e7

View File

@@ -1058,6 +1058,86 @@ static int cmd_keypair_gen() {
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() {
uint16_t algo_fid = 0x0, pk_fid = 0x0;
if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) {
@@ -1091,30 +1171,12 @@ static int cmd_pso() {
if (r != CCID_OK)
return SW_EXEC_ERROR();
if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) {
mbedtls_md_type_t md = MBEDTLS_MD_NONE;
if (memcmp(apdu.cmd_apdu_data, "\x30\x51\x30\x0D\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00",17))
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);
size_t olen = 0;
r = rsa_sign(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, res_APDU, &olen);
mbedtls_rsa_free(&ctx);
if (r != 0) {
if (r != 0)
return SW_EXEC_ERROR();
}
res_APDU_size = key_size;
res_APDU_size = olen;
//apdu.expected_res_size = key_size;
}
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);
size_t olen = 0;
r = mbedtls_rsa_pkcs1_decrypt(&ctx, random_gen, NULL, &olen, apdu.cmd_apdu_data+1, res_APDU, key_size);
mbedtls_rsa_free(&ctx);
if (r != 0) {
mbedtls_rsa_free(&ctx);
return SW_EXEC_ERROR();
}
res_APDU_size = olen;
mbedtls_rsa_free(&ctx);
}
}
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) {
if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) {
mbedtls_ecdsa_context 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);
if (r != CCID_OK)
return SW_CONDITIONS_NOT_SATISFIED();
size_t olen = 0;
uint8_t buf[MBEDTLS_ECDSA_MAX_LEN];
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);
return SW_EXEC_ERROR();
}
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);
r = ecdsa_sign(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, res_APDU, &olen);
mbedtls_ecdsa_free(&ctx);
if (r != 0)
return SW_EXEC_ERROR();
res_APDU_size = olen;
}
else if (P1(apdu) == 0x80 && P2(apdu) == 0x86) {
mbedtls_ecdh_context ctx;
@@ -1261,104 +1298,31 @@ static int cmd_internal_aut() {
if (!ef)
return SW_FILE_NOT_FOUND();
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) {
mbedtls_rsa_context ctx;
mbedtls_rsa_init(&ctx);
r = load_private_key_rsa(&ctx, ef);
if (r != CCID_OK)
return SW_EXEC_ERROR();
uint8_t *d = apdu.cmd_apdu_data, *end = d+apdu.cmd_apdu_data_len, *hsh = NULL;
size_t seq_len = 0, hash_len = 0;
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);
return SW_EXEC_ERROR();
}
res_APDU_size = key_size;
apdu.expected_res_size = key_size;
size_t olen = 0;
r = rsa_sign(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, res_APDU, &olen);
mbedtls_rsa_free(&ctx);
if (r != 0)
return SW_EXEC_ERROR();
res_APDU_size = olen;
}
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) {
mbedtls_ecdsa_context 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);
if (r != CCID_OK)
return SW_CONDITIONS_NOT_SATISFIED();
size_t olen = 0;
uint8_t buf[MBEDTLS_ECDSA_MAX_LEN];
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);
return SW_EXEC_ERROR();
}
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);
r = ecdsa_sign(&ctx, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, res_APDU, &olen);
mbedtls_ecdsa_free(&ctx);
if (r != 0)
return SW_EXEC_ERROR();
res_APDU_size = olen;
}
return SW_OK();
}