Skip to content

Conversation

@stefanberger
Copy link
Contributor

@stefanberger stefanberger commented Aug 7, 2018

This series of patches implements support for image encryption in containerd and ctr based on OpenPGP (GnuPGP). It is a followup to an issue raised for the opencontainers image specification to support encrypted containers. This pull request is mean to start a discussion based on an implementation.

The following provides example steps for how to encrypt and decrypt images as well as manage the list of recipients that can decrypt an image. It is currently not possible to start an encrypted image right away but one has to go through the step of decryption first. Support for starting an encrypted image could be added following acceptance of an initial set of patches. Also, there are currently no test cases covering this code.

Regards,
Stefan, Brandon, and Harshal

Note: The demo below encrypts an image for [email protected] for which the demonstrator also has the private key. You may want to create your own gpg private key, associate it with your email, and repeat the demo with your new key.

Encrypted Container Images Containerd Demo

Overview

As in this issue, we propose a new media type for encrypted layers of a container image. This addition would facilitate the ecosystem for encrypted container images. This allows users with stricter trust requirements to be able ensure end-to-end encryption from build to runtime. In addition, it allows users to use a centralized managed repository (i.e. Docker Hub) without any risk of their images being compromised.

Today, we have implemented an encrypt/decrypt interface in containerd to perform the cryptographic operations on existing images based on the openpgp protocol RFC4880. The client, ctr, initiating the procedures manages the keys via gpg/gpg2, and is able to encrypt specific layers, as well as add/remove recipients from images.

The current implementation can be found here:

Basic Functions Demo

We will demonstrate the ability to encrypt the public alpine:latest image, and push the encrypted image to a docker registry. We will then show the pulling of the encrypted image from the repository and decryption of the image for use.

Containerd client encrypt

We use existing ctr images pull to get an existing OCI image.

$ ctr images pull --all-platforms docker.io/library/alpine:latest
docker.io/library/alpine:latest:                                                  resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:7043076348bf5040220df6ad703798fd8593a0918d06d3ce30c6c93be117e430:    done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:903e1eeceeb7208949673dcb557659b5f4c8e9065a45432a0668acdd0069268c: done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:30ebbffae9ba098b9c345b890c6610aa8422f067754d7e707978a954f3b7a601: done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:5d757fdef3d336720bbccfbaa6e32089acab8ade35992e14bb0253111beb3026: done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:a332d6595c30bee40576e8cb1c75fc9ea7e646b6d159bb16cd1858085280aad9: done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:0873c923e00e0fd2ba78041bfb64a105e1ecb7678916d1f7776311e45bf5634b: done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:78f3ccd48cc6a55709b65c8fdb3ef81ed922c5393b064d63b0d35f51e0c9fb2e: done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:ea178433f2f09080fbbf77f09da1b16d588b7ced380d495a2f2ad00d28468338:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:cdf21ace94188d512903eea53ea8559677e0e6ffd5d6a180a1d88c118abc96fc:    done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:2fc01d06b47d6dde144adb6c367919461640efac2e3dc219e6ab5d2ba8d194d4:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:8e3ba11ec2a2b39ab372c60c16b421536e50e5ce64a0bc81765c2e38381bcff6:    done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:11cd0b38bc3ceb958ffb2f9bd70be3fb317ce7d255c8a4c3f4af30e298aa1aab:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:b4103359e1ecd9a7253d8b8a041d4e81db1ff4a5e1950bc0e02305d221c9e6c2:    done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:def91cb894ef09cfa305b37c92e9abca641bcdcf30e08654d233b393ba829b8e:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:47e04371c99027fae42871b720fdc6cdddcb65062bfa05f0c3bb0a594cb5bbbd:    done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:cee7671be9941a46ddb85b45d228a4358a2431989ef15953795f8792c17e7f81:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:2e09410b1fce4c4630b3bc57c6ee158ee9821ec415d0acaa1607b9e0bcf76d91:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:e642bcb5b1890a07dd2fc8be2bc35edf5e2b651d4993e71caef03b4b43ace970:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:a1653f4692c1ccea69cd46121d4f1371957f66e97a20141371dd4da10ebaec19:    done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:4407218c8304d3e30a2a0e967cf0355d037b3dbc4e19b0f05dbcb8d2241f7027:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:ee7d700abbf209aa401ef5d53f86af298a25e8154b3259036e9307d08f255c5d:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:6df692b84cf35e6038d677f9ab7de2a3c671c57671043da1d20d99252e0d9c42:    done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:47b871c82c1b54885247da879e50a804ea28c8c5dfda1a113e218a9f69e564c0:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:ef15772113129a5330876ce10683bbf6509a4c4c99b3a99894dcbc7560975052:    done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 2.4 s                                                                    total:  9.9 Mi (4.1 MiB/s)
unpacking linux/amd64 sha256:7043076348bf5040220df6ad703798fd8593a0918d06d3ce30c6c93be117e430...
unpacking linux/arm/v6 sha256:7043076348bf5040220df6ad703798fd8593a0918d06d3ce30c6c93be117e430...
unpacking linux/arm64/v8 sha256:7043076348bf5040220df6ad703798fd8593a0918d06d3ce30c6c93be117e430...
unpacking linux/386 sha256:7043076348bf5040220df6ad703798fd8593a0918d06d3ce30c6c93be117e430...
unpacking linux/ppc64le sha256:7043076348bf5040220df6ad703798fd8593a0918d06d3ce30c6c93be117e430...
unpacking linux/s390x sha256:7043076348bf5040220df6ad703798fd8593a0918d06d3ce30c6c93be117e430...
done

The encryption scheme is based off OpenPGP. Thus, we allow the use of gpg to manage keys. In the event that we want to perform encryption for a trusted party, we want to retrieve their public key so that we can securely share encryption keys with them.

First, we use the gpg client to retrieve the public key of a recipient we want to create an encrypted image for. In this case, we want to create an encrypted image for Brandon Lum <[email protected]>.

$ gpg --keyserver hkp://pgp.mit.edu --search-keys [email protected]
gpg: searching for "[email protected]" from hkp server pgp.mit.edu
(1)	Brandon Lum <[email protected]>
	  4096 bit RSA key A289B9F0, created: 2018-07-19
(2)	Brandon Lum <[email protected]>
	  4096 bit RSA key 795B4468, created: 2010-10-10
