diff --git a/flash/flash.go b/flash/flash.go
new file mode 100644
index 0000000..c37d2dd
--- /dev/null
+++ b/flash/flash.go
@@ -0,0 +1,160 @@
+/**
+ * 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.
+ */
+
+package flash
+
+import (
+	"fmt"
+	"sort"
+)
+
+const FLASH_AREA_NAME_BOOTLOADER = "FLASH_AREA_BOOTLOADER"
+const FLASH_AREA_NAME_IMAGE_0 = "FLASH_AREA_IMAGE_0"
+const FLASH_AREA_NAME_IMAGE_1 = "FLASH_AREA_IMAGE_1"
+const FLASH_AREA_NAME_IMAGE_SCRATCH = "FLASH_AREA_IMAGE_SCRATCH"
+const AREA_USER_ID_MIN = 16
+
+var SYSTEM_AREA_NAME_ID_MAP = map[string]int{
+	FLASH_AREA_NAME_BOOTLOADER:    0,
+	FLASH_AREA_NAME_IMAGE_0:       1,
+	FLASH_AREA_NAME_IMAGE_1:       2,
+	FLASH_AREA_NAME_IMAGE_SCRATCH: 3,
+}
+
+type FlashArea struct {
+	Name   string
+	Id     int
+	Device int
+	Offset int
+	Size   int
+}
+
+type areaOffSorter struct {
+	areas []FlashArea
+}
+
+func (s areaOffSorter) Len() int {
+	return len(s.areas)
+}
+func (s areaOffSorter) Swap(i, j int) {
+	s.areas[i], s.areas[j] = s.areas[j], s.areas[i]
+}
+func (s areaOffSorter) Less(i, j int) bool {
+	ai := s.areas[i]
+	aj := s.areas[j]
+
+	if ai.Device < aj.Device {
+		return true
+	}
+	if ai.Device > aj.Device {
+		return false
+	}
+	return ai.Offset < aj.Offset
+}
+
+func SortFlashAreasByDevOff(areas []FlashArea) []FlashArea {
+	sorter := areaOffSorter{
+		areas: make([]FlashArea, len(areas)),
+	}
+
+	for i, a := range areas {
+		sorter.areas[i] = a
+	}
+
+	sort.Sort(sorter)
+	return sorter.areas
+}
+
+func SortFlashAreasById(areas []FlashArea) []FlashArea {
+	idMap := make(map[int]FlashArea, len(areas))
+	ids := make([]int, 0, len(areas))
+	for _, area := range areas {
+		idMap[area.Id] = area
+		ids = append(ids, area.Id)
+	}
+	sort.Ints(ids)
+
+	sorted := make([]FlashArea, len(ids))
+	for i, id := range ids {
+		sorted[i] = idMap[id]
+	}
+
+	return sorted
+}
+
+func areasDistinct(a FlashArea, b FlashArea) bool {
+	var lo FlashArea
+	var hi FlashArea
+
+	if a.Offset < b.Offset {
+		lo = a
+		hi = b
+	} else {
+		lo = b
+		hi = a
+	}
+
+	return lo.Device != hi.Device || lo.Offset+lo.Size <= hi.Offset
+}
+
+// @return overlapping-areas, id-conflicts.
+func DetectErrors(areas []FlashArea) ([][]FlashArea, [][]FlashArea) {
+	var overlaps [][]FlashArea
+	var conflicts [][]FlashArea
+
+	for i := 0; i < len(areas)-1; i++ {
+		iarea := areas[i]
+		for j := i + 1; j < len(areas); j++ {
+			jarea := areas[j]
+
+			if !areasDistinct(iarea, jarea) {
+				overlaps = append(overlaps, []FlashArea{iarea, jarea})
+			}
+
+			if iarea.Id == jarea.Id {
+				conflicts = append(conflicts, []FlashArea{iarea, jarea})
+			}
+		}
+	}
+
+	return overlaps, conflicts
+}
+
+func ErrorText(overlaps [][]FlashArea, conflicts [][]FlashArea) string {
+	str := ""
+
+	if len(conflicts) > 0 {
+		str += "Conflicting flash area IDs detected:\n"
+
+		for _, pair := range conflicts {
+			str += fmt.Sprintf("    (%d) %s =/= %s\n",
+				pair[0].Id-AREA_USER_ID_MIN, pair[0].Name, pair[1].Name)
+		}
+	}
+
+	if len(overlaps) > 0 {
+		str += "Overlapping flash areas detected:\n"
+
+		for _, pair := range overlaps {
+			str += fmt.Sprintf("    %s =/= %s\n", pair[0].Name, pair[1].Name)
+		}
+	}
+
+	return str
+}
diff --git a/image/create.go b/image/create.go
new file mode 100644
index 0000000..5b28120
--- /dev/null
+++ b/image/create.go
@@ -0,0 +1,427 @@
+/**
+ * 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.
+ */
+
+package image
+
+import (
+	"bytes"
+	"crypto"
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/ecdsa"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/sha256"
+	"encoding/asn1"
+	"encoding/binary"
+	"encoding/hex"
+	"io"
+	"io/ioutil"
+	"math/big"
+
+	"mynewt.apache.org/newt/util"
+)
+
+type ImageCreator struct {
+	Body         []byte
+	Version      ImageVersion
+	SigKeys      []ImageSigKey
+	PlainSecret  []byte
+	CipherSecret []byte
+	HeaderSize   int
+	InitialHash  []byte
+	Bootable     bool
+}
+
+type ImageCreateOpts struct {
+	SrcBinFilename    string
+	SrcEncKeyFilename string
+	Version           ImageVersion
+	SigKeys           []ImageSigKey
+	LoaderHash        []byte
+}
+
+type ECDSASig struct {
+	R *big.Int
+	S *big.Int
+}
+
+func NewImageCreator() ImageCreator {
+	return ImageCreator{
+		HeaderSize: IMAGE_HEADER_SIZE,
+		Bootable:   true,
+	}
+}
+
+func generateEncTlv(cipherSecret []byte) (ImageTlv, error) {
+	var encType uint8
+
+	if len(cipherSecret) == 256 {
+		encType = IMAGE_TLV_ENC_RSA
+	} else if len(cipherSecret) == 24 {
+		encType = IMAGE_TLV_ENC_KEK
+	} else {
+		return ImageTlv{}, util.FmtNewtError("Invalid enc TLV size ")
+	}
+
+	return ImageTlv{
+		Header: ImageTlvHdr{
+			Type: encType,
+			Pad:  0,
+			Len:  uint16(len(cipherSecret)),
+		},
+		Data: cipherSecret,
+	}, nil
+}
+
+func generateSigRsa(key *rsa.PrivateKey, hash []byte) ([]byte, error) {
+	opts := rsa.PSSOptions{
+		SaltLength: rsa.PSSSaltLengthEqualsHash,
+	}
+	signature, err := rsa.SignPSS(
+		rand.Reader, key, crypto.SHA256, hash, &opts)
+	if err != nil {
+		return nil, util.FmtNewtError("Failed to compute signature: %s", err)
+	}
+
+	return signature, nil
+}
+
+func generateSigTlvRsa(key ImageSigKey, hash []byte) (ImageTlv, error) {
+	sig, err := generateSigRsa(key.Rsa, hash)
+	if err != nil {
+		return ImageTlv{}, err
+	}
+
+	return ImageTlv{
+		Header: ImageTlvHdr{
+			Type: key.sigTlvType(),
+			Pad:  0,
+			Len:  256, /* 2048 bits */
+		},
+		Data: sig,
+	}, nil
+}
+
+func generateSigEc(key *ecdsa.PrivateKey, hash []byte) ([]byte, error) {
+	r, s, err := ecdsa.Sign(rand.Reader, key, hash)
+	if err != nil {
+		return nil, util.FmtNewtError("Failed to compute signature: %s", err)
+	}
+
+	ECDSA := ECDSASig{
+		R: r,
+		S: s,
+	}
+
+	signature, err := asn1.Marshal(ECDSA)
+	if err != nil {
+		return nil, util.FmtNewtError("Failed to construct signature: %s", err)
+	}
+
+	return signature, nil
+}
+
+func generateSigTlvEc(key ImageSigKey, hash []byte) (ImageTlv, error) {
+	sig, err := generateSigEc(key.Ec, hash)
+	if err != nil {
+		return ImageTlv{}, err
+	}
+
+	sigLen := key.sigLen()
+	if len(sig) > int(sigLen) {
+		return ImageTlv{}, util.FmtNewtError("Something is really wrong\n")
+	}
+
+	b := &bytes.Buffer{}
+
+	if _, err := b.Write(sig); err != nil {
+		return ImageTlv{},
+			util.FmtNewtError("Failed to append sig: %s", err.Error())
+	}
+
+	pad := make([]byte, int(sigLen)-len(sig))
+	if _, err := b.Write(pad); err != nil {
+		return ImageTlv{}, util.FmtNewtError(
+			"Failed to serialize image trailer: %s", err.Error())
+	}
+
+	return ImageTlv{
+		Header: ImageTlvHdr{
+			Type: key.sigTlvType(),
+			Pad:  0,
+			Len:  sigLen,
+		},
+		Data: b.Bytes(),
+	}, nil
+}
+
+func generateSigTlv(key ImageSigKey, hash []byte) (ImageTlv, error) {
+	key.assertValid()
+
+	if key.Rsa != nil {
+		return generateSigTlvRsa(key, hash)
+	} else {
+		return generateSigTlvEc(key, hash)
+	}
+}
+
+func generateKeyHashTlv(key ImageSigKey) (ImageTlv, error) {
+	key.assertValid()
+
+	keyHash, err := key.sigKeyHash()
+	if err != nil {
+		return ImageTlv{}, util.FmtNewtError(
+			"Failed to compute hash of the public key: %s", err.Error())
+	}
+
+	return ImageTlv{
+		Header: ImageTlvHdr{
+			Type: IMAGE_TLV_KEYHASH,
+			Pad:  0,
+			Len:  uint16(len(keyHash)),
+		},
+		Data: keyHash,
+	}, nil
+}
+
+func GenerateSigTlvs(keys []ImageSigKey, hash []byte) ([]ImageTlv, error) {
+	var tlvs []ImageTlv
+
+	for _, key := range keys {
+		key.assertValid()
+
+		tlv, err := generateKeyHashTlv(key)
+		if err != nil {
+			return nil, err
+		}
+		tlvs = append(tlvs, tlv)
+
+		tlv, err = generateSigTlv(key, hash)
+		if err != nil {
+			return nil, err
+		}
+		tlvs = append(tlvs, tlv)
+	}
+
+	return tlvs, nil
+}
+
+func GenerateImage(opts ImageCreateOpts) (Image, error) {
+	ic := NewImageCreator()
+
+	srcBin, err := ioutil.ReadFile(opts.SrcBinFilename)
+	if err != nil {
+		return Image{}, util.FmtNewtError(
+			"Can't read app binary: %s", err.Error())
+	}
+
+	ic.Body = srcBin
+	ic.Version = opts.Version
+	ic.SigKeys = opts.SigKeys
+
+	if opts.LoaderHash != nil {
+		ic.InitialHash = opts.LoaderHash
+		ic.Bootable = false
+	} else {
+		ic.Bootable = true
+	}
+
+	if opts.SrcEncKeyFilename != "" {
+		plainSecret := make([]byte, 16)
+		if _, err := rand.Read(plainSecret); err != nil {
+			return Image{}, util.FmtNewtError(
+				"Random generation error: %s\n", err)
+		}
+
+		cipherSecret, err := ReadEncKey(opts.SrcEncKeyFilename, plainSecret)
+		if err != nil {
+			return Image{}, err
+		}
+
+		ic.PlainSecret = plainSecret
+		ic.CipherSecret = cipherSecret
+	}
+
+	ri, err := ic.Create()
+	if err != nil {
+		return Image{}, err
+	}
+
+	return ri, nil
+}
+
+func calcHash(initialHash []byte, hdr ImageHdr,
+	plainBody []byte) ([]byte, error) {
+
+	hash := sha256.New()
+
+	add := func(itf interface{}) error {
+		b := &bytes.Buffer{}
+		if err := binary.Write(b, binary.LittleEndian, itf); err != nil {
+			return err
+		}
+		if err := binary.Write(hash, binary.LittleEndian, itf); err != nil {
+			return util.FmtNewtError("Failed to hash data: %s", err.Error())
+		}
+
+		return nil
+	}
+
+	if initialHash != nil {
+		if err := add(initialHash); err != nil {
+			return nil, err
+		}
+	}
+
+	if err := add(hdr); err != nil {
+		return nil, err
+	}
+
+	extra := hdr.HdrSz - IMAGE_HEADER_SIZE
+	if extra > 0 {
+		b := make([]byte, extra)
+		if err := add(b); err != nil {
+			return nil, err
+		}
+	}
+
+	if err := add(plainBody); err != nil {
+		return nil, err
+	}
+
+	return hash.Sum(nil), nil
+}
+
+func (ic *ImageCreator) Create() (Image, error) {
+	ri := Image{}
+
+	// First the header
+	hdr := ImageHdr{
+		Magic: IMAGE_MAGIC,
+		Pad1:  0,
+		HdrSz: IMAGE_HEADER_SIZE,
+		Pad2:  0,
+		ImgSz: uint32(len(ic.Body)),
+		Flags: 0,
+		Vers:  ic.Version,
+		Pad3:  0,
+	}
+
+	if !ic.Bootable {
+		hdr.Flags |= IMAGE_F_NON_BOOTABLE
+	}
+
+	if ic.CipherSecret != nil {
+		hdr.Flags |= IMAGE_F_ENCRYPTED
+	}
+
+	if ic.HeaderSize != 0 {
+		// Pad the header out to the given size.  There will
+		// just be zeros between the header and the start of
+		// the image when it is padded.
+		extra := ic.HeaderSize - IMAGE_HEADER_SIZE
+		if extra < 0 {
+			return ri, util.FmtNewtError("Image header must be at "+
+				"least %d bytes", IMAGE_HEADER_SIZE)
+		}
+
+		hdr.HdrSz = uint16(ic.HeaderSize)
+		for i := 0; i < extra; i++ {
+			ri.Body = append(ri.Body, 0)
+		}
+	}
+
+	ri.Header = hdr
+
+	hashBytes, err := calcHash(ic.InitialHash, hdr, ic.Body)
+	if err != nil {
+		return ri, err
+	}
+
+	var stream cipher.Stream
+	if ic.CipherSecret != nil {
+		block, err := aes.NewCipher(ic.PlainSecret)
+		if err != nil {
+			return ri, util.NewNewtError("Failed to create block cipher")
+		}
+		nonce := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+		stream = cipher.NewCTR(block, nonce)
+	}
+
+	/*
+	 * Followed by data.
+	 */
+	dataBuf := make([]byte, 16)
+	encBuf := make([]byte, 16)
+	r := bytes.NewReader(ic.Body)
+	w := bytes.Buffer{}
+	for {
+		cnt, err := r.Read(dataBuf)
+		if err != nil && err != io.EOF {
+			return ri, util.FmtNewtError(
+				"Failed to read from image body: %s", err.Error())
+		}
+		if cnt == 0 {
+			break
+		}
+
+		if ic.CipherSecret == nil {
+			_, err = w.Write(dataBuf[0:cnt])
+		} else {
+			stream.XORKeyStream(encBuf, dataBuf[0:cnt])
+			_, err = w.Write(encBuf[0:cnt])
+		}
+		if err != nil {
+			return ri, util.FmtNewtError(
+				"Failed to write to image body: %s", err.Error())
+		}
+	}
+	ri.Body = append(ri.Body, w.Bytes()...)
+
+	util.StatusMessage(util.VERBOSITY_VERBOSE,
+		"Computed Hash for image as %s\n", hex.EncodeToString(hashBytes))
+
+	// Hash TLV.
+	tlv := ImageTlv{
+		Header: ImageTlvHdr{
+			Type: IMAGE_TLV_SHA256,
+			Pad:  0,
+			Len:  uint16(len(hashBytes)),
+		},
+		Data: hashBytes,
+	}
+	ri.Tlvs = append(ri.Tlvs, tlv)
+
+	tlvs, err := GenerateSigTlvs(ic.SigKeys, hashBytes)
+	if err != nil {
+		return ri, err
+	}
+	ri.Tlvs = append(ri.Tlvs, tlvs...)
+
+	if ic.CipherSecret != nil {
+		tlv, err := generateEncTlv(ic.CipherSecret)
+		if err != nil {
+			return ri, err
+		}
+		ri.Tlvs = append(ri.Tlvs, tlv)
+	}
+
+	return ri, nil
+}
diff --git a/image/encrypted.go b/image/encrypted.go
new file mode 100644
index 0000000..0547e2f
--- /dev/null
+++ b/image/encrypted.go
@@ -0,0 +1,196 @@
+/**
+ * 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.
+ */
+
+// Decoder for PKCS#5 encrypted PKCS#8 private keys.
+package image
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/sha1"
+	"crypto/sha256"
+	"crypto/x509"
+	"crypto/x509/pkix"
+	"encoding/asn1"
+	"fmt"
+	"hash"
+
+	"golang.org/x/crypto/pbkdf2"
+	"golang.org/x/crypto/ssh/terminal"
+)
+
+var (
+	oidPbes2          = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 13}
+	oidPbkdf2         = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 12}
+	oidHmacWithSha1   = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 7}
+	oidHmacWithSha224 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 8}
+	oidHmacWithSha256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 9}
+	oidAes128CBC      = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 2}
+	oidAes256CBC      = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 42}
+)
+
+// We only support a narrow set of possible key types, namely the type
+// generated by either MCUboot's `imgtool.py` command, or using an
+// OpenSSL command such as:
+//
+//     openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
+//         -aes-256-cbc > keyfile.pem
+//
+// or similar for ECDSA.  Specifically, the encryption must be done
+// with PBES2, and PBKDF2, and aes-256-cbc used as the cipher.
+type pkcs5 struct {
+	Algo      pkix.AlgorithmIdentifier
+	Encrypted []byte
+}
+
+// The parameters when the algorithm in pkcs5 is oidPbes2
+type pbes2 struct {
+	KeyDerivationFunc pkix.AlgorithmIdentifier
+	EncryptionScheme  pkix.AlgorithmIdentifier
+}
+
+// Salt is given as a choice, but we will only support the inlined
+// octet string.
+type pbkdf2Param struct {
+	Salt      []byte
+	IterCount int
+	HashFunc  pkix.AlgorithmIdentifier
+	// Optional and default values omitted, and unsupported.
+}
+
+type hashFunc func() hash.Hash
+
+func parseEncryptedPrivateKey(der []byte) (key interface{}, err error) {
+	var wrapper pkcs5
+	if _, err = asn1.Unmarshal(der, &wrapper); err != nil {
+		return nil, err
+	}
+	if !wrapper.Algo.Algorithm.Equal(oidPbes2) {
+		return nil, fmt.Errorf("pkcs5: Unknown PKCS#5 wrapper algorithm: %v", wrapper.Algo.Algorithm)
+	}
+
+	var pbparm pbes2
+	if _, err = asn1.Unmarshal(wrapper.Algo.Parameters.FullBytes, &pbparm); err != nil {
+		return nil, err
+	}
+	if !pbparm.KeyDerivationFunc.Algorithm.Equal(oidPbkdf2) {
+		return nil, fmt.Errorf("pkcs5: Unknown KDF: %v", pbparm.KeyDerivationFunc.Algorithm)
+	}
+
+	var kdfParam pbkdf2Param
+	if _, err = asn1.Unmarshal(pbparm.KeyDerivationFunc.Parameters.FullBytes, &kdfParam); err != nil {
+		return nil, err
+	}
+
+	var hashNew hashFunc
+	switch {
+	case kdfParam.HashFunc.Algorithm.Equal(oidHmacWithSha1):
+		hashNew = sha1.New
+	case kdfParam.HashFunc.Algorithm.Equal(oidHmacWithSha224):
+		hashNew = sha256.New224
+	case kdfParam.HashFunc.Algorithm.Equal(oidHmacWithSha256):
+		hashNew = sha256.New
+	default:
+		return nil, fmt.Errorf("pkcs5: Unsupported hash: %v", pbparm.EncryptionScheme.Algorithm)
+	}
+
+	// Get the encryption used.
+	size := 0
+	var iv []byte
+	switch {
+	case pbparm.EncryptionScheme.Algorithm.Equal(oidAes256CBC):
+		size = 32
+		if _, err = asn1.Unmarshal(pbparm.EncryptionScheme.Parameters.FullBytes, &iv); err != nil {
+			return nil, err
+		}
+	case pbparm.EncryptionScheme.Algorithm.Equal(oidAes128CBC):
+		size = 16
+		if _, err = asn1.Unmarshal(pbparm.EncryptionScheme.Parameters.FullBytes, &iv); err != nil {
+			return nil, err
+		}
+	default:
+		return nil, fmt.Errorf("pkcs5: Unsupported cipher: %v", pbparm.EncryptionScheme.Algorithm)
+	}
+
+	return unwrapPbes2Pbkdf2(&kdfParam, size, iv, hashNew, wrapper.Encrypted)
+}
+
+func unwrapPbes2Pbkdf2(param *pbkdf2Param, size int, iv []byte, hashNew hashFunc, encrypted []byte) (key interface{}, err error) {
+	pass, err := getPassword()
+	if err != nil {
+		return nil, err
+	}
+	cryptoKey := pbkdf2.Key(pass, param.Salt, param.IterCount, size, hashNew)
+
+	block, err := aes.NewCipher(cryptoKey)
+	if err != nil {
+		return nil, err
+	}
+	enc := cipher.NewCBCDecrypter(block, iv)
+
+	plain := make([]byte, len(encrypted))
+	enc.CryptBlocks(plain, encrypted)
+
+	plain, err = checkPkcs7Padding(plain)
+	if err != nil {
+		return nil, err
+	}
+
+	return x509.ParsePKCS8PrivateKey(plain)
+}
+
+// Verify that PKCS#7 padding is correct on this plaintext message.
+// Returns a new slice with the padding removed.
+func checkPkcs7Padding(buf []byte) ([]byte, error) {
+	if len(buf) < 16 {
+		return nil, fmt.Errorf("Invalid padded buffer")
+	}
+
+	padLen := int(buf[len(buf)-1])
+	if padLen < 1 || padLen > 16 {
+		return nil, fmt.Errorf("Invalid padded buffer")
+	}
+
+	if padLen > len(buf) {
+		return nil, fmt.Errorf("Invalid padded buffer")
+	}
+
+	for pos := len(buf) - padLen; pos < len(buf); pos++ {
+		if int(buf[pos]) != padLen {
+			return nil, fmt.Errorf("Invalid padded buffer")
+		}
+	}
+
+	return buf[:len(buf)-padLen], nil
+}
+
+// For testing, a key can be set here.  If this is empty, the key will
+// be queried via prompt.
+var KeyPassword = []byte{}
+
+// Prompt the user for a password, unless we have stored one for
+// testing.
+func getPassword() ([]byte, error) {
+	if len(KeyPassword) != 0 {
+		return KeyPassword, nil
+	}
+
+	fmt.Printf("key password: ")
+	return terminal.ReadPassword(0)
+}
diff --git a/image/image.go b/image/image.go
new file mode 100644
index 0000000..244cfed
--- /dev/null
+++ b/image/image.go
@@ -0,0 +1,544 @@
+/**
+ * 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.
+ */
+
+package image
+
+import (
+	"bytes"
+	"encoding/binary"
+	"encoding/hex"
+	"encoding/json"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"strconv"
+	"strings"
+
+	"mynewt.apache.org/newt/util"
+)
+
+const (
+	IMAGE_MAGIC         = 0x96f3b83d /* Image header magic */
+	IMAGE_TRAILER_MAGIC = 0x6907     /* Image tlv info magic */
+)
+
+const (
+	IMAGE_HEADER_SIZE  = 32
+	IMAGE_TRAILER_SIZE = 4
+	IMAGE_TLV_SIZE     = 4 /* Plus `value` field. */
+)
+
+/*
+ * Image header flags.
+ */
+const (
+	IMAGE_F_PIC          = 0x00000001
+	IMAGE_F_NON_BOOTABLE = 0x00000002 /* non bootable image */
+	IMAGE_F_ENCRYPTED    = 0x00000004 /* encrypted image */
+)
+
+/*
+ * Image trailer TLV types.
+ */
+const (
+	IMAGE_TLV_KEYHASH  = 0x01
+	IMAGE_TLV_SHA256   = 0x10
+	IMAGE_TLV_RSA2048  = 0x20
+	IMAGE_TLV_ECDSA224 = 0x21
+	IMAGE_TLV_ECDSA256 = 0x22
+	IMAGE_TLV_ENC_RSA  = 0x30
+	IMAGE_TLV_ENC_KEK  = 0x31
+)
+
+var imageTlvTypeNameMap = map[uint8]string{
+	IMAGE_TLV_KEYHASH:  "KEYHASH",
+	IMAGE_TLV_SHA256:   "SHA256",
+	IMAGE_TLV_RSA2048:  "RSA2048",
+	IMAGE_TLV_ECDSA224: "ECDSA224",
+	IMAGE_TLV_ECDSA256: "ECDSA256",
+	IMAGE_TLV_ENC_RSA:  "ENC_RSA",
+	IMAGE_TLV_ENC_KEK:  "ENC_KEK",
+}
+
+type ImageVersion struct {
+	Major    uint8
+	Minor    uint8
+	Rev      uint16
+	BuildNum uint32
+}
+
+type ImageHdr struct {
+	Magic uint32
+	Pad1  uint32
+	HdrSz uint16
+	Pad2  uint16
+	ImgSz uint32
+	Flags uint32
+	Vers  ImageVersion
+	Pad3  uint32
+}
+
+type ImageTlvHdr struct {
+	Type uint8
+	Pad  uint8
+	Len  uint16
+}
+
+type ImageTlv struct {
+	Header ImageTlvHdr
+	Data   []byte
+}
+
+type ImageTrailer struct {
+	Magic     uint16
+	TlvTotLen uint16
+}
+
+type Image struct {
+	Header ImageHdr
+	Body   []byte
+	Tlvs   []ImageTlv
+}
+
+type ImageOffsets struct {
+	Header    int
+	Body      int
+	Trailer   int
+	Tlvs      []int
+	TotalSize int
+}
+
+func ImageTlvTypeName(tlvType uint8) string {
+	name, ok := imageTlvTypeNameMap[tlvType]
+	if !ok {
+		return "???"
+	}
+
+	return name
+}
+
+func ParseVersion(versStr string) (ImageVersion, error) {
+	var err error
+	var major uint64
+	var minor uint64
+	var rev uint64
+	var buildNum uint64
+	var ver ImageVersion
+
+	components := strings.Split(versStr, ".")
+	major, err = strconv.ParseUint(components[0], 10, 8)
+	if err != nil {
+		return ver, util.FmtNewtError("Invalid version string %s", versStr)
+	}
+	if len(components) > 1 {
+		minor, err = strconv.ParseUint(components[1], 10, 8)
+		if err != nil {
+			return ver, util.FmtNewtError("Invalid version string %s", versStr)
+		}
+	}
+	if len(components) > 2 {
+		rev, err = strconv.ParseUint(components[2], 10, 16)
+		if err != nil {
+			return ver, util.FmtNewtError("Invalid version string %s", versStr)
+		}
+	}
+	if len(components) > 3 {
+		buildNum, err = strconv.ParseUint(components[3], 10, 32)
+		if err != nil {
+			return ver, util.FmtNewtError("Invalid version string %s", versStr)
+		}
+	}
+
+	ver.Major = uint8(major)
+	ver.Minor = uint8(minor)
+	ver.Rev = uint16(rev)
+	ver.BuildNum = uint32(buildNum)
+	return ver, nil
+}
+
+func (ver ImageVersion) String() string {
+	return fmt.Sprintf("%d.%d.%d.%d",
+		ver.Major, ver.Minor, ver.Rev, ver.BuildNum)
+}
+
+func (h *ImageHdr) Map(offset int) map[string]interface{} {
+	return map[string]interface{}{
+		"Magic":  h.Magic,
+		"HdrSz":  h.HdrSz,
+		"ImgSz":  h.ImgSz,
+		"Flags":  h.Flags,
+		"Vers":   h.Vers.String(),
+		"offset": offset,
+	}
+}
+
+func rawBodyMap(offset int) map[string]interface{} {
+	return map[string]interface{}{
+		"offset": offset,
+	}
+}
+
+func (t *ImageTrailer) Map(offset int) map[string]interface{} {
+	return map[string]interface{}{
+		"Magic":     t.Magic,
+		"TlvTotLen": t.TlvTotLen,
+		"offset":    offset,
+	}
+}
+
+func (t *ImageTlv) Map(offset int) map[string]interface{} {
+	return map[string]interface{}{
+		"Type":    t.Header.Type,
+		"typestr": ImageTlvTypeName(t.Header.Type),
+		"Len":     t.Header.Len,
+		"offset":  offset,
+		"data":    hex.EncodeToString(t.Data),
+	}
+}
+
+func (img *Image) Map() (map[string]interface{}, error) {
+	offs, err := img.Offsets()
+	if err != nil {
+		return nil, err
+	}
+
+	m := map[string]interface{}{}
+	m["header"] = img.Header.Map(offs.Header)
+	m["body"] = rawBodyMap(offs.Body)
+	trailer := img.Trailer()
+	m["trailer"] = trailer.Map(offs.Trailer)
+
+	tlvMaps := []map[string]interface{}{}
+	for i, tlv := range img.Tlvs {
+		tlvMaps = append(tlvMaps, tlv.Map(offs.Tlvs[i]))
+	}
+	m["tlvs"] = tlvMaps
+
+	return m, nil
+}
+
+func (img *Image) Json() (string, error) {
+	m, err := img.Map()
+	if err != nil {
+		return "", err
+	}
+
+	b, err := json.MarshalIndent(m, "", "    ")
+	if err != nil {
+		return "", util.ChildNewtError(err)
+	}
+
+	return string(b), nil
+}
+
+func (tlv *ImageTlv) Write(w io.Writer) (int, error) {
+	totalSize := 0
+
+	err := binary.Write(w, binary.LittleEndian, &tlv.Header)
+	if err != nil {
+		return totalSize, util.ChildNewtError(err)
+	}
+	totalSize += IMAGE_TLV_SIZE
+
+	size, err := w.Write(tlv.Data)
+	if err != nil {
+		return totalSize, util.ChildNewtError(err)
+	}
+	totalSize += size
+
+	return totalSize, nil
+}
+
+func (i *Image) FindTlvs(tlvType uint8) []ImageTlv {
+	var tlvs []ImageTlv
+
+	for _, tlv := range i.Tlvs {
+		if tlv.Header.Type == tlvType {
+			tlvs = append(tlvs, tlv)
+		}
+	}
+
+	return tlvs
+}
+
+func (i *Image) FindUniqueTlv(tlvType uint8) (*ImageTlv, error) {
+	tlvs := i.FindTlvs(tlvType)
+	if len(tlvs) == 0 {
+		return nil, nil
+	}
+	if len(tlvs) > 1 {
+		return nil, util.FmtNewtError("Image contains %d TLVs with type %d",
+			len(tlvs), tlvType)
+	}
+
+	return &tlvs[0], nil
+}
+
+func (i *Image) RemoveTlvsIf(pred func(tlv ImageTlv) bool) int {
+	numRmed := 0
+	for idx := 0; idx < len(i.Tlvs); {
+		tlv := i.Tlvs[idx]
+		if pred(tlv) {
+			i.Tlvs = append(i.Tlvs[:idx], i.Tlvs[idx+1:]...)
+			numRmed++
+		} else {
+			idx++
+		}
+	}
+
+	return numRmed
+}
+
+func (img *Image) Trailer() ImageTrailer {
+	trailer := ImageTrailer{
+		Magic:     IMAGE_TRAILER_MAGIC,
+		TlvTotLen: IMAGE_TRAILER_SIZE,
+	}
+	for _, tlv := range img.Tlvs {
+		trailer.TlvTotLen += IMAGE_TLV_SIZE + tlv.Header.Len
+	}
+
+	return trailer
+}
+
+func (i *Image) Hash() ([]byte, error) {
+	tlv, err := i.FindUniqueTlv(IMAGE_TLV_SHA256)
+	if err != nil {
+		return nil, err
+	}
+
+	if tlv == nil {
+		return nil, util.FmtNewtError("Image does not contain hash TLV")
+	}
+
+	return tlv.Data, nil
+}
+
+func (i *Image) WritePlusOffsets(w io.Writer) (ImageOffsets, error) {
+	offs := ImageOffsets{}
+	offset := 0
+
+	offs.Header = offset
+
+	err := binary.Write(w, binary.LittleEndian, &i.Header)
+	if err != nil {
+		return offs, util.ChildNewtError(err)
+	}
+	offset += IMAGE_HEADER_SIZE
+
+	offs.Body = offset
+	size, err := w.Write(i.Body)
+	if err != nil {
+		return offs, util.ChildNewtError(err)
+	}
+	offset += size
+
+	trailer := i.Trailer()
+	offs.Trailer = offset
+	err = binary.Write(w, binary.LittleEndian, &trailer)
+	if err != nil {
+		return offs, util.ChildNewtError(err)
+	}
+	offset += IMAGE_TRAILER_SIZE
+
+	for _, tlv := range i.Tlvs {
+		offs.Tlvs = append(offs.Tlvs, offset)
+		size, err := tlv.Write(w)
+		if err != nil {
+			return offs, util.ChildNewtError(err)
+		}
+		offset += size
+	}
+
+	offs.TotalSize = offset
+
+	return offs, nil
+}
+
+func (i *Image) Offsets() (ImageOffsets, error) {
+	return i.WritePlusOffsets(ioutil.Discard)
+}
+
+func (i *Image) TotalSize() (int, error) {
+	offs, err := i.Offsets()
+	if err != nil {
+		return 0, err
+	}
+	return offs.TotalSize, nil
+}
+
+func (i *Image) Write(w io.Writer) (int, error) {
+	offs, err := i.WritePlusOffsets(w)
+	if err != nil {
+		return 0, err
+	}
+
+	return offs.TotalSize, nil
+}
+
+func (i *Image) WriteToFile(filename string) error {
+	f, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
+	if err != nil {
+		return util.ChildNewtError(err)
+	}
+
+	if _, err := i.Write(f); err != nil {
+		return util.ChildNewtError(err)
+	}
+
+	return nil
+}
+
+func parseRawHeader(imgData []byte, offset int) (ImageHdr, int, error) {
+	var hdr ImageHdr
+
+	r := bytes.NewReader(imgData)
+	r.Seek(int64(offset), io.SeekStart)
+
+	if err := binary.Read(r, binary.LittleEndian, &hdr); err != nil {
+		return hdr, 0, util.FmtNewtError(
+			"Error reading image header: %s", err.Error())
+	}
+
+	if hdr.Magic != IMAGE_MAGIC {
+		return hdr, 0, util.FmtNewtError(
+			"Image magic incorrect; expected 0x%08x, got 0x%08x",
+			IMAGE_MAGIC, hdr.Magic)
+	}
+
+	remLen := len(imgData) - offset
+	if remLen < int(hdr.HdrSz) {
+		return hdr, 0, util.FmtNewtError(
+			"Image header incomplete; expected %d bytes, got %d bytes",
+			hdr.HdrSz, remLen)
+	}
+
+	return hdr, int(hdr.HdrSz), nil
+}
+
+func parseRawBody(imgData []byte, hdr ImageHdr,
+	offset int) ([]byte, int, error) {
+
+	imgSz := int(hdr.ImgSz)
+	remLen := len(imgData) - offset
+
+	if remLen < imgSz {
+		return nil, 0, util.FmtNewtError(
+			"Image body incomplete; expected %d bytes, got %d bytes",
+			imgSz, remLen)
+	}
+
+	return imgData[offset : offset+imgSz], imgSz, nil
+}
+
+func parseRawTrailer(imgData []byte, offset int) (ImageTrailer, int, error) {
+	var trailer ImageTrailer
+
+	r := bytes.NewReader(imgData)
+	r.Seek(int64(offset), io.SeekStart)
+
+	if err := binary.Read(r, binary.LittleEndian, &trailer); err != nil {
+		return trailer, 0, util.FmtNewtError(
+			"Image contains invalid trailer at offset %d: %s",
+			offset, err.Error())
+	}
+
+	return trailer, IMAGE_TRAILER_SIZE, nil
+}
+
+func parseRawTlv(imgData []byte, offset int) (ImageTlv, int, error) {
+	tlv := ImageTlv{}
+
+	r := bytes.NewReader(imgData)
+	r.Seek(int64(offset), io.SeekStart)
+
+	if err := binary.Read(r, binary.LittleEndian, &tlv.Header); err != nil {
+		return tlv, 0, util.FmtNewtError(
+			"Image contains invalid TLV at offset %d: %s", offset, err.Error())
+	}
+
+	tlv.Data = make([]byte, tlv.Header.Len)
+	if _, err := r.Read(tlv.Data); err != nil {
+		return tlv, 0, util.FmtNewtError(
+			"Image contains invalid TLV at offset %d: %s", offset, err.Error())
+	}
+
+	return tlv, IMAGE_TLV_SIZE + int(tlv.Header.Len), nil
+}
+
+func ParseImage(imgData []byte) (Image, error) {
+	img := Image{}
+	offset := 0
+
+	hdr, size, err := parseRawHeader(imgData, offset)
+	if err != nil {
+		return img, err
+	}
+	offset += size
+
+	body, size, err := parseRawBody(imgData, hdr, offset)
+	if err != nil {
+		return img, err
+	}
+	offset += size
+
+	trailer, size, err := parseRawTrailer(imgData, offset)
+	if err != nil {
+		return img, err
+	}
+	offset += size
+
+	var tlvs []ImageTlv
+	tlvLen := IMAGE_TRAILER_SIZE
+	for offset < len(imgData) {
+		tlv, size, err := parseRawTlv(imgData, offset)
+		if err != nil {
+			return img, err
+		}
+
+		tlvs = append(tlvs, tlv)
+		offset += size
+
+		tlvLen += IMAGE_TLV_SIZE + int(tlv.Header.Len)
+	}
+
+	if int(trailer.TlvTotLen) != tlvLen {
+		return img, util.FmtNewtError(
+			"invalid image: trailer indicates TLV-length=%d; actual=%d",
+			trailer.TlvTotLen, tlvLen)
+	}
+
+	img.Header = hdr
+	img.Body = body
+	img.Tlvs = tlvs
+
+	return img, nil
+}
+
+func ReadImage(filename string) (Image, error) {
+	ri := Image{}
+
+	imgData, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return ri, util.ChildNewtError(err)
+	}
+
+	return ParseImage(imgData)
+}
diff --git a/image/key.go b/image/key.go
new file mode 100644
index 0000000..9141f6e
--- /dev/null
+++ b/image/key.go
@@ -0,0 +1,294 @@
+/**
+ * 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.
+ */
+
+package image
+
+import (
+	"crypto/aes"
+	"crypto/ecdsa"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/sha256"
+	"crypto/x509"
+	"encoding/asn1"
+	"encoding/base64"
+	"encoding/pem"
+	"io/ioutil"
+
+	keywrap "github.com/NickBall/go-aes-key-wrap"
+
+	"mynewt.apache.org/newt/util"
+)
+
+type ImageSigKey struct {
+	// Only one of these members is non-nil.
+	Rsa *rsa.PrivateKey
+	Ec  *ecdsa.PrivateKey
+}
+
+func ParsePrivateKey(keyBytes []byte) (interface{}, error) {
+	var privKey interface{}
+	var err error
+
+	block, data := pem.Decode(keyBytes)
+	if block != nil && block.Type == "EC PARAMETERS" {
+		/*
+		 * Openssl prepends an EC PARAMETERS block before the
+		 * key itself.  If we see this first, just skip it,
+		 * and go on to the data block.
+		 */
+		block, _ = pem.Decode(data)
+	}
+	if block != nil && block.Type == "RSA PRIVATE KEY" {
+		/*
+		 * ParsePKCS1PrivateKey returns an RSA private key from its ASN.1
+		 * PKCS#1 DER encoded form.
+		 */
+		privKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
+		if err != nil {
+			return nil, util.FmtNewtError(
+				"Private key parsing failed: %s", err)
+		}
+	}
+	if block != nil && block.Type == "EC PRIVATE KEY" {
+		/*
+		 * ParseECPrivateKey returns a EC private key
+		 */
+		privKey, err = x509.ParseECPrivateKey(block.Bytes)
+		if err != nil {
+			return nil, util.FmtNewtError(
+				"Private key parsing failed: %s", err)
+		}
+	}
+	if block != nil && block.Type == "PRIVATE KEY" {
+		// This indicates a PKCS#8 unencrypted private key.
+		// The particular type of key will be indicated within
+		// the key itself.
+		privKey, err = x509.ParsePKCS8PrivateKey(block.Bytes)
+		if err != nil {
+			return nil, util.FmtNewtError(
+				"Private key parsing failed: %s", err)
+		}
+	}
+	if block != nil && block.Type == "ENCRYPTED PRIVATE KEY" {
+		// This indicates a PKCS#8 key wrapped with PKCS#5
+		// encryption.
+		privKey, err = parseEncryptedPrivateKey(block.Bytes)
+		if err != nil {
+			return nil, util.FmtNewtError("Unable to decode encrypted private key: %s", err)
+		}
+	}
+	if privKey == nil {
+		return nil, util.NewNewtError("Unknown private key format, EC/RSA private " +
+			"key in PEM format only.")
+	}
+
+	return privKey, nil
+}
+
+func ReadKey(filename string) (ImageSigKey, error) {
+	key := ImageSigKey{}
+
+	keyBytes, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return key, util.FmtNewtError("Error reading key file: %s", err)
+	}
+
+	privKey, err := ParsePrivateKey(keyBytes)
+	if err != nil {
+		return key, err
+	}
+
+	switch priv := privKey.(type) {
+	case *rsa.PrivateKey:
+		key.Rsa = priv
+	case *ecdsa.PrivateKey:
+		key.Ec = priv
+	default:
+		return key, util.NewNewtError("Unknown private key format")
+	}
+
+	return key, nil
+}
+
+func ReadKeys(filenames []string) ([]ImageSigKey, error) {
+	keys := make([]ImageSigKey, len(filenames))
+
+	for i, filename := range filenames {
+		key, err := ReadKey(filename)
+		if err != nil {
+			return nil, err
+		}
+
+		keys[i] = key
+	}
+
+	return keys, nil
+}
+
+func (key *ImageSigKey) assertValid() {
+	if key.Rsa == nil && key.Ec == nil {
+		panic("invalid key; neither RSA nor ECC")
+	}
+
+	if key.Rsa != nil && key.Ec != nil {
+		panic("invalid key; neither RSA nor ECC")
+	}
+}
+
+func (key *ImageSigKey) sigKeyHash() ([]uint8, error) {
+	key.assertValid()
+
+	if key.Rsa != nil {
+		pubkey, _ := asn1.Marshal(key.Rsa.PublicKey)
+		sum := sha256.Sum256(pubkey)
+		return sum[:4], nil
+	} else {
+		switch key.Ec.Curve.Params().Name {
+		case "P-224":
+			fallthrough
+		case "P-256":
+			pubkey, _ := x509.MarshalPKIXPublicKey(&key.Ec.PublicKey)
+			sum := sha256.Sum256(pubkey)
+			return sum[:4], nil
+		default:
+			return nil, util.NewNewtError("Unsupported ECC curve")
+		}
+	}
+}
+
+func (key *ImageSigKey) sigLen() uint16 {
+	key.assertValid()
+
+	if key.Rsa != nil {
+		return 256
+	} else {
+		switch key.Ec.Curve.Params().Name {
+		case "P-224":
+			return 68
+		case "P-256":
+			return 72
+		default:
+			return 0
+		}
+	}
+}
+
+func (key *ImageSigKey) sigTlvType() uint8 {
+	key.assertValid()
+
+	if key.Rsa != nil {
+		return IMAGE_TLV_RSA2048
+	} else {
+		switch key.Ec.Curve.Params().Name {
+		case "P-224":
+			return IMAGE_TLV_ECDSA224
+		case "P-256":
+			return IMAGE_TLV_ECDSA256
+		default:
+			return 0
+		}
+	}
+}
+
+func parseEncKeyPem(keyBytes []byte, plainSecret []byte) ([]byte, error) {
+	b, _ := pem.Decode(keyBytes)
+	if b == nil {
+		return nil, nil
+	}
+
+	if b.Type != "PUBLIC KEY" && b.Type != "RSA PUBLIC KEY" {
+		return nil, util.NewNewtError("Invalid PEM file")
+	}
+
+	pub, err := x509.ParsePKIXPublicKey(b.Bytes)
+	if err != nil {
+		return nil, util.FmtNewtError(
+			"Error parsing pubkey file: %s", err.Error())
+	}
+
+	var pubk *rsa.PublicKey
+	switch pub.(type) {
+	case *rsa.PublicKey:
+		pubk = pub.(*rsa.PublicKey)
+	default:
+		return nil, util.FmtNewtError(
+			"Error parsing pubkey file: %s", err.Error())
+	}
+
+	rng := rand.Reader
+	cipherSecret, err := rsa.EncryptOAEP(
+		sha256.New(), rng, pubk, plainSecret, nil)
+	if err != nil {
+		return nil, util.FmtNewtError(
+			"Error from encryption: %s\n", err.Error())
+	}
+
+	return cipherSecret, nil
+}
+
+func parseEncKeyBase64(keyBytes []byte, plainSecret []byte) ([]byte, error) {
+	kek, err := base64.StdEncoding.DecodeString(string(keyBytes))
+	if err != nil {
+		return nil, util.FmtNewtError(
+			"Error decoding kek: %s", err.Error())
+	}
+	if len(kek) != 16 {
+		return nil, util.FmtNewtError(
+			"Unexpected key size: %d != 16", len(kek))
+	}
+
+	cipher, err := aes.NewCipher(kek)
+	if err != nil {
+		return nil, util.FmtNewtError(
+			"Error creating keywrap cipher: %s", err.Error())
+	}
+
+	cipherSecret, err := keywrap.Wrap(cipher, plainSecret)
+	if err != nil {
+		return nil, util.FmtNewtError("Error key-wrapping: %s", err.Error())
+	}
+
+	return cipherSecret, nil
+}
+
+func ReadEncKey(filename string, plainSecret []byte) ([]byte, error) {
+	keyBytes, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return nil, util.FmtNewtError(
+			"Error reading pubkey file: %s", err.Error())
+	}
+
+	// Try reading as PEM (asymetric key).
+	cipherSecret, err := parseEncKeyPem(keyBytes, plainSecret)
+	if err != nil {
+		return nil, err
+	}
+	if cipherSecret != nil {
+		return cipherSecret, nil
+	}
+
+	// Not PEM; assume this is a base64 encoded symetric key
+	cipherSecret, err = parseEncKeyBase64(keyBytes, plainSecret)
+	if err != nil {
+		return nil, err
+	}
+
+	return cipherSecret, nil
+}
diff --git a/image/keys_test.go b/image/keys_test.go
new file mode 100644
index 0000000..577d9cd
--- /dev/null
+++ b/image/keys_test.go
@@ -0,0 +1,244 @@
+/**
+ * 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.
+ */
+
+package image_test
+
+import (
+	"io/ioutil"
+	"os"
+	"path"
+	"testing"
+)
+
+func TestRSA(t *testing.T) {
+	signatureTest(t, rsaPkcs1Private)
+}
+
+func TestPlainRSAPKCS8(t *testing.T) {
+	signatureTest(t, rsaPkcs8Private)
+}
+
+func TestEcdsa(t *testing.T) {
+	signatureTest(t, ecdsaPrivate)
+}
+
+func TestPlainEcdsaPkcs8(t *testing.T) {
+	signatureTest(t, ecdsaPkcs8Private)
+}
+
+func TestEncryptedRSA(t *testing.T) {
+	image.KeyPassword = []byte("sample")
+	signatureTest(t, rsaEncryptedPrivate)
+	image.KeyPassword = []byte{}
+}
+
+func TestEncryptedEcdsa(t *testing.T) {
+	image.KeyPassword = []byte("sample")
+	signatureTest(t, ecdsaEncryptedPrivate)
+	image.KeyPassword = []byte{}
+}
+
+func signatureTest(t *testing.T, privateKey []byte) {
+	tmpdir, err := ioutil.TempDir("", "newttest")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmpdir)
+
+	// Create a source image.  Format doesn't really matter that
+	// much, since the header will be placed on it by the image
+	// tool.
+
+	simpleName := path.Join(tmpdir, "simple.bin")
+	hashedName := path.Join(tmpdir, "simple-hashed.bin")
+	signedName := path.Join(tmpdir, "simple-signed.bin")
+	keyName := path.Join(tmpdir, "private.pem")
+
+	tmp := make([]byte, 256)
+	for i := 0; i < len(tmp); i++ {
+		tmp[i] = byte(i & 0xFF)
+	}
+	err = ioutil.WriteFile(simpleName, tmp, 0644)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	img, err := image.NewImage(simpleName, hashedName)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	img.SetVersion("1.5")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	img.Generate(nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Now try with a signature.
+	err = ioutil.WriteFile(keyName, privateKey, 0644)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	img, err = image.NewImage(simpleName, signedName)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = img.SetSigningKey(keyName, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = img.SetVersion("1.6")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = img.Generate(nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+// An RSA private key in the old PKCS1 format.
+var rsaPkcs1Private = []byte(`-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA6q2Q/VoFf6U5xm35ynls+HDbHKwfIbBr27PtFJxlS9YT0xKJ
+bcZScPTVizTlft0wfp2TctX/vGd/Y/X3qo5ckRmz+lKUeHm46i4k6rtOBbhBz2id
+hwrO7/ylzwaf8lxn2dj/9ikoYQKFtBb/cKu8wyuvW3gs/ou51AVEF8aKTrl5Expy
+PrhSlh97er2zUmm8NAoo259I5yHK1SvR9kCw2gNXSDQLpFlK2WikdmEbIu0N+cvN
+WM4ONAhffkasznrEOoLPSI66RDrzYhi/Ks9t+N2buEOXao19fDRcSHgZLKT8e6W6
+uK7WxRiEzNbajzgDddbZFqWlcpE7sqPNHFBijwIDAQABAoIBAQDdXx7fLpTzROvM
+F5/C9GnrraGzWVYAlIgZ9o8Umzceo3GN8PV8fND1xq7Novc9he8h8QjPEbksg0Dz
+DWo0FBiTs3hIELAHOWNKXH7sggVmddp2iUvXwEVWsq/CK5CjsbExGXbSQR7a6+Mt
+72fEY+wq+0Fuel2PPETuEI2cE+gRuyspIcO7asmMvLRkxLi2EXU0s4JlqV9UfxKQ
+aqn0PHlRXa5SIzys3mVhXuoe45T50+VKX0DIfu/RuV8njNkkMx74DeEVvf5W4MJW
+vHrRBHoK6KoMrqiwafyPLW/Rh6fMYAdPrffMVuuThtG7Hp83VBVX1HxFhI4Jrf3S
+Hf63hmSZAoGBAO2R/vYBl57qgWEKiMQaU8rzctRbP0TtTsqNdISPMnHV1Tn/rNAU
+m0N7/6IBDb+IlndXDQwIsW/DTXhF2XJSu7n6GXua8B1LF+zuVWUsFfmE3+eLz7B8
+x8G/OkSnOTfRZCYWEoEvzhynn1dlADQ+x49I/XmKqccvAhY71glk6WULAoGBAPzi
+IYo9G+ktlNj9/3OciX7aTCiIIMDyPYtYS6wi59gwH9IswaicHYK4w2fDpTWKlzEE
+18dKF4puuI5GxnKCwHBiWxGhij063cZKKMqA64X41csK+mumux/PAb2gKbGSzzoF
+mSgkKXJ+sZ4ytlgsijEAHV85Sw7j+xy8A0qnCWMNAoGAeCDR7q1hcM8duucrvxWc
+90vg7bZyKLVimROsLneGR3+cAWbiiJlS5W3nFpE31XkItLHE/CfNKTl1i/KuAJwL
+JwBrMFBpSDa3k2v0rGL9fZ2N5rSQwapnC/ZZTWvNiAcOgB+7Ha4BqAWuke+VidWQ
+7Ug4O+Q882Y2xO1ezoNDbX8CgYBq228KyAm8PXuRObsw8iuTg9D8q5ETlwj0kcng
+IhvP2X4IxMrMYbOCompHtX9hIYADwaUgXCmYYHLyA+wlRSTmGFmdGKKefvppqLqV
+32YmhWBp3Oi2hoy5wzJcG4qis4OHZAg00xsEe464Z3tvxNpcHE1NCJuz3hglKzlE
+2VJ5HQKBgQDRisWDbdnOEp7LTXp3Aa33PF1Rx/pkFk4Wb+2Hk977O1OxsAin2cKM
+S5HCltHvON2sCmSQUIxMXXKaNPJiGL3UZJxWZDj38zSg0vO+msmemS1Yjt0xCpbO
+pkl0kvKb/NVlsY4w9kquvql+t9e1rUu9Ug28TKEsSjc9SFrcnVPoNA==
+-----END RSA PRIVATE KEY-----
+`)
+
+// An RSA private key in PKCS8 format, with no encryption.
+var rsaPkcs8Private = []byte(`-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC+FjuXqPSPucsQ
+adxY4nw+9kTgAdsXRIPxq4Q//wkfjEjYhDczN+/rafi0hApuRh7PN7VMGOsDGGR1
+edyertiLt3SfUHAZROIqZ0VAoKGtxgXmnC+s+mMujAv9Ssntbmbi5tNxDcltdWjA
+SdBn7tbIMVVofKaMMugyuXCglxebMm8yxtkSgUvE1E6zZERnteDJTPo8dBCiqkvU
+hf+vG9s1j9lNDMjrZ+d5CHIFmBxJ/WFa6m49lNBFb1Ba43bKdj6mkK05rZ4VWMXU
+evy3Z/UUgU4VPJpoB+GIKy82iOrtjiU7s/6aDkvZ2e+fgxKksN0pzFE9azeA73QS
+bamp28E/AgMBAAECggEBAJ78+4UDFOKt1JF66YkSjjcfRkZSZwyUCwP0oF3ik5/m
+dvtZws29KJevgAyEMDFBxv0srB/k65QgL84uSgATYB2kKRAjeE86VSyASeUfNXui
+GEdlNV8p4hEJo/GMP06uu7FmvU1e6a36uM20L3LuyoiQ8s29DJRQ8/ORNQmstlrg
+J32FZSjTF1mElGPSc1koxhWvl1hE7UGE9pxsSfdsvPNhCIWwAOnVnIv49xG8EWaK
+CkHhEVVdZW8IvO9GYR5U0BJcgzNmdNkS8HVQBIxZtboGAAuPI32EC7siDomKmCF6
+rEcs40f/J/RlK6lrTyKKfqWb4DPtRrOSh9cmjrFFZlECgYEA6mZIANLXJd7CINZ9
+fjotI+FxH8BDOZF7l8xTnOk1e3Me1ia7t2GMcIL+frfG/zMBiDFq0IQuUYScRK1v
+pAILjJKFiU6yY8vH6FZ3mXqiiag6RPa+q89DaUsO0uXRUjQvhtTd5Yy6r8Eac1ya
+y6XC5T5sCJ6HgaF3qlheap+5FkkCgYEAz5qSLShV5oekuj1R0fs+h/Yn7VW9Q0sj
+px8jOD4MWc8gPZ9gZe0UPTvofOLrM3eAetP4egSif99AE9iD8EbiBzAt16OX7EN8
+d7xNiIN922Ep3pubcD6f1vglaI7Thrca/p52g6kWPip6+PWFd1acU6u31Uj0Xvgz
+VFiafstF+0cCgYEAw2sOcJFXCZ2Tnyjzav85jwZu95ek9CPUNJQGyXSsQAWUGdok
++hf7q/mqDx9Maoqtpkv8z2bD7vZuCdvGjaee1U16wyS3GPhV69/ayjwxsi5slf5Y
+rIiZnPkUnMM5Jh2X2gMyFCSlp82ILdFwxIOn3tOR4gW411w0lfIilSYgevECgYA3
+JAgVZHREcdzH9seHrWLze+co+6/0cr26guO46YogRIp8s5tIF0tb5FCg8yijl+cR
+OMHzrs12h1aertCEfl9Ep4BVmUcd4uLpbqNtUfeY0FrtnIkRrCCKWYieF+mJC5No
+86/o0n1s752QCK51fxSwiJigVutJWkVP7uTCLr2cuwKBgQCJPWMcWmSuRlLOVWnO
+jPFoa02Bb83n8GrRpQkpkZZofHextwfo2dd1sZF72zghRsbdC6e0Zj1GrekJOYXO
+8AXmCpyKlXJU7iH5tPGSo68uFN05R6mINbTNmEIQBNTKv8UoKT+nHcTycFrVtarX
+A8EPW2xB86m+Bjq/GNyRgfbPMg==
+-----END PRIVATE KEY-----
+`)
+
+// An ECDSA key in the X.509 internal private key format.
+var ecdsaPrivate = []byte(`-----BEGIN EC PRIVATE KEY-----
+MGgCAQEEHF64kDx3pZyVvezbqYMIxlLbtuPQmI85k4GRy1mgBwYFK4EEACGhPAM6
+AASRtolOCTLQYkDefkIF02tUXR92MKHrbtH4WK/8bfTSFVkaygTPdJbpNthK2wae
+oX9ZeFHS1pcOfQ==
+-----END EC PRIVATE KEY-----
+`)
+
+// An ECDSA key in PKCS#8 format, no encryption.
+var ecdsaPkcs8Private = []byte(`-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgHKeDq4UU6M+c+pMm
+j0AQZlBs7f4r67668eDCUB8aDR2hRANCAATyZPzsx+xn9JtlxdspevTrYisiMTjl
+YuBJCrV1FZj2HkplEgO+ZIMuD7eRvyTEBS2bw6F1aCeKOMUmYVImAbpc
+-----END PRIVATE KEY-----
+`)
+
+// A password-protected RSA private key in PKCS#5/8 format.  The
+// password for this key is "sample".
+var rsaEncryptedPrivate = []byte(`-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIRMifqJThk8kCAggA
+MB0GCWCGSAFlAwQBKgQQTMUBoFpzjJ5UNRnCIeqf4QSCBNDkQvXnUNmss8erKiDo
+Uqs2tf9ZD8MjDThLBmF/gV1dg1q6aDY+3fI2E4yLXJb2PmKcUq82YZ0FDeoCvJRJ
+BCurzM9slur5akpNBTFoFwtFsdHz7nKNS4MHUul22rGBnVFUUNTySmpjl/m+dxWO
+fa6tWpGTAr7tsCy9gF5PxpSw7NR/NpIL0PmpydHWhTs1tl2csqBqK6Tp014Kefi/
+pmmeb2eRl5cmprxW32rW2QBMtv4z91SsbnlVdz4r8txTG+3S4td9v9jD5kqcIiC2
+KQHrbH9y7okUk/ISsp9ANKPJt10fbYDxORiMK57XssXy1enGjpkIIrUGz1TMydkD
+USfwqkmPuIrrzOXnbxU4ef2wC/pA/h9Smby3WWYo8725/1kZyIediNDcgi/Qgrs4
+1VQAYzsD6duwyUNSo+tgmYVFGvZhsottus3fMWe/Ay1biJ6z6Vk8gqKWI1VV/REJ
+zK/I9hgKGxj2N2Ff6E/YkcwQenHWj/iDWLjvokyOBnPFNqzzM2Qqo1XFpzj4EO5D
+0WD4EzZYvUhk3lZZNydvXiuy8RrCVLLJMS08XgOqQaiFqqxj2hjRwv3nBesk7iA8
+5Tv8GMa5QkNrISCnp4/uGBh+v/CjwVRqPTcK3/mctPN2nLhI6H4pF4Y6apXkz1TN
+NMQqxaxmVVg8fyLaS4/xfUr8LAmiEtOwvs0XOhcqCTvvlsO4N+yec4VD4gmsTDY9
+/2b/+YwSlGMpA+GQQbg0FraaF8NyJRG1mSER6WiUGGM1cuKK44nzBbykQbZwzDSA
+kkhjDaadkhv/NPKAUR3sNy2GXVaNL/ItCpQUHRKKcIPp0HhdXsl0YebuwRlHjw/6
+UOdzNYe23e40X/Xl3vmOKRbzhLP/qO2DV21o0wI4ujF8Xu5h1h8s49HPp58G1ldy
+/hJ6durYKX8T5khiR2iXYewoy0YObuccV//Ov1/ySOp/x0/QuCl/swvs8Jf7awnu
+rpRrHPArpCvMmXmt5Y+TFYXFjkJGwsxTew5TcwBebBlIET2XNbo2pbz4WqJ3eVlK
+CNZVDEZ8mMrGT00FBi759Vfw9rhrnqXnLlNtJZ5VCXFUw8Tos302sLaQWXzHYyf8
+4awM8G9PSu5Q9lFcN9od4H95YrAAv/l8F+pcGgEKD8ZuzsgFIalqgx5wzmUMDcPM
+NKV5u9mtHjI92ru6NB8rGesM6sy6kBGvpotsDWawpV2SoCrkbyEkk+kXaGS+fsG7
+D2H37GfktN8R5Ktc0Uf/JJiNfDzq8lk1J4r7LBQlWUbhKbfGMYxt+7Xo0GsqAsLp
+PKSUwx+hTZb3BmW6s4Q6vivI1MdQbWVT1zh41StvfRSNlo70iOFxOM0lU1jjY989
+UKo+gcolddvZbMNwip0ILPO3dsa+he1jJ/gbo9qBHLy7plfsBLLakZP1Nu6xdlqQ
+TSSobaE8uxUMZk+wMWClA9AOZ1TcUr2yRV5GVj/bxG9ab+H37vF9F8vFE+jjJ7yN
+6pjdohm4gXeSVx7ON4SeZLsVwNYkCVYS89E81qLx1jP9F57+6IUGDZN5EMC0aJLT
+ny75MCCLT00KD7BFsb0KDLXxp++eu/L2hinorT3p6dXp/9mUoxmy6wJqEyqCFniZ
+N2GZN7+LDTIbHUxCijVWamU2DQ==
+-----END ENCRYPTED PRIVATE KEY-----
+`)
+
+// A password-protected ECDSA private key in PKCS#5/8 format.  The
+// password for this key is "sample"
+var ecdsaEncryptedPrivate = []byte(`-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHeMEkGCSqGSIb3DQEFDTA8MBsGCSqGSIb3DQEFDDAOBAjlKrDSKNg9QQICCAAw
+HQYJYIZIAWUDBAEqBBDliPNzQTNpdlppTcYpmuhWBIGQVhfWaVSzUvi/qIZLiZVn
+Nulfw5jDOlbn3UBX9kp/Z9Pro582Q0kjzLfm5UahvDINEJWxL4pc/28UnGQTBr0Q
+nSEg+RbqpuD099C38H0Gq/YkIM+RDG4aiQrkmzHXyVsHshIbG+z2LsLTIwmU69/Z
+v0nX6/hGErVR8YWcrOne086rCvfJVrxyO5+EUqrkLhEr
+-----END ENCRYPTED PRIVATE KEY-----
+`)
diff --git a/image/v1.go b/image/v1.go
new file mode 100644
index 0000000..bab86f6
--- /dev/null
+++ b/image/v1.go
@@ -0,0 +1,487 @@
+/**
+ * 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 file implements parsing and generation of version-1 images.  Much of
+// this code duplicates the v2 code.  The expectation is that this file will be
+// removed when version 1 is oficially retired (soon).
+
+package image
+
+import (
+	"bytes"
+	"crypto"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/sha256"
+	"encoding/binary"
+	"encoding/hex"
+	"io"
+	"io/ioutil"
+
+	"mynewt.apache.org/newt/util"
+)
+
+const IMAGEv1_MAGIC = 0x96f3b83c /* Image header magic */
+
+const (
+	IMAGEv1_F_PIC                      = 0x00000001
+	IMAGEv1_F_SHA256                   = 0x00000002 /* Image contains hash TLV */
+	IMAGEv1_F_PKCS15_RSA2048_SHA256    = 0x00000004 /* PKCS15 w/RSA2048 and SHA256 */
+	IMAGEv1_F_ECDSA224_SHA256          = 0x00000008 /* ECDSA224 over SHA256 */
+	IMAGEv1_F_NON_BOOTABLE             = 0x00000010 /* non bootable image */
+	IMAGEv1_F_ECDSA256_SHA256          = 0x00000020 /* ECDSA256 over SHA256 */
+	IMAGEv1_F_PKCS1_PSS_RSA2048_SHA256 = 0x00000040 /* RSA-PSS w/RSA2048 and SHA256 */
+)
+
+const (
+	IMAGEv1_TLV_SHA256   = 1
+	IMAGEv1_TLV_RSA2048  = 2
+	IMAGEv1_TLV_ECDSA224 = 3
+	IMAGEv1_TLV_ECDSA256 = 4
+)
+
+// Set this to enable RSA-PSS for RSA signatures, instead of PKCS#1
+// v1.5.  Eventually, this should be the default.
+var UseRsaPss = false
+
+type ImageHdrV1 struct {
+	Magic uint32
+	TlvSz uint16
+	KeyId uint8
+	Pad1  uint8
+	HdrSz uint16
+	Pad2  uint16
+	ImgSz uint32
+	Flags uint32
+	Vers  ImageVersion
+	Pad3  uint32
+}
+
+type ImageV1 struct {
+	Header ImageHdrV1
+	Body   []byte
+	Tlvs   []ImageTlv
+}
+
+func (img *ImageV1) FindTlvs(tlvType uint8) []ImageTlv {
+	var tlvs []ImageTlv
+
+	for _, tlv := range img.Tlvs {
+		if tlv.Header.Type == tlvType {
+			tlvs = append(tlvs, tlv)
+		}
+	}
+
+	return tlvs
+}
+
+func (img *ImageV1) Hash() ([]byte, error) {
+	tlvs := img.FindTlvs(IMAGEv1_TLV_SHA256)
+	if len(tlvs) == 0 {
+		return nil, util.FmtNewtError("Image does not contain hash TLV")
+	}
+	if len(tlvs) > 1 {
+		return nil, util.FmtNewtError("Image contains %d hash TLVs", len(tlvs))
+	}
+
+	return tlvs[0].Data, nil
+}
+
+func (img *ImageV1) WritePlusOffsets(w io.Writer) (ImageOffsets, error) {
+	offs := ImageOffsets{}
+	offset := 0
+
+	offs.Header = offset
+
+	err := binary.Write(w, binary.LittleEndian, &img.Header)
+	if err != nil {
+		return offs, util.ChildNewtError(err)
+	}
+	offset += IMAGE_HEADER_SIZE
+
+	offs.Body = offset
+	size, err := w.Write(img.Body)
+	if err != nil {
+		return offs, util.ChildNewtError(err)
+	}
+	offset += size
+
+	for _, tlv := range img.Tlvs {
+		offs.Tlvs = append(offs.Tlvs, offset)
+		size, err := tlv.Write(w)
+		if err != nil {
+			return offs, util.ChildNewtError(err)
+		}
+		offset += size
+	}
+
+	offs.TotalSize = offset
+
+	return offs, nil
+}
+
+func (img *ImageV1) Offsets() (ImageOffsets, error) {
+	return img.WritePlusOffsets(ioutil.Discard)
+}
+
+func (img *ImageV1) TotalSize() (int, error) {
+	offs, err := img.Offsets()
+	if err != nil {
+		return 0, err
+	}
+	return offs.TotalSize, nil
+}
+
+func (img *ImageV1) Write(w io.Writer) (int, error) {
+	offs, err := img.WritePlusOffsets(w)
+	if err != nil {
+		return 0, err
+	}
+
+	return offs.TotalSize, nil
+}
+
+func (key *ImageSigKey) sigHdrTypeV1() (uint32, error) {
+	key.assertValid()
+
+	if key.Rsa != nil {
+		if UseRsaPss {
+			return IMAGEv1_F_PKCS1_PSS_RSA2048_SHA256, nil
+		} else {
+			return IMAGEv1_F_PKCS15_RSA2048_SHA256, nil
+		}
+	} else {
+		switch key.Ec.Curve.Params().Name {
+		case "P-224":
+			return IMAGEv1_F_ECDSA224_SHA256, nil
+		case "P-256":
+			return IMAGEv1_F_ECDSA256_SHA256, nil
+		default:
+			return 0, util.FmtNewtError("Unsupported ECC curve")
+		}
+	}
+}
+
+func (key *ImageSigKey) sigTlvTypeV1() uint8 {
+	key.assertValid()
+
+	if key.Rsa != nil {
+		return IMAGEv1_TLV_RSA2048
+	} else {
+		switch key.Ec.Curve.Params().Name {
+		case "P-224":
+			return IMAGEv1_TLV_ECDSA224
+		case "P-256":
+			return IMAGEv1_TLV_ECDSA256
+		default:
+			return 0
+		}
+	}
+}
+
+func generateV1SigRsa(key *rsa.PrivateKey, hash []byte) ([]byte, error) {
+	var signature []byte
+	var err error
+
+	if UseRsaPss {
+		opts := rsa.PSSOptions{
+			SaltLength: rsa.PSSSaltLengthEqualsHash,
+		}
+		signature, err = rsa.SignPSS(
+			rand.Reader, key, crypto.SHA256, hash, &opts)
+	} else {
+		signature, err = rsa.SignPKCS1v15(
+			rand.Reader, key, crypto.SHA256, hash)
+	}
+	if err != nil {
+		return nil, util.FmtNewtError("Failed to compute signature: %s", err)
+	}
+
+	return signature, nil
+}
+
+func generateV1SigTlvRsa(key ImageSigKey, hash []byte) (ImageTlv, error) {
+	sig, err := generateV1SigRsa(key.Rsa, hash)
+	if err != nil {
+		return ImageTlv{}, err
+	}
+
+	return ImageTlv{
+		Header: ImageTlvHdr{
+			Type: key.sigTlvTypeV1(),
+			Pad:  0,
+			Len:  256, /* 2048 bits */
+		},
+		Data: sig,
+	}, nil
+}
+
+func generateV1SigTlvEc(key ImageSigKey, hash []byte) (ImageTlv, error) {
+	sig, err := generateSigEc(key.Ec, hash)
+	if err != nil {
+		return ImageTlv{}, err
+	}
+
+	sigLen := key.sigLen()
+	if len(sig) > int(sigLen) {
+		return ImageTlv{}, util.FmtNewtError("Something is really wrong\n")
+	}
+
+	b := &bytes.Buffer{}
+
+	if _, err := b.Write(sig); err != nil {
+		return ImageTlv{},
+			util.FmtNewtError("Failed to append sig: %s", err.Error())
+	}
+
+	pad := make([]byte, int(sigLen)-len(sig))
+	if _, err := b.Write(pad); err != nil {
+		return ImageTlv{}, util.FmtNewtError(
+			"Failed to serialize image trailer: %s", err.Error())
+	}
+
+	return ImageTlv{
+		Header: ImageTlvHdr{
+			Type: key.sigTlvTypeV1(),
+			Pad:  0,
+			Len:  sigLen + uint16(len(pad)),
+		},
+		Data: b.Bytes(),
+	}, nil
+}
+
+func generateV1SigTlv(key ImageSigKey, hash []byte) (ImageTlv, error) {
+	key.assertValid()
+
+	if key.Rsa != nil {
+		return generateV1SigTlvRsa(key, hash)
+	} else {
+		return generateV1SigTlvEc(key, hash)
+	}
+}
+
+func calcHashV1(initialHash []byte, hdr ImageHdrV1,
+	plainBody []byte) ([]byte, error) {
+
+	hash := sha256.New()
+
+	add := func(itf interface{}) error {
+		if err := binary.Write(hash, binary.LittleEndian, itf); err != nil {
+			return util.FmtNewtError("Failed to hash data: %s", err.Error())
+		}
+
+		return nil
+	}
+
+	if initialHash != nil {
+		if err := add(initialHash); err != nil {
+			return nil, err
+		}
+	}
+
+	if err := add(hdr); err != nil {
+		return nil, err
+	}
+
+	extra := hdr.HdrSz - IMAGE_HEADER_SIZE
+	if extra > 0 {
+		b := make([]byte, extra)
+		if err := add(b); err != nil {
+			return nil, err
+		}
+	}
+
+	if err := add(plainBody); err != nil {
+		return nil, err
+	}
+
+	return hash.Sum(nil), nil
+}
+
+func (ic *ImageCreator) CreateV1() (ImageV1, error) {
+	ri := ImageV1{}
+
+	if len(ic.SigKeys) > 1 {
+		return ri, util.FmtNewtError(
+			"V1 image format only allows one key, %d keys specified",
+			len(ic.SigKeys))
+	}
+
+	// First the header
+	hdr := ImageHdrV1{
+		Magic: IMAGEv1_MAGIC,
+		TlvSz: 0, // Filled in later.
+		KeyId: 0,
+		Pad1:  0,
+		HdrSz: IMAGE_HEADER_SIZE,
+		Pad2:  0,
+		ImgSz: uint32(len(ic.Body)),
+		Flags: IMAGEv1_F_SHA256,
+		Vers:  ic.Version,
+		Pad3:  0,
+	}
+
+	if !ic.Bootable {
+		hdr.Flags |= IMAGEv1_F_NON_BOOTABLE
+	}
+
+	if ic.HeaderSize != 0 {
+		/*
+		 * Pad the header out to the given size.  There will
+		 * just be zeros between the header and the start of
+		 * the image when it is padded.
+		 */
+		if ic.HeaderSize < IMAGE_HEADER_SIZE {
+			return ri, util.FmtNewtError("Image header must be at "+
+				"least %d bytes", IMAGE_HEADER_SIZE)
+		}
+
+		hdr.HdrSz = uint16(ic.HeaderSize)
+	}
+
+	if len(ic.SigKeys) > 0 {
+		keyFlag, err := ic.SigKeys[0].sigHdrTypeV1()
+		if err != nil {
+			return ri, err
+		}
+		hdr.Flags |= keyFlag
+		hdr.TlvSz = 4 + ic.SigKeys[0].sigLen()
+	}
+	hdr.TlvSz += 4 + 32
+
+	if hdr.HdrSz > IMAGE_HEADER_SIZE {
+		// Pad the header out to the given size.  There will
+		// just be zeros between the header and the start of
+		// the image when it is padded.
+		extra := ic.HeaderSize - IMAGE_HEADER_SIZE
+		if extra < 0 {
+			return ri, util.FmtNewtError("Image header must be at "+
+				"least %d bytes", IMAGE_HEADER_SIZE)
+		}
+
+		hdr.HdrSz = uint16(ic.HeaderSize)
+		for i := 0; i < extra; i++ {
+			ri.Body = append(ri.Body, 0)
+		}
+	}
+
+	hashBytes, err := calcHashV1(ic.InitialHash, hdr, ic.Body)
+	if err != nil {
+		return ri, err
+	}
+
+	util.StatusMessage(util.VERBOSITY_VERBOSE,
+		"Computed Hash for image as %s\n", hex.EncodeToString(hashBytes))
+
+	/*
+	 * Followed by data.
+	 */
+	dataBuf := make([]byte, 1024)
+	r := bytes.NewReader(ic.Body)
+	w := bytes.Buffer{}
+	for {
+		cnt, err := r.Read(dataBuf)
+		if err != nil && err != io.EOF {
+			return ri, util.FmtNewtError(
+				"Failed to read from image body: %s", err.Error())
+		}
+		if cnt == 0 {
+			break
+		}
+
+		if _, err = w.Write(dataBuf[0:cnt]); err != nil {
+			return ri, util.FmtNewtError(
+				"Failed to write to image body: %s", err.Error())
+		}
+	}
+	ri.Body = w.Bytes()
+
+	// Hash TLV.
+	tlv := ImageTlv{
+		Header: ImageTlvHdr{
+			Type: IMAGEv1_TLV_SHA256,
+			Pad:  0,
+			Len:  uint16(len(hashBytes)),
+		},
+		Data: hashBytes,
+	}
+	ri.Tlvs = append(ri.Tlvs, tlv)
+
+	if len(ic.SigKeys) > 0 {
+		tlv, err := generateV1SigTlv(ic.SigKeys[0], hashBytes)
+		if err != nil {
+			return ri, err
+		}
+		ri.Tlvs = append(ri.Tlvs, tlv)
+	}
+
+	offs, err := ri.Offsets()
+	if err != nil {
+		return ri, err
+	}
+	hdr.TlvSz = uint16(offs.TotalSize - offs.Tlvs[0])
+
+	ri.Header = hdr
+
+	return ri, nil
+}
+
+func GenerateV1Image(opts ImageCreateOpts) (ImageV1, error) {
+	ic := NewImageCreator()
+
+	srcBin, err := ioutil.ReadFile(opts.SrcBinFilename)
+	if err != nil {
+		return ImageV1{}, util.FmtNewtError(
+			"Can't read app binary: %s", err.Error())
+	}
+
+	ic.Body = srcBin
+	ic.Version = opts.Version
+	ic.SigKeys = opts.SigKeys
+
+	if opts.LoaderHash != nil {
+		ic.InitialHash = opts.LoaderHash
+		ic.Bootable = false
+	} else {
+		ic.Bootable = true
+	}
+
+	if opts.SrcEncKeyFilename != "" {
+		plainSecret := make([]byte, 16)
+		if _, err := rand.Read(plainSecret); err != nil {
+			return ImageV1{}, util.FmtNewtError(
+				"Random generation error: %s\n", err)
+		}
+
+		cipherSecret, err := ReadEncKey(opts.SrcEncKeyFilename, plainSecret)
+		if err != nil {
+			return ImageV1{}, err
+		}
+
+		ic.PlainSecret = plainSecret
+		ic.CipherSecret = cipherSecret
+	}
+
+	ri, err := ic.CreateV1()
+	if err != nil {
+		return ImageV1{}, err
+	}
+
+	return ri, nil
+}
diff --git a/manifest/manifest.go b/manifest/manifest.go
new file mode 100644
index 0000000..62d8c06
--- /dev/null
+++ b/manifest/manifest.go
@@ -0,0 +1,95 @@
+package manifest
+
+import (
+	"encoding/json"
+	"io"
+	"io/ioutil"
+
+	"mynewt.apache.org/newt/artifact/flash"
+	"mynewt.apache.org/newt/util"
+)
+
+/*
+ * Data that's going to go to build manifest file
+ */
+type ManifestSizeArea struct {
+	Name string `json:"name"`
+	Size uint32 `json:"size"`
+}
+
+type ManifestSizeSym struct {
+	Name  string              `json:"name"`
+	Areas []*ManifestSizeArea `json:"areas"`
+}
+
+type ManifestSizeFile struct {
+	Name string             `json:"name"`
+	Syms []*ManifestSizeSym `json:"sym"`
+}
+
+type ManifestSizePkg struct {
+	Name  string              `json:"name"`
+	Files []*ManifestSizeFile `json:"files"`
+}
+
+type ManifestPkg struct {
+	Name string `json:"name"`
+	Repo string `json:"repo"`
+}
+
+type ManifestRepo struct {
+	Name   string `json:"name"`
+	Commit string `json:"commit"`
+	Dirty  bool   `json:"dirty,omitempty"`
+	URL    string `json:"url,omitempty"`
+}
+
+type Manifest struct {
+	Name       string            `json:"name"`
+	Date       string            `json:"build_time"`
+	Version    string            `json:"build_version"`
+	BuildID    string            `json:"id"`
+	Image      string            `json:"image"`
+	ImageHash  string            `json:"image_hash"`
+	Loader     string            `json:"loader"`
+	LoaderHash string            `json:"loader_hash"`
+	Pkgs       []*ManifestPkg    `json:"pkgs"`
+	LoaderPkgs []*ManifestPkg    `json:"loader_pkgs,omitempty"`
+	TgtVars    []string          `json:"target"`
+	Repos      []*ManifestRepo   `json:"repos"`
+	FlashAreas []flash.FlashArea `json:"flash_map"`
+
+	PkgSizes       []*ManifestSizePkg `json:"pkgsz"`
+	LoaderPkgSizes []*ManifestSizePkg `json:"loader_pkgsz,omitempty"`
+}
+
+func ReadManifest(path string) (Manifest, error) {
+	m := Manifest{}
+
+	content, err := ioutil.ReadFile(path)
+	if err != nil {
+		return m, util.ChildNewtError(err)
+	}
+
+	if err := json.Unmarshal(content, &m); err != nil {
+		return m, util.FmtNewtError(
+			"Failure decoding manifest with path \"%s\": %s",
+			path, err.Error())
+	}
+
+	return m, nil
+}
+
+func (m *Manifest) Write(w io.Writer) (int, error) {
+	buffer, err := json.MarshalIndent(m, "", "  ")
+	if err != nil {
+		return 0, util.FmtNewtError("Cannot encode manifest: %s", err.Error())
+	}
+
+	cnt, err := w.Write(buffer)
+	if err != nil {
+		return 0, util.FmtNewtError("Cannot write manifest: %s", err.Error())
+	}
+
+	return cnt, nil
+}
