view simtool/miscadm.c @ 99:97ba63d9361a

scripts/fcsim1-sst: turn off STK & OTA services In the initial unprogrammed state of the cards from Grcard, SST has services 25 through 29 set to allocated and activated. However, these cards appear to not actually support OTA, ENVELOPE commands do nothing (just return SW 9000), and they were never observed issuing any proactive SIM commands, even after a feature-generous TERMINAL PROFILE. Therefore, let's list these STK & OTA services as allocated, but not activated in our FCSIM1 SST.
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 05 May 2021 04:26:07 +0000
parents ddd767f6e15b
children 1888d88478c4
line wrap: on
line source

/*
 * This module implements write-iccid and write-imsi commands,
 * available only in the admin programming phase after authenticating
 * with some card-vendor-dependent ADM key.
 */

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

static
write_iccid_bin(binrec)
	u_char *binrec;
{
	int rc;

	rc = select_op(FILEID_MF);
	if (rc < 0)
		return(rc);
	rc = select_op(EF_ICCID);
	if (rc < 0)
		return(rc);
	rc = parse_ef_select_response();
	if (rc < 0)
		return(rc);
	if (curfile_structure != 0x00 || curfile_total_size != 10) {
		fprintf(stderr,
		"error: EF_ICCID is not a transparent EF of 10 bytes\n");
		return(-1);
	}
	return update_bin_op(0, binrec, 10);
}

cmd_write_iccid(argc, argv)
	char **argv;
{
	int rc;
	u_char nibbles[20], binrec[10];

	rc = parse_decimal_string_arg(argv[1], nibbles, 20);
	if (rc < 0)
		return(rc);
	pack_reversed_nibbles(nibbles, binrec, 10);
	return write_iccid_bin(binrec);
}

cmd_write_iccid_sh18(argc, argv)
	char **argv;
{
	int rc;
	u_char nibbles[20], binrec[10];

	rc = parse_decimal_shorthand(argv[1], nibbles, 18);
	if (rc < 0)
		return(rc);
	nibbles[18] = compute_iccid_luhn(nibbles);
	nibbles[19] = 0xF;
	pack_reversed_nibbles(nibbles, binrec, 10);
	return write_iccid_bin(binrec);
}

cmd_write_iccid_sh19(argc, argv)
	char **argv;
{
	int rc;
	u_char nibbles[20], binrec[10];

	rc = parse_decimal_shorthand(argv[1], nibbles, 19);
	if (rc < 0)
		return(rc);
	if (nibbles[18] != compute_iccid_luhn(nibbles)) {
		fprintf(stderr, "error: Luhn check digit mismatch\n");
		return(-1);
	}
	nibbles[19] = 0xF;
	pack_reversed_nibbles(nibbles, binrec, 10);
	return write_iccid_bin(binrec);
}

static
write_imsi_bin(binrec)
	u_char *binrec;
{
	int rc;

	rc = select_op(DF_GSM);
	if (rc < 0)
		return(rc);
	rc = select_op(EF_IMSI);
	if (rc < 0)
		return(rc);
	rc = parse_ef_select_response();
	if (rc < 0)
		return(rc);
	if (curfile_structure != 0x00 || curfile_total_size != 9) {
		fprintf(stderr,
			"error: EF_IMSI is not a transparent EF of 9 bytes\n");
		return(-1);
	}
	return update_bin_op(0, binrec, 9);
}

cmd_write_imsi(argc, argv)
	char **argv;
{
	int rc;
	u_char nibbles[16], binrec[9];
	unsigned ndig;

	rc = parse_decimal_string_arg(argv[1], nibbles + 1, 15);
	if (rc < 0)
		return(rc);
	ndig = rc;
	if (ndig & 1)
		nibbles[0] = 9;
	else
		nibbles[0] = 1;
	binrec[0] = (ndig + 2) >> 1;
	pack_reversed_nibbles(nibbles, binrec + 1, 8);
	return write_imsi_bin(binrec);
}

cmd_write_imsi_sh(argc, argv)
	char **argv;
{
	int rc;
	u_char nibbles[16], binrec[9];

	rc = parse_decimal_shorthand(argv[1], nibbles + 1, 15);
	if (rc < 0)
		return(rc);
	nibbles[0] = 9;
	binrec[0] = 8;
	pack_reversed_nibbles(nibbles, binrec + 1, 8);
	return write_imsi_bin(binrec);
}

static
write_acc_bin(binrec)
	u_char *binrec;
{
	int rc;

	rc = select_op(DF_GSM);
	if (rc < 0)
		return(rc);
	rc = select_op(EF_ACC);
	if (rc < 0)
		return(rc);
	rc = parse_ef_select_response();
	if (rc < 0)
		return(rc);
	if (curfile_structure != 0x00 || curfile_total_size != 2) {
		fprintf(stderr,
			"error: EF_ACC is not a transparent EF of 2 bytes\n");
		return(-1);
	}
	return update_bin_op(0, binrec, 2);
}

cmd_write_acc(argc, argv)
	char **argv;
{
	unsigned acc;
	u_char binrec[2];

	acc = strtoul(argv[1], 0, 16);
	if (acc > 0xFFFF) {
		fprintf(stderr, "error: ACC argument is out of range\n");
		return(-1);
	}
	binrec[0] = acc >> 8;
	binrec[1] = acc;
	return write_acc_bin(binrec);
}

static
write_spn_bin(binrec)
	u_char *binrec;
{
	int rc;

	rc = select_op(DF_GSM);
	if (rc < 0)
		return(rc);
	rc = select_op(EF_SPN);
	if (rc < 0)
		return(rc);
	rc = parse_ef_select_response();
	if (rc < 0)
		return(rc);
	if (curfile_structure != 0x00 || curfile_total_size != 17) {
		fprintf(stderr,
			"error: EF_SPN is not a transparent EF of 17 bytes\n");
		return(-1);
	}
	return update_bin_op(0, binrec, 17);
}

cmd_write_spn(argc, argv)
	char **argv;
{
	u_char binrec[17];
	int rc;

	binrec[0] = strtoul(argv[1], 0, 16);
	memset(binrec + 1, 0xFF, 16);
	rc = qstring_arg_to_gsm7(argv[2], binrec + 1, 16);
	if (rc < 0)
		return(rc);
	return write_spn_bin(binrec);
}