You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/08/02 08:39:46 UTC

[GitHub] mkiiskila closed pull request #1294: Encrypted flash

mkiiskila closed pull request #1294: Encrypted flash
URL: https://github.com/apache/mynewt-core/pull/1294
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/fs/fcb/src/fcb.c b/fs/fcb/src/fcb.c
index d0917abcff..b70f5f50ac 100644
--- a/fs/fcb/src/fcb.c
+++ b/fs/fcb/src/fcb.c
@@ -150,9 +150,6 @@ fcb_get_len(uint8_t *buf, uint16_t *len)
     int rc;
 
     if (buf[0] & 0x80) {
-        if (buf[0] == 0xff && buf[1] == 0xff) {
-            return FCB_ERR_NOVAR;
-        }
         *len = (buf[0] & 0x7f) | (buf[1] << 7);
         rc = 2;
     } else {
@@ -199,13 +196,13 @@ fcb_sector_hdr_read(struct fcb *fcb, struct flash_area *fap,
     if (!fdap) {
         fdap = &fda;
     }
+    if (flash_area_isempty_at(fap, 0, sizeof(*fdap))) {
+        return 0;
+    }
     rc = flash_area_read(fap, 0, fdap, sizeof(*fdap));
     if (rc) {
         return FCB_ERR_FLASH;
     }
-    if (fdap->fd_magic == 0xffffffff) {
-        return 0;
-    }
     if (fdap->fd_magic != fcb->f_magic) {
         return FCB_ERR_MAGIC;
     }
diff --git a/fs/fcb/src/fcb_elem_info.c b/fs/fcb/src/fcb_elem_info.c
index 2fc5ef2df8..ad1c4e1a80 100644
--- a/fs/fcb/src/fcb_elem_info.c
+++ b/fs/fcb/src/fcb_elem_info.c
@@ -41,15 +41,15 @@ fcb_elem_crc8(struct fcb *fcb, struct fcb_entry *loc, uint8_t *c8p)
     if (loc->fe_elem_off + 2 > loc->fe_area->fa_size) {
         return FCB_ERR_NOVAR;
     }
+    if (flash_area_isempty_at(loc->fe_area, loc->fe_elem_off, 2)) {
+        return FCB_ERR_NOVAR;
+    }
     rc = flash_area_read(loc->fe_area, loc->fe_elem_off, tmp_str, 2);
     if (rc) {
         return FCB_ERR_FLASH;
     }
 
     cnt = fcb_get_len(tmp_str, &len);
-    if (cnt < 0) {
-        return cnt;
-    }
     loc->fe_data_off = loc->fe_elem_off + fcb_len_in_flash(fcb, cnt);
     loc->fe_data_len = len;
 
diff --git a/hw/bsp/native/pkg.yml b/hw/bsp/native/pkg.yml
index abef00e080..71fdd60606 100644
--- a/hw/bsp/native/pkg.yml
+++ b/hw/bsp/native/pkg.yml
@@ -29,6 +29,7 @@ pkg.keywords:
 pkg.deps:
     - "@apache-mynewt-core/hw/mcu/native"
     - "@apache-mynewt-core/hw/drivers/uart/uart_hal"
+    - "@apache-mynewt-core/hw/drivers/flash/enc_flash/ef_tinycrypt"
     - "@apache-mynewt-core/net/ip/native_sockets"
 
 pkg.deps.BLE_DEVICE:
diff --git a/hw/bsp/native/src/hal_bsp.c b/hw/bsp/native/src/hal_bsp.c
index 84fc69c391..d7ef3b24d2 100644
--- a/hw/bsp/native/src/hal_bsp.c
+++ b/hw/bsp/native/src/hal_bsp.c
@@ -30,6 +30,7 @@
 #include "mcu/native_bsp.h"
 #include "mcu/mcu_hal.h"
 #include "hal/hal_i2c.h"
+#include "ef_tinycrypt/ef_tinycrypt.h"
 
 #if MYNEWT_VAL(SIM_ACCEL_PRESENT)
 #include "sim/sim_accel.h"
@@ -39,16 +40,26 @@ static struct sim_accel os_bsp_accel0;
 static struct uart_dev os_bsp_uart0;
 static struct uart_dev os_bsp_uart1;
 
+static struct eflash_tinycrypt_dev ef_dev0 = {
+    .etd_dev = {
+        .efd_hal = {
+            .hf_itf = &enc_flash_funcs,
+        },
+        .efd_hwdev = &native_flash_dev
+    }
+};
+
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
-    /*
-     * Just one to start with
-     */
-    if (id != 0) {
+    switch (id) {
+    case 0:
+        return &native_flash_dev;
+    case 1:
+        return &ef_dev0.etd_dev.efd_hal;
+    default:
         return NULL;
     }
-    return &native_flash_dev;
 }
 
 int
diff --git a/hw/bsp/nrf52dk/pkg.yml b/hw/bsp/nrf52dk/pkg.yml
index 3f19f9478d..a011d409cb 100644
--- a/hw/bsp/nrf52dk/pkg.yml
+++ b/hw/bsp/nrf52dk/pkg.yml
@@ -36,6 +36,9 @@ pkg.deps:
     - "@apache-mynewt-core/hw/mcu/nordic/nrf52xxx"
     - "@apache-mynewt-core/libc/baselibc"
 
+pkg.deps.ENC_FLASH_DEV:
+    - "@apache-mynewt-core/hw/drivers/flash/enc_flash/ef_nrf5x"
+
 pkg.deps.BLE_DEVICE:
     - "@apache-mynewt-core/hw/drivers/nimble/nrf52"
 
diff --git a/hw/bsp/nrf52dk/src/hal_bsp.c b/hw/bsp/nrf52dk/src/hal_bsp.c
index b9053ece73..4a4663efd8 100644
--- a/hw/bsp/nrf52dk/src/hal_bsp.c
+++ b/hw/bsp/nrf52dk/src/hal_bsp.c
@@ -50,6 +50,9 @@
 #if MYNEWT_VAL(SOFT_PWM)
 #include <soft_pwm/soft_pwm.h>
 #endif
+#if MYNEWT_VAL(ENC_FLASH_DEV)
+#include <ef_nrf5x/ef_nrf5x.h>
+#endif
 
 #if MYNEWT_VAL(UART_0)
 static struct uart_dev os_bsp_uart0;
@@ -134,16 +137,33 @@ static const struct hal_bsp_mem_dump dump_cfg[] = {
     }
 };
 
+#if MYNEWT_VAL(ENC_FLASH_DEV)
+struct eflash_nrf5x_dev enc_flash_dev0 = {
+    .end_dev = {
+        .efd_hal = {
+            .hf_itf = &enc_flash_funcs,
+        },
+        .efd_hwdev = &nrf52k_flash_dev
+    }
+};
+
+#endif
+
 const struct hal_flash *
 hal_bsp_flash_dev(uint8_t id)
 {
     /*
      * Internal flash mapped to id 0.
      */
-    if (id != 0) {
-        return NULL;
+    if (id == 0) {
+        return &nrf52k_flash_dev;
     }
-    return &nrf52k_flash_dev;
+#if MYNEWT_VAL(ENC_FLASH_DEV)
+    if (id == 1) {
+        return &enc_flash_dev0.end_dev.efd_hal;
+    }
+#endif
+    return NULL;
 }
 
 const struct hal_bsp_mem_dump *
diff --git a/hw/bsp/nrf52dk/syscfg.yml b/hw/bsp/nrf52dk/syscfg.yml
index aa59f37c08..2822a71ed6 100644
--- a/hw/bsp/nrf52dk/syscfg.yml
+++ b/hw/bsp/nrf52dk/syscfg.yml
@@ -100,6 +100,9 @@ syscfg.defs:
     TIMER_5:
         description: 'NRF52 RTC 0'
         value:  0
+    ENC_FLASH_DEV:
+        description: 'Encrypting flash driver over interal flash for testing'
+        value: 0
 
 syscfg.defs.BLE_LP_CLOCK:
     TIMER_0:
diff --git a/hw/drivers/flash/enc_flash/ef_nrf5x/include/ef_nrf5x/ef_nrf5x.h b/hw/drivers/flash/enc_flash/ef_nrf5x/include/ef_nrf5x/ef_nrf5x.h
new file mode 100644
index 0000000000..e3dac6507a
--- /dev/null
+++ b/hw/drivers/flash/enc_flash/ef_nrf5x/include/ef_nrf5x/ef_nrf5x.h
@@ -0,0 +1,53 @@
+/*
+ * 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_NRF5X_H__
+#define __EF_NRF5X_H__
+
+/*
+ * Encrypting flash driver for nrf51/nrf52
+ */
+#include <enc_flash/enc_flash.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Structure used by ECB of nrf52 (and nrf51).
+ */
+struct eflash_nrf5x_ecb {
+    uint8_t ene_key[ENC_FLASH_BLK];
+    uint8_t ene_plain[ENC_FLASH_BLK];
+    uint8_t ene_cipher[ENC_FLASH_BLK];
+};
+
+/*
+ * NRF51/52 specific version of the flash device.
+ */
+struct eflash_nrf5x_dev {
+    struct enc_flash_dev end_dev;
+    struct eflash_nrf5x_ecb end_ecb;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ENC_FLASH_NRF5X_H__ */
diff --git a/hw/drivers/flash/enc_flash/ef_nrf5x/pkg.yml b/hw/drivers/flash/enc_flash/ef_nrf5x/pkg.yml
new file mode 100644
index 0000000000..e54fa497d0
--- /dev/null
+++ b/hw/drivers/flash/enc_flash/ef_nrf5x/pkg.yml
@@ -0,0 +1,32 @@
+#
+# 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_nrf5x
+pkg.description: Encrypting flash driver for nrf52/nrf51.
+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/mcu/nordic"
+
diff --git a/hw/drivers/flash/enc_flash/ef_nrf5x/src/ef_nrf5x.c b/hw/drivers/flash/enc_flash/ef_nrf5x/src/ef_nrf5x.c
new file mode 100644
index 0000000000..0d5f775ecc
--- /dev/null
+++ b/hw/drivers/flash/enc_flash/ef_nrf5x/src/ef_nrf5x.c
@@ -0,0 +1,112 @@
+/*
+ * 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/cortex_m4.h>
+
+#if MYNEWT_VAL(BSP_NRF52)
+#include <mcu/nrf52_hal.h>
+#elif MYNEWT_VAL(BSP_NRF51)
+#include <mcu/nrf51_hal.h>
+#else
+#error "Unsupported arch"
+#endif
+
+#include <enc_flash/enc_flash.h>
+#include "ef_nrf5x/ef_nrf5x.h"
+
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
+#error "At the moment CCM/ECB use cannot coexist"
+#endif
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
+#error "At the moment AAR/ECB use cannot coexist"
+#endif
+
+#define EDEV_TO_NRF5X(dev) (struct eflash_nrf5x_dev *)(dev)
+#define ENC_FLASH_NONCE "mynewtencfla"
+
+static uint8_t *
+nrf5x_get_block(struct eflash_nrf5x_dev *dev, uint32_t addr)
+{
+    uint8_t *rblk = NULL;
+    int ctr = 0x100000;
+
+    memcpy(dev->end_ecb.ene_plain + 12, &addr, sizeof(addr));
+
+    NRF_ECB->ECBDATAPTR = (uint32_t)&dev->end_ecb;
+    NRF_ECB->TASKS_STARTECB = 1;
+    while (ctr-- > 0) {
+        if (NRF_ECB->EVENTS_ENDECB) {
+            rblk = dev->end_ecb.ene_cipher;
+            goto out;
+        }
+        if (NRF_ECB->EVENTS_ERRORECB) {
+            NRF_ECB->TASKS_STOPECB = 1;
+            /* XXX maybe sleep and retry? maybe use SW instead? */
+            break;
+        }
+    }
+    if (ctr == 0) {
+        NRF_ECB->TASKS_STOPECB = 1;
+    }
+out:
+    NRF_ECB->EVENTS_ENDECB = 0;
+    NRF_ECB->EVENTS_ERRORECB = 0;
+    return rblk;
+}
+
+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_nrf5x_dev *dev = EDEV_TO_NRF5X(edev);
+    int sr;
+    uint8_t *blk;
+    int i;
+
+    __HAL_DISABLE_INTERRUPTS(sr);
+    blk = nrf5x_get_block(dev, blk_addr);
+    blk += off;
+    for (i = 0 ; i < cnt; i++) {
+        *tgt++ = *blk++ ^ *src++;
+    }
+    __HAL_ENABLE_INTERRUPTS(sr);
+}
+
+void
+enc_flash_setkey_arch(struct enc_flash_dev *edev, uint8_t *key)
+{
+    struct eflash_nrf5x_dev *dev = EDEV_TO_NRF5X(edev);
+
+    memcpy(dev->end_ecb.ene_key, key, ENC_FLASH_BLK);
+}
+
+int
+enc_flash_init_arch(const struct enc_flash_dev *edev)
+{
+    struct eflash_nrf5x_dev *dev = EDEV_TO_NRF5X(edev);
+
+    memcpy(dev->end_ecb.ene_plain, ENC_FLASH_NONCE, 12);
+
+    return 0;
+}
diff --git a/hw/drivers/flash/enc_flash/ef_tinycrypt/include/ef_tinycrypt/ef_tinycrypt.h b/hw/drivers/flash/enc_flash/ef_tinycrypt/include/ef_tinycrypt/ef_tinycrypt.h
new file mode 100644
index 0000000000..9e75694d30
--- /dev/null
+++ b/hw/drivers/flash/enc_flash/ef_tinycrypt/include/ef_tinycrypt/ef_tinycrypt.h
@@ -0,0 +1,44 @@
+/*
+ * 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_TINYCRYPT_H__
+#define __EF_TINYCRYPT_H__
+
+/*
+ * Encrypting flash driver using AES from Tinycrypt
+ */
+#include <enc_flash/enc_flash.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Tinycrypt specific version of the flash device.
+ */
+struct eflash_tinycrypt_dev {
+    struct enc_flash_dev etd_dev;
+    uint8_t etd_key[ENC_FLASH_BLK];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ENC_FLASH_TINYCRYPT_H__ */
diff --git a/hw/drivers/flash/enc_flash/ef_tinycrypt/pkg.yml b/hw/drivers/flash/enc_flash/ef_tinycrypt/pkg.yml
new file mode 100644
index 0000000000..5d0f5c16e1
--- /dev/null
+++ b/hw/drivers/flash/enc_flash/ef_tinycrypt/pkg.yml
@@ -0,0 +1,32 @@
+#
+# 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_tinycrypt
+pkg.description: Encrypting flash driver using Tincrypt AES.
+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/crypto/tinycrypt"
+
diff --git a/hw/drivers/flash/enc_flash/ef_tinycrypt/src/ef_tinycrypt.c b/hw/drivers/flash/enc_flash/ef_tinycrypt/src/ef_tinycrypt.c
new file mode 100644
index 0000000000..6a072ae044
--- /dev/null
+++ b/hw/drivers/flash/enc_flash/ef_tinycrypt/src/ef_tinycrypt.c
@@ -0,0 +1,73 @@
+/*
+ * 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 <tinycrypt/aes.h>
+
+#include <enc_flash/enc_flash.h>
+#include "ef_tinycrypt/ef_tinycrypt.h"
+
+#define EDEV_TO_TC(dev) (struct eflash_tinycrypt_dev *)(edev)
+#define ENC_FLASH_NONCE "mynewtencfla"
+
+static void
+ef_tc_get_block(struct eflash_tinycrypt_dev *dev, uint32_t addr, uint8_t *blk)
+{
+    struct tc_aes_key_sched_struct ctx;
+
+    memcpy(blk, ENC_FLASH_NONCE, 12);
+    memcpy(blk + 12, &addr, sizeof(addr));
+
+    tc_aes128_set_encrypt_key(&ctx, dev->etd_key);
+    tc_aes_encrypt(blk, blk, &ctx);
+}
+
+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_tinycrypt_dev *dev = EDEV_TO_TC(edev);
+    uint8_t blk[ENC_FLASH_BLK];
+    uint8_t *b;
+    int i;
+
+    ef_tc_get_block(dev, blk_addr, blk);
+    b = &blk[off];
+    for (i = 0 ; i < cnt; i++) {
+        *tgt++ = *b++ ^ *src++;
+    }
+}
+
+void
+enc_flash_setkey_arch(struct enc_flash_dev *edev, uint8_t *key)
+{
+    struct eflash_tinycrypt_dev *dev = EDEV_TO_TC(edev);
+
+    memcpy(dev->etd_key, key, ENC_FLASH_BLK);
+}
+
+int
+enc_flash_init_arch(const struct enc_flash_dev *edev)
+{
+    return 0;
+}
diff --git a/hw/drivers/flash/enc_flash/include/enc_flash/enc_flash.h b/hw/drivers/flash/enc_flash/include/enc_flash/enc_flash.h
new file mode 100644
index 0000000000..11e5f72476
--- /dev/null
+++ b/hw/drivers/flash/enc_flash/include/enc_flash/enc_flash.h
@@ -0,0 +1,44 @@
+/*
+ * 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 __ENC_FLASH_H__
+#define __ENC_FLASH_H__
+
+#include <hal/hal_flash_int.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ENC_FLASH_BLK  16 /* AES128 */
+
+struct enc_flash_dev {
+    struct hal_flash efd_hal;
+    const struct hal_flash *efd_hwdev; /* pointer to underlying hw dev */
+};
+
+extern const struct hal_flash_funcs enc_flash_funcs;
+
+void enc_flash_setkey(struct hal_flash *dev, uint8_t *key);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ENC_FLASH_H__ */
diff --git a/hw/drivers/flash/enc_flash/include/enc_flash/enc_flash_int.h b/hw/drivers/flash/enc_flash/include/enc_flash/enc_flash_int.h
new file mode 100644
index 0000000000..e2d8b98a77
--- /dev/null
+++ b/hw/drivers/flash/enc_flash/include/enc_flash/enc_flash_int.h
@@ -0,0 +1,38 @@
+/*
+ * 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 __ENC_FLASH_INT_H_
+#define __ENC_FLASH_INT_H_
+
+/**
+ * Platform specific driver init.
+ */
+int enc_flash_init_arch(struct enc_flash_dev *edev);
+
+/**
+ * Platform specific key setup.
+ */
+void enc_flash_setkey_arch(struct enc_flash_dev *edev, uint8_t *key);
+
+/*
+ * Platform specific encrypt/decrypt function.
+ */
+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);
+
+#endif
diff --git a/hw/drivers/flash/enc_flash/pkg.yml b/hw/drivers/flash/enc_flash/pkg.yml
new file mode 100644
index 0000000000..60dfd3d871
--- /dev/null
+++ b/hw/drivers/flash/enc_flash/pkg.yml
@@ -0,0 +1,31 @@
+#
+# 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
+pkg.description: Pseudo device providing encryption of data stored in flash.
+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/hal"
+
diff --git a/hw/drivers/flash/enc_flash/src/enc_flash.c b/hw/drivers/flash/enc_flash/src/enc_flash.c
new file mode 100644
index 0000000000..02e4a6f7cd
--- /dev/null
+++ b/hw/drivers/flash/enc_flash/src/enc_flash.c
@@ -0,0 +1,190 @@
+/*
+ * 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 "enc_flash/enc_flash.h"
+#include "enc_flash/enc_flash_int.h"
+
+#define HAL_TO_ENC(dev) (struct enc_flash_dev *)(dev)
+
+static int enc_flash_read(const struct hal_flash *h_dev, uint32_t addr,
+                          void *buf, uint32_t len);
+static int enc_flash_write(const struct hal_flash *h_dev, uint32_t addr,
+                           const void *buf, uint32_t len);
+static int enc_flash_erase_sector(const struct hal_flash *h_dev,
+                                  uint32_t addr);
+static int enc_flash_sector_info(const struct hal_flash *h_dev, int idx,
+                                 uint32_t *addr, uint32_t *sz);
+static int enc_flash_is_empty(const struct hal_flash *h_dev, uint32_t addr,
+                              uint32_t len);
+static int enc_flash_init(const struct hal_flash *h_dev);
+
+const struct hal_flash_funcs enc_flash_funcs = {
+    .hff_read         = enc_flash_read,
+    .hff_write        = enc_flash_write,
+    .hff_erase_sector = enc_flash_erase_sector,
+    .hff_sector_info  = enc_flash_sector_info,
+    .hff_is_empty     = enc_flash_is_empty,
+    .hff_init         = enc_flash_init,
+};
+
+/*
+ * Read first all the data in to provided memory area, then apply the
+ * cipher -> text conversion.
+ */
+static int
+enc_flash_read(const struct hal_flash *h_dev, uint32_t addr, void *buf,
+               uint32_t len)
+{
+    struct enc_flash_dev *dev = HAL_TO_ENC(h_dev);
+    uint8_t *bufb = buf;
+    int i;
+    int blk_end;
+    int rc = 0;
+
+    h_dev = dev->efd_hwdev;
+
+    rc = h_dev->hf_itf->hff_read(h_dev, addr, buf, len);
+    if (rc) {
+        return rc;
+    }
+    i = addr & (ENC_FLASH_BLK - 1);
+    addr &= ~(ENC_FLASH_BLK - 1);
+    blk_end = ENC_FLASH_BLK;
+    if (blk_end > i + len) {
+        blk_end = i + len;
+    }
+    while (1) {
+        enc_flash_crypt_arch(dev, addr, bufb, bufb, i, blk_end - i);
+        len -= (blk_end - i);
+        bufb += (blk_end - i);
+        if (len == 0) {
+            break;
+        }
+        i = 0;
+        addr += ENC_FLASH_BLK;
+        blk_end = ENC_FLASH_BLK;
+        if (blk_end > len) {
+            blk_end = len;
+        }
+    }
+    return rc;
+}
+
+static int
+enc_flash_write(const struct hal_flash *h_dev, uint32_t addr,
+                const void *buf, uint32_t len)
+{
+    struct enc_flash_dev *dev = HAL_TO_ENC(h_dev);
+    const uint8_t *bufb = buf;
+    int i;
+    int blksz;
+    int rc = 0;
+    uint8_t ctext[ENC_FLASH_BLK];
+
+    h_dev = dev->efd_hwdev;
+
+    i = addr & (ENC_FLASH_BLK - 1);
+    blksz = ENC_FLASH_BLK - i;
+    if (blksz > len) {
+        blksz = len;
+    }
+    while (1) {
+        enc_flash_crypt_arch(dev, addr & ~(ENC_FLASH_BLK - 1), bufb, ctext,
+                             i, blksz);
+        len -= blksz;
+        bufb += blksz;
+        rc = h_dev->hf_itf->hff_write(h_dev, addr, ctext, blksz);
+        if (rc) {
+            return rc;
+        }
+        if (len == 0) {
+            break;
+        }
+        i = 0;
+        addr += blksz;
+        blksz = ENC_FLASH_BLK;
+        if (blksz > len) {
+            blksz = len;
+        }
+    }
+    return rc;
+}
+
+static int
+enc_flash_erase_sector(const struct hal_flash *h_dev, uint32_t addr)
+{
+    struct enc_flash_dev *dev = HAL_TO_ENC(h_dev);
+
+    h_dev = dev->efd_hwdev;
+
+    return h_dev->hf_itf->hff_erase_sector(h_dev, addr);
+}
+
+static int
+enc_flash_sector_info(const struct hal_flash *h_dev, int idx,
+                      uint32_t *addr, uint32_t *sz)
+{
+    struct enc_flash_dev *dev = HAL_TO_ENC(h_dev);
+
+    h_dev = dev->efd_hwdev;
+
+    return h_dev->hf_itf->hff_sector_info(h_dev, idx, addr, sz);
+}
+
+static int
+enc_flash_is_empty(const struct hal_flash *h_dev, uint32_t addr, uint32_t len)
+{
+    struct enc_flash_dev *dev = HAL_TO_ENC(h_dev);
+
+    h_dev = dev->efd_hwdev;
+
+    if (h_dev->hf_itf->hff_is_empty) {
+        return h_dev->hf_itf->hff_is_empty(h_dev, addr, len);
+    } else {
+        return hal_flash_is_ones(h_dev, addr, len);
+    }
+}
+
+void
+enc_flash_setkey(struct hal_flash *h_dev, uint8_t *key)
+{
+    enc_flash_setkey_arch(HAL_TO_ENC(h_dev), key);
+}
+
+static int
+enc_flash_init(const struct hal_flash *h_dev)
+{
+    struct enc_flash_dev *dev = HAL_TO_ENC(h_dev);
+
+    h_dev = dev->efd_hwdev;
+
+    dev->efd_hal.hf_base_addr = h_dev->hf_base_addr;
+    dev->efd_hal.hf_size =  h_dev->hf_size;
+    dev->efd_hal.hf_sector_cnt = h_dev->hf_sector_cnt;
+    dev->efd_hal.hf_align = h_dev->hf_align;
+
+    enc_flash_init_arch(dev);
+
+    return 0;
+}
diff --git a/hw/hal/include/hal/hal_flash.h b/hw/hal/include/hal/hal_flash.h
index ccef6e2722..7230225026 100644
--- a/hw/hal/include/hal/hal_flash.h
+++ b/hw/hal/include/hal/hal_flash.h
@@ -40,6 +40,7 @@ int hal_flash_write(uint8_t flash_id, uint32_t address, const void *src,
   uint32_t num_bytes);
 int hal_flash_erase_sector(uint8_t flash_id, uint32_t sector_address);
 int hal_flash_erase(uint8_t flash_id, uint32_t address, uint32_t num_bytes);
