diff --git a/example/libusb/ble_server.c b/example/libusb/ble_server.c
index af7d59ab0..1644d83ce 100644
--- a/example/libusb/ble_server.c
+++ b/example/libusb/ble_server.c
@@ -114,6 +114,10 @@ static uint16_t         att_response_handle = 0;
 static uint16_t         att_response_size   = 0;
 static uint8_t          att_response_buffer[28];
 
+// Security Manager Master Keys, please use sm_set_er(er) and sm_set_ir(ir) with your own 128 bit random values
+static key_t sm_persistent_er;
+static key_t sm_persistent_ir;
+
 static uint16_t         sm_response_handle = 0;
 static uint16_t         sm_response_size   = 0;
 static uint8_t          sm_response_buffer[28];
@@ -188,6 +192,23 @@ static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pa
 
 // SECURITY MANAGER (SM) MATERIALIZES HERE
 
+void sm_init(){
+    // set some (BTstack default) ER and IR
+    int i;
+    for (i=0;i<16;i++){
+        sm_persistent_er[i] = 0x30 + i;
+        sm_persistent_ir[i] = 0x90 + i;
+    }
+}
+
+void sm_set_er(key_t er){
+    memcpy(sm_persistent_er, er, 16);
+}
+
+void sm_set_ir(key_t ir){
+    memcpy(sm_persistent_ir, ir, 16);
+}
+
 static inline void swap128(uint8_t src[16], uint8_t dst[16]){
     int i;
     for (i = 0; i < 16; i++)
@@ -200,7 +221,7 @@ static inline void swap56(uint8_t src[7], uint8_t dst[7]){
         dst[6 - i] = src[i];
 }
 
-static void sm_d1(key_t k, uint16_t d, uint16_t r){
+static void sm_d1(key_t k, uint16_t d, uint16_t r, key_t d1){
     // d'= padding || r || d
     key_t d1_prime;
     memset(d1_prime, 0, 16);
@@ -209,8 +230,60 @@ static void sm_d1(key_t k, uint16_t d, uint16_t r){
     // d1(k,d,r) = e(k, d'),
     unsigned long rk[RKLENGTH(KEYBITS)];
     int nrounds = rijndaelSetupEncrypt(rk, &k[0], KEYBITS);
-    key_t d1;
-    rijndaelEncrypt(rk, nrounds, k, d1);
+    rijndaelEncrypt(rk, nrounds, d1_prime, d1);
+}
+
+static uint16_t sm_dm(key_t k, uint8_t r[8]){
+    // r’ = padding || r
+    key_t r_prime;
+    memset(r_prime, 0, 16);
+    memcpy(&r_prime[8], r, 8);
+    // dm(k, r) = e(k, r’) dm(k, r) = e(k, r’) 
+    key_t dm128;
+    unsigned long rk[RKLENGTH(KEYBITS)];
+    int nrounds = rijndaelSetupEncrypt(rk, &k[0], KEYBITS);
+    rijndaelEncrypt(rk, nrounds, r_prime, dm128);
+    uint16_t dm = READ_NET_16(dm128, 14);
+    return dm;
+}
+
+static uint16_t sm_y(key_t dhk, uint8_t rand[8]){
+    // Y = dm(DHK, Rand)
+    return sm_dm(dhk, rand);
+}
+
+static uint16_t sm_ediv(key_t dhk, uint8_t rand[8], uint16_t div){
+    // EDIV = Y xor DIV
+    uint16_t y = sm_y(dhk, rand);
+    uint16_t ediv = y ^ div;
+    return ediv; 
+}
+
+static uint16_t sm_div(key_t dhk, uint8_t rand[8], uint16_t ediv){
+    // DIV = Y xor EDIV
+    uint16_t y = sm_y(dhk, rand);
+    uint16_t div = y ^ ediv;
+    return div;
+}
+
+static void sm_ltk(key_t er, uint16_t div, key_t ltk){
+    // LTK = d1(ER, DIV, 0))
+    sm_d1(er, div, 0, ltk);
+}
+
+static void sm_csrk(key_t er, uint16_t div, key_t csrk){
+    // LTK = d1(ER, DIV, 0))
+    sm_d1(er, div, 1, csrk);
+}
+
+static void sm_irk(key_t ir, key_t irk){
+    // IRK = d1(IR, 1, 0)
+    sm_d1(ir, 1, 0, irk);
+}
+
+static void sm_dhk(key_t ir, key_t dhk){
+    // DHK = d1(IR, 3, 0)
+    sm_d1(ir, 3, 0, dhk);
 }
 
 static void sm_c1(key_t k, key_t r, uint8_t preq[7], uint8_t pres[7], uint8_t iat, uint8_t rat, bd_addr_t ia, bd_addr_t ra, key_t c1){