osmo-auc-gen: Add mode for verifying user-supplied AUTS

When -A is used on the command line, the respective AUTS value
will be validated and the SQN of the UICC printed.
diff --git a/utils/osmo-auc-gen.c b/utils/osmo-auc-gen.c
index c3a4fbc..e3502b2 100644
--- a/utils/osmo-auc-gen.c
+++ b/utils/osmo-auc-gen.c
@@ -62,6 +62,7 @@
 		"-O  --op\tSpecify OP (only for 3G)\n"
 		"-a  --amf\tSpecify AMF (only for 3G)\n"
 		"-s  --sqn\tSpecify SQN (only for 3G)\n"
+		"-A  --auts\tSpecify AUTS (only for 3G)\n"
 		"-r  --rand\tSpecify random value\n");
 }
 
@@ -69,13 +70,16 @@
 {
 	struct osmo_auth_vector _vec;
 	struct osmo_auth_vector *vec = &_vec;
-	uint8_t _rand[16];
+	uint8_t _rand[16], _auts[16];
 	int rc, option_index;
 	int rand_is_set = 0;
+	int auts_is_set = 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;
@@ -89,13 +93,14 @@
 			{ "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:", long_options,
+		c = getopt_long(argc, argv, "23a:k:o:f:s:r:hO:A:", long_options,
 				&option_index);
 
 		if (c == -1)
@@ -146,6 +151,14 @@
 					   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");
@@ -197,24 +210,22 @@
 
 	memset(vec, 0, sizeof(*vec));
 
-	rc = osmo_auth_gen_vec(vec, &test_aud, _rand);
+	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) {
-		fprintf(stderr, "error generating auth vector\n");
+		if (!auts_is_set)
+			fprintf(stderr, "error generating auth vector\n");
+		else
+			fprintf(stderr, "AUTS from MS seems incorrect\n");
 		exit(1);
 	}
 
 	dump_auth_vec(vec);
-#if 0
-	const uint8_t auts[14] = { 0x87, 0x11, 0xa0, 0xec, 0x9e, 0x16, 0x37, 0xdf,
-			     0x17, 0xf8, 0x0b, 0x38, 0x4e, 0xe4 };
 
-	rc = osmo_auth_gen_vec_auts(vec, &test_aud, auts, _rand, _rand);
-	if (rc < 0) {
-		printf("AUTS failed\n");
-	} else {
+	if (auts_is_set)
 		printf("AUTS success: SEQ.MS = %lu\n", test_aud.u.umts.sqn);
-	}
-#endif
-	exit(0);
 
+	exit(0);
 }