Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Add support for encrypted images #2297

Draft
wants to merge 12 commits into
base: criu-dev
Choose a base branch
from

Commits on Jul 8, 2024

  1. tls: enable support for image encryption

    This patch extends CRIU dump with support for encryption of images
    using ChaCha20-Poly1305 authenticated-encryption in combination with
    X.509 certificates.
    
    The '--encrypt' option can be used with the dump/pre-dump commands to
    enable this functionality. When this option has been specified during
    dump, the GnuTLS library will be used to load a public key from X.509
    certificate, and to generate a 256-bit random `token`. The token's
    value is then encrypted with the public key and the corresponding
    ciphertext is saved in `cipher.img`. During restore, if cipher.img
    exists in the images directory, the GnuTLS library will be used to
    load a private key from a corresponding PEM file to decrypt the token
    value.
    
    The token value is used with ChaCha20-Poly1305 to encrypt/decrypt
    all other CRIU images. The 256-bit token is used in combination with
    96-bits `nonce` and 128-bits `tag` to protect data confidentiality
    and provide message authentication for each data entry.
    
    Example:
    	criu dump --encrypt ...
    	criu restore ...
    
    Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
    rst0git committed Jul 8, 2024
    Configuration menu
    Copy the full SHA
    8c262a1 View commit details
    Browse the repository at this point in the history
  2. zdtm: enable tests with encrypted images

    This patch extends ZDTM to run `criu dump` with the `--encrypt`
    option to test the encryption functionality of CRIU images.
    
    Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
    rst0git committed Jul 8, 2024
    Configuration menu
    Copy the full SHA
    aa638cb View commit details
    Browse the repository at this point in the history
  3. bpfmap: rename opts to bpfmap_opts

    'opts' is defined in cr_options.h. This header will be included in a
    subsequent patch. We rename the local variable 'opts' to 'bpfmap_opts'
    to avoid variable shadowing.
    
    Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
    rst0git committed Jul 8, 2024
    Configuration menu
    Copy the full SHA
    b53cf51 View commit details
    Browse the repository at this point in the history
  4. bpfmap: optimize dump of keys/values

    We calculate the total memory size needed for both keys and values and
    allocate a single contiguous memory region using a single mmap call.
    In a subsequent patch, this change would enable encrypting the combined
    memory region using a single pair of ChaCha20-Poly1305 tag and nonce.
    
    Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
    rst0git committed Jul 8, 2024
    Configuration menu
    Copy the full SHA
    9761802 View commit details
    Browse the repository at this point in the history
  5. bpfmap: enable encryption of key/value data

    This patch extends dump_one_bpfmap_data() with support for encryption.
    
    Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
    rst0git committed Jul 8, 2024
    Configuration menu
    Copy the full SHA
    4b5f732 View commit details
    Browse the repository at this point in the history
  6. tls: enable ghost image and pipe data encryption

    During checkpoint, the contents of ghost images and pipe data is
    splice()-ed between file descriptors. To enable encryption for this data
    we introduce `tls_encrypt_file_data()` and `tls_decrypt_file_data()`.
    These functions read data from input file descriptor, perform
    encryption/decryption of the data, and write it to the corresponding
    output file descriptor.
    
    Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
    rst0git committed Jul 8, 2024
    Configuration menu
    Copy the full SHA
    09f550e View commit details
    Browse the repository at this point in the history
  7. crit: add support for decoding encrypted images

    This patch extends CRIT with the ability to decode encrypted images.
    When `cipher.img` is present, crit will load the corresponding private
    key (from /etc/pki/criu/private/key.pem), decrypt the cipher token and
    use it to decrypt the protobuf entries in the image that is being
    decoded.
    
    Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
    rst0git committed Jul 8, 2024
    Configuration menu
    Copy the full SHA
    ee7703a View commit details
    Browse the repository at this point in the history
  8. cr_system: enable data encryption

    cr_system() and cr_system_userns() are used to run external executables
    such as tar, ip, and iptables. These external tools are used to create
    image files in 3rd party format (i.e., raw images). In order to encrypt
    the output of these tools, and to decrypt their input, we replace the
    corresponding input/output file descriptor with a pipe, and perform
    encryption/decryption of the data.
    
    Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
    rst0git committed Jul 8, 2024
    Configuration menu
    Copy the full SHA
    af9b445 View commit details
    Browse the repository at this point in the history
  9. tls: enable support for encryption of memory pages

    We use the AES-XTS block cipher to encrypt memory pages as it is
    designed to encrypt blocks of data with fixed-size (e.g. memory pages),
    allows the use of hardware acceleration available in modern CPUs, and
    uses a single initialization vector (IV), instead of per-page nonce,
    to ensure that encrypting the same plaintext with the same key results
    in different ciphertexts.
    
    In particular, XTS uses two 256-bits AES keys. One key is used to
    perform block encryption, and the other is used to encrypt a so-called
    "tweak value". The encrypted tweak value is further modified (with a
    Galois polynomial function) and XOR-ed with both the plaintext and
    ciphertext of each block. This method ensures that encrypting multiple
    blocks with identical data will produce different ciphertext.
    
    Since CRIU restores memory pages in the restorer context, this PIE code
    cannot be linked with libraries such as GnuTLS to perform decryption.
    Instead, we introduce a helper process to decrypt memory pages data.
    The restorer context communicates with this helper process using PIPEs.
    It sends the function arguments be used by preadv() and receives back
    its return value. The decrypted data is transferred to the target
    address space with process_vm_writev.
    
    Suggested-by: Daiki Ueno <dueno@redhat.com>
    Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
    rst0git committed Jul 8, 2024
    Configuration menu
    Copy the full SHA
    c1215f7 View commit details
    Browse the repository at this point in the history
  10. tls: verify the integrity of memory pages

    The AES-XTS cipher does not provide integrity verification.
    In this patch we add a verification mechanism based on the
    HMAC-SHA-256 algorithm.
    
    In order to support iterative checkpointing and memory deduplication
    with encrypted memory, and to avoid storing HMAC for each memory page,
    we compute XOR for of HMAC value for all memory pages and store this
    value in cipher.img
    
    The XOR computation also allows us to address the problem that memory
    pages are read during restore in a different order then they are written
    during checkpoint. In addition, to ensure that memory pages are restored
    in correct order, we include the PID and VMA address associated with each
    page in the HMAC computation.
    
    The following example illustrates the HMAC value computation:
    
    	H_n = HMAC(PID + VMA + MEMORY + KEY)
    	hmac_value = H_1 ^ H_2 ^ ... ^ H_n
    
    - PID: PID associated with the memory page
    - VMA: virtual memory address associated with memory page
    - KEY: secret key
    - H_n: n-th memory page
    - hmac_value: value stored in cipther.img during checkpoint, and used
                  for integrity verification during restore
    
    Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
    rst0git committed Jul 8, 2024
    Configuration menu
    Copy the full SHA
    0f87cb7 View commit details
    Browse the repository at this point in the history
  11. stats: measure time for encryption/decryption

    Measure the time for data encryption and decryption with
    stream and block ciphers.
    
    Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
    rst0git committed Jul 8, 2024
    Configuration menu
    Copy the full SHA
    8ab8d47 View commit details
    Browse the repository at this point in the history
  12. scripts: add criu-keygen script

    This script, similar to ssh-keygen and certtool, makes it easier
    to generate and install certificate and key to enable encryption
    support with CRIU.
    
    Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
    rst0git committed Jul 8, 2024
    Configuration menu
    Copy the full SHA
    3936cbf View commit details
    Browse the repository at this point in the history