You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ut...@apache.org on 2020/01/06 18:15:46 UTC

[mynewt-core] branch master updated: da1469x: Add Encrypted Flash Driver

This is an automated email from the ASF dual-hosted git repository.

utzig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git


The following commit(s) were added to refs/heads/master by this push:
     new b59779e  da1469x: Add Encrypted Flash Driver
b59779e is described below

commit b59779e8bfbab2992a7e3036c8c5f8e21ee5e9b3
Author: Naveen Kaje <na...@juul.com>
AuthorDate: Mon Dec 9 11:41:24 2019 -0600

    da1469x: Add Encrypted Flash Driver
    
    Add Encrypted Flash Driver that makes use of the AES encrypt engine
    on the SoC. The driver supports CTR mode for 256/192/128 bits.
    
    The AES Key which is stored in the OTP area is securely DMA transferred
    into the AES engine during the encrypt operation.
    
    The OTP area has slots (0-7) that could be used for storing the keys.
    The slot number is specified with a MYNEWT configuration parameter.
    
    Signed-off-by: Naveen Kaje <na...@juul.com>
---
 hw/bsp/dialog_da1469x-dk-pro/syscfg.yml            |   4 +
 .../ef_da1469x/include/ef_da1469x/ef_da1469x.h     |  45 ++++++
 hw/drivers/flash/enc_flash/ef_da1469x/pkg.yml      |  33 +++++
 .../flash/enc_flash/ef_da1469x/src/hw_enc_flash.c  | 164 +++++++++++++++++++++
 4 files changed, 246 insertions(+)

diff --git a/hw/bsp/dialog_da1469x-dk-pro/syscfg.yml b/hw/bsp/dialog_da1469x-dk-pro/syscfg.yml
index 7830eee..3550295 100644
--- a/hw/bsp/dialog_da1469x-dk-pro/syscfg.yml
+++ b/hw/bsp/dialog_da1469x-dk-pro/syscfg.yml
@@ -38,6 +38,10 @@ syscfg.defs:
         description: 'Specifies path to ED25519 private key PEM file'
         value: ''
 
+    USER_AES_SLOT:
+        description: 'Specifies AES key slot for OTP user data encryption and decryption'
+        value: -1
+
 syscfg.defs.BUS_DRIVER_PRESENT:
     BSP_FLASH_SPI_NAME:
         description: 'SPIFLASH device name'
