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
This commit is contained in:
Neels Hofmeyr 2021-06-10 00:48:15 +02:00
parent eabc6fd4b1
commit 4a9756c17a
5 changed files with 73 additions and 10 deletions

View File

@ -54,6 +54,26 @@ struct msgb *gsm0808_create_clear_command2(uint8_t cause, bool csfb_ind);
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);

View File

@ -125,6 +125,8 @@ uint8_t gsm0808_enc_encrypt_info(struct msgb *msg,
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)

View File

@ -228,22 +228,32 @@ struct msgb *gsm0808_create_clear_command2(uint8_t cause, bool csfb_ind)
return msg;
}
/*! Create BSSMAP Cipher Mode Command message
/*! Superseded by gsm0808_create_cipher2() to include Kc128.
* Create BSSMAP Cipher Mode Command message (without Kc128).
* \param[in] ei Mandatory Encryption Information
* \param[in] kc128 optional kc128 key for A5/4
* \param[in] cipher_response_mode optional 1-byte Cipher Response Mode
* \returns callee-allocated msgb with BSSMAP Cipher Mode Command message */
struct msgb *gsm0808_create_cipher(const struct gsm0808_encrypt_info *ei,
const uint8_t *cipher_response_mode)
{
struct gsm0808_cipher_mode_command cmc = {
.ei = *ei,
.cipher_response_mode_present = (cipher_response_mode != NULL),
.cipher_response_mode = (cipher_response_mode ? *cipher_response_mode : 0),
};
return gsm0808_create_cipher2(&cmc);
}
/*! Create BSSMAP Cipher Mode Command message.
* \param[in] cmc Information to encode.
* \returns callee-allocated msgb with BSSMAP Cipher Mode Command message */
struct msgb *gsm0808_create_cipher2(const struct gsm0808_cipher_mode_command *cmc)
{
/* See also: 3GPP TS 48.008 3.2.1.30 CIPHER MODE COMMAND */
struct msgb *msg;
/* Mandatory emelent! */
OSMO_ASSERT(ei);
msg =
msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
"cipher-mode-command");
msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "cipher-mode-command");
if (!msg)
return NULL;
@ -251,12 +261,16 @@ struct msgb *gsm0808_create_cipher(const struct gsm0808_encrypt_info *ei,
msgb_v_put(msg, BSS_MAP_MSG_CIPHER_MODE_CMD);
/* Encryption Information 3.2.2.10 */
gsm0808_enc_encrypt_info(msg, ei);
gsm0808_enc_encrypt_info(msg, &cmc->ei);
/* Cipher Response Mode 3.2.2.34 */
if (cipher_response_mode)
if (cmc->cipher_response_mode_present)
msgb_tv_put(msg, GSM0808_IE_CIPHER_RESPONSE_MODE,
*cipher_response_mode);
cmc->cipher_response_mode);
/* Kc128 3.2.2.109 */
if (cmc->kc128_present)
gsm0808_enc_kc128(msg, cmc->kc128);
/* pre-pend the header */
msg->l3h =

View File

@ -767,6 +767,30 @@ int gsm0808_dec_encrypt_info(struct gsm0808_encrypt_info *ei,
return (int)(elem - old_elem);
}
/*! Encode TS 48.008 Kc128 IE.
* \param[out] msg Message Buffer to which IE is to be appended.
* \param[in] kc128 Pointer to 16 bytes of Kc128 key data.
* \returns number of bytes appended to msg */
int gsm0808_enc_kc128(struct msgb *msg, const uint8_t *kc128)
{
uint8_t *start = msg->tail;
msgb_tv_fixed_put(msg, GSM0808_IE_KC_128, 16, kc128);
return msg->tail - start;
}
/*! Decode TS 48.008 Kc128 IE.
* \param[out] kc128 Target buffer for received Kc128 key, 16 bytes long.
* \param[in] elem IE value to be decoded (without IE discriminator).
* \param[in] len Length of elem in bytes.
* \returns number of bytes parsed; negative on error */
int gsm0808_dec_kc128(uint8_t *kc128, const uint8_t *elem, uint8_t len)
{
if (len != 16)
return -EINVAL;
memcpy(kc128, elem, 16);
return len;
}
/* Store individual Cell Identifier information in a CGI, without clearing the remaining ones.
* This is useful to supplement one CGI with information from more than one Cell Identifier,
* which in turn is useful to match Cell Identifiers of differing kinds to each other.

View File

@ -170,6 +170,7 @@ gsm0808_create_ass_compl2;
gsm0808_create_assignment_failure;
gsm0808_create_ass_fail;
gsm0808_create_cipher;
gsm0808_create_cipher2;
gsm0808_create_cipher_complete;
gsm0808_create_cipher_reject;
gsm0808_create_cipher_reject_ext;
@ -218,6 +219,8 @@ gsm0808_enc_channel_type;
gsm0808_dec_channel_type;
gsm0808_enc_encrypt_info;
gsm0808_dec_encrypt_info;
gsm0808_enc_kc128;
gsm0808_dec_kc128;
gsm0808_enc_cell_id_list;
gsm0808_enc_cell_id_list2;
gsm0808_dec_cell_id_list;