# mlx5dv_dek_create

## NAME



           mlx5dv_dek_create - Creates a DEK
    
           mlx5dv_dek_query - Queries a DEK’s attributes
    
           mlx5dv_dek_destroy - Destroys a DEK
    


## SYNOPSIS



                  #include <infiniband/mlx5dv.h>
    
                  struct mlx5dv_dek *mlx5dv_dek_create(struct ibv_context *context,
                                       struct mlx5dv_dek_init_attr *init_attr);
    
                  int mlx5dv_dek_query(struct mlx5dv_dek *dek, struct mlx5dv_dek_attr *attr);
    
                  int mlx5dv_dek_destroy(struct mlx5dv_dek *dek);
    


## DESCRIPTION



           Data Encryption Keys (DEKs) are used to encrypt and decrypt
           transmitted data.  After a DEK is created, it can be configured in
           MKeys for crypto offload operations.  DEKs are not persistent and
           are destroyed upon process exit.  Therefore, software process
           needs to re-create all needed DEKs on startup.
    
           **mlx5dv_dek_create()** creates a new DEK with the attributes
           specified in _init_attr_.  A pointer to the newly created dek is
           returned, which can be used for DEK query, DEK destruction and
           when configuring a MKey for crypto offload operations.
    
           The DEK can be either wrapped or in plaintext and the format that
           should be used is determined by the specified crypto_login object.
    
           To create a wrapped DEK, the application must have a valid crypto
           login object prior to creating the DEK.  Creating a wrapped DEK
           can be performed in two ways: 1.  Call
           **mlx5dv_crypto_login_create()** to obtain a crypto login object.
           Indicate that the DEK is wrapped by setting
           **MLX5DV_DEK_INIT_ATTR_CRYPTO_LOGIN** value in _comp_mask_ and passing
           the crypto login object in _crypto_login_ field of _init_attr_.  Fill
           the other DEK attributes and create the DEK.
    
           2. Call **mlx5dv_crypto_login()** i.e., the old API.  Supply
              credential, import_kek_id
    
           To create a plaintext DEK, the application must indicate that the
           DEK is in plaintext by setting **MLX5DV_DEK_INIT_ATTR_CRYPTO_LOGIN**
           value in _comp_mask_ and passing NULL value in _crypto_login_ field of
           _init_attr_ , fill the other DEK attributes and create the DEK.
    
           To use the created DEK (either wrapped or plaintext) in a MKey, a
           valid crypto login object or session is not needed.  Revoking the
           import KEK or credential that were used for the crypto login
           object or session (and therefore rendering the crypto login
           invalid) does not prevent using a created DEK.
    
           **mlx5dv_dek_query()** queries the DEK specified by _dek_ and returns
           the queried attributes in _attr_.  A valid crypto login object or
           session is not required to query a plaintext DEK.  On the other
           hand, to query a wrapped DEK a valid crypto login object or
           session must be present.
    
           **mlx5dv_dek_destroy()** destroys the DEK specified by _dek_.
    


