diff options
| author | Kevin Redon <kevredon@mail.tsaitgaist.info> | 2013-11-02 18:11:01 +0100 | 
|---|---|---|
| committer | Harald Welte <laforge@gnumonks.org> | 2013-11-03 15:05:25 +0100 | 
| commit | be355cd78a5aac7d11c1b9234254537b3c55f2d5 (patch) | |
| tree | 55ca95451e9721886ac1f3b675fa7d38ee89797d | |
| parent | 3d557b18d099249b0d60ea91c72695a678c9465f (diff) | |
implement COMP128 version 2 and 3 A3/A8 algorithm
simple copy into C from reversed code from www.hackingprojects.net
| -rw-r--r-- | include/Makefile.am | 1 | ||||
| -rw-r--r-- | include/osmocom/gsm/comp128v23.h | 23 | ||||
| -rw-r--r-- | src/gsm/Makefile.am | 11 | ||||
| -rw-r--r-- | src/gsm/auth_comp128v23.c | 68 | ||||
| -rw-r--r-- | src/gsm/comp128v23.c | 166 | 
5 files changed, 264 insertions, 5 deletions
diff --git a/include/Makefile.am b/include/Makefile.am index 42a2dc2b..b0359064 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -43,6 +43,7 @@ nobase_include_HEADERS = \                         osmocom/gsm/a5.h \                         osmocom/gsm/abis_nm.h \                         osmocom/gsm/comp128.h \ +                       osmocom/gsm/comp128v23.h \                         osmocom/gsm/gan.h \                         osmocom/gsm/gsm0411_smc.h \                         osmocom/gsm/gsm0411_smr.h \ diff --git a/include/osmocom/gsm/comp128v23.h b/include/osmocom/gsm/comp128v23.h new file mode 100644 index 00000000..aa26e56a --- /dev/null +++ b/include/osmocom/gsm/comp128v23.h @@ -0,0 +1,23 @@ +/* + * COMP128v23 header + * + * See comp128v23.c for details + */ + +#ifndef __COMP128V23_H__ +#define __COMP128V23_H__ + +#include <stdint.h> + +/* + * Performs the COMP128 version 2 and 3 algorithm (used as A3/A8) + * ki    : uint8_t [16] + * srand : uint8_t [16] + * version : uint8_t (2 or 3) + * sres  : uint8_t [4] + * kc    : uint8_t [8] + * returns 1 if not version 2 or 3 specified + */ +int comp128v23(const uint8_t *ki, const uint8_t *rand, uint8_t version, uint8_t *sres, uint8_t *kc); + +#endif /* __COMP128V23_H__ */ diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index fa2265a3..3162a7fc 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -11,14 +11,15 @@ noinst_HEADERS = milenage/aes.h milenage/aes_i.h milenage/aes_wrap.h \  lib_LTLIBRARIES = libosmogsm.la -libosmogsm_la_SOURCES = a5.c rxlev_stat.c tlv_parser.c comp128.c gsm_utils.c \ -                        rsl.c gsm48.c gsm48_ie.c gsm0808.c sysinfo.c \ +libosmogsm_la_SOURCES = a5.c rxlev_stat.c tlv_parser.c comp128.c comp128v23.c \ +			gsm_utils.c rsl.c gsm48.c gsm48_ie.c gsm0808.c sysinfo.c \  			gprs_cipher_core.c gsm0480.c abis_nm.c gsm0502.c \  			gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c \  			lapd_core.c lapdm.c \ -			auth_core.c auth_comp128v1.c auth_milenage.c \ -			milenage/aes-encblock.c milenage/aes-internal.c \ -			milenage/aes-internal-enc.c milenage/milenage.c gan.c +			auth_core.c auth_comp128v1.c auth_comp128v23.c \ +			auth_milenage.c milenage/aes-encblock.c \ +			milenage/aes-internal.c milenage/aes-internal-enc.c \ +			milenage/milenage.c gan.c  libosmogsm_la_LDFLAGS = $(LTLDFLAGS_OSMOGSM) -version-info $(LIBVERSION) -no-undefined  libosmogsm_la_LIBADD = $(top_builddir)/src/libosmocore.la diff --git a/src/gsm/auth_comp128v23.c b/src/gsm/auth_comp128v23.c new file mode 100644 index 00000000..36383d93 --- /dev/null +++ b/src/gsm/auth_comp128v23.c @@ -0,0 +1,68 @@ +/* registers COMP128 version 2 and 3 A3/A8 algorithms for the + * GSM/GPRS/3G authentication core infrastructure + * + */ + +/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org> + * (C) 2013 by Kévin Redon <kevredon@mail.tsaitgaist.info> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <osmocom/crypt/auth.h> +#include <osmocom/gsm/comp128v23.h> + +static int c128v2_gen_vec(struct osmo_auth_vector *vec, +			  struct osmo_sub_auth_data *aud, +			  const uint8_t *_rand) +{ +	comp128v23(aud->u.gsm.ki, _rand, 2, vec->sres, vec->kc); +	vec->auth_types = OSMO_AUTH_TYPE_GSM; + +	return 0; +} + +static struct osmo_auth_impl c128v2_alg = { +	.algo = OSMO_AUTH_ALG_COMP128v2, +	.name = "COMP128v2 (libosmogsm built-in)", +	.priority = 1000, +	.gen_vec = &c128v2_gen_vec, +}; + +static int c128v3_gen_vec(struct osmo_auth_vector *vec, +			  struct osmo_sub_auth_data *aud, +			  const uint8_t *_rand) +{ +	comp128v23(aud->u.gsm.ki, _rand, 3, vec->sres, vec->kc); +	vec->auth_types = OSMO_AUTH_TYPE_GSM; + +	return 0; +} + +static struct osmo_auth_impl c128v3_alg = { +	.algo = OSMO_AUTH_ALG_COMP128v3, +	.name = "COMP128v3 (libosmogsm built-in)", +	.priority = 1000, +	.gen_vec = &c128v3_gen_vec, +}; + +static __attribute__((constructor)) void on_dso_load_c128(void) +{ +	osmo_auth_register(&c128v2_alg); +	osmo_auth_register(&c128v3_alg); +} diff --git a/src/gsm/comp128v23.c b/src/gsm/comp128v23.c new file mode 100644 index 00000000..90042084 --- /dev/null +++ b/src/gsm/comp128v23.c @@ -0,0 +1,166 @@ +/* COMP128 version 2 and 3 implementation + * + * This code is a C conversion of the original code from + * http://www.hackingprojects.net/ + * + */ + +/* (C) 2013 by Kévin Redon <kevredon@mail.tsaitgaist.info> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <stdint.h> +#include <string.h> + +static const uint8_t table0[256] = { +	197, 235, 60, 151, 98, 96, 3, 100, 248, 118, 42, 117, 172, 211, 181, 203, 61, +	126, 156, 87, 149, 224, 55, 132, 186, 63, 238, 255, 85, 83, 152, 33, 160, +	184, 210, 219, 159, 11, 180, 194, 130, 212, 147, 5, 215, 92, 27, 46, 113, +	187, 52, 25, 185, 79, 221, 48, 70, 31, 101, 15, 195, 201, 50, 222, 137, +	233, 229, 106, 122, 183, 178, 177, 144, 207, 234, 182, 37, 254, 227, 231, 54, +	209, 133, 65, 202, 69, 237, 220, 189, 146, 120, 68, 21, 125, 38, 30, 2, +	155, 53, 196, 174, 176, 51, 246, 167, 76, 110, 20, 82, 121, 103, 112, 56, +	173, 49, 217, 252, 0, 114, 228, 123, 12, 93, 161, 253, 232, 240, 175, 67, +	128, 22, 158, 89, 18, 77, 109, 190, 17, 62, 4, 153, 163, 59, 145, 138, +	7, 74, 205, 10, 162, 80, 45, 104, 111, 150, 214, 154, 28, 191, 169, 213, +	88, 193, 198, 200, 245, 39, 164, 124, 84, 78, 1, 188, 170, 23, 86, 226, +	141, 32, 6, 131, 127, 199, 40, 135, 16, 57, 71, 91, 225, 168, 242, 206, +	97, 166, 44, 14, 90, 236, 239, 230, 244, 223, 108, 102, 119, 148, 251, 29, +	216, 8, 9, 249, 208, 24, 105, 94, 34, 64, 95, 115, 72, 134, 204, 43, +	247, 243, 218, 47, 58, 73, 107, 241, 179, 116, 66, 36, 143, 81, 250, 139, +	19, 13, 142, 140, 129, 192, 99, 171, 157, 136, 41, 75, 35, 165, 26 +}, table1[256] = { +	170, 42, 95, 141, 109, 30, 71, 89, 26, 147, 231, 205, 239, 212, 124, 129, 216, +	79, 15, 185, 153, 14, 251, 162, 0, 241, 172, 197, 43, 10, 194, 235, 6, +	20, 72, 45, 143, 104, 161, 119, 41, 136, 38, 189, 135, 25, 93, 18, 224, +	171, 252, 195, 63, 19, 58, 165, 23, 55, 133, 254, 214, 144, 220, 178, 156, +	52, 110, 225, 97, 183, 140, 39, 53, 88, 219, 167, 16, 198, 62, 222, 76, +	139, 175, 94, 51, 134, 115, 22, 67, 1, 249, 217, 3, 5, 232, 138, 31, +	56, 116, 163, 70, 128, 234, 132, 229, 184, 244, 13, 34, 73, 233, 154, 179, +	131, 215, 236, 142, 223, 27, 57, 246, 108, 211, 8, 253, 85, 66, 245, 193, +	78, 190, 4, 17, 7, 150, 127, 152, 213, 37, 186, 2, 243, 46, 169, 68, +	101, 60, 174, 208, 158, 176, 69, 238, 191, 90, 83, 166, 125, 77, 59, 21, +	92, 49, 151, 168, 99, 9, 50, 146, 113, 117, 228, 65, 230, 40, 82, 54, +	237, 227, 102, 28, 36, 107, 24, 44, 126, 206, 201, 61, 114, 164, 207, 181, +	29, 91, 64, 221, 255, 48, 155, 192, 111, 180, 210, 182, 247, 203, 148, 209, +	98, 173, 11, 75, 123, 250, 118, 32, 47, 240, 202, 74, 177, 100, 80, 196, +	33, 248, 86, 157, 137, 120, 130, 84, 204, 122, 81, 242, 188, 200, 149, 226, +	218, 160, 187, 106, 35, 87, 105, 96, 145, 199, 159, 12, 121, 103, 112 +}; + +#define RAND_SIZE 16 +#define KI_SIZE 16 +#define SRES_SIZE 4 +#define KC_SIZE 8 + +static void +_comp128v23_internal(uint8_t *output, const uint8_t *kxor, const uint8_t *rand) +{ +	uint8_t temp[RAND_SIZE]; +	uint8_t km_rm[RAND_SIZE+KI_SIZE]; +	uint8_t i,j,k,z; + +	memset(temp,0,sizeof(temp)/sizeof(uint8_t)); +	memcpy(km_rm,rand,RAND_SIZE); +	memcpy(km_rm+RAND_SIZE,kxor,KI_SIZE); + +	for (i=0; i<5; i++) { +		for (z=0; z<16; z++) { +			temp[z] = table0[table1[km_rm[16+z]]^km_rm[z]]; +		} +		j=0; +		while ((1<<i)>j) { +			k = 0; +			while ((1<<(4-i))>k) { +				km_rm[((2*k+1)<<i)+j] = table0[table1[temp[(k<<i)+j]]^(km_rm[(k<<i)+16+j])]; +				km_rm[(k<<(i+1))+j] = temp[(k<<i)+j]; +				k++; +			} +			j++; +		} +	} + +	memset(output,0,16); + +	for (i=0; i<16; i++) { +		for (j=0; j<8; j++) { +			output[i] ^= (((km_rm[(19*(j+8*i)+19)%256/8]>>(3*j+3)%8)&1)<< j); +		} +	} +} + +int +comp128v23(const uint8_t *ki, const uint8_t *rand, uint8_t version, uint8_t *sres, uint8_t *kc) +{ +	uint8_t k_mix[KI_SIZE]; +	uint8_t rand_mix[RAND_SIZE]; +	uint8_t katyvasz[KI_SIZE]; +	uint8_t output[KI_SIZE]; +	uint8_t i,s; + +	if (!(version==2 || version==3)) +		return 1; + +	memset(k_mix,0,sizeof(k_mix)/sizeof(uint8_t)); +	memset(rand_mix,0,sizeof(rand_mix)/sizeof(uint8_t)); +	memset(katyvasz,0,sizeof(katyvasz)/sizeof(uint8_t)); +	memset(output,0,sizeof(output)/sizeof(uint8_t)); + +	for (i=0; i<8; i++) { +		k_mix[i] = ki[15 - i]; +		k_mix[15 - i] = ki[i]; +	} + +	for (i=0; i<8; i++) { +		rand_mix[i] = rand[15 - i]; +		rand_mix[15 - i] = rand[i]; +	} + +	for (i=0; i<16; i++) { +		katyvasz[i] = k_mix[i]^rand_mix[i]; +	} + +	for (i=0; i<8; i++) { +		_comp128v23_internal(rand_mix,katyvasz,rand_mix); +	} + +	for (i=0; i<16; i++) { +		output[i] = rand_mix[15-i]; +	} + +	if (version==2) { +		output[15] = 0; +		output[14] = 4*(output[14]>>2); +	} + +	s = 8; +	i = 0; +	while (i<4) { +		output[s+i-4] = output[s+i]; +		output[s+i] = output[s+i+4]; +		i++; +	} + +	/* the algorithm uses 16 bytes until this point, but only 12 bytes are effective +	 * also 12 bytes coming out from the SIM card */ +	memcpy(sres,output,SRES_SIZE*sizeof(uint8_t)); +	memcpy(kc,&output[SRES_SIZE],KC_SIZE*sizeof(uint8_t)); + +	return 0; +}  | 