Keys 1-2 of 2 for "[email protected]".  Enter number(s), N)ext, or Q)uit > 1
gpg: requesting key A289B9F0 from hkp server pgp.mit.edu
gpg: key A289B9F0: "Brandon Lum <[email protected]>" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1

$ gpg --list-keys
/home/lumjjb/.gnupg/pubring.gpg
-------------------------------
pub   4096R/A289B9F0 2018-07-19
uid                  Brandon Lum <[email protected]>
sub   4096R/A512CBB7 2018-07-19

We then signify that we want to encrypt the image docker.io/library/alpine:latest for user [email protected] and tag the new encrypted image as docker.io/lumjjb/alpine:enc.

$ sudo ctr images encrypt --recipient [email protected] docker.io/library/alpine:latest docker.io/lumjjb/alpine:enc
Encrypting docker.io/library/alpine:latest to docker.io/lumjjb/alpine:enc

$ sudo ctr images list
REF                             TYPE                                                      DIGEST                                                                  SIZE    PLATFORMS                                                                   LABELS
docker.io/library/alpine:latest application/vnd.docker.distribution.manifest.list.v2+json sha256:7043076348bf5040220df6ad703798fd8593a0918d06d3ce30c6c93be117e430 2.1 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm64/v8,linux/ppc64le,linux/s390x -
docker.io/lumjjb/alpine:enc     application/vnd.docker.distribution.manifest.list.v2+json sha256:8152ae17bcfd47664f251e33bfef5051946973668615640637653a7f44e8803d 2.1 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm64/v8,linux/ppc64le,linux/s390x -

We then push the encrypted image to the Docker Hub registry.

TODO: Push

Containerd client decrypt

As user, Brandon Lum <[email protected]>, we will pull, decrypt and use the encrypted alpine:latest image.

We first pull the encrypted image we pushed earlier:

TODO: PULL

$ sudo ctr images list
REF                             TYPE                                                      DIGEST                                                                  SIZE    PLATFORMS                                                                   LABELS
docker.io/lumjjb/alpine:enc     application/vnd.docker.distribution.manifest.list.v2+json sha256:8152ae17bcfd47664f251e33bfef5051946973668615640637653a7f44e8803d 2.1 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm64/v8,linux/ppc64le,linux/s390x -

We then verify that we have the private key necessary to decrypt the wrapped keys, and Proceed with performing a decryption. We note that our private key is passphrase protected. And thus we are asked to enter our passphrase to decrypt the encrypted image. In the command we specify that we would like to decrypt the image docker.io/lumjjb/alpine:enc and save the decrypted image as docker.io/lumjjb/alpine:plain. We note that the decryption process will automatically derive what keys are
required from the annotations within the layers' manifests.

$ gpg --list-secret-keys
/home/lumjjb/.gnupg/secring.gpg
-------------------------------
sec   4096R/A289B9F0 2018-07-19
uid                  Brandon Lum <[email protected]>
ssb   4096R/A512CBB7 2018-07-19

$ sudo ctr images decrypt docker.io/lumjjb/alpine:enc docker.io/lumjjb/alpine:plain
Decrypting docker.io/lumjjb/alpine:enc to docker.io/lumjjb/alpine:plain
Passphrase required for Key id 0x760a6f54a512cbb7:
sec   rsa4096/A289B9F0 2018-07-19 [SC]
uid         [ unknown] Brandon Lum <[email protected]>
ssb   rsa4096/A512CBB7 2018-07-19 [E]

Enter passphrase for key with Id 0x760a6f54a512cbb7:

$ sudo ctr images list
REF                             TYPE                                                      DIGEST                                                                  SIZE    PLATFORMS                                                                   LABELS
docker.io/lumjjb/alpine:enc     application/vnd.docker.distribution.manifest.list.v2+json sha256:8152ae17bcfd47664f251e33bfef5051946973668615640637653a7f44e8803d 2.1 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm64/v8,linux/ppc64le,linux/s390x -
docker.io/lumjjb/alpine:plain   application/vnd.docker.distribution.manifest.list.v2+json sha256:7a90bfa518320e7c0fe4045776cfc1e7de201ae1d1b6b1322d3c889de3b57ea2 2.1 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm64/v8,linux/ppc64le,linux/s390x -

Additional functionality

We have implemented additional functionality to provide convenience and support for various usecases:

Show layer info.

We allow users to show the layer information of an image - as well as the keys associated with the image. This will allow the user to check what keys are required or who is allowed to decrypt the image.

$ sudo ctr images layerinfo docker.io/lumjjb/alpine:enc
   #                                                                    DIGEST         PLATFORM      SIZE   ENCRYPTION              KEY IDS
   0   sha256:43458cf20345ded65a9aca9e37252255b031226f53fb868099cdc5985138b621      linux/amd64   2207033          pgp   0x760a6f54a512cbb7
   0   sha256:10e8be14a58242185c7348f8988d67a4a0bc1534142bdaaf9a0e8dd2dd3fec39     linux/arm/v6   2146483          pgp   0x760a6f54a512cbb7
   1   sha256:1a0845f6ac68b0895bcb90e73188735bfb2587345f9ebaac1d9bf6429a702ba9     linux/arm/v6       258          pgp   0x760a6f54a512cbb7
   0   sha256:4126f7cc423377e26a53e937529474bcc2c4633d6d2056f0cdab9a7a5d59b8f8   linux/arm64/v8   2099981          pgp   0x760a6f54a512cbb7
   1   sha256:a3c6e403d8e067e31caf3e0cdec69bf2df65e96b1325549328cf90b2d13cc3a7   linux/arm64/v8       250          pgp   0x760a6f54a512cbb7
   0   sha256:5584fa94c65b898b4d20a86d7c157941e0cbbbd49875de83f7f52dfae30fe552        linux/386   2271417          pgp   0x760a6f54a512cbb7
   1   sha256:e62eb8fecfa72b0d307c630d7ca5e3a3312d6a4fb3c0c80e6a3cbafa86bbdf9c        linux/386       258          pgp   0x760a6f54a512cbb7
   0   sha256:a7eaa2d506d40bd8a2714a28e1aec2ac50dfae250bc292f25d8d15300f243ccb    linux/ppc64le   2195355          pgp   0x760a6f54a512cbb7
   1   sha256:4e0fa7b800e9e00a51b9220549b3973b5af23e619e0407d5829717166b35bb16    linux/ppc64le       250          pgp   0x760a6f54a512cbb7
   0   sha256:3ac40479ee23a4e0cf693aec2ff31a7cf3cb7ca6f99bb5b27e1d74cca15452b6      linux/s390x   2307983          pgp   0x760a6f54a512cbb7
   1   sha256:816052ed0b36d240b70d6f86e27b1ff6a53c09363d80837ffb6e5a1595959ac4      linux/s390x       258          pgp   0x760a6f54a512cbb7

