Introduce support for XOR-2G algorithm

So far we supported a "xor" algorithm in osmo-hlr, without specifying
whether it's the XOR-3G or the (different) XOR-2G algorithm.

Furthermore, it was buggy in the sense that it permitted the XOR[-3G]
for 2G authentication data in the database.

This patch
* renames existing "xor" to "xor-3g"
* disallows "xor-3g" usage with 2G authentication data
* introduces support for XOR-2G as "xor-2g" in the VTY

Change-Id: I039a1f84fda54a908a82fe621e7fd078cb85e4c6
Depends: libosmocore.git I0ee0565382c1e4515d44ff9b1752685c0a66ae39
diff --git a/TODO-RELEASE b/TODO-RELEASE
index cbfda24..62fe828 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -7,3 +7,4 @@
 # If any interfaces have been added since the last public release: c:r:a + 1.
 # If any interfaces have been removed or changed since the last public release: c:r:0.
 #library        what            description / commit summary line
+libosmogsm	UPDATE_DEP_VER	update libosmogsm version dependency after I0ee0565382c1e4515d44ff9b1752685c0a66ae39 is released
diff --git a/include/osmocom/hlr/hlr_vty.h b/include/osmocom/hlr/hlr_vty.h
index 83691b8..771945d 100644
--- a/include/osmocom/hlr/hlr_vty.h
+++ b/include/osmocom/hlr/hlr_vty.h
@@ -40,6 +40,7 @@
 
 #define A38_XOR_MIN_KEY_LEN	12
 #define A38_XOR_MAX_KEY_LEN	16
+#define A38_XOR2G_KEY_LEN	16
 #define A38_COMP128_KEY_LEN	16
 #define MILENAGE_KEY_LEN	16
 
diff --git a/src/db_hlr.c b/src/db_hlr.c
index 1dc4415..8dfbb15 100644
--- a/src/db_hlr.c
+++ b/src/db_hlr.c
@@ -238,8 +238,9 @@
 		case OSMO_AUTH_ALG_COMP128v1:
 		case OSMO_AUTH_ALG_COMP128v2:
 		case OSMO_AUTH_ALG_COMP128v3:
-		case OSMO_AUTH_ALG_XOR:
+		case OSMO_AUTH_ALG_XOR_2G:
 			break;
