add Kc128 to gsm0808 Create Ciphering Command

Prepare for A5/4 support in osmo-msc.

Add new function gsm0808_create_cipher2() which takes a struct as
argument instead of individual fields. This is akin to e.g.
gsm0808_create_handover_request() below in the file, and allows
backwards compatibly extending the argument list without needing a new
function signature every time.

Add struct gsm0808_cipher_mode_command, as argument list for
gsm0808_create_cipher2(), with kc128 included.

Encode the Kc128 IE in gsm0808_create_cipher2().

Implement gsm0808_create_cipher() by calling gsm0808_create_cipher2().

Change-Id: Ib3906085e0c6e5a496a9f755f0f786238a86ca34
diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h
index dc3610f..3e39460 100644
--- a/include/osmocom/gsm/gsm0808.h
+++ b/include/osmocom/gsm/gsm0808.h
@@ -54,6 +54,26 @@
 struct msgb *gsm0808_create_clear_complete(void);
 struct msgb *gsm0808_create_cipher(const struct gsm0808_encrypt_info *ei,
 				   const uint8_t *cipher_response_mode);
+
+struct gsm0808_cipher_mode_command {
+	struct gsm0808_encrypt_info ei;
+
+	/*! 3GPP TS 48.008 3.2.2.34 Cipher Response Mode, optional IE */
+	bool cipher_response_mode_present;
+	/*! 3GPP TS 48.008 3.2.2.34 Cipher Response Mode:
+	 * 0 - IMEISV must not be included by the Mobile Station;
+	 * 1 - IMEISV must be included by the Mobile Station.
+	 */
+	uint8_t cipher_response_mode;
+
+	bool kc128_present;
+	uint8_t kc128[16];
+
+	/* more items are defined in the spec and may be added later */
+	bool more_items; /*< always set this to false */
+};
+struct msgb *gsm0808_create_cipher2(const struct gsm0808_cipher_mode_command *cmc);
+
 struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id);
 struct msgb *gsm0808_create_cipher_reject(enum gsm0808_cause cause);
 struct msgb *gsm0808_create_cipher_reject_ext(enum gsm0808_cause_class class, uint8_t ext);
diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h
index 76e9064..60e665b 100644
--- a/include/osmocom/gsm/gsm0808_utils.h
+++ b/include/osmocom/gsm/gsm0808_utils.h
@@ -125,6 +125,8 @@
 				 const struct gsm0808_encrypt_info *ei);
 int gsm0808_dec_encrypt_info(struct gsm0808_encrypt_info *ei,
 			     const uint8_t *elem, uint8_t len);
+int gsm0808_enc_kc128(struct msgb *msg, const uint8_t *kc128);
+int gsm0808_dec_kc128(uint8_t *kc128, const uint8_t *elem, uint8_t len);
 uint8_t gsm0808_enc_cell_id_list2(struct msgb *msg, const struct gsm0808_cell_id_list2 *cil);
 uint8_t gsm0808_enc_cell_id_list(struct msgb *msg,
 				 const struct gsm0808_cell_id_list *cil)