Fix crypto deprecated warnings

This commit is contained in:
Charles-Edouard de la Vergne 2023-10-17 16:01:16 +02:00
parent 1b7e959b1b
commit e8e46d7990
No known key found for this signature in database
GPG Key ID: F12296941B7BB9C6
5 changed files with 234 additions and 146 deletions

View File

@ -18,9 +18,11 @@
#include "gpg_types.h"
#include "gpg_api.h"
#include "gpg_vars.h"
#include "cx_errors.h"
int gpg_apdu_get_challenge() {
unsigned int olen, hlen;
cx_err_t error = CX_INTERNAL_ERROR;
if ((G_gpg_vstate.io_p1 & 0x80) == 0x80) {
olen = G_gpg_vstate.io_p2;
@ -35,39 +37,46 @@ int gpg_apdu_get_challenge() {
if ((G_gpg_vstate.io_p1 & 0x82) == 0x82) {
unsigned int path[2];
unsigned char chain[32];
unsigned char Sr[32];
unsigned char Sr[64];
memset(chain, 0, 32);
path[0] = 0x80475047;
path[1] = 0x0F0F0F0F;
os_perso_derive_node_bip32(CX_CURVE_SECP256K1, path, 2, Sr, chain);
CX_CHECK(os_derive_bip32_no_throw(CX_CURVE_SECP256K1, path, 2, Sr, chain));
chain[0] = 'r';
chain[1] = 'n';
chain[2] = 'd';
cx_sha256_init(&G_gpg_vstate.work.md.sha256);
cx_hash((cx_hash_t *) &G_gpg_vstate.work.md.sha256, 0, Sr, 32, NULL, 0);
cx_hash((cx_hash_t *) &G_gpg_vstate.work.md.sha256, 0, chain, 3, NULL, 0);
hlen = cx_hash((cx_hash_t *) &G_gpg_vstate.work.md.sha256,
CX_LAST,
G_gpg_vstate.work.io_buffer,
G_gpg_vstate.io_length,
G_gpg_vstate.work.io_buffer,
32);
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &G_gpg_vstate.work.md.sha256, 0, Sr, 32, NULL, 0));
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &G_gpg_vstate.work.md.sha256, 0, chain, 3, NULL, 0));
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &G_gpg_vstate.work.md.sha256,
CX_LAST,
G_gpg_vstate.work.io_buffer,
G_gpg_vstate.io_length,
G_gpg_vstate.work.io_buffer,
32));
hlen = cx_hash_get_size((const cx_hash_t *) &G_gpg_vstate.work.md.sha256);
cx_sha3_xof_init(&G_gpg_vstate.work.md.sha3, 256, olen);
cx_hash((cx_hash_t *) &G_gpg_vstate.work.md.sha3,
CX_LAST,
G_gpg_vstate.work.io_buffer,
hlen,
G_gpg_vstate.work.io_buffer,
olen);
CX_CHECK(cx_sha3_xof_init_no_throw(&G_gpg_vstate.work.md.sha3, 256, olen));
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &G_gpg_vstate.work.md.sha3,
CX_LAST,
G_gpg_vstate.work.io_buffer,
hlen,
G_gpg_vstate.work.io_buffer,
olen));
} else {
cx_rng(G_gpg_vstate.work.io_buffer, olen);
error = CX_OK;
}
if ((G_gpg_vstate.io_p1 & 0x81) == 0x81) {
cx_math_next_prime(G_gpg_vstate.work.io_buffer, olen);
CX_CHECK(cx_math_next_prime_no_throw(G_gpg_vstate.work.io_buffer, olen));
}
end:
if (error != CX_OK) {
THROW(error);
}
gpg_io_discard(0);
gpg_io_inserted(olen);

View File