Encrypt specific layer

Ability to encrypt specific layers have also been added. This will allow the user to benefit from deduplication of layers of non-secret code/data. I.e. Building a secret application on top of an ubuntu image, the ubuntu part of the image is not secret. Layers are indexed bottom up, with negative layers pointing to top layers. In this example, we specify the encryption of the topmost layer by passing in the --layer -1 flag.

$ sudo ctr images encrypt --recipient [email protected] --layer -1 docker.io/library/alpine:latest docker.io/lumjjb/alpine:enc-layer
Encrypting docker.io/library/alpine:latest to docker.io/lumjjb/alpine:enc-layer

$ sudo ctr images layerinfo docker.io/lumjjb/alpine:enc-layer
   #                                                                    DIGEST         PLATFORM      SIZE   ENCRYPTION              KEY IDS
   0   sha256:444b8ce03329f2615f1567b7fbc36df6b63f804998a41dc8b4b8d171c0360118      linux/amd64   2207033          pgp   0x760a6f54a512cbb7
   0   sha256:ee7d700abbf209aa401ef5d53f86af298a25e8154b3259036e9307d08f255c5d     linux/arm/v6   2145998
   1   sha256:5b59acb1359c7689836884da73320c3f05d28beae142d4d5ab4543638d3c8abc     linux/arm/v6       258          pgp   0x760a6f54a512cbb7
   0   sha256:47e04371c99027fae42871b720fdc6cdddcb65062bfa05f0c3bb0a594cb5bbbd   linux/arm64/v8   2099514
   1   sha256:1be8013b02bfc605de021e0297626755251f520e726265554056e6093a6245d8   linux/arm64/v8       250          pgp   0x760a6f54a512cbb7
   0   sha256:ef15772113129a5330876ce10683bbf6509a4c4c99b3a99894dcbc7560975052        linux/386   2270920
   1   sha256:9e5b0d854e7c35f6b346d205bbc8814b4212f20295213986a43d18e1972d7552        linux/386       258          pgp   0x760a6f54a512cbb7
   0   sha256:e642bcb5b1890a07dd2fc8be2bc35edf5e2b651d4993e71caef03b4b43ace970    linux/ppc64le   2194861
   1   sha256:b7bb6214c5eaaa69a3af200db7c93a237f244a29f261f8a80fe60d71eed9615e    linux/ppc64le       250          pgp   0x760a6f54a512cbb7
   0   sha256:cdf21ace94188d512903eea53ea8559677e0e6ffd5d6a180a1d88c118abc96fc      linux/s390x   2307471
   1   sha256:f9c6417700af0d44f473f477b9db997d48796695a3b226cf800d506e619bfd09      linux/s390x       258          pgp   0x760a6f54a512cbb7

Add recipients

By issuing the encrypt command on an already existing image, it allows the addition of recipients. This allows the adding of recipient wrapped keys to the image without re-encryption of the image. Thus allowing the addition of recipients to benefit from re-uploading the large encrypted blob. Because we need the symmetric key needs to be re-wrapped, the adding of recipients requires access to at least one of the existing wrapped keys of the image.

$ sudo ctr images encrypt --recipient [email protected] docker.io/lumjjb/alpine:enc docker.io/lumjjb/alpine:enc-add
Encrypting docker.io/lumjjb/alpine:enc to docker.io/lumjjb/alpine:enc-add
Passphrase required for Key id 0x760a6f54a512cbb7:
sec   rsa4096/A289B9F0 2018-07-19 [SC]
uid         [ unknown] Brandon Lum <[email protected]>
ssb   rsa4096/A512CBB7 2018-07-19 [E]

Enter passphrase for key with Id 0x760a6f54a512cbb7:
lumjjb@lumjjb-ThinkPad-P50:~/go/src/github.com/containerd/containerd$ sudo ctr images layerinfo docker.io/lumjjb/alpine:enc-add
   #                                                                    DIGEST         PLATFORM      SIZE   ENCRYPTION                                  KEY IDS
   0   sha256:43458cf20345ded65a9aca9e37252255b031226f53fb868099cdc5985138b621      linux/amd64   2207033          pgp   0x760a6f54a512cbb7, 0x2a7ba8ea1cff3e8f
   0   sha256:10e8be14a58242185c7348f8988d67a4a0bc1534142bdaaf9a0e8dd2dd3fec39     linux/arm/v6   2146483          pgp   0x760a6f54a512cbb7, 0x2a7ba8ea1cff3e8f
   1   sha256:1a0845f6ac68b0895bcb90e73188735bfb2587345f9ebaac1d9bf6429a702ba9     linux/arm/v6       258          pgp   0x760a6f54a512cbb7, 0x2a7ba8ea1cff3e8f
   0   sha256:4126f7cc423377e26a53e937529474bcc2c4633d6d2056f0cdab9a7a5d59b8f8   linux/arm64/v8   2099981          pgp   0x760a6f54a512cbb7, 0x2a7ba8ea1cff3e8f
   1   sha256:a3c6e403d8e067e31caf3e0cdec69bf2df65e96b1325549328cf90b2d13cc3a7   linux/arm64/v8       250          pgp   0x760a6f54a512cbb7, 0x2a7ba8ea1cff3e8f
   0   sha256:5584fa94c65b898b4d20a86d7c157941e0cbbbd49875de83f7f52dfae30fe552        linux/386   2271417          pgp   0x760a6f54a512cbb7, 0x2a7ba8ea1cff3e8f
   1   sha256:e62eb8fecfa72b0d307c630d7ca5e3a3312d6a4fb3c0c80e6a3cbafa86bbdf9c        linux/386       258          pgp   0x760a6f54a512cbb7, 0x2a7ba8ea1cff3e8f
   0   sha256:a7eaa2d506d40bd8a2714a28e1aec2ac50dfae250bc292f25d8d15300f243ccb    linux/ppc64le   2195355          pgp   0x760a6f54a512cbb7, 0x2a7ba8ea1cff3e8f
   1   sha256:4e0fa7b800e9e00a51b9220549b3973b5af23e619e0407d5829717166b35bb16    linux/ppc64le       250          pgp   0x760a6f54a512cbb7, 0x2a7ba8ea1cff3e8f
   0   sha256:3ac40479ee23a4e0cf693aec2ff31a7cf3cb7ca6f99bb5b27e1d74cca15452b6      linux/s390x   2307983          pgp   0x760a6f54a512cbb7, 0x2a7ba8ea1cff3e8f
   1   sha256:816052ed0b36d240b70d6f86e27b1ff6a53c09363d80837ffb6e5a1595959ac4      linux/s390x       258          pgp   0x760a6f54a512cbb7, 0x2a7ba8ea1cff3e8f

