diff --git a/openair-cn/MME_APP/mme_app_authentication.c b/openair-cn/MME_APP/mme_app_authentication.c
index 5f20bbc1273ac3d5c3481c744fd7e423a3043ab4..99c6089adeb83ff0fd4a8a57f3b20746d0fef4db 100644
--- a/openair-cn/MME_APP/mme_app_authentication.c
+++ b/openair-cn/MME_APP/mme_app_authentication.c
@@ -65,6 +65,21 @@ int mme_app_request_authentication_info(const mme_app_imsi_t imsi,
     auth_info_req = &message_p->ittiMsg.s6a_auth_info_req;
     MME_APP_IMSI_TO_STRING(imsi, auth_info_req->imsi);
     memcpy(&auth_info_req->visited_plmn, plmn, sizeof(plmn_t));
+    MME_APP_DEBUG("%s visited_plmn MCC %X%X%X MNC %X%X%X\n",
+    		__FUNCTION__,
+    		auth_info_req->visited_plmn.MCCdigit1,
+    		auth_info_req->visited_plmn.MCCdigit2,
+    		auth_info_req->visited_plmn.MCCdigit3,
+    		auth_info_req->visited_plmn.MNCdigit1,
+    		auth_info_req->visited_plmn.MNCdigit2,
+    		auth_info_req->visited_plmn.MNCdigit3);
+    uint8_t *ptr = (uint8_t *)&auth_info_req->visited_plmn;
+    MME_APP_DEBUG("%s visited_plmn %X%X%X%X%X%X\n",
+    		__FUNCTION__,
+    		ptr[0],
+    		ptr[1],
+    		ptr[2]);
+
     auth_info_req->nb_of_vectors = nb_of_vectors;
     if (auts != NULL) {
         auth_info_req->re_synchronization = 1;
diff --git a/openair-cn/MME_APP/mme_app_bearer.c b/openair-cn/MME_APP/mme_app_bearer.c
index aacbf12c18eb22b3960f8a8614672bf70a16940c..1edb32d5090392ff6000eb38e0d73dddc75a6331 100644
--- a/openair-cn/MME_APP/mme_app_bearer.c
+++ b/openair-cn/MME_APP/mme_app_bearer.c
@@ -287,13 +287,15 @@ mme_app_handle_conn_est_cnf(
     mme_app_connection_establishment_cnf_t *establishment_cnf_p = NULL;
     bearer_context_t                       *current_bearer_p    = NULL;
     ebi_t                                   bearer_id           = 0;
-    uint8_t                                *keNB                = NULL;
+    uint8_t                                 keNB[32];
 
     MME_APP_DEBUG("Received NAS_CONNECTION_ESTABLISHMENT_CNF from NAS\n");
 
     ue_context_p = mme_ue_context_exists_nas_ue_id(&mme_app_desc.mme_ue_contexts, nas_conn_est_cnf_pP->UEid);
     if (ue_context_p == NULL) {
-        MME_APP_ERROR("UE context doesn't exist\n");
+        MME_APP_ERROR("UE context doesn't exist for UE ox%08X/dec%u\n",
+        		nas_conn_est_cnf_pP->UEid,
+        		nas_conn_est_cnf_pP->UEid);
         return;
     }
 
@@ -332,9 +334,8 @@ mme_app_handle_conn_est_cnf(
     establishment_cnf_p->ambr                              = ue_context_p->used_ambr;
 
     MME_APP_DEBUG("Derive keNB with UL NAS COUNT %x\n", nas_conn_est_cnf_pP->ul_nas_count);
-    derive_keNB(ue_context_p->vector_in_use->kasme, nas_conn_est_cnf_pP->ul_nas_count, &keNB); //156
+    derive_keNB(ue_context_p->vector_in_use->kasme, nas_conn_est_cnf_pP->ul_nas_count, keNB); //156
     memcpy(establishment_cnf_p->keNB, keNB, 32);
-    free(keNB);
 
     itti_send_msg_to_task(TASK_S1AP, INSTANCE_DEFAULT, message_p);
 }
@@ -355,8 +356,9 @@ mme_app_handle_conn_est_ind(
             &mme_app_desc.mme_ue_contexts,
             conn_est_ind_pP->mme_ue_s1ap_id);
     if (ue_context_p == NULL) {
-        MME_APP_DEBUG("We didn't find this mme_ue_s1ap_id in list of UE: %08x\n",
-                conn_est_ind_pP->mme_ue_s1ap_id);
+        MME_APP_DEBUG("We didn't find this mme_ue_s1ap_id in list of UE: 0x%08x/dec%u\n",
+        		conn_est_ind_pP->mme_ue_s1ap_id,
+        		conn_est_ind_pP->mme_ue_s1ap_id);
         MME_APP_DEBUG("UE context doesn't exist -> create one\n");
         if ((ue_context_p = mme_create_new_ue_context()) == NULL) {
             /* Error during ue context malloc */
@@ -369,11 +371,15 @@ mme_app_handle_conn_est_ind(
         ue_context_p->ue_id          = conn_est_ind_pP->mme_ue_s1ap_id;
         DevAssert(mme_insert_ue_context(&mme_app_desc.mme_ue_contexts, ue_context_p) == 0);
 
-        // test
+        // tests
         ue_context_p = mme_ue_context_exists_mme_ue_s1ap_id(
                     &mme_app_desc.mme_ue_contexts,
                     conn_est_ind_pP->mme_ue_s1ap_id);
         AssertFatal(ue_context_p != NULL, "mme_ue_context_exists_mme_ue_s1ap_id Failed");
+        ue_context_p = mme_ue_context_exists_nas_ue_id(
+                    &mme_app_desc.mme_ue_contexts,
+                    conn_est_ind_pP->mme_ue_s1ap_id);
+        AssertFatal(ue_context_p != NULL, "mme_ue_context_exists_nas_ue_id Failed");
     }
 
     message_p  = itti_alloc_new_message(TASK_MME_APP, NAS_CONNECTION_ESTABLISHMENT_IND);
diff --git a/openair-cn/MME_APP/mme_app_main.c b/openair-cn/MME_APP/mme_app_main.c
index 4c36a03d0b02fb338d2148a0a821899aee563416..4d59ca7f75197b549a5773ce6e8864dbd1c0d521 100644
--- a/openair-cn/MME_APP/mme_app_main.c
+++ b/openair-cn/MME_APP/mme_app_main.c
@@ -101,11 +101,11 @@ void *mme_app_thread(void *args)
                 mme_app_handle_nas_pdn_connectivity_req(&received_message_p->ittiMsg.nas_pdn_connectivity_req);
             } break;
 
-            //case NAS_CONNECTION_ESTABLISHMENT_CNF: {
             case NAS_CONNECTION_ESTABLISHMENT_CNF: {
                 mme_app_handle_conn_est_cnf(&NAS_CONNECTION_ESTABLISHMENT_CNF(received_message_p));
             } break;
 
+            // From S1AP Initiating Message/EMM Attach Request
             case MME_APP_CONNECTION_ESTABLISHMENT_IND: {
                 mme_app_handle_conn_est_ind(&MME_APP_CONNECTION_ESTABLISHMENT_IND(received_message_p));
             } break;
diff --git a/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.c b/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.c
index 0985867168ea8c0c3188920953965e1eeaf3cfaa..524acb467240c1017917e852a87ad8bdcc351863 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.c
@@ -108,6 +108,7 @@ _nas_message_encrypt(
     UInt8_t     type,
     UInt32_t    code,
     UInt8_t     seq,
+    int         const direction,
     int         length,
     const emm_security_context_t * const emm_security_context);
 
@@ -166,6 +167,11 @@ nas_message_encrypt(
             header->security_header_type,
             header->message_authentication_code,
             header->sequence_number,
+#ifdef NAS_MME
+                SECU_DIRECTION_DOWNLINK,
+#else
+                SECU_DIRECTION_UPLINK,
+#endif
             length - size,
             emm_security_context);
         /* Integrity protected the NAS message */
@@ -183,7 +189,7 @@ nas_message_encrypt(
 #endif
                 emm_security_context);
             /* Set the message authentication code of the NAS message */
-            *(UInt32_t*)(outbuf + sizeof(UInt8_t)) = mac;
+            *(UInt32_t*)(outbuf + sizeof(UInt8_t)) = htonl(mac);
         }
     }
     else {
@@ -265,9 +271,22 @@ int nas_message_decrypt(
     int size = _nas_message_header_decode(inbuf, header, length);
 
     if (size < 0) {
+    	LOG_TRACE(DEBUG, "MESSAGE TOO SHORT");
         LOG_FUNC_RETURN (TLV_DECODE_BUFFER_TOO_SHORT);
     }
     else if (size > 1) {
+#if defined(NAS_MME)
+    	if (emm_security_context->ul_count.seq_num > header->sequence_number) {
+    	    emm_security_context->ul_count.overflow += 1;
+    	}
+    	emm_security_context->ul_count.seq_num = header->sequence_number;
+
+#else
+    	if (emm_security_context->dl_count.seq_num > header->sequence_number) {
+    		emm_security_context->dl_count.overflow += 1;
+    	}
+    	emm_security_context->dl_count.seq_num = header->sequence_number;
+#endif
         /* Compute offset of the sequence number field */
         int offset = size - sizeof(UInt8_t);
         /* Compute the NAS message authentication code */
@@ -281,20 +300,29 @@ int nas_message_decrypt(
 #endif
             emm_security_context);
 
+
         /* Check NAS message integrity */
         if (mac != header->message_authentication_code) {
+        	LOG_TRACE(DEBUG,
+        	        "MAC Failure MSG:%08X(%u) <> INT ALGO:%08X(%u)",
+        	        header->message_authentication_code,
+        	        header->message_authentication_code,
+        	        mac,
+        	        mac);
 #if defined(NAS_MME)
             LOG_FUNC_RETURN (TLV_DECODE_MAC_MISMATCH);
 #else
 #warning "added test on integrity algorithm because of SECURITY_MODE_COMMAND not correctly handled in UE (check integrity)"
             if (emm_security_context->selected_algorithms.integrity !=
         		    NAS_SECURITY_ALGORITHMS_EIA0) {
-                LOG_FUNC_RETURN (TLV_DECODE_MAC_MISMATCH);
+            	LOG_FUNC_RETURN (TLV_DECODE_MAC_MISMATCH);
             } else {
                 LOG_TRACE(WARNING,
                 		"MAC failure but continue due to EIA0 selected");
             }
 #endif
+        } else {
+        	LOG_TRACE(DEBUG, "Integrity: MAC Success");
         }
 
         /* Decrypt the security protected NAS message */
@@ -307,6 +335,7 @@ int nas_message_decrypt(
         bytes = length - size;
     }
     else {
+    	LOG_TRACE(DEBUG, "Plain NAS message found");
         /* The input buffer contains a plain NAS message */
         memcpy(outbuf, inbuf, length);
     }
@@ -341,15 +370,6 @@ int nas_message_decode(
     LOG_FUNC_IN;
     emm_security_context_t *emm_security_context   = (emm_security_context_t*)security;
     int bytes;
-#if ((defined(EPC_BUILD) && defined(NAS_MME)) || (defined(ENABLE_NAS_UE_LOGGING) && defined(UE_BUILD) && defined(NAS_UE)))
-    int down_link;
-
-# if ((defined(EPC_BUILD) && defined(NAS_MME)))
-    down_link = 0;
-# else
-    down_link = 1;
-# endif
-#endif
 
     /* Decode the header */
     int size = _nas_message_header_decode(buffer, &msg->header, length);
@@ -358,6 +378,18 @@ int nas_message_decode(
         LOG_FUNC_RETURN (TLV_DECODE_BUFFER_TOO_SHORT);
     }
     else if (size > 1) {
+#if defined(NAS_MME)
+    	if (emm_security_context->ul_count.seq_num > msg->header.sequence_number) {
+    	    emm_security_context->ul_count.overflow += 1;
+    	}
+    	emm_security_context->ul_count.seq_num = msg->header.sequence_number;
+
+#else
+    	if (emm_security_context->dl_count.seq_num > msg->header.sequence_number) {
+    		emm_security_context->dl_count.overflow += 1;
+    	}
+    	emm_security_context->dl_count.seq_num = msg->header.sequence_number;
+#endif
         /* Compute offset of the sequence number field */
         int offset = size - sizeof(UInt8_t);
         /* Compute the NAS message authentication code */
@@ -431,15 +463,7 @@ int nas_message_encode(
 
     emm_security_context_t *emm_security_context   = (emm_security_context_t*)security;
     int bytes;
-#if ((defined(EPC_BUILD) && defined(NAS_MME)) || (defined(ENABLE_NAS_UE_LOGGING) && defined(UE_BUILD) && defined(NAS_UE)))
-    int down_link;
 
-# if ((defined(EPC_BUILD) && defined(NAS_MME)))
-    down_link = 1;
-# else
-    down_link = 0;
-# endif
-#endif
 
     /* Encode the header */
     int size = _nas_message_header_encode(buffer, &msg->header, length);
@@ -459,9 +483,13 @@ int nas_message_encode(
             /* Compute offset of the sequence number field */
             int offset = size - sizeof(UInt8_t);
             /* Compute the NAS message authentication code */
+            LOG_TRACE(DEBUG,
+                "offset %d = %d - %d, hdr encode = %d, length = %d bytes = %d",
+                offset, size, sizeof(UInt8_t),
+                size, length, bytes);
             UInt32_t mac = _nas_message_get_mac(
                 buffer + offset,
-                length - offset,
+                bytes + size - offset,
 #ifdef NAS_MME
                 SECU_DIRECTION_DOWNLINK,
 #else
@@ -469,7 +497,7 @@ int nas_message_encode(
 #endif
                 emm_security_context);
             /* Set the message authentication code of the NAS message */
-            *(UInt32_t*)(buffer + sizeof(UInt8_t)) = mac;
+            *(UInt32_t*)(buffer + sizeof(UInt8_t)) = htonl(mac);
 
             if (emm_security_context) {
 #ifdef NAS_MME
@@ -832,6 +860,11 @@ static int _nas_message_protected_encode(
                 msg->header.security_header_type,
                 msg->header.message_authentication_code,
                 msg->header.sequence_number,
+#ifdef NAS_MME
+                SECU_DIRECTION_DOWNLINK,
+#else
+                SECU_DIRECTION_UPLINK,
+#endif
                 size,
                 emm_security_context);
             //seq, size);
@@ -901,6 +934,7 @@ static int _nas_message_decrypt(
  **		 type:		The security header type                   **
  **		 code:		The message authentication code            **
  **		 seq:		The sequence number                        **
+ **		 direction:	The sequence number                        **
  **		 length:	Maximal capacity of the output buffer      **
  **		 Others:	None                                       **
  **                                                                        **
@@ -917,17 +951,60 @@ static int _nas_message_encrypt(
     UInt8_t     type,
     UInt32_t    code,
     UInt8_t     seq,
+    int         const direction,
     int         length,
     const emm_security_context_t * const emm_security_context)
 {
     LOG_FUNC_IN;
 
-    int size = length;
+    if (!emm_security_context) {
+        LOG_TRACE(ERROR,
+            "No security context set for encryption protection algorithm");
+        LOG_FUNC_RETURN (0);
+    }
+
+    switch (emm_security_context->selected_algorithms.encryption) {
 
-    /* TODO: run the cyphering algorithm */
-    memcpy(dest, src, length);
+        case NAS_SECURITY_ALGORITHMS_EEA1: {
+            LOG_TRACE(WARNING,
+                "TODO NAS_SECURITY_ALGORITHMS_EEA1 dir %d ul_count.seq_num %d dl_count.seq_num %d",
+                direction,
+                emm_security_context->ul_count.seq_num,
+                emm_security_context->dl_count.seq_num);
+            memcpy(dest, src, length);
+            LOG_FUNC_RETURN (length);
 
-    LOG_FUNC_RETURN (size);
+        }break;
+
+        case NAS_SECURITY_ALGORITHMS_EEA2: {
+            LOG_TRACE(WARNING,
+                "TODO NAS_SECURITY_ALGORITHMS_EEA2 dir %d ul_count.seq_num %d dl_count.seq_num %d",
+                direction,
+                emm_security_context->ul_count.seq_num,
+                emm_security_context->dl_count.seq_num);
+            memcpy(dest, src, length);
+            LOG_FUNC_RETURN (length);
+
+            }break;
+
+        case NAS_SECURITY_ALGORITHMS_EEA0:
+            LOG_TRACE(DEBUG,
+                "NAS_SECURITY_ALGORITHMS_EEA0 dir %d ul_count.seq_num %d dl_count.seq_num %d",
+                direction,
+                emm_security_context->ul_count.seq_num,
+                emm_security_context->dl_count.seq_num);
+            memcpy(dest, src, length);
+            LOG_FUNC_RETURN (length);
+
+            break;
+
+        default:
+        	LOG_TRACE(ERROR,
+              "Unknown Cyphering protection algorithm %d",
+              emm_security_context->selected_algorithms.encryption);
+        	break;
+    }
+    LOG_FUNC_RETURN (length);
 }
 
 /*
@@ -938,21 +1015,22 @@ static int _nas_message_encrypt(
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 _nas_message_get_mac()                                    **
+ ** Name:	 _nas_message_get_mac()                                        **
  **                                                                        **
  ** Description: Run integrity algorithm onto cyphered or uncyphered NAS   **
- **		 message encoded in the input buffer and return the compu- **
- **		 ted message authentication code                           **
+ **		 message encoded in the input buffer and return the compu-         **
+ **		 ted message authentication code                                   **
  **                                                                        **
- ** Inputs	 buffer:	Pointer to the integrity protected data    **
- **				buffer                                     **
- **		 count:		Value of the uplink NAS counter            **
- **		 length:	Length of the input buffer                 **
- **		 Others:	None                                       **
+ ** Inputs	 buffer:	Pointer to the integrity protected data            **
+ **				buffer                                                     **
+ **		 count:		Value of the uplink NAS counter                        **
+ **		 length:	Length of the input buffer                             **
+ **	     direction                                                         **
+ **		 Others:	None                                                   **
  **                                                                        **
  ** Outputs:	 None                                                      **
- ** 		 Return:	The message authentication code            **
- **		 Others:	None                                       **
+ ** 		 Return:	The message authentication code                    **
+ **		 Others:	None                                                   **
  **                                                                        **
  ***************************************************************************/
 static UInt32_t _nas_message_get_mac(
@@ -982,11 +1060,8 @@ static UInt32_t _nas_message_get_mac(
             UInt32_t            count;
             UInt32_t           *mac32;
 
-            LOG_TRACE(DEBUG,
-                "NAS_SECURITY_ALGORITHMS_EIA1 dir %d ul_count.seq_num %d dl_count.seq_num %d",
-                direction,
-                emm_security_context->ul_count.seq_num,
-                emm_security_context->dl_count.seq_num);
+            int i,bytes = 0;
+
             if (direction == SECU_DIRECTION_UPLINK) {
                 count = 0x00000000 ||
                     ((emm_security_context->ul_count.overflow && 0x0000FFFF) << 8) ||
@@ -996,7 +1071,31 @@ static UInt32_t _nas_message_get_mac(
                     ((emm_security_context->dl_count.overflow && 0x0000FFFF) << 8) ||
                     (emm_security_context->dl_count.seq_num & 0x000000FF);
             }
-            stream_cipher.key        = emm_security_context->knas_int.value;
+            LOG_TRACE(DEBUG,
+                "NAS_SECURITY_ALGORITHMS_EIA1 dir %s count.seq_num %u count %u",
+                (direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
+                (direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
+                count);
+
+        	fprintf(stderr, "\n[NAS]\t");
+
+        	for (i=0; i < length; i++)
+        	{
+        	    fprintf(stderr, "%.2hx ", (const unsigned char) buffer[i]);
+        	    /* Add new line when the number of displayed bytes exceeds
+        	     * the line's size */
+        	    if ( ++bytes > (16 - 1) ) {
+        		bytes = 0;
+        		fprintf(stderr, "\n[NAS]\t");
+        	    }
+        	}
+        	if (bytes % 16) {
+        	    fprintf(stderr, "\n");
+        	}
+        	fprintf(stderr, "\n");
+        	fflush(stderr);
+
+        	stream_cipher.key        = emm_security_context->knas_int.value;
             stream_cipher.key_length = AUTH_KNAS_INT_SIZE;
             stream_cipher.count      = count;
             stream_cipher.bearer     = 0x00; //33.401 section 8.1.1
@@ -1009,10 +1108,14 @@ static UInt32_t _nas_message_get_mac(
                 &stream_cipher,
                 mac);
             LOG_TRACE(DEBUG,
-                "NAS_SECURITY_ALGORITHMS_EIA1 returned MAC %x.%x.%x.%x for length %d direction %d, count %d",
-                mac[0], mac[1], mac[2],mac[3], length, direction, count);
+                "NAS_SECURITY_ALGORITHMS_EIA1 returned MAC %x.%x.%x.%x(%u) for length %d direction %d, count %d",
+                mac[0], mac[1], mac[2],mac[3],
+                *((UInt32_t*)&mac),
+                length,
+                direction,
+                count);
             mac32 = (UInt32_t*)&mac;
-            LOG_FUNC_RETURN (*mac32);
+            LOG_FUNC_RETURN (ntohl(*mac32));
         }break;
 
         case NAS_SECURITY_ALGORITHMS_EIA2: {
@@ -1021,11 +1124,6 @@ static UInt32_t _nas_message_get_mac(
                 UInt32_t            count;
                 UInt32_t           *mac32;
 
-                LOG_TRACE(DEBUG,
-                    "NAS_SECURITY_ALGORITHMS_EIA2 dir %d ul_count.seq_num %d dl_count.seq_num %d",
-                    direction,
-                    emm_security_context->ul_count.seq_num,
-                    emm_security_context->dl_count.seq_num);
                 if (direction == SECU_DIRECTION_UPLINK) {
                     count = 0x00000000 ||
                         ((emm_security_context->ul_count.overflow && 0x0000FFFF) << 8) ||
@@ -1035,6 +1133,12 @@ static UInt32_t _nas_message_get_mac(
                         ((emm_security_context->dl_count.overflow && 0x0000FFFF) << 8) ||
                         (emm_security_context->dl_count.seq_num & 0x000000FF);
                 }
+                LOG_TRACE(DEBUG,
+                    "NAS_SECURITY_ALGORITHMS_EIA2 dir %s count.seq_num %u count %u",
+                    (direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
+                    (direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
+                    count);
+
                 stream_cipher.key        = emm_security_context->knas_int.value;
                 stream_cipher.key_length = AUTH_KNAS_INT_SIZE;
                 stream_cipher.count      = count;
@@ -1048,18 +1152,23 @@ static UInt32_t _nas_message_get_mac(
                     &stream_cipher,
                     mac);
                 LOG_TRACE(DEBUG,
-                    "NAS_SECURITY_ALGORITHMS_EIA2 returned MAC %x.%x.%x.%x for length %d direction %d, count %d",
-                    mac[0], mac[1], mac[2],mac[3], length, direction, count);
+                    "NAS_SECURITY_ALGORITHMS_EIA2 returned MAC %x.%x.%x.%x(%u) for length %d direction %d, count %d",
+                    mac[0], mac[1], mac[2],mac[3],
+                    *((UInt32_t*)&mac),
+                    length,
+                    direction,
+                    count);
                 mac32 = (UInt32_t*)&mac;
-                LOG_FUNC_RETURN (*mac32);
+                LOG_FUNC_RETURN (ntohl(*mac32));
             }break;
 
         case NAS_SECURITY_ALGORITHMS_EIA0:
             LOG_TRACE(DEBUG,
-                "NAS_SECURITY_ALGORITHMS_EIA0 dir %d ul_count.seq_num %d dl_count.seq_num %d",
-                direction,
-                emm_security_context->ul_count.seq_num,
-                emm_security_context->dl_count.seq_num);
+                "NAS_SECURITY_ALGORITHMS_EIA0 dir %s count.seq_num %u",
+                (direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
+                (direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num
+           );
+
 #if defined(EPC_BUILD) || defined(UE_BUILD)
             LOG_FUNC_RETURN (0);
 #else
@@ -1071,6 +1180,7 @@ static UInt32_t _nas_message_get_mac(
         	LOG_TRACE(ERROR,
               "Unknown integrity protection algorithm %d",
               emm_security_context->selected_algorithms.integrity);
+        	break;
     }
     LOG_FUNC_RETURN (0);
 }
diff --git a/openair-cn/NAS/EURECOM-NAS/src/api/usim/usim_api.c b/openair-cn/NAS/EURECOM-NAS/src/api/usim/usim_api.c
index 03aa86ad5f64ee829a2bc08bf3327628e72e82ba..404f07a3c87f97d5649d80c8d429d243bfa83734 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/api/usim/usim_api.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/api/usim/usim_api.c
@@ -222,8 +222,8 @@ int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP
     int rc;
     int i;
 
-	LOG_TRACE(DEBUG, "USIM-API  - rand :");dump_octet_string(rand_pP);
-	LOG_TRACE(DEBUG, "USIM-API  - autn :");dump_octet_string(autn_pP);
+	LOG_TRACE(DEBUG, "USIM-API  - rand :%s",dump_octet_string(rand_pP));
+	LOG_TRACE(DEBUG, "USIM-API  - autn :%s",dump_octet_string(autn_pP));
 
     /* Compute the authentication response RES = f2K (RAND) */
     /* Compute the cipher key CK = f3K (RAND) */
@@ -233,9 +233,9 @@ int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP
     u8 ak[USIM_API_AK_SIZE];
     f2345(_usim_api_k, rand_pP->value,
           res_pP->value, ck_pP->value, ik_pP->value, ak);
-	LOG_TRACE(DEBUG, "USIM-API  - res(f2)  :");dump_octet_string(res_pP);
-	LOG_TRACE(DEBUG, "USIM-API  - ck(f3)   :");dump_octet_string(ck_pP);
-	LOG_TRACE(DEBUG, "USIM-API  - ik(f4)   :");dump_octet_string(ik_pP);
+	LOG_TRACE(DEBUG, "USIM-API  - res(f2)  :%s",dump_octet_string(res_pP));
+	LOG_TRACE(DEBUG, "USIM-API  - ck(f3)   :%s",dump_octet_string(ck_pP));
+	LOG_TRACE(DEBUG, "USIM-API  - ik(f4)   :%s",dump_octet_string(ik_pP));
 	LOG_TRACE(DEBUG, "USIM-API  - ak(f5)   : %02X%02X%02X%02X%02X%02X",
 			ak[0],ak[1],ak[2],ak[3],ak[4],ak[5]);
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c b/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c
index e616f972c30fb3264162eed350cfdf09a903491e..3e339ae19db7f09d4cd8befef578ace6e43780a5 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c
@@ -1672,29 +1672,40 @@ static int _emm_attach_release(void *args)
 
         if (emm_ctx->guti) {
             free(emm_ctx->guti);
+            emm_ctx->guti = NULL;
         }
         if (emm_ctx->imsi) {
             free(emm_ctx->imsi);
+            emm_ctx->imsi = NULL;
         }
         if (emm_ctx->imei) {
             free(emm_ctx->imei);
+            emm_ctx->imei = NULL;
         }
         if (emm_ctx->esm_msg.length > 0) {
             free(emm_ctx->esm_msg.value);
+            emm_ctx->esm_msg.value = NULL;
         }
         /* Release NAS security context */
         if (emm_ctx->security) {
             emm_security_context_t *security = emm_ctx->security;
             if (security->kasme.value) {
                 free(security->kasme.value);
+                security->kasme.value  = NULL;
+                security->kasme.length = 0;
             }
             if (security->knas_enc.value) {
                 free(security->knas_enc.value);
+                security->knas_enc.value  = NULL;
+                security->knas_enc.length = 0;
             }
             if (security->knas_int.value) {
                 free(security->knas_int.value);
+                security->knas_int.value  = NULL;
+                security->knas_int.length = 0;
             }
             free(emm_ctx->security);
+            emm_ctx->security = NULL;
         }
         /* Release the EMM context */
 #if defined(EPC_BUILD)
diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c b/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c
index bbcd674b3d1c82964e6ee21eabc5bd1491c7a1cf..8b81f5e84223662dd59459624c59ed91de2e1c6a 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c
@@ -59,6 +59,7 @@ Description Defines the authentication EMM procedure executed by the
 
 #include <stdlib.h> // malloc, free
 #include <string.h> // memcpy, memcmp, memset
+#include <arpa/inet.h> // htons
 
 #include "emm_proc.h"
 #include "nas_log.h"
@@ -389,8 +390,7 @@ int emm_proc_authentication_request(int native_ksi, int ksi,
             /* Derive the Kasme from the authentication challenge using
              * the PLMN identity of the selected PLMN */
             _emm_data.non_current->kasme.length = AUTH_KASME_SIZE;
-            _emm_data.non_current->kasme.value =
-                (uint8_t *)malloc(sizeof(AUTH_KASME_SIZE));
+            _emm_data.non_current->kasme.value  = malloc(32);
             _authentication_kasme(autn, &ck, &ik, &_emm_data.splmn,
                                   &_emm_data.non_current->kasme);
             /* NAS integrity and cyphering keys are not yet available */
@@ -1171,68 +1171,78 @@ static int _authentication_kasme(const OctetString *autn,
 {
     LOG_FUNC_IN;
 
+    LOG_TRACE(INFO,"EMM-PROC  _authentication_kasme INPUT CK %s",
+    		dump_octet_string(ck));
+    LOG_TRACE(INFO,"EMM-PROC  _authentication_kasme INPUT IK %s",
+    		dump_octet_string(ik));
+    LOG_TRACE(INFO,"EMM-PROC  _authentication_kasme INPUT AUTN %s",
+    		dump_octet_string(autn));
+    LOG_TRACE(INFO,"EMM-PROC  _authentication_kasme INPUT KASME LENGTH %u",
+    		kasme->length);
+
     /* Compute the derivation key KEY = CK || IK */
     UInt8_t key[ck->length + ik->length];
     memcpy(key, ck->value, ck->length);
     memcpy(key + ck->length, ik->value, ik->length);
 
-    /* Compute the KDF input parameter
+    /* Compute the KDF input_s parameter
      * S = FC(0x10) || SNid(MCC, MNC) || 0x00 0x03 || SQN ⊕ AK || 0x00 0x06
      */
-    UInt8_t  input[kasme->length];
+    UInt8_t  input_s[16]; // less than 16
+    UInt8_t  sn_id[AUTH_SNID_SIZE]; // less than 16
     UInt16_t length;
     int      offset         = 0;
     int      size_of_length = sizeof(length);
 
     // FC
-    input[offset] = 0x10;
+    input_s[offset] = 0x10;
     offset       += 1;
 
     // P0=SN id
     length        = AUTH_SNID_SIZE;
-    memcpy(input + offset, plmn, length);
+    sn_id[0] = (plmn->MCCdigit2 << 4) | plmn->MCCdigit1;
+    sn_id[1] = (plmn->MNCdigit3 << 4) | plmn->MCCdigit3;
+    sn_id[2] = (plmn->MNCdigit2 << 4) | plmn->MNCdigit1;
+
+    memcpy(input_s + offset, sn_id, length);
     LOG_TRACE(INFO,"EMM-PROC  _authentication_kasme P0 MCC,MNC %02X %02X %02X",
-    		input[offset],
-    		input[offset+1],
-    		input[offset+2]);
+    		input_s[offset],
+    		input_s[offset+1],
+    		input_s[offset+2]);
     offset += length;
     // L0=SN id length
-    memcpy(input + offset, &length, size_of_length);
+    length = htons(length);
+    memcpy(input_s + offset, &length, size_of_length);
     offset += size_of_length;
 
     // P1=Authentication token
     length = AUTH_SQN_SIZE;
-    memcpy(input + offset, autn, length);
+    memcpy(input_s + offset, autn->value, length);
     offset += length;
     // L1
-    memcpy(input + offset, &length, size_of_length);
+    length = htons(length);
+    memcpy(input_s + offset, &length, size_of_length);
     offset += size_of_length;
 
-    /* TODO !!! Compute the Kasme key */
-    // todo_hmac_256(key, input, kasme->value);
-    kdf(input,
+    LOG_TRACE(INFO,
+    		"EMM-PROC  _authentication_kasme input S to KFD (length %u)%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
     		offset,
-    		key,
-    		ck->length + ik->length , /*key_length*/
-    		&kasme->value,
-    		kasme->length);
-
-    LOG_TRACE(INFO,"EMM-PROC  CK (l=%d)", ck->length);
-    LOG_TRACE(INFO,"EMM-PROC  IK (l=%d)", ik->length);
-
-    LOG_TRACE(INFO,"EMM-PROC  KASME (l=%d)%02X%02X%02X%02X%02X%02X%02X%02X",
-    		"%02X%02X%02X%02X%02X%02X%02X%02X",
-    		"%02X%02X%02X%02X%02X%02X%02X%02X",
-    		"%02X%02X%02X%02X%02X%02X%02X%02X",
+    		input_s[0],input_s[1],input_s[2],input_s[3],
+    		input_s[4],input_s[5],input_s[6],input_s[7],
+    		input_s[8],input_s[9],input_s[10],input_s[11],
+    		input_s[12],input_s[13]);
+    /* TODO !!! Compute the Kasme key */
+    // todo_hmac_256(key, input_s, kasme->value);
+    kdf(key,
+    	ck->length + ik->length , /*key_length*/
+    	input_s,
+  		offset,
+  		kasme->value,
+  		kasme->length);
+
+    LOG_TRACE(INFO,"EMM-PROC  KASME (l=%d)%s",
     		kasme->length,
-    		kasme->value[0],kasme->value[1],kasme->value[2],kasme->value[3],
-    		kasme->value[4],kasme->value[5],kasme->value[6],kasme->value[7],
-    		kasme->value[8],kasme->value[9],kasme->value[10],kasme->value[11],
-    		kasme->value[12],kasme->value[13],kasme->value[14],kasme->value[15],
-    		kasme->value[16],kasme->value[17],kasme->value[18],kasme->value[19],
-    		kasme->value[20],kasme->value[21],kasme->value[22],kasme->value[23],
-    		kasme->value[24],kasme->value[25],kasme->value[26],kasme->value[27],
-    		kasme->value[28],kasme->value[29],kasme->value[30],kasme->value[31]);
+    		dump_octet_string(kasme));
 
     LOG_FUNC_RETURN (RETURNok);
 }
diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.c b/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.c
index 51f3470c3ae1afcd2690463de5f0b45100098311..38600d8db0f4d9a3687d1dc0e6c4d688a025949b 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.c
@@ -483,24 +483,29 @@ void emm_as_set_security_data(emm_as_security_data_t *data, const void *args,
          * into use, UE and MME shall cipher and integrity protect all
          * NAS signalling messages with the selected NAS ciphering and
          * NAS integrity algorithms */
-        LOG_TRACE(WARNING,
-            "EPS security context exists is new %u KSI %u SQN %u count %u knas_int %s",
+        LOG_TRACE(INFO,
+            "EPS security context exists is new %u KSI %u SQN %u count %u",
             is_new,
             context->eksi,
             context->ul_count.seq_num,
-            *(UInt32_t *)(&context->ul_count),
-            context->knas_int.value
-            );
+            *(UInt32_t *)(&context->ul_count));
+        LOG_TRACE(INFO,
+                "knas_int %s",dump_octet_string(&context->knas_int));
+        LOG_TRACE(INFO,
+                "knas_enc %s",dump_octet_string(&context->knas_enc));
+        LOG_TRACE(INFO,
+                "kasme %s",dump_octet_string(&context->kasme));
+
         data->is_new = is_new;
-        data->ksi = context->eksi;
+        data->ksi    = context->eksi;
 #if defined (NAS_UE)
-        data->sqn = context->ul_count.seq_num;
+        data->sqn    = context->ul_count.seq_num;
         // LG data->count = *(UInt32_t *)(&context->ul_count);
-        data->count = 0x00000000 | (context->ul_count.overflow << 8 ) | context->ul_count.seq_num;
+        data->count  = 0x00000000 | (context->ul_count.overflow << 8 ) | context->ul_count.seq_num;
 #else
-        data->sqn = context->dl_count.seq_num;
+        data->sqn    = context->dl_count.seq_num;
         // LG data->count = *(UInt32_t *)(&context->ul_count);
-        data->count = 0x00000000 | (context->dl_count.overflow << 8 ) | context->dl_count.seq_num;
+        data->count  = 0x00000000 | (context->dl_count.overflow << 8 ) | context->dl_count.seq_num;
 #endif
         /* NAS integrity and cyphering keys may not be available if the
          * current security context is a partial EPS security context
@@ -515,9 +520,7 @@ void emm_as_set_security_data(emm_as_security_data_t *data, const void *args,
              * The MME shall send the SECURITY MODE COMMAND message integrity
              * protected and unciphered */
             LOG_TRACE(WARNING,
-                "EPS security context exists knas_enc %s",
-                context->knas_enc.value
-                );
+                "EPS security context exists knas_enc");
             data->k_enc = &context->knas_enc;
         }
     } else {
diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c b/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c
index 257822e6d72718ade6c7120d8d52024e09157bfc..6c7e0226561bb26f3558f68384131b149aeba6d1 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c
@@ -234,12 +234,12 @@ int emm_proc_security_mode_command(int native_ksi, int ksi,
         LOG_TRACE(INFO, "EMM-PROC  - Update the non-current EPS security context seea=%u seia=%u", seea, seia);
         /* Update selected cyphering and integrity algorithms */
         _emm_data.non_current->capability.encryption = seea;
-        _emm_data.non_current->capability.integrity = seia;
+        _emm_data.non_current->capability.integrity  = seia;
 
         /* Derive the NAS cyphering key */
         if (_emm_data.non_current->knas_enc.value == NULL) {
             _emm_data.non_current->knas_enc.value =
-                (uint8_t *)malloc(AUTH_KNAS_ENC_SIZE);
+                (uint8_t *)calloc(1,AUTH_KNAS_ENC_SIZE);
             _emm_data.non_current->knas_enc.length = AUTH_KNAS_ENC_SIZE;
         }
         if (_emm_data.non_current->knas_enc.value != NULL) {
@@ -250,26 +250,27 @@ int emm_proc_security_mode_command(int native_ksi, int ksi,
         /* Derive the NAS integrity key */
         if (_emm_data.non_current->knas_int.value == NULL) {
             _emm_data.non_current->knas_int.value =
-                (uint8_t *)malloc(AUTH_KNAS_INT_SIZE);
+                (uint8_t *)calloc(1,AUTH_KNAS_INT_SIZE);
             _emm_data.non_current->knas_int.length = AUTH_KNAS_INT_SIZE;
         }
         if (_emm_data.non_current->knas_int.value != NULL) {
             if (rc != RETURNerror) {
                 LOG_TRACE(INFO, "EMM-PROC  - Update the non-current EPS security context knas_int");
                 rc = _security_knas_int(&_emm_data.non_current->kasme,
-                                        &_emm_data.non_current->knas_int, seea);
+                                        &_emm_data.non_current->knas_int, seia);
             }
         }
         /* Derive the eNodeB key */
         if (_security_data.kenb.value == NULL) {
-            _security_data.kenb.value = (uint8_t *)malloc(AUTH_KENB_SIZE);
+            _security_data.kenb.value = (uint8_t *)calloc(1,AUTH_KENB_SIZE);
             _security_data.kenb.length = AUTH_KENB_SIZE;
         }
         if (_security_data.kenb.value != NULL) {
             if (rc != RETURNerror) {
                 LOG_TRACE(INFO, "EMM-PROC  - Update the non-current EPS security context kenb");
-                rc = _security_kenb(&_security_data.kenb,
-                                    &_emm_data.security->kasme,
+                // LG COMMENT rc = _security_kenb(&_emm_data.security->kasme,
+                rc = _security_kenb(&_emm_data.non_current->kasme,
+                					&_security_data.kenb,
                                     *(UInt32_t *)(&_emm_data.non_current->ul_count));
             }
         }
@@ -319,6 +320,10 @@ int emm_proc_security_mode_command(int native_ksi, int ksi,
                     _emm_data.security->ul_count.seq_num = 0;
                 }
             }
+
+            _emm_data.security->selected_algorithms.encryption = seea;
+            _emm_data.security->selected_algorithms.integrity  = seia;
+
         }
         /*
          * NAS security mode command not accepted by the UE
@@ -446,6 +451,13 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia,
             // LG: Kasme should have been received from authentication
             //     information request (S6A)
             // Kasme is located in emm_ctx->vector.kasme
+            FREE_OCTET_STRING(emm_ctx->security->kasme);
+
+            emm_ctx->security->kasme.value = malloc(32);
+            memcpy(emm_ctx->security->kasme.value,
+            	emm_ctx->vector.kasme,
+            	32);
+            emm_ctx->security->kasme.length = 32;
 
             rc = _security_select_algorithms(
                 eia,
@@ -474,7 +486,7 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia,
                 NAS_INT_ALG,
                 emm_ctx->security->selected_algorithms.integrity,
                 emm_ctx->vector.kasme,
-                &emm_ctx->security->knas_int.value);
+                emm_ctx->security->knas_int.value);
 
             if ( ! emm_ctx->security->knas_enc.value) {
                 emm_ctx->security->knas_enc.value = malloc(AUTH_KNAS_ENC_SIZE);
@@ -488,7 +500,7 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia,
                 NAS_ENC_ALG,
                 emm_ctx->security->selected_algorithms.encryption,
                 emm_ctx->vector.kasme,
-                &emm_ctx->security->knas_enc.value);
+                emm_ctx->security->knas_enc.value);
 
             /* Set new security context indicator */
             security_context_is_new = TRUE;
@@ -733,14 +745,20 @@ static void _security_release(emm_security_context_t *ctx)
         /* Release Kasme security key */
         if (ctx->kasme.value) {
             free(ctx->kasme.value);
+            ctx->kasme.value  = NULL;
+            ctx->kasme.length = 0;
         }
         /* Release NAS cyphering key */
         if (ctx->knas_enc.value) {
             free(ctx->knas_enc.value);
+            ctx->knas_enc.value  = NULL;
+            ctx->knas_enc.length = 0;
         }
         /* Release NAS integrity key */
         if (ctx->knas_int.value) {
             free(ctx->knas_int.value);
+            ctx->knas_int.value  = NULL;
+            ctx->knas_int.length = 0;
         }
         /* Release the NAS security context */
         free(ctx);
@@ -771,6 +789,7 @@ static int _security_knas_enc(const OctetString *kasme, OctetString *knas_enc,
                               UInt8_t eea)
 {
     LOG_FUNC_IN;
+    LOG_TRACE(INFO, "%s  with algo dist %d algo id %d", __FUNCTION__,0x01, eea);
     LOG_FUNC_RETURN (_security_kdf(kasme, knas_enc, 0x01, eea));
 }
 
@@ -796,6 +815,7 @@ static int _security_knas_int(const OctetString *kasme, OctetString *knas_int,
                               UInt8_t eia)
 {
     LOG_FUNC_IN;
+    LOG_TRACE(INFO, "%s  with algo dist %d algo id %d", __FUNCTION__,0x02, eia);
     LOG_FUNC_RETURN (_security_kdf(kasme, knas_int, 0x02, eia));
 }
 
@@ -823,18 +843,24 @@ static int _security_kenb(const OctetString *kasme, OctetString *kenb,
     /* Compute the KDF input parameter
      * S = FC(0x11) || UL NAS Count || 0x00 0x04
      */
-    UInt8_t input[kasme->length];
-    UInt16_t length = 4;
-    int offset = 0;
-
-    input[offset] = 0x11;
-    offset += 1;
-    input[offset] = count;
-    offset += length;
-    input[offset] = length;
-
-    /* TODO !!! Compute the derived key */
-    // todo_hmac_256(key, input, kasme->value);
+    UInt8_t  input[32];
+    UInt16_t length    = 4;
+    int      offset    = 0;
+
+    LOG_TRACE(INFO, "%s  with count= %d", __FUNCTION__, count);
+    memset(input, 0, 32);
+    input[0] = 0x11;
+    // P0
+    input[1] = count >> 24;
+    input[2] = (UInt8_t)(count >> 16);
+    input[3] = (UInt8_t)(count >> 8);
+    input[4] = (UInt8_t)count;
+    // L0
+    input[5] = 0;
+    input[6] = 4;
+
+    kdf(kasme->value, 32, input, 7, kenb->value, 32);
+    kenb->length = 32;
     return (RETURNok);
 }
 
@@ -865,24 +891,29 @@ static int _security_kdf(const OctetString *kasme, OctetString *key,
      * S = FC(0x15) || Algorithm distinguisher || 0x00 0x01
             || Algorithm identity || 0x00 0x01
     */
-    UInt8_t input[kasme->length];
-    UInt16_t length = 1;
-    int offset = 0;
-    int size_of_length = sizeof(length);
-
-    input[offset] = 0x15;
-    offset += 1;
-    input[offset] = algo_dist;
-    offset += length;
-    input[offset] = length;
-    offset += size_of_length;
-    input[offset] = algo_id;
-    offset += length;
-    input[offset] = length;
-
-    /* TODO !!! Compute the derived key */
-    // todo_hmac_256(key, input, kasme->value);
-
+    UInt8_t input[32];
+    UInt8_t output[32];
+    LOG_TRACE(DEBUG, "%s:%u output key mem %p lenth %u",
+    		__FUNCTION__, __LINE__,
+    		key->value,
+    		key->length);
+    memset(input, 0, 32);
+    // FC
+    input[0] = 0x15;
+    // P0 = Algorithm distinguisher
+    input[1] = algo_dist;
+    // L0 = 0x00 01
+    input[2] = 0x00;
+    input[3] = 0x01;
+    // P1 = Algorithm identity
+    input[4] = algo_id;
+    // L1 = length of Algorithm identity 0x00 0x01
+    input[5] = 0x00;
+    input[6] = 0x01;
+
+    /* Compute the derived key */
+    kdf(kasme->value, kasme->length, input, 7, output, 32);
+    memcpy(key->value, &output[31 - key->length + 1], key->length);
     return (RETURNok);
 }
 #endif // NAS_UE
diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/emm_main.c b/openair-cn/NAS/EURECOM-NAS/src/emm/emm_main.c
index 3380de29cb6a2ad815d31de6d47e0c9d53f7ed3d..209313daa40804004166daecef3fac781596722c 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/emm/emm_main.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/emm/emm_main.c
@@ -534,12 +534,18 @@ void emm_main_cleanup(void)
         emm_security_context_t *security = _emm_data.security;
         if (security->kasme.value) {
             free(security->kasme.value);
+            security->kasme.value  = NULL;
+            security->kasme.length = 0;
         }
         if (security->knas_enc.value) {
             free(security->knas_enc.value);
+            security->knas_enc.value  = NULL;
+            security->knas_enc.length = 0;
         }
         if (security->knas_int.value) {
             free(security->knas_int.value);
+            security->knas_int.value  = NULL;
+            security->knas_int.length = 0;
         }
         free(_emm_data.security);
         _emm_data.security = NULL;
diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c
index 7abad57522e09eaf7b22a1af1d74e397b1d0c695..54dee6652661b1198d1774409ec72467ee790484 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c
@@ -1263,6 +1263,9 @@ static int _emm_as_send(const emm_as_t *msg)
                         as_msg.msg.nas_establish_rsp.nasMsg.length);
                     LOG_FUNC_RETURN (RETURNok);
                 } else {
+                    LOG_TRACE(DEBUG, "EMMAS-SAP - "
+                              "Sending nas_itti_establish_cnf to S1AP UE ID %d",
+                              as_msg.msg.nas_establish_rsp.UEid);
                     /* Handle success case */
                     nas_itti_establish_cnf(
                         as_msg.msg.nas_establish_rsp.UEid,
diff --git a/openair-cn/NAS/EURECOM-NAS/src/ies/AccessPointName.c b/openair-cn/NAS/EURECOM-NAS/src/ies/AccessPointName.c
index 09e76a4650af454500b1c56b22c539527538d682..e7aa2569c392ce4fa771e14b0d5cbf0b89ad3d27 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/ies/AccessPointName.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/ies/AccessPointName.c
@@ -88,7 +88,7 @@ void dump_access_point_name_xml(AccessPointName *accesspointname, uint8_t iei)
     if (iei > 0)
         /* Don't display IEI if = 0 */
         printf("    <IEI>0x%X</IEI>\n", iei);
-    dump_octet_string_xml(&accesspointname->accesspointnamevalue);
-    printf("</Access Point Name>\n");
+    printf("%s</Access Point Name>\n",
+    		dump_octet_string_xml(&accesspointname->accesspointnamevalue));
 }
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/ies/AuthenticationFailureParameter.c b/openair-cn/NAS/EURECOM-NAS/src/ies/AuthenticationFailureParameter.c
index 62d266d6a7ade86828912e183ade5ad304ad8933..cc2f2a7def33c0da49b88d540822f82b751f06ff 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/ies/AuthenticationFailureParameter.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/ies/AuthenticationFailureParameter.c
@@ -88,7 +88,7 @@ void dump_authentication_failure_parameter_xml(AuthenticationFailureParameter *a
     if (iei > 0)
         /* Don't display IEI if = 0 */
         printf("    <IEI>0x%X</IEI>\n", iei);
-    dump_octet_string_xml(&authenticationfailureparameter->auts);
+    printf("%s",dump_octet_string_xml(&authenticationfailureparameter->auts));
     printf("</Authentication Failure Parameter>\n");
 }
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/ies/AuthenticationParameterAutn.c b/openair-cn/NAS/EURECOM-NAS/src/ies/AuthenticationParameterAutn.c
index 024498dd8cb18b34362e8a00445b7dd688e8167f..0d869071c88c38a717221ec49f73faab83529d56 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/ies/AuthenticationParameterAutn.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/ies/AuthenticationParameterAutn.c
@@ -88,7 +88,7 @@ void dump_authentication_parameter_autn_xml(AuthenticationParameterAutn *authent
     if (iei > 0)
         /* Don't display IEI if = 0 */
         printf("    <IEI>0x%X</IEI>\n", iei);
-    dump_octet_string_xml(&authenticationparameterautn->autn);
+    printf("%s", dump_octet_string_xml(&authenticationparameterautn->autn));
     printf("</Authentication Parameter Autn>\n");
 }
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/ies/AuthenticationParameterRand.c b/openair-cn/NAS/EURECOM-NAS/src/ies/AuthenticationParameterRand.c
index 989df216396507e38f4c3bb53fff4948ae58633d..805faa89a6c991e86563b162cdaa81a7c5f516a9 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/ies/AuthenticationParameterRand.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/ies/AuthenticationParameterRand.c
@@ -82,7 +82,7 @@ void dump_authentication_parameter_rand_xml(AuthenticationParameterRand *authent
     if (iei > 0)
         /* Don't display IEI if = 0 */
         printf("    <IEI>0x%X</IEI>\n", iei);
-    dump_octet_string_xml(&authenticationparameterrand->rand);
+    printf("%s",dump_octet_string_xml(&authenticationparameterrand->rand));
     printf("</Authentication Parameter Rand>\n");
 }
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/ies/Cli.c b/openair-cn/NAS/EURECOM-NAS/src/ies/Cli.c
index bbe5fd7f7ba683c589d76796c477575beac4fe5d..71a2ac5477535229a04d6f514be070c0e3b50fc7 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/ies/Cli.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/ies/Cli.c
@@ -88,7 +88,7 @@ void dump_cli_xml(Cli *cli, uint8_t iei)
     if (iei > 0)
         /* Don't display IEI if = 0 */
         printf("    <IEI>0x%X</IEI>\n", iei);
-    dump_octet_string_xml(&cli->clivalue);
+    printf("%s", dump_octet_string_xml(&cli->clivalue));
     printf("</Cli>\n");
 }
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/ies/EsmMessageContainer.c b/openair-cn/NAS/EURECOM-NAS/src/ies/EsmMessageContainer.c
index 575c0731c2bc2047497e2a1582cf736851ff16e7..4df8b7c34fe77b1fe3b157e51c359d8c81d99a38 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/ies/EsmMessageContainer.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/ies/EsmMessageContainer.c
@@ -100,7 +100,7 @@ void dump_esm_message_container_xml(EsmMessageContainer *esmmessagecontainer, ui
     if (iei > 0)
         /* Don't display IEI if = 0 */
         printf("    <IEI>0x%X</IEI>\n", iei);
-    dump_octet_string_xml(&esmmessagecontainer->esmmessagecontainercontents);
+    printf("%s", dump_octet_string_xml(&esmmessagecontainer->esmmessagecontainercontents));
     printf("</Esm Message Container>\n");
 }
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/ies/LcsClientIdentity.c b/openair-cn/NAS/EURECOM-NAS/src/ies/LcsClientIdentity.c
index c62079b20830bc57a48d102cc0d231db38d72453..15e4a729740c2d5ffdd5c57773f8a19848c16f0e 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/ies/LcsClientIdentity.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/ies/LcsClientIdentity.c
@@ -88,7 +88,7 @@ void dump_lcs_client_identity_xml(LcsClientIdentity *lcsclientidentity, uint8_t
     if (iei > 0)
         /* Don't display IEI if = 0 */
         printf("    <IEI>0x%X</IEI>\n", iei);
-    dump_octet_string_xml(&lcsclientidentity->lcsclientidentityvalue);
+    printf("%s",dump_octet_string_xml(&lcsclientidentity->lcsclientidentityvalue));
     printf("</Lcs Client Identity>\n");
 }
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/ies/MsNetworkCapability.c b/openair-cn/NAS/EURECOM-NAS/src/ies/MsNetworkCapability.c
index fb26d6f7a26b0b59f4b2156dfb59aba002b60af8..386e467a680b6a2e295a035d2d9f4c702b68d6c6 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/ies/MsNetworkCapability.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/ies/MsNetworkCapability.c
@@ -88,7 +88,7 @@ void dump_ms_network_capability_xml(MsNetworkCapability *msnetworkcapability, ui
     if (iei > 0)
         /* Don't display IEI if = 0 */
         printf("    <IEI>0x%X</IEI>\n", iei);
-    dump_octet_string_xml(&msnetworkcapability->msnetworkcapabilityvalue);
+    printf("%s",dump_octet_string_xml(&msnetworkcapability->msnetworkcapabilityvalue));
     printf("</Ms Network Capability>\n");
 }
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/ies/NasMessageContainer.c b/openair-cn/NAS/EURECOM-NAS/src/ies/NasMessageContainer.c
index bd176632c1635605b58c3c51a417c16bb5d77685..a7760a472c823506e7f251c192bd2fcbac9e6ae9 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/ies/NasMessageContainer.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/ies/NasMessageContainer.c
@@ -88,7 +88,7 @@ void dump_nas_message_container_xml(NasMessageContainer *nasmessagecontainer, ui
     if (iei > 0)
         /* Don't display IEI if = 0 */
         printf("    <IEI>0x%X</IEI>\n", iei);
-    dump_octet_string_xml(&nasmessagecontainer->nasmessagecontainercontents);
+    printf("%s", dump_octet_string_xml(&nasmessagecontainer->nasmessagecontainercontents));
     printf("</Nas Message Container>\n");
 }
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/ies/NetworkName.c b/openair-cn/NAS/EURECOM-NAS/src/ies/NetworkName.c
index 9124f4949297fdda909fb8f6a94989d081ca4dfd..f5d2f39e80dec1fe85f021b8bbd549801f19963f 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/ies/NetworkName.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/ies/NetworkName.c
@@ -104,7 +104,7 @@ void dump_network_name_xml(NetworkName *networkname, uint8_t iei)
     printf("    <Coding scheme>%u</Coding scheme>\n", networkname->codingscheme);
     printf("    <Add CI>%u</Add CI>\n", networkname->addci);
     printf("    <Number of spare bits in last octet>%u</Number of spare bits in last octet>\n", networkname->numberofsparebitsinlastoctet);
-    dump_octet_string_xml(&networkname->textstring);
+    printf("%s", dump_octet_string_xml(&networkname->textstring));
     printf("</Network Name>\n");
 }
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/ies/PTmsiSignature.c b/openair-cn/NAS/EURECOM-NAS/src/ies/PTmsiSignature.c
index 778d4adc3d62fd9786cc4bbe467768c0a5299b85..170cc4ad901a9251dd48a4f4fad77951912f7f31 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/ies/PTmsiSignature.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/ies/PTmsiSignature.c
@@ -82,7 +82,7 @@ void dump_p_tmsi_signature_xml(PTmsiSignature *ptmsisignature, uint8_t iei)
     if (iei > 0)
         /* Don't display IEI if = 0 */
         printf("    <IEI>0x%X</IEI>\n", iei);
-    dump_octet_string_xml(&ptmsisignature->ptmsisignaturevalue);
+    printf("%s",dump_octet_string_xml(&ptmsisignature->ptmsisignaturevalue));
     printf("</P Tmsi Signature>\n");
 }
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/ies/PdnAddress.c b/openair-cn/NAS/EURECOM-NAS/src/ies/PdnAddress.c
index f935661503c337f863086429c20b7b09a0857886..faf943a276766bf2c5cd819f591421c47a035feb 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/ies/PdnAddress.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/ies/PdnAddress.c
@@ -94,7 +94,7 @@ void dump_pdn_address_xml(PdnAddress *pdnaddress, uint8_t iei)
         /* Don't display IEI if = 0 */
         printf("    <IEI>0x%X</IEI>\n", iei);
     printf("    <PDN type value>%u</PDN type value>\n", pdnaddress->pdntypevalue);
-    dump_octet_string_xml(&pdnaddress->pdnaddressinformation);
+    printf("%s", dump_octet_string_xml(&pdnaddress->pdnaddressinformation));
     printf("</Pdn Address>\n");
 }
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/ies/ProtocolConfigurationOptions.c b/openair-cn/NAS/EURECOM-NAS/src/ies/ProtocolConfigurationOptions.c
index 098a3cc2b8d613eb2e50450881613d954cc2a7d2..6c0bbe393657eecd288ea74bc1c095db14bafc28 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/ies/ProtocolConfigurationOptions.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/ies/ProtocolConfigurationOptions.c
@@ -117,7 +117,7 @@ void dump_protocol_configuration_options_xml(ProtocolConfigurationOptions *proto
     printf("    <Configuration protol>%u</Configuration protol>\n", protocolconfigurationoptions->configurationprotol);
     printf("    <Protocol ID>%u</Protocol ID>\n", protocolconfigurationoptions->protocolid);
     printf("    <Length of protocol ID>%u</Length of protocol ID>\n", protocolconfigurationoptions->lengthofprotocolid);
-    dump_octet_string_xml(&protocolconfigurationoptions->protocolidcontents);
+    printf("%s",dump_octet_string_xml(&protocolconfigurationoptions->protocolidcontents));
     printf("</Protocol Configuration Options>\n");
 }
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/util/OctetString.c b/openair-cn/NAS/EURECOM-NAS/src/util/OctetString.c
index 78a4e2e460a09a5f8e44c2633742fd054666cd77..de4ba350bc6172e7ee9e714b6fe49c60987fa518 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/util/OctetString.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/util/OctetString.c
@@ -34,6 +34,9 @@
 #include "TLVDecoder.h"
 #include "OctetString.h"
 
+#define DUMP_OUTPUT_SIZE 1024
+static  char _dump_output[DUMP_OUTPUT_SIZE];
+
 OctetString* dup_octet_string(OctetString *octetstring)
 {
     OctetString *os_p = NULL;
@@ -78,20 +81,29 @@ int decode_octet_string(OctetString *octetstring, uint16_t pdulen, uint8_t *buff
     return octetstring->length;
 }
 
-void dump_octet_string_xml(OctetString *octetstring)
+char* dump_octet_string_xml( const OctetString * const octetstring)
 {
     int i;
-    printf("    <Length>%u</Length>\n    <values>", octetstring->length);
-    for (i = 0; i < octetstring->length; i++)
-        printf("0x%x ", octetstring->value[i]);
-    printf("</values>\n");
+    int remaining_size = DUMP_OUTPUT_SIZE;
+    int size           = 0;
+    size = snprintf(_dump_output, remaining_size, "<Length>%u</Length>\n\t<values>", octetstring->length);
+    remaining_size -= size;
+    for (i = 0; i < octetstring->length; i++) {
+    	size +=snprintf(&_dump_output[size], remaining_size, "0x%x ", octetstring->value[i]);
+        remaining_size -= size;
+    }
+    size +=snprintf(&_dump_output[size], remaining_size, "</values>\n");
+    return _dump_output;
 }
 
-void dump_octet_string(OctetString *octetstring)
+char* dump_octet_string( const OctetString * const octetstring)
 {
     int i;
-    printf("    <Length=%u><values>", octetstring->length);
-    for (i = 0; i < octetstring->length; i++)
-        printf("0x%x ", octetstring->value[i]);
-    printf("</values>\n");
+    int remaining_size = DUMP_OUTPUT_SIZE;
+    int size           = 0;
+    for (i = 0; i < octetstring->length; i++) {
+    	size +=snprintf(&_dump_output[size], remaining_size, "0x%x ", octetstring->value[i]);
+        remaining_size -= size;
+    }
+    return _dump_output;
 }
diff --git a/openair-cn/NAS/EURECOM-NAS/src/util/OctetString.h b/openair-cn/NAS/EURECOM-NAS/src/util/OctetString.h
index 06471d8292f7b2d21a58698c2b94aaeb8ace3ecd..650f5d246288b5235b61f3da68cbda5837ac345a 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/util/OctetString.h
+++ b/openair-cn/NAS/EURECOM-NAS/src/util/OctetString.h
@@ -55,11 +55,10 @@ typedef struct OctetString_tag {
         }                                                                     \
         (oCTETsTRINGcOPY).length = strlen((const char*)(oCTETsTRINGoRIG).value);\
         assert((oCTETsTRINGoRIG).length == (oCTETsTRINGcOPY).length);         \
-        (oCTETsTRINGcOPY).value  = malloc((oCTETsTRINGoRIG).length+1);        \
+        (oCTETsTRINGcOPY).value  = malloc((oCTETsTRINGoRIG).length);        \
         memcpy((oCTETsTRINGcOPY).value,                                       \
             (oCTETsTRINGoRIG).value,                                          \
             (oCTETsTRINGoRIG).length);                                        \
-        (oCTETsTRINGcOPY).value[(oCTETsTRINGoRIG).length] = '\0';             \
     } while (0);
 
 OctetString* dup_octet_string(OctetString*octetstring);
@@ -70,9 +69,9 @@ int encode_octet_string(OctetString *octetstring, uint8_t *buffer, uint32_t len)
 
 int decode_octet_string(OctetString *octetstring, uint16_t pdulen, uint8_t *buffer, uint32_t buflen);
 
-void dump_octet_string_xml(OctetString *octetstring);
+char* dump_octet_string_xml(const OctetString * const octetstring);
 
-void dump_octet_string(OctetString *octetstring);
+char* dump_octet_string(const OctetString * const octetstring);
 
 #endif /* OCTET_STRING_H_ */
 
diff --git a/openair-cn/S6A/s6a_auth_info.c b/openair-cn/S6A/s6a_auth_info.c
index 7682c4420ce0ef6d8cfdbb89441a8ee4817df4fb..ccc85dc6393be367f28496130adac5cbd8cc99cf 100644
--- a/openair-cn/S6A/s6a_auth_info.c
+++ b/openair-cn/S6A/s6a_auth_info.c
@@ -347,12 +347,23 @@ int s6a_generate_authentication_info_req(s6a_auth_info_req_t *air_p)
 
         CHECK_FCT(fd_msg_avp_new(s6a_fd_cnf.dataobj_s6a_visited_plmn_id, 0, &avp));
 
+
         PLMN_T_TO_TBCD(air_p->visited_plmn, plmn);
         value.os.data = plmn;
         value.os.len  = 3;
         CHECK_FCT(fd_msg_avp_setvalue(avp, &value));
 
         CHECK_FCT(fd_msg_avp_add(msg, MSG_BRW_LAST_CHILD, avp));
+        S6A_DEBUG("%s plmn: %02X%02X%02X\n",
+            __FUNCTION__,
+            plmn[0],
+            plmn[1],
+            plmn[2]);
+        S6A_DEBUG("%s visited_plmn: %02X%02X%02X\n",
+            __FUNCTION__,
+            value.os.data[0],
+            value.os.data[1],
+            value.os.data[2]);
     }
     /* Adding the requested E-UTRAN authentication info AVP */
     {
diff --git a/openair-cn/SECU/kdf.c b/openair-cn/SECU/kdf.c
index 399ed7343b3622034350ff424db4072a77ad458d..0b0c6d97888bc94830ad53d599dee7b027876a0d 100644
--- a/openair-cn/SECU/kdf.c
+++ b/openair-cn/SECU/kdf.c
@@ -28,45 +28,43 @@
  *******************************************************************************/
 #include <stdlib.h>
 #include <stdint.h>
+#include <string.h>
 
 #include <nettle/hmac.h>
 
 #include "security_types.h"
 #include "secu_defs.h"
 
-void kdf(const uint8_t *s, const uint32_t s_length, const uint8_t *key,
-         const uint32_t key_length, uint8_t **out, uint32_t out_length)
+void kdf(uint8_t *key, uint16_t key_len, uint8_t *s, uint16_t s_len, uint8_t *out,
+         uint16_t out_len)
 {
     struct hmac_sha256_ctx ctx;
 
-    uint8_t *buffer;
+    memset(&ctx, 0, sizeof(ctx));
 
-    buffer = malloc(sizeof(uint8_t) * out_length);
-
-    hmac_sha256_set_key(&ctx, key_length, key);
-    hmac_sha256_update(&ctx, s_length, s);
-    hmac_sha256_digest(&ctx, out_length, buffer);
-
-    *out = buffer;
+    hmac_sha256_set_key(&ctx, key_len, key);
+    hmac_sha256_update(&ctx, s_len, s);
+    hmac_sha256_digest(&ctx, out_len, out);
 }
+
 #ifndef NAS_UE
-int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB)
+int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB)
 {
-    uint8_t string[7];
+    uint8_t s[7];
 
     // FC
-    string[0] = FC_KENB;
+    s[0] = FC_KENB;
     // P0 = Uplink NAS count
-    string[1] = (nas_count & 0xff000000) >> 24;
-    string[2] = (nas_count & 0x00ff0000) >> 16;
-    string[3] = (nas_count & 0x0000ff00) >> 8;
-    string[4] = (nas_count & 0x000000ff);
+    s[1] = (nas_count & 0xff000000) >> 24;
+    s[2] = (nas_count & 0x00ff0000) >> 16;
+    s[3] = (nas_count & 0x0000ff00) >> 8;
+    s[4] = (nas_count & 0x000000ff);
 
     // Length of NAS count
-    string[5] = 0x00;
-    string[6] = 0x04;
+    s[5] = 0x00;
+    s[6] = 0x04;
 
-    kdf(string, 7, kasme, 32, keNB, 32);
+    kdf(kasme, 32, s, 7, keNB, 32);
 
     return 0;
 }
diff --git a/openair-cn/SECU/key_nas_deriver.c b/openair-cn/SECU/key_nas_deriver.c
index 7ed51d3d52806d12f577a249ca403750bdb741d4..0de7562ced69bf36d089052d10ce0da5bf4a5a36 100644
--- a/openair-cn/SECU/key_nas_deriver.c
+++ b/openair-cn/SECU/key_nas_deriver.c
@@ -34,6 +34,7 @@
 #include "security_types.h"
 #include "secu_defs.h"
 
+#define SECU_DEBUG 1
 /*!
  * @brief Derive the kNASenc from kasme and perform truncate on the generated key to
  * reduce his size to 128 bits. Definition of the derivation function can
@@ -49,9 +50,10 @@
  * NOTE: knas is dynamically allocated by the KDF function
  */
 int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
-                   const uint8_t kasme[32], uint8_t **knas)
+                   const uint8_t kasme[32], uint8_t *knas)
 {
     uint8_t s[7];
+    uint8_t out[32];
 #if defined(SECU_DEBUG)
     int i;
 #endif
@@ -74,13 +76,17 @@ int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
     s[6] = 0x01;
 
 #if defined(SECU_DEBUG)
+    printf("%s FC %d nas_alg_type distinguisher %d nas_enc_alg_identity %d\n",
+    		__FUNCTION__, FC_ALG_KEY_DER, nas_alg_type, nas_enc_alg_id);
     for (i = 0; i < 7; i ++) {
         printf("0x%02x ", s[i]);
     }
     printf("\n");
 #endif
 
-    kdf(s, 7, kasme, 32, knas, 32);
+    kdf(kasme, 32, s, 7, out, 32);
+
+    memcpy(knas, &out[31-16+1], 16);
 
     return 0;
 }
diff --git a/openair-cn/SECU/key_nas_encryption.c b/openair-cn/SECU/key_nas_encryption.c
index f7e8b747f51a6cf0a94c5c38961c65d70381d60f..0341c8180b592a32e455ce34392c7e7e9bf51174 100644
--- a/openair-cn/SECU/key_nas_encryption.c
+++ b/openair-cn/SECU/key_nas_encryption.c
@@ -66,7 +66,7 @@
     s[5] = 0x00;
     s[6] = 0x01;
 
-    kdf(s, 7, (uint8_t*)kasme, 32, (uint8_t**)&knas_temp, 32);
+    kdf((uint8_t*)kasme, 32, s, 7, (uint8_t**)&knas_temp, 32);
 
     // Truncate the generate key to 128 bits
     memcpy(knas, knas_temp, 16);
diff --git a/openair-cn/SECU/nas_stream_eea1.c b/openair-cn/SECU/nas_stream_eea1.c
index c090c18f622e264d41fce147bedab821af7789be..b99923722c4f498df0f93d134633a2f8957320fa 100755
--- a/openair-cn/SECU/nas_stream_eea1.c
+++ b/openair-cn/SECU/nas_stream_eea1.c
@@ -43,7 +43,7 @@
 // #define SECU_DEBUG
 
 
-int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t **out)
+int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t *out)
 {
     snow_3g_context_t snow_3g_context;
 	int       n ;
@@ -102,11 +102,17 @@ int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t **out)
 	for (i=0;i<n*4;i++) {
 		stream_cipher->message[i] ^= *(((uint8_t*)KS)+i);
 	}
+	int ceil_index = 0;
     if (zero_bit > 0) {
-    	int ceil_index = (stream_cipher->blength+7) >> 3;
+    	ceil_index = (stream_cipher->blength+7) >> 3;
     	stream_cipher->message[ceil_index - 1] = stream_cipher->message[ceil_index - 1] & (uint8_t)(0xFF << (8 - zero_bit));
     }
     free(KS);
     *out = stream_cipher->message;
+    memcpy(out, stream_cipher->message, n*4);
+    if (zero_bit > 0) {
+    	out[ceil_index - 1] = stream_cipher->message[ceil_index - 1];
+    }
+
     return 0;
 }
diff --git a/openair-cn/SECU/nas_stream_eea2.c b/openair-cn/SECU/nas_stream_eea2.c
index 10de4ceb861081f79f8c171d2aca91a2e0d01a5c..546230e463aec984167c0b2e2743797796f3f0b8 100644
--- a/openair-cn/SECU/nas_stream_eea2.c
+++ b/openair-cn/SECU/nas_stream_eea2.c
@@ -41,7 +41,7 @@
 
 // #define SECU_DEBUG
 
-int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t **out)
+int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out)
 {
     uint8_t m[16];
     uint32_t local_count;
@@ -92,8 +92,9 @@ int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t **out)
     if (zero_bit > 0)
         data[byte_length - 1] = data[byte_length - 1] & (uint8_t)(0xFF << (8 - zero_bit));
 
-    *out = data;
 
+    memcpy(out, data, byte_length);
+    free(data);
     free(ctx);
 
     return 0;
diff --git a/openair-cn/SECU/secu_defs.h b/openair-cn/SECU/secu_defs.h
index 568383579005e175ea0b4db6e4f690b82aaaa5a7..3652cabbc39f709945d237e161732b7fe132c41e 100644
--- a/openair-cn/SECU/secu_defs.h
+++ b/openair-cn/SECU/secu_defs.h
@@ -42,13 +42,17 @@
 #define SECU_DIRECTION_UPLINK   0
 #define SECU_DIRECTION_DOWNLINK 1
 
-void kdf(const uint8_t *s, const uint32_t s_length, const uint8_t *key,
-         const uint32_t key_length, uint8_t **out, uint32_t out_length);
+void kdf(uint8_t *key,
+		uint16_t key_len,
+		uint8_t *s,
+		uint16_t s_len,
+		uint8_t *out,
+		uint16_t out_len);
 
-int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB);
+int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB);
 
 int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
-                   const uint8_t kasme[32], uint8_t **knas);
+                   const uint8_t kasme[32], uint8_t *knas);
 
 #define derive_key_nas_enc(aLGiD, kASME, kNAS)  \
     derive_key_nas(NAS_ENC_ALG, aLGiD, kASME, kNAS)
@@ -82,11 +86,11 @@ typedef struct {
     uint32_t  blength;
 } nas_stream_cipher_t;
 
-int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t **out);
+int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t *out);
 
 int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out[4]);
 
