diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h index f93363b4..89886962 100644 --- a/cipher/cipher-internal.h +++ b/cipher/cipher-internal.h @@ -1,747 +1,749 @@ /* cipher-internal.h - Internal defs for cipher.c * Copyright (C) 2011 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser general Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #ifndef G10_CIPHER_INTERNAL_H #define G10_CIPHER_INTERNAL_H #include "./poly1305-internal.h" /* The maximum supported size of a block in bytes. */ #define MAX_BLOCKSIZE 16 /* The length for an OCB block. Although OCB supports any block length it does not make sense to use a 64 bit blocklen (and cipher) because this reduces the security margin to an unacceptable state. Thus we require a cipher with 128 bit blocklength. */ #define OCB_BLOCK_LEN (128/8) /* The size of the pre-computed L table for OCB. This takes the same size as the table used for GCM and thus we don't save anything by not using such a table. */ #define OCB_L_TABLE_SIZE 16 /* Check the above constants. */ #if OCB_BLOCK_LEN > MAX_BLOCKSIZE # error OCB_BLOCKLEN > MAX_BLOCKSIZE #endif /* Magic values for the context structure. */ #define CTX_MAGIC_NORMAL 0x24091964 #define CTX_MAGIC_SECURE 0x46919042 /* Try to use 16 byte aligned cipher context for better performance. We use the aligned attribute, thus it is only possible to implement this with gcc. */ #undef NEED_16BYTE_ALIGNED_CONTEXT #ifdef HAVE_GCC_ATTRIBUTE_ALIGNED # define NEED_16BYTE_ALIGNED_CONTEXT 1 #endif /* Undef this symbol to trade GCM speed for 256 bytes of memory per context */ #define GCM_USE_TABLES 1 /* GCM_USE_INTEL_PCLMUL indicates whether to compile GCM with Intel PCLMUL code. */ #undef GCM_USE_INTEL_PCLMUL #if defined(ENABLE_PCLMUL_SUPPORT) && defined(GCM_USE_TABLES) # if ((defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)) # if __GNUC__ >= 4 # define GCM_USE_INTEL_PCLMUL 1 # endif # endif #endif /* GCM_USE_INTEL_PCLMUL */ /* GCM_USE_ARM_PMULL indicates whether to compile GCM with ARMv8 PMULL code. */ #undef GCM_USE_ARM_PMULL #if defined(ENABLE_ARM_CRYPTO_SUPPORT) && defined(GCM_USE_TABLES) # if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \ && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \ && defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO) # define GCM_USE_ARM_PMULL 1 # elif defined(__AARCH64EL__) && \ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \ defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO) # define GCM_USE_ARM_PMULL 1 # endif #endif /* GCM_USE_ARM_PMULL */ typedef unsigned int (*ghash_fn_t) (gcry_cipher_hd_t c, byte *result, const byte *buf, size_t nblocks); /* A VIA processor with the Padlock engine as well as the Intel AES_NI instructions require an alignment of most data on a 16 byte boundary. Because we trick out the compiler while allocating the context, the align attribute as used in rijndael.c does not work on its own. Thus we need to make sure that the entire context structure is a aligned on that boundary. We achieve this by defining a new type and use that instead of our usual alignment type. */ typedef union { PROPERLY_ALIGNED_TYPE foo; #ifdef NEED_16BYTE_ALIGNED_CONTEXT char bar[16] __attribute__ ((aligned (16))); #endif char c[1]; } cipher_context_alignment_t; /* Storage structure for CMAC, for CMAC and EAX modes. */ typedef struct { /* The initialization vector. Also contains tag after finalization. */ union { cipher_context_alignment_t iv_align; unsigned char iv[MAX_BLOCKSIZE]; } u_iv; /* Subkeys for tag creation, not cleared by gcry_cipher_reset. */ unsigned char subkeys[2][MAX_BLOCKSIZE]; /* Space to save partial input lengths for MAC. */ unsigned char macbuf[MAX_BLOCKSIZE]; int mac_unused; /* Number of unprocessed bytes in MACBUF. */ unsigned int tag:1; /* Set to 1 if tag has been finalized. */ } gcry_cmac_context_t; /* The handle structure. */ struct gcry_cipher_handle { int magic; size_t actual_handle_size; /* Allocated size of this handle. */ size_t handle_offset; /* Offset to the malloced block. */ gcry_cipher_spec_t *spec; /* The algorithm id. This is a hack required because the module interface does not easily allow to retrieve this value. */ int algo; /* A structure with function pointers for mode operations. */ struct { gcry_err_code_t (*encrypt)(gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t (*decrypt)(gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t (*setiv)(gcry_cipher_hd_t c, const unsigned char *iv, size_t ivlen); gcry_err_code_t (*authenticate)(gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen); gcry_err_code_t (*get_tag)(gcry_cipher_hd_t c, unsigned char *outtag, size_t taglen); gcry_err_code_t (*check_tag)(gcry_cipher_hd_t c, const unsigned char *intag, size_t taglen); } mode_ops; /* A structure with function pointers for bulk operations. Due to limitations of the module system (we don't want to change the API) we need to keep these function pointers here. The cipher open function initializes them and the actual encryption routines use them if they are not NULL. */ struct { void (*cfb_enc)(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); void (*cfb_dec)(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); void (*cbc_enc)(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int cbc_mac); void (*cbc_dec)(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); void (*ctr_enc)(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); size_t (*ocb_crypt)(gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); size_t (*ocb_auth)(gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); void (*xts_crypt)(void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); } bulk; int mode; unsigned int flags; struct { unsigned int key:1; /* Set to 1 if a key has been set. */ unsigned int iv:1; /* Set to 1 if a IV has been set. */ unsigned int tag:1; /* Set to 1 if a tag is finalized. */ unsigned int finalize:1; /* Next encrypt/decrypt has the final data. */ } marks; /* The initialization vector. For best performance we make sure that it is properly aligned. In particular some implementations of bulk operations expect an 16 byte aligned IV. IV is also used to store CBC-MAC in CCM mode; counter IV is stored in U_CTR. For OCB mode it is used for the offset value. */ union { cipher_context_alignment_t iv_align; unsigned char iv[MAX_BLOCKSIZE]; } u_iv; /* The counter for CTR mode. This field is also used by AESWRAP and thus we can't use the U_IV union. For OCB mode it is used for the checksum. */ union { cipher_context_alignment_t iv_align; unsigned char ctr[MAX_BLOCKSIZE]; } u_ctr; /* Space to save an IV or CTR for chaining operations. */ unsigned char lastiv[MAX_BLOCKSIZE]; int unused; /* Number of unused bytes in LASTIV. */ union { /* Mode specific storage for CCM mode. */ struct { u64 encryptlen; u64 aadlen; unsigned int authlen; /* Space to save partial input lengths for MAC. */ unsigned char macbuf[GCRY_CCM_BLOCK_LEN]; int mac_unused; /* Number of unprocessed bytes in MACBUF. */ unsigned char s0[GCRY_CCM_BLOCK_LEN]; unsigned int nonce:1; /* Set to 1 if nonce has been set. */ unsigned int lengths:1; /* Set to 1 if CCM length parameters has been processed. */ } ccm; /* Mode specific storage for Poly1305 mode. */ struct { /* byte counter for AAD. */ u32 aadcount[2]; /* byte counter for data. */ u32 datacount[2]; unsigned int aad_finalized:1; unsigned int bytecount_over_limits:1; poly1305_context_t ctx; } poly1305; /* Mode specific storage for CMAC mode. */ gcry_cmac_context_t cmac; /* Mode specific storage for EAX mode. */ struct { /* CMAC for header (AAD). */ gcry_cmac_context_t cmac_header; /* CMAC for ciphertext. */ gcry_cmac_context_t cmac_ciphertext; } eax; /* Mode specific storage for GCM mode. */ struct { /* The interim tag for GCM mode. */ union { cipher_context_alignment_t iv_align; unsigned char tag[MAX_BLOCKSIZE]; } u_tag; /* Space to save partial input lengths for MAC. */ unsigned char macbuf[GCRY_CCM_BLOCK_LEN]; int mac_unused; /* Number of unprocessed bytes in MACBUF. */ /* byte counters for GCM */ u32 aadlen[2]; u32 datalen[2]; /* encrypted tag counter */ unsigned char tagiv[MAX_BLOCKSIZE]; unsigned int ghash_data_finalized:1; unsigned int ghash_aad_finalized:1; unsigned int datalen_over_limits:1; unsigned int disallow_encryption_because_of_setiv_in_fips_mode:1; /* --- Following members are not cleared in gcry_cipher_reset --- */ /* GHASH multiplier from key. */ union { cipher_context_alignment_t iv_align; unsigned char key[MAX_BLOCKSIZE]; } u_ghash_key; /* GHASH implementation in use. */ ghash_fn_t ghash_fn; /* Pre-calculated table for GCM. */ #ifdef GCM_USE_TABLES #if (SIZEOF_UNSIGNED_LONG == 8 || defined(__x86_64__)) #define GCM_TABLES_USE_U64 1 u64 gcm_table[2 * 16]; #else #undef GCM_TABLES_USE_U64 u32 gcm_table[4 * 16]; #endif #endif } gcm; /* Mode specific storage for OCB mode. */ struct { /* Helper variables and pre-computed table of L values. */ unsigned char L_star[OCB_BLOCK_LEN]; unsigned char L_dollar[OCB_BLOCK_LEN]; - unsigned char L[OCB_BLOCK_LEN][OCB_L_TABLE_SIZE]; + unsigned char L0L1[OCB_BLOCK_LEN]; + unsigned char L0L1L0[OCB_BLOCK_LEN]; + unsigned char L[OCB_L_TABLE_SIZE][OCB_BLOCK_LEN]; /* The tag is valid if marks.tag has been set. */ unsigned char tag[OCB_BLOCK_LEN]; /* A buffer to hold the offset for the AAD processing. */ unsigned char aad_offset[OCB_BLOCK_LEN]; /* A buffer to hold the current sum of AAD processing. We can't use tag here because tag may already hold the preprocessed checksum of the data. */ unsigned char aad_sum[OCB_BLOCK_LEN]; /* A buffer to store AAD data not yet processed. */ unsigned char aad_leftover[OCB_BLOCK_LEN]; /* Number of data/aad blocks processed so far. */ u64 data_nblocks; u64 aad_nblocks; /* Number of valid bytes in AAD_LEFTOVER. */ unsigned char aad_nleftover; /* Length of the tag. Fixed for now but may eventually be specified using a set of gcry_cipher_flags. */ unsigned char taglen; /* Flags indicating that the final data/aad block has been processed. */ unsigned int data_finalized:1; unsigned int aad_finalized:1; } ocb; /* Mode specific storage for XTS mode. */ struct { /* Pointer to tweak cipher context, allocated after actual * cipher context. */ char *tweak_context; } xts; } u_mode; /* What follows are two contexts of the cipher in use. The first one needs to be aligned well enough for the cipher operation whereas the second one is a copy created by cipher_setkey and used by cipher_reset. That second copy has no need for proper aligment because it is only accessed by memcpy. */ cipher_context_alignment_t context; }; /*-- cipher-cbc.c --*/ gcry_err_code_t _gcry_cipher_cbc_encrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_cbc_decrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_cbc_cts_encrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_cbc_cts_decrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); /*-- cipher-cfb.c --*/ gcry_err_code_t _gcry_cipher_cfb_encrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_cfb_decrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_cfb8_encrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_cfb8_decrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); /*-- cipher-ofb.c --*/ gcry_err_code_t _gcry_cipher_ofb_encrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); /*-- cipher-ctr.c --*/ gcry_err_code_t _gcry_cipher_ctr_encrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); /*-- cipher-aeswrap.c --*/ gcry_err_code_t _gcry_cipher_aeswrap_encrypt /* */ (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, const byte *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_aeswrap_decrypt /* */ (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, const byte *inbuf, size_t inbuflen); /*-- cipher-ccm.c --*/ gcry_err_code_t _gcry_cipher_ccm_encrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_ccm_decrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_ccm_set_nonce /* */ (gcry_cipher_hd_t c, const unsigned char *nonce, size_t noncelen); gcry_err_code_t _gcry_cipher_ccm_authenticate /* */ (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen); gcry_err_code_t _gcry_cipher_ccm_set_lengths /* */ (gcry_cipher_hd_t c, u64 encryptedlen, u64 aadlen, u64 taglen); gcry_err_code_t _gcry_cipher_ccm_get_tag /* */ (gcry_cipher_hd_t c, unsigned char *outtag, size_t taglen); gcry_err_code_t _gcry_cipher_ccm_check_tag /* */ (gcry_cipher_hd_t c, const unsigned char *intag, size_t taglen); /*-- cipher-cmac.c --*/ gcry_err_code_t _gcry_cmac_generate_subkeys /* */ (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx); gcry_err_code_t _gcry_cmac_write /* */ (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx, const byte * inbuf, size_t inlen); gcry_err_code_t _gcry_cmac_final /* */ (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx); void _gcry_cmac_reset (gcry_cmac_context_t *ctx); /*-- cipher-eax.c --*/ gcry_err_code_t _gcry_cipher_eax_encrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_eax_decrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_eax_set_nonce /* */ (gcry_cipher_hd_t c, const unsigned char *nonce, size_t noncelen); gcry_err_code_t _gcry_cipher_eax_authenticate /* */ (gcry_cipher_hd_t c, const unsigned char *aadbuf, size_t aadbuflen); gcry_err_code_t _gcry_cipher_eax_get_tag /* */ (gcry_cipher_hd_t c, unsigned char *outtag, size_t taglen); gcry_err_code_t _gcry_cipher_eax_check_tag /* */ (gcry_cipher_hd_t c, const unsigned char *intag, size_t taglen); gcry_err_code_t _gcry_cipher_eax_setkey /* */ (gcry_cipher_hd_t c); /*-- cipher-gcm.c --*/ gcry_err_code_t _gcry_cipher_gcm_encrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_gcm_decrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_gcm_setiv /* */ (gcry_cipher_hd_t c, const unsigned char *iv, size_t ivlen); gcry_err_code_t _gcry_cipher_gcm_authenticate /* */ (gcry_cipher_hd_t c, const unsigned char *aadbuf, size_t aadbuflen); gcry_err_code_t _gcry_cipher_gcm_get_tag /* */ (gcry_cipher_hd_t c, unsigned char *outtag, size_t taglen); gcry_err_code_t _gcry_cipher_gcm_check_tag /* */ (gcry_cipher_hd_t c, const unsigned char *intag, size_t taglen); void _gcry_cipher_gcm_setkey /* */ (gcry_cipher_hd_t c); /*-- cipher-poly1305.c --*/ gcry_err_code_t _gcry_cipher_poly1305_encrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_poly1305_decrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_poly1305_setiv /* */ (gcry_cipher_hd_t c, const unsigned char *iv, size_t ivlen); gcry_err_code_t _gcry_cipher_poly1305_authenticate /* */ (gcry_cipher_hd_t c, const unsigned char *aadbuf, size_t aadbuflen); gcry_err_code_t _gcry_cipher_poly1305_get_tag /* */ (gcry_cipher_hd_t c, unsigned char *outtag, size_t taglen); gcry_err_code_t _gcry_cipher_poly1305_check_tag /* */ (gcry_cipher_hd_t c, const unsigned char *intag, size_t taglen); void _gcry_cipher_poly1305_setkey /* */ (gcry_cipher_hd_t c); /*-- cipher-ocb.c --*/ gcry_err_code_t _gcry_cipher_ocb_encrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_ocb_decrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_ocb_set_nonce /* */ (gcry_cipher_hd_t c, const unsigned char *nonce, size_t noncelen); gcry_err_code_t _gcry_cipher_ocb_authenticate /* */ (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen); gcry_err_code_t _gcry_cipher_ocb_get_tag /* */ (gcry_cipher_hd_t c, unsigned char *outtag, size_t taglen); gcry_err_code_t _gcry_cipher_ocb_check_tag /* */ (gcry_cipher_hd_t c, const unsigned char *intag, size_t taglen); /*-- cipher-xts.c --*/ gcry_err_code_t _gcry_cipher_xts_encrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); gcry_err_code_t _gcry_cipher_xts_decrypt /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen); /* Return the L-value for block N. Note: 'cipher_ocb.c' ensures that N * will never be multiple of 65536 (1 << OCB_L_TABLE_SIZE), thus N can * be directly passed to _gcry_ctz() function and resulting index will * never overflow the table. */ static inline const unsigned char * ocb_get_l (gcry_cipher_hd_t c, u64 n) { unsigned long ntz; #if ((defined(__i386__) || defined(__x86_64__)) && __GNUC__ >= 4) /* Assumes that N != 0. */ asm ("rep;bsfl %k[low], %k[ntz]\n\t" : [ntz] "=r" (ntz) : [low] "r" ((unsigned long)n) : "cc"); #else ntz = _gcry_ctz (n); #endif return c->u_mode.ocb.L[ntz]; } /* Return bit-shift of blocksize. */ static inline unsigned int _gcry_blocksize_shift(gcry_cipher_hd_t c) { /* Only blocksizes 8 and 16 are used. Return value in such way * that compiler can optimize calling functions based on this. */ return c->spec->blocksize == 8 ? 3 : 4; } /* Optimized function for cipher block copying */ static inline void cipher_block_cpy(void *_dst, const void *_src, size_t blocksize) { byte *dst = _dst; const byte *src = _src; u64 s[2]; if (blocksize == 8) { buf_put_he64(dst + 0, buf_get_he64(src + 0)); } else /* blocksize == 16 */ { s[0] = buf_get_he64(src + 0); s[1] = buf_get_he64(src + 8); buf_put_he64(dst + 0, s[0]); buf_put_he64(dst + 8, s[1]); } } /* Optimized function for cipher block xoring */ static inline void cipher_block_xor(void *_dst, const void *_src1, const void *_src2, size_t blocksize) { byte *dst = _dst; const byte *src1 = _src1; const byte *src2 = _src2; u64 s1[2]; u64 s2[2]; if (blocksize == 8) { buf_put_he64(dst + 0, buf_get_he64(src1 + 0) ^ buf_get_he64(src2 + 0)); } else /* blocksize == 16 */ { s1[0] = buf_get_he64(src1 + 0); s1[1] = buf_get_he64(src1 + 8); s2[0] = buf_get_he64(src2 + 0); s2[1] = buf_get_he64(src2 + 8); buf_put_he64(dst + 0, s1[0] ^ s2[0]); buf_put_he64(dst + 8, s1[1] ^ s2[1]); } } /* Optimized function for in-place cipher block xoring */ static inline void cipher_block_xor_1(void *_dst, const void *_src, size_t blocksize) { cipher_block_xor (_dst, _dst, _src, blocksize); } /* Optimized function for cipher block xoring with two destination cipher blocks. Used mainly by CFB mode encryption. */ static inline void cipher_block_xor_2dst(void *_dst1, void *_dst2, const void *_src, size_t blocksize) { byte *dst1 = _dst1; byte *dst2 = _dst2; const byte *src = _src; u64 d2[2]; u64 s[2]; if (blocksize == 8) { d2[0] = buf_get_he64(dst2 + 0) ^ buf_get_he64(src + 0); buf_put_he64(dst2 + 0, d2[0]); buf_put_he64(dst1 + 0, d2[0]); } else /* blocksize == 16 */ { s[0] = buf_get_he64(src + 0); s[1] = buf_get_he64(src + 8); d2[0] = buf_get_he64(dst2 + 0); d2[1] = buf_get_he64(dst2 + 8); d2[0] = d2[0] ^ s[0]; d2[1] = d2[1] ^ s[1]; buf_put_he64(dst2 + 0, d2[0]); buf_put_he64(dst2 + 8, d2[1]); buf_put_he64(dst1 + 0, d2[0]); buf_put_he64(dst1 + 8, d2[1]); } } /* Optimized function for combined cipher block xoring and copying. Used by mainly CBC mode decryption. */ static inline void cipher_block_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy, const void *_src_cpy, size_t blocksize) { byte *dst_xor = _dst_xor; byte *srcdst_cpy = _srcdst_cpy; const byte *src_xor = _src_xor; const byte *src_cpy = _src_cpy; u64 sc[2]; u64 sx[2]; u64 sdc[2]; if (blocksize == 8) { sc[0] = buf_get_he64(src_cpy + 0); buf_put_he64(dst_xor + 0, buf_get_he64(srcdst_cpy + 0) ^ buf_get_he64(src_xor + 0)); buf_put_he64(srcdst_cpy + 0, sc[0]); } else /* blocksize == 16 */ { sc[0] = buf_get_he64(src_cpy + 0); sc[1] = buf_get_he64(src_cpy + 8); sx[0] = buf_get_he64(src_xor + 0); sx[1] = buf_get_he64(src_xor + 8); sdc[0] = buf_get_he64(srcdst_cpy + 0); sdc[1] = buf_get_he64(srcdst_cpy + 8); sx[0] ^= sdc[0]; sx[1] ^= sdc[1]; buf_put_he64(dst_xor + 0, sx[0]); buf_put_he64(dst_xor + 8, sx[1]); buf_put_he64(srcdst_cpy + 0, sc[0]); buf_put_he64(srcdst_cpy + 8, sc[1]); } } /* Optimized function for combined cipher block xoring and copying. Used by mainly CFB mode decryption. */ static inline void cipher_block_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src, size_t blocksize) { cipher_block_xor_n_copy_2(_dst_xor, _src, _srcdst_cpy, _src, blocksize); } #endif /*G10_CIPHER_INTERNAL_H*/ diff --git a/cipher/cipher-ocb.c b/cipher/cipher-ocb.c index f71520ad..58f7be7e 100644 --- a/cipher/cipher-ocb.c +++ b/cipher/cipher-ocb.c @@ -1,728 +1,739 @@ /* cipher-ocb.c - OCB cipher mode * Copyright (C) 2015, 2016 g10 Code GmbH * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser general Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * * * OCB is covered by several patents but may be used freely by most * software. See http://web.cs.ucdavis.edu/~rogaway/ocb/license.htm . * In particular license 1 is suitable for Libgcrypt: See * http://web.cs.ucdavis.edu/~rogaway/ocb/license1.pdf for the full * license document; it basically says: * * License 1 — License for Open-Source Software Implementations of OCB * (Jan 9, 2013) * * Under this license, you are authorized to make, use, and * distribute open-source software implementations of OCB. This * license terminates for you if you sue someone over their * open-source software implementation of OCB claiming that you have * a patent covering their implementation. */ #include #include #include #include #include #include "g10lib.h" #include "cipher.h" #include "bufhelp.h" #include "./cipher-internal.h" /* Double the OCB_BLOCK_LEN sized block B in-place. */ static inline void double_block (unsigned char *b) { #if OCB_BLOCK_LEN != 16 unsigned char b_0 = b[0]; int i; for (i=0; i < OCB_BLOCK_LEN - 1; i++) b[i] = (b[i] << 1) | (b[i+1] >> 7); b[OCB_BLOCK_LEN-1] = (b[OCB_BLOCK_LEN-1] << 1) ^ ((b_0 >> 7) * 135); #else /* This is the generic code for 16 byte blocks. However it is not faster than the straight byte by byte implementation. */ u64 l_0, l, r; l = buf_get_be64 (b); r = buf_get_be64 (b + 8); l_0 = -(l >> 63); l = (l + l) ^ (r >> 63); r = (r + r) ^ (l_0 & 135); buf_put_be64 (b, l); buf_put_be64 (b+8, r); #endif } /* Double the OCB_BLOCK_LEN sized block S and store it at D. S and D may point to the same memory location but they may not overlap. */ static void double_block_cpy (unsigned char *d, const unsigned char *s) { if (d != s) cipher_block_cpy (d, s, OCB_BLOCK_LEN); double_block (d); } /* Copy NBYTES from buffer S starting at bit offset BITOFF to buffer D. */ static void bit_copy (unsigned char *d, const unsigned char *s, unsigned int bitoff, unsigned int nbytes) { unsigned int shift; s += bitoff / 8; shift = bitoff % 8; if (shift) { for (; nbytes; nbytes--, d++, s++) *d = (s[0] << shift) | (s[1] >> (8 - shift)); } else { for (; nbytes; nbytes--, d++, s++) *d = *s; } } /* Get L_big value for block N, where N is multiple of 65536. */ static void ocb_get_L_big (gcry_cipher_hd_t c, u64 n, unsigned char *l_buf) { int ntz = _gcry_ctz64 (n); gcry_assert(ntz >= OCB_L_TABLE_SIZE); double_block_cpy (l_buf, c->u_mode.ocb.L[OCB_L_TABLE_SIZE - 1]); for (ntz -= OCB_L_TABLE_SIZE; ntz; ntz--) double_block (l_buf); } /* Set the nonce for OCB. This requires that the key has been set. Using it again resets start a new encryption cycle using the same key. */ gcry_err_code_t _gcry_cipher_ocb_set_nonce (gcry_cipher_hd_t c, const unsigned char *nonce, size_t noncelen) { unsigned char ktop[OCB_BLOCK_LEN]; unsigned char stretch[OCB_BLOCK_LEN + 8]; unsigned int bottom; int i; unsigned int burn = 0; unsigned int nburn; /* Check args. */ if (!c->marks.key) return GPG_ERR_INV_STATE; /* Key must have been set first. */ switch (c->u_mode.ocb.taglen) { case 8: case 12: case 16: break; default: return GPG_ERR_BUG; /* Invalid tag length. */ } if (c->spec->blocksize != OCB_BLOCK_LEN) return GPG_ERR_CIPHER_ALGO; if (!nonce) return GPG_ERR_INV_ARG; /* 120 bit is the allowed maximum. In addition we impose a minimum of 64 bit. */ if (noncelen > (120/8) || noncelen < (64/8) || noncelen >= OCB_BLOCK_LEN) return GPG_ERR_INV_LENGTH; /* Set up the L table. */ /* L_star = E(zero_128) */ memset (ktop, 0, OCB_BLOCK_LEN); nburn = c->spec->encrypt (&c->context.c, c->u_mode.ocb.L_star, ktop); burn = nburn > burn ? nburn : burn; /* L_dollar = double(L_star) */ double_block_cpy (c->u_mode.ocb.L_dollar, c->u_mode.ocb.L_star); /* L_0 = double(L_dollar), ... */ double_block_cpy (c->u_mode.ocb.L[0], c->u_mode.ocb.L_dollar); for (i = 1; i < OCB_L_TABLE_SIZE; i++) double_block_cpy (c->u_mode.ocb.L[i], c->u_mode.ocb.L[i-1]); + /* Precalculated offsets L0+L1, L0+L1+L0 */ + cipher_block_xor (c->u_mode.ocb.L0L1, + c->u_mode.ocb.L[0], c->u_mode.ocb.L[1], OCB_BLOCK_LEN); + cipher_block_xor (c->u_mode.ocb.L0L1L0, + c->u_mode.ocb.L[0], c->u_mode.ocb.L0L1, OCB_BLOCK_LEN); /* Prepare the nonce. */ memset (ktop, 0, (OCB_BLOCK_LEN - noncelen)); buf_cpy (ktop + (OCB_BLOCK_LEN - noncelen), nonce, noncelen); ktop[0] = ((c->u_mode.ocb.taglen * 8) % 128) << 1; ktop[OCB_BLOCK_LEN - noncelen - 1] |= 1; bottom = ktop[OCB_BLOCK_LEN - 1] & 0x3f; ktop[OCB_BLOCK_LEN - 1] &= 0xc0; /* Zero the bottom bits. */ nburn = c->spec->encrypt (&c->context.c, ktop, ktop); burn = nburn > burn ? nburn : burn; /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */ cipher_block_cpy (stretch, ktop, OCB_BLOCK_LEN); cipher_block_xor (stretch + OCB_BLOCK_LEN, ktop, ktop + 1, 8); /* Offset_0 = Stretch[1+bottom..128+bottom] (We use the IV field to store the offset) */ bit_copy (c->u_iv.iv, stretch, bottom, OCB_BLOCK_LEN); c->marks.iv = 1; /* Checksum_0 = zeros(128) (We use the CTR field to store the checksum) */ memset (c->u_ctr.ctr, 0, OCB_BLOCK_LEN); /* Clear AAD buffer. */ memset (c->u_mode.ocb.aad_offset, 0, OCB_BLOCK_LEN); memset (c->u_mode.ocb.aad_sum, 0, OCB_BLOCK_LEN); /* Setup other values. */ memset (c->lastiv, 0, sizeof(c->lastiv)); c->unused = 0; c->marks.tag = 0; c->marks.finalize = 0; c->u_mode.ocb.data_nblocks = 0; c->u_mode.ocb.aad_nblocks = 0; c->u_mode.ocb.aad_nleftover = 0; c->u_mode.ocb.data_finalized = 0; c->u_mode.ocb.aad_finalized = 0; /* log_printhex ("L_* ", c->u_mode.ocb.L_star, OCB_BLOCK_LEN); */ /* log_printhex ("L_$ ", c->u_mode.ocb.L_dollar, OCB_BLOCK_LEN); */ /* log_printhex ("L_0 ", c->u_mode.ocb.L[0], OCB_BLOCK_LEN); */ /* log_printhex ("L_1 ", c->u_mode.ocb.L[1], OCB_BLOCK_LEN); */ /* log_debug ( "bottom : %u (decimal)\n", bottom); */ /* log_printhex ("Ktop ", ktop, OCB_BLOCK_LEN); */ /* log_printhex ("Stretch ", stretch, sizeof stretch); */ /* log_printhex ("Offset_0 ", c->u_iv.iv, OCB_BLOCK_LEN); */ /* Cleanup */ wipememory (ktop, sizeof ktop); wipememory (stretch, sizeof stretch); if (burn > 0) _gcry_burn_stack (burn + 4*sizeof(void*)); return 0; } /* Process additional authentication data. This implementation allows to add additional authentication data at any time before the final gcry_cipher_gettag. */ gcry_err_code_t _gcry_cipher_ocb_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen) { const size_t table_maxblks = 1 << OCB_L_TABLE_SIZE; const u32 table_size_mask = ((1 << OCB_L_TABLE_SIZE) - 1); unsigned char l_tmp[OCB_BLOCK_LEN]; unsigned int burn = 0; unsigned int nburn; /* Check that a nonce and thus a key has been set and that we have not yet computed the tag. We also return an error if the aad has been finalized (i.e. a short block has been processed). */ if (!c->marks.iv || c->marks.tag || c->u_mode.ocb.aad_finalized) return GPG_ERR_INV_STATE; /* Check correct usage and arguments. */ if (c->spec->blocksize != OCB_BLOCK_LEN) return GPG_ERR_CIPHER_ALGO; /* Process remaining data from the last call first. */ if (c->u_mode.ocb.aad_nleftover) { for (; abuflen && c->u_mode.ocb.aad_nleftover < OCB_BLOCK_LEN; abuf++, abuflen--) c->u_mode.ocb.aad_leftover[c->u_mode.ocb.aad_nleftover++] = *abuf; if (c->u_mode.ocb.aad_nleftover == OCB_BLOCK_LEN) { c->u_mode.ocb.aad_nblocks++; if ((c->u_mode.ocb.aad_nblocks % table_maxblks) == 0) { /* Table overflow, L needs to be generated. */ ocb_get_L_big(c, c->u_mode.ocb.aad_nblocks + 1, l_tmp); } else { cipher_block_cpy (l_tmp, ocb_get_l (c, c->u_mode.ocb.aad_nblocks), OCB_BLOCK_LEN); } /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, l_tmp, OCB_BLOCK_LEN); /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ cipher_block_xor (l_tmp, c->u_mode.ocb.aad_offset, c->u_mode.ocb.aad_leftover, OCB_BLOCK_LEN); nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp); burn = nburn > burn ? nburn : burn; cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); c->u_mode.ocb.aad_nleftover = 0; } } if (!abuflen) { if (burn > 0) _gcry_burn_stack (burn + 4*sizeof(void*)); return 0; } /* Full blocks handling. */ while (abuflen >= OCB_BLOCK_LEN) { size_t nblks = abuflen / OCB_BLOCK_LEN; size_t nmaxblks; /* Check how many blocks to process till table overflow. */ nmaxblks = (c->u_mode.ocb.aad_nblocks + 1) % table_maxblks; nmaxblks = (table_maxblks - nmaxblks) % table_maxblks; if (nmaxblks == 0) { /* Table overflow, generate L and process one block. */ c->u_mode.ocb.aad_nblocks++; ocb_get_L_big(c, c->u_mode.ocb.aad_nblocks, l_tmp); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, l_tmp, OCB_BLOCK_LEN); /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ cipher_block_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, OCB_BLOCK_LEN); nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp); burn = nburn > burn ? nburn : burn; cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); abuf += OCB_BLOCK_LEN; abuflen -= OCB_BLOCK_LEN; nblks--; /* With overflow handled, retry loop again. Next overflow will * happen after 65535 blocks. */ continue; } nblks = nblks < nmaxblks ? nblks : nmaxblks; /* Use a bulk method if available. */ if (nblks && c->bulk.ocb_auth) { size_t nleft; size_t ndone; nleft = c->bulk.ocb_auth (c, abuf, nblks); ndone = nblks - nleft; abuf += ndone * OCB_BLOCK_LEN; abuflen -= ndone * OCB_BLOCK_LEN; nblks = nleft; } /* Hash all full blocks. */ while (nblks) { c->u_mode.ocb.aad_nblocks++; gcry_assert(c->u_mode.ocb.aad_nblocks & table_size_mask); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, ocb_get_l (c, c->u_mode.ocb.aad_nblocks), OCB_BLOCK_LEN); /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ cipher_block_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, OCB_BLOCK_LEN); nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp); burn = nburn > burn ? nburn : burn; cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); abuf += OCB_BLOCK_LEN; abuflen -= OCB_BLOCK_LEN; nblks--; } } /* Store away the remaining data. */ for (; abuflen && c->u_mode.ocb.aad_nleftover < OCB_BLOCK_LEN; abuf++, abuflen--) c->u_mode.ocb.aad_leftover[c->u_mode.ocb.aad_nleftover++] = *abuf; gcry_assert (!abuflen); if (burn > 0) _gcry_burn_stack (burn + 4*sizeof(void*)); return 0; } /* Hash final partial AAD block. */ static void ocb_aad_finalize (gcry_cipher_hd_t c) { unsigned char l_tmp[OCB_BLOCK_LEN]; unsigned int burn = 0; unsigned int nburn; /* Check that a nonce and thus a key has been set and that we have not yet computed the tag. We also skip this if the aad has been finalized. */ if (!c->marks.iv || c->marks.tag || c->u_mode.ocb.aad_finalized) return; if (c->spec->blocksize != OCB_BLOCK_LEN) return; /* Ooops. */ /* Hash final partial block if any. */ if (c->u_mode.ocb.aad_nleftover) { /* Offset_* = Offset_m xor L_* */ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, c->u_mode.ocb.L_star, OCB_BLOCK_LEN); /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */ buf_cpy (l_tmp, c->u_mode.ocb.aad_leftover, c->u_mode.ocb.aad_nleftover); memset (l_tmp + c->u_mode.ocb.aad_nleftover, 0, OCB_BLOCK_LEN - c->u_mode.ocb.aad_nleftover); l_tmp[c->u_mode.ocb.aad_nleftover] = 0x80; cipher_block_xor_1 (l_tmp, c->u_mode.ocb.aad_offset, OCB_BLOCK_LEN); /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */ nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp); burn = nburn > burn ? nburn : burn; cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); c->u_mode.ocb.aad_nleftover = 0; } /* Mark AAD as finalized so that gcry_cipher_ocb_authenticate can * return an erro when called again. */ c->u_mode.ocb.aad_finalized = 1; if (burn > 0) _gcry_burn_stack (burn + 4*sizeof(void*)); } /* Checksumming for encrypt and decrypt. */ static void ocb_checksum (unsigned char *chksum, const unsigned char *plainbuf, size_t nblks) { while (nblks > 0) { /* Checksum_i = Checksum_{i-1} xor P_i */ cipher_block_xor_1(chksum, plainbuf, OCB_BLOCK_LEN); plainbuf += OCB_BLOCK_LEN; nblks--; } } /* Common code for encrypt and decrypt. */ static gcry_err_code_t ocb_crypt (gcry_cipher_hd_t c, int encrypt, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen) { const size_t table_maxblks = 1 << OCB_L_TABLE_SIZE; const u32 table_size_mask = ((1 << OCB_L_TABLE_SIZE) - 1); unsigned char l_tmp[OCB_BLOCK_LEN]; unsigned int burn = 0; unsigned int nburn; gcry_cipher_encrypt_t crypt_fn = encrypt ? c->spec->encrypt : c->spec->decrypt; /* Check that a nonce and thus a key has been set and that we are not yet in end of data state. */ if (!c->marks.iv || c->u_mode.ocb.data_finalized) return GPG_ERR_INV_STATE; /* Check correct usage and arguments. */ if (c->spec->blocksize != OCB_BLOCK_LEN) return GPG_ERR_CIPHER_ALGO; if (outbuflen < inbuflen) return GPG_ERR_BUFFER_TOO_SHORT; if (c->marks.finalize) ; /* Allow arbitarty length. */ else if ((inbuflen % OCB_BLOCK_LEN)) return GPG_ERR_INV_LENGTH; /* We support only full blocks for now. */ /* Full blocks handling. */ while (inbuflen >= OCB_BLOCK_LEN) { size_t nblks = inbuflen / OCB_BLOCK_LEN; size_t nmaxblks; /* Check how many blocks to process till table overflow. */ nmaxblks = (c->u_mode.ocb.data_nblocks + 1) % table_maxblks; nmaxblks = (table_maxblks - nmaxblks) % table_maxblks; if (nmaxblks == 0) { /* Table overflow, generate L and process one block. */ c->u_mode.ocb.data_nblocks++; ocb_get_L_big(c, c->u_mode.ocb.data_nblocks, l_tmp); if (encrypt) { /* Checksum_i = Checksum_{i-1} xor P_i */ ocb_checksum (c->u_ctr.ctr, inbuf, 1); } /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ cipher_block_xor_1 (c->u_iv.iv, l_tmp, OCB_BLOCK_LEN); /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ cipher_block_xor (outbuf, c->u_iv.iv, inbuf, OCB_BLOCK_LEN); nburn = crypt_fn (&c->context.c, outbuf, outbuf); burn = nburn > burn ? nburn : burn; cipher_block_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN); if (!encrypt) { /* Checksum_i = Checksum_{i-1} xor P_i */ ocb_checksum (c->u_ctr.ctr, outbuf, 1); } inbuf += OCB_BLOCK_LEN; inbuflen -= OCB_BLOCK_LEN; outbuf += OCB_BLOCK_LEN; outbuflen =- OCB_BLOCK_LEN; nblks--; /* With overflow handled, retry loop again. Next overflow will * happen after 65535 blocks. */ continue; } nblks = nblks < nmaxblks ? nblks : nmaxblks; + /* Since checksum xoring is done before/after encryption/decryption, + process input in 24KiB chunks to keep data loaded in L1 cache for + checksumming. */ + if (nblks > 24 * 1024 / OCB_BLOCK_LEN) + nblks = 24 * 1024 / OCB_BLOCK_LEN; + /* Use a bulk method if available. */ if (nblks && c->bulk.ocb_crypt) { size_t nleft; size_t ndone; nleft = c->bulk.ocb_crypt (c, outbuf, inbuf, nblks, encrypt); ndone = nblks - nleft; inbuf += ndone * OCB_BLOCK_LEN; outbuf += ndone * OCB_BLOCK_LEN; inbuflen -= ndone * OCB_BLOCK_LEN; outbuflen -= ndone * OCB_BLOCK_LEN; nblks = nleft; } if (nblks) { size_t nblks_chksum = nblks; if (encrypt) { /* Checksum_i = Checksum_{i-1} xor P_i */ ocb_checksum (c->u_ctr.ctr, inbuf, nblks_chksum); } /* Encrypt all full blocks. */ while (nblks) { c->u_mode.ocb.data_nblocks++; gcry_assert(c->u_mode.ocb.data_nblocks & table_size_mask); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ cipher_block_xor_1 (c->u_iv.iv, ocb_get_l (c, c->u_mode.ocb.data_nblocks), OCB_BLOCK_LEN); /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ cipher_block_xor (outbuf, c->u_iv.iv, inbuf, OCB_BLOCK_LEN); nburn = crypt_fn (&c->context.c, outbuf, outbuf); burn = nburn > burn ? nburn : burn; cipher_block_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN); inbuf += OCB_BLOCK_LEN; inbuflen -= OCB_BLOCK_LEN; outbuf += OCB_BLOCK_LEN; outbuflen =- OCB_BLOCK_LEN; nblks--; } if (!encrypt) { /* Checksum_i = Checksum_{i-1} xor P_i */ ocb_checksum (c->u_ctr.ctr, outbuf - nblks_chksum * OCB_BLOCK_LEN, nblks_chksum); } } } /* Encrypt final partial block. Note that we expect INBUFLEN to be shorter than OCB_BLOCK_LEN (see above). */ if (inbuflen) { unsigned char pad[OCB_BLOCK_LEN]; /* Offset_* = Offset_m xor L_* */ cipher_block_xor_1 (c->u_iv.iv, c->u_mode.ocb.L_star, OCB_BLOCK_LEN); /* Pad = ENCIPHER(K, Offset_*) */ nburn = c->spec->encrypt (&c->context.c, pad, c->u_iv.iv); burn = nburn > burn ? nburn : burn; if (encrypt) { /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */ /* Note that INBUFLEN is less than OCB_BLOCK_LEN. */ buf_cpy (l_tmp, inbuf, inbuflen); memset (l_tmp + inbuflen, 0, OCB_BLOCK_LEN - inbuflen); l_tmp[inbuflen] = 0x80; cipher_block_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN); /* C_* = P_* xor Pad[1..bitlen(P_*)] */ buf_xor (outbuf, inbuf, pad, inbuflen); } else { /* P_* = C_* xor Pad[1..bitlen(C_*)] */ /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */ cipher_block_cpy (l_tmp, pad, OCB_BLOCK_LEN); buf_cpy (l_tmp, inbuf, inbuflen); cipher_block_xor_1 (l_tmp, pad, OCB_BLOCK_LEN); l_tmp[inbuflen] = 0x80; buf_cpy (outbuf, l_tmp, inbuflen); cipher_block_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN); } } /* Compute the tag if the finalize flag has been set. */ if (c->marks.finalize) { /* Tag = ENCIPHER(K, Checksum xor Offset xor L_$) xor HASH(K,A) */ cipher_block_xor (c->u_mode.ocb.tag, c->u_ctr.ctr, c->u_iv.iv, OCB_BLOCK_LEN); cipher_block_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.L_dollar, OCB_BLOCK_LEN); nburn = c->spec->encrypt (&c->context.c, c->u_mode.ocb.tag, c->u_mode.ocb.tag); burn = nburn > burn ? nburn : burn; c->u_mode.ocb.data_finalized = 1; /* Note that the the final part of the tag computation is done by _gcry_cipher_ocb_get_tag. */ } if (burn > 0) _gcry_burn_stack (burn + 4*sizeof(void*)); return 0; } /* Encrypt (INBUF,INBUFLEN) in OCB mode to OUTBUF. OUTBUFLEN gives the allocated size of OUTBUF. This function accepts only multiples of a full block unless gcry_cipher_final has been called in which case the next block may have any length. */ gcry_err_code_t _gcry_cipher_ocb_encrypt (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen) { return ocb_crypt (c, 1, outbuf, outbuflen, inbuf, inbuflen); } /* Decrypt (INBUF,INBUFLEN) in OCB mode to OUTBUF. OUTBUFLEN gives the allocated size of OUTBUF. This function accepts only multiples of a full block unless gcry_cipher_final has been called in which case the next block may have any length. */ gcry_err_code_t _gcry_cipher_ocb_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen) { return ocb_crypt (c, 0, outbuf, outbuflen, inbuf, inbuflen); } /* Compute the tag. The last data operation has already done some part of it. To allow adding AAD even after having done all data, we finish the tag computation only here. */ static void compute_tag_if_needed (gcry_cipher_hd_t c) { if (!c->marks.tag) { ocb_aad_finalize (c); cipher_block_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.aad_sum, OCB_BLOCK_LEN); c->marks.tag = 1; } } /* Copy the already computed tag to OUTTAG. OUTTAGSIZE is the allocated size of OUTTAG; the function returns an error if that is too short to hold the tag. */ gcry_err_code_t _gcry_cipher_ocb_get_tag (gcry_cipher_hd_t c, unsigned char *outtag, size_t outtagsize) { if (c->u_mode.ocb.taglen > outtagsize) return GPG_ERR_BUFFER_TOO_SHORT; if (!c->u_mode.ocb.data_finalized) return GPG_ERR_INV_STATE; /* Data has not yet been finalized. */ compute_tag_if_needed (c); memcpy (outtag, c->u_mode.ocb.tag, c->u_mode.ocb.taglen); return 0; } /* Check that the tag (INTAG,TAGLEN) matches the computed tag for the handle C. */ gcry_err_code_t _gcry_cipher_ocb_check_tag (gcry_cipher_hd_t c, const unsigned char *intag, size_t taglen) { size_t n; if (!c->u_mode.ocb.data_finalized) return GPG_ERR_INV_STATE; /* Data has not yet been finalized. */ compute_tag_if_needed (c); n = c->u_mode.ocb.taglen; if (taglen < n) n = taglen; if (!buf_eq_const (intag, c->u_mode.ocb.tag, n) || c->u_mode.ocb.taglen != taglen) return GPG_ERR_CHECKSUM; return 0; } diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c index d190c0ac..c1ebab06 100644 --- a/cipher/rijndael-aesni.c +++ b/cipher/rijndael-aesni.c @@ -1,3344 +1,3517 @@ /* AES-NI accelerated AES for Libgcrypt * Copyright (C) 2000, 2001, 2002, 2003, 2007, * 2008, 2011, 2012 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #include #include #include #include /* for memcmp() */ #include "types.h" /* for byte and u32 typedefs */ #include "g10lib.h" #include "cipher.h" #include "bufhelp.h" #include "cipher-selftest.h" #include "rijndael-internal.h" #include "./cipher-internal.h" #ifdef USE_AESNI #if _GCRY_GCC_VERSION >= 40400 /* 4.4 */ /* Prevent compiler from issuing SSE instructions between asm blocks. */ # pragma GCC target("no-sse") #endif +#define ALWAYS_INLINE inline __attribute__((always_inline)) +#define NO_INLINE __attribute__((noinline)) + + typedef struct u128_s { u32 a, b, c, d; } __attribute__((packed, aligned(1), may_alias)) u128_t; /* Copy of ocb_get_l needed here as GCC is unable to inline ocb_get_l because of 'pragma target'. */ -static inline const unsigned char * +static ALWAYS_INLINE const unsigned char * aes_ocb_get_l (gcry_cipher_hd_t c, u64 n) { unsigned long ntz; /* Assumes that N != 0. */ asm ("rep;bsfl %k[low], %k[ntz]\n\t" : [ntz] "=r" (ntz) : [low] "r" ((unsigned long)n) : "cc"); return c->u_mode.ocb.L[ntz]; } /* Two macros to be called prior and after the use of AESNI instructions. There should be no external function calls between the use of these macros. There purpose is to make sure that the SSE regsiters are cleared and won't reveal any information about the key or the data. */ #ifdef __WIN64__ /* XMM6-XMM15 are callee-saved registers on WIN64. */ -# define aesni_prepare_2_6_variable char win64tmp[16] -# define aesni_prepare_7_15_variable char win64tmp7_15[16 * 9] +# define aesni_prepare_2_7_variable char win64tmp[16 * 2] +# define aesni_prepare_8_15_variable char win64tmp8_15[16 * 8] # define aesni_prepare() do { } while (0) -# define aesni_prepare_2_6() \ +# define aesni_prepare_2_7() \ do { asm volatile ("movdqu %%xmm6, %0\n\t" \ - : "=m" (*win64tmp) \ + "movdqu %%xmm7, %1\n\t" \ + : "=m" (*win64tmp), "=m" (*(win64tmp+16)) \ : \ : "memory"); \ } while (0) -# define aesni_prepare_7_15() \ - do { asm volatile ("movdqu %%xmm7, 0*16(%0)\n\t" \ - "movdqu %%xmm8, 1*16(%0)\n\t" \ - "movdqu %%xmm9, 2*16(%0)\n\t" \ - "movdqu %%xmm10, 3*16(%0)\n\t" \ - "movdqu %%xmm11, 4*16(%0)\n\t" \ - "movdqu %%xmm12, 5*16(%0)\n\t" \ - "movdqu %%xmm13, 6*16(%0)\n\t" \ - "movdqu %%xmm14, 7*16(%0)\n\t" \ - "movdqu %%xmm15, 8*16(%0)\n\t" \ +# define aesni_prepare_8_15() \ + do { asm volatile ("movdqu %%xmm8, 0*16(%0)\n\t" \ + "movdqu %%xmm9, 1*16(%0)\n\t" \ + "movdqu %%xmm10, 2*16(%0)\n\t" \ + "movdqu %%xmm11, 3*16(%0)\n\t" \ + "movdqu %%xmm12, 4*16(%0)\n\t" \ + "movdqu %%xmm13, 5*16(%0)\n\t" \ + "movdqu %%xmm14, 6*16(%0)\n\t" \ + "movdqu %%xmm15, 7*16(%0)\n\t" \ : \ - : "r" (win64tmp7_15) \ + : "r" (win64tmp8_15) \ : "memory"); \ } while (0) # define aesni_cleanup() \ do { asm volatile ("pxor %%xmm0, %%xmm0\n\t" \ "pxor %%xmm1, %%xmm1\n" :: ); \ } while (0) -# define aesni_cleanup_2_6() \ +# define aesni_cleanup_2_7() \ do { asm volatile ("movdqu %0, %%xmm6\n\t" \ + "movdqu %1, %%xmm7\n\t" \ "pxor %%xmm2, %%xmm2\n" \ "pxor %%xmm3, %%xmm3\n" \ "pxor %%xmm4, %%xmm4\n" \ "pxor %%xmm5, %%xmm5\n" \ : \ - : "m" (*win64tmp) \ + : "m" (*win64tmp), "m" (*(win64tmp+16)) \ : "memory"); \ } while (0) -# define aesni_cleanup_7_15() \ - do { asm volatile ("movdqu 0*16(%0), %%xmm7\n\t" \ - "movdqu 1*16(%0), %%xmm8\n\t" \ - "movdqu 2*16(%0), %%xmm9\n\t" \ - "movdqu 3*16(%0), %%xmm10\n\t" \ - "movdqu 4*16(%0), %%xmm11\n\t" \ - "movdqu 5*16(%0), %%xmm12\n\t" \ - "movdqu 6*16(%0), %%xmm13\n\t" \ - "movdqu 7*16(%0), %%xmm14\n\t" \ - "movdqu 8*16(%0), %%xmm15\n\t" \ +# define aesni_cleanup_8_15() \ + do { asm volatile ("movdqu 0*16(%0), %%xmm8\n\t" \ + "movdqu 1*16(%0), %%xmm9\n\t" \ + "movdqu 2*16(%0), %%xmm10\n\t" \ + "movdqu 3*16(%0), %%xmm11\n\t" \ + "movdqu 4*16(%0), %%xmm12\n\t" \ + "movdqu 5*16(%0), %%xmm13\n\t" \ + "movdqu 6*16(%0), %%xmm14\n\t" \ + "movdqu 7*16(%0), %%xmm15\n\t" \ : \ - : "r" (win64tmp7_15) \ + : "r" (win64tmp8_15) \ : "memory"); \ } while (0) #else -# define aesni_prepare_2_6_variable +# define aesni_prepare_2_7_variable # define aesni_prepare() do { } while (0) -# define aesni_prepare_2_6() do { } while (0) +# define aesni_prepare_2_7() do { } while (0) # define aesni_cleanup() \ do { asm volatile ("pxor %%xmm0, %%xmm0\n\t" \ "pxor %%xmm1, %%xmm1\n" :: ); \ } while (0) -# define aesni_cleanup_2_6() \ - do { asm volatile ("pxor %%xmm2, %%xmm2\n\t" \ +# define aesni_cleanup_2_7() \ + do { asm volatile ("pxor %%xmm7, %%xmm7\n\t" \ + "pxor %%xmm2, %%xmm2\n\t" \ "pxor %%xmm3, %%xmm3\n" \ "pxor %%xmm4, %%xmm4\n" \ "pxor %%xmm5, %%xmm5\n" \ "pxor %%xmm6, %%xmm6\n":: ); \ } while (0) # ifdef __x86_64__ -# define aesni_prepare_7_15_variable -# define aesni_prepare_7_15() do { } while (0) -# define aesni_cleanup_7_15() \ - do { asm volatile ("pxor %%xmm7, %%xmm7\n\t" \ - "pxor %%xmm8, %%xmm8\n" \ +# define aesni_prepare_8_15_variable +# define aesni_prepare_8_15() do { } while (0) +# define aesni_cleanup_8_15() \ + do { asm volatile ("pxor %%xmm8, %%xmm8\n" \ "pxor %%xmm9, %%xmm9\n" \ "pxor %%xmm10, %%xmm10\n" \ "pxor %%xmm11, %%xmm11\n" \ "pxor %%xmm12, %%xmm12\n" \ "pxor %%xmm13, %%xmm13\n" \ "pxor %%xmm14, %%xmm14\n" \ "pxor %%xmm15, %%xmm15\n":: ); \ } while (0) # endif #endif void _gcry_aes_aesni_do_setkey (RIJNDAEL_context *ctx, const byte *key) { - aesni_prepare_2_6_variable; + aesni_prepare_2_7_variable; aesni_prepare(); - aesni_prepare_2_6(); + aesni_prepare_2_7(); if (ctx->rounds < 12) { /* 128-bit key */ #define AESKEYGENASSIST_xmm1_xmm2(imm8) \ ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t" #define AESKEY_EXPAND128 \ "pshufd $0xff, %%xmm2, %%xmm2\n\t" \ "movdqa %%xmm1, %%xmm3\n\t" \ "pslldq $4, %%xmm3\n\t" \ "pxor %%xmm3, %%xmm1\n\t" \ "pslldq $4, %%xmm3\n\t" \ "pxor %%xmm3, %%xmm1\n\t" \ "pslldq $4, %%xmm3\n\t" \ "pxor %%xmm3, %%xmm2\n\t" \ "pxor %%xmm2, %%xmm1\n\t" asm volatile ("movdqu (%[key]), %%xmm1\n\t" /* xmm1 := key */ "movdqa %%xmm1, (%[ksch])\n\t" /* ksch[0] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x01) AESKEY_EXPAND128 "movdqa %%xmm1, 0x10(%[ksch])\n\t" /* ksch[1] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x02) AESKEY_EXPAND128 "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x04) AESKEY_EXPAND128 "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x08) AESKEY_EXPAND128 "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x10) AESKEY_EXPAND128 "movdqa %%xmm1, 0x50(%[ksch])\n\t" /* ksch[5] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x20) AESKEY_EXPAND128 "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x40) AESKEY_EXPAND128 "movdqa %%xmm1, 0x70(%[ksch])\n\t" /* ksch[7] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x80) AESKEY_EXPAND128 "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x1b) AESKEY_EXPAND128 "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x36) AESKEY_EXPAND128 "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1 */ : : [key] "r" (key), [ksch] "r" (ctx->keyschenc) : "cc", "memory" ); #undef AESKEYGENASSIST_xmm1_xmm2 #undef AESKEY_EXPAND128 } else if (ctx->rounds == 12) { /* 192-bit key */ #define AESKEYGENASSIST_xmm3_xmm2(imm8) \ ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t" #define AESKEY_EXPAND192 \ "pshufd $0x55, %%xmm2, %%xmm2\n\t" \ "movdqu %%xmm1, %%xmm4\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm1\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm1\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm1\n\t" \ "pxor %%xmm2, %%xmm1\n\t" \ "pshufd $0xff, %%xmm1, %%xmm2\n\t" \ "movdqu %%xmm3, %%xmm4\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm3\n\t" \ "pxor %%xmm2, %%xmm3\n\t" asm volatile ("movdqu (%[key]), %%xmm1\n\t" /* xmm1 := key[0..15] */ "movq 16(%[key]), %%xmm3\n\t" /* xmm3 := key[16..23] */ "movdqa %%xmm1, (%[ksch])\n\t" /* ksch[0] := xmm1 */ "movdqa %%xmm3, %%xmm5\n\t" AESKEYGENASSIST_xmm3_xmm2(0x01) AESKEY_EXPAND192 "shufpd $0, %%xmm1, %%xmm5\n\t" "movdqa %%xmm5, 0x10(%[ksch])\n\t" /* ksch[1] := xmm5 */ "movdqa %%xmm1, %%xmm6\n\t" "shufpd $1, %%xmm3, %%xmm6\n\t" "movdqa %%xmm6, 0x20(%[ksch])\n\t" /* ksch[2] := xmm6 */ AESKEYGENASSIST_xmm3_xmm2(0x02) AESKEY_EXPAND192 "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1 */ "movdqa %%xmm3, %%xmm5\n\t" AESKEYGENASSIST_xmm3_xmm2(0x04) AESKEY_EXPAND192 "shufpd $0, %%xmm1, %%xmm5\n\t" "movdqa %%xmm5, 0x40(%[ksch])\n\t" /* ksch[4] := xmm5 */ "movdqa %%xmm1, %%xmm6\n\t" "shufpd $1, %%xmm3, %%xmm6\n\t" "movdqa %%xmm6, 0x50(%[ksch])\n\t" /* ksch[5] := xmm6 */ AESKEYGENASSIST_xmm3_xmm2(0x08) AESKEY_EXPAND192 "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1 */ "movdqa %%xmm3, %%xmm5\n\t" AESKEYGENASSIST_xmm3_xmm2(0x10) AESKEY_EXPAND192 "shufpd $0, %%xmm1, %%xmm5\n\t" "movdqa %%xmm5, 0x70(%[ksch])\n\t" /* ksch[7] := xmm5 */ "movdqa %%xmm1, %%xmm6\n\t" "shufpd $1, %%xmm3, %%xmm6\n\t" "movdqa %%xmm6, 0x80(%[ksch])\n\t" /* ksch[8] := xmm6 */ AESKEYGENASSIST_xmm3_xmm2(0x20) AESKEY_EXPAND192 "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1 */ "movdqa %%xmm3, %%xmm5\n\t" AESKEYGENASSIST_xmm3_xmm2(0x40) AESKEY_EXPAND192 "shufpd $0, %%xmm1, %%xmm5\n\t" "movdqa %%xmm5, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm5 */ "movdqa %%xmm1, %%xmm6\n\t" "shufpd $1, %%xmm3, %%xmm6\n\t" "movdqa %%xmm6, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm6 */ AESKEYGENASSIST_xmm3_xmm2(0x80) AESKEY_EXPAND192 "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1 */ : : [key] "r" (key), [ksch] "r" (ctx->keyschenc) : "cc", "memory" ); #undef AESKEYGENASSIST_xmm3_xmm2 #undef AESKEY_EXPAND192 } else if (ctx->rounds > 12) { /* 256-bit key */ #define AESKEYGENASSIST_xmm1_xmm2(imm8) \ ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t" #define AESKEYGENASSIST_xmm3_xmm2(imm8) \ ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t" #define AESKEY_EXPAND256_A \ "pshufd $0xff, %%xmm2, %%xmm2\n\t" \ "movdqa %%xmm1, %%xmm4\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm1\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm1\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm1\n\t" \ "pxor %%xmm2, %%xmm1\n\t" #define AESKEY_EXPAND256_B \ "pshufd $0xaa, %%xmm2, %%xmm2\n\t" \ "movdqa %%xmm3, %%xmm4\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm3\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm3\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm3\n\t" \ "pxor %%xmm2, %%xmm3\n\t" asm volatile ("movdqu (%[key]), %%xmm1\n\t" /* xmm1 := key[0..15] */ "movdqu 16(%[key]), %%xmm3\n\t" /* xmm3 := key[16..31] */ "movdqa %%xmm1, (%[ksch])\n\t" /* ksch[0] := xmm1 */ "movdqa %%xmm3, 0x10(%[ksch])\n\t" /* ksch[1] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x01) AESKEY_EXPAND256_A "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x00) AESKEY_EXPAND256_B "movdqa %%xmm3, 0x30(%[ksch])\n\t" /* ksch[3] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x02) AESKEY_EXPAND256_A "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x00) AESKEY_EXPAND256_B "movdqa %%xmm3, 0x50(%[ksch])\n\t" /* ksch[5] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x04) AESKEY_EXPAND256_A "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x00) AESKEY_EXPAND256_B "movdqa %%xmm3, 0x70(%[ksch])\n\t" /* ksch[7] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x08) AESKEY_EXPAND256_A "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x00) AESKEY_EXPAND256_B "movdqa %%xmm3, 0x90(%[ksch])\n\t" /* ksch[9] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x10) AESKEY_EXPAND256_A "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x00) AESKEY_EXPAND256_B "movdqa %%xmm3, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x20) AESKEY_EXPAND256_A "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x00) AESKEY_EXPAND256_B "movdqa %%xmm3, 0xd0(%[ksch])\n\t" /* ksch[13] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x40) AESKEY_EXPAND256_A "movdqa %%xmm1, 0xe0(%[ksch])\n\t" /* ksch[14] := xmm1 */ : : [key] "r" (key), [ksch] "r" (ctx->keyschenc) : "cc", "memory" ); #undef AESKEYGENASSIST_xmm1_xmm2 #undef AESKEYGENASSIST_xmm3_xmm2 #undef AESKEY_EXPAND256_A #undef AESKEY_EXPAND256_B } aesni_cleanup(); - aesni_cleanup_2_6(); + aesni_cleanup_2_7(); } /* Make a decryption key from an encryption key. */ -static inline void +static ALWAYS_INLINE void do_aesni_prepare_decryption (RIJNDAEL_context *ctx) { /* The AES-NI decrypt instructions use the Equivalent Inverse Cipher, thus we can't use the the standard decrypt key preparation. */ u128_t *ekey = (u128_t *)ctx->keyschenc; u128_t *dkey = (u128_t *)ctx->keyschdec; int rr; int r; #define DO_AESNI_AESIMC() \ asm volatile ("movdqa %[ekey], %%xmm1\n\t" \ /*"aesimc %%xmm1, %%xmm1\n\t"*/ \ ".byte 0x66, 0x0f, 0x38, 0xdb, 0xc9\n\t" \ "movdqa %%xmm1, %[dkey]" \ : [dkey] "=m" (dkey[r]) \ : [ekey] "m" (ekey[rr]) \ : "memory") dkey[0] = ekey[ctx->rounds]; r=1; rr=ctx->rounds-1; DO_AESNI_AESIMC(); r++; rr--; /* round 1 */ DO_AESNI_AESIMC(); r++; rr--; /* round 2 */ DO_AESNI_AESIMC(); r++; rr--; /* round 3 */ DO_AESNI_AESIMC(); r++; rr--; /* round 4 */ DO_AESNI_AESIMC(); r++; rr--; /* round 5 */ DO_AESNI_AESIMC(); r++; rr--; /* round 6 */ DO_AESNI_AESIMC(); r++; rr--; /* round 7 */ DO_AESNI_AESIMC(); r++; rr--; /* round 8 */ DO_AESNI_AESIMC(); r++; rr--; /* round 9 */ if (ctx->rounds > 10) { DO_AESNI_AESIMC(); r++; rr--; /* round 10 */ DO_AESNI_AESIMC(); r++; rr--; /* round 11 */ if (ctx->rounds > 12) { DO_AESNI_AESIMC(); r++; rr--; /* round 12 */ DO_AESNI_AESIMC(); r++; rr--; /* round 13 */ } } dkey[r] = ekey[0]; #undef DO_AESNI_AESIMC } void _gcry_aes_aesni_prepare_decryption (RIJNDAEL_context *ctx) { aesni_prepare(); do_aesni_prepare_decryption (ctx); aesni_cleanup(); } /* Encrypt one block using the Intel AES-NI instructions. Block is input * and output through SSE register xmm0. */ -static inline void +static ALWAYS_INLINE void do_aesni_enc (const RIJNDAEL_context *ctx) { #define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" #define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" asm volatile ("movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x20(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x30(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x40(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x50(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x60(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x70(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x80(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x90(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xa0(%[key]), %%xmm1\n\t" "cmpl $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xc0(%[key]), %%xmm1\n\t" "cmpl $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xd0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" aesenclast_xmm1_xmm0 "\n" : : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) : "cc", "memory"); #undef aesenc_xmm1_xmm0 #undef aesenclast_xmm1_xmm0 } /* Decrypt one block using the Intel AES-NI instructions. Block is input * and output through SSE register xmm0. */ -static inline void +static ALWAYS_INLINE void do_aesni_dec (const RIJNDAEL_context *ctx) { #define aesdec_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xde, 0xc1\n\t" #define aesdeclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc1\n\t" asm volatile ("movdqa (%[key]), %%xmm1\n\t" "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x20(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x30(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x40(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x50(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x60(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x70(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x80(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x90(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0xa0(%[key]), %%xmm1\n\t" "cmpl $10, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm1_xmm0 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0xc0(%[key]), %%xmm1\n\t" "cmpl $12, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm1_xmm0 "movdqa 0xd0(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0xe0(%[key]), %%xmm1\n" ".Ldeclast%=:\n\t" aesdeclast_xmm1_xmm0 "\n" : : [key] "r" (ctx->keyschdec), [rounds] "r" (ctx->rounds) : "cc", "memory"); #undef aesdec_xmm1_xmm0 #undef aesdeclast_xmm1_xmm0 } /* Encrypt four blocks using the Intel AES-NI instructions. Blocks are input * and output through SSE registers xmm1 to xmm4. */ -static inline void +static ALWAYS_INLINE void do_aesni_enc_vec4 (const RIJNDAEL_context *ctx) { #define aesenc_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc8\n\t" #define aesenc_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd0\n\t" #define aesenc_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd8\n\t" #define aesenc_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe0\n\t" #define aesenclast_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc8\n\t" #define aesenclast_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd0\n\t" #define aesenclast_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd8\n\t" #define aesenclast_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe0\n\t" asm volatile ("movdqa (%[key]), %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x20(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x30(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x40(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x50(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x60(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x70(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x80(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x90(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0xa0(%[key]), %%xmm0\n\t" "cmpl $10, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0xb0(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0xc0(%[key]), %%xmm0\n\t" "cmpl $12, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0xd0(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0xe0(%[key]), %%xmm0\n" ".Ldeclast%=:\n\t" aesenclast_xmm0_xmm1 aesenclast_xmm0_xmm2 aesenclast_xmm0_xmm3 aesenclast_xmm0_xmm4 : /* no output */ : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) : "cc", "memory"); #undef aesenc_xmm0_xmm1 #undef aesenc_xmm0_xmm2 #undef aesenc_xmm0_xmm3 #undef aesenc_xmm0_xmm4 #undef aesenclast_xmm0_xmm1 #undef aesenclast_xmm0_xmm2 #undef aesenclast_xmm0_xmm3 #undef aesenclast_xmm0_xmm4 } /* Decrypt four blocks using the Intel AES-NI instructions. Blocks are input * and output through SSE registers xmm1 to xmm4. */ -static inline void +static ALWAYS_INLINE void do_aesni_dec_vec4 (const RIJNDAEL_context *ctx) { #define aesdec_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xde, 0xc8\n\t" #define aesdec_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xde, 0xd0\n\t" #define aesdec_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xde, 0xd8\n\t" #define aesdec_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xde, 0xe0\n\t" #define aesdeclast_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc8\n\t" #define aesdeclast_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xd0\n\t" #define aesdeclast_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xd8\n\t" #define aesdeclast_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xe0\n\t" asm volatile ("movdqa (%[key]), %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x20(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x30(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x40(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x50(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x60(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x70(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x80(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x90(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0xa0(%[key]), %%xmm0\n\t" "cmpl $10, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0xb0(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0xc0(%[key]), %%xmm0\n\t" "cmpl $12, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0xd0(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0xe0(%[key]), %%xmm0\n" ".Ldeclast%=:\n\t" aesdeclast_xmm0_xmm1 aesdeclast_xmm0_xmm2 aesdeclast_xmm0_xmm3 aesdeclast_xmm0_xmm4 : /* no output */ : [key] "r" (ctx->keyschdec), [rounds] "r" (ctx->rounds) : "cc", "memory"); #undef aesdec_xmm0_xmm1 #undef aesdec_xmm0_xmm2 #undef aesdec_xmm0_xmm3 #undef aesdec_xmm0_xmm4 #undef aesdeclast_xmm0_xmm1 #undef aesdeclast_xmm0_xmm2 #undef aesdeclast_xmm0_xmm3 #undef aesdeclast_xmm0_xmm4 } #ifdef __x86_64__ /* Encrypt eight blocks using the Intel AES-NI instructions. Blocks are input * and output through SSE registers xmm1 to xmm4 and xmm8 to xmm11. */ -static inline void +static ALWAYS_INLINE void do_aesni_enc_vec8 (const RIJNDAEL_context *ctx) { asm volatile ("movdqa (%[key]), %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ "pxor %%xmm0, %%xmm8\n\t" /* xmm8 ^= key[0] */ "pxor %%xmm0, %%xmm9\n\t" /* xmm9 ^= key[0] */ "pxor %%xmm0, %%xmm10\n\t" /* xmm10 ^= key[0] */ "pxor %%xmm0, %%xmm11\n\t" /* xmm11 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm0\n\t" "cmpl $12, %[rounds]\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x20(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x30(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x40(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x50(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x60(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x70(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x80(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x90(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xa0(%[key]), %%xmm0\n\t" "jb .Ldeclast%=\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xb0(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xc0(%[key]), %%xmm0\n\t" "je .Ldeclast%=\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xd0(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xe0(%[key]), %%xmm0\n" ".Ldeclast%=:\n\t" "aesenclast %%xmm0, %%xmm1\n\t" "aesenclast %%xmm0, %%xmm2\n\t" "aesenclast %%xmm0, %%xmm3\n\t" "aesenclast %%xmm0, %%xmm4\n\t" "aesenclast %%xmm0, %%xmm8\n\t" "aesenclast %%xmm0, %%xmm9\n\t" "aesenclast %%xmm0, %%xmm10\n\t" "aesenclast %%xmm0, %%xmm11\n\t" : /* no output */ : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) : "cc", "memory"); } /* Decrypt eight blocks using the Intel AES-NI instructions. Blocks are input * and output through SSE registers xmm1 to xmm4 and xmm8 to xmm11. */ -static inline void +static ALWAYS_INLINE void do_aesni_dec_vec8 (const RIJNDAEL_context *ctx) { asm volatile ("movdqa (%[key]), %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ "pxor %%xmm0, %%xmm8\n\t" /* xmm8 ^= key[0] */ "pxor %%xmm0, %%xmm9\n\t" /* xmm9 ^= key[0] */ "pxor %%xmm0, %%xmm10\n\t" /* xmm10 ^= key[0] */ "pxor %%xmm0, %%xmm11\n\t" /* xmm11 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm0\n\t" "cmpl $12, %[rounds]\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x20(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x30(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x40(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x50(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x60(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x70(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x80(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x90(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xa0(%[key]), %%xmm0\n\t" "jb .Ldeclast%=\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xb0(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xc0(%[key]), %%xmm0\n\t" "je .Ldeclast%=\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xd0(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xe0(%[key]), %%xmm0\n" ".Ldeclast%=:\n\t" "aesdeclast %%xmm0, %%xmm1\n\t" "aesdeclast %%xmm0, %%xmm2\n\t" "aesdeclast %%xmm0, %%xmm3\n\t" "aesdeclast %%xmm0, %%xmm4\n\t" "aesdeclast %%xmm0, %%xmm8\n\t" "aesdeclast %%xmm0, %%xmm9\n\t" "aesdeclast %%xmm0, %%xmm10\n\t" "aesdeclast %%xmm0, %%xmm11\n\t" : /* no output */ : [key] "r" (ctx->keyschdec), [rounds] "r" (ctx->rounds) : "cc", "memory"); } #endif /* __x86_64__ */ /* Perform a CTR encryption round using the counter CTR and the input block A. Write the result to the output block B and update CTR. CTR needs to be a 16 byte aligned little-endian value. */ static void do_aesni_ctr (const RIJNDAEL_context *ctx, unsigned char *ctr, unsigned char *b, const unsigned char *a) { #define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" #define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" asm volatile ("movdqa %%xmm5, %%xmm0\n\t" /* xmm0 := CTR (xmm5) */ "pcmpeqd %%xmm1, %%xmm1\n\t" "psrldq $8, %%xmm1\n\t" /* xmm1 = -1 */ "pshufb %%xmm6, %%xmm5\n\t" "psubq %%xmm1, %%xmm5\n\t" /* xmm5++ (big endian) */ /* detect if 64-bit carry handling is needed */ "cmpl $0xffffffff, 8(%[ctr])\n\t" "jne .Lno_carry%=\n\t" "cmpl $0xffffffff, 12(%[ctr])\n\t" "jne .Lno_carry%=\n\t" "pslldq $8, %%xmm1\n\t" /* move lower 64-bit to high */ "psubq %%xmm1, %%xmm5\n\t" /* add carry to upper 64bits */ ".Lno_carry%=:\n\t" "pshufb %%xmm6, %%xmm5\n\t" "movdqa %%xmm5, (%[ctr])\n\t" /* Update CTR (mem). */ "pxor (%[key]), %%xmm0\n\t" /* xmm1 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x20(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x30(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x40(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x50(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x60(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x70(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x80(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x90(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xa0(%[key]), %%xmm1\n\t" "cmpl $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xc0(%[key]), %%xmm1\n\t" "cmpl $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xd0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" aesenclast_xmm1_xmm0 "movdqu %[src], %%xmm1\n\t" /* xmm1 := input */ "pxor %%xmm1, %%xmm0\n\t" /* EncCTR ^= input */ "movdqu %%xmm0, %[dst]" /* Store EncCTR. */ : [dst] "=m" (*b) : [src] "m" (*a), [ctr] "r" (ctr), [key] "r" (ctx->keyschenc), [rounds] "g" (ctx->rounds) : "cc", "memory"); #undef aesenc_xmm1_xmm0 #undef aesenclast_xmm1_xmm0 } /* Four blocks at a time variant of do_aesni_ctr. */ static void do_aesni_ctr_4 (const RIJNDAEL_context *ctx, unsigned char *ctr, unsigned char *b, const unsigned char *a) { static const byte bige_addb_const[4][16] __attribute__ ((aligned (16))) = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 } }; const void *bige_addb = bige_addb_const; #define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" #define aesenc_xmm1_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd1\n\t" #define aesenc_xmm1_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd9\n\t" #define aesenc_xmm1_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe1\n\t" #define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" #define aesenclast_xmm1_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd1\n\t" #define aesenclast_xmm1_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd9\n\t" #define aesenclast_xmm1_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe1\n\t" /* Register usage: [key] keyschedule xmm0 CTR-0 xmm1 temp / round key xmm2 CTR-1 xmm3 CTR-2 xmm4 CTR-3 xmm5 copy of *ctr xmm6 endian swapping mask */ asm volatile (/* detect if 8-bit carry handling is needed */ "cmpb $0xfb, 15(%[ctr])\n\t" "ja .Ladd32bit%=\n\t" "movdqa %%xmm5, %%xmm0\n\t" /* xmm0 := CTR (xmm5) */ "movdqa 0*16(%[addb]), %%xmm2\n\t" /* xmm2 := be(1) */ "movdqa 1*16(%[addb]), %%xmm3\n\t" /* xmm3 := be(2) */ "movdqa 2*16(%[addb]), %%xmm4\n\t" /* xmm4 := be(3) */ "movdqa 3*16(%[addb]), %%xmm5\n\t" /* xmm5 := be(4) */ "paddb %%xmm0, %%xmm2\n\t" /* xmm2 := be(1) + CTR (xmm0) */ "paddb %%xmm0, %%xmm3\n\t" /* xmm3 := be(2) + CTR (xmm0) */ "paddb %%xmm0, %%xmm4\n\t" /* xmm4 := be(3) + CTR (xmm0) */ "paddb %%xmm0, %%xmm5\n\t" /* xmm5 := be(4) + CTR (xmm0) */ "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "jmp .Lstore_ctr%=\n\t" ".Ladd32bit%=:\n\t" "movdqa %%xmm5, %%xmm0\n\t" /* xmm0, xmm2 := CTR (xmm5) */ "movdqa %%xmm0, %%xmm2\n\t" "pcmpeqd %%xmm1, %%xmm1\n\t" "psrldq $8, %%xmm1\n\t" /* xmm1 = -1 */ "pshufb %%xmm6, %%xmm2\n\t" /* xmm2 := le(xmm2) */ "psubq %%xmm1, %%xmm2\n\t" /* xmm2++ */ "movdqa %%xmm2, %%xmm3\n\t" /* xmm3 := xmm2 */ "psubq %%xmm1, %%xmm3\n\t" /* xmm3++ */ "movdqa %%xmm3, %%xmm4\n\t" /* xmm4 := xmm3 */ "psubq %%xmm1, %%xmm4\n\t" /* xmm4++ */ "movdqa %%xmm4, %%xmm5\n\t" /* xmm5 := xmm4 */ "psubq %%xmm1, %%xmm5\n\t" /* xmm5++ */ /* detect if 64-bit carry handling is needed */ "cmpl $0xffffffff, 8(%[ctr])\n\t" "jne .Lno_carry%=\n\t" "movl 12(%[ctr]), %%esi\n\t" "bswapl %%esi\n\t" "cmpl $0xfffffffc, %%esi\n\t" "jb .Lno_carry%=\n\t" /* no carry */ "pslldq $8, %%xmm1\n\t" /* move lower 64-bit to high */ "je .Lcarry_xmm5%=\n\t" /* esi == 0xfffffffc */ "cmpl $0xfffffffe, %%esi\n\t" "jb .Lcarry_xmm4%=\n\t" /* esi == 0xfffffffd */ "je .Lcarry_xmm3%=\n\t" /* esi == 0xfffffffe */ /* esi == 0xffffffff */ "psubq %%xmm1, %%xmm2\n\t" ".Lcarry_xmm3%=:\n\t" "psubq %%xmm1, %%xmm3\n\t" ".Lcarry_xmm4%=:\n\t" "psubq %%xmm1, %%xmm4\n\t" ".Lcarry_xmm5%=:\n\t" "psubq %%xmm1, %%xmm5\n\t" ".Lno_carry%=:\n\t" "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "pshufb %%xmm6, %%xmm2\n\t" /* xmm2 := be(xmm2) */ "pshufb %%xmm6, %%xmm3\n\t" /* xmm3 := be(xmm3) */ "pshufb %%xmm6, %%xmm4\n\t" /* xmm4 := be(xmm4) */ "pshufb %%xmm6, %%xmm5\n\t" /* xmm5 := be(xmm5) */ ".Lstore_ctr%=:\n\t" "movdqa %%xmm5, (%[ctr])\n\t" /* Update CTR (mem). */ : : [ctr] "r" (ctr), [key] "r" (ctx->keyschenc), [addb] "r" (bige_addb) : "%esi", "cc", "memory"); asm volatile ("pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ "pxor %%xmm1, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm1, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm1, %%xmm4\n\t" /* xmm4 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x20(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x30(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x40(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x50(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x60(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x70(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x80(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x90(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0xa0(%[key]), %%xmm1\n\t" "cmpl $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0xc0(%[key]), %%xmm1\n\t" "cmpl $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0xd0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" aesenclast_xmm1_xmm0 aesenclast_xmm1_xmm2 aesenclast_xmm1_xmm3 aesenclast_xmm1_xmm4 : : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) : "cc", "memory"); asm volatile ("movdqu (%[src]), %%xmm1\n\t" /* Get block 1. */ "pxor %%xmm1, %%xmm0\n\t" /* EncCTR-1 ^= input */ "movdqu %%xmm0, (%[dst])\n\t" /* Store block 1 */ "movdqu 16(%[src]), %%xmm1\n\t" /* Get block 2. */ "pxor %%xmm1, %%xmm2\n\t" /* EncCTR-2 ^= input */ "movdqu %%xmm2, 16(%[dst])\n\t" /* Store block 2. */ "movdqu 32(%[src]), %%xmm1\n\t" /* Get block 3. */ "pxor %%xmm1, %%xmm3\n\t" /* EncCTR-3 ^= input */ "movdqu %%xmm3, 32(%[dst])\n\t" /* Store block 3. */ "movdqu 48(%[src]), %%xmm1\n\t" /* Get block 4. */ "pxor %%xmm1, %%xmm4\n\t" /* EncCTR-4 ^= input */ "movdqu %%xmm4, 48(%[dst])" /* Store block 4. */ : : [src] "r" (a), [dst] "r" (b) : "memory"); #undef aesenc_xmm1_xmm0 #undef aesenc_xmm1_xmm2 #undef aesenc_xmm1_xmm3 #undef aesenc_xmm1_xmm4 #undef aesenclast_xmm1_xmm0 #undef aesenclast_xmm1_xmm2 #undef aesenclast_xmm1_xmm3 #undef aesenclast_xmm1_xmm4 } #ifdef __x86_64__ /* Eight blocks at a time variant of do_aesni_ctr. */ static void do_aesni_ctr_8 (const RIJNDAEL_context *ctx, unsigned char *ctr, unsigned char *b, const unsigned char *a) { static const byte bige_addb_const[8][16] __attribute__ ((aligned (16))) = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 } }; const void *bige_addb = bige_addb_const; /* Register usage: [key] keyschedule xmm0 CTR-0 xmm1 temp / round key xmm2 CTR-1 xmm3 CTR-2 xmm4 CTR-3 xmm5 copy of *ctr xmm6 endian swapping mask xmm8 CTR-4 xmm9 CTR-5 xmm10 CTR-6 xmm11 CTR-7 xmm12 temp xmm13 temp xmm14 temp xmm15 temp */ asm volatile (/* detect if 8-bit carry handling is needed */ "cmpb $0xf7, 15(%[ctr])\n\t" "ja .Ladd32bit%=\n\t" "movdqa %%xmm5, %%xmm0\n\t" /* xmm0 := CTR (xmm5) */ "movdqa 0*16(%[addb]), %%xmm2\n\t" /* xmm2 := be(1) */ "movdqa 1*16(%[addb]), %%xmm3\n\t" /* xmm3 := be(2) */ "movdqa 2*16(%[addb]), %%xmm4\n\t" /* xmm4 := be(3) */ "movdqa 3*16(%[addb]), %%xmm8\n\t" /* xmm8 := be(4) */ "movdqa 4*16(%[addb]), %%xmm9\n\t" /* xmm9 := be(5) */ "movdqa 5*16(%[addb]), %%xmm10\n\t" /* xmm10 := be(6) */ "movdqa 6*16(%[addb]), %%xmm11\n\t" /* xmm11 := be(7) */ "movdqa 7*16(%[addb]), %%xmm5\n\t" /* xmm5 := be(8) */ "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "paddb %%xmm0, %%xmm2\n\t" /* xmm2 := be(1) + CTR (xmm0) */ "paddb %%xmm0, %%xmm3\n\t" /* xmm3 := be(2) + CTR (xmm0) */ "paddb %%xmm0, %%xmm4\n\t" /* xmm4 := be(3) + CTR (xmm0) */ "paddb %%xmm0, %%xmm8\n\t" /* xmm8 := be(4) + CTR (xmm0) */ "paddb %%xmm0, %%xmm9\n\t" /* xmm9 := be(5) + CTR (xmm0) */ "paddb %%xmm0, %%xmm10\n\t" /* xmm10 := be(6) + CTR (xmm0) */ "paddb %%xmm0, %%xmm11\n\t" /* xmm11 := be(7) + CTR (xmm0) */ "paddb %%xmm0, %%xmm5\n\t" /* xmm5 := be(8) + CTR (xmm0) */ "jmp .Lstore_ctr%=\n\t" ".Ladd32bit%=:\n\t" "movdqa %%xmm5, %%xmm0\n\t" /* xmm0, xmm2 := CTR (xmm5) */ "movdqa %%xmm0, %%xmm2\n\t" "pcmpeqd %%xmm1, %%xmm1\n\t" "psrldq $8, %%xmm1\n\t" /* xmm1 = -1 */ "pshufb %%xmm6, %%xmm2\n\t" /* xmm2 := le(xmm2) */ "psubq %%xmm1, %%xmm2\n\t" /* xmm2++ */ "movdqa %%xmm2, %%xmm3\n\t" /* xmm3 := xmm2 */ "psubq %%xmm1, %%xmm3\n\t" /* xmm3++ */ "movdqa %%xmm3, %%xmm4\n\t" /* xmm4 := xmm3 */ "psubq %%xmm1, %%xmm4\n\t" /* xmm4++ */ "movdqa %%xmm4, %%xmm8\n\t" /* xmm8 := xmm4 */ "psubq %%xmm1, %%xmm8\n\t" /* xmm8++ */ "movdqa %%xmm8, %%xmm9\n\t" /* xmm9 := xmm8 */ "psubq %%xmm1, %%xmm9\n\t" /* xmm9++ */ "movdqa %%xmm9, %%xmm10\n\t" /* xmm10 := xmm9 */ "psubq %%xmm1, %%xmm10\n\t" /* xmm10++ */ "movdqa %%xmm10, %%xmm11\n\t" /* xmm11 := xmm10 */ "psubq %%xmm1, %%xmm11\n\t" /* xmm11++ */ "movdqa %%xmm11, %%xmm5\n\t" /* xmm5 := xmm11 */ "psubq %%xmm1, %%xmm5\n\t" /* xmm5++ */ /* detect if 64-bit carry handling is needed */ "cmpl $0xffffffff, 8(%[ctr])\n\t" "jne .Lno_carry%=\n\t" "movl 12(%[ctr]), %%esi\n\t" "bswapl %%esi\n\t" "cmpl $0xfffffff8, %%esi\n\t" "jb .Lno_carry%=\n\t" /* no carry */ "pslldq $8, %%xmm1\n\t" /* move lower 64-bit to high */ "je .Lcarry_xmm5%=\n\t" /* esi == 0xfffffff8 */ "cmpl $0xfffffffa, %%esi\n\t" "jb .Lcarry_xmm11%=\n\t" /* esi == 0xfffffff9 */ "je .Lcarry_xmm10%=\n\t" /* esi == 0xfffffffa */ "cmpl $0xfffffffc, %%esi\n\t" "jb .Lcarry_xmm9%=\n\t" /* esi == 0xfffffffb */ "je .Lcarry_xmm8%=\n\t" /* esi == 0xfffffffc */ "cmpl $0xfffffffe, %%esi\n\t" "jb .Lcarry_xmm4%=\n\t" /* esi == 0xfffffffd */ "je .Lcarry_xmm3%=\n\t" /* esi == 0xfffffffe */ /* esi == 0xffffffff */ "psubq %%xmm1, %%xmm2\n\t" ".Lcarry_xmm3%=:\n\t" "psubq %%xmm1, %%xmm3\n\t" ".Lcarry_xmm4%=:\n\t" "psubq %%xmm1, %%xmm4\n\t" ".Lcarry_xmm8%=:\n\t" "psubq %%xmm1, %%xmm8\n\t" ".Lcarry_xmm9%=:\n\t" "psubq %%xmm1, %%xmm9\n\t" ".Lcarry_xmm10%=:\n\t" "psubq %%xmm1, %%xmm10\n\t" ".Lcarry_xmm11%=:\n\t" "psubq %%xmm1, %%xmm11\n\t" ".Lcarry_xmm5%=:\n\t" "psubq %%xmm1, %%xmm5\n\t" ".Lno_carry%=:\n\t" "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "pshufb %%xmm6, %%xmm2\n\t" /* xmm2 := be(xmm2) */ "pshufb %%xmm6, %%xmm3\n\t" /* xmm3 := be(xmm3) */ "pshufb %%xmm6, %%xmm4\n\t" /* xmm4 := be(xmm4) */ "pshufb %%xmm6, %%xmm5\n\t" /* xmm5 := be(xmm5) */ "pshufb %%xmm6, %%xmm8\n\t" /* xmm8 := be(xmm8) */ "pshufb %%xmm6, %%xmm9\n\t" /* xmm9 := be(xmm9) */ "pshufb %%xmm6, %%xmm10\n\t" /* xmm10 := be(xmm10) */ "pshufb %%xmm6, %%xmm11\n\t" /* xmm11 := be(xmm11) */ ".Lstore_ctr%=:\n\t" "movdqa %%xmm5, (%[ctr])\n\t" /* Update CTR (mem). */ : : [ctr] "r" (ctr), [key] "r" (ctx->keyschenc), [addb] "r" (bige_addb) : "%esi", "cc", "memory"); asm volatile ("pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ "pxor %%xmm1, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm1, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm1, %%xmm4\n\t" /* xmm4 ^= key[0] */ "pxor %%xmm1, %%xmm8\n\t" /* xmm8 ^= key[0] */ "pxor %%xmm1, %%xmm9\n\t" /* xmm9 ^= key[0] */ "pxor %%xmm1, %%xmm10\n\t" /* xmm10 ^= key[0] */ "pxor %%xmm1, %%xmm11\n\t" /* xmm11 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm1\n\t" "cmpl $12, %[rounds]\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x20(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x30(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x40(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x50(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x60(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x70(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x80(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x90(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0xa0(%[key]), %%xmm1\n\t" "jb .Lenclast%=\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0xb0(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0xc0(%[key]), %%xmm1\n\t" "je .Lenclast%=\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0xd0(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" "aesenclast %%xmm1, %%xmm0\n\t" "aesenclast %%xmm1, %%xmm2\n\t" "aesenclast %%xmm1, %%xmm3\n\t" "aesenclast %%xmm1, %%xmm4\n\t" "aesenclast %%xmm1, %%xmm8\n\t" "aesenclast %%xmm1, %%xmm9\n\t" "aesenclast %%xmm1, %%xmm10\n\t" "aesenclast %%xmm1, %%xmm11\n\t" : : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) : "cc", "memory"); asm volatile ("movdqu 0*16(%[src]), %%xmm12\n\t" /* Get block 1. */ "movdqu 1*16(%[src]), %%xmm13\n\t" /* Get block 2. */ "movdqu 2*16(%[src]), %%xmm14\n\t" /* Get block 3. */ "movdqu 3*16(%[src]), %%xmm15\n\t" /* Get block 4. */ "movdqu 4*16(%[src]), %%xmm1\n\t" /* Get block 5. */ "pxor %%xmm12, %%xmm0\n\t" /* EncCTR-1 ^= input */ "movdqu 5*16(%[src]), %%xmm12\n\t" /* Get block 6. */ "pxor %%xmm13, %%xmm2\n\t" /* EncCTR-2 ^= input */ "movdqu 6*16(%[src]), %%xmm13\n\t" /* Get block 7. */ "pxor %%xmm14, %%xmm3\n\t" /* EncCTR-3 ^= input */ "movdqu 7*16(%[src]), %%xmm14\n\t" /* Get block 8. */ "pxor %%xmm15, %%xmm4\n\t" /* EncCTR-4 ^= input */ "movdqu %%xmm0, 0*16(%[dst])\n\t" /* Store block 1 */ "pxor %%xmm1, %%xmm8\n\t" /* EncCTR-5 ^= input */ "movdqu %%xmm0, 0*16(%[dst])\n\t" /* Store block 1 */ "pxor %%xmm12, %%xmm9\n\t" /* EncCTR-6 ^= input */ "movdqu %%xmm2, 1*16(%[dst])\n\t" /* Store block 2. */ "pxor %%xmm13, %%xmm10\n\t" /* EncCTR-7 ^= input */ "movdqu %%xmm3, 2*16(%[dst])\n\t" /* Store block 3. */ "pxor %%xmm14, %%xmm11\n\t" /* EncCTR-8 ^= input */ "movdqu %%xmm4, 3*16(%[dst])\n\t" /* Store block 4. */ "movdqu %%xmm8, 4*16(%[dst])\n\t" /* Store block 8. */ "movdqu %%xmm9, 5*16(%[dst])\n\t" /* Store block 9. */ "movdqu %%xmm10, 6*16(%[dst])\n\t" /* Store block 10. */ "movdqu %%xmm11, 7*16(%[dst])\n\t" /* Store block 11. */ : : [src] "r" (a), [dst] "r" (b) : "memory"); } #endif /* __x86_64__ */ unsigned int _gcry_aes_aesni_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src) { aesni_prepare (); asm volatile ("movdqu %[src], %%xmm0\n\t" : : [src] "m" (*src) : "memory" ); do_aesni_enc (ctx); asm volatile ("movdqu %%xmm0, %[dst]\n\t" : [dst] "=m" (*dst) : : "memory" ); aesni_cleanup (); return 0; } void _gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { aesni_prepare (); asm volatile ("movdqu %[iv], %%xmm0\n\t" : /* No output */ : [iv] "m" (*iv) : "memory" ); for ( ;nblocks; nblocks-- ) { do_aesni_enc (ctx); asm volatile ("movdqu %[inbuf], %%xmm1\n\t" "pxor %%xmm1, %%xmm0\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : [inbuf] "m" (*inbuf) : "memory" ); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm0, %[iv]\n\t" : [iv] "=m" (*iv) : : "memory" ); aesni_cleanup (); } void _gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks, int cbc_mac) { - aesni_prepare_2_6_variable; + aesni_prepare_2_7_variable; aesni_prepare (); - aesni_prepare_2_6(); + aesni_prepare_2_7(); asm volatile ("movdqu %[iv], %%xmm5\n\t" : /* No output */ : [iv] "m" (*iv) : "memory" ); for ( ;nblocks; nblocks-- ) { asm volatile ("movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm5, %%xmm0\n\t" : /* No output */ : [inbuf] "m" (*inbuf) : "memory" ); do_aesni_enc (ctx); asm volatile ("movdqa %%xmm0, %%xmm5\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); inbuf += BLOCKSIZE; if (!cbc_mac) outbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm5, %[iv]\n\t" : [iv] "=m" (*iv) : : "memory" ); aesni_cleanup (); - aesni_cleanup_2_6 (); + aesni_cleanup_2_7 (); } void _gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, unsigned char *ctr, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { static const unsigned char be_mask[16] __attribute__ ((aligned (16))) = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; - aesni_prepare_2_6_variable; + aesni_prepare_2_7_variable; aesni_prepare (); - aesni_prepare_2_6(); + aesni_prepare_2_7(); asm volatile ("movdqa %[mask], %%xmm6\n\t" /* Preload mask */ "movdqa %[ctr], %%xmm5\n\t" /* Preload CTR */ : /* No output */ : [mask] "m" (*be_mask), [ctr] "m" (*ctr) : "memory"); #ifdef __x86_64__ if (nblocks >= 8) { - aesni_prepare_7_15_variable; + aesni_prepare_8_15_variable; - aesni_prepare_7_15(); + aesni_prepare_8_15(); for ( ;nblocks >= 8 ; nblocks -= 8 ) { do_aesni_ctr_8 (ctx, ctr, outbuf, inbuf); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } - aesni_cleanup_7_15(); + aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4 ; nblocks -= 4 ) { do_aesni_ctr_4 (ctx, ctr, outbuf, inbuf); outbuf += 4*BLOCKSIZE; inbuf += 4*BLOCKSIZE; } for ( ;nblocks; nblocks-- ) { do_aesni_ctr (ctx, ctr, outbuf, inbuf); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } aesni_cleanup (); - aesni_cleanup_2_6 (); + aesni_cleanup_2_7 (); } unsigned int _gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src) { aesni_prepare (); asm volatile ("movdqu %[src], %%xmm0\n\t" : : [src] "m" (*src) : "memory" ); do_aesni_dec (ctx); asm volatile ("movdqu %%xmm0, %[dst]\n\t" : [dst] "=m" (*dst) : : "memory" ); aesni_cleanup (); return 0; } void _gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { - aesni_prepare_2_6_variable; + aesni_prepare_2_7_variable; aesni_prepare (); - aesni_prepare_2_6(); + aesni_prepare_2_7(); asm volatile ("movdqu %[iv], %%xmm6\n\t" : /* No output */ : [iv] "m" (*iv) : "memory" ); /* CFB decryption can be parallelized */ #ifdef __x86_64__ if (nblocks >= 8) { - aesni_prepare_7_15_variable; + aesni_prepare_8_15_variable; - aesni_prepare_7_15(); + aesni_prepare_8_15(); for ( ;nblocks >= 8; nblocks -= 8) { asm volatile ("movdqu %%xmm6, %%xmm1\n\t" /* load input blocks */ "movdqu 0*16(%[inbuf]), %%xmm2\n\t" "movdqu 1*16(%[inbuf]), %%xmm3\n\t" "movdqu 2*16(%[inbuf]), %%xmm4\n\t" "movdqu 3*16(%[inbuf]), %%xmm8\n\t" "movdqu 4*16(%[inbuf]), %%xmm9\n\t" "movdqu 5*16(%[inbuf]), %%xmm10\n\t" "movdqu 6*16(%[inbuf]), %%xmm11\n\t" "movdqu 7*16(%[inbuf]), %%xmm6\n\t" /* update IV */ "movdqa %%xmm2, %%xmm12\n\t" "movdqa %%xmm3, %%xmm13\n\t" "movdqa %%xmm4, %%xmm14\n\t" "movdqa %%xmm8, %%xmm15\n\t" : /* No output */ : [inbuf] "r" (inbuf) : "memory"); do_aesni_enc_vec8 (ctx); asm volatile ( "pxor %%xmm12, %%xmm1\n\t" "movdqu 4*16(%[inbuf]), %%xmm12\n\t" "pxor %%xmm13, %%xmm2\n\t" "movdqu 5*16(%[inbuf]), %%xmm13\n\t" "pxor %%xmm14, %%xmm3\n\t" "movdqu 6*16(%[inbuf]), %%xmm14\n\t" "pxor %%xmm15, %%xmm4\n\t" "movdqu 7*16(%[inbuf]), %%xmm15\n\t" "pxor %%xmm12, %%xmm8\n\t" "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "pxor %%xmm13, %%xmm9\n\t" "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "pxor %%xmm14, %%xmm10\n\t" "movdqu %%xmm3, 2*16(%[outbuf])\n\t" "pxor %%xmm15, %%xmm11\n\t" "movdqu %%xmm4, 3*16(%[outbuf])\n\t" "movdqu %%xmm8, 4*16(%[outbuf])\n\t" "movdqu %%xmm9, 5*16(%[outbuf])\n\t" "movdqu %%xmm10, 6*16(%[outbuf])\n\t" "movdqu %%xmm11, 7*16(%[outbuf])\n\t" : /* No output */ : [inbuf] "r" (inbuf), [outbuf] "r" (outbuf) : "memory"); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } - aesni_cleanup_7_15(); + aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4; nblocks -= 4) { asm volatile ("movdqu %%xmm6, %%xmm1\n\t" /* load input blocks */ "movdqu 0*16(%[inbuf]), %%xmm2\n\t" "movdqu 1*16(%[inbuf]), %%xmm3\n\t" "movdqu 2*16(%[inbuf]), %%xmm4\n\t" "movdqu 3*16(%[inbuf]), %%xmm6\n\t" /* update IV */ : /* No output */ : [inbuf] "r" (inbuf) : "memory"); do_aesni_enc_vec4 (ctx); asm volatile ("movdqu 0*16(%[inbuf]), %%xmm5\n\t" "pxor %%xmm5, %%xmm1\n\t" "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "movdqu 1*16(%[inbuf]), %%xmm5\n\t" "pxor %%xmm5, %%xmm2\n\t" "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "movdqu 2*16(%[inbuf]), %%xmm5\n\t" "pxor %%xmm5, %%xmm3\n\t" "movdqu %%xmm3, 2*16(%[outbuf])\n\t" "movdqu 3*16(%[inbuf]), %%xmm5\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqu %%xmm4, 3*16(%[outbuf])\n\t" : /* No output */ : [inbuf] "r" (inbuf), [outbuf] "r" (outbuf) : "memory"); outbuf += 4*BLOCKSIZE; inbuf += 4*BLOCKSIZE; } asm volatile ("movdqu %%xmm6, %%xmm0\n\t" ::: "cc"); for ( ;nblocks; nblocks-- ) { do_aesni_enc (ctx); asm volatile ("movdqa %%xmm0, %%xmm6\n\t" "movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm0, %%xmm6\n\t" "movdqu %%xmm6, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : [inbuf] "m" (*inbuf) : "memory" ); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm0, %[iv]\n\t" : [iv] "=m" (*iv) : : "memory" ); aesni_cleanup (); - aesni_cleanup_2_6 (); + aesni_cleanup_2_7 (); } void _gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { - aesni_prepare_2_6_variable; + aesni_prepare_2_7_variable; aesni_prepare (); - aesni_prepare_2_6(); + aesni_prepare_2_7(); if ( !ctx->decryption_prepared ) { do_aesni_prepare_decryption ( ctx ); ctx->decryption_prepared = 1; } asm volatile ("movdqu %[iv], %%xmm5\n\t" /* use xmm5 as fast IV storage */ : /* No output */ : [iv] "m" (*iv) : "memory"); #ifdef __x86_64__ if (nblocks >= 8) { - aesni_prepare_7_15_variable; + aesni_prepare_8_15_variable; - aesni_prepare_7_15(); + aesni_prepare_8_15(); for ( ;nblocks >= 8 ; nblocks -= 8 ) { asm volatile ("movdqu 0*16(%[inbuf]), %%xmm1\n\t" /* load input blocks */ "movdqu 1*16(%[inbuf]), %%xmm2\n\t" "movdqu 2*16(%[inbuf]), %%xmm3\n\t" "movdqu 3*16(%[inbuf]), %%xmm4\n\t" "movdqu 4*16(%[inbuf]), %%xmm8\n\t" "movdqu 5*16(%[inbuf]), %%xmm9\n\t" "movdqu 6*16(%[inbuf]), %%xmm10\n\t" "movdqu 7*16(%[inbuf]), %%xmm11\n\t" "movdqa %%xmm1, %%xmm12\n\t" "movdqa %%xmm2, %%xmm13\n\t" "movdqa %%xmm3, %%xmm14\n\t" "movdqa %%xmm4, %%xmm15\n\t" : /* No output */ : [inbuf] "r" (inbuf) : "memory"); do_aesni_dec_vec8 (ctx); asm volatile ("pxor %%xmm5, %%xmm1\n\t" /* xor IV with output */ "pxor %%xmm12, %%xmm2\n\t" /* xor IV with output */ "movdqu 4*16(%[inbuf]), %%xmm12\n\t" "pxor %%xmm13, %%xmm3\n\t" /* xor IV with output */ "movdqu 5*16(%[inbuf]), %%xmm13\n\t" "pxor %%xmm14, %%xmm4\n\t" /* xor IV with output */ "movdqu 6*16(%[inbuf]), %%xmm14\n\t" "pxor %%xmm15, %%xmm8\n\t" /* xor IV with output */ "movdqu 7*16(%[inbuf]), %%xmm5\n\t" "pxor %%xmm12, %%xmm9\n\t" /* xor IV with output */ "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "pxor %%xmm13, %%xmm10\n\t" /* xor IV with output */ "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "pxor %%xmm14, %%xmm11\n\t" /* xor IV with output */ "movdqu %%xmm3, 2*16(%[outbuf])\n\t" "movdqu %%xmm4, 3*16(%[outbuf])\n\t" "movdqu %%xmm8, 4*16(%[outbuf])\n\t" "movdqu %%xmm9, 5*16(%[outbuf])\n\t" "movdqu %%xmm10, 6*16(%[outbuf])\n\t" "movdqu %%xmm11, 7*16(%[outbuf])\n\t" : /* No output */ : [inbuf] "r" (inbuf), [outbuf] "r" (outbuf) : "memory"); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } - aesni_cleanup_7_15(); + aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4 ; nblocks -= 4 ) { asm volatile ("movdqu 0*16(%[inbuf]), %%xmm1\n\t" /* load input blocks */ "movdqu 1*16(%[inbuf]), %%xmm2\n\t" "movdqu 2*16(%[inbuf]), %%xmm3\n\t" "movdqu 3*16(%[inbuf]), %%xmm4\n\t" : /* No output */ : [inbuf] "r" (inbuf) : "memory"); do_aesni_dec_vec4 (ctx); asm volatile ("pxor %%xmm5, %%xmm1\n\t" /* xor IV with output */ "movdqu 0*16(%[inbuf]), %%xmm5\n\t" /* load new IV */ "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "pxor %%xmm5, %%xmm2\n\t" /* xor IV with output */ "movdqu 1*16(%[inbuf]), %%xmm5\n\t" /* load new IV */ "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "pxor %%xmm5, %%xmm3\n\t" /* xor IV with output */ "movdqu 2*16(%[inbuf]), %%xmm5\n\t" /* load new IV */ "movdqu %%xmm3, 2*16(%[outbuf])\n\t" "pxor %%xmm5, %%xmm4\n\t" /* xor IV with output */ "movdqu 3*16(%[inbuf]), %%xmm5\n\t" /* load new IV */ "movdqu %%xmm4, 3*16(%[outbuf])\n\t" : /* No output */ : [inbuf] "r" (inbuf), [outbuf] "r" (outbuf) : "memory"); outbuf += 4*BLOCKSIZE; inbuf += 4*BLOCKSIZE; } for ( ;nblocks; nblocks-- ) { asm volatile ("movdqu %[inbuf], %%xmm0\n\t" "movdqa %%xmm0, %%xmm2\n\t" /* use xmm2 as savebuf */ : /* No output */ : [inbuf] "m" (*inbuf) : "memory"); /* uses only xmm0 and xmm1 */ do_aesni_dec (ctx); asm volatile ("pxor %%xmm5, %%xmm0\n\t" /* xor IV with output */ "movdqu %%xmm0, %[outbuf]\n\t" "movdqu %%xmm2, %%xmm5\n\t" /* store savebuf as new IV */ : [outbuf] "=m" (*outbuf) : : "memory"); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm5, %[iv]\n\t" /* store IV */ : /* No output */ : [iv] "m" (*iv) : "memory"); aesni_cleanup (); - aesni_cleanup_2_6 (); + aesni_cleanup_2_7 (); } -static void +static ALWAYS_INLINE void +aesni_ocb_checksum (gcry_cipher_hd_t c, const unsigned char *plaintext, + size_t nblocks) +{ + RIJNDAEL_context *ctx = (void *)&c->context.c; + + /* Calculate checksum */ + asm volatile ("movdqu %[checksum], %%xmm6\n\t" + "pxor %%xmm1, %%xmm1\n\t" + "pxor %%xmm2, %%xmm2\n\t" + "pxor %%xmm3, %%xmm3\n\t" + : + :[checksum] "m" (*c->u_ctr.ctr) + : "memory" ); + + if (0) {} +#if defined(HAVE_GCC_INLINE_ASM_AVX2) + else if (nblocks >= 16 && ctx->use_avx2) + { + /* Use wider 256-bit registers for fast xoring of plaintext. */ + asm volatile ("vzeroupper\n\t" + "vpxor %%xmm0, %%xmm0, %%xmm0\n\t" + "vpxor %%xmm4, %%xmm4, %%xmm4\n\t" + "vpxor %%xmm5, %%xmm5, %%xmm5\n\t" + "vpxor %%xmm7, %%xmm7, %%xmm7\n\t" + : + : + : "memory"); + + for (;nblocks >= 16; nblocks -= 16) + { + asm volatile ("vpxor %[ptr0], %%ymm6, %%ymm6\n\t" + "vpxor %[ptr1], %%ymm1, %%ymm1\n\t" + "vpxor %[ptr2], %%ymm2, %%ymm2\n\t" + "vpxor %[ptr3], %%ymm3, %%ymm3\n\t" + "vpxor %[ptr4], %%ymm0, %%ymm0\n\t" + "vpxor %[ptr5], %%ymm4, %%ymm4\n\t" + "vpxor %[ptr6], %%ymm5, %%ymm5\n\t" + "vpxor %[ptr7], %%ymm7, %%ymm7\n\t" + : + : [ptr0] "m" (*(plaintext + 0 * BLOCKSIZE * 2)), + [ptr1] "m" (*(plaintext + 1 * BLOCKSIZE * 2)), + [ptr2] "m" (*(plaintext + 2 * BLOCKSIZE * 2)), + [ptr3] "m" (*(plaintext + 3 * BLOCKSIZE * 2)), + [ptr4] "m" (*(plaintext + 4 * BLOCKSIZE * 2)), + [ptr5] "m" (*(plaintext + 5 * BLOCKSIZE * 2)), + [ptr6] "m" (*(plaintext + 6 * BLOCKSIZE * 2)), + [ptr7] "m" (*(plaintext + 7 * BLOCKSIZE * 2)) + : "memory" ); + plaintext += BLOCKSIZE * 16; + } + + asm volatile ("vpxor %%ymm0, %%ymm6, %%ymm6\n\t" + "vpxor %%ymm4, %%ymm1, %%ymm1\n\t" + "vpxor %%ymm5, %%ymm2, %%ymm2\n\t" + "vpxor %%ymm7, %%ymm3, %%ymm3\n\t" + "vextracti128 $1, %%ymm6, %%xmm0\n\t" + "vextracti128 $1, %%ymm1, %%xmm4\n\t" + "vextracti128 $1, %%ymm2, %%xmm5\n\t" + "vextracti128 $1, %%ymm3, %%xmm7\n\t" + "vpxor %%xmm0, %%xmm6, %%xmm6\n\t" + "vpxor %%xmm4, %%xmm1, %%xmm1\n\t" + "vpxor %%xmm5, %%xmm2, %%xmm2\n\t" + "vpxor %%xmm7, %%xmm3, %%xmm3\n\t" + "vzeroupper\n\t" + : + : + : "memory" ); + } +#endif +#if defined(HAVE_GCC_INLINE_ASM_AVX) + else if (nblocks >= 16 && ctx->use_avx) + { + /* Same as AVX2, except using 256-bit floating point instructions. */ + asm volatile ("vzeroupper\n\t" + "vxorpd %%xmm0, %%xmm0, %%xmm0\n\t" + "vxorpd %%xmm4, %%xmm4, %%xmm4\n\t" + "vxorpd %%xmm5, %%xmm5, %%xmm5\n\t" + "vxorpd %%xmm7, %%xmm7, %%xmm7\n\t" + : + : + : "memory"); + + for (;nblocks >= 16; nblocks -= 16) + { + asm volatile ("vxorpd %[ptr0], %%ymm6, %%ymm6\n\t" + "vxorpd %[ptr1], %%ymm1, %%ymm1\n\t" + "vxorpd %[ptr2], %%ymm2, %%ymm2\n\t" + "vxorpd %[ptr3], %%ymm3, %%ymm3\n\t" + "vxorpd %[ptr4], %%ymm0, %%ymm0\n\t" + "vxorpd %[ptr5], %%ymm4, %%ymm4\n\t" + "vxorpd %[ptr6], %%ymm5, %%ymm5\n\t" + "vxorpd %[ptr7], %%ymm7, %%ymm7\n\t" + : + : [ptr0] "m" (*(plaintext + 0 * BLOCKSIZE * 2)), + [ptr1] "m" (*(plaintext + 1 * BLOCKSIZE * 2)), + [ptr2] "m" (*(plaintext + 2 * BLOCKSIZE * 2)), + [ptr3] "m" (*(plaintext + 3 * BLOCKSIZE * 2)), + [ptr4] "m" (*(plaintext + 4 * BLOCKSIZE * 2)), + [ptr5] "m" (*(plaintext + 5 * BLOCKSIZE * 2)), + [ptr6] "m" (*(plaintext + 6 * BLOCKSIZE * 2)), + [ptr7] "m" (*(plaintext + 7 * BLOCKSIZE * 2)) + : "memory" ); + plaintext += BLOCKSIZE * 16; + } + + asm volatile ("vxorpd %%ymm0, %%ymm6, %%ymm6\n\t" + "vxorpd %%ymm4, %%ymm1, %%ymm1\n\t" + "vxorpd %%ymm5, %%ymm2, %%ymm2\n\t" + "vxorpd %%ymm7, %%ymm3, %%ymm3\n\t" + "vextractf128 $1, %%ymm6, %%xmm0\n\t" + "vextractf128 $1, %%ymm1, %%xmm4\n\t" + "vextractf128 $1, %%ymm2, %%xmm5\n\t" + "vextractf128 $1, %%ymm3, %%xmm7\n\t" + "vxorpd %%xmm0, %%xmm6, %%xmm6\n\t" + "vxorpd %%xmm4, %%xmm1, %%xmm1\n\t" + "vxorpd %%xmm5, %%xmm2, %%xmm2\n\t" + "vxorpd %%xmm7, %%xmm3, %%xmm3\n\t" + "vzeroupper\n\t" + : + : + : "memory" ); + } +#endif + + for (;nblocks >= 4; nblocks -= 4) + { + asm volatile ("movdqu %[ptr0], %%xmm0\n\t" + "movdqu %[ptr1], %%xmm4\n\t" + "movdqu %[ptr2], %%xmm5\n\t" + "movdqu %[ptr3], %%xmm7\n\t" + "pxor %%xmm0, %%xmm6\n\t" + "pxor %%xmm4, %%xmm1\n\t" + "pxor %%xmm5, %%xmm2\n\t" + "pxor %%xmm7, %%xmm3\n\t" + : + : [ptr0] "m" (*(plaintext + 0 * BLOCKSIZE)), + [ptr1] "m" (*(plaintext + 1 * BLOCKSIZE)), + [ptr2] "m" (*(plaintext + 2 * BLOCKSIZE)), + [ptr3] "m" (*(plaintext + 3 * BLOCKSIZE)) + : "memory" ); + plaintext += BLOCKSIZE * 4; + } + + for (;nblocks >= 1; nblocks -= 1) + { + asm volatile ("movdqu %[ptr0], %%xmm0\n\t" + "pxor %%xmm0, %%xmm6\n\t" + : + : [ptr0] "m" (*(plaintext + 0 * BLOCKSIZE)) + : "memory" ); + plaintext += BLOCKSIZE; + } + + asm volatile ("pxor %%xmm1, %%xmm6\n\t" + "pxor %%xmm2, %%xmm6\n\t" + "pxor %%xmm3, %%xmm6\n\t" + "movdqu %%xmm6, %[checksum]\n\t" + : [checksum] "=m" (*c->u_ctr.ctr) + : + : "memory" ); +} + + +static unsigned int NO_INLINE aesni_ocb_enc (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { RIJNDAEL_context *ctx = (void *)&c->context.c; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; u64 n = c->u_mode.ocb.data_nblocks; const unsigned char *l; - aesni_prepare_2_6_variable; + aesni_prepare_2_7_variable; aesni_prepare (); - aesni_prepare_2_6 (); + aesni_prepare_2_7 (); + + aesni_ocb_checksum (c, inbuf_arg, nblocks); - /* Preload Offset and Checksum */ + /* Preload Offset */ asm volatile ("movdqu %[iv], %%xmm5\n\t" - "movdqu %[ctr], %%xmm6\n\t" : /* No output */ - : [iv] "m" (*c->u_iv.iv), - [ctr] "m" (*c->u_ctr.ctr) + : [iv] "m" (*c->u_iv.iv) : "memory" ); - for ( ;nblocks && n % 4; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ - /* Checksum_i = Checksum_{i-1} xor P_i */ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ asm volatile ("movdqu %[l], %%xmm1\n\t" "movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm1, %%xmm5\n\t" - "pxor %%xmm0, %%xmm6\n\t" "pxor %%xmm5, %%xmm0\n\t" : : [l] "m" (*l), [inbuf] "m" (*inbuf) : "memory" ); do_aesni_enc (ctx); asm volatile ("pxor %%xmm5, %%xmm0\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); inbuf += BLOCKSIZE; outbuf += BLOCKSIZE; } #ifdef __x86_64__ if (nblocks >= 8) { - aesni_prepare_7_15_variable; + aesni_prepare_8_15_variable; - aesni_prepare_7_15(); + aesni_prepare_8_15(); - asm volatile ("movdqu %[l0], %%xmm7\n\t" + asm volatile ("movdqu %[l0], %%xmm6\n\t" : : [l0] "m" (*c->u_mode.ocb.L[0]) : "memory" ); for ( ;nblocks >= 8 ; nblocks -= 8 ) { n += 4; l = aes_ocb_get_l(c, n); - /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ - /* Checksum_i = Checksum_{i-1} xor P_i */ - /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ - - asm volatile ("movdqu %[l1], %%xmm10\n\t" - "movdqu %[inbuf0], %%xmm1\n\t" - "pxor %%xmm7, %%xmm5\n\t" - "pxor %%xmm1, %%xmm6\n\t" - "pxor %%xmm5, %%xmm1\n\t" - "movdqa %%xmm5, %%xmm12\n\t" + asm volatile ("movdqu %[l0l1], %%xmm10\n\t" + "movdqu %[l0l1l0], %%xmm11\n\t" + "movdqu %[l3], %%xmm15\n\t" : - : [l1] "m" (*c->u_mode.ocb.L[1]), - [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)) + : [l0l1] "m" (*c->u_mode.ocb.L0L1), + [l0l1l0] "m" (*c->u_mode.ocb.L0L1L0), + [l3] "m" (*l) : "memory" ); - asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" - "pxor %%xmm10, %%xmm5\n\t" - "pxor %%xmm2, %%xmm6\n\t" - "pxor %%xmm5, %%xmm2\n\t" - "movdqa %%xmm5, %%xmm13\n\t" + + n += 4; + l = aes_ocb_get_l(c, n); + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ + /* P_i = Offset_i xor ENCIPHER(K, C_i xor Offset_i) */ + asm volatile ("movdqu %[inbuf0], %%xmm1\n\t" + "movdqu %[inbuf1], %%xmm2\n\t" + "movdqu %[inbuf2], %%xmm3\n\t" : - : [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)) + : [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)), + [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)), + [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" - "pxor %%xmm7, %%xmm5\n\t" - "pxor %%xmm3, %%xmm6\n\t" - "pxor %%xmm5, %%xmm3\n\t" - "movdqa %%xmm5, %%xmm14\n\t" + asm volatile ("movdqu %[inbuf3], %%xmm4\n\t" + "movdqu %[inbuf4], %%xmm8\n\t" + "movdqu %[inbuf5], %%xmm9\n\t" : - : [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) + : [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)), + [inbuf4] "m" (*(inbuf + 4 * BLOCKSIZE)), + [inbuf5] "m" (*(inbuf + 5 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[l3], %%xmm15\n\t" - "movdqu %[inbuf3], %%xmm4\n\t" + asm volatile ("movdqa %%xmm6, %%xmm12\n\t" + "pxor %%xmm5, %%xmm12\n\t" + "pxor %%xmm12, %%xmm1\n\t" + + "movdqa %%xmm10, %%xmm13\n\t" + "pxor %%xmm5, %%xmm13\n\t" + "pxor %%xmm13, %%xmm2\n\t" + + "movdqa %%xmm11, %%xmm14\n\t" + "pxor %%xmm5, %%xmm14\n\t" + "pxor %%xmm14, %%xmm3\n\t" + + "pxor %%xmm11, %%xmm5\n\t" "pxor %%xmm15, %%xmm5\n\t" - "pxor %%xmm4, %%xmm6\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqa %%xmm5, %%xmm15\n\t" - : - : [l3] "m" (*l), - [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)) - : "memory" ); - n += 4; - l = aes_ocb_get_l(c, n); - - asm volatile ("movdqu %[inbuf4], %%xmm8\n\t" - "pxor %%xmm7, %%xmm5\n\t" - "pxor %%xmm8, %%xmm6\n\t" - "pxor %%xmm5, %%xmm8\n\t" - "movdqu %%xmm5, %[outbuf4]\n\t" - : [outbuf4] "=m" (*(outbuf + 4 * BLOCKSIZE)) - : [inbuf4] "m" (*(inbuf + 4 * BLOCKSIZE)) - : "memory" ); - asm volatile ("movdqu %[inbuf5], %%xmm9\n\t" - "pxor %%xmm10, %%xmm5\n\t" - "pxor %%xmm9, %%xmm6\n\t" - "pxor %%xmm5, %%xmm9\n\t" - "movdqu %%xmm5, %[outbuf5]\n\t" - : [outbuf5] "=m" (*(outbuf + 5 * BLOCKSIZE)) - : [inbuf5] "m" (*(inbuf + 5 * BLOCKSIZE)) + "movdqa %%xmm5, %%xmm0\n\t" + "pxor %%xmm6, %%xmm0\n\t" + "pxor %%xmm0, %%xmm8\n\t" + "movdqu %%xmm0, %[outbuf4]\n\t" + + "movdqa %%xmm10, %%xmm0\n\t" + "pxor %%xmm5, %%xmm0\n\t" + "pxor %%xmm0, %%xmm9\n\t" + "movdqu %%xmm0, %[outbuf5]\n\t" + : [outbuf4] "=m" (*(outbuf + 4 * BLOCKSIZE)), + [outbuf5] "=m" (*(outbuf + 5 * BLOCKSIZE)) + : : "memory" ); asm volatile ("movdqu %[inbuf6], %%xmm10\n\t" - "pxor %%xmm7, %%xmm5\n\t" - "pxor %%xmm10, %%xmm6\n\t" - "pxor %%xmm5, %%xmm10\n\t" - "movdqu %%xmm5, %[outbuf6]\n\t" + "movdqa %%xmm11, %%xmm0\n\t" + "pxor %%xmm5, %%xmm0\n\t" + "pxor %%xmm0, %%xmm10\n\t" + "movdqu %%xmm0, %[outbuf6]\n\t" : [outbuf6] "=m" (*(outbuf + 6 * BLOCKSIZE)) : [inbuf6] "m" (*(inbuf + 6 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[l7], %%xmm11\n\t" + asm volatile ("movdqu %[l7], %%xmm0\n\t" "pxor %%xmm11, %%xmm5\n\t" + "pxor %%xmm0, %%xmm5\n\t" "movdqu %[inbuf7], %%xmm11\n\t" - "pxor %%xmm11, %%xmm6\n\t" "pxor %%xmm5, %%xmm11\n\t" : : [l7] "m" (*l), [inbuf7] "m" (*(inbuf + 7 * BLOCKSIZE)) : "memory" ); do_aesni_enc_vec8 (ctx); asm volatile ("pxor %%xmm12, %%xmm1\n\t" "pxor %%xmm13, %%xmm2\n\t" "movdqu %[outbuf4],%%xmm0\n\t" "movdqu %[outbuf5],%%xmm12\n\t" "movdqu %[outbuf6],%%xmm13\n\t" "pxor %%xmm14, %%xmm3\n\t" "pxor %%xmm15, %%xmm4\n\t" "pxor %%xmm0, %%xmm8\n\t" "pxor %%xmm12, %%xmm9\n\t" "pxor %%xmm13, %%xmm10\n\t" "pxor %%xmm5, %%xmm11\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" "movdqu %%xmm3, %[outbuf2]\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" "movdqu %%xmm8, %[outbuf4]\n\t" "movdqu %%xmm9, %[outbuf5]\n\t" "movdqu %%xmm10, %[outbuf6]\n\t" "movdqu %%xmm11, %[outbuf7]\n\t" : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)), [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)), [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)), [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)), [outbuf4] "+m" (*(outbuf + 4 * BLOCKSIZE)), [outbuf5] "+m" (*(outbuf + 5 * BLOCKSIZE)), [outbuf6] "+m" (*(outbuf + 6 * BLOCKSIZE)), [outbuf7] "=m" (*(outbuf + 7 * BLOCKSIZE)) : : "memory" ); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } - aesni_cleanup_7_15(); + aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4 ; nblocks -= 4 ) { n += 4; l = aes_ocb_get_l(c, n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ - /* Checksum_i = Checksum_{i-1} xor P_i */ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ - asm volatile ("movdqu %[l0], %%xmm4\n\t" + asm volatile ("movdqu %[l0], %%xmm0\n\t" "movdqu %[inbuf0], %%xmm1\n\t" - "pxor %%xmm4, %%xmm5\n\t" - "pxor %%xmm1, %%xmm6\n\t" - "pxor %%xmm5, %%xmm1\n\t" - "movdqu %%xmm5, %[outbuf0]\n\t" - : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)) + "movdqu %[l0l1], %%xmm3\n\t" + : : [l0] "m" (*c->u_mode.ocb.L[0]), + [l0l1] "m" (*c->u_mode.ocb.L0L1), [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[l1], %%xmm0\n\t" - "movdqu %[inbuf1], %%xmm2\n\t" - "pxor %%xmm0, %%xmm5\n\t" - "pxor %%xmm2, %%xmm6\n\t" - "pxor %%xmm5, %%xmm2\n\t" - "movdqu %%xmm5, %[outbuf1]\n\t" - : [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)) - : [l1] "m" (*c->u_mode.ocb.L[1]), - [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)) + asm volatile ("movdqu %[l0l1l0], %%xmm4\n\t" + "movdqu %[l3], %%xmm6\n\t" + "pxor %%xmm5, %%xmm0\n\t" + "pxor %%xmm0, %%xmm1\n\t" + "movdqu %%xmm0, %[outbuf0]\n\t" + : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)) + : [l0l1l0] "m" (*c->u_mode.ocb.L0L1L0), + [l3] "m" (*l) : "memory" ); - asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" - "pxor %%xmm4, %%xmm5\n\t" - "pxor %%xmm3, %%xmm6\n\t" + asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm3\n\t" - "movdqu %%xmm5, %[outbuf2]\n\t" + "pxor %%xmm3, %%xmm2\n\t" + "movdqu %%xmm3, %[outbuf1]\n\t" + : [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)) + : [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqa %%xmm4, %%xmm0\n\t" + "movdqu %[inbuf2], %%xmm3\n\t" + "pxor %%xmm5, %%xmm0\n\t" + "pxor %%xmm0, %%xmm3\n\t" + "movdqu %%xmm0, %[outbuf2]\n\t" : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)) - : [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) + : + [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[l3], %%xmm4\n\t" + asm volatile ("pxor %%xmm6, %%xmm5\n\t" "pxor %%xmm4, %%xmm5\n\t" "movdqu %[inbuf3], %%xmm4\n\t" - "pxor %%xmm4, %%xmm6\n\t" "pxor %%xmm5, %%xmm4\n\t" : - : [l3] "m" (*l), - [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)) + : [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)) : "memory" ); do_aesni_enc_vec4 (ctx); asm volatile ("movdqu %[outbuf0],%%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "movdqu %[outbuf1],%%xmm0\n\t" "pxor %%xmm0, %%xmm2\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" "movdqu %[outbuf2],%%xmm0\n\t" "pxor %%xmm0, %%xmm3\n\t" "movdqu %%xmm3, %[outbuf2]\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" : [outbuf0] "+m" (*(outbuf + 0 * BLOCKSIZE)), [outbuf1] "+m" (*(outbuf + 1 * BLOCKSIZE)), [outbuf2] "+m" (*(outbuf + 2 * BLOCKSIZE)), [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)) : : "memory" ); outbuf += 4*BLOCKSIZE; inbuf += 4*BLOCKSIZE; } for ( ;nblocks; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ - /* Checksum_i = Checksum_{i-1} xor P_i */ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ asm volatile ("movdqu %[l], %%xmm1\n\t" "movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm1, %%xmm5\n\t" - "pxor %%xmm0, %%xmm6\n\t" "pxor %%xmm5, %%xmm0\n\t" : : [l] "m" (*l), [inbuf] "m" (*inbuf) : "memory" ); do_aesni_enc (ctx); asm volatile ("pxor %%xmm5, %%xmm0\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); inbuf += BLOCKSIZE; outbuf += BLOCKSIZE; } c->u_mode.ocb.data_nblocks = n; asm volatile ("movdqu %%xmm5, %[iv]\n\t" - "movdqu %%xmm6, %[ctr]\n\t" - : [iv] "=m" (*c->u_iv.iv), - [ctr] "=m" (*c->u_ctr.ctr) + : [iv] "=m" (*c->u_iv.iv) : : "memory" ); aesni_cleanup (); - aesni_cleanup_2_6 (); + aesni_cleanup_2_7 (); + + return 0; } -static void +static unsigned int NO_INLINE aesni_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, - const void *inbuf_arg, size_t nblocks) + const void *inbuf_arg, size_t nblocks_arg) { RIJNDAEL_context *ctx = (void *)&c->context.c; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; u64 n = c->u_mode.ocb.data_nblocks; const unsigned char *l; - aesni_prepare_2_6_variable; + size_t nblocks = nblocks_arg; + aesni_prepare_2_7_variable; aesni_prepare (); - aesni_prepare_2_6 (); + aesni_prepare_2_7 (); if ( !ctx->decryption_prepared ) { do_aesni_prepare_decryption ( ctx ); ctx->decryption_prepared = 1; } - /* Preload Offset and Checksum */ + /* Preload Offset */ asm volatile ("movdqu %[iv], %%xmm5\n\t" - "movdqu %[ctr], %%xmm6\n\t" : /* No output */ - : [iv] "m" (*c->u_iv.iv), - [ctr] "m" (*c->u_ctr.ctr) + : [iv] "m" (*c->u_iv.iv) : "memory" ); for ( ;nblocks && n % 4; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ - /* Checksum_i = Checksum_{i-1} xor P_i */ asm volatile ("movdqu %[l], %%xmm1\n\t" "movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm1, %%xmm5\n\t" "pxor %%xmm5, %%xmm0\n\t" : : [l] "m" (*l), [inbuf] "m" (*inbuf) : "memory" ); do_aesni_dec (ctx); asm volatile ("pxor %%xmm5, %%xmm0\n\t" - "pxor %%xmm0, %%xmm6\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); inbuf += BLOCKSIZE; outbuf += BLOCKSIZE; } #ifdef __x86_64__ if (nblocks >= 8) { - aesni_prepare_7_15_variable; + aesni_prepare_8_15_variable; - aesni_prepare_7_15(); + aesni_prepare_8_15(); - asm volatile ("movdqu %[l0], %%xmm7\n\t" + asm volatile ("movdqu %[l0], %%xmm6\n\t" : : [l0] "m" (*c->u_mode.ocb.L[0]) : "memory" ); for ( ;nblocks >= 8 ; nblocks -= 8 ) { n += 4; l = aes_ocb_get_l(c, n); - /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ - /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ - /* Checksum_i = Checksum_{i-1} xor P_i */ - - asm volatile ("movdqu %[l1], %%xmm10\n\t" - "movdqu %[inbuf0], %%xmm1\n\t" - "pxor %%xmm7, %%xmm5\n\t" - "pxor %%xmm5, %%xmm1\n\t" - "movdqa %%xmm5, %%xmm12\n\t" + asm volatile ("movdqu %[l0l1], %%xmm10\n\t" + "movdqu %[l0l1l0], %%xmm11\n\t" + "movdqu %[l3], %%xmm15\n\t" : - : [l1] "m" (*c->u_mode.ocb.L[1]), - [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)) + : [l0l1] "m" (*c->u_mode.ocb.L0L1), + [l0l1l0] "m" (*c->u_mode.ocb.L0L1L0), + [l3] "m" (*l) : "memory" ); - asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" - "pxor %%xmm10, %%xmm5\n\t" - "pxor %%xmm5, %%xmm2\n\t" - "movdqa %%xmm5, %%xmm13\n\t" + + n += 4; + l = aes_ocb_get_l(c, n); + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ + /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ + asm volatile ("movdqu %[inbuf0], %%xmm1\n\t" + "movdqu %[inbuf1], %%xmm2\n\t" + "movdqu %[inbuf2], %%xmm3\n\t" : - : [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)) + : [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)), + [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)), + [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" - "pxor %%xmm7, %%xmm5\n\t" - "pxor %%xmm5, %%xmm3\n\t" - "movdqa %%xmm5, %%xmm14\n\t" + asm volatile ("movdqu %[inbuf3], %%xmm4\n\t" + "movdqu %[inbuf4], %%xmm8\n\t" + "movdqu %[inbuf5], %%xmm9\n\t" : - : [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) + : [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)), + [inbuf4] "m" (*(inbuf + 4 * BLOCKSIZE)), + [inbuf5] "m" (*(inbuf + 5 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[l3], %%xmm0\n\t" - "movdqu %[inbuf3], %%xmm4\n\t" - "pxor %%xmm0, %%xmm5\n\t" + asm volatile ("movdqa %%xmm6, %%xmm12\n\t" + "pxor %%xmm5, %%xmm12\n\t" + "pxor %%xmm12, %%xmm1\n\t" + + "movdqa %%xmm10, %%xmm13\n\t" + "pxor %%xmm5, %%xmm13\n\t" + "pxor %%xmm13, %%xmm2\n\t" + + "movdqa %%xmm11, %%xmm14\n\t" + "pxor %%xmm5, %%xmm14\n\t" + "pxor %%xmm14, %%xmm3\n\t" + + "pxor %%xmm11, %%xmm5\n\t" + "pxor %%xmm15, %%xmm5\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqa %%xmm5, %%xmm15\n\t" - : - : [l3] "m" (*l), - [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)) - : "memory" ); - - n += 4; - l = aes_ocb_get_l(c, n); - asm volatile ("movdqu %[inbuf4], %%xmm8\n\t" - "pxor %%xmm7, %%xmm5\n\t" - "pxor %%xmm5, %%xmm8\n\t" - "movdqu %%xmm5, %[outbuf4]\n\t" - : [outbuf4] "=m" (*(outbuf + 4 * BLOCKSIZE)) - : [inbuf4] "m" (*(inbuf + 4 * BLOCKSIZE)) - : "memory" ); - asm volatile ("movdqu %[inbuf5], %%xmm9\n\t" - "pxor %%xmm10, %%xmm5\n\t" - "pxor %%xmm5, %%xmm9\n\t" - "movdqu %%xmm5, %[outbuf5]\n\t" - : [outbuf5] "=m" (*(outbuf + 5 * BLOCKSIZE)) - : [inbuf5] "m" (*(inbuf + 5 * BLOCKSIZE)) + "movdqa %%xmm5, %%xmm0\n\t" + "pxor %%xmm6, %%xmm0\n\t" + "pxor %%xmm0, %%xmm8\n\t" + "movdqu %%xmm0, %[outbuf4]\n\t" + + "movdqa %%xmm10, %%xmm0\n\t" + "pxor %%xmm5, %%xmm0\n\t" + "pxor %%xmm0, %%xmm9\n\t" + "movdqu %%xmm0, %[outbuf5]\n\t" + : [outbuf4] "=m" (*(outbuf + 4 * BLOCKSIZE)), + [outbuf5] "=m" (*(outbuf + 5 * BLOCKSIZE)) + : : "memory" ); asm volatile ("movdqu %[inbuf6], %%xmm10\n\t" - "pxor %%xmm7, %%xmm5\n\t" - "pxor %%xmm5, %%xmm10\n\t" - "movdqu %%xmm5, %[outbuf6]\n\t" + "movdqa %%xmm11, %%xmm0\n\t" + "pxor %%xmm5, %%xmm0\n\t" + "pxor %%xmm0, %%xmm10\n\t" + "movdqu %%xmm0, %[outbuf6]\n\t" : [outbuf6] "=m" (*(outbuf + 6 * BLOCKSIZE)) : [inbuf6] "m" (*(inbuf + 6 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqu %[l7], %%xmm0\n\t" - "movdqu %[inbuf7], %%xmm11\n\t" + "pxor %%xmm11, %%xmm5\n\t" "pxor %%xmm0, %%xmm5\n\t" + "movdqu %[inbuf7], %%xmm11\n\t" "pxor %%xmm5, %%xmm11\n\t" : : [l7] "m" (*l), [inbuf7] "m" (*(inbuf + 7 * BLOCKSIZE)) : "memory" ); do_aesni_dec_vec8 (ctx); asm volatile ("pxor %%xmm12, %%xmm1\n\t" "pxor %%xmm13, %%xmm2\n\t" "movdqu %[outbuf4],%%xmm0\n\t" "movdqu %[outbuf5],%%xmm12\n\t" "movdqu %[outbuf6],%%xmm13\n\t" "pxor %%xmm14, %%xmm3\n\t" "pxor %%xmm15, %%xmm4\n\t" "pxor %%xmm0, %%xmm8\n\t" "pxor %%xmm12, %%xmm9\n\t" "pxor %%xmm13, %%xmm10\n\t" "pxor %%xmm5, %%xmm11\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" "movdqu %%xmm3, %[outbuf2]\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" "movdqu %%xmm8, %[outbuf4]\n\t" "movdqu %%xmm9, %[outbuf5]\n\t" "movdqu %%xmm10, %[outbuf6]\n\t" "movdqu %%xmm11, %[outbuf7]\n\t" - "pxor %%xmm2, %%xmm1\n\t" - "pxor %%xmm4, %%xmm1\n\t" - "pxor %%xmm9, %%xmm1\n\t" - "pxor %%xmm11, %%xmm1\n\t" - "pxor %%xmm3, %%xmm6\n\t" - "pxor %%xmm8, %%xmm6\n\t" - "pxor %%xmm10, %%xmm6\n\t" - "pxor %%xmm1, %%xmm6\n\t" : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)), [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)), [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)), [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)), [outbuf4] "+m" (*(outbuf + 4 * BLOCKSIZE)), [outbuf5] "+m" (*(outbuf + 5 * BLOCKSIZE)), [outbuf6] "+m" (*(outbuf + 6 * BLOCKSIZE)), [outbuf7] "=m" (*(outbuf + 7 * BLOCKSIZE)) : : "memory" ); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } - aesni_cleanup_7_15(); + aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4 ; nblocks -= 4 ) { n += 4; l = aes_ocb_get_l(c, n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ - /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ - /* Checksum_i = Checksum_{i-1} xor P_i */ - asm volatile ("movdqu %[l0], %%xmm4\n\t" + /* C_i = Offset_i xor DECIPHER(K, P_i xor Offset_i) */ + asm volatile ("movdqu %[l0], %%xmm0\n\t" "movdqu %[inbuf0], %%xmm1\n\t" - "pxor %%xmm4, %%xmm5\n\t" - "pxor %%xmm5, %%xmm1\n\t" - "movdqu %%xmm5, %[outbuf0]\n\t" - : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)) + "movdqu %[l0l1], %%xmm3\n\t" + : : [l0] "m" (*c->u_mode.ocb.L[0]), + [l0l1] "m" (*c->u_mode.ocb.L0L1), [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[l1], %%xmm0\n\t" - "movdqu %[inbuf1], %%xmm2\n\t" - "pxor %%xmm0, %%xmm5\n\t" - "pxor %%xmm5, %%xmm2\n\t" - "movdqu %%xmm5, %[outbuf1]\n\t" - : [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)) - : [l1] "m" (*c->u_mode.ocb.L[1]), - [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)) + asm volatile ("movdqu %[l0l1l0], %%xmm4\n\t" + "movdqu %[l3], %%xmm6\n\t" + "pxor %%xmm5, %%xmm0\n\t" + "pxor %%xmm0, %%xmm1\n\t" + "movdqu %%xmm0, %[outbuf0]\n\t" + : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)) + : [l0l1l0] "m" (*c->u_mode.ocb.L0L1L0), + [l3] "m" (*l) : "memory" ); - asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" - "pxor %%xmm4, %%xmm5\n\t" + asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm3\n\t" - "movdqu %%xmm5, %[outbuf2]\n\t" + "pxor %%xmm3, %%xmm2\n\t" + "movdqu %%xmm3, %[outbuf1]\n\t" + : [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)) + : [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)) + : "memory" ); + asm volatile ("movdqa %%xmm4, %%xmm0\n\t" + "movdqu %[inbuf2], %%xmm3\n\t" + "pxor %%xmm5, %%xmm0\n\t" + "pxor %%xmm0, %%xmm3\n\t" + "movdqu %%xmm0, %[outbuf2]\n\t" : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)) - : [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) + : + [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[l3], %%xmm0\n\t" + asm volatile ("pxor %%xmm6, %%xmm5\n\t" + "pxor %%xmm4, %%xmm5\n\t" "movdqu %[inbuf3], %%xmm4\n\t" - "pxor %%xmm0, %%xmm5\n\t" "pxor %%xmm5, %%xmm4\n\t" : - : [l3] "m" (*l), - [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)) + : [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)) : "memory" ); do_aesni_dec_vec4 (ctx); asm volatile ("movdqu %[outbuf0],%%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "movdqu %[outbuf1],%%xmm0\n\t" "pxor %%xmm0, %%xmm2\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" "movdqu %[outbuf2],%%xmm0\n\t" "pxor %%xmm0, %%xmm3\n\t" "movdqu %%xmm3, %[outbuf2]\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" - "pxor %%xmm1, %%xmm6\n\t" - "pxor %%xmm2, %%xmm6\n\t" - "pxor %%xmm3, %%xmm6\n\t" - "pxor %%xmm4, %%xmm6\n\t" : [outbuf0] "+m" (*(outbuf + 0 * BLOCKSIZE)), [outbuf1] "+m" (*(outbuf + 1 * BLOCKSIZE)), [outbuf2] "+m" (*(outbuf + 2 * BLOCKSIZE)), [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)) : : "memory" ); outbuf += 4*BLOCKSIZE; inbuf += 4*BLOCKSIZE; } for ( ;nblocks; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ /* Checksum_i = Checksum_{i-1} xor P_i */ asm volatile ("movdqu %[l], %%xmm1\n\t" "movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm1, %%xmm5\n\t" "pxor %%xmm5, %%xmm0\n\t" : : [l] "m" (*l), [inbuf] "m" (*inbuf) : "memory" ); do_aesni_dec (ctx); asm volatile ("pxor %%xmm5, %%xmm0\n\t" - "pxor %%xmm0, %%xmm6\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); inbuf += BLOCKSIZE; outbuf += BLOCKSIZE; } c->u_mode.ocb.data_nblocks = n; asm volatile ("movdqu %%xmm5, %[iv]\n\t" - "movdqu %%xmm6, %[ctr]\n\t" - : [iv] "=m" (*c->u_iv.iv), - [ctr] "=m" (*c->u_ctr.ctr) + : [iv] "=m" (*c->u_iv.iv) : : "memory" ); + aesni_ocb_checksum (c, outbuf_arg, nblocks_arg); + aesni_cleanup (); - aesni_cleanup_2_6 (); + aesni_cleanup_2_7 (); + + return 0; } size_t _gcry_aes_aesni_ocb_crypt(gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt) { if (encrypt) - aesni_ocb_enc(c, outbuf_arg, inbuf_arg, nblocks); + return aesni_ocb_enc(c, outbuf_arg, inbuf_arg, nblocks); else - aesni_ocb_dec(c, outbuf_arg, inbuf_arg, nblocks); - - return 0; + return aesni_ocb_dec(c, outbuf_arg, inbuf_arg, nblocks); } size_t _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks) { RIJNDAEL_context *ctx = (void *)&c->context.c; const unsigned char *abuf = abuf_arg; u64 n = c->u_mode.ocb.aad_nblocks; const unsigned char *l; - aesni_prepare_2_6_variable; + aesni_prepare_2_7_variable; aesni_prepare (); - aesni_prepare_2_6 (); + aesni_prepare_2_7 (); /* Preload Offset and Sum */ asm volatile ("movdqu %[iv], %%xmm5\n\t" "movdqu %[ctr], %%xmm6\n\t" : /* No output */ : [iv] "m" (*c->u_mode.ocb.aad_offset), [ctr] "m" (*c->u_mode.ocb.aad_sum) : "memory" ); for ( ;nblocks && n % 4; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ asm volatile ("movdqu %[l], %%xmm1\n\t" "movdqu %[abuf], %%xmm0\n\t" "pxor %%xmm1, %%xmm5\n\t" "pxor %%xmm5, %%xmm0\n\t" : : [l] "m" (*l), [abuf] "m" (*abuf) : "memory" ); do_aesni_enc (ctx); asm volatile ("pxor %%xmm0, %%xmm6\n\t" : : : "memory" ); abuf += BLOCKSIZE; } #ifdef __x86_64__ if (nblocks >= 8) { - aesni_prepare_7_15_variable; + aesni_prepare_8_15_variable; - aesni_prepare_7_15(); + aesni_prepare_8_15(); - asm volatile ("movdqu %[l0], %%xmm7\n\t" - "movdqu %[l1], %%xmm12\n\t" + asm volatile ("movdqu %[l0], %%xmm7\n\t" + "movdqu %[l0l1], %%xmm12\n\t" + "movdqu %[l0l1l0], %%xmm13\n\t" : : [l0] "m" (*c->u_mode.ocb.L[0]), - [l1] "m" (*c->u_mode.ocb.L[1]) + [l0l1] "m" (*c->u_mode.ocb.L0L1), + [l0l1l0] "m" (*c->u_mode.ocb.L0L1L0) : "memory" ); for ( ;nblocks >= 8 ; nblocks -= 8 ) { n += 4; l = aes_ocb_get_l(c, n); + asm volatile ("movdqu %[l3], %%xmm0\n\t" + "pxor %%xmm13, %%xmm0\n\t" + : + : [l3] "m" (*l) + : "memory" ); + + n += 4; + l = aes_ocb_get_l(c, n); + + asm volatile ("movdqu %[l7], %%xmm14\n\t" + "pxor %%xmm13, %%xmm14\n\t" + : + : [l7] "m" (*l) + : "memory" ); + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ asm volatile ("movdqu %[abuf0], %%xmm1\n\t" - "pxor %%xmm7, %%xmm5\n\t" - "pxor %%xmm5, %%xmm1\n\t" + "movdqu %[abuf1], %%xmm2\n\t" + "movdqu %[abuf2], %%xmm3\n\t" + "movdqu %[abuf3], %%xmm4\n\t" + "movdqu %[abuf4], %%xmm8\n\t" + "movdqu %[abuf5], %%xmm9\n\t" + "movdqu %[abuf6], %%xmm10\n\t" + "movdqu %[abuf7], %%xmm11\n\t" : - : [abuf0] "m" (*(abuf + 0 * BLOCKSIZE)) + : [abuf0] "m" (*(abuf + 0 * BLOCKSIZE)), + [abuf1] "m" (*(abuf + 1 * BLOCKSIZE)), + [abuf2] "m" (*(abuf + 2 * BLOCKSIZE)), + [abuf3] "m" (*(abuf + 3 * BLOCKSIZE)), + [abuf4] "m" (*(abuf + 4 * BLOCKSIZE)), + [abuf5] "m" (*(abuf + 5 * BLOCKSIZE)), + [abuf6] "m" (*(abuf + 6 * BLOCKSIZE)), + [abuf7] "m" (*(abuf + 7 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[abuf1], %%xmm2\n\t" - "pxor %%xmm12, %%xmm5\n\t" + asm volatile ("pxor %%xmm7, %%xmm1\n\t" + "pxor %%xmm5, %%xmm1\n\t" + + "pxor %%xmm12, %%xmm2\n\t" "pxor %%xmm5, %%xmm2\n\t" - : - : [abuf1] "m" (*(abuf + 1 * BLOCKSIZE)) - : "memory" ); - asm volatile ("movdqu %[abuf2], %%xmm3\n\t" - "pxor %%xmm7, %%xmm5\n\t" + + "pxor %%xmm13, %%xmm3\n\t" "pxor %%xmm5, %%xmm3\n\t" - : - : [abuf2] "m" (*(abuf + 2 * BLOCKSIZE)) - : "memory" ); - asm volatile ("movdqu %[l3], %%xmm0\n\t" - "movdqu %[abuf3], %%xmm4\n\t" + "pxor %%xmm0, %%xmm5\n\t" "pxor %%xmm5, %%xmm4\n\t" - : - : [l3] "m" (*l), - [abuf3] "m" (*(abuf + 3 * BLOCKSIZE)) - : "memory" ); - n += 4; - l = aes_ocb_get_l(c, n); - - asm volatile ("movdqu %[abuf4], %%xmm8\n\t" - "pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm7, %%xmm8\n\t" "pxor %%xmm5, %%xmm8\n\t" - : - : [abuf4] "m" (*(abuf + 4 * BLOCKSIZE)) - : "memory" ); - asm volatile ("movdqu %[abuf5], %%xmm9\n\t" - "pxor %%xmm12, %%xmm5\n\t" + + "pxor %%xmm12, %%xmm9\n\t" "pxor %%xmm5, %%xmm9\n\t" - : - : [abuf5] "m" (*(abuf + 5 * BLOCKSIZE)) - : "memory" ); - asm volatile ("movdqu %[abuf6], %%xmm10\n\t" - "pxor %%xmm7, %%xmm5\n\t" + + "pxor %%xmm13, %%xmm10\n\t" "pxor %%xmm5, %%xmm10\n\t" - : - : [abuf6] "m" (*(abuf + 6 * BLOCKSIZE)) - : "memory" ); - asm volatile ("movdqu %[l7], %%xmm0\n\t" - "movdqu %[abuf7], %%xmm11\n\t" - "pxor %%xmm0, %%xmm5\n\t" + + "pxor %%xmm14, %%xmm5\n\t" "pxor %%xmm5, %%xmm11\n\t" : - : [l7] "m" (*l), - [abuf7] "m" (*(abuf + 7 * BLOCKSIZE)) + : : "memory" ); do_aesni_enc_vec8 (ctx); asm volatile ("pxor %%xmm2, %%xmm1\n\t" "pxor %%xmm3, %%xmm1\n\t" "pxor %%xmm4, %%xmm1\n\t" "pxor %%xmm8, %%xmm1\n\t" "pxor %%xmm9, %%xmm6\n\t" "pxor %%xmm10, %%xmm6\n\t" "pxor %%xmm11, %%xmm6\n\t" "pxor %%xmm1, %%xmm6\n\t" : : : "memory" ); abuf += 8*BLOCKSIZE; } - aesni_cleanup_7_15(); + aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4 ; nblocks -= 4 ) { n += 4; l = aes_ocb_get_l(c, n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ - asm volatile ("movdqu %[l0], %%xmm4\n\t" + asm volatile ("movdqu %[l0], %%xmm0\n\t" "movdqu %[abuf0], %%xmm1\n\t" - "pxor %%xmm4, %%xmm5\n\t" - "pxor %%xmm5, %%xmm1\n\t" + "movdqu %[l0l1], %%xmm3\n\t" : : [l0] "m" (*c->u_mode.ocb.L[0]), + [l0l1] "m" (*c->u_mode.ocb.L0L1), [abuf0] "m" (*(abuf + 0 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[l1], %%xmm0\n\t" - "movdqu %[abuf1], %%xmm2\n\t" - "pxor %%xmm0, %%xmm5\n\t" - "pxor %%xmm5, %%xmm2\n\t" + asm volatile ("movdqu %[l0l1l0], %%xmm4\n\t" + "movdqu %[l3], %%xmm7\n\t" + "pxor %%xmm5, %%xmm0\n\t" + "pxor %%xmm0, %%xmm1\n\t" : - : [l1] "m" (*c->u_mode.ocb.L[1]), - [abuf1] "m" (*(abuf + 1 * BLOCKSIZE)) + : [l0l1l0] "m" (*c->u_mode.ocb.L0L1L0), + [l3] "m" (*l) : "memory" ); - asm volatile ("movdqu %[abuf2], %%xmm3\n\t" - "pxor %%xmm4, %%xmm5\n\t" + asm volatile ("movdqu %[abuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm3\n\t" + "pxor %%xmm3, %%xmm2\n\t" : - : [l2] "m" (*c->u_mode.ocb.L[0]), - [abuf2] "m" (*(abuf + 2 * BLOCKSIZE)) + : [abuf1] "m" (*(abuf + 1 * BLOCKSIZE)) : "memory" ); - asm volatile ("movdqu %[l3], %%xmm0\n\t" + asm volatile ("movdqa %%xmm4, %%xmm0\n\t" + "movdqu %[abuf2], %%xmm3\n\t" + "pxor %%xmm5, %%xmm0\n\t" + "pxor %%xmm0, %%xmm3\n\t" + : + : [abuf2] "m" (*(abuf + 2 * BLOCKSIZE)) + : "memory" ); + asm volatile ("pxor %%xmm7, %%xmm5\n\t" + "pxor %%xmm4, %%xmm5\n\t" "movdqu %[abuf3], %%xmm4\n\t" - "pxor %%xmm0, %%xmm5\n\t" "pxor %%xmm5, %%xmm4\n\t" : - : [l3] "m" (*l), - [abuf3] "m" (*(abuf + 3 * BLOCKSIZE)) + : [abuf3] "m" (*(abuf + 3 * BLOCKSIZE)) : "memory" ); do_aesni_enc_vec4 (ctx); asm volatile ("pxor %%xmm1, %%xmm6\n\t" "pxor %%xmm2, %%xmm6\n\t" "pxor %%xmm3, %%xmm6\n\t" "pxor %%xmm4, %%xmm6\n\t" : : : "memory" ); abuf += 4*BLOCKSIZE; } for ( ;nblocks; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ asm volatile ("movdqu %[l], %%xmm1\n\t" "movdqu %[abuf], %%xmm0\n\t" "pxor %%xmm1, %%xmm5\n\t" "pxor %%xmm5, %%xmm0\n\t" : : [l] "m" (*l), [abuf] "m" (*abuf) : "memory" ); do_aesni_enc (ctx); asm volatile ("pxor %%xmm0, %%xmm6\n\t" : : : "memory" ); abuf += BLOCKSIZE; } c->u_mode.ocb.aad_nblocks = n; asm volatile ("movdqu %%xmm5, %[iv]\n\t" "movdqu %%xmm6, %[ctr]\n\t" : [iv] "=m" (*c->u_mode.ocb.aad_offset), [ctr] "=m" (*c->u_mode.ocb.aad_sum) : : "memory" ); aesni_cleanup (); - aesni_cleanup_2_6 (); + aesni_cleanup_2_7 (); return 0; } static const u64 xts_gfmul_const[16] __attribute__ ((aligned (16))) = { 0x87, 0x01 }; static void _gcry_aes_aesni_xts_enc (RIJNDAEL_context *ctx, unsigned char *tweak, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { - aesni_prepare_2_6_variable; + aesni_prepare_2_7_variable; aesni_prepare (); - aesni_prepare_2_6 (); + aesni_prepare_2_7 (); /* Preload Tweak */ asm volatile ("movdqu %[tweak], %%xmm5\n\t" "movdqa %[gfmul], %%xmm6\n\t" : : [tweak] "m" (*tweak), [gfmul] "m" (*xts_gfmul_const) : "memory" ); for ( ;nblocks >= 4; nblocks -= 4 ) { asm volatile ("pshufd $0x13, %%xmm5, %%xmm4\n\t" "movdqu %[inbuf0], %%xmm1\n\t" "pxor %%xmm5, %%xmm1\n\t" "movdqu %%xmm5, %[outbuf0]\n\t" "movdqa %%xmm4, %%xmm0\n\t" "paddd %%xmm4, %%xmm4\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf0] "=m" (*(outbuf + 0 * 16)) : [inbuf0] "m" (*(inbuf + 0 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm2\n\t" "movdqu %%xmm5, %[outbuf1]\n\t" "movdqa %%xmm4, %%xmm0\n\t" "paddd %%xmm4, %%xmm4\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf1] "=m" (*(outbuf + 1 * 16)) : [inbuf1] "m" (*(inbuf + 1 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" "pxor %%xmm5, %%xmm3\n\t" "movdqu %%xmm5, %[outbuf2]\n\t" "movdqa %%xmm4, %%xmm0\n\t" "paddd %%xmm4, %%xmm4\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf2] "=m" (*(outbuf + 2 * 16)) : [inbuf2] "m" (*(inbuf + 2 * 16)) : "memory" ); asm volatile ("movdqa %%xmm4, %%xmm0\n\t" "movdqu %[inbuf3], %%xmm4\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqu %%xmm5, %[outbuf3]\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf3] "=m" (*(outbuf + 3 * 16)) : [inbuf3] "m" (*(inbuf + 3 * 16)) : "memory" ); do_aesni_enc_vec4 (ctx); asm volatile ("movdqu %[outbuf0], %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" "movdqu %[outbuf1], %%xmm0\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "movdqu %[outbuf2], %%xmm1\n\t" "pxor %%xmm0, %%xmm2\n\t" "movdqu %[outbuf3], %%xmm0\n\t" "pxor %%xmm1, %%xmm3\n\t" "pxor %%xmm0, %%xmm4\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" "movdqu %%xmm3, %[outbuf2]\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" : [outbuf0] "+m" (*(outbuf + 0 * 16)), [outbuf1] "+m" (*(outbuf + 1 * 16)), [outbuf2] "+m" (*(outbuf + 2 * 16)), [outbuf3] "+m" (*(outbuf + 3 * 16)) : : "memory" ); outbuf += BLOCKSIZE * 4; inbuf += BLOCKSIZE * 4; } for ( ;nblocks; nblocks-- ) { asm volatile ("movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm5, %%xmm0\n\t" "movdqa %%xmm5, %%xmm4\n\t" "pshufd $0x13, %%xmm5, %%xmm1\n\t" "psrad $31, %%xmm1\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm1\n\t" "pxor %%xmm1, %%xmm5\n\t" : : [inbuf] "m" (*inbuf) : "memory" ); do_aesni_enc (ctx); asm volatile ("pxor %%xmm4, %%xmm0\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm5, %[tweak]\n\t" : [tweak] "=m" (*tweak) : : "memory" ); aesni_cleanup (); - aesni_cleanup_2_6 (); + aesni_cleanup_2_7 (); } static void _gcry_aes_aesni_xts_dec (RIJNDAEL_context *ctx, unsigned char *tweak, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { - aesni_prepare_2_6_variable; + aesni_prepare_2_7_variable; aesni_prepare (); - aesni_prepare_2_6 (); + aesni_prepare_2_7 (); if ( !ctx->decryption_prepared ) { do_aesni_prepare_decryption ( ctx ); ctx->decryption_prepared = 1; } /* Preload Tweak */ asm volatile ("movdqu %[tweak], %%xmm5\n\t" "movdqa %[gfmul], %%xmm6\n\t" : : [tweak] "m" (*tweak), [gfmul] "m" (*xts_gfmul_const) : "memory" ); for ( ;nblocks >= 4; nblocks -= 4 ) { asm volatile ("pshufd $0x13, %%xmm5, %%xmm4\n\t" "movdqu %[inbuf0], %%xmm1\n\t" "pxor %%xmm5, %%xmm1\n\t" "movdqu %%xmm5, %[outbuf0]\n\t" "movdqa %%xmm4, %%xmm0\n\t" "paddd %%xmm4, %%xmm4\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf0] "=m" (*(outbuf + 0 * 16)) : [inbuf0] "m" (*(inbuf + 0 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm2\n\t" "movdqu %%xmm5, %[outbuf1]\n\t" "movdqa %%xmm4, %%xmm0\n\t" "paddd %%xmm4, %%xmm4\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf1] "=m" (*(outbuf + 1 * 16)) : [inbuf1] "m" (*(inbuf + 1 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" "pxor %%xmm5, %%xmm3\n\t" "movdqu %%xmm5, %[outbuf2]\n\t" "movdqa %%xmm4, %%xmm0\n\t" "paddd %%xmm4, %%xmm4\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf2] "=m" (*(outbuf + 2 * 16)) : [inbuf2] "m" (*(inbuf + 2 * 16)) : "memory" ); asm volatile ("movdqa %%xmm4, %%xmm0\n\t" "movdqu %[inbuf3], %%xmm4\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqu %%xmm5, %[outbuf3]\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf3] "=m" (*(outbuf + 3 * 16)) : [inbuf3] "m" (*(inbuf + 3 * 16)) : "memory" ); do_aesni_dec_vec4 (ctx); asm volatile ("movdqu %[outbuf0], %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" "movdqu %[outbuf1], %%xmm0\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "movdqu %[outbuf2], %%xmm1\n\t" "pxor %%xmm0, %%xmm2\n\t" "movdqu %[outbuf3], %%xmm0\n\t" "pxor %%xmm1, %%xmm3\n\t" "pxor %%xmm0, %%xmm4\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" "movdqu %%xmm3, %[outbuf2]\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" : [outbuf0] "+m" (*(outbuf + 0 * 16)), [outbuf1] "+m" (*(outbuf + 1 * 16)), [outbuf2] "+m" (*(outbuf + 2 * 16)), [outbuf3] "+m" (*(outbuf + 3 * 16)) : : "memory" ); outbuf += BLOCKSIZE * 4; inbuf += BLOCKSIZE * 4; } for ( ;nblocks; nblocks-- ) { asm volatile ("movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm5, %%xmm0\n\t" "movdqa %%xmm5, %%xmm4\n\t" "pshufd $0x13, %%xmm5, %%xmm1\n\t" "psrad $31, %%xmm1\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm1\n\t" "pxor %%xmm1, %%xmm5\n\t" : : [inbuf] "m" (*inbuf) : "memory" ); do_aesni_dec (ctx); asm volatile ("pxor %%xmm4, %%xmm0\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm5, %[tweak]\n\t" : [tweak] "=m" (*tweak) : : "memory" ); aesni_cleanup (); - aesni_cleanup_2_6 (); + aesni_cleanup_2_7 (); } void _gcry_aes_aesni_xts_crypt (RIJNDAEL_context *ctx, unsigned char *tweak, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks, int encrypt) { if (encrypt) _gcry_aes_aesni_xts_enc(ctx, tweak, outbuf, inbuf, nblocks); else _gcry_aes_aesni_xts_dec(ctx, tweak, outbuf, inbuf, nblocks); } #endif /* USE_AESNI */ diff --git a/cipher/rijndael-internal.h b/cipher/rijndael-internal.h index 160fb8c3..876d55fe 100644 --- a/cipher/rijndael-internal.h +++ b/cipher/rijndael-internal.h @@ -1,166 +1,168 @@ /* Rijndael (AES) for GnuPG * Copyright (C) 2000, 2001, 2002, 2003, 2007, * 2008, 2011, 2012 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #ifndef G10_RIJNDAEL_INTERNAL_H #define G10_RIJNDAEL_INTERNAL_H #include "types.h" /* for byte and u32 typedefs */ #define MAXKC (256/32) #define MAXROUNDS 14 #define BLOCKSIZE (128/8) /* Helper macro to force alignment to 16 bytes. */ #ifdef HAVE_GCC_ATTRIBUTE_ALIGNED # define ATTR_ALIGNED_16 __attribute__ ((aligned (16))) #else # define ATTR_ALIGNED_16 #endif /* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */ #undef USE_AMD64_ASM #if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_AMD64_ASM 1 #endif /* USE_SSSE3 indicates whether to use SSSE3 code. */ #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \ (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_SSSE3 1 #endif /* USE_ARM_ASM indicates whether to use ARM assembly code. */ #undef USE_ARM_ASM #if defined(__ARMEL__) # ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS # define USE_ARM_ASM 1 # endif #endif #if defined(__AARCH64EL__) # ifdef HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS # define USE_ARM_ASM 1 # endif #endif /* USE_PADLOCK indicates whether to compile the padlock specific code. */ #undef USE_PADLOCK #ifdef ENABLE_PADLOCK_SUPPORT # ifdef HAVE_GCC_ATTRIBUTE_ALIGNED # if (defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__) # define USE_PADLOCK 1 # endif # endif #endif /*ENABLE_PADLOCK_SUPPORT*/ /* USE_AESNI inidicates whether to compile with Intel AES-NI code. We need the vector-size attribute which seems to be available since gcc 3. However, to be on the safe side we require at least gcc 4. */ #undef USE_AESNI #ifdef ENABLE_AESNI_SUPPORT # if ((defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)) # if __GNUC__ >= 4 # define USE_AESNI 1 # endif # endif #endif /* ENABLE_AESNI_SUPPORT */ /* USE_ARM_CE indicates whether to enable ARMv8 Crypto Extension assembly * code. */ #undef USE_ARM_CE #ifdef ENABLE_ARM_CRYPTO_SUPPORT # if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \ && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \ && defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO) # define USE_ARM_CE 1 # elif defined(__AARCH64EL__) \ && defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) \ && defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO) # define USE_ARM_CE 1 # endif #endif /* ENABLE_ARM_CRYPTO_SUPPORT */ struct RIJNDAEL_context_s; typedef unsigned int (*rijndael_cryptfn_t)(const struct RIJNDAEL_context_s *ctx, unsigned char *bx, const unsigned char *ax); typedef void (*rijndael_prefetchfn_t)(void); /* Our context object. */ typedef struct RIJNDAEL_context_s { /* The first fields are the keyschedule arrays. This is so that they are aligned on a 16 byte boundary if using gcc. This alignment is required for the AES-NI code and a good idea in any case. The alignment is guaranteed due to the way cipher.c allocates the space for the context. The PROPERLY_ALIGNED_TYPE hack is used to force a minimal alignment if not using gcc of if the alignment requirement is higher that 16 bytes. */ union { PROPERLY_ALIGNED_TYPE dummy; byte keyschedule[MAXROUNDS+1][4][4]; u32 keyschedule32[MAXROUNDS+1][4]; #ifdef USE_PADLOCK /* The key as passed to the padlock engine. It is only used if the padlock engine is used (USE_PADLOCK, below). */ unsigned char padlock_key[16] __attribute__ ((aligned (16))); #endif /*USE_PADLOCK*/ } u1; union { PROPERLY_ALIGNED_TYPE dummy; byte keyschedule[MAXROUNDS+1][4][4]; u32 keyschedule32[MAXROUNDS+1][4]; } u2; int rounds; /* Key-length-dependent number of rounds. */ unsigned int decryption_prepared:1; /* The decryption key schedule is available. */ #ifdef USE_PADLOCK unsigned int use_padlock:1; /* Padlock shall be used. */ #endif /*USE_PADLOCK*/ #ifdef USE_AESNI unsigned int use_aesni:1; /* AES-NI shall be used. */ + unsigned int use_avx:1; /* AVX shall be used. */ + unsigned int use_avx2:1; /* AVX2 shall be used. */ #endif /*USE_AESNI*/ #ifdef USE_SSSE3 unsigned int use_ssse3:1; /* SSSE3 shall be used. */ #endif /*USE_SSSE3*/ #ifdef USE_ARM_CE unsigned int use_arm_ce:1; /* ARMv8 CE shall be used. */ #endif /*USE_ARM_CE*/ rijndael_cryptfn_t encrypt_fn; rijndael_cryptfn_t decrypt_fn; rijndael_prefetchfn_t prefetch_enc_fn; rijndael_prefetchfn_t prefetch_dec_fn; } RIJNDAEL_context ATTR_ALIGNED_16; /* Macros defining alias for the keyschedules. */ #define keyschenc u1.keyschedule #define keyschenc32 u1.keyschedule32 #define keyschdec u2.keyschedule #define keyschdec32 u2.keyschedule32 #define padlockkey u1.padlock_key #endif /* G10_RIJNDAEL_INTERNAL_H */ diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 1bc8b0fc..80945376 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -1,2087 +1,2089 @@ /* Rijndael (AES) for GnuPG * Copyright (C) 2000, 2001, 2002, 2003, 2007, * 2008, 2011, 2012 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . ******************************************************************* * The code here is based on the optimized implementation taken from * http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ on Oct 2, 2000, * which carries this notice: *------------------------------------------ * rijndael-alg-fst.c v2.3 April '2000 * * Optimised ANSI C code * * authors: v1.0: Antoon Bosselaers * v2.0: Vincent Rijmen * v2.3: Paulo Barreto * * This code is placed in the public domain. *------------------------------------------ * * The SP800-38a document is available at: * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf * */ #include #include #include #include /* for memcmp() */ #include "types.h" /* for byte and u32 typedefs */ #include "g10lib.h" #include "cipher.h" #include "bufhelp.h" #include "cipher-selftest.h" #include "rijndael-internal.h" #include "./cipher-internal.h" #ifdef USE_AMD64_ASM /* AMD64 assembly implementations of AES */ extern unsigned int _gcry_aes_amd64_encrypt_block(const void *keysched_enc, unsigned char *out, const unsigned char *in, int rounds, const void *encT); extern unsigned int _gcry_aes_amd64_decrypt_block(const void *keysched_dec, unsigned char *out, const unsigned char *in, int rounds, const void *decT); #endif /*USE_AMD64_ASM*/ #ifdef USE_AESNI /* AES-NI (AMD64 & i386) accelerated implementations of AES */ extern void _gcry_aes_aesni_do_setkey(RIJNDAEL_context *ctx, const byte *key); extern void _gcry_aes_aesni_prepare_decryption(RIJNDAEL_context *ctx); extern unsigned int _gcry_aes_aesni_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern unsigned int _gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern void _gcry_aes_aesni_cfb_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_aesni_cbc_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int cbc_mac); extern void _gcry_aes_aesni_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_aesni_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_aesni_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern size_t _gcry_aes_aesni_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); extern size_t _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); extern void _gcry_aes_aesni_xts_crypt (void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); #endif #ifdef USE_SSSE3 /* SSSE3 (AMD64) vector permutation implementation of AES */ extern void _gcry_aes_ssse3_do_setkey(RIJNDAEL_context *ctx, const byte *key); extern void _gcry_aes_ssse3_prepare_decryption(RIJNDAEL_context *ctx); extern unsigned int _gcry_aes_ssse3_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern unsigned int _gcry_aes_ssse3_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern void _gcry_aes_ssse3_cfb_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_ssse3_cbc_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int cbc_mac); extern void _gcry_aes_ssse3_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_ssse3_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_ssse3_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern size_t _gcry_aes_ssse3_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); extern size_t _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); #endif #ifdef USE_PADLOCK extern unsigned int _gcry_aes_padlock_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax); extern unsigned int _gcry_aes_padlock_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax); #endif #ifdef USE_ARM_ASM /* ARM assembly implementations of AES */ extern unsigned int _gcry_aes_arm_encrypt_block(const void *keysched_enc, unsigned char *out, const unsigned char *in, int rounds, const void *encT); extern unsigned int _gcry_aes_arm_decrypt_block(const void *keysched_dec, unsigned char *out, const unsigned char *in, int rounds, const void *decT); #endif /*USE_ARM_ASM*/ #ifdef USE_ARM_CE /* ARMv8 Crypto Extension implementations of AES */ extern void _gcry_aes_armv8_ce_setkey(RIJNDAEL_context *ctx, const byte *key); extern void _gcry_aes_armv8_ce_prepare_decryption(RIJNDAEL_context *ctx); extern unsigned int _gcry_aes_armv8_ce_encrypt(const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern unsigned int _gcry_aes_armv8_ce_decrypt(const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern void _gcry_aes_armv8_ce_cfb_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_armv8_ce_cbc_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int cbc_mac); extern void _gcry_aes_armv8_ce_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_armv8_ce_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_armv8_ce_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern size_t _gcry_aes_armv8_ce_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); extern size_t _gcry_aes_armv8_ce_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); extern void _gcry_aes_armv8_ce_xts_crypt (void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); #endif /*USE_ARM_ASM*/ static unsigned int do_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax); static unsigned int do_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax); /* All the numbers. */ #include "rijndael-tables.h" /* Function prototypes. */ static const char *selftest(void); /* Prefetching for encryption/decryption tables. */ static void prefetch_table(const volatile byte *tab, size_t len) { size_t i; for (i = 0; i < len; i += 8 * 32) { (void)tab[i + 0 * 32]; (void)tab[i + 1 * 32]; (void)tab[i + 2 * 32]; (void)tab[i + 3 * 32]; (void)tab[i + 4 * 32]; (void)tab[i + 5 * 32]; (void)tab[i + 6 * 32]; (void)tab[i + 7 * 32]; } (void)tab[len - 1]; } static void prefetch_enc(void) { prefetch_table((const void *)encT, sizeof(encT)); } static void prefetch_dec(void) { prefetch_table((const void *)&dec_tables, sizeof(dec_tables)); } /* Perform the key setup. */ static gcry_err_code_t do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen, gcry_cipher_hd_t hd) { static int initialized = 0; static const char *selftest_failed = 0; int rounds; int i,j, r, t, rconpointer = 0; int KC; #if defined(USE_AESNI) || defined(USE_PADLOCK) || defined(USE_SSSE3) \ || defined(USE_ARM_CE) unsigned int hwfeatures; #endif (void)hd; /* The on-the-fly self tests are only run in non-fips mode. In fips mode explicit self-tests are required. Actually the on-the-fly self-tests are not fully thread-safe and it might happen that a failed self-test won't get noticed in another thread. FIXME: We might want to have a central registry of succeeded self-tests. */ if (!fips_mode () && !initialized) { initialized = 1; selftest_failed = selftest (); if (selftest_failed) log_error ("%s\n", selftest_failed ); } if (selftest_failed) return GPG_ERR_SELFTEST_FAILED; if( keylen == 128/8 ) { rounds = 10; KC = 4; } else if ( keylen == 192/8 ) { rounds = 12; KC = 6; } else if ( keylen == 256/8 ) { rounds = 14; KC = 8; } else return GPG_ERR_INV_KEYLEN; ctx->rounds = rounds; #if defined(USE_AESNI) || defined(USE_PADLOCK) || defined(USE_SSSE3) \ || defined(USE_ARM_CE) hwfeatures = _gcry_get_hw_features (); #endif ctx->decryption_prepared = 0; #ifdef USE_PADLOCK ctx->use_padlock = 0; #endif #ifdef USE_AESNI ctx->use_aesni = 0; #endif #ifdef USE_SSSE3 ctx->use_ssse3 = 0; #endif #ifdef USE_ARM_CE ctx->use_arm_ce = 0; #endif if (0) { ; } #ifdef USE_AESNI else if (hwfeatures & HWF_INTEL_AESNI) { ctx->encrypt_fn = _gcry_aes_aesni_encrypt; ctx->decrypt_fn = _gcry_aes_aesni_decrypt; ctx->prefetch_enc_fn = NULL; ctx->prefetch_dec_fn = NULL; ctx->use_aesni = 1; + ctx->use_avx = !!(hwfeatures & HWF_INTEL_AVX); + ctx->use_avx2 = !!(hwfeatures & HWF_INTEL_AVX2); if (hd) { hd->bulk.cfb_enc = _gcry_aes_aesni_cfb_enc; hd->bulk.cfb_dec = _gcry_aes_aesni_cfb_dec; hd->bulk.cbc_enc = _gcry_aes_aesni_cbc_enc; hd->bulk.cbc_dec = _gcry_aes_aesni_cbc_dec; hd->bulk.ctr_enc = _gcry_aes_aesni_ctr_enc; hd->bulk.ocb_crypt = _gcry_aes_aesni_ocb_crypt; hd->bulk.ocb_auth = _gcry_aes_aesni_ocb_auth; hd->bulk.xts_crypt = _gcry_aes_aesni_xts_crypt; } } #endif #ifdef USE_PADLOCK else if (hwfeatures & HWF_PADLOCK_AES && keylen == 128/8) { ctx->encrypt_fn = _gcry_aes_padlock_encrypt; ctx->decrypt_fn = _gcry_aes_padlock_decrypt; ctx->prefetch_enc_fn = NULL; ctx->prefetch_dec_fn = NULL; ctx->use_padlock = 1; memcpy (ctx->padlockkey, key, keylen); } #endif #ifdef USE_SSSE3 else if (hwfeatures & HWF_INTEL_SSSE3) { ctx->encrypt_fn = _gcry_aes_ssse3_encrypt; ctx->decrypt_fn = _gcry_aes_ssse3_decrypt; ctx->prefetch_enc_fn = NULL; ctx->prefetch_dec_fn = NULL; ctx->use_ssse3 = 1; if (hd) { hd->bulk.cfb_enc = _gcry_aes_ssse3_cfb_enc; hd->bulk.cfb_dec = _gcry_aes_ssse3_cfb_dec; hd->bulk.cbc_enc = _gcry_aes_ssse3_cbc_enc; hd->bulk.cbc_dec = _gcry_aes_ssse3_cbc_dec; hd->bulk.ctr_enc = _gcry_aes_ssse3_ctr_enc; hd->bulk.ocb_crypt = _gcry_aes_ssse3_ocb_crypt; hd->bulk.ocb_auth = _gcry_aes_ssse3_ocb_auth; } } #endif #ifdef USE_ARM_CE else if (hwfeatures & HWF_ARM_AES) { ctx->encrypt_fn = _gcry_aes_armv8_ce_encrypt; ctx->decrypt_fn = _gcry_aes_armv8_ce_decrypt; ctx->prefetch_enc_fn = NULL; ctx->prefetch_dec_fn = NULL; ctx->use_arm_ce = 1; if (hd) { hd->bulk.cfb_enc = _gcry_aes_armv8_ce_cfb_enc; hd->bulk.cfb_dec = _gcry_aes_armv8_ce_cfb_dec; hd->bulk.cbc_enc = _gcry_aes_armv8_ce_cbc_enc; hd->bulk.cbc_dec = _gcry_aes_armv8_ce_cbc_dec; hd->bulk.ctr_enc = _gcry_aes_armv8_ce_ctr_enc; hd->bulk.ocb_crypt = _gcry_aes_armv8_ce_ocb_crypt; hd->bulk.ocb_auth = _gcry_aes_armv8_ce_ocb_auth; hd->bulk.xts_crypt = _gcry_aes_armv8_ce_xts_crypt; } } #endif else { ctx->encrypt_fn = do_encrypt; ctx->decrypt_fn = do_decrypt; ctx->prefetch_enc_fn = prefetch_enc; ctx->prefetch_dec_fn = prefetch_dec; } /* NB: We don't yet support Padlock hardware key generation. */ if (0) { ; } #ifdef USE_AESNI else if (ctx->use_aesni) _gcry_aes_aesni_do_setkey (ctx, key); #endif #ifdef USE_SSSE3 else if (ctx->use_ssse3) _gcry_aes_ssse3_do_setkey (ctx, key); #endif #ifdef USE_ARM_CE else if (ctx->use_arm_ce) _gcry_aes_armv8_ce_setkey (ctx, key); #endif else { const byte *sbox = ((const byte *)encT) + 1; union { PROPERLY_ALIGNED_TYPE dummy; byte data[MAXKC][4]; u32 data32[MAXKC]; } tkk[2]; #define k tkk[0].data #define k_u32 tkk[0].data32 #define tk tkk[1].data #define tk_u32 tkk[1].data32 #define W (ctx->keyschenc) #define W_u32 (ctx->keyschenc32) prefetch_enc(); for (i = 0; i < keylen; i++) { k[i >> 2][i & 3] = key[i]; } for (j = KC-1; j >= 0; j--) { tk_u32[j] = k_u32[j]; } r = 0; t = 0; /* Copy values into round key array. */ for (j = 0; (j < KC) && (r < rounds + 1); ) { for (; (j < KC) && (t < 4); j++, t++) { W_u32[r][t] = le_bswap32(tk_u32[j]); } if (t == 4) { r++; t = 0; } } while (r < rounds + 1) { /* While not enough round key material calculated calculate new values. */ tk[0][0] ^= sbox[tk[KC-1][1] * 4]; tk[0][1] ^= sbox[tk[KC-1][2] * 4]; tk[0][2] ^= sbox[tk[KC-1][3] * 4]; tk[0][3] ^= sbox[tk[KC-1][0] * 4]; tk[0][0] ^= rcon[rconpointer++]; if (KC != 8) { for (j = 1; j < KC; j++) { tk_u32[j] ^= tk_u32[j-1]; } } else { for (j = 1; j < KC/2; j++) { tk_u32[j] ^= tk_u32[j-1]; } tk[KC/2][0] ^= sbox[tk[KC/2 - 1][0] * 4]; tk[KC/2][1] ^= sbox[tk[KC/2 - 1][1] * 4]; tk[KC/2][2] ^= sbox[tk[KC/2 - 1][2] * 4]; tk[KC/2][3] ^= sbox[tk[KC/2 - 1][3] * 4]; for (j = KC/2 + 1; j < KC; j++) { tk_u32[j] ^= tk_u32[j-1]; } } /* Copy values into round key array. */ for (j = 0; (j < KC) && (r < rounds + 1); ) { for (; (j < KC) && (t < 4); j++, t++) { W_u32[r][t] = le_bswap32(tk_u32[j]); } if (t == 4) { r++; t = 0; } } } #undef W #undef tk #undef k #undef W_u32 #undef tk_u32 #undef k_u32 wipememory(&tkk, sizeof(tkk)); } return 0; } static gcry_err_code_t rijndael_setkey (void *context, const byte *key, const unsigned keylen, gcry_cipher_hd_t hd) { RIJNDAEL_context *ctx = context; return do_setkey (ctx, key, keylen, hd); } /* Make a decryption key from an encryption key. */ static void prepare_decryption( RIJNDAEL_context *ctx ) { int r; if (0) ; #ifdef USE_AESNI else if (ctx->use_aesni) { _gcry_aes_aesni_prepare_decryption (ctx); } #endif /*USE_AESNI*/ #ifdef USE_SSSE3 else if (ctx->use_ssse3) { _gcry_aes_ssse3_prepare_decryption (ctx); } #endif /*USE_SSSE3*/ #ifdef USE_ARM_CE else if (ctx->use_arm_ce) { _gcry_aes_armv8_ce_prepare_decryption (ctx); } #endif /*USE_SSSE3*/ #ifdef USE_PADLOCK else if (ctx->use_padlock) { /* Padlock does not need decryption subkeys. */ } #endif /*USE_PADLOCK*/ else { const byte *sbox = ((const byte *)encT) + 1; prefetch_enc(); prefetch_dec(); ctx->keyschdec32[0][0] = ctx->keyschenc32[0][0]; ctx->keyschdec32[0][1] = ctx->keyschenc32[0][1]; ctx->keyschdec32[0][2] = ctx->keyschenc32[0][2]; ctx->keyschdec32[0][3] = ctx->keyschenc32[0][3]; for (r = 1; r < ctx->rounds; r++) { u32 *wi = ctx->keyschenc32[r]; u32 *wo = ctx->keyschdec32[r]; u32 wt; wt = wi[0]; wo[0] = rol(decT[sbox[(byte)(wt >> 0) * 4]], 8 * 0) ^ rol(decT[sbox[(byte)(wt >> 8) * 4]], 8 * 1) ^ rol(decT[sbox[(byte)(wt >> 16) * 4]], 8 * 2) ^ rol(decT[sbox[(byte)(wt >> 24) * 4]], 8 * 3); wt = wi[1]; wo[1] = rol(decT[sbox[(byte)(wt >> 0) * 4]], 8 * 0) ^ rol(decT[sbox[(byte)(wt >> 8) * 4]], 8 * 1) ^ rol(decT[sbox[(byte)(wt >> 16) * 4]], 8 * 2) ^ rol(decT[sbox[(byte)(wt >> 24) * 4]], 8 * 3); wt = wi[2]; wo[2] = rol(decT[sbox[(byte)(wt >> 0) * 4]], 8 * 0) ^ rol(decT[sbox[(byte)(wt >> 8) * 4]], 8 * 1) ^ rol(decT[sbox[(byte)(wt >> 16) * 4]], 8 * 2) ^ rol(decT[sbox[(byte)(wt >> 24) * 4]], 8 * 3); wt = wi[3]; wo[3] = rol(decT[sbox[(byte)(wt >> 0) * 4]], 8 * 0) ^ rol(decT[sbox[(byte)(wt >> 8) * 4]], 8 * 1) ^ rol(decT[sbox[(byte)(wt >> 16) * 4]], 8 * 2) ^ rol(decT[sbox[(byte)(wt >> 24) * 4]], 8 * 3); } ctx->keyschdec32[r][0] = ctx->keyschenc32[r][0]; ctx->keyschdec32[r][1] = ctx->keyschenc32[r][1]; ctx->keyschdec32[r][2] = ctx->keyschenc32[r][2]; ctx->keyschdec32[r][3] = ctx->keyschenc32[r][3]; } } #if !defined(USE_ARM_ASM) && !defined(USE_AMD64_ASM) /* Encrypt one block. A and B may be the same. */ static unsigned int do_encrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b, const unsigned char *a) { #define rk (ctx->keyschenc32) const byte *sbox = ((const byte *)encT) + 1; int rounds = ctx->rounds; int r; u32 sa[4]; u32 sb[4]; sb[0] = buf_get_le32(a + 0); sb[1] = buf_get_le32(a + 4); sb[2] = buf_get_le32(a + 8); sb[3] = buf_get_le32(a + 12); sa[0] = sb[0] ^ rk[0][0]; sa[1] = sb[1] ^ rk[0][1]; sa[2] = sb[2] ^ rk[0][2]; sa[3] = sb[3] ^ rk[0][3]; sb[0] = rol(encT[(byte)(sa[0] >> (0 * 8))], (0 * 8)); sb[3] = rol(encT[(byte)(sa[0] >> (1 * 8))], (1 * 8)); sb[2] = rol(encT[(byte)(sa[0] >> (2 * 8))], (2 * 8)); sb[1] = rol(encT[(byte)(sa[0] >> (3 * 8))], (3 * 8)); sa[0] = rk[1][0] ^ sb[0]; sb[1] ^= rol(encT[(byte)(sa[1] >> (0 * 8))], (0 * 8)); sa[0] ^= rol(encT[(byte)(sa[1] >> (1 * 8))], (1 * 8)); sb[3] ^= rol(encT[(byte)(sa[1] >> (2 * 8))], (2 * 8)); sb[2] ^= rol(encT[(byte)(sa[1] >> (3 * 8))], (3 * 8)); sa[1] = rk[1][1] ^ sb[1]; sb[2] ^= rol(encT[(byte)(sa[2] >> (0 * 8))], (0 * 8)); sa[1] ^= rol(encT[(byte)(sa[2] >> (1 * 8))], (1 * 8)); sa[0] ^= rol(encT[(byte)(sa[2] >> (2 * 8))], (2 * 8)); sb[3] ^= rol(encT[(byte)(sa[2] >> (3 * 8))], (3 * 8)); sa[2] = rk[1][2] ^ sb[2]; sb[3] ^= rol(encT[(byte)(sa[3] >> (0 * 8))], (0 * 8)); sa[2] ^= rol(encT[(byte)(sa[3] >> (1 * 8))], (1 * 8)); sa[1] ^= rol(encT[(byte)(sa[3] >> (2 * 8))], (2 * 8)); sa[0] ^= rol(encT[(byte)(sa[3] >> (3 * 8))], (3 * 8)); sa[3] = rk[1][3] ^ sb[3]; for (r = 2; r < rounds; r++) { sb[0] = rol(encT[(byte)(sa[0] >> (0 * 8))], (0 * 8)); sb[3] = rol(encT[(byte)(sa[0] >> (1 * 8))], (1 * 8)); sb[2] = rol(encT[(byte)(sa[0] >> (2 * 8))], (2 * 8)); sb[1] = rol(encT[(byte)(sa[0] >> (3 * 8))], (3 * 8)); sa[0] = rk[r][0] ^ sb[0]; sb[1] ^= rol(encT[(byte)(sa[1] >> (0 * 8))], (0 * 8)); sa[0] ^= rol(encT[(byte)(sa[1] >> (1 * 8))], (1 * 8)); sb[3] ^= rol(encT[(byte)(sa[1] >> (2 * 8))], (2 * 8)); sb[2] ^= rol(encT[(byte)(sa[1] >> (3 * 8))], (3 * 8)); sa[1] = rk[r][1] ^ sb[1]; sb[2] ^= rol(encT[(byte)(sa[2] >> (0 * 8))], (0 * 8)); sa[1] ^= rol(encT[(byte)(sa[2] >> (1 * 8))], (1 * 8)); sa[0] ^= rol(encT[(byte)(sa[2] >> (2 * 8))], (2 * 8)); sb[3] ^= rol(encT[(byte)(sa[2] >> (3 * 8))], (3 * 8)); sa[2] = rk[r][2] ^ sb[2]; sb[3] ^= rol(encT[(byte)(sa[3] >> (0 * 8))], (0 * 8)); sa[2] ^= rol(encT[(byte)(sa[3] >> (1 * 8))], (1 * 8)); sa[1] ^= rol(encT[(byte)(sa[3] >> (2 * 8))], (2 * 8)); sa[0] ^= rol(encT[(byte)(sa[3] >> (3 * 8))], (3 * 8)); sa[3] = rk[r][3] ^ sb[3]; r++; sb[0] = rol(encT[(byte)(sa[0] >> (0 * 8))], (0 * 8)); sb[3] = rol(encT[(byte)(sa[0] >> (1 * 8))], (1 * 8)); sb[2] = rol(encT[(byte)(sa[0] >> (2 * 8))], (2 * 8)); sb[1] = rol(encT[(byte)(sa[0] >> (3 * 8))], (3 * 8)); sa[0] = rk[r][0] ^ sb[0]; sb[1] ^= rol(encT[(byte)(sa[1] >> (0 * 8))], (0 * 8)); sa[0] ^= rol(encT[(byte)(sa[1] >> (1 * 8))], (1 * 8)); sb[3] ^= rol(encT[(byte)(sa[1] >> (2 * 8))], (2 * 8)); sb[2] ^= rol(encT[(byte)(sa[1] >> (3 * 8))], (3 * 8)); sa[1] = rk[r][1] ^ sb[1]; sb[2] ^= rol(encT[(byte)(sa[2] >> (0 * 8))], (0 * 8)); sa[1] ^= rol(encT[(byte)(sa[2] >> (1 * 8))], (1 * 8)); sa[0] ^= rol(encT[(byte)(sa[2] >> (2 * 8))], (2 * 8)); sb[3] ^= rol(encT[(byte)(sa[2] >> (3 * 8))], (3 * 8)); sa[2] = rk[r][2] ^ sb[2]; sb[3] ^= rol(encT[(byte)(sa[3] >> (0 * 8))], (0 * 8)); sa[2] ^= rol(encT[(byte)(sa[3] >> (1 * 8))], (1 * 8)); sa[1] ^= rol(encT[(byte)(sa[3] >> (2 * 8))], (2 * 8)); sa[0] ^= rol(encT[(byte)(sa[3] >> (3 * 8))], (3 * 8)); sa[3] = rk[r][3] ^ sb[3]; } /* Last round is special. */ sb[0] = (sbox[(byte)(sa[0] >> (0 * 8)) * 4]) << (0 * 8); sb[3] = (sbox[(byte)(sa[0] >> (1 * 8)) * 4]) << (1 * 8); sb[2] = (sbox[(byte)(sa[0] >> (2 * 8)) * 4]) << (2 * 8); sb[1] = (sbox[(byte)(sa[0] >> (3 * 8)) * 4]) << (3 * 8); sa[0] = rk[r][0] ^ sb[0]; sb[1] ^= (sbox[(byte)(sa[1] >> (0 * 8)) * 4]) << (0 * 8); sa[0] ^= (sbox[(byte)(sa[1] >> (1 * 8)) * 4]) << (1 * 8); sb[3] ^= (sbox[(byte)(sa[1] >> (2 * 8)) * 4]) << (2 * 8); sb[2] ^= (sbox[(byte)(sa[1] >> (3 * 8)) * 4]) << (3 * 8); sa[1] = rk[r][1] ^ sb[1]; sb[2] ^= (sbox[(byte)(sa[2] >> (0 * 8)) * 4]) << (0 * 8); sa[1] ^= (sbox[(byte)(sa[2] >> (1 * 8)) * 4]) << (1 * 8); sa[0] ^= (sbox[(byte)(sa[2] >> (2 * 8)) * 4]) << (2 * 8); sb[3] ^= (sbox[(byte)(sa[2] >> (3 * 8)) * 4]) << (3 * 8); sa[2] = rk[r][2] ^ sb[2]; sb[3] ^= (sbox[(byte)(sa[3] >> (0 * 8)) * 4]) << (0 * 8); sa[2] ^= (sbox[(byte)(sa[3] >> (1 * 8)) * 4]) << (1 * 8); sa[1] ^= (sbox[(byte)(sa[3] >> (2 * 8)) * 4]) << (2 * 8); sa[0] ^= (sbox[(byte)(sa[3] >> (3 * 8)) * 4]) << (3 * 8); sa[3] = rk[r][3] ^ sb[3]; buf_put_le32(b + 0, sa[0]); buf_put_le32(b + 4, sa[1]); buf_put_le32(b + 8, sa[2]); buf_put_le32(b + 12, sa[3]); #undef rk return (56 + 2*sizeof(int)); } #endif /*!USE_ARM_ASM && !USE_AMD64_ASM*/ static unsigned int do_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax) { #ifdef USE_AMD64_ASM return _gcry_aes_amd64_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds, encT); #elif defined(USE_ARM_ASM) return _gcry_aes_arm_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds, encT); #else return do_encrypt_fn (ctx, bx, ax); #endif /* !USE_ARM_ASM && !USE_AMD64_ASM*/ } static unsigned int rijndael_encrypt (void *context, byte *b, const byte *a) { RIJNDAEL_context *ctx = context; if (ctx->prefetch_enc_fn) ctx->prefetch_enc_fn(); return ctx->encrypt_fn (ctx, b, a); } /* Bulk encryption of complete blocks in CFB mode. Caller needs to make sure that IV is aligned on an unsigned long boundary. This function is only intended for the bulk encryption feature of cipher.c. */ void _gcry_aes_cfb_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned int burn_depth = 0; if (0) ; #ifdef USE_AESNI else if (ctx->use_aesni) { _gcry_aes_aesni_cfb_enc (ctx, iv, outbuf, inbuf, nblocks); return; } #endif /*USE_AESNI*/ #ifdef USE_SSSE3 else if (ctx->use_ssse3) { _gcry_aes_ssse3_cfb_enc (ctx, iv, outbuf, inbuf, nblocks); return; } #endif /*USE_SSSE3*/ #ifdef USE_ARM_CE else if (ctx->use_arm_ce) { _gcry_aes_armv8_ce_cfb_enc (ctx, iv, outbuf, inbuf, nblocks); return; } #endif /*USE_ARM_CE*/ else { rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; if (ctx->prefetch_enc_fn) ctx->prefetch_enc_fn(); for ( ;nblocks; nblocks-- ) { /* Encrypt the IV. */ burn_depth = encrypt_fn (ctx, iv, iv); /* XOR the input with the IV and store input into IV. */ cipher_block_xor_2dst(outbuf, iv, inbuf, BLOCKSIZE); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } } if (burn_depth) _gcry_burn_stack (burn_depth + 4 * sizeof(void *)); } /* Bulk encryption of complete blocks in CBC mode. Caller needs to make sure that IV is aligned on an unsigned long boundary. This function is only intended for the bulk encryption feature of cipher.c. */ void _gcry_aes_cbc_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int cbc_mac) { RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char *last_iv; unsigned int burn_depth = 0; if (0) ; #ifdef USE_AESNI else if (ctx->use_aesni) { _gcry_aes_aesni_cbc_enc (ctx, iv, outbuf, inbuf, nblocks, cbc_mac); return; } #endif /*USE_AESNI*/ #ifdef USE_SSSE3 else if (ctx->use_ssse3) { _gcry_aes_ssse3_cbc_enc (ctx, iv, outbuf, inbuf, nblocks, cbc_mac); return; } #endif /*USE_SSSE3*/ #ifdef USE_ARM_CE else if (ctx->use_arm_ce) { _gcry_aes_armv8_ce_cbc_enc (ctx, iv, outbuf, inbuf, nblocks, cbc_mac); return; } #endif /*USE_ARM_CE*/ else { rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; if (ctx->prefetch_enc_fn) ctx->prefetch_enc_fn(); last_iv = iv; for ( ;nblocks; nblocks-- ) { cipher_block_xor(outbuf, inbuf, last_iv, BLOCKSIZE); burn_depth = encrypt_fn (ctx, outbuf, outbuf); last_iv = outbuf; inbuf += BLOCKSIZE; if (!cbc_mac) outbuf += BLOCKSIZE; } if (last_iv != iv) cipher_block_cpy (iv, last_iv, BLOCKSIZE); } if (burn_depth) _gcry_burn_stack (burn_depth + 4 * sizeof(void *)); } /* Bulk encryption of complete blocks in CTR mode. Caller needs to make sure that CTR is aligned on a 16 byte boundary if AESNI; the minimum alignment is for an u32. This function is only intended for the bulk encryption feature of cipher.c. CTR is expected to be of size BLOCKSIZE. */ void _gcry_aes_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned int burn_depth = 0; int i; if (0) ; #ifdef USE_AESNI else if (ctx->use_aesni) { _gcry_aes_aesni_ctr_enc (ctx, ctr, outbuf, inbuf, nblocks); return; } #endif /*USE_AESNI*/ #ifdef USE_SSSE3 else if (ctx->use_ssse3) { _gcry_aes_ssse3_ctr_enc (ctx, ctr, outbuf, inbuf, nblocks); return; } #endif /*USE_SSSE3*/ #ifdef USE_ARM_CE else if (ctx->use_arm_ce) { _gcry_aes_armv8_ce_ctr_enc (ctx, ctr, outbuf, inbuf, nblocks); return; } #endif /*USE_ARM_CE*/ else { union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } tmp; rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; if (ctx->prefetch_enc_fn) ctx->prefetch_enc_fn(); for ( ;nblocks; nblocks-- ) { /* Encrypt the counter. */ burn_depth = encrypt_fn (ctx, tmp.x1, ctr); /* XOR the input with the encrypted counter and store in output. */ cipher_block_xor(outbuf, tmp.x1, inbuf, BLOCKSIZE); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; /* Increment the counter. */ for (i = BLOCKSIZE; i > 0; i--) { ctr[i-1]++; if (ctr[i-1]) break; } } wipememory(&tmp, sizeof(tmp)); } if (burn_depth) _gcry_burn_stack (burn_depth + 4 * sizeof(void *)); } #if !defined(USE_ARM_ASM) && !defined(USE_AMD64_ASM) /* Decrypt one block. A and B may be the same. */ static unsigned int do_decrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b, const unsigned char *a) { #define rk (ctx->keyschdec32) int rounds = ctx->rounds; int r; u32 sa[4]; u32 sb[4]; sb[0] = buf_get_le32(a + 0); sb[1] = buf_get_le32(a + 4); sb[2] = buf_get_le32(a + 8); sb[3] = buf_get_le32(a + 12); sa[0] = sb[0] ^ rk[rounds][0]; sa[1] = sb[1] ^ rk[rounds][1]; sa[2] = sb[2] ^ rk[rounds][2]; sa[3] = sb[3] ^ rk[rounds][3]; for (r = rounds - 1; r > 1; r--) { sb[0] = rol(decT[(byte)(sa[0] >> (0 * 8))], (0 * 8)); sb[1] = rol(decT[(byte)(sa[0] >> (1 * 8))], (1 * 8)); sb[2] = rol(decT[(byte)(sa[0] >> (2 * 8))], (2 * 8)); sb[3] = rol(decT[(byte)(sa[0] >> (3 * 8))], (3 * 8)); sa[0] = rk[r][0] ^ sb[0]; sb[1] ^= rol(decT[(byte)(sa[1] >> (0 * 8))], (0 * 8)); sb[2] ^= rol(decT[(byte)(sa[1] >> (1 * 8))], (1 * 8)); sb[3] ^= rol(decT[(byte)(sa[1] >> (2 * 8))], (2 * 8)); sa[0] ^= rol(decT[(byte)(sa[1] >> (3 * 8))], (3 * 8)); sa[1] = rk[r][1] ^ sb[1]; sb[2] ^= rol(decT[(byte)(sa[2] >> (0 * 8))], (0 * 8)); sb[3] ^= rol(decT[(byte)(sa[2] >> (1 * 8))], (1 * 8)); sa[0] ^= rol(decT[(byte)(sa[2] >> (2 * 8))], (2 * 8)); sa[1] ^= rol(decT[(byte)(sa[2] >> (3 * 8))], (3 * 8)); sa[2] = rk[r][2] ^ sb[2]; sb[3] ^= rol(decT[(byte)(sa[3] >> (0 * 8))], (0 * 8)); sa[0] ^= rol(decT[(byte)(sa[3] >> (1 * 8))], (1 * 8)); sa[1] ^= rol(decT[(byte)(sa[3] >> (2 * 8))], (2 * 8)); sa[2] ^= rol(decT[(byte)(sa[3] >> (3 * 8))], (3 * 8)); sa[3] = rk[r][3] ^ sb[3]; r--; sb[0] = rol(decT[(byte)(sa[0] >> (0 * 8))], (0 * 8)); sb[1] = rol(decT[(byte)(sa[0] >> (1 * 8))], (1 * 8)); sb[2] = rol(decT[(byte)(sa[0] >> (2 * 8))], (2 * 8)); sb[3] = rol(decT[(byte)(sa[0] >> (3 * 8))], (3 * 8)); sa[0] = rk[r][0] ^ sb[0]; sb[1] ^= rol(decT[(byte)(sa[1] >> (0 * 8))], (0 * 8)); sb[2] ^= rol(decT[(byte)(sa[1] >> (1 * 8))], (1 * 8)); sb[3] ^= rol(decT[(byte)(sa[1] >> (2 * 8))], (2 * 8)); sa[0] ^= rol(decT[(byte)(sa[1] >> (3 * 8))], (3 * 8)); sa[1] = rk[r][1] ^ sb[1]; sb[2] ^= rol(decT[(byte)(sa[2] >> (0 * 8))], (0 * 8)); sb[3] ^= rol(decT[(byte)(sa[2] >> (1 * 8))], (1 * 8)); sa[0] ^= rol(decT[(byte)(sa[2] >> (2 * 8))], (2 * 8)); sa[1] ^= rol(decT[(byte)(sa[2] >> (3 * 8))], (3 * 8)); sa[2] = rk[r][2] ^ sb[2]; sb[3] ^= rol(decT[(byte)(sa[3] >> (0 * 8))], (0 * 8)); sa[0] ^= rol(decT[(byte)(sa[3] >> (1 * 8))], (1 * 8)); sa[1] ^= rol(decT[(byte)(sa[3] >> (2 * 8))], (2 * 8)); sa[2] ^= rol(decT[(byte)(sa[3] >> (3 * 8))], (3 * 8)); sa[3] = rk[r][3] ^ sb[3]; } sb[0] = rol(decT[(byte)(sa[0] >> (0 * 8))], (0 * 8)); sb[1] = rol(decT[(byte)(sa[0] >> (1 * 8))], (1 * 8)); sb[2] = rol(decT[(byte)(sa[0] >> (2 * 8))], (2 * 8)); sb[3] = rol(decT[(byte)(sa[0] >> (3 * 8))], (3 * 8)); sa[0] = rk[1][0] ^ sb[0]; sb[1] ^= rol(decT[(byte)(sa[1] >> (0 * 8))], (0 * 8)); sb[2] ^= rol(decT[(byte)(sa[1] >> (1 * 8))], (1 * 8)); sb[3] ^= rol(decT[(byte)(sa[1] >> (2 * 8))], (2 * 8)); sa[0] ^= rol(decT[(byte)(sa[1] >> (3 * 8))], (3 * 8)); sa[1] = rk[1][1] ^ sb[1]; sb[2] ^= rol(decT[(byte)(sa[2] >> (0 * 8))], (0 * 8)); sb[3] ^= rol(decT[(byte)(sa[2] >> (1 * 8))], (1 * 8)); sa[0] ^= rol(decT[(byte)(sa[2] >> (2 * 8))], (2 * 8)); sa[1] ^= rol(decT[(byte)(sa[2] >> (3 * 8))], (3 * 8)); sa[2] = rk[1][2] ^ sb[2]; sb[3] ^= rol(decT[(byte)(sa[3] >> (0 * 8))], (0 * 8)); sa[0] ^= rol(decT[(byte)(sa[3] >> (1 * 8))], (1 * 8)); sa[1] ^= rol(decT[(byte)(sa[3] >> (2 * 8))], (2 * 8)); sa[2] ^= rol(decT[(byte)(sa[3] >> (3 * 8))], (3 * 8)); sa[3] = rk[1][3] ^ sb[3]; /* Last round is special. */ sb[0] = inv_sbox[(byte)(sa[0] >> (0 * 8))] << (0 * 8); sb[1] = inv_sbox[(byte)(sa[0] >> (1 * 8))] << (1 * 8); sb[2] = inv_sbox[(byte)(sa[0] >> (2 * 8))] << (2 * 8); sb[3] = inv_sbox[(byte)(sa[0] >> (3 * 8))] << (3 * 8); sa[0] = sb[0] ^ rk[0][0]; sb[1] ^= inv_sbox[(byte)(sa[1] >> (0 * 8))] << (0 * 8); sb[2] ^= inv_sbox[(byte)(sa[1] >> (1 * 8))] << (1 * 8); sb[3] ^= inv_sbox[(byte)(sa[1] >> (2 * 8))] << (2 * 8); sa[0] ^= inv_sbox[(byte)(sa[1] >> (3 * 8))] << (3 * 8); sa[1] = sb[1] ^ rk[0][1]; sb[2] ^= inv_sbox[(byte)(sa[2] >> (0 * 8))] << (0 * 8); sb[3] ^= inv_sbox[(byte)(sa[2] >> (1 * 8))] << (1 * 8); sa[0] ^= inv_sbox[(byte)(sa[2] >> (2 * 8))] << (2 * 8); sa[1] ^= inv_sbox[(byte)(sa[2] >> (3 * 8))] << (3 * 8); sa[2] = sb[2] ^ rk[0][2]; sb[3] ^= inv_sbox[(byte)(sa[3] >> (0 * 8))] << (0 * 8); sa[0] ^= inv_sbox[(byte)(sa[3] >> (1 * 8))] << (1 * 8); sa[1] ^= inv_sbox[(byte)(sa[3] >> (2 * 8))] << (2 * 8); sa[2] ^= inv_sbox[(byte)(sa[3] >> (3 * 8))] << (3 * 8); sa[3] = sb[3] ^ rk[0][3]; buf_put_le32(b + 0, sa[0]); buf_put_le32(b + 4, sa[1]); buf_put_le32(b + 8, sa[2]); buf_put_le32(b + 12, sa[3]); #undef rk return (56+2*sizeof(int)); } #endif /*!USE_ARM_ASM && !USE_AMD64_ASM*/ /* Decrypt one block. AX and BX may be the same. */ static unsigned int do_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax) { #ifdef USE_AMD64_ASM return _gcry_aes_amd64_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds, &dec_tables); #elif defined(USE_ARM_ASM) return _gcry_aes_arm_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds, &dec_tables); #else return do_decrypt_fn (ctx, bx, ax); #endif /*!USE_ARM_ASM && !USE_AMD64_ASM*/ } static inline void check_decryption_preparation (RIJNDAEL_context *ctx) { if ( !ctx->decryption_prepared ) { prepare_decryption ( ctx ); ctx->decryption_prepared = 1; } } static unsigned int rijndael_decrypt (void *context, byte *b, const byte *a) { RIJNDAEL_context *ctx = context; check_decryption_preparation (ctx); if (ctx->prefetch_dec_fn) ctx->prefetch_dec_fn(); return ctx->decrypt_fn (ctx, b, a); } /* Bulk decryption of complete blocks in CFB mode. Caller needs to make sure that IV is aligned on an unsigned long boundary. This function is only intended for the bulk encryption feature of cipher.c. */ void _gcry_aes_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned int burn_depth = 0; if (0) ; #ifdef USE_AESNI else if (ctx->use_aesni) { _gcry_aes_aesni_cfb_dec (ctx, iv, outbuf, inbuf, nblocks); return; } #endif /*USE_AESNI*/ #ifdef USE_SSSE3 else if (ctx->use_ssse3) { _gcry_aes_ssse3_cfb_dec (ctx, iv, outbuf, inbuf, nblocks); return; } #endif /*USE_SSSE3*/ #ifdef USE_ARM_CE else if (ctx->use_arm_ce) { _gcry_aes_armv8_ce_cfb_dec (ctx, iv, outbuf, inbuf, nblocks); return; } #endif /*USE_ARM_CE*/ else { rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; if (ctx->prefetch_enc_fn) ctx->prefetch_enc_fn(); for ( ;nblocks; nblocks-- ) { burn_depth = encrypt_fn (ctx, iv, iv); cipher_block_xor_n_copy(outbuf, iv, inbuf, BLOCKSIZE); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } } if (burn_depth) _gcry_burn_stack (burn_depth + 4 * sizeof(void *)); } /* Bulk decryption of complete blocks in CBC mode. Caller needs to make sure that IV is aligned on an unsigned long boundary. This function is only intended for the bulk encryption feature of cipher.c. */ void _gcry_aes_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned int burn_depth = 0; if (0) ; #ifdef USE_AESNI else if (ctx->use_aesni) { _gcry_aes_aesni_cbc_dec (ctx, iv, outbuf, inbuf, nblocks); return; } #endif /*USE_AESNI*/ #ifdef USE_SSSE3 else if (ctx->use_ssse3) { _gcry_aes_ssse3_cbc_dec (ctx, iv, outbuf, inbuf, nblocks); return; } #endif /*USE_SSSE3*/ #ifdef USE_ARM_CE else if (ctx->use_arm_ce) { _gcry_aes_armv8_ce_cbc_dec (ctx, iv, outbuf, inbuf, nblocks); return; } #endif /*USE_ARM_CE*/ else { unsigned char savebuf[BLOCKSIZE] ATTR_ALIGNED_16; rijndael_cryptfn_t decrypt_fn = ctx->decrypt_fn; check_decryption_preparation (ctx); if (ctx->prefetch_dec_fn) ctx->prefetch_dec_fn(); for ( ;nblocks; nblocks-- ) { /* INBUF is needed later and it may be identical to OUTBUF, so store the intermediate result to SAVEBUF. */ burn_depth = decrypt_fn (ctx, savebuf, inbuf); cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOCKSIZE); inbuf += BLOCKSIZE; outbuf += BLOCKSIZE; } wipememory(savebuf, sizeof(savebuf)); } if (burn_depth) _gcry_burn_stack (burn_depth + 4 * sizeof(void *)); } /* Bulk encryption/decryption of complete blocks in OCB mode. */ size_t _gcry_aes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt) { RIJNDAEL_context *ctx = (void *)&c->context.c; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned int burn_depth = 0; if (0) ; #ifdef USE_AESNI else if (ctx->use_aesni) { return _gcry_aes_aesni_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); } #endif /*USE_AESNI*/ #ifdef USE_SSSE3 else if (ctx->use_ssse3) { return _gcry_aes_ssse3_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); } #endif /*USE_SSSE3*/ #ifdef USE_ARM_CE else if (ctx->use_arm_ce) { return _gcry_aes_armv8_ce_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); } #endif /*USE_ARM_CE*/ else if (encrypt) { union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp; rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; if (ctx->prefetch_enc_fn) ctx->prefetch_enc_fn(); for ( ;nblocks; nblocks-- ) { u64 i = ++c->u_mode.ocb.data_nblocks; const unsigned char *l = ocb_get_l(c, i); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ cipher_block_xor_1 (c->u_iv.iv, l, BLOCKSIZE); cipher_block_cpy (l_tmp.x1, inbuf, BLOCKSIZE); /* Checksum_i = Checksum_{i-1} xor P_i */ cipher_block_xor_1 (c->u_ctr.ctr, l_tmp.x1, BLOCKSIZE); /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ cipher_block_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); burn_depth = encrypt_fn (ctx, l_tmp.x1, l_tmp.x1); cipher_block_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); cipher_block_cpy (outbuf, l_tmp.x1, BLOCKSIZE); inbuf += BLOCKSIZE; outbuf += BLOCKSIZE; } } else { union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp; rijndael_cryptfn_t decrypt_fn = ctx->decrypt_fn; check_decryption_preparation (ctx); if (ctx->prefetch_dec_fn) ctx->prefetch_dec_fn(); for ( ;nblocks; nblocks-- ) { u64 i = ++c->u_mode.ocb.data_nblocks; const unsigned char *l = ocb_get_l(c, i); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ cipher_block_xor_1 (c->u_iv.iv, l, BLOCKSIZE); cipher_block_cpy (l_tmp.x1, inbuf, BLOCKSIZE); /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ cipher_block_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); burn_depth = decrypt_fn (ctx, l_tmp.x1, l_tmp.x1); cipher_block_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); /* Checksum_i = Checksum_{i-1} xor P_i */ cipher_block_xor_1 (c->u_ctr.ctr, l_tmp.x1, BLOCKSIZE); cipher_block_cpy (outbuf, l_tmp.x1, BLOCKSIZE); inbuf += BLOCKSIZE; outbuf += BLOCKSIZE; } } if (burn_depth) _gcry_burn_stack (burn_depth + 4 * sizeof(void *)); return 0; } /* Bulk authentication of complete blocks in OCB mode. */ size_t _gcry_aes_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks) { RIJNDAEL_context *ctx = (void *)&c->context.c; const unsigned char *abuf = abuf_arg; unsigned int burn_depth = 0; if (0) ; #ifdef USE_AESNI else if (ctx->use_aesni) { return _gcry_aes_aesni_ocb_auth (c, abuf, nblocks); } #endif /*USE_AESNI*/ #ifdef USE_SSSE3 else if (ctx->use_ssse3) { return _gcry_aes_ssse3_ocb_auth (c, abuf, nblocks); } #endif /*USE_SSSE3*/ #ifdef USE_ARM_CE else if (ctx->use_arm_ce) { return _gcry_aes_armv8_ce_ocb_auth (c, abuf, nblocks); } #endif /*USE_ARM_CE*/ else { union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp; rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; if (ctx->prefetch_enc_fn) ctx->prefetch_enc_fn(); for ( ;nblocks; nblocks-- ) { u64 i = ++c->u_mode.ocb.aad_nblocks; const unsigned char *l = ocb_get_l(c, i); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, l, BLOCKSIZE); /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ cipher_block_xor (l_tmp.x1, c->u_mode.ocb.aad_offset, abuf, BLOCKSIZE); burn_depth = encrypt_fn (ctx, l_tmp.x1, l_tmp.x1); cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp.x1, BLOCKSIZE); abuf += BLOCKSIZE; } wipememory(&l_tmp, sizeof(l_tmp)); } if (burn_depth) _gcry_burn_stack (burn_depth + 4 * sizeof(void *)); return 0; } /* Bulk encryption/decryption of complete blocks in XTS mode. */ void _gcry_aes_xts_crypt (void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt) { RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned int burn_depth = 0; rijndael_cryptfn_t crypt_fn; u64 tweak_lo, tweak_hi, tweak_next_lo, tweak_next_hi, tmp_lo, tmp_hi, carry; if (0) ; #ifdef USE_AESNI else if (ctx->use_aesni) { _gcry_aes_aesni_xts_crypt (ctx, tweak, outbuf, inbuf, nblocks, encrypt); return; } #endif /*USE_AESNI*/ #ifdef USE_ARM_CE else if (ctx->use_arm_ce) { _gcry_aes_armv8_ce_xts_crypt (ctx, tweak, outbuf, inbuf, nblocks, encrypt); return; } #endif /*USE_ARM_CE*/ else { if (encrypt) { if (ctx->prefetch_enc_fn) ctx->prefetch_enc_fn(); crypt_fn = ctx->encrypt_fn; } else { check_decryption_preparation (ctx); if (ctx->prefetch_dec_fn) ctx->prefetch_dec_fn(); crypt_fn = ctx->decrypt_fn; } tweak_next_lo = buf_get_le64 (tweak + 0); tweak_next_hi = buf_get_le64 (tweak + 8); while (nblocks) { tweak_lo = tweak_next_lo; tweak_hi = tweak_next_hi; /* Xor-Encrypt/Decrypt-Xor block. */ tmp_lo = buf_get_le64 (inbuf + 0) ^ tweak_lo; tmp_hi = buf_get_le64 (inbuf + 8) ^ tweak_hi; buf_put_le64 (outbuf + 0, tmp_lo); buf_put_le64 (outbuf + 8, tmp_hi); /* Generate next tweak. */ carry = -(tweak_next_hi >> 63) & 0x87; tweak_next_hi = (tweak_next_hi << 1) + (tweak_next_lo >> 63); tweak_next_lo = (tweak_next_lo << 1) ^ carry; burn_depth = crypt_fn (ctx, outbuf, outbuf); buf_put_le64 (outbuf + 0, buf_get_le64 (outbuf + 0) ^ tweak_lo); buf_put_le64 (outbuf + 8, buf_get_le64 (outbuf + 8) ^ tweak_hi); outbuf += GCRY_XTS_BLOCK_LEN; inbuf += GCRY_XTS_BLOCK_LEN; nblocks--; } buf_put_le64 (tweak + 0, tweak_next_lo); buf_put_le64 (tweak + 8, tweak_next_hi); } if (burn_depth) _gcry_burn_stack (burn_depth + 5 * sizeof(void *)); } /* Run the self-tests for AES 128. Returns NULL on success. */ static const char* selftest_basic_128 (void) { RIJNDAEL_context *ctx; unsigned char *ctxmem; unsigned char scratch[16]; /* The test vectors are from the AES supplied ones; more or less randomly taken from ecb_tbl.txt (I=42,81,14) */ #if 1 static const unsigned char plaintext_128[16] = { 0x01,0x4B,0xAF,0x22,0x78,0xA6,0x9D,0x33, 0x1D,0x51,0x80,0x10,0x36,0x43,0xE9,0x9A }; static const unsigned char key_128[16] = { 0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF,0xF0, 0xF2,0xF3,0xF4,0xF5,0xF7,0xF8,0xF9,0xFA }; static const unsigned char ciphertext_128[16] = { 0x67,0x43,0xC3,0xD1,0x51,0x9A,0xB4,0xF2, 0xCD,0x9A,0x78,0xAB,0x09,0xA5,0x11,0xBD }; #else /* Test vectors from fips-197, appendix C. */ # warning debug test vectors in use static const unsigned char plaintext_128[16] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77, 0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff }; static const unsigned char key_128[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f /* 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, */ /* 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c */ }; static const unsigned char ciphertext_128[16] = { 0x69,0xc4,0xe0,0xd8,0x6a,0x7b,0x04,0x30, 0xd8,0xcd,0xb7,0x80,0x70,0xb4,0xc5,0x5a }; #endif /* Because gcc/ld can only align the CTX struct on 8 bytes on the stack, we need to allocate that context on the heap. */ ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem); if (!ctx) return "failed to allocate memory"; rijndael_setkey (ctx, key_128, sizeof (key_128), NULL); rijndael_encrypt (ctx, scratch, plaintext_128); if (memcmp (scratch, ciphertext_128, sizeof (ciphertext_128))) { xfree (ctxmem); return "AES-128 test encryption failed."; } rijndael_decrypt (ctx, scratch, scratch); xfree (ctxmem); if (memcmp (scratch, plaintext_128, sizeof (plaintext_128))) return "AES-128 test decryption failed."; return NULL; } /* Run the self-tests for AES 192. Returns NULL on success. */ static const char* selftest_basic_192 (void) { RIJNDAEL_context *ctx; unsigned char *ctxmem; unsigned char scratch[16]; static unsigned char plaintext_192[16] = { 0x76,0x77,0x74,0x75,0xF1,0xF2,0xF3,0xF4, 0xF8,0xF9,0xE6,0xE7,0x77,0x70,0x71,0x72 }; static unsigned char key_192[24] = { 0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C, 0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16, 0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20 }; static const unsigned char ciphertext_192[16] = { 0x5D,0x1E,0xF2,0x0D,0xCE,0xD6,0xBC,0xBC, 0x12,0x13,0x1A,0xC7,0xC5,0x47,0x88,0xAA }; ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem); if (!ctx) return "failed to allocate memory"; rijndael_setkey (ctx, key_192, sizeof(key_192), NULL); rijndael_encrypt (ctx, scratch, plaintext_192); if (memcmp (scratch, ciphertext_192, sizeof (ciphertext_192))) { xfree (ctxmem); return "AES-192 test encryption failed."; } rijndael_decrypt (ctx, scratch, scratch); xfree (ctxmem); if (memcmp (scratch, plaintext_192, sizeof (plaintext_192))) return "AES-192 test decryption failed."; return NULL; } /* Run the self-tests for AES 256. Returns NULL on success. */ static const char* selftest_basic_256 (void) { RIJNDAEL_context *ctx; unsigned char *ctxmem; unsigned char scratch[16]; static unsigned char plaintext_256[16] = { 0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21 }; static unsigned char key_256[32] = { 0x08,0x09,0x0A,0x0B,0x0D,0x0E,0x0F,0x10, 0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1A, 0x1C,0x1D,0x1E,0x1F,0x21,0x22,0x23,0x24, 0x26,0x27,0x28,0x29,0x2B,0x2C,0x2D,0x2E }; static const unsigned char ciphertext_256[16] = { 0x08,0x0E,0x95,0x17,0xEB,0x16,0x77,0x71, 0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3 }; ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem); if (!ctx) return "failed to allocate memory"; rijndael_setkey (ctx, key_256, sizeof(key_256), NULL); rijndael_encrypt (ctx, scratch, plaintext_256); if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256))) { xfree (ctxmem); return "AES-256 test encryption failed."; } rijndael_decrypt (ctx, scratch, scratch); xfree (ctxmem); if (memcmp (scratch, plaintext_256, sizeof (plaintext_256))) return "AES-256 test decryption failed."; return NULL; } /* Run the self-tests for AES-CTR-128, tests IV increment of bulk CTR encryption. Returns NULL on success. */ static const char* selftest_ctr_128 (void) { const int nblocks = 8+1; const int blocksize = BLOCKSIZE; const int context_size = sizeof(RIJNDAEL_context); return _gcry_selftest_helper_ctr("AES", &rijndael_setkey, &rijndael_encrypt, &_gcry_aes_ctr_enc, nblocks, blocksize, context_size); } /* Run the self-tests for AES-CBC-128, tests bulk CBC decryption. Returns NULL on success. */ static const char* selftest_cbc_128 (void) { const int nblocks = 8+2; const int blocksize = BLOCKSIZE; const int context_size = sizeof(RIJNDAEL_context); return _gcry_selftest_helper_cbc("AES", &rijndael_setkey, &rijndael_encrypt, &_gcry_aes_cbc_dec, nblocks, blocksize, context_size); } /* Run the self-tests for AES-CFB-128, tests bulk CFB decryption. Returns NULL on success. */ static const char* selftest_cfb_128 (void) { const int nblocks = 8+2; const int blocksize = BLOCKSIZE; const int context_size = sizeof(RIJNDAEL_context); return _gcry_selftest_helper_cfb("AES", &rijndael_setkey, &rijndael_encrypt, &_gcry_aes_cfb_dec, nblocks, blocksize, context_size); } /* Run all the self-tests and return NULL on success. This function is used for the on-the-fly self-tests. */ static const char * selftest (void) { const char *r; if ( (r = selftest_basic_128 ()) || (r = selftest_basic_192 ()) || (r = selftest_basic_256 ()) ) return r; if ( (r = selftest_ctr_128 ()) ) return r; if ( (r = selftest_cbc_128 ()) ) return r; if ( (r = selftest_cfb_128 ()) ) return r; return r; } /* SP800-38a.pdf for AES-128. */ static const char * selftest_fips_128_38a (int requested_mode) { static const struct tv { int mode; const unsigned char key[16]; const unsigned char iv[16]; struct { const unsigned char input[16]; const unsigned char output[16]; } data[4]; } tv[2] = { { GCRY_CIPHER_MODE_CFB, /* F.3.13, CFB128-AES128 */ { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, { { { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }, { 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a } }, { { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 }, { 0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f, 0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b } }, { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef }, { 0x26, 0x75, 0x1f, 0x67, 0xa3, 0xcb, 0xb1, 0x40, 0xb1, 0x80, 0x8c, 0xf1, 0x87, 0xa4, 0xf4, 0xdf } }, { { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, { 0xc0, 0x4b, 0x05, 0x35, 0x7c, 0x5d, 0x1c, 0x0e, 0xea, 0xc4, 0xc6, 0x6f, 0x9f, 0xf7, 0xf2, 0xe6 } } } }, { GCRY_CIPHER_MODE_OFB, { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, { { { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }, { 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a } }, { { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 }, { 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25 } }, { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef }, { 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc } }, { { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, { 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e } }, } } }; unsigned char scratch[16]; gpg_error_t err; int tvi, idx; gcry_cipher_hd_t hdenc = NULL; gcry_cipher_hd_t hddec = NULL; #define Fail(a) do { \ _gcry_cipher_close (hdenc); \ _gcry_cipher_close (hddec); \ return a; \ } while (0) gcry_assert (sizeof tv[0].data[0].input == sizeof scratch); gcry_assert (sizeof tv[0].data[0].output == sizeof scratch); for (tvi=0; tvi < DIM (tv); tvi++) if (tv[tvi].mode == requested_mode) break; if (tvi == DIM (tv)) Fail ("no test data for this mode"); err = _gcry_cipher_open (&hdenc, GCRY_CIPHER_AES, tv[tvi].mode, 0); if (err) Fail ("open"); err = _gcry_cipher_open (&hddec, GCRY_CIPHER_AES, tv[tvi].mode, 0); if (err) Fail ("open"); err = _gcry_cipher_setkey (hdenc, tv[tvi].key, sizeof tv[tvi].key); if (!err) err = _gcry_cipher_setkey (hddec, tv[tvi].key, sizeof tv[tvi].key); if (err) Fail ("set key"); err = _gcry_cipher_setiv (hdenc, tv[tvi].iv, sizeof tv[tvi].iv); if (!err) err = _gcry_cipher_setiv (hddec, tv[tvi].iv, sizeof tv[tvi].iv); if (err) Fail ("set IV"); for (idx=0; idx < DIM (tv[tvi].data); idx++) { err = _gcry_cipher_encrypt (hdenc, scratch, sizeof scratch, tv[tvi].data[idx].input, sizeof tv[tvi].data[idx].input); if (err) Fail ("encrypt command"); if (memcmp (scratch, tv[tvi].data[idx].output, sizeof scratch)) Fail ("encrypt mismatch"); err = _gcry_cipher_decrypt (hddec, scratch, sizeof scratch, tv[tvi].data[idx].output, sizeof tv[tvi].data[idx].output); if (err) Fail ("decrypt command"); if (memcmp (scratch, tv[tvi].data[idx].input, sizeof scratch)) Fail ("decrypt mismatch"); } #undef Fail _gcry_cipher_close (hdenc); _gcry_cipher_close (hddec); return NULL; } /* Complete selftest for AES-128 with all modes and driver code. */ static gpg_err_code_t selftest_fips_128 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; what = "low-level"; errtxt = selftest_basic_128 (); if (errtxt) goto failed; if (extended) { what = "cfb"; errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_CFB); if (errtxt) goto failed; what = "ofb"; errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_OFB); if (errtxt) goto failed; } return 0; /* Succeeded. */ failed: if (report) report ("cipher", GCRY_CIPHER_AES128, what, errtxt); return GPG_ERR_SELFTEST_FAILED; } /* Complete selftest for AES-192. */ static gpg_err_code_t selftest_fips_192 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; (void)extended; /* No extended tests available. */ what = "low-level"; errtxt = selftest_basic_192 (); if (errtxt) goto failed; return 0; /* Succeeded. */ failed: if (report) report ("cipher", GCRY_CIPHER_AES192, what, errtxt); return GPG_ERR_SELFTEST_FAILED; } /* Complete selftest for AES-256. */ static gpg_err_code_t selftest_fips_256 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; (void)extended; /* No extended tests available. */ what = "low-level"; errtxt = selftest_basic_256 (); if (errtxt) goto failed; return 0; /* Succeeded. */ failed: if (report) report ("cipher", GCRY_CIPHER_AES256, what, errtxt); return GPG_ERR_SELFTEST_FAILED; } /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; switch (algo) { case GCRY_CIPHER_AES128: ec = selftest_fips_128 (extended, report); break; case GCRY_CIPHER_AES192: ec = selftest_fips_192 (extended, report); break; case GCRY_CIPHER_AES256: ec = selftest_fips_256 (extended, report); break; default: ec = GPG_ERR_CIPHER_ALGO; break; } return ec; } static const char *rijndael_names[] = { "RIJNDAEL", "AES128", "AES-128", NULL }; static gcry_cipher_oid_spec_t rijndael_oids[] = { { "2.16.840.1.101.3.4.1.1", GCRY_CIPHER_MODE_ECB }, { "2.16.840.1.101.3.4.1.2", GCRY_CIPHER_MODE_CBC }, { "2.16.840.1.101.3.4.1.3", GCRY_CIPHER_MODE_OFB }, { "2.16.840.1.101.3.4.1.4", GCRY_CIPHER_MODE_CFB }, { NULL } }; gcry_cipher_spec_t _gcry_cipher_spec_aes = { GCRY_CIPHER_AES, {0, 1}, "AES", rijndael_names, rijndael_oids, 16, 128, sizeof (RIJNDAEL_context), rijndael_setkey, rijndael_encrypt, rijndael_decrypt, NULL, NULL, run_selftests }; static const char *rijndael192_names[] = { "RIJNDAEL192", "AES-192", NULL }; static gcry_cipher_oid_spec_t rijndael192_oids[] = { { "2.16.840.1.101.3.4.1.21", GCRY_CIPHER_MODE_ECB }, { "2.16.840.1.101.3.4.1.22", GCRY_CIPHER_MODE_CBC }, { "2.16.840.1.101.3.4.1.23", GCRY_CIPHER_MODE_OFB }, { "2.16.840.1.101.3.4.1.24", GCRY_CIPHER_MODE_CFB }, { NULL } }; gcry_cipher_spec_t _gcry_cipher_spec_aes192 = { GCRY_CIPHER_AES192, {0, 1}, "AES192", rijndael192_names, rijndael192_oids, 16, 192, sizeof (RIJNDAEL_context), rijndael_setkey, rijndael_encrypt, rijndael_decrypt, NULL, NULL, run_selftests }; static const char *rijndael256_names[] = { "RIJNDAEL256", "AES-256", NULL }; static gcry_cipher_oid_spec_t rijndael256_oids[] = { { "2.16.840.1.101.3.4.1.41", GCRY_CIPHER_MODE_ECB }, { "2.16.840.1.101.3.4.1.42", GCRY_CIPHER_MODE_CBC }, { "2.16.840.1.101.3.4.1.43", GCRY_CIPHER_MODE_OFB }, { "2.16.840.1.101.3.4.1.44", GCRY_CIPHER_MODE_CFB }, { NULL } }; gcry_cipher_spec_t _gcry_cipher_spec_aes256 = { GCRY_CIPHER_AES256, {0, 1}, "AES256", rijndael256_names, rijndael256_oids, 16, 256, sizeof (RIJNDAEL_context), rijndael_setkey, rijndael_encrypt, rijndael_decrypt, NULL, NULL, run_selftests }; diff --git a/tests/basic.c b/tests/basic.c index f3d89515..0afae304 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1,11712 +1,11932 @@ /* basic.c - basic regression tests * Copyright (C) 2001, 2002, 2003, 2005, 2008, * 2009 Free Software Foundation, Inc. * Copyright (C) 2013 g10 Code GmbH * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "../src/gcrypt-int.h" #define PGM "basic" #include "t-common.h" typedef struct test_spec_pubkey_key { const char *secret; const char *public; const char *grip; } test_spec_pubkey_key_t; typedef struct test_spec_pubkey { int id; int flags; test_spec_pubkey_key_t key; } test_spec_pubkey_t; #define FLAG_CRYPT (1 << 0) #define FLAG_SIGN (1 << 1) #define FLAG_GRIP (1 << 2) static int in_fips_mode; #define MAX_DATA_LEN 128 static void mismatch (const void *expected, size_t expectedlen, const void *computed, size_t computedlen) { const unsigned char *p; fprintf (stderr, "expected:"); for (p = expected; expectedlen; p++, expectedlen--) fprintf (stderr, " %02x", *p); fprintf (stderr, "\ncomputed:"); for (p = computed; computedlen; p++, computedlen--) fprintf (stderr, " %02x", *p); fprintf (stderr, "\n"); } /* Convert STRING consisting of hex characters into its binary representation and return it as an allocated buffer. The valid length of the buffer is returned at R_LENGTH. The string is delimited by end of string. The function terminates on error. */ static void * hex2buffer (const char *string, size_t *r_length) { const char *s; unsigned char *buffer; size_t length; buffer = xmalloc (strlen(string)/2+1); length = 0; for (s=string; *s; s +=2 ) { if (!hexdigitp (s) || !hexdigitp (s+1)) die ("invalid hex digits in \"%s\"\n", string); ((unsigned char*)buffer)[length++] = xtoi_2 (s); } *r_length = length; return buffer; } static void show_sexp (const char *prefix, gcry_sexp_t a) { char *buf; size_t size; if (prefix) fputs (prefix, stderr); size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); buf = gcry_xmalloc (size); gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); fprintf (stderr, "%.*s", (int)size, buf); gcry_free (buf); } static void show_note (const char *format, ...) { va_list arg_ptr; if (!verbose && getenv ("srcdir")) fputs (" ", stderr); /* To align above "PASS: ". */ else fprintf (stderr, "%s: ", PGM); va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); if (*format && format[strlen(format)-1] != '\n') putc ('\n', stderr); va_end (arg_ptr); } static void show_md_not_available (int algo) { static int list[100]; static int listlen; int i; if (!verbose && algo == GCRY_MD_MD2) return; /* Do not print the diagnostic for that one. */ for (i=0; i < listlen; i++) if (algo == list[i]) return; /* Note already printed. */ if (listlen < DIM (list)) list[listlen++] = algo; show_note ("hash algorithm %d not available - skipping tests", algo); } static void show_old_hmac_not_available (int algo) { static int list[100]; static int listlen; int i; if (!verbose && algo == GCRY_MD_MD2) return; /* Do not print the diagnostic for that one. */ for (i=0; i < listlen; i++) if (algo == list[i]) return; /* Note already printed. */ if (listlen < DIM (list)) list[listlen++] = algo; show_note ("hash algorithm %d for old HMAC API not available " "- skipping tests", algo); } static void show_mac_not_available (int algo) { static int list[100]; static int listlen; int i; if (!verbose && algo == GCRY_MD_MD2) return; /* Do not print the diagnostic for that one. */ for (i=0; i < listlen; i++) if (algo == list[i]) return; /* Note already printed. */ if (listlen < DIM (list)) list[listlen++] = algo; show_note ("MAC algorithm %d not available - skipping tests", algo); } void progress_handler (void *cb_data, const char *what, int printchar, int current, int total) { (void)cb_data; (void)what; (void)current; (void)total; if (printchar == '\n') fputs ( "", stdout); else putchar (printchar); fflush (stdout); } static void check_cbc_mac_cipher (void) { static const struct tv { int algo; char key[MAX_DATA_LEN]; unsigned char plaintext[MAX_DATA_LEN]; size_t plaintextlen; char mac[MAX_DATA_LEN]; } tv[] = { { GCRY_CIPHER_AES, "chicken teriyaki", "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", 0, "\x23\x8f\x6d\xc7\x53\x6a\x62\x97\x11\xc4\xa5\x16\x43\xea\xb0\xb6" }, { GCRY_CIPHER_3DES, "abcdefghABCDEFGH01234567", "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", 0, "\x5c\x11\xf0\x01\x47\xbd\x3d\x3a" }, { GCRY_CIPHER_DES, "abcdefgh", "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", 0, "\xfa\x4b\xdf\x9d\xfa\xab\x01\x70" } }; gcry_cipher_hd_t hd; unsigned char out[MAX_DATA_LEN]; int i, blklen, keylen; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting CBC MAC checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); continue; } err = gcry_cipher_open (&hd, tv[i].algo, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC); if (!hd) { fail ("cbc-mac algo %d, gcry_cipher_open failed: %s\n", tv[i].algo, gpg_strerror (err)); return; } blklen = gcry_cipher_get_algo_blklen(tv[i].algo); if (!blklen) { fail ("cbc-mac algo %d, gcry_cipher_get_algo_blklen failed\n", tv[i].algo); gcry_cipher_close (hd); return; } keylen = gcry_cipher_get_algo_keylen (tv[i].algo); if (!keylen) { fail ("cbc-mac algo %d, gcry_cipher_get_algo_keylen failed\n", tv[i].algo); return; } err = gcry_cipher_setkey (hd, tv[i].key, keylen); if (err) { fail ("cbc-mac algo %d, gcry_cipher_setkey failed: %s\n", tv[i].algo, gpg_strerror (err)); gcry_cipher_close (hd); return; } err = gcry_cipher_setiv (hd, NULL, 0); if (err) { fail ("cbc-mac algo %d, gcry_cipher_setiv failed: %s\n", tv[i].algo, gpg_strerror (err)); gcry_cipher_close (hd); return; } if (verbose) fprintf (stderr, " checking CBC MAC for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); err = gcry_cipher_encrypt (hd, out, blklen, tv[i].plaintext, tv[i].plaintextlen ? tv[i].plaintextlen : strlen ((char*)tv[i].plaintext)); if (err) { fail ("cbc-mac algo %d, gcry_cipher_encrypt failed: %s\n", tv[i].algo, gpg_strerror (err)); gcry_cipher_close (hd); return; } #if 0 { int j; for (j = 0; j < gcry_cipher_get_algo_blklen (tv[i].algo); j++) printf ("\\x%02x", out[j] & 0xFF); printf ("\n"); } #endif if (memcmp (tv[i].mac, out, blklen)) fail ("cbc-mac algo %d, encrypt mismatch entry %d\n", tv[i].algo, i); gcry_cipher_close (hd); } if (verbose) fprintf (stderr, " Completed CBC MAC checks.\n"); } static void check_aes128_cbc_cts_cipher (void) { static const char key[128 / 8] = "chicken teriyaki"; static const unsigned char plaintext[] = "I would like the General Gau's Chicken, please, and wonton soup."; static const struct tv { unsigned char out[MAX_DATA_LEN]; int inlen; } tv[] = { { "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f" "\x97", 17 }, { "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22" "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5", 31 }, { "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84", 32 }, { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e" "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5", 47 }, { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8" "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8", 48 }, { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" "\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40" "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8", 64 }, }; gcry_cipher_hd_t hd; unsigned char out[MAX_DATA_LEN]; int i; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting AES128 CBC CTS checks.\n"); err = gcry_cipher_open (&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS); if (err) { fail ("aes-cbc-cts, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } err = gcry_cipher_setkey (hd, key, 128 / 8); if (err) { fail ("aes-cbc-cts, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); return; } for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { err = gcry_cipher_setiv (hd, NULL, 0); if (err) { fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); return; } if (verbose) fprintf (stderr, " checking encryption for length %i\n", tv[i].inlen); err = gcry_cipher_encrypt (hd, out, MAX_DATA_LEN, plaintext, tv[i].inlen); if (err) { fail ("aes-cbc-cts, gcry_cipher_encrypt failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); return; } if (memcmp (tv[i].out, out, tv[i].inlen)) fail ("aes-cbc-cts, encrypt mismatch entry %d\n", i); err = gcry_cipher_setiv (hd, NULL, 0); if (err) { fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); return; } if (verbose) fprintf (stderr, " checking decryption for length %i\n", tv[i].inlen); err = gcry_cipher_decrypt (hd, out, tv[i].inlen, NULL, 0); if (err) { fail ("aes-cbc-cts, gcry_cipher_decrypt failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); return; } if (memcmp (plaintext, out, tv[i].inlen)) fail ("aes-cbc-cts, decrypt mismatch entry %d\n", i); } gcry_cipher_close (hd); if (verbose) fprintf (stderr, " Completed AES128 CBC CTS checks.\n"); } static void check_ctr_cipher (void) { static const struct tv { int algo; char key[MAX_DATA_LEN]; char ctr[MAX_DATA_LEN]; struct data { unsigned char plaintext[MAX_DATA_LEN]; int inlen; char out[MAX_DATA_LEN]; } data[8]; } tv[] = { /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */ { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd\xff" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" }, { "", 0, "" } } }, { GCRY_CIPHER_AES192, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b" "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x1a\xbc\x93\x24\x17\x52\x1c\xa2\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x09\x03\x39\xec\x0a\xa6\xfa\xef\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70\xd1\xbd\x1d\x66\x56\x20\xab\xf7" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x4f\x78\xa7\xf6\xd2\x98\x09\x58\x5a\x97\xda\xec\x58\xc6\xb0\x50" }, { "", 0, "" } } }, { GCRY_CIPHER_AES256, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x60\x1e\xc3\x13\x77\x57\x89\xa5\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a\xca\x84\xe9\x90\xca\xca\xf5\xc5" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c\xe8\x70\x17\xba\x2d\x84\x98\x8d" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd\x08\x45\x79\x41\xa6" }, { "", 0, "" } } }, /* Some truncation tests. With a truncated second block and also with a single truncated block. */ { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e", 15, "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd" }, {"", 0, "" } } }, { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, {"\xae", 1, "\x98" }, {"", 0, "" } } }, { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17", 15, "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6" }, {"", 0, "" } } }, { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", {{"\x6b", 1, "\x87" }, {"", 0, "" } } }, /* Tests to see whether it works correctly as a stream cipher. */ { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e", 15, "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd" }, {"\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 17, "\xff\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" }, {"\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" }, { "", 0, "" } } }, { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", {{"\x6b", 1, "\x87" }, {"\xc1\xbe", 2, "\x4d\x61" }, {"\xe2\x2e\x40", 3, "\x91\xb6\x20" }, {"\x9f", 1, "\xe3" }, {"\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 9, "\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e", 15, "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd" }, {"\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 9, "\xff\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e" }, { "", 0, "" } } }, #if USE_CAST5 /* A selfmade test vector using an 64 bit block cipher. */ { GCRY_CIPHER_CAST5, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8", {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\xe8\xa7\xac\x68\xca\xca\xa0\x20\x10\xcb\x1b\xcc\x79\x2c\xc4\x48" }, {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c", 8, "\x16\xe8\x72\x77\xb0\x98\x29\x68" }, {"\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 8, "\x9a\xb3\xa8\x03\x3b\xb4\x14\xba" }, {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\xa1\x00", 10, "\x31\x5e\xd3\xfb\x1b\x8d\xd1\xf9\xb0\x83" }, { "", 0, "" } } }, #endif /*USE_CAST5*/ { 0, "", "", { {"", 0, "" } } } }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; int i, j, keylen, blklen; gcry_error_t err = 0; size_t taglen2; if (verbose) fprintf (stderr, " Starting CTR cipher checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (!tv[i].algo) continue; if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); continue; } err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); if (err) { fail ("aes-ctr, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("aes-ctr, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("aes-ctr, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } blklen = gcry_cipher_get_algo_blklen(tv[i].algo); if (!blklen) { fail ("aes-ctr, gcry_cipher_get_algo_blklen failed\n"); return; } err = gcry_cipher_setctr (hde, tv[i].ctr, blklen); if (!err) err = gcry_cipher_setctr (hdd, tv[i].ctr, blklen); if (err) { fail ("aes-ctr, gcry_cipher_setctr failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2); if (gpg_err_code (err) != GPG_ERR_INV_CIPHER_MODE) { fail ("aes-ctr, gcryctl_get_taglen failed to fail (tv %d): %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (verbose) fprintf (stderr, " checking CTR mode for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); for (j = 0; tv[i].data[j].inlen; j++) { err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].data[j].plaintext, tv[i].data[j].inlen == -1 ? strlen ((char*)tv[i].data[j].plaintext) : tv[i].data[j].inlen); if (err) { fail ("aes-ctr, gcry_cipher_encrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) { fail ("aes-ctr, encrypt mismatch entry %d:%d\n", i, j); mismatch (tv[i].data[j].out, tv[i].data[j].inlen, out, tv[i].data[j].inlen); } err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0); if (err) { fail ("aes-ctr, gcry_cipher_decrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) { fail ("aes-ctr, decrypt mismatch entry %d:%d\n", i, j); mismatch (tv[i].data[j].plaintext, tv[i].data[j].inlen, out, tv[i].data[j].inlen); } } /* Now check that we get valid return codes back for good and bad inputs. */ err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, "1234567890123456", 16); if (err) fail ("aes-ctr, encryption failed for valid input"); err = gcry_cipher_encrypt (hde, out, 15, "1234567890123456", 16); if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT) fail ("aes-ctr, too short output buffer returned wrong error: %s\n", gpg_strerror (err)); err = gcry_cipher_encrypt (hde, out, 0, "1234567890123456", 16); if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT) fail ("aes-ctr, 0 length output buffer returned wrong error: %s\n", gpg_strerror (err)); err = gcry_cipher_encrypt (hde, out, 16, "1234567890123456", 16); if (err) fail ("aes-ctr, correct length output buffer returned error: %s\n", gpg_strerror (err)); /* Again, now for decryption. */ err = gcry_cipher_decrypt (hde, out, MAX_DATA_LEN, "1234567890123456", 16); if (err) fail ("aes-ctr, decryption failed for valid input"); err = gcry_cipher_decrypt (hde, out, 15, "1234567890123456", 16); if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT) fail ("aes-ctr, too short output buffer returned wrong error: %s\n", gpg_strerror (err)); err = gcry_cipher_decrypt (hde, out, 0, "1234567890123456", 16); if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT) fail ("aes-ctr, 0 length output buffer returned wrong error: %s\n", gpg_strerror (err)); err = gcry_cipher_decrypt (hde, out, 16, "1234567890123456", 16); if (err) fail ("aes-ctr, correct length output buffer returned error: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed CTR cipher checks.\n"); } static void check_cfb_cipher (void) { static const struct tv { int algo; int cfb8; char key[MAX_DATA_LEN]; char iv[MAX_DATA_LEN]; struct data { unsigned char plaintext[MAX_DATA_LEN]; int inlen; char out[MAX_DATA_LEN]; } data[MAX_DATA_LEN]; } tv[] = { /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */ { GCRY_CIPHER_AES, 0, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\xc8\xa6\x45\x37\xa0\xb3\xa9\x3f\xcd\xe3\xcd\xad\x9f\x1c\xe5\x8b"}, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x26\x75\x1f\x67\xa3\xcb\xb1\x40\xb1\x80\x8c\xf1\x87\xa4\xf4\xdf" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\xc0\x4b\x05\x35\x7c\x5d\x1c\x0e\xea\xc4\xc6\x6f\x9f\xf7\xf2\xe6" }, } }, { GCRY_CIPHER_AES192, 0, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b" "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x67\xce\x7f\x7f\x81\x17\x36\x21\x96\x1a\x2b\x70\x17\x1d\x3d\x7a" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x2e\x1e\x8a\x1d\xd5\x9b\x88\xb1\xc8\xe6\x0f\xed\x1e\xfa\xc4\xc9" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\xc0\x5f\x9f\x9c\xa9\x83\x4f\xa0\x42\xae\x8f\xba\x58\x4b\x09\xff" }, } }, { GCRY_CIPHER_AES256, 0, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x39\xff\xed\x14\x3b\x28\xb1\xc8\x32\x11\x3c\x63\x31\xe5\x40\x7b" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\xdf\x10\x13\x24\x15\xe5\x4b\x92\xa1\x3e\xd0\xa8\x26\x7a\xe2\xf9" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x75\xa3\x85\x74\x1a\xb9\xce\xf8\x20\x31\x62\x3d\x55\xb1\xe4\x71" } } }, { GCRY_CIPHER_AES, 1, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b", 1, "\x3b"}, { "\xc1", 1, "\x79"}, { "\xbe", 1, "\x42"}, { "\xe2", 1, "\x4c"}, } }, { GCRY_CIPHER_AES192, 1, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5" "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b", 1, "\xcd"}, { "\xc1", 1, "\xa2"}, { "\xbe", 1, "\x52"}, { "\xe2", 1, "\x1e"}, } }, { GCRY_CIPHER_AES256, 1, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b", 1, "\xdc"}, { "\xc1", 1, "\x1f"}, { "\xbe", 1, "\x1a"}, { "\xe2", 1, "\x85"}, } }, { GCRY_CIPHER_AES, 1, "\x3a\x6f\x91\x59\x26\x3f\xa6\xce\xf2\xa0\x75\xca\xfa\xce\x58\x17", "\x0f\xc2\x36\x62\xb7\xdb\xf7\x38\x27\xf0\xc7\xde\x32\x1c\xa3\x6e", { { "\x87\xef\xeb\x8d\x55\x9e\xd3\x36\x77\x28", 10, "\x8e\x9c\x50\x42\x56\x14\xd5\x40\xce\x11"}, } }, { GCRY_CIPHER_AES192, 1, "\x53\x7e\x7b\xf6\x61\xfd\x40\x24\xa0\x24\x61\x3f\x15\xb1\x36\x90" "\xf7\xd0\xc8\x47\xc1\xe1\x89\x65", "\x3a\x81\xf9\xd9\xd3\xc1\x55\xb0\xca\xad\x5d\x73\x34\x94\x76\xfc", { { "\xd3\xd8\xb9\xb9\x84\xad\xc2\x42\x37\xee", 10, "\x38\x79\xfe\xa7\x2a\xc9\x99\x29\xe5\x3a"}, } }, { GCRY_CIPHER_AES256, 1, "\xeb\xbb\x45\x66\xb5\xe1\x82\xe0\xf0\x72\x46\x6b\x0b\x31\x1d\xf3" "\x8f\x91\x75\xbc\x02\x13\xa5\x53\x0b\xce\x2e\xc4\xd7\x4f\x40\x0d", "\x09\x56\xa4\x8e\x01\x00\x2c\x9e\x16\x37\x6d\x6e\x30\x8d\xba\xd1", { { "\xb0\xfe\x25\xac\x8d\x3d\x28\xa2\xf4\x71", 10, "\x63\x8c\x68\x23\xe7\x25\x6f\xb5\x62\x6e"}, } }, { GCRY_CIPHER_3DES, 1, "\xe3\x34\x7a\x6b\x0b\xc1\x15\x2c\x64\x2a\x25\xcb\xd3\xbc\x31\xab" "\xfb\xa1\x62\xa8\x1f\x19\x7c\x15", "\xb7\x40\xcc\x21\xe9\x25\xe3\xc8", { { "\xdb\xe9\x15\xfc\xb3\x3b\xca\x18\xef\x14", 10, "\xf4\x80\x1a\x8d\x03\x9d\xb4\xca\x8f\xf6"}, } }, { GCRY_CIPHER_3DES, 1, "\x7c\xa2\x89\x38\xba\x6b\xec\x1f\xfe\xc7\x8f\x7c\xd6\x97\x61\x94" "\x7c\xa2\x89\x38\xba\x6b\xec\x1f", "\x95\x38\x96\x58\x6e\x49\xd3\x8f", { { "\x2e\xa9\x56\xd4\xa2\x11\xdb\x68\x59\xb7", 10, "\xf2\x0e\x53\x66\x74\xa6\x6f\xa7\x38\x05"}, } }, }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; int i, j, keylen, blklen, mode; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting CFB checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); continue; } mode = tv[i].cfb8? GCRY_CIPHER_MODE_CFB8 : GCRY_CIPHER_MODE_CFB; if (verbose) fprintf (stderr, " checking CFB mode for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); err = gcry_cipher_open (&hde, tv[i].algo, mode, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, mode, 0); if (err) { fail ("aes-cfb, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("aes-cfb, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("aes-cfb, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } blklen = gcry_cipher_get_algo_blklen(tv[i].algo); if (!blklen) { fail ("aes-cfb, gcry_cipher_get_algo_blklen failed\n"); return; } err = gcry_cipher_setiv (hde, tv[i].iv, blklen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, blklen); if (err) { fail ("aes-cfb, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } for (j = 0; tv[i].data[j].inlen; j++) { err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].data[j].plaintext, tv[i].data[j].inlen); if (err) { fail ("aes-cfb, gcry_cipher_encrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) { fail ("aes-cfb, encrypt mismatch entry %d:%d\n", i, j); } err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0); if (err) { fail ("aes-cfb, gcry_cipher_decrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) fail ("aes-cfb, decrypt mismatch entry %d:%d\n", i, j); } gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed CFB checks.\n"); } static void check_ofb_cipher (void) { static const struct tv { int algo; char key[MAX_DATA_LEN]; char iv[MAX_DATA_LEN]; struct data { unsigned char plaintext[MAX_DATA_LEN]; unsigned int inlen; char out[MAX_DATA_LEN]; } data[MAX_DATA_LEN]; } tv[] = { /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */ { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x77\x89\x50\x8d\x16\x91\x8f\x03\xf5\x3c\x52\xda\xc5\x4e\xd8\x25"}, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x97\x40\x05\x1e\x9c\x5f\xec\xf6\x43\x44\xf7\xa8\x22\x60\xed\xcc" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x30\x4c\x65\x28\xf6\x59\xc7\x78\x66\xa5\x10\xd9\xc1\xd6\xae\x5e" }, } }, { GCRY_CIPHER_AES192, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b" "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\xfc\xc2\x8b\x8d\x4c\x63\x83\x7c\x09\xe8\x17\x00\xc1\x10\x04\x01" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x8d\x9a\x9a\xea\xc0\xf6\x59\x6f\x55\x9c\x6d\x4d\xaf\x59\xa5\xf2" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x6d\x9f\x20\x08\x57\xca\x6c\x3e\x9c\xac\x52\x4b\xd9\xac\xc9\x2a" }, } }, { GCRY_CIPHER_AES256, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x4f\xeb\xdc\x67\x40\xd2\x0b\x3a\xc8\x8f\x6a\xd8\x2a\x4f\xb0\x8d" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x71\xab\x47\xa0\x86\xe8\x6e\xed\xf3\x9d\x1c\x5b\xba\x97\xc4\x08" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x01\x26\x14\x1d\x67\xf3\x7b\xe8\x53\x8f\x5a\x8b\xe7\x40\xe4\x84" } } } }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; int i, j, keylen, blklen; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting OFB checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); continue; } if (verbose) fprintf (stderr, " checking OFB mode for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_OFB, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_OFB, 0); if (err) { fail ("aes-ofb, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("aes-ofb, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("aes-ofb, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } blklen = gcry_cipher_get_algo_blklen(tv[i].algo); if (!blklen) { fail ("aes-ofb, gcry_cipher_get_algo_blklen failed\n"); return; } err = gcry_cipher_setiv (hde, tv[i].iv, blklen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, blklen); if (err) { fail ("aes-ofb, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } for (j = 0; tv[i].data[j].inlen; j++) { err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].data[j].plaintext, tv[i].data[j].inlen); if (err) { fail ("aes-ofb, gcry_cipher_encrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) fail ("aes-ofb, encrypt mismatch entry %d:%d\n", i, j); err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0); if (err) { fail ("aes-ofb, gcry_cipher_decrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) fail ("aes-ofb, decrypt mismatch entry %d:%d\n", i, j); } err = gcry_cipher_reset(hde); if (!err) err = gcry_cipher_reset(hdd); if (err) { fail ("aes-ofb, gcry_cipher_reset (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* gcry_cipher_reset clears the IV */ err = gcry_cipher_setiv (hde, tv[i].iv, blklen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, blklen); if (err) { fail ("aes-ofb, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* this time we encrypt and decrypt one byte at a time */ for (j = 0; tv[i].data[j].inlen; j++) { int byteNum; for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum) { err = gcry_cipher_encrypt (hde, out+byteNum, 1, (tv[i].data[j].plaintext) + byteNum, 1); if (err) { fail ("aes-ofb, gcry_cipher_encrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) fail ("aes-ofb, encrypt mismatch entry %d:%d\n", i, j); for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum) { err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0); if (err) { fail ("aes-ofb, gcry_cipher_decrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) fail ("aes-ofb, decrypt mismatch entry %d:%d\n", i, j); } gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed OFB checks.\n"); } static void _check_gcm_cipher (unsigned int step) { #define MAX_GCM_DATA_LEN (256 + 32) static const struct tv { int algo; char key[MAX_DATA_LEN]; char iv[MAX_DATA_LEN]; int ivlen; unsigned char aad[MAX_DATA_LEN]; int aadlen; unsigned char plaintext[MAX_GCM_DATA_LEN]; int inlen; char out[MAX_GCM_DATA_LEN]; char tag[MAX_DATA_LEN]; int taglen; int should_fail; } tv[] = { /* http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf */ { GCRY_CIPHER_AES, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "", 0, "", 0, "", "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7\x45\x5a" }, { GCRY_CIPHER_AES, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "", 0, "", 0, "", "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7\x45", 15 }, { GCRY_CIPHER_AES, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "", 0, "", 0, "", "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7", 14 }, { GCRY_CIPHER_AES, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "", 0, "", 0, "", "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4", 13 }, { GCRY_CIPHER_AES, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "", 0, "", 0, "", "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57", 12 }, { GCRY_CIPHER_AES, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "", 0, "", 0, "", "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d", 11, 1 }, { GCRY_CIPHER_AES, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "", 0, "", 0, "", "\x58\xe2\xfc\xce\xfa\x7e\x30\x61", 8 }, { GCRY_CIPHER_AES, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "", 0, "", 0, "", "\x58\xe2\xfc\xce", 4 }, { GCRY_CIPHER_AES, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "", 0, "", 0, "", "\x58", 1, 1 }, { GCRY_CIPHER_AES, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, "\x03\x88\xda\xce\x60\xb6\xa3\x92\xf3\x28\xc2\xb9\x71\xb2\xfe\x78", "\xab\x6e\x47\xd4\x2c\xec\x13\xbd\xf5\x3a\x67\xb2\x12\x57\xbd\xdf" }, { GCRY_CIPHER_AES, "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08", "\xca\xfe\xba\xbe\xfa\xce\xdb\xad\xde\xca\xf8\x88", 12, "", 0, "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39\x1a\xaf\xd2\x55", 64, "\x42\x83\x1e\xc2\x21\x77\x74\x24\x4b\x72\x21\xb7\x84\xd0\xd4\x9c" "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0\x35\xc1\x7e\x23\x29\xac\xa1\x2e" "\x21\xd5\x14\xb2\x54\x66\x93\x1c\x7d\x8f\x6a\x5a\xac\x84\xaa\x05" "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97\x3d\x58\xe0\x91\x47\x3f\x59\x85", "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4" }, { GCRY_CIPHER_AES, "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08", "\xca\xfe\xba\xbe\xfa\xce\xdb\xad\xde\xca\xf8\x88", 12, "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef" "\xab\xad\xda\xd2", 20, "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39", 60, "\x42\x83\x1e\xc2\x21\x77\x74\x24\x4b\x72\x21\xb7\x84\xd0\xd4\x9c" "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0\x35\xc1\x7e\x23\x29\xac\xa1\x2e" "\x21\xd5\x14\xb2\x54\x66\x93\x1c\x7d\x8f\x6a\x5a\xac\x84\xaa\x05" "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97\x3d\x58\xe0\x91\x47\x3f\x59\x85", "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb\x94\xfa\xe9\x5a\xe7\x12\x1a\x47" }, { GCRY_CIPHER_AES, "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08", "\xca\xfe\xba\xbe\xfa\xce\xdb\xad", 8, "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef" "\xab\xad\xda\xd2", 20, "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39", 60, "\x61\x35\x3b\x4c\x28\x06\x93\x4a\x77\x7f\xf5\x1f\xa2\x2a\x47\x55" "\x69\x9b\x2a\x71\x4f\xcd\xc6\xf8\x37\x66\xe5\xf9\x7b\x6c\x74\x23" "\x73\x80\x69\x00\xe4\x9f\x24\xb2\x2b\x09\x75\x44\xd4\x89\x6b\x42" "\x49\x89\xb5\xe1\xeb\xac\x0f\x07\xc2\x3f\x45\x98", "\x36\x12\xd2\xe7\x9e\x3b\x07\x85\x56\x1b\xe1\x4a\xac\xa2\xfc\xcb" }, { GCRY_CIPHER_AES, "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08", "\x93\x13\x22\x5d\xf8\x84\x06\xe5\x55\x90\x9c\x5a\xff\x52\x69\xaa" "\x6a\x7a\x95\x38\x53\x4f\x7d\xa1\xe4\xc3\x03\xd2\xa3\x18\xa7\x28" "\xc3\xc0\xc9\x51\x56\x80\x95\x39\xfc\xf0\xe2\x42\x9a\x6b\x52\x54" "\x16\xae\xdb\xf5\xa0\xde\x6a\x57\xa6\x37\xb3\x9b", 60, "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef" "\xab\xad\xda\xd2", 20, "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39", 60, "\x8c\xe2\x49\x98\x62\x56\x15\xb6\x03\xa0\x33\xac\xa1\x3f\xb8\x94" "\xbe\x91\x12\xa5\xc3\xa2\x11\xa8\xba\x26\x2a\x3c\xca\x7e\x2c\xa7" "\x01\xe4\xa9\xa4\xfb\xa4\x3c\x90\xcc\xdc\xb2\x81\xd4\x8c\x7c\x6f" "\xd6\x28\x75\xd2\xac\xa4\x17\x03\x4c\x34\xae\xe5", "\x61\x9c\xc5\xae\xff\xfe\x0b\xfa\x46\x2a\xf4\x3c\x16\x99\xd0\x50" }, { GCRY_CIPHER_AES192, "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" "\xfe\xff\xe9\x92\x86\x65\x73\x1c", "\x93\x13\x22\x5d\xf8\x84\x06\xe5\x55\x90\x9c\x5a\xff\x52\x69\xaa" "\x6a\x7a\x95\x38\x53\x4f\x7d\xa1\xe4\xc3\x03\xd2\xa3\x18\xa7\x28" "\xc3\xc0\xc9\x51\x56\x80\x95\x39\xfc\xf0\xe2\x42\x9a\x6b\x52\x54" "\x16\xae\xdb\xf5\xa0\xde\x6a\x57\xa6\x37\xb3\x9b", 60, "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef" "\xab\xad\xda\xd2", 20, "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39", 60, "\xd2\x7e\x88\x68\x1c\xe3\x24\x3c\x48\x30\x16\x5a\x8f\xdc\xf9\xff" "\x1d\xe9\xa1\xd8\xe6\xb4\x47\xef\x6e\xf7\xb7\x98\x28\x66\x6e\x45" "\x81\xe7\x90\x12\xaf\x34\xdd\xd9\xe2\xf0\x37\x58\x9b\x29\x2d\xb3" "\xe6\x7c\x03\x67\x45\xfa\x22\xe7\xe9\xb7\x37\x3b", "\xdc\xf5\x66\xff\x29\x1c\x25\xbb\xb8\x56\x8f\xc3\xd3\x76\xa6\xd9" }, { GCRY_CIPHER_AES256, "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08", "\x93\x13\x22\x5d\xf8\x84\x06\xe5\x55\x90\x9c\x5a\xff\x52\x69\xaa" "\x6a\x7a\x95\x38\x53\x4f\x7d\xa1\xe4\xc3\x03\xd2\xa3\x18\xa7\x28" "\xc3\xc0\xc9\x51\x56\x80\x95\x39\xfc\xf0\xe2\x42\x9a\x6b\x52\x54" "\x16\xae\xdb\xf5\xa0\xde\x6a\x57\xa6\x37\xb3\x9b", 60, "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef" "\xab\xad\xda\xd2", 20, "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39", 60, "\x5a\x8d\xef\x2f\x0c\x9e\x53\xf1\xf7\x5d\x78\x53\x65\x9e\x2a\x20" "\xee\xb2\xb2\x2a\xaf\xde\x64\x19\xa0\x58\xab\x4f\x6f\x74\x6b\xf4" "\x0f\xc0\xc3\xb7\x80\xf2\x44\x45\x2d\xa3\xeb\xf1\xc5\xd8\x2c\xde" "\xa2\x41\x89\x97\x20\x0e\xf8\x2e\x44\xae\x7e\x3f", "\xa4\x4a\x82\x66\xee\x1c\x8e\xb0\xc8\xb5\xd4\xcf\x5a\xe9\xf1\x9a" }, /* Test vectors for overflowing CTR. */ /* After setiv, ctr_low: 0xffffffff */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\xdd\x40\xe7", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x7d\x6e\x38\xfd\xd0\x04\x9d\x28\xdf\x4a\x10\x3f\xa3\x9e\xf8\xf8" "\x6c\x2c\x10\xa7\x91\xab\xc0\x86\xd4\x6d\x69\xea\x58\xc4\xf9\xc0" "\xd4\xee\xc2\xb0\x9d\x36\xae\xe7\xc9\xa9\x1f\x71\xa8\xee\xa2\x1d" "\x20\xfd\x79\xc7\xd9\xc4\x90\x51\x38\x97\xb6\x9f\x55\xea\xf3\xf0" "\x78\xb4\xd3\x8c\xa9\x9b\x32\x7d\x19\x36\x96\xbc\x8e\xab\x80\x9f" "\x61\x56\xcc\xbd\x3a\x80\xc6\x69\x37\x0a\x89\x89\x21\x82\xb7\x79" "\x6d\xe9\xb4\x34\xc4\x31\xe0\xbe\x71\xad\xf3\x50\x05\xb2\x61\xab" "\xb3\x1a\x80\x57\xcf\xe1\x11\x26\xcb\xa9\xd1\xf6\x58\x46\xf1\x69" "\xa2\xb8\x42\x3c\xe8\x28\x13\xca\x58\xd9\x28\x99\xf8\xc8\x17\x32" "\x4a\xf9\xb3\x4c\x7a\x47\xad\xe4\x77\x64\xec\x70\xa1\x01\x0b\x88" "\xe7\x30\x0b\xbd\x66\x25\x39\x1e\x51\x67\xee\xec\xdf\xb8\x24\x5d" "\x7f\xcb\xee\x7a\x4e\xa9\x93\xf0\xa1\x84\x7b\xfe\x5a\xe3\x86\xb2" "\xfb\xcd\x39\xe7\x1e\x5e\x48\x65\x4b\x50\x2b\x4a\x99\x46\x3f\x6f" "\xdb\xd9\x97\xdb\xe5\x6d\xa4\xdd\x6c\x18\x64\x5e\xae\x7e\x2c\xd3" "\xb4\xf3\x57\x5c\xb5\xf8\x7f\xe5\x87\xb5\x35\xdb\x80\x38\x6e\x2c" "\x5c\xdd\xeb\x7c\x63\xac\xe4\xb5\x5a\x6a\x40\x6d\x72\x69\x9a\xa9" "\x8f\x5e\x93\x91\x4d\xce\xeb\x87\xf5\x25\xed\x75\x6b\x3b\x1a\xf2" "\x0c\xd2\xa4\x10\x45\xd2\x87\xae\x29\x6d\xeb\xea\x66\x5f\xa0\xc2", "\x8c\x22\xe3\xda\x9d\x94\x8a\xbe\x8a\xbc\x55\x2c\x94\x63\x44\x40" }, /* After setiv, ctr_low: 0xfffffffe */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\xd1\xc1\xdf", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\xac\x6a\x10\x3f\xe2\x8d\xed\x27\x55\x14\xca\x1f\x03\x67\x0a\xa8" "\xa1\x07\xbf\x00\x73\x5b\x64\xef\xac\x30\x83\x81\x48\x4c\xaa\xd5" "\xff\xca\xef\x2f\x77\xbe\xfe\x1b\x20\x5c\x86\x19\xc7\xf9\x11\x99" "\x27\xc5\x57\xa7\x0a\xc2\xa8\x05\xd9\x07\x2b\xb9\x38\xa4\xef\x58" "\x92\x74\xcf\x89\xc7\xba\xfc\xb9\x70\xac\x86\xe2\x31\xba\x7c\xf9" "\xc4\xe2\xe0\x4c\x1b\xe4\x3f\x75\x83\x5c\x40\x0e\xa4\x13\x8b\x04" "\x60\x78\x57\x29\xbb\xe6\x61\x93\xe3\x16\xf9\x58\x07\x75\xd0\x96" "\xfb\x8f\x6d\x1e\x49\x0f\xd5\x31\x9e\xee\x31\xe6\x0a\x85\x93\x49" "\x22\xcf\xd6\x1b\x40\x44\x63\x9c\x95\xaf\xf0\x44\x23\x51\x37\x92" "\x0d\xa0\x22\x37\xb9\x6d\x13\xf9\x78\xba\x27\x27\xed\x08\x7e\x35" "\xe4\xe2\x28\xeb\x0e\xbe\x3d\xce\x89\x93\x35\x84\x0f\xa0\xf9\x8d" "\x94\xe9\x5a\xec\xd4\x0d\x1f\x5c\xbe\x6f\x8e\x6a\x4d\x10\x65\xbb" "\xc7\x0b\xa0\xd5\x5c\x20\x80\x0b\x4a\x43\xa6\xe1\xb0\xe0\x56\x6a" "\xde\x90\xe0\x6a\x45\xe7\xc2\xd2\x69\x9b\xc6\x62\x11\xe3\x2b\xa5" "\x45\x98\xb0\x80\xd3\x57\x4d\x1f\x09\x83\x58\xd4\x4d\xa6\xc5\x95" "\x87\x59\xb0\x58\x6c\x81\x49\xc5\x95\x18\x23\x1b\x6f\x10\x86\xa2" "\xd9\x56\x19\x30\xec\xd3\x4a\x4b\xe8\x1c\x11\x37\xfb\x31\x60\x4d" "\x4f\x9b\xc4\x95\xba\xda\x49\x43\x6c\xc7\x3d\x5b\x13\xf9\x91\xf8", "\xcd\x2b\x83\xd5\x5b\x5a\x8e\x0b\x2e\x77\x0d\x97\xbf\xf7\xaa\xab" }, /* After setiv, ctr_low: 0xfffffffd */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x76\x8c\x18\x92", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x3d\x6f\x4e\xf6\xd2\x6f\x4e\xce\xa6\xb4\x4a\x9e\xcb\x57\x13\x90" "\x51\x3b\xf6\xb2\x40\x55\x0c\x2c\xa2\x85\x44\x72\xf2\x90\xaf\x6b" "\x86\x8c\x75\x2a\x9c\xd6\x52\x50\xee\xc6\x5f\x59\xbc\x8d\x18\xd7" "\x87\xa5\x7f\xa0\x13\xd1\x5d\x54\x77\x30\xe2\x5d\x1b\x4f\x87\x9f" "\x3a\x41\xcb\x6a\xdf\x44\x4f\xa2\x1a\xbc\xfb\x4b\x16\x67\xed\x59" "\x65\xf0\x77\x48\xca\xfd\xf0\xb6\x90\x65\xca\x23\x09\xca\x83\x43" "\x8f\xf0\x78\xb4\x5f\x96\x2a\xfd\x29\xae\xda\x62\x85\xc5\x87\x4b" "\x2a\x3f\xba\xbe\x15\x5e\xb0\x4e\x8e\xe7\x66\xae\xb4\x80\x66\x90" "\x10\x9d\x81\xb9\x64\xd3\x36\x00\xb2\x95\xa8\x7d\xaf\x54\xf8\xbd" "\x8f\x7a\xb1\xa1\xde\x09\x0d\x10\xc8\x8e\x1e\x18\x2c\x1e\x73\x71" "\x2f\x1e\xfd\x16\x6e\xbe\xe1\x3e\xe5\xb4\xb5\xbf\x03\x63\xf4\x5a" "\x0d\xeb\xff\xe0\x61\x80\x67\x51\xb4\xa3\x1f\x18\xa5\xa9\xf1\x9a" "\xeb\x2a\x7f\x56\xb6\x01\x88\x82\x78\xdb\xec\xb7\x92\xfd\xef\x56" "\x55\xd3\x72\x35\xcd\xa4\x0d\x19\x6a\xb6\x79\x91\xd5\xcb\x0e\x3b" "\xfb\xea\xa3\x55\x9f\x77\xfb\x75\xc2\x3e\x09\x02\x73\x7a\xff\x0e" "\xa5\xf0\x83\x11\xeb\xe7\xff\x3b\xd0\xfd\x7a\x07\x53\x63\x43\x89" "\xf5\x7b\xc4\x7d\x3b\x2c\x9b\xca\x1c\xf6\xb2\xab\x13\xf5\xc4\x2a" "\xbf\x46\x77\x3b\x09\xdd\xd1\x80\xef\x55\x11\x3e\xd8\xe4\x42\x22", "\xa3\x86\xa1\x5f\xe3\x4f\x3b\xed\x12\x23\xeb\x5c\xb8\x0c\xad\x4a" }, /* After setiv, ctr_low: 0xfffffffc */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xc8\xc3\xaf", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x33\x5f\xdc\x8d\x5d\x77\x7b\x78\xc1\x5b\x7b\xb3\xd9\x08\x9a\x0c" "\xce\x63\x4e\xef\x19\xf8\x8c\x7a\xcb\x31\x39\x93\x69\x7a\x2c\x97" "\x3a\xb4\x52\x45\x9e\x7b\x78\xbc\xa9\xad\x54\x7f\x88\xa6\xae\xd5" "\xc0\x8b\x7a\xe4\x23\x6b\xb2\x29\x98\xea\x25\x7a\xae\x11\x0c\xc9" "\xf3\x77\xa1\x74\x82\xde\x0c\xec\x68\xce\x94\xfd\xb0\xa0\xc5\x32" "\xd6\xbb\xc3\xe7\xed\x3c\x6f\x0b\x53\x9d\xf3\xc8\xeb\x4e\xee\x99" "\x19\xc7\x16\xd1\xa5\x59\x1d\xa9\xd3\xe6\x43\x52\x74\x61\x28\xe6" "\xac\xd8\x47\x63\xc2\xb7\x53\x39\xc1\x9a\xb0\xa3\xa4\x26\x14\xd0" "\x88\xa9\x8c\xc5\x6d\xe9\x21\x7c\xb9\xa5\xab\x67\xe3\x8d\xe9\x1d" "\xe3\x1c\x7b\xcd\xa4\x12\x0c\xd7\xa6\x5d\x41\xcf\xdd\x3d\xfc\xbc" "\x2a\xbb\xa2\x7a\x9c\x4b\x3a\x42\x6c\x98\x1d\x50\x99\x9c\xfb\xda" "\x21\x09\x2a\x31\xff\x05\xeb\xa5\xf1\xba\x65\x78\xbe\x15\x8e\x84" "\x35\xdd\x45\x29\xcc\xcd\x32\x2d\x27\xe9\xa8\x94\x4b\x16\x16\xcc" "\xab\xf2\xec\xfb\xa0\xb5\x9d\x39\x81\x3e\xec\x5e\x3d\x13\xd1\x83" "\x04\x79\x2d\xbb\x2c\x76\x76\x93\x28\x77\x27\x13\xdd\x1d\x3e\x89" "\x3e\x37\x46\x4c\xb8\x34\xbe\xbf\x9f\x4f\x9f\x37\xff\x0c\xe6\x14" "\x14\x66\x52\x41\x18\xa9\x39\x2b\x0c\xe5\x44\x04\xb0\x93\x06\x64" "\x67\xf7\xa0\x19\xa7\x61\xcf\x03\x7b\xcb\xc8\xb3\x88\x28\xe4\xe7", "\xe6\xe8\x0a\xe3\x72\xfc\xe0\x07\x69\x09\xf2\xeb\xbc\xc8\x6a\xf0" }, /* After setiv, ctr_low: 0xfffffffb */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x95\x1a\xe2", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\xd8\x32\x5a\xe3\x55\x8e\xb3\xc2\x51\x84\x2b\x09\x01\x5e\x6c\xfb" "\x4a\xc4\x88\xa0\x33\xe7\x3e\xbf\xe5\x7c\xd2\x00\x4c\x1a\x85\x32" "\x34\xec\x38\x9d\x18\x5f\xf1\x50\x61\x82\xee\xf3\x84\x5a\x84\x4e" "\xeb\x29\x08\x4c\x7b\xb5\x27\xec\x7d\x79\x77\xd7\xa1\x68\x91\x32" "\x2d\xf3\x38\xa9\xd6\x27\x16\xfb\x7d\x8b\x09\x5e\xcf\x1b\x74\x6d" "\xcf\x51\x91\x91\xa1\xe7\x40\x19\x43\x7b\x0d\xa5\xa9\xa5\xf4\x2e" "\x7f\x1c\xc7\xba\xa2\xea\x00\xdd\x24\x01\xa8\x66\x1e\x88\xf1\xf6" "\x0c\x9a\xd6\x2b\xda\x3f\x3e\xb2\x98\xea\x89\xc7\xc6\x63\x27\xb7" "\x6a\x48\x9a\xee\x1e\x70\xa0\xc8\xec\x3d\xc3\x3e\xb5\xf0\xc2\xb1" "\xb9\x71\x1a\x69\x9d\xdd\x72\x1e\xfe\x72\xa0\x21\xb8\x9f\x18\x96" "\x26\xcf\x89\x2e\x92\xf1\x02\x65\xa5\xb4\x2e\xb7\x4e\x12\xbd\xa0" "\x48\xbe\xf6\x5c\xef\x7e\xf3\x0a\xcf\x9d\x1f\x1e\x14\x70\x3e\xa0" "\x01\x0f\x14\xbf\x38\x10\x3a\x3f\x3f\xc2\x76\xe0\xb0\xe0\x7c\xc6" "\x77\x6d\x7f\x69\x8e\xa0\x4b\x00\xc3\x9d\xf9\x0b\x7f\x8a\x8e\xd3" "\x17\x58\x40\xfe\xaf\xf4\x16\x3a\x65\xff\xce\x85\xbb\x80\xfa\xb8" "\x34\xc9\xef\x3a\xdd\x04\x46\xca\x8f\x70\x48\xbc\x1c\x71\x4d\x6a" "\x17\x30\x32\x87\x2e\x2e\x54\x9e\x3f\x15\xed\x17\xd7\xa1\xcf\x6c" "\x5d\x0f\x3c\xee\xf5\x96\xf1\x8f\x68\x1c\xbc\x27\xdc\x10\x3c\x3c", "\x8c\x31\x06\xbb\xf8\x18\x2d\x9d\xd1\x0d\x03\x56\x2b\x28\x25\x9b" }, /* After setiv, ctr_low: 0xfffffffa */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6b\x99\x9b\xda", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x7a\x74\x57\xe7\xc1\xb8\x7e\xcf\x91\x98\xf4\x1a\xa4\xdb\x4d\x2c" "\x6e\xdc\x05\x0b\xd1\x16\xdf\x25\xa8\x1e\x42\xa6\xf9\x09\x36\xfb" "\x02\x8a\x10\x7d\xa1\x07\x88\x40\xb7\x41\xfd\x64\xf6\xe3\x92\x20" "\xfd\xc9\xde\xbd\x88\x46\xd3\x1f\x20\x14\x73\x86\x09\xb6\x68\x61" "\x64\x90\xda\x24\xa8\x0f\x6a\x10\xc5\x01\xbf\x52\x8a\xee\x23\x44" "\xd5\xb0\xd8\x68\x5e\x77\xc3\x62\xed\xcb\x3c\x1b\x0c\x1f\x13\x92" "\x2c\x74\x6d\xee\x40\x1b\x6b\xfe\xbe\x3c\xb8\x02\xdd\x24\x9d\xd3" "\x3d\x4e\xd3\x9b\x18\xfd\xd6\x8f\x95\xef\xa3\xbf\xa9\x2f\x33\xa8" "\xc2\x37\x69\x58\x92\x42\x3a\x30\x46\x12\x1b\x2c\x04\xf0\xbf\xa9" "\x79\x55\xcd\xac\x45\x36\x79\xc0\xb4\xb2\x5f\x82\x88\x49\xe8\xa3" "\xbf\x33\x41\x7a\xcb\xc4\x11\x0e\xcc\x61\xed\xd1\x6b\x59\x5f\x9d" "\x20\x6f\x85\x01\xd0\x16\x2a\x51\x1b\x79\x35\x42\x5e\x49\xdf\x6f" "\x64\x68\x31\xac\x49\x34\xfb\x2b\xbd\xb1\xd9\x12\x4e\x4b\x16\xc5" "\xa6\xfe\x15\xd3\xaf\xac\x51\x08\x95\x1f\x8c\xd2\x52\x37\x8b\x88" "\xf3\x20\xe2\xf7\x09\x55\x82\x83\x1c\x38\x5f\x17\xfc\x37\x26\x21" "\xb8\xf1\xfe\xa9\xac\x54\x1e\x53\x83\x53\x3f\x43\xe4\x67\x22\xd5" "\x86\xec\xf2\xb6\x4a\x8b\x8a\x66\xea\xe0\x92\x50\x3b\x51\xe4\x00" "\x25\x2a\x7a\x64\x14\xd6\x09\xe1\x6c\x75\x32\x28\x53\x5e\xb3\xab", "\x5d\x4b\xb2\x8f\xfe\xa5\x7f\x01\x6d\x78\x6c\x13\x58\x08\xe4\x94" }, /* After setiv, ctr_low: 0xfffffff9 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xc4\x42\x97", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\xf5\xc1\xed\xb8\x7f\x55\x7b\xb5\x47\xed\xaa\x42\xd2\xda\x33\x41" "\x4a\xe0\x36\x6d\x51\x28\x40\x9c\x35\xfb\x11\x65\x18\x83\x9c\xb5" "\x02\xb2\xa7\xe5\x52\x27\xa4\xe8\x57\x3d\xb3\xf5\xea\xcb\x21\x07" "\x67\xbe\xbe\x0f\xf6\xaa\x32\xa1\x4b\x5e\x79\x4f\x50\x67\xcd\x80" "\xfc\xf1\x65\xf2\x6c\xd0\xdb\x17\xcc\xf9\x52\x93\xfd\x5e\xa6\xb9" "\x5c\x9f\xa8\xc6\x36\xb7\x80\x80\x6a\xea\x62\xdc\x61\x13\x45\xbe" "\xab\x8f\xd8\x99\x17\x51\x9b\x29\x04\x6e\xdb\x3e\x9f\x83\xc6\x35" "\xb3\x90\xce\xcc\x74\xec\xcb\x04\x41\xac\xb1\x92\xde\x20\xb1\x67" "\xb0\x38\x14\xaa\x7d\xee\x3c\xb2\xd3\xbb\x2f\x88\x0b\x73\xcf\x7b" "\x69\xc1\x55\x5b\x2b\xf2\xd4\x38\x2b\x3c\xef\x04\xc9\x14\x7c\x31" "\xd6\x61\x88\xa8\xb3\x8c\x69\xb4\xbc\xaa\x0d\x15\xd2\xd5\x27\x63" "\xc4\xa4\x80\xe9\x2b\xe9\xd2\x34\xc9\x0e\x3f\x7b\xd3\x43\x0d\x47" "\x5d\x37\x8e\x42\xa4\x4e\xef\xcd\xbb\x3a\x5b\xa4\xe1\xb0\x8d\x64" "\xb7\x0b\x58\x52\xec\x55\xd0\xef\x23\xfe\xf2\x8d\xe0\xd1\x6a\x2c" "\xaa\x1c\x03\xc7\x3e\x58\x4c\x61\x72\x07\xc6\xfd\x0e\xbc\xd4\x6b" "\x99\x4f\x91\xda\xff\x6f\xea\x81\x0c\x76\x85\x5d\x0c\x7f\x1c\xb8" "\x84\x8c\x2f\xe1\x36\x3e\x68\xa0\x57\xf5\xdf\x13\x0a\xd6\xe1\xcd" "\xae\x23\x99\x4e\xed\x7a\x72\x1b\x7c\xe5\x65\xd1\xb7\xcf\x2f\x73", "\x1e\x2f\xcf\x3c\x95\x9a\x29\xec\xd3\x37\x90\x8c\x84\x8a\xfb\x95" }, /* After setiv, ctr_low: 0xfffffff8 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\xfa\xc7\x4f", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x14\x33\xc6\x9d\x04\xd3\x48\x29\x0c\x6a\x24\x27\xdf\x5f\x0a\xd2" "\x71\xd6\xd0\x18\x04\xc0\x9f\x72\x0a\x60\xb7\x10\x52\x56\xf7\xae" "\x64\xb0\x28\xd4\xfd\x25\x93\x8e\x67\x7e\xac\xc2\x93\xc7\x54\x2e" "\x82\x93\x88\x6a\xb9\x8b\x73\xbc\x88\xec\x27\xdd\x4f\x9b\x21\x9e" "\x77\x98\x70\x0b\xf4\xd8\x55\xfe\xf4\xc3\x3a\xcb\xca\x3a\xfb\xd4" "\x52\x72\x2f\xf8\xac\xa9\x6a\xf5\x13\xab\x7a\x2e\x9f\x52\x41\xbd" "\x87\x90\x68\xad\x17\xbd\x5a\xff\xc3\xc6\x10\x4d\xc1\xfe\xfc\x72" "\x21\xb5\x53\x4a\x3f\xe0\x15\x9f\x29\x36\x23\xc0\x9a\x31\xb2\x0f" "\xcd\x2f\xa6\xd0\xfc\xe6\x4d\xed\x68\xb3\x3d\x26\x67\xab\x40\xf0" "\xab\xcf\x72\xc0\x50\xb1\x1e\x86\x38\xe2\xe0\x46\x3a\x2e\x3e\x1d" "\x07\xd6\x9d\xe8\xfc\xa3\xe7\xac\xc9\xa0\xb3\x22\x05\xbc\xbf\xd2" "\x63\x44\x66\xfc\xb4\x7b\xb4\x70\x7e\x96\xa9\x16\x1b\xb2\x7d\x93" "\x44\x92\x5e\xbd\x16\x34\xa7\x11\xd0\xdf\x52\xad\x6f\xbd\x23\x3c" "\x3d\x58\x16\xaf\x99\x8b\xbb\xa0\xdc\x3a\xff\x17\xda\x56\xba\x77" "\xae\xc4\xb1\x51\xe2\x61\x4f\xf0\x66\x1b\x4c\xac\x79\x34\x1c\xfd" "\x6c\x5f\x9a\x2c\x60\xfc\x47\x00\x5f\x2d\x81\xcc\xa9\xdd\x2b\xf4" "\x5b\x53\x44\x61\xd4\x13\x5a\xf3\x93\xf0\xc9\x24\xd4\xe6\x60\x6f" "\x78\x02\x0c\x75\x9d\x0d\x23\x97\x35\xe2\x06\x8a\x49\x5e\xe5\xbe", "\x23\xc0\x4a\x2f\x98\x93\xca\xbd\x2e\x44\xde\x05\xcc\xe7\xf1\xf5" }, /* After setiv, ctr_low: 0xfffffff7 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4c\xa7\x1e\x02", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x51\x51\x64\x89\xeb\x9f\xf9\xd6\xb1\xa6\x73\x5f\xf1\x62\xb5\xe4" "\x00\x80\xdb\x4c\x1c\xce\xe5\x00\xeb\xea\x6c\x57\xe4\x27\xfc\x71" "\x08\x8c\xa1\xfc\x59\x1d\x07\x45\x3c\xc9\x4e\x0f\xb6\xea\x96\x90" "\xae\xf7\x81\x1e\x7e\x6c\x5e\x50\xaf\x34\x3e\xa0\x55\x59\x8e\xe7" "\xc1\xba\x48\xfa\x9e\x07\xf6\x6a\x24\x54\x3e\x9b\xa5\xfe\x31\x16" "\x3d\x4d\x9c\xc4\xe1\xec\x26\xa0\x8b\x59\xa6\xf3\x94\xf8\x88\xda" "\x1f\x88\x23\x5f\xfb\xfd\x79\xa2\xd3\x62\x30\x66\x69\xd9\x0d\x05" "\xc0\x75\x4c\xb8\x48\x34\x1d\x97\xcf\x29\x6a\x12\x1c\x26\x54\x1d" "\x80\xa9\x06\x74\x86\xff\xc6\xb4\x72\xee\x34\xe2\x56\x06\x6c\xf5" "\x11\xe7\x26\x71\x47\x6b\x05\xbd\xe4\x0b\x40\x78\x84\x3c\xf9\xf2" "\x78\x34\x2b\x3c\x5f\x0e\x4c\xfb\x17\x39\xdc\x59\x6b\xd1\x56\xac" "\xe4\x1f\xb9\x19\xbc\xec\xb1\xd0\x6d\x47\x3b\x37\x4d\x0d\x6b\x65" "\x7c\x70\xe9\xec\x58\xcc\x09\xd4\xd9\xbf\x9f\xe0\x6c\x7f\x60\x28" "\xd8\xdf\x8e\xd1\x6a\x73\x42\xf3\x50\x01\x79\x68\x41\xc3\xba\x19" "\x1e\x2d\x30\xc2\x81\x2c\x9f\x11\x8b\xd0\xdc\x31\x3b\x01\xfe\x53" "\xa5\x11\x13\x22\x89\x40\xb9\x1b\x12\x89\xef\x9a\xcb\xa8\x03\x4f" "\x54\x1a\x15\x6d\x11\xba\x05\x09\xd3\xdb\xbf\x05\x42\x3a\x5a\x27" "\x3b\x34\x5c\x58\x8a\x5c\xa4\xc2\x28\xdc\xb2\x3a\xe9\x99\x01\xd6", "\x30\xb2\xb5\x11\x8a\x3a\x8d\x70\x67\x71\x14\xde\xed\xa7\x43\xb5" }, /* After setiv, ctr_low: 0xfffffff6 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x47\xab\x9f\x3a", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x05\x72\x44\xa0\x99\x11\x1d\x2c\x4b\x03\x4f\x20\x92\x88\xbe\x55" "\xee\x31\x2c\xd9\xc0\xc1\x64\x77\x79\xd7\x3e\xfa\x5a\x7d\xf0\x48" "\xf8\xc8\xfe\x81\x8f\x89\x92\xa6\xc2\x07\xdc\x9f\x3f\xb2\xc8\xf2" "\xf3\xe9\xe1\xd3\xed\x55\xb4\xab\xc3\x22\xed\x8f\x00\xde\x32\x95" "\x91\xc0\xc5\xf3\xd3\x93\xf0\xee\x56\x14\x8f\x96\xff\xd0\x6a\xbd" "\xfc\x57\xc2\xc3\x7b\xc1\x1d\x56\x48\x3f\xa6\xc7\x92\x47\xf7\x2f" "\x0b\x85\x1c\xff\x87\x29\xe1\xbb\x9b\x14\x6c\xac\x51\x0a\xc0\x7b" "\x22\x25\xb0\x48\x92\xad\x09\x09\x6e\x39\x8e\x96\x13\x05\x55\x92" "\xbd\xd7\x5d\x95\x35\xdd\x8a\x9d\x05\x59\x60\xae\xbb\xc0\x85\x92" "\x4c\x8b\xa0\x3f\xa2\x4a\xe5\x2e\xde\x85\x1a\x39\x10\x22\x11\x1b" "\xdd\xcc\x96\xf4\x93\x97\xf5\x81\x85\xf3\x33\xda\xa1\x9a\xba\xfd" "\xb8\xaf\x60\x81\x37\xf1\x02\x88\x54\x15\xeb\x21\xd1\x19\x1a\x1f" "\x28\x9f\x02\x27\xca\xce\x97\xda\xdc\xd2\x0f\xc5\x0e\x2e\xdd\x4f" "\x1d\x24\x62\xe4\x6e\x4a\xbe\x96\x95\x38\x0c\xe9\x26\x14\xf3\xf0" "\x92\xbc\x97\xdc\x38\xeb\x64\xc3\x04\xc1\xa2\x6c\xad\xbd\xf8\x03" "\xa0\xa4\x68\xaa\x9d\x1f\x09\xe6\x62\x95\xa2\x1c\x32\xef\x62\x28" "\x7e\x54\x6d\x4b\x6a\xcc\x4a\xd0\x82\x47\x46\x0d\x45\x3c\x36\x03" "\x86\x90\x44\x65\x18\xac\x19\x75\xe6\xba\xb1\x9a\xb4\x5d\x84\x9b", "\x31\x22\x2b\x11\x6e\x2b\x94\x56\x37\x9d\xc3\xa5\xde\xe7\x6e\xc9" }, /* After setiv, ctr_low: 0xfffffff5 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xf6\x46\x77", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x6e\x32\xdb\x04\x32\x57\x15\x78\x0e\x4c\x70\x66\x5c\x91\x43\x0c" "\x63\x73\xb8\x86\xad\xb0\xf1\x34\x0f\x0c\x7e\xd3\x4e\xcb\xc9\xea" "\x19\x3c\xb8\x14\xd0\xab\x9e\x9b\x22\xda\x7a\x96\xa7\xf5\xa2\x99" "\x58\xe3\xd6\x72\x0f\xf5\xdf\x88\xd1\x33\xb1\xe5\x03\x72\x62\x1c" "\xa7\xf2\x67\x50\x0e\x70\xc3\x7a\x6c\x4a\x90\xba\x78\x9e\xd2\x0b" "\x29\xd4\xc8\xa7\x57\x06\xf2\xf4\x01\x4b\x30\x53\xea\xf7\xde\xbf" "\x1c\x12\x03\xcf\x9f\xcf\x80\x8b\x77\xfd\x73\x48\x79\x19\xbe\x38" "\x75\x0b\x6d\x78\x7d\x79\x05\x98\x65\x3b\x35\x8f\x68\xff\x30\x7a" "\x6e\xf7\x10\x9e\x11\x25\xc4\x95\x97\x7d\x92\x0f\xbf\x38\x95\xbd" "\x5d\x2a\xf2\x06\x2c\xd9\x5a\x80\x91\x4e\x22\x7d\x5f\x69\x85\x03" "\xa7\x5d\xda\x22\x09\x2b\x8d\x29\x67\x7c\x8c\xf6\xb6\x49\x20\x63" "\xb9\xb6\x4d\xb6\x37\xa3\x7b\x19\xa4\x28\x90\x83\x55\x3d\x4e\x18" "\xc8\x65\xbc\xd1\xe7\xb5\xcf\x65\x28\xea\x19\x11\x5c\xea\x83\x8c" "\x44\x1f\xac\xc5\xf5\x3a\x4b\x1c\x2b\xbf\x76\xd8\x98\xdb\x50\xeb" "\x64\x45\xae\xa5\x39\xb7\xc8\xdf\x5a\x73\x6d\x2d\x0f\x4a\x5a\x17" "\x37\x66\x1c\x3d\x27\xd5\xd6\x7d\xe1\x08\x7f\xba\x4d\x43\xc2\x29" "\xf7\xbe\x83\xec\xd0\x3b\x2e\x19\x9e\xf7\xbf\x1b\x16\x34\xd8\xfa" "\x32\x17\x2a\x90\x55\x93\xd5\x3e\x14\x8d\xd6\xa1\x40\x45\x09\x52", "\x89\xf2\xae\x78\x38\x8e\xf2\xd2\x52\xa8\xba\xb6\xf2\x5d\x7c\xfc" }, /* After setiv, ctr_low: 0xfffffff4 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x51\xb2\x9d\x4a", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x1d\xb8\x77\xcd\xcd\xfe\xde\x07\x97\xcb\x97\x3a\x4f\xa0\xd0\xe6" "\xcc\xcf\x8b\x71\xd5\x65\x3d\xc4\x17\x52\xe7\x1d\x6a\x68\x4a\x77" "\xca\x04\x4a\xef\x8e\x7e\xce\x79\xa1\x80\x0d\x9e\xd5\xf4\xce\x66" "\x4d\x54\xb1\x09\xd1\xb6\xb0\x43\x28\xe8\x53\xe2\x24\x9c\x76\xc5" "\x4d\x22\xf3\x6e\x13\xf3\xd7\xe0\x85\xb8\x9e\x0b\x17\x22\xc0\x79" "\x2b\x72\x57\xaa\xbd\x43\xc3\xf7\xde\xce\x22\x41\x3c\x7e\x37\x1a" "\x55\x2e\x36\x0e\x7e\xdc\xb3\xde\xd7\x33\x36\xc9\xc8\x56\x93\x51" "\x68\x77\x9a\xb0\x08\x5c\x22\x35\xef\x5c\x9b\xbf\x3e\x20\x8a\x84" "\x3d\xb3\x60\x10\xe1\x97\x30\xd7\xb3\x6f\x40\x5a\x2c\xe0\xe5\x52" "\x19\xb6\x2b\xed\x6e\x8e\x18\xb4\x8d\x78\xbd\xc4\x9f\x4f\xbd\x82" "\x98\xd6\x71\x3d\x71\x5b\x78\x73\xee\x8e\x4b\x37\x88\x9e\x21\xca" "\x00\x6c\xc2\x96\x8d\xf0\xcd\x09\x58\x54\x5a\x58\x59\x8e\x9b\xf8" "\x72\x93\xd7\xa0\xf9\xc4\xdc\x48\x89\xaa\x31\x95\xda\x4e\x2f\x79" "\x1e\x37\x49\x92\x2e\x32\x2e\x76\x54\x2a\x64\xa8\x96\x67\xe9\x75" "\x10\xa6\xeb\xad\xc6\xa8\xec\xb7\x18\x0a\x32\x26\x8d\x6e\x03\x74" "\x0e\x1f\xfc\xde\x76\xff\x6e\x96\x42\x2d\x80\x0a\xc6\x78\x70\xc4" "\xd8\x56\x7b\xa6\x38\x2f\xf6\xc0\x9b\xd7\x21\x6e\x88\x5d\xc8\xe5" "\x02\x6a\x09\x1e\xb3\x46\x44\x80\x82\x5b\xd1\x66\x06\x61\x4f\xb8", "\x16\x0e\x73\xa3\x14\x43\xdb\x15\x9c\xb0\x0d\x30\x6d\x9b\xe1\xb1" }, /* After setiv, ctr_low: 0xfffffff3 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\xef\x44\x07", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x42\x71\x54\xe2\xdb\x50\x5d\x3c\x10\xbd\xf8\x60\xbd\xdb\x26\x14" "\x7d\x13\x59\x98\x28\xfb\x43\x42\xca\x72\xe6\xd8\x58\x00\xa2\x1b" "\x6a\x61\xb4\x3a\x80\x6b\x9e\x14\xbd\x11\x33\xab\xe9\xb9\x91\x95" "\xd7\x5d\xc3\x98\x1f\x7f\xcb\xa8\xf0\xec\x31\x26\x51\xea\x2e\xdf" "\xd9\xde\x70\xf5\x84\x27\x3a\xac\x22\x05\xb9\xce\x2a\xfb\x2a\x83" "\x1e\xce\x0e\xb2\x31\x35\xc6\xe6\xc0\xd7\xb0\x5f\xf5\xca\xdb\x13" "\xa7\xfe\x4f\x85\xa3\x4f\x94\x5c\xc1\x04\x12\xde\x6f\xa1\xdb\x41" "\x59\x82\x22\x22\x65\x97\x6d\xc8\x67\xab\xf3\x90\xeb\xa4\x00\xb3" "\x7d\x94\x3d\x7b\x2a\xe2\x85\x36\x87\x16\xb8\x19\x92\x02\xe0\x43" "\x42\x85\xa1\xe6\xb8\x11\x30\xcc\x2c\xd8\x63\x09\x0e\x53\x5f\xa3" "\xe0\xd4\xee\x0e\x04\xee\x65\x61\x96\x84\x42\x0c\x68\x8d\xb7\x48" "\xa3\x02\xb4\x82\x69\xf2\x35\xe4\xce\x3b\xe3\x44\xce\xad\x49\x32" "\xab\xda\x04\xea\x06\x60\xa6\x2a\x7d\xee\x0f\xb8\x95\x90\x22\x62" "\x9c\x78\x59\xd3\x7b\x61\x02\x65\x63\x96\x9f\x67\x50\xa0\x61\x43" "\x53\xb2\x3f\x22\xed\x8c\x42\x39\x97\xd9\xbc\x6e\x81\xb9\x21\x97" "\xc6\x5b\x68\xd7\x7f\xd0\xc5\x4a\xfb\x74\xc4\xfd\x9a\x2a\xb8\x9b" "\x48\xe0\x00\xea\x6d\xf5\x30\x26\x61\x8f\xa5\x45\x70\xc9\x3a\xea" "\x6d\x19\x11\x57\x0f\x21\xe6\x0a\x53\x94\xe3\x0c\x99\xb0\x2f\xc5", "\x92\x92\x89\xcd\x4f\x3c\x6d\xbc\xe8\xb3\x70\x14\x5b\x3c\x12\xe4" }, /* After setiv, ctr_low: 0xfffffff2 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xe3\xc5\x3f", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x41\xc3\xcb\xd7\x6e\xde\x2a\xc6\x15\x05\xc6\xba\x27\xae\xcd\x37" "\xc0\xe5\xbf\xb9\x5c\xdc\xd6\xad\x1a\xe1\x35\x7c\xc0\x85\x85\x51" "\x8c\x98\x06\xc0\x72\x43\x71\x7a\x2d\x7c\x81\x3c\xe7\xd6\x32\x8e" "\x22\x2b\x46\x95\x6a\xde\x45\x40\x56\xe9\x63\x32\x68\xbf\xb6\x78" "\xb7\x86\x00\x9d\x2c\x9e\xed\x67\xc1\x9b\x09\x9e\xd9\x0a\x56\xcb" "\x57\xc9\x48\x14\x23\x4e\x97\x04\xb5\x85\x25\x1d\xcb\x1a\x79\x9b" "\x54\x06\x95\xad\x16\x81\x84\x3a\x38\xec\x41\x90\x2a\xfa\x50\xe0" "\xb9\x20\xa6\xeb\xfe\x2e\x5c\xa1\xf6\x3c\x69\x4c\xce\xf8\x30\xe0" "\x87\x68\xa2\x3a\x9d\xad\x75\xd4\xa5\x6b\x0a\x90\x65\xa2\x27\x64" "\x9d\xf5\xa0\x6f\xd0\xd3\x62\xa5\x2d\xae\x02\x89\xb4\x1a\xfa\x32" "\x9b\xa0\x44\xdd\x50\xde\xaf\x41\xa9\x89\x1e\xb0\x41\xbc\x9c\x41" "\xb0\x35\x5e\xf1\x9a\xd9\xab\x57\x53\x21\xca\x39\xfc\x8b\xb4\xd4" "\xb2\x19\x8a\xe9\xb2\x24\x1e\xce\x2e\x19\xb0\xd2\x93\x30\xc4\x70" "\xe2\xf8\x6a\x8a\x99\x3b\xed\x71\x7e\x9e\x98\x99\x2a\xc6\xdd\xcf" "\x43\x32\xdb\xfb\x27\x22\x89\xa4\xc5\xe0\xa2\x94\xe9\xcf\x9d\x48" "\xab\x3f\xfa\x4f\x75\x63\x46\xdd\xfe\xfa\xf0\xbf\x6e\xa1\xf9\xca" "\xb1\x77\x79\x35\x6c\x33\xe1\x57\x68\x50\xe9\x78\x4e\xe4\xe2\xf0" "\xcf\xe4\x23\xde\xf4\xa7\x34\xb3\x44\x97\x38\xd2\xbd\x27\x44\x0e", "\x75\x0a\x41\x3b\x87\xe3\xc7\xf6\xd6\xe3\xab\xfa\x4b\xbe\x2e\x56" }, /* After setiv, ctr_low: 0xfffffff1 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5a\xbe\x1c\x72", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\xf1\x3c\x7a\xa4\xa9\xaf\xe7\x49\x19\x7d\xad\x50\xc1\x6a\x84\x87" "\xf5\x69\xe4\xe5\xc2\x0a\x90\x33\xc3\xeb\x76\x63\x5f\x9b\x1d\xf9" "\x53\x4a\x2a\x6d\x6b\x61\xe0\x5d\xed\xcb\x98\x0d\xf2\x57\x33\x12" "\xd1\x44\xaa\x7a\x7e\x4e\x41\x0e\xe6\xa7\x9f\x17\x92\x28\x91\xad" "\xca\xce\xf2\xa8\x73\x4a\xad\x89\x62\x73\x0b\x9a\x68\x91\xa8\x11" "\x44\x01\xfd\x57\xe4\xf8\x84\x55\x2b\x66\xdb\xb9\xd6\xee\x83\xe5" "\x57\xea\x5c\x6a\x23\x87\xdd\x0a\x45\x63\xb4\x0c\x8f\xc5\x9f\x22" "\xf3\x4f\x4e\x6f\x7b\x14\x62\xf7\x80\x59\x4a\xc5\xc8\xae\x8a\x6f" "\x5e\xe3\x1e\xe6\xae\xec\x99\x77\x6b\x88\x14\xe3\x58\x88\x61\x74" "\x38\x91\xa1\x32\xb8\xd2\x39\x6b\xe2\xcb\x8e\x77\xde\x92\x36\x78" "\xad\x50\xcf\x08\xb8\xfa\x29\x59\xb4\x68\x1b\x23\x10\x57\x32\x92" "\xf8\xec\xe1\x97\xdb\x30\x85\x22\xb5\x68\x2f\xf2\x98\xda\x06\xee" "\x65\x02\xe7\xf9\xc8\xc1\xca\x8f\xd3\xed\x4a\x3c\x09\xdd\xde\x64" "\xd9\x85\x17\x2c\x62\x41\x35\x24\xed\x6b\x87\x78\x1e\xb5\x7a\x9b" "\xa3\x90\xa3\x99\xc7\x39\x51\x10\xb7\x6a\x12\x3b\x64\xfe\x32\x3c" "\xb6\x84\x9a\x3f\x95\xd3\xcb\x22\x69\x9c\xf9\xb7\xc2\x8b\xf4\x55" "\x68\x60\x11\x20\xc5\x3e\x0a\xc0\xba\x00\x0e\x88\x96\x66\xfa\xf0" "\x75\xbc\x2b\x9c\xff\xc5\x33\x7b\xaf\xb2\xa6\x34\x78\x44\x9c\xa7", "\x01\x24\x0e\x17\x17\xe5\xfc\x90\x07\xfa\x78\xd5\x5d\x66\xa3\xf5" }, }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_GCM_DATA_LEN]; unsigned char tag[GCRY_GCM_BLOCK_LEN]; int i, keylen; gcry_error_t err = 0; size_t pos, poslen, taglen2; int byteNum; if (verbose) fprintf (stderr, " Starting GCM checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); continue; } if (verbose) fprintf (stderr, " checking GCM mode for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_GCM, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_GCM, 0); if (err) { fail ("aes-gcm, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("aes-gcm, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("aes-gcm, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen); if (err) { fail ("aes-gcm, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2); if (err) { fail ("cipher-gcm, gcryctl_get_taglen failed (tv %d): %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (taglen2 != GCRY_GCM_BLOCK_LEN) { fail ("cipher-gcm, gcryctl_get_taglen returned bad length" " (tv %d): got=%zu want=%d\n", i, taglen2, GCRY_GCM_BLOCK_LEN); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } for (pos = 0; pos < tv[i].aadlen; pos += step) { poslen = (pos + step < tv[i].aadlen) ? step : tv[i].aadlen - pos; err = gcry_cipher_authenticate(hde, tv[i].aad + pos, poslen); if (err) { fail ("aes-gcm, gcry_cipher_authenticate (%d) (%lu:%d) failed: " "%s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_authenticate(hdd, tv[i].aad + pos, poslen); if (err) { fail ("aes-gcm, de gcry_cipher_authenticate (%d) (%lu:%d) failed: " "%s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } for (pos = 0; pos < tv[i].inlen; pos += step) { poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos; err = gcry_cipher_encrypt (hde, out + pos, poslen, tv[i].plaintext + pos, poslen); if (err) { fail ("aes-gcm, gcry_cipher_encrypt (%d) (%lu:%d) failed: %s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].out, out, tv[i].inlen)) fail ("aes-gcm, encrypt mismatch entry %d (step %d)\n", i, step); for (pos = 0; pos < tv[i].inlen; pos += step) { poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos; err = gcry_cipher_decrypt (hdd, out + pos, poslen, NULL, 0); if (err) { fail ("aes-gcm, gcry_cipher_decrypt (%d) (%lu:%d) failed: %s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].plaintext, out, tv[i].inlen)) fail ("aes-gcm, decrypt mismatch entry %d (step %d)\n", i, step); taglen2 = tv[i].taglen ? tv[i].taglen : GCRY_GCM_BLOCK_LEN; err = gcry_cipher_gettag (hde, out, taglen2); if (err) { if (tv[i].should_fail) goto next_tv; fail ("aes-gcm, gcry_cipher_gettag(%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].tag, out, taglen2)) fail ("aes-gcm, encrypt tag mismatch entry %d\n", i); err = gcry_cipher_checktag (hdd, out, taglen2); if (err) { fail ("aes-gcm, gcry_cipher_checktag(%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_reset(hde); if (!err) err = gcry_cipher_reset(hdd); if (err) { fail ("aes-gcm, gcry_cipher_reset (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* gcry_cipher_reset clears the IV */ err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen); if (err) { fail ("aes-gcm, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* this time we authenticate, encrypt and decrypt one byte at a time */ for (byteNum = 0; byteNum < tv[i].aadlen; ++byteNum) { err = gcry_cipher_authenticate(hde, tv[i].aad + byteNum, 1); if (err) { fail ("aes-gcm, gcry_cipher_authenticate (%d) (byte-buf) failed: " "%s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_authenticate(hdd, tv[i].aad + byteNum, 1); if (err) { fail ("aes-gcm, de gcry_cipher_authenticate (%d) (byte-buf) " "failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum) { err = gcry_cipher_encrypt (hde, out+byteNum, 1, (tv[i].plaintext) + byteNum, 1); if (err) { fail ("aes-gcm, gcry_cipher_encrypt (%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].out, out, tv[i].inlen)) fail ("aes-gcm, encrypt mismatch entry %d, (byte-buf)\n", i); /* Test output to larger than 16-byte buffer. */ taglen2 = tv[i].taglen ? tv[i].taglen : GCRY_GCM_BLOCK_LEN + 1; err = gcry_cipher_gettag (hde, tag, taglen2); if (err) { if (tv[i].should_fail) goto next_tv; fail ("aes-gcm, gcry_cipher_gettag(%d, %lu) (byte-buf) failed: %s\n", i, (unsigned long) taglen2, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } taglen2 = tv[i].taglen ? tv[i].taglen : GCRY_GCM_BLOCK_LEN; if (memcmp (tv[i].tag, tag, taglen2)) fail ("aes-gcm, encrypt tag mismatch entry %d, (byte-buf)\n", i); for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum) { err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0); if (err) { fail ("aes-gcm, gcry_cipher_decrypt (%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].plaintext, out, tv[i].inlen)) fail ("aes-gcm, decrypt mismatch entry %d\n", i); err = gcry_cipher_checktag (hdd, tag, taglen2); if (err) { fail ("aes-gcm, gcry_cipher_checktag(%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_checktag (hdd, tag, 1); if (!err) { fail ("aes-gcm, gcry_cipher_checktag(%d) did not fail for invalid " " tag length of '%d'\n", i, 1); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_checktag (hdd, tag, 17); if (!err) { fail ("aes-gcm, gcry_cipher_checktag(%d) did not fail for invalid " " tag length of '%d'\n", i, 17); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (tv[i].should_fail) { fail ("aes-gcm, negative test succeeded %d\n", i); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } next_tv: gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed GCM checks.\n"); } static void check_gcm_cipher (void) { /* Large buffers, no splitting. */ _check_gcm_cipher(0xffffffff); /* Split input to one byte buffers. */ _check_gcm_cipher(1); /* Split input to 7 byte buffers. */ _check_gcm_cipher(7); /* Split input to 15 byte buffers. */ _check_gcm_cipher(15); /* Split input to 16 byte buffers. */ _check_gcm_cipher(16); /* Split input to 17 byte buffers. */ _check_gcm_cipher(17); } static void _check_eax_cipher (unsigned int step) { static const struct tv { int algo; char key[MAX_DATA_LEN]; char nonce[MAX_DATA_LEN]; int noncelen; unsigned char header[MAX_DATA_LEN]; int headerlen; unsigned char plaintext[MAX_DATA_LEN]; int inlen; char out[MAX_DATA_LEN]; char tag[MAX_DATA_LEN]; int taglen; int should_fail; } tv[] = { /* Test vectors from http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf */ { GCRY_CIPHER_AES, "\x23\x39\x52\xDE\xE4\xD5\xED\x5F\x9B\x9C\x6D\x6F\xF8\x0F\xF4\x78", "\x62\xEC\x67\xF9\xC3\xA4\xA4\x07\xFC\xB2\xA8\xC4\x90\x31\xA8\xB3", 16, "\x6B\xFB\x91\x4F\xD0\x7E\xAE\x6B", 8, "", 0, "", "\xE0\x37\x83\x0E\x83\x89\xF2\x7B\x02\x5A\x2D\x65\x27\xE7\x9D\x01", 16, 0 }, { GCRY_CIPHER_AES, "\x91\x94\x5D\x3F\x4D\xCB\xEE\x0B\xF4\x5E\xF5\x22\x55\xF0\x95\xA4", "\xBE\xCA\xF0\x43\xB0\xA2\x3D\x84\x31\x94\xBA\x97\x2C\x66\xDE\xBD", 16, "\xFA\x3B\xFD\x48\x06\xEB\x53\xFA", 8, "\xF7\xFB", 2, "\x19\xDD", "\x5C\x4C\x93\x31\x04\x9D\x0B\xDA\xB0\x27\x74\x08\xF6\x79\x67\xE5", 16, 0 }, { GCRY_CIPHER_AES, "\x01\xF7\x4A\xD6\x40\x77\xF2\xE7\x04\xC0\xF6\x0A\xDA\x3D\xD5\x23", "\x70\xC3\xDB\x4F\x0D\x26\x36\x84\x00\xA1\x0E\xD0\x5D\x2B\xFF\x5E", 16, "\x23\x4A\x34\x63\xC1\x26\x4A\xC6", 8, "\x1A\x47\xCB\x49\x33", 5, "\xD8\x51\xD5\xBA\xE0", "\x3A\x59\xF2\x38\xA2\x3E\x39\x19\x9D\xC9\x26\x66\x26\xC4\x0F\x80", 16, 0 }, { GCRY_CIPHER_AES, "\xD0\x7C\xF6\xCB\xB7\xF3\x13\xBD\xDE\x66\xB7\x27\xAF\xD3\xC5\xE8", "\x84\x08\xDF\xFF\x3C\x1A\x2B\x12\x92\xDC\x19\x9E\x46\xB7\xD6\x17", 16, "\x33\xCC\xE2\xEA\xBF\xF5\xA7\x9D", 8, "\x48\x1C\x9E\x39\xB1", 5, "\x63\x2A\x9D\x13\x1A", "\xD4\xC1\x68\xA4\x22\x5D\x8E\x1F\xF7\x55\x93\x99\x74\xA7\xBE\xDE", 16, 0 }, { GCRY_CIPHER_AES, "\x35\xB6\xD0\x58\x00\x05\xBB\xC1\x2B\x05\x87\x12\x45\x57\xD2\xC2", "\xFD\xB6\xB0\x66\x76\xEE\xDC\x5C\x61\xD7\x42\x76\xE1\xF8\xE8\x16", 16, "\xAE\xB9\x6E\xAE\xBE\x29\x70\xE9", 8, "\x40\xD0\xC0\x7D\xA5\xE4", 6, "\x07\x1D\xFE\x16\xC6\x75", "\xCB\x06\x77\xE5\x36\xF7\x3A\xFE\x6A\x14\xB7\x4E\xE4\x98\x44\xDD", 16, 0 }, { GCRY_CIPHER_AES, "\xBD\x8E\x6E\x11\x47\x5E\x60\xB2\x68\x78\x4C\x38\xC6\x2F\xEB\x22", "\x6E\xAC\x5C\x93\x07\x2D\x8E\x85\x13\xF7\x50\x93\x5E\x46\xDA\x1B", 16, "\xD4\x48\x2D\x1C\xA7\x8D\xCE\x0F", 8, "\x4D\xE3\xB3\x5C\x3F\xC0\x39\x24\x5B\xD1\xFB\x7D", 12, "\x83\x5B\xB4\xF1\x5D\x74\x3E\x35\x0E\x72\x84\x14", "\xAB\xB8\x64\x4F\xD6\xCC\xB8\x69\x47\xC5\xE1\x05\x90\x21\x0A\x4F", 16, 0 }, { GCRY_CIPHER_AES, "\x7C\x77\xD6\xE8\x13\xBE\xD5\xAC\x98\xBA\xA4\x17\x47\x7A\x2E\x7D", "\x1A\x8C\x98\xDC\xD7\x3D\x38\x39\x3B\x2B\xF1\x56\x9D\xEE\xFC\x19", 16, "\x65\xD2\x01\x79\x90\xD6\x25\x28", 8, "\x8B\x0A\x79\x30\x6C\x9C\xE7\xED\x99\xDA\xE4\xF8\x7F\x8D\xD6\x16\x36", 17, "\x02\x08\x3E\x39\x79\xDA\x01\x48\x12\xF5\x9F\x11\xD5\x26\x30\xDA\x30", "\x13\x73\x27\xD1\x06\x49\xB0\xAA\x6E\x1C\x18\x1D\xB6\x17\xD7\xF2", 16, 0 }, { GCRY_CIPHER_AES, "\x5F\xFF\x20\xCA\xFA\xB1\x19\xCA\x2F\xC7\x35\x49\xE2\x0F\x5B\x0D", "\xDD\xE5\x9B\x97\xD7\x22\x15\x6D\x4D\x9A\xFF\x2B\xC7\x55\x98\x26", 16, "\x54\xB9\xF0\x4E\x6A\x09\x18\x9A", 8, "\x1B\xDA\x12\x2B\xCE\x8A\x8D\xBA\xF1\x87\x7D\x96\x2B\x85\x92\xDD" "\x2D\x56", 18, "\x2E\xC4\x7B\x2C\x49\x54\xA4\x89\xAF\xC7\xBA\x48\x97\xED\xCD\xAE" "\x8C\xC3", "\x3B\x60\x45\x05\x99\xBD\x02\xC9\x63\x82\x90\x2A\xEF\x7F\x83\x2A", 16, 0 }, { GCRY_CIPHER_AES, "\xA4\xA4\x78\x2B\xCF\xFD\x3E\xC5\xE7\xEF\x6D\x8C\x34\xA5\x61\x23", "\xB7\x81\xFC\xF2\xF7\x5F\xA5\xA8\xDE\x97\xA9\xCA\x48\xE5\x22\xEC", 16, "\x89\x9A\x17\x58\x97\x56\x1D\x7E", 8, "\x6C\xF3\x67\x20\x87\x2B\x85\x13\xF6\xEA\xB1\xA8\xA4\x44\x38\xD5" "\xEF\x11", 18, "\x0D\xE1\x8F\xD0\xFD\xD9\x1E\x7A\xF1\x9F\x1D\x8E\xE8\x73\x39\x38" "\xB1\xE8", "\xE7\xF6\xD2\x23\x16\x18\x10\x2F\xDB\x7F\xE5\x5F\xF1\x99\x17\x00", 16, 0 }, { GCRY_CIPHER_AES, "\x83\x95\xFC\xF1\xE9\x5B\xEB\xD6\x97\xBD\x01\x0B\xC7\x66\xAA\xC3", "\x22\xE7\xAD\xD9\x3C\xFC\x63\x93\xC5\x7E\xC0\xB3\xC1\x7D\x6B\x44", 16, "\x12\x67\x35\xFC\xC3\x20\xD2\x5A", 8, "\xCA\x40\xD7\x44\x6E\x54\x5F\xFA\xED\x3B\xD1\x2A\x74\x0A\x65\x9F" "\xFB\xBB\x3C\xEA\xB7", 21, "\xCB\x89\x20\xF8\x7A\x6C\x75\xCF\xF3\x96\x27\xB5\x6E\x3E\xD1\x97" "\xC5\x52\xD2\x95\xA7", "\xCF\xC4\x6A\xFC\x25\x3B\x46\x52\xB1\xAF\x37\x95\xB1\x24\xAB\x6E", 16, 0 }, /* Negative test for bad tag. */ { GCRY_CIPHER_AES, "\x23\x39\x52\xDE\xE4\xD5\xED\x5F\x9B\x9C\x6D\x6F\xF8\x0F\xF4\x78", "\x62\xEC\x67\xF9\xC3\xA4\xA4\x07\xFC\xB2\xA8\xC4\x90\x31\xA8\xB3", 16, "\x6B\xFB\x91\x4F\xD0\x7E\xAE\x6B", 8, "", 0, "", "\x00\x37\x83\x0E\x83\x89\xF2\x7B\x02\x5A\x2D\x65\x27\xE7\x9D\x01", 16, 1 }, /* Test vectors from libtomcrypt. */ { GCRY_CIPHER_AES, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", "", 0, "", 0, "", 0, "", "\x9a\xd0\x7e\x7d\xbf\xf3\x01\xf5\x05\xde\x59\x6b\x96\x15\xdf\xff", 16, 0 }, { GCRY_CIPHER_AES, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16, "", 0, "", 0, "", "\x1c\xe1\x0d\x3e\xff\xd4\xca\xdb\xe2\xe4\x4b\x58\xd6\x0a\xb9\xec", 16, 0 }, { GCRY_CIPHER_AES, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", "", 0, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16, "", 0, "", "\x3a\x69\x8f\x7a\x27\x0e\x51\xb0\xf6\x5b\x3d\x3e\x47\x19\x3c\xff", 16, 0 }, { GCRY_CIPHER_AES, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", 32, "\x29\xd8\x78\xd1\xa3\xbe\x85\x7b\x6f\xb8\xc8\xea\x59\x50\xa7\x78" "\x33\x1f\xbf\x2c\xcf\x33\x98\x6f\x35\xe8\xcf\x12\x1d\xcb\x30\xbc", "\x4f\xbe\x03\x38\xbe\x1c\x8c\x7e\x1d\x7a\xe7\xe4\x5b\x92\xc5\x87", 16, 0 }, { GCRY_CIPHER_AES, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e", 15, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d", 14, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c", 29, "\xdd\x25\xc7\x54\xc5\xb1\x7c\x59\x28\xb6\x9b\x73\x15\x5f\x7b\xb8" "\x88\x8f\xaf\x37\x09\x1a\xd9\x2c\x8a\x24\xdb\x86\x8b", "\x0d\x1a\x14\xe5\x22\x24\xff\xd2\x3a\x05\xfa\x02\xcd\xef\x52\xda", 16, 0 }, }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; unsigned char tag[16]; int i, keylen; gcry_error_t err = 0; size_t pos, poslen, taglen2; int byteNum; if (verbose) fprintf (stderr, " Starting EAX checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); continue; } if (verbose) fprintf (stderr, " checking EAX mode for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_EAX, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_EAX, 0); if (err) { fail ("aes-eax, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("aes-eax, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("aes-eax, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_setiv (hde, tv[i].nonce, tv[i].noncelen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].nonce, tv[i].noncelen); if (err) { fail ("aes-eax, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2); if (err) { fail ("cipher-eax, gcryctl_get_taglen failed (tv %d): %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (taglen2 != 16) { fail ("cipher-eax, gcryctl_get_taglen returned bad length" " (tv %d): got=%zu want=%d\n", i, taglen2, 16); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } for (pos = 0; pos < tv[i].headerlen; pos += step) { poslen = (pos + step < tv[i].headerlen) ? step : tv[i].headerlen - pos; err = gcry_cipher_authenticate(hde, tv[i].header + pos, poslen); if (err) { fail ("aes-eax, gcry_cipher_authenticate (%d) (%lu:%d) failed: " "%s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_authenticate(hdd, tv[i].header + pos, poslen); if (err) { fail ("aes-eax, de gcry_cipher_authenticate (%d) (%lu:%d) failed: " "%s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } for (pos = 0; pos < tv[i].inlen; pos += step) { poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos; err = gcry_cipher_encrypt (hde, out + pos, poslen, tv[i].plaintext + pos, poslen); if (err) { fail ("aes-eax, gcry_cipher_encrypt (%d) (%lu:%d) failed: %s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].out, out, tv[i].inlen)) fail ("aes-eax, encrypt mismatch entry %d (step %d)\n", i, step); for (pos = 0; pos < tv[i].inlen; pos += step) { poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos; err = gcry_cipher_decrypt (hdd, out + pos, poslen, NULL, 0); if (err) { fail ("aes-eax, gcry_cipher_decrypt (%d) (%lu:%d) failed: %s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].plaintext, out, tv[i].inlen)) fail ("aes-eax, decrypt mismatch entry %d (step %d)\n", i, step); taglen2 = tv[i].taglen ? tv[i].taglen : 16; err = gcry_cipher_gettag (hde, out, taglen2); if (err) { if (tv[i].should_fail) goto next_tv; fail ("aes-eax, gcry_cipher_gettag(%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if ((memcmp (tv[i].tag, out, taglen2) != 0) ^ tv[i].should_fail) fail ("aes-eax, encrypt tag mismatch entry %d\n", i); err = gcry_cipher_checktag (hdd, tv[i].tag, taglen2); if (err) { if (tv[i].should_fail) goto next_tv; fail ("aes-eax, gcry_cipher_checktag(%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_reset(hde); if (!err) err = gcry_cipher_reset(hdd); if (err) { fail ("aes-eax, gcry_cipher_reset (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* gcry_cipher_reset clears the IV */ err = gcry_cipher_setiv (hde, tv[i].nonce, tv[i].noncelen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].nonce, tv[i].noncelen); if (err) { fail ("aes-eax, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* this time we authenticate, encrypt and decrypt one byte at a time */ for (byteNum = 0; byteNum < tv[i].headerlen; ++byteNum) { err = gcry_cipher_authenticate(hde, tv[i].header + byteNum, 1); if (err) { fail ("aes-eax, gcry_cipher_authenticate (%d) (byte-buf) failed: " "%s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_authenticate(hdd, tv[i].header + byteNum, 1); if (err) { fail ("aes-eax, de gcry_cipher_authenticate (%d) (byte-buf) " "failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum) { err = gcry_cipher_encrypt (hde, out+byteNum, 1, (tv[i].plaintext) + byteNum, 1); if (err) { fail ("aes-eax, gcry_cipher_encrypt (%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].out, out, tv[i].inlen)) fail ("aes-eax, encrypt mismatch entry %d, (byte-buf)\n", i); /* Test output to larger than 16-byte buffer. */ taglen2 = tv[i].taglen ? tv[i].taglen : 16 + 1; err = gcry_cipher_gettag (hde, tag, taglen2); if (err) { if (tv[i].should_fail) goto next_tv; fail ("aes-eax, gcry_cipher_gettag(%d, %lu) (byte-buf) failed: %s\n", i, (unsigned long) taglen2, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } taglen2 = tv[i].taglen ? tv[i].taglen : 16; if ((memcmp (tv[i].tag, tag, taglen2) != 0) ^ tv[i].should_fail) fail ("aes-eax, encrypt tag mismatch entry %d, (byte-buf)\n", i); for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum) { err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0); if (err) { fail ("aes-eax, gcry_cipher_decrypt (%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].plaintext, out, tv[i].inlen)) fail ("aes-eax, decrypt mismatch entry %d\n", i); err = gcry_cipher_checktag (hdd, tv[i].tag, taglen2); if (err) { if (tv[i].should_fail) goto next_tv; fail ("aes-eax, gcry_cipher_checktag(%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_checktag (hdd, tag, 17); if (!err) { fail ("aes-eax, gcry_cipher_checktag(%d) did not fail for invalid " " tag length of '%d'\n", i, 17); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (tv[i].should_fail) { fail ("aes-eax, negative test succeeded %d\n", i); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } next_tv: gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed EAX checks.\n"); } static void check_eax_cipher (void) { /* Large buffers, no splitting. */ _check_eax_cipher(0xffffffff); /* Split input to one byte buffers. */ _check_eax_cipher(1); /* Split input to 7 byte buffers. */ _check_eax_cipher(7); /* Split input to 16 byte buffers. */ _check_eax_cipher(16); } static void _check_poly1305_cipher (unsigned int step) { static const struct tv { int algo; const char *key; const char *iv; int ivlen; const char *aad; int aadlen; const char *plaintext; int inlen; const char *out; const char *tag; } tv[] = { /* draft-irtf-cfrg-chacha20-poly1305-03 */ { GCRY_CIPHER_CHACHA20, "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a\xf3\x33\x88\x86\x04\xf6\xb5\xf0" "\x47\x39\x17\xc1\x40\x2b\x80\x09\x9d\xca\x5c\xbc\x20\x70\x75\xc0", "\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08", 12, "\xf3\x33\x88\x86\x00\x00\x00\x00\x00\x00\x4e\x91", 12, "\x49\x6e\x74\x65\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20" "\x61\x72\x65\x20\x64\x72\x61\x66\x74\x20\x64\x6f\x63\x75\x6d\x65" "\x6e\x74\x73\x20\x76\x61\x6c\x69\x64\x20\x66\x6f\x72\x20\x61\x20" "\x6d\x61\x78\x69\x6d\x75\x6d\x20\x6f\x66\x20\x73\x69\x78\x20\x6d" "\x6f\x6e\x74\x68\x73\x20\x61\x6e\x64\x20\x6d\x61\x79\x20\x62\x65" "\x20\x75\x70\x64\x61\x74\x65\x64\x2c\x20\x72\x65\x70\x6c\x61\x63" "\x65\x64\x2c\x20\x6f\x72\x20\x6f\x62\x73\x6f\x6c\x65\x74\x65\x64" "\x20\x62\x79\x20\x6f\x74\x68\x65\x72\x20\x64\x6f\x63\x75\x6d\x65" "\x6e\x74\x73\x20\x61\x74\x20\x61\x6e\x79\x20\x74\x69\x6d\x65\x2e" "\x20\x49\x74\x20\x69\x73\x20\x69\x6e\x61\x70\x70\x72\x6f\x70\x72" "\x69\x61\x74\x65\x20\x74\x6f\x20\x75\x73\x65\x20\x49\x6e\x74\x65" "\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20\x61\x73\x20\x72" "\x65\x66\x65\x72\x65\x6e\x63\x65\x20\x6d\x61\x74\x65\x72\x69\x61" "\x6c\x20\x6f\x72\x20\x74\x6f\x20\x63\x69\x74\x65\x20\x74\x68\x65" "\x6d\x20\x6f\x74\x68\x65\x72\x20\x74\x68\x61\x6e\x20\x61\x73\x20" "\x2f\xe2\x80\x9c\x77\x6f\x72\x6b\x20\x69\x6e\x20\x70\x72\x6f\x67" "\x72\x65\x73\x73\x2e\x2f\xe2\x80\x9d", 265, "\x64\xa0\x86\x15\x75\x86\x1a\xf4\x60\xf0\x62\xc7\x9b\xe6\x43\xbd" "\x5e\x80\x5c\xfd\x34\x5c\xf3\x89\xf1\x08\x67\x0a\xc7\x6c\x8c\xb2" "\x4c\x6c\xfc\x18\x75\x5d\x43\xee\xa0\x9e\xe9\x4e\x38\x2d\x26\xb0" "\xbd\xb7\xb7\x3c\x32\x1b\x01\x00\xd4\xf0\x3b\x7f\x35\x58\x94\xcf" "\x33\x2f\x83\x0e\x71\x0b\x97\xce\x98\xc8\xa8\x4a\xbd\x0b\x94\x81" "\x14\xad\x17\x6e\x00\x8d\x33\xbd\x60\xf9\x82\xb1\xff\x37\xc8\x55" "\x97\x97\xa0\x6e\xf4\xf0\xef\x61\xc1\x86\x32\x4e\x2b\x35\x06\x38" "\x36\x06\x90\x7b\x6a\x7c\x02\xb0\xf9\xf6\x15\x7b\x53\xc8\x67\xe4" "\xb9\x16\x6c\x76\x7b\x80\x4d\x46\xa5\x9b\x52\x16\xcd\xe7\xa4\xe9" "\x90\x40\xc5\xa4\x04\x33\x22\x5e\xe2\x82\xa1\xb0\xa0\x6c\x52\x3e" "\xaf\x45\x34\xd7\xf8\x3f\xa1\x15\x5b\x00\x47\x71\x8c\xbc\x54\x6a" "\x0d\x07\x2b\x04\xb3\x56\x4e\xea\x1b\x42\x22\x73\xf5\x48\x27\x1a" "\x0b\xb2\x31\x60\x53\xfa\x76\x99\x19\x55\xeb\xd6\x31\x59\x43\x4e" "\xce\xbb\x4e\x46\x6d\xae\x5a\x10\x73\xa6\x72\x76\x27\x09\x7a\x10" "\x49\xe6\x17\xd9\x1d\x36\x10\x94\xfa\x68\xf0\xff\x77\x98\x71\x30" "\x30\x5b\xea\xba\x2e\xda\x04\xdf\x99\x7b\x71\x4d\x6c\x6f\x2c\x29" "\xa6\xad\x5c\xb4\x02\x2b\x02\x70\x9b", "\xee\xad\x9d\x67\x89\x0c\xbb\x22\x39\x23\x36\xfe\xa1\x85\x1f\x38" }, /* draft-irtf-cfrg-chacha20-poly1305-03 */ { GCRY_CIPHER_CHACHA20, "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", "\x07\x00\x00\x00\x40\x41\x42\x43\x44\x45\x46\x47", 12, "\x50\x51\x52\x53\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7", 12, "Ladies and Gentlemen of the class of '99: If I could offer you " "only one tip for the future, sunscreen would be it.", 114, "\xd3\x1a\x8d\x34\x64\x8e\x60\xdb\x7b\x86\xaf\xbc\x53\xef\x7e\xc2" "\xa4\xad\xed\x51\x29\x6e\x08\xfe\xa9\xe2\xb5\xa7\x36\xee\x62\xd6" "\x3d\xbe\xa4\x5e\x8c\xa9\x67\x12\x82\xfa\xfb\x69\xda\x92\x72\x8b" "\x1a\x71\xde\x0a\x9e\x06\x0b\x29\x05\xd6\xa5\xb6\x7e\xcd\x3b\x36" "\x92\xdd\xbd\x7f\x2d\x77\x8b\x8c\x98\x03\xae\xe3\x28\x09\x1b\x58" "\xfa\xb3\x24\xe4\xfa\xd6\x75\x94\x55\x85\x80\x8b\x48\x31\xd7\xbc" "\x3f\xf4\xde\xf0\x8e\x4b\x7a\x9d\xe5\x76\xd2\x65\x86\xce\xc6\x4b" "\x61\x16", "\x1a\xe1\x0b\x59\x4f\x09\xe2\x6a\x7e\x90\x2e\xcb\xd0\x60\x06\x91" }, }; gcry_cipher_hd_t hde, hdd; unsigned char out[1024]; unsigned char tag[16]; int i, keylen; gcry_error_t err = 0; size_t pos, poslen, taglen2; int byteNum; if (verbose) fprintf (stderr, " Starting POLY1305 checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (verbose) fprintf (stderr, " checking POLY1305 mode for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_POLY1305, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_POLY1305, 0); if (err) { fail ("poly1305, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("poly1305, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("poly1305, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen); if (err) { fail ("poly1305, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2); if (err) { fail ("cipher-poly1305, gcryctl_get_taglen failed (tv %d): %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (taglen2 != 16) { fail ("cipher-poly1305, gcryctl_get_taglen returned bad length" " (tv %d): got=%zu want=%d\n", i, taglen2, 16); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } for (pos = 0; pos < tv[i].aadlen; pos += step) { poslen = (pos + step < tv[i].aadlen) ? step : tv[i].aadlen - pos; err = gcry_cipher_authenticate(hde, tv[i].aad + pos, poslen); if (err) { fail ("poly1305, gcry_cipher_authenticate (%d) (%lu:%d) failed: " "%s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_authenticate(hdd, tv[i].aad + pos, poslen); if (err) { fail ("poly1305, de gcry_cipher_authenticate (%d) (%lu:%d) failed: " "%s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } for (pos = 0; pos < tv[i].inlen; pos += step) { poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos; err = gcry_cipher_encrypt (hde, out + pos, poslen, tv[i].plaintext + pos, poslen); if (err) { fail ("poly1305, gcry_cipher_encrypt (%d) (%lu:%d) failed: %s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].out, out, tv[i].inlen)) fail ("poly1305, encrypt mismatch entry %d (step %d)\n", i, step); for (pos = 0; pos < tv[i].inlen; pos += step) { poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos; err = gcry_cipher_decrypt (hdd, out + pos, poslen, NULL, 0); if (err) { fail ("poly1305, gcry_cipher_decrypt (%d) (%lu:%d) failed: %s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].plaintext, out, tv[i].inlen)) fail ("poly1305, decrypt mismatch entry %d (step %d)\n", i, step); err = gcry_cipher_gettag (hde, out, 16); if (err) { fail ("poly1305, gcry_cipher_gettag(%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].tag, out, 16)) fail ("poly1305, encrypt tag mismatch entry %d\n", i); err = gcry_cipher_checktag (hdd, out, 16); if (err) { fail ("poly1305, gcry_cipher_checktag(%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_reset(hde); if (!err) err = gcry_cipher_reset(hdd); if (err) { fail ("poly1305, gcry_cipher_reset (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* gcry_cipher_reset clears the IV */ err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen); if (err) { fail ("poly1305, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* this time we authenticate, encrypt and decrypt one byte at a time */ for (byteNum = 0; byteNum < tv[i].aadlen; ++byteNum) { err = gcry_cipher_authenticate(hde, tv[i].aad + byteNum, 1); if (err) { fail ("poly1305, gcry_cipher_authenticate (%d) (byte-buf) failed: " "%s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_authenticate(hdd, tv[i].aad + byteNum, 1); if (err) { fail ("poly1305, de gcry_cipher_authenticate (%d) (byte-buf) " "failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum) { err = gcry_cipher_encrypt (hde, out+byteNum, 1, (tv[i].plaintext) + byteNum, 1); if (err) { fail ("poly1305, gcry_cipher_encrypt (%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].out, out, tv[i].inlen)) fail ("poly1305, encrypt mismatch entry %d, (byte-buf)\n", i); err = gcry_cipher_gettag (hde, tag, 16); if (err) { fail ("poly1305, gcry_cipher_gettag(%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].tag, tag, 16)) fail ("poly1305, encrypt tag mismatch entry %d, (byte-buf)\n", i); for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum) { err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0); if (err) { fail ("poly1305, gcry_cipher_decrypt (%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].plaintext, out, tv[i].inlen)) fail ("poly1305, decrypt mismatch entry %d\n", i); err = gcry_cipher_checktag (hdd, tag, 16); if (err) { fail ("poly1305, gcry_cipher_checktag(%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed POLY1305 checks.\n"); } static void check_poly1305_cipher (void) { /* Large buffers, no splitting. */ _check_poly1305_cipher(0xffffffff); /* Split input to one byte buffers. */ _check_poly1305_cipher(1); /* Split input to 7 byte buffers. */ _check_poly1305_cipher(7); /* Split input to 16 byte buffers. */ _check_poly1305_cipher(16); } static void check_ccm_cipher (void) { static const struct tv { int algo; int keylen; const char *key; int noncelen; const char *nonce; int aadlen; const char *aad; int plainlen; const char *plaintext; int cipherlen; const char *ciphertext; } tv[] = { /* RFC 3610 */ { GCRY_CIPHER_AES, /* Packet Vector #1 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x03\x02\x01\x00\xA0\xA1\xA2\xA3\xA4\xA5", 8, "\x00\x01\x02\x03\x04\x05\x06\x07", 23, "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E", 31, "\x58\x8C\x97\x9A\x61\xC6\x63\xD2\xF0\x66\xD0\xC2\xC0\xF9\x89\x80\x6D\x5F\x6B\x61\xDA\xC3\x84\x17\xE8\xD1\x2C\xFD\xF9\x26\xE0"}, { GCRY_CIPHER_AES, /* Packet Vector #2 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x04\x03\x02\x01\xA0\xA1\xA2\xA3\xA4\xA5", 8, "\x00\x01\x02\x03\x04\x05\x06\x07", 24, "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32, "\x72\xC9\x1A\x36\xE1\x35\xF8\xCF\x29\x1C\xA8\x94\x08\x5C\x87\xE3\xCC\x15\xC4\x39\xC9\xE4\x3A\x3B\xA0\x91\xD5\x6E\x10\x40\x09\x16"}, { GCRY_CIPHER_AES, /* Packet Vector #3 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x05\x04\x03\x02\xA0\xA1\xA2\xA3\xA4\xA5", 8, "\x00\x01\x02\x03\x04\x05\x06\x07", 25, "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20", 33, "\x51\xB1\xE5\xF4\x4A\x19\x7D\x1D\xA4\x6B\x0F\x8E\x2D\x28\x2A\xE8\x71\xE8\x38\xBB\x64\xDA\x85\x96\x57\x4A\xDA\xA7\x6F\xBD\x9F\xB0\xC5"}, { GCRY_CIPHER_AES, /* Packet Vector #4 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x06\x05\x04\x03\xA0\xA1\xA2\xA3\xA4\xA5", 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B", 19, "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E", 27, "\xA2\x8C\x68\x65\x93\x9A\x9A\x79\xFA\xAA\x5C\x4C\x2A\x9D\x4A\x91\xCD\xAC\x8C\x96\xC8\x61\xB9\xC9\xE6\x1E\xF1"}, { GCRY_CIPHER_AES, /* Packet Vector #5 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x07\x06\x05\x04\xA0\xA1\xA2\xA3\xA4\xA5", 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B", 20, "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 28, "\xDC\xF1\xFB\x7B\x5D\x9E\x23\xFB\x9D\x4E\x13\x12\x53\x65\x8A\xD8\x6E\xBD\xCA\x3E\x51\xE8\x3F\x07\x7D\x9C\x2D\x93"}, { GCRY_CIPHER_AES, /* Packet Vector #6 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x08\x07\x06\x05\xA0\xA1\xA2\xA3\xA4\xA5", 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B", 21, "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20", 29, "\x6F\xC1\xB0\x11\xF0\x06\x56\x8B\x51\x71\xA4\x2D\x95\x3D\x46\x9B\x25\x70\xA4\xBD\x87\x40\x5A\x04\x43\xAC\x91\xCB\x94"}, { GCRY_CIPHER_AES, /* Packet Vector #7 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x09\x08\x07\x06\xA0\xA1\xA2\xA3\xA4\xA5", 8, "\x00\x01\x02\x03\x04\x05\x06\x07", 23, "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E", 33, "\x01\x35\xD1\xB2\xC9\x5F\x41\xD5\xD1\xD4\xFE\xC1\x85\xD1\x66\xB8\x09\x4E\x99\x9D\xFE\xD9\x6C\x04\x8C\x56\x60\x2C\x97\xAC\xBB\x74\x90"}, { GCRY_CIPHER_AES, /* Packet Vector #8 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x0A\x09\x08\x07\xA0\xA1\xA2\xA3\xA4\xA5", 8, "\x00\x01\x02\x03\x04\x05\x06\x07", 24, "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 34, "\x7B\x75\x39\x9A\xC0\x83\x1D\xD2\xF0\xBB\xD7\x58\x79\xA2\xFD\x8F\x6C\xAE\x6B\x6C\xD9\xB7\xDB\x24\xC1\x7B\x44\x33\xF4\x34\x96\x3F\x34\xB4"}, { GCRY_CIPHER_AES, /* Packet Vector #9 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x0B\x0A\x09\x08\xA0\xA1\xA2\xA3\xA4\xA5", 8, "\x00\x01\x02\x03\x04\x05\x06\x07", 25, "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20", 35, "\x82\x53\x1A\x60\xCC\x24\x94\x5A\x4B\x82\x79\x18\x1A\xB5\xC8\x4D\xF2\x1C\xE7\xF9\xB7\x3F\x42\xE1\x97\xEA\x9C\x07\xE5\x6B\x5E\xB1\x7E\x5F\x4E"}, { GCRY_CIPHER_AES, /* Packet Vector #10 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x0C\x0B\x0A\x09\xA0\xA1\xA2\xA3\xA4\xA5", 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B", 19, "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E", 29, "\x07\x34\x25\x94\x15\x77\x85\x15\x2B\x07\x40\x98\x33\x0A\xBB\x14\x1B\x94\x7B\x56\x6A\xA9\x40\x6B\x4D\x99\x99\x88\xDD"}, { GCRY_CIPHER_AES, /* Packet Vector #11 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x0D\x0C\x0B\x0A\xA0\xA1\xA2\xA3\xA4\xA5", 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B", 20, "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 30, "\x67\x6B\xB2\x03\x80\xB0\xE3\x01\xE8\xAB\x79\x59\x0A\x39\x6D\xA7\x8B\x83\x49\x34\xF5\x3A\xA2\xE9\x10\x7A\x8B\x6C\x02\x2C"}, { GCRY_CIPHER_AES, /* Packet Vector #12 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x0E\x0D\x0C\x0B\xA0\xA1\xA2\xA3\xA4\xA5", 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B", 21, "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20", 31, "\xC0\xFF\xA0\xD6\xF0\x5B\xDB\x67\xF2\x4D\x43\xA4\x33\x8D\x2A\xA4\xBE\xD7\xB2\x0E\x43\xCD\x1A\xA3\x16\x62\xE7\xAD\x65\xD6\xDB"}, { GCRY_CIPHER_AES, /* Packet Vector #13 */ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B", 13, "\x00\x41\x2B\x4E\xA9\xCD\xBE\x3C\x96\x96\x76\x6C\xFA", 8, "\x0B\xE1\xA8\x8B\xAC\xE0\x18\xB1", 23, "\x08\xE8\xCF\x97\xD8\x20\xEA\x25\x84\x60\xE9\x6A\xD9\xCF\x52\x89\x05\x4D\x89\x5C\xEA\xC4\x7C", 31, "\x4C\xB9\x7F\x86\xA2\xA4\x68\x9A\x87\x79\x47\xAB\x80\x91\xEF\x53\x86\xA6\xFF\xBD\xD0\x80\xF8\xE7\x8C\xF7\xCB\x0C\xDD\xD7\xB3"}, { GCRY_CIPHER_AES, /* Packet Vector #14 */ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B", 13, "\x00\x33\x56\x8E\xF7\xB2\x63\x3C\x96\x96\x76\x6C\xFA", 8, "\x63\x01\x8F\x76\xDC\x8A\x1B\xCB", 24, "\x90\x20\xEA\x6F\x91\xBD\xD8\x5A\xFA\x00\x39\xBA\x4B\xAF\xF9\xBF\xB7\x9C\x70\x28\x94\x9C\xD0\xEC", 32, "\x4C\xCB\x1E\x7C\xA9\x81\xBE\xFA\xA0\x72\x6C\x55\xD3\x78\x06\x12\x98\xC8\x5C\x92\x81\x4A\xBC\x33\xC5\x2E\xE8\x1D\x7D\x77\xC0\x8A"}, { GCRY_CIPHER_AES, /* Packet Vector #15 */ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B", 13, "\x00\x10\x3F\xE4\x13\x36\x71\x3C\x96\x96\x76\x6C\xFA", 8, "\xAA\x6C\xFA\x36\xCA\xE8\x6B\x40", 25, "\xB9\x16\xE0\xEA\xCC\x1C\x00\xD7\xDC\xEC\x68\xEC\x0B\x3B\xBB\x1A\x02\xDE\x8A\x2D\x1A\xA3\x46\x13\x2E", 33, "\xB1\xD2\x3A\x22\x20\xDD\xC0\xAC\x90\x0D\x9A\xA0\x3C\x61\xFC\xF4\xA5\x59\xA4\x41\x77\x67\x08\x97\x08\xA7\x76\x79\x6E\xDB\x72\x35\x06"}, { GCRY_CIPHER_AES, /* Packet Vector #16 */ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B", 13, "\x00\x76\x4C\x63\xB8\x05\x8E\x3C\x96\x96\x76\x6C\xFA", 12, "\xD0\xD0\x73\x5C\x53\x1E\x1B\xEC\xF0\x49\xC2\x44", 19, "\x12\xDA\xAC\x56\x30\xEF\xA5\x39\x6F\x77\x0C\xE1\xA6\x6B\x21\xF7\xB2\x10\x1C", 27, "\x14\xD2\x53\xC3\x96\x7B\x70\x60\x9B\x7C\xBB\x7C\x49\x91\x60\x28\x32\x45\x26\x9A\x6F\x49\x97\x5B\xCA\xDE\xAF"}, { GCRY_CIPHER_AES, /* Packet Vector #17 */ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B", 13, "\x00\xF8\xB6\x78\x09\x4E\x3B\x3C\x96\x96\x76\x6C\xFA", 12, "\x77\xB6\x0F\x01\x1C\x03\xE1\x52\x58\x99\xBC\xAE", 20, "\xE8\x8B\x6A\x46\xC7\x8D\x63\xE5\x2E\xB8\xC5\x46\xEF\xB5\xDE\x6F\x75\xE9\xCC\x0D", 28, "\x55\x45\xFF\x1A\x08\x5E\xE2\xEF\xBF\x52\xB2\xE0\x4B\xEE\x1E\x23\x36\xC7\x3E\x3F\x76\x2C\x0C\x77\x44\xFE\x7E\x3C"}, { GCRY_CIPHER_AES, /* Packet Vector #18 */ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B", 13, "\x00\xD5\x60\x91\x2D\x3F\x70\x3C\x96\x96\x76\x6C\xFA", 12, "\xCD\x90\x44\xD2\xB7\x1F\xDB\x81\x20\xEA\x60\xC0", 21, "\x64\x35\xAC\xBA\xFB\x11\xA8\x2E\x2F\x07\x1D\x7C\xA4\xA5\xEB\xD9\x3A\x80\x3B\xA8\x7F", 29, "\x00\x97\x69\xEC\xAB\xDF\x48\x62\x55\x94\xC5\x92\x51\xE6\x03\x57\x22\x67\x5E\x04\xC8\x47\x09\x9E\x5A\xE0\x70\x45\x51"}, { GCRY_CIPHER_AES, /* Packet Vector #19 */ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B", 13, "\x00\x42\xFF\xF8\xF1\x95\x1C\x3C\x96\x96\x76\x6C\xFA", 8, "\xD8\x5B\xC7\xE6\x9F\x94\x4F\xB8", 23, "\x8A\x19\xB9\x50\xBC\xF7\x1A\x01\x8E\x5E\x67\x01\xC9\x17\x87\x65\x98\x09\xD6\x7D\xBE\xDD\x18", 33, "\xBC\x21\x8D\xAA\x94\x74\x27\xB6\xDB\x38\x6A\x99\xAC\x1A\xEF\x23\xAD\xE0\xB5\x29\x39\xCB\x6A\x63\x7C\xF9\xBE\xC2\x40\x88\x97\xC6\xBA"}, { GCRY_CIPHER_AES, /* Packet Vector #20 */ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B", 13, "\x00\x92\x0F\x40\xE5\x6C\xDC\x3C\x96\x96\x76\x6C\xFA", 8, "\x74\xA0\xEB\xC9\x06\x9F\x5B\x37", 24, "\x17\x61\x43\x3C\x37\xC5\xA3\x5F\xC1\xF3\x9F\x40\x63\x02\xEB\x90\x7C\x61\x63\xBE\x38\xC9\x84\x37", 34, "\x58\x10\xE6\xFD\x25\x87\x40\x22\xE8\x03\x61\xA4\x78\xE3\xE9\xCF\x48\x4A\xB0\x4F\x44\x7E\xFF\xF6\xF0\xA4\x77\xCC\x2F\xC9\xBF\x54\x89\x44"}, { GCRY_CIPHER_AES, /* Packet Vector #21 */ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B", 13, "\x00\x27\xCA\x0C\x71\x20\xBC\x3C\x96\x96\x76\x6C\xFA", 8, "\x44\xA3\xAA\x3A\xAE\x64\x75\xCA", 25, "\xA4\x34\xA8\xE5\x85\x00\xC6\xE4\x15\x30\x53\x88\x62\xD6\x86\xEA\x9E\x81\x30\x1B\x5A\xE4\x22\x6B\xFA", 35, "\xF2\xBE\xED\x7B\xC5\x09\x8E\x83\xFE\xB5\xB3\x16\x08\xF8\xE2\x9C\x38\x81\x9A\x89\xC8\xE7\x76\xF1\x54\x4D\x41\x51\xA4\xED\x3A\x8B\x87\xB9\xCE"}, { GCRY_CIPHER_AES, /* Packet Vector #22 */ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B", 13, "\x00\x5B\x8C\xCB\xCD\x9A\xF8\x3C\x96\x96\x76\x6C\xFA", 12, "\xEC\x46\xBB\x63\xB0\x25\x20\xC3\x3C\x49\xFD\x70", 19, "\xB9\x6B\x49\xE2\x1D\x62\x17\x41\x63\x28\x75\xDB\x7F\x6C\x92\x43\xD2\xD7\xC2", 29, "\x31\xD7\x50\xA0\x9D\xA3\xED\x7F\xDD\xD4\x9A\x20\x32\xAA\xBF\x17\xEC\x8E\xBF\x7D\x22\xC8\x08\x8C\x66\x6B\xE5\xC1\x97"}, { GCRY_CIPHER_AES, /* Packet Vector #23 */ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B", 13, "\x00\x3E\xBE\x94\x04\x4B\x9A\x3C\x96\x96\x76\x6C\xFA", 12, "\x47\xA6\x5A\xC7\x8B\x3D\x59\x42\x27\xE8\x5E\x71", 20, "\xE2\xFC\xFB\xB8\x80\x44\x2C\x73\x1B\xF9\x51\x67\xC8\xFF\xD7\x89\x5E\x33\x70\x76", 30, "\xE8\x82\xF1\xDB\xD3\x8C\xE3\xED\xA7\xC2\x3F\x04\xDD\x65\x07\x1E\xB4\x13\x42\xAC\xDF\x7E\x00\xDC\xCE\xC7\xAE\x52\x98\x7D"}, { GCRY_CIPHER_AES, /* Packet Vector #24 */ 16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B", 13, "\x00\x8D\x49\x3B\x30\xAE\x8B\x3C\x96\x96\x76\x6C\xFA", 12, "\x6E\x37\xA6\xEF\x54\x6D\x95\x5D\x34\xAB\x60\x59", 21, "\xAB\xF2\x1C\x0B\x02\xFE\xB8\x8F\x85\x6D\xF4\xA3\x73\x81\xBC\xE3\xCC\x12\x85\x17\xD4", 31, "\xF3\x29\x05\xB8\x8A\x64\x1B\x04\xB9\xC9\xFF\xB5\x8C\xC3\x90\x90\x0F\x3D\xA1\x2A\xB1\x6D\xCE\x9E\x82\xEF\xA1\x6D\xA6\x20\x59"}, /* RFC 5528 */ { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #1 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x03\x02\x01\x00\xA0\xA1\xA2\xA3\xA4\xA5", 8, "\x00\x01\x02\x03\x04\x05\x06\x07", 23, "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E", 31, "\xBA\x73\x71\x85\xE7\x19\x31\x04\x92\xF3\x8A\x5F\x12\x51\xDA\x55\xFA\xFB\xC9\x49\x84\x8A\x0D\xFC\xAE\xCE\x74\x6B\x3D\xB9\xAD"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #2 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x04\x03\x02\x01\xA0\xA1\xA2\xA3\xA4\xA5", 8, "\x00\x01\x02\x03\x04\x05\x06\x07", 24, "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32, "\x5D\x25\x64\xBF\x8E\xAF\xE1\xD9\x95\x26\xEC\x01\x6D\x1B\xF0\x42\x4C\xFB\xD2\xCD\x62\x84\x8F\x33\x60\xB2\x29\x5D\xF2\x42\x83\xE8"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #3 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x05\x04\x03\x02\xA0\xA1\xA2\xA3\xA4\xA5", 8, "\x00\x01\x02\x03\x04\x05\x06\x07", 25, "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20", 33, "\x81\xF6\x63\xD6\xC7\x78\x78\x17\xF9\x20\x36\x08\xB9\x82\xAD\x15\xDC\x2B\xBD\x87\xD7\x56\xF7\x92\x04\xF5\x51\xD6\x68\x2F\x23\xAA\x46"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #4 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x06\x05\x04\x03\xA0\xA1\xA2\xA3\xA4\xA5", 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B", 19, "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E", 27, "\xCA\xEF\x1E\x82\x72\x11\xB0\x8F\x7B\xD9\x0F\x08\xC7\x72\x88\xC0\x70\xA4\xA0\x8B\x3A\x93\x3A\x63\xE4\x97\xA0"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #5 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x07\x06\x05\x04\xA0\xA1\xA2\xA3\xA4\xA5", 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B", 20, "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 28, "\x2A\xD3\xBA\xD9\x4F\xC5\x2E\x92\xBE\x43\x8E\x82\x7C\x10\x23\xB9\x6A\x8A\x77\x25\x8F\xA1\x7B\xA7\xF3\x31\xDB\x09"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #6 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x08\x07\x06\x05\xA0\xA1\xA2\xA3\xA4\xA5", 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B", 21, "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20", 29, "\xFE\xA5\x48\x0B\xA5\x3F\xA8\xD3\xC3\x44\x22\xAA\xCE\x4D\xE6\x7F\xFA\x3B\xB7\x3B\xAB\xAB\x36\xA1\xEE\x4F\xE0\xFE\x28"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #7 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x09\x08\x07\x06\xA0\xA1\xA2\xA3\xA4\xA5", 8, "\x00\x01\x02\x03\x04\x05\x06\x07", 23, "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E", 33, "\x54\x53\x20\x26\xE5\x4C\x11\x9A\x8D\x36\xD9\xEC\x6E\x1E\xD9\x74\x16\xC8\x70\x8C\x4B\x5C\x2C\xAC\xAF\xA3\xBC\xCF\x7A\x4E\xBF\x95\x73"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #8 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x0A\x09\x08\x07\xA0\xA1\xA2\xA3\xA4\xA5", 8, "\x00\x01\x02\x03\x04\x05\x06\x07", 24, "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 34, "\x8A\xD1\x9B\x00\x1A\x87\xD1\x48\xF4\xD9\x2B\xEF\x34\x52\x5C\xCC\xE3\xA6\x3C\x65\x12\xA6\xF5\x75\x73\x88\xE4\x91\x3E\xF1\x47\x01\xF4\x41"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #9 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x0B\x0A\x09\x08\xA0\xA1\xA2\xA3\xA4\xA5", 8, "\x00\x01\x02\x03\x04\x05\x06\x07", 25, "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20", 35, "\x5D\xB0\x8D\x62\x40\x7E\x6E\x31\xD6\x0F\x9C\xA2\xC6\x04\x74\x21\x9A\xC0\xBE\x50\xC0\xD4\xA5\x77\x87\x94\xD6\xE2\x30\xCD\x25\xC9\xFE\xBF\x87"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #10 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x0C\x0B\x0A\x09\xA0\xA1\xA2\xA3\xA4\xA5", 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B", 19, "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E", 29, "\xDB\x11\x8C\xCE\xC1\xB8\x76\x1C\x87\x7C\xD8\x96\x3A\x67\xD6\xF3\xBB\xBC\x5C\xD0\x92\x99\xEB\x11\xF3\x12\xF2\x32\x37"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #11 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x0D\x0C\x0B\x0A\xA0\xA1\xA2\xA3\xA4\xA5", 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B", 20, "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 30, "\x7C\xC8\x3D\x8D\xC4\x91\x03\x52\x5B\x48\x3D\xC5\xCA\x7E\xA9\xAB\x81\x2B\x70\x56\x07\x9D\xAF\xFA\xDA\x16\xCC\xCF\x2C\x4E"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #12 */ 16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", 13, "\x00\x00\x00\x0E\x0D\x0C\x0B\xA0\xA1\xA2\xA3\xA4\xA5", 12, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B", 21, "\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20", 31, "\x2C\xD3\x5B\x88\x20\xD2\x3E\x7A\xA3\x51\xB0\xE9\x2F\xC7\x93\x67\x23\x8B\x2C\xC7\x48\xCB\xB9\x4C\x29\x47\x79\x3D\x64\xAF\x75"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #13 */ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD", 13, "\x00\xA9\x70\x11\x0E\x19\x27\xB1\x60\xB6\xA3\x1C\x1C", 8, "\x6B\x7F\x46\x45\x07\xFA\xE4\x96", 23, "\xC6\xB5\xF3\xE6\xCA\x23\x11\xAE\xF7\x47\x2B\x20\x3E\x73\x5E\xA5\x61\xAD\xB1\x7D\x56\xC5\xA3", 31, "\xA4\x35\xD7\x27\x34\x8D\xDD\x22\x90\x7F\x7E\xB8\xF5\xFD\xBB\x4D\x93\x9D\xA6\x52\x4D\xB4\xF6\x45\x58\xC0\x2D\x25\xB1\x27\xEE"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #14 */ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD", 13, "\x00\x83\xCD\x8C\xE0\xCB\x42\xB1\x60\xB6\xA3\x1C\x1C", 8, "\x98\x66\x05\xB4\x3D\xF1\x5D\xE7", 24, "\x01\xF6\xCE\x67\x64\xC5\x74\x48\x3B\xB0\x2E\x6B\xBF\x1E\x0A\xBD\x26\xA2\x25\x72\xB4\xD8\x0E\xE7", 32, "\x8A\xE0\x52\x50\x8F\xBE\xCA\x93\x2E\x34\x6F\x05\xE0\xDC\x0D\xFB\xCF\x93\x9E\xAF\xFA\x3E\x58\x7C\x86\x7D\x6E\x1C\x48\x70\x38\x06"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #15 */ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD", 13, "\x00\x5F\x54\x95\x0B\x18\xF2\xB1\x60\xB6\xA3\x1C\x1C", 8, "\x48\xF2\xE7\xE1\xA7\x67\x1A\x51", 25, "\xCD\xF1\xD8\x40\x6F\xC2\xE9\x01\x49\x53\x89\x70\x05\xFB\xFB\x8B\xA5\x72\x76\xF9\x24\x04\x60\x8E\x08", 33, "\x08\xB6\x7E\xE2\x1C\x8B\xF2\x6E\x47\x3E\x40\x85\x99\xE9\xC0\x83\x6D\x6A\xF0\xBB\x18\xDF\x55\x46\x6C\xA8\x08\x78\xA7\x90\x47\x6D\xE5"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #16 */ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD", 13, "\x00\xEC\x60\x08\x63\x31\x9A\xB1\x60\xB6\xA3\x1C\x1C", 12, "\xDE\x97\xDF\x3B\x8C\xBD\x6D\x8E\x50\x30\xDA\x4C", 19, "\xB0\x05\xDC\xFA\x0B\x59\x18\x14\x26\xA9\x61\x68\x5A\x99\x3D\x8C\x43\x18\x5B", 27, "\x63\xB7\x8B\x49\x67\xB1\x9E\xDB\xB7\x33\xCD\x11\x14\xF6\x4E\xB2\x26\x08\x93\x68\xC3\x54\x82\x8D\x95\x0C\xC5"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #17 */ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD", 13, "\x00\x60\xCF\xF1\xA3\x1E\xA1\xB1\x60\xB6\xA3\x1C\x1C", 12, "\xA5\xEE\x93\xE4\x57\xDF\x05\x46\x6E\x78\x2D\xCF", 20, "\x2E\x20\x21\x12\x98\x10\x5F\x12\x9D\x5E\xD9\x5B\x93\xF7\x2D\x30\xB2\xFA\xCC\xD7", 28, "\x0B\xC6\xBB\xE2\xA8\xB9\x09\xF4\x62\x9E\xE6\xDC\x14\x8D\xA4\x44\x10\xE1\x8A\xF4\x31\x47\x38\x32\x76\xF6\x6A\x9F"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #18 */ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD", 13, "\x00\x0F\x85\xCD\x99\x5C\x97\xB1\x60\xB6\xA3\x1C\x1C", 12, "\x24\xAA\x1B\xF9\xA5\xCD\x87\x61\x82\xA2\x50\x74", 21, "\x26\x45\x94\x1E\x75\x63\x2D\x34\x91\xAF\x0F\xC0\xC9\x87\x6C\x3B\xE4\xAA\x74\x68\xC9", 29, "\x22\x2A\xD6\x32\xFA\x31\xD6\xAF\x97\x0C\x34\x5F\x7E\x77\xCA\x3B\xD0\xDC\x25\xB3\x40\xA1\xA3\xD3\x1F\x8D\x4B\x44\xB7"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #19 */ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD", 13, "\x00\xC2\x9B\x2C\xAA\xC4\xCD\xB1\x60\xB6\xA3\x1C\x1C", 8, "\x69\x19\x46\xB9\xCA\x07\xBE\x87", 23, "\x07\x01\x35\xA6\x43\x7C\x9D\xB1\x20\xCD\x61\xD8\xF6\xC3\x9C\x3E\xA1\x25\xFD\x95\xA0\xD2\x3D", 33, "\x05\xB8\xE1\xB9\xC4\x9C\xFD\x56\xCF\x13\x0A\xA6\x25\x1D\xC2\xEC\xC0\x6C\xCC\x50\x8F\xE6\x97\xA0\x06\x6D\x57\xC8\x4B\xEC\x18\x27\x68"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #20 */ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD", 13, "\x00\x2C\x6B\x75\x95\xEE\x62\xB1\x60\xB6\xA3\x1C\x1C", 8, "\xD0\xC5\x4E\xCB\x84\x62\x7D\xC4", 24, "\xC8\xC0\x88\x0E\x6C\x63\x6E\x20\x09\x3D\xD6\x59\x42\x17\xD2\xE1\x88\x77\xDB\x26\x4E\x71\xA5\xCC", 34, "\x54\xCE\xB9\x68\xDE\xE2\x36\x11\x57\x5E\xC0\x03\xDF\xAA\x1C\xD4\x88\x49\xBD\xF5\xAE\x2E\xDB\x6B\x7F\xA7\x75\xB1\x50\xED\x43\x83\xC5\xA9"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #21 */ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD", 13, "\x00\xC5\x3C\xD4\xC2\xAA\x24\xB1\x60\xB6\xA3\x1C\x1C", 8, "\xE2\x85\xE0\xE4\x80\x8C\xDA\x3D", 25, "\xF7\x5D\xAA\x07\x10\xC4\xE6\x42\x97\x79\x4D\xC2\xB7\xD2\xA2\x07\x57\xB1\xAA\x4E\x44\x80\x02\xFF\xAB", 35, "\xB1\x40\x45\x46\xBF\x66\x72\x10\xCA\x28\xE3\x09\xB3\x9B\xD6\xCA\x7E\x9F\xC8\x28\x5F\xE6\x98\xD4\x3C\xD2\x0A\x02\xE0\xBD\xCA\xED\x20\x10\xD3"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #22 */ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD", 13, "\x00\xBE\xE9\x26\x7F\xBA\xDC\xB1\x60\xB6\xA3\x1C\x1C", 12, "\x6C\xAE\xF9\x94\x11\x41\x57\x0D\x7C\x81\x34\x05", 19, "\xC2\x38\x82\x2F\xAC\x5F\x98\xFF\x92\x94\x05\xB0\xAD\x12\x7A\x4E\x41\x85\x4E", 29, "\x94\xC8\x95\x9C\x11\x56\x9A\x29\x78\x31\xA7\x21\x00\x58\x57\xAB\x61\xB8\x7A\x2D\xEA\x09\x36\xB6\xEB\x5F\x62\x5F\x5D"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #23 */ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD", 13, "\x00\xDF\xA8\xB1\x24\x50\x07\xB1\x60\xB6\xA3\x1C\x1C", 12, "\x36\xA5\x2C\xF1\x6B\x19\xA2\x03\x7A\xB7\x01\x1E", 20, "\x4D\xBF\x3E\x77\x4A\xD2\x45\xE5\xD5\x89\x1F\x9D\x1C\x32\xA0\xAE\x02\x2C\x85\xD7", 30, "\x58\x69\xE3\xAA\xD2\x44\x7C\x74\xE0\xFC\x05\xF9\xA4\xEA\x74\x57\x7F\x4D\xE8\xCA\x89\x24\x76\x42\x96\xAD\x04\x11\x9C\xE7"}, { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #24 */ 16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD", 13, "\x00\x3B\x8F\xD8\xD3\xA9\x37\xB1\x60\xB6\xA3\x1C\x1C", 12, "\xA4\xD4\x99\xF7\x84\x19\x72\x8C\x19\x17\x8B\x0C", 21, "\x9D\xC9\xED\xAE\x2F\xF5\xDF\x86\x36\xE8\xC6\xDE\x0E\xED\x55\xF7\x86\x7E\x33\x33\x7D", 31, "\x4B\x19\x81\x56\x39\x3B\x0F\x77\x96\x08\x6A\xAF\xB4\x54\xF8\xC3\xF0\x34\xCC\xA9\x66\x94\x5F\x1F\xCE\xA7\xE1\x1B\xEE\x6A\x2F"} }; static const int cut[] = { 0, 1, 8, 10, 16, 19, -1 }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; u64 ctl_params[3]; int split, aadsplit; size_t j, i, keylen, blklen, authlen, taglen2; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting CCM checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); continue; } if (verbose) fprintf (stderr, " checking CCM mode for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); for (j = 0; j < sizeof (cut) / sizeof (cut[0]); j++) { split = cut[j] < 0 ? tv[i].plainlen : cut[j]; if (tv[i].plainlen < split) continue; err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CCM, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CCM, 0); if (err) { fail ("cipher-ccm, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("cipher-ccm, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("cipher-ccm, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } blklen = gcry_cipher_get_algo_blklen(tv[i].algo); if (!blklen) { fail ("cipher-ccm, gcry_cipher_get_algo_blklen failed\n"); return; } err = gcry_cipher_setiv (hde, tv[i].nonce, tv[i].noncelen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].nonce, tv[i].noncelen); if (err) { fail ("cipher-ccm, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } authlen = tv[i].cipherlen - tv[i].plainlen; ctl_params[0] = tv[i].plainlen; /* encryptedlen */ ctl_params[1] = tv[i].aadlen; /* aadlen */ ctl_params[2] = authlen; /* authtaglen */ err = gcry_cipher_ctl (hde, GCRYCTL_SET_CCM_LENGTHS, ctl_params, sizeof(ctl_params)); if (!err) err = gcry_cipher_ctl (hdd, GCRYCTL_SET_CCM_LENGTHS, ctl_params, sizeof(ctl_params)); if (err) { fail ("cipher-ccm, gcry_cipher_ctl GCRYCTL_SET_CCM_LENGTHS " "failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2); if (err) { fail ("cipher-ccm, gcryctl_get_taglen failed (tv %lu): %s\n", (unsigned long) i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (taglen2 != authlen) { fail ("cipher-ccm, gcryctl_get_taglen returned bad length" " (tv %lu): got=%zu want=%zu\n", (unsigned long) i, taglen2, authlen); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } aadsplit = split > tv[i].aadlen ? 0 : split; err = gcry_cipher_authenticate (hde, tv[i].aad, tv[i].aadlen - aadsplit); if (!err) err = gcry_cipher_authenticate (hde, &tv[i].aad[tv[i].aadlen - aadsplit], aadsplit); if (!err) err = gcry_cipher_authenticate (hdd, tv[i].aad, tv[i].aadlen - aadsplit); if (!err) err = gcry_cipher_authenticate (hdd, &tv[i].aad[tv[i].aadlen - aadsplit], aadsplit); if (err) { fail ("cipher-ccm, gcry_cipher_authenticate failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].plaintext, tv[i].plainlen - split); if (!err) err = gcry_cipher_encrypt (hde, &out[tv[i].plainlen - split], MAX_DATA_LEN - (tv[i].plainlen - split), &tv[i].plaintext[tv[i].plainlen - split], split); if (err) { fail ("cipher-ccm, gcry_cipher_encrypt (%lu:%lu) failed: %s\n", (unsigned long) i, (unsigned long) j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_gettag (hde, &out[tv[i].plainlen], authlen); if (err) { fail ("cipher-ccm, gcry_cipher_gettag (%lu:%lu) failed: %s\n", (unsigned long) i, (unsigned long) j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].ciphertext, out, tv[i].cipherlen)) fail ("cipher-ccm, encrypt mismatch entry %lu:%lu\n", (unsigned long) i, (unsigned long) j); err = gcry_cipher_decrypt (hdd, out, tv[i].plainlen - split, NULL, 0); if (!err) err = gcry_cipher_decrypt (hdd, &out[tv[i].plainlen - split], split, NULL, 0); if (err) { fail ("cipher-ccm, gcry_cipher_decrypt (%lu:%lu) failed: %s\n", (unsigned long) i, (unsigned long) j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].plaintext, out, tv[i].plainlen)) fail ("cipher-ccm, decrypt mismatch entry %lu:%lu\n", (unsigned long) i, (unsigned long) j); err = gcry_cipher_checktag (hdd, &out[tv[i].plainlen], authlen); if (err) { fail ("cipher-ccm, gcry_cipher_checktag (%lu:%lu) failed: %s\n", (unsigned long) i, (unsigned long) j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } gcry_cipher_close (hde); gcry_cipher_close (hdd); } } /* Large buffer tests. */ /* Test encoding of aadlen > 0xfeff. */ { static const char key[]={0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47, 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}; static const char iv[]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19}; static const char tag[]={0x9C,0x76,0xE7,0x33,0xD5,0x15,0xB3,0x6C, 0xBA,0x76,0x95,0xF7,0xFB,0x91}; char buf[1024]; size_t enclen = 0x20000; size_t aadlen = 0x20000; size_t taglen = sizeof(tag); err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CCM, 0); if (err) { fail ("cipher-ccm-large, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } err = gcry_cipher_setkey (hde, key, sizeof (key)); if (err) { fail ("cipher-ccm-large, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } err = gcry_cipher_setiv (hde, iv, sizeof (iv)); if (err) { fail ("cipher-ccm-large, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } ctl_params[0] = enclen; /* encryptedlen */ ctl_params[1] = aadlen; /* aadlen */ ctl_params[2] = taglen; /* authtaglen */ err = gcry_cipher_ctl (hde, GCRYCTL_SET_CCM_LENGTHS, ctl_params, sizeof(ctl_params)); if (err) { fail ("cipher-ccm-large, gcry_cipher_ctl GCRYCTL_SET_CCM_LENGTHS " "failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } memset (buf, 0xaa, sizeof(buf)); for (i = 0; i < aadlen; i += sizeof(buf)) { err = gcry_cipher_authenticate (hde, buf, sizeof (buf)); if (err) { fail ("cipher-ccm-large, gcry_cipher_authenticate failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } } for (i = 0; i < enclen; i += sizeof(buf)) { memset (buf, 0xee, sizeof(buf)); err = gcry_cipher_encrypt (hde, buf, sizeof (buf), NULL, 0); if (err) { fail ("cipher-ccm-large, gcry_cipher_encrypt failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } } err = gcry_cipher_gettag (hde, buf, taglen); if (err) { fail ("cipher-ccm-large, gcry_cipher_gettag failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } if (memcmp (buf, tag, taglen) != 0) fail ("cipher-ccm-large, encrypt mismatch entry\n"); gcry_cipher_close (hde); } #if 0 /* Test encoding of aadlen > 0xffffffff. */ { static const char key[]={0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47, 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}; static const char iv[]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19}; static const char tag[]={0x01,0xB2,0xC3,0x4A,0xA6,0x6A,0x07,0x6D, 0xBC,0xBD,0xEA,0x17,0xD3,0x73,0xD7,0xD4}; char buf[1024]; size_t enclen = (size_t)0xffffffff + 1 + 1024; size_t aadlen = (size_t)0xffffffff + 1 + 1024; size_t taglen = sizeof(tag); err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CCM, 0); if (err) { fail ("cipher-ccm-huge, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } err = gcry_cipher_setkey (hde, key, sizeof (key)); if (err) { fail ("cipher-ccm-huge, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } err = gcry_cipher_setiv (hde, iv, sizeof (iv)); if (err) { fail ("cipher-ccm-huge, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } ctl_params[0] = enclen; /* encryptedlen */ ctl_params[1] = aadlen; /* aadlen */ ctl_params[2] = taglen; /* authtaglen */ err = gcry_cipher_ctl (hde, GCRYCTL_SET_CCM_LENGTHS, ctl_params, sizeof(ctl_params)); if (err) { fail ("cipher-ccm-huge, gcry_cipher_ctl GCRYCTL_SET_CCM_LENGTHS failed:" "%s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } memset (buf, 0xaa, sizeof(buf)); for (i = 0; i < aadlen; i += sizeof(buf)) { err = gcry_cipher_authenticate (hde, buf, sizeof (buf)); if (err) { fail ("cipher-ccm-huge, gcry_cipher_authenticate failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } } for (i = 0; i < enclen; i += sizeof(buf)) { memset (buf, 0xee, sizeof(buf)); err = gcry_cipher_encrypt (hde, buf, sizeof (buf), NULL, 0); if (err) { fail ("cipher-ccm-huge, gcry_cipher_encrypt failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } } err = gcry_cipher_gettag (hde, buf, taglen); if (err) { fail ("cipher-ccm-huge, gcry_cipher_gettag failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } if (memcmp (buf, tag, taglen) != 0) fail ("cipher-ccm-huge, encrypt mismatch entry\n"); gcry_cipher_close (hde); } if (verbose) fprintf (stderr, " Completed CCM checks.\n"); #endif } static void do_check_ocb_cipher (int inplace) { /* Note that we use hex strings and not binary strings in TV. That makes it easier to maintain the test vectors. */ static const struct { int algo; int taglen; /* 16, 12, or 8 bytes */ const char *key; /* NULL means "000102030405060708090A0B0C0D0E0F" */ const char *nonce; const char *aad; const char *plain; const char *ciph; } tv[] = { /* The RFC-7253 test vectos*/ { GCRY_CIPHER_AES, 16, NULL, "BBAA99887766554433221100", "", "", "785407BFFFC8AD9EDCC5520AC9111EE6" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA99887766554433221101", "0001020304050607", "0001020304050607", "6820B3657B6F615A5725BDA0D3B4EB3A257C9AF1F8F03009" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA99887766554433221102", "0001020304050607", "", "81017F8203F081277152FADE694A0A00" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA99887766554433221103", "", "0001020304050607", "45DD69F8F5AAE72414054CD1F35D82760B2CD00D2F99BFA9" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA99887766554433221104", "000102030405060708090A0B0C0D0E0F", "000102030405060708090A0B0C0D0E0F", "571D535B60B277188BE5147170A9A22C3AD7A4FF3835B8C5" "701C1CCEC8FC3358" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA99887766554433221105", "000102030405060708090A0B0C0D0E0F", "", "8CF761B6902EF764462AD86498CA6B97" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA99887766554433221106", "", "000102030405060708090A0B0C0D0E0F", "5CE88EC2E0692706A915C00AEB8B2396F40E1C743F52436B" "DF06D8FA1ECA343D" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA99887766554433221107", "000102030405060708090A0B0C0D0E0F1011121314151617", "000102030405060708090A0B0C0D0E0F1011121314151617", "1CA2207308C87C010756104D8840CE1952F09673A448A122" "C92C62241051F57356D7F3C90BB0E07F" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA99887766554433221108", "000102030405060708090A0B0C0D0E0F1011121314151617", "", "6DC225A071FC1B9F7C69F93B0F1E10DE" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA99887766554433221109", "", "000102030405060708090A0B0C0D0E0F1011121314151617", "221BD0DE7FA6FE993ECCD769460A0AF2D6CDED0C395B1C3C" "E725F32494B9F914D85C0B1EB38357FF" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA9988776655443322110A", "000102030405060708090A0B0C0D0E0F1011121314151617" "18191A1B1C1D1E1F", "000102030405060708090A0B0C0D0E0F1011121314151617" "18191A1B1C1D1E1F", "BD6F6C496201C69296C11EFD138A467ABD3C707924B964DE" "AFFC40319AF5A48540FBBA186C5553C68AD9F592A79A4240" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA9988776655443322110B", "000102030405060708090A0B0C0D0E0F1011121314151617" "18191A1B1C1D1E1F", "", "FE80690BEE8A485D11F32965BC9D2A32" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA9988776655443322110C", "", "000102030405060708090A0B0C0D0E0F1011121314151617" "18191A1B1C1D1E1F", "2942BFC773BDA23CABC6ACFD9BFD5835BD300F0973792EF4" "6040C53F1432BCDFB5E1DDE3BC18A5F840B52E653444D5DF" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA9988776655443322110D", "000102030405060708090A0B0C0D0E0F1011121314151617" "18191A1B1C1D1E1F2021222324252627", "000102030405060708090A0B0C0D0E0F1011121314151617" "18191A1B1C1D1E1F2021222324252627", "D5CA91748410C1751FF8A2F618255B68A0A12E093FF45460" "6E59F9C1D0DDC54B65E8628E568BAD7AED07BA06A4A69483" "A7035490C5769E60" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA9988776655443322110E", "000102030405060708090A0B0C0D0E0F1011121314151617" "18191A1B1C1D1E1F2021222324252627", "", "C5CD9D1850C141E358649994EE701B68" }, { GCRY_CIPHER_AES, 16, NULL, "BBAA9988776655443322110F", "", "000102030405060708090A0B0C0D0E0F1011121314151617" "18191A1B1C1D1E1F2021222324252627", "4412923493C57D5DE0D700F753CCE0D1D2D95060122E9F15" "A5DDBFC5787E50B5CC55EE507BCB084E479AD363AC366B95" "A98CA5F3000B1479" }, { GCRY_CIPHER_AES, 12, "0F0E0D0C0B0A09080706050403020100", "BBAA9988776655443322110D", "000102030405060708090A0B0C0D0E0F1011121314151617" "18191A1B1C1D1E1F2021222324252627", "000102030405060708090A0B0C0D0E0F1011121314151617" "18191A1B1C1D1E1F2021222324252627", "1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1" "A0124B0A55BAE884ED93481529C76B6AD0C515F4D1CDD4FD" "AC4F02AA" + }, + { GCRY_CIPHER_AES, 12, "0F0E0D0C0B0A09080706050403020100", + "BBAA9988776655443322110D", + "000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F2021222324252627", + /* test vector for checksumming */ + "01000000000000000000000000000000" + "02000000000000000000000000000000" + "04000000000000000000000000000000" + "08000000000000000000000000000000" + "10000000000000000000000000000000" + "20000000000000000000000000000000" + "40000000000000000000000000000000" + "80000000000000000000000000000000" + "00010000000000000000000000000000" + "00020000000000000000000000000000" + "00040000000000000000000000000000" + "00080000000000000000000000000000" + "00100000000000000000000000000000" + "00200000000000000000000000000000" + "00400000000000000000000000000000" + "00800000000000000000000000000000" + "00000100000000000000000000000000" + "00000200000000000000000000000000" + "00000400000000000000000000000000" + "00000800000000000000000000000000" + "00001000000000000000000000000000" + "00002000000000000000000000000000" + "00004000000000000000000000000000" + "00008000000000000000000000000000" + "00000001000000000000000000000000" + "00000002000000000000000000000000" + "00000004000000000000000000000000" + "00000008000000000000000000000000" + "00000010000000000000000000000000" + "00000020000000000000000000000000" + "00000040000000000000000000000000" + "00000080000000000000000000000000" + "00000000010000000000000000000000" + "00000000020000000000000000000000" + "00000000040000000000000000000000" + "00000000080000000000000000000000" + "00000000100000000000000000000000" + "00000000200000000000000000000000" + "00000000400000000000000000000000" + "00000000800000000000000000000000" + "00000000000100000000000000000000" + "00000000000200000000000000000000" + "00000000000400000000000000000000" + "00000000000800000000000000000000" + "00000000001000000000000000000000" + "00000000002000000000000000000000" + "00000000004000000000000000000000" + "00000000008000000000000000000000", + "01105c6e36f6ac480f022c51e31ed702" + "90fda4b7b783194d4b4be8e4e1e2dff4" + "6a0804d1c5f9f808ea7933e31c063233" + "2bf65a22b20bb13cde3b80b3682ba965" + "b1207c58916f7856fa9968b410e50dee" + "98b35c071163d1b352b9bbccd09fde29" + "b850f40e71a8ae7d2e2d577f5ee39c46" + "7fa28130b50a123c29958e4665dda9a5" + "e0793997f8f19633a96392141d6e0e88" + "77850ed4364065d1d2f8746e2f1d5fd1" + "996cdde03215306503a30e41f58ef3c4" + "400365cfea4fa6381157c12a46598edf" + "18604854462ec66e3d3cf26d4723cb6a" + "9d801095048086a606fdb9192760889b" + "a8ce2e70e1b55a469137a9e2e6734565" + "283cb1e2c74f37e0854d03e33f8ba499" + "ef5d9af4edfce077c6280338f0a64286" + "2e6bc27ebd5a4c91b3778e22631251c8" + "c5bb75a10945597a9d6c274fc82d3338" + "b403a0a549d1375f26e71ef22bce0941" + "93ea87e2ed72fce0546148c351eec3be" + "867bb1b96070c377fff3c98e21562beb" + "475cfe28abcaaedf49981f6599b15140" + "ea6130d24407079f18ba9d4a8960b082" + "b39c57320e2e064f02fde88c23112146" + "1cac3655868aef584714826ee4f361fb" + "e6d692e1589cbb9dd3c74fa628df2a1f" + "3b0029b1d62b7e9978013ed3c793c1dd" + "1f184c8f7022a853cac40b74ac749aa3" + "f33f0d14732dfda0f2c3c20591bf1f5a" + "710ec0d0bca342baa5146068a78ff58c" + "66316312b7a98af35a0f4e92799b4047" + "f047ae61f25c28d232ce5c168cc745d6" + "6da13cb0f9e38a696635dba7a21571cf" + "cd64ec8cc33db7879f59a90d9edd00f6" + "a899e39ab36b9269a3ac04ebad9326bf" + "53cd9b400168a61714cd628a4056d236" + "bd8622c76daa54cb65f5db2fe03bafbe" + "0b23549ae31136f607293e8093a21934" + "74fd5e9c2451b4c8e0499e6ad34fafc8" + "ab77722a282f7f84b14ddebf7e696300" + "c1ef92d4a0263c6cca104530f996e272" + "f58992ff68d642b071a5848dc4acf2ae" + "28fb1f27ae0f297d5136a7a0a4a03e89" + "b588755b8217a1c62773790e69261269" + "19f45daf7b3ccf18e3fc590a9a0e172f" + "033ac4d13c3decc4c62d7de718ace802" + "140452dc850989f6762e3578bbb04be3" + "1a237c599c4649f4e586b2de" } }; gpg_error_t err = 0; gcry_cipher_hd_t hde, hdd; - unsigned char out[MAX_DATA_LEN]; + unsigned char out[1024]; unsigned char tag[16]; int tidx; if (verbose) fprintf (stderr, " Starting OCB checks.\n"); for (tidx = 0; tidx < DIM (tv); tidx++) { char *key, *nonce, *aad, *ciph, *plain; size_t keylen, noncelen, aadlen, ciphlen, plainlen; int taglen; size_t taglen2; if (verbose) fprintf (stderr, " checking OCB mode for %s [%i] (tv %d)\n", gcry_cipher_algo_name (tv[tidx].algo), tv[tidx].algo, tidx); /* Convert to hex strings to binary. */ key = hex2buffer (tv[tidx].key? tv[tidx].key /* */: "000102030405060708090A0B0C0D0E0F", &keylen); nonce = hex2buffer (tv[tidx].nonce, &noncelen); aad = hex2buffer (tv[tidx].aad, &aadlen); plain = hex2buffer (tv[tidx].plain, &plainlen); ciph = hex2buffer (tv[tidx].ciph, &ciphlen); /* Check that our test vectors are sane. */ assert (plainlen <= sizeof out); assert (tv[tidx].taglen <= ciphlen); assert (tv[tidx].taglen <= sizeof tag); err = gcry_cipher_open (&hde, tv[tidx].algo, GCRY_CIPHER_MODE_OCB, 0); if (!err) err = gcry_cipher_open (&hdd, tv[tidx].algo, GCRY_CIPHER_MODE_OCB, 0); if (err) { fail ("cipher-ocb, gcry_cipher_open failed (tv %d): %s\n", tidx, gpg_strerror (err)); return; } /* Set the taglen. For the first handle we do this only for a non-default taglen. For the second handle we check that we can also set to the default taglen. */ taglen = tv[tidx].taglen; if (taglen != 16) { err = gcry_cipher_ctl (hde, GCRYCTL_SET_TAGLEN, &taglen, sizeof taglen); if (err) { fail ("cipher-ocb, gcryctl_set_taglen failed (tv %d): %s\n", tidx, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } err = gcry_cipher_ctl (hdd, GCRYCTL_SET_TAGLEN, &taglen, sizeof taglen); if (err) { fail ("cipher-ocb, gcryctl_set_taglen failed (tv %d): %s\n", tidx, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2); if (err) { fail ("cipher-ocb, gcryctl_get_taglen failed (tv %d): %s\n", tidx, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (taglen2 != tv[tidx].taglen) { fail ("cipher-ocb, gcryctl_get_taglen returned bad length (tv %d): " "got=%zu want=%d\n", tidx, taglen2, tv[tidx].taglen); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_setkey (hde, key, keylen); if (!err) err = gcry_cipher_setkey (hdd, key, keylen); if (err) { fail ("cipher-ocb, gcry_cipher_setkey failed (tv %d): %s\n", tidx, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_setiv (hde, nonce, noncelen); if (!err) err = gcry_cipher_setiv (hdd, nonce, noncelen); if (err) { fail ("cipher-ocb, gcry_cipher_setiv failed (tv %d): %s\n", tidx, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_authenticate (hde, aad, aadlen); if (err) { fail ("cipher-ocb, gcry_cipher_authenticate failed (tv %d): %s\n", tidx, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_final (hde); if (!err) { if (inplace) { memcpy(out, plain, plainlen); err = gcry_cipher_encrypt (hde, out, plainlen, NULL, 0); } else { - err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, + err = gcry_cipher_encrypt (hde, out, sizeof(out), plain, plainlen); } } if (err) { fail ("cipher-ocb, gcry_cipher_encrypt failed (tv %d): %s\n", tidx, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* Check that the encrypt output matches the expected cipher text without the tag (i.e. at the length of plaintext). */ if (memcmp (ciph, out, plainlen)) { mismatch (ciph, plainlen, out, plainlen); fail ("cipher-ocb, encrypt data mismatch (tv %d)\n", tidx); } /* Check that the tag matches TAGLEN bytes from the end of the expected ciphertext. */ err = gcry_cipher_gettag (hde, tag, tv[tidx].taglen); if (err) { fail ("cipher_ocb, gcry_cipher_gettag failed (tv %d): %s\n", tidx, gpg_strerror (err)); } if (memcmp (ciph + ciphlen - tv[tidx].taglen, tag, tv[tidx].taglen)) { mismatch (ciph + ciphlen - tv[tidx].taglen, tv[tidx].taglen, tag, tv[tidx].taglen); fail ("cipher-ocb, encrypt tag mismatch (tv %d)\n", tidx); } err = gcry_cipher_authenticate (hdd, aad, aadlen); if (err) { fail ("cipher-ocb, gcry_cipher_authenticate failed (tv %d): %s\n", tidx, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* Now for the decryption. */ err = gcry_cipher_final (hdd); if (!err) { if (inplace) { err = gcry_cipher_decrypt (hdd, out, plainlen, NULL, 0); } else { - unsigned char tmp[MAX_DATA_LEN]; + unsigned char tmp[sizeof(out)]; memcpy(tmp, out, plainlen); err = gcry_cipher_decrypt (hdd, out, plainlen, tmp, plainlen); } } if (err) { fail ("cipher-ocb, gcry_cipher_decrypt (tv %d) failed: %s\n", tidx, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* We still have TAG from the encryption. */ err = gcry_cipher_checktag (hdd, tag, tv[tidx].taglen); if (err) { fail ("cipher-ocb, gcry_cipher_checktag failed (tv %d): %s\n", tidx, gpg_strerror (err)); } /* Check that the decrypt output matches the original plaintext. */ if (memcmp (plain, out, plainlen)) { mismatch (plain, plainlen, out, plainlen); fail ("cipher-ocb, decrypt data mismatch (tv %d)\n", tidx); } /* Check that gettag also works for decryption. */ err = gcry_cipher_gettag (hdd, tag, tv[tidx].taglen); if (err) { fail ("cipher_ocb, decrypt gettag failed (tv %d): %s\n", tidx, gpg_strerror (err)); } if (memcmp (ciph + ciphlen - tv[tidx].taglen, tag, tv[tidx].taglen)) { mismatch (ciph + ciphlen - tv[tidx].taglen, tv[tidx].taglen, tag, tv[tidx].taglen); fail ("cipher-ocb, decrypt tag mismatch (tv %d)\n", tidx); } gcry_cipher_close (hde); gcry_cipher_close (hdd); xfree (nonce); xfree (aad); xfree (ciph); xfree (plain); xfree (key); } if (verbose) fprintf (stderr, " Completed OCB checks.\n"); } static void check_ocb_cipher_largebuf_split (int algo, int keylen, const char *tagexpect, unsigned int splitpos) { static const unsigned char key[32] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"; static const unsigned char nonce[12] = "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x00\x01\x02\x03"; const size_t buflen = 1024 * 1024 * 2 + 32; unsigned char *inbuf; unsigned char *outbuf; gpg_error_t err = 0; gcry_cipher_hd_t hde, hdd; unsigned char tag[16]; int i; inbuf = xmalloc(buflen); if (!inbuf) { fail ("out-of-memory\n"); return; } outbuf = xmalloc(buflen); if (!outbuf) { fail ("out-of-memory\n"); xfree(inbuf); return; } for (i = 0; i < buflen; i++) - inbuf[i] = 'a'; + inbuf[i] = (i + 181081) * 5039; err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); if (!err) err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0); if (err) { fail ("cipher-ocb, gcry_cipher_open failed (large, algo %d): %s\n", algo, gpg_strerror (err)); goto out_free; } err = gcry_cipher_setkey (hde, key, keylen); if (!err) err = gcry_cipher_setkey (hdd, key, keylen); if (err) { fail ("cipher-ocb, gcry_cipher_setkey failed (large, algo %d): %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); goto out_free; } err = gcry_cipher_setiv (hde, nonce, 12); if (!err) err = gcry_cipher_setiv (hdd, nonce, 12); if (err) { fail ("cipher-ocb, gcry_cipher_setiv failed (large, algo %d): %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); goto out_free; } if (splitpos) { err = gcry_cipher_authenticate (hde, inbuf, splitpos); } if (!err) { err = gcry_cipher_authenticate (hde, inbuf + splitpos, buflen - splitpos); } if (err) { fail ("cipher-ocb, gcry_cipher_authenticate failed (large, algo %d): %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); goto out_free; } if (splitpos) { err = gcry_cipher_encrypt (hde, outbuf, splitpos, inbuf, splitpos); } if (!err) { err = gcry_cipher_final (hde); if (!err) { err = gcry_cipher_encrypt (hde, outbuf + splitpos, buflen - splitpos, inbuf + splitpos, buflen - splitpos); } } if (err) { fail ("cipher-ocb, gcry_cipher_encrypt failed (large, algo %d): %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); goto out_free; } /* Check that the tag matches. */ err = gcry_cipher_gettag (hde, tag, 16); if (err) { fail ("cipher_ocb, gcry_cipher_gettag failed (large, algo %d): %s\n", algo, gpg_strerror (err)); } if (memcmp (tagexpect, tag, 16)) { mismatch (tagexpect, 16, tag, 16); fail ("cipher-ocb, encrypt tag mismatch (large, algo %d)\n", algo); } err = gcry_cipher_authenticate (hdd, inbuf, buflen); if (err) { fail ("cipher-ocb, gcry_cipher_authenticate failed (large, algo %d): %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); goto out_free; } /* Now for the decryption. */ if (splitpos) { err = gcry_cipher_decrypt (hdd, outbuf, splitpos, NULL, 0); } if (!err) { err = gcry_cipher_final (hdd); if (!err) { err = gcry_cipher_decrypt (hdd, outbuf + splitpos, buflen - splitpos, NULL, 0); } } if (err) { fail ("cipher-ocb, gcry_cipher_decrypt (large, algo %d) failed: %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); goto out_free; } /* We still have TAG from the encryption. */ err = gcry_cipher_checktag (hdd, tag, 16); if (err) { fail ("cipher-ocb, gcry_cipher_checktag failed (large, algo %d): %s\n", algo, gpg_strerror (err)); } /* Check that the decrypt output matches the original plaintext. */ if (memcmp (inbuf, outbuf, buflen)) { /*mismatch (inbuf, buflen, outbuf, buflen);*/ fail ("cipher-ocb, decrypt data mismatch (large, algo %d)\n", algo); } /* Check that gettag also works for decryption. */ err = gcry_cipher_gettag (hdd, tag, 16); if (err) { fail ("cipher_ocb, decrypt gettag failed (large, algo %d): %s\n", algo, gpg_strerror (err)); } if (memcmp (tagexpect, tag, 16)) { mismatch (tagexpect, 16, tag, 16); fail ("cipher-ocb, decrypt tag mismatch (large, algo %d)\n", algo); } gcry_cipher_close (hde); gcry_cipher_close (hdd); out_free: xfree(outbuf); xfree(inbuf); } +static void +check_ocb_cipher_checksum (int algo, int keylen) +{ + static const unsigned char key[32] = + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"; + static const unsigned char nonce[12] = + "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x00\x01\x02\x03"; + const size_t buflen = 128 * 16; + unsigned char *inbuf, *outbuf; + gpg_error_t err = 0; + gcry_cipher_hd_t hde, hde2; + unsigned char tag[16]; + unsigned char tag2[16]; + int i; + + inbuf = xmalloc(buflen); + if (!inbuf) + { + fail ("out-of-memory\n"); + return; + } + outbuf = xmalloc(buflen); + if (!inbuf) + { + fail ("out-of-memory\n"); + xfree(inbuf); + return; + } + + memset(inbuf, 0, buflen); + for (i = 0; i < 128; i += 16) + { + unsigned char *blk = inbuf + i; + int bit2set = i / 16; + int byteidx = bit2set / 8; + int bitpos = bit2set % 8; + + blk[byteidx] |= 1 << bitpos; + } + + err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); + if (!err) + err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0); + if (err) + { + fail ("cipher-ocb, gcry_cipher_open failed (checksum, algo %d): %s\n", + algo, gpg_strerror (err)); + goto out_free; + } + + err = gcry_cipher_setkey (hde, key, keylen); + if (!err) + err = gcry_cipher_setkey (hde2, key, keylen); + if (err) + { + fail ("cipher-ocb, gcry_cipher_setkey failed (checksum, algo %d): %s\n", + algo, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hde2); + goto out_free; + } + + err = gcry_cipher_setiv (hde, nonce, 12); + if (!err) + err = gcry_cipher_setiv (hde2, nonce, 12); + if (err) + { + fail ("cipher-ocb, gcry_cipher_setiv failed (checksum, algo %d): %s\n", + algo, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hde2); + goto out_free; + } + + err = gcry_cipher_final (hde); + if (!err) + { + err = gcry_cipher_encrypt (hde, outbuf, buflen, inbuf, buflen); + } + for (i = 0; i < buflen && !err; i += 16) + { + if (i + 16 == buflen) + err = gcry_cipher_final (hde2); + if (!err) + err = gcry_cipher_encrypt (hde2, outbuf + i, 16, inbuf + i, 16); + } + + if (err) + { + fail ("cipher-ocb, gcry_cipher_encrypt failed (checksum, algo %d): %s\n", + algo, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hde2); + goto out_free; + } + + /* Check that the tag matches. */ + err = gcry_cipher_gettag (hde, tag, 16); + if (err) + { + fail ("cipher_ocb, gcry_cipher_gettag failed (checksum, algo %d): %s\n", + algo, gpg_strerror (err)); + } + err = gcry_cipher_gettag (hde2, tag2, 16); + if (err) + { + fail ("cipher_ocb, gcry_cipher_gettag failed (checksum2, algo %d): %s\n", + algo, gpg_strerror (err)); + } + if (memcmp (tag, tag2, 16)) + { + mismatch (tag, 16, tag2, 16); + fail ("cipher-ocb, encrypt tag mismatch (checksum, algo %d)\n", algo); + } + + gcry_cipher_close (hde); + gcry_cipher_close (hde2); + +out_free: + xfree(inbuf); + xfree(outbuf); +} + + static void check_ocb_cipher_largebuf (int algo, int keylen, const char *tagexpect) { unsigned int split; for (split = 0; split < 32 * 16; split = split * 2 + 16) { check_ocb_cipher_largebuf_split(algo, keylen, tagexpect, split); } + + check_ocb_cipher_checksum(algo, keylen); } static void check_ocb_cipher_splitaad (void) { const char t_nonce[] = ("BBAA9988776655443322110D"); const char t_plain[] = ("000102030405060708090A0B0C0D0E0F1011121314151617" "18191A1B1C1D1E1F2021222324252627"); const char t_ciph[] = ("D5CA91748410C1751FF8A2F618255B68A0A12E093FF45460" "6E59F9C1D0DDC54B65E8628E568BAD7AED07BA06A4A69483" "A7035490C5769E60"); struct { const char *aad0; const char *aad1; const char *aad2; const char *aad3; } tv[] = { { "000102030405060708090A0B0C0D0E0F" "101112131415161718191A1B1C1D1E1F2021222324252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "2021222324252627" }, { "000102030405060708090A0B0C0D0E0F", "1011121314151617", "18191A1B1C1D1E1F", "2021222324252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "20", "21222324252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "2021", "222324252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "202122", "2324252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "20212223", "24252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "2021222324", "252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "202122232425", "2627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "20212223242526" "27" }, { "000102030405060708090A0B0C0D0E0F", "1011121314151617", "18191A1B1C1D1E1F2021222324252627" }, { "00", "0102030405060708090A0B0C0D0E0F", "1011121314151617", "18191A1B1C1D1E1F2021222324252627" }, { "0001", "02030405060708090A0B0C0D0E0F", "1011121314151617", "18191A1B1C1D1E1F2021222324252627" }, { "000102030405060708090A0B0C0D", "0E0F", "1011121314151617", "18191A1B1C1D1E1F2021222324252627" }, { "000102030405060708090A0B0C0D0E", "0F", "1011121314151617", "18191A1B1C1D1E1F2021222324252627" }, { "000102030405060708090A0B0C0D0E", "0F101112131415161718191A1B1C1D1E1F20212223242526", "27" } }; gpg_error_t err = 0; gcry_cipher_hd_t hde; unsigned char out[MAX_DATA_LEN]; unsigned char tag[16]; int tidx; char *key, *nonce, *ciph, *plain; size_t keylen, noncelen, ciphlen, plainlen; int i; /* Convert to hex strings to binary. */ key = hex2buffer ("000102030405060708090A0B0C0D0E0F", &keylen); nonce = hex2buffer (t_nonce, &noncelen); plain = hex2buffer (t_plain, &plainlen); ciph = hex2buffer (t_ciph, &ciphlen); /* Check that our test vectors are sane. */ assert (plainlen <= sizeof out); assert (16 <= ciphlen); assert (16 <= sizeof tag); for (tidx = 0; tidx < DIM (tv); tidx++) { char *aad[4]; size_t aadlen[4]; if (verbose) fprintf (stderr, " checking OCB aad split (tv %d)\n", tidx); aad[0] = tv[tidx].aad0? hex2buffer (tv[tidx].aad0, aadlen+0) : NULL; aad[1] = tv[tidx].aad1? hex2buffer (tv[tidx].aad1, aadlen+1) : NULL; aad[2] = tv[tidx].aad2? hex2buffer (tv[tidx].aad2, aadlen+2) : NULL; aad[3] = tv[tidx].aad3? hex2buffer (tv[tidx].aad3, aadlen+3) : NULL; err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OCB, 0); if (err) { fail ("cipher-ocb-splitadd, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } err = gcry_cipher_setkey (hde, key, keylen); if (err) { fail ("cipher-ocb-splitaad, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } err = gcry_cipher_setiv (hde, nonce, noncelen); if (err) { fail ("cipher-ocb-splitaad, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } for (i=0; i < DIM (aad); i++) { if (!aad[i]) continue; err = gcry_cipher_authenticate (hde, aad[i], aadlen[i]); if (err) { fail ("cipher-ocb-splitaad," " gcry_cipher_authenticate failed (tv=%d,i=%d): %s\n", tidx, i, gpg_strerror (err)); gcry_cipher_close (hde); return; } } err = gcry_cipher_final (hde); if (!err) err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, plain, plainlen); if (err) { fail ("cipher-ocb-splitaad, gcry_cipher_encrypt failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } /* Check that the encrypt output matches the expected cipher text without the tag (i.e. at the length of plaintext). */ if (memcmp (ciph, out, plainlen)) { mismatch (ciph, plainlen, out, plainlen); fail ("cipher-ocb-splitaad, encrypt data mismatch\n"); } /* Check that the tag matches TAGLEN bytes from the end of the expected ciphertext. */ err = gcry_cipher_gettag (hde, tag, 16); if (err) { fail ("cipher-ocb-splitaad, gcry_cipher_gettag failed: %s\n", gpg_strerror (err)); } if (memcmp (ciph + ciphlen - 16, tag, 16)) { mismatch (ciph + ciphlen - 16, 16, tag, 16); fail ("cipher-ocb-splitaad, encrypt tag mismatch\n"); } gcry_cipher_close (hde); xfree (aad[0]); xfree (aad[1]); xfree (aad[2]); xfree (aad[3]); } xfree (nonce); xfree (ciph); xfree (plain); xfree (key); } static void check_ocb_cipher (void) { /* Check OCB cipher with separate destination and source buffers for * encryption/decryption. */ do_check_ocb_cipher(0); /* Check OCB cipher with inplace encrypt/decrypt. */ do_check_ocb_cipher(1); /* Check large buffer encryption/decryption. */ check_ocb_cipher_largebuf(GCRY_CIPHER_AES, 16, - "\xf5\xf3\x12\x7d\x58\x2d\x96\xe8" - "\x33\xfd\x7a\x4f\x42\x60\x5d\x20"); + "\xc1\x5b\xf1\x80\xa4\xd5\xea\xfd\xae\x17\xa6\xcd\x6b\x10\xa8\xea"); check_ocb_cipher_largebuf(GCRY_CIPHER_AES256, 32, - "\xfa\x26\xa5\xbf\xf6\x7d\x3a\x8d" - "\xfe\x96\x67\xc9\xc8\x41\x03\x51"); + "\x2b\xb7\x25\x6b\x77\xc7\xfb\x21\x5c\xc9\x6c\x36\x17\x1a\x1a\xd5"); check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA128, 16, - "\x28\x23\x38\x45\x2b\xfd\x42\x45" - "\x43\x64\x7e\x67\x7f\xf4\x8b\xcd"); + "\xe0\xae\x3f\x29\x3a\xee\xd8\xe3\xf2\x20\xc1\xa2\xd8\x72\x12\xd9"); check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA192, 24, - "\xee\xca\xe5\x39\x27\x2d\x33\xe7" - "\x79\x74\xb0\x1d\x37\x12\xd5\x6c"); + "\xd7\x98\x71\xcf\x19\x5c\xa3\x3d\x6c\xfc\xc9\xbe\x9f\x13\x6b\xbd"); check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA256, 32, - "\x39\x39\xd0\x2d\x05\x68\x74\xee" - "\x18\x6b\xea\x3d\x0b\xd3\x58\xae"); + "\x03\xf6\xec\x1a\x0e\xae\x66\x24\x2b\xba\x26\x0f\xb3\xb3\x1f\xb9"); check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 16, - "\x63\xe3\x0e\xb9\x11\x6f\x14\xba" - "\x79\xe4\xa7\x9e\xad\x3c\x02\x0c"); + "\x1c\xf9\xc7\xfc\x3a\x32\xac\xc7\x5e\x0a\xc2\x5c\x90\xd6\xf6\xf9"); check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 32, - "\xf6\xd4\xfe\x4e\x50\x85\x13\x59" - "\x69\x0e\x4c\x67\x3e\xdd\x47\x90"); + "\x53\x02\xc8\x0d\x4e\x9a\x44\x9e\x43\xd4\xaa\x06\x30\x93\xcc\x16"); check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT128, 16, - "\x3c\xfb\x66\x14\x3c\xc8\x6c\x67" - "\x26\xb8\x23\xeb\xaf\x43\x98\x69"); + "\xd3\x64\xac\x40\x48\x88\x77\xe2\x41\x26\x4c\xde\x21\x29\x21\x8d"); check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT192, 24, - "\x5e\x62\x27\xc5\x32\xc3\x1d\xe6" - "\x2e\x65\xe7\xd6\xfb\x05\xd7\xb2"); + "\x99\xeb\x35\xb0\x62\x4e\x7b\xf1\x5e\x9f\xed\x32\x78\x90\x0b\xd0"); check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT256, 32, - "\xe7\x8b\xe6\xd4\x2f\x7a\x36\x4c" - "\xba\xee\x20\xe2\x68\xf4\xcb\xcc"); + "\x71\x66\x2f\x68\xbf\xdd\xcc\xb1\xbf\x81\x56\x5f\x01\x73\xeb\x44"); /* Check that the AAD data is correctly buffered. */ check_ocb_cipher_splitaad (); } static void do_check_xts_cipher (int inplace) { /* Note that we use hex strings and not binary strings in TV. That makes it easier to maintain the test vectors. */ static const struct { int algo; const char *key; /* NULL means "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F" */ const char *iv; const char *plain; const char *ciph; } tv[] = { /* CAVS; hex/XTSGenAES128.rsp; COUNT=100 */ { GCRY_CIPHER_AES, "bcb6613c495de4bdad9c19f04e4b3915f9ecb379e1a575b633337e934fca1050", "64981173159d58ac355a20120c8e81f1", "189acacee06dfa7c94484c7dae59e166", "7900191d0f19a97668fdba9def84eedc" }, /* CAVS; hex/XTSGenAES128.rsp; COUNT=101 */ { GCRY_CIPHER_AES, "b7b93f516aef295eff3a29d837cf1f135347e8a21dae616ff5062b2e8d78ce5e", "873edea653b643bd8bcf51403197ed14", "236f8a5b58dd55f6194ed70c4ac1a17f1fe60ec9a6c454d087ccb77d6b638c47", "22e6a3c6379dcf7599b052b5a749c7f78ad8a11b9f1aa9430cf3aef445682e19" }, /* CAVS; hex/XTSGenAES128.rsp; COUNT=301 */ { GCRY_CIPHER_AES, "394c97881abd989d29c703e48a72b397a7acf51b59649eeea9b33274d8541df4", "4b15c684a152d485fe9937d39b168c29", "2f3b9dcfbae729583b1d1ffdd16bb6fe2757329435662a78f0", "f3473802e38a3ffef4d4fb8e6aa266ebde553a64528a06463e" }, /* CAVS; hex/XTSGenAES128.rsp; COUNT=500 */ { GCRY_CIPHER_AES, "783a83ec52a27405dff9de4c57f9c979b360b6a5df88d67ec1a052e6f582a717", "886e975b29bdf6f0c01bb47f61f6f0f5", "b04d84da856b9a59ce2d626746f689a8051dacd6bce3b990aa901e4030648879", "f941039ebab8cac39d59247cbbcb4d816c726daed11577692c55e4ac6d3e6820" }, /* CAVS; hex/XTSGenAES256.rsp; COUNT=1 */ { GCRY_CIPHER_AES256, "1ea661c58d943a0e4801e42f4b0947149e7f9f8e3e68d0c7505210bd311a0e7c" "d6e13ffdf2418d8d1911c004cda58da3d619b7e2b9141e58318eea392cf41b08", "adf8d92627464ad2f0428e84a9f87564", "2eedea52cd8215e1acc647e810bbc3642e87287f8d2e57e36c0a24fbc12a202e", "cbaad0e2f6cea3f50b37f934d46a9b130b9d54f07e34f36af793e86f73c6d7db" }, /* CAVS; hex/XTSGenAES256.rsp; COUNT=101 */ { GCRY_CIPHER_AES256, "266c336b3b01489f3267f52835fd92f674374b88b4e1ebd2d36a5f457581d9d0" "42c3eef7b0b7e5137b086496b4d9e6ac658d7196a23f23f036172fdb8faee527", "06b209a7a22f486ecbfadb0f3137ba42", "ca7d65ef8d3dfad345b61ccddca1ad81de830b9e86c7b426d76cb7db766852d9" "81c6b21409399d78f42cc0b33a7bbb06", "c73256870cc2f4dd57acc74b5456dbd776912a128bc1f77d72cdebbf270044b7" "a43ceed29025e1e8be211fa3c3ed002d" }, /* CAVS; hex/XTSGenAES256.rsp; COUNT=401 */ { GCRY_CIPHER_AES256, "33e89e817ff8d037d6ac5a2296657503f20885d94c483e26449066bd9284d130" "2dbdbb4b66b6b9f4687f13dd028eb6aa528ca91deb9c5f40db93218806033801", "a78c04335ab7498a52b81ed74b48e6cf", "14c3ac31291b075f40788247c3019e88c7b40bac3832da45bbc6c4fe7461371b" "4dfffb63f71c9f8edb98f28ff4f33121", "dead7e587519bc78c70d99279fbe3d9b1ad13cdaae69824e0ab8135413230bfd" "b13babe8f986fbb30d46ab5ec56b916e" }, /* From https://github.com/heisencoder/XTS-AES/blob/master/testvals/ */ { GCRY_CIPHER_AES, "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0", "9a785634120000000000000000000000", "000102030405060708090a0b0c0d0e0f10", "7fb2e8beccbb5c118aa52ddca31220bb1b" }, { GCRY_CIPHER_AES, "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0", "9a785634120000000000000000000000", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e", "d05bc090a8e04f1b3d3ecdd5baec0fd4edbf9dace45d6f6a7306e64be5dd82" }, { GCRY_CIPHER_AES, "2718281828459045235360287471352631415926535897932384626433832795", "00000000000000000000000000000000", "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F" "20212223", "27A7479BEFA1D476489F308CD4CFA6E288F548E5C4239F91712A587E2B05AC3D" "A96E4BBE" }, { GCRY_CIPHER_AES256, "2718281828459045235360287471352662497757247093699959574966967627" "3141592653589793238462643383279502884197169399375105820974944592", "11000000000000000000000000000000", "3A060A8CAD115A6F44572E3759E43C8F8832FEDC28A8E35B357B5CF3EDBEF788" "CAD8BFCB23", "6D1C78A8BAD91DB2924C507CCEDE835F5BADD157DA0AF55C98BBC28CF676F9FA" "61618FA696" }, { GCRY_CIPHER_AES256, "2718281828459045235360287471352662497757247093699959574966967627" "3141592653589793238462643383279502884197169399375105820974944592", "11000000000000000000000000000000", "3A060A8CAD115A6F44572E3759E43C8F8832FEDC28A8E35B357B5CF3EDBEF788" "CAD8BFCB23", "6D1C78A8BAD91DB2924C507CCEDE835F5BADD157DA0AF55C98BBC28CF676F9FA" "61618FA696" }, { GCRY_CIPHER_AES, "e0e1e2e3e4e5e6e7e8e9eaebecedeeefc0c1c2c3c4c5c6c7c8c9cacbcccdcecf", "21436587a90000000000000000000000", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" "0001020304050607", "38b45812ef43a05bd957e545907e223b954ab4aaf088303ad910eadf14b42be6" "8b2461149d8c8ba85f992be970bc621f1b06573f63e867bf5875acafa04e42cc" "bd7bd3c2a0fb1fff791ec5ec36c66ae4ac1e806d81fbf709dbe29e471fad3854" "9c8e66f5345d7c1eb94f405d1ec785cc6f6a68f6254dd8339f9d84057e01a177" "41990482999516b5611a38f41bb6478e6f173f320805dd71b1932fc333cb9ee3" "9936beea9ad96fa10fb4112b901734ddad40bc1878995f8e11aee7d141a2f5d4" "8b7a4e1e7f0b2c04830e69a4fd1378411c2f287edf48c6c4e5c247a19680f7fe" "41cefbd49b582106e3616cbbe4dfb2344b2ae9519391f3e0fb4922254b1d6d2d" "19c6d4d537b3a26f3bcc51588b32f3eca0829b6a5ac72578fb814fb43cf80d64" "a233e3f997a3f02683342f2b33d25b492536b93becb2f5e1a8b82f5b88334272" "9e8ae09d16938841a21a97fb543eea3bbff59f13c1a18449e398701c1ad51648" "346cbc04c27bb2da3b93a1372ccae548fb53bee476f9e9c91773b1bb19828394" "d55d3e1a20ed69113a860b6829ffa847224604435070221b257e8dff783615d2" "cae4803a93aa4334ab482a0afac9c0aeda70b45a481df5dec5df8cc0f423c77a" "5fd46cd312021d4b438862419a791be03bb4d97c0e59578542531ba466a83baf" "92cefc151b5cc1611a167893819b63fb37ec662bc0fc907db74a94468a55a7bc" "8a6b18e86de60290" }, { GCRY_CIPHER_AES256, "2718281828459045235360287471352662497757247093699959574966967627" "3141592653589793238462643383279502884197169399375105820974944592", "ffffffff000000000000000000000000", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "bf53d2dade78e822a4d949a9bc6766b01b06a8ef70d26748c6a7fc36d80ae4c5" "520f7c4ab0ac8544424fa405162fef5a6b7f229498063618d39f0003cb5fb8d1" "c86b643497da1ff945c8d3bedeca4f479702a7a735f043ddb1d6aaade3c4a0ac" "7ca7f3fa5279bef56f82cd7a2f38672e824814e10700300a055e1630b8f1cb0e" "919f5e942010a416e2bf48cb46993d3cb6a51c19bacf864785a00bc2ecff15d3" "50875b246ed53e68be6f55bd7e05cfc2b2ed6432198a6444b6d8c247fab941f5" "69768b5c429366f1d3f00f0345b96123d56204c01c63b22ce78baf116e525ed9" "0fdea39fa469494d3866c31e05f295ff21fea8d4e6e13d67e47ce722e9698a1c" "1048d68ebcde76b86fcf976eab8aa9790268b7068e017a8b9b749409514f1053" "027fd16c3786ea1bac5f15cb79711ee2abe82f5cf8b13ae73030ef5b9e4457e7" "5d1304f988d62dd6fc4b94ed38ba831da4b7634971b6cd8ec325d9c61c00f1df" "73627ed3745a5e8489f3a95c69639c32cd6e1d537a85f75cc844726e8a72fc00" "77ad22000f1d5078f6b866318c668f1ad03d5a5fced5219f2eabbd0aa5c0f460" "d183f04404a0d6f469558e81fab24a167905ab4c7878502ad3e38fdbe62a4155" "6cec37325759533ce8f25f367c87bb5578d667ae93f9e2fd99bcbc5f2fbba88c" "f6516139420fcff3b7361d86322c4bd84c82f335abb152c4a93411373aaa8220" } }; gpg_error_t err = 0; gcry_cipher_hd_t hde, hdd; int tidx; int got_err = 0; if (verbose) fprintf (stderr, " Starting XTS checks.\n"); for (tidx = 0; !got_err && tidx < DIM (tv); tidx++) { const char *hexkey = tv[tidx].key; char *key, *iv, *ciph, *plain, *out; size_t keylen, ivlen, ciphlen, plainlen, outlen; if (verbose) fprintf (stderr, " checking XTS mode for %s [%i] (tv %d)\n", gcry_cipher_algo_name (tv[tidx].algo), tv[tidx].algo, tidx); if (!hexkey) hexkey = "000102030405060708090A0B0C0D0E0F" "101112131415161718191A1B1C1D1E1F"; /* Convert to hex strings to binary. */ key = hex2buffer (hexkey, &keylen); iv = hex2buffer (tv[tidx].iv, &ivlen); plain = hex2buffer (tv[tidx].plain, &plainlen); ciph = hex2buffer (tv[tidx].ciph, &ciphlen); outlen = plainlen + 5; out = xmalloc (outlen); assert (plainlen == ciphlen); assert (plainlen <= outlen); assert (out); err = gcry_cipher_open (&hde, tv[tidx].algo, GCRY_CIPHER_MODE_XTS, 0); if (!err) err = gcry_cipher_open (&hdd, tv[tidx].algo, GCRY_CIPHER_MODE_XTS, 0); if (err) { fail ("cipher-xts, gcry_cipher_open failed (tv %d): %s\n", tidx, gpg_strerror (err)); return; } err = gcry_cipher_setkey (hde, key, keylen); if (err && in_fips_mode && memcmp(key, key + keylen/2, keylen/2) == 0) { /* Since both halves of key are the same, fail to set key in FIPS mode is expected. */ goto next_tv; } if (!err) err = gcry_cipher_setkey (hdd, key, keylen); if (err) { fail ("cipher-xts, gcry_cipher_setkey failed (tv %d): %s\n", tidx, gpg_strerror (err)); goto err_out; } err = gcry_cipher_setiv (hde, iv, ivlen); if (!err) err = gcry_cipher_setiv (hdd, iv, ivlen); if (err) { fail ("cipher-xts, gcry_cipher_setiv failed (tv %d): %s\n", tidx, gpg_strerror (err)); goto err_out; } if (inplace) { memcpy(out, plain, plainlen); err = gcry_cipher_encrypt (hde, out, plainlen, NULL, 0); } else { err = gcry_cipher_encrypt (hde, out, outlen, plain, plainlen); } if (err) { fail ("cipher-xts, gcry_cipher_encrypt failed (tv %d): %s\n", tidx, gpg_strerror (err)); goto err_out; } /* Check that the encrypt output matches the expected cipher text. */ if (memcmp (ciph, out, plainlen)) { mismatch (ciph, plainlen, out, plainlen); fail ("cipher-xts, encrypt data mismatch (tv %d)\n", tidx); } /* Now for the decryption. */ if (inplace) { err = gcry_cipher_decrypt (hdd, out, plainlen, NULL, 0); } else { memcpy(ciph, out, ciphlen); err = gcry_cipher_decrypt (hdd, out, plainlen, ciph, ciphlen); } if (err) { fail ("cipher-xts, gcry_cipher_decrypt (tv %d) failed: %s\n", tidx, gpg_strerror (err)); goto err_out; } /* Check that the decrypt output matches the expected plain text. */ if (memcmp (plain, out, plainlen)) { mismatch (plain, plainlen, out, plainlen); fail ("cipher-xts, decrypt data mismatch (tv %d)\n", tidx); } if (0) { err_out: got_err = 1; } next_tv: gcry_cipher_close (hde); gcry_cipher_close (hdd); xfree (iv); xfree (ciph); xfree (plain); xfree (key); xfree (out); } if (verbose) fprintf (stderr, " Completed XTS checks.\n"); } static void check_xts_cipher (void) { /* Check XTS cipher with separate destination and source buffers for * encryption/decryption. */ do_check_xts_cipher(0); /* Check XTS cipher with inplace encrypt/decrypt. */ do_check_xts_cipher(1); } static void check_gost28147_cipher (void) { #if USE_GOST28147 static const struct { char key[MAX_DATA_LEN]; const char *oid; unsigned char plaintext[MAX_DATA_LEN]; int inlen; char out[MAX_DATA_LEN]; } tv[] = { { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.7.1.2.5.1.1", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\xce\x5a\x5e\xd7\xe0\x57\x7a\x5f", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.31.0", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\x98\x56\xcf\x8b\xfc\xc2\x82\xf4", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.31.1", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\x66\x81\x84\xae\xdc\x48\xc9\x17", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.31.2", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\xdb\xee\x81\x14\x7b\x74\xb0\xf2", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.31.3", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\x31\xa3\x85\x9d\x0a\xee\xb8\x0e", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.31.4", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\xb1\x32\x3e\x0b\x21\x73\xcb\xd1", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.30.0", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\xce\xd5\x2a\x7f\xf7\xf2\x60\xd5", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.30.1", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\xe4\x21\x75\xe1\x69\x22\xd0\xa8", } }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; int i, keylen; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting GOST28147 cipher checks.\n"); keylen = gcry_cipher_get_algo_keylen(GCRY_CIPHER_GOST28147); if (!keylen) { fail ("gost28147, gcry_cipher_get_algo_keylen failed\n"); return; } for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { err = gcry_cipher_open (&hde, GCRY_CIPHER_GOST28147, GCRY_CIPHER_MODE_ECB, 0); if (!err) err = gcry_cipher_open (&hdd, GCRY_CIPHER_GOST28147, GCRY_CIPHER_MODE_ECB, 0); if (err) { fail ("gost28147, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("gost28147, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_set_sbox (hde, tv[i].oid); if (!err) err = gcry_cipher_set_sbox (hdd, tv[i].oid); if (err) { fail ("gost28147, gcry_cipher_set_sbox failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].plaintext, tv[i].inlen == -1 ? strlen ((char*)tv[i].plaintext) : tv[i].inlen); if (err) { fail ("gost28147, gcry_cipher_encrypt (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].out, out, tv[i].inlen)) { fail ("gost28147, encrypt mismatch entry %d\n", i); mismatch (tv[i].out, tv[i].inlen, out, tv[i].inlen); } err = gcry_cipher_decrypt (hdd, out, tv[i].inlen, NULL, 0); if (err) { fail ("gost28147, gcry_cipher_decrypt (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].plaintext, out, tv[i].inlen)) { fail ("gost28147, decrypt mismatch entry %d\n", i); mismatch (tv[i].plaintext, tv[i].inlen, out, tv[i].inlen); } gcry_cipher_close (hde); gcry_cipher_close (hdd); } #endif } static void check_stream_cipher (void) { static const struct tv { const char *name; int algo; int keylen; int ivlen; const char *key; const char *iv; struct data { unsigned int inlen; const char *plaintext; const char *out; } data[MAX_DATA_LEN]; } tv[] = { #ifdef USE_SALSA20 { "Salsa20 128 bit, test 1", GCRY_CIPHER_SALSA20, 16, 8, "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\x4D\xFA\x5E\x48\x1D\xA2\x3E\xA0" } } }, { "Salsa20 128 bit, test 2", GCRY_CIPHER_SALSA20, 16, 8, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x80\x00\x00\x00\x00\x00\x00\x00", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\xB6\x6C\x1E\x44\x46\xDD\x95\x57" } } }, { "Salsa20 128 bit, test 3", GCRY_CIPHER_SALSA20, 16, 8, "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD", "\x0D\x74\xDB\x42\xA9\x10\x77\xDE", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\x05\xE1\xE7\xBE\xB6\x97\xD9\x99" } } }, { "Salsa20 256 bit, test 1", GCRY_CIPHER_SALSA20, 32, 8, "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\xE3\xBE\x8F\xDD\x8B\xEC\xA2\xE3" } } }, { "Salsa20 256 bit, test 2", GCRY_CIPHER_SALSA20, 32, 8, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x80\x00\x00\x00\x00\x00\x00\x00", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\x2A\xBA\x3D\xC4\x5B\x49\x47\x00" } } }, { "Salsa20 256 bit, ecrypt verified, set 6, vector 0", GCRY_CIPHER_SALSA20, 32, 8, "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD" "\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D", "\x0D\x74\xDB\x42\xA9\x10\x77\xDE", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\xF5\xFA\xD5\x3F\x79\xF9\xDF\x58" }, { 64, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\xF5\xFA\xD5\x3F\x79\xF9\xDF\x58\xC4\xAE\xA0\xD0\xED\x9A\x96\x01" "\xF2\x78\x11\x2C\xA7\x18\x0D\x56\x5B\x42\x0A\x48\x01\x96\x70\xEA" "\xF2\x4C\xE4\x93\xA8\x62\x63\xF6\x77\xB4\x6A\xCE\x19\x24\x77\x3D" "\x2B\xB2\x55\x71\xE1\xAA\x85\x93\x75\x8F\xC3\x82\xB1\x28\x0B\x71" } } }, { "Salsa20/12 128 bit, test 1", GCRY_CIPHER_SALSA20R12, 16, 8, "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\xFC\x20\x7D\xBF\xC7\x6C\x5E\x17" } } }, { "Salsa20/12 128 bit, test 2", GCRY_CIPHER_SALSA20R12, 16, 8, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x80\x00\x00\x00\x00\x00\x00\x00", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\x08\x28\x39\x9A\x6F\xEF\x20\xDA" } } }, { "Salsa20/12 128 bit, test 3", GCRY_CIPHER_SALSA20R12, 16, 8, "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD", "\x0D\x74\xDB\x42\xA9\x10\x77\xDE", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\xAD\x9E\x60\xE6\xD2\xA2\x64\xB8" } } }, { "Salsa20/12 256 bit, test 1", GCRY_CIPHER_SALSA20R12, 32, 8, "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\xAF\xE4\x11\xED\x1C\x4E\x07\xE4" } } }, { "Salsa20/12 256 bit, test 2", GCRY_CIPHER_SALSA20R12, 32, 8, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x80\x00\x00\x00\x00\x00\x00\x00", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\x17\x2C\x51\x92\xCB\x6E\x64\x5B" } } }, { "Salsa20/12 256 bit, ecrypt verified, set 6, vector 0", GCRY_CIPHER_SALSA20R12, 32, 8, "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD" "\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D", "\x0D\x74\xDB\x42\xA9\x10\x77\xDE", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\x52\xE2\x0C\xF8\x77\x5A\xE8\x82" }, { 64, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x52\xE2\x0C\xF8\x77\x5A\xE8\x82\xF2\x00\xC2\x99\x9F\xE4\xBA\x31" "\xA7\xA1\x8F\x1D\x5C\x97\x16\x19\x1D\x12\x31\x75\xE1\x47\xBD\x4E" "\x8C\xA6\xED\x16\x6C\xE0\xFC\x8E\x65\xA5\xCA\x60\x84\x20\xFC\x65" "\x44\xC9\x70\x0A\x0F\x21\x38\xE8\xC1\xA2\x86\xFB\x8C\x1F\xBF\xA0" } } }, #endif /*USE_SALSA20*/ #ifdef USE_CHACHA20 /* From draft-strombergson-chacha-test-vectors-01 */ { "ChaCha20 128 bit, TC1", GCRY_CIPHER_CHACHA20, 16, 8, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\x89\x67\x09\x52\x60\x83\x64\xfd" }, { 112, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x89\x67\x09\x52\x60\x83\x64\xfd\x00\xb2\xf9\x09\x36\xf0\x31\xc8" "\xe7\x56\xe1\x5d\xba\x04\xb8\x49\x3d\x00\x42\x92\x59\xb2\x0f\x46" "\xcc\x04\xf1\x11\x24\x6b\x6c\x2c\xe0\x66\xbe\x3b\xfb\x32\xd9\xaa" "\x0f\xdd\xfb\xc1\x21\x23\xd4\xb9\xe4\x4f\x34\xdc\xa0\x5a\x10\x3f" "\x6c\xd1\x35\xc2\x87\x8c\x83\x2b\x58\x96\xb1\x34\xf6\x14\x2a\x9d" "\x4d\x8d\x0d\x8f\x10\x26\xd2\x0a\x0a\x81\x51\x2c\xbc\xe6\xe9\x75" "\x8a\x71\x43\xd0\x21\x97\x80\x22\xa3\x84\x14\x1a\x80\xce\xa3\x06" }, { 128, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x89\x67\x09\x52\x60\x83\x64\xfd\x00\xb2\xf9\x09\x36\xf0\x31\xc8" "\xe7\x56\xe1\x5d\xba\x04\xb8\x49\x3d\x00\x42\x92\x59\xb2\x0f\x46" "\xcc\x04\xf1\x11\x24\x6b\x6c\x2c\xe0\x66\xbe\x3b\xfb\x32\xd9\xaa" "\x0f\xdd\xfb\xc1\x21\x23\xd4\xb9\xe4\x4f\x34\xdc\xa0\x5a\x10\x3f" "\x6c\xd1\x35\xc2\x87\x8c\x83\x2b\x58\x96\xb1\x34\xf6\x14\x2a\x9d" "\x4d\x8d\x0d\x8f\x10\x26\xd2\x0a\x0a\x81\x51\x2c\xbc\xe6\xe9\x75" "\x8a\x71\x43\xd0\x21\x97\x80\x22\xa3\x84\x14\x1a\x80\xce\xa3\x06" "\x2f\x41\xf6\x7a\x75\x2e\x66\xad\x34\x11\x98\x4c\x78\x7e\x30\xad" } } }, { "ChaCha20 256 bit, TC1", GCRY_CIPHER_CHACHA20, 32, 8, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00", { { 8, "\x00\x00\x00\x00\x00\x00\x00\x00", "\x76\xb8\xe0\xad\xa0\xf1\x3d\x90" }, { 112, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x76\xb8\xe0\xad\xa0\xf1\x3d\x90\x40\x5d\x6a\xe5\x53\x86\xbd\x28" "\xbd\xd2\x19\xb8\xa0\x8d\xed\x1a\xa8\x36\xef\xcc\x8b\x77\x0d\xc7" "\xda\x41\x59\x7c\x51\x57\x48\x8d\x77\x24\xe0\x3f\xb8\xd8\x4a\x37" "\x6a\x43\xb8\xf4\x15\x18\xa1\x1c\xc3\x87\xb6\x69\xb2\xee\x65\x86" "\x9f\x07\xe7\xbe\x55\x51\x38\x7a\x98\xba\x97\x7c\x73\x2d\x08\x0d" "\xcb\x0f\x29\xa0\x48\xe3\x65\x69\x12\xc6\x53\x3e\x32\xee\x7a\xed" "\x29\xb7\x21\x76\x9c\xe6\x4e\x43\xd5\x71\x33\xb0\x74\xd8\x39\xd5" }, { 128, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x76\xb8\xe0\xad\xa0\xf1\x3d\x90\x40\x5d\x6a\xe5\x53\x86\xbd\x28" "\xbd\xd2\x19\xb8\xa0\x8d\xed\x1a\xa8\x36\xef\xcc\x8b\x77\x0d\xc7" "\xda\x41\x59\x7c\x51\x57\x48\x8d\x77\x24\xe0\x3f\xb8\xd8\x4a\x37" "\x6a\x43\xb8\xf4\x15\x18\xa1\x1c\xc3\x87\xb6\x69\xb2\xee\x65\x86" "\x9f\x07\xe7\xbe\x55\x51\x38\x7a\x98\xba\x97\x7c\x73\x2d\x08\x0d" "\xcb\x0f\x29\xa0\x48\xe3\x65\x69\x12\xc6\x53\x3e\x32\xee\x7a\xed" "\x29\xb7\x21\x76\x9c\xe6\x4e\x43\xd5\x71\x33\xb0\x74\xd8\x39\xd5" "\x31\xed\x1f\x28\x51\x0a\xfb\x45\xac\xe1\x0a\x1f\x4b\x79\x4d\x6f" } } }, { "ChaCha20 256 bit, TC2", GCRY_CIPHER_CHACHA20, 32, 8, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00", { { 128, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\xc5\xd3\x0a\x7c\xe1\xec\x11\x93\x78\xc8\x4f\x48\x7d\x77\x5a\x85" "\x42\xf1\x3e\xce\x23\x8a\x94\x55\xe8\x22\x9e\x88\x8d\xe8\x5b\xbd" "\x29\xeb\x63\xd0\xa1\x7a\x5b\x99\x9b\x52\xda\x22\xbe\x40\x23\xeb" "\x07\x62\x0a\x54\xf6\xfa\x6a\xd8\x73\x7b\x71\xeb\x04\x64\xda\xc0" "\x10\xf6\x56\xe6\xd1\xfd\x55\x05\x3e\x50\xc4\x87\x5c\x99\x30\xa3" "\x3f\x6d\x02\x63\xbd\x14\xdf\xd6\xab\x8c\x70\x52\x1c\x19\x33\x8b" "\x23\x08\xb9\x5c\xf8\xd0\xbb\x7d\x20\x2d\x21\x02\x78\x0e\xa3\x52" "\x8f\x1c\xb4\x85\x60\xf7\x6b\x20\xf3\x82\xb9\x42\x50\x0f\xce\xac" } } }, { "ChaCha20 256 bit, TC3", GCRY_CIPHER_CHACHA20, 32, 8, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01\x00\x00\x00\x00\x00\x00\x00", { { 128, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\xef\x3f\xdf\xd6\xc6\x15\x78\xfb\xf5\xcf\x35\xbd\x3d\xd3\x3b\x80" "\x09\x63\x16\x34\xd2\x1e\x42\xac\x33\x96\x0b\xd1\x38\xe5\x0d\x32" "\x11\x1e\x4c\xaf\x23\x7e\xe5\x3c\xa8\xad\x64\x26\x19\x4a\x88\x54" "\x5d\xdc\x49\x7a\x0b\x46\x6e\x7d\x6b\xbd\xb0\x04\x1b\x2f\x58\x6b" "\x53\x05\xe5\xe4\x4a\xff\x19\xb2\x35\x93\x61\x44\x67\x5e\xfb\xe4" "\x40\x9e\xb7\xe8\xe5\xf1\x43\x0f\x5f\x58\x36\xae\xb4\x9b\xb5\x32" "\x8b\x01\x7c\x4b\x9d\xc1\x1f\x8a\x03\x86\x3f\xa8\x03\xdc\x71\xd5" "\x72\x6b\x2b\x6b\x31\xaa\x32\x70\x8a\xfe\x5a\xf1\xd6\xb6\x90\x58" } } }, { "ChaCha20 256 bit, TC4", GCRY_CIPHER_CHACHA20, 32, 8, "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", "\xff\xff\xff\xff\xff\xff\xff\xff", { { 128, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\xd9\xbf\x3f\x6b\xce\x6e\xd0\xb5\x42\x54\x55\x77\x67\xfb\x57\x44" "\x3d\xd4\x77\x89\x11\xb6\x06\x05\x5c\x39\xcc\x25\xe6\x74\xb8\x36" "\x3f\xea\xbc\x57\xfd\xe5\x4f\x79\x0c\x52\xc8\xae\x43\x24\x0b\x79" "\xd4\x90\x42\xb7\x77\xbf\xd6\xcb\x80\xe9\x31\x27\x0b\x7f\x50\xeb" "\x5b\xac\x2a\xcd\x86\xa8\x36\xc5\xdc\x98\xc1\x16\xc1\x21\x7e\xc3" "\x1d\x3a\x63\xa9\x45\x13\x19\xf0\x97\xf3\xb4\xd6\xda\xb0\x77\x87" "\x19\x47\x7d\x24\xd2\x4b\x40\x3a\x12\x24\x1d\x7c\xca\x06\x4f\x79" "\x0f\x1d\x51\xcc\xaf\xf6\xb1\x66\x7d\x4b\xbc\xa1\x95\x8c\x43\x06" } } }, { "ChaCha20 256 bit, TC5", GCRY_CIPHER_CHACHA20, 32, 8, "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55" "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55", "\x55\x55\x55\x55\x55\x55\x55\x55", { { 128, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\xbe\xa9\x41\x1a\xa4\x53\xc5\x43\x4a\x5a\xe8\xc9\x28\x62\xf5\x64" "\x39\x68\x55\xa9\xea\x6e\x22\xd6\xd3\xb5\x0a\xe1\xb3\x66\x33\x11" "\xa4\xa3\x60\x6c\x67\x1d\x60\x5c\xe1\x6c\x3a\xec\xe8\xe6\x1e\xa1" "\x45\xc5\x97\x75\x01\x7b\xee\x2f\xa6\xf8\x8a\xfc\x75\x80\x69\xf7" "\xe0\xb8\xf6\x76\xe6\x44\x21\x6f\x4d\x2a\x34\x22\xd7\xfa\x36\xc6" "\xc4\x93\x1a\xca\x95\x0e\x9d\xa4\x27\x88\xe6\xd0\xb6\xd1\xcd\x83" "\x8e\xf6\x52\xe9\x7b\x14\x5b\x14\x87\x1e\xae\x6c\x68\x04\xc7\x00" "\x4d\xb5\xac\x2f\xce\x4c\x68\xc7\x26\xd0\x04\xb1\x0f\xca\xba\x86" } } }, { "ChaCha20 256 bit, TC6", GCRY_CIPHER_CHACHA20, 32, 8, "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", { { 128, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x9a\xa2\xa9\xf6\x56\xef\xde\x5a\xa7\x59\x1c\x5f\xed\x4b\x35\xae" "\xa2\x89\x5d\xec\x7c\xb4\x54\x3b\x9e\x9f\x21\xf5\xe7\xbc\xbc\xf3" "\xc4\x3c\x74\x8a\x97\x08\x88\xf8\x24\x83\x93\xa0\x9d\x43\xe0\xb7" "\xe1\x64\xbc\x4d\x0b\x0f\xb2\x40\xa2\xd7\x21\x15\xc4\x80\x89\x06" "\x72\x18\x44\x89\x44\x05\x45\xd0\x21\xd9\x7e\xf6\xb6\x93\xdf\xe5" "\xb2\xc1\x32\xd4\x7e\x6f\x04\x1c\x90\x63\x65\x1f\x96\xb6\x23\xe6" "\x2a\x11\x99\x9a\x23\xb6\xf7\xc4\x61\xb2\x15\x30\x26\xad\x5e\x86" "\x6a\x2e\x59\x7e\xd0\x7b\x84\x01\xde\xc6\x3a\x09\x34\xc6\xb2\xa9" } } }, { "ChaCha20 256 bit, TC7", GCRY_CIPHER_CHACHA20, 32, 8, "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff" "\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00", "\x0f\x1e\x2d\x3c\x4b\x5a\x69\x78", { { 128, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x9f\xad\xf4\x09\xc0\x08\x11\xd0\x04\x31\xd6\x7e\xfb\xd8\x8f\xba" "\x59\x21\x8d\x5d\x67\x08\xb1\xd6\x85\x86\x3f\xab\xbb\x0e\x96\x1e" "\xea\x48\x0f\xd6\xfb\x53\x2b\xfd\x49\x4b\x21\x51\x01\x50\x57\x42" "\x3a\xb6\x0a\x63\xfe\x4f\x55\xf7\xa2\x12\xe2\x16\x7c\xca\xb9\x31" "\xfb\xfd\x29\xcf\x7b\xc1\xd2\x79\xed\xdf\x25\xdd\x31\x6b\xb8\x84" "\x3d\x6e\xde\xe0\xbd\x1e\xf1\x21\xd1\x2f\xa1\x7c\xbc\x2c\x57\x4c" "\xcc\xab\x5e\x27\x51\x67\xb0\x8b\xd6\x86\xf8\xa0\x9d\xf8\x7e\xc3" "\xff\xb3\x53\x61\xb9\x4e\xbf\xa1\x3f\xec\x0e\x48\x89\xd1\x8d\xa5" } } }, { "ChaCha20 256 bit, TC8", GCRY_CIPHER_CHACHA20, 32, 8, "\xc4\x6e\xc1\xb1\x8c\xe8\xa8\x78\x72\x5a\x37\xe7\x80\xdf\xb7\x35" "\x1f\x68\xed\x2e\x19\x4c\x79\xfb\xc6\xae\xbe\xe1\xa6\x67\x97\x5d", "\x1a\xda\x31\xd5\xcf\x68\x82\x21", { { 128, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\xf6\x3a\x89\xb7\x5c\x22\x71\xf9\x36\x88\x16\x54\x2b\xa5\x2f\x06" "\xed\x49\x24\x17\x92\x30\x2b\x00\xb5\xe8\xf8\x0a\xe9\xa4\x73\xaf" "\xc2\x5b\x21\x8f\x51\x9a\xf0\xfd\xd4\x06\x36\x2e\x8d\x69\xde\x7f" "\x54\xc6\x04\xa6\xe0\x0f\x35\x3f\x11\x0f\x77\x1b\xdc\xa8\xab\x92" "\xe5\xfb\xc3\x4e\x60\xa1\xd9\xa9\xdb\x17\x34\x5b\x0a\x40\x27\x36" "\x85\x3b\xf9\x10\xb0\x60\xbd\xf1\xf8\x97\xb6\x29\x0f\x01\xd1\x38" "\xae\x2c\x4c\x90\x22\x5b\xa9\xea\x14\xd5\x18\xf5\x59\x29\xde\xa0" "\x98\xca\x7a\x6c\xcf\xe6\x12\x27\x05\x3c\x84\xe4\x9a\x4a\x33\x32" }, { 127, "\xf6\x3a\x89\xb7\x5c\x22\x71\xf9\x36\x88\x16\x54\x2b\xa5\x2f\x06" "\xed\x49\x24\x17\x92\x30\x2b\x00\xb5\xe8\xf8\x0a\xe9\xa4\x73\xaf" "\xc2\x5b\x21\x8f\x51\x9a\xf0\xfd\xd4\x06\x36\x2e\x8d\x69\xde\x7f" "\x54\xc6\x04\xa6\xe0\x0f\x35\x3f\x11\x0f\x77\x1b\xdc\xa8\xab\x92" "\xe5\xfb\xc3\x4e\x60\xa1\xd9\xa9\xdb\x17\x34\x5b\x0a\x40\x27\x36" "\x85\x3b\xf9\x10\xb0\x60\xbd\xf1\xf8\x97\xb6\x29\x0f\x01\xd1\x38" "\xae\x2c\x4c\x90\x22\x5b\xa9\xea\x14\xd5\x18\xf5\x59\x29\xde\xa0" "\x98\xca\x7a\x6c\xcf\xe6\x12\x27\x05\x3c\x84\xe4\x9a\x4a\x33", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } } }, /* from draft-nir-cfrg-chacha20-poly1305-02 */ { "ChaCha20 256 bit, IV96-bit", GCRY_CIPHER_CHACHA20, 32, 12, "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", "\x07\x00\x00\x00\x40\x41\x42\x43\x44\x45\x46\x47", { { 64, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x7b\xac\x2b\x25\x2d\xb4\x47\xaf\x09\xb6\x7a\x55\xa4\xe9\x55\x84" "\x0a\xe1\xd6\x73\x10\x75\xd9\xeb\x2a\x93\x75\x78\x3e\xd5\x53\xff" "\xa2\x7e\xcc\xde\xad\xdb\x4d\xb4\xd1\x17\x9c\xe4\xc9\x0b\x43\xd8" "\xbc\xb7\x94\x8c\x4b\x4b\x7d\x8b\x7d\xf6\x27\x39\x32\xa4\x69\x16" }, }, }, #endif /*USE_CHACHA20*/ }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; int i, j; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting stream cipher checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); continue; } if (verbose) fprintf (stderr, " checking stream mode for %s [%i] (%s)\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo, tv[i].name); if (gcry_cipher_get_algo_blklen(tv[i].algo) != 1) { fail ("stream, gcry_cipher_get_algo_blklen: bad block length\n"); continue; } err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_STREAM, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_STREAM, 0); if (err) { fail ("stream, gcry_cipher_open for stream mode failed: %s\n", gpg_strerror (err)); continue; } /* Now loop over all the data samples. */ for (j = 0; tv[i].data[j].inlen; j++) { err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, tv[i].keylen); if (err) { fail ("stream, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); goto next; } err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen); if (err) { fail ("stream, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); goto next; } err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].data[j].plaintext, tv[i].data[j].inlen); if (err) { fail ("stream, gcry_cipher_encrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); goto next; } if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) { fail ("stream, encrypt mismatch entry %d:%d\n", i, j); mismatch (tv[i].data[j].out, tv[i].data[j].inlen, out, tv[i].data[j].inlen); } err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0); if (err) { fail ("stream, gcry_cipher_decrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); goto next; } if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) fail ("stream, decrypt mismatch entry %d:%d\n", i, j); } /* This time we encrypt and decrypt one byte at a time */ for (j = 0; tv[i].data[j].inlen; j++) { int byteNum; err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, tv[i].keylen); if (err) { fail ("stream, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); goto next; } err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen); if (err) { fail ("stream, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); goto next; } for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum) { err = gcry_cipher_encrypt (hde, out+byteNum, 1, (tv[i].data[j].plaintext) + byteNum, 1); if (err) { fail ("stream, gcry_cipher_encrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); goto next; } } if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) fail ("stream, encrypt mismatch entry %d:%d (byte-wise)\n", i, j); for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum) { err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0); if (err) { fail ("stream, gcry_cipher_decrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); goto next; } } if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) fail ("stream, decrypt mismatch entry %d:%d (byte-wise)\n", i, j); } next: gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed stream cipher checks.\n"); } static void check_stream_cipher_large_block (void) { static const struct tv { const char *name; int algo; int keylen; int ivlen; const char *key; const char *iv; struct data { int offset, length; const char *result; } data[MAX_DATA_LEN]; } tv[] = { #ifdef USE_SALSA20 { "Salsa20 256 bit, ecrypt verified, set 6, vector 0", GCRY_CIPHER_SALSA20, 32, 8, "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD" "\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D", "\x0D\x74\xDB\x42\xA9\x10\x77\xDE", { { 0, 64, "\xF5\xFA\xD5\x3F\x79\xF9\xDF\x58\xC4\xAE\xA0\xD0\xED\x9A\x96\x01" "\xF2\x78\x11\x2C\xA7\x18\x0D\x56\x5B\x42\x0A\x48\x01\x96\x70\xEA" "\xF2\x4C\xE4\x93\xA8\x62\x63\xF6\x77\xB4\x6A\xCE\x19\x24\x77\x3D" "\x2B\xB2\x55\x71\xE1\xAA\x85\x93\x75\x8F\xC3\x82\xB1\x28\x0B\x71" }, { 65472, 64, "\xB7\x0C\x50\x13\x9C\x63\x33\x2E\xF6\xE7\x7A\xC5\x43\x38\xA4\x07" "\x9B\x82\xBE\xC9\xF9\xA4\x03\xDF\xEA\x82\x1B\x83\xF7\x86\x07\x91" "\x65\x0E\xF1\xB2\x48\x9D\x05\x90\xB1\xDE\x77\x2E\xED\xA4\xE3\xBC" "\xD6\x0F\xA7\xCE\x9C\xD6\x23\xD9\xD2\xFD\x57\x58\xB8\x65\x3E\x70" }, { 65536, 64, "\x81\x58\x2C\x65\xD7\x56\x2B\x80\xAE\xC2\xF1\xA6\x73\xA9\xD0\x1C" "\x9F\x89\x2A\x23\xD4\x91\x9F\x6A\xB4\x7B\x91\x54\xE0\x8E\x69\x9B" "\x41\x17\xD7\xC6\x66\x47\x7B\x60\xF8\x39\x14\x81\x68\x2F\x5D\x95" "\xD9\x66\x23\xDB\xC4\x89\xD8\x8D\xAA\x69\x56\xB9\xF0\x64\x6B\x6E" }, { 131008, 64, "\xA1\x3F\xFA\x12\x08\xF8\xBF\x50\x90\x08\x86\xFA\xAB\x40\xFD\x10" "\xE8\xCA\xA3\x06\xE6\x3D\xF3\x95\x36\xA1\x56\x4F\xB7\x60\xB2\x42" "\xA9\xD6\xA4\x62\x8C\xDC\x87\x87\x62\x83\x4E\x27\xA5\x41\xDA\x2A" "\x5E\x3B\x34\x45\x98\x9C\x76\xF6\x11\xE0\xFE\xC6\xD9\x1A\xCA\xCC" } } }, { "Salsa20 256 bit, ecrypt verified, set 6, vector 1", GCRY_CIPHER_SALSA20, 32, 8, "\x05\x58\xAB\xFE\x51\xA4\xF7\x4A\x9D\xF0\x43\x96\xE9\x3C\x8F\xE2" "\x35\x88\xDB\x2E\x81\xD4\x27\x7A\xCD\x20\x73\xC6\x19\x6C\xBF\x12", "\x16\x7D\xE4\x4B\xB2\x19\x80\xE7", { { 0, 64, "\x39\x44\xF6\xDC\x9F\x85\xB1\x28\x08\x38\x79\xFD\xF1\x90\xF7\xDE" "\xE4\x05\x3A\x07\xBC\x09\x89\x6D\x51\xD0\x69\x0B\xD4\xDA\x4A\xC1" "\x06\x2F\x1E\x47\xD3\xD0\x71\x6F\x80\xA9\xB4\xD8\x5E\x6D\x60\x85" "\xEE\x06\x94\x76\x01\xC8\x5F\x1A\x27\xA2\xF7\x6E\x45\xA6\xAA\x87" }, { 65472, 64, "\x36\xE0\x3B\x4B\x54\xB0\xB2\xE0\x4D\x06\x9E\x69\x00\x82\xC8\xC5" "\x92\xDF\x56\xE6\x33\xF5\xD8\xC7\x68\x2A\x02\xA6\x5E\xCD\x13\x71" "\x8C\xA4\x35\x2A\xAC\xCB\x0D\xA2\x0E\xD6\xBB\xBA\x62\xE1\x77\xF2" "\x10\xE3\x56\x0E\x63\xBB\x82\x2C\x41\x58\xCA\xA8\x06\xA8\x8C\x82" }, { 65536, 64, "\x1B\x77\x9E\x7A\x91\x7C\x8C\x26\x03\x9F\xFB\x23\xCF\x0E\xF8\xE0" "\x8A\x1A\x13\xB4\x3A\xCD\xD9\x40\x2C\xF5\xDF\x38\x50\x10\x98\xDF" "\xC9\x45\xA6\xCC\x69\xA6\xA1\x73\x67\xBC\x03\x43\x1A\x86\xB3\xED" "\x04\xB0\x24\x5B\x56\x37\x9B\xF9\x97\xE2\x58\x00\xAD\x83\x7D\x7D" }, { 131008, 64, "\x7E\xC6\xDA\xE8\x1A\x10\x5E\x67\x17\x2A\x0B\x8C\x4B\xBE\x7D\x06" "\xA7\xA8\x75\x9F\x91\x4F\xBE\xB1\xAF\x62\xC8\xA5\x52\xEF\x4A\x4F" "\x56\x96\x7E\xA2\x9C\x74\x71\xF4\x6F\x3B\x07\xF7\xA3\x74\x6E\x95" "\x3D\x31\x58\x21\xB8\x5B\x6E\x8C\xB4\x01\x22\xB9\x66\x35\x31\x3C" } } }, { "Salsa20 256 bit, ecrypt verified, set 6, vector 2", GCRY_CIPHER_SALSA20, 32, 8, "\x0A\x5D\xB0\x03\x56\xA9\xFC\x4F\xA2\xF5\x48\x9B\xEE\x41\x94\xE7" "\x3A\x8D\xE0\x33\x86\xD9\x2C\x7F\xD2\x25\x78\xCB\x1E\x71\xC4\x17", "\x1F\x86\xED\x54\xBB\x22\x89\xF0", { { 0, 64, "\x3F\xE8\x5D\x5B\xB1\x96\x0A\x82\x48\x0B\x5E\x6F\x4E\x96\x5A\x44" "\x60\xD7\xA5\x45\x01\x66\x4F\x7D\x60\xB5\x4B\x06\x10\x0A\x37\xFF" "\xDC\xF6\xBD\xE5\xCE\x3F\x48\x86\xBA\x77\xDD\x5B\x44\xE9\x56\x44" "\xE4\x0A\x8A\xC6\x58\x01\x15\x5D\xB9\x0F\x02\x52\x2B\x64\x40\x23" }, { 65472, 64, "\xC8\xD6\xE5\x4C\x29\xCA\x20\x40\x18\xA8\x30\xE2\x66\xCE\xEE\x0D" "\x03\x7D\xC4\x7E\x92\x19\x47\x30\x2A\xCE\x40\xD1\xB9\x96\xA6\xD8" "\x0B\x59\x86\x77\xF3\x35\x2F\x1D\xAA\x6D\x98\x88\xF8\x91\xAD\x95" "\xA1\xC3\x2F\xFE\xB7\x1B\xB8\x61\xE8\xB0\x70\x58\x51\x51\x71\xC9" }, { 65536, 64, "\xB7\x9F\xD7\x76\x54\x2B\x46\x20\xEF\xCB\x88\x44\x95\x99\xF2\x34" "\x03\xE7\x4A\x6E\x91\xCA\xCC\x50\xA0\x5A\x8F\x8F\x3C\x0D\xEA\x8B" "\x00\xE1\xA5\xE6\x08\x1F\x55\x26\xAE\x97\x5B\x3B\xC0\x45\x0F\x1A" "\x0C\x8B\x66\xF8\x08\xF1\x90\x4B\x97\x13\x61\x13\x7C\x93\x15\x6F" }, { 131008, 64, "\x79\x98\x20\x4F\xED\x70\xCE\x8E\x0D\x02\x7B\x20\x66\x35\xC0\x8C" "\x8B\xC4\x43\x62\x26\x08\x97\x0E\x40\xE3\xAE\xDF\x3C\xE7\x90\xAE" "\xED\xF8\x9F\x92\x26\x71\xB4\x53\x78\xE2\xCD\x03\xF6\xF6\x23\x56" "\x52\x9C\x41\x58\xB7\xFF\x41\xEE\x85\x4B\x12\x35\x37\x39\x88\xC8" } } }, { "Salsa20 256 bit, ecrypt verified, set 6, vector 3", GCRY_CIPHER_SALSA20, 32, 8, "\x0F\x62\xB5\x08\x5B\xAE\x01\x54\xA7\xFA\x4D\xA0\xF3\x46\x99\xEC" "\x3F\x92\xE5\x38\x8B\xDE\x31\x84\xD7\x2A\x7D\xD0\x23\x76\xC9\x1C", "\x28\x8F\xF6\x5D\xC4\x2B\x92\xF9", { { 0, 64, "\x5E\x5E\x71\xF9\x01\x99\x34\x03\x04\xAB\xB2\x2A\x37\xB6\x62\x5B" "\xF8\x83\xFB\x89\xCE\x3B\x21\xF5\x4A\x10\xB8\x10\x66\xEF\x87\xDA" "\x30\xB7\x76\x99\xAA\x73\x79\xDA\x59\x5C\x77\xDD\x59\x54\x2D\xA2" "\x08\xE5\x95\x4F\x89\xE4\x0E\xB7\xAA\x80\xA8\x4A\x61\x76\x66\x3F" }, { 65472, 64, "\x2D\xA2\x17\x4B\xD1\x50\xA1\xDF\xEC\x17\x96\xE9\x21\xE9\xD6\xE2" "\x4E\xCF\x02\x09\xBC\xBE\xA4\xF9\x83\x70\xFC\xE6\x29\x05\x6F\x64" "\x91\x72\x83\x43\x6E\x2D\x3F\x45\x55\x62\x25\x30\x7D\x5C\xC5\xA5" "\x65\x32\x5D\x89\x93\xB3\x7F\x16\x54\x19\x5C\x24\x0B\xF7\x5B\x16" }, { 65536, 64, "\xAB\xF3\x9A\x21\x0E\xEE\x89\x59\x8B\x71\x33\x37\x70\x56\xC2\xFE" "\xF4\x2D\xA7\x31\x32\x75\x63\xFB\x67\xC7\xBE\xDB\x27\xF3\x8C\x7C" "\x5A\x3F\xC2\x18\x3A\x4C\x6B\x27\x7F\x90\x11\x52\x47\x2C\x6B\x2A" "\xBC\xF5\xE3\x4C\xBE\x31\x5E\x81\xFD\x3D\x18\x0B\x5D\x66\xCB\x6C" }, { 131008, 64, "\x1B\xA8\x9D\xBD\x3F\x98\x83\x97\x28\xF5\x67\x91\xD5\xB7\xCE\x23" "\x50\x36\xDE\x84\x3C\xCC\xAB\x03\x90\xB8\xB5\x86\x2F\x1E\x45\x96" "\xAE\x8A\x16\xFB\x23\xDA\x99\x7F\x37\x1F\x4E\x0A\xAC\xC2\x6D\xB8" "\xEB\x31\x4E\xD4\x70\xB1\xAF\x6B\x9F\x8D\x69\xDD\x79\xA9\xD7\x50" } } }, { "Salsa20/12 256 bit, ecrypt verified, set 6, vector 0", GCRY_CIPHER_SALSA20R12, 32, 8, "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD" "\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D", "\x0D\x74\xDB\x42\xA9\x10\x77\xDE", { { 0, 64, "\x52\xE2\x0C\xF8\x77\x5A\xE8\x82\xF2\x00\xC2\x99\x9F\xE4\xBA\x31" "\xA7\xA1\x8F\x1D\x5C\x97\x16\x19\x1D\x12\x31\x75\xE1\x47\xBD\x4E" "\x8C\xA6\xED\x16\x6C\xE0\xFC\x8E\x65\xA5\xCA\x60\x84\x20\xFC\x65" "\x44\xC9\x70\x0A\x0F\x21\x38\xE8\xC1\xA2\x86\xFB\x8C\x1F\xBF\xA0" }, { 65472, 64, "\x8F\xBC\x9F\xE8\x69\x1B\xD4\xF0\x82\xB4\x7F\x54\x05\xED\xFB\xC1" "\x6F\x4D\x5A\x12\xDD\xCB\x2D\x75\x4E\x8A\x99\x98\xD0\xB2\x19\x55" "\x7D\xFE\x29\x84\xF4\xA1\xD2\xDD\xA7\x6B\x95\x96\x92\x8C\xCE\x05" "\x56\xF5\x00\x66\xCD\x59\x9E\x44\xEF\x5C\x14\xB2\x26\x68\x3A\xEF" }, { 65536, 64, "\xBC\xBD\x01\xDD\x28\x96\x1C\xC7\xAD\x30\x47\x38\x6C\xBC\xC6\x7C" "\x10\x8D\x6A\xF1\x11\x67\xE4\x0D\x7A\xE1\xB2\xFC\x45\x18\xA8\x67" "\xEF\xE4\x02\x65\x1D\x1D\x88\x51\xC4\xFD\x23\x30\xC5\x97\xB3\x6A" "\x46\xD5\x68\x9E\x00\xFC\x96\xFE\xCF\x9C\xE3\xE2\x21\x1D\x44\xBE" }, { 131008, 64, "\x91\x66\xF3\x1C\xD8\x5B\x5B\xB1\x8F\xC6\x14\xE5\x4E\x4A\xD6\x7F" "\xB8\x65\x8E\x3B\xF9\xFB\x19\xB7\xA8\x2F\x0F\xE7\xDC\x90\x2D\xF5" "\x63\xC6\xAC\x4F\x44\x67\x48\xC4\xBC\x3E\x14\x05\xE1\x24\x82\x0D" "\xC4\x09\x41\x99\x8F\x44\xA8\x10\xE7\x22\x78\x7F\xCD\x47\x78\x4C" } } }, { "Salsa20/12 256 bit, ecrypt verified, set 6, vector 1", GCRY_CIPHER_SALSA20R12, 32, 8, "\x05\x58\xAB\xFE\x51\xA4\xF7\x4A\x9D\xF0\x43\x96\xE9\x3C\x8F\xE2" "\x35\x88\xDB\x2E\x81\xD4\x27\x7A\xCD\x20\x73\xC6\x19\x6C\xBF\x12", "\x16\x7D\xE4\x4B\xB2\x19\x80\xE7", { { 0, 64, "\xC0\x75\x60\xB3\xE7\x76\xB4\x71\xC5\xE2\x93\x14\x26\xCA\xF1\xED" "\x3A\xE4\xB8\x67\x08\x76\x82\xCA\x9D\xFD\xC2\xBA\xE8\x93\x50\xBD" "\x84\x82\x1C\xAE\xFF\x85\xAA\xC4\x9D\x74\x35\xA7\xD9\x88\x93\x52" "\xF5\x27\x9E\x36\x12\x3F\x41\x72\x8A\x14\xEF\x26\x9F\xCB\x94\x4B" }, { 65472, 64, "\xEE\xD1\xBB\x58\xF9\x0C\x89\xE0\x5C\xC6\x8B\x2D\xB6\x05\x58\x49" "\xB3\xD2\xB1\x87\xB7\xF0\x2F\x9A\x24\xCE\x34\x2A\xF0\xFC\x47\xA3" "\x74\xBD\x75\x90\xFB\xF4\xFD\x9E\xE5\x9B\x1A\x38\x1E\xBF\xD2\x29" "\xAD\x2A\x29\x01\xB3\xFB\x61\x08\x12\x90\x0B\x92\x30\xE6\x22\xE9" }, { 65536, 64, "\x70\xF0\x49\x3A\x1B\x62\x53\xCC\x5E\xD3\x45\x0A\x31\xCF\x37\x7D" "\x83\x4B\xAD\x20\x72\x30\x29\x27\xCC\xD8\x30\x10\x4B\xD3\x05\xFF" "\x59\xD2\x94\x17\xB2\x32\x88\x4E\xC9\x59\x19\x4D\x60\x47\xC3\xDD" "\x66\x56\xC4\x7E\x32\x00\x64\xEB\x01\x44\xF7\x34\x1B\xC3\xD6\x97" }, { 131008, 64, "\xD2\xCC\xF7\xC1\xAF\x2A\xB4\x66\xE6\x27\xDB\x44\x08\x40\x96\x9A" "\xBD\xAB\x68\xD8\x86\xAE\x6A\x38\xA1\x3F\xEE\x17\x50\xCA\x97\xB5" "\xD3\x31\x5B\x84\x08\x47\x28\x86\x2F\xBC\xC7\xD4\xA9\x7C\x75\xC8" "\x65\x5F\xF9\xD6\xBB\xC2\x61\x88\x63\x6F\x3E\xDF\xE1\x5C\x7D\x30" } } }, { "Salsa20/12 256 bit, ecrypt verified, set 6, vector 2", GCRY_CIPHER_SALSA20R12, 32, 8, "\x0A\x5D\xB0\x03\x56\xA9\xFC\x4F\xA2\xF5\x48\x9B\xEE\x41\x94\xE7" "\x3A\x8D\xE0\x33\x86\xD9\x2C\x7F\xD2\x25\x78\xCB\x1E\x71\xC4\x17", "\x1F\x86\xED\x54\xBB\x22\x89\xF0", { { 0, 64, "\x51\x22\x52\x91\x01\x90\xD1\x54\xD1\x4D\x0B\x92\x32\xB8\x84\x31" "\x8C\xCB\x43\x81\x9B\xD5\x42\x19\x32\xC0\x3A\x13\xF0\x7B\x40\x10" "\x83\xD7\x89\x72\x5A\xA9\xDA\x0B\x41\xCB\x62\x24\x94\x5E\xDC\xB0" "\xFB\x6F\xD7\xC2\x34\x22\x35\xC9\x70\xF6\x4E\x10\x1C\x25\x68\x64" }, { 65472, 64, "\x97\x96\x74\x55\x84\x0A\x4A\xE5\xC1\xCA\xCE\x49\x15\x19\x13\x8A" "\xA3\x5E\x5F\x02\x40\x7D\x4A\x1F\xE5\x08\x6D\x35\xF3\x55\x1E\xF4" "\x77\xD9\x28\x9D\x17\x23\x79\x7C\x1A\x49\xEC\x26\x62\x9A\xFA\xDC" "\x56\xA0\x38\xA3\x8C\x75\x88\x1B\x62\x17\xFD\x74\x67\x25\x59\x09" }, { 65536, 64, "\x1B\xF8\x2E\x3D\x5C\x54\xDA\xAB\xCF\x84\x15\xF8\xA2\xA1\xA2\x2E" "\x86\x88\x06\x33\x4F\xF3\x11\x36\x04\x74\x1C\x1D\xF2\xB9\x84\x0F" "\x87\xDE\xEF\xB0\x07\x23\xA8\xA1\xB2\x4A\x4D\xA1\x7E\xCD\xAD\x00" "\x01\xF9\x79\xDD\xAE\x2D\xF0\xC5\xE1\xE5\x32\xC4\x8F\x8E\x0D\x34" }, { 131008, 64, "\x06\xD8\x4F\x6A\x71\x34\x84\x20\x32\x9F\xCD\x0C\x41\x75\x9A\xD1" "\x8F\x99\x57\xA3\x8F\x22\x89\x3B\xA5\x58\xC5\x05\x11\x97\x28\x5C" "\x6B\xE2\xFD\x6C\x96\xA5\xC6\x62\xAF\xD3\x11\x78\xE7\x0F\x96\x0A" "\xAB\x3F\x47\x96\x23\xA4\x44\xB6\x81\x91\xE4\xC5\x28\x46\x93\x88" } } }, { "Salsa20/12 256 bit, ecrypt verified, set 6, vector 3", GCRY_CIPHER_SALSA20R12, 32, 8, "\x0F\x62\xB5\x08\x5B\xAE\x01\x54\xA7\xFA\x4D\xA0\xF3\x46\x99\xEC" "\x3F\x92\xE5\x38\x8B\xDE\x31\x84\xD7\x2A\x7D\xD0\x23\x76\xC9\x1C", "\x28\x8F\xF6\x5D\xC4\x2B\x92\xF9", { { 0, 64, "\x99\xDB\x33\xAD\x11\xCE\x0C\xCB\x3B\xFD\xBF\x8D\x0C\x18\x16\x04" "\x52\xD0\x14\xCD\xE9\x89\xB4\xC4\x11\xA5\x59\xFF\x7C\x20\xA1\x69" "\xE6\xDC\x99\x09\xD8\x16\xBE\xCE\xDC\x40\x63\xCE\x07\xCE\xA8\x28" "\xF4\x4B\xF9\xB6\xC9\xA0\xA0\xB2\x00\xE1\xB5\x2A\xF4\x18\x59\xC5" }, { 65472, 64, "\x2F\xF2\x02\x64\xEE\xAF\x47\xAB\x7D\x57\xC3\x62\x24\x53\x54\x51" "\x73\x5A\xC8\x36\xD3\x2D\xD2\x8A\xE6\x36\x45\xCE\x95\x2F\x7F\xDB" "\xE6\x68\x9C\x69\x59\x77\xB1\xC7\x6E\x60\xDD\x5B\x27\xAC\xA4\x76" "\xD2\x62\x0F\xDC\x93\x13\xE8\x48\x9B\xA5\x6A\x70\xC9\xF4\xC3\xA8" }, { 65536, 64, "\xEB\x30\xCD\xA7\x27\xC0\xF8\xB7\xE4\x5D\x5E\xF3\x0D\xB7\xCB\xE0" "\x21\xF2\x29\x1E\x5F\x56\x93\x8D\x56\xF6\x87\xB7\x37\xC3\xB4\x27" "\x54\x5C\x56\xA6\xD3\xA0\xBF\x2B\x2F\x47\xB4\x84\x93\xFA\xE4\x5E" "\xD5\x0C\x2E\x9B\xBE\x49\xFD\x92\xD6\x7C\x76\x49\x05\x5F\x06\xFD" }, { 131008, 64, "\x0E\xBF\x6C\xC3\xCB\xCB\xE7\x4E\x6E\xE8\x07\x47\x1B\x49\x2A\x67" "\x39\xA5\x2F\x57\x11\x31\xA2\x50\xBC\xDF\xA0\x76\xA2\x65\x90\xD7" "\xED\xE6\x75\x1C\x03\x26\xA0\x2C\xB1\x1C\x58\x77\x35\x52\x80\x4F" "\xD8\x68\x67\x15\x35\x5C\x5A\x5C\xC5\x91\x96\x3A\x75\xE9\x94\xB4" } } } #endif /*USE_SALSA20*/ }; char zeroes[512]; gcry_cipher_hd_t hde; unsigned char *buffer; unsigned char *p; size_t buffersize; unsigned int n; int i, j; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting large block stream cipher checks.\n"); memset (zeroes, 0, 512); buffersize = 128 * 1024; buffer = gcry_xmalloc (buffersize+1024); memset (buffer+buffersize, 0x5a, 1024); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); continue; } if (verbose) fprintf (stderr, " checking large block stream for %s [%i] (%s)\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo, tv[i].name); err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_STREAM, 0); if (err) { fail ("large stream, gcry_cipher_open for stream mode failed: %s\n", gpg_strerror (err)); continue; } err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen); if (err) { fail ("large stream, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); goto next; } err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen); if (err) { fail ("large stream, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); goto next; } for (j=0, p=buffer; j < buffersize/512; j++, p += 512) { err = gcry_cipher_encrypt (hde, p, 512, zeroes, 512); if (err) { fail ("large stream, " "gcry_cipher_encrypt (%d) block %d failed: %s\n", i, j, gpg_strerror (err)); goto next; } } for (j=0, p=buffer+buffersize; j < 1024; j++, p++) if (*p != 0x5a) die ("large stream, buffer corrupted at j=%d\n", j); /* Now loop over all the data samples. */ for (j = 0; tv[i].data[j].length; j++) { assert (tv[i].data[j].offset + tv[i].data[j].length <= buffersize); if (memcmp (tv[i].data[j].result, buffer + tv[i].data[j].offset, tv[i].data[j].length)) { fail ("large stream, encrypt mismatch entry %d:%d\n", i, j); mismatch (tv[i].data[j].result, tv[i].data[j].length, buffer + tv[i].data[j].offset, tv[i].data[j].length); } } /* * Let's do the same thing again but using changing block sizes. */ err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen); if (err) { fail ("large stream, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); goto next; } err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen); if (err) { fail ("large stream, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); goto next; } for (n=0, p=buffer, j = 0; n < buffersize; n += j, p += j) { switch (j) { case 0: j = 1; break; case 1: j = 64; break; case 64: j= 384; break; case 384: j = 63; break; case 63: j = 512; break; case 512: j = 32; break; case 32: j = 503; break; default: j = 509; break; } if ( n + j >= buffersize ) j = buffersize - n; assert (j <= 512); err = gcry_cipher_encrypt (hde, p, j, zeroes, j); if (err) { fail ("large stream, " "gcry_cipher_encrypt (%d) offset %u failed: %s\n", i, n, gpg_strerror (err)); goto next; } } for (j=0, p=buffer+buffersize; j < 1024; j++, p++) if (*p != 0x5a) die ("large stream, buffer corrupted at j=%d (line %d)\n", j, __LINE__); /* Now loop over all the data samples. */ for (j = 0; tv[i].data[j].length; j++) { assert (tv[i].data[j].offset + tv[i].data[j].length <= buffersize); if (memcmp (tv[i].data[j].result, buffer + tv[i].data[j].offset, tv[i].data[j].length)) { fail ("large stream var, encrypt mismatch entry %d:%d\n", i, j); mismatch (tv[i].data[j].result, tv[i].data[j].length, buffer + tv[i].data[j].offset, tv[i].data[j].length); } } next: gcry_cipher_close (hde); } gcry_free (buffer); if (verbose) fprintf (stderr, " Completed large block stream cipher checks.\n"); } /* Check that our bulk encryption functions work properly. */ static void check_bulk_cipher_modes (void) { static const struct { int algo; int mode; const char *key; int keylen; const char *iv; int ivlen; char t1_hash[20]; } tv[] = { { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CFB, "abcdefghijklmnop", 16, "1234567890123456", 16, /*[0]*/ { 0x53, 0xda, 0x27, 0x3c, 0x78, 0x3d, 0x54, 0x66, 0x19, 0x63, 0xd7, 0xe6, 0x20, 0x10, 0xcd, 0xc0, 0x5a, 0x0b, 0x06, 0xcc } }, { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB, "abcdefghijklmnopABCDEFG", 24, "1234567890123456", 16, /*[1]*/ { 0xc7, 0xb1, 0xd0, 0x09, 0x95, 0x04, 0x34, 0x61, 0x2b, 0xd9, 0xcb, 0xb3, 0xc7, 0xcb, 0xef, 0xea, 0x16, 0x19, 0x9b, 0x3e } }, { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB, "abcdefghijklmnopABCDEFGHIJKLMNOP", 32, "1234567890123456", 16, /*[2]*/ { 0x31, 0xe1, 0x1f, 0x63, 0x65, 0x47, 0x8c, 0x3f, 0x53, 0xdb, 0xd9, 0x4d, 0x91, 0x1d, 0x02, 0x9c, 0x05, 0x25, 0x58, 0x29 } }, { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, "abcdefghijklmnop", 16, "1234567890123456", 16, /*[3]*/ { 0xdc, 0x0c, 0xc2, 0xd9, 0x6b, 0x47, 0xf9, 0xeb, 0x06, 0xb4, 0x2f, 0x6e, 0xec, 0x72, 0xbf, 0x55, 0x26, 0x7f, 0xa9, 0x97 } }, { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC, "abcdefghijklmnopABCDEFG", 24, "1234567890123456", 16, /*[4]*/ { 0x2b, 0x90, 0x9b, 0xe6, 0x40, 0xab, 0x6e, 0xc2, 0xc5, 0xb1, 0x87, 0xf5, 0x43, 0x84, 0x7b, 0x04, 0x06, 0x47, 0xd1, 0x8f } }, { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, "abcdefghijklmnopABCDEFGHIJKLMNOP", 32, "1234567890123456", 16, /*[5]*/ { 0xaa, 0xa8, 0xdf, 0x03, 0xb0, 0xba, 0xc4, 0xe3, 0xc1, 0x02, 0x38, 0x31, 0x8d, 0x86, 0xcb, 0x49, 0x6d, 0xad, 0xae, 0x01 } }, { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OFB, "abcdefghijklmnop", 16, "1234567890123456", 16, /*[6]*/ { 0x65, 0xfe, 0xde, 0x48, 0xd0, 0xa1, 0xa6, 0xf9, 0x24, 0x6b, 0x52, 0x5f, 0x21, 0x8a, 0x6f, 0xc7, 0x70, 0x3b, 0xd8, 0x4a } }, { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB, "abcdefghijklmnopABCDEFG", 24, "1234567890123456", 16, /*[7]*/ { 0x59, 0x5b, 0x02, 0xa2, 0x88, 0xc0, 0xbe, 0x94, 0x43, 0xaa, 0x39, 0xf6, 0xbd, 0xcc, 0x83, 0x99, 0xee, 0x00, 0xa1, 0x91 } }, { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB, "abcdefghijklmnopABCDEFGHIJKLMNOP", 32, "1234567890123456", 16, /*[8]*/ { 0x38, 0x8c, 0xe1, 0xe2, 0xbe, 0x67, 0x60, 0xe8, 0xeb, 0xce, 0xd0, 0xc6, 0xaa, 0xd6, 0xf6, 0x26, 0x15, 0x56, 0xd0, 0x2b } }, { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR, "abcdefghijklmnop", 16, "1234567890123456", 16, /*[9]*/ { 0x9a, 0x48, 0x94, 0xd6, 0x50, 0x46, 0x81, 0xdb, 0x68, 0x34, 0x3b, 0xc5, 0x9e, 0x66, 0x94, 0x81, 0x98, 0xa0, 0xf9, 0xff } }, { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR, "abcdefghijklmnopABCDEFG", 24, "1234567890123456", 16, /*[10]*/ { 0x2c, 0x2c, 0xd3, 0x75, 0x81, 0x2a, 0x59, 0x07, 0xeb, 0x08, 0xce, 0x28, 0x4c, 0x0c, 0x6a, 0xa8, 0x8f, 0xa3, 0x98, 0x7e } }, { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, "abcdefghijklmnopABCDEFGHIJKLMNOP", 32, "1234567890123456", 16, /*[11]*/ { 0x64, 0xce, 0x73, 0x03, 0xc7, 0x89, 0x99, 0x1f, 0xf1, 0xce, 0xfe, 0xfb, 0xb9, 0x42, 0x30, 0xdf, 0xbb, 0x68, 0x6f, 0xd3 } }, { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, "abcdefghijklmnop", 16, "1234567890123456", 16, /*[12]*/ { 0x51, 0xae, 0xf5, 0xac, 0x22, 0xa0, 0xba, 0x11, 0xc5, 0xaa, 0xb4, 0x70, 0x99, 0xce, 0x18, 0x08, 0x12, 0x9b, 0xb1, 0xc5 } }, { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB, "abcdefghijklmnopABCDEFG", 24, "1234567890123456", 16, /*[13]*/ { 0x57, 0x91, 0xea, 0x48, 0xd8, 0xbf, 0x9e, 0xc1, 0xae, 0x33, 0xb3, 0xfd, 0xf7, 0x7a, 0xeb, 0x30, 0xb1, 0x62, 0x0d, 0x82 } }, { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB, "abcdefghijklmnopABCDEFGHIJKLMNOP", 32, "1234567890123456", 16, /*[14]*/ { 0x2d, 0x71, 0x54, 0xb9, 0xc5, 0x28, 0x76, 0xff, 0x76, 0xb5, 0x99, 0x37, 0x99, 0x9d, 0xf7, 0x10, 0x6d, 0x86, 0x4f, 0x3f } }, { GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_XTS, "abcdefghijklmnopABCDEFGHIJKLMNOP", 32, "1234567890123456", 16, /*[15]*/ { 0x71, 0x46, 0x40, 0xb0, 0xed, 0x6f, 0xc4, 0x82, 0x2b, 0x3f, 0xb6, 0xf7, 0x81, 0x08, 0x4c, 0x8b, 0xc1, 0x66, 0x4c, 0x1b } }, { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_XTS, "abcdefghijklmnopABCDEFGHIJKLMNOP_abcdefghijklmnopABCDEFGHIJKLMNO", 64, "1234567890123456", 16, /*[16]*/ { 0x8e, 0xbc, 0xa5, 0x21, 0x0a, 0x4b, 0x53, 0x14, 0x79, 0x81, 0x25, 0xad, 0x24, 0x45, 0x98, 0xbd, 0x9f, 0x27, 0x5f, 0x01 } } }; gcry_cipher_hd_t hde = NULL; gcry_cipher_hd_t hdd = NULL; unsigned char *buffer_base, *outbuf_base; /* Allocated buffers. */ unsigned char *buffer, *outbuf; /* Aligned buffers. */ size_t buflen; unsigned char hash[20]; int i, j, keylen, blklen; gcry_error_t err = 0; if (verbose) fprintf (stderr, "Starting bulk cipher checks.\n"); buflen = 16*100; /* We check a 1600 byte buffer. */ buffer_base = gcry_xmalloc (buflen+16); buffer = buffer_base + (16 - ((size_t)buffer_base & 0x0f)); outbuf_base = gcry_xmalloc (buflen+16); outbuf = outbuf_base + (16 - ((size_t)outbuf_base & 0x0f)); for (i = 0; i < DIM (tv); i++) { if (verbose) fprintf (stderr, " checking bulk encryption for %s [%i], mode %d\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo, tv[i].mode); err = gcry_cipher_open (&hde, tv[i].algo, tv[i].mode, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, tv[i].mode, 0); if (err) { fail ("gcry_cipher_open failed: %s\n", gpg_strerror (err)); goto leave; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("gcry_cipher_get_algo_keylen failed\n"); goto leave; } err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, tv[i].keylen); if (err) { fail ("gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); goto leave; } blklen = gcry_cipher_get_algo_blklen(tv[i].algo); if (!blklen) { fail ("gcry_cipher_get_algo_blklen failed\n"); goto leave; } err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen); if (err) { fail ("gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); goto leave; } /* Fill the buffer with our test pattern. */ for (j=0; j < buflen; j++) buffer[j] = ((j & 0xff) ^ ((j >> 8) & 0xff)); err = gcry_cipher_encrypt (hde, outbuf, buflen, buffer, buflen); if (err) { fail ("gcry_cipher_encrypt (algo %d, mode %d) failed: %s\n", tv[i].algo, tv[i].mode, gpg_strerror (err)); goto leave; } gcry_md_hash_buffer (GCRY_MD_SHA1, hash, outbuf, buflen); #if 0 printf ("/*[%d]*/\n", i); fputs (" {", stdout); for (j=0; j < 20; j++) printf (" 0x%02x%c%s", hash[j], j==19? ' ':',', j == 9? "\n ":""); puts ("}"); #endif if (memcmp (hash, tv[i].t1_hash, 20)) fail ("encrypt mismatch (algo %d, mode %d)\n", tv[i].algo, tv[i].mode); err = gcry_cipher_decrypt (hdd, outbuf, buflen, NULL, 0); if (err) { fail ("gcry_cipher_decrypt (algo %d, mode %d) failed: %s\n", tv[i].algo, tv[i].mode, gpg_strerror (err)); goto leave; } if (memcmp (buffer, outbuf, buflen)) fail ("decrypt mismatch (algo %d, mode %d)\n", tv[i].algo, tv[i].mode); gcry_cipher_close (hde); hde = NULL; gcry_cipher_close (hdd); hdd = NULL; } if (verbose) fprintf (stderr, "Completed bulk cipher checks.\n"); leave: gcry_cipher_close (hde); gcry_cipher_close (hdd); gcry_free (buffer_base); gcry_free (outbuf_base); } static unsigned int get_algo_mode_blklen (int algo, int mode) { unsigned int blklen = gcry_cipher_get_algo_blklen(algo); /* Some modes override blklen. */ switch (mode) { case GCRY_CIPHER_MODE_STREAM: case GCRY_CIPHER_MODE_OFB: case GCRY_CIPHER_MODE_CTR: case GCRY_CIPHER_MODE_CCM: case GCRY_CIPHER_MODE_GCM: case GCRY_CIPHER_MODE_EAX: case GCRY_CIPHER_MODE_POLY1305: return 1; } return blklen; } static int check_one_cipher_core_reset (gcry_cipher_hd_t hd, int algo, int mode, int pass, int nplain) { static const unsigned char iv[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; u64 ctl_params[3]; int err; gcry_cipher_reset (hd); if (mode == GCRY_CIPHER_MODE_OCB || mode == GCRY_CIPHER_MODE_CCM) { err = gcry_cipher_setiv (hd, iv, sizeof(iv)); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_setiv failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } } if (mode == GCRY_CIPHER_MODE_CCM) { ctl_params[0] = nplain; /* encryptedlen */ ctl_params[1] = 0; /* aadlen */ ctl_params[2] = 16; /* authtaglen */ err = gcry_cipher_ctl (hd, GCRYCTL_SET_CCM_LENGTHS, ctl_params, sizeof(ctl_params)); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_ctl " "GCRYCTL_SET_CCM_LENGTHS failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } } return 0; } /* The core of the cipher check. In addition to the parameters passed to check_one_cipher it also receives the KEY and the plain data. PASS is printed with error messages. The function returns 0 on success. */ static int check_one_cipher_core (int algo, int mode, int flags, const char *key, size_t nkey, const unsigned char *plain, size_t nplain, int bufshift, int pass) { gcry_cipher_hd_t hd; unsigned char in_buffer[1040+1], out_buffer[1040+1]; unsigned char enc_result[1040]; unsigned char *in, *out; int keylen; gcry_error_t err = 0; unsigned int blklen; unsigned int piecelen; unsigned int pos; blklen = get_algo_mode_blklen(algo, mode); assert (nkey == 64); assert (nplain == 1040); assert (sizeof(in_buffer) == nplain + 1); assert (sizeof(out_buffer) == sizeof(in_buffer)); assert (blklen > 0); if ((mode == GCRY_CIPHER_MODE_CBC && (flags & GCRY_CIPHER_CBC_CTS)) || mode == GCRY_CIPHER_MODE_XTS) { /* Input cannot be split in to multiple operations with CTS. */ blklen = nplain; } if (!bufshift) { in = in_buffer; out = out_buffer; } else if (bufshift == 1) { in = in_buffer+1; out = out_buffer; } else if (bufshift == 2) { in = in_buffer+1; out = out_buffer+1; } else { in = in_buffer; out = out_buffer+1; } keylen = gcry_cipher_get_algo_keylen (algo); if (!keylen) { fail ("pass %d, algo %d, mode %d, gcry_cipher_get_algo_keylen failed\n", pass, algo, mode); return -1; } if (keylen < 40 / 8 || keylen > 32) { fail ("pass %d, algo %d, mode %d, keylength problem (%d)\n", pass, algo, mode, keylen); return -1; } if (mode == GCRY_CIPHER_MODE_XTS) { keylen *= 2; } err = gcry_cipher_open (&hd, algo, mode, flags); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_open failed: %s\n", pass, algo, mode, gpg_strerror (err)); return -1; } err = gcry_cipher_setkey (hd, key, keylen); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_setkey failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) return -1; err = gcry_cipher_encrypt (hd, out, nplain, plain, nplain); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } memcpy (enc_result, out, nplain); if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) return -1; err = gcry_cipher_decrypt (hd, in, nplain, out, nplain); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_decrypt failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } if (memcmp (plain, in, nplain)) fail ("pass %d, algo %d, mode %d, encrypt-decrypt mismatch\n", pass, algo, mode); /* Again, using in-place encryption. */ if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) return -1; memcpy (out, plain, nplain); err = gcry_cipher_encrypt (hd, out, nplain, NULL, 0); if (err) { fail ("pass %d, algo %d, mode %d, in-place, gcry_cipher_encrypt failed:" " %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } if (memcmp (enc_result, out, nplain)) fail ("pass %d, algo %d, mode %d, in-place, encrypt mismatch\n", pass, algo, mode); if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) return -1; err = gcry_cipher_decrypt (hd, out, nplain, NULL, 0); if (err) { fail ("pass %d, algo %d, mode %d, in-place, gcry_cipher_decrypt failed:" " %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } if (memcmp (plain, out, nplain)) fail ("pass %d, algo %d, mode %d, in-place, encrypt-decrypt mismatch\n", pass, algo, mode); /* Again, splitting encryption in multiple operations. */ if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) return -1; piecelen = blklen; pos = 0; while (pos < nplain) { if (piecelen > nplain - pos) piecelen = nplain - pos; err = gcry_cipher_encrypt (hd, out + pos, piecelen, plain + pos, piecelen); if (err) { fail ("pass %d, algo %d, mode %d, split-buffer (pos: %d, " "piecelen: %d), gcry_cipher_encrypt failed: %s\n", pass, algo, mode, pos, piecelen, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } pos += piecelen; piecelen = piecelen * 2 - ((piecelen != blklen) ? blklen : 0); } if (memcmp (enc_result, out, nplain)) fail ("pass %d, algo %d, mode %d, split-buffer, encrypt mismatch\n", pass, algo, mode); if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) return -1; piecelen = blklen; pos = 0; while (pos < nplain) { if (piecelen > nplain - pos) piecelen = nplain - pos; err = gcry_cipher_decrypt (hd, in + pos, piecelen, out + pos, piecelen); if (err) { fail ("pass %d, algo %d, mode %d, split-buffer (pos: %d, " "piecelen: %d), gcry_cipher_decrypt failed: %s\n", pass, algo, mode, pos, piecelen, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } pos += piecelen; piecelen = piecelen * 2 - ((piecelen != blklen) ? blklen : 0); } if (memcmp (plain, in, nplain)) fail ("pass %d, algo %d, mode %d, split-buffer, encrypt-decrypt mismatch\n", pass, algo, mode); /* Again, using in-place encryption and splitting encryption in multiple * operations. */ if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) return -1; piecelen = blklen; pos = 0; while (pos < nplain) { if (piecelen > nplain - pos) piecelen = nplain - pos; memcpy (out + pos, plain + pos, piecelen); err = gcry_cipher_encrypt (hd, out + pos, piecelen, NULL, 0); if (err) { fail ("pass %d, algo %d, mode %d, in-place split-buffer (pos: %d, " "piecelen: %d), gcry_cipher_encrypt failed: %s\n", pass, algo, mode, pos, piecelen, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } pos += piecelen; piecelen = piecelen * 2 - ((piecelen != blklen) ? blklen : 0); } if (memcmp (enc_result, out, nplain)) fail ("pass %d, algo %d, mode %d, in-place split-buffer, encrypt mismatch\n", pass, algo, mode); if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) return -1; piecelen = blklen; pos = 0; while (pos < nplain) { if (piecelen > nplain - pos) piecelen = nplain - pos; err = gcry_cipher_decrypt (hd, out + pos, piecelen, NULL, 0); if (err) { fail ("pass %d, algo %d, mode %d, in-place split-buffer (pos: %d, " "piecelen: %d), gcry_cipher_decrypt failed: %s\n", pass, algo, mode, pos, piecelen, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } pos += piecelen; piecelen = piecelen * 2 - ((piecelen != blklen) ? blklen : 0); } if (memcmp (plain, out, nplain)) fail ("pass %d, algo %d, mode %d, in-place split-buffer, encrypt-decrypt" " mismatch\n", pass, algo, mode); gcry_cipher_close (hd); return 0; } static void check_one_cipher (int algo, int mode, int flags) { char key[64+1]; unsigned char plain[1040+1]; int bufshift, i; for (bufshift=0; bufshift < 4; bufshift++) { /* Pass 0: Standard test. */ memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF_" "0123456789abcdef.,;/[]{}-=ABCDEF", 64); memcpy (plain, "foobar42FOOBAR17", 16); for (i = 16; i < 1040; i += 16) { memcpy (&plain[i], &plain[i-16], 16); if (!++plain[i+7]) plain[i+6]++; if (!++plain[i+15]) plain[i+14]++; } if (check_one_cipher_core (algo, mode, flags, key, 64, plain, 1040, bufshift, 0+10*bufshift)) return; /* Pass 1: Key not aligned. */ memmove (key+1, key, 64); if (check_one_cipher_core (algo, mode, flags, key+1, 64, plain, 1040, bufshift, 1+10*bufshift)) return; /* Pass 2: Key not aligned and data not aligned. */ memmove (plain+1, plain, 1040); if (check_one_cipher_core (algo, mode, flags, key+1, 64, plain+1, 1040, bufshift, 2+10*bufshift)) return; /* Pass 3: Key aligned and data not aligned. */ memmove (key, key+1, 64); if (check_one_cipher_core (algo, mode, flags, key, 64, plain+1, 1040, bufshift, 3+10*bufshift)) return; } return; } static void check_ciphers (void) { static const int algos[] = { #if USE_BLOWFISH GCRY_CIPHER_BLOWFISH, #endif #if USE_DES GCRY_CIPHER_DES, GCRY_CIPHER_3DES, #endif #if USE_CAST5 GCRY_CIPHER_CAST5, #endif #if USE_AES GCRY_CIPHER_AES, GCRY_CIPHER_AES192, GCRY_CIPHER_AES256, #endif #if USE_TWOFISH GCRY_CIPHER_TWOFISH, GCRY_CIPHER_TWOFISH128, #endif #if USE_SERPENT GCRY_CIPHER_SERPENT128, GCRY_CIPHER_SERPENT192, GCRY_CIPHER_SERPENT256, #endif #if USE_RFC2268 GCRY_CIPHER_RFC2268_40, #endif #if USE_SEED GCRY_CIPHER_SEED, #endif #if USE_CAMELLIA GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_CAMELLIA192, GCRY_CIPHER_CAMELLIA256, #endif #if USE_IDEA GCRY_CIPHER_IDEA, #endif #if USE_GOST28147 GCRY_CIPHER_GOST28147, #endif 0 }; static const int algos2[] = { #if USE_ARCFOUR GCRY_CIPHER_ARCFOUR, #endif #if USE_SALSA20 GCRY_CIPHER_SALSA20, GCRY_CIPHER_SALSA20R12, #endif #if USE_CHACHA20 GCRY_CIPHER_CHACHA20, #endif 0 }; int i; if (verbose) fprintf (stderr, "Starting Cipher checks.\n"); for (i = 0; algos[i]; i++) { if (gcry_cipher_test_algo (algos[i]) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i]); continue; } if (verbose) fprintf (stderr, " checking %s [%i]\n", gcry_cipher_algo_name (algos[i]), gcry_cipher_map_name (gcry_cipher_algo_name (algos[i]))); check_one_cipher (algos[i], GCRY_CIPHER_MODE_ECB, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CFB, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CFB8, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_OFB, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CTR, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_EAX, 0); if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_CCM_BLOCK_LEN) check_one_cipher (algos[i], GCRY_CIPHER_MODE_CCM, 0); if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN) check_one_cipher (algos[i], GCRY_CIPHER_MODE_GCM, 0); if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_OCB_BLOCK_LEN) check_one_cipher (algos[i], GCRY_CIPHER_MODE_OCB, 0); if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_XTS_BLOCK_LEN) check_one_cipher (algos[i], GCRY_CIPHER_MODE_XTS, 0); } for (i = 0; algos2[i]; i++) { if (gcry_cipher_test_algo (algos2[i]) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos2[i]); continue; } if (verbose) fprintf (stderr, " checking %s\n", gcry_cipher_algo_name (algos2[i])); check_one_cipher (algos2[i], GCRY_CIPHER_MODE_STREAM, 0); if (algos2[i] == GCRY_CIPHER_CHACHA20) check_one_cipher (algos2[i], GCRY_CIPHER_MODE_POLY1305, 0); } /* we have now run all cipher's selftests */ if (verbose) fprintf (stderr, "Completed Cipher checks.\n"); /* TODO: add some extra encryption to test the higher level functions */ } static void check_cipher_modes(void) { if (verbose) fprintf (stderr, "Starting Cipher Mode checks.\n"); check_aes128_cbc_cts_cipher (); check_cbc_mac_cipher (); check_ctr_cipher (); check_cfb_cipher (); check_ofb_cipher (); check_ccm_cipher (); check_gcm_cipher (); check_poly1305_cipher (); check_ocb_cipher (); check_xts_cipher (); check_eax_cipher (); check_gost28147_cipher (); check_stream_cipher (); check_stream_cipher_large_block (); if (verbose) fprintf (stderr, "Completed Cipher Mode checks.\n"); } static void fillbuf_count (char *buf, size_t buflen, unsigned char pos) { while (buflen--) *((unsigned char *)(buf++)) = pos++; } static void check_one_md (int algo, const char *data, int len, const char *expect, int elen, const char *key, int klen) { gcry_md_hd_t hd, hd2; unsigned char *p; int mdlen; int i; int xof = 0; gcry_error_t err = 0; err = gcry_md_open (&hd, algo, 0); if (err) { fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err)); return; } mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 500) { if (mdlen == 0 && (algo == GCRY_MD_SHAKE128 || algo == GCRY_MD_SHAKE256)) { xof = 1; } else { gcry_md_close (hd); fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen); return; } } if (key && klen) { err = gcry_md_setkey (hd, key, klen); if (err) { gcry_md_close (hd); fail ("algo %d, gcry_md_setkey failed: %s\n", algo, gpg_strerror (err)); return; } } if ((*data == '!' && !data[1]) || /* hash one million times a "a" */ (*data == '?' && !data[1])) /* hash million byte data-set with byte pattern 0x00,0x01,0x02,... */ { char aaa[1000]; size_t left = 1000 * 1000; size_t startlen = 1; size_t piecelen = startlen; if (*data == '!') memset (aaa, 'a', 1000); /* Write in chuck with all sizes 1 to 1000 (500500 bytes) */ for (i = 1; i <= 1000 && left > 0; i++) { piecelen = i; if (piecelen > sizeof(aaa)) piecelen = sizeof(aaa); if (piecelen > left) piecelen = left; if (*data == '?') fillbuf_count(aaa, piecelen, 1000 * 1000 - left); gcry_md_write (hd, aaa, piecelen); left -= piecelen; } /* Write in odd size chunks so that we test the buffering. */ while (left > 0) { if (piecelen > sizeof(aaa)) piecelen = sizeof(aaa); if (piecelen > left) piecelen = left; if (*data == '?') fillbuf_count(aaa, piecelen, 1000 * 1000 - left); gcry_md_write (hd, aaa, piecelen); left -= piecelen; if (piecelen == sizeof(aaa)) piecelen = ++startlen; else piecelen = piecelen * 2 - ((piecelen != startlen) ? startlen : 0); } } else gcry_md_write (hd, data, len); err = gcry_md_copy (&hd2, hd); if (err) { fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err)); } gcry_md_close (hd); if (!xof) { p = gcry_md_read (hd2, algo); if (memcmp (p, expect, mdlen)) { printf ("computed: "); for (i = 0; i < mdlen; i++) printf ("%02x ", p[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < mdlen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } } else { char buf[1000]; int outmax = sizeof(buf) > elen ? elen : sizeof(buf); err = gcry_md_copy (&hd, hd2); if (err) { fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err)); } err = gcry_md_extract(hd2, algo, buf, outmax); if (err) { fail ("algo %d, gcry_md_extract failed: %s\n", algo, gpg_strerror (err)); } if (memcmp (buf, expect, outmax)) { printf ("computed: "); for (i = 0; i < outmax; i++) printf ("%02x ", buf[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < outmax; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } memset(buf, 0, sizeof(buf)); /* Extract one byte at time. */ for (i = 0; i < outmax && !err; i++) err = gcry_md_extract(hd, algo, &buf[i], 1); if (err) { fail ("algo %d, gcry_md_extract failed: %s\n", algo, gpg_strerror (err)); } if (memcmp (buf, expect, outmax)) { printf ("computed: "); for (i = 0; i < outmax; i++) printf ("%02x ", buf[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < outmax; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } if (*data == '!' && !data[1]) { int crcalgo = GCRY_MD_RMD160; gcry_md_hd_t crc1, crc2; size_t startlen; size_t piecelen; size_t left; const unsigned char *p1, *p2; int crclen; crclen = gcry_md_get_algo_dlen (crcalgo); err = gcry_md_open (&crc1, crcalgo, 0); if (err) { fail ("algo %d, crcalgo: %d, gcry_md_open failed: %s\n", algo, crcalgo, gpg_strerror (err)); return; } err = gcry_md_open (&crc2, crcalgo, 0); if (err) { fail ("algo %d, crcalgo: %d, gcry_md_open failed: %s\n", algo, crcalgo, gpg_strerror (err)); return; } /* Extract large chucks, total 1000000 additional bytes. */ for (i = 0; i < 1000; i++) { err = gcry_md_extract(hd, algo, buf, 1000); if (!err) gcry_md_write(crc1, buf, 1000); } if (err) { fail ("algo %d, gcry_md_extract failed: %s\n", algo, gpg_strerror (err)); } /* Extract in odd size chunks, total 1000000 additional bytes. */ left = 1000 * 1000; startlen = 1; piecelen = startlen; while (!err && left > 0) { if (piecelen > sizeof(buf)) piecelen = sizeof(buf); if (piecelen > left) piecelen = left; err = gcry_md_extract (hd2, algo, buf, piecelen); if (!err) gcry_md_write(crc2, buf, piecelen); if (err) { fail ("algo %d, gcry_md_extract failed: %s\n", algo, gpg_strerror (err)); } left -= piecelen; if (piecelen == sizeof(buf)) piecelen = ++startlen; else piecelen = piecelen * 2 - ((piecelen != startlen) ? startlen : 0); } p1 = gcry_md_read (crc1, crcalgo); p2 = gcry_md_read (crc2, crcalgo); if (memcmp (p1, p2, crclen)) { printf ("computed: "); for (i = 0; i < crclen; i++) printf ("%02x ", p2[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < crclen; i++) printf ("%02x ", p1[i] & 0xFF); printf ("\n"); fail ("algo %d, large xof output mismatch\n", algo); } gcry_md_close (crc1); gcry_md_close (crc2); } gcry_md_close (hd); } gcry_md_close (hd2); } static void check_one_md_multi (int algo, const char *data, int len, const char *expect) { gpg_error_t err; gcry_buffer_t iov[3]; int iovcnt; char digest[64]; int mdlen; int i; mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 64) { if (mdlen == 0 && (algo == GCRY_MD_SHAKE128 || algo == GCRY_MD_SHAKE256)) return; fail ("check_one_md_multi: algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen); return; } if (*data == '!' && !data[1]) return; /* We can't do that here. */ if (*data == '?' && !data[1]) return; /* We can't do that here. */ memset (iov, 0, sizeof iov); iov[0].data = (void*)data; if (len) { iov[0].len = 1; len--; data++; } iovcnt = 1; if (len >= 4) { iov[iovcnt].data = (void*)data; iov[iovcnt].len = 4; iovcnt++; data += 4; len -= 4; } iov[iovcnt].data = (void*)data; iov[iovcnt].len = len; iovcnt++; assert (iovcnt <= DIM (iov)); err = gcry_md_hash_buffers (algo, 0, digest, iov, iovcnt); if (err) { fail ("check_one_md_multi: algo %d, gcry_hash_buffers failed: %s\n", algo, gpg_strerror (err)); return; } if (memcmp (digest, expect, mdlen)) { printf ("computed: "); for (i = 0; i < mdlen; i++) printf ("%02x ", digest[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < mdlen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("check_one_md_multi: algo %d, digest mismatch\n", algo); } } static void check_digests (void) { static const char blake2_data_vector[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"; static const struct algos { int md; const char *data; const char *expect; int datalen; int expectlen; const char *key; int keylen; } algos[] = { { GCRY_MD_MD2, "", "\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69\x27\x73" }, { GCRY_MD_MD2, "a", "\x32\xec\x01\xec\x4a\x6d\xac\x72\xc0\xab\x96\xfb\x34\xc0\xb5\xd1" }, { GCRY_MD_MD2, "message digest", "\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe\x06\xb0" }, { GCRY_MD_MD4, "", "\x31\xD6\xCF\xE0\xD1\x6A\xE9\x31\xB7\x3C\x59\xD7\xE0\xC0\x89\xC0" }, { GCRY_MD_MD4, "a", "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb\x24" }, { GCRY_MD_MD4, "message digest", "\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01\x4b" }, { GCRY_MD_MD5, "", "\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\x09\x98\xEC\xF8\x42\x7E" }, { GCRY_MD_MD5, "a", "\x0C\xC1\x75\xB9\xC0\xF1\xB6\xA8\x31\xC3\x99\xE2\x69\x77\x26\x61" }, { GCRY_MD_MD5, "abc", "\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72" }, { GCRY_MD_MD5, "message digest", "\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0" }, { GCRY_MD_MD5, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\xc4\x1a\x5c\x0b\x44\x5f\xba\x1a\xda\xbc\xc0\x38\x0e\x0c\x9e\x33" }, { GCRY_MD_MD5, "!", "\x77\x07\xd6\xae\x4e\x02\x7c\x70\xee\xa2\xa9\x35\xc2\x29\x6f\x21" }, { GCRY_MD_MD5, "?", "\x5c\x72\x5c\xbc\x2d\xbb\xe1\x14\x81\x59\xe9\xd9\xcf\x90\x64\x8f" }, { GCRY_MD_SHA1, "abc", "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E" "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D" }, { GCRY_MD_SHA1, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE" "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1" }, { GCRY_MD_SHA1, "!" /* kludge for "a"*1000000 */ , "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E" "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F" }, { GCRY_MD_SHA1, "?" /* kludge for "\x00\x01\x02"..."\xfe\xff\x00\x01"... (length 1000000) */ , "\x5f\x8d\x3c\x4f\x12\xf0\x49\x9e\x28\x73" "\x79\xec\x97\x3b\x98\x4c\x94\x75\xaa\x8f" }, { GCRY_MD_SHA1, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\xf5\xd9\xcb\x66\x91\xb4\x7a\x7c\x60\x35\xe2\x1c\x38\x26\x52\x13" "\x8e\xd5\xe5\xdf" }, /* From RFC3874 */ { GCRY_MD_SHA224, "abc", "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3" "\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7" }, { GCRY_MD_SHA224, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50" "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25" }, { GCRY_MD_SHA224, "!", "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b" "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67" }, { GCRY_MD_SHA224, "?", "\xfa\xb9\xf0\xdf\x12\xfe\xa1\x1a\x34\x78\x96\x31\xe6\x53\x48\xbf" "\x3b\xca\x70\x78\xf2\x44\xdf\x62\xab\x27\xb8\xda" }, { GCRY_MD_SHA224, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\x80\xf0\x60\x79\xb0\xe9\x65\xab\x8a\x76\xbf\x6e\x88\x64\x75\xe7" "\xfd\xf0\xc2\x4c\xf6\xf2\xa6\x01\xed\x50\x71\x08" }, { GCRY_MD_SHA256, "abc", "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23" "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" }, { GCRY_MD_SHA256, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39" "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" }, { GCRY_MD_SHA256, "!", "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67" "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0" }, { GCRY_MD_SHA256, "?", "\x67\x87\x0d\xfc\x9c\x64\xe7\xaa\x27\x0a\x3f\x7e\x80\x51\xae\x65" "\xd2\x07\xf9\x3f\xc3\xdf\x04\xd7\x57\x2e\x63\x65\xaf\x69\xcd\x0d" }, { GCRY_MD_SHA256, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\xb0\x18\x70\x67\xb8\xac\x68\x50\xec\x95\x43\x77\xb5\x44\x5b\x0f" "\x2e\xbd\x40\xc9\xdc\x2a\x2c\x33\x8b\x53\xeb\x3e\x9e\x01\xd7\x02" }, { GCRY_MD_SHA384, "abc", "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07" "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed" "\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7" }, { GCRY_MD_SHA384, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\xe4\x6d\xb4\x28\x33\x77\x99\x49\x94\x0f\xcf\x87\xc2\x2f\x30\xd6" "\x06\x24\x82\x9d\x80\x64\x8a\x07\xa1\x20\x8f\x5f\xf3\x85\xb3\xaa" "\x39\xb8\x61\x00\xfc\x7f\x18\xc6\x82\x23\x4b\x45\xfa\xf1\xbc\x69" }, { GCRY_MD_SHA384, "!", "\x9d\x0e\x18\x09\x71\x64\x74\xcb\x08\x6e\x83\x4e\x31\x0a\x4a\x1c" "\xed\x14\x9e\x9c\x00\xf2\x48\x52\x79\x72\xce\xc5\x70\x4c\x2a\x5b" "\x07\xb8\xb3\xdc\x38\xec\xc4\xeb\xae\x97\xdd\xd8\x7f\x3d\x89\x85" }, { GCRY_MD_SHA384, "?", "\xfa\x77\xbb\x86\x3a\xd5\xae\x88\xa9\x9c\x5e\xda\xb5\xc7\xcb\x40" "\xcd\xf4\x30\xef\xa8\x1b\x23\x7b\xa9\xde\xfd\x81\x12\xf6\x7e\xed" "\xa7\xd2\x27\x91\xd1\xbc\x76\x44\x57\x59\x71\x11\xe6\x8a\x2c\xde" }, { GCRY_MD_SHA512, "abc", "\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31" "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A" "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD" "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F" }, { GCRY_MD_SHA512, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\x72\x8c\xde\xd8\xe4\xd7\xb6\xa5\x0f\xde\x6b\x4d\x33\xaf\x15\x19" "\xdd\xec\x62\x0f\xf7\x1a\x1e\x10\x32\x05\x02\xa6\xb0\x1f\x70\x37" "\xbc\xd7\x15\xed\x71\x6c\x78\x20\xc8\x54\x87\xd0\x66\x6a\x17\x83" "\x05\x61\x92\xbe\xcc\x8f\x3b\xbf\x11\x72\x22\x69\x23\x5b\x48\x5c" }, { GCRY_MD_SHA512, "!", "\xe7\x18\x48\x3d\x0c\xe7\x69\x64\x4e\x2e\x42\xc7\xbc\x15\xb4\x63" "\x8e\x1f\x98\xb1\x3b\x20\x44\x28\x56\x32\xa8\x03\xaf\xa9\x73\xeb" "\xde\x0f\xf2\x44\x87\x7e\xa6\x0a\x4c\xb0\x43\x2c\xe5\x77\xc3\x1b" "\xeb\x00\x9c\x5c\x2c\x49\xaa\x2e\x4e\xad\xb2\x17\xad\x8c\xc0\x9b" }, { GCRY_MD_SHA512, "?", "\x91\xe9\x42\x4e\xa9\xdc\x44\x01\x40\x64\xa4\x5a\x69\xcc\xac\xa3" "\x74\xee\x78\xeb\x79\x1f\x94\x38\x5b\x73\xef\xf8\xfd\x5d\x74\xd8" "\x51\x36\xfe\x63\x52\xde\x07\x70\x95\xd6\x78\x2b\x7b\x46\x8a\x2c" "\x30\x0f\x48\x0c\x74\x43\x06\xdb\xa3\x8d\x64\x3d\xe9\xa1\xa7\x72" }, { GCRY_MD_SHA3_224, "abc", "\xe6\x42\x82\x4c\x3f\x8c\xf2\x4a\xd0\x92\x34\xee\x7d\x3c\x76\x6f" "\xc9\xa3\xa5\x16\x8d\x0c\x94\xad\x73\xb4\x6f\xdf" }, { GCRY_MD_SHA3_256, "abc", "\x3a\x98\x5d\xa7\x4f\xe2\x25\xb2\x04\x5c\x17\x2d\x6b\xd3\x90\xbd" "\x85\x5f\x08\x6e\x3e\x9d\x52\x5b\x46\xbf\xe2\x45\x11\x43\x15\x32" }, { GCRY_MD_SHA3_384, "abc", "\xec\x01\x49\x82\x88\x51\x6f\xc9\x26\x45\x9f\x58\xe2\xc6\xad\x8d" "\xf9\xb4\x73\xcb\x0f\xc0\x8c\x25\x96\xda\x7c\xf0\xe4\x9b\xe4\xb2" "\x98\xd8\x8c\xea\x92\x7a\xc7\xf5\x39\xf1\xed\xf2\x28\x37\x6d\x25" }, { GCRY_MD_SHA3_512, "abc", "\xb7\x51\x85\x0b\x1a\x57\x16\x8a\x56\x93\xcd\x92\x4b\x6b\x09\x6e" "\x08\xf6\x21\x82\x74\x44\xf7\x0d\x88\x4f\x5d\x02\x40\xd2\x71\x2e" "\x10\xe1\x16\xe9\x19\x2a\xf3\xc9\x1a\x7e\xc5\x76\x47\xe3\x93\x40" "\x57\x34\x0b\x4c\xf4\x08\xd5\xa5\x65\x92\xf8\x27\x4e\xec\x53\xf0" }, { GCRY_MD_SHA3_224, "", "\x6b\x4e\x03\x42\x36\x67\xdb\xb7\x3b\x6e\x15\x45\x4f\x0e\xb1\xab" "\xd4\x59\x7f\x9a\x1b\x07\x8e\x3f\x5b\x5a\x6b\xc7" }, { GCRY_MD_SHA3_256, "", "\xa7\xff\xc6\xf8\xbf\x1e\xd7\x66\x51\xc1\x47\x56\xa0\x61\xd6\x62" "\xf5\x80\xff\x4d\xe4\x3b\x49\xfa\x82\xd8\x0a\x4b\x80\xf8\x43\x4a" }, { GCRY_MD_SHA3_384, "", "\x0c\x63\xa7\x5b\x84\x5e\x4f\x7d\x01\x10\x7d\x85\x2e\x4c\x24\x85" "\xc5\x1a\x50\xaa\xaa\x94\xfc\x61\x99\x5e\x71\xbb\xee\x98\x3a\x2a" "\xc3\x71\x38\x31\x26\x4a\xdb\x47\xfb\x6b\xd1\xe0\x58\xd5\xf0\x04" }, { GCRY_MD_SHA3_512, "", "\xa6\x9f\x73\xcc\xa2\x3a\x9a\xc5\xc8\xb5\x67\xdc\x18\x5a\x75\x6e" "\x97\xc9\x82\x16\x4f\xe2\x58\x59\xe0\xd1\xdc\xc1\x47\x5c\x80\xa6" "\x15\xb2\x12\x3a\xf1\xf5\xf9\x4c\x11\xe3\xe9\x40\x2c\x3a\xc5\x58" "\xf5\x00\x19\x9d\x95\xb6\xd3\xe3\x01\x75\x85\x86\x28\x1d\xcd\x26" }, { GCRY_MD_SHA3_224, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlm" "nomnopnopq", "\x8a\x24\x10\x8b\x15\x4a\xda\x21\xc9\xfd\x55\x74\x49\x44\x79\xba" "\x5c\x7e\x7a\xb7\x6e\xf2\x64\xea\xd0\xfc\xce\x33" }, { GCRY_MD_SHA3_256, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlm" "nomnopnopq", "\x41\xc0\xdb\xa2\xa9\xd6\x24\x08\x49\x10\x03\x76\xa8\x23\x5e\x2c" "\x82\xe1\xb9\x99\x8a\x99\x9e\x21\xdb\x32\xdd\x97\x49\x6d\x33\x76" }, { GCRY_MD_SHA3_384, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlm" "nomnopnopq", "\x99\x1c\x66\x57\x55\xeb\x3a\x4b\x6b\xbd\xfb\x75\xc7\x8a\x49\x2e" "\x8c\x56\xa2\x2c\x5c\x4d\x7e\x42\x9b\xfd\xbc\x32\xb9\xd4\xad\x5a" "\xa0\x4a\x1f\x07\x6e\x62\xfe\xa1\x9e\xef\x51\xac\xd0\x65\x7c\x22" }, { GCRY_MD_SHA3_512, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlm" "nomnopnopq", "\x04\xa3\x71\xe8\x4e\xcf\xb5\xb8\xb7\x7c\xb4\x86\x10\xfc\xa8\x18" "\x2d\xd4\x57\xce\x6f\x32\x6a\x0f\xd3\xd7\xec\x2f\x1e\x91\x63\x6d" "\xee\x69\x1f\xbe\x0c\x98\x53\x02\xba\x1b\x0d\x8d\xc7\x8c\x08\x63" "\x46\xb5\x33\xb4\x9c\x03\x0d\x99\xa2\x7d\xaf\x11\x39\xd6\xe7\x5e" }, { GCRY_MD_SHA3_224, "abcdefghbcdefghicdefghijdefghijkefghijklfghijk" "lmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x54\x3e\x68\x68\xe1\x66\x6c\x1a\x64\x36\x30\xdf\x77\x36\x7a\xe5" "\xa6\x2a\x85\x07\x0a\x51\xc1\x4c\xbf\x66\x5c\xbc" }, { GCRY_MD_SHA3_256, "abcdefghbcdefghicdefghijdefghijkefghijklfghijk" "lmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x91\x6f\x60\x61\xfe\x87\x97\x41\xca\x64\x69\xb4\x39\x71\xdf\xdb" "\x28\xb1\xa3\x2d\xc3\x6c\xb3\x25\x4e\x81\x2b\xe2\x7a\xad\x1d\x18" }, { GCRY_MD_SHA3_384, "abcdefghbcdefghicdefghijdefghijkefghijklfghijk" "lmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x79\x40\x7d\x3b\x59\x16\xb5\x9c\x3e\x30\xb0\x98\x22\x97\x47\x91" "\xc3\x13\xfb\x9e\xcc\x84\x9e\x40\x6f\x23\x59\x2d\x04\xf6\x25\xdc" "\x8c\x70\x9b\x98\xb4\x3b\x38\x52\xb3\x37\x21\x61\x79\xaa\x7f\xc7" }, { GCRY_MD_SHA3_512, "abcdefghbcdefghicdefghijdefghijkefghijklfghijk" "lmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\xaf\xeb\xb2\xef\x54\x2e\x65\x79\xc5\x0c\xad\x06\xd2\xe5\x78\xf9" "\xf8\xdd\x68\x81\xd7\xdc\x82\x4d\x26\x36\x0f\xee\xbf\x18\xa4\xfa" "\x73\xe3\x26\x11\x22\x94\x8e\xfc\xfd\x49\x2e\x74\xe8\x2e\x21\x89" "\xed\x0f\xb4\x40\xd1\x87\xf3\x82\x27\x0c\xb4\x55\xf2\x1d\xd1\x85" }, { GCRY_MD_SHA3_224, "!", "\xd6\x93\x35\xb9\x33\x25\x19\x2e\x51\x6a\x91\x2e\x6d\x19\xa1\x5c" "\xb5\x1c\x6e\xd5\xc1\x52\x43\xe7\xa7\xfd\x65\x3c" }, { GCRY_MD_SHA3_256, "!", "\x5c\x88\x75\xae\x47\x4a\x36\x34\xba\x4f\xd5\x5e\xc8\x5b\xff\xd6" "\x61\xf3\x2a\xca\x75\xc6\xd6\x99\xd0\xcd\xcb\x6c\x11\x58\x91\xc1" }, { GCRY_MD_SHA3_384, "!", "\xee\xe9\xe2\x4d\x78\xc1\x85\x53\x37\x98\x34\x51\xdf\x97\xc8\xad" "\x9e\xed\xf2\x56\xc6\x33\x4f\x8e\x94\x8d\x25\x2d\x5e\x0e\x76\x84" "\x7a\xa0\x77\x4d\xdb\x90\xa8\x42\x19\x0d\x2c\x55\x8b\x4b\x83\x40" }, { GCRY_MD_SHA3_512, "!", "\x3c\x3a\x87\x6d\xa1\x40\x34\xab\x60\x62\x7c\x07\x7b\xb9\x8f\x7e" "\x12\x0a\x2a\x53\x70\x21\x2d\xff\xb3\x38\x5a\x18\xd4\xf3\x88\x59" "\xed\x31\x1d\x0a\x9d\x51\x41\xce\x9c\xc5\xc6\x6e\xe6\x89\xb2\x66" "\xa8\xaa\x18\xac\xe8\x28\x2a\x0e\x0d\xb5\x96\xc9\x0b\x0a\x7b\x87" }, { GCRY_MD_SHA3_224, "?", "\x1b\xd1\xc6\x12\x02\x35\x52\x8b\x44\x7e\x16\x39\x20\x05\xec\x67" "\x2d\x57\x20\xe0\x90\xc9\x78\x08\x86\x4f\x1b\xd0" }, { GCRY_MD_SHA3_256, "?", "\xfe\xb7\xf4\x76\x78\x97\x48\x2f\xe2\x29\x1b\x66\x85\xc1\x7b\x45" "\xc5\x08\xed\x82\x50\xcc\x5d\x99\x96\xd2\xc3\x82\x1a\xa8\xd4\xa7" }, { GCRY_MD_SHA3_384, "?", "\x45\x1f\x0b\x93\x4b\xca\x3e\x65\x93\xd4\xaa\x8c\x18\xc1\x04\x84" "\x12\xd5\x1e\x35\xe1\x05\xd9\x77\x3f\xc1\x08\x8b\x77\x36\xad\x4a" "\x33\x70\xaf\x49\x8b\xea\x4c\x5c\x52\xe7\x5b\xed\x31\x74\x57\x12" }, { GCRY_MD_SHA3_512, "?", "\xa2\xee\xb5\x6f\x2a\x87\xa5\xb3\x9b\xd9\x1c\xf0\xaa\xdf\xb1\xd5" "\xad\x0a\x1a\xaa\xd3\x63\x81\xcf\xb8\x7c\x36\xa7\x80\x3b\x03\xd6" "\x31\x5c\x5d\x33\x8e\x52\xb1\x42\x4d\x27\x1c\xa2\xa5\xf2\xc5\x97" "\x10\x12\xe5\xee\x86\xa3\xcc\xaf\x91\x7a\x94\x28\x65\xea\x66\xe3" }, { GCRY_MD_RMD160, "", "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28" "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31" }, { GCRY_MD_RMD160, "a", "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae" "\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe" }, { GCRY_MD_RMD160, "abc", "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04" "\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc" }, { GCRY_MD_RMD160, "message digest", "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8" "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36" }, { GCRY_MD_RMD160, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\x06\x6d\x3c\x4e\xc9\xba\x89\x75\x16\x90\x96\x4e\xfd\x43\x07\xde" "\x04\xca\x69\x6b" }, { GCRY_MD_RMD160, "!", "\x52\x78\x32\x43\xc1\x69\x7b\xdb\xe1\x6d\x37\xf9\x7f\x68\xf0\x83" "\x25\xdc\x15\x28" }, { GCRY_MD_RMD160, "?", "\x68\x14\x86\x70\x3d\x51\x4e\x36\x68\x50\xf8\xb3\x00\x75\xda\x49" "\x0a\xaa\x2c\xf6" }, { GCRY_MD_CRC32, "", "\x00\x00\x00\x00" }, { GCRY_MD_CRC32, "foo", "\x8c\x73\x65\x21" }, { GCRY_MD_CRC32, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\x4A\x53\x7D\x67" }, { GCRY_MD_CRC32, "123456789", "\xcb\xf4\x39\x26" }, { GCRY_MD_CRC32, "!", "\xdc\x25\xbf\xbc" }, { GCRY_MD_CRC32, "?", "\x61\x82\x29\x1B" }, { GCRY_MD_CRC32_RFC1510, "", "\x00\x00\x00\x00" }, { GCRY_MD_CRC32_RFC1510, "foo", "\x73\x32\xbc\x33" }, { GCRY_MD_CRC32_RFC1510, "test0123456789", "\xb8\x3e\x88\xd6" }, { GCRY_MD_CRC32_RFC1510, "MASSACHVSETTS INSTITVTE OF TECHNOLOGY", "\xe3\x41\x80\xf7" }, { GCRY_MD_CRC32_RFC1510, "\x80\x00", "\x3b\x83\x98\x4b", 2 }, { GCRY_MD_CRC32_RFC1510, "\x00\x08", "\x0e\xdb\x88\x32", 2 }, { GCRY_MD_CRC32_RFC1510, "\x00\x80", "\xed\xb8\x83\x20", 2 }, { GCRY_MD_CRC32_RFC1510, "\x80", "\xed\xb8\x83\x20" }, { GCRY_MD_CRC32_RFC1510, "\x80\x00\x00\x00", "\xed\x59\xb6\x3b", 4 }, { GCRY_MD_CRC32_RFC1510, "\x00\x00\x00\x01", "\x77\x07\x30\x96", 4 }, { GCRY_MD_CRC32_RFC1510, "123456789", "\x2d\xfd\x2d\x88" }, { GCRY_MD_CRC32_RFC1510, "!", "\xce\x5c\x74\x22" }, { GCRY_MD_CRC32_RFC1510, "?", "\x73\xfb\xe2\x85" }, { GCRY_MD_CRC24_RFC2440, "", "\xb7\x04\xce" }, { GCRY_MD_CRC24_RFC2440, "foo", "\x4f\xc2\x55" }, { GCRY_MD_CRC24_RFC2440, "123456789", "\x21\xcf\x02" }, { GCRY_MD_CRC24_RFC2440, "!", "\xa5\xcb\x6b" }, { GCRY_MD_CRC24_RFC2440, "?", "\x7f\x67\x03" }, { GCRY_MD_TIGER, "", "\x24\xF0\x13\x0C\x63\xAC\x93\x32\x16\x16\x6E\x76" "\xB1\xBB\x92\x5F\xF3\x73\xDE\x2D\x49\x58\x4E\x7A" }, { GCRY_MD_TIGER, "abc", "\xF2\x58\xC1\xE8\x84\x14\xAB\x2A\x52\x7A\xB5\x41" "\xFF\xC5\xB8\xBF\x93\x5F\x7B\x95\x1C\x13\x29\x51" }, { GCRY_MD_TIGER, "Tiger", "\x9F\x00\xF5\x99\x07\x23\x00\xDD\x27\x6A\xBB\x38" "\xC8\xEB\x6D\xEC\x37\x79\x0C\x11\x6F\x9D\x2B\xDF" }, { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg" "hijklmnopqrstuvwxyz0123456789+-", "\x87\xFB\x2A\x90\x83\x85\x1C\xF7\x47\x0D\x2C\xF8" "\x10\xE6\xDF\x9E\xB5\x86\x44\x50\x34\xA5\xA3\x86" }, { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdef" "ghijklmnopqrstuvwxyz+0123456789", "\x46\x7D\xB8\x08\x63\xEB\xCE\x48\x8D\xF1\xCD\x12" "\x61\x65\x5D\xE9\x57\x89\x65\x65\x97\x5F\x91\x97" }, { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, " "by Ross Anderson and Eli Biham", "\x0C\x41\x0A\x04\x29\x68\x86\x8A\x16\x71\xDA\x5A" "\x3F\xD2\x9A\x72\x5E\xC1\xE4\x57\xD3\xCD\xB3\x03" }, { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, " "by Ross Anderson and Eli Biham, proceedings of Fa" "st Software Encryption 3, Cambridge.", "\xEB\xF5\x91\xD5\xAF\xA6\x55\xCE\x7F\x22\x89\x4F" "\xF8\x7F\x54\xAC\x89\xC8\x11\xB6\xB0\xDA\x31\x93" }, { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, " "by Ross Anderson and Eli Biham, proceedings of Fa" "st Software Encryption 3, Cambridge, 1996.", "\x3D\x9A\xEB\x03\xD1\xBD\x1A\x63\x57\xB2\x77\x4D" "\xFD\x6D\x5B\x24\xDD\x68\x15\x1D\x50\x39\x74\xFC" }, { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh" "ijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRS" "TUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", "\x00\xB8\x3E\xB4\xE5\x34\x40\xC5\x76\xAC\x6A\xAE" "\xE0\xA7\x48\x58\x25\xFD\x15\xE7\x0A\x59\xFF\xE4" }, { GCRY_MD_TIGER1, "", "\x32\x93\xAC\x63\x0C\x13\xF0\x24\x5F\x92\xBB\xB1" "\x76\x6E\x16\x16\x7A\x4E\x58\x49\x2D\xDE\x73\xF3" }, { GCRY_MD_TIGER1, "a", "\x77\xBE\xFB\xEF\x2E\x7E\xF8\xAB\x2E\xC8\xF9\x3B" "\xF5\x87\xA7\xFC\x61\x3E\x24\x7F\x5F\x24\x78\x09" }, { GCRY_MD_TIGER1, "abc", "\x2A\xAB\x14\x84\xE8\xC1\x58\xF2\xBF\xB8\xC5\xFF" "\x41\xB5\x7A\x52\x51\x29\x13\x1C\x95\x7B\x5F\x93" }, { GCRY_MD_TIGER1, "message digest", "\xD9\x81\xF8\xCB\x78\x20\x1A\x95\x0D\xCF\x30\x48" "\x75\x1E\x44\x1C\x51\x7F\xCA\x1A\xA5\x5A\x29\xF6" }, { GCRY_MD_TIGER1, "abcdefghijklmnopqrstuvwxyz", "\x17\x14\xA4\x72\xEE\xE5\x7D\x30\x04\x04\x12\xBF" "\xCC\x55\x03\x2A\x0B\x11\x60\x2F\xF3\x7B\xEE\xE9" }, { GCRY_MD_TIGER1, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x0F\x7B\xF9\xA1\x9B\x9C\x58\xF2\xB7\x61\x0D\xF7" "\xE8\x4F\x0A\xC3\xA7\x1C\x63\x1E\x7B\x53\xF7\x8E" }, { GCRY_MD_TIGER1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789", "\x8D\xCE\xA6\x80\xA1\x75\x83\xEE\x50\x2B\xA3\x8A" "\x3C\x36\x86\x51\x89\x0F\xFB\xCC\xDC\x49\xA8\xCC" }, { GCRY_MD_TIGER1, "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890", "\x1C\x14\x79\x55\x29\xFD\x9F\x20\x7A\x95\x8F\x84" "\xC5\x2F\x11\xE8\x87\xFA\x0C\xAB\xDF\xD9\x1B\xFD" }, { GCRY_MD_TIGER1, "!", "\x6D\xB0\xE2\x72\x9C\xBE\xAD\x93\xD7\x15\xC6\xA7" "\xD3\x63\x02\xE9\xB3\xCE\xE0\xD2\xBC\x31\x4B\x41" }, { GCRY_MD_TIGER1, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\x60\xee\xdf\x95\x39\xc8\x44\x94\x64\xdc\xdf\x3d\x2e\x1c\xe5\x79" "\x6a\x95\xbd\x30\x68\x8c\x7e\xb8" }, { GCRY_MD_TIGER1, "?", "\x4b\xe2\x3f\x23\xf5\x34\xbe\xbf\x97\x42\x95\x80" "\x54\xe4\x6c\x12\x64\x85\x44\x0a\xa9\x49\x9b\x65" }, { GCRY_MD_TIGER2, "", "\x44\x41\xBE\x75\xF6\x01\x87\x73\xC2\x06\xC2\x27" "\x45\x37\x4B\x92\x4A\xA8\x31\x3F\xEF\x91\x9F\x41" }, { GCRY_MD_TIGER2, "a", "\x67\xE6\xAE\x8E\x9E\x96\x89\x99\xF7\x0A\x23\xE7" "\x2A\xEA\xA9\x25\x1C\xBC\x7C\x78\xA7\x91\x66\x36" }, { GCRY_MD_TIGER2, "abc", "\xF6\x8D\x7B\xC5\xAF\x4B\x43\xA0\x6E\x04\x8D\x78" "\x29\x56\x0D\x4A\x94\x15\x65\x8B\xB0\xB1\xF3\xBF" }, { GCRY_MD_TIGER2, "message digest", "\xE2\x94\x19\xA1\xB5\xFA\x25\x9D\xE8\x00\x5E\x7D" "\xE7\x50\x78\xEA\x81\xA5\x42\xEF\x25\x52\x46\x2D" }, { GCRY_MD_TIGER2, "abcdefghijklmnopqrstuvwxyz", "\xF5\xB6\xB6\xA7\x8C\x40\x5C\x85\x47\xE9\x1C\xD8" "\x62\x4C\xB8\xBE\x83\xFC\x80\x4A\x47\x44\x88\xFD" }, { GCRY_MD_TIGER2, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\xA6\x73\x7F\x39\x97\xE8\xFB\xB6\x3D\x20\xD2\xDF" "\x88\xF8\x63\x76\xB5\xFE\x2D\x5C\xE3\x66\x46\xA9" }, { GCRY_MD_TIGER2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789", "\xEA\x9A\xB6\x22\x8C\xEE\x7B\x51\xB7\x75\x44\xFC" "\xA6\x06\x6C\x8C\xBB\x5B\xBA\xE6\x31\x95\x05\xCD" }, { GCRY_MD_TIGER2, "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890", "\xD8\x52\x78\x11\x53\x29\xEB\xAA\x0E\xEC\x85\xEC" "\xDC\x53\x96\xFD\xA8\xAA\x3A\x58\x20\x94\x2F\xFF" }, { GCRY_MD_TIGER2, "!", "\xE0\x68\x28\x1F\x06\x0F\x55\x16\x28\xCC\x57\x15" "\xB9\xD0\x22\x67\x96\x91\x4D\x45\xF7\x71\x7C\xF4" }, { GCRY_MD_WHIRLPOOL, "", "\x19\xFA\x61\xD7\x55\x22\xA4\x66\x9B\x44\xE3\x9C\x1D\x2E\x17\x26" "\xC5\x30\x23\x21\x30\xD4\x07\xF8\x9A\xFE\xE0\x96\x49\x97\xF7\xA7" "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB\xCF\x88\xE3\xE0\x3C\x4F\x07\x57" "\xEA\x89\x64\xE5\x9B\x63\xD9\x37\x08\xB1\x38\xCC\x42\xA6\x6E\xB3" }, { GCRY_MD_WHIRLPOOL, "a", "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F\x11\xA6\x72\x06\x53\x1F\xB7\xD7" "\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42" "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59" "\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" }, { GCRY_MD_WHIRLPOOL, "?", "\x88\xf0\x78\x6d\x0d\x47\xe5\x32\x1f\x88\xb1\x48\x05\x53\x58\x7d" "\x19\x4b\x32\x9b\xf1\xfb\x17\xc5\x98\x3a\x87\xa2\x48\x61\x3d\x2b" "\xb2\xbc\x9f\x0d\xd2\x14\x37\x30\x55\x30\x91\xa7\xb8\x0c\x0f\x80" "\x7c\x7b\x94\xf6\x55\xf6\x0b\x12\x85\x0c\x8e\x6d\x17\x5b\x1e\x71" }, { GCRY_MD_WHIRLPOOL, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B\xF1\x1F\x00\xED\x9A\xBA\x26\x90" "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E" "\x08\xEB\xA2\x66\x29\x12\x9D\x8F\xB7\xCB\x57\x21\x1B\x92\x81\xA6" "\x55\x17\xCC\x87\x9D\x7B\x96\x21\x42\xC6\x5F\x5A\x7A\xF0\x14\x67" }, { GCRY_MD_WHIRLPOOL, "!", "\x0C\x99\x00\x5B\xEB\x57\xEF\xF5\x0A\x7C\xF0\x05\x56\x0D\xDF\x5D" "\x29\x05\x7F\xD8\x6B\x20\xBF\xD6\x2D\xEC\xA0\xF1\xCC\xEA\x4A\xF5" "\x1F\xC1\x54\x90\xED\xDC\x47\xAF\x32\xBB\x2B\x66\xC3\x4F\xF9\xAD" "\x8C\x60\x08\xAD\x67\x7F\x77\x12\x69\x53\xB2\x26\xE4\xED\x8B\x01" }, { GCRY_MD_WHIRLPOOL, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\xcd\x4a\xa4\xaf\xf6\x7f\xec\xce\xbb\x6c\xdf\x91\x96\xe1\xf3\xf6" "\x78\xe2\x8e\x3a\x76\xcf\x06\xc7\xa1\x20\x7b\x81\x32\x60\xf7\x8e" "\x68\x19\x62\x33\x4f\xe5\x0a\x24\xfb\x9e\x74\x03\x74\xe4\x61\x29" "\x6f\xb3\x13\xe6\x7e\xc2\x88\x99\x9e\xfb\xe7\x9d\x11\x30\x89\xd2" }, { GCRY_MD_GOSTR3411_94, "This is message, length=32 bytes", "\xB1\xC4\x66\xD3\x75\x19\xB8\x2E\x83\x19\x81\x9F\xF3\x25\x95\xE0" "\x47\xA2\x8C\xB6\xF8\x3E\xFF\x1C\x69\x16\xA8\x15\xA6\x37\xFF\xFA" }, { GCRY_MD_GOSTR3411_94, "Suppose the original message has length = 50 bytes", "\x47\x1A\xBA\x57\xA6\x0A\x77\x0D\x3A\x76\x13\x06\x35\xC1\xFB\xEA" "\x4E\xF1\x4D\xE5\x1F\x78\xB4\xAE\x57\xDD\x89\x3B\x62\xF5\x52\x08" }, { GCRY_MD_GOSTR3411_94, "", "\xCE\x85\xB9\x9C\xC4\x67\x52\xFF\xFE\xE3\x5C\xAB\x9A\x7B\x02\x78" "\xAB\xB4\xC2\xD2\x05\x5C\xFF\x68\x5A\xF4\x91\x2C\x49\x49\x0F\x8D" }, { GCRY_MD_GOSTR3411_94, "!", "\x5C\x00\xCC\xC2\x73\x4C\xDD\x33\x32\xD3\xD4\x74\x95\x76\xE3\xC1" "\xA7\xDB\xAF\x0E\x7E\xA7\x4E\x9F\xA6\x02\x41\x3C\x90\xA1\x29\xFA" }, { GCRY_MD_GOSTR3411_94, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\x00\x0c\x85\xc8\x54\xd2\x9a\x6e\x47\x2e\xff\xa4\xa2\xe7\xd0\x2e" "\x8a\xcc\x14\x53\xb4\x87\xc8\x5c\x95\x9a\x3e\x85\x8c\x7d\x6e\x0c" }, { GCRY_MD_STRIBOG512, "012345678901234567890123456789012345678901234567890123456789012", "\x1b\x54\xd0\x1a\x4a\xf5\xb9\xd5\xcc\x3d\x86\xd6\x8d\x28\x54\x62" "\xb1\x9a\xbc\x24\x75\x22\x2f\x35\xc0\x85\x12\x2b\xe4\xba\x1f\xfa" "\x00\xad\x30\xf8\x76\x7b\x3a\x82\x38\x4c\x65\x74\xf0\x24\xc3\x11" "\xe2\xa4\x81\x33\x2b\x08\xef\x7f\x41\x79\x78\x91\xc1\x64\x6f\x48" }, { GCRY_MD_STRIBOG256, "012345678901234567890123456789012345678901234567890123456789012", "\x9d\x15\x1e\xef\xd8\x59\x0b\x89\xda\xa6\xba\x6c\xb7\x4a\xf9\x27" "\x5d\xd0\x51\x02\x6b\xb1\x49\xa4\x52\xfd\x84\xe5\xe5\x7b\x55\x00" }, { GCRY_MD_STRIBOG512, "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee" "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20" "\xf1\x20\xec\xee\xf0\xff\x20\xf1\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20" "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0\xfb\xff\x20\xef\xeb\xfa\xea\xfb" "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb", "\x1e\x88\xe6\x22\x26\xbf\xca\x6f\x99\x94\xf1\xf2\xd5\x15\x69\xe0" "\xda\xf8\x47\x5a\x3b\x0f\xe6\x1a\x53\x00\xee\xe4\x6d\x96\x13\x76" "\x03\x5f\xe8\x35\x49\xad\xa2\xb8\x62\x0f\xcd\x7c\x49\x6c\xe5\xb3" "\x3f\x0c\xb9\xdd\xdc\x2b\x64\x60\x14\x3b\x03\xda\xba\xc9\xfb\x28" }, { GCRY_MD_STRIBOG256, "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee" "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20" "\xf1\x20\xec\xee\xf0\xff\x20\xf1\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20" "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0\xfb\xff\x20\xef\xeb\xfa\xea\xfb" "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb", "\x9d\xd2\xfe\x4e\x90\x40\x9e\x5d\xa8\x7f\x53\x97\x6d\x74\x05\xb0" "\xc0\xca\xc6\x28\xfc\x66\x9a\x74\x1d\x50\x06\x3c\x55\x7e\x8f\x50" }, #include "./sha3-224.h" #include "./sha3-256.h" #include "./sha3-384.h" #include "./sha3-512.h" { GCRY_MD_SHAKE128, "", "\x7F\x9C\x2B\xA4\xE8\x8F\x82\x7D\x61\x60\x45\x50\x76\x05\x85\x3E" "\xD7\x3B\x80\x93\xF6\xEF\xBC\x88\xEB\x1A\x6E\xAC\xFA\x66\xEF\x26" "\x3C\xB1\xEE\xA9\x88\x00\x4B\x93\x10\x3C\xFB\x0A\xEE\xFD\x2A\x68" "\x6E\x01\xFA\x4A\x58\xE8\xA3\x63\x9C\xA8\xA1\xE3\xF9\xAE\x57\xE2" "\x35\xB8\xCC\x87\x3C\x23\xDC\x62\xB8\xD2\x60\x16\x9A\xFA\x2F\x75" "\xAB\x91\x6A\x58\xD9\x74\x91\x88\x35\xD2\x5E\x6A\x43\x50\x85\xB2" "\xBA\xDF\xD6\xDF\xAA\xC3\x59\xA5\xEF\xBB\x7B\xCC\x4B\x59\xD5\x38" "\xDF\x9A\x04\x30\x2E\x10\xC8\xBC\x1C\xBF\x1A\x0B\x3A\x51\x20\xEA" "\x17\xCD\xA7\xCF\xAD\x76\x5F\x56\x23\x47\x4D\x36\x8C\xCC\xA8\xAF" "\x00\x07\xCD\x9F\x5E\x4C\x84\x9F\x16\x7A\x58\x0B\x14\xAA\xBD\xEF" "\xAE\xE7\xEE\xF4\x7C\xB0\xFC\xA9\x76\x7B\xE1\xFD\xA6\x94\x19\xDF" "\xB9\x27\xE9\xDF\x07\x34\x8B\x19\x66\x91\xAB\xAE\xB5\x80\xB3\x2D" "\xEF\x58\x53\x8B\x8D\x23\xF8\x77\x32\xEA\x63\xB0\x2B\x4F\xA0\xF4" "\x87\x33\x60\xE2\x84\x19\x28\xCD\x60\xDD\x4C\xEE\x8C\xC0\xD4\xC9" "\x22\xA9\x61\x88\xD0\x32\x67\x5C\x8A\xC8\x50\x93\x3C\x7A\xFF\x15" "\x33\xB9\x4C\x83\x4A\xDB\xB6\x9C\x61\x15\xBA\xD4\x69\x2D\x86\x19" "\xF9\x0B\x0C\xDF\x8A\x7B\x9C\x26\x40\x29\xAC\x18\x5B\x70\xB8\x3F" "\x28\x01\xF2\xF4\xB3\xF7\x0C\x59\x3E\xA3\xAE\xEB\x61\x3A\x7F\x1B" "\x1D\xE3\x3F\xD7\x50\x81\xF5\x92\x30\x5F\x2E\x45\x26\xED\xC0\x96" "\x31\xB1\x09\x58\xF4\x64\xD8\x89\xF3\x1B\xA0\x10\x25\x0F\xDA\x7F" "\x13\x68\xEC\x29\x67\xFC\x84\xEF\x2A\xE9\xAF\xF2\x68\xE0\xB1\x70" "\x0A\xFF\xC6\x82\x0B\x52\x3A\x3D\x91\x71\x35\xF2\xDF\xF2\xEE\x06" "\xBF\xE7\x2B\x31\x24\x72\x1D\x4A\x26\xC0\x4E\x53\xA7\x5E\x30\xE7" "\x3A\x7A\x9C\x4A\x95\xD9\x1C\x55\xD4\x95\xE9\xF5\x1D\xD0\xB5\xE9" "\xD8\x3C\x6D\x5E\x8C\xE8\x03\xAA\x62\xB8\xD6\x54\xDB\x53\xD0\x9B" "\x8D\xCF\xF2\x73\xCD\xFE\xB5\x73\xFA\xD8\xBC\xD4\x55\x78\xBE\xC2" "\xE7\x70\xD0\x1E\xFD\xE8\x6E\x72\x1A\x3F\x7C\x6C\xCE\x27\x5D\xAB" "\xE6\xE2\x14\x3F\x1A\xF1\x8D\xA7\xEF\xDD\xC4\xC7\xB7\x0B\x5E\x34" "\x5D\xB9\x3C\xC9\x36\xBE\xA3\x23\x49\x1C\xCB\x38\xA3\x88\xF5\x46" "\xA9\xFF\x00\xDD\x4E\x13\x00\xB9\xB2\x15\x3D\x20\x41\xD2\x05\xB4" "\x43\xE4\x1B\x45\xA6\x53\xF2\xA5\xC4\x49\x2C\x1A\xDD\x54\x45\x12" "\xDD\xA2\x52\x98\x33\x46\x2B\x71\xA4\x1A\x45\xBE\x97\x29\x0B\x6F", 0, 512, }, { GCRY_MD_SHAKE128, "\x5A\xAB\x62\x75\x6D\x30\x7A\x66\x9D\x14\x6A\xBA\x98\x8D\x90\x74" "\xC5\xA1\x59\xB3\xDE\x85\x15\x1A\x81\x9B\x11\x7C\xA1\xFF\x65\x97" "\xF6\x15\x6E\x80\xFD\xD2\x8C\x9C\x31\x76\x83\x51\x64\xD3\x7D\xA7" "\xDA\x11\xD9\x4E\x09\xAD\xD7\x70\xB6\x8A\x6E\x08\x1C\xD2\x2C\xA0" "\xC0\x04\xBF\xE7\xCD\x28\x3B\xF4\x3A\x58\x8D\xA9\x1F\x50\x9B\x27" "\xA6\x58\x4C\x47\x4A\x4A\x2F\x3E\xE0\xF1\xF5\x64\x47\x37\x92\x40" "\xA5\xAB\x1F\xB7\x7F\xDC\xA4\x9B\x30\x5F\x07\xBA\x86\xB6\x27\x56" "\xFB\x9E\xFB\x4F\xC2\x25\xC8\x68\x45\xF0\x26\xEA\x54\x20\x76\xB9" "\x1A\x0B\xC2\xCD\xD1\x36\xE1\x22\xC6\x59\xBE\x25\x9D\x98\xE5\x84" "\x1D\xF4\xC2\xF6\x03\x30\xD4\xD8\xCD\xEE\x7B\xF1\xA0\xA2\x44\x52" "\x4E\xEC\xC6\x8F\xF2\xAE\xF5\xBF\x00\x69\xC9\xE8\x7A\x11\xC6\xE5" "\x19\xDE\x1A\x40\x62\xA1\x0C\x83\x83\x73\x88\xF7\xEF\x58\x59\x8A" "\x38\x46\xF4\x9D\x49\x96\x82\xB6\x83\xC4\xA0\x62\xB4\x21\x59\x4F" "\xAF\xBC\x13\x83\xC9\x43\xBA\x83\xBD\xEF\x51\x5E\xFC\xF1\x0D", "\xF0\x71\x5D\xE3\x56\x92\xFD\x70\x12\x3D\xC6\x83\x68\xD0\xFE\xEC" "\x06\xA0\xC7\x4C\xF8\xAD\xB0\x5D\xDC\x25\x54\x87\xB1\xA8\xD4\xD1" "\x21\x3E\x9E\xAB\xAF\x41\xF1\x16\x17\x19\xD0\x65\xD7\x94\xB7\x50" "\xF8\x4B\xE3\x2A\x32\x34\xB4\xD5\x36\x46\x0D\x55\x20\x68\x8A\x5A" "\x79\xA1\x7A\x4B\xA8\x98\x7F\xCB\x61\xBF\x7D\xAA\x8B\x54\x7B\xF5" "\xC1\xCE\x36\xB5\x6A\x73\x25\x7D\xBB\xF1\xBA\xBB\x64\xF2\x49\xBD" "\xCE\xB6\x7B\xA1\xC8\x88\x37\x0A\x96\x3D\xFD\x6B\x6A\x2A\xDE\x2C" "\xEF\xD1\x4C\x32\x52\xCB\x37\x58\x52\x0F\x0C\x65\xF4\x52\x46\x82" "\x77\x24\x99\x46\x3A\xE1\xA3\x41\x80\x01\x83\xAA\x60\xEF\xA0\x51" "\x18\xA2\x82\x01\x74\x4F\x7B\xA0\xB0\xA3\x92\x8D\xD7\xC0\x26\x3F" "\xD2\x64\xB7\xCD\x7B\x2E\x2E\x09\xB3\x22\xBF\xCE\xA8\xEE\xD0\x42" "\x75\x79\x5B\xE7\xC0\xF0\x0E\x11\x38\x27\x37\x0D\x05\x1D\x50\x26" "\x95\x80\x30\x00\x05\xAC\x12\x88\xFE\xA6\xCD\x9A\xE9\xF4\xF3\x7C" "\xE0\xF8\xAC\xE8\xBF\x3E\xBE\x1D\x70\x56\x25\x59\x54\xC7\x61\x93" "\x1D\x3C\x42\xED\x62\xF7\xF1\xCE\x1B\x94\x5C\xDE\xCC\x0A\x74\x32" "\x2D\x7F\x64\xD6\x00\x4F\xF2\x16\x84\x14\x93\x07\x28\x8B\x44\x8E" "\x45\x43\x34\x75\xB1\xEA\x13\x14\xB0\x0F\x1F\xC4\x50\x08\x9A\x9D" "\x1F\x77\x10\xC6\xD7\x65\x2E\xCF\x65\x4F\x3B\x48\x7D\x02\x83\xD4" "\xD8\xA2\x8E\xFB\x50\x66\xC4\x25\x0D\x5A\xD6\x98\xE1\x5D\xBA\x88" "\xE9\x25\xE4\xDE\x99\xB6\x9B\xC3\x83\xAC\x80\x45\xB7\xF1\x02\x2A" "\xDD\x39\xD4\x43\x54\x6A\xE0\x92\x4F\x13\xF4\x89\x60\x96\xDF\xDF" "\x37\xCA\x72\x20\x79\x87\xC4\xA7\x70\x5A\x7A\xBE\x72\x4B\x7F\xA1" "\x0C\x90\x9F\x39\x25\x44\x9F\x01\x0D\x61\xE2\x07\xAD\xD9\x52\x19" "\x07\x1A\xCE\xED\xB9\xB9\xDC\xED\x32\xA9\xE1\x23\x56\x1D\x60\x82" "\xD4\x6A\xEF\xAE\x07\xEE\x1B\xD1\x32\x76\x5E\x3E\x51\x3C\x66\x50" "\x1B\x38\x7A\xB2\xEE\x09\xA0\x4A\xE6\x3E\x25\x80\x85\x17\xAF\xEA" "\x3E\x05\x11\x69\xCF\xD2\xFF\xF8\xC5\x85\x8E\x2D\x96\x23\x89\x7C" "\x9E\x85\x17\x5A\xC5\xA8\x63\x94\xCD\x0A\x32\xA0\xA6\x2A\x8F\x5D" "\x6C\xCC\xBF\x49\x3D\xAA\x43\xF7\x83\x62\xBB\xCA\x40\xAD\xF7\x33" "\xF8\x71\xE0\xC0\x09\x98\xD9\xBF\xD6\x88\x06\x56\x66\x6C\xD7\xBE" "\x4F\xE9\x89\x2C\x61\xDC\xD5\xCD\x23\xA5\xE4\x27\x7E\xEE\x8B\x4A" "\xFD\x29\xB6\x9B\xBA\x55\x66\x0A\x21\x71\x12\xFF\x6E\x34\x56\xB1", 223, 512, }, { GCRY_MD_SHAKE128, "!", "\x9d\x22\x2c\x79\xc4\xff\x9d\x09\x2c\xf6\xca\x86\x14\x3a\xa4\x11" "\xe3\x69\x97\x38\x08\xef\x97\x09\x32\x55\x82\x6c\x55\x72\xef\x58" "\x42\x4c\x4b\x5c\x28\x47\x5f\xfd\xcf\x98\x16\x63\x86\x7f\xec\x63" "\x21\xc1\x26\x2e\x38\x7b\xcc\xf8\xca\x67\x68\x84\xc4\xa9\xd0\xc1" "\x3b\xfa\x68\x69\x76\x3d\x5a\xe4\xbb\xc9\xb3\xcc\xd0\x9d\x1c\xa5" "\xea\x74\x46\x53\x8d\x69\xb3\xfb\x98\xc7\x2b\x59\xa2\xb4\x81\x7d" "\xb5\xea\xdd\x90\x11\xf9\x0f\xa7\x10\x91\x93\x1f\x81\x34\xf4\xf0" "\x0b\x56\x2e\x2f\xe1\x05\x93\x72\x70\x36\x1c\x19\x09\x86\x2a\xd4" "\x50\x46\xe3\x93\x2f\x5d\xd3\x11\xec\x72\xfe\xc5\xf8\xfb\x8f\x60" "\xb4\x5a\x3b\xee\x3f\x85\xbb\xf7\xfc\xed\xc6\xa5\x55\x67\x76\x48" "\xe0\x65\x4b\x38\x19\x41\xa8\x6b\xd3\xe5\x12\x65\x7b\x0d\x57\xa7" "\x99\x1f\xc4\x54\x3f\x89\xd8\x29\x04\x92\x22\x2c\xe4\xa3\x3e\x17" "\x60\x2b\x3b\x99\xc0\x09\xf7\x65\x5f\x87\x53\x5c\xda\xa3\x71\x6f" "\x58\xc4\x7b\x8a\x15\x7a\xd1\x95\xf0\x28\x09\xf2\x75\x00\xb9\x25" "\x49\x79\x31\x1c\x6b\xb4\x15\x96\x8c\xd1\x04\x31\x16\x9a\x27\xd5" "\xa8\xd6\x1e\x13\xa6\xb8\xb7\x7a\xf1\xf8\xb6\xdd\x2e\xef\xde\xa0" "\x40\x78\x96\x80\x49\x0b\x5e\xdc\xb1\xd3\xe5\x38\xa4\x66\xf7\x57" "\xad\x71\x8f\xe1\xfd\x9f\xae\xef\xa4\x72\x46\xad\x5e\x36\x7f\x87" "\xd3\xb4\x85\x0d\x44\x86\xeb\x21\x99\xe9\x4a\x79\x79\xe2\x09\x1a" "\xbc\xdf\x3b\xc1\x33\x79\xc8\x96\xdc\xeb\x79\xa8\xfd\x08\xf1\x10" "\x73\xf3\x3e\x3f\x99\x23\x22\xb3\x12\x02\xde\xe2\x34\x33\x0c\xf3" "\x30\x4a\x58\x8f\x0d\x59\xda\xe4\xe6\x3b\xa2\xac\x3c\xe6\x82\xcc" "\x19\xd4\xe3\x41\x67\x8c\xc3\xa6\x7a\x47\xc1\x13\xb4\xdb\x89\x0f" "\x30\xa9\x2a\xa0\x8a\x1f\x6d\xc8\xfb\x64\x63\xf8\x03\x8c\x2b\x40" "\xb2\x53\x00\x77\xb2\x36\xce\x88\xaf\xcc\xcd\xa0\x8a\xd6\xd7\x5e" "\xee\x18\x99\xb1\x0c\xd8\x00\xc2\xce\x53\x72\xbf\xf2\x2e\xe3\xa3" "\x39\xd4\xb9\xc1\xa2\xf5\xf4\xb8\x20\xf6\x87\xe5\x51\x9b\xd0\x5b" "\x1f\xc5\xda\x0e\xb4\x53\x36\x81\x4f\x48\x13\x2c\x64\x0e\x66\xc3" "\xa0\x2a\x22\xe6\x35\x98\xf9\x4f\x22\xf3\x51\x84\x11\x04\x46\xb6" "\x48\xcf\x84\x74\xf3\x0c\x43\xea\xd5\x83\x09\xfb\x25\x90\x16\x09" "\xe2\x41\x87\xe8\x01\xc8\x09\x56\x1a\x64\x80\x94\x50\xe6\x03\xc4" "\xa8\x03\x95\x25\xc4\x76\xb5\x8e\x32\xce\x2c\x47\xb3\x7d\xa5\x91", 0, 512, }, { GCRY_MD_SHAKE256, "", "\x46\xB9\xDD\x2B\x0B\xA8\x8D\x13\x23\x3B\x3F\xEB\x74\x3E\xEB\x24" "\x3F\xCD\x52\xEA\x62\xB8\x1B\x82\xB5\x0C\x27\x64\x6E\xD5\x76\x2F" "\xD7\x5D\xC4\xDD\xD8\xC0\xF2\x00\xCB\x05\x01\x9D\x67\xB5\x92\xF6" "\xFC\x82\x1C\x49\x47\x9A\xB4\x86\x40\x29\x2E\xAC\xB3\xB7\xC4\xBE" "\x14\x1E\x96\x61\x6F\xB1\x39\x57\x69\x2C\xC7\xED\xD0\xB4\x5A\xE3" "\xDC\x07\x22\x3C\x8E\x92\x93\x7B\xEF\x84\xBC\x0E\xAB\x86\x28\x53" "\x34\x9E\xC7\x55\x46\xF5\x8F\xB7\xC2\x77\x5C\x38\x46\x2C\x50\x10" "\xD8\x46\xC1\x85\xC1\x51\x11\xE5\x95\x52\x2A\x6B\xCD\x16\xCF\x86" "\xF3\xD1\x22\x10\x9E\x3B\x1F\xDD\x94\x3B\x6A\xEC\x46\x8A\x2D\x62" "\x1A\x7C\x06\xC6\xA9\x57\xC6\x2B\x54\xDA\xFC\x3B\xE8\x75\x67\xD6" "\x77\x23\x13\x95\xF6\x14\x72\x93\xB6\x8C\xEA\xB7\xA9\xE0\xC5\x8D" "\x86\x4E\x8E\xFD\xE4\xE1\xB9\xA4\x6C\xBE\x85\x47\x13\x67\x2F\x5C" "\xAA\xAE\x31\x4E\xD9\x08\x3D\xAB\x4B\x09\x9F\x8E\x30\x0F\x01\xB8" "\x65\x0F\x1F\x4B\x1D\x8F\xCF\x3F\x3C\xB5\x3F\xB8\xE9\xEB\x2E\xA2" "\x03\xBD\xC9\x70\xF5\x0A\xE5\x54\x28\xA9\x1F\x7F\x53\xAC\x26\x6B" "\x28\x41\x9C\x37\x78\xA1\x5F\xD2\x48\xD3\x39\xED\xE7\x85\xFB\x7F" "\x5A\x1A\xAA\x96\xD3\x13\xEA\xCC\x89\x09\x36\xC1\x73\xCD\xCD\x0F" "\xAB\x88\x2C\x45\x75\x5F\xEB\x3A\xED\x96\xD4\x77\xFF\x96\x39\x0B" "\xF9\xA6\x6D\x13\x68\xB2\x08\xE2\x1F\x7C\x10\xD0\x4A\x3D\xBD\x4E" "\x36\x06\x33\xE5\xDB\x4B\x60\x26\x01\xC1\x4C\xEA\x73\x7D\xB3\xDC" "\xF7\x22\x63\x2C\xC7\x78\x51\xCB\xDD\xE2\xAA\xF0\xA3\x3A\x07\xB3" "\x73\x44\x5D\xF4\x90\xCC\x8F\xC1\xE4\x16\x0F\xF1\x18\x37\x8F\x11" "\xF0\x47\x7D\xE0\x55\xA8\x1A\x9E\xDA\x57\xA4\xA2\xCF\xB0\xC8\x39" "\x29\xD3\x10\x91\x2F\x72\x9E\xC6\xCF\xA3\x6C\x6A\xC6\xA7\x58\x37" "\x14\x30\x45\xD7\x91\xCC\x85\xEF\xF5\xB2\x19\x32\xF2\x38\x61\xBC" "\xF2\x3A\x52\xB5\xDA\x67\xEA\xF7\xBA\xAE\x0F\x5F\xB1\x36\x9D\xB7" "\x8F\x3A\xC4\x5F\x8C\x4A\xC5\x67\x1D\x85\x73\x5C\xDD\xDB\x09\xD2" "\xB1\xE3\x4A\x1F\xC0\x66\xFF\x4A\x16\x2C\xB2\x63\xD6\x54\x12\x74" "\xAE\x2F\xCC\x86\x5F\x61\x8A\xBE\x27\xC1\x24\xCD\x8B\x07\x4C\xCD" "\x51\x63\x01\xB9\x18\x75\x82\x4D\x09\x95\x8F\x34\x1E\xF2\x74\xBD" "\xAB\x0B\xAE\x31\x63\x39\x89\x43\x04\xE3\x58\x77\xB0\xC2\x8A\x9B" "\x1F\xD1\x66\xC7\x96\xB9\xCC\x25\x8A\x06\x4A\x8F\x57\xE2\x7F\x2A", 0, 512, }, { GCRY_MD_SHAKE256, "\xB3\x2D\x95\xB0\xB9\xAA\xD2\xA8\x81\x6D\xE6\xD0\x6D\x1F\x86\x00" "\x85\x05\xBD\x8C\x14\x12\x4F\x6E\x9A\x16\x3B\x5A\x2A\xDE\x55\xF8" "\x35\xD0\xEC\x38\x80\xEF\x50\x70\x0D\x3B\x25\xE4\x2C\xC0\xAF\x05" "\x0C\xCD\x1B\xE5\xE5\x55\xB2\x30\x87\xE0\x4D\x7B\xF9\x81\x36\x22" "\x78\x0C\x73\x13\xA1\x95\x4F\x87\x40\xB6\xEE\x2D\x3F\x71\xF7\x68" "\xDD\x41\x7F\x52\x04\x82\xBD\x3A\x08\xD4\xF2\x22\xB4\xEE\x9D\xBD" "\x01\x54\x47\xB3\x35\x07\xDD\x50\xF3\xAB\x42\x47\xC5\xDE\x9A\x8A" "\xBD\x62\xA8\xDE\xCE\xA0\x1E\x3B\x87\xC8\xB9\x27\xF5\xB0\x8B\xEB" "\x37\x67\x4C\x6F\x8E\x38\x0C\x04", "\xCC\x2E\xAA\x04\xEE\xF8\x47\x9C\xDA\xE8\x56\x6E\xB8\xFF\xA1\x10" "\x0A\x40\x79\x95\xBF\x99\x9A\xE9\x7E\xDE\x52\x66\x81\xDC\x34\x90" "\x61\x6F\x28\x44\x2D\x20\xDA\x92\x12\x4C\xE0\x81\x58\x8B\x81\x49" "\x1A\xED\xF6\x5C\xAA\xF0\xD2\x7E\x82\xA4\xB0\xE1\xD1\xCA\xB2\x38" "\x33\x32\x8F\x1B\x8D\xA4\x30\xC8\xA0\x87\x66\xA8\x63\x70\xFA\x84" "\x8A\x79\xB5\x99\x8D\xB3\xCF\xFD\x05\x7B\x96\xE1\xE2\xEE\x0E\xF2" "\x29\xEC\xA1\x33\xC1\x55\x48\xF9\x83\x99\x02\x04\x37\x30\xE4\x4B" "\xC5\x2C\x39\xFA\xDC\x1D\xDE\xEA\xD9\x5F\x99\x39\xF2\x20\xCA\x30" "\x06\x61\x54\x0D\xF7\xED\xD9\xAF\x37\x8A\x5D\x4A\x19\xB2\xB9\x3E" "\x6C\x78\xF4\x9C\x35\x33\x43\xA0\xB5\xF1\x19\x13\x2B\x53\x12\xD0" "\x04\x83\x1D\x01\x76\x9A\x31\x6D\x2F\x51\xBF\x64\xCC\xB2\x0A\x21" "\xC2\xCF\x7A\xC8\xFB\x6F\x6E\x90\x70\x61\x26\xBD\xAE\x06\x11\xDD" "\x13\x96\x2E\x8B\x53\xD6\xEA\xE2\x6C\x7B\x0D\x25\x51\xDA\xF6\x24" "\x8E\x9D\x65\x81\x73\x82\xB0\x4D\x23\x39\x2D\x10\x8E\x4D\x34\x43" "\xDE\x5A\xDC\x72\x73\xC7\x21\xA8\xF8\x32\x0E\xCF\xE8\x17\x7A\xC0" "\x67\xCA\x8A\x50\x16\x9A\x6E\x73\x00\x0E\xBC\xDC\x1E\x4E\xE6\x33" "\x9F\xC8\x67\xC3\xD7\xAE\xAB\x84\x14\x63\x98\xD7\xBA\xDE\x12\x1D" "\x19\x89\xFA\x45\x73\x35\x56\x4E\x97\x57\x70\xA3\xA0\x02\x59\xCA" "\x08\x70\x61\x08\x26\x1A\xA2\xD3\x4D\xE0\x0F\x8C\xAC\x7D\x45\xD3" "\x5E\x5A\xA6\x3E\xA6\x9E\x1D\x1A\x2F\x7D\xAB\x39\x00\xD5\x1E\x0B" "\xC6\x53\x48\xA2\x55\x54\x00\x70\x39\xA5\x2C\x3C\x30\x99\x80\xD1" "\x7C\xAD\x20\xF1\x15\x63\x10\xA3\x9C\xD3\x93\x76\x0C\xFE\x58\xF6" "\xF8\xAD\xE4\x21\x31\x28\x82\x80\xA3\x5E\x1D\xB8\x70\x81\x83\xB9" "\x1C\xFA\xF5\x82\x7E\x96\xB0\xF7\x74\xC4\x50\x93\xB4\x17\xAF\xF9" "\xDD\x64\x17\xE5\x99\x64\xA0\x1B\xD2\xA6\x12\xFF\xCF\xBA\x18\xA0" "\xF1\x93\xDB\x29\x7B\x9A\x6C\xC1\xD2\x70\xD9\x7A\xAE\x8F\x8A\x3A" "\x6B\x26\x69\x5A\xB6\x64\x31\xC2\x02\xE1\x39\xD6\x3D\xD3\xA2\x47" "\x78\x67\x6C\xEF\xE3\xE2\x1B\x02\xEC\x4E\x8F\x5C\xFD\x66\x58\x7A" "\x12\xB4\x40\x78\xFC\xD3\x9E\xEE\x44\xBB\xEF\x4A\x94\x9A\x63\xC0" "\xDF\xD5\x8C\xF2\xFB\x2C\xD5\xF0\x02\xE2\xB0\x21\x92\x66\xCF\xC0" "\x31\x81\x74\x86\xDE\x70\xB4\x28\x5A\x8A\x70\xF3\xD3\x8A\x61\xD3" "\x15\x5D\x99\xAA\xF4\xC2\x53\x90\xD7\x36\x45\xAB\x3E\x8D\x80\xF0", 136, 512, }, { GCRY_MD_SHAKE256, "!", "\x35\x78\xa7\xa4\xca\x91\x37\x56\x9c\xdf\x76\xed\x61\x7d\x31\xbb" "\x99\x4f\xca\x9c\x1b\xbf\x8b\x18\x40\x13\xde\x82\x34\xdf\xd1\x3a" "\x3f\xd1\x24\xd4\xdf\x76\xc0\xa5\x39\xee\x7d\xd2\xf6\xe1\xec\x34" "\x61\x24\xc8\x15\xd9\x41\x0e\x14\x5e\xb5\x61\xbc\xd9\x7b\x18\xab" "\x6c\xe8\xd5\x55\x3e\x0e\xab\x3d\x1f\x7d\xfb\x8f\x9d\xee\xfe\x16" "\x84\x7e\x21\x92\xf6\xf6\x1f\xb8\x2f\xb9\x0d\xde\x60\xb1\x90\x63" "\xc5\x6a\x4c\x55\xcd\xd7\xb6\x72\xb7\x5b\xf5\x15\xad\xbf\xe2\x04" "\x90\x3c\x8c\x00\x36\xde\x54\xa2\x99\x9a\x92\x0d\xe9\x0f\x66\xd7" "\xff\x6e\xc8\xe4\xc9\x3d\x24\xae\x34\x6f\xdc\xb3\xa5\xa5\xbd\x57" "\x39\xec\x15\xa6\xed\xdb\x5c\xe5\xb0\x2d\xa5\x30\x39\xfa\xc6\x3e" "\x19\x55\x5f\xaa\x2e\xdd\xc6\x93\xb1\xf0\xc2\xa6\xfc\xbe\x7c\x0a" "\x0a\x09\x1d\x0e\xe7\x00\xd7\x32\x2e\x4b\x0f\xf0\x95\x90\xde\x16" "\x64\x22\xf9\xea\xd5\xda\x4c\x99\x3d\x60\x5f\xe4\xd9\xc6\x34\x84" "\x3a\xa1\x78\xb1\x76\x72\xc6\x56\x8c\x8a\x2e\x62\xab\xeb\xea\x2c" "\x21\xc3\x02\xbd\x36\x6a\xd6\x98\x95\x9e\x1f\x6e\x43\x4a\xf1\x55" "\x56\x8b\x27\x34\xd8\x37\x9f\xcd\x3f\xfe\x64\x89\xba\xff\xa6\xd7" "\x11\x09\x44\x2e\x1b\x34\x4f\x13\x8a\x09\xca\xe3\xe2\xd3\x94\x2e" "\xee\x82\x8f\xc4\x7e\x64\xde\xb5\xe0\x0a\x02\x4a\xe1\xf2\xc0\x77" "\xe6\xb7\xb1\x33\xf6\xc1\xde\x91\x30\x92\xd4\xe8\x29\xec\xd2\xb2" "\xef\x28\xca\x80\x20\x82\x1e\x2b\x8b\xe5\x17\xd9\x3e\xd0\x88\x36" "\xf6\xf0\x66\xcc\x3d\x03\xb6\x25\xd8\x49\x7f\x29\xdb\xc1\xc3\x9e" "\x6f\xe4\x63\x22\x6f\x85\xc1\x28\xa2\xc2\x98\x88\x11\x2e\x06\xa9" "\x9c\x5d\x17\xb2\x5e\x90\x0d\x20\x4f\x39\x72\x31\xcd\xf7\x9c\x31" "\x34\x46\x53\x2d\xad\x07\xf4\xc0\xbd\x9f\xba\x1d\xd4\x13\xd8\xa7" "\xe6\xcb\xc0\xa0\x86\x2c\xc7\x69\x23\x9a\x89\xf9\xdb\x08\x5b\x78" "\xa0\x54\x59\x6a\xd7\x08\x0d\xdf\x96\x01\x9b\x73\x99\xb5\x03\x48" "\x0e\x5a\x65\xa2\x20\x8d\x74\x72\x4c\x98\x7d\x32\x5e\x9b\x0e\x82" "\xfe\xcd\x4f\x27\xf3\x13\x5b\x1d\x9e\x27\xb4\x8e\x69\xdd\x6f\x59" "\x62\xb8\xa6\x3b\x48\x92\x1e\xc8\xee\x53\x86\x9f\x1a\xc1\xc8\x18" "\x23\x87\xee\x0d\x6c\xfe\xf6\x53\xff\x8b\xf6\x05\xf1\x47\x04\xb7" "\x1b\xeb\x65\x53\xf2\x81\xfa\x75\x69\x48\xc4\x38\x49\x4b\x19\xb4" "\xee\x69\xa5\x43\x6b\x22\x2b\xc9\x88\xed\xa4\xac\x60\x00\x24\xc9", 0, 512, }, { GCRY_MD_BLAKE2B_512, "abc", "\xBA\x80\xA5\x3F\x98\x1C\x4D\x0D\x6A\x27\x97\xB6\x9F\x12\xF6\xE9" "\x4C\x21\x2F\x14\x68\x5A\xC4\xB7\x4B\x12\xBB\x6F\xDB\xFF\xA2\xD1" "\x7D\x87\xC5\x39\x2A\xAB\x79\x2D\xC2\x52\xD5\xDE\x45\x33\xCC\x95" "\x18\xD3\x8A\xA8\xDB\xF1\x92\x5A\xB9\x23\x86\xED\xD4\x00\x99\x23" }, { GCRY_MD_BLAKE2B_512, "\x00", "\x96\x1f\x6d\xd1\xe4\xdd\x30\xf6\x39\x01\x69\x0c\x51\x2e\x78\xe4" "\xb4\x5e\x47\x42\xed\x19\x7c\x3c\x5e\x45\xc5\x49\xfd\x25\xf2\xe4" "\x18\x7b\x0b\xc9\xfe\x30\x49\x2b\x16\xb0\xd0\xbc\x4e\xf9\xb0\xf3" "\x4c\x70\x03\xfa\xc0\x9a\x5e\xf1\x53\x2e\x69\x43\x02\x34\xce\xbd", 1, 64, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f", 64 }, #include "./blake2b.h" { GCRY_MD_BLAKE2B_160, "", "\xad\x75\xea\xd7\x9f\x71\x21\xd1\xf0\x8a\xfe\x59\x99\x27\xa5\xa3" "\x8b\xe1\xb1\x79", 0, 20, "\x65\x65\xcb\x30\xfb\x2c\x28\x54\x7c\xd0\x4c\x1d\x6a\x88\xf2\x7a" "\x6d\xe8\x55\x3d", 20 }, { GCRY_MD_BLAKE2B_160, "\x9c\x9c\x38", "\x82\x79\x9d\x7b\xe8\xf4\xd1\x69\xfb\x85\xe6\x63\x6a\x7b\x6c\x50" "\xa0\x1f\x70\xa2", 3, 20, "\x65\x65\xcb\x30\xfb\x2c\x28\x54\x7c\xd0\x4c\x1d\x6a\x88\xf2\x7a" "\x6d\xe8\x55\x3d", 20 }, { GCRY_MD_BLAKE2B_256, "", "\x89\x36\x29\x47\x52\x79\xdf\xd8\x2a\x84\x1a\x8f\x21\xa3\x72\xed" "\x30\xcc\xb8\xae\x34\x62\xe1\x90\x7f\x50\x66\x3f\x3c\x03\x66\x83", 0, 32, "\xd5\xd5\xab\x80\x2c\xad\xd9\x86\x60\xe7\x47\x2f\x77\xa6\x1d\xc4" "\xe2\xa6\x88\x2f\xb7\xe6\x9e\x85\x23\xa9\xcd\x76\x43\xb9\xfd\xb7", 32 }, { GCRY_MD_BLAKE2B_256, "\x9c\x9c\x38", "\x01\x6a\x18\xbb\x10\xe0\xc3\xa5\xe5\x9f\xce\xfd\x1a\x40\x7a\xb7" "\xf1\xc0\x36\x1b\x3f\x98\x34\x77\x42\x54\xd3\xf0\x4c\xda\x38\x98", 3, 32, "\xd5\xd5\xab\x80\x2c\xad\xd9\x86\x60\xe7\x47\x2f\x77\xa6\x1d\xc4" "\xe2\xa6\x88\x2f\xb7\xe6\x9e\x85\x23\xa9\xcd\x76\x43\xb9\xfd\xb7", 32 }, { GCRY_MD_BLAKE2B_384, "", "\xd7\x2c\x9b\x4a\x73\x4e\xb2\x07\xe9\xdd\xbf\xf0\x0b\x10\xc3\x70" "\xc8\x9d\x67\xd7\x96\xc3\xa7\xb9\x68\x15\xa9\x53\x92\x1b\xb2\x97" "\x59\xd2\x9d\x25\x63\xf3\xda\x4d\x7f\x3e\xa4\xa6\xe3\x4c\x32\x6b", 0, 48, "\xc0\xc0\x80\x41\xc2\x03\xc6\xca\x90\x5b\xeb\x46\x32\x79\xac\x26" "\xd3\xf9\xcc\xc6\x93\x5a\xed\x48\x35\x7d\xb3\x31\xe5\x16\xfb\x12" "\x0e\x21\x2f\x51\x80\xd1\x52\x24\x77\x9c\x13\xaf\xc3\x73\x37\xaa", 48 }, { GCRY_MD_BLAKE2B_384, "\x9c\x9c\x38", "\xef\x46\xfa\x54\xa2\xc2\x20\xda\x06\xa8\x4c\x77\x6e\x87\xdd\x0a" "\x21\xee\xb5\xe9\x40\x1a\x0a\x78\x11\x19\x74\x18\xfe\x92\x70\x15" "\x77\xd0\xa8\x53\x24\x48\xe8\xb8\x53\x6a\xa6\xc7\x42\xcd\x2c\x62", 3, 48, "\xc0\xc0\x80\x41\xc2\x03\xc6\xca\x90\x5b\xeb\x46\x32\x79\xac\x26" "\xd3\xf9\xcc\xc6\x93\x5a\xed\x48\x35\x7d\xb3\x31\xe5\x16\xfb\x12" "\x0e\x21\x2f\x51\x80\xd1\x52\x24\x77\x9c\x13\xaf\xc3\x73\x37\xaa", 48 }, { GCRY_MD_BLAKE2B_512, "", "\xd7\x4b\xf3\x1e\x5c\xe5\xd8\xa2\x5d\x09\x21\x52\x53\xca\xd2\xf8" "\xd2\xfd\xa9\x10\x09\x30\x16\x05\xa6\x8c\xc3\x86\x5b\xb7\x93\x5b" "\xca\xff\x6f\x2a\xf6\x43\xa7\x76\x99\xe8\x02\x61\xa1\xfd\x2c\x80" "\xe8\x37\xb5\x62\x32\xf7\xb1\x46\x43\x4a\xa7\x4d\x71\x18\xbb\x16", 0, 64, "\xab\xab\x56\x01\x58\x5a\xb3\x0d\xc1\xce\x8f\x5e\xee\x4d\x3b\x88" "\xc4\x4c\x11\x5e\x6f\xcd\x3d\x0a\x47\x52\x9a\xec\x86\x73\xfa\x6e" "\x68\xd6\x3f\x16\x55\x6b\xc1\x2d\xef\x1d\x0c\x29\x35\x5f\x94\xf3" "\x88\x7c\x04\x81\x86\x07\x8e\x95\x23\xb9\xdd\x97\x74\x0c\x80\x8c", 64 }, { GCRY_MD_BLAKE2B_512, "\x9c\x9c\x38", "\x70\xfc\x57\xe1\x49\x5f\xe4\x39\x0d\x38\xa1\xd3\x97\x05\xee\xf6" "\xaa\xbb\xd2\x64\xc7\xce\x66\x11\x8d\x0a\x87\xd4\x25\x94\xb3\x87" "\xdc\x50\x18\x8b\xba\x61\xf0\x91\xd6\xb3\x4f\xf5\x4e\x09\x1e\x70" "\x24\x01\x83\xcd\xb9\x21\x1f\x14\x39\x77\x5c\xc6\xe6\xe9\x35\x73", 3, 64, "\xab\xab\x56\x01\x58\x5a\xb3\x0d\xc1\xce\x8f\x5e\xee\x4d\x3b\x88" "\xc4\x4c\x11\x5e\x6f\xcd\x3d\x0a\x47\x52\x9a\xec\x86\x73\xfa\x6e" "\x68\xd6\x3f\x16\x55\x6b\xc1\x2d\xef\x1d\x0c\x29\x35\x5f\x94\xf3" "\x88\x7c\x04\x81\x86\x07\x8e\x95\x23\xb9\xdd\x97\x74\x0c\x80\x8c", 64 }, { GCRY_MD_BLAKE2B_512, "!", "\x98\xfb\x3e\xfb\x72\x06\xfd\x19\xeb\xf6\x9b\x6f\x31\x2c\xf7\xb6" "\x4e\x3b\x94\xdb\xe1\xa1\x71\x07\x91\x39\x75\xa7\x93\xf1\x77\xe1" "\xd0\x77\x60\x9d\x7f\xba\x36\x3c\xbb\xa0\x0d\x05\xf7\xaa\x4e\x4f" "\xa8\x71\x5d\x64\x28\x10\x4c\x0a\x75\x64\x3b\x0f\xf3\xfd\x3e\xaf" }, { GCRY_MD_BLAKE2B_512, "?", "\xae\x9c\xf5\x7a\xc2\xff\x7b\x37\x7a\x5b\xb5\xcc\x2e\x62\x92\x20" "\xa9\xba\x0a\x09\xc2\x2a\x0f\xdb\xd9\xa3\xae\xd6\x32\xc1\x72\x0e" "\x6d\x82\x9f\x74\x7f\xba\x12\xe8\x31\xa2\x45\x8d\xf0\x73\x4e\xe0" "\x12\x27\x52\xd3\xe2\x2c\x36\xc4\x42\x89\x3b\xcd\xd1\xbd\xd9\x08" }, { GCRY_MD_BLAKE2B_384, "?", "\x22\x66\x8e\x05\x81\x44\x52\xa5\x23\x84\xce\x67\xd4\xad\x0e\x03" "\xdf\xe7\x1a\xc1\x56\x9d\x95\x4a\xd2\x22\x7a\x70\x2a\xfe\x6c\x68" "\x5c\x7d\x65\x30\x2b\xc0\xde\xc6\xea\x72\x1e\xdd\x46\xdf\xb2\x08" }, { GCRY_MD_BLAKE2B_256, "?", "\xfa\x11\x30\xd8\xba\x8a\x4c\x5a\x0e\x6f\x4f\x4c\xd2\xd1\x38\x0c" "\xb9\x22\x2a\xbd\xf6\x20\x70\xf8\x02\x1b\x34\xdd\xd7\x24\x92\x1b" }, { GCRY_MD_BLAKE2B_160, "?", "\xe7\x86\x08\x31\xf8\x96\x8d\x64\x9b\xe0\x15\x68\x33\xf3\xbd\x2a" "\x5f\x0b\xdb\x40" }, { GCRY_MD_BLAKE2S_256, "abc", "\x50\x8C\x5E\x8C\x32\x7C\x14\xE2\xE1\xA7\x2B\xA3\x4E\xEB\x45\x2F" "\x37\x45\x8B\x20\x9E\xD6\x3A\x29\x4D\x99\x9B\x4C\x86\x67\x59\x82" }, #include "./blake2s.h" { GCRY_MD_BLAKE2S_128, "", "\x84\x89\x68\xb3\x59\x01\xe9\x57\x9a\x4d\xbf\x28\xdf\x99\xec\x23", 0, 16, "\xea\xea\xd5\xc0\x96\x56\xec\x43\x30\x73\xa3\x17\xbb\xd3\x8e\x62", 16 }, { GCRY_MD_BLAKE2S_128, "\x9c\x9c\x38", "\x2e\xbb\x18\x78\xda\x34\x05\xad\x98\x1a\x33\x06\x50\x35\xd3\x75", 3, 16, "\xea\xea\xd5\xc0\x96\x56\xec\x43\x30\x73\xa3\x17\xbb\xd3\x8e\x62", 16 }, { GCRY_MD_BLAKE2S_128, "\xab\xab\x56\x01\x58\x5a\xb3\x0d\xc1\xce\x8f\x5e\xee\x4d\x3b\x88" "\xc4\x4c\x11\x5e\x6f\xcd\x3d\x0a\x47\x52\x9a\xec\x86\x73\xfa\x6e" "\x68\xd6\x3f\x16\x55\x6b\xc1\x2d\xef\x1d\x0c\x29\x35\x5f\x94\xf3" "\x88\x7c\x04\x81\x86\x07\x8e\x95\x23\xb9\xdd\x97\x74\x0c\x80\x8c", "\x3c\xd4\xea\xd7\x88\x0b\x8e\x82\xde\x07\x9c\x1f\xad\x34\x17\xd4", 64, 16, "\xea\xea\xd5\xc0\x96\x56\xec\x43\x30\x73\xa3\x17\xbb\xd3\x8e\x62", 16 }, { GCRY_MD_BLAKE2S_128, "\x8a\x8a\x14\x9e\xb2\x50\x02\x52\x54\xa6\xfa\xa0\x9a\x3a\xd4\x0e" "\xe3\xf2\xd5\xc7\x9d\x64\x02\x66\x68\xcf\x38\x08\x41\x49\x8a\xd3" "\x5e\x32\x90\xc2\x53\x15\x68\x7e\xe6\x65\x4b\xb0\xfc\xad\xaa\x58" "\x02\x5b\x5e\xb9\x18\xd1\xe9\xbb\xa5\x61\x07\x68\x70\xd9\x49\x22" "\x6b", "\xee\x92\xc5\x25\x4c\x29\x7a\x88\xe6\x9a\x23\x69\x56\xb6\x7c\xee", 65, 16, "\xea\xea\xd5\xc0\x96\x56\xec\x43\x30\x73\xa3\x17\xbb\xd3\x8e\x62", 16 }, { GCRY_MD_BLAKE2S_160, "", "\x68\x64\x48\x80\x0c\x80\xc6\xd0\x4f\xb7\x3f\xc1\x7f\xa0\x8c\xa2" "\x39\x03\xe1\xe9", 0, 20, "\x65\x65\xcb\x30\xfb\x2c\x28\x54\x7c\xd0\x4c\x1d\x6a\x88\xf2\x7a" "\x6d\xe8\x55\x3d", 20 }, { GCRY_MD_BLAKE2S_160, "\x9c\x9c\x38", "\xba\xb3\x5b\x8c\x87\x04\x1a\x00\x24\x44\xa5\xca\x45\x13\x2d\x75" "\xef\xd3\x4c\xb9", 3, 20, "\x65\x65\xcb\x30\xfb\x2c\x28\x54\x7c\xd0\x4c\x1d\x6a\x88\xf2\x7a" "\x6d\xe8\x55\x3d", 20 }, { GCRY_MD_BLAKE2S_160, "\xab\xab\x56\x01\x58\x5a\xb3\x0d\xc1\xce\x8f\x5e\xee\x4d\x3b\x88" "\xc4\x4c\x11\x5e\x6f\xcd\x3d\x0a\x47\x52\x9a\xec\x86\x73\xfa\x6e" "\x68\xd6\x3f\x16\x55\x6b\xc1\x2d\xef\x1d\x0c\x29\x35\x5f\x94\xf3" "\x88\x7c\x04\x81\x86\x07\x8e\x95\x23\xb9\xdd\x97\x74\x0c\x80\x8c", "\xe8\xc3\xf1\xdb\x1c\xf8\xe9\xd1\xb5\x4a\x54\x0a\xdc\xe7\x18\x13" "\x0f\xf4\x12\x98", 64, 20, "\x65\x65\xcb\x30\xfb\x2c\x28\x54\x7c\xd0\x4c\x1d\x6a\x88\xf2\x7a" "\x6d\xe8\x55\x3d", 20 }, { GCRY_MD_BLAKE2S_160, "\x8a\x8a\x14\x9e\xb2\x50\x02\x52\x54\xa6\xfa\xa0\x9a\x3a\xd4\x0e" "\xe3\xf2\xd5\xc7\x9d\x64\x02\x66\x68\xcf\x38\x08\x41\x49\x8a\xd3" "\x5e\x32\x90\xc2\x53\x15\x68\x7e\xe6\x65\x4b\xb0\xfc\xad\xaa\x58" "\x02\x5b\x5e\xb9\x18\xd1\xe9\xbb\xa5\x61\x07\x68\x70\xd9\x49\x22" "\x6b", "\x59\x02\xf8\x38\x18\x77\x9c\xd8\x13\x40\x0f\xd6\xbb\x23\x04\x1b" "\x64\x9a\x57\xa7", 65, 20, "\x65\x65\xcb\x30\xfb\x2c\x28\x54\x7c\xd0\x4c\x1d\x6a\x88\xf2\x7a" "\x6d\xe8\x55\x3d", 20 }, { GCRY_MD_BLAKE2S_224, "", "\xa8\x66\x86\x63\x35\x3a\xe0\x8f\x4e\x4b\x6b\x1e\xcb\x43\x19\xc8" "\x2b\x41\x3f\x5e\xe5\x43\x95\x9c\xa5\x9a\x73\x1b", 0, 28, "\x5a\x5a\xb5\x10\xc6\xd7\x9e\x76\x14\x8a\x9e\x29\xc8\xf1\xba\xab" "\x65\x11\x77\x89\x00\x89\x8a\x14\x9f\xb4\x53\x07", 28 }, { GCRY_MD_BLAKE2S_224, "\x9c\x9c\x38", "\x1a\x34\x9d\xc1\x51\xbd\x8b\xa2\xa7\xa6\x6b\xe4\x93\x98\x51\x88" "\x33\x49\x71\x02\x09\xb1\x20\x85\x8c\x4c\x67\xb8", 3, 28, "\x5a\x5a\xb5\x10\xc6\xd7\x9e\x76\x14\x8a\x9e\x29\xc8\xf1\xba\xab" "\x65\x11\x77\x89\x00\x89\x8a\x14\x9f\xb4\x53\x07", 28 }, { GCRY_MD_BLAKE2S_224, "\xab\xab\x56\x01\x58\x5a\xb3\x0d\xc1\xce\x8f\x5e\xee\x4d\x3b\x88" "\xc4\x4c\x11\x5e\x6f\xcd\x3d\x0a\x47\x52\x9a\xec\x86\x73\xfa\x6e" "\x68\xd6\x3f\x16\x55\x6b\xc1\x2d\xef\x1d\x0c\x29\x35\x5f\x94\xf3" "\x88\x7c\x04\x81\x86\x07\x8e\x95\x23\xb9\xdd\x97\x74\x0c\x80\x8c", "\x3a\x0e\xd5\x46\x95\x8c\xd6\xf9\x7c\x38\xd0\xe7\x1c\xfd\xd4\xc5" "\x67\x6d\x5c\xcc\x35\x06\xec\x87\x87\x09\x26\x39", 64, 28, "\x5a\x5a\xb5\x10\xc6\xd7\x9e\x76\x14\x8a\x9e\x29\xc8\xf1\xba\xab" "\x65\x11\x77\x89\x00\x89\x8a\x14\x9f\xb4\x53\x07", 28 }, { GCRY_MD_BLAKE2S_224, "\x8a\x8a\x14\x9e\xb2\x50\x02\x52\x54\xa6\xfa\xa0\x9a\x3a\xd4\x0e" "\xe3\xf2\xd5\xc7\x9d\x64\x02\x66\x68\xcf\x38\x08\x41\x49\x8a\xd3" "\x5e\x32\x90\xc2\x53\x15\x68\x7e\xe6\x65\x4b\xb0\xfc\xad\xaa\x58" "\x02\x5b\x5e\xb9\x18\xd1\xe9\xbb\xa5\x61\x07\x68\x70\xd9\x49\x22" "\x6b", "\x63\xd7\x98\xcc\x8e\xe3\x00\x45\x2f\xd8\x19\x83\x02\x94\x7f\xf1" "\xb3\x82\x73\xaa\x19\xae\x72\x8b\x1f\x64\xbe\x88", 65, 28, "\x5a\x5a\xb5\x10\xc6\xd7\x9e\x76\x14\x8a\x9e\x29\xc8\xf1\xba\xab" "\x65\x11\x77\x89\x00\x89\x8a\x14\x9f\xb4\x53\x07", 28 }, { GCRY_MD_BLAKE2S_256, "", "\x98\xf3\x21\xe5\x43\xb8\x07\x35\x27\x9c\x86\x1c\x36\x33\x9b\x43" "\x45\x50\xc6\x9d\x23\xc6\xc8\xff\x96\xbf\x4e\x03\x86\x10\x24\xfd", 0, 32, "\xd5\xd5\xab\x80\x2c\xad\xd9\x86\x60\xe7\x47\x2f\x77\xa6\x1d\xc4" "\xe2\xa6\x88\x2f\xb7\xe6\x9e\x85\x23\xa9\xcd\x76\x43\xb9\xfd\xb7", 32 }, { GCRY_MD_BLAKE2S_256, "\x9c\x9c\x38", "\x7b\x10\xa3\x67\xb8\x5d\x29\x9a\x91\x27\x37\x05\x9d\x05\x9d\x3d" "\xe6\x42\xa3\x19\x04\x57\x01\xb6\x25\x0b\xfd\x3c\x6c\xb9\x4f\x87", 3, 32, "\xd5\xd5\xab\x80\x2c\xad\xd9\x86\x60\xe7\x47\x2f\x77\xa6\x1d\xc4" "\xe2\xa6\x88\x2f\xb7\xe6\x9e\x85\x23\xa9\xcd\x76\x43\xb9\xfd\xb7", 32 }, { GCRY_MD_BLAKE2S_256, "\xab\xab\x56\x01\x58\x5a\xb3\x0d\xc1\xce\x8f\x5e\xee\x4d\x3b\x88" "\xc4\x4c\x11\x5e\x6f\xcd\x3d\x0a\x47\x52\x9a\xec\x86\x73\xfa\x6e" "\x68\xd6\x3f\x16\x55\x6b\xc1\x2d\xef\x1d\x0c\x29\x35\x5f\x94\xf3" "\x88\x7c\x04\x81\x86\x07\x8e\x95\x23\xb9\xdd\x97\x74\x0c\x80\x8c", "\xd7\x8b\x98\x28\x54\x4c\xc1\x62\x9e\xab\x7d\xfe\xb1\xfa\xdd\x2b" "\xed\x98\x1c\xe6\x5f\xef\xd8\x08\x42\x9a\x11\x1e\x97\x44\x92\xa3", 64, 32, "\xd5\xd5\xab\x80\x2c\xad\xd9\x86\x60\xe7\x47\x2f\x77\xa6\x1d\xc4" "\xe2\xa6\x88\x2f\xb7\xe6\x9e\x85\x23\xa9\xcd\x76\x43\xb9\xfd\xb7", 32 }, { GCRY_MD_BLAKE2S_256, "\x8a\x8a\x14\x9e\xb2\x50\x02\x52\x54\xa6\xfa\xa0\x9a\x3a\xd4\x0e" "\xe3\xf2\xd5\xc7\x9d\x64\x02\x66\x68\xcf\x38\x08\x41\x49\x8a\xd3" "\x5e\x32\x90\xc2\x53\x15\x68\x7e\xe6\x65\x4b\xb0\xfc\xad\xaa\x58" "\x02\x5b\x5e\xb9\x18\xd1\xe9\xbb\xa5\x61\x07\x68\x70\xd9\x49\x22" "\x6b", "\x1b\x9e\x26\x9a\x90\xf8\x73\x51\x73\xbc\x4f\x65\xce\x29\x2c\x61" "\x16\x65\xc7\xb0\x72\x07\xa8\x0b\xfb\x2e\xea\x12\x7d\x97\xcd\x06", 65, 32, "\xd5\xd5\xab\x80\x2c\xad\xd9\x86\x60\xe7\x47\x2f\x77\xa6\x1d\xc4" "\xe2\xa6\x88\x2f\xb7\xe6\x9e\x85\x23\xa9\xcd\x76\x43\xb9\xfd\xb7", 32 }, { GCRY_MD_BLAKE2S_256, "!", "\xbe\xc0\xc0\xe6\xcd\xe5\xb6\x7a\xcb\x73\xb8\x1f\x79\xa6\x7a\x40" "\x79\xae\x1c\x60\xda\xc9\xd2\x66\x1a\xf1\x8e\x9f\x8b\x50\xdf\xa5" }, { GCRY_MD_BLAKE2S_256, "?", "\xdc\x5a\xe7\x1b\xd4\x63\xa1\xf8\x4d\x73\x33\x44\x63\x6b\xa6\x87" "\xe6\xbd\xf4\xba\xed\xc3\xef\xc8\xb3\x86\x55\xbb\x08\x56\x3e\xdb" }, { GCRY_MD_BLAKE2S_224, "?", "\x2e\x34\x7d\x6b\xcc\x80\xbe\xc3\xf8\x61\x35\x6a\x88\x27\xcd\x84" "\x32\xd4\xd4\x05\xe0\x43\x20\x58\xc7\xb6\xda\xa3" }, { GCRY_MD_BLAKE2S_160, "?", "\xaa\x83\xe1\xcd\x8d\x4e\x9c\xb7\xf4\x6b\x43\xe1\xbc\x6f\x73\x3b" "\x0e\xfc\x29\xde" }, { GCRY_MD_BLAKE2S_128, "?", "\x70\x0b\x8a\x71\x1d\x34\x0a\xf0\x13\x93\x19\x93\x5e\xd7\x54\x9c" }, { GCRY_MD_SM3, "abc", "\x66\xc7\xf0\xf4\x62\xee\xed\xd9\xd1\xf2\xd4\x6b\xdc\x10\xe4\xe2" "\x41\x67\xc4\x87\x5c\xf2\xf7\xa2\x29\x7d\xa0\x2b\x8f\x4b\xa8\xe0" }, { GCRY_MD_SM3, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x63\x9b\x6c\xc5\xe6\x4d\x9e\x37\xa3\x90\xb1\x92\xdf\x4f\xa1\xea" "\x07\x20\xab\x74\x7f\xf6\x92\xb9\xf3\x8c\x4e\x66\xad\x7b\x8c\x05" }, { GCRY_MD_SM3, "!", "\xc8\xaa\xf8\x94\x29\x55\x40\x29\xe2\x31\x94\x1a\x2a\xcc\x0a\xd6" "\x1f\xf2\xa5\xac\xd8\xfa\xdd\x25\x84\x7a\x3a\x73\x2b\x3b\x02\xc3" }, { GCRY_MD_SM3, "?", "\x3a\x3f\x53\xfc\x96\xc2\xde\xb2\xd9\x12\x3a\x1b\xd8\x47\x71\x28" "\xbc\x5d\x5e\x94\xea\x08\x86\x3d\xfb\xe4\x00\x5a\xd9\xed\x79\x26" }, { GCRY_MD_SM3, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\x8b\x91\x3f\x0e\x85\xae\x43\x25\x6d\x28\x38\x6c\x09\x5c\xc7\x72" "\xcc\x2e\x78\x89\x7e\x2e\x4e\x5a\x3d\xf6\x55\xfe\x87\xbe\xa6\xbc" }, { 0 } }; gcry_error_t err; int i; if (verbose) fprintf (stderr, "Starting hash checks.\n"); for (i = 0; algos[i].md; i++) { if (gcry_md_test_algo (algos[i].md)) { show_md_not_available (algos[i].md); continue; } if (gcry_md_test_algo (algos[i].md) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i].md); continue; } if (verbose) fprintf (stderr, " checking %s [%i] for length %d\n", gcry_md_algo_name (algos[i].md), algos[i].md, (!strcmp (algos[i].data, "!") || !strcmp (algos[i].data, "?"))? 1000000 : (int)strlen(algos[i].data)); check_one_md (algos[i].md, algos[i].data, algos[i].datalen > 0 ? algos[i].datalen : strlen (algos[i].data), algos[i].expect, algos[i].expectlen, algos[i].key, algos[i].keylen); if (algos[i].key && algos[i].keylen) continue; check_one_md_multi (algos[i].md, algos[i].data, algos[i].datalen > 0 ? algos[i].datalen : strlen (algos[i].data), algos[i].expect); } /* Check the Whirlpool bug emulation. */ if (!gcry_md_test_algo (GCRY_MD_WHIRLPOOL) && !in_fips_mode) { static const char expect[] = "\x35\x28\xd6\x4c\x56\x2c\x55\x2e\x3b\x91\x93\x95\x7b\xdd\xcc\x6e" "\x6f\xb7\xbf\x76\x22\x9c\xc6\x23\xda\x3e\x09\x9b\x36\xe8\x6d\x76" "\x2f\x94\x3b\x0c\x63\xa0\xba\xa3\x4d\x66\x71\xe6\x5d\x26\x67\x28" "\x36\x1f\x0e\x1a\x40\xf0\xce\x83\x50\x90\x1f\xfa\x3f\xed\x6f\xfd"; gcry_md_hd_t hd; int algo = GCRY_MD_WHIRLPOOL; unsigned char *p; int mdlen; err = gcry_md_open (&hd, GCRY_MD_WHIRLPOOL, GCRY_MD_FLAG_BUGEMU1); if (err) { fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err)); goto leave; } mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 500) { fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen); gcry_md_close (hd); goto leave; } /* Hash 62 byes in chunks. */ gcry_md_write (hd, "1234567890", 10); gcry_md_write (hd, "1234567890123456789012345678901234567890123456789012", 52); p = gcry_md_read (hd, algo); if (memcmp (p, expect, mdlen)) { printf ("computed: "); for (i = 0; i < mdlen; i++) printf ("%02x ", p[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < mdlen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } gcry_md_close (hd); } leave: if (verbose) fprintf (stderr, "Completed hash checks.\n"); } static void check_one_hmac (int algo, const char *data, int datalen, const char *key, int keylen, const char *expect) { gcry_md_hd_t hd, hd2; unsigned char *p; int mdlen; int i; gcry_error_t err = 0; err = gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC); if (err) { fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err)); return; } mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 500) { fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen); return; } gcry_md_setkey( hd, key, keylen ); gcry_md_write (hd, data, datalen); err = gcry_md_copy (&hd2, hd); if (err) { fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err)); } gcry_md_close (hd); p = gcry_md_read (hd2, algo); if (!p) fail("algo %d, hmac gcry_md_read failed\n", algo); if (memcmp (p, expect, mdlen)) { printf ("computed: "); for (i = 0; i < mdlen; i++) printf ("%02x ", p[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < mdlen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } gcry_md_close (hd2); } static void check_hmac (void) { static const struct algos { int md; const char *data; const char *key; const char *expect; } algos[] = { { GCRY_MD_MD5, "what do ya want for nothing?", "Jefe", "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38" }, { GCRY_MD_MD5, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d" }, { GCRY_MD_MD5, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA", "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6" }, { GCRY_MD_MD5, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea\x3a\x75\x16\x47\x46\xff\xaa\x79" }, { GCRY_MD_MD5, "Test With Truncation", "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", "\x56\x46\x1e\xf2\x34\x2e\xdc\x00\xf9\xba\xb9\x95\x69\x0e\xfd\x4c" }, { GCRY_MD_MD5, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa", "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd" }, { GCRY_MD_MD5, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa", "\x6f\x63\x0f\xad\x67\xcd\xa0\xee\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e", }, { GCRY_MD_SHA256, "what do ya want for nothing?", "Jefe", "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7\x5a" "\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43" }, { GCRY_MD_SHA256, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88" "\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7" }, { GCRY_MD_SHA256, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA\xAA", "\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81\xa7" "\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5\x65\xfe" }, { GCRY_MD_SHA256, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\x82\x55\x8a\x38\x9a\x44\x3c\x0e\xa4\xcc\x81\x98\x99\xf2\x08" "\x3a\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b" }, { GCRY_MD_SHA256, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f" "\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54" }, { GCRY_MD_SHA256, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44" "\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2" }, { GCRY_MD_SHA224, "what do ya want for nothing?", "Jefe", "\xa3\x0e\x01\x09\x8b\xc6\xdb\xbf\x45\x69\x0f\x3a\x7e\x9e\x6d\x0f" "\x8b\xbe\xa2\xa3\x9e\x61\x48\x00\x8f\xd0\x5e\x44" }, { GCRY_MD_SHA224, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\x89\x6f\xb1\x12\x8a\xbb\xdf\x19\x68\x32\x10\x7c\xd4\x9d\xf3\x3f\x47" "\xb4\xb1\x16\x99\x12\xba\x4f\x53\x68\x4b\x22" }, { GCRY_MD_SHA224, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA\xAA", "\x7f\xb3\xcb\x35\x88\xc6\xc1\xf6\xff\xa9\x69\x4d\x7d\x6a\xd2\x64" "\x93\x65\xb0\xc1\xf6\x5d\x69\xd1\xec\x83\x33\xea" }, { GCRY_MD_SHA224, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\x6c\x11\x50\x68\x74\x01\x3c\xac\x6a\x2a\xbc\x1b\xb3\x82\x62" "\x7c\xec\x6a\x90\xd8\x6e\xfc\x01\x2d\xe7\xaf\xec\x5a" }, { GCRY_MD_SHA224, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x95\xe9\xa0\xdb\x96\x20\x95\xad\xae\xbe\x9b\x2d\x6f\x0d\xbc\xe2" "\xd4\x99\xf1\x12\xf2\xd2\xb7\x27\x3f\xa6\x87\x0e" }, { GCRY_MD_SHA224, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x3a\x85\x41\x66\xac\x5d\x9f\x02\x3f\x54\xd5\x17\xd0\xb3\x9d\xbd" "\x94\x67\x70\xdb\x9c\x2b\x95\xc9\xf6\xf5\x65\xd1" }, { GCRY_MD_SHA384, "what do ya want for nothing?", "Jefe", "\xaf\x45\xd2\xe3\x76\x48\x40\x31\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b" "\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47\xe4\x2e\xc3\x73\x63\x22\x44\x5e" "\x8e\x22\x40\xca\x5e\x69\xe2\xc7\x8b\x32\x39\xec\xfa\xb2\x16\x49" }, { GCRY_MD_SHA384, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\xaf\xd0\x39\x44\xd8\x48\x95\x62\x6b\x08\x25\xf4\xab\x46\x90\x7f\x15" "\xf9\xda\xdb\xe4\x10\x1e\xc6\x82\xaa\x03\x4c\x7c\xeb\xc5\x9c\xfa\xea" "\x9e\xa9\x07\x6e\xde\x7f\x4a\xf1\x52\xe8\xb2\xfa\x9c\xb6" }, { GCRY_MD_SHA384, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA\xAA", "\x88\x06\x26\x08\xd3\xe6\xad\x8a\x0a\xa2\xac\xe0\x14\xc8\xa8\x6f" "\x0a\xa6\x35\xd9\x47\xac\x9f\xeb\xe8\x3e\xf4\xe5\x59\x66\x14\x4b" "\x2a\x5a\xb3\x9d\xc1\x38\x14\xb9\x4e\x3a\xb6\xe1\x01\xa3\x4f\x27" }, { GCRY_MD_SHA384, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\x3e\x8a\x69\xb7\x78\x3c\x25\x85\x19\x33\xab\x62\x90\xaf\x6c\xa7" "\x7a\x99\x81\x48\x08\x50\x00\x9c\xc5\x57\x7c\x6e\x1f\x57\x3b\x4e" "\x68\x01\xdd\x23\xc4\xa7\xd6\x79\xcc\xf8\xa3\x86\xc6\x74\xcf\xfb" }, { GCRY_MD_SHA384, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x4e\xce\x08\x44\x85\x81\x3e\x90\x88\xd2\xc6\x3a\x04\x1b\xc5\xb4" "\x4f\x9e\xf1\x01\x2a\x2b\x58\x8f\x3c\xd1\x1f\x05\x03\x3a\xc4\xc6" "\x0c\x2e\xf6\xab\x40\x30\xfe\x82\x96\x24\x8d\xf1\x63\xf4\x49\x52" }, { GCRY_MD_SHA384, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x66\x17\x17\x8e\x94\x1f\x02\x0d\x35\x1e\x2f\x25\x4e\x8f\xd3\x2c" "\x60\x24\x20\xfe\xb0\xb8\xfb\x9a\xdc\xce\xbb\x82\x46\x1e\x99\xc5" "\xa6\x78\xcc\x31\xe7\x99\x17\x6d\x38\x60\xe6\x11\x0c\x46\x52\x3e" }, { GCRY_MD_SHA512, "what do ya want for nothing?", "Jefe", "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3" "\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25\x05\x54" "\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd" "\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a\x38\xbc\xe7\x37" }, { GCRY_MD_SHA512, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\x87\xaa\x7c\xde\xa5\xef\x61\x9d\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0" "\x23\x79\xf4\xe2\xce\x4e\xc2\x78\x7a\xd0\xb3\x05\x45\xe1\x7c\xde" "\xda\xa8\x33\xb7\xd6\xb8\xa7\x02\x03\x8b\x27\x4e\xae\xa3\xf4\xe4" "\xbe\x9d\x91\x4e\xeb\x61\xf1\x70\x2e\x69\x6c\x20\x3a\x12\x68\x54" }, { GCRY_MD_SHA512, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA\xAA", "\xfa\x73\xb0\x08\x9d\x56\xa2\x84\xef\xb0\xf0\x75\x6c\x89\x0b\xe9" "\xb1\xb5\xdb\xdd\x8e\xe8\x1a\x36\x55\xf8\x3e\x33\xb2\x27\x9d\x39" "\xbf\x3e\x84\x82\x79\xa7\x22\xc8\x06\xb4\x85\xa4\x7e\x67\xc8\x07" "\xb9\x46\xa3\x37\xbe\xe8\x94\x26\x74\x27\x88\x59\xe1\x32\x92\xfb" }, { GCRY_MD_SHA512, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\xb0\xba\x46\x56\x37\x45\x8c\x69\x90\xe5\xa8\xc5\xf6\x1d\x4a\xf7" "\xe5\x76\xd9\x7f\xf9\x4b\x87\x2d\xe7\x6f\x80\x50\x36\x1e\xe3\xdb" "\xa9\x1c\xa5\xc1\x1a\xa2\x5e\xb4\xd6\x79\x27\x5c\xc5\x78\x80\x63" "\xa5\xf1\x97\x41\x12\x0c\x4f\x2d\xe2\xad\xeb\xeb\x10\xa2\x98\xdd" }, { GCRY_MD_SHA512, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x80\xb2\x42\x63\xc7\xc1\xa3\xeb\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4" "\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1\x12\x1b\x01\x37\x83\xf8\xf3\x52" "\x6b\x56\xd0\x37\xe0\x5f\x25\x98\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52" "\x95\xe6\x4f\x73\xf6\x3f\x0a\xec\x8b\x91\x5a\x98\x5d\x78\x65\x98" }, { GCRY_MD_SHA512, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd" "\xde\xbd\x71\xf8\x86\x72\x89\x86\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44" "\xb6\x02\x2c\xac\x3c\x49\x82\xb1\x0d\x5e\xeb\x55\xc3\xe4\xde\x15" "\x13\x46\x76\xfb\x6d\xe0\x44\x60\x65\xc9\x74\x40\xfa\x8c\x6a\x58" }, { 0 }, }; int i; if (verbose) fprintf (stderr, "Starting hashed MAC checks.\n"); for (i = 0; algos[i].md; i++) { if (gcry_md_test_algo (algos[i].md)) { show_old_hmac_not_available (algos[i].md); continue; } if (gcry_md_test_algo (algos[i].md) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i].md); continue; } if (verbose) fprintf (stderr, " checking %s [%i] for %d byte key and %d byte data\n", gcry_md_algo_name (algos[i].md), algos[i].md, (int)strlen(algos[i].key), (int)strlen(algos[i].data)); check_one_hmac (algos[i].md, algos[i].data, strlen (algos[i].data), algos[i].key, strlen(algos[i].key), algos[i].expect); } if (verbose) fprintf (stderr, "Completed hashed MAC checks.\n"); } static void check_one_mac (int algo, const char *data, int datalen, const char *key, int keylen, const char *iv, int ivlen, const char *expect, int test_buffering) { gcry_mac_hd_t hd; unsigned char *p; unsigned int maclen; size_t macoutlen; int i; gcry_error_t err = 0; if (test_buffering) { if ((*data == '!' && !data[1]) || (*data == '?' && !data[1])) { return; /* Skip. */ } } err = gcry_mac_open (&hd, algo, 0, NULL); if (err) { fail ("algo %d, gcry_mac_open failed: %s\n", algo, gpg_strerror (err)); return; } i = gcry_mac_get_algo (hd); if (i != algo) { fail ("algo %d, gcry_mac_get_algo failed: %d\n", algo, i); } maclen = gcry_mac_get_algo_maclen (algo); if (maclen < 1 || maclen > 500) { fail ("algo %d, gcry_mac_get_algo_maclen failed: %d\n", algo, maclen); return; } p = malloc(maclen); if (!p) { fail ("algo %d, could not malloc %d bytes\n", algo, maclen); return; } err = gcry_mac_setkey (hd, key, keylen); if (err) fail("algo %d, mac gcry_mac_setkey failed: %s\n", algo, gpg_strerror (err)); if (err) goto out; if (ivlen && iv) { err = gcry_mac_setiv (hd, iv, ivlen); if (err) fail("algo %d, mac gcry_mac_ivkey failed: %s\n", algo, gpg_strerror (err)); if (err) goto out; } if (test_buffering) { for (i = 0; i < datalen; i++) { err = gcry_mac_write (hd, &data[i], 1); if (err) fail("algo %d, mac gcry_mac_write [buf-offset: %d] failed: %s\n", algo, i, gpg_strerror (err)); if (err) goto out; } } else { if ((*data == '!' && !data[1]) || /* hash one million times a "a" */ (*data == '?' && !data[1])) /* hash million byte data-set with byte pattern 0x00,0x01,0x02,... */ { char aaa[1000]; size_t left = 1000 * 1000; size_t startlen = 1; size_t piecelen = startlen; if (*data == '!') memset (aaa, 'a', 1000); /* Write in chuck with all sizes 1 to 1000 (500500 bytes) */ for (i = 1; i <= 1000 && left > 0; i++) { piecelen = i; if (piecelen > sizeof(aaa)) piecelen = sizeof(aaa); if (piecelen > left) piecelen = left; if (*data == '?') fillbuf_count(aaa, piecelen, 1000 * 1000 - left); gcry_mac_write (hd, aaa, piecelen); left -= piecelen; } /* Write in odd size chunks so that we test the buffering. */ while (left > 0) { if (piecelen > sizeof(aaa)) piecelen = sizeof(aaa); if (piecelen > left) piecelen = left; if (*data == '?') fillbuf_count(aaa, piecelen, 1000 * 1000 - left); gcry_mac_write (hd, aaa, piecelen); left -= piecelen; if (piecelen == sizeof(aaa)) piecelen = ++startlen; else piecelen = piecelen * 2 - ((piecelen != startlen) ? startlen : 0); } } else { err = gcry_mac_write (hd, data, datalen); } if (err) fail("algo %d, mac gcry_mac_write failed: %s\n", algo, gpg_strerror (err)); if (err) goto out; } err = gcry_mac_verify (hd, expect, maclen); if (err) fail("algo %d, mac gcry_mac_verify failed: %s\n", algo, gpg_strerror (err)); macoutlen = maclen; err = gcry_mac_read (hd, p, &macoutlen); if (err) fail("algo %d, mac gcry_mac_read failed: %s\n", algo, gpg_strerror (err)); if (err) goto out; if (memcmp (p, expect, maclen)) { printf ("computed: "); for (i = 0; i < maclen; i++) printf ("%02x ", p[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < maclen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } if (err) goto out; out: free (p); gcry_mac_close (hd); } static void check_mac (void) { static const struct algos { int algo; const char *data; const char *key; const char *expect; const char *iv; unsigned int dlen; unsigned int klen; } algos[] = { { GCRY_MAC_HMAC_MD5, "what do ya want for nothing?", "Jefe", "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38" }, { GCRY_MAC_HMAC_MD5, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d" }, { GCRY_MAC_HMAC_MD5, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA", "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6" }, { GCRY_MAC_HMAC_MD5, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea\x3a\x75\x16\x47\x46\xff\xaa\x79" }, { GCRY_MAC_HMAC_MD5, "Test With Truncation", "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", "\x56\x46\x1e\xf2\x34\x2e\xdc\x00\xf9\xba\xb9\x95\x69\x0e\xfd\x4c" }, { GCRY_MAC_HMAC_MD5, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa", "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd" }, { GCRY_MAC_HMAC_MD5, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa", "\x6f\x63\x0f\xad\x67\xcd\xa0\xee\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e", }, { GCRY_MAC_HMAC_MD5, "?", "????????????????", "\x7e\x28\xf8\x8e\xf4\x6c\x48\x30\xa2\x0c\xe3\xe1\x42\xd4\xb5\x6b" }, { GCRY_MAC_HMAC_SHA256, "what do ya want for nothing?", "Jefe", "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7\x5a" "\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43" }, { GCRY_MAC_HMAC_SHA256, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88" "\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7" }, { GCRY_MAC_HMAC_SHA256, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA\xAA", "\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81\xa7" "\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5\x65\xfe" }, { GCRY_MAC_HMAC_SHA256, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\x82\x55\x8a\x38\x9a\x44\x3c\x0e\xa4\xcc\x81\x98\x99\xf2\x08" "\x3a\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b" }, { GCRY_MAC_HMAC_SHA256, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f" "\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54" }, { GCRY_MAC_HMAC_SHA256, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44" "\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2" }, { GCRY_MAC_HMAC_SHA256, "?", "????????????????", "\x1c\x0e\x57\xad\x4a\x02\xd2\x30\xce\x7e\xf8\x08\x23\x25\x71\x5e" "\x16\x9b\x30\xca\xc3\xf4\x99\xc5\x1d\x4c\x25\x32\xa9\xf2\x15\x28" }, { GCRY_MAC_HMAC_SHA224, "what do ya want for nothing?", "Jefe", "\xa3\x0e\x01\x09\x8b\xc6\xdb\xbf\x45\x69\x0f\x3a\x7e\x9e\x6d\x0f" "\x8b\xbe\xa2\xa3\x9e\x61\x48\x00\x8f\xd0\x5e\x44" }, { GCRY_MAC_HMAC_SHA224, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\x89\x6f\xb1\x12\x8a\xbb\xdf\x19\x68\x32\x10\x7c\xd4\x9d\xf3\x3f\x47" "\xb4\xb1\x16\x99\x12\xba\x4f\x53\x68\x4b\x22" }, { GCRY_MAC_HMAC_SHA224, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA\xAA", "\x7f\xb3\xcb\x35\x88\xc6\xc1\xf6\xff\xa9\x69\x4d\x7d\x6a\xd2\x64" "\x93\x65\xb0\xc1\xf6\x5d\x69\xd1\xec\x83\x33\xea" }, { GCRY_MAC_HMAC_SHA224, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\x6c\x11\x50\x68\x74\x01\x3c\xac\x6a\x2a\xbc\x1b\xb3\x82\x62" "\x7c\xec\x6a\x90\xd8\x6e\xfc\x01\x2d\xe7\xaf\xec\x5a" }, { GCRY_MAC_HMAC_SHA224, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x95\xe9\xa0\xdb\x96\x20\x95\xad\xae\xbe\x9b\x2d\x6f\x0d\xbc\xe2" "\xd4\x99\xf1\x12\xf2\xd2\xb7\x27\x3f\xa6\x87\x0e" }, { GCRY_MAC_HMAC_SHA224, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x3a\x85\x41\x66\xac\x5d\x9f\x02\x3f\x54\xd5\x17\xd0\xb3\x9d\xbd" "\x94\x67\x70\xdb\x9c\x2b\x95\xc9\xf6\xf5\x65\xd1" }, { GCRY_MAC_HMAC_SHA224, "?", "????????????????", "\xc1\x88\xaf\xcf\xce\x51\xa2\x14\x3d\xc1\xaf\x93\xcc\x2b\xe9\x4d" "\x39\x55\x90\x4c\x46\x70\xfc\xc2\x04\xcf\xab\xfa" }, { GCRY_MAC_HMAC_SHA384, "what do ya want for nothing?", "Jefe", "\xaf\x45\xd2\xe3\x76\x48\x40\x31\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b" "\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47\xe4\x2e\xc3\x73\x63\x22\x44\x5e" "\x8e\x22\x40\xca\x5e\x69\xe2\xc7\x8b\x32\x39\xec\xfa\xb2\x16\x49" }, { GCRY_MAC_HMAC_SHA384, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\xaf\xd0\x39\x44\xd8\x48\x95\x62\x6b\x08\x25\xf4\xab\x46\x90\x7f\x15" "\xf9\xda\xdb\xe4\x10\x1e\xc6\x82\xaa\x03\x4c\x7c\xeb\xc5\x9c\xfa\xea" "\x9e\xa9\x07\x6e\xde\x7f\x4a\xf1\x52\xe8\xb2\xfa\x9c\xb6" }, { GCRY_MAC_HMAC_SHA384, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA\xAA", "\x88\x06\x26\x08\xd3\xe6\xad\x8a\x0a\xa2\xac\xe0\x14\xc8\xa8\x6f" "\x0a\xa6\x35\xd9\x47\xac\x9f\xeb\xe8\x3e\xf4\xe5\x59\x66\x14\x4b" "\x2a\x5a\xb3\x9d\xc1\x38\x14\xb9\x4e\x3a\xb6\xe1\x01\xa3\x4f\x27" }, { GCRY_MAC_HMAC_SHA384, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\x3e\x8a\x69\xb7\x78\x3c\x25\x85\x19\x33\xab\x62\x90\xaf\x6c\xa7" "\x7a\x99\x81\x48\x08\x50\x00\x9c\xc5\x57\x7c\x6e\x1f\x57\x3b\x4e" "\x68\x01\xdd\x23\xc4\xa7\xd6\x79\xcc\xf8\xa3\x86\xc6\x74\xcf\xfb" }, { GCRY_MAC_HMAC_SHA384, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x4e\xce\x08\x44\x85\x81\x3e\x90\x88\xd2\xc6\x3a\x04\x1b\xc5\xb4" "\x4f\x9e\xf1\x01\x2a\x2b\x58\x8f\x3c\xd1\x1f\x05\x03\x3a\xc4\xc6" "\x0c\x2e\xf6\xab\x40\x30\xfe\x82\x96\x24\x8d\xf1\x63\xf4\x49\x52" }, { GCRY_MAC_HMAC_SHA384, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x66\x17\x17\x8e\x94\x1f\x02\x0d\x35\x1e\x2f\x25\x4e\x8f\xd3\x2c" "\x60\x24\x20\xfe\xb0\xb8\xfb\x9a\xdc\xce\xbb\x82\x46\x1e\x99\xc5" "\xa6\x78\xcc\x31\xe7\x99\x17\x6d\x38\x60\xe6\x11\x0c\x46\x52\x3e" }, { GCRY_MAC_HMAC_SHA384, "?", "????????????????", "\xe7\x96\x29\xa3\x40\x5f\x1e\x6e\x92\xa5\xdb\xa5\xc6\xe9\x60\xa8" "\xf5\xd1\x6d\xcb\x10\xec\x30\x2f\x6b\x9c\x37\xe0\xea\xf1\x53\x28" "\x08\x01\x9b\xe3\x4a\x43\xc6\xc2\x2b\x0c\xd9\x43\x64\x35\x25\x78" }, { GCRY_MAC_HMAC_SHA512, "what do ya want for nothing?", "Jefe", "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3" "\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25\x05\x54" "\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd" "\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a\x38\xbc\xe7\x37" }, { GCRY_MAC_HMAC_SHA512, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\x87\xaa\x7c\xde\xa5\xef\x61\x9d\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0" "\x23\x79\xf4\xe2\xce\x4e\xc2\x78\x7a\xd0\xb3\x05\x45\xe1\x7c\xde" "\xda\xa8\x33\xb7\xd6\xb8\xa7\x02\x03\x8b\x27\x4e\xae\xa3\xf4\xe4" "\xbe\x9d\x91\x4e\xeb\x61\xf1\x70\x2e\x69\x6c\x20\x3a\x12\x68\x54" }, { GCRY_MAC_HMAC_SHA512, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA\xAA", "\xfa\x73\xb0\x08\x9d\x56\xa2\x84\xef\xb0\xf0\x75\x6c\x89\x0b\xe9" "\xb1\xb5\xdb\xdd\x8e\xe8\x1a\x36\x55\xf8\x3e\x33\xb2\x27\x9d\x39" "\xbf\x3e\x84\x82\x79\xa7\x22\xc8\x06\xb4\x85\xa4\x7e\x67\xc8\x07" "\xb9\x46\xa3\x37\xbe\xe8\x94\x26\x74\x27\x88\x59\xe1\x32\x92\xfb" }, { GCRY_MAC_HMAC_SHA512, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\xb0\xba\x46\x56\x37\x45\x8c\x69\x90\xe5\xa8\xc5\xf6\x1d\x4a\xf7" "\xe5\x76\xd9\x7f\xf9\x4b\x87\x2d\xe7\x6f\x80\x50\x36\x1e\xe3\xdb" "\xa9\x1c\xa5\xc1\x1a\xa2\x5e\xb4\xd6\x79\x27\x5c\xc5\x78\x80\x63" "\xa5\xf1\x97\x41\x12\x0c\x4f\x2d\xe2\xad\xeb\xeb\x10\xa2\x98\xdd" }, { GCRY_MAC_HMAC_SHA512, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x80\xb2\x42\x63\xc7\xc1\xa3\xeb\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4" "\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1\x12\x1b\x01\x37\x83\xf8\xf3\x52" "\x6b\x56\xd0\x37\xe0\x5f\x25\x98\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52" "\x95\xe6\x4f\x73\xf6\x3f\x0a\xec\x8b\x91\x5a\x98\x5d\x78\x65\x98" }, { GCRY_MAC_HMAC_SHA512, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd" "\xde\xbd\x71\xf8\x86\x72\x89\x86\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44" "\xb6\x02\x2c\xac\x3c\x49\x82\xb1\x0d\x5e\xeb\x55\xc3\xe4\xde\x15" "\x13\x46\x76\xfb\x6d\xe0\x44\x60\x65\xc9\x74\x40\xfa\x8c\x6a\x58" }, { GCRY_MAC_HMAC_SHA512, "?", "????????????????", "\xd4\x43\x61\xfa\x3d\x3d\x57\xd6\xac\xc3\x9f\x1c\x3d\xd9\x26\x84" "\x1f\xfc\x4d\xf2\xbf\x78\x87\x72\x5e\x6c\x3e\x00\x6d\x39\x5f\xfa" "\xd7\x3a\xf7\x83\xb7\xb5\x61\xbd\xfb\x33\xe0\x03\x97\xa7\x72\x79" "\x66\x66\xbf\xbd\x44\xfa\x04\x01\x1b\xc1\x48\x1d\x9e\xde\x5b\x8e" }, /* HMAC-SHA3 test vectors from * http://wolfgang-ehrhardt.de/hmac-sha3-testvectors.html */ { GCRY_MAC_HMAC_SHA3_224, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\x3b\x16\x54\x6b\xbc\x7b\xe2\x70\x6a\x03\x1d\xca\xfd\x56\x37\x3d" "\x98\x84\x36\x76\x41\xd8\xc5\x9a\xf3\xc8\x60\xf7" }, { GCRY_MAC_HMAC_SHA3_256, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\xba\x85\x19\x23\x10\xdf\xfa\x96\xe2\xa3\xa4\x0e\x69\x77\x43\x51" "\x14\x0b\xb7\x18\x5e\x12\x02\xcd\xcc\x91\x75\x89\xf9\x5e\x16\xbb" }, { GCRY_MAC_HMAC_SHA3_512, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\xeb\x3f\xbd\x4b\x2e\xaa\xb8\xf5\xc5\x04\xbd\x3a\x41\x46\x5a\xac" "\xec\x15\x77\x0a\x7c\xab\xac\x53\x1e\x48\x2f\x86\x0b\x5e\xc7\xba" "\x47\xcc\xb2\xc6\xf2\xaf\xce\x8f\x88\xd2\x2b\x6d\xc6\x13\x80\xf2" "\x3a\x66\x8f\xd3\x88\x8b\xb8\x05\x37\xc0\xa0\xb8\x64\x07\x68\x9e" }, { GCRY_MAC_HMAC_SHA3_224, "what do ya want for nothing?", "Jefe", "\x7f\xdb\x8d\xd8\x8b\xd2\xf6\x0d\x1b\x79\x86\x34\xad\x38\x68\x11" "\xc2\xcf\xc8\x5b\xfa\xf5\xd5\x2b\xba\xce\x5e\x66" }, { GCRY_MAC_HMAC_SHA3_256, "what do ya want for nothing?", "Jefe", "\xc7\xd4\x07\x2e\x78\x88\x77\xae\x35\x96\xbb\xb0\xda\x73\xb8\x87" "\xc9\x17\x1f\x93\x09\x5b\x29\x4a\xe8\x57\xfb\xe2\x64\x5e\x1b\xa5" }, { GCRY_MAC_HMAC_SHA3_384, "what do ya want for nothing?", "Jefe", "\xf1\x10\x1f\x8c\xbf\x97\x66\xfd\x67\x64\xd2\xed\x61\x90\x3f\x21" "\xca\x9b\x18\xf5\x7c\xf3\xe1\xa2\x3c\xa1\x35\x08\xa9\x32\x43\xce" "\x48\xc0\x45\xdc\x00\x7f\x26\xa2\x1b\x3f\x5e\x0e\x9d\xf4\xc2\x0a" }, { GCRY_MAC_HMAC_SHA3_512, "what do ya want for nothing?", "Jefe", "\x5a\x4b\xfe\xab\x61\x66\x42\x7c\x7a\x36\x47\xb7\x47\x29\x2b\x83" "\x84\x53\x7c\xdb\x89\xaf\xb3\xbf\x56\x65\xe4\xc5\xe7\x09\x35\x0b" "\x28\x7b\xae\xc9\x21\xfd\x7c\xa0\xee\x7a\x0c\x31\xd0\x22\xa9\x5e" "\x1f\xc9\x2b\xa9\xd7\x7d\xf8\x83\x96\x02\x75\xbe\xb4\xe6\x20\x24" }, { GCRY_MAC_HMAC_SHA3_224, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\xb9\x6d\x73\x0c\x14\x8c\x2d\xaa\xd8\x64\x9d\x83\xde\xfa\xa3\x71" "\x97\x38\xd3\x47\x75\x39\x7b\x75\x71\xc3\x85\x15" }, { GCRY_MAC_HMAC_SHA3_256, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\xa6\x07\x2f\x86\xde\x52\xb3\x8b\xb3\x49\xfe\x84\xcd\x6d\x97\xfb" "\x6a\x37\xc4\xc0\xf6\x2a\xae\x93\x98\x11\x93\xa7\x22\x9d\x34\x67" }, { GCRY_MAC_HMAC_SHA3_384, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x71\x3d\xff\x03\x02\xc8\x50\x86\xec\x5a\xd0\x76\x8d\xd6\x5a\x13" "\xdd\xd7\x90\x68\xd8\xd4\xc6\x21\x2b\x71\x2e\x41\x64\x94\x49\x11" "\x14\x80\x23\x00\x44\x18\x5a\x99\x10\x3e\xd8\x20\x04\xdd\xbf\xcc" }, { GCRY_MAC_HMAC_SHA3_512, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\xb1\x48\x35\xc8\x19\xa2\x90\xef\xb0\x10\xac\xe6\xd8\x56\x8d\xc6" "\xb8\x4d\xe6\x0b\xc4\x9b\x00\x4c\x3b\x13\xed\xa7\x63\x58\x94\x51" "\xe5\xdd\x74\x29\x28\x84\xd1\xbd\xce\x64\xe6\xb9\x19\xdd\x61\xdc" "\x9c\x56\xa2\x82\xa8\x1c\x0b\xd1\x4f\x1f\x36\x5b\x49\xb8\x3a\x5b" }, { GCRY_MAC_HMAC_SHA3_224, "This is a test using a larger than block-size key and a larger " "than block-size data. The key needs to be hashed before being " "used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\xc7\x9c\x9b\x09\x34\x24\xe5\x88\xa9\x87\x8b\xbc\xb0\x89\xe0\x18" "\x27\x00\x96\xe9\xb4\xb1\xa9\xe8\x22\x0c\x86\x6a" }, { GCRY_MAC_HMAC_SHA3_256, "This is a test using a larger than block-size key and a larger " "than block-size data. The key needs to be hashed before being " "used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\xe6\xa3\x6d\x9b\x91\x5f\x86\xa0\x93\xca\xc7\xd1\x10\xe9\xe0\x4c" "\xf1\xd6\x10\x0d\x30\x47\x55\x09\xc2\x47\x5f\x57\x1b\x75\x8b\x5a" }, { GCRY_MAC_HMAC_SHA3_384, "This is a test using a larger than block-size key and a larger " "than block-size data. The key needs to be hashed before being " "used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\xca\xd1\x8a\x8f\xf6\xc4\xcc\x3a\xd4\x87\xb9\x5f\x97\x69\xe9\xb6" "\x1c\x06\x2a\xef\xd6\x95\x25\x69\xe6\xe6\x42\x18\x97\x05\x4c\xfc" "\x70\xb5\xfd\xc6\x60\x5c\x18\x45\x71\x12\xfc\x6a\xaa\xd4\x55\x85" }, { GCRY_MAC_HMAC_SHA3_512, "This is a test using a larger than block-size key and a larger " "than block-size data. The key needs to be hashed before being " "used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\xdc\x03\x0e\xe7\x88\x70\x34\xf3\x2c\xf4\x02\xdf\x34\x62\x2f\x31" "\x1f\x3e\x6c\xf0\x48\x60\xc6\xbb\xd7\xfa\x48\x86\x74\x78\x2b\x46" "\x59\xfd\xbd\xf3\xfd\x87\x78\x52\x88\x5c\xfe\x6e\x22\x18\x5f\xe7" "\xb2\xee\x95\x20\x43\x62\x9b\xc9\xd5\xf3\x29\x8a\x41\xd0\x2c\x66" }, { GCRY_MAC_HMAC_SHA3_224, "?", "????????????????", "\x80\x2b\x3c\x84\xfe\x3e\x01\x22\x14\xf8\xba\x74\x79\xfd\xb5\x02" "\xea\x0c\x06\xa4\x7e\x01\xe3\x2c\xc7\x24\x89\xc3" }, { GCRY_MAC_HMAC_SHA3_256, "?", "????????????????", "\x6c\x7c\x96\x5b\x19\xba\xcd\x61\x69\x8a\x2c\x7a\x2b\x96\xa1\xc3" "\x33\xa0\x3c\x5d\x54\x87\x37\x60\xc8\x2f\xa2\xa6\x12\x38\x8d\x1b" }, { GCRY_MAC_HMAC_SHA3_384, "?", "????????????????", "\xc0\x20\xd0\x9b\xa7\xb9\xd5\xb8\xa6\xa4\xba\x20\x55\xd9\x0b\x35" "\x8b\xe0\xb7\xec\x1e\x9f\xe6\xb9\xbd\xd5\xe9\x9b\xfc\x0a\x11\x3a" "\x15\x41\xed\xfd\xef\x30\x8d\x03\xb8\xca\x3a\xa8\xc7\x2d\x89\x32" }, { GCRY_MAC_HMAC_SHA3_512, "?", "????????????????", "\xb4\xef\x24\xd2\x07\xa7\x01\xb3\xe1\x81\x11\x22\x93\x83\x64\xe0" "\x5e\xad\x03\xb7\x43\x4f\x87\xa1\x14\x8e\x17\x8f\x2a\x97\x7d\xe8" "\xbd\xb0\x37\x3b\x67\xb9\x97\x36\xa5\x82\x9b\xdc\x0d\xe4\x5a\x8c" "\x5e\xda\xb5\xca\xea\xa9\xb4\x6e\xba\xca\x25\xc8\xbf\xa1\x0e\xb0" }, { GCRY_MAC_HMAC_STRIBOG256, "\x01\x26\xbd\xb8\x78\x00\xaf\x21\x43\x41\x45\x65\x63\x78\x01\x00", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", "\xa1\xaa\x5f\x7d\xe4\x02\xd7\xb3\xd3\x23\xf2\x99\x1c\x8d\x45\x34" "\x01\x31\x37\x01\x0a\x83\x75\x4f\xd0\xaf\x6d\x7c\xd4\x92\x2e\xd9", NULL, 16, 32 }, { GCRY_MAC_HMAC_STRIBOG512, "\x01\x26\xbd\xb8\x78\x00\xaf\x21\x43\x41\x45\x65\x63\x78\x01\x00", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", "\xa5\x9b\xab\x22\xec\xae\x19\xc6\x5f\xbd\xe6\xe5\xf4\xe9\xf5\xd8" "\x54\x9d\x31\xf0\x37\xf9\xdf\x9b\x90\x55\x00\xe1\x71\x92\x3a\x77" "\x3d\x5f\x15\x30\xf2\xed\x7e\x96\x4c\xb2\xee\xdc\x29\xe9\xad\x2f" "\x3a\xfe\x93\xb2\x81\x4f\x79\xf5\x00\x0f\xfc\x03\x66\xc2\x51\xe6", NULL, 16, 32 }, /* CMAC AES and DES test vectors from http://web.archive.org/web/20130930212819/http://csrc.nist.gov/publica\ tions/nistpubs/800-38B/Updated_CMAC_Examples.pdf */ { GCRY_MAC_CMAC_AES, "", "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xbb\x1d\x69\x29\xe9\x59\x37\x28\x7f\xa3\x7d\x12\x9b\x75\x67\x46" }, { GCRY_MAC_CMAC_AES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\x07\x0a\x16\xb4\x6b\x4d\x41\x44\xf7\x9b\xdd\x9d\xd0\x4a\x28\x7c" }, { GCRY_MAC_CMAC_AES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xdf\xa6\x67\x47\xde\x9a\xe6\x30\x30\xca\x32\x61\x14\x97\xc8\x27" }, { GCRY_MAC_CMAC_AES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\x51\xf0\xbe\xbf\x7e\x3b\x9d\x92\xfc\x49\x74\x17\x79\x36\x3c\xfe" }, { GCRY_MAC_CMAC_AES, "", "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5" "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", "\xd1\x7d\xdf\x46\xad\xaa\xcd\xe5\x31\xca\xc4\x83\xde\x7a\x93\x67" }, { GCRY_MAC_CMAC_AES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5" "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", "\x9e\x99\xa7\xbf\x31\xe7\x10\x90\x06\x62\xf6\x5e\x61\x7c\x51\x84" }, { GCRY_MAC_CMAC_AES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5" "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", "\x8a\x1d\xe5\xbe\x2e\xb3\x1a\xad\x08\x9a\x82\xe6\xee\x90\x8b\x0e" }, { GCRY_MAC_CMAC_AES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5" "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", "\xa1\xd5\xdf\x0e\xed\x79\x0f\x79\x4d\x77\x58\x96\x59\xf3\x9a\x11" }, { GCRY_MAC_CMAC_AES, "", "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", "\x02\x89\x62\xf6\x1b\x7b\xf8\x9e\xfc\x6b\x55\x1f\x46\x67\xd9\x83" }, { GCRY_MAC_CMAC_AES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", "\x28\xa7\x02\x3f\x45\x2e\x8f\x82\xbd\x4b\xf2\x8d\x8c\x37\xc3\x5c" }, { GCRY_MAC_CMAC_AES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", "\xaa\xf3\xd8\xf1\xde\x56\x40\xc2\x32\xf5\xb1\x69\xb9\xc9\x11\xe6" }, { GCRY_MAC_CMAC_AES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", "\xe1\x99\x21\x90\x54\x9f\x6e\xd5\x69\x6a\x2c\x05\x6c\x31\x54\x10" }, { GCRY_MAC_CMAC_AES, "?", "????????????????????????????????", "\x9f\x72\x73\x68\xb0\x49\x2e\xb1\x35\xa0\x1d\xf9\xa8\x0a\xf6\xee" }, { GCRY_MAC_CMAC_3DES, "", "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", "\xb7\xa6\x88\xe1\x22\xff\xaf\x95" }, { GCRY_MAC_CMAC_3DES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96", "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", "\x8e\x8f\x29\x31\x36\x28\x37\x97" }, { GCRY_MAC_CMAC_3DES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" "\xae\x2d\x8a\x57", "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", "\x74\x3d\xdb\xe0\xce\x2d\xc2\xed" }, { GCRY_MAC_CMAC_3DES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", "\x33\xe6\xb1\x09\x24\x00\xea\xe5" }, { GCRY_MAC_CMAC_3DES, "", "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5\x8a\x3d\x10\xba\x80\x57\x0d\x38" "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5", "\xbd\x2e\xbf\x9a\x3b\xa0\x03\x61" }, { GCRY_MAC_CMAC_3DES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96", "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5\x8a\x3d\x10\xba\x80\x57\x0d\x38" "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5", "\x4f\xf2\xab\x81\x3c\x53\xce\x83" }, { GCRY_MAC_CMAC_3DES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" "\xae\x2d\x8a\x57", "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5\x8a\x3d\x10\xba\x80\x57\x0d\x38" "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5", "\x62\xdd\x1b\x47\x19\x02\xbd\x4e" }, { GCRY_MAC_CMAC_3DES, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5\x8a\x3d\x10\xba\x80\x57\x0d\x38" "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5", "\x31\xb1\xe4\x31\xda\xbc\x4e\xb8" }, { GCRY_MAC_CMAC_3DES, "?", "????????????????????????", "\xc1\x38\x13\xb2\x31\x8f\x3a\xdf" }, /* CMAC Camellia test vectors from http://tools.ietf.org/html/draft-kato-ipsec-camellia-cmac96and128-05 */ { GCRY_MAC_CMAC_CAMELLIA, "", "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xba\x92\x57\x82\xaa\xa1\xf5\xd9\xa0\x0f\x89\x64\x80\x94\xfc\x71" }, { GCRY_MAC_CMAC_CAMELLIA, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\x6d\x96\x28\x54\xa3\xb9\xfd\xa5\x6d\x7d\x45\xa9\x5e\xe1\x79\x93" }, { GCRY_MAC_CMAC_CAMELLIA, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\x5c\x18\xd1\x19\xcc\xd6\x76\x61\x44\xac\x18\x66\x13\x1d\x9f\x22" }, { GCRY_MAC_CMAC_CAMELLIA, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xc2\x69\x9a\x6e\xba\x55\xce\x9d\x93\x9a\x8a\x4e\x19\x46\x6e\xe9" }, { GCRY_MAC_CMAC_CAMELLIA, "?", "????????????????????????????????", "\xba\x8a\x5a\x8d\xa7\x54\x26\x83\x3e\xb1\x20\xb5\x45\xd0\x9f\x4e" }, /* http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip */ { GCRY_MAC_GMAC_AES, "", "\x11\x75\x4c\xd7\x2a\xec\x30\x9b\xf5\x2f\x76\x87\x21\x2e\x89\x57", "\x25\x03\x27\xc6\x74\xaa\xf4\x77\xae\xf2\x67\x57\x48\xcf\x69\x71", "\x3c\x81\x9d\x9a\x9b\xed\x08\x76\x15\x03\x0b\x65" }, { GCRY_MAC_GMAC_AES, "\x2b\x63\x26\x64\x29\x67\x4a\xb5\xe2\xea\xff\x63\x9c\x23\x14\x66" "\x2f\x92\x57\x4b\x29\x8f\x57\x7a\xcf\x7d\x6f\x99\x1a\x87\x92\x1f" "\xc2\x32\xea\xfc\xc7\xb1\x46\x48\x96\x63\x2d\x6c\x8a\xbe\x88\xc2" "\xcc\xa4\x04\xdb\xf8\x7c\x20\x6a\x19\xd3\x73\xed\x99\x50\x17\x34" "\x69\x13\x4d\x7c\x14\xc2\x84\x7d\xf2\x4a\x88\xc1\xc5\x3b\x4d\xe4" "\x9d\xb3\x66\x39\x2b\x6d\xc6\x51\x27\x6e", "\x0f\x3b\x17\xde\xae\x62\x13\x64\x55\x4a\xe5\x39\xdb\x09\xde\x11", "\xff\xb0\xbb\x6d\xfc\x23\x58\x75\x4f\x17\x78\x48\x5b\x59\x65\x7f", "\xa7\xf6\x07\x4c\xda\x56\x1c\xd2\xaa\x15\xba\x8c\x2f\xa6\x39\x42" "\x59\x3e\x7c\xcf\x45\xc2\x9a\x57\xda\xd8\xa6\xe2\xea\x63\x54\xce" "\x8a\xde\x39\xdd\xde\x4a\xc4\x5b\xbd\xc6\x63\xf0\xa5\x37\xc9\x48" "\x18\x23\x5a\x73\xd8\xa0\x8b\xd8\x98\xab\xd0\x99\xe1\x5c\x08\x8c" "\x6e\x21\x17\x5a\xf4\xe9\xa4\x99\x70\x12\x82\xed\x32\x81\x50\xa6" "\xd9\x90\xe8\xec\x87\x85\xce\x26\x1b\xe1\xb8\x3f\xd8\x59\x1e\x57" "\x76\x5f\x3d\xc1\x11\x3f\xd0\x2a\x40\xf5\x01\x6a\xd0\xd0\xed\xc4" "\x92\x9a\x02\xe0\x17\xb2\xc5\xf4\x18\xd2\x96\xab\xd6\xc2\xea\x2e" }, { GCRY_MAC_GMAC_AES, "\x61\x14\x60\x11\x90\xf6\xef\x5e\x59\x23\x5d\xc0\x42\x8c\x09\xe3" "\x27\x0b\x19\xea", "\x15\xa4\x14\x46\x6a\x7f\x90\xea\x32\xbf\xd7\xf6\xe5\x8b\xfa\x06" "\xe9\x07\xfc\x41\x66\x89\xd9\x60\x39\x45\xd7\x94\x54\xd4\x23\x17", "\x19\x6e\x0e\x01\x0f\x08\x56\xf9\x82\xb4\x08\x92\x41\xd6\x24\x84", "\xab" }, { GCRY_MAC_GMAC_AES, "\x8b\x5c\x12\x4b\xef\x6e\x2f\x0f\xe4\xd8\xc9\x5c\xd5\xfa\x4c\xf1", "\x41\xc5\xda\x86\x67\xef\x72\x52\x20\xff\xe3\x9a\xe0\xac\x59\x0a" "\xc9\xfc\xa7\x29\xab\x60\xad\xa0", "\x20\x4b\xdb\x1b\xd6\x21\x54\xbf\x08\x92\x2a\xaa\x54\xee\xd7\x05", "\x05\xad\x13\xa5\xe2\xc2\xab\x66\x7e\x1a\x6f\xbc" }, { GCRY_MAC_GMAC_AES, "?", "????????????????????????????????", "\x84\x37\xc3\x42\xae\xf5\xd0\x40\xd3\x73\x90\xa9\x36\xed\x8a\x12" }, /* from NaCl */ { GCRY_MAC_POLY1305, "\x8e\x99\x3b\x9f\x48\x68\x12\x73\xc2\x96\x50\xba\x32\xfc\x76\xce" "\x48\x33\x2e\xa7\x16\x4d\x96\xa4\x47\x6f\xb8\xc5\x31\xa1\x18\x6a" "\xc0\xdf\xc1\x7c\x98\xdc\xe8\x7b\x4d\xa7\xf0\x11\xec\x48\xc9\x72" "\x71\xd2\xc2\x0f\x9b\x92\x8f\xe2\x27\x0d\x6f\xb8\x63\xd5\x17\x38" "\xb4\x8e\xee\xe3\x14\xa7\xcc\x8a\xb9\x32\x16\x45\x48\xe5\x26\xae" "\x90\x22\x43\x68\x51\x7a\xcf\xea\xbd\x6b\xb3\x73\x2b\xc0\xe9\xda" "\x99\x83\x2b\x61\xca\x01\xb6\xde\x56\x24\x4a\x9e\x88\xd5\xf9\xb3" "\x79\x73\xf6\x22\xa4\x3d\x14\xa6\x59\x9b\x1f\x65\x4c\xb4\x5a\x74" "\xe3\x55\xa5", "\xee\xa6\xa7\x25\x1c\x1e\x72\x91\x6d\x11\xc2\xcb\x21\x4d\x3c\x25" "\x25\x39\x12\x1d\x8e\x23\x4e\x65\x2d\x65\x1f\xa4\xc8\xcf\xf8\x80", "\xf3\xff\xc7\x70\x3f\x94\x00\xe5\x2a\x7d\xfb\x4b\x3d\x33\x05\xd9" }, /* from draft-nir-cfrg-chacha20-poly1305-03 */ { GCRY_MAC_POLY1305, "Cryptographic Forum Research Group", "\x85\xd6\xbe\x78\x57\x55\x6d\x33\x7f\x44\x52\xfe\x42\xd5\x06\xa8" "\x01\x03\x80\x8a\xfb\x0d\xb2\xfd\x4a\xbf\xf6\xaf\x41\x49\xf5\x1b", "\xa8\x06\x1d\xc1\x30\x51\x36\xc6\xc2\x2b\x8b\xaf\x0c\x01\x27\xa9" }, { GCRY_MAC_POLY1305, "'Twas brillig, and the slithy toves\n" "Did gyre and gimble in the wabe:\n" "All mimsy were the borogoves,\n" "And the mome raths outgrabe.", "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a\xf3\x33\x88\x86\x04\xf6\xb5\xf0" "\x47\x39\x17\xc1\x40\x2b\x80\x09\x9d\xca\x5c\xbc\x20\x70\x75\xc0", "\x45\x41\x66\x9a\x7e\xaa\xee\x61\xe7\x08\xdc\x7c\xbc\xc5\xeb\x62" }, { GCRY_MAC_POLY1305, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", NULL, 191, 32 }, { GCRY_MAC_POLY1305, "Any submission to the IETF intended by the Contributor for " "publication as all or part of an IETF Internet-Draft or RFC and " "any statement made within the context of an IETF activity is " "considered an \"IETF Contribution\". Such statements include " "oral statements in IETF sessions, as well as written and " "electronic communications made at any time or place, which are " "addressed to", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x36\xe5\xf6\xb5\xc5\xe0\x60\x70\xf0\xef\xca\x96\x22\x7a\x86\x3e", "\x36\xe5\xf6\xb5\xc5\xe0\x60\x70\xf0\xef\xca\x96\x22\x7a\x86\x3e", NULL, 0, 32 }, { GCRY_MAC_POLY1305, "Any submission to the IETF intended by the Contributor for " "publication as all or part of an IETF Internet-Draft or RFC and " "any statement made within the context of an IETF activity is " "considered an \"IETF Contribution\". Such statements include " "oral statements in IETF sessions, as well as written and " "electronic communications made at any time or place, which are " "addressed to", "\x36\xe5\xf6\xb5\xc5\xe0\x60\x70\xf0\xef\xca\x96\x22\x7a\x86\x3e" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\xf3\x47\x7e\x7c\xd9\x54\x17\xaf\x89\xa6\xb8\x79\x4c\x31\x0c\xf0", NULL, 0, 32 }, /* draft-irtf-cfrg-chacha20-poly1305-01 */ /* TV#5 */ { GCRY_MAC_POLY1305, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", NULL, 16, 32 }, /* TV#6 */ { GCRY_MAC_POLY1305, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", NULL, 16, 32 }, /* TV#7 */ { GCRY_MAC_POLY1305, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xF0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", NULL, 48, 32 }, /* TV#8 */ { GCRY_MAC_POLY1305, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFB\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE" "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01", "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", NULL, 48, 32 }, /* TV#9 */ { GCRY_MAC_POLY1305, "\xFD\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\xFA\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", NULL, 16, 32 }, /* TV#10 */ { GCRY_MAC_POLY1305, "\xE3\x35\x94\xD7\x50\x5E\x43\xB9\x00\x00\x00\x00\x00\x00\x00\x00" "\x33\x94\xD7\x50\x5E\x43\x79\xCD\x01\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x14\x00\x00\x00\x00\x00\x00\x00\x55\x00\x00\x00\x00\x00\x00\x00", NULL, 64, 32 }, /* TV#11 */ { GCRY_MAC_POLY1305, "\xE3\x35\x94\xD7\x50\x5E\x43\xB9\x00\x00\x00\x00\x00\x00\x00\x00" "\x33\x94\xD7\x50\x5E\x43\x79\xCD\x01\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", NULL, 48, 32 }, /* from http://cr.yp.to/mac/poly1305-20050329.pdf */ { GCRY_MAC_POLY1305, "\xf3\xf6", "\x85\x1f\xc4\x0c\x34\x67\xac\x0b\xe0\x5c\xc2\x04\x04\xf3\xf7\x00" "\x58\x0b\x3b\x0f\x94\x47\xbb\x1e\x69\xd0\x95\xb5\x92\x8b\x6d\xbc", "\xf4\xc6\x33\xc3\x04\x4f\xc1\x45\xf8\x4f\x33\x5c\xb8\x19\x53\xde", NULL, 0, 32 }, { GCRY_MAC_POLY1305, "", "\xa0\xf3\x08\x00\x00\xf4\x64\x00\xd0\xc7\xe9\x07\x6c\x83\x44\x03" "\xdd\x3f\xab\x22\x51\xf1\x1a\xc7\x59\xf0\x88\x71\x29\xcc\x2e\xe7", "\xdd\x3f\xab\x22\x51\xf1\x1a\xc7\x59\xf0\x88\x71\x29\xcc\x2e\xe7", NULL, 0, 32 }, { GCRY_MAC_POLY1305, "\x66\x3c\xea\x19\x0f\xfb\x83\xd8\x95\x93\xf3\xf4\x76\xb6\xbc\x24" "\xd7\xe6\x79\x10\x7e\xa2\x6a\xdb\x8c\xaf\x66\x52\xd0\x65\x61\x36", "\x48\x44\x3d\x0b\xb0\xd2\x11\x09\xc8\x9a\x10\x0b\x5c\xe2\xc2\x08" "\x83\x14\x9c\x69\xb5\x61\xdd\x88\x29\x8a\x17\x98\xb1\x07\x16\xef", "\x0e\xe1\xc1\x6b\xb7\x3f\x0f\x4f\xd1\x98\x81\x75\x3c\x01\xcd\xbe", NULL, 0, 32 }, { GCRY_MAC_POLY1305, "\xab\x08\x12\x72\x4a\x7f\x1e\x34\x27\x42\xcb\xed\x37\x4d\x94\xd1" "\x36\xc6\xb8\x79\x5d\x45\xb3\x81\x98\x30\xf2\xc0\x44\x91\xfa\xf0" "\x99\x0c\x62\xe4\x8b\x80\x18\xb2\xc3\xe4\xa0\xfa\x31\x34\xcb\x67" "\xfa\x83\xe1\x58\xc9\x94\xd9\x61\xc4\xcb\x21\x09\x5c\x1b\xf9", "\x12\x97\x6a\x08\xc4\x42\x6d\x0c\xe8\xa8\x24\x07\xc4\xf4\x82\x07" "\x80\xf8\xc2\x0a\xa7\x12\x02\xd1\xe2\x91\x79\xcb\xcb\x55\x5a\x57", "\x51\x54\xad\x0d\x2c\xb2\x6e\x01\x27\x4f\xc5\x11\x48\x49\x1f\x1b" }, { GCRY_MAC_POLY1305, "?", "????????????????????????????????", "\xc3\x88\xce\x8a\x52\xd6\xe7\x21\x86\xfa\xaa\x5d\x2d\x16\xf9\xa3" }, /* from http://cr.yp.to/mac/poly1305-20050329.pdf */ { GCRY_MAC_POLY1305_AES, "\xf3\xf6", "\xec\x07\x4c\x83\x55\x80\x74\x17\x01\x42\x5b\x62\x32\x35\xad\xd6" "\x85\x1f\xc4\x0c\x34\x67\xac\x0b\xe0\x5c\xc2\x04\x04\xf3\xf7\x00", "\xf4\xc6\x33\xc3\x04\x4f\xc1\x45\xf8\x4f\x33\x5c\xb8\x19\x53\xde", "\xfb\x44\x73\x50\xc4\xe8\x68\xc5\x2a\xc3\x27\x5c\xf9\xd4\x32\x7e", 0, 32 }, { GCRY_MAC_POLY1305_AES, "", "\x75\xde\xaa\x25\xc0\x9f\x20\x8e\x1d\xc4\xce\x6b\x5c\xad\x3f\xbf" "\xa0\xf3\x08\x00\x00\xf4\x64\x00\xd0\xc7\xe9\x07\x6c\x83\x44\x03", "\xdd\x3f\xab\x22\x51\xf1\x1a\xc7\x59\xf0\x88\x71\x29\xcc\x2e\xe7", "\x61\xee\x09\x21\x8d\x29\xb0\xaa\xed\x7e\x15\x4a\x2c\x55\x09\xcc", 0, 32 }, { GCRY_MAC_POLY1305_AES, "\x66\x3c\xea\x19\x0f\xfb\x83\xd8\x95\x93\xf3\xf4\x76\xb6\xbc\x24" "\xd7\xe6\x79\x10\x7e\xa2\x6a\xdb\x8c\xaf\x66\x52\xd0\x65\x61\x36", "\x6a\xcb\x5f\x61\xa7\x17\x6d\xd3\x20\xc5\xc1\xeb\x2e\xdc\xdc\x74" "\x48\x44\x3d\x0b\xb0\xd2\x11\x09\xc8\x9a\x10\x0b\x5c\xe2\xc2\x08", "\x0e\xe1\xc1\x6b\xb7\x3f\x0f\x4f\xd1\x98\x81\x75\x3c\x01\xcd\xbe", "\xae\x21\x2a\x55\x39\x97\x29\x59\x5d\xea\x45\x8b\xc6\x21\xff\x0e", 0, 32 }, { GCRY_MAC_POLY1305_AES, "\xab\x08\x12\x72\x4a\x7f\x1e\x34\x27\x42\xcb\xed\x37\x4d\x94\xd1" "\x36\xc6\xb8\x79\x5d\x45\xb3\x81\x98\x30\xf2\xc0\x44\x91\xfa\xf0" "\x99\x0c\x62\xe4\x8b\x80\x18\xb2\xc3\xe4\xa0\xfa\x31\x34\xcb\x67" "\xfa\x83\xe1\x58\xc9\x94\xd9\x61\xc4\xcb\x21\x09\x5c\x1b\xf9", "\xe1\xa5\x66\x8a\x4d\x5b\x66\xa5\xf6\x8c\xc5\x42\x4e\xd5\x98\x2d" "\x12\x97\x6a\x08\xc4\x42\x6d\x0c\xe8\xa8\x24\x07\xc4\xf4\x82\x07", "\x51\x54\xad\x0d\x2c\xb2\x6e\x01\x27\x4f\xc5\x11\x48\x49\x1f\x1b", "\x9a\xe8\x31\xe7\x43\x97\x8d\x3a\x23\x52\x7c\x71\x28\x14\x9e\x3a", 0, 32 }, { GCRY_MAC_POLY1305_AES, "?", "????????????????????????????????", "\x9d\xeb\xb0\xcd\x24\x90\xd3\x9b\x47\x78\x37\x0a\x81\xf2\x83\x2a", "\x61\xee\x09\x21\x8d\x29\xb0\xaa\xed\x7e\x15\x4a\x2c\x55\x09\xcc", 0, 32 }, { 0 }, }; int i; if (verbose) fprintf (stderr, "Starting MAC checks.\n"); for (i = 0; algos[i].algo; i++) { size_t klen, dlen; if (gcry_mac_test_algo (algos[i].algo)) { show_mac_not_available (algos[i].algo); continue; } if (gcry_mac_test_algo (algos[i].algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i].algo); continue; } if (verbose) fprintf (stderr, " checking %s [%i] for %d byte key and %d byte data\n", gcry_mac_algo_name (algos[i].algo), algos[i].algo, (int)strlen(algos[i].key), (!strcmp(algos[i].data, "!") || !strcmp(algos[i].data, "?")) ? 1000000 : (int)strlen(algos[i].data)); klen = algos[i].klen ? algos[i].klen : strlen(algos[i].key); dlen = algos[i].dlen ? algos[i].dlen : strlen (algos[i].data); check_one_mac (algos[i].algo, algos[i].data, dlen, algos[i].key, klen, algos[i].iv, algos[i].iv ? strlen(algos[i].iv) : 0, algos[i].expect, 0); check_one_mac (algos[i].algo, algos[i].data, dlen, algos[i].key, klen, algos[i].iv, algos[i].iv ? strlen(algos[i].iv) : 0, algos[i].expect, 1); } if (verbose) fprintf (stderr, "Completed MAC checks.\n"); } /* Check that the signature SIG matches the hash HASH. PKEY is the public key used for the verification. BADHASH is a hash value which should result in a bad signature status. */ static void verify_one_signature (gcry_sexp_t pkey, gcry_sexp_t hash, gcry_sexp_t badhash, gcry_sexp_t sig) { gcry_error_t rc; rc = gcry_pk_verify (sig, hash, pkey); if (rc) fail ("gcry_pk_verify failed: %s\n", gpg_strerror (rc)); rc = gcry_pk_verify (sig, badhash, pkey); if (gcry_err_code (rc) != GPG_ERR_BAD_SIGNATURE) fail ("gcry_pk_verify failed to detect a bad signature: %s\n", gpg_strerror (rc)); } /* Test the public key sign function using the private ket SKEY. PKEY is used for verification. */ static void check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo) { gcry_error_t rc; gcry_sexp_t sig, badhash, hash; int dataidx; static const char baddata[] = "(data\n (flags pkcs1)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203041#))\n"; static const struct { const char *data; int algo; int expected_rc; } datas[] = { { "(data\n (flags pkcs1)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags pkcs1-raw)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, GPG_ERR_CONFLICT }, { "(data\n (flags oaep)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", 0, GPG_ERR_CONFLICT }, /* This test is to see whether hash algorithms not hard wired in pubkey.c are detected: */ { "(data\n (flags pkcs1)\n" " (hash oid.1.3.14.3.2.29 " " #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags )\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", 0, GPG_ERR_CONFLICT }, { "(data\n (flags pkcs1)\n" " (hash foo #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, GPG_ERR_DIGEST_ALGO }, { "(data\n (flags )\n" " (value #11223344556677889900AA#))\n", 0, 0 }, { "(data\n (flags )\n" " (value #0090223344556677889900AA#))\n", 0, 0 }, { "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n", 0, 0 }, { "(data\n (flags pkcs1)\n" " (value #11223344556677889900AA#))\n", GCRY_PK_RSA, GPG_ERR_CONFLICT }, { "(data\n (flags pkcs1-raw)\n" " (value #11223344556677889900AA#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags raw foo)\n" " (value #11223344556677889900AA#))\n", 0, GPG_ERR_INV_FLAG }, { "(data\n (flags pss)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags pss)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#)\n" " (random-override #4253647587980912233445566778899019283747#))\n", GCRY_PK_RSA, 0 }, { NULL } }; rc = gcry_sexp_sscan (&badhash, NULL, baddata, strlen (baddata)); if (rc) die ("converting data failed: %s\n", gpg_strerror (rc)); for (dataidx = 0; datas[dataidx].data; dataidx++) { if (datas[dataidx].algo && datas[dataidx].algo != algo) continue; if (verbose) fprintf (stderr, " test %d, signature test %d (%s)\n", n, dataidx, gcry_pk_algo_name (algo)); rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data, strlen (datas[dataidx].data)); if (rc) die ("converting data failed: %s\n", gpg_strerror (rc)); rc = gcry_pk_sign (&sig, hash, skey); if (gcry_err_code (rc) != datas[dataidx].expected_rc) fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc)); if (!rc) verify_one_signature (pkey, hash, badhash, sig); gcry_sexp_release (sig); sig = NULL; gcry_sexp_release (hash); hash = NULL; } gcry_sexp_release (badhash); } /* Test the public key sign function using the private ket SKEY. PKEY is used for verification. This variant is only used for ECDSA. */ static void check_pubkey_sign_ecdsa (int n, gcry_sexp_t skey, gcry_sexp_t pkey) { gcry_error_t rc; gcry_sexp_t sig, badhash, hash; unsigned int nbits; int dataidx; static const struct { unsigned int nbits; const char *data; int expected_rc; const char *baddata; int dummy; } datas[] = { { 192, "(data (flags raw)\n" " (value #00112233445566778899AABBCCDDEEFF0001020304050607#))", 0, "(data (flags raw)\n" " (value #80112233445566778899AABBCCDDEEFF0001020304050607#))", 0 }, { 256, "(data (flags raw)\n" " (value #00112233445566778899AABBCCDDEEFF" /* */ "000102030405060708090A0B0C0D0E0F#))", 0, "(data (flags raw)\n" " (value #80112233445566778899AABBCCDDEEFF" /* */ "000102030405060708090A0B0C0D0E0F#))", 0 }, { 256, "(data (flags raw)\n" " (hash sha256 #00112233445566778899AABBCCDDEEFF" /* */ "000102030405060708090A0B0C0D0E0F#))", 0, "(data (flags raw)\n" " (hash sha256 #80112233445566778899AABBCCDDEEFF" /* */ "000102030405060708090A0B0C0D0E0F#))", 0 }, { 256, "(data (flags gost)\n" " (value #00112233445566778899AABBCCDDEEFF" /* */ "000102030405060708090A0B0C0D0E0F#))", 0, "(data (flags gost)\n" " (value #80112233445566778899AABBCCDDEEFF" /* */ "000102030405060708090A0B0C0D0E0F#))", 0 }, { 512, "(data (flags gost)\n" " (value #00112233445566778899AABBCCDDEEFF" /* */ "000102030405060708090A0B0C0D0E0F" /* */ "000102030405060708090A0B0C0D0E0F" /* */ "000102030405060708090A0B0C0D0E0F#))", 0, "(data (flags gost)\n" " (value #80112233445566778899AABBCCDDEEFF" /* */ "000102030405060708090A0B0C0D0E0F" /* */ "000102030405060708090A0B0C0D0E0F" /* */ "000102030405060708090A0B0C0D0E0F#))", 0 }, { 0, NULL } }; nbits = gcry_pk_get_nbits (skey); for (dataidx = 0; datas[dataidx].data; dataidx++) { if (datas[dataidx].nbits != nbits) continue; if (verbose) fprintf (stderr, " test %d, signature test %d (%u bit ecdsa)\n", n, dataidx, nbits); rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data, strlen (datas[dataidx].data)); if (rc) die ("converting data failed: %s\n", gpg_strerror (rc)); rc = gcry_sexp_sscan (&badhash, NULL, datas[dataidx].baddata, strlen (datas[dataidx].baddata)); if (rc) die ("converting data failed: %s\n", gpg_strerror (rc)); rc = gcry_pk_sign (&sig, hash, skey); if (gcry_err_code (rc) != datas[dataidx].expected_rc) fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc)); if (!rc && verbose > 1) show_sexp ("ECDSA signature:\n", sig); if (!rc) verify_one_signature (pkey, hash, badhash, sig); gcry_sexp_release (sig); sig = NULL; gcry_sexp_release (badhash); badhash = NULL; gcry_sexp_release (hash); hash = NULL; } } static void check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo) { gcry_error_t rc; gcry_sexp_t plain = NULL; gcry_sexp_t ciph = NULL; gcry_sexp_t data = NULL; int dataidx; static const struct { int algo; /* If not 0 run test only if ALGO matches. */ const char *data; const char *hint; int unpadded; int encrypt_expected_rc; int decrypt_expected_rc; int special; } datas[] = { { GCRY_PK_RSA, "(data\n (flags pkcs1)\n" " (value #11223344556677889900AA#))\n", NULL, 0, 0, 0 }, { GCRY_PK_RSA, "(data\n (flags pkcs1)\n" " (value #11223344556677889900AA#))\n", "(flags pkcs1)", 1, 0, 0 }, { GCRY_PK_RSA, "(data\n (flags oaep)\n" " (value #11223344556677889900AA#))\n", "(flags oaep)", 1, 0, 0 }, { GCRY_PK_RSA, "(data\n (flags oaep)\n (hash-algo sha1)\n" " (value #11223344556677889900AA#))\n", "(flags oaep)(hash-algo sha1)", 1, 0, 0 }, { GCRY_PK_RSA, "(data\n (flags oaep)\n (hash-algo sha1)\n (label \"test\")\n" " (value #11223344556677889900AA#))\n", "(flags oaep)(hash-algo sha1)(label \"test\")", 1, 0, 0 }, { GCRY_PK_RSA, "(data\n (flags oaep)\n (hash-algo sha1)\n (label \"test\")\n" " (value #11223344556677889900AA#)\n" " (random-override #4253647587980912233445566778899019283747#))\n", "(flags oaep)(hash-algo sha1)(label \"test\")", 1, 0, 0 }, { 0, "(data\n (flags )\n" " (value #11223344556677889900AA#))\n", NULL, 1, 0, 0 }, { 0, "(data\n (flags )\n" " (value #0090223344556677889900AA#))\n", NULL, 1, 0, 0 }, { 0, "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n", NULL, 1, 0, 0 }, { GCRY_PK_RSA, "(data\n (flags pkcs1)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", NULL, 0, GPG_ERR_CONFLICT, 0}, { 0, "(data\n (flags raw foo)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", NULL, 0, GPG_ERR_INV_FLAG, 0}, { 0, "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n", "(flags oaep)", 1, 0, GPG_ERR_ENCODING_PROBLEM, 1 }, { GCRY_PK_RSA, "(data\n (flags oaep)\n" " (value #11223344556677889900AA#))\n", "(flags pkcs1)", 1, 0, GPG_ERR_ENCODING_PROBLEM, 1 }, { 0, "(data\n (flags pss)\n" " (value #11223344556677889900AA#))\n", NULL, 0, GPG_ERR_CONFLICT }, { 0, NULL } }; (void)n; for (dataidx = 0; datas[dataidx].data; dataidx++) { if (datas[dataidx].algo && datas[dataidx].algo != algo) continue; if (verbose) fprintf (stderr, " encryption/decryption test %d (algo %d)\n", dataidx, algo); rc = gcry_sexp_sscan (&data, NULL, datas[dataidx].data, strlen (datas[dataidx].data)); if (rc) die ("converting data failed: %s\n", gpg_strerror (rc)); rc = gcry_pk_encrypt (&ciph, data, pkey); if (gcry_err_code (rc) != datas[dataidx].encrypt_expected_rc) fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (rc)); if (!rc) { int expect_mismatch = 0; /* Insert decoding hint to CIPH. */ if (datas[dataidx].hint) { size_t hint_len, len; char *hint, *buf; gcry_sexp_t list; /* Convert decoding hint into canonical sexp. */ hint_len = gcry_sexp_new (&list, datas[dataidx].hint, strlen (datas[dataidx].hint), 1); hint_len = gcry_sexp_sprint (list, GCRYSEXP_FMT_CANON, NULL, 0); hint = gcry_malloc (hint_len); if (!hint) die ("can't allocate memory\n"); hint_len = gcry_sexp_sprint (list, GCRYSEXP_FMT_CANON, hint, hint_len); gcry_sexp_release (list); /* Convert CIPH into canonical sexp. */ len = gcry_sexp_sprint (ciph, GCRYSEXP_FMT_CANON, NULL, 0); buf = gcry_malloc (len + hint_len); if (!buf) die ("can't allocate memory\n"); len = gcry_sexp_sprint (ciph, GCRYSEXP_FMT_CANON, buf, len); /* assert (!strcmp (buf, "(7:enc-val", 10)); */ /* Copy decoding hint into CIPH. */ memmove (buf + 10 + hint_len, buf + 10, len - 10); memcpy (buf + 10, hint, hint_len); gcry_free (hint); gcry_sexp_new (&list, buf, len + hint_len, 1); gcry_free (buf); gcry_sexp_release (ciph); ciph = list; } rc = gcry_pk_decrypt (&plain, ciph, skey); if (!rc && datas[dataidx].special == 1) { /* It may happen that OAEP formatted data which is decrypted as pkcs#1 data returns a valid pkcs#1 frame. However, the returned value will not be identical - thus we expect a mismatch and test further on whether this mismatch actually happened. */ expect_mismatch = 1; } else if (gcry_err_code (rc) != datas[dataidx].decrypt_expected_rc) { if (verbose) { show_sexp (" data:\n", data); show_sexp (" ciph:\n", ciph); show_sexp (" key:\n", skey); } fail ("gcry_pk_decrypt failed: expected %d (%s), got %d (%s)\n", datas[dataidx].decrypt_expected_rc, gpg_strerror (datas[dataidx].decrypt_expected_rc), rc, gpg_strerror (rc)); } if (!rc && datas[dataidx].unpadded) { gcry_sexp_t p1, p2; p1 = gcry_sexp_find_token (data, "value", 0); p2 = gcry_sexp_find_token (plain, "value", 0); if (p1 && p2) { const char *s1, *s2; size_t n1, n2; s1 = gcry_sexp_nth_data (p1, 1, &n1); s2 = gcry_sexp_nth_data (p2, 1, &n2); if (n1 != n2 || memcmp (s1, s2, n1)) { if (expect_mismatch) expect_mismatch = 0; else fail ("gcry_pk_encrypt/gcry_pk_decrypt " "do not roundtrip\n"); } } if (expect_mismatch) fail ("gcry_pk_encrypt/gcry_pk_decrypt " "expected mismatch did not happen\n"); gcry_sexp_release (p1); gcry_sexp_release (p2); } } gcry_sexp_release (plain); plain = NULL; gcry_sexp_release (ciph); ciph = NULL; gcry_sexp_release (data); data = NULL; } } static void check_pubkey_grip (int n, const unsigned char *grip, gcry_sexp_t skey, gcry_sexp_t pkey, int algo) { unsigned char sgrip[20], pgrip[20]; (void)algo; if (!gcry_pk_get_keygrip (skey, sgrip)) die ("get keygrip for private RSA key failed\n"); if (!gcry_pk_get_keygrip (pkey, pgrip)) die ("[%i] get keygrip for public RSA key failed\n", n); if (memcmp (sgrip, pgrip, 20)) fail ("[%i] keygrips don't match\n", n); if (memcmp (sgrip, grip, 20)) fail ("wrong keygrip for RSA key\n"); } static void do_check_one_pubkey (int n, gcry_sexp_t skey, gcry_sexp_t pkey, const unsigned char *grip, int algo, int flags) { if (flags & FLAG_SIGN) { if (algo == GCRY_PK_ECDSA) check_pubkey_sign_ecdsa (n, skey, pkey); else check_pubkey_sign (n, skey, pkey, algo); } if (flags & FLAG_CRYPT) check_pubkey_crypt (n, skey, pkey, algo); if (grip && (flags & FLAG_GRIP)) check_pubkey_grip (n, grip, skey, pkey, algo); } static void check_one_pubkey (int n, test_spec_pubkey_t spec) { gcry_error_t err = GPG_ERR_NO_ERROR; gcry_sexp_t skey, pkey; err = gcry_sexp_sscan (&skey, NULL, spec.key.secret, strlen (spec.key.secret)); if (!err) err = gcry_sexp_sscan (&pkey, NULL, spec.key.public, strlen (spec.key.public)); if (err) die ("converting sample key failed: %s\n", gpg_strerror (err)); do_check_one_pubkey (n, skey, pkey, (const unsigned char*)spec.key.grip, spec.id, spec.flags); gcry_sexp_release (skey); gcry_sexp_release (pkey); } static void get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) { gcry_sexp_t key_spec, key, pub_key, sec_key; int rc; if (verbose) fprintf (stderr, " generating RSA key:"); rc = gcry_sexp_new (&key_spec, in_fips_mode ? "(genkey (rsa (nbits 4:2048)))" : "(genkey (rsa (nbits 4:1024)(transient-key)))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gpg_strerror (rc)); rc = gcry_pk_genkey (&key, key_spec); gcry_sexp_release (key_spec); if (rc) die ("error generating RSA key: %s\n", gpg_strerror (rc)); pub_key = gcry_sexp_find_token (key, "public-key", 0); if (! pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key, "private-key", 0); if (! sec_key) die ("private part missing in key\n"); gcry_sexp_release (key); *pkey = pub_key; *skey = sec_key; } static void check_one_pubkey_new (int n) { gcry_sexp_t skey, pkey; get_keys_new (&pkey, &skey); do_check_one_pubkey (n, skey, pkey, NULL, GCRY_PK_RSA, FLAG_SIGN | FLAG_CRYPT); gcry_sexp_release (pkey); gcry_sexp_release (skey); } /* Run all tests for the public key functions. */ static void check_pubkey (void) { static const test_spec_pubkey_t pubkeys[] = { { GCRY_PK_RSA, FLAG_CRYPT | FLAG_SIGN, { "(private-key\n" " (rsa\n" " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" " 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" " ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" " 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea2" " 51#)\n" " (e #010001#)\n" " (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" " 7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" " C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" " C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781" " #)\n" " (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" " fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424" " f1#)\n" " (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9" " 35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad3" " 61#)\n" " (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" " ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b" " #)))\n", "(public-key\n" " (rsa\n" " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" " 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" " ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" " 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea2" " 51#)\n" " (e #010001#)))\n", "\x32\x10\x0c\x27\x17\x3e\xf6\xe9\xc4\xe9" "\xa2\x5d\x3d\x69\xf8\x6d\x37\xa4\xf9\x39"} }, { GCRY_PK_DSA, FLAG_SIGN, { "(private-key\n" " (DSA\n" " (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" " 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" " CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" " 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D877" " 7B#)\n" " (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n" " (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" " AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" " B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" " 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15" " #)\n" " (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" " A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" " 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" " 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB" " #)\n" " (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))\n", "(public-key\n" " (DSA\n" " (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" " 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" " CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" " 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D877" " 7B#)\n" " (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n" " (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" " AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" " B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" " 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15" " #)\n" " (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" " A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" " 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" " 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB" " #)))\n", "\xc6\x39\x83\x1a\x43\xe5\x05\x5d\xc6\xd8" "\x4a\xa6\xf9\xeb\x23\xbf\xa9\x12\x2d\x5b" } }, { GCRY_PK_ELG, FLAG_SIGN | FLAG_CRYPT, { "(private-key\n" " (ELG\n" " (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D" " F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517" " B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797" " 6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2" " A7#)\n" " (g #05#)\n" " (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B" " E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B" " D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675" " 56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4" " #)\n" " (x #03C28900087B38DABF4A0AB98ACEA39BB674D6557096C01D72E31C16BDD32214" " #)))\n", "(public-key\n" " (ELG\n" " (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D" " F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517" " B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797" " 6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2" " A7#)\n" " (g #05#)\n" " (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B" " E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B" " D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675" " 56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4" " #)))\n", "\xa7\x99\x61\xeb\x88\x83\xd2\xf4\x05\xc8" "\x4f\xba\x06\xf8\x78\x09\xbc\x1e\x20\xe5" } }, { /* ECDSA test. */ GCRY_PK_ECDSA, FLAG_SIGN, { "(private-key\n" " (ecdsa\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)\n" " (d #00D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D#)))\n", "(public-key\n" " (ecdsa\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)))\n", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } }, { /* ECDSA test with the public key algorithm given as "ecc". */ GCRY_PK_ECDSA, FLAG_SIGN, { "(private-key\n" " (ecdsa\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)\n" " (d #00D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D#)))\n", "(public-key\n" " (ecc\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)))\n", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } }, { /* ECDSA test with the private key algorithm given as "ecc". */ GCRY_PK_ECDSA, FLAG_SIGN, { "(private-key\n" " (ecc\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)\n" " (d #00D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D#)))\n", "(public-key\n" " (ecdsa\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)))\n", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } }, { /* ECDSA test with the key algorithms given as "ecc". */ GCRY_PK_ECDSA, FLAG_SIGN, { "(private-key\n" " (ecc\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)\n" " (d #00D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D#)))\n", "(public-key\n" " (ecc\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)))\n", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } }, { /* ECDSA test 256 bit. */ GCRY_PK_ECDSA, FLAG_SIGN, { "(private-key\n" " (ecc\n" " (curve nistp256)\n" " (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2B" " EB6644D3609FC781B71F9A8072F58CB66AE2F89BB1245187" " 3ABF7D91F9E1FBF96BF2F70E73AAC9A283#)\n" " (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F74" " 4715E1D5BBE70378#)))\n", "(public-key\n" " (ecc\n" " (curve nistp256)\n" " (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2B" " EB6644D3609FC781B71F9A8072F58CB66AE2F89BB1245187" " 3ABF7D91F9E1FBF96BF2F70E73AAC9A283#)))\n", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } }, { /* GOST R 34.10-2001/2012 test 256 bit. */ GCRY_PK_ECDSA, FLAG_SIGN, { "(private-key\n" " (ecc\n" " (curve GOST2001-test)\n" " (q #047F2B49E270DB6D90D8595BEC458B50C58585BA1D4E9B78" " 8F6689DBD8E56FD80B26F1B489D6701DD185C8413A977B3C" " BBAF64D1C593D26627DFFB101A87FF77DA#)\n" " (d #7A929ADE789BB9BE10ED359DD39A72C11B60961F49397EEE" " 1D19CE9891EC3B28#)))\n", "(public-key\n" " (ecc\n" " (curve GOST2001-test)\n" " (q #047F2B49E270DB6D90D8595BEC458B50C58585BA1D4E9B78" " 8F6689DBD8E56FD80B26F1B489D6701DD185C8413A977B3C" " BBAF64D1C593D26627DFFB101A87FF77DA#)))\n", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } }, { /* GOST R 34.10-2012 test 512 bit. */ GCRY_PK_ECDSA, FLAG_SIGN, { "(private-key\n" " (ecc\n" " (curve GOST2012-test)\n" " (q #04115DC5BC96760C7B48598D8AB9E740D4C4A85A65BE33C1" " 815B5C320C854621DD5A515856D13314AF69BC5B924C8B" " 4DDFF75C45415C1D9DD9DD33612CD530EFE137C7C90CD4" " 0B0F5621DC3AC1B751CFA0E2634FA0503B3D52639F5D7F" " B72AFD61EA199441D943FFE7F0C70A2759A3CDB84C114E" " 1F9339FDF27F35ECA93677BEEC#)\n" " (d #0BA6048AADAE241BA40936D47756D7C93091A0E851466970" " 0EE7508E508B102072E8123B2200A0563322DAD2827E2714" " A2636B7BFD18AADFC62967821FA18DD4#)))\n", "(public-key\n" " (ecc\n" " (curve GOST2012-test)\n" " (q #04115DC5BC96760C7B48598D8AB9E740D4C4A85A65BE33C1" " 815B5C320C854621DD5A515856D13314AF69BC5B924C8B" " 4DDFF75C45415C1D9DD9DD33612CD530EFE137C7C90CD4" " 0B0F5621DC3AC1B751CFA0E2634FA0503B3D52639F5D7F" " B72AFD61EA199441D943FFE7F0C70A2759A3CDB84C114E" " 1F9339FDF27F35ECA93677BEEC#)))\n" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } }, { /* secp256k1 test 256 bit. */ GCRY_PK_ECDSA, FLAG_SIGN, { "(private-key\n" " (ecc\n" " (curve secp256k1)\n" " (q #0439A36013301597DAEF41FBE593A02CC513D0B55527EC2D" " F1050E2E8FF49C85C23CBE7DED0E7CE6A594896B8F62888F" " DBC5C8821305E2EA42BF01E37300116281#)\n" " (d #E8F32E723DECF4051AEFAC8E2C93C9C5B214313817CDB01A" " 1494B917C8436B35#)))\n", "(public-key\n" " (ecc\n" " (curve secp256k1)\n" " (q #0439A36013301597DAEF41FBE593A02CC513D0B55527EC2D" " F1050E2E8FF49C85C23CBE7DED0E7CE6A594896B8F62888F" " DBC5C8821305E2EA42BF01E37300116281#)))\n" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } } }; int i; if (verbose) fprintf (stderr, "Starting public key checks.\n"); for (i = 0; i < sizeof (pubkeys) / sizeof (*pubkeys); i++) if (pubkeys[i].id) { if (gcry_pk_test_algo (pubkeys[i].id) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", pubkeys[i].id); continue; } check_one_pubkey (i, pubkeys[i]); } if (verbose) fprintf (stderr, "Completed public key checks.\n"); if (verbose) fprintf (stderr, "Starting additional public key checks.\n"); for (i = 0; i < sizeof (pubkeys) / sizeof (*pubkeys); i++) if (pubkeys[i].id) { if (gcry_pk_test_algo (pubkeys[i].id) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", pubkeys[i].id); continue; } check_one_pubkey_new (i); } if (verbose) fprintf (stderr, "Completed additional public key checks.\n"); } int main (int argc, char **argv) { gpg_error_t err; int last_argc = -1; int use_fips = 0; int selftest_only = 0; int pubkey_only = 0; int cipher_modes_only = 0; int loop = 0; unsigned int loopcount = 0; if (argc) { argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } else if (!strcmp (*argv, "--verbose")) { verbose++; argc--; argv++; } else if (!strcmp (*argv, "--debug")) { verbose = debug = 1; argc--; argv++; } else if (!strcmp (*argv, "--fips")) { use_fips = 1; argc--; argv++; } else if (!strcmp (*argv, "--selftest")) { selftest_only = 1; verbose += 2; argc--; argv++; } else if (!strcmp (*argv, "--pubkey")) { pubkey_only = 1; argc--; argv++; } else if (!strcmp (*argv, "--cipher-modes")) { cipher_modes_only = 1; argc--; argv++; } else if (!strcmp (*argv, "--die")) { die_on_error = 1; argc--; argv++; } else if (!strcmp (*argv, "--loop")) { argc--; argv++; if (argc) { loop = atoi (*argv); argc--; argv++; } } else if (!strcmp (*argv, "--disable-hwf")) { argc--; argv++; if (argc) { if (gcry_control (GCRYCTL_DISABLE_HWF, *argv, NULL)) fprintf (stderr, PGM ": unknown hardware feature `%s' - option ignored\n", *argv); argc--; argv++; } } } xgcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); if (use_fips) xgcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); /* Check that we test exactly our version - including the patchlevel. */ if (strcmp (GCRYPT_VERSION, gcry_check_version (NULL))) die ("version mismatch; pgm=%s, library=%s\n", GCRYPT_VERSION,gcry_check_version (NULL)); if ( gcry_fips_mode_active () ) in_fips_mode = 1; if (!in_fips_mode) xgcry_control (GCRYCTL_DISABLE_SECMEM, 0); if (verbose) gcry_set_progress_handler (progress_handler, NULL); xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); /* No valuable keys are create, so we can speed up our RNG. */ xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); do { if (pubkey_only) check_pubkey (); else if (cipher_modes_only) { check_ciphers (); check_cipher_modes (); } else if (!selftest_only) { check_ciphers (); check_cipher_modes (); check_bulk_cipher_modes (); check_digests (); check_hmac (); check_mac (); check_pubkey (); } loopcount++; if (loop) { fprintf (stderr, "Test iteration %u completed.\n", loopcount); if (loop != -1) loop--; } } while (loop); if (in_fips_mode && !selftest_only) { /* If we are in fips mode do some more tests. */ gcry_md_hd_t md; /* First trigger a self-test. */ xgcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) fail ("not in operational state after self-test\n"); /* Get us into the error state. */ err = gcry_md_open (&md, GCRY_MD_SHA1, 0); if (err) fail ("failed to open SHA-1 hash context: %s\n", gpg_strerror (err)); else { err = gcry_md_enable (md, GCRY_MD_SHA256); if (err) fail ("failed to add SHA-256 hash context: %s\n", gpg_strerror (err)); else { /* gcry_md_get_algo is only defined for a context with just one digest algorithm. With our setup it should put the oibrary intoerror state. */ fputs ("Note: Two lines with error messages follow " "- this is expected\n", stderr); gcry_md_get_algo (md); gcry_md_close (md); if (gcry_control (GCRYCTL_OPERATIONAL_P, 0)) fail ("expected error state but still in operational state\n"); else { /* Now run a self-test and to get back into operational state. */ xgcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) fail ("did not reach operational after error " "and self-test\n"); } } } } else { /* If in standard mode, run selftests. */ if (gcry_control (GCRYCTL_SELFTEST, 0)) fail ("running self-test failed\n"); } if (verbose) fprintf (stderr, "\nAll tests completed. Errors: %i\n", error_count); if (in_fips_mode && !gcry_fips_mode_active ()) fprintf (stderr, "FIPS mode is not anymore active\n"); return error_count ? 1 : 0; }