+		case OSMO_AUTH_ALG_XOR_3G:
 		case OSMO_AUTH_ALG_MILENAGE:
 			LOGP(DAUC, LOGL_ERROR, "Cannot update auth tokens:"
 			     " auth algo not suited for 2G: %s\n",
@@ -267,11 +268,12 @@
 		switch (aud->algo) {
 		case OSMO_AUTH_ALG_NONE:
 		case OSMO_AUTH_ALG_MILENAGE:
-		case OSMO_AUTH_ALG_XOR:
+		case OSMO_AUTH_ALG_XOR_3G:
 			break;
 		case OSMO_AUTH_ALG_COMP128v1:
 		case OSMO_AUTH_ALG_COMP128v2:
 		case OSMO_AUTH_ALG_COMP128v3:
+		case OSMO_AUTH_ALG_XOR_2G:
 			LOGP(DAUC, LOGL_ERROR, "Cannot update auth tokens:"
 			     " auth algo not suited for 3G: %s\n",
 			     osmo_auth_alg_name(aud->algo));
diff --git a/src/hlr_vty_subscr.c b/src/hlr_vty_subscr.c
index c851062..60a25bf 100644
--- a/src/hlr_vty_subscr.c
+++ b/src/hlr_vty_subscr.c
@@ -460,12 +460,12 @@
 	return false;
 }
 
-#define AUTH_ALG_TYPES_2G "(comp128v1|comp128v2|comp128v3|xor)"
+#define AUTH_ALG_TYPES_2G "(comp128v1|comp128v2|comp128v3|xor-2g)"
 #define AUTH_ALG_TYPES_2G_HELP \
 	"Use COMP128v1 algorithm\n" \
 	"Use COMP128v2 algorithm\n" \
 	"Use COMP128v3 algorithm\n" \
-	"Use XOR algorithm\n"
+	"Use XOR-2G algorithm\n"
 
 #define AUTH_ALG_TYPES_3G "milenage"
 #define AUTH_ALG_TYPES_3G_HELP \
@@ -486,10 +486,13 @@
 	} else if (!strcasecmp(alg_str, "comp128v3")) {
 		*algo = OSMO_AUTH_ALG_COMP128v3;
 		*minlen = *maxlen = A38_COMP128_KEY_LEN;
-	} else if (!strcasecmp(alg_str, "xor")) {
-		*algo = OSMO_AUTH_ALG_XOR;
+	} else if (!strcasecmp(alg_str, "xor-3g")) {
+		*algo = OSMO_AUTH_ALG_XOR_3G;
 		*minlen = A38_XOR_MIN_KEY_LEN;
 		*maxlen = A38_XOR_MAX_KEY_LEN;
+	} else if (!strcasecmp(alg_str, "xor-2g")) {
+		*algo = OSMO_AUTH_ALG_XOR_2G;
+		*minlen = *maxlen = A38_XOR2G_KEY_LEN;
 	} else if (!strcasecmp(alg_str, "milenage")) {
 		*algo = OSMO_AUTH_ALG_MILENAGE;
 		*minlen = *maxlen = MILENAGE_KEY_LEN;
@@ -659,11 +662,11 @@
 
 DEFUN(subscriber_aud3g_xor,
       subscriber_aud3g_xor_cmd,
-      SUBSCR_UPDATE "aud3g xor k K"
+      SUBSCR_UPDATE "aud3g xor-3g k K"
       " [ind-bitlen] [<0-28>]",
       SUBSCR_UPDATE_HELP
       "Set UMTS authentication data (3G, and 2G with UMTS AKA)\n"
-      "Use XOR algorithm\n"
+      "Use XOR-3G algorithm\n"
       "Set Encryption Key K\n" "K as 32 hexadecimal characters\n"
       "Set IND bit length\n" "IND bit length value (default: 5)\n")
 {
@@ -685,8 +688,8 @@
 		},
 	};
 
-	if (!auth_algo_parse("xor", &aud3g.algo, &minlen, &maxlen)) {
-		vty_out(vty, "%% Unknown auth algorithm: '%s'%s", "xor", VTY_NEWLINE);
+	if (!auth_algo_parse("xor-3g", &aud3g.algo, &minlen, &maxlen)) {
+		vty_out(vty, "%% Unknown auth algorithm: '%s'%s", "xor-3g", VTY_NEWLINE);
 		return CMD_WARNING;
 	}
 
diff --git a/tests/auc/auc_test.c b/tests/auc/auc_test.c
index 61cf82f..f39a5ad 100644
--- a/tests/auc/auc_test.c
+++ b/tests/auc/auc_test.c
@@ -477,7 +477,7 @@
 
 	aud3g = (struct osmo_sub_auth_data){
 		.type = OSMO_AUTH_TYPE_UMTS,
-		.algo = OSMO_AUTH_ALG_XOR,
+		.algo = OSMO_AUTH_ALG_XOR_3G,
 		.u.umts.sqn = 0,
 	};
 
diff --git a/tests/db/db_test.c b/tests/db/db_test.c
index ab997bf..6727812 100644
--- a/tests/db/db_test.c
+++ b/tests/db/db_test.c
@@ -586,7 +586,7 @@
 	ASSERT_SEL_AUD(imsi0, 0, id);
 
 	ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
-		mk_aud_2g(OSMO_AUTH_ALG_XOR, "CededEffacedAceFacedBadFadedBeef")),
+		mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "CededEffacedAceFacedBadFadedBeef")),
 		0);
 	ASSERT_SEL_AUD(imsi0, 0, id);
 
@@ -604,7 +604,7 @@
 		-ENOENT);
 
 	ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
-		mk_aud_2g(OSMO_AUTH_ALG_XOR, "CededEffacedAceFacedBadFadedBeef")),
+		mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "CededEffacedAceFacedBadFadedBeef")),
 		0);
 	ASSERT_SEL_AUD(imsi0, 0, id);
 