@ -18,6 +18,7 @@
#include "gpg_types.h"
#include "gpg_api.h"
#include "gpg_vars.h"
#include "cx_errors.h"
int gpg_apdu_select_data(unsigned int ref, int record) {
G_gpg_vstate.DO_current = ref;
@ -224,6 +225,7 @@ int gpg_apdu_put_data(unsigned int ref) {
unsigned int t, l, sw;
unsigned int *ptr_l;
unsigned char *ptr_v;
cx_err_t error = CX_INTERNAL_ERROR;
G_gpg_vstate.DO_current = ref;
sw = SW_OK;
@ -452,7 +454,7 @@ int gpg_apdu_put_data(unsigned int ref) {
_e[1] = e >> 16;
_e[2] = e >> 8;
_e[3] = e >> 0;
cx_rsa_generate_pair(ksz << 1, rsa_pub, rsa_priv, _e, 4, pq);
CX_CHECK(cx_rsa_generate_pair_no_throw(ksz << 1, rsa_pub, rsa_priv, _e, 4, pq));
// write keys
nvm_write(&keygpg->pub_key.rsa, rsa_pub->e, 4);
@ -479,10 +481,10 @@ int gpg_apdu_put_data(unsigned int ref) {
memmove(G_gpg_vstate.work.ecfp.private.d,
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
ksz);
cx_ecfp_generate_pair(curve,
&G_gpg_vstate.work.ecfp.public,
&G_gpg_vstate.work.ecfp.private,
1);
CX_CHECK(cx_ecfp_generate_pair_no_throw(curve,
&G_gpg_vstate.work.ecfp.public,
&G_gpg_vstate.work.ecfp.private,
1));
nvm_write(&keygpg->pub_key.ecfp,
&G_gpg_vstate.work.ecfp.public,
sizeof(cx_ecfp_public_key_t));
@ -682,17 +684,21 @@ int gpg_apdu_put_data(unsigned int ref) {
pkey = &G_gpg_vstate.kslot->AES_dec;
goto init_aes_key;
init_aes_key:
cx_aes_init_key(G_gpg_vstate.work.io_buffer, G_gpg_vstate.io_length, &aes_key);
CX_CHECK(cx_aes_init_key_no_throw(G_gpg_vstate.work.io_buffer,
G_gpg_vstate.io_length,
&aes_key));
gpg_nvm_write(pkey, &aes_key, sizeof(cx_aes_key_t));
break;
/* AES key: one shot */
case 0xF4:
cx_aes_init_key(G_gpg_vstate.work.io_buffer, G_gpg_vstate.io_length, &aes_key);
CX_CHECK(cx_aes_init_key_no_throw(G_gpg_vstate.work.io_buffer,
G_gpg_vstate.io_length,
&aes_key));
gpg_nvm_write((void *) &N_gpg_pstate->SM_enc, &aes_key, sizeof(cx_aes_key_t));
cx_aes_init_key(G_gpg_vstate.work.io_buffer + 16,
G_gpg_vstate.io_length,
&aes_key);
CX_CHECK(cx_aes_init_key_no_throw(G_gpg_vstate.work.io_buffer + 16,
G_gpg_vstate.io_length,
&aes_key));
gpg_nvm_write((void *) &N_gpg_pstate->SM_mac, &aes_key, sizeof(cx_aes_key_t));
break;
}
@ -744,14 +750,22 @@ int gpg_apdu_put_data(unsigned int ref) {
gpg_io_discard(1);
return sw;
end:
THROW(error);
}
static void gpg_init_keyenc(cx_aes_key_t *keyenc) {
unsigned char seed[32];
cx_err_t error = CX_INTERNAL_ERROR;
gpg_pso_derive_slot_seed(G_gpg_vstate.slot, seed);
gpg_pso_derive_key_seed(seed, (unsigned char *) PIC("key "), 1, seed, 16);
cx_aes_init_key(seed, 16, keyenc);
CX_CHECK(cx_aes_init_key_no_throw(seed, 16, keyenc));
end:
if (error != CX_OK) {
THROW(error);
}
}
// cmd
@ -761,6 +775,7 @@ int gpg_apdu_get_key_data(unsigned int ref) {
gpg_key_t *keygpg;
unsigned int len = 0;
gpg_init_keyenc(&keyenc);
cx_err_t error = CX_INTERNAL_ERROR;
switch (ref) {
case 0x00B6:
@ -780,8 +795,13 @@ int gpg_apdu_get_key_data(unsigned int ref) {
gpg_io_discard(1);
// clear part
gpg_io_insert_u32(TARGET_ID);
gpg_io_insert_u32(CX_APILEVEL);
gpg_io_insert_u32(CX_COMPAT_APILEVEL);
// TODO; Check
// gpg_io_insert_u32(CX_APILEVEL);
// gpg_io_insert_u32(CX_COMPAT_APILEVEL);
gpg_io_insert_u32(get_api_level());
gpg_io_insert_u32(get_api_level());
// encrypted part
switch (keygpg->attributes.value[0]) {
case 0x01: // RSA
@ -791,12 +811,13 @@ int gpg_apdu_get_key_data(unsigned int ref) {
// insert privkey
gpg_io_mark();
len = cx_aes(&keyenc,
CX_ENCRYPT | CX_CHAIN_CBC | CX_PAD_ISO9797M2 | CX_LAST,
(unsigned char *) &keygpg->priv_key.rsa4096,
sizeof(cx_rsa_4096_private_key_t),
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
GPG_IO_BUFFER_LENGTH - G_gpg_vstate.io_offset);
len = GPG_IO_BUFFER_LENGTH - G_gpg_vstate.io_offset;
CX_CHECK(cx_aes_no_throw(&keyenc,
CX_ENCRYPT | CX_CHAIN_CBC | CX_PAD_ISO9797M2 | CX_LAST,
(unsigned char *) &keygpg->priv_key.rsa4096,
sizeof(cx_rsa_4096_private_key_t),
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
&len));
gpg_io_inserted(len);
gpg_io_set_offset(IO_OFFSET_MARK);
gpg_io_insert_u32(len);
@ -813,12 +834,13 @@ int gpg_apdu_get_key_data(unsigned int ref) {
// insert privkey
gpg_io_mark();
len = cx_aes(&keyenc,
CX_ENCRYPT | CX_CHAIN_CBC | CX_PAD_ISO9797M2 | CX_LAST,
(unsigned char *) &keygpg->priv_key.ecfp640,
sizeof(cx_ecfp_640_private_key_t),
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
GPG_IO_BUFFER_LENGTH - G_gpg_vstate.io_offset);
len = GPG_IO_BUFFER_LENGTH - G_gpg_vstate.io_offset;
CX_CHECK(cx_aes_no_throw(&keyenc,
CX_ENCRYPT | CX_CHAIN_CBC | CX_PAD_ISO9797M2 | CX_LAST,
(unsigned char *) &keygpg->priv_key.ecfp640,
sizeof(cx_ecfp_640_private_key_t),
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
&len));
gpg_io_inserted(len);
gpg_io_set_offset(IO_OFFSET_MARK);
gpg_io_insert_u32(len);
@ -830,6 +852,8 @@ int gpg_apdu_get_key_data(unsigned int ref) {
return SW_REFERENCED_DATA_NOT_FOUND;
}
return SW_OK;
end:
THROW(error);
}
// cmd TID API COMPAT len_pub len_priv priv
@ -840,6 +864,7 @@ int gpg_apdu_put_key_data(unsigned int ref) {
unsigned int len;
unsigned int offset;
gpg_init_keyenc(&keyenc);
cx_err_t error = CX_INTERNAL_ERROR;
switch (ref) {
case 0xB6:
@ -881,12 +906,13 @@ int gpg_apdu_put_key_data(unsigned int ref) {
}
offset = G_gpg_vstate.io_offset;
gpg_io_discard(0);
len = cx_aes(&keyenc,
CX_DECRYPT | CX_CHAIN_CBC | CX_PAD_ISO9797M2 | CX_LAST,
G_gpg_vstate.work.io_buffer + offset,
len,
G_gpg_vstate.work.io_buffer,
GPG_IO_BUFFER_LENGTH);
len = GPG_IO_BUFFER_LENGTH;
CX_CHECK(cx_aes_no_throw(&keyenc,
CX_DECRYPT | CX_CHAIN_CBC | CX_PAD_ISO9797M2 | CX_LAST,
G_gpg_vstate.work.io_buffer + offset,
len,
G_gpg_vstate.work.io_buffer,
&len));
if (len != sizeof(cx_rsa_4096_private_key_t)) {
THROW(SW_WRONG_DATA);
}
@ -915,12 +941,13 @@ int gpg_apdu_put_key_data(unsigned int ref) {
offset = G_gpg_vstate.io_offset;
gpg_io_discard(0);
len = cx_aes(&keyenc,
CX_DECRYPT | CX_CHAIN_CBC | CX_PAD_ISO9797M2 | CX_LAST,
G_gpg_vstate.work.io_buffer + offset,
len,
G_gpg_vstate.work.io_buffer,
GPG_IO_BUFFER_LENGTH);
len = GPG_IO_BUFFER_LENGTH;
CX_CHECK(cx_aes_no_throw(&keyenc,
CX_DECRYPT | CX_CHAIN_CBC | CX_PAD_ISO9797M2 | CX_LAST,
G_gpg_vstate.work.io_buffer + offset,
len,
G_gpg_vstate.work.io_buffer,
&len));
if (len != sizeof(cx_ecfp_640_private_key_t)) {
THROW(SW_WRONG_DATA);
return SW_WRONG_DATA;
@ -936,4 +963,6 @@ int gpg_apdu_put_key_data(unsigned int ref) {
}
gpg_io_discard(1);
return SW_OK;
end:
THROW(error);
}

View File

@ -18,6 +18,7 @@
#include "gpg_types.h"
#include "gpg_api.h"
#include "gpg_vars.h"
#include "cx_errors.h"
/* @in slot slot num [0 ; GPG_KEYS_SLOTS[
* @out seed 32 bytes master seed for given slot
@ -25,11 +26,17 @@
void gpg_pso_derive_slot_seed(int slot, unsigned char *seed) {
unsigned int path[2];
unsigned char chain[32];
cx_err_t error = CX_INTERNAL_ERROR;
memset(chain, 0, 32);
path[0] = 0x80475047;
path[1] = slot + 1;
os_perso_derive_node_bip32(CX_CURVE_SECP256K1, path, 2, seed, chain);
CX_CHECK(os_derive_bip32_no_throw(CX_CURVE_SECP256K1, path, 2, seed, chain));
end:
if (error != CX_OK) {
THROW(error);
}
}
/* @in Sn master seed slot number
@ -44,21 +51,31 @@ void gpg_pso_derive_key_seed(unsigned char *Sn,
unsigned char *Ski,
unsigned int Ski_len) {
unsigned char h[32];
cx_err_t error = CX_INTERNAL_ERROR;
h[0] = idx >> 8;
h[1] = idx;
cx_sha256_init(&G_gpg_vstate.work.md.sha256);
cx_hash((cx_hash_t *) &G_gpg_vstate.work.md.sha256, 0, Sn, 32, NULL, 0);
cx_hash((cx_hash_t *) &G_gpg_vstate.work.md.sha256, 0, (unsigned char *) key_name, 4, NULL, 0);
cx_hash((cx_hash_t *) &G_gpg_vstate.work.md.sha256, CX_LAST, h, 2, h, 32);
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &G_gpg_vstate.work.md.sha256, 0, Sn, 32, NULL, 0));
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &G_gpg_vstate.work.md.sha256,
0,
(unsigned char *) key_name,
4,
NULL,
0));
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &G_gpg_vstate.work.md.sha256, CX_LAST, h, 2, h, 32));
#ifdef GPG_SHAKE256
cx_shake256_init(&G_gpg_vstate.work.md.sha3, Ski_len);
cx_sha3_update(&G_gpg_vstate.work.md.sha3, h, 32);
cx_sha3_final(&G_gpg_vstate.work.md.sha3, Ski);
CX_CHECK(cx_shake256_init_no_throw(&G_gpg_vstate.work.md.sha3, Ski_len));
CX_CHECK(cx_sha3_update(&G_gpg_vstate.work.md.sha3, h, 32));
CX_CHECK(cx_sha3_final(&G_gpg_vstate.work.md.sha3, Ski));
#else
cx_sha3_xof_init(&G_gpg_vstate.work.md.sha3, 256, Ski_len);
cx_hash((cx_hash_t *) &G_gpg_vstate.work.md.sha3, CX_LAST, h, 32, Ski, Ski_len);
CX_CHECK(cx_sha3_xof_init_no_throw(&G_gpg_vstate.work.md.sha3, 256, Ski_len));
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &G_gpg_vstate.work.md.sha3, CX_LAST, h, 32, Ski, Ski_len));
#endif
end:
if (error != CX_OK) {
THROW(error);
}
}
/* assume command is fully received */
@ -67,6 +84,7 @@ int gpg_apdu_gen() {
gpg_key_t *keygpg;
unsigned char seed[66];
unsigned char *name;
cx_err_t error = CX_INTERNAL_ERROR;
switch ((G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2) {
case 0x8000:
@ -147,16 +165,17 @@ int gpg_apdu_gen() {
gpg_pso_derive_key_seed(seed, name, 2, pq + size, size);
*pq |= 0x80;
*(pq + size) |= 0x80;
cx_math_next_prime(pq, size);
cx_math_next_prime(pq + size, size);
CX_CHECK(cx_math_next_prime_no_throw(pq, size));
CX_CHECK(cx_math_next_prime_no_throw(pq + size, size));
}
cx_rsa_generate_pair(ksz,
rsa_pub,
rsa_priv,
(const unsigned char *) N_gpg_pstate->default_RSA_exponent,
4,
pq);
CX_CHECK(cx_rsa_generate_pair_no_throw(
ksz,
rsa_pub,
rsa_priv,
(const unsigned char *) N_gpg_pstate->default_RSA_exponent,
4,
pq));
nvm_write(pkey, rsa_priv, pkey_size);
nvm_write(&keygpg->pub_key.rsa[0], rsa_pub->e, 4);
@ -182,14 +201,17 @@ int gpg_apdu_gen() {
ksz = gpg_curve2domainlen(curve);
gpg_pso_derive_slot_seed(G_gpg_vstate.slot, seed);
gpg_pso_derive_key_seed(seed, name, 1, seed, ksz);
cx_ecfp_init_private_key(curve, seed, ksz, &G_gpg_vstate.work.ecfp.private);
CX_CHECK(cx_ecfp_init_private_key_no_throw(curve,
seed,
ksz,
&G_gpg_vstate.work.ecfp.private));
keepprivate = 1;
}
cx_ecfp_generate_pair(curve,
&G_gpg_vstate.work.ecfp.public,
&G_gpg_vstate.work.ecfp.private,
keepprivate);
CX_CHECK(cx_ecfp_generate_pair_no_throw(curve,
&G_gpg_vstate.work.ecfp.public,
&G_gpg_vstate.work.ecfp.private,
keepprivate));
nvm_write(&keygpg->priv_key.ecfp,
&G_gpg_vstate.work.ecfp.private,
sizeof(cx_ecfp_private_key_t));
@ -272,9 +294,9 @@ int gpg_apdu_gen() {
memmove(G_gpg_vstate.work.io_buffer + 128,
keygpg->pub_key.ecfp256.W,
keygpg->pub_key.ecfp256.W_len);
cx_edward_compress_point(CX_CURVE_Ed25519,
G_gpg_vstate.work.io_buffer + 128,
65);
CX_CHECK(cx_edwards_compress_point_no_throw(CX_CURVE_Ed25519,
G_gpg_vstate.work.io_buffer + 128,
65));
gpg_io_insert_tlv(0x86,
32,
G_gpg_vstate.work.io_buffer + 129); // 129: discard 02
@ -301,4 +323,6 @@ int gpg_apdu_gen() {
THROW(SW_WRONG_DATA);
return SW_WRONG_DATA;
end:
THROW(error);
}

View File

@ -50,6 +50,7 @@ static int gpg_pin_get_state_index(unsigned int pinref) {
static int gpg_pin_check_internal(gpg_pin_t *pin, unsigned char *pin_val, int pin_len) {
unsigned int counter;
cx_err_t error = CX_INTERNAL_ERROR;
if (pin->counter == 0) {
return SW_PIN_BLOCKED;
@ -58,12 +59,12 @@ static int gpg_pin_check_internal(gpg_pin_t *pin, unsigned char *pin_val, int pi
counter = pin->counter - 1;
gpg_nvm_write(&(pin->counter), &counter, sizeof(int));
cx_sha256_init(&G_gpg_vstate.work.md.sha256);
cx_hash((cx_hash_t *) &G_gpg_vstate.work.md.sha256,
CX_LAST,
pin_val,
pin_len,
G_gpg_vstate.work.md.H,
sizeof(G_gpg_vstate.work.md.H));
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &G_gpg_vstate.work.md.sha256,
CX_LAST,
pin_val,
pin_len,
G_gpg_vstate.work.md.H,
sizeof(G_gpg_vstate.work.md.H)));
if (memcmp(G_gpg_vstate.work.md.H, pin->value, 32)) {
return SW_SECURITY_STATUS_NOT_SATISFIED;
}
@ -71,6 +72,11 @@ static int gpg_pin_check_internal(gpg_pin_t *pin, unsigned char *pin_val, int pi
counter = 3;
gpg_nvm_write(&(pin->counter), &counter, sizeof(int));
return SW_OK;
end:
if (error != CX_OK) {
THROW(error);
}
return SW_UNKNOWN;
}
static void gpg_pin_check_throw(gpg_pin_t *pin, int pinID, unsigned char *pin_val, int pin_len) {
@ -97,15 +103,19 @@ int gpg_pin_check(gpg_pin_t *pin, int pinID, unsigned char *pin_val, unsigned in
void gpg_pin_set(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len) {
cx_sha256_t sha256;
cx_err_t error = CX_INTERNAL_ERROR;
gpg_pin_t newpin;
cx_sha256_init(&sha256);
cx_hash((cx_hash_t *) &sha256, CX_LAST, pin_val, pin_len, newpin.value, 32);
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &sha256, CX_LAST, pin_val, pin_len, newpin.value, 32));
newpin.length = pin_len;
newpin.counter = 3;
gpg_nvm_write(pin, &newpin, sizeof(gpg_pin_t));
end:
if (error != CX_OK) {
THROW(error);
}
}
int gpg_pin_set_verified(int pinID, int verified) {

View File

@ -19,6 +19,7 @@
#include "gpg_api.h"
#include "gpg_vars.h"
#include "gpg_ux_nanos.h"
#include "cx_errors.h"
const unsigned char gpg_oid_sha256[] = {0x30,
0x31,
@ -67,6 +68,7 @@ static void gpg_pso_reset_PW1() {
static int gpg_sign(gpg_key_t *sigkey) {
// --- RSA
cx_err_t error = CX_INTERNAL_ERROR;
if (sigkey->attributes.value[0] == 1) {
cx_rsa_private_key_t *key;
unsigned int ksz, l;
@ -106,13 +108,13 @@ static int gpg_sign(gpg_key_t *sigkey) {
G_gpg_vstate.work.io_buffer[0] = 0;
G_gpg_vstate.work.io_buffer[1] = 1;
G_gpg_vstate.work.io_buffer[l - 1] = 0;
ksz = cx_rsa_decrypt(key,
CX_PAD_NONE,
CX_NONE,
G_gpg_vstate.work.io_buffer,
ksz,
G_gpg_vstate.work.io_buffer,
ksz);
CX_CHECK(cx_rsa_decrypt_no_throw(key,
CX_PAD_NONE,
CX_NONE,
G_gpg_vstate.work.io_buffer,
ksz,
G_gpg_vstate.work.io_buffer,
&ksz));
// send
gpg_io_discard(0);
gpg_io_inserted(ksz);
@ -122,7 +124,8 @@ static int gpg_sign(gpg_key_t *sigkey) {
// --- ECDSA/EdDSA
if ((sigkey->attributes.value[0] == 19) || (sigkey->attributes.value[0] == 22)) {
cx_ecfp_private_key_t *key;
unsigned int sz, i, rs_len, info;
size_t sz;
unsigned int s_len, i, rs_len, info;
unsigned char *rs;
key = &sigkey->priv_key.ecfp;
@ -135,15 +138,16 @@ static int gpg_sign(gpg_key_t *sigkey) {
THROW(SW_CONDITIONS_NOT_SATISFIED);
return SW_CONDITIONS_NOT_SATISFIED;
}
sz = cx_ecdsa_sign(key,
CX_RND_TRNG,
CX_NONE,
G_gpg_vstate.work.io_buffer,
sz,
RS,
256,
&info);
// reencode r,s in MPI format
s_len = 256;
CX_CHECK(cx_ecdsa_sign_no_throw(key,
CX_RND_TRNG,
CX_NONE,
G_gpg_vstate.work.io_buffer,
sz,
RS,
&s_len,
&info));
// re-encode r,s in MPI format
gpg_io_discard(0);
rs_len = RS[3];
@ -161,16 +165,15 @@ static int gpg_sign(gpg_key_t *sigkey) {
rs += 2;
}
} else {
sz = cx_eddsa_sign(key,
CX_NONE,
CX_SHA512,
G_gpg_vstate.work.io_buffer,
G_gpg_vstate.io_length,
NULL,
0,
RS,
256,
NULL);
sz = 256;
CX_CHECK(cx_eddsa_sign_no_throw(key,
CX_SHA512,
G_gpg_vstate.work.io_buffer,
G_gpg_vstate.io_length,
RS,
sz));
CX_CHECK(cx_ecdomain_parameters_length(key->curve, &sz));
sz *= 2;
gpg_io_discard(0);
gpg_io_insert(RS, sz);
}
@ -183,6 +186,8 @@ static int gpg_sign(gpg_key_t *sigkey) {
// --- PSO:CDS NOT SUPPORTED
THROW(SW_REFERENCED_DATA_NOT_FOUND);
return SW_REFERENCED_DATA_NOT_FOUND;
end:
THROW(error);
}
int gpg_apdu_pso() {
@ -190,6 +195,7 @@ int gpg_apdu_pso() {
unsigned int pso;
unsigned int sz;
cx_err_t error = CX_INTERNAL_ERROR;
pso = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2;
@ -239,12 +245,13 @@ int gpg_apdu_pso() {
return SW_CONDITIONS_NOT_SATISFIED;
}
msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset;
sz = cx_aes(key,
CX_ENCRYPT | CX_CHAIN_CBC | CX_LAST,
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
msg_len,
G_gpg_vstate.work.io_buffer + 1,
GPG_IO_BUFFER_LENGTH - 1);
sz = GPG_IO_BUFFER_LENGTH - 1;
CX_CHECK(cx_aes_no_throw(key,
CX_ENCRYPT | CX_CHAIN_CBC | CX_LAST,
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
msg_len,
G_gpg_vstate.work.io_buffer + 1,
&sz));
// send
gpg_io_discard(0);
G_gpg_vstate.work.io_buffer[0] = 0x02;
@ -290,13 +297,15 @@ int gpg_apdu_pso() {
return SW_CONDITIONS_NOT_SATISFIED;
}
msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset;
sz = cx_rsa_decrypt(key,
CX_PAD_PKCS1_1o5,
CX_NONE,
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
msg_len,
G_gpg_vstate.work.io_buffer,
ksz);
sz = ksz;
CX_CHECK(cx_rsa_decrypt_no_throw(
key,
CX_PAD_PKCS1_1o5,
CX_NONE,
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
msg_len,
G_gpg_vstate.work.io_buffer,
&sz));
// send
gpg_io_discard(0);
gpg_io_inserted(sz);
@ -312,12 +321,13 @@ int gpg_apdu_pso() {
return SW_CONDITIONS_NOT_SATISFIED;
}
msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset;
sz = cx_aes(key,
CX_DECRYPT | CX_CHAIN_CBC | CX_LAST,
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
msg_len,
G_gpg_vstate.work.io_buffer,
GPG_IO_BUFFER_LENGTH);
sz = GPG_IO_BUFFER_LENGTH;
CX_CHECK(cx_aes_no_throw(key,
CX_DECRYPT | CX_CHAIN_CBC | CX_LAST,
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
msg_len,
G_gpg_vstate.work.io_buffer,
&sz));
// send
gpg_io_discard(0);
gpg_io_inserted(sz);
@ -360,24 +370,28 @@ int gpg_apdu_pso() {
(G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset)[31 - i];
}
G_gpg_vstate.work.io_buffer[511] = 0x02;
sz = cx_ecdh(key,
CX_ECDH_X,
G_gpg_vstate.work.io_buffer + 511,
65,
G_gpg_vstate.work.io_buffer + 256,
160);
CX_CHECK(cx_ecdh_no_throw(key,
CX_ECDH_X,
G_gpg_vstate.work.io_buffer + 511,
65,
G_gpg_vstate.work.io_buffer + 256,
160));
CX_CHECK(cx_ecdomain_parameters_length(key->curve, &sz));
for (i = 0; i <= 31; i++) {
G_gpg_vstate.work.io_buffer[128 + i] =
G_gpg_vstate.work.io_buffer[287 - i];
}
sz = 32;
} else {
sz = cx_ecdh(key,
CX_ECDH_X,
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
65,
G_gpg_vstate.work.io_buffer + 128,
160);
CX_CHECK(
cx_ecdh_no_throw(key,
CX_ECDH_X,
G_gpg_vstate.work.io_buffer + G_gpg_vstate.io_offset,
65,
G_gpg_vstate.work.io_buffer + 128,
160));
CX_CHECK(cx_ecdomain_parameters_length(key->curve, &sz));
}
// send
gpg_io_discard(0);
@ -399,6 +413,8 @@ int gpg_apdu_pso() {
}
THROW(SW_REFERENCED_DATA_NOT_FOUND);
return SW_REFERENCED_DATA_NOT_FOUND;
end:
THROW(error);
}
int gpg_apdu_internal_authenticate() {