diff options
author | Sylvain Munaut <tnt@246tNt.com> | 2012-04-02 21:41:26 +0200 |
---|---|---|
committer | Sylvain Munaut <tnt@246tNt.com> | 2012-04-02 21:41:26 +0200 |
commit | e4794d0c077a9d139e87612cd9477ebc828380f7 (patch) | |
tree | 97a2a010ac7bfe1a8d24abc6c7b7fdb3624c362e /src/shared | |
parent | 143abe661a50948f58c6a917f0231cde068db2a7 (diff) | |
parent | 738f13395d1d8a005011e45ebbc6a869bbcfd9a6 (diff) |
Merge commit '738f13395d1d8a005011e45ebbc6a869bbcfd9a6'
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/libosmocore/configure.ac | 2 | ||||
-rw-r--r-- | src/shared/libosmocore/include/osmocom/core/socket.h | 1 | ||||
-rw-r--r-- | src/shared/libosmocore/include/osmocom/crypt/auth.h | 1 | ||||
-rw-r--r-- | src/shared/libosmocore/include/osmocom/vty/misc.h | 3 | ||||
-rw-r--r-- | src/shared/libosmocore/src/gsm/a5.c | 8 | ||||
-rw-r--r-- | src/shared/libosmocore/src/gsm/auth_milenage.c | 15 | ||||
-rw-r--r-- | src/shared/libosmocore/src/gsm/lapd_core.c | 3 | ||||
-rw-r--r-- | src/shared/libosmocore/src/gsm/milenage/milenage.c | 15 | ||||
-rw-r--r-- | src/shared/libosmocore/src/gsm/milenage/milenage.h | 2 | ||||
-rw-r--r-- | src/shared/libosmocore/src/vty/command.c | 176 | ||||
-rw-r--r-- | src/shared/libosmocore/tests/auth/milenage_test.c | 20 | ||||
-rw-r--r-- | src/shared/libosmocore/tests/auth/milenage_test.ok | 2 | ||||
-rw-r--r-- | src/shared/libosmocore/utils/osmo-auc-gen.c | 80 |
13 files changed, 257 insertions, 71 deletions
diff --git a/src/shared/libosmocore/configure.ac b/src/shared/libosmocore/configure.ac index ec79a923..0fea115f 100644 --- a/src/shared/libosmocore/configure.ac +++ b/src/shared/libosmocore/configure.ac @@ -1,6 +1,6 @@ AC_INIT([libosmocore], m4_esyscmd([./git-version-gen .tarball-version]), - [openbsc-devel@lists.openbsc.org]) + [openbsc@lists.osmocom.org]) AM_INIT_AUTOMAKE([dist-bzip2]) AC_CONFIG_TESTDIR(tests) diff --git a/src/shared/libosmocore/include/osmocom/core/socket.h b/src/shared/libosmocore/include/osmocom/core/socket.h index c5288dfc..88214632 100644 --- a/src/shared/libosmocore/include/osmocom/core/socket.h +++ b/src/shared/libosmocore/include/osmocom/core/socket.h @@ -12,6 +12,7 @@ #include <stdint.h> struct sockaddr; +struct osmo_fd; /* flags for osmo_sock_init. */ #define OSMO_SOCK_F_CONNECT (1 << 0) diff --git a/src/shared/libosmocore/include/osmocom/crypt/auth.h b/src/shared/libosmocore/include/osmocom/crypt/auth.h index 30e16e82..67b32009 100644 --- a/src/shared/libosmocore/include/osmocom/crypt/auth.h +++ b/src/shared/libosmocore/include/osmocom/crypt/auth.h @@ -33,6 +33,7 @@ struct osmo_sub_auth_data { uint8_t k[16]; uint8_t amf[2]; uint64_t sqn; + int opc_is_op; } umts; struct { uint8_t ki[16]; diff --git a/src/shared/libosmocore/include/osmocom/vty/misc.h b/src/shared/libosmocore/include/osmocom/vty/misc.h index 707f82fa..89234733 100644 --- a/src/shared/libosmocore/include/osmocom/vty/misc.h +++ b/src/shared/libosmocore/include/osmocom/vty/misc.h @@ -7,4 +7,7 @@ void vty_out_rate_ctr_group(struct vty *vty, const char *prefix, struct rate_ctr_group *ctrg); +int osmo_vty_write_config_file(const char *filename); +int osmo_vty_save_config_file(void); + #endif diff --git a/src/shared/libosmocore/src/gsm/a5.c b/src/shared/libosmocore/src/gsm/a5.c index e330c759..34f271a8 100644 --- a/src/shared/libosmocore/src/gsm/a5.c +++ b/src/shared/libosmocore/src/gsm/a5.c @@ -89,10 +89,10 @@ osmo_a5(int n, const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul) #define A5_R3_MASK ((1<<A5_R3_LEN)-1) #define A5_R4_MASK ((1<<A5_R4_LEN)-1) -#define A5_R1_TAPS 0x072000 /* x^19 + x^5 + x^2 + x + 1 */ -#define A5_R2_TAPS 0x300000 /* x^22 + x + 1 */ -#define A5_R3_TAPS 0x700080 /* x^23 + x^15 + x^2 + x + 1 */ -#define A5_R4_TAPS 0x010800 /* x^17 + x^5 + 1 */ +#define A5_R1_TAPS 0x072000 /* x^19 + x^18 + x^17 + x^14 + 1 */ +#define A5_R2_TAPS 0x300000 /* x^22 + x^21 + 1 */ +#define A5_R3_TAPS 0x700080 /* x^23 + x^22 + x^21 + x^8 + 1 */ +#define A5_R4_TAPS 0x010800 /* x^17 + x^12 + 1 */ /*! \brief Computes parity of a 32-bit word * \param[in] x 32 bit word diff --git a/src/shared/libosmocore/src/gsm/auth_milenage.c b/src/shared/libosmocore/src/gsm/auth_milenage.c index 2a9ba334..5b2787dd 100644 --- a/src/shared/libosmocore/src/gsm/auth_milenage.c +++ b/src/shared/libosmocore/src/gsm/auth_milenage.c @@ -83,10 +83,21 @@ static int milenage_gen_vec_auts(struct osmo_auth_vector *vec, const uint8_t *_rand) { uint8_t sqn_out[6]; + uint8_t gen_opc[16]; + uint8_t *opc; int rc; - rc = milenage_auts(aud->u.umts.opc, aud->u.umts.k, - rand_auts, auts, sqn_out); + /* Check if we only know OP and compute OPC if required */ + if (aud->type == OSMO_AUTH_TYPE_UMTS && aud->u.umts.opc_is_op) { + rc = milenage_opc_gen(gen_opc, aud->u.umts.k, + aud->u.umts.opc); + if (rc < 0) + return rc; + opc = gen_opc; + } else + opc = aud->u.umts.opc; + + rc = milenage_auts(opc, aud->u.umts.k, rand_auts, auts, sqn_out); if (rc < 0) return rc; diff --git a/src/shared/libosmocore/src/gsm/lapd_core.c b/src/shared/libosmocore/src/gsm/lapd_core.c index fb79a2f0..96099edb 100644 --- a/src/shared/libosmocore/src/gsm/lapd_core.c +++ b/src/shared/libosmocore/src/gsm/lapd_core.c @@ -707,7 +707,7 @@ static void lapd_acknowledge(struct lapd_msg_ctx *lctx) { struct lapd_datalink *dl = lctx->dl; uint8_t nr = lctx->n_recv; - int s = 0, rej = 0, t200_reset = 0, t200_start = 0; + int s = 0, rej = 0, t200_reset = 0; int i, h; /* supervisory frame ? */ @@ -758,7 +758,6 @@ static void lapd_acknowledge(struct lapd_msg_ctx *lctx) if (dl->tx_hist[sub_mod(dl->v_send, 1, dl->range_hist)].msg) { LOGP(DLLAPD, LOGL_INFO, "start T200, due to unacked I " "frame(s)\n"); - t200_start = 1; lapd_start_t200(dl); } } diff --git a/src/shared/libosmocore/src/gsm/milenage/milenage.c b/src/shared/libosmocore/src/gsm/milenage/milenage.c index cc4e95c5..b43f986a 100644 --- a/src/shared/libosmocore/src/gsm/milenage/milenage.c +++ b/src/shared/libosmocore/src/gsm/milenage/milenage.c @@ -327,3 +327,18 @@ int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand, return 0; } + +int milenage_opc_gen(u8 *opc, const u8 *k, const u8 *op) +{ + int i; + + /* Encrypt OP using K */ + if (aes_128_encrypt_block(k, op, opc)) + return -1; + + /* XOR the resulting Ek(OP) with OP */ + for (i = 0; i < 16; i++) + opc[i] = opc[i] ^ op[i]; + + return 0; +} diff --git a/src/shared/libosmocore/src/gsm/milenage/milenage.h b/src/shared/libosmocore/src/gsm/milenage/milenage.h index d5054d6d..a91e946a 100644 --- a/src/shared/libosmocore/src/gsm/milenage/milenage.h +++ b/src/shared/libosmocore/src/gsm/milenage/milenage.h @@ -30,4 +30,6 @@ int milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand, int milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand, u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar); +int milenage_opc_gen(u8 *opc, const u8 *k, const u8 *op); + #endif /* MILENAGE_H */ diff --git a/src/shared/libosmocore/src/vty/command.c b/src/shared/libosmocore/src/vty/command.c index ab1eacaa..fda2e17f 100644 --- a/src/shared/libosmocore/src/vty/command.c +++ b/src/shared/libosmocore/src/vty/command.c @@ -2268,31 +2268,19 @@ gDEFUN(config_list, config_list_cmd, "list", "Print command list\n") return CMD_SUCCESS; } -/* Write current configuration into file. */ -DEFUN(config_write_file, - config_write_file_cmd, - "write file", - "Write running configuration to memory, network, or terminal\n" - "Write to configuration file\n") +static int write_config_file(const char *config_file, char **outpath) { unsigned int i; int fd; struct cmd_node *node; - char *config_file; char *config_file_tmp = NULL; char *config_file_sav = NULL; struct vty *file_vty; + struct stat st; - /* Check and see if we are operating under vtysh configuration */ - if (host.config == NULL) { - vty_out(vty, "Can't save to configuration file, using vtysh.%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - /* Get filename. */ - config_file = host.config; + *outpath = NULL; + /* Check and see if we are operating under vtysh configuration */ config_file_sav = _talloc_zero(tall_vty_cmd_ctx, strlen(config_file) + strlen(CONF_BACKUP_EXT) + 1, @@ -2307,11 +2295,10 @@ DEFUN(config_write_file, /* Open file to configuration write. */ fd = mkstemp(config_file_tmp); if (fd < 0) { - vty_out(vty, "Can't open configuration file %s.%s", - config_file_tmp, VTY_NEWLINE); + *outpath = talloc_strdup(tall_vty_cmd_ctx, config_file_tmp); talloc_free(config_file_tmp); talloc_free(config_file_sav); - return CMD_WARNING; + return -1; } /* Make vty for configuration file. */ @@ -2334,38 +2321,37 @@ DEFUN(config_write_file, if (unlink(config_file_sav) != 0) if (errno != ENOENT) { - vty_out(vty, - "Can't unlink backup configuration file %s.%s", - config_file_sav, VTY_NEWLINE); + *outpath = talloc_strdup(tall_vty_cmd_ctx, config_file_sav); talloc_free(config_file_sav); talloc_free(config_file_tmp); unlink(config_file_tmp); - return CMD_WARNING; + return -2; + } + + /* Only link the .sav file if the original file exists */ + if (stat(config_file, &st) == 0) { + if (link(config_file, config_file_sav) != 0) { + *outpath = talloc_strdup(tall_vty_cmd_ctx, config_file_sav); + talloc_free(config_file_sav); + talloc_free(config_file_tmp); + unlink(config_file_tmp); + return -3; + } + sync(); + if (unlink(config_file) != 0) { + *outpath = talloc_strdup(tall_vty_cmd_ctx, config_file); + talloc_free(config_file_sav); + talloc_free(config_file_tmp); + unlink(config_file_tmp); + return -4; } - if (link(config_file, config_file_sav) != 0) { - vty_out(vty, "Can't backup old configuration file %s.%s", - config_file_sav, VTY_NEWLINE); - talloc_free(config_file_sav); - talloc_free(config_file_tmp); - unlink(config_file_tmp); - return CMD_WARNING; - } - sync(); - if (unlink(config_file) != 0) { - vty_out(vty, "Can't unlink configuration file %s.%s", - config_file, VTY_NEWLINE); - talloc_free(config_file_sav); - talloc_free(config_file_tmp); - unlink(config_file_tmp); - return CMD_WARNING; } if (link(config_file_tmp, config_file) != 0) { - vty_out(vty, "Can't save configuration file %s.%s", config_file, - VTY_NEWLINE); + *outpath = talloc_strdup(tall_vty_cmd_ctx, config_file); talloc_free(config_file_sav); talloc_free(config_file_tmp); unlink(config_file_tmp); - return CMD_WARNING; + return -5; } unlink(config_file_tmp); sync(); @@ -2374,13 +2360,70 @@ DEFUN(config_write_file, talloc_free(config_file_tmp); if (chmod(config_file, 0666 & ~CONFIGFILE_MASK) != 0) { - vty_out(vty, "Can't chmod configuration file %s: %s (%d).%s", - config_file, strerror(errno), errno, VTY_NEWLINE); + *outpath = talloc_strdup(tall_vty_cmd_ctx, config_file); + return -6; + } + + return 0; +} + + +/* Write current configuration into file. */ +DEFUN(config_write_file, + config_write_file_cmd, + "write file", + "Write running configuration to memory, network, or terminal\n" + "Write to configuration file\n") +{ + char *failed_file; + int rc; + + if (host.config == NULL) { + vty_out(vty, "Can't save to configuration file, using vtysh.%s", + VTY_NEWLINE); return CMD_WARNING; } - vty_out(vty, "Configuration saved to %s%s", config_file, VTY_NEWLINE); - return CMD_SUCCESS; + rc = write_config_file(host.config, &failed_file); + switch (rc) { + case -1: + vty_out(vty, "Can't open configuration file %s.%s", + failed_file, VTY_NEWLINE); + rc = CMD_WARNING; + break; + case -2: + vty_out(vty, "Can't unlink backup configuration file %s.%s", + failed_file, VTY_NEWLINE); + rc = CMD_WARNING; + break; + case -3: + vty_out(vty, "Can't backup old configuration file %s.%s", + failed_file, VTY_NEWLINE); + rc = CMD_WARNING; + break; + case -4: + vty_out(vty, "Can't unlink configuration file %s.%s", + failed_file, VTY_NEWLINE); + rc = CMD_WARNING; + break; + case -5: + vty_out(vty, "Can't save configuration file %s.%s", failed_file, + VTY_NEWLINE); + rc = CMD_WARNING; + break; + case -6: + vty_out(vty, "Can't chmod configuration file %s: %s (%d).%s", + failed_file, strerror(errno), errno, VTY_NEWLINE); + rc = CMD_WARNING; + break; + default: + vty_out(vty, "Configuration saved to %s%s", host.config, VTY_NEWLINE); + rc = CMD_SUCCESS; + break; + } + + talloc_free(failed_file); + return rc; } ALIAS(config_write_file, @@ -3160,6 +3203,47 @@ void install_default(enum node_type node) install_element(node, &show_running_config_cmd); } +/** + * \brief Write the current running config to a given file + * \param[in] vty the vty of the code + * \param[in] filename where to store the file + * \return 0 in case of success. + * + * If the filename already exists create a filename.sav + * version with the current code. + * + */ +int osmo_vty_write_config_file(const char *filename) +{ + char *failed_file; + int rc; + + rc = write_config_file(filename, &failed_file); + talloc_free(failed_file); + return rc; +} + +/** + * \brief Save the current state to the config file + * \return 0 in case of success. + * + * If the filename already exists create a filename.sav + * version with the current code. + * + */ +int osmo_vty_save_config_file(void) +{ + char *failed_file; + int rc; + + if (host.config == NULL) + return -7; + + rc = write_config_file(host.config, &failed_file); + talloc_free(failed_file); + return rc; +} + /* Initialize command interface. Install basic nodes and commands. */ void cmd_init(int terminal) { diff --git a/src/shared/libosmocore/tests/auth/milenage_test.c b/src/shared/libosmocore/tests/auth/milenage_test.c index da7c800a..7c996f02 100644 --- a/src/shared/libosmocore/tests/auth/milenage_test.c +++ b/src/shared/libosmocore/tests/auth/milenage_test.c @@ -37,6 +37,24 @@ static struct osmo_sub_auth_data test_aud = { }, }; +static int opc_test(const struct osmo_sub_auth_data *aud) +{ + int rc; + uint8_t opc[16]; +#if 0 + const uint8_t op[16] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; +#else + const uint8_t op[16] = { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 }; +#endif + + rc = milenage_opc_gen(opc, aud->u.umts.k, op); + + printf("OP:\t%s\n", osmo_hexdump(op, sizeof(op))); + printf("OPC:\t%s\n", osmo_hexdump(opc, sizeof(opc))); + return rc; +} + int main(int argc, char **argv) { struct osmo_auth_vector _vec; @@ -73,6 +91,8 @@ int main(int argc, char **argv) printf("AUTS success: SEQ.MS = %lu\n", test_aud.u.umts.sqn); } + opc_test(&test_aud); + exit(0); } diff --git a/src/shared/libosmocore/tests/auth/milenage_test.ok b/src/shared/libosmocore/tests/auth/milenage_test.ok index 66337ca9..00ffc222 100644 --- a/src/shared/libosmocore/tests/auth/milenage_test.ok +++ b/src/shared/libosmocore/tests/auth/milenage_test.ok @@ -6,3 +6,5 @@ RES: e9 fc 88 cc c8 a3 53 81 SRES: 21 5f db 4d Kc: 6d e8 16 a7 59 a4 29 12 AUTS success: SEQ.MS = 33 +OP: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +OPC: c6 a1 3b 37 87 8f 5b 82 6f 4f 81 62 a1 c8 d8 79 diff --git a/src/shared/libosmocore/utils/osmo-auc-gen.c b/src/shared/libosmocore/utils/osmo-auc-gen.c index 62b51289..e3502b2c 100644 --- a/src/shared/libosmocore/utils/osmo-auc-gen.c +++ b/src/shared/libosmocore/utils/osmo-auc-gen.c @@ -1,6 +1,6 @@ /* GSM/GPRS/3G authentication testing tool */ -/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org> +/* (C) 2010-2012 by Harald Welte <laforge@gnumonks.org> * * All Rights Reserved * @@ -52,17 +52,34 @@ static struct osmo_sub_auth_data test_aud = { .algo = OSMO_AUTH_ALG_NONE, }; +static void help() +{ + printf( "-2 --2g\tUse 2G (GSM) authentication\n" + "-3 --3g\tUse 3G (UMTS) authentication\n" + "-a --algorithm\tSpecify name of the algorithm\n" + "-k --key\tSpecify Ki / K\n" + "-o --opc\tSpecify OPC (only for 3G)\n" + "-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"); +} + int main(int argc, char **argv) { 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 by Harald Welte\n"); + 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; @@ -72,15 +89,18 @@ int main(int argc, char **argv) { "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:", long_options, + c = getopt_long(argc, argv, "23a:k:o:f:s:r:hO:A:", long_options, &option_index); if (c == -1) @@ -120,6 +140,24 @@ int main(int argc, char **argv) } 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) { @@ -141,6 +179,12 @@ int main(int argc, char **argv) rc = osmo_hexparse(optarg, _rand, sizeof(_rand)); rand_is_set = 1; break; + case 'h': + help(); + exit(0); + default: + help(); + exit(1); } if (rc < 0) { @@ -158,26 +202,30 @@ int main(int argc, char **argv) *(uint32_t *)(&_rand[12]) = rand(); } + if (test_aud.type == OSMO_AUTH_TYPE_NONE || + test_aud.algo == OSMO_AUTH_ALG_NONE) { + help(); + exit(2); + } + 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); } |