MyEID support for RAW RSA signature for 2048 bit keys
MyEID does not support RAW RSA signature for 2048 bit key. (Source: MyEID reference manual 2.1.4) This hack uses decipher operation for calculating RAW 2048 bit signature.
This commit is contained in:
parent
e069654f3b
commit
deab9cce73
|
@ -881,7 +881,73 @@ myeid_convert_ec_signature(struct sc_context *ctx, size_t s_len, unsigned char *
|
||||||
free(buf);
|
free(buf);
|
||||||
return buflen;
|
return buflen;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
MyEID does not support RAW RSA signature for 2048 bit key.
|
||||||
|
(Source: MyEID reference manual 2.1.4)
|
||||||
|
|
||||||
|
This function uses decipher operation for calculating RAW 2048 bit signature.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
myeid_compute_raw_2048_signature(struct sc_card *card, const u8 * data, size_t datalen,
|
||||||
|
u8 * out, size_t outlen)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
struct sc_context *ctx;
|
||||||
|
struct myeid_private_data *priv;
|
||||||
|
struct sc_apdu apdu;
|
||||||
|
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||||
|
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||||
|
sc_security_env_t env;
|
||||||
|
|
||||||
|
ctx = card->ctx;
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
|
||||||
|
priv = (myeid_private_data_t *) card->drv_data;
|
||||||
|
|
||||||
|
/* security env change - use DECIPHER operation */
|
||||||
|
memcpy(&env, priv->sec_env, sizeof(sc_security_env_t));
|
||||||
|
env.flags |= SC_SEC_ENV_ALG_REF_PRESENT;
|
||||||
|
env.flags |= SC_SEC_ENV_FILE_REF_PRESENT;
|
||||||
|
env.flags |= SC_SEC_ENV_KEY_REF_PRESENT;
|
||||||
|
env.operation = SC_SEC_OPERATION_DECIPHER;
|
||||||
|
myeid_set_security_env_rsa(card, &env, 0);
|
||||||
|
|
||||||
|
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x80, 0x86);
|
||||||
|
apdu.resp = rbuf;
|
||||||
|
apdu.resplen = sizeof(rbuf);
|
||||||
|
apdu.le = 0; /* there is no response to 1st part of data */
|
||||||
|
|
||||||
|
/* prepare 1st part of data */
|
||||||
|
sbuf[0] = 0x81;
|
||||||
|
memcpy(sbuf + 1, data, datalen / 2);
|
||||||
|
apdu.lc = datalen / 2 + 1;
|
||||||
|
apdu.datalen = apdu.lc;
|
||||||
|
apdu.data = sbuf;
|
||||||
|
|
||||||
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
|
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
|
||||||
|
/* prepare 2nd part of data */
|
||||||
|
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86);
|
||||||
|
apdu.resp = rbuf;
|
||||||
|
apdu.resplen = sizeof(rbuf);
|
||||||
|
apdu.le = datalen;
|
||||||
|
sbuf[0] = 0x82;
|
||||||
|
memcpy(sbuf + 1, data + datalen / 2, datalen / 2);
|
||||||
|
apdu.lc = datalen / 2 + 1;
|
||||||
|
apdu.datalen = apdu.lc;
|
||||||
|
apdu.data = sbuf;
|
||||||
|
|
||||||
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
|
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||||
|
|
||||||
|
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
|
||||||
|
int len = apdu.resplen > outlen ? outlen : apdu.resplen;
|
||||||
|
memcpy(out, apdu.resp, len);
|
||||||
|
LOG_FUNC_RETURN(card->ctx, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen,
|
myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen,
|
||||||
|
@ -919,6 +985,9 @@ myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen,
|
||||||
if ((datalen + pad_chars) > 256)
|
if ((datalen + pad_chars) > 256)
|
||||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||||
|
|
||||||
|
if (datalen == 256 && priv->sec_env->algorithm == SC_ALGORITHM_RSA)
|
||||||
|
return myeid_compute_raw_2048_signature(card, data, datalen, out, outlen);
|
||||||
|
|
||||||
/* INS: 0x2A PERFORM SECURITY OPERATION
|
/* INS: 0x2A PERFORM SECURITY OPERATION
|
||||||
* P1: 0x9E Resp: Digital Signature
|
* P1: 0x9E Resp: Digital Signature
|
||||||
* P2: 0x9A Cmd: Input for Digital Signature */
|
* P2: 0x9A Cmd: Input for Digital Signature */
|
||||||
|
@ -926,17 +995,9 @@ myeid_compute_signature(struct sc_card *card, const u8 * data, size_t datalen,
|
||||||
apdu.resp = rbuf;
|
apdu.resp = rbuf;
|
||||||
apdu.resplen = sizeof(rbuf);
|
apdu.resplen = sizeof(rbuf);
|
||||||
apdu.le = 256;
|
apdu.le = 256;
|
||||||
if (datalen == 256) {
|
memcpy(sbuf + pad_chars, data, datalen);
|
||||||
apdu.p2 = data[0];
|
apdu.lc = datalen + pad_chars;
|
||||||
memcpy(sbuf, data+1, datalen-1);
|
apdu.datalen = datalen + pad_chars;
|
||||||
apdu.lc = datalen - 1;
|
|
||||||
apdu.datalen = datalen - 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
memcpy(sbuf + pad_chars, data, datalen);
|
|
||||||
apdu.lc = datalen + pad_chars;
|
|
||||||
apdu.datalen = datalen + pad_chars;
|
|
||||||
}
|
|
||||||
|
|
||||||
apdu.data = sbuf;
|
apdu.data = sbuf;
|
||||||
r = sc_transmit_apdu(card, &apdu);
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
|
|
Loading…
Reference in New Issue