Remove recipients

This allows the removal of a recipient of an encrypted image. This is done by issuing the --remove flag.

$ sudo ctr images encrypt --remove --recipient [email protected] docker.io/lumjjb/alpine:enc-add docker.io/lumjjb/alpine:enc-removed
Encrypting docker.io/lumjjb/alpine:enc-add to docker.io/lumjjb/alpine:enc-removed
lumjjb@lumjjb-ThinkPad-P50:~/go/src/github.com/containerd/containerd$ sudo ctr images layerinfo docker.io/lumjjb/alpine:enc-removed
   #                                                                    DIGEST         PLATFORM      SIZE   ENCRYPTION              KEY IDS
   0   sha256:43458cf20345ded65a9aca9e37252255b031226f53fb868099cdc5985138b621      linux/amd64   2207033          pgp   0x760a6f54a512cbb7
   0   sha256:10e8be14a58242185c7348f8988d67a4a0bc1534142bdaaf9a0e8dd2dd3fec39     linux/arm/v6   2146483          pgp   0x760a6f54a512cbb7
   1   sha256:1a0845f6ac68b0895bcb90e73188735bfb2587345f9ebaac1d9bf6429a702ba9     linux/arm/v6       258          pgp   0x760a6f54a512cbb7
   0   sha256:4126f7cc423377e26a53e937529474bcc2c4633d6d2056f0cdab9a7a5d59b8f8   linux/arm64/v8   2099981          pgp   0x760a6f54a512cbb7
   1   sha256:a3c6e403d8e067e31caf3e0cdec69bf2df65e96b1325549328cf90b2d13cc3a7   linux/arm64/v8       250          pgp   0x760a6f54a512cbb7
   0   sha256:5584fa94c65b898b4d20a86d7c157941e0cbbbd49875de83f7f52dfae30fe552        linux/386   2271417          pgp   0x760a6f54a512cbb7
   1   sha256:e62eb8fecfa72b0d307c630d7ca5e3a3312d6a4fb3c0c80e6a3cbafa86bbdf9c        linux/386       258          pgp   0x760a6f54a512cbb7
   0   sha256:a7eaa2d506d40bd8a2714a28e1aec2ac50dfae250bc292f25d8d15300f243ccb    linux/ppc64le   2195355          pgp   0x760a6f54a512cbb7
   1   sha256:4e0fa7b800e9e00a51b9220549b3973b5af23e619e0407d5829717166b35bb16    linux/ppc64le       250          pgp   0x760a6f54a512cbb7
   0   sha256:3ac40479ee23a4e0cf693aec2ff31a7cf3cb7ca6f99bb5b27e1d74cca15452b6      linux/s390x   2307983          pgp   0x760a6f54a512cbb7
   1   sha256:816052ed0b36d240b70d6f86e27b1ff6a53c09363d80837ffb6e5a1595959ac4      linux/s390x       258          pgp   0x760a6f54a512cbb7

Next steps

Implement handling of encrypted container mediatype by containerd

Currently, the way decryption of an image is done is via the use of an explicit ctr client. We would like for runtimes to be able to decrypt the images directly when running them. i.e. containerd daemon should know how to handle the mediaType of +pgp and decrypt the image as part of the image unpacking process.

Passing of keys to runtime

We note that when having containerd handle the encrypted mediatype, it would have to be able to access keys for the decryption process. However, we need to be able to properly handle permissions of access of keys.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't make sense in the containerd model. The decryption/encryption should occur client-side, as part of unpacking/packing an image.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me explain this a little more clearly: unpacking of images isn't really performed in this service. This service is only dealing with metadata.

There may be some integration with the diff/applier service. I'll let @dmcgowan expand on that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though retrieving information about the layers should be done by containerd then for existing images? So it's not like containerd 'owns' the /var/lib/containerd/ directory and its subdirectories but ctr can also touch it for writing to? Also that bolt database is shared between containerd and ctr ?

Copy link
Member

@dmcgowan dmcgowan Aug 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bolt is only for containerd daemon is accessed via the higher level interfaces, content, snapshot, etc....

The client does not need to touch /var/lib/containerd, but it is allowed to read content using the content store interface and mount snapshots it got from the snapshotter interface to do client side unpacking. As @stevvooe mentioned, we have a diff/applier service which allows doing this in the daemon to avoid roundtripping the entire content blobs, this interface is designed to be extensible via the content type, however we have not yet implemented plugins. The best solution maybe to add diff and apply plugins which this PoC could leverage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I must say I have had my challenges understanding the code at the beginning. Now I guess I may need some help here for seeing how things are done and probably also which code paths to go into. I guess the 'bootstrapping' has to start with creating a first encyrpted image. Would the encryption go into 'ctr images push' then?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the 'bootstrapping' has to start with creating a first encyrpted image. Would the encryption go into 'ctr images push' then?

ctr images push does not build images. Doing this would look like...

  1. Read and parse the image manifest
  2. Read each content blob, encrypt, and write back to the content store
  3. Update the image manifest with the updated descriptors
  4. Write the image manifest back to the content store
  5. Create the image pointing at the new manifest descriptor
  6. ctr images push the new image

It would be the expectation that a tool like buildkit would be responsible for creating content, or maybe a helper tool in ctr which did steps 1-5 above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can tell, we are doing steps 1-5 in images encrypt now, inside containerd though. The command also allows encryption of individual layers and for each platform separately, along with management of the recipients. Removing the RPC layer may be more or less straight forward if we can still write into the content store and bolt directly from the client, which I haven't tried. Though which command would this code go into if "ctr images push does not build images"? Either way, it would be good if it still allows management of recipients then as well as control over the encryption of individual layers.

@codecov-io
Copy link

codecov-io commented Aug 7, 2018

Codecov Report

Merging #2532 into master will decrease coverage by 0.76%.
The diff coverage is 34.62%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master   #2532      +/-   ##
=========================================
- Coverage   43.96%   43.2%   -0.77%     
=========================================
  Files         102     113      +11     
  Lines       10881   11904    +1023     
