mynewt-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject [2/2] incubator-mynewt-core git commit: Support image signatures as ECDSA224.
Date Thu, 07 Apr 2016 01:37:06 GMT
Support image signatures as ECDSA224.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/855a6afe
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/855a6afe
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/855a6afe

Branch: refs/heads/develop
Commit: 855a6afe0b643dee6cc30fb1190f5e28d1e1b557
Parents: 03a60f6
Author: Marko Kiiskila <marko@runtime.io>
Authored: Wed Apr 6 18:32:55 2016 -0700
Committer: Marko Kiiskila <marko@runtime.io>
Committed: Wed Apr 6 18:34:47 2016 -0700

----------------------------------------------------------------------
 libs/bootutil/include/bootutil/image.h |   2 +
 libs/bootutil/pkg.yml                  |   3 +-
 libs/bootutil/src/bootutil_priv.h      |   3 +
 libs/bootutil/src/image_ec.c           | 118 ++++++++++++++++++
 libs/bootutil/src/image_rsa.c          | 141 +++++++++++++++++++++
 libs/bootutil/src/image_validate.c     | 186 ++++++----------------------
 6 files changed, 307 insertions(+), 146 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/855a6afe/libs/bootutil/include/bootutil/image.h
----------------------------------------------------------------------
diff --git a/libs/bootutil/include/bootutil/image.h b/libs/bootutil/include/bootutil/image.h
index e1b94bf..cf5ae34 100644
--- a/libs/bootutil/include/bootutil/image.h
+++ b/libs/bootutil/include/bootutil/image.h
@@ -31,6 +31,7 @@
 #define IMAGE_F_PIC                 0x00000001
 #define IMAGE_F_SHA256              0x00000002	/* Image contains hash TLV */
 #define IMAGE_F_PKCS15_RSA2048_SHA256   0x00000004 /* PKCS15 w/RSA and SHA */
+#define IMAGE_F_ECDSA224_SHA256     0x00000008  /* ECDSA256 over SHA256 */
 
 #define IMAGE_HEADER_SIZE           32
 
@@ -39,6 +40,7 @@
  */
 #define IMAGE_TLV_SHA256            1	/* SHA256 of image hdr and body */
 #define IMAGE_TLV_RSA2048           2	/* RSA2048 of hash output */
+#define IMAGE_TLV_ECDSA224          3   /* ECDSA of hash output */
 
 struct image_version {
     uint8_t iv_major;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/855a6afe/libs/bootutil/pkg.yml
----------------------------------------------------------------------
diff --git a/libs/bootutil/pkg.yml b/libs/bootutil/pkg.yml
index 2c334bc..c1bd59a 100644
--- a/libs/bootutil/pkg.yml
+++ b/libs/bootutil/pkg.yml
@@ -32,4 +32,5 @@ pkg.deps:
     - libs/mbedtls
     - hw/hal
 
-pkg.cflags.IMAGE_KEYS: -DIMAGE_SIGNATURES
+pkg.cflags.IMAGE_KEYS_RSA: -DIMAGE_SIGNATURES_RSA
+pkg.cflags.IMAGE_KEYS_EC: -DIMAGE_SIGNATURES_EC

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/855a6afe/libs/bootutil/src/bootutil_priv.h
----------------------------------------------------------------------
diff --git a/libs/bootutil/src/bootutil_priv.h b/libs/bootutil/src/bootutil_priv.h
index e9680c7..13e259e 100644
--- a/libs/bootutil/src/bootutil_priv.h
+++ b/libs/bootutil/src/bootutil_priv.h
@@ -71,5 +71,8 @@ int boot_write_status(const struct boot_status *status,
                       int num_areas);
 void boot_clear_status(void);
 
+int bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, int slen,
+    uint8_t key_id);
+
 #endif
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/855a6afe/libs/bootutil/src/image_ec.c
----------------------------------------------------------------------
diff --git a/libs/bootutil/src/image_ec.c b/libs/bootutil/src/image_ec.c
new file mode 100644
index 0000000..6b21ab2
--- /dev/null
+++ b/libs/bootutil/src/image_ec.c
@@ -0,0 +1,118 @@
+/**
+ * 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.
+ */
+#ifdef IMAGE_SIGNATURES_EC
+#include <bootutil/sign_key.h>
+
+#include <mbedtls/sha256.h>
+#include <mbedtls/ecdsa.h>
+#include <mbedtls/oid.h>
+#include <mbedtls/asn1.h>
+
+#include "bootutil_priv.h"
+
+/*
+ * Declaring these like this adds NULL termination.
+ */
+static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_EC_ALG_UNRESTRICTED;
+static const uint8_t ec_secp224r1_oid[] = MBEDTLS_OID_EC_GRP_SECP224R1;
+
+/*
+ * Parse the public key used for signing. Simple RSA format.
+ */
+static int
+bootutil_parse_eckey(mbedtls_ecdsa_context *ctx, uint8_t **p, uint8_t *end)
+{
+    size_t len;
+    mbedtls_asn1_buf alg;
+    mbedtls_asn1_buf param;
+
+    if (mbedtls_asn1_get_tag(p, end, &len,
+        MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
+        return -1;
+    }
+    end = *p + len;
+
+    if (mbedtls_asn1_get_alg(p, end, &alg, &param)) {
+        return -2;
+    }
+    if (alg.len != sizeof(ec_pubkey_oid) - 1 ||
+      memcmp(alg.p, ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
+        return -3;
+    }
+    if (param.len != sizeof(ec_secp224r1_oid) - 1||
+      memcmp(param.p, ec_secp224r1_oid, sizeof(ec_secp224r1_oid) - 1)) {
+        return -4;
+    }
+
+    if (mbedtls_ecp_group_load_secp224r1(&ctx->grp)) {
+        return -5;
+    }
+
+    if (mbedtls_asn1_get_bitstring_null(p, end, &len)) {
+        return -6;
+    }
+    if (*p + len != end) {
+        return -7;
+    }
+
+    if (mbedtls_ecp_point_read_binary(&ctx->grp, &ctx->Q, *p, end - *p)) {
+        return -8;
+    }
+
+    if (mbedtls_ecp_check_pubkey(&ctx->grp, &ctx->Q)) {
+        return -9;
+    }
+    return 0;
+}
+
+static int
+bootutil_cmp_sig(mbedtls_ecdsa_context *ctx, uint8_t *hash, uint32_t hlen,
+  uint8_t *sig, int slen)
+{
+    return mbedtls_ecdsa_read_signature(ctx, hash, hlen, sig, slen);
+}
+
+int
+bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, int slen,
+  uint8_t key_id)
+{
+    int rc;
+    uint8_t *cp;
+    uint8_t *end;
+    mbedtls_ecdsa_context ctx;
+
+    mbedtls_ecdsa_init(&ctx);
+
+    cp = (uint8_t *)bootutil_keys[key_id].key;
+    end = cp + *bootutil_keys[key_id].len;
+
+    rc = bootutil_parse_eckey(&ctx, &cp, end);
+    if (rc) {
+        return -1;
+    }
+
+    while (sig[slen - 1] == '\0') {
+        slen--;
+    }
+    rc = bootutil_cmp_sig(&ctx, hash, hlen, sig, slen);
+    mbedtls_ecdsa_free(&ctx);
+
+    return rc;
+}
+#endif /* IMAGE_SIGNATURES_EC */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/855a6afe/libs/bootutil/src/image_rsa.c
----------------------------------------------------------------------
diff --git a/libs/bootutil/src/image_rsa.c b/libs/bootutil/src/image_rsa.c
new file mode 100644
index 0000000..8f02329
--- /dev/null
+++ b/libs/bootutil/src/image_rsa.c
@@ -0,0 +1,141 @@
+/**
+ * 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.
+ */
+#ifdef IMAGE_SIGNATURES_RSA
+#include <bootutil/sign_key.h>
+
+#include <mbedtls/rsa.h>
+#include <mbedtls/asn1.h>
+
+#include "bootutil_priv.h"
+
+static const uint8_t sha256_oid[] = {
+    0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+    0x00, 0x04, 0x20
+};
+
+/*
+ * Parse the public key used for signing. Simple RSA format.
+ */
+static int
+bootutil_parse_rsakey(mbedtls_rsa_context *ctx, uint8_t **p, uint8_t *end)
+{
+    int rc;
+    size_t len;
+
+    if ((rc = mbedtls_asn1_get_tag(p, end, &len,
+          MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+        return -1;
+    }
+
+    if (*p + len != end) {
+        return -2;
+    }
+
+    if ((rc = mbedtls_asn1_get_mpi(p, end, &ctx->N)) != 0 ||
+      (rc = mbedtls_asn1_get_mpi(p, end, &ctx->E)) != 0) {
+        return -3;
+    }
+
+    if (*p != end) {
+        return -4;
+    }
+
+    if ((rc = mbedtls_rsa_check_pubkey(ctx)) != 0) {
+        return -5;
+    }
+
+    ctx->len = mbedtls_mpi_size(&ctx->N);
+
+    return 0;
+}
+
+/*
+ * PKCS1.5 using RSA2048 computed over SHA256.
+ */
+static int
+bootutil_cmp_rsasig(mbedtls_rsa_context *ctx, uint8_t *hash, uint32_t hlen,
+  uint8_t *sig)
+{
+    uint8_t buf[MBEDTLS_MPI_MAX_SIZE];
+    uint8_t *p;
+
+    if (ctx->len != 256) {
+        return -1;
+    }
+
+    if (mbedtls_rsa_public(ctx, sig, buf)) {
+        return -1;
+    }
+
+    p = buf;
+
+    if (*p++ != 0 || *p++ != MBEDTLS_RSA_SIGN) {
+        return -1;
+    }
+
+    while (*p != 0) {
+        if (p >= buf + ctx->len - 1 || *p != 0xFF) {
+            return -1;
+        }
+        p++;
+    }
+    p++;
+
+    if ((p - buf) + sizeof(sha256_oid) + hlen != ctx->len) {
+        return -1;
+    }
+
+    if (memcmp(p, sha256_oid, sizeof(sha256_oid))) {
+        return -1;
+    }
+    p += sizeof(sha256_oid);
+
+    if (memcmp(p, hash, hlen)) {
+        return -1;
+    }
+
+    return 0;
+}
+
+int
+bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, int slen,
+  uint8_t key_id)
+{
+    mbedtls_rsa_context ctx;
+    int rc;
+    uint8_t *cp;
+    uint8_t *end;
+
+    mbedtls_rsa_init(&ctx, 0, 0);
+
+    cp = (uint8_t *)bootutil_keys[key_id].key;
+    end = cp + *bootutil_keys[key_id].len;
+
+    rc = bootutil_parse_rsakey(&ctx, &cp, end);
+    if (rc || slen != ctx.len) {
+        mbedtls_rsa_free(&ctx);
+        return rc;
+    }
+    rc = bootutil_cmp_rsasig(&ctx, hash, hlen, sig);
+    mbedtls_rsa_free(&ctx);
+
+    return rc;
+}
+#endif /* IMAGE_SIGNATURES_RSA */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/855a6afe/libs/bootutil/src/image_validate.c
----------------------------------------------------------------------
diff --git a/libs/bootutil/src/image_validate.c b/libs/bootutil/src/image_validate.c
index 9307640..b491790 100644
--- a/libs/bootutil/src/image_validate.c
+++ b/libs/bootutil/src/image_validate.c
@@ -24,21 +24,14 @@
 #include <hal/hal_flash.h>
 
 #include <bootutil/image.h>
-#ifdef IMAGE_SIGNATURES
 #include <bootutil/sign_key.h>
-#endif
 
 #include <mbedtls/sha256.h>
 #include <mbedtls/rsa.h>
+#include <mbedtls/ecdsa.h>
 #include <mbedtls/asn1.h>
 
-#ifdef IMAGE_SIGNATURES
-static const uint8_t sha256_oid[] = {
-    0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
-    0x00, 0x04, 0x20
-};
-#endif
+#include "bootutil_priv.h"
 
 /*
  * Compute SHA256 over the image.
@@ -79,117 +72,6 @@ bootutil_img_hash(struct image_header *hdr, uint8_t flash_id, uint32_t
addr,
     return 0;
 }
 
-#ifdef IMAGE_SIGNATURES
-/*
- * Parse the public key used for signing. Simple RSA format.
- */
-static int
-bootutil_parse_rsakey(mbedtls_rsa_context *ctx, uint8_t **p, uint8_t *end)
-{
-    int rc;
-    size_t len;
-
-    if ((rc = mbedtls_asn1_get_tag(p, end, &len,
-          MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
-        return -1;
-    }
-
-    if (*p + len != end) {
-        return -2;
-    }
-
-    if ((rc = mbedtls_asn1_get_mpi(p, end, &ctx->N)) != 0 ||
-      (rc = mbedtls_asn1_get_mpi(p, end, &ctx->E)) != 0) {
-        return -3;
-    }
-
-    if (*p != end) {
-        return -4;
-    }
-
-    if ((rc = mbedtls_rsa_check_pubkey(ctx)) != 0) {
-        return -5;
-    }
-
-    ctx->len = mbedtls_mpi_size(&ctx->N);
-
-    return 0;
-}
-
-/*
- * PKCS1.5 using RSA2048 computed over SHA256.
- */
-static int
-bootutil_cmp_rsasig(mbedtls_rsa_context *ctx, uint8_t *hash, uint32_t hlen,
-  uint8_t *sig)
-{
-    uint8_t buf[MBEDTLS_MPI_MAX_SIZE];
-    uint8_t *p;
-
-    if (ctx->len != 256) {
-        return -1;
-    }
-
-    if (mbedtls_rsa_public(ctx, sig, buf)) {
-        return -1;
-    }
-
-    p = buf;
-
-    if (*p++ != 0 || *p++ != MBEDTLS_RSA_SIGN) {
-        return -1;
-    }
-
-    while (*p != 0) {
-        if (p >= buf + ctx->len - 1 || *p != 0xFF) {
-            return -1;
-        }
-        p++;
-    }
-    p++;
-
-    if ((p - buf) + sizeof(sha256_oid) + hlen != ctx->len) {
-        return -1;
-    }
-
-    if (memcmp(p, sha256_oid, sizeof(sha256_oid))) {
-        return -1;
-    }
-    p += sizeof(sha256_oid);
-
-    if (memcmp(p, hash, hlen)) {
-        return -1;
-    }
-
-    return 0;
-}
-
-static int
-bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, int slen,
-  uint8_t key_id)
-{
-    mbedtls_rsa_context ctx;
-    int rc;
-    uint8_t *cp;
-    uint8_t *end;
-
-    mbedtls_rsa_init(&ctx, 0, 0);
-
-    cp = (uint8_t *)bootutil_keys[key_id].key;
-    end = cp + *bootutil_keys[key_id].len;
-
-    rc = bootutil_parse_rsakey(&ctx, &cp, end);
-    if (rc || slen != ctx.len) {
-        mbedtls_rsa_free(&ctx);
-        return rc;
-    }
-    rc = bootutil_cmp_rsasig(&ctx, hash, hlen, sig);
-    mbedtls_rsa_free(&ctx);
-
-    return rc;
-}
-#endif
-
 /*
  * Verify the integrity of the image.
  * Return non-zero if image could not be validated/does not validate.
@@ -201,19 +83,25 @@ bootutil_img_validate(struct image_header *hdr, uint8_t flash_id, uint32_t
addr,
     uint32_t off;
     uint32_t size;
     uint32_t sha_off = 0;
-#ifdef IMAGE_SIGNATURES
-    uint32_t rsa_off = 0;
+#if defined(IMAGE_SIGNATURES_RSA) || defined(IMAGE_SIGNATURES_EC)
+    uint32_t sig_off = 0;
+    uint32_t sig_len = 0;
 #endif
     struct image_tlv tlv;
     uint8_t buf[256];
     uint8_t hash[32];
     int rc;
 
-#ifdef IMAGE_SIGNATURES
+#ifdef IMAGE_SIGNATURES_RSA
     if ((hdr->ih_flags & IMAGE_F_PKCS15_RSA2048_SHA256) == 0) {
         return -1;
     }
 #endif
+#ifdef IMAGE_SIGNATURES_EC
+    if ((hdr->ih_flags & IMAGE_F_ECDSA224_SHA256) == 0) {
+        return -1;
+    }
+#endif
     if ((hdr->ih_flags & IMAGE_F_SHA256) == 0) {
         return -1;
     }
@@ -240,12 +128,22 @@ bootutil_img_validate(struct image_header *hdr, uint8_t flash_id, uint32_t
addr,
             }
             sha_off = addr + off + sizeof(tlv);
         }
-#ifdef IMAGE_SIGNATURES
+#ifdef IMAGE_SIGNATURES_RSA
         if (tlv.it_type == IMAGE_TLV_RSA2048) {
             if (tlv.it_len != 256) { /* 2048 bits */
                 return -1;
             }
-            rsa_off = addr + off + sizeof(tlv);
+            sig_off = addr + off + sizeof(tlv);
+            sig_len = tlv.it_len;
+        }
+#endif
+#ifdef IMAGE_SIGNATURES_EC
+        if (tlv.it_type == IMAGE_TLV_ECDSA224) {
+            if (tlv.it_len < 64) { /* oids + 2 * 28 bytes */
+                return -1;
+            }
+            sig_off = addr + off + sizeof(tlv);
+            sig_len = tlv.it_len;
         }
 #endif
     }
