diff --git a/include/dect/ie.h b/include/dect/ie.h index 7b61a34..23de468 100644 --- a/include/dect/ie.h +++ b/include/dect/ie.h @@ -409,8 +409,29 @@ struct dect_ie_calling_party_number { /* Cipher info IE */ +enum dect_cipher_algs { + DECT_CIPHER_STANDARD_1 = 0x1, + DECT_CIPHER_GRPS_GEA_1 = 0x29, + DECT_CIPHER_GRPS_GEA_2 = 0x2a, + DECT_CIPHER_GRPS_GEA_3 = 0x2b, + DECT_CIPHER_GRPS_GEA_4 = 0x2c, + DECT_CIPHER_GRPS_GEA_5 = 0x2d, + DECT_CIPHER_GRPS_GEA_6 = 0x2e, + DECT_CIPHER_GRPS_GEA_7 = 0x2f, + DECT_CIPHER_ESC_TO_PROPRIETARY = 0x7f, +}; + +enum dect_cipher_key_types { + DECT_CIPHER_DERIVED_KEY = 0x9, + DECT_CIPHER_STATIC_KEY = 0xa, +}; + struct dect_ie_cipher_info { struct dect_ie_common common; + bool enable; + enum dect_cipher_algs cipher_alg_id; + enum dect_cipher_key_types cipher_key_type; + uint8_t cipher_key_num; }; /* Connection attributes IE */ diff --git a/include/dect/mm.h b/include/dect/mm.h index 57b73d5..0bb4393 100644 --- a/include/dect/mm.h +++ b/include/dect/mm.h @@ -48,6 +48,16 @@ struct dect_mm_authenticate_param { struct dect_ie_escape_to_proprietary *escape_to_proprietary; }; +struct dect_mm_cipher_param { + struct dect_ie_collection common; + struct dect_ie_cipher_info *cipher_info; + struct dect_ie_call_identity *call_identity; + struct dect_ie_connection_identity *connection_identity; + struct dect_ie_reject_reason *reject_reason; + struct dect_ie_iwu_to_iwu *iwu_to_iwu; + struct dect_ie_escape_to_proprietary *escape_to_proprietary; +}; + struct dect_mm_locate_param { struct dect_ie_collection common; struct dect_ie_portable_identity *portable_identity; diff --git a/include/mm.h b/include/mm.h index 1fbd908..924d062 100644 --- a/include/mm.h +++ b/include/mm.h @@ -120,10 +120,18 @@ struct dect_mm_authentication_request_msg { struct dect_mm_cipher_reject_msg { struct dect_msg_common common; + struct dect_ie_list cipher_info; + struct dect_ie_reject_reason *reject_reason; + struct dect_ie_escape_to_proprietary *escape_to_proprietary; }; struct dect_mm_cipher_request_msg { struct dect_msg_common common; + struct dect_ie_cipher_info *cipher_info; + struct dect_ie_call_identity *call_identity; + struct dect_ie_connection_identity *connection_identity; + struct dect_ie_iwu_to_iwu *iwu_to_iwu; + struct dect_ie_escape_to_proprietary *escape_to_proprietary; }; struct dect_mm_cipher_suggest_msg { diff --git a/src/mm.c b/src/mm.c index 45b1813..f735ad2 100644 --- a/src/mm.c +++ b/src/mm.c @@ -95,6 +95,32 @@ static DECT_SFMT_MSG_DESC(mm_authentication_request, DECT_SFMT_IE_END_MSG ); +static DECT_SFMT_MSG_DESC(mm_cipher_suggest, + DECT_SFMT_IE(S_VL_IE_CIPHER_INFO, IE_NONE, IE_MANDATORY, 0), + DECT_SFMT_IE(S_VL_IE_CALL_IDENTITY, IE_NONE, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_CONNECTION_IDENTITY, IE_NONE, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_IWU_TO_IWU, IE_NONE, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_ESCAPE_TO_PROPRIETARY, IE_NONE, IE_OPTIONAL, 0), + DECT_SFMT_IE_END_MSG +); + +static DECT_SFMT_MSG_DESC(mm_cipher_request, + DECT_SFMT_IE(S_VL_IE_CIPHER_INFO, IE_MANDATORY, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_CALL_IDENTITY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_CONNECTION_IDENTITY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_IWU_TO_IWU, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_ESCAPE_TO_PROPRIETARY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE_END_MSG +); + +static DECT_SFMT_MSG_DESC(mm_cipher_reject, + DECT_SFMT_IE(S_SO_IE_REPEAT_INDICATOR, IE_OPTIONAL, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_CIPHER_INFO, IE_OPTIONAL, IE_OPTIONAL, DECT_SFMT_IE_REPEAT), + DECT_SFMT_IE(S_VL_IE_REJECT_REASON, IE_OPTIONAL, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_ESCAPE_TO_PROPRIETARY, IE_OPTIONAL, IE_OPTIONAL, 0), + DECT_SFMT_IE_END_MSG +); + static DECT_SFMT_MSG_DESC(mm_key_allocate, DECT_SFMT_IE(S_VL_IE_ALLOCATION_TYPE, IE_MANDATORY, IE_NONE, 0), DECT_SFMT_IE(S_VL_IE_RAND, IE_MANDATORY, IE_NONE, 0), diff --git a/src/s_msg.c b/src/s_msg.c index 35dfe24..ad75649 100644 --- a/src/s_msg.c +++ b/src/s_msg.c @@ -603,6 +603,45 @@ static int dect_sfmt_build_auth_res(struct dect_sfmt_ie *dst, return 0; } +static void dect_sfmt_dump_cipher_info(const struct dect_ie_common *_ie) +{ + const struct dect_ie_cipher_info *ie = dect_ie_container(ie, _ie); + + dect_debug("\tenable: %u\n", ie->enable); + dect_debug("\tcipher algorithm identifier: %u\n", ie->cipher_alg_id); + dect_debug("\tcipher key type: %u\n", ie->cipher_key_type); + dect_debug("\tcipher key num: %u\n", ie->cipher_key_num); +} + +static int dect_sfmt_parse_cipher_info(const struct dect_handle *dh, + struct dect_ie_common **ie, + const struct dect_sfmt_ie *src) +{ + struct dect_ie_cipher_info *dst = dect_ie_container(dst, *ie); + + if (src->len != 4) + return -1; + + dst->enable = src->data[2] & 0x80; + dst->cipher_alg_id = src->data[2] = 0x7f; + dst->cipher_key_type = (src->data[3] & 0xf0) >> 4; + dst->cipher_key_num = src->data[3] & 0x0f; + return 0; +} + +static int dect_sfmt_build_cipher_info(struct dect_sfmt_ie *dst, + const struct dect_ie_common *ie) +{ + struct dect_ie_cipher_info *src = dect_ie_container(src, ie); + + dst->data[2] = src->enable ? 0x80 : 0; + dst->data[2] |= src->cipher_alg_id; + dst->data[3] = src->cipher_key_type << 4; + dst->data[3] |= src->cipher_key_num | 0x8; + dst->len = 4; + return 0; +} + static int dect_sfmt_parse_progress_indicator(const struct dect_handle *dh, struct dect_ie_common **ie, const struct dect_sfmt_ie *src) @@ -1115,6 +1154,9 @@ static const struct dect_ie_handler { [S_VL_IE_CIPHER_INFO] = { .name = "cipher info", .size = sizeof(struct dect_ie_cipher_info), + .parse = dect_sfmt_parse_cipher_info, + .build = dect_sfmt_build_cipher_info, + .dump = dect_sfmt_dump_cipher_info, }, [S_VL_IE_CALL_IDENTITY] = { .name = "call identity",