=========================================
+ Hits         4784    5143     +359     
- Misses       5362    5956     +594     
- Partials      735     805      +70
Flag Coverage Δ
#linux 46.74% <37.51%> (-0.84%) ⬇️
#windows 40.59% <34.62%> (-0.59%) ⬇️
Impacted Files Coverage Δ
content/content.go 0% <ø> (ø) ⬆️
images/encryption/utils.go 0% <0%> (ø)
platforms/platforms.go 71.56% <0%> (-7.78%) ⬇️
content/helpers.go 16.55% <0%> (-6.09%) ⬇️
images/encryption/gpg.go 0% <0%> (ø)
images/encryption/gpgvault.go 0% <0%> (ø)
images/encryption/keywrap/pgp/keywrapper_gpg.go 35% <35%> (ø)
...mages/encryption/keywrap/pkcs7/keywrapper_pkcs7.go 44.61% <44.61%> (ø)
images/encryption/keywrap/jwe/keywrapper_jwe.go 52.77% <52.77%> (ø)
images/encryption/encryption.go 56.65% <56.65%> (ø)
... and 26 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 543ee8e...77a1977. Read the comment docs.

@stefanberger stefanberger force-pushed the image-encryption.pr branch 2 times, most recently from f72ff86 to b3b8511 Compare September 7, 2018 14:14
@stefanberger
Copy link
Contributor Author

stefanberger commented Sep 7, 2018

The current implementation requires OpenPGP keys and results in an OpenPGP formatted blob for the wrapped keys and the bulk data. This could be abstracted to only require a public key for encryption as input and result in a common format for the wrapped session key (wrapped once for each recipient) and the symmetrically encrypted bulk data. However, I think this may require the definition of a new format since no standard exists that can accomodate any type of public key. I just want to mention this here.

So, for OpenPGP RFC 4880 defines the wrapped session key as follows :

struct  openpgp_wrapped_key {
  uint8_t version;
  uint8_t keyid[8];
  uint8_t public_key_algo;
  uint8_t wrapped_key[]; // like 256 bytes
};

For PKCS#7 the wrapped session key is defined like this:

RecipientInfo ::= SEQUENCE {
     version Version,
     issuerAndSerialNumber IssuerAndSerialNumber,
     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
     encryptedKey EncryptedKey }

   EncryptedKey ::= OCTET STRING

I would argue one could come up with a data structure like this here in exemplary JSON format that could accommodate any of these wrapped keys:

{
    "key_type": <key_type>,
    "specifics": {
        <key type specific map>
    },
}

For OpenPGP this would look like this:

{
    "key_type": "OpenPGP",
    "specifics" : {
        "version": "3",
        "keyid": 0x1234567890abcdef,
        "public_key_algo": OPENPGPG_RSA_VALUE,
        "wrapped_key": "<base64 encoded wrapped key"
    }
}

For PKCS#7 this would look like this:

{
    "key_type": "PKCS7",
    "specifics": {
        "version": ...,
        "issuerAndSerialNumber": "..."
        "keyEncryptionAlgorithm": PKCS7_RSA_VALUE,
        "encryptedKey": "<base64 encoded wrapped key>"
    }
}

The image encryption process would create a list of the above two examples, one such map for each recipient and specific to the recipient's key. The JSON format is just an example here. The bulk data, which are the layer data, could then be written out in a format like this one that can be handled easily:

struct bulk_data {
    uint8_t symmetric_encryption_algo; // AES128+CBC etc.
    uint8_t iv[];
    <other fields>
    uint8_t symmetrically_encrypted_data[]; // encrypted layer data
};

The advantage of this type of format would be that this should allow us to handle any type of public key as input (OpenPGP, OpenSSL, x509, JWK, TPM1.2, TPM2, SmartCards, HSMs) and we can define the 'specifics' for the individual key type. In some cases 'specifics' could point to some sort of config file where the IP address is located to reach the device to handle the decryption. The specific technology would be required to unwrap the symmetric key using the private key. The symmetric key could then generically be used to decrypt the bulk data.

This would avoid possibly different formats for the encrypted layer. The current OpenPGP implementation produces one such very specific format.

@stefanberger
Copy link
Contributor Author

The keyid in OpenPGP is used to look up the private key for decrypting the data (rather trying all the private keys one after another). Similarly all other technologies would have to provide a keyid of some format serving as a lookup index to quickly find the private key. Sometimes a password may be needed to access the key, which would be stored in some sort of config file.

@stefanberger
Copy link
Contributor Author

We could also use JWK to represent some of the keys. Some types of keys, like for hardware security modules or TPMs, could be provided as JWKs to the person encrypting the image and that person could then pass multiple of those on the command line. The JWK format for hardware devices' keys is not standardized in JWK specs afaics, though, but using JWK provides a path to support it in the future. Some other keys, like in the more common PEM format or for PGP recipients could still be passed directly. The client tool may need to detect the format:

ctr images encrypt --recipient foo.jwk --recipient [email protected] --recipient foo.pem myimage:latest myimage.encrypted:latest

Internally we should probably convert the pem and pgp type of keys into a map[string]string like JWK and could then use JWK fields to represent the 'specifics' map above when storing metadata for the wrapped key. Though this is all outside some standard and would have to be agreed upon.

@stefanberger
Copy link
Contributor Author

stefanberger commented Sep 10, 2018

JWE would probably be the best (unifying) standard to follow, though we probably couldn't follow it to the letter. The encrypted bulk data is part of the JSON there and in the layer case it would be a file. Also for the standards route I haven't seen OpenPGP type of keys representation in JWK format.

@stefanberger
Copy link
Contributor Author

stefanberger commented Sep 20, 2018

@stevvooe @dmcgowan

Next version supports recipients with different key types (so far: PEM,DER,OpenPGP) and supports JWE (PEM, DER) and OpenPGP (OpenPGP keys) for the encryption of the symmetric key that in turn handles the layer encryption:

