Adding first filesystem layout.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2022-04-20 01:10:41 +02:00
parent 470c866201
commit 3271e0fe33
3 changed files with 256 additions and 9 deletions

View File

@@ -18,10 +18,71 @@
#include "files.h"
extern const uint8_t openpgp_aid[];
extern const uint8_t openpgp_aid_full[];
#define ACL_NONE {0xff,0xff,0xff,0xff,0xff,0xff,0xff}
#define ACL_ALL {0}
#define ACL_RO {0xff,0xff,0xff,0xff,0xff,0xff,0x00}
#define ACL_RW {0xff,0xff,0xff,0xff,0x00,0x00,0x00}
#define ACL_R_WP {0xff,0xff,0xff,0xff,0x90,0x90,0x00}
#define ACL_WP {0xff,0xff,0xff,0xff,0x90,0x90,0xff}
extern int parse_ch_data(const file_t *f, int mode);
extern int parse_sec_tpl(const file_t *f, int mode);
extern int parse_ch_cert(const file_t *f, int mode);
extern int parse_exlen_info(const file_t *f, int mode);
extern int parse_gfm(const file_t *f, int mode);
extern int parse_fp(const file_t *f, int mode);
extern int parse_cafp(const file_t *f, int mode);
extern int parse_ts(const file_t *f, int mode);
extern int parse_keyinfo(const file_t *f, int mode);
extern int parse_algoinfo(const file_t *f, int mode);
extern int parse_app_data(const file_t *f, int mode);
extern int parse_discrete_do(const file_t *f, int mode);
file_t file_entries[] = {
{ .fid = 0x0000, .parent = 0, .name = openpgp_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} },
/* 25 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = {0} } //end
/* 0 */ { .fid = 0x3f00, .parent = 0xff, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, .ef_structure = 0, .acl = ACL_NONE }, // MF
/* 1 */ { .fid = EF_FULL_AID, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = (uint8_t *)openpgp_aid_full, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 2 */ { .fid = EF_CH_NAME, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 3 */ { .fid = EF_LOGIN_DATA, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 4 */ { .fid = EF_LANG_PREF, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 5 */ { .fid = EF_SEX, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 6 */ { .fid = EF_URI_URL, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 7 */ { .fid = EF_HIST_BYTES, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 8 */ { .fid = EF_CH_DATA, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_ch_data, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 9 */ { .fid = EF_SEC_TPL, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_sec_tpl, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 10 */ { .fid = EF_CH_CERT, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_ch_cert, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 11 */ { .fid = EF_EXLEN_INFO, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_exlen_info, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 12 */ { .fid = EF_GFM, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_gfm, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 13 */ { .fid = EF_SIG_COUNT, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 14 */ { .fid = EF_EXT_CAP, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 15 */ { .fid = EF_ALGO_SIG, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 16 */ { .fid = EF_ALGO_DEC, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 17 */ { .fid = EF_ALGO_AUT, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 18 */ { .fid = EF_PW_STATUS, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 19 */ { .fid = EF_FP, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_fp, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 20 */ { .fid = EF_FP_SIG, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 21 */ { .fid = EF_FP_DEC, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 22 */ { .fid = EF_FP_AUT, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 23 */ { .fid = EF_CA_FP, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_cafp, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 24 */ { .fid = EF_FP_CA1, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 25 */ { .fid = EF_FP_CA2, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 26 */ { .fid = EF_FP_CA3, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 27 */ { .fid = EF_TS_ALL, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_ts, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 28 */ { .fid = EF_TS_SIG, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 29 */ { .fid = EF_TS_DEC, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 30 */ { .fid = EF_TS_AUT, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 31 */ { .fid = EF_RESET_CODE, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP },
/* 32 */ { .fid = EF_UIF_SIG, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 33 */ { .fid = EF_UIF_DEC, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 34 */ { .fid = EF_UIF_AUT, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
/* 35 */ { .fid = EF_KEY_INFO, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_keyinfo, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 36 */ { .fid = EF_ALGO_INFO, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_algoinfo, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 37 */ { .fid = EF_APP_DATA, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_app_data, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 38 */ { .fid = EF_DISCRETE_DO, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_discrete_do, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 39 */ { .fid = 0x0000, .parent = 0, .name = openpgp_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
/* 40 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = ACL_NONE } //end
};
const file_t *MF = &file_entries[0];

View File

@@ -21,4 +21,44 @@
#include "file.h"
#define EF_EXT_HEADER 0x004d //C
#define EF_FULL_AID 0x004f //S
#define EF_CH_NAME 0x005b //S
#define EF_LOGIN_DATA 0x005e //S
#define EF_CH_DATA 0x0065 //C
#define EF_APP_DATA 0x006e //C
#define EF_DISCRETE_DO 0x0073 //C
#define EF_SEC_TPL 0x007a //C
#define EF_SIG_COUNT 0x0093 //S
#define EF_EXT_CAP 0x00c0 //S
#define EF_ALGO_SIG 0x00c1 //S
#define EF_ALGO_DEC 0x00c2 //S
#define EF_ALGO_AUT 0x00c3 //S
#define EF_PW_STATUS 0x00c4 //S
#define EF_FP 0x00c5 //S
#define EF_CA_FP 0x00c6 //S
#define EF_FP_SIG 0x00c7 //S
#define EF_FP_DEC 0x00c8 //S
#define EF_FP_AUT 0x00c9 //S
#define EF_FP_CA1 0x00ca //S
#define EF_FP_CA2 0x00cb //S
#define EF_FP_CA3 0x00cc //S
#define EF_TS_ALL 0x00cd //S
#define EF_TS_SIG 0x00ce //S
#define EF_TS_DEC 0x00cf //S
#define EF_TS_AUT 0x00d0 //S
#define EF_RESET_CODE 0x00d3 //S
#define EF_UIF_SIG 0x00d6 //S
#define EF_UIF_DEC 0x00d7 //S
#define EF_UIF_AUT 0x00d8 //S
#define EF_KEY_INFO 0x00de //S
#define EF_ALGO_INFO 0x00fa //C
#define EF_LANG_PREF 0x5f2d //S
#define EF_SEX 0x5f35 //S
#define EF_URI_URL 0x5f50 //S
#define EF_HIST_BYTES 0x5f52 //S
#define EF_CH_CERT 0x7f21 //C
#define EF_EXLEN_INFO 0x7f66 //C
#define EF_GFM 0x7f74 //C
#endif

View File

@@ -17,11 +17,18 @@
#include "openpgp.h"
#include "version.h"
#include "files.h"
#include "eac.h"
const uint8_t openpgp_aid[] = {
uint8_t openpgp_aid[] = {
6,
0xD2,0x76,0x00,0x01,0x24,0x01
0xD2,0x76,0x00,0x01,0x24,0x01,
};
uint8_t openpgp_aid_full[] = {
16,00,
0xD2,0x76,0x00,0x01,0x24,0x01,
OPGP_VERSION_MAJOR,OPGP_VERSION_MINOR,0xff,0xfe,0xff,0xff,0xff,0xff,0x00,0x00
};
char atr_openpgp[] = {
@@ -121,8 +128,17 @@ static int cmd_select() {
return SW_OK ();
}
void scan_files() {
file_t *ef;
if ((ef = search_by_fid(EF_FULL_AID, NULL, SPECIFY_ANY))) {
ef->data = openpgp_aid_full;
pico_get_unique_board_id_string(ef->data+12, 4);
}
}
void init_openpgp() {
isUserAuthenticated = false;
scan_files();
cmd_select();
}
@@ -132,11 +148,7 @@ int openpgp_unload() {
}
app_t *openpgp_select_aid(app_t *a) {
printf("AIDS \r\n");
DEBUG_PAYLOAD(apdu.cmd_apdu_data,apdu.cmd_apdu_data_len);
DEBUG_PAYLOAD(openpgp_aid+1,openpgp_aid[0]);
if (!memcmp(apdu.cmd_apdu_data, openpgp_aid+1, MIN(apdu.cmd_apdu_data_len,openpgp_aid[0]))) {
printf("SELECTING OPENPGP\r\n");
if (!memcmp(apdu.cmd_apdu_data, openpgp_aid+1, openpgp_aid[0])) {
a->aid = openpgp_aid;
a->process_apdu = openpgp_process_apdu;
a->unload = openpgp_unload;
@@ -151,13 +163,147 @@ void __attribute__ ((constructor)) openpgp_ctor() {
register_app(openpgp_select_aid);
}
int parse_do(uint16_t *fids, int mode) {
int len = 0;
file_t *ef;
for (int i = 0; i < fids[0]; i++) {
if ((ef = search_by_fid(fids[i+1], NULL, SPECIFY_EF)) && ef->data) {
uint16_t data_len;
if ((ef->type & FILE_DATA_FUNC) == FILE_DATA_FUNC) {
data_len = ((int (*)(const file_t *, int))(ef->data))((const file_t *)ef, 1);
}
else {
data_len = file_read_uint16(ef->data);
if (mode == 1) {
if (fids[0] > 1) {
if (fids[i+1] < 0x0100) {
res_APDU[res_APDU_size++] = fids[i+1] & 0xff;
}
else {
res_APDU[res_APDU_size++] = fids[i+1] >> 8;
res_APDU[res_APDU_size++] = fids[i+1] & 0xff;
}
res_APDU_size += format_tlv_len(data_len, res_APDU);
}
memcpy(res_APDU+res_APDU_size, file_read(ef->data+2), data_len);
res_APDU_size += data_len;
}
}
len += data_len;
}
}
return len;
}
int parse_trium(uint16_t fid, uint8_t num, size_t size) {
for (uint8_t i = 0; i < num; i++) {
file_t *ef;
if ((ef = search_by_fid(fid+i, NULL, SPECIFY_EF)) && ef->data) {
uint16_t data_len = file_read_uint16(ef->data);
memcpy(res_APDU+res_APDU_size, file_read(ef->data+2), data_len);
res_APDU_size += data_len;
}
else {
memset(res_APDU+res_APDU_size, 0, size);
res_APDU_size += size;
}
}
return num*size;
}
int parse_ch_data(const file_t *f, int mode) {
uint16_t fids[] = {
3,
EF_CH_NAME, EF_LANG_PREF, EF_SEX
};
return parse_do(fids, mode);
}
int parse_sec_tpl(const file_t *f, int mode) {
}
int parse_ch_cert(const file_t *f, int mode) {
}
int parse_exlen_info(const file_t *f, int mode) {
}
int parse_gfm(const file_t *f, int mode) {
}
int parse_fp(const file_t *f, int mode) {
return parse_trium(EF_FP_SIG, 3, 20);
}
int parse_cafp(const file_t *f, int mode) {
return parse_trium(EF_FP_CA1, 3, 20);
}
int parse_ts(const file_t *f, int mode) {
return parse_trium(EF_TS_SIG, 3, 4);
}
int parse_keyinfo(const file_t *f, int mode) {
}
int parse_algoinfo(const file_t *f, int mode) {
}
int parse_app_data(const file_t *f, int mode) {
uint16_t fids[] = {
5,
EF_FULL_AID, EF_HIST_BYTES, EF_EXLEN_INFO, EF_GFM, EF_DISCRETE_DO
};
return parse_do(fids, mode);
}
int parse_discrete_do(const file_t *f, int mode) {
uint16_t fids[] = {
11,
EF_EXT_CAP, EF_ALGO_SIG, EF_ALGO_DEC, EF_ALGO_AUT, EF_PW_STATUS, EF_FP, EF_CA_FP, EF_TS_ALL, EF_UIF_SIG, EF_UIF_DEC, EF_UIF_AUT
};
return parse_do(fids, mode);
}
static int cmd_get_data() {
if (apdu.cmd_apdu_data_len > 0)
return SW_WRONG_LENGTH();
uint16_t fid = (P1(apdu) << 8) | P2(apdu);
file_t *ef;
if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF)))
return SW_FILE_NOT_FOUND();
if (!authenticate_action(ef, ACL_OP_READ_SEARCH)) {
return SW_SECURITY_STATUS_NOT_SATISFIED();
}
if (ef->data) {
uint16_t fids[] = {1,fid};
uint16_t data_len = parse_do(fids, 1);
if (apdu.expected_res_size > data_len)
apdu.expected_res_size = data_len;
}
return SW_OK();
}
typedef struct cmd
{
uint8_t ins;
int (*cmd_handler)();
} cmd_t;
#define INS_SELECT 0xA4
#define INS_GET_DATA 0xCA
static const cmd_t cmds[] = {
{ INS_GET_DATA, cmd_get_data },
{ INS_SELECT, cmd_select },
{ 0x00, 0x0}
};