diff --git a/CMakeLists.txt b/CMakeLists.txt
index 577a5f0..49b0567 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,6 +52,7 @@ target_sources(pico_hsm PUBLIC
${CMAKE_CURRENT_LIST_DIR}/src/rng/random.c
${CMAKE_CURRENT_LIST_DIR}/src/rng/neug.c
${CMAKE_CURRENT_LIST_DIR}/src/hsm/hash_utils.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/hsm/dkek.c
${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/sha256.c
${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/aes.c
diff --git a/src/hsm/dkek.c b/src/hsm/dkek.c
new file mode 100644
index 0000000..5453fba
--- /dev/null
+++ b/src/hsm/dkek.c
@@ -0,0 +1,129 @@
+/*
+ * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm).
+ * Copyright (c) 2022 Pol Henarejos.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include "stdlib.h"
+#include "pico/stdlib.h"
+#include "dkek.h"
+#include "hash_utils.h"
+#include "random.h"
+#include "sc_hsm.h"
+#include "mbedtls/md.h"
+#include "mbedtls/cmac.h"
+
+static uint8_t dkek[32];
+
+void init_dkek() {
+ memset(dkek, 0, sizeof(dkek));
+}
+
+void import_dkek_share(const uint8_t *share) {
+ for (int i = 0; i < 32; i++)
+ dkek[i] ^= share[i];
+}
+
+void dkek_kcv(uint8_t *kcv) { //kcv 8 bytes
+ uint8_t hsh[32];
+ hash256(dkek, sizeof(dkek), hsh);
+ memcpy(kcv, hsh, 8);
+}
+
+void dkek_kenc(uint8_t *kenc) { //kenc 32 bytes
+ uint8_t buf[32+4];
+ memcpy(buf, dkek, sizeof(dkek));
+ memcpy(buf, "\x0\x0\x0\x1", 4);
+ hash256(dkek, sizeof(dkek), kenc);
+}
+
+void dkek_kmac(uint8_t *kmac) { //kmac 32 bytes
+ uint8_t buf[32+4];
+ memcpy(buf, dkek, sizeof(dkek));
+ memcpy(buf, "\x0\x0\x0\x2", 4);
+ hash256(dkek, sizeof(dkek), kmac);
+}
+
+int dkek_encode_aes_key(uint8_t *key, int key_size, uint8_t *out, size_t *out_len) { //out has to be 93 bytes at least
+ if (key_size != 16 || key_size != 24 || key_size != 32)
+ return HSM_WRONG_DATA;
+ if (*out_len < 8+1+10+6+4+48+16)
+ return HSM_WRONG_LENGTH;
+ uint8_t kb[48]; //worst case (8+2+key_size+padding)
+ memset(kb, 0, sizeof(kb));
+
+ uint8_t kenc[32];
+ memset(kenc, 0, sizeof(kenc));
+ dkek_kenc(kenc);
+
+ uint8_t kcv[8];
+ memset(kcv, 0, sizeof(kcv));
+ dkek_kcv(kcv);
+
+ uint8_t kmac[32];
+ memset(kmac, 0, sizeof(kmac));
+ dkek_kmac(kmac);
+
+ int kb_len = 8+2+key_size;
+ int kb_len_pad = ((int)(kb_len/16))*16;
+ if (kb_len % 16 > 0)
+ kb_len_pad = ((int)(kb_len/16)+1)*16;
+ memcpy(kb, random_bytes_get(8), 8);
+ put_uint16_t(key_size, kb+8);
+ memcpy(kb+8+2, key, key_size);
+ if (kb_len < kb_len_pad) {
+ kb[kb_len] = 0x80;
+ }
+ int r = aes_encrypt(kenc, NULL, 32, kb, kb_len_pad);
+ if (r != HSM_OK)
+ return r;
+
+ memset(out, 0, *out_len);
+ *out_len = 0;
+ uint8_t *aes_oid = "\x00\x08\x60\x86\x48\x01\x65\x03\x04\x01"; //2.16.840.1.101.3.4.1 (2+8)
+ uint8_t *aes_algo = "\x00\x04\x10\x11\x18\x99"; //(2+4)
+
+ memcpy(out+*out_len, kcv, 8);
+ *out_len += 8;
+
+ out[*out_len] = 15;
+ *out_len += 1;
+
+ memcpy(out+*out_len, aes_oid, 10);
+ *out_len += 10;
+
+ memcpy(out+*out_len, aes_algo, 6);
+ *out_len += 6;
+
+ //add 4 zeros
+ *out_len += 4;
+
+ memcpy(out+*out_len, kb, kb_len_pad);
+ *out_len += kb_len_pad;
+
+ const mbedtls_cipher_info_t *cipher_info;
+ if (key_size == 16)
+ cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
+ else if (key_size == 24)
+ cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_192_ECB);
+ else if (key_size == 32)
+ cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB);
+ r = mbedtls_cipher_cmac(cipher_info, kmac, 256, out, *out_len, out+*out_len);
+
+ *out_len += 16;
+ if (r != 0)
+ return r;
+ return HSM_OK;
+}
\ No newline at end of file
diff --git a/src/hsm/dkek.h b/src/hsm/dkek.h
new file mode 100644
index 0000000..aa6ca53
--- /dev/null
+++ b/src/hsm/dkek.h
@@ -0,0 +1,21 @@
+/*
+ * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm).
+ * Copyright (c) 2022 Pol Henarejos.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef _DKEK_H_
+#define _DKEK_H_
+
+#endif