-int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t **out);
+int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out);
 
 int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4]);
 
diff --git a/openair-cn/TEST/test_kdf.c b/openair-cn/TEST/test_kdf.c
index 4f81c9f6652db35fb619f40d650a0c6678ac277d..3a1b5d2b5419b41c0958e7929d4f711c8b7e0d56 100644
--- a/openair-cn/TEST/test_kdf.c
+++ b/openair-cn/TEST/test_kdf.c
@@ -44,7 +44,7 @@ void do_kdf(uint8_t *key, unsigned key_length, uint8_t *data, unsigned data_leng
 {
     uint8_t *result;
 
-    kdf(data, data_length, key, key_length, &result, 32);
+    kdf(key, key_length, data, data_length, &result, 32);
     if (compare_buffer(result, exp_length, exp, exp_length) != 0) {
         fail("Fail: kdf\n");
     }
diff --git a/openair-cn/UTILS/conversions.h b/openair-cn/UTILS/conversions.h
index b5dfdba55ecefd94cf26b64bdd2da60e9d7e1a4e..0d9eac09d4d9985c03486a41d604268f3c7bc76f 100644
--- a/openair-cn/UTILS/conversions.h
+++ b/openair-cn/UTILS/conversions.h
@@ -241,9 +241,14 @@ do {                                                                \
 #define PLMN_T_TO_TBCD(pLMN, tBCDsTRING)                            \
 do {                                                                \
     tBCDsTRING[0] = (pLMN.MCCdigit2 << 4) | pLMN.MCCdigit3;         \
-    tBCDsTRING[1] = ((pLMN.MNCdigit1 == 0 ? 0xF : pLMN.MNCdigit1) << 4) \
-    | pLMN.MCCdigit1;                                               \
-    tBCDsTRING[2] = (pLMN.MNCdigit2 << 4) | pLMN.MNCdigit3;         \
+    /* ambiguous (think about len 2) */                             \
+    if (pLMN.MNCdigit1 == 0) {                                      \
+        tBCDsTRING[1] = (0x0F << 4) | pLMN.MCCdigit1;               \
+        tBCDsTRING[2] = (pLMN.MNCdigit3 << 4) | pLMN.MNCdigit2;     \
+    } else {                                                        \
+        tBCDsTRING[1] = (pLMN.MNCdigit3 << 4) | pLMN.MCCdigit1;     \
+        tBCDsTRING[2] = (pLMN.MNCdigit2 << 4) | pLMN.MNCdigit1;     \
+    }                                                               \
 } while(0)
 
 #define PLMN_T_TO_MCC_MNC(pLMN, mCC, mNC, mNCdIGITlENGTH)               \