diff --git a/hw/drivers/flash/enc_flash/ef_da1469x/include/ef_da1469x/ef_da1469x.h b/hw/drivers/flash/enc_flash/ef_da1469x/include/ef_da1469x/ef_da1469x.h
new file mode 100644
index 0000000..53ba27c
--- /dev/null
+++ b/hw/drivers/flash/enc_flash/ef_da1469x/include/ef_da1469x/ef_da1469x.h
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __EF_DA1469X_H__
+#define __EF_DA1469X_H__
+
+/*
+ * Encrypting flash driver for da1469x
+ */
+#include <enc_flash/enc_flash.h>
+#include <os/mynewt.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * da1469x specific version of the flash device.
+ */
+struct eflash_da1469x_dev {
+    struct enc_flash_dev end_dev;
+    struct os_sem ef_sem;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __EF_DA1469X_H__ */
diff --git a/hw/drivers/flash/enc_flash/ef_da1469x/pkg.yml b/hw/drivers/flash/enc_flash/ef_da1469x/pkg.yml
new file mode 100644
index 0000000..b7e1501
--- /dev/null
+++ b/hw/drivers/flash/enc_flash/ef_da1469x/pkg.yml
@@ -0,0 +1,33 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/drivers/flash/enc_flash/ef_da1469x
+pkg.description: Encrypting flash driver for dialog da1469x
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - security
+    - encrypt
+    - flash
+
+pkg.deps:
+    - "@apache-mynewt-core/hw/drivers/flash/enc_flash"
+    - "@apache-mynewt-core/hw/drivers/flash/enc_flash/ef_da1469x"
+    - "@apache-mynewt-core/hw/mcu/dialog"
+
diff --git a/hw/drivers/flash/enc_flash/ef_da1469x/src/hw_enc_flash.c b/hw/drivers/flash/enc_flash/ef_da1469x/src/hw_enc_flash.c
new file mode 100644
index 0000000..188399b
--- /dev/null
+++ b/hw/drivers/flash/enc_flash/ef_da1469x/src/hw_enc_flash.c
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <os/mynewt.h>
+#include <mcu/da1469x_clock.h>
+
+#include "enc_flash/enc_flash.h"
+#include "enc_flash/enc_flash_int.h"
+#include "ef_da1469x/ef_da1469x.h"
+#include <mcu/da1469x_dma.h>
+#include <mcu/da1469x_otp.h>
+
+#define EDEV_TO_DA1469X(dev)   (struct eflash_da1469x_dev *)dev
+#define DA1469X_AES_KEYSIZE 256
+
+static void
+do_dma_key_tx(const struct hal_flash *h_dev, uint32_t slot)
+{
+    DMA_Type *dma_regs = DMA;
+
+    /* enable OTP clock and set in read mode */
+    da1469x_clock_amba_enable(CRG_TOP_CLK_AMBA_REG_OTP_ENABLE_Msk);
+    da1469x_otp_set_mode(OTPC_MODE_READ);
+
+    /* program start and end addresses */
+    QSPIC->QSPIC_CTR_SADDR_REG = h_dev->hf_base_addr;
+    QSPIC->QSPIC_CTR_EADDR_REG = h_dev->hf_size + h_dev->hf_base_addr;
+
+    /* securely DMA hardware key from secret storage to QSPI decrypt engine */
+    dma_regs->DMA_REQ_MUX_REG |= 0xf000;
+    dma_regs->DMA7_LEN_REG = 8;
+    dma_regs->DMA7_A_START_REG = MCU_OTPM_BASE + OTP_SEGMENT_USER_DATA_KEYS +
+                                 (32 * (slot));
+    dma_regs->DMA7_B_START_REG = (uint32_t)&AES_HASH->CRYPTO_KEYS_START;
+    dma_regs->DMA7_CTRL_REG = DMA_DMA7_CTRL_REG_AINC_Msk |
+                              DMA_DMA7_CTRL_REG_BINC_Msk |
+                              (MCU_DMA_BUS_WIDTH_4B << DMA_DMA7_CTRL_REG_BW_Pos) |
+                              DMA_DMA7_CTRL_REG_DMA_ON_Msk;
+    while (dma_regs->DMA7_IDX_REG != 8);
+
+    /* set OTP to standby and turn off clock */
+    da1469x_otp_set_mode(OTPC_MODE_STBY);
+    da1469x_clock_amba_disable(CRG_TOP_CLK_AMBA_REG_OTP_ENABLE_Msk);
+}
+
+static uint32_t
+get_key_size_mask(int keysize)
+{
+    uint32_t val = 0;
+
+    switch (keysize) {
+    case 256:
+        /*
+         * XXX: Datasheet for da1469x Rev 2.0 (CFR0011-120-00)
+         * indicates that a value of 2 and 3 correspond to
+         * 256 bit AES Key, However, only 2 works.
+         */
+        val = 2;
+        break;
+    case 192:
+        val = 1;
+        break;
+    default:
+        /* 128 bits */
+        val = 0;
+        break;
+   }
+   return (val << AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEY_SZ_Pos);
+}
+
+void
+do_encrypt(const struct hal_flash *h_dev, uint32_t *ctr, const uint8_t *src, uint8_t *tgt, int off, int cnt)
+{
+    /* Select AES CTR, set CRYPTO_ALG_MD bits to 10 */
+    uint32_t algo_sel = (2 << AES_HASH_CRYPTO_CTRL_REG_CRYPTO_ALG_MD_Pos);
+    uint32_t ks_mask = get_key_size_mask(DA1469X_AES_KEYSIZE);
+
+    /* XXX: for now assume we are only user of crypto block */
+    da1469x_clock_amba_enable(CRG_TOP_CLK_AMBA_REG_AES_CLK_ENABLE_Msk);
+
+    /*
+     * Set CRYPTO_CTRL_REG to:
+     *  Enable CRYPTO_OUT_MD: Write back to memory only the final block of
+     * resulting data
+     *  Set Key Size to 256 bits
+     *  Set algo mode to CTR.
+     */
+    AES_HASH->CRYPTO_CTRL_REG = AES_HASH_CRYPTO_CTRL_REG_CRYPTO_OUT_MD_Msk |
+                                AES_HASH_CRYPTO_CTRL_REG_CRYPTO_AES_KEXP_Msk |
+                                ks_mask |
+                                algo_sel;
+
+    AES_HASH->CRYPTO_LEN_REG = ENC_FLASH_BLK;
+    AES_HASH->CRYPTO_FETCH_ADDR_REG = (uint32_t)src;
+    AES_HASH->CRYPTO_DEST_ADDR_REG = (uint32_t)tgt;
+
+    /* Set nonce and ctr */
+    AES_HASH->CRYPTO_MREG0_REG = ctr[0];
+    AES_HASH->CRYPTO_MREG1_REG = ctr[1];
+    AES_HASH->CRYPTO_MREG2_REG = ctr[2];
+    AES_HASH->CRYPTO_MREG3_REG = ctr[3];
+
+    assert((AES_HASH->CRYPTO_STATUS_REG & 0x01) == 1);
+
+    /* securely transfer the key from OTP area */
+    do_dma_key_tx(h_dev, MYNEWT_VAL(USER_AES_SLOT));
+    /* Start encryption */
+    AES_HASH->CRYPTO_START_REG = 1;
+
+    /* wait till done */
+    while ((AES_HASH->CRYPTO_STATUS_REG & 0x01) == 0);
+
+    da1469x_clock_amba_disable(CRG_TOP_CLK_AMBA_REG_AES_CLK_ENABLE_Msk);
+}
+
+void
+enc_flash_crypt_arch(struct enc_flash_dev *edev, uint32_t blk_addr,
+                     const uint8_t *src, uint8_t *tgt, int off, int cnt)
+{
+    struct eflash_da1469x_dev *dev = EDEV_TO_DA1469X(edev);
+    const struct hal_flash *h_dev = edev->efd_hwdev;
+    uint32_t ctr[4] = {0};
+
+    ctr[0] = (uint32_t) ((blk_addr - h_dev->hf_base_addr) / ENC_FLASH_BLK);
+
+    os_sem_pend(&dev->ef_sem, OS_TIMEOUT_NEVER);
+    do_encrypt(h_dev, ctr, src, tgt, off, cnt);
+    os_sem_release(&dev->ef_sem);
+}
+
+/* Key is securely DMA transferred from OTP user data key slot */
+void
+enc_flash_setkey_arch(struct enc_flash_dev *h_dev, uint8_t *key)
+{
+    return;
+}
+
+int
+enc_flash_init_arch(struct enc_flash_dev *edev)
+{
+    struct eflash_da1469x_dev *dev = EDEV_TO_DA1469X(edev);
+
+    os_sem_init(&dev->ef_sem, 1);
+    return 0;
+}