@@ -707,12 +707,12 @@
 	ASSERT_SEL_AUD(imsi0, 0, id);
 
 	ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
-		mk_aud_2g(OSMO_AUTH_ALG_XOR, "f000000000000f00000000000f000000f00000000")),
+		mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "f000000000000f00000000000f000000f00000000")),
 		-EINVAL);
 	ASSERT_SEL_AUD(imsi0, 0, id);
 
 	ASSERT_RC(db_subscr_update_aud_by_id(dbc, id,
-		mk_aud_2g(OSMO_AUTH_ALG_XOR, "f00")),
+		mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "f00")),
 		-EINVAL);
 	ASSERT_SEL_AUD(imsi0, 0, id);
 
diff --git a/tests/db/db_test.err b/tests/db/db_test.err
index b4373cd..222d3a1 100644
--- a/tests/db/db_test.err
+++ b/tests/db/db_test.err
@@ -872,14 +872,14 @@
 }
 3G: none
 
-db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR, "CededEffacedAceFacedBadFadedBeef")) --> 0
+db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "CededEffacedAceFacedBadFadedBeef")) --> 0
 
 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0
 DAUC IMSI='123456789000000': No 3G Auth Data
 
 2G: struct osmo_sub_auth_data {
   .type = GSM,
-  .algo = XOR-3G,
+  .algo = XOR-2G,
   .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef',
 }
 3G: none
@@ -900,14 +900,14 @@
 
 db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_NONE, NULL)) --> -ENOENT
 
-db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR, "CededEffacedAceFacedBadFadedBeef")) --> 0
+db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "CededEffacedAceFacedBadFadedBeef")) --> 0
 
 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0
 DAUC IMSI='123456789000000': No 3G Auth Data
 
 2G: struct osmo_sub_auth_data {
   .type = GSM,
-  .algo = XOR-3G,
+  .algo = XOR-2G,
   .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef',
 }
 3G: none
@@ -1112,7 +1112,7 @@
   .u.umts.ind_bitlen = 5,
 }
 
-db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR, "f000000000000f00000000000f000000f00000000")) --> -EINVAL
+db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "f000000000000f00000000000f000000f00000000")) --> -EINVAL
 DAUC Cannot update auth tokens: Invalid KI: 'f000000000000f00000000000f000000f00000000'
 
 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0
@@ -1132,7 +1132,7 @@
   .u.umts.ind_bitlen = 5,
 }
 
-db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR, "f00")) --> -EINVAL
+db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "f00")) --> -EINVAL
 DAUC Cannot update auth tokens: Invalid KI: 'f00'
 
 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0
diff --git a/tests/db_upgrade/create_subscribers.vty b/tests/db_upgrade/create_subscribers.vty
index 30eeba6..6e30b37 100644
--- a/tests/db_upgrade/create_subscribers.vty
+++ b/tests/db_upgrade/create_subscribers.vty
@@ -43,5 +43,5 @@
     MSISDN: none
 OsmoHLR# subscriber imsi 5555555 update msisdn 55555555555555
 % Updated subscriber IMSI='5555555' to MSISDN='55555555555555'
-OsmoHLR# subscriber imsi 5555555 update aud2g xor ki 55555555555555555555555555555555
+OsmoHLR# subscriber imsi 5555555 update aud2g xor-2g ki 55555555555555555555555555555555
 OsmoHLR# subscriber imsi 5555555 update aud3g milenage k 55555555555555555555555555555555 opc 55555555555555555555555555555555
diff --git a/tests/db_upgrade/db_upgrade_test.ok b/tests/db_upgrade/db_upgrade_test.ok
index 0a45f7c..ce5b17c 100644
--- a/tests/db_upgrade/db_upgrade_test.ok
+++ b/tests/db_upgrade/db_upgrade_test.ok
@@ -12,7 +12,7 @@
 algo_id_2g|ki|subscriber_id
 1|BeefedCafeFaceAcedAddedDecadeFee|1
 2|33333333333333333333333333333333|4
