ons. */
    GCRY_CIPHER_ARCFOUR     = 301,  /* Fully compatible with RSA's RC4 (tm). */
    GCRY_CIPHER_DES         = 302,  /* Yes, this is single key 56 bit DES. */
    GCRY_CIPHER_TWOFISH128  = 303,
    GCRY_CIPHER_SERPENT128  = 304,
    GCRY_CIPHER_SERPENT192  = 305,
    GCRY_CIPHER_SERPENT256  = 306,
    GCRY_CIPHER_RFC2268_40  = 307,  /* Ron's Cipher 2 (40 bit). */
    GCRY_CIPHER_RFC2268_128 = 308,  /* Ron's Cipher 2 (128 bit). */
    GCRY_CIPHER_SEED        = 309,  /* 128 bit cipher described in RFC4269. */
    GCRY_CIPHER_CAMELLIA128 = 310,
    GCRY_CIPHER_CAMELLIA192 = 311,
    GCRY_CIPHER_CAMELLIA256 = 312,
    GCRY_CIPHER_SALSA20     = 313,
    GCRY_CIPHER_SALSA20R12  = 314,
    GCRY_CIPHER_GOST28147   = 315,
    GCRY_CIPHER_CHACHA20    = 316,
    GCRY_CIPHER_GOST28147_MESH   = 317, /* With CryptoPro key meshing.  */
    GCRY_CIPHER_SM4         = 318,
    GCRY_CIPHER_ARIA128     = 319,
    GCRY_CIPHER_ARIA192     = 320,
    GCRY_CIPHER_ARIA256     = 321
  };

/* The Rijndael algorithm is basically AES, so provide some macros. */
#define GCRY_CIPHER_AES128      GCRY_CIPHER_AES
#define GCRY_CIPHER_RIJNDAEL    GCRY_CIPHER_AES
#define GCRY_CIPHER_RIJNDAEL128 GCRY_CIPHER_AES128
#define GCRY_CIPHER_RIJNDAEL192 GCRY_CIPHER_AES192
#define GCRY_CIPHER_RIJNDAEL256 GCRY_CIPHER_AES256

/* The supported encryption modes.  Note that not all of them are
   supported for each algorithm. */
enum gcry_cipher_modes
  {
    GCRY_CIPHER_MODE_NONE     = 0,   /* Not yet specified. */
    GCRY_CIPHER_MODE_ECB      = 1,   /* Electronic codebook. */
    GCRY_CIPHER_MODE_CFB      = 2,   /* Cipher feedback. */
    GCRY_CIPHER_MODE_CBC      = 3,   /* Cipher block chaining. */
    GCRY_CIPHER_MODE_STREAM   = 4,   /* Used with stream ciphers. */
    GCRY_CIPHER_MODE_OFB      = 5,   /* Outer feedback. */
    GCRY_CIPHER_MODE_CTR      = 6,   /* Counter. */
    GCRY_CIPHER_MODE_AESWRAP  = 7,   /* AES-WRAP algorithm.  */
    GCRY_CIPHER_MODE_CCM      = 8,   /* Counter with CBC-MAC.  */
    GCRY_CIPHER_MODE_GCM      = 9,   /* Galois Counter Mode. */
    GCRY_CIPHER_MODE_POLY1305 = 10,  /* Poly1305 based AEAD mode. */
    GCRY_CIPHER_MODE_OCB      = 11,  /* OCB3 mode.  */
    GCRY_CIPHER_MODE_CFB8     = 12,  /* Cipher feedback (8 bit mode). */
    GCRY_CIPHER_MODE_XTS      = 13,  /* XTS mode.  */
    GCRY_CIPHER_MODE_EAX      = 14,  /* EAX mode.  */
    GCRY_CIPHER_MODE_SIV      = 15,  /* SIV mode.  */
    GCRY_CIPHER_MODE_GCM_SIV  = 16   /* GCM-SIV mode.  */
  };

/* Flags used with the open function. */
enum gcry_cipher_flags
  {
    GCRY_CIPHER_SECURE      = 1,  /* Allocate in secure memory. */
    GCRY_CIPHER_ENABLE_SYNC = 2,  /* Enable CFB sync mode. */
    GCRY_CIPHER_CBC_CTS     = 4,  /* Enable CBC cipher text stealing (CTS). */
    GCRY_CIPHER_CBC_MAC     = 8,  /* Enable CBC message auth. code (MAC).  */
    GCRY_CIPHER_EXTENDED    = 16  /* Enable extended AES-WRAP.  */
  };

/* Methods used for AEAD IV generation. */
enum gcry_cipher_geniv_methods
  {
    GCRY_CIPHER_GENIV_METHOD_CONCAT = 1,
    GCRY_CIPHER_GENIV_METHOD_XOR = 2
  };

/* GCM works only with blocks of 128 bits */
#define GCRY_GCM_BLOCK_LEN  (128 / 8)

/* CCM works only with blocks of 128 bits.  */
#define GCRY_CCM_BLOCK_LEN  (128 / 8)

