diff mbox

Update internal GPRS cipher API

Message ID 1461242790-18639-1-git-send-email-msuraev@sysmocom.de
State Not Applicable
Headers show

Commit Message

Max April 21, 2016, 12:46 p.m. UTC
From: Max <msuraev@sysmocom.de>

Update internal API (for GPRS cipher implementors): make it compliant
with ETSI TS 155.22. External API left untouched.
---
 TODO-RELEASE                        |  3 ++-
 include/osmocom/crypt/gprs_cipher.h |  8 ++++++--
 src/gsm/gprs_cipher_core.c          | 23 +++++++++++++++++++++--
 src/gsm/libosmogsm.map              |  1 +
 4 files changed, 30 insertions(+), 5 deletions(-)
diff mbox

Patch

diff --git a/TODO-RELEASE b/TODO-RELEASE
index 0939336..ffdea4b 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -1,3 +1,4 @@ 
-#library	what		description / commit summary line
+#library	what			description / commit summary line
+libosmogsm	internal API update	Internal API for GPRS cipher implementors updated to accommodate for arbitrary key lengths
 libosmocore	change major	external talloc dependency / internal talloc removal
 libosmocore	change major	size of ph_data_param struct changed / Extend L1SAP PH-DATA with presence information
\ No newline at end of file
diff --git a/include/osmocom/crypt/gprs_cipher.h b/include/osmocom/crypt/gprs_cipher.h
index 940b07b..d6edefa 100644
--- a/include/osmocom/crypt/gprs_cipher.h
+++ b/include/osmocom/crypt/gprs_cipher.h
@@ -9,6 +9,7 @@  enum gprs_ciph_algo {
 	GPRS_ALGO_GEA1,
 	GPRS_ALGO_GEA2,
 	GPRS_ALGO_GEA3,
+	GPRS_ALGO_GEA4,
 	_GPRS_ALGO_NUM
 };
 
@@ -27,7 +28,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);
 };
 
@@ -39,11 +40,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..e4fac04 100644
--- a/src/gsm/gprs_cipher_core.c
+++ b/src/gsm/gprs_cipher_core.c
@@ -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,23 @@  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);
 }
 
+/*! \brief Obtain key lenght for given GPRS cipher
+ *  \param[in] algo Enum representive GPRS cipher
+ *  \returns unsigned integer key length for supported algorithms,
+ *  for GEA0 and unknown ciphers will return 0
+ */
+unsigned gprs_cipher_key_length(enum gprs_ciph_algo algo)
+{
+	switch (algo) {
+	case GPRS_ALGO_GEA0: return 0;
+	case GPRS_ALGO_GEA1:
+	case GPRS_ALGO_GEA2:
+	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 6886a6c..a526756 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -40,6 +40,7 @@  gprs_cipher_load;
 gprs_cipher_register;
 gprs_cipher_run;
 gprs_cipher_supported;
+gprs_cipher_key_length;
 gprs_tlli_type;
 gprs_tmsi2tlli;