+int hal_flash_isempty(uint8_t flash_id, uint32_t address, uint32_t num_bytes);
 uint8_t hal_flash_align(uint8_t flash_id);
 int hal_flash_init(void);
 
diff --git a/hw/hal/include/hal/hal_flash_int.h b/hw/hal/include/hal/hal_flash_int.h
index d424bb17d9..bc8fdb320c 100644
--- a/hw/hal/include/hal/hal_flash_int.h
+++ b/hw/hal/include/hal/hal_flash_int.h
@@ -40,6 +40,8 @@ struct hal_flash_funcs {
             uint32_t sector_address);
     int (*hff_sector_info)(const struct hal_flash *dev, int idx,
             uint32_t *address, uint32_t *size);
+    int (*hff_is_empty)(const struct hal_flash *dev, uint32_t address,
+            uint32_t num_bytes);
     int (*hff_init)(const struct hal_flash *dev);
 };
 
@@ -56,6 +58,11 @@ struct hal_flash {
  */
 uint32_t hal_flash_sector_size(const struct hal_flash *hf, int sec_idx);
 
+/*
+ * Use as hal_flash_funcs.hff_is_empty if flash is erased to zeroes.
+ */
+int hal_flash_is_zeroes(const struct hal_flash *, uint32_t, uint32_t);
+int hal_flash_is_ones(const struct hal_flash *, uint32_t, uint32_t);
 
 #ifdef __cplusplus
 }
diff --git a/hw/hal/pkg.yml b/hw/hal/pkg.yml
index 524e77b60b..1bec4e017b 100644
--- a/hw/hal/pkg.yml
+++ b/hw/hal/pkg.yml
@@ -24,4 +24,4 @@ pkg.homepage: "http://mynewt.apache.org/"
 pkg.keywords:
 
 pkg.deps:
-    - kernel/os
+    - "@apache-mynewt-core/kernel/os"
diff --git a/hw/hal/src/hal_flash.c b/hw/hal/src/hal_flash.c
index 8e6a61c581..d0811c5a26 100644
--- a/hw/hal/src/hal_flash.c
+++ b/hw/hal/src/hal_flash.c
@@ -6,7 +6,7 @@
  * 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,
@@ -298,6 +298,66 @@ hal_flash_erase(uint8_t id, uint32_t address, uint32_t num_bytes)
     return 0;
 }
 
+static int
+hal_flash_is_setto(const struct hal_flash *hf, uint32_t address,
+                   uint32_t num_bytes, uint8_t val)
+{
+    uint8_t buf[32];
+    uint32_t blksz;
+    int i;
+
+    while (num_bytes) {
+        blksz = sizeof(buf);
+        if (blksz > num_bytes) {
+            blksz = num_bytes;
+        }
+        if (hf->hf_itf->hff_read(hf, address, buf, blksz)) {
+            return -1;
+        }
+        for (i = 0; i < blksz; i++) {
+            if (buf[i] != val) {
+                return 0;
+            }
+        }
+        num_bytes -= blksz;
+    }
+    return 1;
+}
+
+int
+hal_flash_is_ones(const struct hal_flash *hf, uint32_t address,
+                   uint32_t num_bytes)
+{
+    return hal_flash_is_setto(hf, address, num_bytes, 0xff);
+}
+
+int
+hal_flash_is_zeroes(const struct hal_flash *hf, uint32_t address,
+                   uint32_t num_bytes)
+{
+    return hal_flash_is_setto(hf, address, num_bytes, 0);
+}
+
+int
+hal_flash_isempty(uint8_t id, uint32_t address, uint32_t num_bytes)
+{
+    const struct hal_flash *hf;
+
+    hf = hal_bsp_flash_dev(id);
+    if (!hf) {
+        return -1;
+    }
+    if (hal_flash_check_addr(hf, address) ||
+      hal_flash_check_addr(hf, address + num_bytes)) {
+        return -1;
+    }
+    if (hf->hf_itf->hff_is_empty) {
+        return hf->hf_itf->hff_is_empty(hf, address, num_bytes);
+    } else {
+        return hal_flash_is_ones(hf, address, num_bytes);
+    }
+}
+
 int
 hal_flash_ioctl(uint8_t id, uint32_t cmd, void *args)
 {
diff --git a/sys/flash_map/include/flash_map/flash_map.h b/sys/flash_map/include/flash_map/flash_map.h
index 146d5355a5..a5be399498 100644
--- a/sys/flash_map/include/flash_map/flash_map.h
+++ b/sys/flash_map/include/flash_map/flash_map.h
@@ -76,8 +76,18 @@ int flash_area_read(const struct flash_area *, uint32_t off, void *dst,
 int flash_area_write(const struct flash_area *, uint32_t off, const void *src,
   uint32_t len);
 int flash_area_erase(const struct flash_area *, uint32_t off, uint32_t len);
+
+/*
+ * Whether the whole area is empty.
+ */
 int flash_area_is_empty(const struct flash_area *, bool *);
 
+/*
+ * Whether a region of flash_area is empty
+ */
+int flash_area_isempty_at(const struct flash_area *, uint32_t off,
+  uint32_t len);
+
 /*
  * Alignment restriction for flash writes.
  */
diff --git a/sys/flash_map/src/flash_map.c b/sys/flash_map/src/flash_map.c
index cea44d97d2..0637e4476c 100644
--- a/sys/flash_map/src/flash_map.c
+++ b/sys/flash_map/src/flash_map.c
@@ -182,32 +182,25 @@ flash_area_align(const struct flash_area *fa)
 int
 flash_area_is_empty(const struct flash_area *fa, bool *empty)
 {
-    uint32_t data[64 >> 2];
-    uint32_t data_off = 0;
-    int8_t bytes_to_read;
-    uint8_t i;
     int rc;
 
-    while (data_off < fa->fa_size) {
-        bytes_to_read = min(64, fa->fa_size - data_off);
-        rc = flash_area_read(fa, data_off, data, bytes_to_read);
-        if (rc) {
-            return rc;
-        }
-        for (i = 0; i < bytes_to_read >> 2; i++) {
-          if (data[i] != (uint32_t) -1) {
-            goto not_empty;
-          }
-        }
-        data_off += bytes_to_read;
+    rc = hal_flash_isempty(fa->fa_device_id, fa->fa_off, fa->fa_size);
+    if (rc < 0) {
+        return rc;
+    } else if (rc == 1) {
+        *empty = true;
+    } else {
+        *empty = false;
     }
-    *empty = true;
-    return 0;
-not_empty:
-    *empty = false;
     return 0;
 }
 
+int
+flash_area_isempty_at(const struct flash_area *fa, uint32_t off, uint32_t len)
+{
+    return hal_flash_isempty(fa->fa_device_id, fa->fa_off + off, len);
+}
+
 /**
  * Converts the specified image slot index to a flash area ID.  If the
  * specified value is not a valid image slot index (0 or 1), a crash is


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services