view simtool/sjs1_hacks.c @ 93:6041c601304d

fcsim1-mkprov: revert OTA key addition It appears that GrcardSIM2 cards (which is what we got for FCSIM1) do not support OTA after all, contrary to what we were previously led to believe by some tech support emails from Grcard - apparently those support emails and OTA descriptions referred to some other card model(s).
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 21 Apr 2021 05:38:39 +0000
parents ddd767f6e15b
children
line wrap: on
line source

/*
 * This module implements a few special commands for the recently
 * discontinued sysmoUSIM-SJS1 card model from Sysmocom.  These commands
 * are NOT applicable to the successor sysmoISIM-SJA2 card model!
 */

#include <sys/types.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include "simresp.h"
#include "curfile.h"
#include "file_id.h"

/*
 * SJS1 is natively a UICC, supporting the classic GSM 11.11 SIM protocol
 * only as a backward compatibility mode.  The makers of that UICC CardOS
 * clearly did not want people to do administrative programming via the
 * GSM 11.11 SIM protocol, instead their vision was that admin programming
 * should only be done in UICC mode.  Toward this end, SJS1 cards do not
 * accept VERIFY CHV commands with CLA=0xA0 P2=0x0A for ADM1 authentication,
 * instead they only accept VERIFY PIN with CLA=0x00 for this purpose.
 *
 * They did leave one open loophole, however: if the UICC-style VERIFY PIN
 * command with P2=0x0A for ADM1 authentication is given as the very first
 * command in the card session, then it can be followed either by other
 * UICC protocol commands (making a UICC card session), or by CLA=0xA0
 * protocol commands, making a GSM 11.11 SIM session with ADM1 authentication.
 * In other words, they allow one special exception to the general rule
 * where SIM and UICC protocol commands are never allowed to mix in the
 * same card session.
 */

cmd_verify_sjs1_adm1(argc, argv)
	char **argv;
{
	u_char cmd[13];
	int rc;

	/* UICC-style VERIFY PIN command APDU */
	cmd[0] = 0x00;
	cmd[1] = 0x20;
	cmd[2] = 0x00;
	cmd[3] = 0x0A;
	cmd[4] = 8;
	rc = encode_pin_entry(argv[1], cmd + 5);
	if (rc < 0)
		return(rc);
	rc = apdu_exchange(cmd, 13);
	if (rc < 0)
		return(rc);
	if (sim_resp_sw != 0x9000) {
		fprintf(stderr, "bad SW response: %04X\n", sim_resp_sw);
		return(-1);
	}
	return(0);
}

/*
 * Early sysmoUSIM-SJS1 cards (those sold in 2017, but not the very last
 * ones sold in late 2020) were shipped with a misprogrammed MSISDN record.
 * Our fix-sysmo-msisdn command fixes this particular misprogramming.
 */

cmd_fix_sysmo_msisdn()
{
	int rc;
	unsigned n;
	u_char newrec[34];

	rc = select_op(DF_TELECOM);
	if (rc < 0)
		return(rc);
	rc = select_op(EF_MSISDN);
	if (rc < 0)
		return(rc);
	rc = parse_ef_select_response();
	if (rc < 0)
		return(rc);
	if (curfile_structure != 0x01) {
		fprintf(stderr, "error: EF_MSISDN is not linear fixed\n");
		return(-1);
	}
	if (curfile_record_len != 34) {
		fprintf(stderr,
		"error: expected EF_MSISDN record length of 34 bytes, got %u\n",
			curfile_record_len);
		return(-1);
	}
	rc = readrec_op(1, 0x04, 34);
	if (rc < 0)
		return(rc);
	for (n = 0; n < 18; n++) {
		if (sim_resp_data[n] != 0xFF) {
			fprintf(stderr,
		"error: non-FF data in the first 18 bytes of alpha tag area\n");
			return(-1);
		}
	}
	if (sim_resp_data[18] == 0xFF && sim_resp_data[19] == 0xFF) {
		printf(
		"last 2 bytes of alpha tag area are clear - already fixed?\n");
		return(0);
	}
	if (sim_resp_data[18] != 0x07 || sim_resp_data[19] != 0x91) {
		fprintf(stderr,
	"error: bytes 18 & 19 don't match expected bogus programming\n");
		return(-1);
	}
	memset(newrec, 0xFF, 34);
	memcpy(newrec + 20, sim_resp_data + 18, 8);
	return update_rec_op(1, 0x04, newrec, 34);
}