diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
index 9425c06e3792753f377d4046cd195fce3c1fc620..ac438136acb2aac7f47460736fe6b1cb6ebee974 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
@@ -212,12 +212,20 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
                       header_size + size + integrity_size, sdu_id);
 }
 
-static void nr_pdcp_entity_set_integrity_key(nr_pdcp_entity_t *entity,
-                                             char *key)
+static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity,
+                                        int integrity_algorithm,
+                                        char *integrity_key,
+                                        int ciphering_algorithm,
+                                        char *ciphering_key)
 {
-  LOG_E(PDCP, "%s: %d: %s: TODO? to remove?\n", __FILE__, __LINE__, __FUNCTION__);
-  exit(1);
-  //memcpy(entity->integrity_key, key, 16);
+  if (integrity_algorithm != -1)
+    entity->integrity_algorithm = integrity_algorithm;
+  if (ciphering_algorithm != -1)
+    entity->ciphering_algorithm = ciphering_algorithm;
+  if (integrity_key != NULL)
+    memcpy(entity->integrity_key, integrity_key, 16);
+  if (ciphering_key != NULL)
+    memcpy(entity->ciphering_key, ciphering_key, 16);
 }
 
 static void check_t_reordering(nr_pdcp_entity_t *entity)
@@ -310,10 +318,10 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
 
   ret->type = type;
 
-  ret->recv_pdu          = nr_pdcp_entity_recv_pdu;
-  ret->recv_sdu          = nr_pdcp_entity_recv_sdu;
-  ret->set_integrity_key = nr_pdcp_entity_set_integrity_key;
-  ret->set_time          = nr_pdcp_entity_set_time;
+  ret->recv_pdu     = nr_pdcp_entity_recv_pdu;
+  ret->recv_sdu     = nr_pdcp_entity_recv_sdu;
+  ret->set_security = nr_pdcp_entity_set_security;
+  ret->set_time     = nr_pdcp_entity_set_time;
 
   ret->delete = nr_pdcp_entity_delete;
 
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
index 4ae7a45abb57140fb5557971e6669caec133119c..b7093c71820497b13fdbd1926f38730d8c885bc0 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
@@ -40,7 +40,16 @@ typedef struct nr_pdcp_entity_t {
   void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
                    int sdu_id);
   void (*delete)(struct nr_pdcp_entity_t *entity);
-  void (*set_integrity_key)(struct nr_pdcp_entity_t *entity, char *key);
+  /* set_security: pass -1 to integrity_algorithm / ciphering_algorithm
+   *               to keep the current algorithm
+   *               pass NULL to integrity_key / ciphering_key
+   *               to keep the current key
+   */
+  void (*set_security)(struct nr_pdcp_entity_t *entity,
+                       int integrity_algorithm,
+                       char *integrity_key,
+                       int ciphering_algorithm,
+                       char *ciphering_key);
   void (*set_time)(struct nr_pdcp_entity_t *entity, uint64_t now);
 
   /* callbacks provided to the PDCP module */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index 921776bf266449bd603cf927b6fc8bb4caba031e..a7831e72e919f245f673f871d7e3cda9b0ed9332 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -1044,6 +1044,12 @@ void pdcp_config_set_security(
         uint8_t *const kRRCint_pP,
         uint8_t *const kUPenc_pP)
 {
+  nr_pdcp_ue_t *ue;
+  nr_pdcp_entity_t *rb;
+  int rnti = ctxt_pP->rnti;
+  int integrity_algorithm;
+  int ciphering_algorithm;
+
   DevAssert(pdcp_pP != NULL);
 
   if ((security_modeP >= 0) && (security_modeP <= 0x77)) {
@@ -1073,6 +1079,33 @@ void pdcp_config_set_security(
           PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP),
           security_modeP);
   }
+
+  nr_pdcp_manager_lock(nr_pdcp_ue_manager);
+
+  ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
+
+  /* TODO: proper handling of DRBs, for the moment only SRBs are handled */
+
+  if (rb_id >= 1 && rb_id <= 3) {
+    rb = ue->srb[rb_id - 1];
+
+    if (rb == NULL) {
+      LOG_E(PDCP, "%s:%d:%s: no SRB found (rnti %d, rb_id %ld)\n",
+            __FILE__, __LINE__, __FUNCTION__, rnti, rb_id);
+      nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+      return;
+    }
+
+    integrity_algorithm = (security_modeP>>4) & 0xf;
+    ciphering_algorithm = security_modeP & 0x0f;
+    rb->set_security(rb, integrity_algorithm, (char *)kRRCint_pP,
+                     ciphering_algorithm, (char *)kRRCenc_pP);
+  } else {
+    LOG_E(PDCP, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
+    exit(1);
+  }
+
+  nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
 }
 
 
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index 02a183fe2fd500d4c71d6b3c80c75187681ad8e5..c0ca18bad9e7ecbbd852b9e30f776a0645429269 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -304,25 +304,45 @@ nr_rrc_pdcp_config_security(
   uint8_t                            *kRRCenc = NULL;
   uint8_t                            *kRRCint = NULL;
   uint8_t                            *kUPenc = NULL;
+  uint8_t                            *k_kdf  = NULL;
   pdcp_t                             *pdcp_p   = NULL;
   static int                          print_keys= 1;
   hashtable_rc_t                      h_rc;
   hash_key_t                          key;
 
 #ifndef PHYSIM
-    /* Derive the keys from kgnb */
-    if (SRB_configList != NULL) {
-        nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
-                          ue_context_pP->ue_context.kgnb,
-                          &kUPenc);
-    }
+  /* Derive the keys from kgnb */
+  if (SRB_configList != NULL) {
+    k_kdf = NULL;
+    nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
+                         ue_context_pP->ue_context.kgnb,
+                         &k_kdf);
+    /* kUPenc: last 128 bits of key derivation function which returns 256 bits */
+    kUPenc = malloc(16);
+    if (kUPenc == NULL) exit(1);
+    memcpy(kUPenc, k_kdf+16, 16);
+    free(k_kdf);
+  }
 
-    nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
-                          ue_context_pP->ue_context.kgnb,
-                          &kRRCenc);
-    nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
-                          ue_context_pP->ue_context.kgnb,
-                          &kRRCint);
+  k_kdf = NULL;
+  nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
+                        ue_context_pP->ue_context.kgnb,
+                        &k_kdf);
+  /* kRRCenc: last 128 bits of key derivation function which returns 256 bits */
+  kRRCenc = malloc(16);
+  if (kRRCenc == NULL) exit(1);
+  memcpy(kRRCenc, k_kdf+16, 16);
+  free(k_kdf);
+
+  k_kdf = NULL;
+  nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
+                        ue_context_pP->ue_context.kgnb,
+                        &k_kdf);
+  /* kRRCint: last 128 bits of key derivation function which returns 256 bits */
+  kRRCint = malloc(16);
+  if (kRRCint == NULL) exit(1);
+  memcpy(kRRCint, k_kdf+16, 16);
+  free(k_kdf);
 #endif
   if (!IS_SOFTMODEM_IQPLAYER) {
     SET_LOG_DUMP(DEBUG_SECURITY) ;