## ARGUMENTS



       **context**
           The device context to create the DEK with.
    
       **init_attr**
                  enum mlx5dv_dek_init_attr_mask {
                      MLX5DV_DEK_INIT_ATTR_CRYPTO_LOGIN = 1 << 0,
                  };
    
                  struct mlx5dv_dek_init_attr {
                      enum mlx5dv_crypto_key_size key_size;
                      bool has_keytag;
                      enum mlx5dv_crypto_key_purpose key_purpose;
                      struct ibv_pd *pd;
                      char opaque[8];
                      char key[128];
                      uint64_t comp_mask; /* Use enum mlx5dv_dek_init_attr_mask */
                      struct mlx5dv_crypto_login_obj *crypto_login;
                  };
    
           _key_size_
                  The size of the key, can be one of the following
    
                  **MLX5DV_CRYPTO_KEY_SIZE_128**
                         Key size is 128 bit.
    
                  **MLX5DV_CRYPTO_KEY_SIZE_256**
                         Key size is 256 bit.
    
           _has_keytag_
                  Whether the DEK has a keytag or not.  If set, the key
                  should include a 8 Bytes keytag.  Keytag is used to verify
                  that the DEK being used by a MKey is the expected DEK.
                  This is done by comparing the keytag that was defined
                  during DEK creation with the keytag provided in the MKey
                  crypto configuration, and failing the operation if they are
                  different.
    
           _key_purpose_
                  The purpose of the key, currently can only be the following
                  value
    
                  **MLX5DV_CRYPTO_KEY_PURPOSE_AES_XTS**
                         The key will be used for AES-XTS crypto engine.
    
           _pd_     The protection domain to be associated with the DEK.
    
           _opaque_ Plaintext metadata to describe the key.
    
           _key_    The key that will be used for encryption and decryption of
                  transmitted data.  For plaintext DEK _key_ must be provided
                  in plaintext.  For wrapped DEK _key_ must be provided wrapped
                  by the import KEK that was specified in the crypto login.
                  Actual size and layout of this field depend on the provided
                  _key_size_ and _has_keytag_ fields, as well as on the format of
                  the key (plaintext or wrapped).  _key_ should be constructed
                  according to the following table.
    
                  DEK _key_ Field Construction.
                  Import         Has Keytag   Key size     Key Layout
                  Method
                  ────────────────────────────────────────────────────────────────────────────────
                  Plaintext      No           128 Bit      key1_128b + key2_128b
    
                  Plaintext      No           256 Bit      key1_256b + key2_256b
    
                  Plaintext      Yes          128 Bit      key1_128b + key2_128b + keytag_64b
    
                  Plaintext      Yes          256 Bit      key1_256b + key2_256b + keytag_64b
    
                  Wrapped        No           128 Bit      ENC(iv_64b + key1_128b + key2_128b)
    
                  Wrapped        No           256 Bit      ENC(iv_64b + key1_256b + key2_256b)
    
                  Wrapped        Yes          128 Bit      ENC(iv_64b + key1_128b + key2_128b +
                                                           keytag_64b)
    
                  Wrapped        Yes          256 Bit      ENC(iv_64b + key1_256b + key2_256b +
                                                           keytag_64b)
    
                  Where ENC() is AES key wrap algorithm and iv_64b is
                  0xA6A6A6A6A6A6A6A6 as per the NIST SP 800-38F AES key wrap
                  spec.
    
                  The following example shows how to wrap a 128 bit key that
                  has keytag using a 128 bit import KEK in OpenSSL:
    
                         #include <openssl/evp.h>
    
                         unsigned char import_kek[16]; /* 128 bit import KEK in plaintext for wrapping */
                         unsigned char iv[8] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6};
    
                         /*
                          * Indexes 0-15 are key1 in plaintext, indexes 16-31 are key2 in plaintext,
                          * and indexes 32-39 are key_tag in plaintext.
                          */
                         unsigned char key[40];
    
                         unsigned char wrapped_key[48];
                         EVP_CIPHER_CTX *ctx;
                         int len;
    
                         ctx = EVP_CIPHER_CTX_new();
                         EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
                         EVP_EncryptInit_ex(ctx, EVP_aes_128_wrap(), NULL, import_kek, iv);
                         EVP_EncryptUpdate(ctx, wrapped_key, &len, key, sizeof(key));
                         EVP_EncryptFinal_ex(ctx, wrapped_key + len, &len);
                         EVP_CIPHER_CTX_free(ctx);
    
           _comp_mask_
                  Currently can be the following value:
    
                  **MLX5DV_DEK_INIT_ATTR_CRYPTO_LOGIN** , which indicates that
                  _crypto_login_ field is applicable.
    
           _crypto_login_
                  Pointer to a crypto login object.  If set to a valid crypto
                  login object, indicates that this is a wrapped DEK that
                  will be created using the given crypto login object.  If
                  set to NULL, indicates that this is a plaintext DEK.  Must
                  be NULL if **MLX5DV_DEK_INIT_ATTR_CRYPTO_LOGIN** is not set.
                  Only relevant when comp_mask is set with
                  _MLX5DV_DEK_INIT_ATTR_CRYPTO_LOGIN_
    
       **dek**
                  Pointer to an existing DEK to query or to destroy.
    
       **attr**
                  DEK attributes to be populated when querying a DEK.
    
                  struct mlx5dv_dek_attr {
                      enum mlx5dv_dek_state state;
                      char opaque[8];
                      uint64_t comp_mask;
                  };
    
           _state_  The state of the DEK, can be one of the following
    
                  **MLX5DV_DEK_STATE_READY**
                         The key is ready for use.  This is the state of the
                         key when it is first created.
    
                  **MLX5DV_DEK_STATE_ERROR**
                         The key is unusable.  The key needs to be destroyed
                         and re-created in order to be used.  This can
                         happen, for example, due to DEK memory corruption.
    
           _opaque_ Plaintext metadata to describe the key.
    
           _comp_mask_
                  Reserved for future extension, must be 0 now.
    


## RETURN VALUE



           **mlx5dv_dek_create()** returns a pointer to a new _struct mlx5dv_dek_
           on success.  On error NULL is returned and errno is set.
    
           **mlx5dv_dek_query()** returns 0 on success and updates _attr_ with the
           queried DEK attributes.  On error errno value is returned.
    
           **mlx5dv_dek_destroy()** returns 0 on success and errno value on
           error.
    


* * *