diff mbox series

[meta-swupdate] Support for image encryption

Message ID 20180405135636.20560-1-vincent.dehors@smile.fr
State Changes Requested
Headers show
Series [meta-swupdate] Support for image encryption | expand

Commit Message

Vincent DEHORS April 5, 2018, 1:56 p.m. UTC
This commit allows to automatically encrypt image files by setting the
following variables in bundle recipes :
SWUPDATE_ENCRYPT = "AES-CBC"
SWUPDATE_ENCRYPT_KEY = "[path to the symetric key]"
SWUPDATE_ENCRYPT_FILES[image-name] = "1"

The encryption key is the same file as described in the documentation
containing hex-encoded key, iv and salt.

In sw-description file, the encrypted image must have 'encrypted = true'
The '.enc' extension is automatically added, so filenames in sw-description
should end with ".enc" and the ones in Yocto recipe should not.

Note that, with this implementation, additional files set in SRC_URI
cannot be encrypted.

Signed-off-by: Vincent Dehors <vincent.dehors@smile.fr>
Cc: Astree Mendoza <astree_mendoza@bookeen.com>
Cc: Christophe Barbe <christophe_barbe@bookeen.com>
---
 classes/swupdate.bbclass | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

Comments

Stefano Babic April 6, 2018, 1:23 p.m. UTC | #1
Hi Vincent,

On 05/04/2018 15:56, Vincent Dehors wrote:
> This commit allows to automatically encrypt image files by setting the
> following variables in bundle recipes :
> SWUPDATE_ENCRYPT = "AES-CBC"
> SWUPDATE_ENCRYPT_KEY = "[path to the symetric key]"
> SWUPDATE_ENCRYPT_FILES[image-name] = "1"
> 
> The encryption key is the same file as described in the documentation
> containing hex-encoded key, iv and salt.
> 
> In sw-description file, the encrypted image must have 'encrypted = true'
> The '.enc' extension is automatically added, so filenames in sw-description
> should end with ".enc" and the ones in Yocto recipe should not.
> 
> Note that, with this implementation, additional files set in SRC_URI
> cannot be encrypted.

Thanks for patch - anyway, I am thinking about if this is the correct
way to do. In fact, the encryption could be thought as a different type
of "conversion", like compression is currently in OE. A more general
approach could be to add a new image type to IMAGE_FSTYPES, and then the
encryption coul be used in more general way, like "rootfs.ext4.enc.gz".
A new class could be added to meta-swupdate, but with the goal to push
it to OE mainline.

What do you think about ?

Best regards,
Stefano Babic

