You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/04/28 02:09:46 UTC
[19/32] incubator-mynewt-newt git commit: Support ECDSA 224 for image
signatures.
Support ECDSA 224 for image signatures.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/bf788977
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/bf788977
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/bf788977
Branch: refs/heads/master
Commit: bf78897739a4b4ac1e6dd56cdf7bd6463d8bfa9c
Parents: b70ee82
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Wed Apr 6 18:31:06 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Wed Apr 6 18:34:57 2016 -0700
----------------------------------------------------------------------
newt/image/image.go | 105 +++++++++++++++++++++++++++++++++++++++--------
1 file changed, 87 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/bf788977/newt/image/image.go
----------------------------------------------------------------------
diff --git a/newt/image/image.go b/newt/image/image.go
index 2d61339..0af34b6 100644
--- a/newt/image/image.go
+++ b/newt/image/image.go
@@ -22,16 +22,19 @@ package image
import (
"bytes"
"crypto"
+ "crypto/ecdsa"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
+ "encoding/asn1"
"encoding/binary"
"encoding/json"
"encoding/pem"
"fmt"
"io"
"io/ioutil"
+ "math/big"
"os"
"path/filepath"
"sort"
@@ -60,7 +63,8 @@ type Image struct {
targetImg string
manifestFile string
version ImageVersion
- signingKey *rsa.PrivateKey
+ signingRSA *rsa.PrivateKey
+ signingEC *ecdsa.PrivateKey
keyId uint8
hash []byte
}
@@ -99,14 +103,16 @@ const (
IMAGE_F_PIC = 0x00000001
IMAGE_F_SHA256 = 0x00000002 /* Image contains hash TLV */
IMAGE_F_PKCS15_RSA2048_SHA256 = 0x00000004 /* PKCS15 w/RSA2048 and SHA256 */
+ IMAGE_F_ECDSA224_SHA256 = 0x00000008 /* ECDSA224 over SHA256 */
)
/*
* Image trailer TLV types.
*/
const (
- IMAGE_TLV_SHA256 = 1
- IMAGE_TLV_RSA2048 = 2
+ IMAGE_TLV_SHA256 = 1
+ IMAGE_TLV_RSA2048 = 2
+ IMAGE_TLV_ECDSA224 = 3
)
/*
@@ -125,6 +131,11 @@ type ImageManifestPkg struct {
Name string `json:"name"`
}
+type ECDSASig struct {
+ R *big.Int
+ S *big.Int
+}
+
func NewImage(b *builder.Builder) (*Image, error) {
image := &Image{
builder: b,
@@ -203,20 +214,33 @@ func (image *Image) SetSigningKey(fileName string, keyId uint8) error {
}
block, _ := pem.Decode(data)
- if block == nil || block.Type != "RSA PRIVATE KEY" {
- return util.NewNewtError(fmt.Sprintf("No RSA private key in file"))
+ if block != nil && block.Type == "RSA PRIVATE KEY" {
+ /*
+ * ParsePKCS1PrivateKey returns an RSA private key from its ASN.1
+ * PKCS#1 DER encoded form.
+ */
+ privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Private key parsing "+
+ "failed: %s", err))
+ }
+ image.signingRSA = privateKey
}
-
- /*
- * ParsePKCS1PrivateKey returns an RSA private key from its ASN.1 PKCS#1 DER
- * encoded form.
- */
- privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Private key parsing failed: %s",
- err))
+ if block != nil && block.Type == "EC PRIVATE KEY" {
+ /*
+ * ParseECPrivateKey returns a EC private key
+ */
+ privateKey, err := x509.ParseECPrivateKey(block.Bytes)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Private key parsing "+
+ "failed: %s", err))
+ }
+ image.signingEC = privateKey
+ }
+ if image.signingEC == nil && image.signingRSA == nil {
+ return util.NewNewtError("Unknown private key format, EC/RSA private " +
+ "key in PEM format only.")
}
- image.signingKey = privateKey
image.keyId = keyId
return nil
@@ -264,10 +288,13 @@ func (image *Image) Generate() error {
Vers: image.version,
Pad3: 0,
}
- if image.signingKey != nil {
+ if image.signingRSA != nil {
hdr.TlvSz = 4 + 256 + 4 + 32
hdr.Flags = IMAGE_F_PKCS15_RSA2048_SHA256 | IMAGE_F_SHA256
hdr.KeyId = image.keyId
+ } else if image.signingEC != nil {
+ hdr.TlvSz = 4 + 68 + 4 + 32
+ hdr.Flags = IMAGE_F_ECDSA224_SHA256 | IMAGE_F_SHA256
} else {
hdr.TlvSz = 4 + 32
hdr.Flags = IMAGE_F_SHA256
@@ -330,7 +357,7 @@ func (image *Image) Generate() error {
err.Error()))
}
- if image.signingKey != nil {
+ if image.signingRSA != nil {
/*
* If signing key was set, generate TLV for that.
*/
@@ -339,7 +366,7 @@ func (image *Image) Generate() error {
Pad: 0,
Len: 256, /* 2048 bits */
}
- signature, err := rsa.SignPKCS1v15(rand.Reader, image.signingKey,
+ signature, err := rsa.SignPKCS1v15(rand.Reader, image.signingRSA,
crypto.SHA256, image.hash)
if err != nil {
return util.NewNewtError(fmt.Sprintf(
@@ -357,6 +384,48 @@ func (image *Image) Generate() error {
err.Error()))
}
}
+ if image.signingEC != nil {
+ r, s, err := ecdsa.Sign(rand.Reader, image.signingEC, image.hash)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf(
+ "Failed to compute signature: %s", err))
+ }
+
+ var ECDSA ECDSASig
+ ECDSA.R = r
+ ECDSA.S = s
+ signature, err := asn1.Marshal(ECDSA)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf(
+ "Failed to construct signature: %s", err))
+ }
+ if len(signature) > 68 {
+ return util.NewNewtError(fmt.Sprintf(
+ "Something is really wrong\n"))
+ }
+ tlv := &ImageTrailerTlv{
+ Type: IMAGE_TLV_ECDSA224,
+ Pad: 0,
+ Len: 68,
+ }
+ err = binary.Write(imgFile, binary.LittleEndian, tlv)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Failed to serialize image "+
+ "trailer: %s", err.Error()))
+ }
+ _, err = imgFile.Write(signature)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Failed to append sig: %s",
+ err.Error()))
+ }
+ pad := make([]byte, 68-len(signature))
+ _, err = imgFile.Write(pad)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Failed to serialize image "+
+ "trailer: %s", err.Error()))
+ }
+ }
+
return nil
}