Example #1
0
/**
 * Start with a good voice frame and then simulate 20 consecutive bad frames,
 * watching how the error concealment decreases the XMAXC parameters.
 */
void test_fr_concealment(void)
{
	struct osmo_ecu_fr_state state;
	uint8_t frame[GSM_FR_BYTES];
	uint64_t xmaxc[4];
	int i, rc;
	int j = 0;

	while (sample_frame_hex[j] != NULL) {
		/* Parse frame from string to hex */
		osmo_hexparse(sample_frame_hex[j], frame, GSM_FR_BYTES);
		parse_xmaxc_frame(frame, xmaxc);
		printf("Start with: %s, XMAXC: [%"PRIx64", %"PRIx64", %"PRIx64", %"PRIx64"]\n",
		       sample_frame_hex[j], xmaxc[0], xmaxc[1], xmaxc[2], xmaxc[3]);

		/* Reset the ECU with the proposed known good frame */
		osmo_ecu_fr_reset(&state, frame);

		/* Now pretend that we do not receive any good frames anymore */
		for (i = 0; i < 20; i++) {

			rc = osmo_ecu_fr_conceal(&state, frame);
			OSMO_ASSERT(rc == 0);
			parse_xmaxc_frame(frame, xmaxc);

			printf("conceal: %02i, result: %s XMAXC: [%"PRIx64", %"PRIx64", %"PRIx64", %"PRIx64"]\n",
			       i, osmo_hexdump_nospc(frame, GSM_FR_BYTES),
			       xmaxc[0], xmaxc[1], xmaxc[2], xmaxc[3]);
		}

		/* Go to the next frame */
		j++;
	}
}
Example #2
0
/* Simulate a real life situation: voice frames with a few dropouts */
void test_fr_concealment_realistic()
{
	struct osmo_ecu_fr_state state;
	uint8_t frame[GSM_FR_BYTES];
	unsigned int frame_len;
	int rc, i = 0;

	while (fr_frames_hex[i] != NULL) {
		/* Debug print */
		printf("Frame No. %03i:\n", i);

		/* Good or bad frame? */
		frame_len = strlen(fr_frames_hex[i]) / 2;
		if (frame_len == GSM_FR_BYTES) {
			printf(" * input:  %s\n", fr_frames_hex[i]);
			osmo_hexparse(fr_frames_hex[i], frame, GSM_FR_BYTES);
			osmo_ecu_fr_reset(&state, frame);
		} else {
			printf(" * input:  (bad)\n");
			memset(frame, 0x00, GSM_FR_BYTES);
			rc = osmo_ecu_fr_conceal(&state, frame);
			OSMO_ASSERT(rc == 0);
		}

		/* Print result */
		printf(" * output: %s\n",
			osmo_hexdump_nospc(frame, GSM_FR_BYTES));

		/* Go to the next frame */
		i++;
	}
}
Example #3
0
static inline void test_gea(bool v4, char *kc, uint32_t iv, int dir,
			    uint16_t len, char *res)
{
    uint8_t out[len], ck[256];
    printf("len %d, dir %d, INPUT 0x%X -> ", len, dir, iv);
    osmo_hexparse(kc, ck, len);
    int t = gprs_cipher_run(out, len, v4 ? GPRS_ALGO_GEA4 : GPRS_ALGO_GEA3, ck,
			    iv, dir);
    printf("%s ", t < 0 ? strerror(-t) : "OK");
    print_check(res, out, len);
}
Example #4
0
static inline void print_check(char *res, uint8_t *out, uint16_t len)
{
    uint8_t buf[len];
    osmo_hexparse(res, buf, len);
    if (0 != memcmp(buf, out, len)) {
	printf("FAIL:\n");
	printf("OUT: %s\n", osmo_hexdump_nospc(out, len));
	printf("EXP: %s\n", osmo_hexdump_nospc(buf, len));
    } else
	    printf("\n");
}
Example #5
0
inline bool test_a5(int n, char * kc, uint32_t count, char * block1, char * block2) {
    ubit_t out[114];
    int k = (n == 4) ? 16 : 8;
    uint8_t key[k];
    osmo_hexparse(kc, key, k);

    osmo_a5(n, key, count, out, NULL);
    bool d = print_a5(n, k, "DL", out, block1);

    osmo_a5(n, key, count, NULL, out);
    bool u = print_a5(n, k, "UL", out, block2);

    return d & u;
}
Example #6
0
inline bool print_a5(int n, int k, char * dir, ubit_t * out, char * block) {
    uint8_t len = 114 / 8 + 1, buf[len], res[len];
    printf("A5/%d - %s: %s => ", n, dir, osmo_ubit_dump(out, 114));
    osmo_hexparse(block, res, len);
    osmo_ubit2pbit(buf, out, 114);
    if (0 != memcmp(buf, res, len)) {
	printf("FAIL");
	printf("\nGOT: [%d] %s", k, osmo_hexdump_nospc(buf, len));
	printf("\nEXP: [%d] %s\n", k, osmo_hexdump_nospc(res, len));
	return false;
    }
    printf("OK\n");
    return true;
}
Example #7
0
static void test_oap_api(void)
{
	printf("Testing OAP API\n  - Config parsing\n");

	struct oap_config _config;
	struct oap_config *config = &_config;

	struct oap_state _state;
	struct oap_state *state = &_state;

	memset(config, 0, sizeof(*config));
	memset(state, 0, sizeof(*state));

	OSMO_ASSERT(osmo_hexparse("0102030405060708090a0b0c0d0e0f10", config->secret_k, 16) == 16);
	OSMO_ASSERT(osmo_hexparse("1112131415161718191a1b1c1d1e1f20", config->secret_opc, 16) == 16);

	/* make sure filling with zeros means uninitialized */
	OSMO_ASSERT(state->state == OAP_UNINITIALIZED);

	/* invalid client_id and shared secret */
	config->client_id = 0;
	config->secret_k_present = 0;
	config->secret_opc_present = 0;
	OSMO_ASSERT( oap_init(config, state) == 0 );
	OSMO_ASSERT(state->state == OAP_DISABLED);

	/* reset state */
	memset(state, 0, sizeof(*state));

	/* only client_id is invalid */
	config->client_id = 0;
	config->secret_k_present = 1;
	config->secret_opc_present = 1;
	OSMO_ASSERT( oap_init(config, state) == 0 );
	OSMO_ASSERT(state->state == OAP_DISABLED);

	memset(state, 0, sizeof(*state));

	/* valid id, but omitted shared_secret (1/2) */
	config->client_id = 12345;
	config->secret_k_present = 0;
	config->secret_opc_present = 1;
	OSMO_ASSERT( oap_init(config, state) == 0 );
	OSMO_ASSERT(state->state == OAP_DISABLED);

	memset(state, 0, sizeof(*state));

	/* valid id, but omitted shared_secret (2/2) */
	config->client_id = 12345;
	config->secret_k_present = 1;
	config->secret_opc_present = 0;
	OSMO_ASSERT( oap_init(config, state) == 0 );
	OSMO_ASSERT(state->state == OAP_DISABLED);

	memset(state, 0, sizeof(*state));


	/* mint configuration */
	config->client_id = 12345;
	config->secret_k_present = 1;
	config->secret_opc_present = 1;
	/*config->secret_* buffers are still set from the top */
	OSMO_ASSERT( oap_init(config, state) == 0 );
	OSMO_ASSERT(state->state == OAP_INITIALIZED);

	printf("  - AUTN failures\n");

	struct oap_message oap_rx;
	struct oap_message oap_tx;
	struct msgb *msg_rx;
	struct msgb *msg_tx;

	memset(&oap_rx, 0, sizeof(oap_rx));

	/* Missing challenge data */
	oap_rx.message_type = OAP_MSGT_CHALLENGE_REQUEST;
	oap_rx.rand_present = 0;
	oap_rx.autn_present = 0;
	msg_rx = oap_encoded(&oap_rx);
	OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -2);
	msgb_free(msg_rx);
	OSMO_ASSERT(!msg_tx);

	/* AUTN missing */
	osmo_hexparse("0102030405060708090a0b0c0d0e0f10",
		      oap_rx.rand, 16);
	oap_rx.rand_present = 1;
	msg_rx = oap_encoded(&oap_rx);
	OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -2);
	msgb_free(msg_rx);
	OSMO_ASSERT(!msg_tx);

	/* RAND missing */
	oap_rx.rand_present = 0;
	osmo_hexparse("cec4e3848a33000086781158ca40f136",
		      oap_rx.autn, 16);
	oap_rx.autn_present = 1;
	msg_rx = oap_encoded(&oap_rx);
	OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -2);
	msgb_free(msg_rx);
	OSMO_ASSERT(!msg_tx);

	/* wrong autn (by one bit) */
	osmo_hexparse("0102030405060708090a0b0c0d0e0f10",
		      oap_rx.rand, 16);
	osmo_hexparse("dec4e3848a33000086781158ca40f136",
		      oap_rx.autn, 16);
	oap_rx.rand_present = 1;
	oap_rx.autn_present = 1;
	msg_rx = oap_encoded(&oap_rx);
	OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -2);
	msgb_free(msg_rx);
	OSMO_ASSERT(!msg_tx);

	/* all data correct */
	osmo_hexparse("cec4e3848a33000086781158ca40f136",
		      oap_rx.autn, 16);
	msg_rx = oap_encoded(&oap_rx);

	/* but refuse to evaluate in uninitialized state */
	OSMO_ASSERT(state->state == OAP_INITIALIZED);

	state->state = OAP_UNINITIALIZED;
	OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -1);
	OSMO_ASSERT(!msg_tx);

	state->state = OAP_DISABLED;
	OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -1);
	OSMO_ASSERT(!msg_tx);

	state->state = OAP_INITIALIZED;

	/* now everything is correct */
	printf("  - AUTN success\n");
	/* a successful return value here indicates correct autn */
	OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == 0);
	msgb_free(msg_rx);

	/* Expect the challenge response in msg_tx */
	OSMO_ASSERT(msg_tx);
	OSMO_ASSERT(oap_decode(msg_tx->data, msg_tx->len, &oap_tx) == 0);
	OSMO_ASSERT(oap_tx.message_type == OAP_MSGT_CHALLENGE_RESULT);
	OSMO_ASSERT(strcmp("e2d05b598c61d9ba",
			   osmo_hexdump_nospc(oap_tx.xres, sizeof(oap_tx.xres)))
		    == 0);
	OSMO_ASSERT(state->state == OAP_SENT_CHALLENGE_RESULT);
	msgb_free(msg_tx);
	msg_tx = 0;

	struct oap_state saved_state = _state;

	printf("  - Registration failure\n");

	memset(&oap_rx, 0, sizeof(oap_rx));
	oap_rx.message_type = OAP_MSGT_REGISTER_ERROR;
	oap_rx.cause = GMM_CAUSE_PROTO_ERR_UNSPEC;
	msg_rx = oap_encoded(&oap_rx);

	/* Receive registration error for the first time. */
	OSMO_ASSERT(state->registration_failures == 0);
	OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == 0);
	OSMO_ASSERT(state->registration_failures == 1);
	OSMO_ASSERT(msg_tx);
	OSMO_ASSERT(oap_decode(msg_tx->data, msg_tx->len, &oap_tx) == 0);
	OSMO_ASSERT(oap_tx.message_type == OAP_MSGT_REGISTER_REQUEST);
	OSMO_ASSERT(state->state == OAP_REQUESTED_CHALLENGE);
	msgb_free(msg_tx);
	msg_tx = 0;

	/* Receive registration error for the Nth time. */
	state->registration_failures = 999;
	OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -11);
	OSMO_ASSERT(!msg_tx);
	OSMO_ASSERT(state->state == OAP_INITIALIZED);
	msgb_free(msg_tx);
	msg_tx = 0;

	msgb_free(msg_rx);

	printf("  - Registration success\n");

	_state = saved_state;
	memset(&oap_rx, 0, sizeof(oap_rx));
	oap_rx.message_type = OAP_MSGT_REGISTER_RESULT;
	msg_rx = oap_encoded(&oap_rx);
	OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == 0);
	OSMO_ASSERT(!msg_tx);
	OSMO_ASSERT(state->state == OAP_REGISTERED);
	msgb_free(msg_rx);
}
Example #8
0
int main(int argc, char **argv)
{
	struct osmo_auth_vector _vec;
	struct osmo_auth_vector *vec = &_vec;
	uint8_t _rand[16], _auts[16];
	int rc, option_index;
	int rand_is_set = 0;
	int auts_is_set = 0;
	int fmt_triplets_dat = 0;

	printf("osmo-auc-gen (C) 2011-2012 by Harald Welte\n");
	printf("This is FREE SOFTWARE with ABSOLUTELY NO WARRANTY\n\n");

	memset(_auts, 0, sizeof(_auts));

	while (1) {
		int c;
		unsigned long ul;
		static struct option long_options[] = {
			{ "2g", 0, 0, '2' },
			{ "3g", 0, 0, '3' },
			{ "algorithm", 1, 0, 'a' },
			{ "key", 1, 0, 'k' },
			{ "opc", 1, 0, 'o' },
			{ "op", 1, 0, 'O' },
			{ "amf", 1, 0, 'f' },
			{ "sqn", 1, 0, 's' },
			{ "rand", 1, 0, 'r' },
			{ "auts", 1, 0, 'A' },
			{ "help", 0, 0, 'h' },
			{ 0, 0, 0, 0 }
		};

		rc = 0;

		c = getopt_long(argc, argv, "23a:k:o:f:s:r:hO:A:I", long_options,
				&option_index);

		if (c == -1)
			break;

		switch (c) {
		case '2':
			test_aud.type = OSMO_AUTH_TYPE_GSM;
			break;
		case '3':
			test_aud.type = OSMO_AUTH_TYPE_UMTS;
			break;
		case 'a':
			rc = osmo_auth_alg_parse(optarg);
			if (rc < 0)
				break;
			test_aud.algo = rc;
			break;
		case 'k':
			switch (test_aud.type) {
			case OSMO_AUTH_TYPE_GSM:
				rc = osmo_hexparse(optarg, test_aud.u.gsm.ki,
						   sizeof(test_aud.u.gsm.ki));
				break;
			case OSMO_AUTH_TYPE_UMTS:
				rc = osmo_hexparse(optarg, test_aud.u.umts.k,
						   sizeof(test_aud.u.umts.k));
				break;
			default:
				fprintf(stderr, "please specify 2g/3g first!\n");
			}
			break;
		case 'o':
			if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
				fprintf(stderr, "Only UMTS has OPC\n");
				exit(2);
			}
			rc = osmo_hexparse(optarg, test_aud.u.umts.opc,
					   sizeof(test_aud.u.umts.opc));
			test_aud.u.umts.opc_is_op = 0;
			break;
		case 'O':
			if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
				fprintf(stderr, "Only UMTS has OP\n");
				exit(2);
			}
			rc = osmo_hexparse(optarg, test_aud.u.umts.opc,
					   sizeof(test_aud.u.umts.opc));
			test_aud.u.umts.opc_is_op = 1;
			break;
		case 'A':
			if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
				fprintf(stderr, "Only UMTS has AUTS\n");
				exit(2);
			}
			rc = osmo_hexparse(optarg, _auts, sizeof(_auts));
			auts_is_set = 1;
			break;
		case 'f':
			if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
				fprintf(stderr, "Only UMTS has AMF\n");
				exit(2);
			}
			rc = osmo_hexparse(optarg, test_aud.u.umts.amf,
					   sizeof(test_aud.u.umts.amf));
			break;
		case 's':
			if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
				fprintf(stderr, "Only UMTS has SQN\n");
				exit(2);
			}
			ul = strtoul(optarg, 0, 10);
			test_aud.u.umts.sqn = ul;
			break;
		case 'r':
			rc = osmo_hexparse(optarg, _rand, sizeof(_rand));
			rand_is_set = 1;
			break;
		case 'I':
			fmt_triplets_dat = 1;
			break;
		case 'h':
			help();
			exit(0);
		default:
			help();
			exit(1);
		}

		if (rc < 0) {
			fprintf(stderr, "Error parsing argument of option `%c'\n", c);
			exit(2);
		}
	}

	if (!rand_is_set) {
		int i;
		printf("WARNING: We're using really weak random numbers!\n\n");
		srand(time(NULL));

		for (i = 0; i < 4; ++i) {
			uint32_t r;
			r = rand();
			memcpy(&_rand[i*4], &r, 4);
		}
	}

	if (test_aud.type == OSMO_AUTH_TYPE_NONE ||
	    test_aud.algo == OSMO_AUTH_ALG_NONE) {
		help();
		exit(2);
	}

	memset(vec, 0, sizeof(*vec));

	if (!auts_is_set)
		rc = osmo_auth_gen_vec(vec, &test_aud, _rand);
	else
		rc = osmo_auth_gen_vec_auts(vec, &test_aud, _auts, _rand, _rand);
	if (rc < 0) {
		if (!auts_is_set)
			fprintf(stderr, "error generating auth vector\n");
		else
			fprintf(stderr, "AUTS from MS seems incorrect\n");
		exit(1);
	}

	if (fmt_triplets_dat)
		dump_triplets_dat(vec);
	else
		dump_auth_vec(vec);

	if (auts_is_set)
		printf("AUTS success: SEQ.MS = %" PRIu64 "\n", test_aud.u.umts.sqn);

	exit(0);
}
Example #9
0
static int set_subscriber_modify(struct ctrl_cmd *cmd, void *data)
{
	struct gsm_network *net = cmd->node;
	char *tmp, *imsi, *msisdn, *alg, *ki, *saveptr = NULL;
	struct gsm_subscriber* subscr;
	int rc;

	tmp = talloc_strdup(cmd, cmd->value);
	if (!tmp)
		return 1;

	imsi = strtok_r(tmp, ",", &saveptr);
	msisdn = strtok_r(NULL, ",", &saveptr);
	alg = strtok_r(NULL, ",", &saveptr);
	ki = strtok_r(NULL, ",", &saveptr);

	subscr = subscr_get_by_imsi(net->subscr_group, imsi);
	if (!subscr)
		subscr = subscr_create_subscriber(net->subscr_group, imsi);
	if (!subscr)
		goto fail;

	subscr->authorized = 1;
	strncpy(subscr->extension, msisdn, GSM_EXTENSION_LENGTH - 1);
	subscr->extension[GSM_EXTENSION_LENGTH-1] = '\0';

	/* put it back to the db */
	rc = db_sync_subscriber(subscr);
	db_subscriber_update(subscr);

	/* handle optional ciphering */
	if (alg) {
		if (strcasecmp(alg, "none") == 0)
			db_sync_authinfo_for_subscr(NULL, subscr);
		else {
			struct gsm_auth_info ainfo = { 0, };
			/* the verify should make sure that this is okay */
			OSMO_ASSERT(alg);
			OSMO_ASSERT(ki);

			if (strcasecmp(alg, "xor") == 0)
				ainfo.auth_algo = AUTH_ALGO_XOR;
			else if (strcasecmp(alg, "comp128v1") == 0)
				ainfo.auth_algo = AUTH_ALGO_COMP128v1;

			rc = osmo_hexparse(ki, ainfo.a3a8_ki, sizeof(ainfo.a3a8_ki));
			if (rc < 0) {
				subscr_put(subscr);
				talloc_free(tmp);
				cmd->reply = "Failed to parse KI";
				return CTRL_CMD_ERROR;
			}

			ainfo.a3a8_ki_len = rc;
			db_sync_authinfo_for_subscr(&ainfo, subscr);
			rc = 0;
		}
		db_sync_lastauthtuple_for_subscr(NULL, subscr);
	}
	subscr_put(subscr);

	talloc_free(tmp);

	if (rc != 0) {
		cmd->reply = "Failed to store the record in the DB";
		return CTRL_CMD_ERROR;
	}

	cmd->reply = "OK";
	return CTRL_CMD_REPLY;

fail:
	talloc_free(tmp);
	cmd->reply = "Failed to create subscriber";
	return CTRL_CMD_ERROR;
}