-4|55555555555555555555555555555555|6
+6|55555555555555555555555555555555|6
 
 Table: auc_3g
 name|type|notnull|dflt_value|pk
@@ -100,7 +100,7 @@
 algo_id_2g|ki|subscriber_id
 1|BeefedCafeFaceAcedAddedDecadeFee|1
 2|33333333333333333333333333333333|4
-4|55555555555555555555555555555555|6
+6|55555555555555555555555555555555|6
 
 Table: auc_3g
 name|type|notnull|dflt_value|pk
diff --git a/tests/db_upgrade/hlr_db_v0.sql b/tests/db_upgrade/hlr_db_v0.sql
index 46c985d..eb24eb5 100644
--- a/tests/db_upgrade/hlr_db_v0.sql
+++ b/tests/db_upgrade/hlr_db_v0.sql
@@ -61,7 +61,7 @@
 );
 INSERT INTO auc_2g VALUES(1,1,'BeefedCafeFaceAcedAddedDecadeFee');
 INSERT INTO auc_2g VALUES(4,2,'33333333333333333333333333333333');
-INSERT INTO auc_2g VALUES(6,4,'55555555555555555555555555555555');
+INSERT INTO auc_2g VALUES(6,6,'55555555555555555555555555555555');
 CREATE TABLE auc_3g (
 	subscriber_id	INTEGER PRIMARY KEY,	-- subscriber.id
 	algo_id_3g	INTEGER NOT NULL,	-- enum osmo_auth_algo value
diff --git a/tests/test_subscriber.ctrl b/tests/test_subscriber.ctrl
index fba7458..c2f09dc 100644
--- a/tests/test_subscriber.ctrl
+++ b/tests/test_subscriber.ctrl
@@ -674,11 +674,11 @@
 GET 112 subscriber.by-imsi-901991234567891.aud2g
 GET_REPLY 112 subscriber.by-imsi-901991234567891.aud2g none
 
-SET 113 subscriber.by-imsi-901991234567891.aud2g xor,c01ffedc1cadaeac1d1f1edacac1ab0a
+SET 113 subscriber.by-imsi-901991234567891.aud2g xor-2g,c01ffedc1cadaeac1d1f1edacac1ab0a
 SET_REPLY 113 subscriber.by-imsi-901991234567891.aud2g OK
 
 GET 114 subscriber.by-imsi-901991234567891.aud2g
-GET_REPLY 114 subscriber.by-imsi-901991234567891.aud2g XOR-3G,c01ffedc1cadaeac1d1f1edacac1ab0a
+GET_REPLY 114 subscriber.by-imsi-901991234567891.aud2g XOR-2G,c01ffedc1cadaeac1d1f1edacac1ab0a
 
 SET 115 subscriber.by-imsi-901991234567891.aud2g none
 SET_REPLY 115 subscriber.by-imsi-901991234567891.aud2g OK
diff --git a/tests/test_subscriber.vty b/tests/test_subscriber.vty
index a119cee..dbe9327 100644
--- a/tests/test_subscriber.vty
+++ b/tests/test_subscriber.vty
@@ -8,10 +8,10 @@
   subscriber (imsi|msisdn|id|imei) IDENT delete
   subscriber (imsi|msisdn|id|imei) IDENT update msisdn (none|MSISDN)
   subscriber (imsi|msisdn|id|imei) IDENT update aud2g none
-  subscriber (imsi|msisdn|id|imei) IDENT update aud2g (comp128v1|comp128v2|comp128v3|xor) ki KI
+  subscriber (imsi|msisdn|id|imei) IDENT update aud2g (comp128v1|comp128v2|comp128v3|xor-2g) ki KI
   subscriber (imsi|msisdn|id|imei) IDENT update aud3g none
   subscriber (imsi|msisdn|id|imei) IDENT update aud3g milenage k K (op|opc) OP_C [ind-bitlen] [<0-28>]
-  subscriber (imsi|msisdn|id|imei) IDENT update aud3g xor k K [ind-bitlen] [<0-28>]
+  subscriber (imsi|msisdn|id|imei) IDENT update aud3g xor-3g k K [ind-bitlen] [<0-28>]
   subscriber (imsi|msisdn|id|imei) IDENT update imei (none|IMEI)
   subscriber (imsi|msisdn|id|imei) IDENT update network-access-mode (none|cs|ps|cs+ps)
   show mslookup services
@@ -144,7 +144,7 @@
   comp128v1  Use COMP128v1 algorithm
   comp128v2  Use COMP128v2 algorithm
   comp128v3  Use COMP128v3 algorithm
-  xor        Use XOR algorithm
+  xor-2g     Use XOR-2G algorithm
 
 OsmoHLR# subscriber imsi 123456789023000 update aud2g comp128v1 ?
   ki  Set Ki Encryption Key
@@ -155,12 +155,12 @@
 OsmoHLR# subscriber imsi 123456789023000 update aud2g comp128v1 ki val ?
   <cr>  
 
-OsmoHLR# subscriber imsi 123456789023000 update aud2g xor ki Deaf0ff1ceD0d0DabbedD1ced1ceF00d
+OsmoHLR# subscriber imsi 123456789023000 update aud2g xor-2g ki Deaf0ff1ceD0d0DabbedD1ced1ceF00d
 OsmoHLR# subscriber imsi 123456789023000 show
     ID: 101
     IMSI: 123456789023000
     MSISDN: 423
-    2G auth: XOR-3G
+    2G auth: XOR-2G
              KI=deaf0ff1ced0d0dabbedd1ced1cef00d
 
 OsmoHLR# subscriber imsi 123456789023000 update aud2g comp128v1 ki BeefedCafeFaceAcedAddedDecadeFee
@@ -241,7 +241,7 @@
     2G auth: COMP128v3
              KI=c01ffedc1cadaeac1d1f1edacac1ab0a
 
-OsmoHLR# subscriber id 101 update aud2g xor ki CoiffedCicadaeAcidifiedAcaciaBoa
+OsmoHLR# subscriber id 101 update aud2g xor-2g ki CoiffedCicadaeAcidifiedAcaciaBoa
 % Invalid value for KI: 'CoiffedCicadaeAcidifiedAcaciaBoa'
 OsmoHLR# subscriber id 101 show
     ID: 101
@@ -250,7 +250,7 @@
     2G auth: COMP128v3
              KI=c01ffedc1cadaeac1d1f1edacac1ab0a
 
-OsmoHLR# subscriber id 101 update aud2g xor ki C01ffedC1cadaeAc1d1f1edAcac1aB0aX
+OsmoHLR# subscriber id 101 update aud2g xor-2g ki C01ffedC1cadaeAc1d1f1edAcac1aB0aX
 % Invalid value for KI: 'C01ffedC1cadaeAc1d1f1edAcac1aB0aX'
 OsmoHLR# subscriber id 101 show
     ID: 101
@@ -269,7 +269,7 @@
 OsmoHLR# subscriber imsi 123456789023000 update aud3g ?
   none      Delete 3G authentication data
   milenage  Use Milenage algorithm
-  xor       Use XOR algorithm
+  xor-3g    Use XOR-3G algorithm
 
 OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage ?
   k  Set Encryption Key K
diff --git a/tests/test_subscriber_errors.ctrl b/tests/test_subscriber_errors.ctrl
index 6b1ade6..4603a77 100644
--- a/tests/test_subscriber_errors.ctrl
+++ b/tests/test_subscriber_errors.ctrl
@@ -130,7 +130,7 @@
 SET 55 subscriber.by-imsi-901990000000003.aud2g foobar,2134
 ERROR 55 Unknown auth algorithm.
 
-SET 56 subscriber.by-imsi-901990000000003.aud2g xor,2134
+SET 56 subscriber.by-imsi-901990000000003.aud2g xor-2g,2134
 ERROR 56 Invalid KI.
 
 SET 57 subscriber.by-imsi-901990000000003.aud3g foobar