/* OCB works only with blocks of 128 bits.  */
#define GCRY_OCB_BLOCK_LEN  (128 / 8)

/* XTS works only with blocks of 128 bits.  */
#define GCRY_XTS_BLOCK_LEN  (128 / 8)

/* SIV and GCM-SIV works only with blocks of 128 bits */
#define GCRY_SIV_BLOCK_LEN  (128 / 8)

/* Create a handle for algorithm ALGO to be used in MODE.  FLAGS may
   be given as an bitwise OR of the gcry_cipher_flags values. */
gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle,
                              int algo, int mode, unsigned int flags);

/* Close the cipher handle H and release all resource. */
void gcry_cipher_close (gcry_cipher_hd_t h);

/* Perform various operations on the cipher object H. */
gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer,
                             size_t buflen);

/* Retrieve various information about the cipher object H. */
gcry_error_t gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer,
                              size_t *nbytes);

/* Retrieve various information about the cipher algorithm ALGO. */
gcry_error_t gcry_cipher_algo_info (int algo, int what, void *buffer,
                                   size_t *nbytes);

/* Map the cipher algorithm whose ID is contained in ALGORITHM to a
   string representation of the algorithm name.  For unknown algorithm
   IDs this function returns "?".  */
const char *gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;

/* Map the algorithm name NAME to an cipher algorithm ID.  Return 0 if
   the algorithm name is not known. */
int gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE;

/* Given an ASN.1 object identifier in standard IETF dotted decimal
   format in STRING, return the encryption mode associated with that
   OID or 0 if not known or applicable. */
int gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE;

/* Encrypt the plaintext of size INLEN in IN using the cipher handle H
   into the buffer OUT which has an allocated length of OUTSIZE.  For
   most algorithms it is possible to pass NULL for in and 0 for INLEN
   and do a in-place decryption of the data provided in OUT.  */
gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h,
                                  void *out, size_t outsize,
                                  const void *in, size_t inlen);

/* The counterpart to gcry_cipher_encrypt.  */
gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t h,
                                  void *out, size_t outsize,
                                  const void *in, size_t inlen);

/* Set KEY of length KEYLEN bytes for the cipher handle HD.  */
gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd,
                                 const void *key, size_t keylen);


/* Set initialization vector IV of length IVLEN for the cipher handle HD. */
gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd,
                                const void *iv, size_t ivlen);

/* Initialization vector generation setup for AEAD modes/ciphers.  */
gcry_error_t gcry_cipher_setup_geniv (gcry_cipher_hd_t hd, int method,
                                      const void *fixed_iv, size_t fixed_ivlen,
                                      const void *dyn_iv, size_t dyn_ivlen);

/* Initialization vector generation for AEAD modes/ciphers.  */
gcry_error_t gcry_cipher_geniv (gcry_cipher_hd_t hd,
                                void *iv, size_t ivlen);

/* Provide additional authentication data for AEAD modes/ciphers.  */
gcry_error_t gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf,
                                       size_t abuflen);

/* Get authentication tag for AEAD modes/ciphers.  */
gcry_error_t gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag,
                                 size_t taglen);

/* Check authentication tag for AEAD modes/ciphers.  */
gcry_error_t gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag,
                                   size_t taglen);

/* Reset the handle to the state after open.  */
#define gcry_cipher_reset(h)  gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0)

/* Perform the OpenPGP sync operation if this is enabled for the
   cipher handle H. */
#define gcry_cipher_sync(h)  gcry_cipher_ctl( (h), GCRYCTL_CFB_SYNC, NULL, 0)

/* Enable or disable CTS in future calls to gcry_cipher_encrypt().
 * CBC mode only. */
#define gcry_cipher_cts(h,on)  gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \
                                                                   NULL, on )

#define gcry_cipher_set_sbox(h,oid) gcry_cipher_ctl( (h), GCRYCTL_SET_SBOX, \
                                                     (void *) oid, 0);

/* Indicate to the encrypt and decrypt functions that the next call
   provides the final data.  Only used with some modes.  */
#define gcry_cipher_final(a) \
            gcry_cipher_ctl ((a), GCRYCTL_FINALIZE, NULL, 0)

/* Set counter for CTR mode.  (CTR,CTRLEN) must denote a buffer of
   block size length, or (NULL,0) to set the CTR to the all-zero block. */
gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd,
                                const void *ctr, size_t ctrlen);

/* Retrieve the key length in bytes used with algorithm A. */
size_t gcry_cipher_get_algo_keylen (int algo);

/* Retrieve the block length in bytes used with algorithm A. */
size_t gcry_cipher_get_algo_blklen (int algo);

/* Return 0 if the algorithm A is available for use. */
#define gcry_cipher_test_algo(a) \
            gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )

/* Setup tag for decryption (for SIV and GCM-SIV mode). */
#define gcry_cipher_set_decryption_tag(a, tag, taglen) \
            gcry_cipher_ctl ((a), GCRYCTL_SET_DECRYPTION_TAG, \
                             (void *)(tag), (taglen))

