diff mbox

Update GPRS cipher API to comply with ETSI TS 155.22

Message ID 1395085252-7428-1-git-send-email-max.suraev@fairwaves.co
State Superseded, archived
Headers show

Commit Message

Max March 17, 2014, 7:40 p.m. UTC
---
 include/osmocom/crypt/gprs_cipher.h |  8 ++++++--
 src/gsm/gprs_cipher_core.c          | 20 +++++++++++++++++---
 src/gsm/libosmogsm.map              |  1 +
 3 files changed, 24 insertions(+), 5 deletions(-)

Comments

Max June 13, 2014, 10:45 a.m. UTC | #1
I've just realized that this patch missing explicit comment.

Old API assumed that GPRS key length is always 64 bit - ETSI TS 155.22 proves this
assumption wrong. Thit patch removes this assumption. It also makes GPRS cipher API
to match the style of GSM cipher API which does not make any assumptions on the key
length.

cheers,
Max.
diff mbox

Patch

diff --git a/include/osmocom/crypt/gprs_cipher.h b/include/osmocom/crypt/gprs_cipher.h
index 3051071..b6b8e93 100644
--- a/include/osmocom/crypt/gprs_cipher.h
+++ b/include/osmocom/crypt/gprs_cipher.h
@@ -10,6 +10,7 @@  enum gprs_ciph_algo {
 	GPRS_ALGO_GEA1,
 	GPRS_ALGO_GEA2,
 	GPRS_ALGO_GEA3,
+	GPRS_ALGO_GEA4,
 	_GPRS_ALGO_NUM
 };
 
@@ -28,7 +29,7 @@  struct gprs_cipher_impl {
 	/* As specified in 04.64 Annex A.  Uses Kc, IV and direction
 	 * to generate the 1523 bytes cipher stream that need to be
 	 * XORed wit the plaintext for encrypt / ciphertext for decrypt */
-	int (*run)(uint8_t *out, uint16_t len, uint64_t kc, uint32_t iv,
+	int (*run)(uint8_t *out, uint16_t len, uint8_t *kc, uint32_t iv,
 		   enum gprs_cipher_direction direction);
 };
 
@@ -40,11 +41,14 @@  int gprs_cipher_load(const char *path);
 
 /* function to be called by core code */
 int gprs_cipher_run(uint8_t *out, uint16_t len, enum gprs_ciph_algo algo,
-		    uint64_t kc, uint32_t iv, enum gprs_cipher_direction dir);
+		    uint8_t *kc, uint32_t iv, enum gprs_cipher_direction dir);
 
 /* Do we have an implementation for this cipher? */
 int gprs_cipher_supported(enum gprs_ciph_algo algo);
 
+/* Return key length for supported cipher, in bytes */
+unsigned gprs_cipher_key_length(enum gprs_ciph_algo algo);
+
 /* GSM TS 04.64 / Section A.2.1 : Generation of 'input' */
 uint32_t gprs_cipher_gen_input_ui(uint32_t iov_ui, uint8_t sapi, uint32_t lfn, uint32_t oc);
 
diff --git a/src/gsm/gprs_cipher_core.c b/src/gsm/gprs_cipher_core.c
index b9a22a1..450272b 100644
--- a/src/gsm/gprs_cipher_core.c
+++ b/src/gsm/gprs_cipher_core.c
@@ -26,8 +26,8 @@ 
 #include <osmocom/core/utils.h>
 #include <osmocom/core/linuxlist.h>
 #include <osmocom/core/plugin.h>
-
 #include <osmocom/crypt/gprs_cipher.h>
+#include <osmocom/gsm/gea.h>
 
 static LLIST_HEAD(gprs_ciphers);
 
@@ -53,12 +53,14 @@  int gprs_cipher_register(struct gprs_cipher_impl *ciph)
 int gprs_cipher_load(const char *path)
 {
 	/* load all plugins available from path */
-	return osmo_plugin_load_all(path);
+	if (path)
+		return osmo_plugin_load_all(path);
+	return 0;
 }
 
 /* function to be called by core code */
 int gprs_cipher_run(uint8_t *out, uint16_t len, enum gprs_ciph_algo algo,
-		    uint64_t kc, uint32_t iv, enum gprs_cipher_direction dir)
+		    uint8_t *kc, uint32_t iv, enum gprs_cipher_direction dir)
 {
 	if (algo >= ARRAY_SIZE(selected_ciphers))
 		return -ERANGE;
@@ -73,6 +75,18 @@  int gprs_cipher_run(uint8_t *out, uint16_t len, enum gprs_ciph_algo algo,
 	return selected_ciphers[algo]->run(out, len, kc, iv, dir);
 }
 
+unsigned gprs_cipher_key_length(enum gprs_ciph_algo algo)
+{
+	switch (algo) {
+	case GPRS_ALGO_GEA0: return 0;
+	case GPRS_ALGO_GEA1: return 8;
+	case GPRS_ALGO_GEA2: return 8;
+	case GPRS_ALGO_GEA3: return 8;
+	case GPRS_ALGO_GEA4: return 16;
+	default: return 0;
+	}
+}
+
 int gprs_cipher_supported(enum gprs_ciph_algo algo)
 {
 	if (algo >= ARRAY_SIZE(selected_ciphers))
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 3a4a643..3beb1e9 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -31,6 +31,7 @@  gprs_cipher_load;
 gprs_cipher_register;
 gprs_cipher_run;
 gprs_cipher_supported;
+gprs_cipher_key_length;
 gprs_tlli_type;
 gprs_tmsi2tlli;