> 
> Signed-off-by: Vincent Dehors <vincent.dehors@smile.fr>
> Cc: Astree Mendoza <astree_mendoza@bookeen.com>
> Cc: Christophe Barbe <christophe_barbe@bookeen.com>
> ---
>  classes/swupdate.bbclass | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/classes/swupdate.bbclass b/classes/swupdate.bbclass
> index 02db631..570ef3e 100644
> --- a/classes/swupdate.bbclass
> +++ b/classes/swupdate.bbclass
> @@ -64,6 +64,23 @@ def swupdate_getdepends(d):
>          depstr += " " + dep + ":do_build"
>      return depstr
>  
> +def swupdate_encrypt_aes_cbc(s, clearfile, encryptedfile, encryption_key):
> +    infile = os.path.join(s, clearfile)
> +    outfile = os.path.join(s, encryptedfile)
> +
> +    with open(encryption_key, 'r') as f:
> +        keys_part = f.read().split(" ")
> +
> +    enccmd = "openssl enc -aes-256-cbc -in '%s' -out '%s' -K '%s' -iv '%s' -S '%s'" % (
> +        infile,
> +        outfile,
> +        keys_part[0],
> +        keys_part[1],
> +        keys_part[2])
> +
> +    if os.system(enccmd) != 0:
> +        bb.fatal("Failed to encrypt file %s with %s" % (clearfile, encryption_key))
> +
>  IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"
>  
>  do_swuimage[dirs] = "${TOPDIR}"
> @@ -96,6 +113,7 @@ python do_swuimage () {
>  
>      workdir = d.getVar('WORKDIR', True)
>      images = (d.getVar('SWUPDATE_IMAGES', True) or "").split()
> +    encryption = d.getVar('SWUPDATE_ENCRYPT', True)
>      s = d.getVar('S', True)
>      shutil.copyfile(os.path.join(workdir, "sw-description"), os.path.join(s, "sw-description"))
>      fetch = bb.fetch2.Fetch([], d)
> @@ -134,6 +152,20 @@ python do_swuimage () {
>              src = os.path.join(deploydir, "%s" % imagename)
>              dst = os.path.join(s, "%s" % imagename)
>              shutil.copyfile(src, dst)
> +
> +            if encryption == "AES-CBC":
> +                need_encryption = d.getVarFlag("SWUPDATE_ENCRYPT_FILES", image, True)
> +                if need_encryption == "1":
> +                    encryption_key = d.getVar("SWUPDATE_ENCRYPT_KEY", True)
> +                    if not encryption_key:
> +                        bb.fatal("SWUPDATE_ENCRYPT_KEY isn't set")
> +                    if not os.path.exists(encryption_key):
> +                        bb.fatal("SWUPDATE_ENCRYPT_KEY %s doesn't exist" % (encryption_key))
> +                    clearfile = imagename
> +                    encryptedfile = imagename + '.enc'
> +                    swupdate_encrypt_aes_cbc(s, clearfile, encryptedfile, encryption_key)
> +                    imagename = encryptedfile
> +
>              list_for_cpio.append(imagename)
>  
>      for file in list_for_cpio:
>
Vincent DEHORS April 12, 2018, 1:36 p.m. UTC | #2
Hi Stefano, 

I agree with you, we could do it using an
IMAGE_FSTYPES but it will prevent us from using encryption for non-image
artifacts (like scripts or files). I will try an implementation using
IMAGE_FSTYPE. 

Regards, 

Vincent 

Le 2018-04-06 15:23, Stefano Babic
a écrit : 

> Hi Vincent,
> 
> On 05/04/2018 15:56, Vincent Dehors
wrote:
> 
>> This commit allows to automatically encrypt image files by
setting the following variables in bundle recipes : SWUPDATE_ENCRYPT =
"AES-CBC" SWUPDATE_ENCRYPT_KEY = "[path to the symetric key]"
SWUPDATE_ENCRYPT_FILES[image-name] = "1" The encryption key is the same
file as described in the documentation containing hex-encoded key, iv
and salt. In sw-description file, the encrypted image must have
'encrypted = true' The '.enc' extension is automatically added, so
filenames in sw-description should end with ".enc" and the ones in Yocto
recipe should not. Note that, with this implementation, additional files
set in SRC_URI cannot be encrypted.
> 
> Thanks for patch - anyway, I am
thinking about if this is the correct
> way to do. In fact, the
encryption could be thought as a different type
> of "conversion", like
compression is currently in OE. A more general
> approach could be to
add a new image type to IMAGE_FSTYPES, and then the
> encryption coul be
used in more general way, like "rootfs.ext4.enc.gz".
> A new class could
be added to meta-swupdate, but with the goal to push
> it to OE
mainline.
> 
> What do you think about ?
> 
> Best regards,
> Stefano
Babic
> 
>> Signed-off-by: Vincent Dehors <vincent.dehors@smile.fr> Cc:
Astree Mendoza <astree_mendoza@bookeen.com> Cc: Christophe Barbe
<christophe_barbe@bookeen.com> --- classes/swupdate.bbclass | 32
++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff
--git a/classes/swupdate.bbclass b/classes/swupdate.bbclass index
02db631..570ef3e 100644 --- a/classes/swupdate.bbclass +++
b/classes/swupdate.bbclass @@ -64,6 +64,23 @@ def
swupdate_getdepends(d): depstr += " " + dep + ":do_build" return depstr
+def swupdate_encrypt_aes_cbc(s, clearfile, encryptedfile,
encryption_key): + infile = os.path.join(s, clearfile) + outfile =
os.path.join(s, encryptedfile) + + with open(encryption_key, 'r') as f:
+ keys_part = f.read().split(" ") + + enccmd = "openssl enc -aes-256-cbc
-in '%s' -out '%s' -K '%s' -iv '%s' -S '%s'" % ( + infile, + outfile, +
keys_part[0], + keys_part[1], + keys_part[2]) + + if os.system(enccmd)
!= 0: + bb.fatal("Failed to encrypt file %s with %s" % (clearfile,
encryption_key)) + IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"
do_swuimage[dirs] = "${TOPDIR}" @@ -96,6 +113,7 @@ python do_swuimage ()
{ workdir = d.getVar('WORKDIR', True) images =
(d.getVar('SWUPDATE_IMAGES', True) or "").split() + encryption =
d.getVar('SWUPDATE_ENCRYPT', True) s = d.getVar('S', True)
shutil.copyfile(os.path.join(workdir, "sw-description"), os.path.join(s,
"sw-description")) fetch = bb.fetch2.Fetch([], d) @@ -134,6 +152,20 @@
python do_swuimage () { src = os.path.join(deploydir, "%s" % imagename)
dst = os.path.join(s, "%s" % imagename) shutil.copyfile(src, dst) + + if
encryption == "AES-CBC": + need_encryption =
d.getVarFlag("SWUPDATE_ENCRYPT_FILES", image, True) + if need_encryption
== "1": + encryption_key = d.getVar("SWUPDATE_ENCRYPT_KEY", True) + if
not encryption_key: + bb.fatal("SWUPDATE_ENCRYPT_KEY isn't set") + if
not os.path.exists(encryption_key): + bb.fatal("SWUPDATE_ENCRYPT_KEY %s
doesn't exist" % (encryption_key)) + clearfile = imagename +
encryptedfile = imagename + '.enc' + swupdate_encrypt_aes_cbc(s,
clearfile, encryptedfile, encryption_key) + imagename = encryptedfile +
list_for_cpio.append(imagename) for file in list_for_cpio:
diff mbox series

Patch

diff --git a/classes/swupdate.bbclass b/classes/swupdate.bbclass
index 02db631..570ef3e 100644
--- a/classes/swupdate.bbclass
+++ b/classes/swupdate.bbclass
@@ -64,6 +64,23 @@  def swupdate_getdepends(d):
         depstr += " " + dep + ":do_build"
     return depstr
 
+def swupdate_encrypt_aes_cbc(s, clearfile, encryptedfile, encryption_key):
+    infile = os.path.join(s, clearfile)
+    outfile = os.path.join(s, encryptedfile)
+
+    with open(encryption_key, 'r') as f:
+        keys_part = f.read().split(" ")
+
+    enccmd = "openssl enc -aes-256-cbc -in '%s' -out '%s' -K '%s' -iv '%s' -S '%s'" % (
+        infile,
+        outfile,
+        keys_part[0],
+        keys_part[1],
+        keys_part[2])
+
+    if os.system(enccmd) != 0:
+        bb.fatal("Failed to encrypt file %s with %s" % (clearfile, encryption_key))
+
 IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"
 
 do_swuimage[dirs] = "${TOPDIR}"
@@ -96,6 +113,7 @@  python do_swuimage () {
 
     workdir = d.getVar('WORKDIR', True)
     images = (d.getVar('SWUPDATE_IMAGES', True) or "").split()
+    encryption = d.getVar('SWUPDATE_ENCRYPT', True)
     s = d.getVar('S', True)
     shutil.copyfile(os.path.join(workdir, "sw-description"), os.path.join(s, "sw-description"))
     fetch = bb.fetch2.Fetch([], d)
@@ -134,6 +152,20 @@  python do_swuimage () {
             src = os.path.join(deploydir, "%s" % imagename)
             dst = os.path.join(s, "%s" % imagename)
             shutil.copyfile(src, dst)
+
+            if encryption == "AES-CBC":
+                need_encryption = d.getVarFlag("SWUPDATE_ENCRYPT_FILES", image, True)
+                if need_encryption == "1":
+                    encryption_key = d.getVar("SWUPDATE_ENCRYPT_KEY", True)
+                    if not encryption_key:
+                        bb.fatal("SWUPDATE_ENCRYPT_KEY isn't set")
+                    if not os.path.exists(encryption_key):
+                        bb.fatal("SWUPDATE_ENCRYPT_KEY %s doesn't exist" % (encryption_key))
+                    clearfile = imagename
+                    encryptedfile = imagename + '.enc'
+                    swupdate_encrypt_aes_cbc(s, clearfile, encryptedfile, encryption_key)
+                    imagename = encryptedfile
+
             list_for_cpio.append(imagename)
 
     for file in list_for_cpio: