sc-hsm: Undo the change to mechanism.c in commit f24bcd346340d80b552c0859942a49fd5e8feeff
sc-hsm: Change ECDSA signature format from DER to r/s format
This commit is contained in:
parent
03632f336e
commit
dc927fbe3c
|
@ -60,7 +60,7 @@ static struct sc_atr_table sc_hsm_atrs[] = {
|
||||||
|
|
||||||
/* Information the driver maintains between calls */
|
/* Information the driver maintains between calls */
|
||||||
typedef struct sc_hsm_private_data {
|
typedef struct sc_hsm_private_data {
|
||||||
sc_security_env_t *env;
|
const sc_security_env_t *env;
|
||||||
u8 algorithm;
|
u8 algorithm;
|
||||||
} sc_hsm_private_data_t;
|
} sc_hsm_private_data_t;
|
||||||
|
|
||||||
|
@ -208,6 +208,67 @@ static int sc_hsm_set_security_env(sc_card_t *card,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int sc_hsm_decode_ecdsa_signature(sc_card_t *card,
|
||||||
|
const u8 * data, size_t datalen,
|
||||||
|
u8 * out, size_t outlen) {
|
||||||
|
|
||||||
|
int fieldsizebytes, i, r;
|
||||||
|
const u8 *body, *tag;
|
||||||
|
size_t bodylen, taglen;
|
||||||
|
|
||||||
|
// Determine field size from length of signature
|
||||||
|
if (datalen <= 58) { // 192 bit curve = 24 * 2 + 10 byte maximum DER signature
|
||||||
|
fieldsizebytes = 24;
|
||||||
|
} else if (datalen <= 66) { // 224 bit curve = 28 * 2 + 10 byte maximum DER signature
|
||||||
|
fieldsizebytes = 28;
|
||||||
|
} else if (datalen <= 74) { // 256 bit curve = 32 * 2 + 10 byte maximum DER signature
|
||||||
|
fieldsizebytes = 32;
|
||||||
|
} else if (datalen <= 110) { // 320 bit curve = 50 * 2 + 10 byte maximum DER signature
|
||||||
|
fieldsizebytes = 50;
|
||||||
|
} else {
|
||||||
|
fieldsizebytes = 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outlen < (fieldsizebytes * 2)) {
|
||||||
|
LOG_TEST_RETURN(card->ctx, SC_ERROR_INVALID_DATA, "output too small for EC signature");
|
||||||
|
}
|
||||||
|
memset(out, 0, outlen);
|
||||||
|
|
||||||
|
// Copied from card-piv.c. Thanks
|
||||||
|
body = sc_asn1_find_tag(card->ctx, data, datalen, 0x30, &bodylen);
|
||||||
|
|
||||||
|
for (i = 0; i<2; i++) {
|
||||||
|
if (body) {
|
||||||
|
tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x02, &taglen);
|
||||||
|
if (tag) {
|
||||||
|
bodylen -= taglen - (tag - body);
|
||||||
|
body = tag + taglen;
|
||||||
|
|
||||||
|
if (taglen > fieldsizebytes) { /* drop leading 00 if present */
|
||||||
|
if (*tag != 0x00) {
|
||||||
|
r = SC_ERROR_INVALID_DATA;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
tag++;
|
||||||
|
taglen--;
|
||||||
|
}
|
||||||
|
memcpy(out + fieldsizebytes*i + fieldsizebytes - taglen , tag, taglen);
|
||||||
|
} else {
|
||||||
|
r = SC_ERROR_INVALID_DATA;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r = SC_ERROR_INVALID_DATA;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r = 2 * fieldsizebytes;
|
||||||
|
err:
|
||||||
|
LOG_FUNC_RETURN(card->ctx, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int sc_hsm_compute_signature(sc_card_t *card,
|
static int sc_hsm_compute_signature(sc_card_t *card,
|
||||||
const u8 * data, size_t datalen,
|
const u8 * data, size_t datalen,
|
||||||
u8 * out, size_t outlen)
|
u8 * out, size_t outlen)
|
||||||
|
@ -237,9 +298,17 @@ static int sc_hsm_compute_signature(sc_card_t *card,
|
||||||
r = sc_transmit_apdu(card, &apdu);
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||||
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
|
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
|
||||||
size_t len = apdu.resplen > outlen ? outlen : apdu.resplen;
|
size_t len;
|
||||||
|
|
||||||
memcpy(out, apdu.resp, len);
|
if ((priv->algorithm & 0xF0) == ALGO_EC_RAW) {
|
||||||
|
len = sc_hsm_decode_ecdsa_signature(card, apdu.resp, apdu.resplen, out, outlen);
|
||||||
|
if (len < 0) {
|
||||||
|
LOG_FUNC_RETURN(card->ctx, len);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
len = apdu.resplen > outlen ? outlen : apdu.resplen;
|
||||||
|
memcpy(out, apdu.resp, len);
|
||||||
|
}
|
||||||
LOG_FUNC_RETURN(card->ctx, len);
|
LOG_FUNC_RETURN(card->ctx, len);
|
||||||
}
|
}
|
||||||
LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
|
LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
|
||||||
|
|
|
@ -472,7 +472,7 @@ sc_pkcs11_signature_size(sc_pkcs11_operation_t *operation, CK_ULONG_PTR pLength)
|
||||||
case CKK_EC:
|
case CKK_EC:
|
||||||
/* TODO: -DEE we should use something other then CKA_MODULUS_BITS... */
|
/* TODO: -DEE we should use something other then CKA_MODULUS_BITS... */
|
||||||
rv = key->ops->get_attribute(operation->session, key, &attr);
|
rv = key->ops->get_attribute(operation->session, key, &attr);
|
||||||
*pLength = ((*pLength + 7)/8) * 2 + 8; /* 2*nLen in bytes plus SEQUENCE and 2 INTEGER tags plus leading '00' for signed integer */
|
*pLength = ((*pLength + 7)/8) * 2 ; /* 2*nLen in bytes */
|
||||||
break;
|
break;
|
||||||
case CKK_GOSTR3410:
|
case CKK_GOSTR3410:
|
||||||
rv = key->ops->get_attribute(operation->session, key, &attr);
|
rv = key->ops->get_attribute(operation->session, key, &attr);
|
||||||
|
|
Loading…
Reference in New Issue