diff --git a/docs/_pages/docs.md b/docs/_pages/docs.md
index 4340c7140..436bdbca4 100644
--- a/docs/_pages/docs.md
+++ b/docs/_pages/docs.md
@@ -40,6 +40,7 @@ head_inline: ""
 - @infinitydon
   - [Open5GS on Amazon Elastic Kubernetes Service](https://aws.amazon.com/blogs/opensource/open-source-mobile-core-network-implementation-on-amazon-elastic-kubernetes-service/)
   - [Kubernetes Open5GS Deployment](https://dev.to/infinitydon/virtual-4g-simulation-using-kubernetes-and-gns3-3b7k?fbclid=IwAR1p99h13a-mCfejanbBQe0H0-jp5grXkn5mWf1WrTHf47UtegB2-UHGGZQ)
+  - [5G Core SBI mTLS Using External Certificate PKI](https://futuredon.medium.com/5g-core-sbi-mtls-using-external-certificate-pki-4ffc02ac7728)
 
 - @nickvsnetworking
   - [My first 5G Core : Open5GS and UERANSIM](http://nickvsnetworking.com/my-first-5g-core-open5gs-and-ueransim/)
diff --git a/lib/proto/types.h b/lib/proto/types.h
index b05626a2a..ae209fd0d 100644
--- a/lib/proto/types.h
+++ b/lib/proto/types.h
@@ -80,6 +80,7 @@ extern "C" {
 #define OGS_MAX_DNN_LEN                 100
 #define OGS_MAX_APN_LEN                 OGS_MAX_DNN_LEN
 #define OGS_MAX_PCO_LEN                 251
+#define OGS_MAX_EPCO_LEN                65535
 #define OGS_MAX_FQDN_LEN                256
 
 #define OGS_MAX_NUM_OF_SERVED_GUAMI     8
diff --git a/src/amf/context.c b/src/amf/context.c
index e13600083..c1075554c 100644
--- a/src/amf/context.c
+++ b/src/amf/context.c
@@ -2112,9 +2112,6 @@ void amf_sess_remove(amf_sess_t *sess)
     if (sess->nssf.nrf.client)
         ogs_sbi_client_remove(sess->nssf.nrf.client);
 
-    OGS_NAS_CLEAR_DATA(&sess->ue_pco);
-    OGS_TLV_CLEAR_DATA(&sess->pgw_pco);
-
     ogs_pool_free(&amf_sess_pool, sess);
 
     stats_remove_amf_session();
diff --git a/src/amf/context.h b/src/amf/context.h
index 1479f00d2..8660bfdc7 100644
--- a/src/amf/context.h
+++ b/src/amf/context.h
@@ -648,15 +648,6 @@ typedef struct amf_sess_s {
     ogs_s_nssai_t mapped_hplmn;
     char *dnn;
 
-    /* Save Protocol Configuration Options from UE */
-    struct {
-        uint8_t length;
-        uint8_t *buffer;
-    } ue_pco; 
-
-    /* Save Protocol Configuration Options from PGW */
-    ogs_tlv_octet_t pgw_pco;
-
 } amf_sess_t;
 
 void amf_context_init(void);
diff --git a/src/mme/esm-build.c b/src/mme/esm-build.c
index 55edfef25..5ab89be36 100644
--- a/src/mme/esm-build.c
+++ b/src/mme/esm-build.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 by Sukchan Lee 
+ * Copyright (C) 2019-2023 by Sukchan Lee 
  *
  * This file is part of Open5GS.
  *
@@ -228,21 +228,20 @@ ogs_pkbuf_t *esm_build_activate_default_bearer_context_request(
         apn_ambr_build(apn_ambr, session->ambr.downlink, session->ambr.uplink);
     }
 
-    if (sess->pgw_pco.presence && sess->pgw_pco.len && sess->pgw_pco.data) {
-        if (mme_ue->ue_network_capability.
-                extended_protocol_configuration_options) {
-            activate_default_eps_bearer_context_request->presencemask |=
-                OGS_NAS_EPS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_EXTENDED_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT;
-            extended_protocol_configuration_options->length = sess->pgw_pco.len;
-            extended_protocol_configuration_options->buffer =
-                sess->pgw_pco.data;
-        } else {
-            activate_default_eps_bearer_context_request->presencemask |=
-                OGS_NAS_EPS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT;
-            protocol_configuration_options->length = sess->pgw_pco.len;
-            memcpy(protocol_configuration_options->buffer,
-                    sess->pgw_pco.data, protocol_configuration_options->length);
-        }
+    if (sess->pgw_epco.presence && sess->pgw_epco.len && sess->pgw_epco.data) {
+        activate_default_eps_bearer_context_request->presencemask |=
+            OGS_NAS_EPS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_EXTENDED_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT;
+        extended_protocol_configuration_options->length =
+            sess->pgw_epco.len;
+        extended_protocol_configuration_options->buffer =
+            sess->pgw_epco.data;
+    } else if (sess->pgw_pco.presence && sess->pgw_pco.len &&
+            sess->pgw_pco.data) {
+        activate_default_eps_bearer_context_request->presencemask |=
+            OGS_NAS_EPS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT;
+        protocol_configuration_options->length = sess->pgw_pco.len;
+        memcpy(protocol_configuration_options->buffer,
+                sess->pgw_pco.data, protocol_configuration_options->length);
     }
 
     if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST)
diff --git a/src/mme/esm-handler.c b/src/mme/esm-handler.c
index cb5d819b9..3eb0bd4f3 100644
--- a/src/mme/esm-handler.c
+++ b/src/mme/esm-handler.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 by Sukchan Lee 
+ * Copyright (C) 2019-2023 by Sukchan Lee 
  *
  * This file is part of Open5GS.
  *
@@ -106,9 +106,17 @@ int esm_handle_pdn_connectivity_request(mme_bearer_t *bearer,
     }
 
     if (req->presencemask &
+        OGS_NAS_EPS_PDN_CONNECTIVITY_REQUEST_EXTENDED_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT) {
+        ogs_nas_extended_protocol_configuration_options_t
+            *extended_protocol_configuration_options =
+            &req->extended_protocol_configuration_options;
+
+        OGS_NAS_STORE_DATA(&sess->ue_epco,
+            extended_protocol_configuration_options);
+    } else if (req->presencemask &
         OGS_NAS_EPS_PDN_CONNECTIVITY_REQUEST_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT) {
         ogs_nas_protocol_configuration_options_t
-            *protocol_configuration_options = 
+            *protocol_configuration_options =
             &req->protocol_configuration_options;
 
         OGS_NAS_STORE_DATA(&sess->ue_pco, protocol_configuration_options);
@@ -182,9 +190,17 @@ int esm_handle_information_response(mme_sess_t *sess,
     }
 
     if (rsp->presencemask &
+        OGS_NAS_EPS_ESM_INFORMATION_RESPONSE_EXTENDED_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT) {
+        ogs_nas_extended_protocol_configuration_options_t
+            *extended_protocol_configuration_options =
+            &rsp->extended_protocol_configuration_options;
+
+        OGS_NAS_STORE_DATA(&sess->ue_epco,
+            extended_protocol_configuration_options);
+    } else if (rsp->presencemask &
         OGS_NAS_EPS_ESM_INFORMATION_RESPONSE_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT) {
         ogs_nas_protocol_configuration_options_t
-            *protocol_configuration_options = 
+            *protocol_configuration_options =
                 &rsp->protocol_configuration_options;
         OGS_NAS_STORE_DATA(&sess->ue_pco, protocol_configuration_options);
     }
diff --git a/src/mme/mme-context.c b/src/mme/mme-context.c
index 8013aab10..86a22fe0d 100644
--- a/src/mme/mme-context.c
+++ b/src/mme/mme-context.c
@@ -3260,7 +3260,9 @@ void mme_sess_remove(mme_sess_t *sess)
     mme_bearer_remove_all(sess);
 
     OGS_NAS_CLEAR_DATA(&sess->ue_pco);
+    OGS_NAS_CLEAR_DATA(&sess->ue_epco);
     OGS_TLV_CLEAR_DATA(&sess->pgw_pco);
+    OGS_TLV_CLEAR_DATA(&sess->pgw_epco);
 
     ogs_pool_free(&mme_sess_pool, sess);
 
diff --git a/src/mme/mme-context.h b/src/mme/mme-context.h
index 6e44c0ba9..1dbf08dc1 100644
--- a/src/mme/mme-context.h
+++ b/src/mme/mme-context.h
@@ -641,8 +641,17 @@ typedef struct mme_sess_s {
         uint8_t *buffer;
     } ue_pco;
 
+    /* Save Extended Protocol Configuration Options from UE */
+    struct {
+        uint16_t length;
+        uint8_t *buffer;
+    } ue_epco;
+
     /* Save Protocol Configuration Options from PGW */
     ogs_tlv_octet_t pgw_pco;
+
+    /* Save Extended Protocol Configuration Options from PGW */
+    ogs_tlv_octet_t pgw_epco;
 } mme_sess_t;
 
 #define MME_HAVE_ENB_S1U_PATH(__bEARER) \
diff --git a/src/mme/mme-s11-build.c b/src/mme/mme-s11-build.c
index bf7f67df0..75640921f 100644
--- a/src/mme/mme-s11-build.c
+++ b/src/mme/mme-s11-build.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 by Sukchan Lee 
+ * Copyright (C) 2019-2023 by Sukchan Lee 
  *
  * This file is part of Open5GS.
  *
@@ -253,7 +253,13 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
         req->aggregate_maximum_bit_rate.len = sizeof(ambr);
     }
 
-    if (sess->ue_pco.length && sess->ue_pco.buffer) {
+    if (sess->ue_epco.length && sess->ue_epco.buffer) {
+        req->extended_protocol_configuration_options.presence = 1;
+        req->extended_protocol_configuration_options.data =
+            sess->ue_epco.buffer;
+        req->extended_protocol_configuration_options.len =
+            sess->ue_epco.length;
+    } else if (sess->ue_pco.length && sess->ue_pco.buffer) {
         req->protocol_configuration_options.presence = 1;
         req->protocol_configuration_options.data = sess->ue_pco.buffer;
         req->protocol_configuration_options.len = sess->ue_pco.length;
diff --git a/src/mme/mme-s11-handler.c b/src/mme/mme-s11-handler.c
index 6bef8937f..59f1ea98d 100644
--- a/src/mme/mme-s11-handler.c
+++ b/src/mme/mme-s11-handler.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 by Sukchan Lee 
+ * Copyright (C) 2019-2023 by Sukchan Lee 
  *
  * This file is part of Open5GS.
  *
@@ -373,8 +373,13 @@ void mme_s11_handle_create_session_response(
                 rsp->pdn_address_allocation.len);
     }
 
+    /* ePCO */
+    if (rsp->extended_protocol_configuration_options.presence) {
+        OGS_TLV_STORE_DATA(&sess->pgw_epco,
+                &rsp->extended_protocol_configuration_options);
+
     /* PCO */
-    if (rsp->protocol_configuration_options.presence) {
+    } else if (rsp->protocol_configuration_options.presence) {
         OGS_TLV_STORE_DATA(&sess->pgw_pco,
                 &rsp->protocol_configuration_options);
     }
diff --git a/src/smf/context.c b/src/smf/context.c
index 867c11480..6e7a73588 100644
--- a/src/smf/context.c
+++ b/src/smf/context.c
@@ -1667,12 +1667,13 @@ void smf_sess_remove(smf_sess_t *sess)
     ogs_fsm_fini(&sess->sm, &e);
 
     OGS_TLV_CLEAR_DATA(&sess->gtp.ue_pco);
+    OGS_TLV_CLEAR_DATA(&sess->gtp.ue_epco);
     OGS_TLV_CLEAR_DATA(&sess->gtp.user_location_information);
     OGS_TLV_CLEAR_DATA(&sess->gtp.ue_timezone);
     OGS_TLV_CLEAR_DATA(&sess->gtp.charging_characteristics);
     OGS_TLV_CLEAR_DATA(&sess->gtp.v1.qos);
 
-    OGS_NAS_CLEAR_DATA(&sess->nas.ue_pco);
+    OGS_NAS_CLEAR_DATA(&sess->nas.ue_epco);
 
     for (i = 0; i < sess->policy.num_of_pcc_rule; i++)
         OGS_PCC_RULE_FREE(&sess->policy.pcc_rule[i]);
diff --git a/src/smf/context.h b/src/smf/context.h
index 40eebb76f..2429a3138 100644
--- a/src/smf/context.h
+++ b/src/smf/context.h
@@ -325,6 +325,7 @@ typedef struct smf_sess_s {
     struct {
         uint8_t version; /* GTPC version */
         ogs_tlv_octet_t ue_pco;
+        ogs_tlv_octet_t ue_epco;
         ogs_tlv_octet_t user_location_information;
         ogs_tlv_octet_t ue_timezone;
         ogs_tlv_octet_t charging_characteristics;
@@ -354,7 +355,7 @@ typedef struct smf_sess_s {
     } gy;
 
     struct {
-        ogs_nas_extended_protocol_configuration_options_t ue_pco;
+        ogs_nas_extended_protocol_configuration_options_t ue_epco;
     } nas; /* Saved from NAS-5GS */
 
     struct {
diff --git a/src/smf/gsm-build.c b/src/smf/gsm-build.c
index 2311c9223..87059b402 100644
--- a/src/smf/gsm-build.c
+++ b/src/smf/gsm-build.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019,2020 by Sukchan Lee 
+ * Copyright (C) 2019-2023 by Sukchan Lee 
  *
  * This file is part of Open5GS.
  *
@@ -48,8 +48,8 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess)
     ogs_nas_qos_flow_description_t
         qos_flow_description[OGS_NAS_MAX_NUM_OF_QOS_FLOW_DESCRIPTION];
 
-    uint8_t pco_buf[OGS_MAX_PCO_LEN];
-    int16_t pco_len;
+    uint8_t *epco_buf = NULL;
+    int16_t epco_len;
 
     selected_pdu_session_type = &pdu_session_establishment_accept->
         selected_pdu_session_type;
@@ -134,11 +134,11 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess)
     rv = ogs_nas_build_qos_rules(authorized_qos_rules, qos_rule, 1);
     if (rv != OGS_OK) {
         ogs_error("ogs_nas_build_qos_rules() failed");
-        return NULL;
+        goto cleanup;
     }
     if (!authorized_qos_rules->length) {
         ogs_error("No length");
-        return NULL;
+        goto cleanup;
     }
 
     /* Session-AMBR */
@@ -167,7 +167,7 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess)
         pdu_address->length = OGS_NAS_PDU_ADDRESS_IPV4V6_LEN;
     } else {
         ogs_error("Unexpected PDN Type %u", pdu_address->pdn_type);
-        return NULL;
+        goto cleanup;
     }
 
     /* GSM cause */
@@ -211,22 +211,24 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess)
             authorized_qos_flow_descriptions, qos_flow_description, 1);
     if (rv != OGS_OK) {
         ogs_error("ogs_nas_build_qos_flow_descriptions() failed");
-        return NULL;
+        goto cleanup;
     }
     if (!authorized_qos_flow_descriptions->length) {
         ogs_error("No length");
-        return NULL;
+        goto cleanup;
     }
 
     /* Extended protocol configuration options */
-    if (sess->nas.ue_pco.buffer && sess->nas.ue_pco.length) {
-        pco_len = smf_pco_build(pco_buf,
-                sess->nas.ue_pco.buffer, sess->nas.ue_pco.length);
-        ogs_assert(pco_len > 0);
+    if (sess->nas.ue_epco.buffer && sess->nas.ue_epco.length) {
+        epco_buf = ogs_calloc(OGS_MAX_EPCO_LEN, sizeof(uint8_t));
+        ogs_assert(epco_buf);
+        epco_len = smf_pco_build(epco_buf,
+                sess->nas.ue_epco.buffer, sess->nas.ue_epco.length);
+        ogs_assert(epco_len > 0);
         pdu_session_establishment_accept->presencemask |=
             OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_ACCEPT_EXTENDED_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT;
-        extended_protocol_configuration_options->buffer = pco_buf;
-        extended_protocol_configuration_options->length = pco_len;
+        extended_protocol_configuration_options->buffer = epco_buf;
+        extended_protocol_configuration_options->length = epco_len;
     }
 
     /* DNN */
@@ -240,8 +242,14 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess)
     pkbuf = ogs_nas_5gs_plain_encode(&message);
     ogs_assert(pkbuf);
 
-    ogs_free(authorized_qos_rules->buffer);
-    ogs_free(authorized_qos_flow_descriptions->buffer);
+cleanup:
+    if (epco_buf)
+        ogs_free(epco_buf);
+
+    if (authorized_qos_rules->buffer)
+        ogs_free(authorized_qos_rules->buffer);
+    if (authorized_qos_flow_descriptions->buffer)
+        ogs_free(authorized_qos_flow_descriptions->buffer);
 
     return pkbuf;
 }
diff --git a/src/smf/gsm-handler.c b/src/smf/gsm-handler.c
index 4f2eb6bda..4bdca9b1b 100644
--- a/src/smf/gsm-handler.c
+++ b/src/smf/gsm-handler.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019,2020 by Sukchan Lee 
+ * Copyright (C) 2019-2023 by Sukchan Lee 
  *
  * This file is part of Open5GS.
  *
@@ -62,7 +62,7 @@ int gsm_handle_pdu_session_establishment_request(
 
     if (pdu_session_establishment_request->presencemask &
         OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_REQUEST_EXTENDED_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT) {
-        OGS_NAS_STORE_DATA(&sess->nas.ue_pco,
+        OGS_NAS_STORE_DATA(&sess->nas.ue_epco,
             &pdu_session_establishment_request->
                 extended_protocol_configuration_options);
     }
diff --git a/src/smf/s5c-build.c b/src/smf/s5c-build.c
index 02041f327..b779dca18 100644
--- a/src/smf/s5c-build.c
+++ b/src/smf/s5c-build.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 by Sukchan Lee 
+ * Copyright (C) 2019-2023 by Sukchan Lee 
  *
  * This file is part of Open5GS.
  *
@@ -28,6 +28,8 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
     int rv;
     smf_bearer_t *bearer = NULL;
 
+    ogs_pkbuf_t *pkbuf = NULL;
+
     ogs_gtp2_message_t gtp_message;
     ogs_gtp2_create_session_response_t *rsp = NULL;
 
@@ -45,6 +47,8 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
     int len;
     uint8_t pco_buf[OGS_MAX_PCO_LEN];
     int16_t pco_len;
+    uint8_t *epco_buf = NULL;
+    int16_t epco_len;
 
     ogs_debug("[SMF] Create Session Response");
 
@@ -85,7 +89,7 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
             &smf_s5c_teid, &len);
     if (rv != OGS_OK) {
         ogs_error("ogs_gtp2_sockaddr_to_f_teid() failed");
-        return NULL;
+        goto cleanup;
     }
     rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.
         presence = 1;
@@ -141,6 +145,19 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
         rsp->protocol_configuration_options.len = pco_len;
     }
 
+    /* ePCO */
+    if (sess->gtp.ue_epco.presence &&
+            sess->gtp.ue_epco.len && sess->gtp.ue_epco.data) {
+        epco_buf = ogs_calloc(OGS_MAX_EPCO_LEN, sizeof(uint8_t));
+        ogs_assert(epco_buf);
+        epco_len = smf_pco_build(
+                epco_buf, sess->gtp.ue_epco.data, sess->gtp.ue_epco.len);
+        ogs_assert(epco_len > 0);
+        rsp->extended_protocol_configuration_options.presence = 1;
+        rsp->extended_protocol_configuration_options.data = epco_buf;
+        rsp->extended_protocol_configuration_options.len = epco_len;
+    }
+
     i = 0;
     ogs_list_for_each(&sess->bearer_list, bearer) {
         ogs_assert(i < OGS_BEARER_PER_UE);
@@ -190,7 +207,7 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
             &pgw_s5u_teid[i], &pgw_s5u_len[i]);
         if (rv != OGS_OK) {
             ogs_error("ogs_gtp2_sockaddr_to_f_teid() failed");
-            return NULL;
+            goto cleanup;
         }
 
         switch (sess->gtp_rat_type) {
@@ -219,18 +236,28 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
     }
 
     gtp_message.h.type = type;
-    return ogs_gtp2_build_msg(>p_message);
+    pkbuf = ogs_gtp2_build_msg(>p_message);
+
+cleanup:
+    if (epco_buf)
+        ogs_free(epco_buf);
+
+    return pkbuf;
 }
 
 ogs_pkbuf_t *smf_s5c_build_delete_session_response(
         uint8_t type, smf_sess_t *sess)
 {
+    ogs_pkbuf_t *pkbuf = NULL;
+
     ogs_gtp2_message_t gtp_message;
     ogs_gtp2_delete_session_response_t *rsp = NULL;
 
     ogs_gtp2_cause_t cause;
     uint8_t pco_buf[OGS_MAX_PCO_LEN];
     int16_t pco_len;
+    uint8_t *epco_buf = NULL;
+    int16_t epco_len;
 
     /* prepare cause */
     memset(&cause, 0, sizeof(cause));
@@ -257,11 +284,30 @@ ogs_pkbuf_t *smf_s5c_build_delete_session_response(
         rsp->protocol_configuration_options.len = pco_len;
     }
 
+    /* ePCO */
+    if (sess->gtp.ue_epco.presence &&
+            sess->gtp.ue_epco.len && sess->gtp.ue_epco.data) {
+        epco_buf = ogs_calloc(OGS_MAX_EPCO_LEN, sizeof(uint8_t));
+        ogs_assert(epco_buf);
+        epco_len = smf_pco_build(
+                epco_buf, sess->gtp.ue_epco.data, sess->gtp.ue_epco.len);
+        ogs_assert(epco_len > 0);
+        rsp->extended_protocol_configuration_options.presence = 1;
+        rsp->extended_protocol_configuration_options.data = epco_buf;
+        rsp->extended_protocol_configuration_options.len = epco_len;
+    }
+
     /* Private Extension */
 
     /* build */
     gtp_message.h.type = type;
-    return ogs_gtp2_build_msg(>p_message);
+    pkbuf = ogs_gtp2_build_msg(>p_message);
+
+cleanup:
+    if (epco_buf)
+        ogs_free(epco_buf);
+
+    return pkbuf;
 }
 
 ogs_pkbuf_t *smf_s5c_build_modify_bearer_response(
diff --git a/src/smf/s5c-handler.c b/src/smf/s5c-handler.c
index 555c1b303..18fdda119 100644
--- a/src/smf/s5c-handler.c
+++ b/src/smf/s5c-handler.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 by Sukchan Lee 
+ * Copyright (C) 2019-2023 by Sukchan Lee 
  *
  * This file is part of Open5GS.
  *
@@ -347,8 +347,13 @@ uint8_t smf_s5c_handle_create_session_request(
         sess->session.ambr.uplink = be32toh(ambr->uplink) * 1000;
     }
 
+    /* ePCO */
+    if (req->extended_protocol_configuration_options.presence) {
+        OGS_TLV_STORE_DATA(&sess->gtp.ue_epco,
+                &req->extended_protocol_configuration_options);
+
     /* PCO */
-    if (req->protocol_configuration_options.presence) {
+    } else if (req->protocol_configuration_options.presence) {
         OGS_TLV_STORE_DATA(&sess->gtp.ue_pco,
                 &req->protocol_configuration_options);
     }
@@ -420,13 +425,24 @@ uint8_t smf_s5c_handle_delete_session_request(
         OGS_TLV_STORE_DATA(&sess->gtp.ue_pco,
                 &req->protocol_configuration_options);
     } else {
-        /* 
+        /*
          * Clear contents to reflect whether PCO IE was included or not as part
          * of session deletion procedure
          */
         OGS_TLV_CLEAR_DATA(&sess->gtp.ue_pco);
     }
 
+    if (req->extended_protocol_configuration_options.presence) {
+        OGS_TLV_STORE_DATA(&sess->gtp.ue_epco,
+                &req->extended_protocol_configuration_options);
+    } else {
+        /*
+         * Clear contents to reflect whether PCO IE was included or not as part
+         * of session deletion procedure
+         */
+        OGS_TLV_CLEAR_DATA(&sess->gtp.ue_epco);
+    }
+
     ogs_debug("    SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
             sess->sgw_s5c_teid, sess->smf_n4_teid);
 
diff --git a/tests/attach/guti-test.c b/tests/attach/guti-test.c
index dd837144e..a66bea3db 100644
--- a/tests/attach/guti-test.c
+++ b/tests/attach/guti-test.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 by Sukchan Lee 
+ * Copyright (C) 2019-2023 by Sukchan Lee 
  *
  * This file is part of Open5GS.
  *
@@ -228,7 +228,7 @@ static void test1_func(abts_case *tc, void *data)
     memset(&sess->pdn_connectivity_param,
             0, sizeof(sess->pdn_connectivity_param));
     sess->pdn_connectivity_param.eit = 1;
-    sess->pdn_connectivity_param.pco = 1;
+    sess->pdn_connectivity_param.epco = 1;
     sess->pdn_connectivity_param.request_type =
         OGS_NAS_EPS_REQUEST_TYPE_INITIAL;
     esmbuf = testesm_build_pdn_connectivity_request(sess, false);
diff --git a/tests/attach/simple-test.c b/tests/attach/simple-test.c
index 252b08b10..655fab113 100644
--- a/tests/attach/simple-test.c
+++ b/tests/attach/simple-test.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 by Sukchan Lee 
+ * Copyright (C) 2019-2023 by Sukchan Lee 
  *
  * This file is part of Open5GS.
  *
@@ -149,7 +149,7 @@ static void test1_func(abts_case *tc, void *data)
     tests1ap_recv(test_ue, recvbuf);
 
     /* Send ESM Information Response */
-    sess->esm_information_param.pco = 1;
+    sess->esm_information_param.epco = 1;
     esmbuf = testesm_build_esm_information_response(sess);
     ABTS_PTR_NOTNULL(tc, esmbuf);
     sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf);
diff --git a/tests/common/context.h b/tests/common/context.h
index 081fbc1b7..422a6b2ab 100644
--- a/tests/common/context.h
+++ b/tests/common/context.h
@@ -257,10 +257,11 @@ typedef struct test_pdu_session_establishment_param_s {
 typedef struct test_pdn_connectivity_param_s {
     union {
         struct {
-        ED6(uint8_t eit:1;,
+        ED7(uint8_t eit:1;,
             uint8_t eit_no_required:1;,
             uint8_t apn:1;,
             uint8_t pco:1;,
+            uint8_t epco:1;,
             uint8_t spare:1;,
             uint8_t request_type:3;)
         };
@@ -272,7 +273,7 @@ typedef struct test_esm_information_param_s {
     union {
         struct {
         ED8(uint8_t pco:1;,
-            uint8_t spare1:1;,
+            uint8_t epco:1;,
             uint8_t spare2:1;,
             uint8_t spare3:1;,
             uint8_t spare4:1;,
diff --git a/tests/common/esm-build.c b/tests/common/esm-build.c
index d45e908e4..93e6034ba 100644
--- a/tests/common/esm-build.c
+++ b/tests/common/esm-build.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019,2020 by Sukchan Lee 
+ * Copyright (C) 2019-2023 by Sukchan Lee 
  *
  * This file is part of Open5GS.
  *
@@ -34,6 +34,8 @@ ogs_pkbuf_t *testesm_build_pdn_connectivity_request(
         &pdn_connectivity_request->esm_information_transfer_flag;
     ogs_nas_protocol_configuration_options_t *protocol_configuration_options =
         &pdn_connectivity_request->protocol_configuration_options;
+    ogs_nas_extended_protocol_configuration_options_t *extended_protocol_configuration_options =
+        &pdn_connectivity_request->extended_protocol_configuration_options;
 #if 0
     uint8_t ue_pco[29] =
             "\x80\x80\x21\x10\x01\x01\x00\x10\x81\x06\x00\x00\x00\x00"
@@ -87,12 +89,25 @@ ogs_pkbuf_t *testesm_build_pdn_connectivity_request(
         pdn_connectivity_request->presencemask |= OGS_NAS_EPS_PDN_CONNECTIVITY_REQUEST_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT;
         protocol_configuration_options->length = sizeof(ue_pco);
         memcpy(protocol_configuration_options->buffer, ue_pco, sizeof(ue_pco));
+    } else if (sess->pdn_connectivity_param.epco) {
+        pdn_connectivity_request->presencemask |= OGS_NAS_EPS_PDN_CONNECTIVITY_REQUEST_EXTENDED_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT;
+        extended_protocol_configuration_options->length = sizeof(ue_pco);
+        extended_protocol_configuration_options->buffer =
+            ogs_calloc(sizeof(uint8_t), extended_protocol_configuration_options->length);
+        ogs_assert(extended_protocol_configuration_options->buffer);
+        memcpy(extended_protocol_configuration_options->buffer, ue_pco, sizeof(ue_pco));
     }
 
     if (integrity_protected)
-        return test_nas_eps_security_encode(test_ue, &message);
+        pkbuf = test_nas_eps_security_encode(test_ue, &message);
     else
-        return ogs_nas_eps_plain_encode(&message);
+        pkbuf = ogs_nas_eps_plain_encode(&message);
+    ogs_assert(pkbuf);
+
+    if (extended_protocol_configuration_options->buffer)
+        ogs_free(extended_protocol_configuration_options->buffer);
+
+    return pkbuf;
 }
 
 ogs_pkbuf_t *testesm_build_pdn_disconnect_request(test_sess_t *sess)
@@ -139,6 +154,8 @@ ogs_pkbuf_t *testesm_build_esm_information_response(test_sess_t *sess)
         &esm_information_response->access_point_name;
     ogs_nas_protocol_configuration_options_t *protocol_configuration_options =
         &esm_information_response->protocol_configuration_options;
+    ogs_nas_extended_protocol_configuration_options_t *extended_protocol_configuration_options =
+        &esm_information_response->extended_protocol_configuration_options;
 
 #if 0
     uint8_t ue_pco[29] =
@@ -191,9 +208,22 @@ ogs_pkbuf_t *testesm_build_esm_information_response(test_sess_t *sess)
         esm_information_response->presencemask |= OGS_NAS_EPS_ESM_INFORMATION_RESPONSE_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT;
         protocol_configuration_options->length = sizeof(ue_pco);
         memcpy(protocol_configuration_options->buffer, ue_pco, sizeof(ue_pco));
+    } else if (sess->esm_information_param.epco) {
+        esm_information_response->presencemask |= OGS_NAS_EPS_ESM_INFORMATION_RESPONSE_EXTENDED_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT;
+        extended_protocol_configuration_options->length = sizeof(ue_pco);
+        extended_protocol_configuration_options->buffer =
+            ogs_calloc(sizeof(uint8_t), extended_protocol_configuration_options->length);
+        ogs_assert(extended_protocol_configuration_options->buffer);
+        memcpy(extended_protocol_configuration_options->buffer, ue_pco, sizeof(ue_pco));
     }
 
-    return test_nas_eps_security_encode(test_ue, &message);
+    pkbuf = test_nas_eps_security_encode(test_ue, &message);
+    ogs_assert(pkbuf);
+
+    if (extended_protocol_configuration_options->buffer)
+        ogs_free(extended_protocol_configuration_options->buffer);
+
+    return pkbuf;
 }
 
 ogs_pkbuf_t *testesm_build_activate_default_eps_bearer_context_accept(