Upgrade to version 3.2

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2025-01-15 11:24:15 +01:00
28 changed files with 1907 additions and 1481 deletions

View File

@@ -0,0 +1,138 @@
/*
* This file is part of the Pico OpenPGP distribution (https://github.com/polhenarejos/pico-openpgp).
* Copyright (c) 2022 Pol Henarejos.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "openpgp.h"
#include "do.h"
#include "random.h"
int cmd_keypair_gen() {
if (P2(apdu) != 0x0) {
return SW_INCORRECT_P1P2();
}
if (apdu.nc != 2 && apdu.nc != 5) {
return SW_WRONG_LENGTH();
}
if (!has_pw3 && P1(apdu) == 0x80) {
return SW_SECURITY_STATUS_NOT_SATISFIED();
}
uint16_t fid = 0x0;
int r = PICOKEY_OK;
if (apdu.data[0] == 0xB6) {
fid = EF_PK_SIG;
}
else if (apdu.data[0] == 0xB8) {
fid = EF_PK_DEC;
}
else if (apdu.data[0] == 0xA4) {
fid = EF_PK_AUT;
}
else {
return SW_WRONG_DATA();
}
file_t *algo_ef = search_by_fid(fid - 0x0010, NULL, SPECIFY_EF);
if (!algo_ef) {
return SW_REFERENCE_NOT_FOUND();
}
const uint8_t *algo = algorithm_attr_rsa2k + 1;
uint16_t algo_len = algorithm_attr_rsa2k[0];
if (algo_ef && algo_ef->data) {
algo = file_get_data(algo_ef);
algo_len = file_get_size(algo_ef);
}
if (P1(apdu) == 0x80) { //generate
if (algo[0] == ALGO_RSA) {
int exponent = 65537, nlen = (algo[1] << 8) | algo[2];
printf("KEYPAIR RSA %d\r\n", nlen);
//if (nlen != 2048 && nlen != 4096)
// return SW_FUNC_NOT_SUPPORTED();
mbedtls_rsa_context rsa;
mbedtls_rsa_init(&rsa);
uint8_t index = 0;
r = mbedtls_rsa_gen_key(&rsa, random_gen, &index, nlen, exponent);
if (r != 0) {
mbedtls_rsa_free(&rsa);
return SW_EXEC_ERROR();
}
r = store_keys(&rsa, ALGO_RSA, fid, true);
make_rsa_response(&rsa);
mbedtls_rsa_free(&rsa);
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
}
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA || algo[0] == ALGO_EDDSA) {
printf("KEYPAIR ECDSA\r\n");
mbedtls_ecp_group_id gid = get_ec_group_id_from_attr(algo + 1, algo_len - 1);
if (gid == MBEDTLS_ECP_DP_NONE) {
return SW_FUNC_NOT_SUPPORTED();
}
mbedtls_ecp_keypair ecdsa;
mbedtls_ecp_keypair_init(&ecdsa);
uint8_t index = 0;
r = mbedtls_ecdsa_genkey(&ecdsa, gid, random_gen, &index);
if (r != 0) {
mbedtls_ecp_keypair_free(&ecdsa);
return SW_EXEC_ERROR();
}
r = store_keys(&ecdsa, algo[0], fid, true);
make_ecdsa_response(&ecdsa);
mbedtls_ecp_keypair_free(&ecdsa);
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
}
else {
return SW_FUNC_NOT_SUPPORTED();
}
file_t *pbef = search_by_fid(fid + 3, NULL, SPECIFY_EF);
if (!pbef) {
return SW_REFERENCE_NOT_FOUND();
}
r = file_put_data(pbef, res_APDU, res_APDU_size);
if (r != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
if (fid == EF_PK_SIG) {
reset_sig_count();
}
else if (fid == EF_PK_DEC) {
// OpenPGP does not allow generating AES keys. So, we generate a new one when gen for DEC is called.
// It is a 256 AES key by default.
uint8_t aes_key[32]; //maximum AES key size
uint8_t key_size = 32;
memcpy(aes_key, random_bytes_get(key_size), key_size);
r = store_keys(aes_key, ALGO_AES_256, EF_AES_KEY, true);
/* if storing the key fails, we silently continue */
//if (r != PICOKEY_OK)
// return SW_EXEC_ERROR();
}
low_flash_available();
return SW_OK();
}
else if (P1(apdu) == 0x81) { //read
file_t *ef = search_by_fid(fid + 3, NULL, SPECIFY_EF);
if (!ef || !ef->data) {
return SW_REFERENCE_NOT_FOUND();
}
res_APDU_size = file_get_size(ef);
memcpy(res_APDU, file_get_data(ef), res_APDU_size);
return SW_OK();
}
return SW_INCORRECT_P1P2();
}