Replace multiple 'if' by 'switch/case'

pull/104/head
Charles-Edouard de la Vergne 7 months ago
parent d97b0ea3b4
commit 37f7ab8571
No known key found for this signature in database
GPG Key ID: F12296941B7BB9C6

@ -78,32 +78,39 @@ static void gpg_pso_reset_PW1() {
*/ */
static int gpg_sign(gpg_key_t *sigkey) { static int gpg_sign(gpg_key_t *sigkey) {
cx_err_t error = CX_INTERNAL_ERROR; cx_err_t error = CX_INTERNAL_ERROR;
if (sigkey->attributes.value[0] == KEY_ID_RSA) { cx_rsa_private_key_t *rsa_key = NULL;
cx_rsa_private_key_t *key = NULL;
unsigned int ksz, l; unsigned int ksz, l;
cx_ecfp_private_key_t *ecfp_key = NULL;
unsigned int s_len, i, rs_len, info;
unsigned char *rs;
switch (sigkey->attributes.value[0]) {
case KEY_ID_RSA:
ksz = U2BE(sigkey->attributes.value, 1) >> 3; ksz = U2BE(sigkey->attributes.value, 1) >> 3;
switch (ksz) { switch (ksz) {
case 2048 / 8: case 2048 / 8:
key = (cx_rsa_private_key_t *) &sigkey->priv_key.rsa2048; rsa_key = (cx_rsa_private_key_t *) &sigkey->priv_key.rsa2048;
break; break;
case 3072 / 8: case 3072 / 8:
key = (cx_rsa_private_key_t *) &sigkey->priv_key.rsa3072; rsa_key = (cx_rsa_private_key_t *) &sigkey->priv_key.rsa3072;
break; break;
#ifdef WITH_SUPPORT_RSA4096 #ifdef WITH_SUPPORT_RSA4096
case 4096 / 8: case 4096 / 8:
key = (cx_rsa_private_key_t *) &sigkey->priv_key.rsa4096; rsa_key = (cx_rsa_private_key_t *) &sigkey->priv_key.rsa4096;
break; break;
#endif #endif
default: default:
break; break;
} }
if ((key == NULL) || (key->size != ksz)) { if ((rsa_key == NULL) || (rsa_key->size != ksz)) {
return SW_CONDITIONS_NOT_SATISFIED; error = SW_CONDITIONS_NOT_SATISFIED;
break;
} }
// sign // sign
if (ksz < G_gpg_vstate.io_length) { if (ksz < G_gpg_vstate.io_length) {
return SW_WRONG_LENGTH; error = SW_WRONG_LENGTH;
break;
} }
l = ksz - G_gpg_vstate.io_length; l = ksz - G_gpg_vstate.io_length;
memmove(G_gpg_vstate.work.io_buffer + l, memmove(G_gpg_vstate.work.io_buffer + l,
@ -113,7 +120,7 @@ static int gpg_sign(gpg_key_t *sigkey) {
G_gpg_vstate.work.io_buffer[0] = 0; G_gpg_vstate.work.io_buffer[0] = 0;
G_gpg_vstate.work.io_buffer[1] = 1; G_gpg_vstate.work.io_buffer[1] = 1;
G_gpg_vstate.work.io_buffer[l - 1] = 0; G_gpg_vstate.work.io_buffer[l - 1] = 0;
CX_CHECK(cx_rsa_decrypt_no_throw(key, CX_CHECK(cx_rsa_decrypt_no_throw(rsa_key,
CX_PAD_NONE, CX_PAD_NONE,
CX_NONE, CX_NONE,
G_gpg_vstate.work.io_buffer, G_gpg_vstate.work.io_buffer,
@ -124,26 +131,19 @@ static int gpg_sign(gpg_key_t *sigkey) {
gpg_io_discard(0); gpg_io_discard(0);
gpg_io_inserted(ksz); gpg_io_inserted(ksz);
gpg_pso_reset_PW1(); gpg_pso_reset_PW1();
return SW_OK; error = SW_OK;
} break;
if ((sigkey->attributes.value[0] == KEY_ID_ECDSA) ||
(sigkey->attributes.value[0] == KEY_ID_EDDSA)) {
cx_ecfp_private_key_t *key;
size_t ksz;
unsigned int s_len, i, rs_len, info;
unsigned char *rs;
key = &sigkey->priv_key.ecfp;
// sign
#define RS (G_gpg_vstate.work.io_buffer + (GPG_IO_BUFFER_LENGTH - 256)) #define RS (G_gpg_vstate.work.io_buffer + (GPG_IO_BUFFER_LENGTH - 256))
if (sigkey->attributes.value[0] == KEY_ID_ECDSA) { case KEY_ID_ECDSA:
ksz = (unsigned int) gpg_curve2domainlen(key->curve); ecfp_key = &sigkey->priv_key.ecfp;
if ((ksz == 0) || (key->d_len != ksz)) { ksz = (unsigned int) gpg_curve2domainlen(ecfp_key->curve);
return SW_CONDITIONS_NOT_SATISFIED; if ((ksz == 0) || (ecfp_key->d_len != ksz)) {
error = SW_CONDITIONS_NOT_SATISFIED;
break;
} }
s_len = 256; s_len = 256;
CX_CHECK(cx_ecdsa_sign_no_throw(key, CX_CHECK(cx_ecdsa_sign_no_throw(ecfp_key,
CX_RND_TRNG, CX_RND_TRNG,
CX_NONE, CX_NONE,
G_gpg_vstate.work.io_buffer, G_gpg_vstate.work.io_buffer,
@ -168,27 +168,33 @@ static int gpg_sign(gpg_key_t *sigkey) {
rs_len = rs[1]; rs_len = rs[1];
rs += 2; rs += 2;
} }
} else { error = SW_OK;
break;
case KEY_ID_EDDSA:
ecfp_key = &sigkey->priv_key.ecfp;
ksz = 256; ksz = 256;
CX_CHECK(cx_eddsa_sign_no_throw(key, CX_CHECK(cx_eddsa_sign_no_throw(ecfp_key,
CX_SHA512, CX_SHA512,
G_gpg_vstate.work.io_buffer, G_gpg_vstate.work.io_buffer,
G_gpg_vstate.io_length, G_gpg_vstate.io_length,
RS, RS,
ksz)); ksz));
CX_CHECK(cx_ecdomain_parameters_length(key->curve, &ksz)); CX_CHECK(cx_ecdomain_parameters_length(ecfp_key->curve, &ksz));
ksz *= 2; ksz *= 2;
gpg_io_discard(0); gpg_io_discard(0);
gpg_io_insert(RS, ksz); gpg_io_insert(RS, ksz);
} error = SW_OK;
break;
// send default:
gpg_pso_reset_PW1();
return SW_OK;
}
// --- PSO:CDS NOT SUPPORTED // --- PSO:CDS NOT SUPPORTED
return SW_REFERENCED_DATA_NOT_FOUND; error = SW_REFERENCED_DATA_NOT_FOUND;
break;
}
end: end:
gpg_pso_reset_PW1();
return error; return error;
} }
@ -199,8 +205,14 @@ end:
* *
*/ */
int gpg_apdu_pso() { int gpg_apdu_pso() {
unsigned int t, l, ksz;
cx_err_t error = CX_INTERNAL_ERROR; cx_err_t error = CX_INTERNAL_ERROR;
unsigned int t, l, ksz;
unsigned int cnt, pad_byte;
unsigned int msg_len;
unsigned int curve;
cx_aes_key_t *aes_key = NULL;
cx_rsa_private_key_t *rsa_key = NULL;
cx_ecfp_private_key_t *ecfp_key = NULL;
// UIF HANDLE // UIF HANDLE
switch (G_gpg_vstate.io_p1p2) { switch (G_gpg_vstate.io_p1p2) {
@ -229,26 +241,20 @@ int gpg_apdu_pso() {
// --- PSO:ENC --- // --- PSO:ENC ---
switch (G_gpg_vstate.io_p1p2) { switch (G_gpg_vstate.io_p1p2) {
// --- PSO:CDS --- case PSO_CDS:
case PSO_CDS: { error = gpg_sign(&G_gpg_vstate.kslot->sig);
unsigned int cnt;
int sw = SW_UNKNOWN;
sw = gpg_sign(&G_gpg_vstate.kslot->sig);
cnt = G_gpg_vstate.kslot->sig_count + 1; cnt = G_gpg_vstate.kslot->sig_count + 1;
nvm_write(&G_gpg_vstate.kslot->sig_count, &cnt, sizeof(unsigned int)); nvm_write(&G_gpg_vstate.kslot->sig_count, &cnt, sizeof(unsigned int));
return sw; break;
}
// --- PSO:ENC --- case PSO_ENC:
case PSO_ENC: { aes_key = &G_gpg_vstate.kslot->AES_dec;
unsigned int msg_len; if (!(aes_key->size != CX_AES_128_KEY_LEN)) {
cx_aes_key_t *key = NULL;
key = &G_gpg_vstate.kslot->AES_dec;
if (!(key->size != CX_AES_128_KEY_LEN)) {
return SW_CONDITIONS_NOT_SATISFIED; return SW_CONDITIONS_NOT_SATISFIED;
} }
msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset; msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset;
ksz = GPG_IO_BUFFER_LENGTH - 1; ksz = GPG_IO_BUFFER_LENGTH - 1;
CX_CHECK(cx_aes_no_throw(key, CX_CHECK(cx_aes_no_throw(aes_key,
CX_ENCRYPT | CX_CHAIN_CBC | CX_LAST, CX_ENCRYPT | CX_CHAIN_CBC | CX_LAST,
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset, G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
msg_len, msg_len,
@ -258,44 +264,43 @@ int gpg_apdu_pso() {
gpg_io_discard(0); gpg_io_discard(0);
G_gpg_vstate.work.io_buffer[0] = PAD_AES; G_gpg_vstate.work.io_buffer[0] = PAD_AES;
gpg_io_inserted(1 + ksz); gpg_io_inserted(1 + ksz);
return SW_OK; error = SW_OK;
} break;
// --- PSO:DEC --- case PSO_DEC:
case PSO_DEC: {
unsigned int msg_len;
unsigned int pad_byte;
pad_byte = gpg_io_fetch_u8(); pad_byte = gpg_io_fetch_u8();
switch (pad_byte) { switch (pad_byte) {
// --- PSO:DEC:RSA case PAD_RSA:
case PAD_RSA: {
cx_rsa_private_key_t *key = NULL;
if (G_gpg_vstate.mse_dec->attributes.value[0] != KEY_ID_RSA) { if (G_gpg_vstate.mse_dec->attributes.value[0] != KEY_ID_RSA) {
return SW_CONDITIONS_NOT_SATISFIED; error = SW_CONDITIONS_NOT_SATISFIED;
break;
} }
ksz = U2BE(G_gpg_vstate.mse_dec->attributes.value, 1) >> 3; ksz = U2BE(G_gpg_vstate.mse_dec->attributes.value, 1) >> 3;
key = NULL;
switch (ksz) { switch (ksz) {
case 2048 / 8: case 2048 / 8:
key = (cx_rsa_private_key_t *) &G_gpg_vstate.mse_dec->priv_key.rsa2048; rsa_key =
(cx_rsa_private_key_t *) &G_gpg_vstate.mse_dec->priv_key.rsa2048;
break; break;
case 3072 / 8: case 3072 / 8:
key = (cx_rsa_private_key_t *) &G_gpg_vstate.mse_dec->priv_key.rsa3072; rsa_key =
(cx_rsa_private_key_t *) &G_gpg_vstate.mse_dec->priv_key.rsa3072;
break; break;
#ifdef WITH_SUPPORT_RSA4096 #ifdef WITH_SUPPORT_RSA4096
case 4096 / 8: case 4096 / 8:
key = (cx_rsa_private_key_t *) &G_gpg_vstate.mse_dec->priv_key.rsa4096; rsa_key =
(cx_rsa_private_key_t *) &G_gpg_vstate.mse_dec->priv_key.rsa4096;
break; break;
#endif #endif
} }
if ((key == NULL) || (key->size != ksz)) { if ((rsa_key == NULL) || (rsa_key->size != ksz)) {
return SW_CONDITIONS_NOT_SATISFIED; error = SW_CONDITIONS_NOT_SATISFIED;
break;
} }
msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset; msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset;
CX_CHECK(cx_rsa_decrypt_no_throw( CX_CHECK(cx_rsa_decrypt_no_throw(
key, rsa_key,
CX_PAD_PKCS1_1o5, CX_PAD_PKCS1_1o5,
CX_NONE, CX_NONE,
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset, G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
@ -305,19 +310,18 @@ int gpg_apdu_pso() {
// send // send
gpg_io_discard(0); gpg_io_discard(0);
gpg_io_inserted(ksz); gpg_io_inserted(ksz);
return SW_OK; error = SW_OK;
} break;
// --- PSO:DEC:AES case PAD_AES:
case PAD_AES: { aes_key = &G_gpg_vstate.kslot->AES_dec;
cx_aes_key_t *key; if (!(aes_key->size != CX_AES_128_KEY_LEN)) {
key = &G_gpg_vstate.kslot->AES_dec; error = SW_CONDITIONS_NOT_SATISFIED;
if (!(key->size != CX_AES_128_KEY_LEN)) { break;
return SW_CONDITIONS_NOT_SATISFIED;
} }
msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset; msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset;
ksz = GPG_IO_BUFFER_LENGTH; ksz = GPG_IO_BUFFER_LENGTH;
CX_CHECK(cx_aes_no_throw(key, CX_CHECK(cx_aes_no_throw(aes_key,
CX_DECRYPT | CX_CHAIN_CBC | CX_LAST, CX_DECRYPT | CX_CHAIN_CBC | CX_LAST,
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset, G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
msg_len, msg_len,
@ -326,81 +330,80 @@ int gpg_apdu_pso() {
// send // send
gpg_io_discard(0); gpg_io_discard(0);
gpg_io_inserted(ksz); gpg_io_inserted(ksz);
return SW_OK; error = SW_OK;
} break;
// --- PSO:DEC:ECDH
case PAD_ECDH: {
cx_ecfp_private_key_t *key;
unsigned int curve;
case PAD_ECDH:
if (G_gpg_vstate.mse_dec->attributes.value[0] != KEY_ID_ECDH) { if (G_gpg_vstate.mse_dec->attributes.value[0] != KEY_ID_ECDH) {
return SW_CONDITIONS_NOT_SATISFIED; error = SW_CONDITIONS_NOT_SATISFIED;
break;
} }
key = &G_gpg_vstate.mse_dec->priv_key.ecfp; ecfp_key = &G_gpg_vstate.mse_dec->priv_key.ecfp;
gpg_io_fetch_l(&l); gpg_io_fetch_l(&l);
gpg_io_fetch_tl(&t, &l); gpg_io_fetch_tl(&t, &l);
if (t != 0x7f49) { if (t != 0x7f49) {
return SW_WRONG_DATA; error = SW_WRONG_DATA;
break;
} }
gpg_io_fetch_tl(&t, &l); gpg_io_fetch_tl(&t, &l);
if (t != 0x86) { if (t != 0x86) {
return SW_WRONG_DATA; error = SW_WRONG_DATA;
break;
} }
curve = gpg_oid2curve(G_gpg_vstate.mse_dec->attributes.value + 1, curve = gpg_oid2curve(G_gpg_vstate.mse_dec->attributes.value + 1,
G_gpg_vstate.mse_dec->attributes.length - 1); G_gpg_vstate.mse_dec->attributes.length - 1);
if (key->curve != curve) { if (ecfp_key->curve != curve) {
return SW_CONDITIONS_NOT_SATISFIED; error = SW_CONDITIONS_NOT_SATISFIED;
break;
} }
if (curve == CX_CURVE_Curve25519) { if (curve == CX_CURVE_Curve25519) {
unsigned int i; for (cnt = 0; cnt <= 31; cnt++) {
G_gpg_vstate.work.io_buffer[512 + cnt] =
for (i = 0; i <= 31; i++) { (G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset)[31 - cnt];
G_gpg_vstate.work.io_buffer[512 + i] =
(G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset)[31 - i];
} }
G_gpg_vstate.work.io_buffer[511] = 0x02; G_gpg_vstate.work.io_buffer[511] = 0x02;
CX_CHECK(cx_ecdh_no_throw(key, CX_CHECK(cx_ecdh_no_throw(ecfp_key,
CX_ECDH_X, CX_ECDH_X,
G_gpg_vstate.work.io_buffer + 511, G_gpg_vstate.work.io_buffer + 511,
65, 65,
G_gpg_vstate.work.io_buffer + 256, G_gpg_vstate.work.io_buffer + 256,
160)); 160));
CX_CHECK(cx_ecdomain_parameters_length(key->curve, &ksz)); CX_CHECK(cx_ecdomain_parameters_length(ecfp_key->curve, &ksz));
for (i = 0; i <= 31; i++) { for (cnt = 0; cnt <= 31; cnt++) {
G_gpg_vstate.work.io_buffer[128 + i] = G_gpg_vstate.work.io_buffer[128 + cnt] =
G_gpg_vstate.work.io_buffer[287 - i]; G_gpg_vstate.work.io_buffer[287 - cnt];
} }
ksz = 32; ksz = 32;
} else { } else {
CX_CHECK( CX_CHECK(
cx_ecdh_no_throw(key, cx_ecdh_no_throw(ecfp_key,
CX_ECDH_X, CX_ECDH_X,
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset, G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
65, 65,
G_gpg_vstate.work.io_buffer + 128, G_gpg_vstate.work.io_buffer + 128,
160)); 160));
CX_CHECK(cx_ecdomain_parameters_length(key->curve, &ksz)); CX_CHECK(cx_ecdomain_parameters_length(ecfp_key->curve, &ksz));
} }
// send // send
gpg_io_discard(0); gpg_io_discard(0);
gpg_io_insert(G_gpg_vstate.work.io_buffer + 128, ksz); gpg_io_insert(G_gpg_vstate.work.io_buffer + 128, ksz);
return SW_OK; error = SW_OK;
} break;
// --- PSO:DEC:xx NOT SUPPORTED // --- PSO:DEC:xx NOT SUPPORTED
default: default:
return SW_REFERENCED_DATA_NOT_FOUND; error = SW_REFERENCED_DATA_NOT_FOUND;
} break;
} }
break;
//--- PSO:yy NOT SUPPORTED --- //--- PSO:yy NOT SUPPORTED ---
default: default:
return SW_REFERENCED_DATA_NOT_FOUND; error = SW_REFERENCED_DATA_NOT_FOUND;
break;
} }
return SW_REFERENCED_DATA_NOT_FOUND;
end: end:
return error; return error;
} }

Loading…
Cancel
Save