$ ./bin/ctr images encrypt --recipient mypubkey.der --recipient [email protected] docker.io/library/alpine:latest docker.io/library/alpine:enc
Encrypting docker.io/library/alpine:latest to docker.io/library/alpine:enc
$ ./bin/ctr images layerinfo docker.io/library/alpine:enc
   #                                                                    DIGEST         PLATFORM      SIZE   ENCRYPTION           RECIPIENTS
   0   sha256:f08d7546ef57875d3a955ce6ec283207ed43b6af435e9b6986c4339bac4ad751      linux/amd64   2206558      jwe,pgp   0x31b1a243cca8327c
   0   sha256:cadd080d7d536dbc5e24fc042741b2e42cca30eeb0cfffa33212c2a6b352ad9b     linux/arm/v6   2146014      jwe,pgp   0x31b1a243cca8327c
   1   sha256:b403f3d81c8e3d72a5b6a04f9cbf97cc01c0a0de0b2a7f6765c0dad90eabe817     linux/arm/v6       191      jwe,pgp   0x31b1a243cca8327c
   0   sha256:e991388e789a5e6b4245fb75bbb40414f005fb4aa119211d961bfba8888bd6d8   linux/arm64/v8   2099530      jwe,pgp   0x31b1a243cca8327c
   1   sha256:3ce7819e926b326e4fc3ae0f3b0ba291104048d032f0d8e288a781bb9c325263   linux/arm64/v8       192      jwe,pgp   0x31b1a243cca8327c
   0   sha256:1402e1efe8d82d25c1afe9e6d193c3feb702d2761f125711634f9918b2f0ca9b        linux/386   2270936      jwe,pgp   0x31b1a243cca8327c
   1   sha256:01187aab1b4f9fb9dc363c9d364feb489eb9df2d3b4d7e8a071b05f40093b6ab        linux/386       191      jwe,pgp   0x31b1a243cca8327c
   0   sha256:a5fea124b55c297ed02283c7de9475985113a946c52c0872b38ab001653391a9    linux/ppc64le   2194877      jwe,pgp   0x31b1a243cca8327c
   1   sha256:34dd7a216a042b98e852b007f36ddb2576dfe0a97d9b4b3a7b2050d1662003f9    linux/ppc64le       192      jwe,pgp   0x31b1a243cca8327c
   0   sha256:751813c9e9cdb8374d1aec0fe11cde9be0b8cda9f45fc032435ea48ddb445016      linux/s390x   2307487      jwe,pgp   0x31b1a243cca8327c
   1   sha256:46033bd0b600a1ff37d1604f3d0c425efd1e64b1ba493dec0a29543264c8aaf3      linux/s390x       191      jwe,pgp   0x31b1a243cca8327c
$ ./bin/ctr images decrypt docker.io/library/alpine:enc docker.io/library/alpine:dec --key ./mykey.der 
Decrypting docker.io/library/alpine:enc to docker.io/library/alpine:dec

$ ./bin/ctr images layerinfo docker.io/library/alpine:dec
   #                                                                    DIGEST         PLATFORM      SIZE   ENCRYPTION   RECIPIENTS
   0   sha256:8e3ba11ec2a2b39ab372c60c16b421536e50e5ce64a0bc81765c2e38381bcff6      linux/amd64   2206542                          
   0   sha256:ee7d700abbf209aa401ef5d53f86af298a25e8154b3259036e9307d08f255c5d     linux/arm/v6   2145998                          
   1   sha256:a1653f4692c1ccea69cd46121d4f1371957f66e97a20141371dd4da10ebaec19     linux/arm/v6       175                          
   0   sha256:47e04371c99027fae42871b720fdc6cdddcb65062bfa05f0c3bb0a594cb5bbbd   linux/arm64/v8   2099514                          
   1   sha256:b4103359e1ecd9a7253d8b8a041d4e81db1ff4a5e1950bc0e02305d221c9e6c2   linux/arm64/v8       176                          
   0   sha256:ef15772113129a5330876ce10683bbf6509a4c4c99b3a99894dcbc7560975052        linux/386   2270920                          
   1   sha256:6df692b84cf35e6038d677f9ab7de2a3c671c57671043da1d20d99252e0d9c42        linux/386       175                          
   0   sha256:e642bcb5b1890a07dd2fc8be2bc35edf5e2b651d4993e71caef03b4b43ace970    linux/ppc64le   2194861                          
   1   sha256:2e09410b1fce4c4630b3bc57c6ee158ee9821ec415d0acaa1607b9e0bcf76d91    linux/ppc64le       176                          
   0   sha256:cdf21ace94188d512903eea53ea8559677e0e6ffd5d6a180a1d88c118abc96fc      linux/s390x   2307471                          
   1   sha256:ea178433f2f09080fbbf77f09da1b16d588b7ced380d495a2f2ad00d28468338      linux/s390x       175                          
$ ./bin/ctr images decrypt docker.io/library/alpine:enc docker.io/library/alpine:dec2 --key ./1F0CB5C638F9153E50C299648671DD2E305C10E8.bin 
Decrypting docker.io/library/alpine:enc to docker.io/library/alpine:dec2

$ ./bin/ctr images layerinfo docker.io/library/alpine:dec2
   #                                                                    DIGEST         PLATFORM      SIZE   ENCRYPTION   RECIPIENTS
   0   sha256:8e3ba11ec2a2b39ab372c60c16b421536e50e5ce64a0bc81765c2e38381bcff6      linux/amd64   2206542                          
   0   sha256:ee7d700abbf209aa401ef5d53f86af298a25e8154b3259036e9307d08f255c5d     linux/arm/v6   2145998                          
   1   sha256:a1653f4692c1ccea69cd46121d4f1371957f66e97a20141371dd4da10ebaec19     linux/arm/v6       175                          
   0   sha256:47e04371c99027fae42871b720fdc6cdddcb65062bfa05f0c3bb0a594cb5bbbd   linux/arm64/v8   2099514                          
   1   sha256:b4103359e1ecd9a7253d8b8a041d4e81db1ff4a5e1950bc0e02305d221c9e6c2   linux/arm64/v8       176                          
   0   sha256:ef15772113129a5330876ce10683bbf6509a4c4c99b3a99894dcbc7560975052        linux/386   2270920                          
   1   sha256:6df692b84cf35e6038d677f9ab7de2a3c671c57671043da1d20d99252e0d9c42        linux/386       175                          
   0   sha256:e642bcb5b1890a07dd2fc8be2bc35edf5e2b651d4993e71caef03b4b43ace970    linux/ppc64le   2194861                          
   1   sha256:2e09410b1fce4c4630b3bc57c6ee158ee9821ec415d0acaa1607b9e0bcf76d91    linux/ppc64le       176                          
   0   sha256:cdf21ace94188d512903eea53ea8559677e0e6ffd5d6a180a1d88c118abc96fc      linux/s390x   2307471                          
   1   sha256:ea178433f2f09080fbbf77f09da1b16d588b7ced380d495a2f2ad00d28468338      linux/s390x       175                          

