Merge pull request #44 from utzig/create-doc

Move design doc to doc dir
diff --git a/Makefile b/Makefile
index 410ed4b..a0c7587 100644
--- a/Makefile
+++ b/Makefile
@@ -10,11 +10,11 @@
 
 # RSA
 CONF_FILE = boot/zephyr/prj.conf
-CFLAGS += -DBOOTUTIL_SIGN_RSA
+CFLAGS += -DBOOTUTIL_SIGN_RSA -DBOOTUTIL_USE_MBED_TLS
 
 # ECDSA P-256
 #CONF_FILE = boot/zephyr/prj-p256.conf
-#CFLAGS += -DBOOTUTIL_SIGN_EC256
+#CFLAGS += -DBOOTUTIL_SIGN_EC256 -DBOOTUTIL_USE_TINYCRYPT
 
 # Enable this option to have the bootloader verify the signature of
 # the primary image upon every boot.  Without it, signature
diff --git a/boot/bootutil/include/bootutil/sha256.h b/boot/bootutil/include/bootutil/sha256.h
new file mode 100644
index 0000000..9bc366c
--- /dev/null
+++ b/boot/bootutil/include/bootutil/sha256.h
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+/*
+ * This module provides a thin abstraction over some of the crypto
+ * primitives to make it easier to swap out the used crypto library.
+ *
+ * At this point, there are two choices: BOOTUTIL_USE_MBED_TLS, or
+ * BOOTUTIL_USE_TINYCRYPT.  It is a compile error there is not exactly
+ * one of these defined.
+ */
+
+#ifndef __BOOTUTIL_CRYPTO_H_
+#define __BOOTUTIL_CRYPTO_H_
+
+#if defined(BOOTUTIL_USE_MBED_TLS) && defined(BOOTUTIL_USE_TINYCRYPT)
+    #error "Cannot define both MBED_TLS and TINYCRYPT"
+#endif
+
+#if !defined(BOOTUTIL_USE_MBED_TLS) && !defined(BOOTUTIL_USE_TINYCRYPT)
+    #error "One of MBED_TLS or TINYCRYPT must be defined"
+#endif
+
+#ifdef BOOTUTIL_USE_MBED_TLS
+    #include <mbedtls/sha256.h>
+#endif /* BOOTUTIL_USE_MBED_TLS */
+
+#ifdef BOOTUTIL_USE_TINYCRYPT
+    #include <tinycrypt/sha256.h>
+#endif /* BOOTUTIL_USE_TINYCRYPT */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef BOOTUTIL_USE_MBED_TLS
+typedef mbedtls_sha256_context bootutil_sha256_context;
+
+static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
+{
+    mbedtls_sha256_init(ctx);
+    mbedtls_sha256_starts(ctx, 0);
+}
+
+static inline void bootutil_sha256_update(bootutil_sha256_context *ctx,
+                                          const void *data,
+                                          uint32_t data_len)
+{
+    mbedtls_sha256_update(ctx, data, data_len);
+}
+
+static inline void bootutil_sha256_finish(bootutil_sha256_context *ctx,
+                                          uint8_t *output)
+{
+    mbedtls_sha256_finish(ctx, output);
+}
+#endif /* BOOTUTIL_USE_MBED_TLS */
+
+#ifdef BOOTUTIL_USE_TINYCRYPT
+typedef struct tc_sha256_state_struct bootutil_sha256_context;
+static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
+{
+    tc_sha256_init(ctx);
+}
+
+static inline void bootutil_sha256_update(bootutil_sha256_context *ctx,
+                                          const void *data,
+                                          uint32_t data_len)
+{
+    tc_sha256_update(ctx, data, data_len);
+}
+
+static inline void bootutil_sha256_finish(bootutil_sha256_context *ctx,
+                                          uint8_t *output)
+{
+    tc_sha256_final(output, ctx);
+}
+#endif /* BOOTUTIL_USE_TINYCRYPT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOOTUTIL_SIGN_KEY_H_ */
diff --git a/boot/bootutil/src/Makefile b/boot/bootutil/src/Makefile
index 2ee4452..8a69d87 100644
--- a/boot/bootutil/src/Makefile
+++ b/boot/bootutil/src/Makefile
@@ -1,3 +1,5 @@
 # Makefile for Zephyr build
 
+include $(ZEPHYR_BASE)/ext/lib/crypto/mbedtls/Makefile.include
+
 obj-y += loader.o bootutil_misc.o image_validate.o image_rsa.o image_ec256.o
diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c
index 9ab08b7..0e78407 100644
--- a/boot/bootutil/src/image_validate.c
+++ b/boot/bootutil/src/image_validate.c
@@ -26,11 +26,15 @@
 #include "hal/hal_flash.h"
 #include "flash_map/flash_map.h"
 #include "bootutil/image.h"
+#include "bootutil/sha256.h"
 #include "bootutil/sign_key.h"
 
-#include "mbedtls/sha256.h"
+#if MYNEWT_VAL(BOOTUTIL_SIGN_RSA)
 #include "mbedtls/rsa.h"
+#endif
+#if MYNEWT_VAL(BOOTUTIL_SIGN_EC) || MYNEWT_VAL(BOOTUTIL_SIGN_EC256)
 #include "mbedtls/ecdsa.h"
+#endif
 #include "mbedtls/asn1.h"
 
 #include "bootutil_priv.h"
@@ -43,19 +47,18 @@
                   uint8_t *tmp_buf, uint32_t tmp_buf_sz,
                   uint8_t *hash_result, uint8_t *seed, int seed_len)
 {
-    mbedtls_sha256_context sha256_ctx;
+    bootutil_sha256_context sha256_ctx;
     uint32_t blk_sz;
     uint32_t size;
     uint32_t off;
     int rc;
 
-    mbedtls_sha256_init(&sha256_ctx);
-    mbedtls_sha256_starts(&sha256_ctx, 0);
+    bootutil_sha256_init(&sha256_ctx);
 
     /* in some cases (split image) the hash is seeded with data from
      * the loader image */
     if(seed && (seed_len > 0)) {
-        mbedtls_sha256_update(&sha256_ctx, seed, seed_len);
+        bootutil_sha256_update(&sha256_ctx, seed, seed_len);
     }
 
     size = hdr->ih_img_size + hdr->ih_hdr_size;
@@ -74,9 +77,9 @@
         if (rc) {
             return rc;
         }
-        mbedtls_sha256_update(&sha256_ctx, tmp_buf, blk_sz);
+        bootutil_sha256_update(&sha256_ctx, tmp_buf, blk_sz);
     }
-    mbedtls_sha256_finish(&sha256_ctx, hash_result);
+    bootutil_sha256_finish(&sha256_ctx, hash_result);
 
     return 0;
 }
diff --git a/boot/zephyr/include/config-asn1.h b/boot/zephyr/include/config-asn1.h
index ba5b97c..25d33fb 100644
--- a/boot/zephyr/include/config-asn1.h
+++ b/boot/zephyr/include/config-asn1.h
@@ -26,8 +26,8 @@
  * - RSA or ECDSA signature verification
  */
 
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
+#ifndef MBEDTLS_CONFIG_ASN1_H
+#define MBEDTLS_CONFIG_ASN1_H
 
 #define MBEDTLS_PLATFORM_C
 #define MBEDTLS_PLATFORM_MEMORY
@@ -40,8 +40,8 @@
 // #define MBEDTLS_BIGNUM_C
 // #define MBEDTLS_MD_C
 // #define MBEDTLS_OID_C
-#define MBEDTLS_SHA256_C
+// #define MBEDTLS_SHA256_C
 
 #include "mbedtls/check_config.h"
 
-#endif /* MBEDTLS_CONFIG_H */
+#endif /* MBEDTLS_CONFIG_ASN1_H */
diff --git a/boot/zephyr/include/config-boot.h b/boot/zephyr/include/config-boot.h
index 8639932..a81a02f 100644
--- a/boot/zephyr/include/config-boot.h
+++ b/boot/zephyr/include/config-boot.h
@@ -26,8 +26,8 @@
  * - RSA or ECDSA signature verification
  */
 
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
+#ifndef MBEDTLS_CONFIG_BOOT_H
+#define MBEDTLS_CONFIG_BOOT_H
 
 /* TODO: Configure this between app and target.  Really, we want the
  * config to come from the app. */
@@ -94,4 +94,4 @@
 
 #include "mbedtls/check_config.h"
 
-#endif /* MBEDTLS_CONFIG_H */
+#endif /* MBEDTLS_CONFIG_BOOT_H */
diff --git a/boot/zephyr/prj-p256.conf b/boot/zephyr/prj-p256.conf
index a3cf7c0..5bea3d0 100644
--- a/boot/zephyr/prj-p256.conf
+++ b/boot/zephyr/prj-p256.conf
@@ -9,6 +9,7 @@
 CONFIG_MBEDTLS_CFG_FILE="config-asn1.h"
 CONFIG_TINYCRYPT=y
 CONFIG_TINYCRYPT_ECC_DSA=y
+CONFIG_TINYCRYPT_SHA256=y
 
 ### mbedTLS wants a heap
 CONFIG_HEAP_MEM_POOL_SIZE=16384
diff --git a/boot/zephyr/targets/frdm_k64f.h b/boot/zephyr/targets/frdm_k64f.h
index cfec2b3..fabf08d 100644
--- a/boot/zephyr/targets/frdm_k64f.h
+++ b/boot/zephyr/targets/frdm_k64f.h
@@ -22,9 +22,9 @@
 #define FLASH_DRIVER_NAME		CONFIG_SOC_FLASH_MCUX_DEV_NAME
 #define FLASH_ALIGN			8
 #define FLASH_AREA_IMAGE_0_OFFSET	0x20000
-#define FLASH_AREA_IMAGE_0_SIZE		0x20000
-#define FLASH_AREA_IMAGE_1_OFFSET	0x40000
-#define FLASH_AREA_IMAGE_1_SIZE		0x20000
-#define FLASH_AREA_IMAGE_SCRATCH_OFFSET	0x60000
+#define FLASH_AREA_IMAGE_0_SIZE		0x60000
+#define FLASH_AREA_IMAGE_1_OFFSET	0x80000
+#define FLASH_AREA_IMAGE_1_SIZE		0x60000
+#define FLASH_AREA_IMAGE_SCRATCH_OFFSET	0xe0000
 #define FLASH_AREA_IMAGE_SCRATCH_SIZE	0x20000
 #define FLASH_AREA_IMAGE_SECTOR_SIZE	0x01000
diff --git a/project.yml b/project.yml
index 42f23aa..0dbda44 100644
--- a/project.yml
+++ b/project.yml
@@ -26,6 +26,6 @@
 # This provides mirroring automatically for us.
 repository.apache-mynewt-core:
     type: github
-    vers: 0-latest
+    vers: 0-dev
     user: apache
     repo: incubator-mynewt-core
diff --git a/sim/src/main.rs b/sim/src/main.rs
index d6117f7..de9e588 100644
--- a/sim/src/main.rs
+++ b/sim/src/main.rs
@@ -255,10 +255,14 @@
             failed = true;
         }
 
-        let (fl4, total_counts) = try_random_fails(&flash, &areadesc, 5);
-        info!("Random fails at counts={:?}", total_counts);
-        if !verify_image(&fl4, slot0_base, &upgrade) {
-            error!("Image mismatch after random fails");
+        let (fl4, total_counts) = try_random_fails(&flash, &areadesc, total_count, 5);
+        info!("Random fails at reset points={:?}", total_counts);
+        let slot0_ok = verify_image(&fl4, slot0_base, &upgrade);
+        let slot1_ok = verify_image(&fl4, slot1_base, &primary);
+        if !slot0_ok || !slot1_ok {
+            error!("Image mismatch after random fails: slot0={} slot1={}",
+                   if slot0_ok { "ok" } else { "fail" },
+                   if slot1_ok { "ok" } else { "fail" });
             self.failures += 1;
             return;
         }
@@ -306,6 +310,12 @@
     // Clone the flash to have a new copy.
     let mut fl = flash.clone();
 
+    // mark permanent upgrade
+    let ok = [1u8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
+    let (base, _) = areadesc.find(FlashId::ImageScratch);
+    let align = c::get_sim_flash_align() as usize;
+    fl.write(base - align, &ok[..align]).unwrap();
+
     c::set_flash_counter(stop.unwrap_or(0));
     let (first_interrupted, cnt1) = match c::boot_go(&mut fl, &areadesc) {
         -0x13579 => (true, stop.unwrap()),
@@ -354,28 +364,29 @@
     fl
 }
 
-fn try_random_fails(flash: &Flash, areadesc: &AreaDesc, count: usize) -> (Flash, Vec<i32>) {
-    // Clone the flash to have a new copy.
+fn try_random_fails(flash: &Flash, areadesc: &AreaDesc, total_ops: i32, 
+                    count: usize) -> (Flash, Vec<i32>) {
     let mut fl = flash.clone();
 
-    c::set_flash_counter(0);
-    let (_, total_ops) = match c::boot_go(&mut fl, &areadesc) {
-        -0x13579 => panic!("Should not be have been interrupted!"),
-        0 => (false, -c::get_flash_counter()),
-        x => panic!("Unknown return: {}", x),
-    };
+    // mark permanent upgrade
+    let ok = [1u8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
+    let (base, _) = areadesc.find(FlashId::ImageScratch);
+    let align = c::get_sim_flash_align() as usize;
+    fl.write(base - align, &ok[..align]).unwrap();
 
     let mut rng = rand::thread_rng();
-    let ops = Range::new(1, total_ops);
-    let mut stops = vec![0i32; count];
+    let mut resets = vec![0i32; count];
+    let mut remaining_ops = total_ops;
     for i in 0 .. count {
+        let ops = Range::new(1, remaining_ops / 2);
         let reset_counter = ops.ind_sample(&mut rng);
         c::set_flash_counter(reset_counter);
         match c::boot_go(&mut fl, &areadesc) {
             0 | -0x13579 => (),
             x => panic!("Unknown return: {}", x),
         }
-        stops[i] = reset_counter;
+        remaining_ops -= reset_counter;
+        resets[i] = reset_counter;
     }
 
     c::set_flash_counter(0);
@@ -385,7 +396,7 @@
         x => panic!("Unknown return: {}", x),
     }
 
-    (fl, stops)
+    (fl, resets)
 }
 
 /// Show the flash layout.