@@ -264,27 +162,25 @@ bootutil_img_validate(struct image_header *hdr, uint8_t flash_id, uint32_t
addr,
             return -1;
         }
     }
-#ifdef IMAGE_SIGNATURES
-    if (hdr->ih_flags & IMAGE_F_PKCS15_RSA2048_SHA256) {
-        if (!rsa_off) {
-            /*
-             * Header said there should be PKCS1.v5 signature, no TLV
-             * found.
-             */
-            return -1;
-        }
-        rc = hal_flash_read(flash_id, rsa_off, buf, 256);
-        if (rc) {
-            return -1;
-        }
+#if defined(IMAGE_SIGNATURES_RSA) || defined(IMAGE_SIGNATURES_EC)
+    if (!sig_off) {
+        /*
+         * Header said there should be PKCS1.v5 signature, no TLV
+         * found.
+         */
+        return -1;
+    }
+    rc = hal_flash_read(flash_id, sig_off, buf, sig_len);
+    if (rc) {
+        return -1;
+    }
 
-        if (hdr->ih_key_id >= bootutil_key_cnt) {
-            return -1;
-        }
-        rc = bootutil_verify_sig(hash, sizeof(hash), buf, 256, hdr->ih_key_id);
-        if (rc) {
-            return -1;
-        }
+    if (hdr->ih_key_id >= bootutil_key_cnt) {
+        return -1;
+    }
+    rc = bootutil_verify_sig(hash, sizeof(hash), buf, sig_len, hdr->ih_key_id);
+    if (rc) {
+        return -1;
     }
 #endif
     return 0;


Mime
View raw message