@stefanberger stefanberger changed the title [WIP] Extend containerd and ctr with support for OpenPGP based image encryption [WIP] Extend containerd and ctr with support for (extensible) image encryption (OpenPGP, JWE, ...) Sep 20, 2018
@stefanberger
Copy link
Contributor Author

Encryption to PGP, JWE, and PKCS7 recipients:

$ ./bin/ctr images encrypt --gpg-homedir /tmp/tmp.AGrSDkaSad/gpg2 --recipient [email protected] --recipient [email protected] --recipient /tmp/tmp.AGrSDkaSad/mypubkey.pem --recipient /tmp/tmp.AGrSDkaSad/mypubkey2.pem --recipient /tmp/tmp.AGrSDkaSad/clientcert.pem --recipient /tmp/tmp.AGrSDkaSad/client2cert.pem docker.io/library/alpine:latest docker.io/library/alpine:enc
Encrypting docker.io/library/alpine:latest to docker.io/library/alpine:enc
$ ./bin/ctr images layerinfo docker.io/library/alpine:enc
   #                                                                    DIGEST         PLATFORM      SIZE      ENCRYPTION                                               RECIPIENTS
   0   sha256:3427d6934e7749d556be6881a17265c9817abc6447df80a09c8eecc465c5bfb3      linux/amd64   2206947   jwe,pgp,pkcs7   0x6d6d5017a3752cbd, 0xb0310f009d3abc2f, [jwe], [pkcs7]
   0   sha256:d9a094b6b49fc760501d44ae96f19284e86db0a51b979756ca8a0df4a2746c79     linux/arm/v6   2146469   jwe,pgp,pkcs7   0x6d6d5017a3752cbd, 0xb0310f009d3abc2f, [jwe], [pkcs7]
   1   sha256:ef87d8b3048d8f1f7af7605328f63aab078a1433116dc15738989551184d7a87     linux/arm/v6       191   jwe,pgp,pkcs7   0x6d6d5017a3752cbd, 0xb0310f009d3abc2f, [jwe], [pkcs7]
   0   sha256:4b0872dff46806a4037c5f158d1d17d5252c9e1f421b7c61445f1a64f6a853a8   linux/arm64/v8   2099778   jwe,pgp,pkcs7   0x6d6d5017a3752cbd, 0xb0310f009d3abc2f, [jwe], [pkcs7]
   1   sha256:fe022206e6848082f9c1d6e69974157af70ad56bf8698d89e1641d4598bf8ce9   linux/arm64/v8       192   jwe,pgp,pkcs7   0x6d6d5017a3752cbd, 0xb0310f009d3abc2f, [jwe], [pkcs7]
   0   sha256:d1fceb26d4a2dc1f30d05fd0f9567edb5997d504f044ad6486aecc3d5aaa9b4e        linux/386   2271476   jwe,pgp,pkcs7   0x6d6d5017a3752cbd, 0xb0310f009d3abc2f, [jwe], [pkcs7]
   1   sha256:383a3d4c6789667dbfb6b3742492c4a925315e750f99a5d664ff72f2bb0ae659        linux/386       191   jwe,pgp,pkcs7   0x6d6d5017a3752cbd, 0xb0310f009d3abc2f, [jwe], [pkcs7]
   0   sha256:8aea19b10fd75004ab8fd2d02df719c06528ad3539e686a2d26c933d53f25675    linux/ppc64le   2195242   jwe,pgp,pkcs7   0x6d6d5017a3752cbd, 0xb0310f009d3abc2f, [jwe], [pkcs7]
   1   sha256:965a60ab5513a2eee33f4d960b63ee347215eb31d06a4ed61f6d90d209462d76    linux/ppc64le       193   jwe,pgp,pkcs7   0x6d6d5017a3752cbd, 0xb0310f009d3abc2f, [jwe], [pkcs7]
   0   sha256:783541963cb4e52173193fe947bb7a7f7e5a6657a4cbbb6b8b077bbee7255605      linux/s390x   2307762   jwe,pgp,pkcs7   0x6d6d5017a3752cbd, 0xb0310f009d3abc2f, [jwe], [pkcs7]
   1   sha256:69d3260b3f5430ade9a3ee0f1b71a32a8e4ef268552beeae29930a8795dc54bf      linux/s390x       192   jwe,pgp,pkcs7   0x6d6d5017a3752cbd, 0xb0310f009d3abc2f, [jwe], [pkcs7]'

@stefanberger stefanberger force-pushed the image-encryption.pr branch 3 times, most recently from 91546d4 to 6efdf5b Compare October 3, 2018 14:07
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't seem to find the definition of this function but I would prefer not to have this be a bool. There should be discrete encrypt/decrypt functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this now so that images now exports EncryptImage and DecryptImage but then funnels right into the previous cryptImage function. The reason is that encryption and decryption share a lot of code. There are quite a few functions that start with crypt in the name but are not exported from images.

image.go Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These interface methods are way to specific for the image. Notice the other methods aren't specific to an implementation or specific image format. These should probably be set through the client or as part of an option set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think by now this could be a map[string]string where we pass the different types of decryption keys (gpg, pem/der keys) and other material (x509s).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This package should be broken up such that the encryption package defines the interfaces primitives and the sub packages have the implementations. For example, you'd have image/encryption, image/encryption/gpg and image/encryption/pkcs7 and so on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes for the next version.

stefanberger and others added 20 commits February 14, 2019 07:43
Allow encryption of images with elliptic curve keys using JWE.

Signed-off-by: Stefan Berger <[email protected]>
Set ContentEncryptionAlgorithm = EncryptionAlgorithmAES128GCM
to activate AES128GCM for encryption.

Signed-off-by: Stefan Berger <[email protected]>
errdefs/errors.go primarily wraps grpc related errors, so do not wrap the
wrong passsord error there.

Signed-off-by: Stefan Berger <[email protected]>
Use HasEncryptedLayer() to determine whether an image is encrypted.
For this to work we also need to add the missing MediaType to the LayerInfos.

Have the ctr image decrypt tool use this function rather than relying on
the number of Annotations, which is the wrong indicator.

Signed-off-by: Stefan Berger <[email protected]>
Roll back the extension of the Diff plugin's Apply() API call with the
dcparameters and use a key in the Annotations map to pass a JSON
representation of the dcparameters map ([string][][]bytes) in a temporary
key "_dcparameters" that we insert before the grpc call and remove on the
server side.

Signed-off-by: Harshal Patil <[email protected]>
Signed-off-by: Stefan Berger <[email protected]>
Properly clean up the decrypted image and do this synchronously so it is
gone afterwards.

Without this the ImageIsUnpacked test case would occasionally fail since
the image wasn't entirely gone by the time that test case checked whether
it is UnPacked().

Signed-off-by: Stefan Berger <[email protected]>
This is a first step in the conversion of using the notion of
message streams in the block cipher implementation. In this patch
we convert the code to pass a content.ReadAt to the encryption
function so that later on we can replace the symmetric cipher
with an implementation that works on blocks read from this reader.

Signed-off-by: Stefan Berger <[email protected]>
The block cipher functions now return a Reader that is wrapping
an io.Reader and the Hash and size of the resulting layer. We need
the latter two to be able to store the layer along with its size
and the filename derived from the hash.

Signed-off-by: Stefan Berger <[email protected]>
Implement support for ocispec.Descriptor.Size = 0 when writing
the blob to the content store. We introduce a new function WriteLayer()
that returns the size of the encrypted layer.

Signed-off-by: Stefan Berger <[email protected]>
Remove the ocispec.Descriptor from the WriteBlobN() parameter list
since it holds no valid content that is needed for writing a layer
blob.

Signed-off-by: Stefan Berger <[email protected]>
Refactor the GCM block cipher to do all the work in the Reader's Read()
function. This changes the semantics of the Size() function a bit, which
will only return the size of the encrypted or decrypted data after
Read() has been called for all the data. So the test cases need to be
adjusted for this. Also errors related to decrypting the data with
the wrong key only become apparent when calling Read(), which also
requires test cases to be adapted.

Signed-off-by: Stefan Berger <[email protected]>
Signed-off-by: Stefan Berger <[email protected]>
Use AES-SIV-CMAC-512 rather than AEAD GCM and get rid of the latter.

The AES-SIV-CMAC-512 is used by reading chunks from the input stream,
encrypting or decrypting the chunk, and then returning the data through
the buffer passed to the Read() function.

When encrypting a chunk the size of the encrypted chunk is a certain amount
larger than the plain one. We have to make sure that the encrypted chunks
passed back to the caller are given to us by the caller exactly the same
when decrypting them. We make the chunksize of an encrypted chunk 1MB but
only read plain data of the size 1MB - Overhead.

Signed-off-by: Stefan Berger <[email protected]>
@estesp
Copy link
Member

estesp commented Jun 13, 2019

Any reason to keep this PR open? The code seems out of date compared to the much more recent PRs which are in-flight.

@lumjjb
Copy link
Contributor

lumjjb commented Jun 13, 2019

I think the only thing here is the pull path code. But I think at this point, with all the changes, we would have to end up rewriting a chunk of it anyway. I'm in favor of closing this and focusing on the other PRs.

@estesp
Copy link
Member

estesp commented Jun 21, 2019

Per @lumjjb closing this PR as we have existing PRs for review and potential merge. All the discussion, code commits, and initial opening info describing the capabilities are still available, but the PR won't be in the open list.

@estesp estesp closed this Jun 21, 2019
samuelkarp added a commit to samuelkarp/containerd that referenced this pull request Oct 7, 2024
diff: opencontainers/runc@v1.1.14...v1.1.15

Release notes:

- The -ENOSYS seccomp stub is now always generated for the native
  architecture that runc is running on. This is needed to work around some
  arguably specification-incompliant behaviour from Docker on architectures
  such as ppc64le, where the allowed architecture list is set to null. This
  ensures that we always generate at least one -ENOSYS stub for the native
  architecture even with these weird configs. (containerd#4391)
- On a system with older kernel, reading /proc/self/mountinfo may skip some
  entries, as a consequence runc may not properly set mount propagation,
  causing container mounts leak onto the host mount namespace. (containerd#2404, containerd#4425)
- In order to fix performance issues in the "lightweight" bindfd protection
  against [CVE-2019-5736], the temporary ro bind-mount of /proc/self/exe
  has been removed. runc now creates a binary copy in all cases. (containerd#4392, containerd#2532)

Signed-off-by: Samuel Karp <[email protected]>
k8s-infra-cherrypick-robot pushed a commit to k8s-infra-cherrypick-robot/containerd that referenced this pull request Oct 8, 2024
diff: opencontainers/runc@v1.1.14...v1.1.15

Release notes:

- The -ENOSYS seccomp stub is now always generated for the native
  architecture that runc is running on. This is needed to work around some
  arguably specification-incompliant behaviour from Docker on architectures
  such as ppc64le, where the allowed architecture list is set to null. This
  ensures that we always generate at least one -ENOSYS stub for the native
  architecture even with these weird configs. (containerd#4391)
- On a system with older kernel, reading /proc/self/mountinfo may skip some
  entries, as a consequence runc may not properly set mount propagation,
  causing container mounts leak onto the host mount namespace. (containerd#2404, containerd#4425)
- In order to fix performance issues in the "lightweight" bindfd protection
  against [CVE-2019-5736], the temporary ro bind-mount of /proc/self/exe
  has been removed. runc now creates a binary copy in all cases. (containerd#4392, containerd#2532)

Signed-off-by: Samuel Karp <[email protected]>
k8s-infra-cherrypick-robot pushed a commit to k8s-infra-cherrypick-robot/containerd that referenced this pull request Oct 8, 2024
diff: opencontainers/runc@v1.1.14...v1.1.15

Release notes:

- The -ENOSYS seccomp stub is now always generated for the native
  architecture that runc is running on. This is needed to work around some
  arguably specification-incompliant behaviour from Docker on architectures
  such as ppc64le, where the allowed architecture list is set to null. This
  ensures that we always generate at least one -ENOSYS stub for the native
  architecture even with these weird configs. (containerd#4391)
- On a system with older kernel, reading /proc/self/mountinfo may skip some
  entries, as a consequence runc may not properly set mount propagation,
  causing container mounts leak onto the host mount namespace. (containerd#2404, containerd#4425)
- In order to fix performance issues in the "lightweight" bindfd protection
  against [CVE-2019-5736], the temporary ro bind-mount of /proc/self/exe
  has been removed. runc now creates a binary copy in all cases. (containerd#4392, containerd#2532)

Signed-off-by: Samuel Karp <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants