diff --git a/cipher/Makefile.am b/cipher/Makefile.am index a6171bf5..250b229e 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -1,279 +1,278 @@ # Makefile for cipher modules # Copyright (C) 1998, 1999, 2000, 2001, 2002, # 2003, 2009 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 . # Process this file with automake to produce Makefile.in # Need to include ../src in addition to top_srcdir because gcrypt.h is # a built header. AM_CPPFLAGS = -I../src -I$(top_srcdir)/src -I../mpi -I$(top_srcdir)/mpi AM_CFLAGS = $(GPG_ERROR_CFLAGS) AM_CCASFLAGS = $(NOEXECSTACK_FLAGS) EXTRA_DIST = gost-s-box.c CLEANFILES = gost-s-box$(EXEEXT_FOR_BUILD) DISTCLEANFILES = gost-sb.h noinst_LTLIBRARIES = libcipher.la GCRYPT_MODULES = @GCRYPT_CIPHERS@ @GCRYPT_PUBKEY_CIPHERS@ \ @GCRYPT_DIGESTS@ @GCRYPT_KDFS@ libcipher_la_DEPENDENCIES = $(GCRYPT_MODULES) libcipher_la_LIBADD = $(GCRYPT_MODULES) libcipher_la_SOURCES = \ cipher.c cipher-internal.h \ cipher-cbc.c \ cipher-cfb.c \ cipher-ofb.c \ cipher-ctr.c \ cipher-aeswrap.c \ cipher-ccm.c \ cipher-cmac.c \ cipher-gcm.c \ cipher-poly1305.c \ cipher-ocb.c \ cipher-xts.c \ cipher-eax.c \ cipher-siv.c \ cipher-gcm-siv.c \ - cipher-selftest.c cipher-selftest.h \ pubkey.c pubkey-internal.h pubkey-util.c \ md.c \ mac.c mac-internal.h \ mac-hmac.c mac-cmac.c mac-gmac.c mac-poly1305.c \ poly1305.c poly1305-internal.h \ kdf.c kdf-internal.h \ bithelp.h \ bufhelp.h \ primegen.c \ hash-common.c hash-common.h \ dsa-common.c rsa-common.c \ sha1.h EXTRA_libcipher_la_SOURCES = \ asm-common-aarch64.h \ asm-common-amd64.h \ asm-common-s390x.h \ asm-inline-s390x.h \ asm-poly1305-aarch64.h \ asm-poly1305-amd64.h \ asm-poly1305-s390x.h \ arcfour.c arcfour-amd64.S \ blowfish.c blowfish-amd64.S blowfish-arm.S \ cast5.c cast5-amd64.S cast5-arm.S \ chacha20.c chacha20-amd64-ssse3.S chacha20-amd64-avx2.S \ chacha20-amd64-avx512.S chacha20-armv7-neon.S chacha20-aarch64.S \ chacha20-ppc.c chacha20-s390x.S \ cipher-gcm-ppc.c cipher-gcm-intel-pclmul.c cipher-gcm-armv7-neon.S \ cipher-gcm-armv8-aarch32-ce.S cipher-gcm-armv8-aarch64-ce.S \ crc.c crc-intel-pclmul.c crc-armv8-ce.c \ crc-armv8-aarch64-ce.S \ crc-ppc.c \ des.c des-amd64.S \ dsa.c \ elgamal.c \ ecc.c ecc-curves.c ecc-misc.c ecc-common.h \ ecc-ecdh.c ecc-ecdsa.c ecc-eddsa.c ecc-gost.c ecc-sm2.c \ idea.c \ gost28147.c gost.h \ gostr3411-94.c \ md4.c \ md5.c \ poly1305-s390x.S poly1305-amd64-avx512.S \ rijndael.c rijndael-internal.h rijndael-tables.h \ rijndael-aesni.c rijndael-padlock.c \ rijndael-amd64.S rijndael-arm.S \ rijndael-ssse3-amd64.c rijndael-ssse3-amd64-asm.S \ rijndael-vaes.c rijndael-vaes-avx2-amd64.S \ rijndael-armv8-ce.c rijndael-armv8-aarch32-ce.S \ rijndael-armv8-aarch64-ce.S rijndael-aarch64.S \ rijndael-ppc.c rijndael-ppc9le.c \ rijndael-p10le.c rijndael-gcm-p10le.s \ rijndael-ppc-common.h rijndael-ppc-functions.h \ rijndael-s390x.c \ rmd160.c \ rsa.c \ salsa20.c salsa20-amd64.S salsa20-armv7-neon.S \ scrypt.c \ seed.c \ serpent.c serpent-sse2-amd64.S \ sm4.c sm4-aesni-avx-amd64.S sm4-aesni-avx2-amd64.S sm4-aarch64.S \ sm4-armv8-aarch64-ce.S sm4-gfni-avx2-amd64.S \ serpent-avx2-amd64.S serpent-armv7-neon.S \ sha1.c sha1-ssse3-amd64.S sha1-avx-amd64.S sha1-avx-bmi2-amd64.S \ sha1-avx2-bmi2-amd64.S sha1-armv7-neon.S sha1-armv8-aarch32-ce.S \ sha1-armv8-aarch64-ce.S sha1-intel-shaext.c \ sha256.c sha256-ssse3-amd64.S sha256-avx-amd64.S \ sha256-avx2-bmi2-amd64.S \ sha256-armv8-aarch32-ce.S sha256-armv8-aarch64-ce.S \ sha256-intel-shaext.c sha256-ppc.c \ sha512.c sha512-ssse3-amd64.S sha512-avx-amd64.S \ sha512-avx2-bmi2-amd64.S sha512-avx512-amd64.S \ sha512-armv7-neon.S sha512-arm.S \ sha512-ppc.c sha512-ssse3-i386.c \ sm3.c sm3-avx-bmi2-amd64.S sm3-aarch64.S sm3-armv8-aarch64-ce.S \ keccak.c keccak_permute_32.h keccak_permute_64.h keccak-armv7-neon.S \ stribog.c \ tiger.c \ whirlpool.c whirlpool-sse2-amd64.S \ twofish.c twofish-amd64.S twofish-arm.S twofish-aarch64.S \ twofish-avx2-amd64.S \ rfc2268.c \ camellia.c camellia.h camellia-glue.c camellia-aesni-avx-amd64.S \ camellia-aesni-avx2-amd64.h \ camellia-gfni-avx2-amd64.S camellia-gfni-avx512-amd64.S \ camellia-vaes-avx2-amd64.S camellia-aesni-avx2-amd64.S \ camellia-arm.S camellia-aarch64.S \ blake2.c \ blake2b-amd64-avx2.S blake2s-amd64-avx.S gost28147.lo: gost-sb.h gost-sb.h: gost-s-box$(EXEEXT_FOR_BUILD) ./gost-s-box$(EXEEXT_FOR_BUILD) $@ gost-s-box$(EXEEXT_FOR_BUILD): gost-s-box.c $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) \ $(CPPFLAGS_FOR_BUILD) -o $@ $(srcdir)/gost-s-box.c if ENABLE_O_FLAG_MUNGING o_flag_munging = sed -e 's/-O\([2-9sg][2-9sg]*\)/-O1/' -e 's/-Ofast/-O1/g' else o_flag_munging = cat endif # We need to lower the optimization for this module. tiger.o: $(srcdir)/tiger.c Makefile `echo $(COMPILE) -c $< | $(o_flag_munging) ` tiger.lo: $(srcdir)/tiger.c Makefile `echo $(LTCOMPILE) -c $< | $(o_flag_munging) ` # We need to disable instrumentation for these modules as they use cc as # thin assembly front-end and do not tolerate in-between function calls # inserted by compiler as those functions may clobber the XMM registers. if ENABLE_INSTRUMENTATION_MUNGING instrumentation_munging = sed \ -e 's/-fsanitize[=,\-][=,a-z,A-Z,0-9,\,,\-]*//g' \ -e 's/-fprofile[=,\-][=,a-z,A-Z,0-9,\,,\-]*//g' \ -e 's/-fcoverage[=,\-][=,a-z,A-Z,0-9,\,,\-]*//g' else instrumentation_munging = cat endif rijndael-aesni.o: $(srcdir)/rijndael-aesni.c Makefile `echo $(COMPILE) -c $< | $(instrumentation_munging) ` rijndael-aesni.lo: $(srcdir)/rijndael-aesni.c Makefile `echo $(LTCOMPILE) -c $< | $(instrumentation_munging) ` rijndael-ssse3-amd64.o: $(srcdir)/rijndael-ssse3-amd64.c Makefile `echo $(COMPILE) -c $< | $(instrumentation_munging) ` rijndael-ssse3-amd64.lo: $(srcdir)/rijndael-ssse3-amd64.c Makefile `echo $(LTCOMPILE) -c $< | $(instrumentation_munging) ` cipher-gcm-intel-pclmul.o: $(srcdir)/cipher-gcm-intel-pclmul.c Makefile `echo $(COMPILE) -c $< | $(instrumentation_munging) ` cipher-gcm-intel-pclmul.lo: $(srcdir)/cipher-gcm-intel-pclmul.c Makefile `echo $(LTCOMPILE) -c $< | $(instrumentation_munging) ` sha1-intel-shaext.o: $(srcdir)/sha1-intel-shaext.c Makefile `echo $(COMPILE) -c $< | $(instrumentation_munging) ` sha1-intel-shaext.lo: $(srcdir)/sha1-intel-shaext.c Makefile `echo $(LTCOMPILE) -c $< | $(instrumentation_munging) ` sha256-intel-shaext.o: $(srcdir)/sha256-intel-shaext.c Makefile `echo $(COMPILE) -c $< | $(instrumentation_munging) ` sha256-intel-shaext.lo: $(srcdir)/sha256-intel-shaext.c Makefile `echo $(LTCOMPILE) -c $< | $(instrumentation_munging) ` sha256-ssse3-i386.o: $(srcdir)/sha256-ssse3-i386.c Makefile `echo $(COMPILE) -c $< | $(instrumentation_munging) ` sha256-ssse3-i386.lo: $(srcdir)/sha256-ssse3-i386.c Makefile `echo $(LTCOMPILE) -c $< | $(instrumentation_munging) ` crc-intel-pclmul.o: $(srcdir)/crc-intel-pclmul.c Makefile `echo $(COMPILE) -c $< | $(instrumentation_munging) ` crc-intel-pclmul.lo: $(srcdir)/crc-intel-pclmul.c Makefile `echo $(LTCOMPILE) -c $< | $(instrumentation_munging) ` if ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS ppc_vcrypto_cflags = -O2 -maltivec -mvsx -mcrypto else ppc_vcrypto_cflags = endif rijndael-ppc.o: $(srcdir)/rijndael-ppc.c Makefile `echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` rijndael-ppc.lo: $(srcdir)/rijndael-ppc.c Makefile `echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` rijndael-ppc9le.o: $(srcdir)/rijndael-ppc9le.c Makefile `echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` rijndael-ppc9le.lo: $(srcdir)/rijndael-ppc9le.c Makefile `echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` rijndael-p10le.o: $(srcdir)/rijndael-p10le.c Makefile `echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` rijndael-p10le.lo: $(srcdir)/rijndael-p10le.c Makefile `echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` sha256-ppc.o: $(srcdir)/sha256-ppc.c Makefile `echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` sha256-ppc.lo: $(srcdir)/sha256-ppc.c Makefile `echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` sha512-ppc.o: $(srcdir)/sha512-ppc.c Makefile `echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` sha512-ppc.lo: $(srcdir)/sha512-ppc.c Makefile `echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` chacha20-ppc.o: $(srcdir)/chacha20-ppc.c Makefile `echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` chacha20-ppc.lo: $(srcdir)/chacha20-ppc.c Makefile `echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` crc-ppc.o: $(srcdir)/crc-ppc.c Makefile `echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` crc-ppc.lo: $(srcdir)/crc-ppc.c Makefile `echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` cipher-gcm-ppc.o: $(srcdir)/cipher-gcm-ppc.c Makefile `echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` cipher-gcm-ppc.lo: $(srcdir)/cipher-gcm-ppc.c Makefile `echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< | $(instrumentation_munging) ` diff --git a/cipher/blowfish.c b/cipher/blowfish.c index 7b001306..1b11d718 100644 --- a/cipher/blowfish.c +++ b/cipher/blowfish.c @@ -1,1142 +1,1089 @@ /* blowfish.c - Blowfish encryption * Copyright (C) 1998, 2001, 2002, 2003 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * For a description of the algorithm, see: * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996. * ISBN 0-471-11709-9. Pages 336 ff. */ /* Test values: * key "abcdefghijklmnopqrstuvwxyz"; * plain "BLOWFISH" * cipher 32 4E D0 FE F4 13 A2 03 * */ #include #include #include #include #include "types.h" #include "g10lib.h" #include "cipher.h" #include "bufhelp.h" #include "cipher-internal.h" -#include "cipher-selftest.h" #define BLOWFISH_BLOCKSIZE 8 #define BLOWFISH_KEY_MIN_BITS 8 #define BLOWFISH_KEY_MAX_BITS 576 /* 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_ARM_ASM indicates whether to use ARM assembly code. */ #undef USE_ARM_ASM #if defined(__ARMEL__) # if defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) # define USE_ARM_ASM 1 # endif #endif typedef struct { u32 s0[256]; u32 s1[256]; u32 s2[256]; u32 s3[256]; u32 p[16+2]; } BLOWFISH_context; static gcry_err_code_t bf_setkey (void *c, const byte *key, unsigned keylen, cipher_bulk_ops_t *bulk_ops); static unsigned int encrypt_block (void *bc, byte *outbuf, const byte *inbuf); static unsigned int decrypt_block (void *bc, byte *outbuf, const byte *inbuf); /* precomputed S boxes */ static const u32 ks0[256] = { 0xD1310BA6,0x98DFB5AC,0x2FFD72DB,0xD01ADFB7,0xB8E1AFED,0x6A267E96, 0xBA7C9045,0xF12C7F99,0x24A19947,0xB3916CF7,0x0801F2E2,0x858EFC16, 0x636920D8,0x71574E69,0xA458FEA3,0xF4933D7E,0x0D95748F,0x728EB658, 0x718BCD58,0x82154AEE,0x7B54A41D,0xC25A59B5,0x9C30D539,0x2AF26013, 0xC5D1B023,0x286085F0,0xCA417918,0xB8DB38EF,0x8E79DCB0,0x603A180E, 0x6C9E0E8B,0xB01E8A3E,0xD71577C1,0xBD314B27,0x78AF2FDA,0x55605C60, 0xE65525F3,0xAA55AB94,0x57489862,0x63E81440,0x55CA396A,0x2AAB10B6, 0xB4CC5C34,0x1141E8CE,0xA15486AF,0x7C72E993,0xB3EE1411,0x636FBC2A, 0x2BA9C55D,0x741831F6,0xCE5C3E16,0x9B87931E,0xAFD6BA33,0x6C24CF5C, 0x7A325381,0x28958677,0x3B8F4898,0x6B4BB9AF,0xC4BFE81B,0x66282193, 0x61D809CC,0xFB21A991,0x487CAC60,0x5DEC8032,0xEF845D5D,0xE98575B1, 0xDC262302,0xEB651B88,0x23893E81,0xD396ACC5,0x0F6D6FF3,0x83F44239, 0x2E0B4482,0xA4842004,0x69C8F04A,0x9E1F9B5E,0x21C66842,0xF6E96C9A, 0x670C9C61,0xABD388F0,0x6A51A0D2,0xD8542F68,0x960FA728,0xAB5133A3, 0x6EEF0B6C,0x137A3BE4,0xBA3BF050,0x7EFB2A98,0xA1F1651D,0x39AF0176, 0x66CA593E,0x82430E88,0x8CEE8619,0x456F9FB4,0x7D84A5C3,0x3B8B5EBE, 0xE06F75D8,0x85C12073,0x401A449F,0x56C16AA6,0x4ED3AA62,0x363F7706, 0x1BFEDF72,0x429B023D,0x37D0D724,0xD00A1248,0xDB0FEAD3,0x49F1C09B, 0x075372C9,0x80991B7B,0x25D479D8,0xF6E8DEF7,0xE3FE501A,0xB6794C3B, 0x976CE0BD,0x04C006BA,0xC1A94FB6,0x409F60C4,0x5E5C9EC2,0x196A2463, 0x68FB6FAF,0x3E6C53B5,0x1339B2EB,0x3B52EC6F,0x6DFC511F,0x9B30952C, 0xCC814544,0xAF5EBD09,0xBEE3D004,0xDE334AFD,0x660F2807,0x192E4BB3, 0xC0CBA857,0x45C8740F,0xD20B5F39,0xB9D3FBDB,0x5579C0BD,0x1A60320A, 0xD6A100C6,0x402C7279,0x679F25FE,0xFB1FA3CC,0x8EA5E9F8,0xDB3222F8, 0x3C7516DF,0xFD616B15,0x2F501EC8,0xAD0552AB,0x323DB5FA,0xFD238760, 0x53317B48,0x3E00DF82,0x9E5C57BB,0xCA6F8CA0,0x1A87562E,0xDF1769DB, 0xD542A8F6,0x287EFFC3,0xAC6732C6,0x8C4F5573,0x695B27B0,0xBBCA58C8, 0xE1FFA35D,0xB8F011A0,0x10FA3D98,0xFD2183B8,0x4AFCB56C,0x2DD1D35B, 0x9A53E479,0xB6F84565,0xD28E49BC,0x4BFB9790,0xE1DDF2DA,0xA4CB7E33, 0x62FB1341,0xCEE4C6E8,0xEF20CADA,0x36774C01,0xD07E9EFE,0x2BF11FB4, 0x95DBDA4D,0xAE909198,0xEAAD8E71,0x6B93D5A0,0xD08ED1D0,0xAFC725E0, 0x8E3C5B2F,0x8E7594B7,0x8FF6E2FB,0xF2122B64,0x8888B812,0x900DF01C, 0x4FAD5EA0,0x688FC31C,0xD1CFF191,0xB3A8C1AD,0x2F2F2218,0xBE0E1777, 0xEA752DFE,0x8B021FA1,0xE5A0CC0F,0xB56F74E8,0x18ACF3D6,0xCE89E299, 0xB4A84FE0,0xFD13E0B7,0x7CC43B81,0xD2ADA8D9,0x165FA266,0x80957705, 0x93CC7314,0x211A1477,0xE6AD2065,0x77B5FA86,0xC75442F5,0xFB9D35CF, 0xEBCDAF0C,0x7B3E89A0,0xD6411BD3,0xAE1E7E49,0x00250E2D,0x2071B35E, 0x226800BB,0x57B8E0AF,0x2464369B,0xF009B91E,0x5563911D,0x59DFA6AA, 0x78C14389,0xD95A537F,0x207D5BA2,0x02E5B9C5,0x83260376,0x6295CFA9, 0x11C81968,0x4E734A41,0xB3472DCA,0x7B14A94A,0x1B510052,0x9A532915, 0xD60F573F,0xBC9BC6E4,0x2B60A476,0x81E67400,0x08BA6FB5,0x571BE91F, 0xF296EC6B,0x2A0DD915,0xB6636521,0xE7B9F9B6,0xFF34052E,0xC5855664, 0x53B02D5D,0xA99F8FA1,0x08BA4799,0x6E85076A }; static const u32 ks1[256] = { 0x4B7A70E9,0xB5B32944,0xDB75092E,0xC4192623,0xAD6EA6B0,0x49A7DF7D, 0x9CEE60B8,0x8FEDB266,0xECAA8C71,0x699A17FF,0x5664526C,0xC2B19EE1, 0x193602A5,0x75094C29,0xA0591340,0xE4183A3E,0x3F54989A,0x5B429D65, 0x6B8FE4D6,0x99F73FD6,0xA1D29C07,0xEFE830F5,0x4D2D38E6,0xF0255DC1, 0x4CDD2086,0x8470EB26,0x6382E9C6,0x021ECC5E,0x09686B3F,0x3EBAEFC9, 0x3C971814,0x6B6A70A1,0x687F3584,0x52A0E286,0xB79C5305,0xAA500737, 0x3E07841C,0x7FDEAE5C,0x8E7D44EC,0x5716F2B8,0xB03ADA37,0xF0500C0D, 0xF01C1F04,0x0200B3FF,0xAE0CF51A,0x3CB574B2,0x25837A58,0xDC0921BD, 0xD19113F9,0x7CA92FF6,0x94324773,0x22F54701,0x3AE5E581,0x37C2DADC, 0xC8B57634,0x9AF3DDA7,0xA9446146,0x0FD0030E,0xECC8C73E,0xA4751E41, 0xE238CD99,0x3BEA0E2F,0x3280BBA1,0x183EB331,0x4E548B38,0x4F6DB908, 0x6F420D03,0xF60A04BF,0x2CB81290,0x24977C79,0x5679B072,0xBCAF89AF, 0xDE9A771F,0xD9930810,0xB38BAE12,0xDCCF3F2E,0x5512721F,0x2E6B7124, 0x501ADDE6,0x9F84CD87,0x7A584718,0x7408DA17,0xBC9F9ABC,0xE94B7D8C, 0xEC7AEC3A,0xDB851DFA,0x63094366,0xC464C3D2,0xEF1C1847,0x3215D908, 0xDD433B37,0x24C2BA16,0x12A14D43,0x2A65C451,0x50940002,0x133AE4DD, 0x71DFF89E,0x10314E55,0x81AC77D6,0x5F11199B,0x043556F1,0xD7A3C76B, 0x3C11183B,0x5924A509,0xF28FE6ED,0x97F1FBFA,0x9EBABF2C,0x1E153C6E, 0x86E34570,0xEAE96FB1,0x860E5E0A,0x5A3E2AB3,0x771FE71C,0x4E3D06FA, 0x2965DCB9,0x99E71D0F,0x803E89D6,0x5266C825,0x2E4CC978,0x9C10B36A, 0xC6150EBA,0x94E2EA78,0xA5FC3C53,0x1E0A2DF4,0xF2F74EA7,0x361D2B3D, 0x1939260F,0x19C27960,0x5223A708,0xF71312B6,0xEBADFE6E,0xEAC31F66, 0xE3BC4595,0xA67BC883,0xB17F37D1,0x018CFF28,0xC332DDEF,0xBE6C5AA5, 0x65582185,0x68AB9802,0xEECEA50F,0xDB2F953B,0x2AEF7DAD,0x5B6E2F84, 0x1521B628,0x29076170,0xECDD4775,0x619F1510,0x13CCA830,0xEB61BD96, 0x0334FE1E,0xAA0363CF,0xB5735C90,0x4C70A239,0xD59E9E0B,0xCBAADE14, 0xEECC86BC,0x60622CA7,0x9CAB5CAB,0xB2F3846E,0x648B1EAF,0x19BDF0CA, 0xA02369B9,0x655ABB50,0x40685A32,0x3C2AB4B3,0x319EE9D5,0xC021B8F7, 0x9B540B19,0x875FA099,0x95F7997E,0x623D7DA8,0xF837889A,0x97E32D77, 0x11ED935F,0x16681281,0x0E358829,0xC7E61FD6,0x96DEDFA1,0x7858BA99, 0x57F584A5,0x1B227263,0x9B83C3FF,0x1AC24696,0xCDB30AEB,0x532E3054, 0x8FD948E4,0x6DBC3128,0x58EBF2EF,0x34C6FFEA,0xFE28ED61,0xEE7C3C73, 0x5D4A14D9,0xE864B7E3,0x42105D14,0x203E13E0,0x45EEE2B6,0xA3AAABEA, 0xDB6C4F15,0xFACB4FD0,0xC742F442,0xEF6ABBB5,0x654F3B1D,0x41CD2105, 0xD81E799E,0x86854DC7,0xE44B476A,0x3D816250,0xCF62A1F2,0x5B8D2646, 0xFC8883A0,0xC1C7B6A3,0x7F1524C3,0x69CB7492,0x47848A0B,0x5692B285, 0x095BBF00,0xAD19489D,0x1462B174,0x23820E00,0x58428D2A,0x0C55F5EA, 0x1DADF43E,0x233F7061,0x3372F092,0x8D937E41,0xD65FECF1,0x6C223BDB, 0x7CDE3759,0xCBEE7460,0x4085F2A7,0xCE77326E,0xA6078084,0x19F8509E, 0xE8EFD855,0x61D99735,0xA969A7AA,0xC50C06C2,0x5A04ABFC,0x800BCADC, 0x9E447A2E,0xC3453484,0xFDD56705,0x0E1E9EC9,0xDB73DBD3,0x105588CD, 0x675FDA79,0xE3674340,0xC5C43465,0x713E38D8,0x3D28F89E,0xF16DFF20, 0x153E21E7,0x8FB03D4A,0xE6E39F2B,0xDB83ADF7 }; static const u32 ks2[256] = { 0xE93D5A68,0x948140F7,0xF64C261C,0x94692934,0x411520F7,0x7602D4F7, 0xBCF46B2E,0xD4A20068,0xD4082471,0x3320F46A,0x43B7D4B7,0x500061AF, 0x1E39F62E,0x97244546,0x14214F74,0xBF8B8840,0x4D95FC1D,0x96B591AF, 0x70F4DDD3,0x66A02F45,0xBFBC09EC,0x03BD9785,0x7FAC6DD0,0x31CB8504, 0x96EB27B3,0x55FD3941,0xDA2547E6,0xABCA0A9A,0x28507825,0x530429F4, 0x0A2C86DA,0xE9B66DFB,0x68DC1462,0xD7486900,0x680EC0A4,0x27A18DEE, 0x4F3FFEA2,0xE887AD8C,0xB58CE006,0x7AF4D6B6,0xAACE1E7C,0xD3375FEC, 0xCE78A399,0x406B2A42,0x20FE9E35,0xD9F385B9,0xEE39D7AB,0x3B124E8B, 0x1DC9FAF7,0x4B6D1856,0x26A36631,0xEAE397B2,0x3A6EFA74,0xDD5B4332, 0x6841E7F7,0xCA7820FB,0xFB0AF54E,0xD8FEB397,0x454056AC,0xBA489527, 0x55533A3A,0x20838D87,0xFE6BA9B7,0xD096954B,0x55A867BC,0xA1159A58, 0xCCA92963,0x99E1DB33,0xA62A4A56,0x3F3125F9,0x5EF47E1C,0x9029317C, 0xFDF8E802,0x04272F70,0x80BB155C,0x05282CE3,0x95C11548,0xE4C66D22, 0x48C1133F,0xC70F86DC,0x07F9C9EE,0x41041F0F,0x404779A4,0x5D886E17, 0x325F51EB,0xD59BC0D1,0xF2BCC18F,0x41113564,0x257B7834,0x602A9C60, 0xDFF8E8A3,0x1F636C1B,0x0E12B4C2,0x02E1329E,0xAF664FD1,0xCAD18115, 0x6B2395E0,0x333E92E1,0x3B240B62,0xEEBEB922,0x85B2A20E,0xE6BA0D99, 0xDE720C8C,0x2DA2F728,0xD0127845,0x95B794FD,0x647D0862,0xE7CCF5F0, 0x5449A36F,0x877D48FA,0xC39DFD27,0xF33E8D1E,0x0A476341,0x992EFF74, 0x3A6F6EAB,0xF4F8FD37,0xA812DC60,0xA1EBDDF8,0x991BE14C,0xDB6E6B0D, 0xC67B5510,0x6D672C37,0x2765D43B,0xDCD0E804,0xF1290DC7,0xCC00FFA3, 0xB5390F92,0x690FED0B,0x667B9FFB,0xCEDB7D9C,0xA091CF0B,0xD9155EA3, 0xBB132F88,0x515BAD24,0x7B9479BF,0x763BD6EB,0x37392EB3,0xCC115979, 0x8026E297,0xF42E312D,0x6842ADA7,0xC66A2B3B,0x12754CCC,0x782EF11C, 0x6A124237,0xB79251E7,0x06A1BBE6,0x4BFB6350,0x1A6B1018,0x11CAEDFA, 0x3D25BDD8,0xE2E1C3C9,0x44421659,0x0A121386,0xD90CEC6E,0xD5ABEA2A, 0x64AF674E,0xDA86A85F,0xBEBFE988,0x64E4C3FE,0x9DBC8057,0xF0F7C086, 0x60787BF8,0x6003604D,0xD1FD8346,0xF6381FB0,0x7745AE04,0xD736FCCC, 0x83426B33,0xF01EAB71,0xB0804187,0x3C005E5F,0x77A057BE,0xBDE8AE24, 0x55464299,0xBF582E61,0x4E58F48F,0xF2DDFDA2,0xF474EF38,0x8789BDC2, 0x5366F9C3,0xC8B38E74,0xB475F255,0x46FCD9B9,0x7AEB2661,0x8B1DDF84, 0x846A0E79,0x915F95E2,0x466E598E,0x20B45770,0x8CD55591,0xC902DE4C, 0xB90BACE1,0xBB8205D0,0x11A86248,0x7574A99E,0xB77F19B6,0xE0A9DC09, 0x662D09A1,0xC4324633,0xE85A1F02,0x09F0BE8C,0x4A99A025,0x1D6EFE10, 0x1AB93D1D,0x0BA5A4DF,0xA186F20F,0x2868F169,0xDCB7DA83,0x573906FE, 0xA1E2CE9B,0x4FCD7F52,0x50115E01,0xA70683FA,0xA002B5C4,0x0DE6D027, 0x9AF88C27,0x773F8641,0xC3604C06,0x61A806B5,0xF0177A28,0xC0F586E0, 0x006058AA,0x30DC7D62,0x11E69ED7,0x2338EA63,0x53C2DD94,0xC2C21634, 0xBBCBEE56,0x90BCB6DE,0xEBFC7DA1,0xCE591D76,0x6F05E409,0x4B7C0188, 0x39720A3D,0x7C927C24,0x86E3725F,0x724D9DB9,0x1AC15BB4,0xD39EB8FC, 0xED545578,0x08FCA5B5,0xD83D7CD3,0x4DAD0FC4,0x1E50EF5E,0xB161E6F8, 0xA28514D9,0x6C51133C,0x6FD5C7E7,0x56E14EC4,0x362ABFCE,0xDDC6C837, 0xD79A3234,0x92638212,0x670EFA8E,0x406000E0 }; static const u32 ks3[256] = { 0x3A39CE37,0xD3FAF5CF,0xABC27737,0x5AC52D1B,0x5CB0679E,0x4FA33742, 0xD3822740,0x99BC9BBE,0xD5118E9D,0xBF0F7315,0xD62D1C7E,0xC700C47B, 0xB78C1B6B,0x21A19045,0xB26EB1BE,0x6A366EB4,0x5748AB2F,0xBC946E79, 0xC6A376D2,0x6549C2C8,0x530FF8EE,0x468DDE7D,0xD5730A1D,0x4CD04DC6, 0x2939BBDB,0xA9BA4650,0xAC9526E8,0xBE5EE304,0xA1FAD5F0,0x6A2D519A, 0x63EF8CE2,0x9A86EE22,0xC089C2B8,0x43242EF6,0xA51E03AA,0x9CF2D0A4, 0x83C061BA,0x9BE96A4D,0x8FE51550,0xBA645BD6,0x2826A2F9,0xA73A3AE1, 0x4BA99586,0xEF5562E9,0xC72FEFD3,0xF752F7DA,0x3F046F69,0x77FA0A59, 0x80E4A915,0x87B08601,0x9B09E6AD,0x3B3EE593,0xE990FD5A,0x9E34D797, 0x2CF0B7D9,0x022B8B51,0x96D5AC3A,0x017DA67D,0xD1CF3ED6,0x7C7D2D28, 0x1F9F25CF,0xADF2B89B,0x5AD6B472,0x5A88F54C,0xE029AC71,0xE019A5E6, 0x47B0ACFD,0xED93FA9B,0xE8D3C48D,0x283B57CC,0xF8D56629,0x79132E28, 0x785F0191,0xED756055,0xF7960E44,0xE3D35E8C,0x15056DD4,0x88F46DBA, 0x03A16125,0x0564F0BD,0xC3EB9E15,0x3C9057A2,0x97271AEC,0xA93A072A, 0x1B3F6D9B,0x1E6321F5,0xF59C66FB,0x26DCF319,0x7533D928,0xB155FDF5, 0x03563482,0x8ABA3CBB,0x28517711,0xC20AD9F8,0xABCC5167,0xCCAD925F, 0x4DE81751,0x3830DC8E,0x379D5862,0x9320F991,0xEA7A90C2,0xFB3E7BCE, 0x5121CE64,0x774FBE32,0xA8B6E37E,0xC3293D46,0x48DE5369,0x6413E680, 0xA2AE0810,0xDD6DB224,0x69852DFD,0x09072166,0xB39A460A,0x6445C0DD, 0x586CDECF,0x1C20C8AE,0x5BBEF7DD,0x1B588D40,0xCCD2017F,0x6BB4E3BB, 0xDDA26A7E,0x3A59FF45,0x3E350A44,0xBCB4CDD5,0x72EACEA8,0xFA6484BB, 0x8D6612AE,0xBF3C6F47,0xD29BE463,0x542F5D9E,0xAEC2771B,0xF64E6370, 0x740E0D8D,0xE75B1357,0xF8721671,0xAF537D5D,0x4040CB08,0x4EB4E2CC, 0x34D2466A,0x0115AF84,0xE1B00428,0x95983A1D,0x06B89FB4,0xCE6EA048, 0x6F3F3B82,0x3520AB82,0x011A1D4B,0x277227F8,0x611560B1,0xE7933FDC, 0xBB3A792B,0x344525BD,0xA08839E1,0x51CE794B,0x2F32C9B7,0xA01FBAC9, 0xE01CC87E,0xBCC7D1F6,0xCF0111C3,0xA1E8AAC7,0x1A908749,0xD44FBD9A, 0xD0DADECB,0xD50ADA38,0x0339C32A,0xC6913667,0x8DF9317C,0xE0B12B4F, 0xF79E59B7,0x43F5BB3A,0xF2D519FF,0x27D9459C,0xBF97222C,0x15E6FC2A, 0x0F91FC71,0x9B941525,0xFAE59361,0xCEB69CEB,0xC2A86459,0x12BAA8D1, 0xB6C1075E,0xE3056A0C,0x10D25065,0xCB03A442,0xE0EC6E0E,0x1698DB3B, 0x4C98A0BE,0x3278E964,0x9F1F9532,0xE0D392DF,0xD3A0342B,0x8971F21E, 0x1B0A7441,0x4BA3348C,0xC5BE7120,0xC37632D8,0xDF359F8D,0x9B992F2E, 0xE60B6F47,0x0FE3F11D,0xE54CDA54,0x1EDAD891,0xCE6279CF,0xCD3E7E6F, 0x1618B166,0xFD2C1D05,0x848FD2C5,0xF6FB2299,0xF523F357,0xA6327623, 0x93A83531,0x56CCCD02,0xACF08162,0x5A75EBB5,0x6E163697,0x88D273CC, 0xDE966292,0x81B949D0,0x4C50901B,0x71C65614,0xE6C6C7BD,0x327A140A, 0x45E1D006,0xC3F27B9A,0xC9AA53FD,0x62A80F00,0xBB25BFE2,0x35BDD2F6, 0x71126905,0xB2040222,0xB6CBCF7C,0xCD769C2B,0x53113EC0,0x1640E3D3, 0x38ABBD60,0x2547ADF0,0xBA38209C,0xF746CE76,0x77AFA1C5,0x20756060, 0x85CBFE4E,0x8AE88DD8,0x7AAAF9B0,0x4CF9AA7E,0x1948C25C,0x02FB8A8C, 0x01C36AE4,0xD6EBE1F9,0x90D4F869,0xA65CDEA0,0x3F09252D,0xC208E69F, 0xB74E6132,0xCE77E25B,0x578FDFE3,0x3AC372E6 }; static const u32 ps[16+2] = { 0x243F6A88,0x85A308D3,0x13198A2E,0x03707344,0xA4093822,0x299F31D0, 0x082EFA98,0xEC4E6C89,0x452821E6,0x38D01377,0xBE5466CF,0x34E90C6C, 0xC0AC29B7,0xC97C50DD,0x3F84D5B5,0xB5470917,0x9216D5D9,0x8979FB1B }; #ifdef USE_AMD64_ASM /* Assembly implementations of Blowfish. */ extern void _gcry_blowfish_amd64_do_encrypt(BLOWFISH_context *c, u32 *ret_xl, u32 *ret_xr); extern void _gcry_blowfish_amd64_encrypt_block(BLOWFISH_context *c, byte *out, const byte *in); extern void _gcry_blowfish_amd64_decrypt_block(BLOWFISH_context *c, byte *out, const byte *in); /* These assembly implementations process four blocks in parallel. */ extern void _gcry_blowfish_amd64_ctr_enc(BLOWFISH_context *ctx, byte *out, const byte *in, byte *ctr); extern void _gcry_blowfish_amd64_cbc_dec(BLOWFISH_context *ctx, byte *out, const byte *in, byte *iv); extern void _gcry_blowfish_amd64_cfb_dec(BLOWFISH_context *ctx, byte *out, const byte *in, byte *iv); static void do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) { _gcry_blowfish_amd64_do_encrypt (bc, ret_xl, ret_xr); } static void do_encrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf) { _gcry_blowfish_amd64_encrypt_block (context, outbuf, inbuf); } static void do_decrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf) { _gcry_blowfish_amd64_decrypt_block (context, outbuf, inbuf); } static inline void blowfish_amd64_ctr_enc(BLOWFISH_context *ctx, byte *out, const byte *in, byte *ctr) { _gcry_blowfish_amd64_ctr_enc(ctx, out, in, ctr); } static inline void blowfish_amd64_cbc_dec(BLOWFISH_context *ctx, byte *out, const byte *in, byte *iv) { _gcry_blowfish_amd64_cbc_dec(ctx, out, in, iv); } static inline void blowfish_amd64_cfb_dec(BLOWFISH_context *ctx, byte *out, const byte *in, byte *iv) { _gcry_blowfish_amd64_cfb_dec(ctx, out, in, iv); } static unsigned int encrypt_block (void *context , byte *outbuf, const byte *inbuf) { BLOWFISH_context *c = (BLOWFISH_context *) context; do_encrypt_block (c, outbuf, inbuf); return /*burn_stack*/ (2*8); } static unsigned int decrypt_block (void *context, byte *outbuf, const byte *inbuf) { BLOWFISH_context *c = (BLOWFISH_context *) context; do_decrypt_block (c, outbuf, inbuf); return /*burn_stack*/ (2*8); } #elif defined(USE_ARM_ASM) /* Assembly implementations of Blowfish. */ extern void _gcry_blowfish_arm_do_encrypt(BLOWFISH_context *c, u32 *ret_xl, u32 *ret_xr); extern void _gcry_blowfish_arm_encrypt_block(BLOWFISH_context *c, byte *out, const byte *in); extern void _gcry_blowfish_arm_decrypt_block(BLOWFISH_context *c, byte *out, const byte *in); /* These assembly implementations process two blocks in parallel. */ extern void _gcry_blowfish_arm_ctr_enc(BLOWFISH_context *ctx, byte *out, const byte *in, byte *ctr); extern void _gcry_blowfish_arm_cbc_dec(BLOWFISH_context *ctx, byte *out, const byte *in, byte *iv); extern void _gcry_blowfish_arm_cfb_dec(BLOWFISH_context *ctx, byte *out, const byte *in, byte *iv); static void do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) { _gcry_blowfish_arm_do_encrypt (bc, ret_xl, ret_xr); } static void do_encrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf) { _gcry_blowfish_arm_encrypt_block (context, outbuf, inbuf); } static void do_decrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf) { _gcry_blowfish_arm_decrypt_block (context, outbuf, inbuf); } static unsigned int encrypt_block (void *context , byte *outbuf, const byte *inbuf) { BLOWFISH_context *c = (BLOWFISH_context *) context; do_encrypt_block (c, outbuf, inbuf); return /*burn_stack*/ (10*4); } static unsigned int decrypt_block (void *context, byte *outbuf, const byte *inbuf) { BLOWFISH_context *c = (BLOWFISH_context *) context; do_decrypt_block (c, outbuf, inbuf); return /*burn_stack*/ (10*4); } #else /*USE_ARM_ASM*/ #define F(x) ((( s0[(x)>>24] + s1[((x)>>16)&0xff]) \ ^ s2[((x)>>8)&0xff]) + s3[(x)&0xff] ) #define R(l,r,i) do { l ^= p[i]; r ^= F(l); } while(0) #define R3(l,r,i) do { R(l##0,r##0,i);R(l##1,r##1,i);R(l##2,r##2,i);} while(0) static void do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) { u32 xl, xr, *s0, *s1, *s2, *s3, *p; xl = *ret_xl; xr = *ret_xr; p = bc->p; s0 = bc->s0; s1 = bc->s1; s2 = bc->s2; s3 = bc->s3; R( xl, xr, 0); R( xr, xl, 1); R( xl, xr, 2); R( xr, xl, 3); R( xl, xr, 4); R( xr, xl, 5); R( xl, xr, 6); R( xr, xl, 7); R( xl, xr, 8); R( xr, xl, 9); R( xl, xr, 10); R( xr, xl, 11); R( xl, xr, 12); R( xr, xl, 13); R( xl, xr, 14); R( xr, xl, 15); xl ^= p[16]; xr ^= p[16+1]; *ret_xl = xr; *ret_xr = xl; } static void do_encrypt_3 ( BLOWFISH_context *bc, byte *dst, const byte *src ) { u32 xl0, xr0, xl1, xr1, xl2, xr2, *s0, *s1, *s2, *s3, *p; xl0 = buf_get_be32(src + 0); xr0 = buf_get_be32(src + 4); xl1 = buf_get_be32(src + 8); xr1 = buf_get_be32(src + 12); xl2 = buf_get_be32(src + 16); xr2 = buf_get_be32(src + 20); p = bc->p; s0 = bc->s0; s1 = bc->s1; s2 = bc->s2; s3 = bc->s3; R3( xl, xr, 0); R3( xr, xl, 1); R3( xl, xr, 2); R3( xr, xl, 3); R3( xl, xr, 4); R3( xr, xl, 5); R3( xl, xr, 6); R3( xr, xl, 7); R3( xl, xr, 8); R3( xr, xl, 9); R3( xl, xr, 10); R3( xr, xl, 11); R3( xl, xr, 12); R3( xr, xl, 13); R3( xl, xr, 14); R3( xr, xl, 15); xl0 ^= p[16]; xr0 ^= p[16+1]; xl1 ^= p[16]; xr1 ^= p[16+1]; xl2 ^= p[16]; xr2 ^= p[16+1]; buf_put_be32(dst + 0, xr0); buf_put_be32(dst + 4, xl0); buf_put_be32(dst + 8, xr1); buf_put_be32(dst + 12, xl1); buf_put_be32(dst + 16, xr2); buf_put_be32(dst + 20, xl2); } static void decrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) { u32 xl, xr, *s0, *s1, *s2, *s3, *p; xl = *ret_xl; xr = *ret_xr; p = bc->p; s0 = bc->s0; s1 = bc->s1; s2 = bc->s2; s3 = bc->s3; R( xl, xr, 17); R( xr, xl, 16); R( xl, xr, 15); R( xr, xl, 14); R( xl, xr, 13); R( xr, xl, 12); R( xl, xr, 11); R( xr, xl, 10); R( xl, xr, 9); R( xr, xl, 8); R( xl, xr, 7); R( xr, xl, 6); R( xl, xr, 5); R( xr, xl, 4); R( xl, xr, 3); R( xr, xl, 2); xl ^= p[1]; xr ^= p[0]; *ret_xl = xr; *ret_xr = xl; } static void do_decrypt_3 ( BLOWFISH_context *bc, byte *dst, const byte *src ) { u32 xl0, xr0, xl1, xr1, xl2, xr2, *s0, *s1, *s2, *s3, *p; xl0 = buf_get_be32(src + 0); xr0 = buf_get_be32(src + 4); xl1 = buf_get_be32(src + 8); xr1 = buf_get_be32(src + 12); xl2 = buf_get_be32(src + 16); xr2 = buf_get_be32(src + 20); p = bc->p; s0 = bc->s0; s1 = bc->s1; s2 = bc->s2; s3 = bc->s3; R3( xl, xr, 17); R3( xr, xl, 16); R3( xl, xr, 15); R3( xr, xl, 14); R3( xl, xr, 13); R3( xr, xl, 12); R3( xl, xr, 11); R3( xr, xl, 10); R3( xl, xr, 9); R3( xr, xl, 8); R3( xl, xr, 7); R3( xr, xl, 6); R3( xl, xr, 5); R3( xr, xl, 4); R3( xl, xr, 3); R3( xr, xl, 2); xl0 ^= p[1]; xr0 ^= p[0]; xl1 ^= p[1]; xr1 ^= p[0]; xl2 ^= p[1]; xr2 ^= p[0]; buf_put_be32(dst + 0, xr0); buf_put_be32(dst + 4, xl0); buf_put_be32(dst + 8, xr1); buf_put_be32(dst + 12, xl1); buf_put_be32(dst + 16, xr2); buf_put_be32(dst + 20, xl2); } #undef F #undef R #undef R3 static void do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf ) { u32 d1, d2; d1 = buf_get_be32(inbuf); d2 = buf_get_be32(inbuf + 4); do_encrypt( bc, &d1, &d2 ); buf_put_be32(outbuf, d1); buf_put_be32(outbuf + 4, d2); } static unsigned int encrypt_block (void *context, byte *outbuf, const byte *inbuf) { BLOWFISH_context *bc = (BLOWFISH_context *) context; do_encrypt_block (bc, outbuf, inbuf); return /*burn_stack*/ (64); } static void do_decrypt_block (BLOWFISH_context *bc, byte *outbuf, const byte *inbuf) { u32 d1, d2; d1 = buf_get_be32(inbuf); d2 = buf_get_be32(inbuf + 4); decrypt( bc, &d1, &d2 ); buf_put_be32(outbuf, d1); buf_put_be32(outbuf + 4, d2); } static unsigned int decrypt_block (void *context, byte *outbuf, const byte *inbuf) { BLOWFISH_context *bc = (BLOWFISH_context *) context; do_decrypt_block (bc, outbuf, inbuf); return /*burn_stack*/ (64); } #endif /*!USE_AMD64_ASM&&!USE_ARM_ASM*/ /* Bulk encryption of complete blocks in CTR mode. This function is only intended for the bulk encryption feature of cipher.c. CTR is expected to be of size BLOWFISH_BLOCKSIZE. */ static void _gcry_blowfish_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { BLOWFISH_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char tmpbuf[BLOWFISH_BLOCKSIZE * 3]; int burn_stack_depth = (64) + 4 * BLOWFISH_BLOCKSIZE; #ifdef USE_AMD64_ASM { if (nblocks >= 4) burn_stack_depth += 5 * sizeof(void*); /* Process data in 4 block chunks. */ while (nblocks >= 4) { blowfish_amd64_ctr_enc(ctx, outbuf, inbuf, ctr); nblocks -= 4; outbuf += 4 * BLOWFISH_BLOCKSIZE; inbuf += 4 * BLOWFISH_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #elif defined(USE_ARM_ASM) { /* Process data in 2 block chunks. */ while (nblocks >= 2) { _gcry_blowfish_arm_ctr_enc(ctx, outbuf, inbuf, ctr); nblocks -= 2; outbuf += 2 * BLOWFISH_BLOCKSIZE; inbuf += 2 * BLOWFISH_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #endif #if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) for ( ;nblocks >= 3; nblocks -= 3) { /* Prepare the counter blocks. */ cipher_block_cpy (tmpbuf + 0, ctr, BLOWFISH_BLOCKSIZE); cipher_block_cpy (tmpbuf + 8, ctr, BLOWFISH_BLOCKSIZE); cipher_block_cpy (tmpbuf + 16, ctr, BLOWFISH_BLOCKSIZE); cipher_block_add (tmpbuf + 8, 1, BLOWFISH_BLOCKSIZE); cipher_block_add (tmpbuf + 16, 2, BLOWFISH_BLOCKSIZE); cipher_block_add (ctr, 3, BLOWFISH_BLOCKSIZE); /* Encrypt the counter. */ do_encrypt_3(ctx, tmpbuf, tmpbuf); /* XOR the input with the encrypted counter and store in output. */ buf_xor(outbuf, tmpbuf, inbuf, BLOWFISH_BLOCKSIZE * 3); outbuf += BLOWFISH_BLOCKSIZE * 3; inbuf += BLOWFISH_BLOCKSIZE * 3; } #endif for ( ;nblocks; nblocks-- ) { /* Encrypt the counter. */ do_encrypt_block(ctx, tmpbuf, ctr); /* XOR the input with the encrypted counter and store in output. */ cipher_block_xor(outbuf, tmpbuf, inbuf, BLOWFISH_BLOCKSIZE); outbuf += BLOWFISH_BLOCKSIZE; inbuf += BLOWFISH_BLOCKSIZE; /* Increment the counter. */ cipher_block_add (ctr, 1, BLOWFISH_BLOCKSIZE); } wipememory(tmpbuf, sizeof(tmpbuf)); _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CBC mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_blowfish_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { BLOWFISH_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char savebuf[BLOWFISH_BLOCKSIZE * 3]; int burn_stack_depth = (64) + 4 * BLOWFISH_BLOCKSIZE; #ifdef USE_AMD64_ASM { if (nblocks >= 4) burn_stack_depth += 5 * sizeof(void*); /* Process data in 4 block chunks. */ while (nblocks >= 4) { blowfish_amd64_cbc_dec(ctx, outbuf, inbuf, iv); nblocks -= 4; outbuf += 4 * BLOWFISH_BLOCKSIZE; inbuf += 4 * BLOWFISH_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #elif defined(USE_ARM_ASM) { /* Process data in 2 block chunks. */ while (nblocks >= 2) { _gcry_blowfish_arm_cbc_dec(ctx, outbuf, inbuf, iv); nblocks -= 2; outbuf += 2 * BLOWFISH_BLOCKSIZE; inbuf += 2 * BLOWFISH_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #endif #if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) for ( ;nblocks >= 3; nblocks -= 3) { /* INBUF is needed later and it may be identical to OUTBUF, so store the intermediate result to SAVEBUF. */ do_decrypt_3 (ctx, savebuf, inbuf); cipher_block_xor_1 (savebuf + 0, iv, BLOWFISH_BLOCKSIZE); cipher_block_xor_1 (savebuf + 8, inbuf, BLOWFISH_BLOCKSIZE * 2); cipher_block_cpy (iv, inbuf + 16, BLOWFISH_BLOCKSIZE); buf_cpy (outbuf, savebuf, BLOWFISH_BLOCKSIZE * 3); inbuf += BLOWFISH_BLOCKSIZE * 3; outbuf += BLOWFISH_BLOCKSIZE * 3; } #endif for ( ;nblocks; nblocks-- ) { /* INBUF is needed later and it may be identical to OUTBUF, so store the intermediate result to SAVEBUF. */ do_decrypt_block (ctx, savebuf, inbuf); cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOWFISH_BLOCKSIZE); inbuf += BLOWFISH_BLOCKSIZE; outbuf += BLOWFISH_BLOCKSIZE; } wipememory(savebuf, sizeof(savebuf)); _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CFB mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_blowfish_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { BLOWFISH_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char tmpbuf[BLOWFISH_BLOCKSIZE * 3]; int burn_stack_depth = (64) + 4 * BLOWFISH_BLOCKSIZE; #ifdef USE_AMD64_ASM { if (nblocks >= 4) burn_stack_depth += 5 * sizeof(void*); /* Process data in 4 block chunks. */ while (nblocks >= 4) { blowfish_amd64_cfb_dec(ctx, outbuf, inbuf, iv); nblocks -= 4; outbuf += 4 * BLOWFISH_BLOCKSIZE; inbuf += 4 * BLOWFISH_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #elif defined(USE_ARM_ASM) { /* Process data in 2 block chunks. */ while (nblocks >= 2) { _gcry_blowfish_arm_cfb_dec(ctx, outbuf, inbuf, iv); nblocks -= 2; outbuf += 2 * BLOWFISH_BLOCKSIZE; inbuf += 2 * BLOWFISH_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #endif #if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) for ( ;nblocks >= 3; nblocks -= 3 ) { cipher_block_cpy (tmpbuf + 0, iv, BLOWFISH_BLOCKSIZE); cipher_block_cpy (tmpbuf + 8, inbuf + 0, BLOWFISH_BLOCKSIZE * 2); cipher_block_cpy (iv, inbuf + 16, BLOWFISH_BLOCKSIZE); do_encrypt_3 (ctx, tmpbuf, tmpbuf); buf_xor (outbuf, inbuf, tmpbuf, BLOWFISH_BLOCKSIZE * 3); outbuf += BLOWFISH_BLOCKSIZE * 3; inbuf += BLOWFISH_BLOCKSIZE * 3; } #endif for ( ;nblocks; nblocks-- ) { do_encrypt_block(ctx, iv, iv); cipher_block_xor_n_copy(outbuf, iv, inbuf, BLOWFISH_BLOCKSIZE); outbuf += BLOWFISH_BLOCKSIZE; inbuf += BLOWFISH_BLOCKSIZE; } wipememory(tmpbuf, sizeof(tmpbuf)); _gcry_burn_stack(burn_stack_depth); } -/* Run the self-tests for BLOWFISH-CTR, tests IV increment of bulk CTR - encryption. Returns NULL on success. */ -static const char * -selftest_ctr (void) -{ - const int nblocks = 4+1; - const int blocksize = BLOWFISH_BLOCKSIZE; - const int context_size = sizeof(BLOWFISH_context); - - return _gcry_selftest_helper_ctr("BLOWFISH", &bf_setkey, - &encrypt_block, nblocks, blocksize, context_size); -} - - -/* Run the self-tests for BLOWFISH-CBC, tests bulk CBC decryption. - Returns NULL on success. */ -static const char * -selftest_cbc (void) -{ - const int nblocks = 4+2; - const int blocksize = BLOWFISH_BLOCKSIZE; - const int context_size = sizeof(BLOWFISH_context); - - return _gcry_selftest_helper_cbc("BLOWFISH", &bf_setkey, - &encrypt_block, nblocks, blocksize, context_size); -} - - -/* Run the self-tests for BLOWFISH-CFB, tests bulk CBC decryption. - Returns NULL on success. */ -static const char * -selftest_cfb (void) -{ - const int nblocks = 4+2; - const int blocksize = BLOWFISH_BLOCKSIZE; - const int context_size = sizeof(BLOWFISH_context); - - return _gcry_selftest_helper_cfb("BLOWFISH", &bf_setkey, - &encrypt_block, nblocks, blocksize, context_size); -} - - static const char* selftest(void) { BLOWFISH_context c; cipher_bulk_ops_t bulk_ops; byte plain[] = "BLOWFISH"; byte buffer[8]; static const byte plain3[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }; static const byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 }; static const byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 }; - const char *r; bf_setkey( (void *) &c, (const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26, &bulk_ops ); encrypt_block( (void *) &c, buffer, plain ); if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) ) return "Blowfish selftest failed (1)."; decrypt_block( (void *) &c, buffer, buffer ); if( memcmp( buffer, plain, 8 ) ) return "Blowfish selftest failed (2)."; bf_setkey( (void *) &c, key3, 8, &bulk_ops ); encrypt_block( (void *) &c, buffer, plain3 ); if( memcmp( buffer, cipher3, 8 ) ) return "Blowfish selftest failed (3)."; decrypt_block( (void *) &c, buffer, buffer ); if( memcmp( buffer, plain3, 8 ) ) return "Blowfish selftest failed (4)."; - if ( (r = selftest_cbc ()) ) - return r; - - if ( (r = selftest_cfb ()) ) - return r; - - if ( (r = selftest_ctr ()) ) - return r; - return NULL; } struct hashset_elem { u32 val; short nidx; char used; }; static inline byte val_to_hidx(u32 val) { /* bf sboxes are quite random already. */ return (val >> 24) ^ (val >> 16) ^ (val >> 8) ^ val; } static inline int add_val(struct hashset_elem hset[256], u32 val, int *midx, struct hashset_elem *mpool) { struct hashset_elem *elem; byte hidx; hidx = val_to_hidx(val); elem = &hset[hidx]; /* Check if first is in use. */ if (elem->used == 0) { elem->val = val; elem->nidx = -1; elem->used = 1; return 0; } /* Check if first matches. */ if (elem->val == val) return 1; for (; elem->nidx >= 0; elem = &mpool[elem->nidx]) { /* Check if elem matches. */ if (elem->val == val) return 1; } elem->nidx = (*midx)++; elem = &mpool[elem->nidx]; elem->val = val; elem->nidx = -1; elem->used = 1; return 0; } static gcry_err_code_t do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen) { struct hashset_elem mempool[4 * 255]; /* Enough entries for the worst case. */ struct hashset_elem hset[4][256]; int memidx = 0; int weak = 0; int i, j, ret; u32 data, datal, datar; static int initialized; static const char *selftest_failed; if( !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 < BLOWFISH_KEY_MIN_BITS / 8 || keylen > BLOWFISH_KEY_MAX_BITS / 8) return GPG_ERR_INV_KEYLEN; memset(hset, 0, sizeof(hset)); for(i=0; i < 16+2; i++ ) c->p[i] = ps[i]; for(i=0; i < 256; i++ ) { c->s0[i] = ks0[i]; c->s1[i] = ks1[i]; c->s2[i] = ks2[i]; c->s3[i] = ks3[i]; } for(i=j=0; i < 16+2; i++ ) { data = ((u32)key[j] << 24) | ((u32)key[(j+1)%keylen] << 16) | ((u32)key[(j+2)%keylen] << 8) | ((u32)key[(j+3)%keylen]); c->p[i] ^= data; j = (j+4) % keylen; } datal = datar = 0; for(i=0; i < 16+2; i += 2 ) { do_encrypt( c, &datal, &datar ); c->p[i] = datal; c->p[i+1] = datar; } for(i=0; i < 256; i += 2 ) { do_encrypt( c, &datal, &datar ); c->s0[i] = datal; c->s0[i+1] = datar; /* Add values to hashset, detect duplicates (weak keys). */ ret = add_val (hset[0], datal, &memidx, mempool); weak = ret ? 1 : weak; ret = add_val (hset[0], datar, &memidx, mempool); weak = ret ? 1 : weak; } for(i=0; i < 256; i += 2 ) { do_encrypt( c, &datal, &datar ); c->s1[i] = datal; c->s1[i+1] = datar; /* Add values to hashset, detect duplicates (weak keys). */ ret = add_val (hset[1], datal, &memidx, mempool); weak = ret ? 1 : weak; ret = add_val (hset[1], datar, &memidx, mempool); weak = ret ? 1 : weak; } for(i=0; i < 256; i += 2 ) { do_encrypt( c, &datal, &datar ); c->s2[i] = datal; c->s2[i+1] = datar; /* Add values to hashset, detect duplicates (weak keys). */ ret = add_val (hset[2], datal, &memidx, mempool); weak = ret ? 1 : weak; ret = add_val (hset[2], datar, &memidx, mempool); weak = ret ? 1 : weak; } for(i=0; i < 256; i += 2 ) { do_encrypt( c, &datal, &datar ); c->s3[i] = datal; c->s3[i+1] = datar; /* Add values to hashset, detect duplicates (weak keys). */ ret = add_val (hset[3], datal, &memidx, mempool); weak = ret ? 1 : weak; ret = add_val (hset[3], datar, &memidx, mempool); weak = ret ? 1 : weak; } /* Clear stack. */ wipememory(hset, sizeof(hset)); wipememory(mempool, sizeof(mempool[0]) * memidx); _gcry_burn_stack (64); /* Check for weak key. A weak key is a key in which a value in the P-array (here c) occurs more than once per table. */ if (weak) return GPG_ERR_WEAK_KEY; return GPG_ERR_NO_ERROR; } static gcry_err_code_t bf_setkey (void *context, const byte *key, unsigned keylen, cipher_bulk_ops_t *bulk_ops) { BLOWFISH_context *c = (BLOWFISH_context *) context; gcry_err_code_t rc = do_bf_setkey (c, key, keylen); /* Setup bulk encryption routines. */ memset (bulk_ops, 0, sizeof(*bulk_ops)); bulk_ops->cfb_dec = _gcry_blowfish_cfb_dec; bulk_ops->cbc_dec = _gcry_blowfish_cbc_dec; bulk_ops->ctr_enc = _gcry_blowfish_ctr_enc; return rc; } gcry_cipher_spec_t _gcry_cipher_spec_blowfish = { GCRY_CIPHER_BLOWFISH, {0, 0}, "BLOWFISH", NULL, NULL, BLOWFISH_BLOCKSIZE, 128, sizeof (BLOWFISH_context), bf_setkey, encrypt_block, decrypt_block }; diff --git a/cipher/camellia-glue.c b/cipher/camellia-glue.c index a854b82d..c938be71 100644 --- a/cipher/camellia-glue.c +++ b/cipher/camellia-glue.c @@ -1,1628 +1,1579 @@ /* camellia-glue.c - Glue for the Camellia cipher * Copyright (C) 2007 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 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ /* I put all the libgcrypt-specific stuff in this file to keep the camellia.c/camellia.h files exactly as provided by NTT. If they update their code, this should make it easier to bring the changes in. - dshaw There is one small change which needs to be done: Include the following code at the top of camellia.h: */ #if 0 /* To use Camellia with libraries it is often useful to keep the name * space of the library clean. The following macro is thus useful: * * #define CAMELLIA_EXT_SYM_PREFIX foo_ * * This prefixes all external symbols with "foo_". */ #ifdef HAVE_CONFIG_H #include #endif #ifdef CAMELLIA_EXT_SYM_PREFIX #define CAMELLIA_PREFIX1(x,y) x ## y #define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y) #define CAMELLIA_PREFIX(x) CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x) #define Camellia_Ekeygen CAMELLIA_PREFIX(Camellia_Ekeygen) #define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock) #define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock) #define camellia_decrypt128 CAMELLIA_PREFIX(camellia_decrypt128) #define camellia_decrypt256 CAMELLIA_PREFIX(camellia_decrypt256) #define camellia_encrypt128 CAMELLIA_PREFIX(camellia_encrypt128) #define camellia_encrypt256 CAMELLIA_PREFIX(camellia_encrypt256) #define camellia_setup128 CAMELLIA_PREFIX(camellia_setup128) #define camellia_setup192 CAMELLIA_PREFIX(camellia_setup192) #define camellia_setup256 CAMELLIA_PREFIX(camellia_setup256) #endif /*CAMELLIA_EXT_SYM_PREFIX*/ #endif /* Code sample. */ #include #include "types.h" #include "g10lib.h" #include "cipher.h" #include "camellia.h" #include "bufhelp.h" #include "cipher-internal.h" -#include "cipher-selftest.h" #include "bulkhelp.h" /* 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_AESNI inidicates whether to compile with Intel AES-NI/AVX code. */ #undef USE_AESNI_AVX #if defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT) # if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_AESNI_AVX 1 # endif #endif /* USE_AESNI_AVX2 inidicates whether to compile with Intel AES-NI/AVX2 code. */ #undef USE_AESNI_AVX2 #if defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT) # if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_AESNI_AVX2 1 # endif #endif /* USE_VAES_AVX2 inidicates whether to compile with Intel VAES/AVX2 code. */ #undef USE_VAES_AVX2 #if defined(USE_AESNI_AVX2) && defined(HAVE_GCC_INLINE_ASM_VAES_VPCLMUL) # define USE_VAES_AVX2 1 #endif /* USE_GFNI_AVX2 inidicates whether to compile with Intel GFNI/AVX2 code. */ #undef USE_GFNI_AVX2 #if defined(USE_AESNI_AVX2) && defined(ENABLE_GFNI_SUPPORT) # define USE_GFNI_AVX2 1 #endif /* USE_GFNI_AVX512 inidicates whether to compile with Intel GFNI/AVX512 code. */ #undef USE_GFNI_AVX512 #if defined(USE_GFNI_AVX2) && defined(ENABLE_AVX512_SUPPORT) # define USE_GFNI_AVX512 1 #endif typedef struct { KEY_TABLE_TYPE keytable; int keybitlength; #ifdef USE_AESNI_AVX unsigned int use_aesni_avx:1; /* AES-NI/AVX implementation shall be used. */ #endif /*USE_AESNI_AVX*/ #ifdef USE_AESNI_AVX2 unsigned int use_aesni_avx2:1;/* AES-NI/AVX2 implementation shall be used. */ unsigned int use_vaes_avx2:1; /* VAES/AVX2 implementation shall be used. */ unsigned int use_gfni_avx2:1; /* GFNI/AVX2 implementation shall be used. */ unsigned int use_gfni_avx512:1; /* GFNI/AVX512 implementation shall be used. */ #endif /*USE_AESNI_AVX2*/ } CAMELLIA_context; /* Assembly implementations use SystemV ABI, ABI conversion and additional * stack to store XMM6-XMM15 needed on Win64. */ #undef ASM_FUNC_ABI #undef ASM_EXTRA_STACK #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2) # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS # define ASM_FUNC_ABI __attribute__((sysv_abi)) # define ASM_EXTRA_STACK (10 * 16) # else # define ASM_FUNC_ABI # define ASM_EXTRA_STACK 0 # endif #endif #ifdef USE_AESNI_AVX /* Assembler implementations of Camellia using AES-NI and AVX. Process data in 16 blocks same time. */ extern void _gcry_camellia_aesni_avx_ctr_enc(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *ctr) ASM_FUNC_ABI; extern void _gcry_camellia_aesni_avx_cbc_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_camellia_aesni_avx_cfb_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_camellia_aesni_avx_ocb_enc(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; extern void _gcry_camellia_aesni_avx_ocb_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; extern void _gcry_camellia_aesni_avx_ocb_auth(CAMELLIA_context *ctx, const unsigned char *abuf, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; extern void _gcry_camellia_aesni_avx_keygen(CAMELLIA_context *ctx, const unsigned char *key, unsigned int keylen) ASM_FUNC_ABI; static const int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE + 16 + 2 * sizeof(void *) + ASM_EXTRA_STACK; #endif #ifdef USE_AESNI_AVX2 /* Assembler implementations of Camellia using AES-NI and AVX2. Process data in 32 blocks same time. */ extern void _gcry_camellia_aesni_avx2_ctr_enc(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *ctr) ASM_FUNC_ABI; extern void _gcry_camellia_aesni_avx2_cbc_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_camellia_aesni_avx2_cfb_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_camellia_aesni_avx2_ocb_enc(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[32]) ASM_FUNC_ABI; extern void _gcry_camellia_aesni_avx2_ocb_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[32]) ASM_FUNC_ABI; extern void _gcry_camellia_aesni_avx2_ocb_auth(CAMELLIA_context *ctx, const unsigned char *abuf, unsigned char *offset, unsigned char *checksum, const u64 Ls[32]) ASM_FUNC_ABI; extern void _gcry_camellia_aesni_avx2_enc_blk1_32(const CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned int nblocks) ASM_FUNC_ABI; extern void _gcry_camellia_aesni_avx2_dec_blk1_32(const CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned int nblocks) ASM_FUNC_ABI; static const int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 + 2 * sizeof(void *) + ASM_EXTRA_STACK; #endif #ifdef USE_VAES_AVX2 /* Assembler implementations of Camellia using VAES and AVX2. Process data in 32 blocks same time. */ extern void _gcry_camellia_vaes_avx2_ctr_enc(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *ctr) ASM_FUNC_ABI; extern void _gcry_camellia_vaes_avx2_cbc_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_camellia_vaes_avx2_cfb_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_camellia_vaes_avx2_ocb_enc(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[32]) ASM_FUNC_ABI; extern void _gcry_camellia_vaes_avx2_ocb_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[32]) ASM_FUNC_ABI; extern void _gcry_camellia_vaes_avx2_ocb_auth(CAMELLIA_context *ctx, const unsigned char *abuf, unsigned char *offset, unsigned char *checksum, const u64 Ls[32]) ASM_FUNC_ABI; extern void _gcry_camellia_vaes_avx2_enc_blk1_32(const CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned int nblocks) ASM_FUNC_ABI; extern void _gcry_camellia_vaes_avx2_dec_blk1_32(const CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned int nblocks) ASM_FUNC_ABI; #endif #ifdef USE_GFNI_AVX2 /* Assembler implementations of Camellia using GFNI and AVX2. Process data in 32 blocks same time. */ extern void _gcry_camellia_gfni_avx2_ctr_enc(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *ctr) ASM_FUNC_ABI; extern void _gcry_camellia_gfni_avx2_cbc_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_camellia_gfni_avx2_cfb_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_camellia_gfni_avx2_ocb_enc(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[32]) ASM_FUNC_ABI; extern void _gcry_camellia_gfni_avx2_ocb_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[32]) ASM_FUNC_ABI; extern void _gcry_camellia_gfni_avx2_ocb_auth(CAMELLIA_context *ctx, const unsigned char *abuf, unsigned char *offset, unsigned char *checksum, const u64 Ls[32]) ASM_FUNC_ABI; extern void _gcry_camellia_gfni_avx2_enc_blk1_32(const CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned int nblocks) ASM_FUNC_ABI; extern void _gcry_camellia_gfni_avx2_dec_blk1_32(const CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned int nblocks) ASM_FUNC_ABI; #endif #ifdef USE_GFNI_AVX512 /* Assembler implementations of Camellia using GFNI and AVX512. Process data in 64 blocks same time. */ extern void _gcry_camellia_gfni_avx512_ctr_enc(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *ctr) ASM_FUNC_ABI; extern void _gcry_camellia_gfni_avx512_cbc_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_camellia_gfni_avx512_cfb_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_camellia_gfni_avx512_ocb_enc(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[32]) ASM_FUNC_ABI; extern void _gcry_camellia_gfni_avx512_ocb_dec(CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[32]) ASM_FUNC_ABI; extern void _gcry_camellia_gfni_avx512_enc_blk64(const CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in) ASM_FUNC_ABI; extern void _gcry_camellia_gfni_avx512_dec_blk64(const CAMELLIA_context *ctx, unsigned char *out, const unsigned char *in) ASM_FUNC_ABI; /* Stack not used by AVX512 implementation. */ static const int avx512_burn_stack_depth = 0; #endif static const char *selftest(void); static void _gcry_camellia_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static void _gcry_camellia_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static void _gcry_camellia_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static void _gcry_camellia_xts_crypt (void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); static size_t _gcry_camellia_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); static size_t _gcry_camellia_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); static gcry_err_code_t camellia_setkey(void *c, const byte *key, unsigned keylen, cipher_bulk_ops_t *bulk_ops) { CAMELLIA_context *ctx=c; static int initialized=0; static const char *selftest_failed=NULL; #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2) \ || defined(USE_VAES_AVX2) || defined(USE_GFNI_AVX2) unsigned int hwf = _gcry_get_hw_features (); #endif if(keylen!=16 && keylen!=24 && keylen!=32) return GPG_ERR_INV_KEYLEN; if(!initialized) { initialized=1; selftest_failed=selftest(); if(selftest_failed) log_error("%s\n",selftest_failed); } if(selftest_failed) return GPG_ERR_SELFTEST_FAILED; #ifdef USE_AESNI_AVX ctx->use_aesni_avx = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX); #endif #ifdef USE_AESNI_AVX2 ctx->use_aesni_avx2 = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX2); ctx->use_vaes_avx2 = 0; ctx->use_gfni_avx2 = 0; ctx->use_gfni_avx512 = 0; #endif #ifdef USE_VAES_AVX2 ctx->use_vaes_avx2 = (hwf & HWF_INTEL_VAES_VPCLMUL) && (hwf & HWF_INTEL_AVX2); #endif #ifdef USE_GFNI_AVX2 ctx->use_gfni_avx2 = (hwf & HWF_INTEL_GFNI) && (hwf & HWF_INTEL_AVX2); #endif #ifdef USE_GFNI_AVX512 ctx->use_gfni_avx512 = (hwf & HWF_INTEL_GFNI) && (hwf & HWF_INTEL_AVX512); #endif ctx->keybitlength=keylen*8; /* Setup bulk encryption routines. */ memset (bulk_ops, 0, sizeof(*bulk_ops)); bulk_ops->cbc_dec = _gcry_camellia_cbc_dec; bulk_ops->cfb_dec = _gcry_camellia_cfb_dec; bulk_ops->ctr_enc = _gcry_camellia_ctr_enc; bulk_ops->ocb_crypt = _gcry_camellia_ocb_crypt; bulk_ops->ocb_auth = _gcry_camellia_ocb_auth; #ifdef USE_AESNI_AVX2 if (ctx->use_aesni_avx2 || ctx->use_vaes_avx2 || ctx->use_gfni_avx2) bulk_ops->xts_crypt = _gcry_camellia_xts_crypt; #endif if (0) { } #ifdef USE_AESNI_AVX else if (ctx->use_aesni_avx) _gcry_camellia_aesni_avx_keygen(ctx, key, keylen); else #endif { Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable); _gcry_burn_stack ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */ +(4+32)*sizeof(u32)+2*sizeof(void*) /* camellia_setup192 */ +0+sizeof(int)+2*sizeof(void*) /* Camellia_Ekeygen */ +3*2*sizeof(void*) /* Function calls. */ ); } #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) { /* Disable AESNI & VAES implementations when GFNI implementation is * enabled. */ #ifdef USE_AESNI_AVX ctx->use_aesni_avx = 0; #endif #ifdef USE_AESNI_AVX2 ctx->use_aesni_avx2 = 0; #endif #ifdef USE_VAES_AVX2 ctx->use_vaes_avx2 = 0; #endif } #endif return 0; } #ifdef USE_ARM_ASM /* Assembly implementations of Camellia. */ extern void _gcry_camellia_arm_encrypt_block(const KEY_TABLE_TYPE keyTable, byte *outbuf, const byte *inbuf, const int keybits); extern void _gcry_camellia_arm_decrypt_block(const KEY_TABLE_TYPE keyTable, byte *outbuf, const byte *inbuf, const int keybits); static void Camellia_EncryptBlock(const int keyBitLength, const unsigned char *plaintext, const KEY_TABLE_TYPE keyTable, unsigned char *cipherText) { _gcry_camellia_arm_encrypt_block(keyTable, cipherText, plaintext, keyBitLength); } static void Camellia_DecryptBlock(const int keyBitLength, const unsigned char *cipherText, const KEY_TABLE_TYPE keyTable, unsigned char *plaintext) { _gcry_camellia_arm_decrypt_block(keyTable, plaintext, cipherText, keyBitLength); } #ifdef __aarch64__ # define CAMELLIA_encrypt_stack_burn_size (0) # define CAMELLIA_decrypt_stack_burn_size (0) #else # define CAMELLIA_encrypt_stack_burn_size (15*4) # define CAMELLIA_decrypt_stack_burn_size (15*4) #endif static unsigned int camellia_encrypt(void *c, byte *outbuf, const byte *inbuf) { CAMELLIA_context *ctx = c; Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf); return /*burn_stack*/ (CAMELLIA_encrypt_stack_burn_size); } static unsigned int camellia_decrypt(void *c, byte *outbuf, const byte *inbuf) { CAMELLIA_context *ctx=c; Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf); return /*burn_stack*/ (CAMELLIA_decrypt_stack_burn_size); } #else /*USE_ARM_ASM*/ static unsigned int camellia_encrypt(void *c, byte *outbuf, const byte *inbuf) { CAMELLIA_context *ctx=c; Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf); #define CAMELLIA_encrypt_stack_burn_size \ (sizeof(int)+2*sizeof(unsigned char *)+sizeof(void*/*KEY_TABLE_TYPE*/) \ +4*sizeof(u32)+4*sizeof(u32) \ +2*sizeof(u32*)+4*sizeof(u32) \ +2*2*sizeof(void*) /* Function calls. */ \ ) return /*burn_stack*/ (CAMELLIA_encrypt_stack_burn_size); } static unsigned int camellia_decrypt(void *c, byte *outbuf, const byte *inbuf) { CAMELLIA_context *ctx=c; Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf); #define CAMELLIA_decrypt_stack_burn_size \ (sizeof(int)+2*sizeof(unsigned char *)+sizeof(void*/*KEY_TABLE_TYPE*/) \ +4*sizeof(u32)+4*sizeof(u32) \ +2*sizeof(u32*)+4*sizeof(u32) \ +2*2*sizeof(void*) /* Function calls. */ \ ) return /*burn_stack*/ (CAMELLIA_decrypt_stack_burn_size); } #endif /*!USE_ARM_ASM*/ static unsigned int camellia_encrypt_blk1_32 (const void *priv, byte *outbuf, const byte *inbuf, unsigned int num_blks) { const CAMELLIA_context *ctx = priv; unsigned int stack_burn_size = 0; gcry_assert (num_blks <= 32); #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2 && num_blks >= 3) { /* 3 or more parallel block GFNI processing is faster than * generic C implementation. */ _gcry_camellia_gfni_avx2_enc_blk1_32 (ctx, outbuf, inbuf, num_blks); return avx2_burn_stack_depth; } #endif #ifdef USE_VAES_AVX2 if (ctx->use_vaes_avx2 && num_blks >= 6) { /* 6 or more parallel block VAES processing is faster than * generic C implementation. */ _gcry_camellia_vaes_avx2_enc_blk1_32 (ctx, outbuf, inbuf, num_blks); return avx2_burn_stack_depth; } #endif #ifdef USE_AESNI_AVX2 if (ctx->use_aesni_avx2 && num_blks >= 6) { /* 6 or more parallel block AESNI processing is faster than * generic C implementation. */ _gcry_camellia_aesni_avx2_enc_blk1_32 (ctx, outbuf, inbuf, num_blks); return avx2_burn_stack_depth; } #endif while (num_blks) { stack_burn_size = camellia_encrypt((void *)ctx, outbuf, inbuf); outbuf += CAMELLIA_BLOCK_SIZE; inbuf += CAMELLIA_BLOCK_SIZE; num_blks--; } return stack_burn_size; } static unsigned int camellia_encrypt_blk1_64 (const void *priv, byte *outbuf, const byte *inbuf, unsigned int num_blks) { const CAMELLIA_context *ctx = priv; unsigned int stack_burn_size = 0; unsigned int nburn; gcry_assert (num_blks <= 64); #ifdef USE_GFNI_AVX512 if (num_blks == 64 && ctx->use_gfni_avx512) { _gcry_camellia_gfni_avx512_enc_blk64 (ctx, outbuf, inbuf); return avx512_burn_stack_depth; } #endif do { unsigned int curr_blks = num_blks > 32 ? 32 : num_blks; nburn = camellia_encrypt_blk1_32 (ctx, outbuf, inbuf, curr_blks); stack_burn_size = nburn > stack_burn_size ? nburn : stack_burn_size; outbuf += curr_blks * 16; inbuf += curr_blks * 16; num_blks -= curr_blks; } while (num_blks > 0); return stack_burn_size; } static unsigned int camellia_decrypt_blk1_32 (const void *priv, byte *outbuf, const byte *inbuf, unsigned int num_blks) { const CAMELLIA_context *ctx = priv; unsigned int stack_burn_size = 0; gcry_assert (num_blks <= 32); #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2 && num_blks >= 3) { /* 3 or more parallel block GFNI processing is faster than * generic C implementation. */ _gcry_camellia_gfni_avx2_dec_blk1_32 (ctx, outbuf, inbuf, num_blks); return avx2_burn_stack_depth; } #endif #ifdef USE_VAES_AVX2 if (ctx->use_vaes_avx2 && num_blks >= 6) { /* 6 or more parallel block VAES processing is faster than * generic C implementation. */ _gcry_camellia_vaes_avx2_dec_blk1_32 (ctx, outbuf, inbuf, num_blks); return avx2_burn_stack_depth; } #endif #ifdef USE_AESNI_AVX2 if (ctx->use_aesni_avx2 && num_blks >= 6) { /* 6 or more parallel block AESNI processing is faster than * generic C implementation. */ _gcry_camellia_aesni_avx2_dec_blk1_32 (ctx, outbuf, inbuf, num_blks); return avx2_burn_stack_depth; } #endif while (num_blks) { stack_burn_size = camellia_decrypt((void *)ctx, outbuf, inbuf); outbuf += CAMELLIA_BLOCK_SIZE; inbuf += CAMELLIA_BLOCK_SIZE; num_blks--; } return stack_burn_size; } static unsigned int camellia_decrypt_blk1_64 (const void *priv, byte *outbuf, const byte *inbuf, unsigned int num_blks) { const CAMELLIA_context *ctx = priv; unsigned int stack_burn_size = 0; unsigned int nburn; gcry_assert (num_blks <= 64); #ifdef USE_GFNI_AVX512 if (num_blks == 64 && ctx->use_gfni_avx512) { _gcry_camellia_gfni_avx512_dec_blk64 (ctx, outbuf, inbuf); return avx512_burn_stack_depth; } #endif do { unsigned int curr_blks = num_blks > 32 ? 32 : num_blks; nburn = camellia_decrypt_blk1_32 (ctx, outbuf, inbuf, curr_blks); stack_burn_size = nburn > stack_burn_size ? nburn : stack_burn_size; outbuf += curr_blks * 16; inbuf += curr_blks * 16; num_blks -= curr_blks; } while (num_blks > 0); return stack_burn_size; } /* Bulk encryption of complete blocks in CTR mode. This function is only intended for the bulk encryption feature of cipher.c. CTR is expected to be of size CAMELLIA_BLOCK_SIZE. */ static void _gcry_camellia_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { CAMELLIA_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; int burn_stack_depth = 0; #ifdef USE_GFNI_AVX512 if (ctx->use_gfni_avx512) { int did_use_gfni_avx512 = 0; /* Process data in 64 block chunks. */ while (nblocks >= 64) { _gcry_camellia_gfni_avx512_ctr_enc (ctx, outbuf, inbuf, ctr); nblocks -= 64; outbuf += 64 * CAMELLIA_BLOCK_SIZE; inbuf += 64 * CAMELLIA_BLOCK_SIZE; did_use_gfni_avx512 = 1; } if (did_use_gfni_avx512) { if (burn_stack_depth < avx512_burn_stack_depth) burn_stack_depth = avx512_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_AESNI_AVX2 if (ctx->use_aesni_avx2) { int did_use_aesni_avx2 = 0; typeof (&_gcry_camellia_aesni_avx2_ctr_enc) bulk_ctr_fn = _gcry_camellia_aesni_avx2_ctr_enc; #ifdef USE_VAES_AVX2 if (ctx->use_vaes_avx2) bulk_ctr_fn =_gcry_camellia_vaes_avx2_ctr_enc; #endif #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) bulk_ctr_fn =_gcry_camellia_gfni_avx2_ctr_enc; #endif /* Process data in 32 block chunks. */ while (nblocks >= 32) { bulk_ctr_fn (ctx, outbuf, inbuf, ctr); nblocks -= 32; outbuf += 32 * CAMELLIA_BLOCK_SIZE; inbuf += 32 * CAMELLIA_BLOCK_SIZE; did_use_aesni_avx2 = 1; } if (did_use_aesni_avx2) { if (burn_stack_depth < avx2_burn_stack_depth) burn_stack_depth = avx2_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_AESNI_AVX if (ctx->use_aesni_avx) { int did_use_aesni_avx = 0; /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_camellia_aesni_avx_ctr_enc(ctx, outbuf, inbuf, ctr); nblocks -= 16; outbuf += 16 * CAMELLIA_BLOCK_SIZE; inbuf += 16 * CAMELLIA_BLOCK_SIZE; did_use_aesni_avx = 1; } if (did_use_aesni_avx) { if (burn_stack_depth < avx_burn_stack_depth) burn_stack_depth = avx_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif /* Process remaining blocks. */ if (nblocks) { byte tmpbuf[CAMELLIA_BLOCK_SIZE * 32]; unsigned int tmp_used = CAMELLIA_BLOCK_SIZE; size_t nburn; nburn = bulk_ctr_enc_128(ctx, camellia_encrypt_blk1_32, outbuf, inbuf, nblocks, ctr, tmpbuf, sizeof(tmpbuf) / CAMELLIA_BLOCK_SIZE, &tmp_used); burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth; wipememory(tmpbuf, tmp_used); } if (burn_stack_depth) _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CBC mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_camellia_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { CAMELLIA_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; int burn_stack_depth = 0; #ifdef USE_GFNI_AVX512 if (ctx->use_gfni_avx512) { int did_use_gfni_avx512 = 0; /* Process data in 64 block chunks. */ while (nblocks >= 64) { _gcry_camellia_gfni_avx512_cbc_dec (ctx, outbuf, inbuf, iv); nblocks -= 64; outbuf += 64 * CAMELLIA_BLOCK_SIZE; inbuf += 64 * CAMELLIA_BLOCK_SIZE; did_use_gfni_avx512 = 1; } if (did_use_gfni_avx512) { if (burn_stack_depth < avx512_burn_stack_depth) burn_stack_depth = avx512_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_AESNI_AVX2 if (ctx->use_aesni_avx2) { int did_use_aesni_avx2 = 0; typeof (&_gcry_camellia_aesni_avx2_cbc_dec) bulk_cbc_fn = _gcry_camellia_aesni_avx2_cbc_dec; #ifdef USE_VAES_AVX2 if (ctx->use_vaes_avx2) bulk_cbc_fn =_gcry_camellia_vaes_avx2_cbc_dec; #endif #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) bulk_cbc_fn =_gcry_camellia_gfni_avx2_cbc_dec; #endif /* Process data in 32 block chunks. */ while (nblocks >= 32) { bulk_cbc_fn (ctx, outbuf, inbuf, iv); nblocks -= 32; outbuf += 32 * CAMELLIA_BLOCK_SIZE; inbuf += 32 * CAMELLIA_BLOCK_SIZE; did_use_aesni_avx2 = 1; } if (did_use_aesni_avx2) { if (burn_stack_depth < avx2_burn_stack_depth) burn_stack_depth = avx2_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_AESNI_AVX if (ctx->use_aesni_avx) { int did_use_aesni_avx = 0; /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_camellia_aesni_avx_cbc_dec(ctx, outbuf, inbuf, iv); nblocks -= 16; outbuf += 16 * CAMELLIA_BLOCK_SIZE; inbuf += 16 * CAMELLIA_BLOCK_SIZE; did_use_aesni_avx = 1; } if (did_use_aesni_avx) { if (burn_stack_depth < avx_burn_stack_depth) burn_stack_depth = avx_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif /* Process remaining blocks. */ if (nblocks) { byte tmpbuf[CAMELLIA_BLOCK_SIZE * 32]; unsigned int tmp_used = CAMELLIA_BLOCK_SIZE; size_t nburn; nburn = bulk_cbc_dec_128(ctx, camellia_decrypt_blk1_32, outbuf, inbuf, nblocks, iv, tmpbuf, sizeof(tmpbuf) / CAMELLIA_BLOCK_SIZE, &tmp_used); burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth; wipememory(tmpbuf, tmp_used); } if (burn_stack_depth) _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CFB mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_camellia_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { CAMELLIA_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; int burn_stack_depth = 0; #ifdef USE_GFNI_AVX512 if (ctx->use_gfni_avx512) { int did_use_gfni_avx512 = 0; /* Process data in 64 block chunks. */ while (nblocks >= 64) { _gcry_camellia_gfni_avx512_cfb_dec (ctx, outbuf, inbuf, iv); nblocks -= 64; outbuf += 64 * CAMELLIA_BLOCK_SIZE; inbuf += 64 * CAMELLIA_BLOCK_SIZE; did_use_gfni_avx512 = 1; } if (did_use_gfni_avx512) { if (burn_stack_depth < avx512_burn_stack_depth) burn_stack_depth = avx512_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_AESNI_AVX2 if (ctx->use_aesni_avx2) { int did_use_aesni_avx2 = 0; typeof (&_gcry_camellia_aesni_avx2_cfb_dec) bulk_cfb_fn = _gcry_camellia_aesni_avx2_cfb_dec; #ifdef USE_VAES_AVX2 if (ctx->use_vaes_avx2) bulk_cfb_fn =_gcry_camellia_vaes_avx2_cfb_dec; #endif #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) bulk_cfb_fn =_gcry_camellia_gfni_avx2_cfb_dec; #endif /* Process data in 32 block chunks. */ while (nblocks >= 32) { bulk_cfb_fn (ctx, outbuf, inbuf, iv); nblocks -= 32; outbuf += 32 * CAMELLIA_BLOCK_SIZE; inbuf += 32 * CAMELLIA_BLOCK_SIZE; did_use_aesni_avx2 = 1; } if (did_use_aesni_avx2) { if (burn_stack_depth < avx2_burn_stack_depth) burn_stack_depth = avx2_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_AESNI_AVX if (ctx->use_aesni_avx) { int did_use_aesni_avx = 0; /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_camellia_aesni_avx_cfb_dec(ctx, outbuf, inbuf, iv); nblocks -= 16; outbuf += 16 * CAMELLIA_BLOCK_SIZE; inbuf += 16 * CAMELLIA_BLOCK_SIZE; did_use_aesni_avx = 1; } if (did_use_aesni_avx) { if (burn_stack_depth < avx_burn_stack_depth) burn_stack_depth = avx_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif /* Process remaining blocks. */ if (nblocks) { byte tmpbuf[CAMELLIA_BLOCK_SIZE * 32]; unsigned int tmp_used = CAMELLIA_BLOCK_SIZE; size_t nburn; nburn = bulk_cfb_dec_128(ctx, camellia_encrypt_blk1_32, outbuf, inbuf, nblocks, iv, tmpbuf, sizeof(tmpbuf) / CAMELLIA_BLOCK_SIZE, &tmp_used); burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth; wipememory(tmpbuf, tmp_used); } if (burn_stack_depth) _gcry_burn_stack(burn_stack_depth); } /* Bulk encryption/decryption of complete blocks in XTS mode. */ static void _gcry_camellia_xts_crypt (void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt) { CAMELLIA_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; int burn_stack_depth = 0; /* Process remaining blocks. */ if (nblocks) { byte tmpbuf[CAMELLIA_BLOCK_SIZE * 64]; unsigned int tmp_used = CAMELLIA_BLOCK_SIZE; size_t nburn; nburn = bulk_xts_crypt_128(ctx, encrypt ? camellia_encrypt_blk1_64 : camellia_decrypt_blk1_64, outbuf, inbuf, nblocks, tweak, tmpbuf, sizeof(tmpbuf) / CAMELLIA_BLOCK_SIZE, &tmp_used); burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth; wipememory(tmpbuf, tmp_used); } if (burn_stack_depth) _gcry_burn_stack(burn_stack_depth); } /* Bulk encryption/decryption of complete blocks in OCB mode. */ static size_t _gcry_camellia_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt) { #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2) CAMELLIA_context *ctx = (void *)&c->context.c; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; int burn_stack_depth = 0; u64 blkn = c->u_mode.ocb.data_nblocks; #else (void)c; (void)outbuf_arg; (void)inbuf_arg; (void)encrypt; #endif #ifdef USE_GFNI_AVX512 if (ctx->use_gfni_avx512) { int did_use_gfni_avx512 = 0; u64 Ls[64]; u64 *l; if (nblocks >= 64) { typeof (&_gcry_camellia_gfni_avx512_ocb_dec) bulk_ocb_fn = encrypt ? _gcry_camellia_gfni_avx512_ocb_enc : _gcry_camellia_gfni_avx512_ocb_dec; l = bulk_ocb_prepare_L_pointers_array_blk64 (c, Ls, blkn); /* Process data in 64 block chunks. */ while (nblocks >= 64) { blkn += 64; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 64); bulk_ocb_fn (ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); nblocks -= 64; outbuf += 64 * CAMELLIA_BLOCK_SIZE; inbuf += 64 * CAMELLIA_BLOCK_SIZE; did_use_gfni_avx512 = 1; } } if (did_use_gfni_avx512) { if (burn_stack_depth < avx2_burn_stack_depth) burn_stack_depth = avx2_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_AESNI_AVX2 if (ctx->use_aesni_avx2) { int did_use_aesni_avx2 = 0; u64 Ls[32]; u64 *l; if (nblocks >= 32) { typeof (&_gcry_camellia_aesni_avx2_ocb_dec) bulk_ocb_fn = encrypt ? _gcry_camellia_aesni_avx2_ocb_enc : _gcry_camellia_aesni_avx2_ocb_dec; #ifdef USE_VAES_AVX2 if (ctx->use_vaes_avx2) bulk_ocb_fn = encrypt ? _gcry_camellia_vaes_avx2_ocb_enc : _gcry_camellia_vaes_avx2_ocb_dec; #endif #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) bulk_ocb_fn = encrypt ? _gcry_camellia_gfni_avx2_ocb_enc : _gcry_camellia_gfni_avx2_ocb_dec; #endif l = bulk_ocb_prepare_L_pointers_array_blk32 (c, Ls, blkn); /* Process data in 32 block chunks. */ while (nblocks >= 32) { blkn += 32; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 32); bulk_ocb_fn (ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); nblocks -= 32; outbuf += 32 * CAMELLIA_BLOCK_SIZE; inbuf += 32 * CAMELLIA_BLOCK_SIZE; did_use_aesni_avx2 = 1; } } if (did_use_aesni_avx2) { if (burn_stack_depth < avx2_burn_stack_depth) burn_stack_depth = avx2_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_AESNI_AVX if (ctx->use_aesni_avx) { int did_use_aesni_avx = 0; u64 Ls[16]; u64 *l; if (nblocks >= 16) { l = bulk_ocb_prepare_L_pointers_array_blk16 (c, Ls, blkn); /* Process data in 16 block chunks. */ while (nblocks >= 16) { blkn += 16; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16); if (encrypt) _gcry_camellia_aesni_avx_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); else _gcry_camellia_aesni_avx_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); nblocks -= 16; outbuf += 16 * CAMELLIA_BLOCK_SIZE; inbuf += 16 * CAMELLIA_BLOCK_SIZE; did_use_aesni_avx = 1; } } if (did_use_aesni_avx) { if (burn_stack_depth < avx_burn_stack_depth) burn_stack_depth = avx_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2) /* Process remaining blocks. */ if (nblocks) { byte tmpbuf[CAMELLIA_BLOCK_SIZE * 32]; unsigned int tmp_used = CAMELLIA_BLOCK_SIZE; size_t nburn; nburn = bulk_ocb_crypt_128 (c, ctx, encrypt ? camellia_encrypt_blk1_32 : camellia_decrypt_blk1_32, outbuf, inbuf, nblocks, &blkn, encrypt, tmpbuf, sizeof(tmpbuf) / CAMELLIA_BLOCK_SIZE, &tmp_used); burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth; wipememory(tmpbuf, tmp_used); nblocks = 0; } c->u_mode.ocb.data_nblocks = blkn; if (burn_stack_depth) _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *)); #endif return nblocks; } /* Bulk authentication of complete blocks in OCB mode. */ static size_t _gcry_camellia_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks) { #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2) CAMELLIA_context *ctx = (void *)&c->context.c; const unsigned char *abuf = abuf_arg; int burn_stack_depth = 0; u64 blkn = c->u_mode.ocb.aad_nblocks; #else (void)c; (void)abuf_arg; #endif #ifdef USE_AESNI_AVX2 if (ctx->use_aesni_avx2) { int did_use_aesni_avx2 = 0; u64 Ls[32]; u64 *l; if (nblocks >= 32) { typeof (&_gcry_camellia_aesni_avx2_ocb_auth) bulk_auth_fn = _gcry_camellia_aesni_avx2_ocb_auth; #ifdef USE_VAES_AVX2 if (ctx->use_vaes_avx2) bulk_auth_fn = _gcry_camellia_vaes_avx2_ocb_auth; #endif #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) bulk_auth_fn = _gcry_camellia_gfni_avx2_ocb_auth; #endif l = bulk_ocb_prepare_L_pointers_array_blk32 (c, Ls, blkn); /* Process data in 32 block chunks. */ while (nblocks >= 32) { blkn += 32; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 32); bulk_auth_fn (ctx, abuf, c->u_mode.ocb.aad_offset, c->u_mode.ocb.aad_sum, Ls); nblocks -= 32; abuf += 32 * CAMELLIA_BLOCK_SIZE; did_use_aesni_avx2 = 1; } } if (did_use_aesni_avx2) { if (burn_stack_depth < avx2_burn_stack_depth) burn_stack_depth = avx2_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_AESNI_AVX if (ctx->use_aesni_avx) { int did_use_aesni_avx = 0; u64 Ls[16]; u64 *l; if (nblocks >= 16) { l = bulk_ocb_prepare_L_pointers_array_blk16 (c, Ls, blkn); /* Process data in 16 block chunks. */ while (nblocks >= 16) { blkn += 16; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16); _gcry_camellia_aesni_avx_ocb_auth(ctx, abuf, c->u_mode.ocb.aad_offset, c->u_mode.ocb.aad_sum, Ls); nblocks -= 16; abuf += 16 * CAMELLIA_BLOCK_SIZE; did_use_aesni_avx = 1; } } if (did_use_aesni_avx) { if (burn_stack_depth < avx_burn_stack_depth) burn_stack_depth = avx_burn_stack_depth; } /* Use generic code to handle smaller chunks... */ } #endif #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2) /* Process remaining blocks. */ if (nblocks) { byte tmpbuf[CAMELLIA_BLOCK_SIZE * 32]; unsigned int tmp_used = CAMELLIA_BLOCK_SIZE; size_t nburn; nburn = bulk_ocb_auth_128 (c, ctx, camellia_encrypt_blk1_32, abuf, nblocks, &blkn, tmpbuf, sizeof(tmpbuf) / CAMELLIA_BLOCK_SIZE, &tmp_used); burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth; wipememory(tmpbuf, tmp_used); nblocks = 0; } c->u_mode.ocb.aad_nblocks = blkn; if (burn_stack_depth) _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *)); #endif return nblocks; } -/* Run the self-tests for CAMELLIA-CTR-128, tests IV increment of bulk CTR - encryption. Returns NULL on success. */ -static const char* -selftest_ctr_128 (void) -{ - const int nblocks = 64+32+16+1; - const int blocksize = CAMELLIA_BLOCK_SIZE; - const int context_size = sizeof(CAMELLIA_context); - - return _gcry_selftest_helper_ctr("CAMELLIA", &camellia_setkey, - &camellia_encrypt, nblocks, blocksize, context_size); -} - -/* Run the self-tests for CAMELLIA-CBC-128, tests bulk CBC decryption. - Returns NULL on success. */ -static const char* -selftest_cbc_128 (void) -{ - const int nblocks = 64+32+16+2; - const int blocksize = CAMELLIA_BLOCK_SIZE; - const int context_size = sizeof(CAMELLIA_context); - - return _gcry_selftest_helper_cbc("CAMELLIA", &camellia_setkey, - &camellia_encrypt, nblocks, blocksize, context_size); -} - -/* Run the self-tests for CAMELLIA-CFB-128, tests bulk CFB decryption. - Returns NULL on success. */ -static const char* -selftest_cfb_128 (void) -{ - const int nblocks = 64+32+16+2; - const int blocksize = CAMELLIA_BLOCK_SIZE; - const int context_size = sizeof(CAMELLIA_context); - - return _gcry_selftest_helper_cfb("CAMELLIA", &camellia_setkey, - &camellia_encrypt, nblocks, blocksize, context_size); -} static const char * selftest(void) { CAMELLIA_context ctx; byte scratch[16]; cipher_bulk_ops_t bulk_ops; - const char *r; /* These test vectors are from RFC-3713 */ static const byte plaintext[]= { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 }; static const byte key_128[]= { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 }; static const byte ciphertext_128[]= { 0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73, 0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43 }; static const byte key_192[]= { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98, 0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77 }; static const byte ciphertext_192[]= { 0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8, 0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9 }; static const byte key_256[]= { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba, 0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55, 0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff }; static const byte ciphertext_256[]= { 0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c, 0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09 }; camellia_setkey(&ctx,key_128,sizeof(key_128),&bulk_ops); camellia_encrypt(&ctx,scratch,plaintext); if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0) return "CAMELLIA-128 test encryption failed."; camellia_decrypt(&ctx,scratch,scratch); if(memcmp(scratch,plaintext,sizeof(plaintext))!=0) return "CAMELLIA-128 test decryption failed."; camellia_setkey(&ctx,key_192,sizeof(key_192),&bulk_ops); camellia_encrypt(&ctx,scratch,plaintext); if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0) return "CAMELLIA-192 test encryption failed."; camellia_decrypt(&ctx,scratch,scratch); if(memcmp(scratch,plaintext,sizeof(plaintext))!=0) return "CAMELLIA-192 test decryption failed."; camellia_setkey(&ctx,key_256,sizeof(key_256),&bulk_ops); camellia_encrypt(&ctx,scratch,plaintext); if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0) return "CAMELLIA-256 test encryption failed."; camellia_decrypt(&ctx,scratch,scratch); if(memcmp(scratch,plaintext,sizeof(plaintext))!=0) return "CAMELLIA-256 test decryption failed."; - if ( (r = selftest_ctr_128 ()) ) - return r; - - if ( (r = selftest_cbc_128 ()) ) - return r; - - if ( (r = selftest_cfb_128 ()) ) - return r; - return NULL; } /* These oids are from , retrieved May 1, 2007. */ static const gcry_cipher_oid_spec_t camellia128_oids[] = { {"1.2.392.200011.61.1.1.1.2", GCRY_CIPHER_MODE_CBC}, {"0.3.4401.5.3.1.9.1", GCRY_CIPHER_MODE_ECB}, {"0.3.4401.5.3.1.9.3", GCRY_CIPHER_MODE_OFB}, {"0.3.4401.5.3.1.9.4", GCRY_CIPHER_MODE_CFB}, { NULL } }; static const gcry_cipher_oid_spec_t camellia192_oids[] = { {"1.2.392.200011.61.1.1.1.3", GCRY_CIPHER_MODE_CBC}, {"0.3.4401.5.3.1.9.21", GCRY_CIPHER_MODE_ECB}, {"0.3.4401.5.3.1.9.23", GCRY_CIPHER_MODE_OFB}, {"0.3.4401.5.3.1.9.24", GCRY_CIPHER_MODE_CFB}, { NULL } }; static const gcry_cipher_oid_spec_t camellia256_oids[] = { {"1.2.392.200011.61.1.1.1.4", GCRY_CIPHER_MODE_CBC}, {"0.3.4401.5.3.1.9.41", GCRY_CIPHER_MODE_ECB}, {"0.3.4401.5.3.1.9.43", GCRY_CIPHER_MODE_OFB}, {"0.3.4401.5.3.1.9.44", GCRY_CIPHER_MODE_CFB}, { NULL } }; gcry_cipher_spec_t _gcry_cipher_spec_camellia128 = { GCRY_CIPHER_CAMELLIA128, {0, 0}, "CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128, sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt }; gcry_cipher_spec_t _gcry_cipher_spec_camellia192 = { GCRY_CIPHER_CAMELLIA192, {0, 0}, "CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192, sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt }; gcry_cipher_spec_t _gcry_cipher_spec_camellia256 = { GCRY_CIPHER_CAMELLIA256, {0, 0}, "CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256, sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt }; diff --git a/cipher/cast5.c b/cipher/cast5.c index 837ea0fe..20bf7479 100644 --- a/cipher/cast5.c +++ b/cipher/cast5.c @@ -1,1238 +1,1185 @@ /* cast5.c - CAST5 cipher (RFC2144) * Copyright (C) 1998, 2001, 2002, 2003 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* Test vectors: * * 128-bit key = 01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A * plaintext = 01 23 45 67 89 AB CD EF * ciphertext = 23 8B 4F E5 84 7E 44 B2 * * 80-bit key = 01 23 45 67 12 34 56 78 23 45 * = 01 23 45 67 12 34 56 78 23 45 00 00 00 00 00 00 * plaintext = 01 23 45 67 89 AB CD EF * ciphertext = EB 6A 71 1A 2C 02 27 1B * * 40-bit key = 01 23 45 67 12 * = 01 23 45 67 12 00 00 00 00 00 00 00 00 00 00 00 * plaintext = 01 23 45 67 89 AB CD EF * ciphertext = 7A C8 16 D1 6E 9B 30 2E */ #include #include #include #include #include "g10lib.h" #include "types.h" #include "cipher.h" #include "bithelp.h" #include "bufhelp.h" #include "cipher-internal.h" -#include "cipher-selftest.h" /* 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_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 #define CAST5_BLOCKSIZE 8 typedef struct { u32 Km[16]; byte Kr[16]; #ifdef USE_ARM_ASM u32 Kr_arm_enc[16 / sizeof(u32)]; u32 Kr_arm_dec[16 / sizeof(u32)]; #endif } CAST5_context; static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen, cipher_bulk_ops_t *bulk_ops); static unsigned int encrypt_block (void *c, byte *outbuf, const byte *inbuf); static unsigned int decrypt_block (void *c, byte *outbuf, const byte *inbuf); #define s1 _gcry_cast5_s1to4[0] #define s2 _gcry_cast5_s1to4[1] #define s3 _gcry_cast5_s1to4[2] #define s4 _gcry_cast5_s1to4[3] const u32 _gcry_cast5_s1to4[4][256] = { { 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf }, { 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1 }, { 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783 }, { 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2 } }; static const u32 s5[256] = { 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4 }; static const u32 s6[256] = { 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f }; static const u32 s7[256] = { 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3 }; static const u32 s8[256] = { 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e }; #ifdef USE_AMD64_ASM /* Assembly implementations of CAST5. */ extern void _gcry_cast5_amd64_encrypt_block(CAST5_context *c, byte *outbuf, const byte *inbuf); extern void _gcry_cast5_amd64_decrypt_block(CAST5_context *c, byte *outbuf, const byte *inbuf); /* These assembly implementations process four blocks in parallel. */ extern void _gcry_cast5_amd64_ctr_enc(CAST5_context *ctx, byte *out, const byte *in, byte *ctr); extern void _gcry_cast5_amd64_cbc_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv); extern void _gcry_cast5_amd64_cfb_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv); static void do_encrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf) { _gcry_cast5_amd64_encrypt_block (context, outbuf, inbuf); } static void do_decrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf) { _gcry_cast5_amd64_decrypt_block (context, outbuf, inbuf); } static void cast5_amd64_ctr_enc(CAST5_context *ctx, byte *out, const byte *in, byte *ctr) { _gcry_cast5_amd64_ctr_enc (ctx, out, in, ctr); } static void cast5_amd64_cbc_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv) { _gcry_cast5_amd64_cbc_dec (ctx, out, in, iv); } static void cast5_amd64_cfb_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv) { _gcry_cast5_amd64_cfb_dec (ctx, out, in, iv); } static unsigned int encrypt_block (void *context , byte *outbuf, const byte *inbuf) { CAST5_context *c = (CAST5_context *) context; do_encrypt_block (c, outbuf, inbuf); return /*burn_stack*/ (2*8); } static unsigned int decrypt_block (void *context, byte *outbuf, const byte *inbuf) { CAST5_context *c = (CAST5_context *) context; do_decrypt_block (c, outbuf, inbuf); return /*burn_stack*/ (2*8); } #elif defined(USE_ARM_ASM) /* ARM assembly implementations of CAST5. */ extern void _gcry_cast5_arm_encrypt_block(CAST5_context *c, byte *outbuf, const byte *inbuf); extern void _gcry_cast5_arm_decrypt_block(CAST5_context *c, byte *outbuf, const byte *inbuf); /* These assembly implementations process two blocks in parallel. */ extern void _gcry_cast5_arm_ctr_enc(CAST5_context *ctx, byte *out, const byte *in, byte *ctr); extern void _gcry_cast5_arm_cbc_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv); extern void _gcry_cast5_arm_cfb_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv); static void do_encrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf) { _gcry_cast5_arm_encrypt_block (context, outbuf, inbuf); } static void do_decrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf) { _gcry_cast5_arm_decrypt_block (context, outbuf, inbuf); } static unsigned int encrypt_block (void *context , byte *outbuf, const byte *inbuf) { CAST5_context *c = (CAST5_context *) context; do_encrypt_block (c, outbuf, inbuf); return /*burn_stack*/ (10*4); } static unsigned int decrypt_block (void *context, byte *outbuf, const byte *inbuf) { CAST5_context *c = (CAST5_context *) context; do_decrypt_block (c, outbuf, inbuf); return /*burn_stack*/ (10*4); } #else /*USE_ARM_ASM*/ #define F1(D,m,r) ( (I = ((m) + (D))), (I=rol(I,(r))), \ (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) ) #define F2(D,m,r) ( (I = ((m) ^ (D))), (I=rol(I,(r))), \ (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) ) #define F3(D,m,r) ( (I = ((m) - (D))), (I=rol(I,(r))), \ (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) ) static void do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf ) { u32 l, r, t; u32 I; /* used by the Fx macros */ u32 *Km; u32 Kr; Km = c->Km; Kr = buf_get_le32(c->Kr + 0); /* (L0,R0) <-- (m1...m64). (Split the plaintext into left and * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.) */ l = buf_get_be32(inbuf + 0); r = buf_get_be32(inbuf + 4); /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows: * Li = Ri-1; * Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2 * Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1. * Rounds 2, 5, 8, 11, and 14 use f function Type 2. * Rounds 3, 6, 9, 12, and 15 use f function Type 3. */ t = l; l = r; r = t ^ F1(r, Km[ 0], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F2(r, Km[ 1], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F3(r, Km[ 2], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F1(r, Km[ 3], Kr & 31); Kr = buf_get_le32(c->Kr + 4); t = l; l = r; r = t ^ F2(r, Km[ 4], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F3(r, Km[ 5], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F1(r, Km[ 6], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F2(r, Km[ 7], Kr & 31); Kr = buf_get_le32(c->Kr + 8); t = l; l = r; r = t ^ F3(r, Km[ 8], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F1(r, Km[ 9], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F2(r, Km[10], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F3(r, Km[11], Kr & 31); Kr = buf_get_le32(c->Kr + 12); t = l; l = r; r = t ^ F1(r, Km[12], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F2(r, Km[13], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F3(r, Km[14], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F1(r, Km[15], Kr & 31); /* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and * concatenate to form the ciphertext.) */ buf_put_be32(outbuf + 0, r); buf_put_be32(outbuf + 4, l); } static unsigned int encrypt_block (void *context , byte *outbuf, const byte *inbuf) { CAST5_context *c = (CAST5_context *) context; do_encrypt_block (c, outbuf, inbuf); return /*burn_stack*/ (20+4*sizeof(void*)); } static void do_encrypt_block_3( CAST5_context *c, byte *outbuf, const byte *inbuf ) { u32 l0, r0, t0, l1, r1, t1, l2, r2, t2; u32 I; /* used by the Fx macros */ u32 *Km; u32 Kr; Km = c->Km; Kr = buf_get_le32(c->Kr + 0); l0 = buf_get_be32(inbuf + 0); r0 = buf_get_be32(inbuf + 4); l1 = buf_get_be32(inbuf + 8); r1 = buf_get_be32(inbuf + 12); l2 = buf_get_be32(inbuf + 16); r2 = buf_get_be32(inbuf + 20); t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 0], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 0], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 0], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[ 1], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[ 1], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[ 1], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[ 2], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[ 2], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[ 2], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 3], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 3], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 3], Kr & 31); Kr = buf_get_le32(c->Kr + 4); t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[ 4], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[ 4], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[ 4], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[ 5], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[ 5], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[ 5], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 6], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 6], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 6], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[ 7], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[ 7], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[ 7], Kr & 31); Kr = buf_get_le32(c->Kr + 8); t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[ 8], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[ 8], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[ 8], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 9], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 9], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 9], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[10], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[10], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[10], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[11], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[11], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[11], Kr & 31); Kr = buf_get_le32(c->Kr + 12); t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[12], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[12], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[12], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[13], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[13], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[13], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[14], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[14], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[14], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[15], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[15], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[15], Kr & 31); buf_put_be32(outbuf + 0, r0); buf_put_be32(outbuf + 4, l0); buf_put_be32(outbuf + 8, r1); buf_put_be32(outbuf + 12, l1); buf_put_be32(outbuf + 16, r2); buf_put_be32(outbuf + 20, l2); } static void do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf ) { u32 l, r, t; u32 I; u32 *Km; u32 Kr; Km = c->Km; Kr = buf_get_be32(c->Kr + 12); l = buf_get_be32(inbuf + 0); r = buf_get_be32(inbuf + 4); t = l; l = r; r = t ^ F1(r, Km[15], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F3(r, Km[14], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F2(r, Km[13], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F1(r, Km[12], Kr & 31); Kr = buf_get_be32(c->Kr + 8); t = l; l = r; r = t ^ F3(r, Km[11], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F2(r, Km[10], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F1(r, Km[ 9], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F3(r, Km[ 8], Kr & 31); Kr = buf_get_be32(c->Kr + 4); t = l; l = r; r = t ^ F2(r, Km[ 7], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F1(r, Km[ 6], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F3(r, Km[ 5], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F2(r, Km[ 4], Kr & 31); Kr = buf_get_be32(c->Kr + 0); t = l; l = r; r = t ^ F1(r, Km[ 3], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F3(r, Km[ 2], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F2(r, Km[ 1], Kr & 31); Kr >>= 8; t = l; l = r; r = t ^ F1(r, Km[ 0], Kr & 31); buf_put_be32(outbuf + 0, r); buf_put_be32(outbuf + 4, l); } static unsigned int decrypt_block (void *context, byte *outbuf, const byte *inbuf) { CAST5_context *c = (CAST5_context *) context; do_decrypt_block (c, outbuf, inbuf); return /*burn_stack*/ (20+4*sizeof(void*)); } static void do_decrypt_block_3 (CAST5_context *c, byte *outbuf, const byte *inbuf ) { u32 l0, r0, t0, l1, r1, t1, l2, r2, t2; u32 I; u32 *Km; u32 Kr; Km = c->Km; Kr = buf_get_be32(c->Kr + 12); l0 = buf_get_be32(inbuf + 0); r0 = buf_get_be32(inbuf + 4); l1 = buf_get_be32(inbuf + 8); r1 = buf_get_be32(inbuf + 12); l2 = buf_get_be32(inbuf + 16); r2 = buf_get_be32(inbuf + 20); t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[15], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[15], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[15], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[14], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[14], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[14], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[13], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[13], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[13], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[12], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[12], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[12], Kr & 31); Kr = buf_get_be32(c->Kr + 8); t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[11], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[11], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[11], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[10], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[10], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[10], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 9], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 9], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 9], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[ 8], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[ 8], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[ 8], Kr & 31); Kr = buf_get_be32(c->Kr + 4); t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[ 7], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[ 7], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[ 7], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 6], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 6], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 6], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[ 5], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[ 5], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[ 5], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[ 4], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[ 4], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[ 4], Kr & 31); Kr = buf_get_be32(c->Kr + 0); t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 3], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 3], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 3], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F3(r0, Km[ 2], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F3(r1, Km[ 2], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F3(r2, Km[ 2], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F2(r0, Km[ 1], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F2(r1, Km[ 1], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F2(r2, Km[ 1], Kr & 31); Kr >>= 8; t0 = l0; l0 = r0; r0 = t0 ^ F1(r0, Km[ 0], Kr & 31); t1 = l1; l1 = r1; r1 = t1 ^ F1(r1, Km[ 0], Kr & 31); t2 = l2; l2 = r2; r2 = t2 ^ F1(r2, Km[ 0], Kr & 31); buf_put_be32(outbuf + 0, r0); buf_put_be32(outbuf + 4, l0); buf_put_be32(outbuf + 8, r1); buf_put_be32(outbuf + 12, l1); buf_put_be32(outbuf + 16, r2); buf_put_be32(outbuf + 20, l2); } #endif /*!USE_ARM_ASM*/ /* Bulk encryption of complete blocks in CTR mode. This function is only intended for the bulk encryption feature of cipher.c. CTR is expected to be of size CAST5_BLOCKSIZE. */ static void _gcry_cast5_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { CAST5_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char tmpbuf[CAST5_BLOCKSIZE * 3]; int burn_stack_depth = (20 + 4 * sizeof(void*)) + 4 * CAST5_BLOCKSIZE; #ifdef USE_AMD64_ASM { if (nblocks >= 4) burn_stack_depth += 8 * sizeof(void*); /* Process data in 4 block chunks. */ while (nblocks >= 4) { cast5_amd64_ctr_enc(ctx, outbuf, inbuf, ctr); nblocks -= 4; outbuf += 4 * CAST5_BLOCKSIZE; inbuf += 4 * CAST5_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #elif defined(USE_ARM_ASM) { /* Process data in 2 block chunks. */ while (nblocks >= 2) { _gcry_cast5_arm_ctr_enc(ctx, outbuf, inbuf, ctr); nblocks -= 2; outbuf += 2 * CAST5_BLOCKSIZE; inbuf += 2 * CAST5_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #endif #if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) for ( ;nblocks >= 3; nblocks -= 3) { /* Prepare the counter blocks. */ cipher_block_cpy (tmpbuf + 0, ctr, CAST5_BLOCKSIZE); cipher_block_cpy (tmpbuf + 8, ctr, CAST5_BLOCKSIZE); cipher_block_cpy (tmpbuf + 16, ctr, CAST5_BLOCKSIZE); cipher_block_add (tmpbuf + 8, 1, CAST5_BLOCKSIZE); cipher_block_add (tmpbuf + 16, 2, CAST5_BLOCKSIZE); cipher_block_add (ctr, 3, CAST5_BLOCKSIZE); /* Encrypt the counter. */ do_encrypt_block_3(ctx, tmpbuf, tmpbuf); /* XOR the input with the encrypted counter and store in output. */ buf_xor(outbuf, tmpbuf, inbuf, CAST5_BLOCKSIZE * 3); outbuf += CAST5_BLOCKSIZE * 3; inbuf += CAST5_BLOCKSIZE * 3; } #endif for ( ;nblocks; nblocks-- ) { /* Encrypt the counter. */ do_encrypt_block(ctx, tmpbuf, ctr); /* XOR the input with the encrypted counter and store in output. */ cipher_block_xor(outbuf, tmpbuf, inbuf, CAST5_BLOCKSIZE); outbuf += CAST5_BLOCKSIZE; inbuf += CAST5_BLOCKSIZE; /* Increment the counter. */ cipher_block_add (ctr, 1, CAST5_BLOCKSIZE); } wipememory(tmpbuf, sizeof(tmpbuf)); _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CBC mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_cast5_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { CAST5_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char savebuf[CAST5_BLOCKSIZE * 3]; int burn_stack_depth = (20 + 4 * sizeof(void*)) + 4 * CAST5_BLOCKSIZE; #ifdef USE_AMD64_ASM { if (nblocks >= 4) burn_stack_depth += 8 * sizeof(void*); /* Process data in 4 block chunks. */ while (nblocks >= 4) { cast5_amd64_cbc_dec(ctx, outbuf, inbuf, iv); nblocks -= 4; outbuf += 4 * CAST5_BLOCKSIZE; inbuf += 4 * CAST5_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #elif defined(USE_ARM_ASM) { /* Process data in 2 block chunks. */ while (nblocks >= 2) { _gcry_cast5_arm_cbc_dec(ctx, outbuf, inbuf, iv); nblocks -= 2; outbuf += 2 * CAST5_BLOCKSIZE; inbuf += 2 * CAST5_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #endif #if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) for ( ;nblocks >= 3; nblocks -= 3) { /* INBUF is needed later and it may be identical to OUTBUF, so store the intermediate result to SAVEBUF. */ do_decrypt_block_3 (ctx, savebuf, inbuf); cipher_block_xor_1 (savebuf + 0, iv, CAST5_BLOCKSIZE); cipher_block_xor_1 (savebuf + 8, inbuf, CAST5_BLOCKSIZE * 2); cipher_block_cpy (iv, inbuf + 16, CAST5_BLOCKSIZE); buf_cpy (outbuf, savebuf, CAST5_BLOCKSIZE * 3); inbuf += CAST5_BLOCKSIZE * 3; outbuf += CAST5_BLOCKSIZE * 3; } #endif for ( ;nblocks; nblocks-- ) { /* INBUF is needed later and it may be identical to OUTBUF, so store the intermediate result to SAVEBUF. */ do_decrypt_block (ctx, savebuf, inbuf); cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, CAST5_BLOCKSIZE); inbuf += CAST5_BLOCKSIZE; outbuf += CAST5_BLOCKSIZE; } wipememory(savebuf, sizeof(savebuf)); _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CFB mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_cast5_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { CAST5_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char tmpbuf[CAST5_BLOCKSIZE * 3]; int burn_stack_depth = (20 + 4 * sizeof(void*)) + 4 * CAST5_BLOCKSIZE; #ifdef USE_AMD64_ASM { if (nblocks >= 4) burn_stack_depth += 8 * sizeof(void*); /* Process data in 4 block chunks. */ while (nblocks >= 4) { cast5_amd64_cfb_dec(ctx, outbuf, inbuf, iv); nblocks -= 4; outbuf += 4 * CAST5_BLOCKSIZE; inbuf += 4 * CAST5_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #elif defined(USE_ARM_ASM) { /* Process data in 2 block chunks. */ while (nblocks >= 2) { _gcry_cast5_arm_cfb_dec(ctx, outbuf, inbuf, iv); nblocks -= 2; outbuf += 2 * CAST5_BLOCKSIZE; inbuf += 2 * CAST5_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #endif #if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) for ( ;nblocks >= 3; nblocks -= 3 ) { cipher_block_cpy (tmpbuf + 0, iv, CAST5_BLOCKSIZE); cipher_block_cpy (tmpbuf + 8, inbuf + 0, CAST5_BLOCKSIZE * 2); cipher_block_cpy (iv, inbuf + 16, CAST5_BLOCKSIZE); do_encrypt_block_3 (ctx, tmpbuf, tmpbuf); buf_xor (outbuf, inbuf, tmpbuf, CAST5_BLOCKSIZE * 3); outbuf += CAST5_BLOCKSIZE * 3; inbuf += CAST5_BLOCKSIZE * 3; } #endif for ( ;nblocks; nblocks-- ) { do_encrypt_block(ctx, iv, iv); cipher_block_xor_n_copy(outbuf, iv, inbuf, CAST5_BLOCKSIZE); outbuf += CAST5_BLOCKSIZE; inbuf += CAST5_BLOCKSIZE; } wipememory(tmpbuf, sizeof(tmpbuf)); _gcry_burn_stack(burn_stack_depth); } -/* Run the self-tests for CAST5-CTR, tests IV increment of bulk CTR - encryption. Returns NULL on success. */ -static const char * -selftest_ctr (void) -{ - const int nblocks = 4+1; - const int blocksize = CAST5_BLOCKSIZE; - const int context_size = sizeof(CAST5_context); - - return _gcry_selftest_helper_ctr("CAST5", &cast_setkey, - &encrypt_block, nblocks, blocksize, context_size); -} - - -/* Run the self-tests for CAST5-CBC, tests bulk CBC decryption. - Returns NULL on success. */ -static const char * -selftest_cbc (void) -{ - const int nblocks = 4+2; - const int blocksize = CAST5_BLOCKSIZE; - const int context_size = sizeof(CAST5_context); - - return _gcry_selftest_helper_cbc("CAST5", &cast_setkey, - &encrypt_block, nblocks, blocksize, context_size); -} - - -/* Run the self-tests for CAST5-CFB, tests bulk CBC decryption. - Returns NULL on success. */ -static const char * -selftest_cfb (void) -{ - const int nblocks = 4+2; - const int blocksize = CAST5_BLOCKSIZE; - const int context_size = sizeof(CAST5_context); - - return _gcry_selftest_helper_cfb("CAST5", &cast_setkey, - &encrypt_block, nblocks, blocksize, context_size); -} - - static const char* selftest(void) { CAST5_context c; cipher_bulk_ops_t bulk_ops; static const byte key[16] = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A }; static const byte plain[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; static const byte cipher[8] = { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 }; byte buffer[8]; - const char *r; cast_setkey( &c, key, 16, &bulk_ops ); encrypt_block( &c, buffer, plain ); if( memcmp( buffer, cipher, 8 ) ) return "1"; decrypt_block( &c, buffer, buffer ); if( memcmp( buffer, plain, 8 ) ) return "2"; #if 0 /* full maintenance test */ { int i; byte a0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78, 0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A }; byte b0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78, 0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A }; byte a1[16] = { 0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6, 0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92 }; byte b1[16] = { 0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71, 0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E }; for(i=0; i < 1000000; i++ ) { cast_setkey( &c, b0, 16, &bulk_ops ); encrypt_block( &c, a0, a0 ); encrypt_block( &c, a0+8, a0+8 ); cast_setkey( &c, a0, 16, &bulk_ops ); encrypt_block( &c, b0, b0 ); encrypt_block( &c, b0+8, b0+8 ); } if( memcmp( a0, a1, 16 ) || memcmp( b0, b1, 16 ) ) return "3"; } #endif - if ( (r = selftest_cbc ()) ) - return r; - - if ( (r = selftest_cfb ()) ) - return r; - - if ( (r = selftest_ctr ()) ) - return r; - return NULL; } static void key_schedule( u32 *x, u32 *z, u32 *k ) { #define xi(i) ((x[(i)/4] >> (8*(3-((i)%4)))) & 0xff) #define zi(i) ((z[(i)/4] >> (8*(3-((i)%4)))) & 0xff) z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)]; z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)]; z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)]; z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)]; k[0] = s5[zi( 8)]^s6[zi( 9)]^s7[zi( 7)]^s8[zi( 6)]^s5[zi( 2)]; k[1] = s5[zi(10)]^s6[zi(11)]^s7[zi( 5)]^s8[zi( 4)]^s6[zi( 6)]; k[2] = s5[zi(12)]^s6[zi(13)]^s7[zi( 3)]^s8[zi( 2)]^s7[zi( 9)]; k[3] = s5[zi(14)]^s6[zi(15)]^s7[zi( 1)]^s8[zi( 0)]^s8[zi(12)]; x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)]; x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)]; x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)]; x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)]; k[4] = s5[xi( 3)]^s6[xi( 2)]^s7[xi(12)]^s8[xi(13)]^s5[xi( 8)]; k[5] = s5[xi( 1)]^s6[xi( 0)]^s7[xi(14)]^s8[xi(15)]^s6[xi(13)]; k[6] = s5[xi( 7)]^s6[xi( 6)]^s7[xi( 8)]^s8[xi( 9)]^s7[xi( 3)]; k[7] = s5[xi( 5)]^s6[xi( 4)]^s7[xi(10)]^s8[xi(11)]^s8[xi( 7)]; z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)]; z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)]; z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)]; z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)]; k[8] = s5[zi( 3)]^s6[zi( 2)]^s7[zi(12)]^s8[zi(13)]^s5[zi( 9)]; k[9] = s5[zi( 1)]^s6[zi( 0)]^s7[zi(14)]^s8[zi(15)]^s6[zi(12)]; k[10]= s5[zi( 7)]^s6[zi( 6)]^s7[zi( 8)]^s8[zi( 9)]^s7[zi( 2)]; k[11]= s5[zi( 5)]^s6[zi( 4)]^s7[zi(10)]^s8[zi(11)]^s8[zi( 6)]; x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)]; x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)]; x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)]; x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)]; k[12]= s5[xi( 8)]^s6[xi( 9)]^s7[xi( 7)]^s8[xi( 6)]^s5[xi( 3)]; k[13]= s5[xi(10)]^s6[xi(11)]^s7[xi( 5)]^s8[xi( 4)]^s6[xi( 7)]; k[14]= s5[xi(12)]^s6[xi(13)]^s7[xi( 3)]^s8[xi( 2)]^s7[xi( 8)]; k[15]= s5[xi(14)]^s6[xi(15)]^s7[xi( 1)]^s8[xi( 0)]^s8[xi(13)]; #undef xi #undef zi } static gcry_err_code_t do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen ) { static int initialized; static const char* selftest_failed; int i; u32 x[4]; u32 z[4]; u32 k[16]; if( !initialized ) { initialized = 1; selftest_failed = selftest(); if( selftest_failed ) log_error ("CAST5 selftest failed (%s).\n", selftest_failed ); } if( selftest_failed ) return GPG_ERR_SELFTEST_FAILED; if( keylen != 16 ) return GPG_ERR_INV_KEYLEN; x[0] = buf_get_be32(key + 0); x[1] = buf_get_be32(key + 4); x[2] = buf_get_be32(key + 8); x[3] = buf_get_be32(key + 12); key_schedule( x, z, k ); for(i=0; i < 16; i++ ) c->Km[i] = k[i]; key_schedule( x, z, k ); for(i=0; i < 16; i++ ) c->Kr[i] = k[i] & 0x1f; #ifdef USE_ARM_ASM for (i = 0; i < 4; i++) { byte Kr_arm[4]; /* Convert rotate left to rotate right and add shift left * by 2. */ Kr_arm[0] = ((32 - c->Kr[4 * i + 0]) - 2) & 0x1f; Kr_arm[1] = ((32 - c->Kr[4 * i + 1]) - 2) & 0x1f; Kr_arm[2] = ((32 - c->Kr[4 * i + 2]) - 2) & 0x1f; Kr_arm[3] = ((32 - c->Kr[4 * i + 3]) - 2) & 0x1f; /* Endian friendly store. */ c->Kr_arm_enc[i] = Kr_arm[0] | (Kr_arm[1] << 8) | (Kr_arm[2] << 16) | (Kr_arm[3] << 24); c->Kr_arm_dec[i] = Kr_arm[3] | (Kr_arm[2] << 8) | (Kr_arm[1] << 16) | (Kr_arm[0] << 24); wipememory(Kr_arm, sizeof(Kr_arm)); } #endif wipememory(x, sizeof x); wipememory(z, sizeof z); wipememory(k, sizeof k); #undef xi #undef zi return GPG_ERR_NO_ERROR; } static gcry_err_code_t cast_setkey (void *context, const byte *key, unsigned keylen, cipher_bulk_ops_t *bulk_ops) { CAST5_context *c = (CAST5_context *) context; gcry_err_code_t rc = do_cast_setkey (c, key, keylen); /* Setup bulk encryption routines. */ memset (bulk_ops, 0, sizeof(*bulk_ops)); bulk_ops->cfb_dec = _gcry_cast5_cfb_dec; bulk_ops->cbc_dec = _gcry_cast5_cbc_dec; bulk_ops->ctr_enc = _gcry_cast5_ctr_enc; return rc; } gcry_cipher_spec_t _gcry_cipher_spec_cast5 = { GCRY_CIPHER_CAST5, {0, 0}, "CAST5", NULL, NULL, CAST5_BLOCKSIZE, 128, sizeof (CAST5_context), cast_setkey, encrypt_block, decrypt_block }; diff --git a/cipher/cipher-selftest.c b/cipher/cipher-selftest.c deleted file mode 100644 index d7f38a42..00000000 --- a/cipher/cipher-selftest.c +++ /dev/null @@ -1,512 +0,0 @@ -/* cipher-selftest.c - Helper functions for bulk encryption selftests. - * Copyright (C) 2013,2020 Jussi Kivilinna - * - * 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 -#ifdef HAVE_SYSLOG -# include -#endif /*HAVE_SYSLOG*/ - -#include "types.h" -#include "g10lib.h" -#include "cipher.h" -#include "bufhelp.h" -#include "cipher-selftest.h" -#include "cipher-internal.h" - -#ifdef HAVE_STDINT_H -# include /* uintptr_t */ -#elif defined(HAVE_INTTYPES_H) -# include -#else -/* In this case, uintptr_t is provided by config.h. */ -#endif - -/* 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 - - -/* Return an allocated buffers of size CONTEXT_SIZE with an alignment - of 16. The caller must free that buffer using the address returned - at R_MEM. Returns NULL and sets ERRNO on failure. */ -void * -_gcry_cipher_selftest_alloc_ctx (const int context_size, unsigned char **r_mem) -{ - int offs; - unsigned int ctx_aligned_size, memsize; - - ctx_aligned_size = context_size + 15; - ctx_aligned_size -= ctx_aligned_size & 0xf; - - memsize = ctx_aligned_size + 16; - - *r_mem = xtrycalloc (1, memsize); - if (!*r_mem) - return NULL; - - offs = (16 - ((uintptr_t)*r_mem & 15)) & 15; - return (void*)(*r_mem + offs); -} - - -/* Run the self-tests for -CBC-, tests bulk CBC - decryption. Returns NULL on success. */ -const char * -_gcry_selftest_helper_cbc (const char *cipher, gcry_cipher_setkey_t setkey_func, - gcry_cipher_encrypt_t encrypt_one, - const int nblocks, const int blocksize, - const int context_size) -{ - cipher_bulk_ops_t bulk_ops = { 0, }; - int i, offs; - unsigned char *ctx, *plaintext, *plaintext2, *ciphertext, *iv, *iv2, *mem; - unsigned int ctx_aligned_size, memsize; - - static const unsigned char key[16] ATTR_ALIGNED_16 = { - 0x66,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, - 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x22 - }; - - /* Allocate buffers, align first two elements to 16 bytes and latter to - block size. */ - ctx_aligned_size = context_size + 15; - ctx_aligned_size -= ctx_aligned_size & 0xf; - - memsize = ctx_aligned_size + (blocksize * 2) + (blocksize * nblocks * 3) + 16; - - mem = xtrycalloc (1, memsize); - if (!mem) - return "failed to allocate memory"; - - offs = (16 - ((uintptr_t)mem & 15)) & 15; - ctx = (void*)(mem + offs); - iv = ctx + ctx_aligned_size; - iv2 = iv + blocksize; - plaintext = iv2 + blocksize; - plaintext2 = plaintext + nblocks * blocksize; - ciphertext = plaintext2 + nblocks * blocksize; - - /* Initialize ctx */ - if (setkey_func (ctx, key, sizeof(key), &bulk_ops) != GPG_ERR_NO_ERROR) - { - xfree(mem); - return "setkey failed"; - } - - /* Test single block code path */ - memset (iv, 0x4e, blocksize); - memset (iv2, 0x4e, blocksize); - for (i = 0; i < blocksize; i++) - plaintext[i] = i; - - /* CBC manually. */ - buf_xor (ciphertext, iv, plaintext, blocksize); - encrypt_one (ctx, ciphertext, ciphertext); - memcpy (iv, ciphertext, blocksize); - - /* CBC decrypt. */ - bulk_ops.cbc_dec (ctx, iv2, plaintext2, ciphertext, 1); - if (memcmp (plaintext2, plaintext, blocksize)) - { - xfree (mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CBC-%d test failed (plaintext mismatch)", cipher, - blocksize * 8); -#else - (void)cipher; /* Not used. */ -#endif - return "selftest for CBC failed - see syslog for details"; - } - - if (memcmp (iv2, iv, blocksize)) - { - xfree (mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CBC-%d test failed (IV mismatch)", cipher, blocksize * 8); -#endif - return "selftest for CBC failed - see syslog for details"; - } - - /* Test parallelized code paths */ - memset (iv, 0x5f, blocksize); - memset (iv2, 0x5f, blocksize); - - for (i = 0; i < nblocks * blocksize; i++) - plaintext[i] = i; - - /* Create CBC ciphertext manually. */ - for (i = 0; i < nblocks * blocksize; i+=blocksize) - { - buf_xor (&ciphertext[i], iv, &plaintext[i], blocksize); - encrypt_one (ctx, &ciphertext[i], &ciphertext[i]); - memcpy (iv, &ciphertext[i], blocksize); - } - - /* Decrypt using bulk CBC and compare result. */ - bulk_ops.cbc_dec (ctx, iv2, plaintext2, ciphertext, nblocks); - - if (memcmp (plaintext2, plaintext, nblocks * blocksize)) - { - xfree (mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CBC-%d test failed (plaintext mismatch, parallel path)", - cipher, blocksize * 8); -#endif - return "selftest for CBC failed - see syslog for details"; - } - if (memcmp (iv2, iv, blocksize)) - { - xfree (mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CBC-%d test failed (IV mismatch, parallel path)", - cipher, blocksize * 8); -#endif - return "selftest for CBC failed - see syslog for details"; - } - - xfree (mem); - return NULL; -} - -/* Run the self-tests for -CFB-, tests bulk CFB - decryption. Returns NULL on success. */ -const char * -_gcry_selftest_helper_cfb (const char *cipher, gcry_cipher_setkey_t setkey_func, - gcry_cipher_encrypt_t encrypt_one, - const int nblocks, const int blocksize, - const int context_size) -{ - cipher_bulk_ops_t bulk_ops = { 0, }; - int i, offs; - unsigned char *ctx, *plaintext, *plaintext2, *ciphertext, *iv, *iv2, *mem; - unsigned int ctx_aligned_size, memsize; - - static const unsigned char key[16] ATTR_ALIGNED_16 = { - 0x11,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, - 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x33 - }; - - /* Allocate buffers, align first two elements to 16 bytes and latter to - block size. */ - ctx_aligned_size = context_size + 15; - ctx_aligned_size -= ctx_aligned_size & 0xf; - - memsize = ctx_aligned_size + (blocksize * 2) + (blocksize * nblocks * 3) + 16; - - mem = xtrycalloc (1, memsize); - if (!mem) - return "failed to allocate memory"; - - offs = (16 - ((uintptr_t)mem & 15)) & 15; - ctx = (void*)(mem + offs); - iv = ctx + ctx_aligned_size; - iv2 = iv + blocksize; - plaintext = iv2 + blocksize; - plaintext2 = plaintext + nblocks * blocksize; - ciphertext = plaintext2 + nblocks * blocksize; - - /* Initialize ctx */ - if (setkey_func (ctx, key, sizeof(key), &bulk_ops) != GPG_ERR_NO_ERROR) - { - xfree(mem); - return "setkey failed"; - } - - /* Test single block code path */ - memset(iv, 0xd3, blocksize); - memset(iv2, 0xd3, blocksize); - for (i = 0; i < blocksize; i++) - plaintext[i] = i; - - /* CFB manually. */ - encrypt_one (ctx, ciphertext, iv); - buf_xor_2dst (iv, ciphertext, plaintext, blocksize); - - /* CFB decrypt. */ - bulk_ops.cfb_dec (ctx, iv2, plaintext2, ciphertext, 1); - if (memcmp(plaintext2, plaintext, blocksize)) - { - xfree(mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CFB-%d test failed (plaintext mismatch)", cipher, - blocksize * 8); -#else - (void)cipher; /* Not used. */ -#endif - return "selftest for CFB failed - see syslog for details"; - } - - if (memcmp(iv2, iv, blocksize)) - { - xfree(mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CFB-%d test failed (IV mismatch)", cipher, blocksize * 8); -#endif - return "selftest for CFB failed - see syslog for details"; - } - - /* Test parallelized code paths */ - memset(iv, 0xe6, blocksize); - memset(iv2, 0xe6, blocksize); - - for (i = 0; i < nblocks * blocksize; i++) - plaintext[i] = i; - - /* Create CFB ciphertext manually. */ - for (i = 0; i < nblocks * blocksize; i+=blocksize) - { - encrypt_one (ctx, &ciphertext[i], iv); - buf_xor_2dst (iv, &ciphertext[i], &plaintext[i], blocksize); - } - - /* Decrypt using bulk CBC and compare result. */ - bulk_ops.cfb_dec (ctx, iv2, plaintext2, ciphertext, nblocks); - - if (memcmp(plaintext2, plaintext, nblocks * blocksize)) - { - xfree(mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CFB-%d test failed (plaintext mismatch, parallel path)", - cipher, blocksize * 8); -#endif - return "selftest for CFB failed - see syslog for details"; - } - if (memcmp(iv2, iv, blocksize)) - { - xfree(mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CFB-%d test failed (IV mismatch, parallel path)", cipher, - blocksize * 8); -#endif - return "selftest for CFB failed - see syslog for details"; - } - - xfree(mem); - return NULL; -} - -/* Run the self-tests for -CTR-, tests IV increment - of bulk CTR encryption. Returns NULL on success. */ -const char * -_gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func, - gcry_cipher_encrypt_t encrypt_one, - const int nblocks, const int blocksize, - const int context_size) -{ - cipher_bulk_ops_t bulk_ops = { 0, }; - int i, j, offs, diff; - unsigned char *ctx, *plaintext, *plaintext2, *ciphertext, *ciphertext2, - *iv, *iv2, *mem; - unsigned int ctx_aligned_size, memsize; - - static const unsigned char key[16] ATTR_ALIGNED_16 = { - 0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, - 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21 - }; - - /* Allocate buffers, align first two elements to 16 bytes and latter to - block size. */ - ctx_aligned_size = context_size + 15; - ctx_aligned_size -= ctx_aligned_size & 0xf; - - memsize = ctx_aligned_size + (blocksize * 2) + (blocksize * nblocks * 4) + 16; - - mem = xtrycalloc (1, memsize); - if (!mem) - return "failed to allocate memory"; - - offs = (16 - ((uintptr_t)mem & 15)) & 15; - ctx = (void*)(mem + offs); - iv = ctx + ctx_aligned_size; - iv2 = iv + blocksize; - plaintext = iv2 + blocksize; - plaintext2 = plaintext + nblocks * blocksize; - ciphertext = plaintext2 + nblocks * blocksize; - ciphertext2 = ciphertext + nblocks * blocksize; - - /* Initialize ctx */ - if (setkey_func (ctx, key, sizeof(key), &bulk_ops) != GPG_ERR_NO_ERROR) - { - xfree(mem); - return "setkey failed"; - } - - /* Test single block code path */ - memset (iv, 0xff, blocksize); - for (i = 0; i < blocksize; i++) - plaintext[i] = i; - - /* CTR manually. */ - encrypt_one (ctx, ciphertext, iv); - for (i = 0; i < blocksize; i++) - ciphertext[i] ^= plaintext[i]; - for (i = blocksize; i > 0; i--) - { - iv[i-1]++; - if (iv[i-1]) - break; - } - - memset (iv2, 0xff, blocksize); - bulk_ops.ctr_enc (ctx, iv2, plaintext2, ciphertext, 1); - - if (memcmp (plaintext2, plaintext, blocksize)) - { - xfree (mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CTR-%d test failed (plaintext mismatch)", cipher, - blocksize * 8); -#else - (void)cipher; /* Not used. */ -#endif - return "selftest for CTR failed - see syslog for details"; - } - - if (memcmp (iv2, iv, blocksize)) - { - xfree (mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CTR-%d test failed (IV mismatch)", cipher, - blocksize * 8); -#endif - return "selftest for CTR failed - see syslog for details"; - } - - /* Test bulk encryption with typical IV. */ - memset(iv, 0x57, blocksize-4); - iv[blocksize-1] = 1; - iv[blocksize-2] = 0; - iv[blocksize-3] = 0; - iv[blocksize-4] = 0; - memset(iv2, 0x57, blocksize-4); - iv2[blocksize-1] = 1; - iv2[blocksize-2] = 0; - iv2[blocksize-3] = 0; - iv2[blocksize-4] = 0; - - for (i = 0; i < blocksize * nblocks; i++) - plaintext2[i] = plaintext[i] = i; - - /* Create CTR ciphertext manually. */ - for (i = 0; i < blocksize * nblocks; i+=blocksize) - { - encrypt_one (ctx, &ciphertext[i], iv); - for (j = 0; j < blocksize; j++) - ciphertext[i+j] ^= plaintext[i+j]; - for (j = blocksize; j > 0; j--) - { - iv[j-1]++; - if (iv[j-1]) - break; - } - } - - bulk_ops.ctr_enc (ctx, iv2, ciphertext2, plaintext2, nblocks); - - if (memcmp (ciphertext2, ciphertext, blocksize * nblocks)) - { - xfree (mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CTR-%d test failed (ciphertext mismatch, bulk)", cipher, - blocksize * 8); -#endif - return "selftest for CTR failed - see syslog for details"; - } - if (memcmp(iv2, iv, blocksize)) - { - xfree (mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CTR-%d test failed (IV mismatch, bulk)", cipher, - blocksize * 8); -#endif - return "selftest for CTR failed - see syslog for details"; - } - - /* Test parallelized code paths (check counter overflow handling) */ - for (diff = 0; diff < nblocks; diff++) { - memset(iv, 0xff, blocksize); - iv[blocksize-1] -= diff; - iv[0] = iv[1] = 0; - iv[2] = 0x07; - - for (i = 0; i < blocksize * nblocks; i++) - plaintext[i] = i; - - /* Create CTR ciphertext manually. */ - for (i = 0; i < blocksize * nblocks; i+=blocksize) - { - encrypt_one (ctx, &ciphertext[i], iv); - for (j = 0; j < blocksize; j++) - ciphertext[i+j] ^= plaintext[i+j]; - for (j = blocksize; j > 0; j--) - { - iv[j-1]++; - if (iv[j-1]) - break; - } - } - - /* Decrypt using bulk CTR and compare result. */ - memset(iv2, 0xff, blocksize); - iv2[blocksize-1] -= diff; - iv2[0] = iv2[1] = 0; - iv2[2] = 0x07; - - bulk_ops.ctr_enc (ctx, iv2, plaintext2, ciphertext, nblocks); - - if (memcmp (plaintext2, plaintext, blocksize * nblocks)) - { - xfree (mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CTR-%d test failed (plaintext mismatch, diff: %d)", cipher, - blocksize * 8, diff); -#endif - return "selftest for CTR failed - see syslog for details"; - } - if (memcmp(iv2, iv, blocksize)) - { - xfree (mem); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s-CTR-%d test failed (IV mismatch, diff: %d)", cipher, - blocksize * 8, diff); -#endif - return "selftest for CTR failed - see syslog for details"; - } - } - - xfree (mem); - return NULL; -} diff --git a/cipher/cipher-selftest.h b/cipher/cipher-selftest.h deleted file mode 100644 index c3090ad1..00000000 --- a/cipher/cipher-selftest.h +++ /dev/null @@ -1,69 +0,0 @@ -/* cipher-selftest.h - Helper functions for bulk encryption selftests. - * Copyright (C) 2013,2020 Jussi Kivilinna - * - * 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_SELFTEST_HELP_H -#define G10_SELFTEST_HELP_H - -#include -#include "types.h" -#include "g10lib.h" -#include "cipher.h" - -typedef void (*gcry_cipher_bulk_cbc_dec_t)(void *context, unsigned char *iv, - void *outbuf_arg, - const void *inbuf_arg, - size_t nblocks); - -typedef void (*gcry_cipher_bulk_cfb_dec_t)(void *context, unsigned char *iv, - void *outbuf_arg, - const void *inbuf_arg, - size_t nblocks); - -typedef void (*gcry_cipher_bulk_ctr_enc_t)(void *context, unsigned char *iv, - void *outbuf_arg, - const void *inbuf_arg, - size_t nblocks); - -/* Helper function to allocate an aligned context for selftests. */ -void *_gcry_cipher_selftest_alloc_ctx (const int context_size, - unsigned char **r_mem); - - -/* Helper function for bulk CBC decryption selftest */ -const char * -_gcry_selftest_helper_cbc (const char *cipher, gcry_cipher_setkey_t setkey, - gcry_cipher_encrypt_t encrypt_one, - const int nblocks, const int blocksize, - const int context_size); - -/* Helper function for bulk CFB decryption selftest */ -const char * -_gcry_selftest_helper_cfb (const char *cipher, gcry_cipher_setkey_t setkey, - gcry_cipher_encrypt_t encrypt_one, - const int nblocks, const int blocksize, - const int context_size); - -/* Helper function for bulk CTR encryption selftest */ -const char * -_gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey, - gcry_cipher_encrypt_t encrypt_one, - const int nblocks, const int blocksize, - const int context_size); - -#endif /*G10_SELFTEST_HELP_H*/ diff --git a/cipher/des.c b/cipher/des.c index 51116fcf..7a81697a 100644 --- a/cipher/des.c +++ b/cipher/des.c @@ -1,1507 +1,1435 @@ /* des.c - DES and Triple-DES encryption/decryption Algorithm * Copyright (C) 1998, 1999, 2001, 2002, 2003, * 2008 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * For a description of triple encryption, see: * Bruce Schneier: Applied Cryptography. Second Edition. * John Wiley & Sons, 1996. ISBN 0-471-12845-7. Pages 358 ff. * This implementation is according to the definition of DES in FIPS * PUB 46-2 from December 1993. */ /* * Written by Michael Roth , September 1998 */ /* * U S A G E * =========== * * For DES or Triple-DES encryption/decryption you must initialize a proper * encryption context with a key. * * A DES key is 64bit wide but only 56bits of the key are used. The remaining * bits are parity bits and they will _not_ checked in this implementation, but * simply ignored. * * For Triple-DES you could use either two 64bit keys or three 64bit keys. * The parity bits will _not_ checked, too. * * After initializing a context with a key you could use this context to * encrypt or decrypt data in 64bit blocks in Electronic Codebook Mode. * * (In the examples below the slashes at the beginning and ending of comments * are omitted.) * * DES Example * ----------- * unsigned char key[8]; * unsigned char plaintext[8]; * unsigned char ciphertext[8]; * unsigned char recoverd[8]; * des_ctx context; * * * Fill 'key' and 'plaintext' with some data * * .... * * * Set up the DES encryption context * * des_setkey(context, key); * * * Encrypt the plaintext * * des_ecb_encrypt(context, plaintext, ciphertext); * * * To recover the original plaintext from ciphertext use: * * des_ecb_decrypt(context, ciphertext, recoverd); * * * Triple-DES Example * ------------------ * unsigned char key1[8]; * unsigned char key2[8]; * unsigned char key3[8]; * unsigned char plaintext[8]; * unsigned char ciphertext[8]; * unsigned char recoverd[8]; * tripledes_ctx context; * * * If you would like to use two 64bit keys, fill 'key1' and'key2' * then setup the encryption context: * * tripledes_set2keys(context, key1, key2); * * * To use three 64bit keys with Triple-DES use: * * tripledes_set3keys(context, key1, key2, key3); * * * Encrypting plaintext with Triple-DES * * tripledes_ecb_encrypt(context, plaintext, ciphertext); * * * Decrypting ciphertext to recover the plaintext with Triple-DES * * tripledes_ecb_decrypt(context, ciphertext, recoverd); * * * Selftest * -------- * char *error_msg; * * * To perform a selftest of this DES/Triple-DES implementation use the * function selftest(). It will return an error string if there are * some problems with this library. * * * if ( (error_msg = selftest()) ) * { * fprintf(stderr, "An error in the DES/Triple-DES implementation occurred: %s\n", error_msg); * abort(); * } */ #include #include #include /* memcpy, memcmp */ #include "types.h" /* for byte and u32 typedefs */ #include "g10lib.h" #include "cipher.h" #include "bufhelp.h" #include "cipher-internal.h" -#include "cipher-selftest.h" #define DES_BLOCKSIZE 8 /* 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 /* 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 #if defined(__GNUC__) && defined(__GNU_LIBRARY__) # define working_memcmp memcmp #else /* * According to the SunOS man page, memcmp returns indeterminate sign * depending on whether characters are signed or not. */ static int working_memcmp( const void *_a, const void *_b, size_t n ) { const char *a = _a; const char *b = _b; for( ; n; n--, a++, b++ ) if( *a != *b ) return (int)(*(byte*)a) - (int)(*(byte*)b); return 0; } #endif /* * Encryption/Decryption context of DES */ typedef struct _des_ctx { u32 encrypt_subkeys[32]; u32 decrypt_subkeys[32]; } des_ctx[1]; /* * Encryption/Decryption context of Triple-DES */ typedef struct _tripledes_ctx { u32 encrypt_subkeys[96]; u32 decrypt_subkeys[96]; struct { int no_weak_key; } flags; } tripledes_ctx[1]; static void des_key_schedule (const byte *, u32 *); static int des_setkey (struct _des_ctx *, const byte *); static int des_ecb_crypt (struct _des_ctx *, const byte *, byte *, int); static int tripledes_set2keys (struct _tripledes_ctx *, const byte *, const byte *); static int tripledes_set3keys (struct _tripledes_ctx *, const byte *, const byte *, const byte *); static int tripledes_ecb_crypt (struct _tripledes_ctx *, const byte *, byte *, int); static int is_weak_key ( const byte *key ); static const char *selftest (void); static unsigned int do_tripledes_encrypt(void *context, byte *outbuf, const byte *inbuf ); static unsigned int do_tripledes_decrypt(void *context, byte *outbuf, const byte *inbuf ); static gcry_err_code_t do_tripledes_setkey(void *context, const byte *key, unsigned keylen, cipher_bulk_ops_t *bulk_ops); static int initialized; /* * The s-box values are permuted according to the 'primitive function P' * and are rotated one bit to the left. */ static u32 sbox1[64] = { 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004 }; static u32 sbox2[64] = { 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000 }; static u32 sbox3[64] = { 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200 }; static u32 sbox4[64] = { 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080 }; static u32 sbox5[64] = { 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100 }; static u32 sbox6[64] = { 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010 }; static u32 sbox7[64] = { 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002 }; static u32 sbox8[64] = { 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000 }; /* * These two tables are part of the 'permuted choice 1' function. * In this implementation several speed improvements are done. */ static u32 leftkey_swap[16] = { 0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00010000, 0x00010001, 0x00010100, 0x00010101, 0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01010000, 0x01010001, 0x01010100, 0x01010101 }; static u32 rightkey_swap[16] = { 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101, }; /* * Numbers of left shifts per round for encryption subkeys. * To calculate the decryption subkeys we just reverse the * ordering of the calculated encryption subkeys. So their * is no need for a decryption rotate tab. */ static byte encrypt_rotate_tab[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; /* * Table with weak DES keys sorted in ascending order. * In DES their are 64 known keys which are weak. They are weak * because they produce only one, two or four different * subkeys in the subkey scheduling process. * The keys in this table have all their parity bits cleared. */ static byte weak_keys[64][8] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*w*/ { 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e }, { 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0 }, { 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe }, { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e }, /*sw*/ { 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00 }, { 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe }, { 0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0 }, { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0 }, /*sw*/ { 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe }, { 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00 }, { 0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e }, { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe }, /*sw*/ { 0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0 }, { 0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e }, { 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00 }, { 0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e }, { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 }, /*sw*/ { 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe }, { 0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0 }, { 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00 }, { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e }, /*w*/ { 0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0 }, { 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe }, { 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe }, { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 }, /*sw*/ { 0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e }, { 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00 }, { 0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0 }, { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe }, /*sw*/ { 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00 }, { 0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e }, { 0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0 }, { 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe }, { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 }, /*sw*/ { 0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e }, { 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe }, { 0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0 }, { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e }, /*sw*/ { 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00 }, { 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00 }, { 0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e }, { 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 }, /*w*/ { 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe }, { 0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e }, { 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00 }, { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe }, /*sw*/ { 0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0 }, { 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe }, { 0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0 }, { 0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e }, { 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00 }, /*sw*/ { 0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0 }, { 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe }, { 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00 }, { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e }, /*sw*/ { 0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e }, { 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00 }, { 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe }, { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 }, /*sw*/ { 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00 }, { 0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e }, { 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0 }, { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe } /*w*/ }; static unsigned char weak_keys_chksum[20] = { 0xD0, 0xCF, 0x07, 0x38, 0x93, 0x70, 0x8A, 0x83, 0x7D, 0xD7, 0x8A, 0x36, 0x65, 0x29, 0x6C, 0x1F, 0x7C, 0x3F, 0xD3, 0x41 }; /* * Macro to swap bits across two words. */ #define DO_PERMUTATION(a, temp, b, offset, mask) \ temp = ((a>>offset) ^ b) & mask; \ b ^= temp; \ a ^= temp<> 31); \ temp = (left ^ right) & 0xaaaaaaaa; \ right ^= temp; \ left ^= temp; \ left = (left << 1) | (left >> 31); /* * The 'inverse initial permutation'. */ #define FINAL_PERMUTATION(left, temp, right) \ left = (left << 31) | (left >> 1); \ temp = (left ^ right) & 0xaaaaaaaa; \ left ^= temp; \ right ^= temp; \ right = (right << 31) | (right >> 1); \ DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \ DO_PERMUTATION(right, temp, left, 2, 0x33333333) \ DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \ DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) /* * A full DES round including 'expansion function', 'sbox substitution' * and 'primitive function P' but without swapping the left and right word. * Please note: The data in 'from' and 'to' is already rotated one bit to * the left, done in the initial permutation. */ #define DES_ROUND(from, to, work, subkey) \ work = from ^ *subkey++; \ to ^= sbox8[ work & 0x3f ]; \ to ^= sbox6[ (work>>8) & 0x3f ]; \ to ^= sbox4[ (work>>16) & 0x3f ]; \ to ^= sbox2[ (work>>24) & 0x3f ]; \ work = ((from << 28) | (from >> 4)) ^ *subkey++; \ to ^= sbox7[ work & 0x3f ]; \ to ^= sbox5[ (work>>8) & 0x3f ]; \ to ^= sbox3[ (work>>16) & 0x3f ]; \ to ^= sbox1[ (work>>24) & 0x3f ]; /* * Macros to convert 8 bytes from/to 32bit words. */ #define READ_64BIT_DATA(data, left, right) \ left = buf_get_be32(data + 0); \ right = buf_get_be32(data + 4); #define WRITE_64BIT_DATA(data, left, right) \ buf_put_be32(data + 0, left); \ buf_put_be32(data + 4, right); /* * Handy macros for encryption and decryption of data */ #define des_ecb_encrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 0) #define des_ecb_decrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 1) #define tripledes_ecb_encrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,0) #define tripledes_ecb_decrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,1) /* * des_key_schedule(): Calculate 16 subkeys pairs (even/odd) for * 16 encryption rounds. * To calculate subkeys for decryption the caller * have to reorder the generated subkeys. * * rawkey: 8 Bytes of key data * subkey: Array of at least 32 u32s. Will be filled * with calculated subkeys. * */ static void des_key_schedule (const byte * rawkey, u32 * subkey) { u32 left, right, work; int round; READ_64BIT_DATA (rawkey, left, right) DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f) DO_PERMUTATION (right, work, left, 0, 0x10101010) left = ((leftkey_swap[(left >> 0) & 0xf] << 3) | (leftkey_swap[(left >> 8) & 0xf] << 2) | (leftkey_swap[(left >> 16) & 0xf] << 1) | (leftkey_swap[(left >> 24) & 0xf]) | (leftkey_swap[(left >> 5) & 0xf] << 7) | (leftkey_swap[(left >> 13) & 0xf] << 6) | (leftkey_swap[(left >> 21) & 0xf] << 5) | (leftkey_swap[(left >> 29) & 0xf] << 4)); left &= 0x0fffffff; right = ((rightkey_swap[(right >> 1) & 0xf] << 3) | (rightkey_swap[(right >> 9) & 0xf] << 2) | (rightkey_swap[(right >> 17) & 0xf] << 1) | (rightkey_swap[(right >> 25) & 0xf]) | (rightkey_swap[(right >> 4) & 0xf] << 7) | (rightkey_swap[(right >> 12) & 0xf] << 6) | (rightkey_swap[(right >> 20) & 0xf] << 5) | (rightkey_swap[(right >> 28) & 0xf] << 4)); right &= 0x0fffffff; for (round = 0; round < 16; ++round) { left = ((left << encrypt_rotate_tab[round]) | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff; right = ((right << encrypt_rotate_tab[round]) | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff; *subkey++ = (((left << 4) & 0x24000000) | ((left << 28) & 0x10000000) | ((left << 14) & 0x08000000) | ((left << 18) & 0x02080000) | ((left << 6) & 0x01000000) | ((left << 9) & 0x00200000) | ((left >> 1) & 0x00100000) | ((left << 10) & 0x00040000) | ((left << 2) & 0x00020000) | ((left >> 10) & 0x00010000) | ((right >> 13) & 0x00002000) | ((right >> 4) & 0x00001000) | ((right << 6) & 0x00000800) | ((right >> 1) & 0x00000400) | ((right >> 14) & 0x00000200) | (right & 0x00000100) | ((right >> 5) & 0x00000020) | ((right >> 10) & 0x00000010) | ((right >> 3) & 0x00000008) | ((right >> 18) & 0x00000004) | ((right >> 26) & 0x00000002) | ((right >> 24) & 0x00000001)); *subkey++ = (((left << 15) & 0x20000000) | ((left << 17) & 0x10000000) | ((left << 10) & 0x08000000) | ((left << 22) & 0x04000000) | ((left >> 2) & 0x02000000) | ((left << 1) & 0x01000000) | ((left << 16) & 0x00200000) | ((left << 11) & 0x00100000) | ((left << 3) & 0x00080000) | ((left >> 6) & 0x00040000) | ((left << 15) & 0x00020000) | ((left >> 4) & 0x00010000) | ((right >> 2) & 0x00002000) | ((right << 8) & 0x00001000) | ((right >> 14) & 0x00000808) | ((right >> 9) & 0x00000400) | ((right) & 0x00000200) | ((right << 7) & 0x00000100) | ((right >> 7) & 0x00000020) | ((right >> 3) & 0x00000011) | ((right << 2) & 0x00000004) | ((right >> 21) & 0x00000002)); } } /* * Fill a DES context with subkeys calculated from a 64bit key. * Does not check parity bits, but simply ignore them. * Does not check for weak keys. */ static int des_setkey (struct _des_ctx *ctx, const byte * key) { static const char *selftest_failed; int i; 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; des_key_schedule (key, ctx->encrypt_subkeys); _gcry_burn_stack (32); for(i=0; i<32; i+=2) { ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30-i]; ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i]; } return 0; } /* * Electronic Codebook Mode DES encryption/decryption of data according * to 'mode'. */ static int des_ecb_crypt (struct _des_ctx *ctx, const byte * from, byte * to, int mode) { u32 left, right, work; u32 *keys; keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys; READ_64BIT_DATA (from, left, right) INITIAL_PERMUTATION (left, work, right) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) FINAL_PERMUTATION (right, work, left) WRITE_64BIT_DATA (to, right, left) return 0; } /* * Fill a Triple-DES context with subkeys calculated from two 64bit keys. * Does not check the parity bits of the keys, but simply ignore them. * Does not check for weak keys. */ static int tripledes_set2keys (struct _tripledes_ctx *ctx, const byte * key1, const byte * key2) { int i; des_key_schedule (key1, ctx->encrypt_subkeys); des_key_schedule (key2, &(ctx->decrypt_subkeys[32])); _gcry_burn_stack (32); for(i=0; i<32; i+=2) { ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30-i]; ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i]; ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i]; ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i]; ctx->encrypt_subkeys[i+64] = ctx->encrypt_subkeys[i]; ctx->encrypt_subkeys[i+65] = ctx->encrypt_subkeys[i+1]; ctx->decrypt_subkeys[i+64] = ctx->decrypt_subkeys[i]; ctx->decrypt_subkeys[i+65] = ctx->decrypt_subkeys[i+1]; } return 0; } /* * Fill a Triple-DES context with subkeys calculated from three 64bit keys. * Does not check the parity bits of the keys, but simply ignore them. * Does not check for weak keys. */ static int tripledes_set3keys (struct _tripledes_ctx *ctx, const byte * key1, const byte * key2, const byte * key3) { static const char *selftest_failed; int i; 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; des_key_schedule (key1, ctx->encrypt_subkeys); des_key_schedule (key2, &(ctx->decrypt_subkeys[32])); des_key_schedule (key3, &(ctx->encrypt_subkeys[64])); _gcry_burn_stack (32); for(i=0; i<32; i+=2) { ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[94-i]; ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[95-i]; ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i]; ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i]; ctx->decrypt_subkeys[i+64] = ctx->encrypt_subkeys[30-i]; ctx->decrypt_subkeys[i+65] = ctx->encrypt_subkeys[31-i]; } return 0; } #ifdef USE_AMD64_ASM /* Assembly implementation of triple-DES. */ extern void _gcry_3des_amd64_crypt_block(const void *keys, byte *out, const byte *in); /* These assembly implementations process three blocks in parallel. */ extern void _gcry_3des_amd64_ctr_enc(const void *keys, byte *out, const byte *in, byte *ctr); extern void _gcry_3des_amd64_cbc_dec(const void *keys, byte *out, const byte *in, byte *iv); extern void _gcry_3des_amd64_cfb_dec(const void *keys, byte *out, const byte *in, byte *iv); #define TRIPLEDES_ECB_BURN_STACK (8 * sizeof(void *)) /* * Electronic Codebook Mode Triple-DES encryption/decryption of data * according to 'mode'. Sometimes this mode is named 'EDE' mode * (Encryption-Decryption-Encryption). */ static inline int tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, byte * to, int mode) { u32 *keys; keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys; _gcry_3des_amd64_crypt_block(keys, to, from); return 0; } static inline void tripledes_amd64_ctr_enc(const void *keys, byte *out, const byte *in, byte *ctr) { _gcry_3des_amd64_ctr_enc(keys, out, in, ctr); } static inline void tripledes_amd64_cbc_dec(const void *keys, byte *out, const byte *in, byte *iv) { _gcry_3des_amd64_cbc_dec(keys, out, in, iv); } static inline void tripledes_amd64_cfb_dec(const void *keys, byte *out, const byte *in, byte *iv) { _gcry_3des_amd64_cfb_dec(keys, out, in, iv); } #else /*USE_AMD64_ASM*/ #define TRIPLEDES_ECB_BURN_STACK 32 /* * Electronic Codebook Mode Triple-DES encryption/decryption of data * according to 'mode'. Sometimes this mode is named 'EDE' mode * (Encryption-Decryption-Encryption). */ static int tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, byte * to, int mode) { u32 left, right, work; u32 *keys; keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys; READ_64BIT_DATA (from, left, right) INITIAL_PERMUTATION (left, work, right) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) FINAL_PERMUTATION (right, work, left) WRITE_64BIT_DATA (to, right, left) return 0; } #endif /*!USE_AMD64_ASM*/ /* Bulk encryption of complete blocks in CTR mode. This function is only intended for the bulk encryption feature of cipher.c. CTR is expected to be of size DES_BLOCKSIZE. */ static void _gcry_3des_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { struct _tripledes_ctx *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char tmpbuf[DES_BLOCKSIZE]; int burn_stack_depth = TRIPLEDES_ECB_BURN_STACK; #ifdef USE_AMD64_ASM { int asm_burn_depth = 9 * sizeof(void *); if (nblocks >= 3 && burn_stack_depth < asm_burn_depth) burn_stack_depth = asm_burn_depth; /* Process data in 3 block chunks. */ while (nblocks >= 3) { tripledes_amd64_ctr_enc(ctx->encrypt_subkeys, outbuf, inbuf, ctr); nblocks -= 3; outbuf += 3 * DES_BLOCKSIZE; inbuf += 3 * DES_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #endif for ( ;nblocks; nblocks-- ) { /* Encrypt the counter. */ tripledes_ecb_encrypt (ctx, ctr, tmpbuf); /* XOR the input with the encrypted counter and store in output. */ cipher_block_xor(outbuf, tmpbuf, inbuf, DES_BLOCKSIZE); outbuf += DES_BLOCKSIZE; inbuf += DES_BLOCKSIZE; /* Increment the counter. */ cipher_block_add(ctr, 1, DES_BLOCKSIZE); } wipememory(tmpbuf, sizeof(tmpbuf)); _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CBC mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_3des_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { struct _tripledes_ctx *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char savebuf[DES_BLOCKSIZE]; int burn_stack_depth = TRIPLEDES_ECB_BURN_STACK; #ifdef USE_AMD64_ASM { int asm_burn_depth = 10 * sizeof(void *); if (nblocks >= 3 && burn_stack_depth < asm_burn_depth) burn_stack_depth = asm_burn_depth; /* Process data in 3 block chunks. */ while (nblocks >= 3) { tripledes_amd64_cbc_dec(ctx->decrypt_subkeys, outbuf, inbuf, iv); nblocks -= 3; outbuf += 3 * DES_BLOCKSIZE; inbuf += 3 * DES_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #endif for ( ;nblocks; nblocks-- ) { /* INBUF is needed later and it may be identical to OUTBUF, so store the intermediate result to SAVEBUF. */ tripledes_ecb_decrypt (ctx, inbuf, savebuf); cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, DES_BLOCKSIZE); inbuf += DES_BLOCKSIZE; outbuf += DES_BLOCKSIZE; } wipememory(savebuf, sizeof(savebuf)); _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CFB mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_3des_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { struct _tripledes_ctx *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; int burn_stack_depth = TRIPLEDES_ECB_BURN_STACK; #ifdef USE_AMD64_ASM { int asm_burn_depth = 9 * sizeof(void *); if (nblocks >= 3 && burn_stack_depth < asm_burn_depth) burn_stack_depth = asm_burn_depth; /* Process data in 3 block chunks. */ while (nblocks >= 3) { tripledes_amd64_cfb_dec(ctx->encrypt_subkeys, outbuf, inbuf, iv); nblocks -= 3; outbuf += 3 * DES_BLOCKSIZE; inbuf += 3 * DES_BLOCKSIZE; } /* Use generic code to handle smaller chunks... */ } #endif for ( ;nblocks; nblocks-- ) { tripledes_ecb_encrypt (ctx, iv, iv); cipher_block_xor_n_copy(outbuf, iv, inbuf, DES_BLOCKSIZE); outbuf += DES_BLOCKSIZE; inbuf += DES_BLOCKSIZE; } _gcry_burn_stack(burn_stack_depth); } /* * Check whether the 8 byte key is weak. * Does not check the parity bits of the key but simple ignore them. */ static int is_weak_key ( const byte *key ) { byte work[8]; int i, left, right, middle, cmp_result; /* clear parity bits */ for(i=0; i<8; ++i) work[i] = key[i] & 0xfe; /* binary search in the weak key table */ left = 0; right = 63; while(left <= right) { middle = (left + right) / 2; if ( !(cmp_result=working_memcmp(work, weak_keys[middle], 8)) ) return -1; if ( cmp_result > 0 ) left = middle + 1; else right = middle - 1; } return 0; } -/* Alternative setkey for selftests; need larger key than default. */ -static gcry_err_code_t -bulk_selftest_setkey (void *context, const byte *__key, unsigned __keylen, - cipher_bulk_ops_t *bulk_ops) -{ - static const unsigned char key[24] ATTR_ALIGNED_16 = { - 0x66,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, - 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x22, - 0x18,0x2A,0x39,0x47,0x5E,0x6F,0x75,0x82 - }; - - (void)__key; - (void)__keylen; - - return do_tripledes_setkey(context, key, sizeof(key), bulk_ops); -} - - -/* Run the self-tests for DES-CTR, tests IV increment of bulk CTR - encryption. Returns NULL on success. */ -static const char * -selftest_ctr (void) -{ - const int nblocks = 3+1; - const int blocksize = DES_BLOCKSIZE; - const int context_size = sizeof(struct _tripledes_ctx); - - return _gcry_selftest_helper_ctr("3DES", &bulk_selftest_setkey, - &do_tripledes_encrypt, nblocks, blocksize, context_size); -} - - -/* Run the self-tests for DES-CBC, tests bulk CBC decryption. - Returns NULL on success. */ -static const char * -selftest_cbc (void) -{ - const int nblocks = 3+2; - const int blocksize = DES_BLOCKSIZE; - const int context_size = sizeof(struct _tripledes_ctx); - - return _gcry_selftest_helper_cbc("3DES", &bulk_selftest_setkey, - &do_tripledes_encrypt, nblocks, blocksize, context_size); -} - - -/* Run the self-tests for DES-CFB, tests bulk CBC decryption. - Returns NULL on success. */ -static const char * -selftest_cfb (void) -{ - const int nblocks = 3+2; - const int blocksize = DES_BLOCKSIZE; - const int context_size = sizeof(struct _tripledes_ctx); - - return _gcry_selftest_helper_cfb("3DES", &bulk_selftest_setkey, - &do_tripledes_encrypt, nblocks, blocksize, context_size); -} - - /* * Performs a selftest of this DES/Triple-DES implementation. * Returns an string with the error text on failure. * Returns NULL if all is ok. */ static const char * selftest (void) { - const char *r; - /* * Check if 'u32' is really 32 bits wide. This DES / 3DES implementation * need this. */ if (sizeof (u32) != 4) return "Wrong word size for DES configured."; /* * DES Maintenance Test */ { int i; byte key[8] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55}; byte input[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; byte result[8] = {0x24, 0x6e, 0x9d, 0xb9, 0xc5, 0x50, 0x38, 0x1a}; byte temp1[8], temp2[8], temp3[8]; des_ctx des; for (i = 0; i < 64; ++i) { des_setkey (des, key); des_ecb_encrypt (des, input, temp1); des_ecb_encrypt (des, temp1, temp2); des_setkey (des, temp2); des_ecb_decrypt (des, temp1, temp3); memcpy (key, temp3, 8); memcpy (input, temp1, 8); } if (memcmp (temp3, result, 8)) return "DES maintenance test failed."; } /* * Self made Triple-DES test (Does somebody know an official test?) */ { int i; byte input[8] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; byte key1[8] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}; byte key2[8] = {0x11, 0x22, 0x33, 0x44, 0xff, 0xaa, 0xcc, 0xdd}; byte result[8] = {0x7b, 0x38, 0x3b, 0x23, 0xa2, 0x7d, 0x26, 0xd3}; tripledes_ctx des3; for (i = 0; i < 16; ++i) { tripledes_set2keys (des3, key1, key2); tripledes_ecb_encrypt (des3, input, key1); tripledes_ecb_decrypt (des3, input, key2); tripledes_set3keys (des3, key1, input, key2); tripledes_ecb_encrypt (des3, input, input); } if (memcmp (input, result, 8)) return "Triple-DES test failed."; } /* * More Triple-DES test. These are testvectors as used by SSLeay, * thanks to Jeroen C. van Gelderen. */ { static const struct { byte key[24]; byte plain[8]; byte cipher[8]; } testdata[] = { { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }, { 0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00 }, { 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }, { 0x9D,0x64,0x55,0x5A,0x9A,0x10,0xB8,0x52, }, { 0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00 } }, { { 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E, 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E, 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E }, { 0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A }, { 0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A } }, { { 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6, 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6, 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6 }, { 0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2 }, { 0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95 } }, { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }, { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61 }, { 0x3D,0x12,0x4F,0xE2,0x19,0x8B,0xA3,0x18 } }, { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }, { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61 }, { 0xFB,0xAB,0xA1,0xFF,0x9D,0x05,0xE9,0xB1 } }, { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10 }, { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61 }, { 0x18,0xd7,0x48,0xe5,0x63,0x62,0x05,0x72 } }, { { 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17, 0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98, 0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57 }, { 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65 }, { 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30 } }, { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x80,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02 }, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, { 0xe6,0xe6,0xdd,0x5b,0x7e,0x72,0x29,0x74 } }, { { 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20, 0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01, 0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01 }, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, { 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b } } }; byte result[8]; int i; tripledes_ctx des3; for (i=0; icbc_dec = _gcry_3des_cbc_dec; bulk_ops->cfb_dec = _gcry_3des_cfb_dec; bulk_ops->ctr_enc = _gcry_3des_ctr_enc; tripledes_set3keys ( ctx, key, key+8, key+16); if (ctx->flags.no_weak_key) ; /* Detection has been disabled. */ else if (is_weak_key (key) || is_weak_key (key+8) || is_weak_key (key+16)) { _gcry_burn_stack (64); return GPG_ERR_WEAK_KEY; } _gcry_burn_stack (64); return GPG_ERR_NO_ERROR; } static gcry_err_code_t do_tripledes_set_extra_info (void *context, int what, const void *buffer, size_t buflen) { struct _tripledes_ctx *ctx = (struct _tripledes_ctx *)context; gpg_err_code_t ec = 0; (void)buffer; (void)buflen; switch (what) { case CIPHER_INFO_NO_WEAK_KEY: ctx->flags.no_weak_key = 1; break; default: ec = GPG_ERR_INV_OP; break; } return ec; } static unsigned int do_tripledes_encrypt( void *context, byte *outbuf, const byte *inbuf ) { struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context; tripledes_ecb_encrypt ( ctx, inbuf, outbuf ); return /*burn_stack*/ TRIPLEDES_ECB_BURN_STACK; } static unsigned int do_tripledes_decrypt( void *context, byte *outbuf, const byte *inbuf ) { struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context; tripledes_ecb_decrypt ( ctx, inbuf, outbuf ); return /*burn_stack*/ TRIPLEDES_ECB_BURN_STACK; } static gcry_err_code_t do_des_setkey (void *context, const byte *key, unsigned keylen, cipher_bulk_ops_t *bulk_ops) { struct _des_ctx *ctx = (struct _des_ctx *) context; (void)bulk_ops; if (keylen != 8) return GPG_ERR_INV_KEYLEN; des_setkey (ctx, key); if (is_weak_key (key)) { _gcry_burn_stack (64); return GPG_ERR_WEAK_KEY; } _gcry_burn_stack (64); return GPG_ERR_NO_ERROR; } static unsigned int do_des_encrypt( void *context, byte *outbuf, const byte *inbuf ) { struct _des_ctx *ctx = (struct _des_ctx *) context; des_ecb_encrypt ( ctx, inbuf, outbuf ); return /*burn_stack*/ (32); } static unsigned int do_des_decrypt( void *context, byte *outbuf, const byte *inbuf ) { struct _des_ctx *ctx = (struct _des_ctx *) context; des_ecb_decrypt ( ctx, inbuf, outbuf ); return /*burn_stack*/ (32); } /* Self-test section. */ /* Selftest for TripleDES. */ static gpg_err_code_t selftest_fips (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; (void)extended; /* No extended tests available. */ what = "low-level"; errtxt = selftest (); if (errtxt) goto failed; /* The low-level self-tests are quite extensive and thus we can do without high level tests. This is also justified because we have no custom block code implementation for 3des but always use the standard high level block code. */ return 0; /* Succeeded. */ failed: if (report) report ("cipher", GCRY_CIPHER_3DES, 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_3DES: ec = selftest_fips (extended, report); break; default: ec = GPG_ERR_CIPHER_ALGO; break; } return ec; } gcry_cipher_spec_t _gcry_cipher_spec_des = { GCRY_CIPHER_DES, {0, 0}, "DES", NULL, NULL, 8, 64, sizeof (struct _des_ctx), do_des_setkey, do_des_encrypt, do_des_decrypt }; static const gcry_cipher_oid_spec_t oids_tripledes[] = { { "1.2.840.113549.3.7", GCRY_CIPHER_MODE_CBC }, /* Teletrust specific OID for 3DES. */ { "1.3.36.3.1.3.2.1", GCRY_CIPHER_MODE_CBC }, /* pbeWithSHAAnd3_KeyTripleDES_CBC */ { "1.2.840.113549.1.12.1.3", GCRY_CIPHER_MODE_CBC }, { NULL } }; gcry_cipher_spec_t _gcry_cipher_spec_tripledes = { GCRY_CIPHER_3DES, {0, 0}, "3DES", NULL, oids_tripledes, 8, 192, sizeof (struct _tripledes_ctx), do_tripledes_setkey, do_tripledes_encrypt, do_tripledes_decrypt, NULL, NULL, run_selftests, do_tripledes_set_extra_info }; diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c index ff6b0b26..156af015 100644 --- a/cipher/rijndael-aesni.c +++ b/cipher/rijndael-aesni.c @@ -1,4880 +1,4879 @@ /* 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 #if __clang__ # pragma clang attribute push (__attribute__((target("no-sse"))), apply_to = function) #endif #define ALWAYS_INLINE inline __attribute__((always_inline)) #define NO_INLINE __attribute__((noinline)) #define NO_INSTRUMENT_FUNCTION __attribute__((no_instrument_function)) #define ASM_FUNC_ATTR NO_INSTRUMENT_FUNCTION #define ASM_FUNC_ATTR_INLINE ASM_FUNC_ATTR ALWAYS_INLINE #define ASM_FUNC_ATTR_NOINLINE ASM_FUNC_ATTR NO_INLINE 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 ASM_FUNC_ATTR_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_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_7() \ do { asm volatile ("movdqu %%xmm6, %0\n\t" \ "movdqu %%xmm7, %1\n\t" \ : "=m" (*win64tmp), "=m" (*(win64tmp+16)) \ : \ : "memory"); \ } while (0) # 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" (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_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+16)) \ : "memory"); \ } while (0) # 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" (win64tmp8_15) \ : "memory"); \ } while (0) #else # define aesni_prepare_2_7_variable # define aesni_prepare() 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_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_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 ASM_FUNC_ATTR _gcry_aes_aesni_do_setkey (RIJNDAEL_context *ctx, const byte *key) { aesni_prepare_2_7_variable; aesni_prepare(); 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_7(); } /* Make a decryption key from an encryption key. */ static ASM_FUNC_ATTR_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 ASM_FUNC_ATTR _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 ASM_FUNC_ATTR_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 ASM_FUNC_ATTR_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 ASM_FUNC_ATTR_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 ASM_FUNC_ATTR_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 ASM_FUNC_ATTR_INLINE void do_aesni_enc_vec8 (const RIJNDAEL_context *ctx) { asm volatile ("movdqa 0x10(%[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 0x20(%[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 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" : /* 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 ASM_FUNC_ATTR_INLINE void do_aesni_dec_vec8 (const RIJNDAEL_context *ctx) { asm volatile ("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" : /* 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 ASM_FUNC_ATTR_INLINE 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 ASM_FUNC_ATTR_INLINE 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 */ "addb $4, 15(%[ctr])\n\t" "jc .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 .Ldone_ctr%=\n\t" ".Ladd32bit%=:\n\t" "movdqa %%xmm5, (%[ctr])\n\t" /* Restore CTR. */ "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) */ "movdqa %%xmm5, (%[ctr])\n\t" /* Update CTR (mem). */ ".Ldone_ctr%=:\n\t" : : [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 ASM_FUNC_ATTR_INLINE 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 */ "addb $8, 15(%[ctr])\n\t" "jc .Ladd32bit%=\n\t" "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "movdqa 16(%[key]), %%xmm7\n\t" /* xmm7 := key[1] */ "movdqa %%xmm5, %%xmm0\n\t" /* xmm0 := CTR (xmm5) */ "movdqa %%xmm5, %%xmm2\n\t" /* xmm2 := CTR (xmm5) */ "movdqa %%xmm5, %%xmm3\n\t" /* xmm3 := CTR (xmm5) */ "movdqa %%xmm5, %%xmm4\n\t" /* xmm4 := CTR (xmm5) */ "paddb 0*16(%[addb]), %%xmm2\n\t" /* xmm2 := be(1) + CTR */ "paddb 1*16(%[addb]), %%xmm3\n\t" /* xmm3 := be(2) + CTR */ "paddb 2*16(%[addb]), %%xmm4\n\t" /* xmm4 := be(3) + CTR */ "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] */ "aesenc %%xmm7, %%xmm0\n\t" "aesenc %%xmm7, %%xmm2\n\t" "aesenc %%xmm7, %%xmm3\n\t" "aesenc %%xmm7, %%xmm4\n\t" "movdqa %%xmm5, %%xmm8\n\t" /* xmm8 := CTR (xmm5) */ "movdqa %%xmm5, %%xmm9\n\t" /* xmm9 := CTR (xmm5) */ "movdqa %%xmm5, %%xmm10\n\t" /* xmm10 := CTR (xmm5) */ "movdqa %%xmm5, %%xmm11\n\t" /* xmm11 := CTR (xmm5) */ "paddb 3*16(%[addb]), %%xmm8\n\t" /* xmm8 := be(4) + CTR */ "paddb 4*16(%[addb]), %%xmm9\n\t" /* xmm9 := be(5) + CTR */ "paddb 5*16(%[addb]), %%xmm10\n\t" /* xmm10 := be(6) + CTR */ "paddb 6*16(%[addb]), %%xmm11\n\t" /* xmm11 := be(7) + CTR */ "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] */ "aesenc %%xmm7, %%xmm8\n\t" "aesenc %%xmm7, %%xmm9\n\t" "aesenc %%xmm7, %%xmm10\n\t" "aesenc %%xmm7, %%xmm11\n\t" "paddb 7*16(%[addb]), %%xmm5\n\t" /* xmm5 := be(8) + CTR */ "jmp .Ldone_ctr%=\n\t" ".Ladd32bit%=:\n\t" "movdqa %%xmm5, (%[ctr])\n\t" /* Restore CTR. */ "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] */ "movdqa 16(%[key]), %%xmm7\n\t" /* xmm7 := key[1] */ "pshufb %%xmm6, %%xmm2\n\t" /* xmm2 := be(xmm2) */ "pshufb %%xmm6, %%xmm3\n\t" /* xmm3 := be(xmm3) */ "pshufb %%xmm6, %%xmm4\n\t" /* xmm4 := be(xmm4) */ "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] */ "aesenc %%xmm7, %%xmm0\n\t" "aesenc %%xmm7, %%xmm2\n\t" "aesenc %%xmm7, %%xmm3\n\t" "aesenc %%xmm7, %%xmm4\n\t" "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) */ "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] */ "aesenc %%xmm7, %%xmm8\n\t" "aesenc %%xmm7, %%xmm9\n\t" "aesenc %%xmm7, %%xmm10\n\t" "aesenc %%xmm7, %%xmm11\n\t" "pshufb %%xmm6, %%xmm5\n\t" /* xmm5 := be(xmm5) */ "movdqa %%xmm5, (%[ctr])\n\t" /* Update CTR (mem). */ ".align 16\n\t" ".Ldone_ctr%=:\n\t" : : [ctr] "r" (ctr), [key] "r" (ctx->keyschenc), [addb] "r" (bige_addb) : "%esi", "cc", "memory"); asm volatile ("movdqa 0x20(%[key]), %%xmm1\n\t" "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]), %%xmm7\n\t" /* Get block 5. */ "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" "cmpl $12, %[rounds]\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" : : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds), [src] "r" (a) : "cc", "memory"); asm volatile ("pxor %%xmm1, %%xmm12\n\t" /* block1 ^= lastkey */ "pxor %%xmm1, %%xmm13\n\t" /* block2 ^= lastkey */ "pxor %%xmm1, %%xmm14\n\t" /* block3 ^= lastkey */ "pxor %%xmm1, %%xmm15\n\t" /* block4 ^= lastkey */ "aesenclast %%xmm12, %%xmm0\n\t" "aesenclast %%xmm13, %%xmm2\n\t" "aesenclast %%xmm14, %%xmm3\n\t" "aesenclast %%xmm15, %%xmm4\n\t" "movdqu 5*16(%[src]), %%xmm12\n\t" /* Get block 6. */ "movdqu 6*16(%[src]), %%xmm13\n\t" /* Get block 7. */ "movdqu 7*16(%[src]), %%xmm14\n\t" /* Get block 8. */ "movdqu %%xmm0, 0*16(%[dst])\n\t" /* Store block 1. */ "movdqu %%xmm2, 1*16(%[dst])\n\t" /* Store block 2. */ "movdqu %%xmm3, 2*16(%[dst])\n\t" /* Store block 3. */ "movdqu %%xmm4, 3*16(%[dst])\n\t" /* Store block 4. */ "pxor %%xmm1, %%xmm7\n\t" /* block5 ^= lastkey */ "pxor %%xmm1, %%xmm12\n\t" /* block6 ^= lastkey */ "pxor %%xmm1, %%xmm13\n\t" /* block7 ^= lastkey */ "pxor %%xmm1, %%xmm14\n\t" /* block8 ^= lastkey */ "aesenclast %%xmm7, %%xmm8\n\t" "aesenclast %%xmm12, %%xmm9\n\t" "aesenclast %%xmm13, %%xmm10\n\t" "aesenclast %%xmm14, %%xmm11\n\t" "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 ASM_FUNC_ATTR _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 ASM_FUNC_ATTR _gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { unsigned int rounds = ctx->rounds; aesni_prepare_2_7_variable; aesni_prepare (); aesni_prepare_2_7(); asm volatile ("movdqu %[iv], %%xmm0\n\t" : /* No output */ : [iv] "m" (*iv) : "memory" ); asm volatile ("movdqa %[key0], %%xmm2\n\t" /* xmm2 = key[0] */ "movdqa %[keylast], %%xmm4\n\t" /* xmm4 = key[last] */ "movdqa %%xmm0, %%xmm3\n" "pxor %%xmm2, %%xmm4\n\t" /* xmm4 = key[0] ^ key[last] */ "pxor %%xmm2, %%xmm0\n\t" /* xmm0 = IV ^ key[0] */ : /* No output */ : [key0] "m" (ctx->keyschenc[0][0][0]), [keylast] "m" (ctx->keyschenc[rounds][0][0]) : "memory" ); for ( ;nblocks; nblocks-- ) { asm volatile ("movdqu %[inbuf], %%xmm5\n\t" "movdqa %%xmm2, %%xmm3\n\t" "pxor %%xmm4, %%xmm5\n\t" /* xmm5 = input ^ key[last] ^ key[0] */ : : [inbuf] "m" (*inbuf) : "memory" ); #define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" #define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" #define aesenclast_xmm5_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc5\n\t" asm volatile ("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 "cmpl $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" "movdqa 0xa0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "cmpl $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" "movdqa 0xc0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xd0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 ".Lenclast%=:\n\t" aesenclast_xmm5_xmm0 : : [key] "r" (ctx->keyschenc), [rounds] "r" (rounds) : "cc", "memory"); #undef aesenc_xmm1_xmm0 #undef aesenclast_xmm1_xmm0 #undef aesenclast_xmm5_xmm0 asm volatile ("pxor %%xmm0, %%xmm3\n\t" "movdqu %%xmm3, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : [inbuf] "m" (*inbuf) : "memory" ); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm3, %[iv]\n\t" : [iv] "=m" (*iv) : : "memory" ); aesni_cleanup (); aesni_cleanup_2_7 (); } void ASM_FUNC_ATTR _gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks, int cbc_mac) { unsigned int rounds = ctx->rounds; aesni_prepare_2_7_variable; if (nblocks == 0) /* CMAC may call with nblocks 0. */ return; aesni_prepare (); aesni_prepare_2_7(); asm volatile ("movdqu %[iv], %%xmm0\n\t" : /* No output */ : [iv] "m" (*iv) : "memory" ); asm volatile ("movdqa %[key0], %%xmm2\n\t" /* xmm2 = key[0] */ "movdqa %[keylast], %%xmm3\n\t" /* xmm3 = key[last] */ "pxor %%xmm2, %%xmm0\n\t" /* xmm0 = IV ^ key[0] */ "pxor %%xmm3, %%xmm2\n\t" /* xmm2 = key[0] ^ key[last] */ : /* No output */ : [key0] "m" (ctx->keyschenc[0][0][0]), [keylast] "m" (ctx->keyschenc[rounds][0][0]) : "memory" ); asm volatile ("movdqu %[inbuf], %%xmm4\n\t" "pxor %%xmm4, %%xmm0\n\t" /* xmm0 = IV ^ key[0] ^ input */ : : [inbuf] "m" (*inbuf) : "memory" ); inbuf += BLOCKSIZE; for ( ;nblocks; ) { if (--nblocks) { asm volatile ("movdqu %[inbuf], %%xmm4\n\t" /* xmm4 = IV ^ key[0] ^ key[last] ^ input: */ "pxor %%xmm2, %%xmm4\n\t" : : [inbuf] "m" (*inbuf) : "memory" ); inbuf += BLOCKSIZE; } #define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" #define aesenclast_xmm4_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc4\n\t" #define aesenclast_xmm3_xmm5 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xeb\n\t" asm volatile ("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 "cmpl $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" "movdqa 0xa0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "cmpl $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" "movdqa 0xc0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xd0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 ".Lenclast%=:\n\t" "movdqa %%xmm0, %%xmm5\n" aesenclast_xmm4_xmm0 /* xmm0 = IV ^ key[0] */ aesenclast_xmm3_xmm5 /* xmm5 = IV */ : : [key] "r" (ctx->keyschenc), [rounds] "r" (rounds) : "cc", "memory"); #undef aesenc_xmm1_xmm0 #undef aesenclast_xmm4_xmm0 #undef aesenclast_xmm3_xmm5 asm volatile ("movdqu %%xmm5, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); outbuf += -(!cbc_mac) & BLOCKSIZE; } asm volatile ("movdqu %%xmm5, %[iv]\n\t" : [iv] "=m" (*iv) : : "memory" ); aesni_cleanup (); aesni_cleanup_2_7 (); } void ASM_FUNC_ATTR _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_7_variable; aesni_prepare (); 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_8_15_variable; 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_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_7 (); } void ASM_FUNC_ATTR _gcry_aes_aesni_ctr32le_enc (RIJNDAEL_context *ctx, unsigned char *ctr, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { static const byte le_addd_const[8][16] __attribute__ ((aligned (16))) = { { 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; aesni_prepare_2_7_variable; aesni_prepare (); aesni_prepare_2_7(); asm volatile ("movdqa %[ctr], %%xmm5\n\t" /* Preload CTR */ : /* No output */ : [ctr] "m" (*ctr) : "memory"); #ifdef __x86_64__ if (nblocks >= 8) { aesni_prepare_8_15_variable; aesni_prepare_8_15(); for ( ;nblocks >= 8 ; nblocks -= 8 ) { asm volatile ("movdqa (%[key]), %%xmm0\n\t" "movdqa %%xmm5, %%xmm1\n\t" /* load input blocks */ "movdqa %%xmm5, %%xmm2\n\t" "movdqa %%xmm5, %%xmm3\n\t" "movdqa %%xmm5, %%xmm4\n\t" "movdqa %%xmm5, %%xmm8\n\t" "movdqa %%xmm5, %%xmm9\n\t" "movdqa %%xmm5, %%xmm10\n\t" "movdqa %%xmm5, %%xmm11\n\t" "paddd 0*16(%[addd]), %%xmm2\n\t" "paddd 1*16(%[addd]), %%xmm3\n\t" "paddd 2*16(%[addd]), %%xmm4\n\t" "paddd 3*16(%[addd]), %%xmm8\n\t" "paddd 4*16(%[addd]), %%xmm9\n\t" "paddd 5*16(%[addd]), %%xmm10\n\t" "paddd 6*16(%[addd]), %%xmm11\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] */ "movdqu 0*16(%[inbuf]), %%xmm6\n\t" "movdqu 1*16(%[inbuf]), %%xmm7\n\t" "movdqu 2*16(%[inbuf]), %%xmm12\n\t" "movdqu 3*16(%[inbuf]), %%xmm13\n\t" "movdqu 4*16(%[inbuf]), %%xmm14\n\t" "movdqu 5*16(%[inbuf]), %%xmm15\n\t" "paddd 7*16(%[addd]), %%xmm5\n\t" : /* No output */ : [addd] "r" (&le_addd_const[0][0]), [inbuf] "r" (inbuf), [key] "r" (ctx->keyschenc) : "memory"); do_aesni_enc_vec8 (ctx); asm volatile ("pxor %%xmm0, %%xmm6\n\t" "pxor %%xmm0, %%xmm7\n\t" "pxor %%xmm0, %%xmm12\n\t" "pxor %%xmm0, %%xmm13\n\t" "pxor %%xmm0, %%xmm14\n\t" "pxor %%xmm0, %%xmm15\n\t" "aesenclast %%xmm6, %%xmm1\n\t" "aesenclast %%xmm7, %%xmm2\n\t" "movdqu 6*16(%[inbuf]), %%xmm6\n\t" "movdqu 7*16(%[inbuf]), %%xmm7\n\t" "aesenclast %%xmm12, %%xmm3\n\t" "aesenclast %%xmm13, %%xmm4\n\t" "pxor %%xmm0, %%xmm6\n\t" "pxor %%xmm0, %%xmm7\n\t" "aesenclast %%xmm14, %%xmm8\n\t" "aesenclast %%xmm15, %%xmm9\n\t" "aesenclast %%xmm6, %%xmm10\n\t" "aesenclast %%xmm7, %%xmm11\n\t" "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "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_8_15(); } #endif for ( ;nblocks >= 4 ; nblocks -= 4 ) { asm volatile ("movdqa %%xmm5, %%xmm1\n\t" /* load input blocks */ "movdqa %%xmm5, %%xmm2\n\t" "movdqa %%xmm5, %%xmm3\n\t" "movdqa %%xmm5, %%xmm4\n\t" "paddd 0*16(%[addd]), %%xmm2\n\t" "paddd 1*16(%[addd]), %%xmm3\n\t" "paddd 2*16(%[addd]), %%xmm4\n\t" "paddd 3*16(%[addd]), %%xmm5\n\t" "movdqu 0*16(%[inbuf]), %%xmm6\n\t" "movdqu 1*16(%[inbuf]), %%xmm7\n\t" : /* No output */ : [addd] "r" (&le_addd_const[0][0]), [inbuf] "r" (inbuf) : "memory"); do_aesni_enc_vec4 (ctx); asm volatile ("pxor %%xmm6, %%xmm1\n\t" "pxor %%xmm7, %%xmm2\n\t" "movdqu 2*16(%[inbuf]), %%xmm6\n\t" "movdqu 3*16(%[inbuf]), %%xmm7\n\t" "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "pxor %%xmm6, %%xmm3\n\t" "pxor %%xmm7, %%xmm4\n\t" "movdqu %%xmm3, 2*16(%[outbuf])\n\t" "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 ("movdqa %%xmm5, %%xmm0\n\t" "paddd %[add_one], %%xmm5\n\t" "movdqu %[inbuf], %%xmm6\n\t" : : [add_one] "m" (*le_addd_const[0]), [inbuf] "m" (*inbuf) : "memory" ); do_aesni_enc (ctx); asm volatile ("pxor %%xmm0, %%xmm6\n\t" "movdqu %%xmm6, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } asm volatile ("movdqa %%xmm5, %[ctr]\n\t" : [ctr] "=m" (*ctr) : : "memory" ); aesni_cleanup (); aesni_cleanup_2_7 (); } unsigned int ASM_FUNC_ATTR _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 ASM_FUNC_ATTR _gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { aesni_prepare_2_7_variable; aesni_prepare (); 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_8_15_variable; aesni_prepare_8_15(); for ( ;nblocks >= 8; nblocks -= 8) { asm volatile ("movdqa (%[key]), %%xmm0\n\t" "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" "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] */ : /* No output */ : [inbuf] "r" (inbuf), [key] "r" (ctx->keyschenc) : "memory"); do_aesni_enc_vec8 (ctx); asm volatile ( "pxor %%xmm0, %%xmm12\n\t" "pxor %%xmm0, %%xmm13\n\t" "pxor %%xmm0, %%xmm14\n\t" "pxor %%xmm0, %%xmm15\n\t" "aesenclast %%xmm12, %%xmm1\n\t" "aesenclast %%xmm13, %%xmm2\n\t" "aesenclast %%xmm14, %%xmm3\n\t" "aesenclast %%xmm15, %%xmm4\n\t" "movdqu 4*16(%[inbuf]), %%xmm12\n\t" "movdqu 5*16(%[inbuf]), %%xmm13\n\t" "movdqu 6*16(%[inbuf]), %%xmm14\n\t" "movdqu 7*16(%[inbuf]), %%xmm15\n\t" "pxor %%xmm0, %%xmm12\n\t" "pxor %%xmm0, %%xmm13\n\t" "pxor %%xmm0, %%xmm14\n\t" "pxor %%xmm0, %%xmm15\n\t" "aesenclast %%xmm12, %%xmm8\n\t" "aesenclast %%xmm13, %%xmm9\n\t" "aesenclast %%xmm14, %%xmm10\n\t" "aesenclast %%xmm15, %%xmm11\n\t" "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "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_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_7 (); } void ASM_FUNC_ATTR _gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { aesni_prepare_2_7_variable; aesni_prepare (); 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_8_15_variable; aesni_prepare_8_15(); for ( ;nblocks >= 8 ; nblocks -= 8 ) { asm volatile ("movdqa (%[key]), %%xmm0\n\t" "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" "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] */ : /* No output */ : [inbuf] "r" (inbuf), [key] "r" (ctx->keyschdec) : "memory"); do_aesni_dec_vec8 (ctx); asm volatile ( "pxor %%xmm0, %%xmm5\n\t" /* xor IV with key */ "pxor %%xmm0, %%xmm12\n\t" /* xor IV with key */ "pxor %%xmm0, %%xmm13\n\t" /* xor IV with key */ "pxor %%xmm0, %%xmm14\n\t" /* xor IV with key */ "pxor %%xmm0, %%xmm15\n\t" /* xor IV with key */ "aesdeclast %%xmm5, %%xmm1\n\t" "aesdeclast %%xmm12, %%xmm2\n\t" "aesdeclast %%xmm13, %%xmm3\n\t" "aesdeclast %%xmm14, %%xmm4\n\t" "movdqu 4*16(%[inbuf]), %%xmm12\n\t" "movdqu 5*16(%[inbuf]), %%xmm13\n\t" "movdqu 6*16(%[inbuf]), %%xmm14\n\t" "movdqu 7*16(%[inbuf]), %%xmm5\n\t" "pxor %%xmm0, %%xmm12\n\t" /* xor IV with key */ "pxor %%xmm0, %%xmm13\n\t" /* xor IV with key */ "pxor %%xmm0, %%xmm14\n\t" /* xor IV with key */ "aesdeclast %%xmm15, %%xmm8\n\t" "aesdeclast %%xmm12, %%xmm9\n\t" "aesdeclast %%xmm13, %%xmm10\n\t" "aesdeclast %%xmm14, %%xmm11\n\t" "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "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_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_7 (); } static ASM_FUNC_ATTR_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" : : [ptr0] "m" (*(plaintext + 0 * BLOCKSIZE * 2)), [ptr1] "m" (*(plaintext + 1 * BLOCKSIZE * 2)), [ptr2] "m" (*(plaintext + 2 * BLOCKSIZE * 2)), [ptr3] "m" (*(plaintext + 3 * BLOCKSIZE * 2)) : "memory" ); asm volatile ("vpxor %[ptr4], %%ymm0, %%ymm0\n\t" "vpxor %[ptr5], %%ymm4, %%ymm4\n\t" "vpxor %[ptr6], %%ymm5, %%ymm5\n\t" "vpxor %[ptr7], %%ymm7, %%ymm7\n\t" : : [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" : : [ptr0] "m" (*(plaintext + 0 * BLOCKSIZE * 2)), [ptr1] "m" (*(plaintext + 1 * BLOCKSIZE * 2)), [ptr2] "m" (*(plaintext + 2 * BLOCKSIZE * 2)), [ptr3] "m" (*(plaintext + 3 * BLOCKSIZE * 2)) : "memory" ); asm volatile ("vxorpd %[ptr4], %%ymm0, %%ymm0\n\t" "vxorpd %[ptr5], %%ymm4, %%ymm4\n\t" "vxorpd %[ptr6], %%ymm5, %%ymm5\n\t" "vxorpd %[ptr7], %%ymm7, %%ymm7\n\t" : : [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 ASM_FUNC_ATTR_NOINLINE 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; byte tmpbuf_store[3 * 16 + 15]; byte *tmpbuf; aesni_prepare_2_7_variable; asm volatile ("" : "=r" (tmpbuf) : "0" (tmpbuf_store) : "memory"); tmpbuf = tmpbuf + (-(uintptr_t)tmpbuf & 15); aesni_prepare (); aesni_prepare_2_7 (); /* Preload Offset */ asm volatile ("movdqu %[iv], %%xmm5\n\t" "movdqu %[ctr], %%xmm7\n\t" : /* No output */ : [iv] "m" (*c->u_iv.iv), [ctr] "m" (*c->u_ctr.ctr) : "memory" ); for ( ;nblocks && n % 4; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Checksum_i = Checksum_{i-1} xor P_i */ /* Offset_i = Offset_{i-1} xor L_{ntz(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, %%xmm7\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) { unsigned char last_xor_first_key_store[16 + 15]; unsigned char *lxf_key; aesni_prepare_8_15_variable; asm volatile ("" : "=r" (lxf_key) : "0" (last_xor_first_key_store) : "memory"); lxf_key = lxf_key + (-(uintptr_t)lxf_key & 15); aesni_prepare_8_15(); asm volatile ("movdqu %[l0], %%xmm6\n\t" "movdqa %[last_key], %%xmm0\n\t" "pxor %[first_key], %%xmm5\n\t" "pxor %[first_key], %%xmm0\n\t" "movdqa %%xmm0, %[lxfkey]\n\t" : [lxfkey] "=m" (*lxf_key) : [l0] "m" (*c->u_mode.ocb.L[0]), [last_key] "m" (ctx->keyschenc[ctx->rounds][0][0]), [first_key] "m" (ctx->keyschenc[0][0][0]) : "memory" ); for ( ;nblocks >= 8 ; nblocks -= 8 ) { n += 4; l = aes_ocb_get_l(c, n); asm volatile ("movdqu %[l0l1], %%xmm10\n\t" "movdqu %[l1], %%xmm11\n\t" "movdqu %[l3], %%xmm15\n\t" : : [l0l1] "m" (*c->u_mode.ocb.L0L1), [l1] "m" (*c->u_mode.ocb.L[1]), [l3] "m" (*l) : "memory" ); n += 4; l = aes_ocb_get_l(c, n); /* Checksum_i = Checksum_{i-1} xor P_i */ /* 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" : : [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)), [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)), [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqu %[inbuf3], %%xmm4\n\t" "movdqu %[inbuf4], %%xmm8\n\t" "movdqu %[inbuf5], %%xmm9\n\t" : : [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)), [inbuf4] "m" (*(inbuf + 4 * BLOCKSIZE)), [inbuf5] "m" (*(inbuf + 5 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqa %[lxfkey], %%xmm0\n\t" "movdqa %%xmm6, %%xmm12\n\t" "pxor %%xmm5, %%xmm12\n\t" "pxor %%xmm1, %%xmm7\n\t" "pxor %%xmm12, %%xmm1\n\t" "pxor %%xmm0, %%xmm12\n\t" "movdqa %%xmm10, %%xmm13\n\t" "pxor %%xmm5, %%xmm13\n\t" "pxor %%xmm2, %%xmm7\n\t" "pxor %%xmm13, %%xmm2\n\t" "pxor %%xmm0, %%xmm13\n\t" "movdqa %%xmm11, %%xmm14\n\t" "pxor %%xmm5, %%xmm14\n\t" "pxor %%xmm3, %%xmm7\n\t" "pxor %%xmm14, %%xmm3\n\t" "pxor %%xmm0, %%xmm14\n\t" "pxor %%xmm11, %%xmm5\n\t" "pxor %%xmm15, %%xmm5\n\t" "pxor %%xmm4, %%xmm7\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqa %%xmm5, %%xmm15\n\t" "pxor %%xmm0, %%xmm15\n\t" "movdqa %%xmm5, %%xmm0\n\t" "pxor %%xmm6, %%xmm0\n\t" "pxor %%xmm8, %%xmm7\n\t" "pxor %%xmm0, %%xmm8\n\t" "pxor %[lxfkey], %%xmm0\n\t" "movdqa %%xmm0, %[tmpbuf0]\n\t" "movdqa %%xmm10, %%xmm0\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm9, %%xmm7\n\t" "pxor %%xmm0, %%xmm9\n\t" "pxor %[lxfkey], %%xmm0\n" "movdqa %%xmm0, %[tmpbuf1]\n\t" : [tmpbuf0] "=m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "=m" (*(tmpbuf + 1 * BLOCKSIZE)) : [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("movdqu %[inbuf6], %%xmm10\n\t" "movdqa %%xmm11, %%xmm0\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm10, %%xmm7\n\t" "pxor %%xmm0, %%xmm10\n\t" "pxor %[lxfkey], %%xmm0\n\t" "movdqa %%xmm0, %[tmpbuf2]\n\t" : [tmpbuf2] "=m" (*(tmpbuf + 2 * BLOCKSIZE)) : [inbuf6] "m" (*(inbuf + 6 * BLOCKSIZE)), [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("movdqu %[l7], %%xmm0\n\t" "pxor %%xmm11, %%xmm5\n\t" "pxor %%xmm0, %%xmm5\n\t" "movdqa 0x10(%[key]), %%xmm0\n\t" "movdqu %[inbuf7], %%xmm11\n\t" "pxor %%xmm11, %%xmm7\n\t" "pxor %%xmm5, %%xmm11\n\t" : : [l7] "m" (*l), [inbuf7] "m" (*(inbuf + 7 * BLOCKSIZE)), [key] "r" (ctx->keyschenc) : "memory" ); asm volatile ("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" "jb .Ldeclast%=\n\t" "movdqa 0xa0(%[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 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" "je .Ldeclast%=\n\t" "movdqa 0xc0(%[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 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" ".Ldeclast%=:\n\t" : : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) : "cc", "memory"); asm volatile ("aesenclast %%xmm12, %%xmm1\n\t" "aesenclast %%xmm13, %%xmm2\n\t" "aesenclast %%xmm14, %%xmm3\n\t" "aesenclast %%xmm15, %%xmm4\n\t" "aesenclast %[tmpbuf0],%%xmm8\n\t" "aesenclast %[tmpbuf1],%%xmm9\n\t" "aesenclast %[tmpbuf2],%%xmm10\n\t" : : [tmpbuf0] "m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "m" (*(tmpbuf + 1 * BLOCKSIZE)), [tmpbuf2] "m" (*(tmpbuf + 2 * BLOCKSIZE)), [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("aesenclast %%xmm5, %%xmm11\n\t" "pxor %[lxfkey], %%xmm11\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)), [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)) : [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("movdqu %%xmm3, %[outbuf2]\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" "movdqu %%xmm8, %[outbuf4]\n\t" : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)), [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)), [outbuf4] "=m" (*(outbuf + 4 * BLOCKSIZE)) : : "memory" ); asm volatile ("movdqu %%xmm9, %[outbuf5]\n\t" "movdqu %%xmm10, %[outbuf6]\n\t" "movdqu %%xmm11, %[outbuf7]\n\t" : [outbuf5] "=m" (*(outbuf + 5 * BLOCKSIZE)), [outbuf6] "=m" (*(outbuf + 6 * BLOCKSIZE)), [outbuf7] "=m" (*(outbuf + 7 * BLOCKSIZE)) : : "memory" ); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } asm volatile ("pxor %[first_key], %%xmm5\n\t" "pxor %%xmm0, %%xmm0\n\t" "movdqu %%xmm0, %[lxfkey]\n\t" : [lxfkey] "=m" (*lxf_key) : [first_key] "m" (ctx->keyschenc[0][0][0]) : "memory" ); aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4 ; nblocks -= 4 ) { n += 4; l = aes_ocb_get_l(c, n); /* Checksum_i = Checksum_{i-1} xor P_i */ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ asm volatile ("movdqu %[l0], %%xmm0\n\t" "movdqu %[inbuf0], %%xmm1\n\t" "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], %%xmm4\n\t" "movdqu %[l3], %%xmm6\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm1, %%xmm7\n\t" "pxor %%xmm0, %%xmm1\n\t" "movdqa %%xmm0, %[tmpbuf0]\n\t" : [tmpbuf0] "=m" (*(tmpbuf + 0 * BLOCKSIZE)) : [l1] "m" (*c->u_mode.ocb.L[1]), [l3] "m" (*l) : "memory" ); asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm3\n\t" "pxor %%xmm2, %%xmm7\n\t" "pxor %%xmm3, %%xmm2\n\t" "movdqa %%xmm3, %[tmpbuf1]\n\t" : [tmpbuf1] "=m" (*(tmpbuf + 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 %%xmm3, %%xmm7\n\t" "pxor %%xmm0, %%xmm3\n\t" "movdqa %%xmm0, %[tmpbuf2]\n\t" : [tmpbuf2] "=m" (*(tmpbuf + 2 * BLOCKSIZE)) : [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); asm volatile ("pxor %%xmm6, %%xmm5\n\t" "pxor %%xmm4, %%xmm5\n\t" "movdqu %[inbuf3], %%xmm4\n\t" "pxor %%xmm4, %%xmm7\n\t" "pxor %%xmm5, %%xmm4\n\t" : : [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)) : "memory" ); do_aesni_enc_vec4 (ctx); asm volatile ("pxor %[tmpbuf0],%%xmm1\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "pxor %[tmpbuf1],%%xmm2\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)), [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)) : [tmpbuf0] "m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "m" (*(tmpbuf + 1 * BLOCKSIZE)) : "memory" ); asm volatile ("pxor %[tmpbuf2],%%xmm3\n\t" "movdqu %%xmm3, %[outbuf2]\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)), [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)) : [tmpbuf2] "m" (*(tmpbuf + 2 * BLOCKSIZE)) : "memory" ); outbuf += 4*BLOCKSIZE; inbuf += 4*BLOCKSIZE; } for ( ;nblocks; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Checksum_i = Checksum_{i-1} xor P_i */ /* Offset_i = Offset_{i-1} xor L_{ntz(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, %%xmm7\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 %%xmm7, %[ctr]\n\t" : [iv] "=m" (*c->u_iv.iv), [ctr] "=m" (*c->u_ctr.ctr) : : "memory" ); asm volatile ("pxor %%xmm0, %%xmm0\n\t" "movdqa %%xmm0, %[tmpbuf0]\n\t" "movdqa %%xmm0, %[tmpbuf1]\n\t" "movdqa %%xmm0, %[tmpbuf2]\n\t" : [tmpbuf0] "=m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "=m" (*(tmpbuf + 1 * BLOCKSIZE)), [tmpbuf2] "=m" (*(tmpbuf + 2 * BLOCKSIZE)) : : "memory" ); aesni_cleanup (); aesni_cleanup_2_7 (); return 0; } static unsigned int ASM_FUNC_ATTR_NOINLINE aesni_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, 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; size_t nblocks = nblocks_arg; byte tmpbuf_store[3 * 16 + 15]; byte *tmpbuf; aesni_prepare_2_7_variable; asm volatile ("" : "=r" (tmpbuf) : "0" (tmpbuf_store) : "memory"); tmpbuf = tmpbuf + (-(uintptr_t)tmpbuf & 15); aesni_prepare (); aesni_prepare_2_7 (); if ( !ctx->decryption_prepared ) { do_aesni_prepare_decryption ( ctx ); ctx->decryption_prepared = 1; } /* Preload Offset */ asm volatile ("movdqu %[iv], %%xmm5\n\t" : /* No output */ : [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) */ 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" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); inbuf += BLOCKSIZE; outbuf += BLOCKSIZE; } #ifdef __x86_64__ if (nblocks >= 8) { unsigned char last_xor_first_key_store[16 + 15]; unsigned char *lxf_key; aesni_prepare_8_15_variable; asm volatile ("" : "=r" (lxf_key) : "0" (last_xor_first_key_store) : "memory"); lxf_key = lxf_key + (-(uintptr_t)lxf_key & 15); aesni_prepare_8_15(); asm volatile ("movdqu %[l0], %%xmm6\n\t" "movdqa %[last_key], %%xmm0\n\t" "pxor %[first_key], %%xmm5\n\t" "pxor %[first_key], %%xmm0\n\t" "movdqa %%xmm0, %[lxfkey]\n\t" : [lxfkey] "=m" (*lxf_key) : [l0] "m" (*c->u_mode.ocb.L[0]), [last_key] "m" (ctx->keyschdec[ctx->rounds][0][0]), [first_key] "m" (ctx->keyschdec[0][0][0]) : "memory" ); for ( ;nblocks >= 8 ; nblocks -= 8 ) { n += 4; l = aes_ocb_get_l(c, n); asm volatile ("movdqu %[l0l1], %%xmm10\n\t" "movdqu %[l1], %%xmm11\n\t" "movdqu %[l3], %%xmm15\n\t" : : [l0l1] "m" (*c->u_mode.ocb.L0L1), [l1] "m" (*c->u_mode.ocb.L[1]), [l3] "m" (*l) : "memory" ); 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" : : [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)), [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)), [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqu %[inbuf3], %%xmm4\n\t" "movdqu %[inbuf4], %%xmm8\n\t" "movdqu %[inbuf5], %%xmm9\n\t" : : [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)), [inbuf4] "m" (*(inbuf + 4 * BLOCKSIZE)), [inbuf5] "m" (*(inbuf + 5 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqa %[lxfkey], %%xmm0\n\t" "movdqa %%xmm6, %%xmm12\n\t" "pxor %%xmm5, %%xmm12\n\t" "pxor %%xmm12, %%xmm1\n\t" "pxor %%xmm0, %%xmm12\n\t" "movdqa %%xmm10, %%xmm13\n\t" "pxor %%xmm5, %%xmm13\n\t" "pxor %%xmm13, %%xmm2\n\t" "pxor %%xmm0, %%xmm13\n\t" "movdqa %%xmm11, %%xmm14\n\t" "pxor %%xmm5, %%xmm14\n\t" "pxor %%xmm14, %%xmm3\n\t" "pxor %%xmm0, %%xmm14\n\t" "pxor %%xmm11, %%xmm5\n\t" "pxor %%xmm15, %%xmm5\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqa %%xmm5, %%xmm15\n\t" "pxor %%xmm0, %%xmm15\n\t" "movdqa %%xmm5, %%xmm0\n\t" "pxor %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm8\n\t" "pxor %[lxfkey], %%xmm0\n\t" "movdqa %%xmm0, %[tmpbuf0]\n\t" "movdqa %%xmm10, %%xmm0\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm0, %%xmm9\n\t" "pxor %[lxfkey], %%xmm0\n" "movdqa %%xmm0, %[tmpbuf1]\n\t" : [tmpbuf0] "=m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "=m" (*(tmpbuf + 1 * BLOCKSIZE)) : [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("movdqu %[inbuf6], %%xmm10\n\t" "movdqa %%xmm11, %%xmm0\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm0, %%xmm10\n\t" "pxor %[lxfkey], %%xmm0\n\t" "movdqa %%xmm0, %[tmpbuf2]\n\t" : [tmpbuf2] "=m" (*(tmpbuf + 2 * BLOCKSIZE)) : [inbuf6] "m" (*(inbuf + 6 * BLOCKSIZE)), [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("movdqu %[l7], %%xmm0\n\t" "pxor %%xmm11, %%xmm5\n\t" "pxor %%xmm0, %%xmm5\n\t" "movdqa 0x10(%[key]), %%xmm0\n\t" "movdqu %[inbuf7], %%xmm11\n\t" "pxor %%xmm5, %%xmm11\n\t" : : [l7] "m" (*l), [inbuf7] "m" (*(inbuf + 7 * BLOCKSIZE)), [key] "r" (ctx->keyschdec) : "memory" ); asm volatile ("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" "jb .Ldeclast%=\n\t" "movdqa 0xa0(%[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 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" "je .Ldeclast%=\n\t" "movdqa 0xc0(%[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 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" ".Ldeclast%=:\n\t" : : [key] "r" (ctx->keyschdec), [rounds] "r" (ctx->rounds) : "cc", "memory"); asm volatile ("aesdeclast %%xmm12, %%xmm1\n\t" "aesdeclast %%xmm13, %%xmm2\n\t" "aesdeclast %%xmm14, %%xmm3\n\t" "aesdeclast %%xmm15, %%xmm4\n\t" "aesdeclast %[tmpbuf0],%%xmm8\n\t" "aesdeclast %[tmpbuf1],%%xmm9\n\t" "aesdeclast %[tmpbuf2],%%xmm10\n\t" : : [tmpbuf0] "m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "m" (*(tmpbuf + 1 * BLOCKSIZE)), [tmpbuf2] "m" (*(tmpbuf + 2 * BLOCKSIZE)) : "memory" ); asm volatile ("aesdeclast %%xmm5, %%xmm11\n\t" "pxor %[lxfkey], %%xmm11\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)), [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)) : [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("movdqu %%xmm3, %[outbuf2]\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" "movdqu %%xmm8, %[outbuf4]\n\t" : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)), [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)), [outbuf4] "=m" (*(outbuf + 4 * BLOCKSIZE)) : : "memory" ); asm volatile ("movdqu %%xmm9, %[outbuf5]\n\t" "movdqu %%xmm10, %[outbuf6]\n\t" "movdqu %%xmm11, %[outbuf7]\n\t" : [outbuf5] "=m" (*(outbuf + 5 * BLOCKSIZE)), [outbuf6] "=m" (*(outbuf + 6 * BLOCKSIZE)), [outbuf7] "=m" (*(outbuf + 7 * BLOCKSIZE)) : : "memory" ); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } asm volatile ("pxor %[first_key], %%xmm5\n\t" "pxor %%xmm0, %%xmm0\n\t" "movdqu %%xmm0, %[lxfkey]\n\t" : [lxfkey] "=m" (*lxf_key) : [first_key] "m" (ctx->keyschdec[0][0][0]) : "memory" ); 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)} */ /* C_i = Offset_i xor DECIPHER(K, P_i xor Offset_i) */ asm volatile ("movdqu %[l0], %%xmm0\n\t" "movdqu %[inbuf0], %%xmm1\n\t" "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], %%xmm4\n\t" "movdqu %[l3], %%xmm6\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" "movdqa %%xmm0, %[tmpbuf0]\n\t" : [tmpbuf0] "=m" (*(tmpbuf + 0 * BLOCKSIZE)) : [l1] "m" (*c->u_mode.ocb.L[1]), [l3] "m" (*l) : "memory" ); asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm3\n\t" "pxor %%xmm3, %%xmm2\n\t" "movdqa %%xmm3, %[tmpbuf1]\n\t" : [tmpbuf1] "=m" (*(tmpbuf + 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" "movdqa %%xmm0, %[tmpbuf2]\n\t" : [tmpbuf2] "=m" (*(tmpbuf + 2 * BLOCKSIZE)) : [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); asm volatile ("pxor %%xmm6, %%xmm5\n\t" "pxor %%xmm4, %%xmm5\n\t" "movdqu %[inbuf3], %%xmm4\n\t" "pxor %%xmm5, %%xmm4\n\t" : : [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)) : "memory" ); do_aesni_dec_vec4 (ctx); asm volatile ("pxor %[tmpbuf0],%%xmm1\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "pxor %[tmpbuf1],%%xmm2\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)), [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)) : [tmpbuf0] "m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "m" (*(tmpbuf + 1 * BLOCKSIZE)) : "memory" ); asm volatile ("pxor %[tmpbuf2],%%xmm3\n\t" "movdqu %%xmm3, %[outbuf2]\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)), [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)) : [tmpbuf2] "m" (*(tmpbuf + 2 * 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" "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" : [iv] "=m" (*c->u_iv.iv) : : "memory" ); asm volatile ("pxor %%xmm0, %%xmm0\n\t" "movdqa %%xmm0, %[tmpbuf0]\n\t" "movdqa %%xmm0, %[tmpbuf1]\n\t" "movdqa %%xmm0, %[tmpbuf2]\n\t" : [tmpbuf0] "=m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "=m" (*(tmpbuf + 1 * BLOCKSIZE)), [tmpbuf2] "=m" (*(tmpbuf + 2 * BLOCKSIZE)) : : "memory" ); aesni_ocb_checksum (c, outbuf_arg, nblocks_arg); aesni_cleanup (); aesni_cleanup_2_7 (); return 0; } size_t ASM_FUNC_ATTR _gcry_aes_aesni_ocb_crypt(gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt) { if (encrypt) return aesni_ocb_enc(c, outbuf_arg, inbuf_arg, nblocks); else return aesni_ocb_dec(c, outbuf_arg, inbuf_arg, nblocks); } size_t ASM_FUNC_ATTR _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_7_variable; aesni_prepare (); 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_8_15_variable; aesni_prepare_8_15(); asm volatile ("movdqu %[l0], %%xmm7\n\t" "movdqu %[l0l1], %%xmm12\n\t" "movdqu %[l1], %%xmm13\n\t" : : [l0] "m" (*c->u_mode.ocb.L[0]), [l0l1] "m" (*c->u_mode.ocb.L0L1), [l1] "m" (*c->u_mode.ocb.L[1]) : "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" "movdqu %[abuf1], %%xmm2\n\t" "movdqu %[abuf2], %%xmm3\n\t" "movdqu %[abuf3], %%xmm4\n\t" : : [abuf0] "m" (*(abuf + 0 * BLOCKSIZE)), [abuf1] "m" (*(abuf + 1 * BLOCKSIZE)), [abuf2] "m" (*(abuf + 2 * BLOCKSIZE)), [abuf3] "m" (*(abuf + 3 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqu %[abuf4], %%xmm8\n\t" "movdqu %[abuf5], %%xmm9\n\t" "movdqu %[abuf6], %%xmm10\n\t" "movdqu %[abuf7], %%xmm11\n\t" : : [abuf4] "m" (*(abuf + 4 * BLOCKSIZE)), [abuf5] "m" (*(abuf + 5 * BLOCKSIZE)), [abuf6] "m" (*(abuf + 6 * BLOCKSIZE)), [abuf7] "m" (*(abuf + 7 * BLOCKSIZE)) : "memory" ); asm volatile ("pxor %%xmm7, %%xmm1\n\t" "pxor %%xmm5, %%xmm1\n\t" "pxor %%xmm12, %%xmm2\n\t" "pxor %%xmm5, %%xmm2\n\t" "pxor %%xmm13, %%xmm3\n\t" "pxor %%xmm5, %%xmm3\n\t" "pxor %%xmm0, %%xmm5\n\t" "movdqa (%[key]), %%xmm0\n\t" "pxor %%xmm5, %%xmm4\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 %%xmm7, %%xmm8\n\t" "pxor %%xmm5, %%xmm8\n\t" "pxor %%xmm12, %%xmm9\n\t" "pxor %%xmm5, %%xmm9\n\t" "pxor %%xmm13, %%xmm10\n\t" "pxor %%xmm5, %%xmm10\n\t" "pxor %%xmm14, %%xmm5\n\t" "pxor %%xmm5, %%xmm11\n\t" "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] */ : : [key] "r" (ctx->keyschenc) : "memory" ); do_aesni_enc_vec8 (ctx); asm volatile ( "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" "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_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], %%xmm0\n\t" "movdqu %[abuf0], %%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], %%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]), [l3] "m" (*l) : "memory" ); asm volatile ("movdqu %[abuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm3\n\t" "pxor %%xmm3, %%xmm2\n\t" : : [abuf1] "m" (*(abuf + 1 * BLOCKSIZE)) : "memory" ); 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 %%xmm5, %%xmm4\n\t" : : [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_7 (); return 0; } static const u64 xts_gfmul_const[2] __attribute__ ((aligned (16))) = { 0x87, 0x01 }; static void ASM_FUNC_ATTR _gcry_aes_aesni_xts_enc (RIJNDAEL_context *ctx, unsigned char *tweak, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { aesni_prepare_2_7_variable; aesni_prepare (); 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" ); #ifdef __x86_64__ if (nblocks >= 8) { aesni_prepare_8_15_variable; aesni_prepare_8_15(); for ( ;nblocks >= 8 ; nblocks -= 8 ) { asm volatile ("pshufd $0x13, %%xmm5, %%xmm11\n\t" "movdqu %[inbuf0], %%xmm1\n\t" "pxor %%xmm5, %%xmm1\n\t" "movdqa %%xmm5, %%xmm7\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf0] "m" (*(inbuf + 0 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm2\n\t" "movdqa %%xmm5, %%xmm12\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf1] "m" (*(inbuf + 1 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" "pxor %%xmm5, %%xmm3\n\t" "movdqa %%xmm5, %%xmm13\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf2] "m" (*(inbuf + 2 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf3], %%xmm4\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqa %%xmm5, %%xmm14\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf3] "m" (*(inbuf + 3 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf4], %%xmm8\n\t" "pxor %%xmm5, %%xmm8\n\t" "movdqa %%xmm5, %%xmm15\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf4] "m" (*(inbuf + 4 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf5], %%xmm9\n\t" "pxor %%xmm5, %%xmm9\n\t" "movdqu %%xmm5, %[outbuf5]\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf5] "=m" (*(outbuf + 5 * 16)) : [inbuf5] "m" (*(inbuf + 5 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf6], %%xmm10\n\t" "pxor %%xmm5, %%xmm10\n\t" "movdqu %%xmm5, %[outbuf6]\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf6] "=m" (*(outbuf + 6 * 16)) : [inbuf6] "m" (*(inbuf + 6 * 16)) : "memory" ); asm volatile ("movdqa %%xmm11, %%xmm0\n\t" "movdqu %[inbuf7], %%xmm11\n\t" "pxor %%xmm5, %%xmm11\n\t" "movdqu %%xmm5, %[outbuf7]\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf7] "=m" (*(outbuf + 7 * 16)) : [inbuf7] "m" (*(inbuf + 7 * 16)) : "memory" ); asm volatile ("cmpl $12, %[rounds]\n\t" "movdqa (%[key]), %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" "pxor %%xmm0, %%xmm2\n\t" "pxor %%xmm0, %%xmm3\n\t" "pxor %%xmm0, %%xmm4\n\t" "pxor %%xmm0, %%xmm8\n\t" "pxor %%xmm0, %%xmm9\n\t" "pxor %%xmm0, %%xmm10\n\t" "pxor %%xmm0, %%xmm11\n\t" "movdqa 0x10(%[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 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 .Lenclast%=\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 .Lenclast%=\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\t" ".Lenclast%=:\n\t" : : [key] "r" (ctx->keyschenc), [rounds] "rm" (ctx->rounds) : "cc", "memory"); asm volatile ("pxor %%xmm0, %%xmm7\n\t" "pxor %%xmm0, %%xmm12\n\t" "pxor %%xmm0, %%xmm13\n\t" "pxor %%xmm0, %%xmm14\n\t" "aesenclast %%xmm7, %%xmm1\n\t" "aesenclast %%xmm12, %%xmm2\n\t" "aesenclast %%xmm13, %%xmm3\n\t" "aesenclast %%xmm14, %%xmm4\n\t" "movdqu 5*16(%[outbuf]), %%xmm12\n\t" "movdqu 6*16(%[outbuf]), %%xmm13\n\t" "movdqu 7*16(%[outbuf]), %%xmm14\n\t" "pxor %%xmm0, %%xmm15\n\t" "pxor %%xmm0, %%xmm12\n\t" "pxor %%xmm0, %%xmm13\n\t" "pxor %%xmm0, %%xmm14\n\t" "aesenclast %%xmm15, %%xmm8\n\t" "aesenclast %%xmm12, %%xmm9\n\t" "aesenclast %%xmm13, %%xmm10\n\t" "aesenclast %%xmm14, %%xmm11\n\t" "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "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" : : [outbuf] "r" (outbuf) : "memory" ); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } aesni_cleanup_8_15(); } #endif 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_7 (); } static void ASM_FUNC_ATTR _gcry_aes_aesni_xts_dec (RIJNDAEL_context *ctx, unsigned char *tweak, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { aesni_prepare_2_7_variable; aesni_prepare (); 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" ); #ifdef __x86_64__ if (nblocks >= 8) { aesni_prepare_8_15_variable; aesni_prepare_8_15(); for ( ;nblocks >= 8 ; nblocks -= 8 ) { asm volatile ("pshufd $0x13, %%xmm5, %%xmm11\n\t" "movdqu %[inbuf0], %%xmm1\n\t" "pxor %%xmm5, %%xmm1\n\t" "movdqa %%xmm5, %%xmm7\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf0] "m" (*(inbuf + 0 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm2\n\t" "movdqa %%xmm5, %%xmm12\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf1] "m" (*(inbuf + 1 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" "pxor %%xmm5, %%xmm3\n\t" "movdqa %%xmm5, %%xmm13\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf2] "m" (*(inbuf + 2 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf3], %%xmm4\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqa %%xmm5, %%xmm14\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf3] "m" (*(inbuf + 3 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf4], %%xmm8\n\t" "pxor %%xmm5, %%xmm8\n\t" "movdqa %%xmm5, %%xmm15\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf4] "m" (*(inbuf + 4 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf5], %%xmm9\n\t" "pxor %%xmm5, %%xmm9\n\t" "movdqu %%xmm5, %[outbuf5]\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf5] "=m" (*(outbuf + 5 * 16)) : [inbuf5] "m" (*(inbuf + 5 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf6], %%xmm10\n\t" "pxor %%xmm5, %%xmm10\n\t" "movdqu %%xmm5, %[outbuf6]\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf6] "=m" (*(outbuf + 6 * 16)) : [inbuf6] "m" (*(inbuf + 6 * 16)) : "memory" ); asm volatile ("movdqa %%xmm11, %%xmm0\n\t" "movdqu %[inbuf7], %%xmm11\n\t" "pxor %%xmm5, %%xmm11\n\t" "movdqu %%xmm5, %[outbuf7]\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf7] "=m" (*(outbuf + 7 * 16)) : [inbuf7] "m" (*(inbuf + 7 * 16)) : "memory" ); asm volatile ("cmpl $12, %[rounds]\n\t" "movdqa (%[key]), %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" "pxor %%xmm0, %%xmm2\n\t" "pxor %%xmm0, %%xmm3\n\t" "pxor %%xmm0, %%xmm4\n\t" "pxor %%xmm0, %%xmm8\n\t" "pxor %%xmm0, %%xmm9\n\t" "pxor %%xmm0, %%xmm10\n\t" "pxor %%xmm0, %%xmm11\n\t" "movdqa 0x10(%[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 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\t" ".Ldeclast%=:\n\t" : : [key] "r" (ctx->keyschdec), [rounds] "rm" (ctx->rounds) : "cc", "memory"); asm volatile ("pxor %%xmm0, %%xmm7\n\t" "pxor %%xmm0, %%xmm12\n\t" "pxor %%xmm0, %%xmm13\n\t" "pxor %%xmm0, %%xmm14\n\t" "aesdeclast %%xmm7, %%xmm1\n\t" "aesdeclast %%xmm12, %%xmm2\n\t" "aesdeclast %%xmm13, %%xmm3\n\t" "aesdeclast %%xmm14, %%xmm4\n\t" "movdqu 5*16(%[outbuf]), %%xmm12\n\t" "movdqu 6*16(%[outbuf]), %%xmm13\n\t" "movdqu 7*16(%[outbuf]), %%xmm14\n\t" "pxor %%xmm0, %%xmm15\n\t" "pxor %%xmm0, %%xmm12\n\t" "pxor %%xmm0, %%xmm13\n\t" "pxor %%xmm0, %%xmm14\n\t" "aesdeclast %%xmm15, %%xmm8\n\t" "aesdeclast %%xmm12, %%xmm9\n\t" "aesdeclast %%xmm13, %%xmm10\n\t" "aesdeclast %%xmm14, %%xmm11\n\t" "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "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" : : [outbuf] "r" (outbuf) : "memory" ); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } aesni_cleanup_8_15(); } #endif 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_7 (); } void ASM_FUNC_ATTR _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); } #if __clang__ # pragma clang attribute pop #endif #endif /* USE_AESNI */ diff --git a/cipher/rijndael-armv8-ce.c b/cipher/rijndael-armv8-ce.c index b24ae3e9..e53c940e 100644 --- a/cipher/rijndael-armv8-ce.c +++ b/cipher/rijndael-armv8-ce.c @@ -1,431 +1,430 @@ /* ARMv8 Crypto Extension AES for Libgcrypt * Copyright (C) 2016 Jussi Kivilinna * * 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_ARM_CE typedef struct u128_s { u32 a, b, c, d; } u128_t; extern u32 _gcry_aes_sbox4_armv8_ce(u32 in4b); extern void _gcry_aes_invmixcol_armv8_ce(u128_t *dst, const u128_t *src); extern unsigned int _gcry_aes_enc_armv8_ce(const void *keysched, byte *dst, const byte *src, unsigned int nrounds); extern unsigned int _gcry_aes_dec_armv8_ce(const void *keysched, byte *dst, const byte *src, unsigned int nrounds); extern void _gcry_aes_cbc_enc_armv8_ce (const void *keysched, unsigned char *outbuf, const unsigned char *inbuf, unsigned char *iv, size_t nblocks, int cbc_mac, unsigned int nrounds); extern void _gcry_aes_cbc_dec_armv8_ce (const void *keysched, unsigned char *outbuf, const unsigned char *inbuf, unsigned char *iv, size_t nblocks, unsigned int nrounds); extern void _gcry_aes_cfb_enc_armv8_ce (const void *keysched, unsigned char *outbuf, const unsigned char *inbuf, unsigned char *iv, size_t nblocks, unsigned int nrounds); extern void _gcry_aes_cfb_dec_armv8_ce (const void *keysched, unsigned char *outbuf, const unsigned char *inbuf, unsigned char *iv, size_t nblocks, unsigned int nrounds); extern void _gcry_aes_ctr_enc_armv8_ce (const void *keysched, unsigned char *outbuf, const unsigned char *inbuf, unsigned char *iv, size_t nblocks, unsigned int nrounds); extern void _gcry_aes_ctr32le_enc_armv8_ce (const void *keysched, unsigned char *outbuf, const unsigned char *inbuf, unsigned char *iv, size_t nblocks, unsigned int nrounds); extern void _gcry_aes_ocb_enc_armv8_ce (const void *keysched, unsigned char *outbuf, const unsigned char *inbuf, unsigned char *offset, unsigned char *checksum, unsigned char *L_table, size_t nblocks, unsigned int nrounds, unsigned int blkn); extern void _gcry_aes_ocb_dec_armv8_ce (const void *keysched, unsigned char *outbuf, const unsigned char *inbuf, unsigned char *offset, unsigned char *checksum, unsigned char *L_table, size_t nblocks, unsigned int nrounds, unsigned int blkn); extern void _gcry_aes_ocb_auth_armv8_ce (const void *keysched, const unsigned char *abuf, unsigned char *offset, unsigned char *checksum, unsigned char *L_table, size_t nblocks, unsigned int nrounds, unsigned int blkn); extern void _gcry_aes_xts_enc_armv8_ce (const void *keysched, unsigned char *outbuf, const unsigned char *inbuf, unsigned char *tweak, size_t nblocks, unsigned int nrounds); extern void _gcry_aes_xts_dec_armv8_ce (const void *keysched, unsigned char *outbuf, const unsigned char *inbuf, unsigned char *tweak, size_t nblocks, unsigned int nrounds); typedef void (*ocb_crypt_fn_t) (const void *keysched, unsigned char *outbuf, const unsigned char *inbuf, unsigned char *offset, unsigned char *checksum, unsigned char *L_table, size_t nblocks, unsigned int nrounds, unsigned int blkn); typedef void (*xts_crypt_fn_t) (const void *keysched, unsigned char *outbuf, const unsigned char *inbuf, unsigned char *tweak, size_t nblocks, unsigned int nrounds); void _gcry_aes_armv8_ce_setkey (RIJNDAEL_context *ctx, const byte *key) { union { PROPERLY_ALIGNED_TYPE dummy; byte data[MAXKC][4]; u32 data32[MAXKC]; } tkk[2]; unsigned int rounds = ctx->rounds; int KC = rounds - 6; unsigned int keylen = KC * 4; unsigned int i, r, t; byte rcon = 1; int j; #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) 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) { tk_u32[0] ^= _gcry_aes_sbox4_armv8_ce(rol(tk_u32[KC - 1], 24)) ^ rcon; 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_u32[KC/2] ^= _gcry_aes_sbox4_armv8_ce(tk_u32[KC/2 - 1]); 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; } } rcon = (rcon << 1) ^ ((rcon >> 7) * 0x1b); } #undef W #undef tk #undef k #undef W_u32 #undef tk_u32 #undef k_u32 wipememory(&tkk, sizeof(tkk)); } /* Make a decryption key from an encryption key. */ void _gcry_aes_armv8_ce_prepare_decryption (RIJNDAEL_context *ctx) { u128_t *ekey = (u128_t *)(void *)ctx->keyschenc; u128_t *dkey = (u128_t *)(void *)ctx->keyschdec; int rounds = ctx->rounds; int rr; int r; #define DO_AESIMC() _gcry_aes_invmixcol_armv8_ce(&dkey[r], &ekey[rr]) dkey[0] = ekey[rounds]; r = 1; rr = rounds-1; DO_AESIMC(); r++; rr--; /* round 1 */ DO_AESIMC(); r++; rr--; /* round 2 */ DO_AESIMC(); r++; rr--; /* round 3 */ DO_AESIMC(); r++; rr--; /* round 4 */ DO_AESIMC(); r++; rr--; /* round 5 */ DO_AESIMC(); r++; rr--; /* round 6 */ DO_AESIMC(); r++; rr--; /* round 7 */ DO_AESIMC(); r++; rr--; /* round 8 */ DO_AESIMC(); r++; rr--; /* round 9 */ if (rounds >= 12) { if (rounds > 12) { DO_AESIMC(); r++; rr--; /* round 10 */ DO_AESIMC(); r++; rr--; /* round 11 */ } DO_AESIMC(); r++; rr--; /* round 12 / 10 */ DO_AESIMC(); r++; rr--; /* round 13 / 11 */ } dkey[r] = ekey[0]; #undef DO_AESIMC } unsigned int _gcry_aes_armv8_ce_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src) { const void *keysched = ctx->keyschenc32; unsigned int nrounds = ctx->rounds; return _gcry_aes_enc_armv8_ce(keysched, dst, src, nrounds); } unsigned int _gcry_aes_armv8_ce_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src) { const void *keysched = ctx->keyschdec32; unsigned int nrounds = ctx->rounds; return _gcry_aes_dec_armv8_ce(keysched, dst, src, nrounds); } void _gcry_aes_armv8_ce_cbc_enc (const RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks, int cbc_mac) { const void *keysched = ctx->keyschenc32; unsigned int nrounds = ctx->rounds; _gcry_aes_cbc_enc_armv8_ce(keysched, outbuf, inbuf, iv, nblocks, cbc_mac, nrounds); } void _gcry_aes_armv8_ce_cbc_dec (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { const void *keysched = ctx->keyschdec32; unsigned int nrounds = ctx->rounds; if ( !ctx->decryption_prepared ) { _gcry_aes_armv8_ce_prepare_decryption ( ctx ); ctx->decryption_prepared = 1; } _gcry_aes_cbc_dec_armv8_ce(keysched, outbuf, inbuf, iv, nblocks, nrounds); } void _gcry_aes_armv8_ce_cfb_enc (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { const void *keysched = ctx->keyschenc32; unsigned int nrounds = ctx->rounds; _gcry_aes_cfb_enc_armv8_ce(keysched, outbuf, inbuf, iv, nblocks, nrounds); } void _gcry_aes_armv8_ce_cfb_dec (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { const void *keysched = ctx->keyschenc32; unsigned int nrounds = ctx->rounds; _gcry_aes_cfb_dec_armv8_ce(keysched, outbuf, inbuf, iv, nblocks, nrounds); } void _gcry_aes_armv8_ce_ctr_enc (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { const void *keysched = ctx->keyschenc32; unsigned int nrounds = ctx->rounds; _gcry_aes_ctr_enc_armv8_ce(keysched, outbuf, inbuf, iv, nblocks, nrounds); } void _gcry_aes_armv8_ce_ctr32le_enc (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { const void *keysched = ctx->keyschenc32; unsigned int nrounds = ctx->rounds; _gcry_aes_ctr32le_enc_armv8_ce(keysched, outbuf, inbuf, iv, nblocks, nrounds); } 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) { RIJNDAEL_context *ctx = (void *)&c->context.c; const void *keysched = encrypt ? ctx->keyschenc32 : ctx->keyschdec32; ocb_crypt_fn_t crypt_fn = encrypt ? _gcry_aes_ocb_enc_armv8_ce : _gcry_aes_ocb_dec_armv8_ce; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned int nrounds = ctx->rounds; u64 blkn = c->u_mode.ocb.data_nblocks; if ( !encrypt && !ctx->decryption_prepared ) { _gcry_aes_armv8_ce_prepare_decryption ( ctx ); ctx->decryption_prepared = 1; } c->u_mode.ocb.data_nblocks = blkn + nblocks; crypt_fn(keysched, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, c->u_mode.ocb.L[0], nblocks, nrounds, (unsigned int)blkn); return 0; } size_t _gcry_aes_armv8_ce_ocb_auth (gcry_cipher_hd_t c, void *abuf_arg, size_t nblocks) { RIJNDAEL_context *ctx = (void *)&c->context.c; const void *keysched = ctx->keyschenc32; const unsigned char *abuf = abuf_arg; unsigned int nrounds = ctx->rounds; u64 blkn = c->u_mode.ocb.aad_nblocks; c->u_mode.ocb.aad_nblocks = blkn + nblocks; _gcry_aes_ocb_auth_armv8_ce(keysched, abuf, c->u_mode.ocb.aad_offset, c->u_mode.ocb.aad_sum, c->u_mode.ocb.L[0], nblocks, nrounds, (unsigned int)blkn); return 0; } void _gcry_aes_armv8_ce_xts_crypt (RIJNDAEL_context *ctx, unsigned char *tweak, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks, int encrypt) { const void *keysched = encrypt ? ctx->keyschenc32 : ctx->keyschdec32; xts_crypt_fn_t crypt_fn = encrypt ? _gcry_aes_xts_enc_armv8_ce : _gcry_aes_xts_dec_armv8_ce; unsigned int nrounds = ctx->rounds; if ( !encrypt && !ctx->decryption_prepared ) { _gcry_aes_armv8_ce_prepare_decryption ( ctx ); ctx->decryption_prepared = 1; } crypt_fn(keysched, outbuf, inbuf, tweak, nblocks, nrounds); } #endif /* USE_ARM_CE */ diff --git a/cipher/rijndael-padlock.c b/cipher/rijndael-padlock.c index 3af214d7..2583b834 100644 --- a/cipher/rijndael-padlock.c +++ b/cipher/rijndael-padlock.c @@ -1,110 +1,109 @@ /* Padlock 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" #ifdef USE_PADLOCK /* Encrypt or decrypt one block using the padlock engine. A and B may be the same. */ static unsigned int do_padlock (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax, int decrypt_flag) { /* BX and AX are not necessary correctly aligned. Thus we need to copy them here. */ unsigned char a[16] __attribute__ ((aligned (16))); unsigned char b[16] __attribute__ ((aligned (16))); unsigned int cword[4] __attribute__ ((aligned (16))); unsigned char *pa = a; unsigned char *pb = b; int blocks; /* The control word fields are: 127:12 11:10 9 8 7 6 5 4 3:0 RESERVED KSIZE CRYPT INTER KEYGN CIPHR ALIGN DGEST ROUND */ cword[0] = (ctx->rounds & 15); /* (The mask is just a safeguard.) */ cword[1] = 0; cword[2] = 0; cword[3] = 0; if (decrypt_flag) cword[0] |= 0x00000200; memcpy (a, ax, 16); blocks = 1; /* Init counter for just one block. */ #ifdef __x86_64__ asm volatile ("pushfq\n\t" /* Force key reload. */ "popfq\n\t" ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */ : "+S" (pa), "+D" (pb), "+c" (blocks) : "d" (cword), "b" (ctx->padlockkey) : "cc", "memory" ); #else asm volatile ("pushfl\n\t" /* Force key reload. */ "popfl\n\t" "xchg %4, %%ebx\n\t" /* Load key. */ ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */ "xchg %4, %%ebx\n" /* Restore GOT register. */ : "+S" (pa), "+D" (pb), "+c" (blocks) : "d" (cword), "r" (ctx->padlockkey) : "cc", "memory" ); #endif memcpy (bx, b, 16); return (48 + 15 /* possible padding for alignment */); } unsigned int _gcry_aes_padlock_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax) { return do_padlock(ctx, bx, ax, 0); } unsigned int _gcry_aes_padlock_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax) { return do_padlock(ctx, bx, ax, 1); } void _gcry_aes_padlock_prepare_decryption (RIJNDAEL_context *ctx) { /* Padlock does not need decryption subkeys. */ (void)ctx; } #endif /* USE_PADLOCK */ diff --git a/cipher/rijndael-ssse3-amd64.c b/cipher/rijndael-ssse3-amd64.c index b0723853..0f0abf62 100644 --- a/cipher/rijndael-ssse3-amd64.c +++ b/cipher/rijndael-ssse3-amd64.c @@ -1,743 +1,742 @@ /* SSSE3 vector permutation AES for Libgcrypt * Copyright (C) 2014-2017 Jussi Kivilinna * * 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 is based on the public domain library libvpaes version 0.5 * available at http://crypto.stanford.edu/vpaes/ and which carries * this notice: * * libvpaes: constant-time SSSE3 AES encryption and decryption. * version 0.5 * * By Mike Hamburg, Stanford University, 2009. Public domain. * I wrote essentially all of this code. I did not write the test * vectors; they are the NIST known answer tests. I hereby release all * the code and documentation here that I wrote into the public domain. * * This is an implementation of AES following my paper, * "Accelerating AES with Vector Permute Instructions" * CHES 2009; http://shiftleft.org/papers/vector_aes/ */ #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_SSSE3 #if _GCRY_GCC_VERSION >= 40400 /* 4.4 */ /* Prevent compiler from issuing SSE instructions between asm blocks. */ # pragma GCC target("no-sse") #endif #if __clang__ # pragma clang attribute push (__attribute__((target("no-sse"))), apply_to = function) #endif #define ALWAYS_INLINE inline __attribute__((always_inline)) #define NO_INSTRUMENT_FUNCTION __attribute__((no_instrument_function)) #define ASM_FUNC_ATTR NO_INSTRUMENT_FUNCTION #define ASM_FUNC_ATTR_INLINE ASM_FUNC_ATTR ALWAYS_INLINE /* Copy of ocb_get_l needed here as GCC is unable to inline ocb_get_l because of 'pragma target'. */ static ASM_FUNC_ATTR_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]; } /* Assembly functions in rijndael-ssse3-amd64-asm.S. Note that these have custom calling convention (additional XMM parameters). */ extern void _gcry_aes_ssse3_enc_preload(void); extern void _gcry_aes_ssse3_dec_preload(void); extern void _gcry_aes_ssse3_schedule_core(const void *key, u64 keybits, void *buffer, u64 decrypt, u64 rotoffs); extern void _gcry_aes_ssse3_encrypt_core(const void *key, u64 nrounds); extern void _gcry_aes_ssse3_decrypt_core(const void *key, u64 nrounds); /* Two macros to be called prior and after the use of SSSE3 instructions. There should be no external function calls between the use of these macros. There purpose is to make sure that the SSE registers are cleared and won't reveal any information about the key or the data. */ #ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS # define SSSE3_STATE_SIZE (16 * 10) /* XMM6-XMM15 are callee-saved registers on WIN64. */ # define vpaes_ssse3_prepare() \ asm volatile ("movdqu %%xmm6, 0*16(%0)\n\t" \ "movdqu %%xmm7, 1*16(%0)\n\t" \ "movdqu %%xmm8, 2*16(%0)\n\t" \ "movdqu %%xmm9, 3*16(%0)\n\t" \ "movdqu %%xmm10, 4*16(%0)\n\t" \ "movdqu %%xmm11, 5*16(%0)\n\t" \ "movdqu %%xmm12, 6*16(%0)\n\t" \ "movdqu %%xmm13, 7*16(%0)\n\t" \ "movdqu %%xmm14, 8*16(%0)\n\t" \ "movdqu %%xmm15, 9*16(%0)\n\t" \ : \ : "r" (ssse3_state) \ : "memory" ) # define vpaes_ssse3_cleanup() \ asm volatile ("pxor %%xmm0, %%xmm0 \n\t" \ "pxor %%xmm1, %%xmm1 \n\t" \ "pxor %%xmm2, %%xmm2 \n\t" \ "pxor %%xmm3, %%xmm3 \n\t" \ "pxor %%xmm4, %%xmm4 \n\t" \ "pxor %%xmm5, %%xmm5 \n\t" \ "movdqu 0*16(%0), %%xmm6 \n\t" \ "movdqu 1*16(%0), %%xmm7 \n\t" \ "movdqu 2*16(%0), %%xmm8 \n\t" \ "movdqu 3*16(%0), %%xmm9 \n\t" \ "movdqu 4*16(%0), %%xmm10 \n\t" \ "movdqu 5*16(%0), %%xmm11 \n\t" \ "movdqu 6*16(%0), %%xmm12 \n\t" \ "movdqu 7*16(%0), %%xmm13 \n\t" \ "movdqu 8*16(%0), %%xmm14 \n\t" \ "movdqu 9*16(%0), %%xmm15 \n\t" \ : \ : "r" (ssse3_state) \ : "memory" ) #else # define SSSE3_STATE_SIZE 1 # define vpaes_ssse3_prepare() (void)ssse3_state # define vpaes_ssse3_cleanup() \ asm volatile ("pxor %%xmm0, %%xmm0 \n\t" \ "pxor %%xmm1, %%xmm1 \n\t" \ "pxor %%xmm2, %%xmm2 \n\t" \ "pxor %%xmm3, %%xmm3 \n\t" \ "pxor %%xmm4, %%xmm4 \n\t" \ "pxor %%xmm5, %%xmm5 \n\t" \ "pxor %%xmm6, %%xmm6 \n\t" \ "pxor %%xmm7, %%xmm7 \n\t" \ "pxor %%xmm8, %%xmm8 \n\t" \ ::: "memory" ) #endif #define vpaes_ssse3_prepare_enc() \ vpaes_ssse3_prepare(); \ _gcry_aes_ssse3_enc_preload(); #define vpaes_ssse3_prepare_dec() \ vpaes_ssse3_prepare(); \ _gcry_aes_ssse3_dec_preload(); void ASM_FUNC_ATTR _gcry_aes_ssse3_do_setkey (RIJNDAEL_context *ctx, const byte *key) { unsigned int keybits = (ctx->rounds - 10) * 32 + 128; byte ssse3_state[SSSE3_STATE_SIZE]; vpaes_ssse3_prepare(); _gcry_aes_ssse3_schedule_core(key, keybits, &ctx->keyschenc32[0][0], 0, 48); /* Save key for setting up decryption. */ if (keybits > 192) asm volatile ("movdqu (%[src]), %%xmm0\n\t" "movdqu 16(%[src]), %%xmm1\n\t" "movdqu %%xmm0, (%[dst])\n\t" "movdqu %%xmm1, 16(%[dst])\n\t" : /* No output */ : [dst] "r" (&ctx->keyschdec32[0][0]), [src] "r" (key) : "memory" ); else if (keybits == 192) asm volatile ("movdqu (%[src]), %%xmm0\n\t" "movq 16(%[src]), %%xmm1\n\t" "movdqu %%xmm0, (%[dst])\n\t" "movq %%xmm1, 16(%[dst])\n\t" : /* No output */ : [dst] "r" (&ctx->keyschdec32[0][0]), [src] "r" (key) : "memory" ); else asm volatile ("movdqu (%[src]), %%xmm0\n\t" "movdqu %%xmm0, (%[dst])\n\t" : /* No output */ : [dst] "r" (&ctx->keyschdec32[0][0]), [src] "r" (key) : "memory" ); vpaes_ssse3_cleanup(); } /* Make a decryption key from an encryption key. */ static ASM_FUNC_ATTR_INLINE void do_ssse3_prepare_decryption (RIJNDAEL_context *ctx, byte ssse3_state[SSSE3_STATE_SIZE]) { unsigned int keybits = (ctx->rounds - 10) * 32 + 128; vpaes_ssse3_prepare(); _gcry_aes_ssse3_schedule_core(&ctx->keyschdec32[0][0], keybits, &ctx->keyschdec32[ctx->rounds][0], 1, (keybits == 192) ? 0 : 32); vpaes_ssse3_cleanup(); } void ASM_FUNC_ATTR _gcry_aes_ssse3_prepare_decryption (RIJNDAEL_context *ctx) { byte ssse3_state[SSSE3_STATE_SIZE]; do_ssse3_prepare_decryption(ctx, ssse3_state); } /* Encrypt one block using the Intel SSSE3 instructions. Block is input * and output through SSE register xmm0. */ static ASM_FUNC_ATTR_INLINE void do_vpaes_ssse3_enc (const RIJNDAEL_context *ctx, unsigned int nrounds) { _gcry_aes_ssse3_encrypt_core(ctx->keyschenc32, nrounds); } /* Decrypt one block using the Intel SSSE3 instructions. Block is input * and output through SSE register xmm0. */ static ASM_FUNC_ATTR_INLINE void do_vpaes_ssse3_dec (const RIJNDAEL_context *ctx, unsigned int nrounds) { _gcry_aes_ssse3_decrypt_core(ctx->keyschdec32, nrounds); } unsigned int ASM_FUNC_ATTR _gcry_aes_ssse3_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src) { unsigned int nrounds = ctx->rounds; byte ssse3_state[SSSE3_STATE_SIZE]; vpaes_ssse3_prepare_enc (); asm volatile ("movdqu %[src], %%xmm0\n\t" : : [src] "m" (*src) : "memory" ); do_vpaes_ssse3_enc (ctx, nrounds); asm volatile ("movdqu %%xmm0, %[dst]\n\t" : [dst] "=m" (*dst) : : "memory" ); vpaes_ssse3_cleanup (); return 0; } void ASM_FUNC_ATTR _gcry_aes_ssse3_cfb_enc (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { unsigned int nrounds = ctx->rounds; byte ssse3_state[SSSE3_STATE_SIZE]; vpaes_ssse3_prepare_enc (); asm volatile ("movdqu %[iv], %%xmm0\n\t" : /* No output */ : [iv] "m" (*iv) : "memory" ); for ( ;nblocks; nblocks-- ) { do_vpaes_ssse3_enc (ctx, nrounds); 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" ); vpaes_ssse3_cleanup (); } void ASM_FUNC_ATTR _gcry_aes_ssse3_cbc_enc (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks, int cbc_mac) { unsigned int nrounds = ctx->rounds; byte ssse3_state[SSSE3_STATE_SIZE]; vpaes_ssse3_prepare_enc (); asm volatile ("movdqu %[iv], %%xmm7\n\t" : /* No output */ : [iv] "m" (*iv) : "memory" ); for ( ;nblocks; nblocks-- ) { asm volatile ("movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm7, %%xmm0\n\t" : /* No output */ : [inbuf] "m" (*inbuf) : "memory" ); do_vpaes_ssse3_enc (ctx, nrounds); asm volatile ("movdqa %%xmm0, %%xmm7\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); inbuf += BLOCKSIZE; if (!cbc_mac) outbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm7, %[iv]\n\t" : [iv] "=m" (*iv) : : "memory" ); vpaes_ssse3_cleanup (); } void ASM_FUNC_ATTR _gcry_aes_ssse3_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 }; unsigned int nrounds = ctx->rounds; byte ssse3_state[SSSE3_STATE_SIZE]; u64 ctrlow; vpaes_ssse3_prepare_enc (); asm volatile ("movdqa %[mask], %%xmm6\n\t" /* Preload mask */ "movdqa (%[ctr]), %%xmm7\n\t" /* Preload CTR */ "movq 8(%[ctr]), %q[ctrlow]\n\t" "bswapq %q[ctrlow]\n\t" : [ctrlow] "=r" (ctrlow) : [mask] "m" (*be_mask), [ctr] "r" (ctr) : "memory", "cc"); for ( ;nblocks; nblocks-- ) { asm volatile ("movdqa %%xmm7, %%xmm0\n\t" /* xmm0 := CTR (xmm7) */ "pcmpeqd %%xmm1, %%xmm1\n\t" "psrldq $8, %%xmm1\n\t" /* xmm1 = -1 */ "pshufb %%xmm6, %%xmm7\n\t" "psubq %%xmm1, %%xmm7\n\t" /* xmm7++ (big endian) */ /* detect if 64-bit carry handling is needed */ "incq %q[ctrlow]\n\t" "jnz .Lno_carry%=\n\t" "pslldq $8, %%xmm1\n\t" /* move lower 64-bit to high */ "psubq %%xmm1, %%xmm7\n\t" /* add carry to upper 64bits */ ".Lno_carry%=:\n\t" "pshufb %%xmm6, %%xmm7\n\t" : [ctrlow] "+r" (ctrlow) : : "cc", "memory"); do_vpaes_ssse3_enc (ctx, nrounds); asm volatile ("movdqu %[src], %%xmm1\n\t" /* xmm1 := input */ "pxor %%xmm1, %%xmm0\n\t" /* EncCTR ^= input */ "movdqu %%xmm0, %[dst]" /* Store EncCTR. */ : [dst] "=m" (*outbuf) : [src] "m" (*inbuf) : "memory"); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm7, %[ctr]\n\t" /* Update CTR (mem). */ : [ctr] "=m" (*ctr) : : "memory" ); vpaes_ssse3_cleanup (); } unsigned int ASM_FUNC_ATTR _gcry_aes_ssse3_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src) { unsigned int nrounds = ctx->rounds; byte ssse3_state[SSSE3_STATE_SIZE]; vpaes_ssse3_prepare_dec (); asm volatile ("movdqu %[src], %%xmm0\n\t" : : [src] "m" (*src) : "memory" ); do_vpaes_ssse3_dec (ctx, nrounds); asm volatile ("movdqu %%xmm0, %[dst]\n\t" : [dst] "=m" (*dst) : : "memory" ); vpaes_ssse3_cleanup (); return 0; } void ASM_FUNC_ATTR _gcry_aes_ssse3_cfb_dec (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { unsigned int nrounds = ctx->rounds; byte ssse3_state[SSSE3_STATE_SIZE]; vpaes_ssse3_prepare_enc (); asm volatile ("movdqu %[iv], %%xmm0\n\t" : /* No output */ : [iv] "m" (*iv) : "memory" ); for ( ;nblocks; nblocks-- ) { do_vpaes_ssse3_enc (ctx, nrounds); 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" ); vpaes_ssse3_cleanup (); } void ASM_FUNC_ATTR _gcry_aes_ssse3_cbc_dec (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { unsigned int nrounds = ctx->rounds; byte ssse3_state[SSSE3_STATE_SIZE]; if ( !ctx->decryption_prepared ) { do_ssse3_prepare_decryption ( ctx, ssse3_state ); ctx->decryption_prepared = 1; } vpaes_ssse3_prepare_dec (); asm volatile ("movdqu %[iv], %%xmm7\n\t" /* use xmm7 as fast IV storage */ : /* No output */ : [iv] "m" (*iv) : "memory"); for ( ;nblocks; nblocks-- ) { asm volatile ("movdqu %[inbuf], %%xmm0\n\t" "movdqa %%xmm0, %%xmm6\n\t" /* use xmm6 as savebuf */ : /* No output */ : [inbuf] "m" (*inbuf) : "memory"); do_vpaes_ssse3_dec (ctx, nrounds); asm volatile ("pxor %%xmm7, %%xmm0\n\t" /* xor IV with output */ "movdqu %%xmm0, %[outbuf]\n\t" "movdqu %%xmm6, %%xmm7\n\t" /* store savebuf as new IV */ : [outbuf] "=m" (*outbuf) : : "memory"); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm7, %[iv]\n\t" /* store IV */ : /* No output */ : [iv] "m" (*iv) : "memory"); vpaes_ssse3_cleanup (); } static void ASM_FUNC_ATTR ssse3_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; unsigned int nrounds = ctx->rounds; byte ssse3_state[SSSE3_STATE_SIZE]; vpaes_ssse3_prepare_enc (); /* Preload Offset and Checksum */ asm volatile ("movdqu %[iv], %%xmm7\n\t" "movdqu %[ctr], %%xmm6\n\t" : /* No output */ : [iv] "m" (*c->u_iv.iv), [ctr] "m" (*c->u_ctr.ctr) : "memory" ); for ( ;nblocks; nblocks-- ) { const unsigned char *l; 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, %%xmm7\n\t" "pxor %%xmm0, %%xmm6\n\t" "pxor %%xmm7, %%xmm0\n\t" : : [l] "m" (*l), [inbuf] "m" (*inbuf) : "memory" ); do_vpaes_ssse3_enc (ctx, nrounds); asm volatile ("pxor %%xmm7, %%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 %%xmm7, %[iv]\n\t" "movdqu %%xmm6, %[ctr]\n\t" : [iv] "=m" (*c->u_iv.iv), [ctr] "=m" (*c->u_ctr.ctr) : : "memory" ); vpaes_ssse3_cleanup (); } static void ASM_FUNC_ATTR ssse3_ocb_dec (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; unsigned int nrounds = ctx->rounds; byte ssse3_state[SSSE3_STATE_SIZE]; if ( !ctx->decryption_prepared ) { do_ssse3_prepare_decryption ( ctx, ssse3_state ); ctx->decryption_prepared = 1; } vpaes_ssse3_prepare_dec (); /* Preload Offset and Checksum */ asm volatile ("movdqu %[iv], %%xmm7\n\t" "movdqu %[ctr], %%xmm6\n\t" : /* No output */ : [iv] "m" (*c->u_iv.iv), [ctr] "m" (*c->u_ctr.ctr) : "memory" ); for ( ;nblocks; nblocks-- ) { const unsigned char *l; 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, %%xmm7\n\t" "pxor %%xmm7, %%xmm0\n\t" : : [l] "m" (*l), [inbuf] "m" (*inbuf) : "memory" ); do_vpaes_ssse3_dec (ctx, nrounds); asm volatile ("pxor %%xmm7, %%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 %%xmm7, %[iv]\n\t" "movdqu %%xmm6, %[ctr]\n\t" : [iv] "=m" (*c->u_iv.iv), [ctr] "=m" (*c->u_ctr.ctr) : : "memory" ); vpaes_ssse3_cleanup (); } size_t ASM_FUNC_ATTR _gcry_aes_ssse3_ocb_crypt(gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt) { if (encrypt) ssse3_ocb_enc(c, outbuf_arg, inbuf_arg, nblocks); else ssse3_ocb_dec(c, outbuf_arg, inbuf_arg, nblocks); return 0; } size_t ASM_FUNC_ATTR _gcry_aes_ssse3_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; unsigned int nrounds = ctx->rounds; byte ssse3_state[SSSE3_STATE_SIZE]; vpaes_ssse3_prepare_enc (); /* Preload Offset and Sum */ asm volatile ("movdqu %[iv], %%xmm7\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; nblocks-- ) { const unsigned char *l; 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, %%xmm7\n\t" "pxor %%xmm7, %%xmm0\n\t" : : [l] "m" (*l), [abuf] "m" (*abuf) : "memory" ); do_vpaes_ssse3_enc (ctx, nrounds); asm volatile ("pxor %%xmm0, %%xmm6\n\t" : : : "memory" ); abuf += BLOCKSIZE; } c->u_mode.ocb.aad_nblocks = n; asm volatile ("movdqu %%xmm7, %[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" ); vpaes_ssse3_cleanup (); return 0; } #if __clang__ # pragma clang attribute pop #endif #endif /* USE_SSSE3 */ diff --git a/cipher/rijndael-vaes.c b/cipher/rijndael-vaes.c index 0d7d1367..dbcf9afa 100644 --- a/cipher/rijndael-vaes.c +++ b/cipher/rijndael-vaes.c @@ -1,197 +1,196 @@ /* VAES/AVX2 accelerated AES for Libgcrypt * Copyright (C) 2021 Jussi Kivilinna * * 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 "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_VAES # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS # define ASM_FUNC_ABI __attribute__((sysv_abi)) # else # define ASM_FUNC_ABI # endif extern void _gcry_aes_aesni_prepare_decryption(RIJNDAEL_context *ctx); extern void _gcry_vaes_avx2_cbc_dec_amd64 (const void *keysched, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, unsigned int nrounds) ASM_FUNC_ABI; extern void _gcry_vaes_avx2_cfb_dec_amd64 (const void *keysched, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, unsigned int nrounds) ASM_FUNC_ABI; extern void _gcry_vaes_avx2_ctr_enc_amd64 (const void *keysched, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, unsigned int nrounds) ASM_FUNC_ABI; extern void _gcry_vaes_avx2_ctr32le_enc_amd64 (const void *keysched, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, unsigned int nrounds) ASM_FUNC_ABI; extern void _gcry_vaes_avx2_ocb_crypt_amd64 (const void *keysched, unsigned int blkn, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, unsigned int nrounds, unsigned char *offset, unsigned char *checksum, unsigned char *L_table, int encrypt) ASM_FUNC_ABI; extern void _gcry_vaes_avx2_xts_crypt_amd64 (const void *keysched, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, unsigned int nrounds, int encrypt) ASM_FUNC_ABI; void _gcry_aes_vaes_cbc_dec (void *context, unsigned char *iv, void *outbuf, const void *inbuf, size_t nblocks) { RIJNDAEL_context *ctx = context; const void *keysched = ctx->keyschdec32; unsigned int nrounds = ctx->rounds; if (!ctx->decryption_prepared) { _gcry_aes_aesni_prepare_decryption (ctx); ctx->decryption_prepared = 1; } _gcry_vaes_avx2_cbc_dec_amd64 (keysched, iv, outbuf, inbuf, nblocks, nrounds); } void _gcry_aes_vaes_cfb_dec (void *context, unsigned char *iv, void *outbuf, const void *inbuf, size_t nblocks) { RIJNDAEL_context *ctx = context; const void *keysched = ctx->keyschenc32; unsigned int nrounds = ctx->rounds; _gcry_vaes_avx2_cfb_dec_amd64 (keysched, iv, outbuf, inbuf, nblocks, nrounds); } void _gcry_aes_vaes_ctr_enc (void *context, unsigned char *iv, void *outbuf, const void *inbuf, size_t nblocks) { RIJNDAEL_context *ctx = context; const void *keysched = ctx->keyschenc32; unsigned int nrounds = ctx->rounds; _gcry_vaes_avx2_ctr_enc_amd64 (keysched, iv, outbuf, inbuf, nblocks, nrounds); } void _gcry_aes_vaes_ctr32le_enc (void *context, unsigned char *iv, void *outbuf, const void *inbuf, size_t nblocks) { RIJNDAEL_context *ctx = context; const void *keysched = ctx->keyschenc32; unsigned int nrounds = ctx->rounds; _gcry_vaes_avx2_ctr32le_enc_amd64 (keysched, iv, outbuf, inbuf, nblocks, nrounds); } size_t _gcry_aes_vaes_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; const void *keysched = encrypt ? ctx->keyschenc32 : ctx->keyschdec32; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned int nrounds = ctx->rounds; u64 blkn = c->u_mode.ocb.data_nblocks; if (!encrypt && !ctx->decryption_prepared) { _gcry_aes_aesni_prepare_decryption (ctx); ctx->decryption_prepared = 1; } c->u_mode.ocb.data_nblocks = blkn + nblocks; _gcry_vaes_avx2_ocb_crypt_amd64 (keysched, (unsigned int)blkn, outbuf, inbuf, nblocks, nrounds, c->u_iv.iv, c->u_ctr.ctr, c->u_mode.ocb.L[0], encrypt); return 0; } void _gcry_aes_vaes_xts_crypt (void *context, unsigned char *tweak, void *outbuf, const void *inbuf, size_t nblocks, int encrypt) { RIJNDAEL_context *ctx = context; const void *keysched = encrypt ? ctx->keyschenc32 : ctx->keyschdec32; unsigned int nrounds = ctx->rounds; if (!encrypt && !ctx->decryption_prepared) { _gcry_aes_aesni_prepare_decryption (ctx); ctx->decryption_prepared = 1; } _gcry_vaes_avx2_xts_crypt_amd64 (keysched, tweak, outbuf, inbuf, nblocks, nrounds, encrypt); } #endif /* USE_VAES */ diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 9b96b616..dddcbc54 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -1,2102 +1,2026 @@ /* 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_ctr32le_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_VAES /* VAES (AMD64) accelerated implementation of AES */ extern void _gcry_aes_vaes_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_vaes_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_vaes_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_vaes_ctr32le_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern size_t _gcry_aes_vaes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); extern void _gcry_aes_vaes_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); extern void _gcry_aes_padlock_prepare_decryption (RIJNDAEL_context *ctx); #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_ctr32le_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*/ #ifdef USE_PPC_CRYPTO /* PowerPC Crypto implementations of AES */ extern void _gcry_aes_ppc8_setkey(RIJNDAEL_context *ctx, const byte *key); extern void _gcry_aes_ppc8_prepare_decryption(RIJNDAEL_context *ctx); extern unsigned int _gcry_aes_ppc8_encrypt(const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern unsigned int _gcry_aes_ppc8_decrypt(const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern void _gcry_aes_ppc8_cfb_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_ppc8_cbc_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int cbc_mac); extern void _gcry_aes_ppc8_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_ppc8_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_ppc8_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern size_t _gcry_aes_ppc8_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); extern size_t _gcry_aes_ppc8_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); extern void _gcry_aes_ppc8_xts_crypt (void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); #endif /*USE_PPC_CRYPTO*/ #ifdef USE_PPC_CRYPTO_WITH_PPC9LE /* Power9 little-endian crypto implementations of AES */ extern unsigned int _gcry_aes_ppc9le_encrypt(const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern unsigned int _gcry_aes_ppc9le_decrypt(const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern void _gcry_aes_ppc9le_cfb_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_ppc9le_cbc_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int cbc_mac); extern void _gcry_aes_ppc9le_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_ppc9le_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_ppc9le_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern size_t _gcry_aes_ppc9le_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); extern size_t _gcry_aes_ppc9le_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); extern void _gcry_aes_ppc9le_xts_crypt (void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); extern size_t _gcry_aes_p10le_gcm_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); #endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ #ifdef USE_S390X_CRYPTO /* zSeries crypto implementations of AES */ extern int _gcry_aes_s390x_setup_acceleration(RIJNDAEL_context *ctx, unsigned int keylen, unsigned int hwfeatures, cipher_bulk_ops_t *bulk_ops); extern void _gcry_aes_s390x_setkey(RIJNDAEL_context *ctx, const byte *key); extern void _gcry_aes_s390x_prepare_decryption(RIJNDAEL_context *ctx); extern unsigned int _gcry_aes_s390x_encrypt(const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern unsigned int _gcry_aes_s390x_decrypt(const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); #endif /*USE_S390X_CRYPTO*/ 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); static void _gcry_aes_cfb_enc (void *context, unsigned char *iv, void *outbuf, const void *inbuf, size_t nblocks); static void _gcry_aes_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static void _gcry_aes_cbc_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int cbc_mac); static void _gcry_aes_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static void _gcry_aes_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static size_t _gcry_aes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); static size_t _gcry_aes_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); static void _gcry_aes_xts_crypt (void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); /* All the numbers. */ #include "rijndael-tables.h" /* Function prototypes. */ static const char *selftest(void); static void prepare_decryption(RIJNDAEL_context *ctx); /* Prefetching for encryption/decryption tables. */ static inline void prefetch_table(const volatile byte *tab, size_t len) { size_t i; for (i = 0; len - i >= 8 * 32; 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]; } for (; i < len; i += 32) { (void)tab[i]; } (void)tab[len - 1]; } static void prefetch_enc(void) { /* Modify counters to trigger copy-on-write and unsharing if physical pages * of look-up table are shared between processes. Modifying counters also * causes checksums for pages to change and hint same-page merging algorithm * that these pages are frequently changing. */ enc_tables.counter_head++; enc_tables.counter_tail++; /* Prefetch look-up tables to cache. */ prefetch_table((const void *)&enc_tables, sizeof(enc_tables)); } static void prefetch_dec(void) { /* Modify counters to trigger copy-on-write and unsharing if physical pages * of look-up table are shared between processes. Modifying counters also * causes checksums for pages to change and hint same-page merging algorithm * that these pages are frequently changing. */ dec_tables.counter_head++; dec_tables.counter_tail++; /* Prefetch look-up tables to cache. */ 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, cipher_bulk_ops_t *bulk_ops) { static int initialized = 0; static const char *selftest_failed = 0; void (*hw_setkey)(RIJNDAEL_context *ctx, const byte *key) = NULL; int rounds; int i,j, r, t, rconpointer = 0; int KC; unsigned int hwfeatures; /* 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; hwfeatures = _gcry_get_hw_features (); ctx->decryption_prepared = 0; /* Setup default bulk encryption routines. */ memset (bulk_ops, 0, sizeof(*bulk_ops)); bulk_ops->cfb_enc = _gcry_aes_cfb_enc; bulk_ops->cfb_dec = _gcry_aes_cfb_dec; bulk_ops->cbc_enc = _gcry_aes_cbc_enc; bulk_ops->cbc_dec = _gcry_aes_cbc_dec; bulk_ops->ctr_enc = _gcry_aes_ctr_enc; bulk_ops->ocb_crypt = _gcry_aes_ocb_crypt; bulk_ops->ocb_auth = _gcry_aes_ocb_auth; bulk_ops->xts_crypt = _gcry_aes_xts_crypt; (void)hwfeatures; if (0) { ; } #ifdef USE_AESNI else if (hwfeatures & HWF_INTEL_AESNI) { hw_setkey = _gcry_aes_aesni_do_setkey; 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->prepare_decryption = _gcry_aes_aesni_prepare_decryption; ctx->use_avx = !!(hwfeatures & HWF_INTEL_AVX); ctx->use_avx2 = !!(hwfeatures & HWF_INTEL_AVX2); /* Setup AES-NI bulk encryption routines. */ bulk_ops->cfb_enc = _gcry_aes_aesni_cfb_enc; bulk_ops->cfb_dec = _gcry_aes_aesni_cfb_dec; bulk_ops->cbc_enc = _gcry_aes_aesni_cbc_enc; bulk_ops->cbc_dec = _gcry_aes_aesni_cbc_dec; bulk_ops->ctr_enc = _gcry_aes_aesni_ctr_enc; bulk_ops->ctr32le_enc = _gcry_aes_aesni_ctr32le_enc; bulk_ops->ocb_crypt = _gcry_aes_aesni_ocb_crypt; bulk_ops->ocb_auth = _gcry_aes_aesni_ocb_auth; bulk_ops->xts_crypt = _gcry_aes_aesni_xts_crypt; #ifdef USE_VAES if ((hwfeatures & HWF_INTEL_VAES_VPCLMUL) && (hwfeatures & HWF_INTEL_AVX2)) { /* Setup VAES bulk encryption routines. */ bulk_ops->cfb_dec = _gcry_aes_vaes_cfb_dec; bulk_ops->cbc_dec = _gcry_aes_vaes_cbc_dec; bulk_ops->ctr_enc = _gcry_aes_vaes_ctr_enc; bulk_ops->ctr32le_enc = _gcry_aes_vaes_ctr32le_enc; bulk_ops->ocb_crypt = _gcry_aes_vaes_ocb_crypt; bulk_ops->xts_crypt = _gcry_aes_vaes_xts_crypt; } #endif } #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->prepare_decryption = _gcry_aes_padlock_prepare_decryption; memcpy (ctx->padlockkey, key, keylen); } #endif #ifdef USE_SSSE3 else if (hwfeatures & HWF_INTEL_SSSE3) { hw_setkey = _gcry_aes_ssse3_do_setkey; 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->prepare_decryption = _gcry_aes_ssse3_prepare_decryption; /* Setup SSSE3 bulk encryption routines. */ bulk_ops->cfb_enc = _gcry_aes_ssse3_cfb_enc; bulk_ops->cfb_dec = _gcry_aes_ssse3_cfb_dec; bulk_ops->cbc_enc = _gcry_aes_ssse3_cbc_enc; bulk_ops->cbc_dec = _gcry_aes_ssse3_cbc_dec; bulk_ops->ctr_enc = _gcry_aes_ssse3_ctr_enc; bulk_ops->ocb_crypt = _gcry_aes_ssse3_ocb_crypt; bulk_ops->ocb_auth = _gcry_aes_ssse3_ocb_auth; } #endif #ifdef USE_ARM_CE else if (hwfeatures & HWF_ARM_AES) { hw_setkey = _gcry_aes_armv8_ce_setkey; 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->prepare_decryption = _gcry_aes_armv8_ce_prepare_decryption; /* Setup ARM-CE bulk encryption routines. */ bulk_ops->cfb_enc = _gcry_aes_armv8_ce_cfb_enc; bulk_ops->cfb_dec = _gcry_aes_armv8_ce_cfb_dec; bulk_ops->cbc_enc = _gcry_aes_armv8_ce_cbc_enc; bulk_ops->cbc_dec = _gcry_aes_armv8_ce_cbc_dec; bulk_ops->ctr_enc = _gcry_aes_armv8_ce_ctr_enc; bulk_ops->ctr32le_enc = _gcry_aes_armv8_ce_ctr32le_enc; bulk_ops->ocb_crypt = _gcry_aes_armv8_ce_ocb_crypt; bulk_ops->ocb_auth = _gcry_aes_armv8_ce_ocb_auth; bulk_ops->xts_crypt = _gcry_aes_armv8_ce_xts_crypt; } #endif #ifdef USE_PPC_CRYPTO_WITH_PPC9LE else if ((hwfeatures & HWF_PPC_VCRYPTO) && (hwfeatures & HWF_PPC_ARCH_3_00)) { hw_setkey = _gcry_aes_ppc8_setkey; ctx->encrypt_fn = _gcry_aes_ppc9le_encrypt; ctx->decrypt_fn = _gcry_aes_ppc9le_decrypt; ctx->prefetch_enc_fn = NULL; ctx->prefetch_dec_fn = NULL; ctx->prepare_decryption = _gcry_aes_ppc8_prepare_decryption; /* Setup PPC9LE bulk encryption routines. */ bulk_ops->cfb_enc = _gcry_aes_ppc9le_cfb_enc; bulk_ops->cfb_dec = _gcry_aes_ppc9le_cfb_dec; bulk_ops->cbc_enc = _gcry_aes_ppc9le_cbc_enc; bulk_ops->cbc_dec = _gcry_aes_ppc9le_cbc_dec; bulk_ops->ctr_enc = _gcry_aes_ppc9le_ctr_enc; bulk_ops->ocb_crypt = _gcry_aes_ppc9le_ocb_crypt; bulk_ops->ocb_auth = _gcry_aes_ppc9le_ocb_auth; bulk_ops->xts_crypt = _gcry_aes_ppc9le_xts_crypt; if (hwfeatures & HWF_PPC_ARCH_3_10) /* for P10 */ bulk_ops->gcm_crypt = _gcry_aes_p10le_gcm_crypt; } #endif #ifdef USE_PPC_CRYPTO else if (hwfeatures & HWF_PPC_VCRYPTO) { hw_setkey = _gcry_aes_ppc8_setkey; ctx->encrypt_fn = _gcry_aes_ppc8_encrypt; ctx->decrypt_fn = _gcry_aes_ppc8_decrypt; ctx->prefetch_enc_fn = NULL; ctx->prefetch_dec_fn = NULL; ctx->prepare_decryption = _gcry_aes_ppc8_prepare_decryption; /* Setup PPC8 bulk encryption routines. */ bulk_ops->cfb_enc = _gcry_aes_ppc8_cfb_enc; bulk_ops->cfb_dec = _gcry_aes_ppc8_cfb_dec; bulk_ops->cbc_enc = _gcry_aes_ppc8_cbc_enc; bulk_ops->cbc_dec = _gcry_aes_ppc8_cbc_dec; bulk_ops->ctr_enc = _gcry_aes_ppc8_ctr_enc; bulk_ops->ocb_crypt = _gcry_aes_ppc8_ocb_crypt; bulk_ops->ocb_auth = _gcry_aes_ppc8_ocb_auth; bulk_ops->xts_crypt = _gcry_aes_ppc8_xts_crypt; } #endif #ifdef USE_S390X_CRYPTO else if (_gcry_aes_s390x_setup_acceleration (ctx, keylen, hwfeatures, bulk_ops)) { hw_setkey = _gcry_aes_s390x_setkey; ctx->encrypt_fn = _gcry_aes_s390x_encrypt; ctx->decrypt_fn = _gcry_aes_s390x_decrypt; ctx->prefetch_enc_fn = NULL; ctx->prefetch_dec_fn = NULL; ctx->prepare_decryption = _gcry_aes_s390x_prepare_decryption; } #endif else { ctx->encrypt_fn = do_encrypt; ctx->decrypt_fn = do_decrypt; ctx->prefetch_enc_fn = prefetch_enc; ctx->prefetch_dec_fn = prefetch_dec; ctx->prepare_decryption = prepare_decryption; } /* NB: We don't yet support Padlock hardware key generation. */ if (hw_setkey) { hw_setkey (ctx, key); } 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, cipher_bulk_ops_t *bulk_ops) { RIJNDAEL_context *ctx = context; return do_setkey (ctx, key, keylen, bulk_ops); } /* Make a decryption key from an encryption key. */ static void prepare_decryption( RIJNDAEL_context *ctx ) { const byte *sbox = ((const byte *)encT) + 1; int r; 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] = ((u32)sbox[(byte)(sa[0] >> (0 * 8)) * 4]) << (0 * 8); sb[3] = ((u32)sbox[(byte)(sa[0] >> (1 * 8)) * 4]) << (1 * 8); sb[2] = ((u32)sbox[(byte)(sa[0] >> (2 * 8)) * 4]) << (2 * 8); sb[1] = ((u32)sbox[(byte)(sa[0] >> (3 * 8)) * 4]) << (3 * 8); sa[0] = rk[r][0] ^ sb[0]; sb[1] ^= ((u32)sbox[(byte)(sa[1] >> (0 * 8)) * 4]) << (0 * 8); sa[0] ^= ((u32)sbox[(byte)(sa[1] >> (1 * 8)) * 4]) << (1 * 8); sb[3] ^= ((u32)sbox[(byte)(sa[1] >> (2 * 8)) * 4]) << (2 * 8); sb[2] ^= ((u32)sbox[(byte)(sa[1] >> (3 * 8)) * 4]) << (3 * 8); sa[1] = rk[r][1] ^ sb[1]; sb[2] ^= ((u32)sbox[(byte)(sa[2] >> (0 * 8)) * 4]) << (0 * 8); sa[1] ^= ((u32)sbox[(byte)(sa[2] >> (1 * 8)) * 4]) << (1 * 8); sa[0] ^= ((u32)sbox[(byte)(sa[2] >> (2 * 8)) * 4]) << (2 * 8); sb[3] ^= ((u32)sbox[(byte)(sa[2] >> (3 * 8)) * 4]) << (3 * 8); sa[2] = rk[r][2] ^ sb[2]; sb[3] ^= ((u32)sbox[(byte)(sa[3] >> (0 * 8)) * 4]) << (0 * 8); sa[2] ^= ((u32)sbox[(byte)(sa[3] >> (1 * 8)) * 4]) << (1 * 8); sa[1] ^= ((u32)sbox[(byte)(sa[3] >> (2 * 8)) * 4]) << (2 * 8); sa[0] ^= ((u32)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, enc_tables.T); #elif defined(USE_ARM_ASM) return _gcry_aes_arm_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds, enc_tables.T); #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. */ static 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; 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. */ static 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; 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. */ static 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; 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. */ cipher_block_add(ctr, 1, BLOCKSIZE); } 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] = (u32)inv_sbox[(byte)(sa[0] >> (0 * 8))] << (0 * 8); sb[1] = (u32)inv_sbox[(byte)(sa[0] >> (1 * 8))] << (1 * 8); sb[2] = (u32)inv_sbox[(byte)(sa[0] >> (2 * 8))] << (2 * 8); sb[3] = (u32)inv_sbox[(byte)(sa[0] >> (3 * 8))] << (3 * 8); sa[0] = sb[0] ^ rk[0][0]; sb[1] ^= (u32)inv_sbox[(byte)(sa[1] >> (0 * 8))] << (0 * 8); sb[2] ^= (u32)inv_sbox[(byte)(sa[1] >> (1 * 8))] << (1 * 8); sb[3] ^= (u32)inv_sbox[(byte)(sa[1] >> (2 * 8))] << (2 * 8); sa[0] ^= (u32)inv_sbox[(byte)(sa[1] >> (3 * 8))] << (3 * 8); sa[1] = sb[1] ^ rk[0][1]; sb[2] ^= (u32)inv_sbox[(byte)(sa[2] >> (0 * 8))] << (0 * 8); sb[3] ^= (u32)inv_sbox[(byte)(sa[2] >> (1 * 8))] << (1 * 8); sa[0] ^= (u32)inv_sbox[(byte)(sa[2] >> (2 * 8))] << (2 * 8); sa[1] ^= (u32)inv_sbox[(byte)(sa[2] >> (3 * 8))] << (3 * 8); sa[2] = sb[2] ^ rk[0][2]; sb[3] ^= (u32)inv_sbox[(byte)(sa[3] >> (0 * 8))] << (0 * 8); sa[0] ^= (u32)inv_sbox[(byte)(sa[3] >> (1 * 8))] << (1 * 8); sa[1] ^= (u32)inv_sbox[(byte)(sa[3] >> (2 * 8))] << (2 * 8); sa[2] ^= (u32)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.T); #elif defined(USE_ARM_ASM) return _gcry_aes_arm_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds, dec_tables.T); #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 ) { ctx->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. */ static 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; 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. */ static 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; 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. */ static 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 (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. */ static 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; 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. */ static 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 (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 ctxmem[sizeof(*ctx) + 16]; unsigned char scratch[16]; cipher_bulk_ops_t bulk_ops; /* 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"; + ctx = (void *)(ctxmem + ((16 - ((uintptr_t)ctxmem & 15)) & 15)); rijndael_setkey (ctx, key_128, sizeof (key_128), &bulk_ops); 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 ctxmem[sizeof(*ctx) + 16]; unsigned char scratch[16]; cipher_bulk_ops_t bulk_ops; 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"; + ctx = (void *)(ctxmem + ((16 - ((uintptr_t)ctxmem & 15)) & 15)); + rijndael_setkey (ctx, key_192, sizeof(key_192), &bulk_ops); 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 ctxmem[sizeof(*ctx) + 16]; unsigned char scratch[16]; cipher_bulk_ops_t bulk_ops; 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"; + ctx = (void *)(ctxmem + ((16 - ((uintptr_t)ctxmem & 15)) & 15)); + rijndael_setkey (ctx, key_256, sizeof(key_256), &bulk_ops); 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) -{ -#ifdef USE_VAES - const int nblocks = 16+1; -#else - const int nblocks = 8+1; -#endif - const int blocksize = BLOCKSIZE; - const int context_size = sizeof(RIJNDAEL_context); - - return _gcry_selftest_helper_ctr("AES", &rijndael_setkey, - &rijndael_encrypt, 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) -{ -#ifdef USE_VAES - const int nblocks = 16+2; -#else - const int nblocks = 8+2; -#endif - const int blocksize = BLOCKSIZE; - const int context_size = sizeof(RIJNDAEL_context); - - return _gcry_selftest_helper_cbc("AES", &rijndael_setkey, - &rijndael_encrypt, 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) -{ -#ifdef USE_VAES - const int nblocks = 16+2; -#else - const int nblocks = 8+2; -#endif - const int blocksize = BLOCKSIZE; - const int context_size = sizeof(RIJNDAEL_context); - - return _gcry_selftest_helper_cfb("AES", &rijndael_setkey, - &rijndael_encrypt, 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 const 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 }, { "2.16.840.1.101.3.4.1.6", GCRY_CIPHER_MODE_GCM }, { "2.16.840.1.101.3.4.1.7", GCRY_CIPHER_MODE_CCM }, { 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 const 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 }, { "2.16.840.1.101.3.4.1.26", GCRY_CIPHER_MODE_GCM }, { "2.16.840.1.101.3.4.1.27", GCRY_CIPHER_MODE_CCM }, { 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 const 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 }, { "2.16.840.1.101.3.4.1.46", GCRY_CIPHER_MODE_GCM }, { "2.16.840.1.101.3.4.1.47", GCRY_CIPHER_MODE_CCM }, { 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/cipher/serpent.c b/cipher/serpent.c index dfe5cc28..11eeb079 100644 --- a/cipher/serpent.c +++ b/cipher/serpent.c @@ -1,1744 +1,1691 @@ /* serpent.c - Implementation of the Serpent encryption algorithm. * Copyright (C) 2003, 2004, 2005 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include #include #include #include "types.h" #include "g10lib.h" #include "cipher.h" #include "bithelp.h" #include "bufhelp.h" #include "cipher-internal.h" -#include "cipher-selftest.h" #include "bulkhelp.h" /* USE_SSE2 indicates whether to compile with AMD64 SSE2 code. */ #undef USE_SSE2 #if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_SSE2 1 #endif /* USE_AVX2 indicates whether to compile with AMD64 AVX2 code. */ #undef USE_AVX2 #if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # if defined(ENABLE_AVX2_SUPPORT) # define USE_AVX2 1 # endif #endif /* USE_NEON indicates whether to enable ARM NEON assembly code. */ #undef USE_NEON #ifdef ENABLE_NEON_SUPPORT # if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \ && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \ && defined(HAVE_GCC_INLINE_ASM_NEON) # define USE_NEON 1 # endif #endif /*ENABLE_NEON_SUPPORT*/ /* Number of rounds per Serpent encrypt/decrypt operation. */ #define ROUNDS 32 /* Magic number, used during generating of the subkeys. */ #define PHI 0x9E3779B9 /* Serpent works on 128 bit blocks. */ typedef u32 serpent_block_t[4]; /* Serpent key, provided by the user. If the original key is shorter than 256 bits, it is padded. */ typedef u32 serpent_key_t[8]; /* The key schedule consists of 33 128 bit subkeys. */ typedef u32 serpent_subkeys_t[ROUNDS + 1][4]; /* A Serpent context. */ typedef struct serpent_context { serpent_subkeys_t keys; /* Generated subkeys. */ #ifdef USE_AVX2 int use_avx2; #endif #ifdef USE_NEON int use_neon; #endif } serpent_context_t; /* Assembly implementations use SystemV ABI, ABI conversion and additional * stack to store XMM6-XMM15 needed on Win64. */ #undef ASM_FUNC_ABI #if defined(USE_SSE2) || defined(USE_AVX2) # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS # define ASM_FUNC_ABI __attribute__((sysv_abi)) # else # define ASM_FUNC_ABI # endif #endif #ifdef USE_SSE2 /* Assembler implementations of Serpent using SSE2. Process 8 block in parallel. */ extern void _gcry_serpent_sse2_ctr_enc(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *ctr) ASM_FUNC_ABI; extern void _gcry_serpent_sse2_cbc_dec(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_serpent_sse2_cfb_dec(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_serpent_sse2_ocb_enc(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[8]) ASM_FUNC_ABI; extern void _gcry_serpent_sse2_ocb_dec(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[8]) ASM_FUNC_ABI; extern void _gcry_serpent_sse2_ocb_auth(serpent_context_t *ctx, const unsigned char *abuf, unsigned char *offset, unsigned char *checksum, const u64 Ls[8]) ASM_FUNC_ABI; #endif #ifdef USE_AVX2 /* Assembler implementations of Serpent using AVX2. Process 16 block in parallel. */ extern void _gcry_serpent_avx2_ctr_enc(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *ctr) ASM_FUNC_ABI; extern void _gcry_serpent_avx2_cbc_dec(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_serpent_avx2_cfb_dec(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_serpent_avx2_ocb_enc(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; extern void _gcry_serpent_avx2_ocb_dec(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; extern void _gcry_serpent_avx2_ocb_auth(serpent_context_t *ctx, const unsigned char *abuf, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; #endif #ifdef USE_NEON /* Assembler implementations of Serpent using ARM NEON. Process 8 block in parallel. */ extern void _gcry_serpent_neon_ctr_enc(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *ctr); extern void _gcry_serpent_neon_cbc_dec(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv); extern void _gcry_serpent_neon_cfb_dec(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv); extern void _gcry_serpent_neon_ocb_enc(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const void *Ls[8]); extern void _gcry_serpent_neon_ocb_dec(serpent_context_t *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const void *Ls[8]); extern void _gcry_serpent_neon_ocb_auth(serpent_context_t *ctx, const unsigned char *abuf, unsigned char *offset, unsigned char *checksum, const void *Ls[8]); #endif /* Prototypes. */ static const char *serpent_test (void); static void _gcry_serpent_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static void _gcry_serpent_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static void _gcry_serpent_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static size_t _gcry_serpent_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); static size_t _gcry_serpent_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); /* * These are the S-Boxes of Serpent from following research paper. * * D. A. Osvik, “Speeding up Serpent,” in Third AES Candidate Conference, * (New York, New York, USA), p. 317–329, National Institute of Standards and * Technology, 2000. * * Paper is also available at: http://www.ii.uib.no/~osvik/pub/aes3.pdf * */ #define SBOX0(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r3 ^= r0; r4 = r1; \ r1 &= r3; r4 ^= r2; \ r1 ^= r0; r0 |= r3; \ r0 ^= r4; r4 ^= r3; \ r3 ^= r2; r2 |= r1; \ r2 ^= r4; r4 = ~r4; \ r4 |= r1; r1 ^= r3; \ r1 ^= r4; r3 |= r0; \ r1 ^= r3; r4 ^= r3; \ \ w = r1; x = r4; y = r2; z = r0; \ } #define SBOX0_INVERSE(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r2 = ~r2; r4 = r1; \ r1 |= r0; r4 = ~r4; \ r1 ^= r2; r2 |= r4; \ r1 ^= r3; r0 ^= r4; \ r2 ^= r0; r0 &= r3; \ r4 ^= r0; r0 |= r1; \ r0 ^= r2; r3 ^= r4; \ r2 ^= r1; r3 ^= r0; \ r3 ^= r1; \ r2 &= r3; \ r4 ^= r2; \ \ w = r0; x = r4; y = r1; z = r3; \ } #define SBOX1(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r0 = ~r0; r2 = ~r2; \ r4 = r0; r0 &= r1; \ r2 ^= r0; r0 |= r3; \ r3 ^= r2; r1 ^= r0; \ r0 ^= r4; r4 |= r1; \ r1 ^= r3; r2 |= r0; \ r2 &= r4; r0 ^= r1; \ r1 &= r2; \ r1 ^= r0; r0 &= r2; \ r0 ^= r4; \ \ w = r2; x = r0; y = r3; z = r1; \ } #define SBOX1_INVERSE(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r4 = r1; r1 ^= r3; \ r3 &= r1; r4 ^= r2; \ r3 ^= r0; r0 |= r1; \ r2 ^= r3; r0 ^= r4; \ r0 |= r2; r1 ^= r3; \ r0 ^= r1; r1 |= r3; \ r1 ^= r0; r4 = ~r4; \ r4 ^= r1; r1 |= r0; \ r1 ^= r0; \ r1 |= r4; \ r3 ^= r1; \ \ w = r4; x = r0; y = r3; z = r2; \ } #define SBOX2(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r4 = r0; r0 &= r2; \ r0 ^= r3; r2 ^= r1; \ r2 ^= r0; r3 |= r4; \ r3 ^= r1; r4 ^= r2; \ r1 = r3; r3 |= r4; \ r3 ^= r0; r0 &= r1; \ r4 ^= r0; r1 ^= r3; \ r1 ^= r4; r4 = ~r4; \ \ w = r2; x = r3; y = r1; z = r4; \ } #define SBOX2_INVERSE(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r2 ^= r3; r3 ^= r0; \ r4 = r3; r3 &= r2; \ r3 ^= r1; r1 |= r2; \ r1 ^= r4; r4 &= r3; \ r2 ^= r3; r4 &= r0; \ r4 ^= r2; r2 &= r1; \ r2 |= r0; r3 = ~r3; \ r2 ^= r3; r0 ^= r3; \ r0 &= r1; r3 ^= r4; \ r3 ^= r0; \ \ w = r1; x = r4; y = r2; z = r3; \ } #define SBOX3(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r4 = r0; r0 |= r3; \ r3 ^= r1; r1 &= r4; \ r4 ^= r2; r2 ^= r3; \ r3 &= r0; r4 |= r1; \ r3 ^= r4; r0 ^= r1; \ r4 &= r0; r1 ^= r3; \ r4 ^= r2; r1 |= r0; \ r1 ^= r2; r0 ^= r3; \ r2 = r1; r1 |= r3; \ r1 ^= r0; \ \ w = r1; x = r2; y = r3; z = r4; \ } #define SBOX3_INVERSE(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r4 = r2; r2 ^= r1; \ r0 ^= r2; r4 &= r2; \ r4 ^= r0; r0 &= r1; \ r1 ^= r3; r3 |= r4; \ r2 ^= r3; r0 ^= r3; \ r1 ^= r4; r3 &= r2; \ r3 ^= r1; r1 ^= r0; \ r1 |= r2; r0 ^= r3; \ r1 ^= r4; \ r0 ^= r1; \ \ w = r2; x = r1; y = r3; z = r0; \ } #define SBOX4(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r1 ^= r3; r3 = ~r3; \ r2 ^= r3; r3 ^= r0; \ r4 = r1; r1 &= r3; \ r1 ^= r2; r4 ^= r3; \ r0 ^= r4; r2 &= r4; \ r2 ^= r0; r0 &= r1; \ r3 ^= r0; r4 |= r1; \ r4 ^= r0; r0 |= r3; \ r0 ^= r2; r2 &= r3; \ r0 = ~r0; r4 ^= r2; \ \ w = r1; x = r4; y = r0; z = r3; \ } #define SBOX4_INVERSE(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r4 = r2; r2 &= r3; \ r2 ^= r1; r1 |= r3; \ r1 &= r0; r4 ^= r2; \ r4 ^= r1; r1 &= r2; \ r0 = ~r0; r3 ^= r4; \ r1 ^= r3; r3 &= r0; \ r3 ^= r2; r0 ^= r1; \ r2 &= r0; r3 ^= r0; \ r2 ^= r4; \ r2 |= r3; r3 ^= r0; \ r2 ^= r1; \ \ w = r0; x = r3; y = r2; z = r4; \ } #define SBOX5(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r0 ^= r1; r1 ^= r3; \ r3 = ~r3; r4 = r1; \ r1 &= r0; r2 ^= r3; \ r1 ^= r2; r2 |= r4; \ r4 ^= r3; r3 &= r1; \ r3 ^= r0; r4 ^= r1; \ r4 ^= r2; r2 ^= r0; \ r0 &= r3; r2 = ~r2; \ r0 ^= r4; r4 |= r3; \ r2 ^= r4; \ \ w = r1; x = r3; y = r0; z = r2; \ } #define SBOX5_INVERSE(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r1 = ~r1; r4 = r3; \ r2 ^= r1; r3 |= r0; \ r3 ^= r2; r2 |= r1; \ r2 &= r0; r4 ^= r3; \ r2 ^= r4; r4 |= r0; \ r4 ^= r1; r1 &= r2; \ r1 ^= r3; r4 ^= r2; \ r3 &= r4; r4 ^= r1; \ r3 ^= r4; r4 = ~r4; \ r3 ^= r0; \ \ w = r1; x = r4; y = r3; z = r2; \ } #define SBOX6(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r2 = ~r2; r4 = r3; \ r3 &= r0; r0 ^= r4; \ r3 ^= r2; r2 |= r4; \ r1 ^= r3; r2 ^= r0; \ r0 |= r1; r2 ^= r1; \ r4 ^= r0; r0 |= r3; \ r0 ^= r2; r4 ^= r3; \ r4 ^= r0; r3 = ~r3; \ r2 &= r4; \ r2 ^= r3; \ \ w = r0; x = r1; y = r4; z = r2; \ } #define SBOX6_INVERSE(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r0 ^= r2; r4 = r2; \ r2 &= r0; r4 ^= r3; \ r2 = ~r2; r3 ^= r1; \ r2 ^= r3; r4 |= r0; \ r0 ^= r2; r3 ^= r4; \ r4 ^= r1; r1 &= r3; \ r1 ^= r0; r0 ^= r3; \ r0 |= r2; r3 ^= r1; \ r4 ^= r0; \ \ w = r1; x = r2; y = r4; z = r3; \ } #define SBOX7(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r4 = r1; r1 |= r2; \ r1 ^= r3; r4 ^= r2; \ r2 ^= r1; r3 |= r4; \ r3 &= r0; r4 ^= r2; \ r3 ^= r1; r1 |= r4; \ r1 ^= r0; r0 |= r4; \ r0 ^= r2; r1 ^= r4; \ r2 ^= r1; r1 &= r0; \ r1 ^= r4; r2 = ~r2; \ r2 |= r0; \ r4 ^= r2; \ \ w = r4; x = r3; y = r1; z = r0; \ } #define SBOX7_INVERSE(r0, r1, r2, r3, w, x, y, z) \ { \ u32 r4; \ \ r4 = r2; r2 ^= r0; \ r0 &= r3; r4 |= r3; \ r2 = ~r2; r3 ^= r1; \ r1 |= r0; r0 ^= r2; \ r2 &= r4; r3 &= r4; \ r1 ^= r2; r2 ^= r0; \ r0 |= r2; r4 ^= r1; \ r0 ^= r3; r3 ^= r4; \ r4 |= r0; r3 ^= r2; \ r4 ^= r2; \ \ w = r3; x = r0; y = r1; z = r4; \ } /* XOR BLOCK1 into BLOCK0. */ #define BLOCK_XOR(block0, block1) \ { \ block0[0] ^= block1[0]; \ block0[1] ^= block1[1]; \ block0[2] ^= block1[2]; \ block0[3] ^= block1[3]; \ } /* Copy BLOCK_SRC to BLOCK_DST. */ #define BLOCK_COPY(block_dst, block_src) \ { \ block_dst[0] = block_src[0]; \ block_dst[1] = block_src[1]; \ block_dst[2] = block_src[2]; \ block_dst[3] = block_src[3]; \ } /* Apply SBOX number WHICH to to the block found in ARRAY0, writing the output to the block found in ARRAY1. */ #define SBOX(which, array0, array1) \ SBOX##which (array0[0], array0[1], array0[2], array0[3], \ array1[0], array1[1], array1[2], array1[3]); /* Apply inverse SBOX number WHICH to to the block found in ARRAY0, writing the output to the block found in ARRAY1. */ #define SBOX_INVERSE(which, array0, array1) \ SBOX##which##_INVERSE (array0[0], array0[1], array0[2], array0[3], \ array1[0], array1[1], array1[2], array1[3]); /* Apply the linear transformation to BLOCK. */ #define LINEAR_TRANSFORMATION(block) \ { \ block[0] = rol (block[0], 13); \ block[2] = rol (block[2], 3); \ block[1] = block[1] ^ block[0] ^ block[2]; \ block[3] = block[3] ^ block[2] ^ (block[0] << 3); \ block[1] = rol (block[1], 1); \ block[3] = rol (block[3], 7); \ block[0] = block[0] ^ block[1] ^ block[3]; \ block[2] = block[2] ^ block[3] ^ (block[1] << 7); \ block[0] = rol (block[0], 5); \ block[2] = rol (block[2], 22); \ } /* Apply the inverse linear transformation to BLOCK. */ #define LINEAR_TRANSFORMATION_INVERSE(block) \ { \ block[2] = ror (block[2], 22); \ block[0] = ror (block[0] , 5); \ block[2] = block[2] ^ block[3] ^ (block[1] << 7); \ block[0] = block[0] ^ block[1] ^ block[3]; \ block[3] = ror (block[3], 7); \ block[1] = ror (block[1], 1); \ block[3] = block[3] ^ block[2] ^ (block[0] << 3); \ block[1] = block[1] ^ block[0] ^ block[2]; \ block[2] = ror (block[2], 3); \ block[0] = ror (block[0], 13); \ } /* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage. This macro increments `round'. */ #define ROUND(which, subkeys, block, block_tmp) \ { \ BLOCK_XOR (block, subkeys[round]); \ round++; \ SBOX (which, block, block_tmp); \ LINEAR_TRANSFORMATION (block_tmp); \ BLOCK_COPY (block, block_tmp); \ } /* Apply the last Serpent round to BLOCK, using the SBOX number WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage. The result will be stored in BLOCK_TMP. This macro increments `round'. */ #define ROUND_LAST(which, subkeys, block, block_tmp) \ { \ BLOCK_XOR (block, subkeys[round]); \ round++; \ SBOX (which, block, block_tmp); \ BLOCK_XOR (block_tmp, subkeys[round]); \ round++; \ } /* Apply an inverse Serpent round to BLOCK, using the SBOX number WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage. This macro increments `round'. */ #define ROUND_INVERSE(which, subkey, block, block_tmp) \ { \ LINEAR_TRANSFORMATION_INVERSE (block); \ SBOX_INVERSE (which, block, block_tmp); \ BLOCK_XOR (block_tmp, subkey[round]); \ round--; \ BLOCK_COPY (block, block_tmp); \ } /* Apply the first Serpent round to BLOCK, using the SBOX number WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage. The result will be stored in BLOCK_TMP. This macro increments `round'. */ #define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \ { \ BLOCK_XOR (block, subkeys[round]); \ round--; \ SBOX_INVERSE (which, block, block_tmp); \ BLOCK_XOR (block_tmp, subkeys[round]); \ round--; \ } /* Convert the user provided key KEY of KEY_LENGTH bytes into the internally used format. */ static void serpent_key_prepare (const byte *key, unsigned int key_length, serpent_key_t key_prepared) { int i; /* Copy key. */ key_length /= 4; for (i = 0; i < key_length; i++) key_prepared[i] = buf_get_le32 (key + i * 4); if (i < 8) { /* Key must be padded according to the Serpent specification. */ key_prepared[i] = 0x00000001; for (i++; i < 8; i++) key_prepared[i] = 0; } } /* Derive the 33 subkeys from KEY and store them in SUBKEYS. */ static void serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys) { u32 w[8]; /* The `prekey'. */ u32 ws[4]; u32 wt[4]; /* Initialize with key values. */ w[0] = key[0]; w[1] = key[1]; w[2] = key[2]; w[3] = key[3]; w[4] = key[4]; w[5] = key[5]; w[6] = key[6]; w[7] = key[7]; /* Expand to intermediate key using the affine recurrence. */ #define EXPAND_KEY4(wo, r) \ wo[0] = w[(r+0)%8] = \ rol (w[(r+0)%8] ^ w[(r+3)%8] ^ w[(r+5)%8] ^ w[(r+7)%8] ^ PHI ^ (r+0), 11); \ wo[1] = w[(r+1)%8] = \ rol (w[(r+1)%8] ^ w[(r+4)%8] ^ w[(r+6)%8] ^ w[(r+0)%8] ^ PHI ^ (r+1), 11); \ wo[2] = w[(r+2)%8] = \ rol (w[(r+2)%8] ^ w[(r+5)%8] ^ w[(r+7)%8] ^ w[(r+1)%8] ^ PHI ^ (r+2), 11); \ wo[3] = w[(r+3)%8] = \ rol (w[(r+3)%8] ^ w[(r+6)%8] ^ w[(r+0)%8] ^ w[(r+2)%8] ^ PHI ^ (r+3), 11); #define EXPAND_KEY(r) \ EXPAND_KEY4(ws, (r)); \ EXPAND_KEY4(wt, (r + 4)); /* Calculate subkeys via S-Boxes, in bitslice mode. */ EXPAND_KEY (0); SBOX (3, ws, subkeys[0]); SBOX (2, wt, subkeys[1]); EXPAND_KEY (8); SBOX (1, ws, subkeys[2]); SBOX (0, wt, subkeys[3]); EXPAND_KEY (16); SBOX (7, ws, subkeys[4]); SBOX (6, wt, subkeys[5]); EXPAND_KEY (24); SBOX (5, ws, subkeys[6]); SBOX (4, wt, subkeys[7]); EXPAND_KEY (32); SBOX (3, ws, subkeys[8]); SBOX (2, wt, subkeys[9]); EXPAND_KEY (40); SBOX (1, ws, subkeys[10]); SBOX (0, wt, subkeys[11]); EXPAND_KEY (48); SBOX (7, ws, subkeys[12]); SBOX (6, wt, subkeys[13]); EXPAND_KEY (56); SBOX (5, ws, subkeys[14]); SBOX (4, wt, subkeys[15]); EXPAND_KEY (64); SBOX (3, ws, subkeys[16]); SBOX (2, wt, subkeys[17]); EXPAND_KEY (72); SBOX (1, ws, subkeys[18]); SBOX (0, wt, subkeys[19]); EXPAND_KEY (80); SBOX (7, ws, subkeys[20]); SBOX (6, wt, subkeys[21]); EXPAND_KEY (88); SBOX (5, ws, subkeys[22]); SBOX (4, wt, subkeys[23]); EXPAND_KEY (96); SBOX (3, ws, subkeys[24]); SBOX (2, wt, subkeys[25]); EXPAND_KEY (104); SBOX (1, ws, subkeys[26]); SBOX (0, wt, subkeys[27]); EXPAND_KEY (112); SBOX (7, ws, subkeys[28]); SBOX (6, wt, subkeys[29]); EXPAND_KEY (120); SBOX (5, ws, subkeys[30]); SBOX (4, wt, subkeys[31]); EXPAND_KEY4 (ws, 128); SBOX (3, ws, subkeys[32]); wipememory (ws, sizeof (ws)); wipememory (wt, sizeof (wt)); wipememory (w, sizeof (w)); } /* Initialize CONTEXT with the key KEY of KEY_LENGTH bits. */ static gcry_err_code_t serpent_setkey_internal (serpent_context_t *context, const byte *key, unsigned int key_length) { serpent_key_t key_prepared; if (key_length > 32) return GPG_ERR_INV_KEYLEN; serpent_key_prepare (key, key_length, key_prepared); serpent_subkeys_generate (key_prepared, context->keys); #ifdef USE_AVX2 context->use_avx2 = 0; if ((_gcry_get_hw_features () & HWF_INTEL_AVX2)) { context->use_avx2 = 1; } #endif #ifdef USE_NEON context->use_neon = 0; if ((_gcry_get_hw_features () & HWF_ARM_NEON)) { context->use_neon = 1; } #endif wipememory (key_prepared, sizeof(key_prepared)); return 0; } /* Initialize CTX with the key KEY of KEY_LENGTH bytes. */ static gcry_err_code_t serpent_setkey (void *ctx, const byte *key, unsigned int key_length, cipher_bulk_ops_t *bulk_ops) { serpent_context_t *context = ctx; static const char *serpent_test_ret; static int serpent_init_done; gcry_err_code_t ret = GPG_ERR_NO_ERROR; if (! serpent_init_done) { /* Execute a self-test the first time, Serpent is used. */ serpent_init_done = 1; serpent_test_ret = serpent_test (); if (serpent_test_ret) log_error ("Serpent test failure: %s\n", serpent_test_ret); } /* Setup bulk encryption routines. */ memset (bulk_ops, 0, sizeof(*bulk_ops)); bulk_ops->cbc_dec = _gcry_serpent_cbc_dec; bulk_ops->cfb_dec = _gcry_serpent_cfb_dec; bulk_ops->ctr_enc = _gcry_serpent_ctr_enc; bulk_ops->ocb_crypt = _gcry_serpent_ocb_crypt; bulk_ops->ocb_auth = _gcry_serpent_ocb_auth; if (serpent_test_ret) ret = GPG_ERR_SELFTEST_FAILED; else ret = serpent_setkey_internal (context, key, key_length); return ret; } static void serpent_encrypt_internal (serpent_context_t *context, const byte *input, byte *output) { serpent_block_t b, b_next; int round = 0; b[0] = buf_get_le32 (input + 0); b[1] = buf_get_le32 (input + 4); b[2] = buf_get_le32 (input + 8); b[3] = buf_get_le32 (input + 12); ROUND (0, context->keys, b, b_next); ROUND (1, context->keys, b, b_next); ROUND (2, context->keys, b, b_next); ROUND (3, context->keys, b, b_next); ROUND (4, context->keys, b, b_next); ROUND (5, context->keys, b, b_next); ROUND (6, context->keys, b, b_next); ROUND (7, context->keys, b, b_next); ROUND (0, context->keys, b, b_next); ROUND (1, context->keys, b, b_next); ROUND (2, context->keys, b, b_next); ROUND (3, context->keys, b, b_next); ROUND (4, context->keys, b, b_next); ROUND (5, context->keys, b, b_next); ROUND (6, context->keys, b, b_next); ROUND (7, context->keys, b, b_next); ROUND (0, context->keys, b, b_next); ROUND (1, context->keys, b, b_next); ROUND (2, context->keys, b, b_next); ROUND (3, context->keys, b, b_next); ROUND (4, context->keys, b, b_next); ROUND (5, context->keys, b, b_next); ROUND (6, context->keys, b, b_next); ROUND (7, context->keys, b, b_next); ROUND (0, context->keys, b, b_next); ROUND (1, context->keys, b, b_next); ROUND (2, context->keys, b, b_next); ROUND (3, context->keys, b, b_next); ROUND (4, context->keys, b, b_next); ROUND (5, context->keys, b, b_next); ROUND (6, context->keys, b, b_next); ROUND_LAST (7, context->keys, b, b_next); buf_put_le32 (output + 0, b_next[0]); buf_put_le32 (output + 4, b_next[1]); buf_put_le32 (output + 8, b_next[2]); buf_put_le32 (output + 12, b_next[3]); } static void serpent_decrypt_internal (serpent_context_t *context, const byte *input, byte *output) { serpent_block_t b, b_next; int round = ROUNDS; b_next[0] = buf_get_le32 (input + 0); b_next[1] = buf_get_le32 (input + 4); b_next[2] = buf_get_le32 (input + 8); b_next[3] = buf_get_le32 (input + 12); ROUND_FIRST_INVERSE (7, context->keys, b_next, b); ROUND_INVERSE (6, context->keys, b, b_next); ROUND_INVERSE (5, context->keys, b, b_next); ROUND_INVERSE (4, context->keys, b, b_next); ROUND_INVERSE (3, context->keys, b, b_next); ROUND_INVERSE (2, context->keys, b, b_next); ROUND_INVERSE (1, context->keys, b, b_next); ROUND_INVERSE (0, context->keys, b, b_next); ROUND_INVERSE (7, context->keys, b, b_next); ROUND_INVERSE (6, context->keys, b, b_next); ROUND_INVERSE (5, context->keys, b, b_next); ROUND_INVERSE (4, context->keys, b, b_next); ROUND_INVERSE (3, context->keys, b, b_next); ROUND_INVERSE (2, context->keys, b, b_next); ROUND_INVERSE (1, context->keys, b, b_next); ROUND_INVERSE (0, context->keys, b, b_next); ROUND_INVERSE (7, context->keys, b, b_next); ROUND_INVERSE (6, context->keys, b, b_next); ROUND_INVERSE (5, context->keys, b, b_next); ROUND_INVERSE (4, context->keys, b, b_next); ROUND_INVERSE (3, context->keys, b, b_next); ROUND_INVERSE (2, context->keys, b, b_next); ROUND_INVERSE (1, context->keys, b, b_next); ROUND_INVERSE (0, context->keys, b, b_next); ROUND_INVERSE (7, context->keys, b, b_next); ROUND_INVERSE (6, context->keys, b, b_next); ROUND_INVERSE (5, context->keys, b, b_next); ROUND_INVERSE (4, context->keys, b, b_next); ROUND_INVERSE (3, context->keys, b, b_next); ROUND_INVERSE (2, context->keys, b, b_next); ROUND_INVERSE (1, context->keys, b, b_next); ROUND_INVERSE (0, context->keys, b, b_next); buf_put_le32 (output + 0, b_next[0]); buf_put_le32 (output + 4, b_next[1]); buf_put_le32 (output + 8, b_next[2]); buf_put_le32 (output + 12, b_next[3]); } static unsigned int serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in) { serpent_context_t *context = ctx; serpent_encrypt_internal (context, buffer_in, buffer_out); return /*burn_stack*/ (2 * sizeof (serpent_block_t)); } static unsigned int serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in) { serpent_context_t *context = ctx; serpent_decrypt_internal (context, buffer_in, buffer_out); return /*burn_stack*/ (2 * sizeof (serpent_block_t)); } /* Bulk encryption of complete blocks in CTR mode. This function is only intended for the bulk encryption feature of cipher.c. CTR is expected to be of size sizeof(serpent_block_t). */ static void _gcry_serpent_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { serpent_context_t *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char tmpbuf[sizeof(serpent_block_t)]; int burn_stack_depth = 2 * sizeof (serpent_block_t); #ifdef USE_AVX2 if (ctx->use_avx2) { int did_use_avx2 = 0; /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_serpent_avx2_ctr_enc(ctx, outbuf, inbuf, ctr); nblocks -= 16; outbuf += 16 * sizeof(serpent_block_t); inbuf += 16 * sizeof(serpent_block_t); did_use_avx2 = 1; } if (did_use_avx2) { /* serpent-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic/sse2 code to handle smaller chunks... */ /* TODO: use caching instead? */ } #endif #ifdef USE_SSE2 { int did_use_sse2 = 0; /* Process data in 8 block chunks. */ while (nblocks >= 8) { _gcry_serpent_sse2_ctr_enc(ctx, outbuf, inbuf, ctr); nblocks -= 8; outbuf += 8 * sizeof(serpent_block_t); inbuf += 8 * sizeof(serpent_block_t); did_use_sse2 = 1; } if (did_use_sse2) { /* serpent-sse2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic code to handle smaller chunks... */ /* TODO: use caching instead? */ } #endif #ifdef USE_NEON if (ctx->use_neon) { int did_use_neon = 0; /* Process data in 8 block chunks. */ while (nblocks >= 8) { _gcry_serpent_neon_ctr_enc(ctx, outbuf, inbuf, ctr); nblocks -= 8; outbuf += 8 * sizeof(serpent_block_t); inbuf += 8 * sizeof(serpent_block_t); did_use_neon = 1; } if (did_use_neon) { /* serpent-neon assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic code to handle smaller chunks... */ /* TODO: use caching instead? */ } #endif for ( ;nblocks; nblocks-- ) { /* Encrypt the counter. */ serpent_encrypt_internal(ctx, ctr, tmpbuf); /* XOR the input with the encrypted counter and store in output. */ cipher_block_xor(outbuf, tmpbuf, inbuf, sizeof(serpent_block_t)); outbuf += sizeof(serpent_block_t); inbuf += sizeof(serpent_block_t); /* Increment the counter. */ cipher_block_add(ctr, 1, sizeof(serpent_block_t)); } wipememory(tmpbuf, sizeof(tmpbuf)); _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CBC mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_serpent_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { serpent_context_t *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char savebuf[sizeof(serpent_block_t)]; int burn_stack_depth = 2 * sizeof (serpent_block_t); #ifdef USE_AVX2 if (ctx->use_avx2) { int did_use_avx2 = 0; /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_serpent_avx2_cbc_dec(ctx, outbuf, inbuf, iv); nblocks -= 16; outbuf += 16 * sizeof(serpent_block_t); inbuf += 16 * sizeof(serpent_block_t); did_use_avx2 = 1; } if (did_use_avx2) { /* serpent-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic/sse2 code to handle smaller chunks... */ } #endif #ifdef USE_SSE2 { int did_use_sse2 = 0; /* Process data in 8 block chunks. */ while (nblocks >= 8) { _gcry_serpent_sse2_cbc_dec(ctx, outbuf, inbuf, iv); nblocks -= 8; outbuf += 8 * sizeof(serpent_block_t); inbuf += 8 * sizeof(serpent_block_t); did_use_sse2 = 1; } if (did_use_sse2) { /* serpent-sse2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_NEON if (ctx->use_neon) { int did_use_neon = 0; /* Process data in 8 block chunks. */ while (nblocks >= 8) { _gcry_serpent_neon_cbc_dec(ctx, outbuf, inbuf, iv); nblocks -= 8; outbuf += 8 * sizeof(serpent_block_t); inbuf += 8 * sizeof(serpent_block_t); did_use_neon = 1; } if (did_use_neon) { /* serpent-neon assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic code to handle smaller chunks... */ } #endif for ( ;nblocks; nblocks-- ) { /* INBUF is needed later and it may be identical to OUTBUF, so store the intermediate result to SAVEBUF. */ serpent_decrypt_internal (ctx, inbuf, savebuf); cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, sizeof(serpent_block_t)); inbuf += sizeof(serpent_block_t); outbuf += sizeof(serpent_block_t); } wipememory(savebuf, sizeof(savebuf)); _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CFB mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_serpent_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { serpent_context_t *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; int burn_stack_depth = 2 * sizeof (serpent_block_t); #ifdef USE_AVX2 if (ctx->use_avx2) { int did_use_avx2 = 0; /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_serpent_avx2_cfb_dec(ctx, outbuf, inbuf, iv); nblocks -= 16; outbuf += 16 * sizeof(serpent_block_t); inbuf += 16 * sizeof(serpent_block_t); did_use_avx2 = 1; } if (did_use_avx2) { /* serpent-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic/sse2 code to handle smaller chunks... */ } #endif #ifdef USE_SSE2 { int did_use_sse2 = 0; /* Process data in 8 block chunks. */ while (nblocks >= 8) { _gcry_serpent_sse2_cfb_dec(ctx, outbuf, inbuf, iv); nblocks -= 8; outbuf += 8 * sizeof(serpent_block_t); inbuf += 8 * sizeof(serpent_block_t); did_use_sse2 = 1; } if (did_use_sse2) { /* serpent-sse2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_NEON if (ctx->use_neon) { int did_use_neon = 0; /* Process data in 8 block chunks. */ while (nblocks >= 8) { _gcry_serpent_neon_cfb_dec(ctx, outbuf, inbuf, iv); nblocks -= 8; outbuf += 8 * sizeof(serpent_block_t); inbuf += 8 * sizeof(serpent_block_t); did_use_neon = 1; } if (did_use_neon) { /* serpent-neon assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic code to handle smaller chunks... */ } #endif for ( ;nblocks; nblocks-- ) { serpent_encrypt_internal(ctx, iv, iv); cipher_block_xor_n_copy(outbuf, iv, inbuf, sizeof(serpent_block_t)); outbuf += sizeof(serpent_block_t); inbuf += sizeof(serpent_block_t); } _gcry_burn_stack(burn_stack_depth); } /* Bulk encryption/decryption of complete blocks in OCB mode. */ static size_t _gcry_serpent_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt) { #if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON) serpent_context_t *ctx = (void *)&c->context.c; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; int burn_stack_depth = 2 * sizeof (serpent_block_t); u64 blkn = c->u_mode.ocb.data_nblocks; #else (void)c; (void)outbuf_arg; (void)inbuf_arg; (void)encrypt; #endif #ifdef USE_AVX2 if (ctx->use_avx2) { int did_use_avx2 = 0; u64 Ls[16]; u64 *l; if (nblocks >= 16) { l = bulk_ocb_prepare_L_pointers_array_blk16 (c, Ls, blkn); /* Process data in 16 block chunks. */ while (nblocks >= 16) { blkn += 16; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16); if (encrypt) _gcry_serpent_avx2_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); else _gcry_serpent_avx2_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); nblocks -= 16; outbuf += 16 * sizeof(serpent_block_t); inbuf += 16 * sizeof(serpent_block_t); did_use_avx2 = 1; } } if (did_use_avx2) { /* serpent-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_SSE2 { int did_use_sse2 = 0; u64 Ls[8]; u64 *l; if (nblocks >= 8) { l = bulk_ocb_prepare_L_pointers_array_blk8 (c, Ls, blkn); /* Process data in 8 block chunks. */ while (nblocks >= 8) { blkn += 8; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 8); if (encrypt) _gcry_serpent_sse2_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); else _gcry_serpent_sse2_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); nblocks -= 8; outbuf += 8 * sizeof(serpent_block_t); inbuf += 8 * sizeof(serpent_block_t); did_use_sse2 = 1; } } if (did_use_sse2) { /* serpent-sse2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_NEON if (ctx->use_neon) { int did_use_neon = 0; uintptr_t Ls[8]; uintptr_t *l; if (nblocks >= 8) { l = bulk_ocb_prepare_L_pointers_array_blk8 (c, Ls, blkn); /* Process data in 8 block chunks. */ while (nblocks >= 8) { blkn += 8; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 8); if (encrypt) _gcry_serpent_neon_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, (void **)Ls); else _gcry_serpent_neon_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, (void **)Ls); nblocks -= 8; outbuf += 8 * sizeof(serpent_block_t); inbuf += 8 * sizeof(serpent_block_t); did_use_neon = 1; } } if (did_use_neon) { /* serpent-neon assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic code to handle smaller chunks... */ } #endif #if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON) c->u_mode.ocb.data_nblocks = blkn; if (burn_stack_depth) _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *)); #endif return nblocks; } /* Bulk authentication of complete blocks in OCB mode. */ static size_t _gcry_serpent_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks) { #if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON) serpent_context_t *ctx = (void *)&c->context.c; const unsigned char *abuf = abuf_arg; int burn_stack_depth = 2 * sizeof(serpent_block_t); u64 blkn = c->u_mode.ocb.aad_nblocks; #else (void)c; (void)abuf_arg; #endif #ifdef USE_AVX2 if (ctx->use_avx2) { int did_use_avx2 = 0; u64 Ls[16]; u64 *l; if (nblocks >= 16) { l = bulk_ocb_prepare_L_pointers_array_blk16 (c, Ls, blkn); /* Process data in 16 block chunks. */ while (nblocks >= 16) { blkn += 16; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16); _gcry_serpent_avx2_ocb_auth(ctx, abuf, c->u_mode.ocb.aad_offset, c->u_mode.ocb.aad_sum, Ls); nblocks -= 16; abuf += 16 * sizeof(serpent_block_t); did_use_avx2 = 1; } } if (did_use_avx2) { /* serpent-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_SSE2 { int did_use_sse2 = 0; u64 Ls[8]; u64 *l; if (nblocks >= 8) { l = bulk_ocb_prepare_L_pointers_array_blk8 (c, Ls, blkn); /* Process data in 8 block chunks. */ while (nblocks >= 8) { blkn += 8; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 8); _gcry_serpent_sse2_ocb_auth(ctx, abuf, c->u_mode.ocb.aad_offset, c->u_mode.ocb.aad_sum, Ls); nblocks -= 8; abuf += 8 * sizeof(serpent_block_t); did_use_sse2 = 1; } } if (did_use_sse2) { /* serpent-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic code to handle smaller chunks... */ } #endif #ifdef USE_NEON if (ctx->use_neon) { int did_use_neon = 0; uintptr_t Ls[8]; uintptr_t *l; if (nblocks >= 8) { l = bulk_ocb_prepare_L_pointers_array_blk8 (c, Ls, blkn); /* Process data in 8 block chunks. */ while (nblocks >= 8) { blkn += 8; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 8); _gcry_serpent_neon_ocb_auth(ctx, abuf, c->u_mode.ocb.aad_offset, c->u_mode.ocb.aad_sum, (void **)Ls); nblocks -= 8; abuf += 8 * sizeof(serpent_block_t); did_use_neon = 1; } } if (did_use_neon) { /* serpent-neon assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic code to handle smaller chunks... */ } #endif #if defined(USE_AVX2) || defined(USE_SSE2) || defined(USE_NEON) c->u_mode.ocb.aad_nblocks = blkn; if (burn_stack_depth) _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *)); #endif return nblocks; } -/* Run the self-tests for SERPENT-CTR-128, tests IV increment of bulk CTR - encryption. Returns NULL on success. */ -static const char* -selftest_ctr_128 (void) -{ - const int nblocks = 16+8+1; - const int blocksize = sizeof(serpent_block_t); - const int context_size = sizeof(serpent_context_t); - - return _gcry_selftest_helper_ctr("SERPENT", &serpent_setkey, - &serpent_encrypt, nblocks, blocksize, context_size); -} - - -/* Run the self-tests for SERPENT-CBC-128, tests bulk CBC decryption. - Returns NULL on success. */ -static const char* -selftest_cbc_128 (void) -{ - const int nblocks = 16+8+2; - const int blocksize = sizeof(serpent_block_t); - const int context_size = sizeof(serpent_context_t); - - return _gcry_selftest_helper_cbc("SERPENT", &serpent_setkey, - &serpent_encrypt, nblocks, blocksize, context_size); -} - - -/* Run the self-tests for SERPENT-CBC-128, tests bulk CBC decryption. - Returns NULL on success. */ -static const char* -selftest_cfb_128 (void) -{ - const int nblocks = 16+8+2; - const int blocksize = sizeof(serpent_block_t); - const int context_size = sizeof(serpent_context_t); - - return _gcry_selftest_helper_cfb("SERPENT", &serpent_setkey, - &serpent_encrypt, nblocks, blocksize, context_size); -} - - /* Serpent test. */ static const char * serpent_test (void) { serpent_context_t context; unsigned char scratch[16]; unsigned int i; - const char *r; static struct test { int key_length; unsigned char key[32]; unsigned char text_plain[16]; unsigned char text_cipher[16]; } test_data[] = { { 16, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\xD2\x9D\x57\x6F\xCE\xA3\xA3\xA7\xED\x90\x99\xF2\x92\x73\xD7\x8E", "\xB2\x28\x8B\x96\x8A\xE8\xB0\x86\x48\xD1\xCE\x96\x06\xFD\x99\x2D" }, { 24, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00", "\xD2\x9D\x57\x6F\xCE\xAB\xA3\xA7\xED\x98\x99\xF2\x92\x7B\xD7\x8E", "\x13\x0E\x35\x3E\x10\x37\xC2\x24\x05\xE8\xFA\xEF\xB2\xC3\xC3\xE9" }, { 32, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\xD0\x95\x57\x6F\xCE\xA3\xE3\xA7\xED\x98\xD9\xF2\x90\x73\xD7\x8E", "\xB9\x0E\xE5\x86\x2D\xE6\x91\x68\xF2\xBD\xD5\x12\x5B\x45\x47\x2B" }, { 32, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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\x02\x00\x00\x00\x03\x00\x00\x00", "\x20\x61\xA4\x27\x82\xBD\x52\xEC\x69\x1E\xC3\x83\xB0\x3B\xA7\x7C" }, { 0 }, }; for (i = 0; test_data[i].key_length; i++) { serpent_setkey_internal (&context, test_data[i].key, test_data[i].key_length); serpent_encrypt_internal (&context, test_data[i].text_plain, scratch); if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t))) switch (test_data[i].key_length) { case 16: return "Serpent-128 test encryption failed."; case 24: return "Serpent-192 test encryption failed."; case 32: return "Serpent-256 test encryption failed."; } serpent_decrypt_internal (&context, test_data[i].text_cipher, scratch); if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t))) switch (test_data[i].key_length) { case 16: return "Serpent-128 test decryption failed."; case 24: return "Serpent-192 test decryption failed."; case 32: return "Serpent-256 test decryption failed."; } } - if ( (r = selftest_ctr_128 ()) ) - return r; - - if ( (r = selftest_cbc_128 ()) ) - return r; - - if ( (r = selftest_cfb_128 ()) ) - return r; - return NULL; } static const gcry_cipher_oid_spec_t serpent128_oids[] = { {"1.3.6.1.4.1.11591.13.2.1", GCRY_CIPHER_MODE_ECB }, {"1.3.6.1.4.1.11591.13.2.2", GCRY_CIPHER_MODE_CBC }, {"1.3.6.1.4.1.11591.13.2.3", GCRY_CIPHER_MODE_OFB }, {"1.3.6.1.4.1.11591.13.2.4", GCRY_CIPHER_MODE_CFB }, { NULL } }; static const gcry_cipher_oid_spec_t serpent192_oids[] = { {"1.3.6.1.4.1.11591.13.2.21", GCRY_CIPHER_MODE_ECB }, {"1.3.6.1.4.1.11591.13.2.22", GCRY_CIPHER_MODE_CBC }, {"1.3.6.1.4.1.11591.13.2.23", GCRY_CIPHER_MODE_OFB }, {"1.3.6.1.4.1.11591.13.2.24", GCRY_CIPHER_MODE_CFB }, { NULL } }; static const gcry_cipher_oid_spec_t serpent256_oids[] = { {"1.3.6.1.4.1.11591.13.2.41", GCRY_CIPHER_MODE_ECB }, {"1.3.6.1.4.1.11591.13.2.42", GCRY_CIPHER_MODE_CBC }, {"1.3.6.1.4.1.11591.13.2.43", GCRY_CIPHER_MODE_OFB }, {"1.3.6.1.4.1.11591.13.2.44", GCRY_CIPHER_MODE_CFB }, { NULL } }; static const char *serpent128_aliases[] = { "SERPENT", "SERPENT-128", NULL }; static const char *serpent192_aliases[] = { "SERPENT-192", NULL }; static const char *serpent256_aliases[] = { "SERPENT-256", NULL }; gcry_cipher_spec_t _gcry_cipher_spec_serpent128 = { GCRY_CIPHER_SERPENT128, {0, 0}, "SERPENT128", serpent128_aliases, serpent128_oids, 16, 128, sizeof (serpent_context_t), serpent_setkey, serpent_encrypt, serpent_decrypt }; gcry_cipher_spec_t _gcry_cipher_spec_serpent192 = { GCRY_CIPHER_SERPENT192, {0, 0}, "SERPENT192", serpent192_aliases, serpent192_oids, 16, 192, sizeof (serpent_context_t), serpent_setkey, serpent_encrypt, serpent_decrypt }; gcry_cipher_spec_t _gcry_cipher_spec_serpent256 = { GCRY_CIPHER_SERPENT256, {0, 0}, "SERPENT256", serpent256_aliases, serpent256_oids, 16, 256, sizeof (serpent_context_t), serpent_setkey, serpent_encrypt, serpent_decrypt }; diff --git a/cipher/sm4.c b/cipher/sm4.c index 7c7bc1ff..5f8bf224 100644 --- a/cipher/sm4.c +++ b/cipher/sm4.c @@ -1,1556 +1,1506 @@ /* sm4.c - SM4 Cipher Algorithm * Copyright (C) 2020 Alibaba Group. * Copyright (C) 2020 Tianjia Zhang * Copyright (C) 2020-2022 Jussi Kivilinna * * 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 "types.h" /* for byte and u32 typedefs */ #include "bithelp.h" #include "g10lib.h" #include "cipher.h" #include "bufhelp.h" #include "cipher-internal.h" -#include "cipher-selftest.h" #include "bulkhelp.h" /* Helper macro to force alignment to 64 bytes. */ #ifdef HAVE_GCC_ATTRIBUTE_ALIGNED # define ATTR_ALIGNED_64 __attribute__ ((aligned (64))) #else # define ATTR_ALIGNED_64 #endif /* USE_AESNI_AVX inidicates whether to compile with Intel AES-NI/AVX code. */ #undef USE_AESNI_AVX #if defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT) # if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_AESNI_AVX 1 # endif #endif /* USE_AESNI_AVX2 inidicates whether to compile with Intel AES-NI/AVX2 code. */ #undef USE_AESNI_AVX2 #if defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT) # if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_AESNI_AVX2 1 # endif #endif /* USE_GFNI_AVX2 inidicates whether to compile with Intel GFNI/AVX2 code. */ #undef USE_GFNI_AVX2 #if defined(ENABLE_GFNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT) # if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # define USE_GFNI_AVX2 1 # endif #endif /* Assembly implementations use SystemV ABI, ABI conversion and additional * stack to store XMM6-XMM15 needed on Win64. */ #undef ASM_FUNC_ABI #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2) || defined(USE_GFNI_AVX2) # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS # define ASM_FUNC_ABI __attribute__((sysv_abi)) # else # define ASM_FUNC_ABI # endif #endif #undef USE_AARCH64_SIMD #ifdef ENABLE_NEON_SUPPORT # if defined(__AARCH64EL__) && \ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \ defined(HAVE_GCC_INLINE_ASM_AARCH64_NEON) # define USE_AARCH64_SIMD 1 # endif #endif #undef USE_ARM_CE #ifdef ENABLE_ARM_CRYPTO_SUPPORT # if defined(__AARCH64EL__) && \ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \ defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO) # define USE_ARM_CE 1 # endif #endif static const char *sm4_selftest (void); static void _gcry_sm4_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static void _gcry_sm4_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static void _gcry_sm4_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static void _gcry_sm4_xts_crypt (void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); static size_t _gcry_sm4_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); static size_t _gcry_sm4_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); typedef struct { u32 rkey_enc[32]; u32 rkey_dec[32]; #ifdef USE_AESNI_AVX unsigned int use_aesni_avx:1; #endif #ifdef USE_AESNI_AVX2 unsigned int use_aesni_avx2:1; #endif #ifdef USE_GFNI_AVX2 unsigned int use_gfni_avx2:1; #endif #ifdef USE_AARCH64_SIMD unsigned int use_aarch64_simd:1; #endif #ifdef USE_ARM_CE unsigned int use_arm_ce:1; #endif } SM4_context; typedef unsigned int (*crypt_blk1_16_fn_t) (const void *ctx, byte *out, const byte *in, unsigned int num_blks); static const u32 fk[4] = { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc }; static struct { volatile u32 counter_head; u32 cacheline_align[64 / 4 - 1]; byte S[256]; volatile u32 counter_tail; } sbox_table ATTR_ALIGNED_64 = { 0, { 0, }, { 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62, 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8, 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f, 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84, 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48 }, 0 }; static const u32 ck[] = { 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 }; #ifdef USE_AESNI_AVX extern void _gcry_sm4_aesni_avx_expand_key(const byte *key, u32 *rk_enc, u32 *rk_dec, const u32 *fk, const u32 *ck) ASM_FUNC_ABI; extern void _gcry_sm4_aesni_avx_ctr_enc(const u32 *rk_enc, byte *out, const byte *in, byte *ctr) ASM_FUNC_ABI; extern void _gcry_sm4_aesni_avx_cbc_dec(const u32 *rk_dec, byte *out, const byte *in, byte *iv) ASM_FUNC_ABI; extern void _gcry_sm4_aesni_avx_cfb_dec(const u32 *rk_enc, byte *out, const byte *in, byte *iv) ASM_FUNC_ABI; extern void _gcry_sm4_aesni_avx_ocb_enc(const u32 *rk_enc, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[8]) ASM_FUNC_ABI; extern void _gcry_sm4_aesni_avx_ocb_dec(const u32 *rk_dec, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[8]) ASM_FUNC_ABI; extern void _gcry_sm4_aesni_avx_ocb_auth(const u32 *rk_enc, const unsigned char *abuf, unsigned char *offset, unsigned char *checksum, const u64 Ls[8]) ASM_FUNC_ABI; extern unsigned int _gcry_sm4_aesni_avx_crypt_blk1_8(const u32 *rk, byte *out, const byte *in, unsigned int num_blks) ASM_FUNC_ABI; static inline unsigned int sm4_aesni_avx_crypt_blk1_16(const void *rk, byte *out, const byte *in, unsigned int num_blks) { if (num_blks > 8) { _gcry_sm4_aesni_avx_crypt_blk1_8(rk, out, in, 8); in += 8 * 16; out += 8 * 16; num_blks -= 8; } return _gcry_sm4_aesni_avx_crypt_blk1_8(rk, out, in, num_blks); } #endif /* USE_AESNI_AVX */ #ifdef USE_AESNI_AVX2 extern void _gcry_sm4_aesni_avx2_ctr_enc(const u32 *rk_enc, byte *out, const byte *in, byte *ctr) ASM_FUNC_ABI; extern void _gcry_sm4_aesni_avx2_cbc_dec(const u32 *rk_dec, byte *out, const byte *in, byte *iv) ASM_FUNC_ABI; extern void _gcry_sm4_aesni_avx2_cfb_dec(const u32 *rk_enc, byte *out, const byte *in, byte *iv) ASM_FUNC_ABI; extern void _gcry_sm4_aesni_avx2_ocb_enc(const u32 *rk_enc, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; extern void _gcry_sm4_aesni_avx2_ocb_dec(const u32 *rk_dec, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; extern void _gcry_sm4_aesni_avx2_ocb_auth(const u32 *rk_enc, const unsigned char *abuf, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; extern unsigned int _gcry_sm4_aesni_avx2_crypt_blk1_16(const u32 *rk, byte *out, const byte *in, unsigned int num_blks) ASM_FUNC_ABI; static inline unsigned int sm4_aesni_avx2_crypt_blk1_16(const void *rk, byte *out, const byte *in, unsigned int num_blks) { #ifdef USE_AESNI_AVX /* Use 128-bit register implementation for short input. */ if (num_blks <= 8) return _gcry_sm4_aesni_avx_crypt_blk1_8(rk, out, in, num_blks); #endif return _gcry_sm4_aesni_avx2_crypt_blk1_16(rk, out, in, num_blks); } #endif /* USE_AESNI_AVX2 */ #ifdef USE_GFNI_AVX2 extern void _gcry_sm4_gfni_avx_expand_key(const byte *key, u32 *rk_enc, u32 *rk_dec, const u32 *fk, const u32 *ck) ASM_FUNC_ABI; extern void _gcry_sm4_gfni_avx2_ctr_enc(const u32 *rk_enc, byte *out, const byte *in, byte *ctr) ASM_FUNC_ABI; extern void _gcry_sm4_gfni_avx2_cbc_dec(const u32 *rk_dec, byte *out, const byte *in, byte *iv) ASM_FUNC_ABI; extern void _gcry_sm4_gfni_avx2_cfb_dec(const u32 *rk_enc, byte *out, const byte *in, byte *iv) ASM_FUNC_ABI; extern void _gcry_sm4_gfni_avx2_ocb_enc(const u32 *rk_enc, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; extern void _gcry_sm4_gfni_avx2_ocb_dec(const u32 *rk_dec, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; extern void _gcry_sm4_gfni_avx2_ocb_auth(const u32 *rk_enc, const unsigned char *abuf, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; extern unsigned int _gcry_sm4_gfni_avx2_crypt_blk1_16(const u32 *rk, byte *out, const byte *in, unsigned int num_blks) ASM_FUNC_ABI; static inline unsigned int sm4_gfni_avx2_crypt_blk1_16(const void *rk, byte *out, const byte *in, unsigned int num_blks) { return _gcry_sm4_gfni_avx2_crypt_blk1_16(rk, out, in, num_blks); } #endif /* USE_GFNI_AVX2 */ #ifdef USE_AARCH64_SIMD extern void _gcry_sm4_aarch64_crypt(const u32 *rk, byte *out, const byte *in, size_t num_blocks); extern void _gcry_sm4_aarch64_ctr_enc(const u32 *rk_enc, byte *out, const byte *in, byte *ctr, size_t nblocks); extern void _gcry_sm4_aarch64_cbc_dec(const u32 *rk_dec, byte *out, const byte *in, byte *iv, size_t nblocks); extern void _gcry_sm4_aarch64_cfb_dec(const u32 *rk_enc, byte *out, const byte *in, byte *iv, size_t nblocks); extern void _gcry_sm4_aarch64_crypt_blk1_8(const u32 *rk, byte *out, const byte *in, size_t num_blocks); static inline unsigned int sm4_aarch64_crypt_blk1_16(const void *rk, byte *out, const byte *in, unsigned int num_blks) { if (num_blks > 8) { _gcry_sm4_aarch64_crypt_blk1_8(rk, out, in, 8); in += 8 * 16; out += 8 * 16; num_blks -= 8; } _gcry_sm4_aarch64_crypt_blk1_8(rk, out, in, num_blks); return 0; } #endif /* USE_AARCH64_SIMD */ #ifdef USE_ARM_CE extern void _gcry_sm4_armv8_ce_expand_key(const byte *key, u32 *rkey_enc, u32 *rkey_dec, const u32 *fk, const u32 *ck); extern void _gcry_sm4_armv8_ce_crypt(const u32 *rk, byte *out, const byte *in, size_t num_blocks); extern void _gcry_sm4_armv8_ce_ctr_enc(const u32 *rk_enc, byte *out, const byte *in, byte *ctr, size_t nblocks); extern void _gcry_sm4_armv8_ce_cbc_dec(const u32 *rk_dec, byte *out, const byte *in, byte *iv, size_t nblocks); extern void _gcry_sm4_armv8_ce_cfb_dec(const u32 *rk_enc, byte *out, const byte *in, byte *iv, size_t nblocks); extern void _gcry_sm4_armv8_ce_crypt_blk1_8(const u32 *rk, byte *out, const byte *in, size_t num_blocks); static inline unsigned int sm4_armv8_ce_crypt_blk1_16(const void *rk, byte *out, const byte *in, unsigned int num_blks) { if (num_blks > 8) { _gcry_sm4_armv8_ce_crypt_blk1_8(rk, out, in, 8); in += 8 * 16; out += 8 * 16; num_blks -= 8; } _gcry_sm4_armv8_ce_crypt_blk1_8(rk, out, in, num_blks); return 0; } #endif /* USE_ARM_CE */ static inline void prefetch_sbox_table(void) { const volatile byte *vtab = (void *)&sbox_table; /* Modify counters to trigger copy-on-write and unsharing if physical pages * of look-up table are shared between processes. Modifying counters also * causes checksums for pages to change and hint same-page merging algorithm * that these pages are frequently changing. */ sbox_table.counter_head++; sbox_table.counter_tail++; /* Prefetch look-up table to cache. */ (void)vtab[0 * 32]; (void)vtab[1 * 32]; (void)vtab[2 * 32]; (void)vtab[3 * 32]; (void)vtab[4 * 32]; (void)vtab[5 * 32]; (void)vtab[6 * 32]; (void)vtab[7 * 32]; (void)vtab[8 * 32 - 1]; } static inline u32 sm4_t_non_lin_sub(u32 x) { u32 out; out = (u32)sbox_table.S[(x >> 0) & 0xff] << 0; out |= (u32)sbox_table.S[(x >> 8) & 0xff] << 8; out |= (u32)sbox_table.S[(x >> 16) & 0xff] << 16; out |= (u32)sbox_table.S[(x >> 24) & 0xff] << 24; return out; } static inline u32 sm4_key_lin_sub(u32 x) { return x ^ rol(x, 13) ^ rol(x, 23); } static inline u32 sm4_enc_lin_sub(u32 x) { u32 xrol2 = rol(x, 2); return x ^ xrol2 ^ rol(xrol2, 8) ^ rol(xrol2, 16) ^ rol(x, 24); } static inline u32 sm4_key_sub(u32 x) { return sm4_key_lin_sub(sm4_t_non_lin_sub(x)); } static inline u32 sm4_enc_sub(u32 x) { return sm4_enc_lin_sub(sm4_t_non_lin_sub(x)); } static inline u32 sm4_round(const u32 x0, const u32 x1, const u32 x2, const u32 x3, const u32 rk) { return x0 ^ sm4_enc_sub(x1 ^ x2 ^ x3 ^ rk); } static void sm4_expand_key (SM4_context *ctx, const byte *key) { u32 rk[4]; int i; #ifdef USE_GFNI_AVX if (ctx->use_gfni_avx) { _gcry_sm4_gfni_avx_expand_key (key, ctx->rkey_enc, ctx->rkey_dec, fk, ck); return; } #endif #ifdef USE_AESNI_AVX if (ctx->use_aesni_avx) { _gcry_sm4_aesni_avx_expand_key (key, ctx->rkey_enc, ctx->rkey_dec, fk, ck); return; } #endif #ifdef USE_ARM_CE if (ctx->use_arm_ce) { _gcry_sm4_armv8_ce_expand_key (key, ctx->rkey_enc, ctx->rkey_dec, fk, ck); return; } #endif rk[0] = buf_get_be32(key + 4 * 0) ^ fk[0]; rk[1] = buf_get_be32(key + 4 * 1) ^ fk[1]; rk[2] = buf_get_be32(key + 4 * 2) ^ fk[2]; rk[3] = buf_get_be32(key + 4 * 3) ^ fk[3]; for (i = 0; i < 32; i += 4) { rk[0] = rk[0] ^ sm4_key_sub(rk[1] ^ rk[2] ^ rk[3] ^ ck[i + 0]); rk[1] = rk[1] ^ sm4_key_sub(rk[2] ^ rk[3] ^ rk[0] ^ ck[i + 1]); rk[2] = rk[2] ^ sm4_key_sub(rk[3] ^ rk[0] ^ rk[1] ^ ck[i + 2]); rk[3] = rk[3] ^ sm4_key_sub(rk[0] ^ rk[1] ^ rk[2] ^ ck[i + 3]); ctx->rkey_enc[i + 0] = rk[0]; ctx->rkey_enc[i + 1] = rk[1]; ctx->rkey_enc[i + 2] = rk[2]; ctx->rkey_enc[i + 3] = rk[3]; ctx->rkey_dec[31 - i - 0] = rk[0]; ctx->rkey_dec[31 - i - 1] = rk[1]; ctx->rkey_dec[31 - i - 2] = rk[2]; ctx->rkey_dec[31 - i - 3] = rk[3]; } wipememory (rk, sizeof(rk)); } static gcry_err_code_t sm4_setkey (void *context, const byte *key, const unsigned keylen, cipher_bulk_ops_t *bulk_ops) { SM4_context *ctx = context; static int init = 0; static const char *selftest_failed = NULL; unsigned int hwf = _gcry_get_hw_features (); (void)hwf; if (!init) { init = 1; selftest_failed = sm4_selftest(); if (selftest_failed) log_error("%s\n", selftest_failed); } if (selftest_failed) return GPG_ERR_SELFTEST_FAILED; if (keylen != 16) return GPG_ERR_INV_KEYLEN; #ifdef USE_AESNI_AVX ctx->use_aesni_avx = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX); #endif #ifdef USE_AESNI_AVX2 ctx->use_aesni_avx2 = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX2); #endif #ifdef USE_GFNI_AVX2 ctx->use_gfni_avx2 = (hwf & HWF_INTEL_GFNI) && (hwf & HWF_INTEL_AVX2); #endif #ifdef USE_AARCH64_SIMD ctx->use_aarch64_simd = !!(hwf & HWF_ARM_NEON); #endif #ifdef USE_ARM_CE ctx->use_arm_ce = !!(hwf & HWF_ARM_SM4); #endif #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) { /* Disable AESNI implementations when GFNI implementation is enabled. */ #ifdef USE_AESNI_AVX ctx->use_aesni_avx = 0; #endif #ifdef USE_AESNI_AVX2 ctx->use_aesni_avx2 = 0; #endif } #endif /* Setup bulk encryption routines. */ memset (bulk_ops, 0, sizeof(*bulk_ops)); bulk_ops->cbc_dec = _gcry_sm4_cbc_dec; bulk_ops->cfb_dec = _gcry_sm4_cfb_dec; bulk_ops->ctr_enc = _gcry_sm4_ctr_enc; bulk_ops->xts_crypt = _gcry_sm4_xts_crypt; bulk_ops->ocb_crypt = _gcry_sm4_ocb_crypt; bulk_ops->ocb_auth = _gcry_sm4_ocb_auth; sm4_expand_key (ctx, key); return 0; } static unsigned int sm4_do_crypt (const u32 *rk, byte *out, const byte *in) { u32 x[4]; int i; x[0] = buf_get_be32(in + 0 * 4); x[1] = buf_get_be32(in + 1 * 4); x[2] = buf_get_be32(in + 2 * 4); x[3] = buf_get_be32(in + 3 * 4); for (i = 0; i < 32; i += 4) { x[0] = sm4_round(x[0], x[1], x[2], x[3], rk[i + 0]); x[1] = sm4_round(x[1], x[2], x[3], x[0], rk[i + 1]); x[2] = sm4_round(x[2], x[3], x[0], x[1], rk[i + 2]); x[3] = sm4_round(x[3], x[0], x[1], x[2], rk[i + 3]); } buf_put_be32(out + 0 * 4, x[3 - 0]); buf_put_be32(out + 1 * 4, x[3 - 1]); buf_put_be32(out + 2 * 4, x[3 - 2]); buf_put_be32(out + 3 * 4, x[3 - 3]); return /*burn_stack*/ 4*6+sizeof(void*)*4; } static unsigned int sm4_encrypt (void *context, byte *outbuf, const byte *inbuf) { SM4_context *ctx = context; #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) return sm4_gfni_avx2_crypt_blk1_16(ctx->rkey_enc, outbuf, inbuf, 1); #endif #ifdef USE_ARM_CE if (ctx->use_arm_ce) return sm4_armv8_ce_crypt_blk1_16(ctx->rkey_enc, outbuf, inbuf, 1); #endif prefetch_sbox_table (); return sm4_do_crypt (ctx->rkey_enc, outbuf, inbuf); } static unsigned int sm4_decrypt (void *context, byte *outbuf, const byte *inbuf) { SM4_context *ctx = context; #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) return sm4_gfni_avx2_crypt_blk1_16(ctx->rkey_dec, outbuf, inbuf, 1); #endif #ifdef USE_ARM_CE if (ctx->use_arm_ce) return sm4_armv8_ce_crypt_blk1_16(ctx->rkey_dec, outbuf, inbuf, 1); #endif prefetch_sbox_table (); return sm4_do_crypt (ctx->rkey_dec, outbuf, inbuf); } static unsigned int sm4_do_crypt_blks2 (const u32 *rk, byte *out, const byte *in) { u32 x[4]; u32 y[4]; u32 k; int i; /* Encrypts/Decrypts two blocks for higher instruction level * parallelism. */ x[0] = buf_get_be32(in + 0 * 4); x[1] = buf_get_be32(in + 1 * 4); x[2] = buf_get_be32(in + 2 * 4); x[3] = buf_get_be32(in + 3 * 4); y[0] = buf_get_be32(in + 4 * 4); y[1] = buf_get_be32(in + 5 * 4); y[2] = buf_get_be32(in + 6 * 4); y[3] = buf_get_be32(in + 7 * 4); for (i = 0; i < 32; i += 4) { k = rk[i + 0]; x[0] = sm4_round(x[0], x[1], x[2], x[3], k); y[0] = sm4_round(y[0], y[1], y[2], y[3], k); k = rk[i + 1]; x[1] = sm4_round(x[1], x[2], x[3], x[0], k); y[1] = sm4_round(y[1], y[2], y[3], y[0], k); k = rk[i + 2]; x[2] = sm4_round(x[2], x[3], x[0], x[1], k); y[2] = sm4_round(y[2], y[3], y[0], y[1], k); k = rk[i + 3]; x[3] = sm4_round(x[3], x[0], x[1], x[2], k); y[3] = sm4_round(y[3], y[0], y[1], y[2], k); } buf_put_be32(out + 0 * 4, x[3 - 0]); buf_put_be32(out + 1 * 4, x[3 - 1]); buf_put_be32(out + 2 * 4, x[3 - 2]); buf_put_be32(out + 3 * 4, x[3 - 3]); buf_put_be32(out + 4 * 4, y[3 - 0]); buf_put_be32(out + 5 * 4, y[3 - 1]); buf_put_be32(out + 6 * 4, y[3 - 2]); buf_put_be32(out + 7 * 4, y[3 - 3]); return /*burn_stack*/ 4*10+sizeof(void*)*4; } static unsigned int sm4_crypt_blocks (const void *ctx, byte *out, const byte *in, unsigned int num_blks) { const u32 *rk = ctx; unsigned int burn_depth = 0; unsigned int nburn; while (num_blks >= 2) { nburn = sm4_do_crypt_blks2 (rk, out, in); burn_depth = nburn > burn_depth ? nburn : burn_depth; out += 2 * 16; in += 2 * 16; num_blks -= 2; } while (num_blks) { nburn = sm4_do_crypt (rk, out, in); burn_depth = nburn > burn_depth ? nburn : burn_depth; out += 16; in += 16; num_blks--; } if (burn_depth) burn_depth += sizeof(void *) * 5; return burn_depth; } static inline crypt_blk1_16_fn_t sm4_get_crypt_blk1_16_fn(SM4_context *ctx) { if (0) ; #ifdef USE_AESNI_AVX else if (ctx->use_gfni_avx2) { return &sm4_gfni_avx2_crypt_blk1_16; } #endif #ifdef USE_AESNI_AVX2 else if (ctx->use_aesni_avx2) { return &sm4_aesni_avx2_crypt_blk1_16; } #endif #ifdef USE_AESNI_AVX else if (ctx->use_aesni_avx) { return &sm4_aesni_avx_crypt_blk1_16; } #endif #ifdef USE_ARM_CE else if (ctx->use_arm_ce) { return &sm4_armv8_ce_crypt_blk1_16; } #endif #ifdef USE_AARCH64_SIMD else if (ctx->use_aarch64_simd) { return &sm4_aarch64_crypt_blk1_16; } #endif else { prefetch_sbox_table (); return &sm4_crypt_blocks; } } /* Bulk encryption of complete blocks in CTR mode. This function is only intended for the bulk encryption feature of cipher.c. CTR is expected to be of size 16. */ static void _gcry_sm4_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { SM4_context *ctx = context; byte *outbuf = outbuf_arg; const byte *inbuf = inbuf_arg; int burn_stack_depth = 0; #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) { /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_sm4_gfni_avx2_ctr_enc(ctx->rkey_enc, outbuf, inbuf, ctr); nblocks -= 16; outbuf += 16 * 16; inbuf += 16 * 16; } } #endif #ifdef USE_AESNI_AVX2 if (ctx->use_aesni_avx2) { /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_sm4_aesni_avx2_ctr_enc(ctx->rkey_enc, outbuf, inbuf, ctr); nblocks -= 16; outbuf += 16 * 16; inbuf += 16 * 16; } } #endif #ifdef USE_AESNI_AVX if (ctx->use_aesni_avx) { /* Process data in 8 block chunks. */ while (nblocks >= 8) { _gcry_sm4_aesni_avx_ctr_enc(ctx->rkey_enc, outbuf, inbuf, ctr); nblocks -= 8; outbuf += 8 * 16; inbuf += 8 * 16; } } #endif #ifdef USE_ARM_CE if (ctx->use_arm_ce) { /* Process multiples of 8 blocks at a time. */ if (nblocks >= 8) { size_t nblks = nblocks & ~(8 - 1); _gcry_sm4_armv8_ce_ctr_enc(ctx->rkey_enc, outbuf, inbuf, ctr, nblks); nblocks -= nblks; outbuf += nblks * 16; inbuf += nblks * 16; } } #endif #ifdef USE_AARCH64_SIMD if (ctx->use_aarch64_simd) { /* Process multiples of 8 blocks at a time. */ if (nblocks >= 8) { size_t nblks = nblocks & ~(8 - 1); _gcry_sm4_aarch64_ctr_enc(ctx->rkey_enc, outbuf, inbuf, ctr, nblks); nblocks -= nblks; outbuf += nblks * 16; inbuf += nblks * 16; } } #endif /* Process remaining blocks. */ if (nblocks) { crypt_blk1_16_fn_t crypt_blk1_16 = sm4_get_crypt_blk1_16_fn(ctx); byte tmpbuf[16 * 16]; unsigned int tmp_used = 16; size_t nburn; nburn = bulk_ctr_enc_128(ctx->rkey_enc, crypt_blk1_16, outbuf, inbuf, nblocks, ctr, tmpbuf, sizeof(tmpbuf) / 16, &tmp_used); burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth; wipememory(tmpbuf, tmp_used); } if (burn_stack_depth) _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CBC mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_sm4_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { SM4_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; int burn_stack_depth = 0; #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) { /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_sm4_gfni_avx2_cbc_dec(ctx->rkey_dec, outbuf, inbuf, iv); nblocks -= 16; outbuf += 16 * 16; inbuf += 16 * 16; } } #endif #ifdef USE_AESNI_AVX2 if (ctx->use_aesni_avx2) { /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_sm4_aesni_avx2_cbc_dec(ctx->rkey_dec, outbuf, inbuf, iv); nblocks -= 16; outbuf += 16 * 16; inbuf += 16 * 16; } } #endif #ifdef USE_AESNI_AVX if (ctx->use_aesni_avx) { /* Process data in 8 block chunks. */ while (nblocks >= 8) { _gcry_sm4_aesni_avx_cbc_dec(ctx->rkey_dec, outbuf, inbuf, iv); nblocks -= 8; outbuf += 8 * 16; inbuf += 8 * 16; } } #endif #ifdef USE_ARM_CE if (ctx->use_arm_ce) { /* Process multiples of 8 blocks at a time. */ if (nblocks >= 8) { size_t nblks = nblocks & ~(8 - 1); _gcry_sm4_armv8_ce_cbc_dec(ctx->rkey_dec, outbuf, inbuf, iv, nblks); nblocks -= nblks; outbuf += nblks * 16; inbuf += nblks * 16; } } #endif #ifdef USE_AARCH64_SIMD if (ctx->use_aarch64_simd) { /* Process multiples of 8 blocks at a time. */ if (nblocks >= 8) { size_t nblks = nblocks & ~(8 - 1); _gcry_sm4_aarch64_cbc_dec(ctx->rkey_dec, outbuf, inbuf, iv, nblks); nblocks -= nblks; outbuf += nblks * 16; inbuf += nblks * 16; } } #endif /* Process remaining blocks. */ if (nblocks) { crypt_blk1_16_fn_t crypt_blk1_16 = sm4_get_crypt_blk1_16_fn(ctx); unsigned char tmpbuf[16 * 16]; unsigned int tmp_used = 16; size_t nburn; nburn = bulk_cbc_dec_128(ctx->rkey_dec, crypt_blk1_16, outbuf, inbuf, nblocks, iv, tmpbuf, sizeof(tmpbuf) / 16, &tmp_used); burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth; wipememory(tmpbuf, tmp_used); } if (burn_stack_depth) _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CFB mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_sm4_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { SM4_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; int burn_stack_depth = 0; #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) { /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_sm4_gfni_avx2_cfb_dec(ctx->rkey_enc, outbuf, inbuf, iv); nblocks -= 16; outbuf += 16 * 16; inbuf += 16 * 16; } } #endif #ifdef USE_AESNI_AVX2 if (ctx->use_aesni_avx2) { /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_sm4_aesni_avx2_cfb_dec(ctx->rkey_enc, outbuf, inbuf, iv); nblocks -= 16; outbuf += 16 * 16; inbuf += 16 * 16; } } #endif #ifdef USE_AESNI_AVX if (ctx->use_aesni_avx) { /* Process data in 8 block chunks. */ while (nblocks >= 8) { _gcry_sm4_aesni_avx_cfb_dec(ctx->rkey_enc, outbuf, inbuf, iv); nblocks -= 8; outbuf += 8 * 16; inbuf += 8 * 16; } } #endif #ifdef USE_ARM_CE if (ctx->use_arm_ce) { /* Process multiples of 8 blocks at a time. */ if (nblocks >= 8) { size_t nblks = nblocks & ~(8 - 1); _gcry_sm4_armv8_ce_cfb_dec(ctx->rkey_enc, outbuf, inbuf, iv, nblks); nblocks -= nblks; outbuf += nblks * 16; inbuf += nblks * 16; } } #endif #ifdef USE_AARCH64_SIMD if (ctx->use_aarch64_simd) { /* Process multiples of 8 blocks at a time. */ if (nblocks >= 8) { size_t nblks = nblocks & ~(8 - 1); _gcry_sm4_aarch64_cfb_dec(ctx->rkey_enc, outbuf, inbuf, iv, nblks); nblocks -= nblks; outbuf += nblks * 16; inbuf += nblks * 16; } } #endif /* Process remaining blocks. */ if (nblocks) { crypt_blk1_16_fn_t crypt_blk1_16 = sm4_get_crypt_blk1_16_fn(ctx); unsigned char tmpbuf[16 * 16]; unsigned int tmp_used = 16; size_t nburn; nburn = bulk_cfb_dec_128(ctx->rkey_enc, crypt_blk1_16, outbuf, inbuf, nblocks, iv, tmpbuf, sizeof(tmpbuf) / 16, &tmp_used); burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth; wipememory(tmpbuf, tmp_used); } if (burn_stack_depth) _gcry_burn_stack(burn_stack_depth); } /* Bulk encryption/decryption of complete blocks in XTS mode. */ static void _gcry_sm4_xts_crypt (void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt) { SM4_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; int burn_stack_depth = 0; /* Process remaining blocks. */ if (nblocks) { crypt_blk1_16_fn_t crypt_blk1_16 = sm4_get_crypt_blk1_16_fn(ctx); u32 *rk = encrypt ? ctx->rkey_enc : ctx->rkey_dec; unsigned char tmpbuf[16 * 16]; unsigned int tmp_used = 16; size_t nburn; nburn = bulk_xts_crypt_128(rk, crypt_blk1_16, outbuf, inbuf, nblocks, tweak, tmpbuf, sizeof(tmpbuf) / 16, &tmp_used); burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth; wipememory(tmpbuf, tmp_used); } if (burn_stack_depth) _gcry_burn_stack(burn_stack_depth); } /* Bulk encryption/decryption of complete blocks in OCB mode. */ static size_t _gcry_sm4_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt) { SM4_context *ctx = (void *)&c->context.c; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; u64 blkn = c->u_mode.ocb.data_nblocks; int burn_stack_depth = 0; #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) { u64 Ls[16]; u64 *l; if (nblocks >= 16) { l = bulk_ocb_prepare_L_pointers_array_blk16 (c, Ls, blkn); /* Process data in 16 block chunks. */ while (nblocks >= 16) { blkn += 16; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16); if (encrypt) _gcry_sm4_gfni_avx2_ocb_enc(ctx->rkey_enc, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); else _gcry_sm4_gfni_avx2_ocb_dec(ctx->rkey_dec, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); nblocks -= 16; outbuf += 16 * 16; inbuf += 16 * 16; } } } #endif #ifdef USE_AESNI_AVX2 if (ctx->use_aesni_avx2) { u64 Ls[16]; u64 *l; if (nblocks >= 16) { l = bulk_ocb_prepare_L_pointers_array_blk16 (c, Ls, blkn); /* Process data in 16 block chunks. */ while (nblocks >= 16) { blkn += 16; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16); if (encrypt) _gcry_sm4_aesni_avx2_ocb_enc(ctx->rkey_enc, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); else _gcry_sm4_aesni_avx2_ocb_dec(ctx->rkey_dec, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); nblocks -= 16; outbuf += 16 * 16; inbuf += 16 * 16; } } } #endif #ifdef USE_AESNI_AVX if (ctx->use_aesni_avx) { u64 Ls[8]; u64 *l; if (nblocks >= 8) { l = bulk_ocb_prepare_L_pointers_array_blk8 (c, Ls, blkn); /* Process data in 8 block chunks. */ while (nblocks >= 8) { blkn += 8; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 8); if (encrypt) _gcry_sm4_aesni_avx_ocb_enc(ctx->rkey_enc, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); else _gcry_sm4_aesni_avx_ocb_dec(ctx->rkey_dec, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); nblocks -= 8; outbuf += 8 * 16; inbuf += 8 * 16; } } } #endif /* Process remaining blocks. */ if (nblocks) { crypt_blk1_16_fn_t crypt_blk1_16 = sm4_get_crypt_blk1_16_fn(ctx); u32 *rk = encrypt ? ctx->rkey_enc : ctx->rkey_dec; unsigned char tmpbuf[16 * 16]; unsigned int tmp_used = 16; size_t nburn; nburn = bulk_ocb_crypt_128 (c, rk, crypt_blk1_16, outbuf, inbuf, nblocks, &blkn, encrypt, tmpbuf, sizeof(tmpbuf) / 16, &tmp_used); burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth; wipememory(tmpbuf, tmp_used); } c->u_mode.ocb.data_nblocks = blkn; if (burn_stack_depth) _gcry_burn_stack(burn_stack_depth); return 0; } /* Bulk authentication of complete blocks in OCB mode. */ static size_t _gcry_sm4_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks) { SM4_context *ctx = (void *)&c->context.c; const unsigned char *abuf = abuf_arg; u64 blkn = c->u_mode.ocb.aad_nblocks; int burn_stack_depth = 0; #ifdef USE_GFNI_AVX2 if (ctx->use_gfni_avx2) { u64 Ls[16]; u64 *l; if (nblocks >= 16) { l = bulk_ocb_prepare_L_pointers_array_blk16 (c, Ls, blkn); /* Process data in 16 block chunks. */ while (nblocks >= 16) { blkn += 16; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16); _gcry_sm4_gfni_avx2_ocb_auth(ctx->rkey_enc, abuf, c->u_mode.ocb.aad_offset, c->u_mode.ocb.aad_sum, Ls); nblocks -= 16; abuf += 16 * 16; } } } #endif #ifdef USE_AESNI_AVX2 if (ctx->use_aesni_avx2) { u64 Ls[16]; u64 *l; if (nblocks >= 16) { l = bulk_ocb_prepare_L_pointers_array_blk16 (c, Ls, blkn); /* Process data in 16 block chunks. */ while (nblocks >= 16) { blkn += 16; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16); _gcry_sm4_aesni_avx2_ocb_auth(ctx->rkey_enc, abuf, c->u_mode.ocb.aad_offset, c->u_mode.ocb.aad_sum, Ls); nblocks -= 16; abuf += 16 * 16; } } } #endif #ifdef USE_AESNI_AVX if (ctx->use_aesni_avx) { u64 Ls[8]; u64 *l; if (nblocks >= 8) { l = bulk_ocb_prepare_L_pointers_array_blk8 (c, Ls, blkn); /* Process data in 8 block chunks. */ while (nblocks >= 8) { blkn += 8; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 8); _gcry_sm4_aesni_avx_ocb_auth(ctx->rkey_enc, abuf, c->u_mode.ocb.aad_offset, c->u_mode.ocb.aad_sum, Ls); nblocks -= 8; abuf += 8 * 16; } } } #endif /* Process remaining blocks. */ if (nblocks) { crypt_blk1_16_fn_t crypt_blk1_16 = sm4_get_crypt_blk1_16_fn(ctx); unsigned char tmpbuf[16 * 16]; unsigned int tmp_used = 16; size_t nburn; nburn = bulk_ocb_auth_128 (c, ctx->rkey_enc, crypt_blk1_16, abuf, nblocks, &blkn, tmpbuf, sizeof(tmpbuf) / 16, &tmp_used); burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth; wipememory(tmpbuf, tmp_used); } c->u_mode.ocb.aad_nblocks = blkn; if (burn_stack_depth) _gcry_burn_stack(burn_stack_depth); return 0; } -/* Run the self-tests for SM4-CTR, tests IV increment of bulk CTR - encryption. Returns NULL on success. */ -static const char* -selftest_ctr_128 (void) -{ - const int nblocks = 16 - 1; - const int blocksize = 16; - const int context_size = sizeof(SM4_context); - - return _gcry_selftest_helper_ctr("SM4", &sm4_setkey, - &sm4_encrypt, nblocks, blocksize, context_size); -} - -/* Run the self-tests for SM4-CBC, tests bulk CBC decryption. - Returns NULL on success. */ -static const char* -selftest_cbc_128 (void) -{ - const int nblocks = 16 - 1; - const int blocksize = 16; - const int context_size = sizeof(SM4_context); - - return _gcry_selftest_helper_cbc("SM4", &sm4_setkey, - &sm4_encrypt, nblocks, blocksize, context_size); -} - -/* Run the self-tests for SM4-CFB, tests bulk CFB decryption. - Returns NULL on success. */ -static const char* -selftest_cfb_128 (void) -{ - const int nblocks = 16 - 1; - const int blocksize = 16; - const int context_size = sizeof(SM4_context); - - return _gcry_selftest_helper_cfb("SM4", &sm4_setkey, - &sm4_encrypt, nblocks, blocksize, context_size); -} - static const char * sm4_selftest (void) { SM4_context ctx; byte scratch[16]; - const char *r; static const byte plaintext[16] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, }; static const byte key[16] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, }; static const byte ciphertext[16] = { 0x68, 0x1E, 0xDF, 0x34, 0xD2, 0x06, 0x96, 0x5E, 0x86, 0xB3, 0xE9, 0x4F, 0x53, 0x6E, 0x42, 0x46 }; memset (&ctx, 0, sizeof(ctx)); sm4_expand_key (&ctx, key); sm4_encrypt (&ctx, scratch, plaintext); if (memcmp (scratch, ciphertext, sizeof (ciphertext))) return "SM4 test encryption failed."; sm4_decrypt (&ctx, scratch, scratch); if (memcmp (scratch, plaintext, sizeof (plaintext))) return "SM4 test decryption failed."; - if ( (r = selftest_ctr_128 ()) ) - return r; - - if ( (r = selftest_cbc_128 ()) ) - return r; - - if ( (r = selftest_cfb_128 ()) ) - return r; - return NULL; } static gpg_err_code_t run_selftests (int algo, int extended, selftest_report_func_t report) { const char *what; const char *errtxt; (void)extended; if (algo != GCRY_CIPHER_SM4) return GPG_ERR_CIPHER_ALGO; what = "selftest"; errtxt = sm4_selftest (); if (errtxt) goto failed; return 0; failed: if (report) report ("cipher", GCRY_CIPHER_SM4, what, errtxt); return GPG_ERR_SELFTEST_FAILED; } static const gcry_cipher_oid_spec_t sm4_oids[] = { { "1.2.156.10197.1.104.1", GCRY_CIPHER_MODE_ECB }, { "1.2.156.10197.1.104.2", GCRY_CIPHER_MODE_CBC }, { "1.2.156.10197.1.104.3", GCRY_CIPHER_MODE_OFB }, { "1.2.156.10197.1.104.4", GCRY_CIPHER_MODE_CFB }, { "1.2.156.10197.1.104.7", GCRY_CIPHER_MODE_CTR }, { NULL } }; gcry_cipher_spec_t _gcry_cipher_spec_sm4 = { GCRY_CIPHER_SM4, {0, 0}, "SM4", NULL, sm4_oids, 16, 128, sizeof (SM4_context), sm4_setkey, sm4_encrypt, sm4_decrypt, NULL, NULL, run_selftests }; diff --git a/cipher/twofish.c b/cipher/twofish.c index 4ae5d5a6..b300715b 100644 --- a/cipher/twofish.c +++ b/cipher/twofish.c @@ -1,1762 +1,1713 @@ /* Twofish for GPG * Copyright (C) 1998, 2002, 2003 Free Software Foundation, Inc. * Written by Matthew Skala , July 26, 1998 * 256-bit key length added March 20, 1999 * Some modifications to reduce the text size by Werner Koch, April, 1998 * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ******************************************************************** * * This code is a "clean room" implementation, written from the paper * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey, * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available * through http://www.counterpane.com/twofish.html * * For background information on multiplication in finite fields, used for * the matrix operations in the key schedule, see the book _Contemporary * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the * Third Edition. * * Only the 128- and 256-bit key sizes are supported. This code is intended * for GNU C on a 32-bit system, but it should work almost anywhere. Loops * are unrolled, precomputation tables are used, etc., for maximum speed at * some cost in memory consumption. */ #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-internal.h" -#include "cipher-selftest.h" #include "bulkhelp.h" #define TWOFISH_BLOCKSIZE 16 /* 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_ARM_ASM indicates whether to use ARM assembly code. */ #undef USE_ARM_ASM #if defined(__ARMEL__) # if defined(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_AVX2 indicates whether to compile with AMD64 AVX2 code. */ #undef USE_AVX2 #if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) # if defined(ENABLE_AVX2_SUPPORT) # define USE_AVX2 1 # endif #endif /* Prototype for the self-test function. */ static const char *selftest(void); /* Prototypes for the bulk functions. */ static void _gcry_twofish_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static void _gcry_twofish_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static void _gcry_twofish_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); static size_t _gcry_twofish_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); static size_t _gcry_twofish_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); /* Structure for an expanded Twofish key. s contains the key-dependent * S-boxes composed with the MDS matrix; w contains the eight "whitening" * subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note * that k[i] corresponds to what the Twofish paper calls K[i+8]. */ typedef struct { u32 s[4][256], w[8], k[32]; #ifdef USE_AVX2 int use_avx2; #endif } TWOFISH_context; /* Assembly implementations use SystemV ABI, ABI conversion and additional * stack to store XMM6-XMM15 needed on Win64. */ #undef ASM_FUNC_ABI #if defined(USE_AVX2) # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS # define ASM_FUNC_ABI __attribute__((sysv_abi)) # else # define ASM_FUNC_ABI # endif #endif /* These two tables are the q0 and q1 permutations, exactly as described in * the Twofish paper. */ static const byte q0[256] = { 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0 }; static const byte q1[256] = { 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91 }; /* These MDS tables are actually tables of MDS composed with q0 and q1, * because it is only ever used that way and we can save some time by * precomputing. Of course the main saving comes from precomputing the * GF(2^8) multiplication involved in the MDS matrix multiply; by looking * things up in these tables we reduce the matrix multiply to four lookups * and three XORs. Semi-formally, the definition of these tables is: * mds[0][i] = MDS (q1[i] 0 0 0)^T mds[1][i] = MDS (0 q0[i] 0 0)^T * mds[2][i] = MDS (0 0 q1[i] 0)^T mds[3][i] = MDS (0 0 0 q0[i])^T * where ^T means "transpose", the matrix multiply is performed in GF(2^8) * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described * by Schneier et al, and I'm casually glossing over the byte/word * conversion issues. */ static const u32 mds[4][256] = { {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1, 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5, 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796, 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8, 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9, 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E, 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01, 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64, 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E, 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9, 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91}, {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141, 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757, 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656, 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3, 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282, 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC, 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272, 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5, 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3, 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF, 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8}, {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783, 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA, 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07, 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96, 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD, 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85, 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B, 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D, 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D, 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9, 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF}, {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77, 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216, 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7, 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C, 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE, 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4, 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB, 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8, 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA, 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D, 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8} }; /* The exp_to_poly and poly_to_exp tables are used to perform efficient * operations in GF(2^8) represented as GF(2)[x]/w(x) where * w(x)=x^8+x^6+x^3+x^2+1. We care about doing that because it's part of the * definition of the RS matrix in the key schedule. Elements of that field * are polynomials of degree not greater than 7 and all coefficients 0 or 1, * which can be represented naturally by bytes (just substitute x=2). In that * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8) * multiplication is inefficient without hardware support. To multiply * faster, I make use of the fact x is a generator for the nonzero elements, * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for * some n in 0..254. Note that that caret is exponentiation in GF(2^8), * *not* polynomial notation. So if I want to compute pq where p and q are * in GF(2^8), I can just say: * 1. if p=0 or q=0 then pq=0 * 2. otherwise, find m and n such that p=x^m and q=x^n * 3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq * The translations in steps 2 and 3 are looked up in the tables * poly_to_exp (for step 2) and exp_to_poly (for step 3). To see this * in action, look at the CALC_S macro. As additional wrinkles, note that * one of my operands is always a constant, so the poly_to_exp lookup on it * is done in advance; I included the original values in the comments so * readers can have some chance of recognizing that this *is* the RS matrix * from the Twofish paper. I've only included the table entries I actually * need; I never do a lookup on a variable input of zero and the biggest * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll * never sum to more than 491. I'm repeating part of the exp_to_poly table * so that I don't have to do mod-255 reduction in the exponent arithmetic. * Since I know my constant operands are never zero, I only have to worry * about zero values in the variable operand, and I do it with a simple * conditional branch. I know conditionals are expensive, but I couldn't * see a non-horrible way of avoiding them, and I did manage to group the * statements so that each if covers four group multiplications. */ static const u16 poly_to_exp[256] = { 492, 0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19, 0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A, 0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C, 0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B, 0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47, 0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D, 0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8, 0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C, 0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83, 0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48, 0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26, 0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E, 0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3, 0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9, 0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A, 0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D, 0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75, 0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84, 0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64, 0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49, 0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF, 0x85, 0xC8, 0xA1 }; static const byte exp_to_poly[492 + 256] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB, 0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1, 0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, }; /* The table constants are indices of * S-box entries, preprocessed through q0 and q1. */ static byte calc_sb_tbl[512] = { 0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4, 0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8, 0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B, 0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B, 0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD, 0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1, 0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B, 0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F, 0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B, 0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D, 0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E, 0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5, 0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14, 0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3, 0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54, 0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51, 0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A, 0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96, 0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10, 0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C, 0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7, 0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70, 0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB, 0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8, 0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF, 0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC, 0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF, 0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2, 0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82, 0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9, 0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97, 0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17, 0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D, 0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3, 0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C, 0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E, 0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F, 0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49, 0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21, 0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9, 0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD, 0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01, 0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F, 0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48, 0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E, 0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19, 0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57, 0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64, 0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE, 0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5, 0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44, 0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69, 0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15, 0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E, 0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34, 0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC, 0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B, 0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB, 0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52, 0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9, 0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4, 0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2, 0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56, 0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91 }; /* Macro to perform one column of the RS matrix multiplication. The * parameters a, b, c, and d are the four bytes of output; i is the index * of the key bytes, and w, x, y, and z, are the column of constants from * the RS matrix, preprocessed through the poly_to_exp table. */ #define CALC_S(a, b, c, d, i, w, x, y, z) \ { \ tmp = poly_to_exp[key[i]]; \ (a) ^= exp_to_poly[tmp + (w)]; \ (b) ^= exp_to_poly[tmp + (x)]; \ (c) ^= exp_to_poly[tmp + (y)]; \ (d) ^= exp_to_poly[tmp + (z)]; \ } /* Macros to calculate the key-dependent S-boxes for a 128-bit key using * the S vector from CALC_S. CALC_SB_2 computes a single entry in all * four S-boxes, where i is the index of the entry to compute, and a and b * are the index numbers preprocessed through the q0 and q1 tables * respectively. CALC_SB is simply a convenience to make the code shorter; * it calls CALC_SB_2 four times with consecutive indices from i to i+3, * using the remaining parameters two by two. */ #define CALC_SB_2(i, a, b) \ ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \ ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \ ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \ ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh] #define CALC_SB(i, a, b, c, d, e, f, g, h) \ CALC_SB_2 (i, a, b); CALC_SB_2 ((i)+1, c, d); \ CALC_SB_2 ((i)+2, e, f); CALC_SB_2 ((i)+3, g, h) /* Macros exactly like CALC_SB and CALC_SB_2, but for 256-bit keys. */ #define CALC_SB256_2(i, a, b) \ ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \ ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \ ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \ ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp]; #define CALC_SB256(i, a, b, c, d, e, f, g, h) \ CALC_SB256_2 (i, a, b); CALC_SB256_2 ((i)+1, c, d); \ CALC_SB256_2 ((i)+2, e, f); CALC_SB256_2 ((i)+3, g, h) /* Macros to calculate the whitening and round subkeys. CALC_K_2 computes the * last two stages of the h() function for a given index (either 2i or 2i+1). * a, b, c, and d are the four bytes going into the last two stages. For * 128-bit keys, this is the entire h() function and a and c are the index * preprocessed through q0 and q1 respectively; for longer keys they are the * output of previous stages. j is the index of the first key byte to use. * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2 * twice, doing the Pseudo-Hadamard Transform, and doing the necessary * rotations. Its parameters are: a, the array to write the results into, * j, the index of the first output entry, k and l, the preprocessed indices * for index 2i, and m and n, the preprocessed indices for index 2i+1. * CALC_K256_2 expands CALC_K_2 to handle 256-bit keys, by doing two * additional lookup-and-XOR stages. The parameters a and b are the index * preprocessed through q0 and q1 respectively; j is the index of the first * key byte to use. CALC_K256 is identical to CALC_K but for using the * CALC_K256_2 macro instead of CALC_K_2. */ #define CALC_K_2(a, b, c, d, j) \ mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \ ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \ ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \ ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]] #define CALC_K(a, j, k, l, m, n) \ x = CALC_K_2 (k, l, k, l, 0); \ y = CALC_K_2 (m, n, m, n, 4); \ y = (y << 8) + (y >> 24); \ x += y; y += x; ctx->a[j] = x; \ ctx->a[(j) + 1] = (y << 9) + (y >> 23) #define CALC_K256_2(a, b, j) \ CALC_K_2 (q0[q1[b ^ key[(j) + 24]] ^ key[(j) + 16]], \ q1[q1[a ^ key[(j) + 25]] ^ key[(j) + 17]], \ q0[q0[a ^ key[(j) + 26]] ^ key[(j) + 18]], \ q1[q0[b ^ key[(j) + 27]] ^ key[(j) + 19]], j) #define CALC_K256(a, j, k, l, m, n) \ x = CALC_K256_2 (k, l, 0); \ y = CALC_K256_2 (m, n, 4); \ y = (y << 8) + (y >> 24); \ x += y; y += x; ctx->a[j] = x; \ ctx->a[(j) + 1] = (y << 9) + (y >> 23) /* Perform the key setup. Note that this works only with 128- and 256-bit * keys, despite the API that looks like it might support other sizes. */ static gcry_err_code_t do_twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen) { int i, j, k; /* Temporaries for CALC_K. */ u32 x, y; /* The S vector used to key the S-boxes, split up into individual bytes. * 128-bit keys use only sa through sh; 256-bit use all of them. */ byte sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0; byte si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0; /* Temporary for CALC_S. */ unsigned int tmp; /* Flags for self-test. */ static int initialized = 0; static const char *selftest_failed=0; /* Check key length. */ if( ( ( keylen - 16 ) | 16 ) != 16 ) return GPG_ERR_INV_KEYLEN; /* Do self-test if necessary. */ if (!initialized) { initialized = 1; selftest_failed = selftest (); if( selftest_failed ) log_error("%s\n", selftest_failed ); } if( selftest_failed ) return GPG_ERR_SELFTEST_FAILED; /* Compute the first two words of the S vector. The magic numbers are * the entries of the RS matrix, preprocessed through poly_to_exp. The * numbers in the comments are the original (polynomial form) matrix * entries. */ CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */ CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */ CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */ CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */ CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */ CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */ CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */ CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */ CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */ CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */ CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */ CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */ CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */ CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */ CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */ CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */ if (keylen == 32) /* 256-bit key */ { /* Calculate the remaining two words of the S vector */ CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */ CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */ CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */ CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */ CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */ CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */ CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */ CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */ CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */ CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */ CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */ CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */ CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */ CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */ CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */ CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */ /* Compute the S-boxes. */ for(i=j=0,k=1; i < 256; i++, j += 2, k += 2 ) { CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] ); } /* Calculate whitening and round subkeys. */ for (i = 0; i < 8; i += 2) { CALC_K256 ( w, i, q0[i], q1[i], q0[i + 1], q1[i + 1] ); } for (j = 0; j < 32; j += 2, i += 2) { CALC_K256 ( k, j, q0[i], q1[i], q0[i + 1], q1[i + 1] ); } } else { /* Compute the S-boxes. */ for(i=j=0,k=1; i < 256; i++, j += 2, k += 2 ) { CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] ); } /* Calculate whitening and round subkeys. */ for (i = 0; i < 8; i += 2) { CALC_K ( w, i, q0[i], q1[i], q0[i + 1], q1[i + 1] ); } for (j = 0; j < 32; j += 2, i += 2) { CALC_K ( k, j, q0[i], q1[i], q0[i + 1], q1[i + 1] ); } } return 0; } static gcry_err_code_t twofish_setkey (void *context, const byte *key, unsigned int keylen, cipher_bulk_ops_t *bulk_ops) { TWOFISH_context *ctx = context; unsigned int hwfeatures = _gcry_get_hw_features (); int rc; rc = do_twofish_setkey (ctx, key, keylen); #ifdef USE_AVX2 ctx->use_avx2 = 0; if ((hwfeatures & HWF_INTEL_AVX2) && (hwfeatures & HWF_INTEL_FAST_VPGATHER)) { ctx->use_avx2 = 1; } #endif /* Setup bulk encryption routines. */ memset (bulk_ops, 0, sizeof(*bulk_ops)); bulk_ops->cbc_dec = _gcry_twofish_cbc_dec; bulk_ops->cfb_dec = _gcry_twofish_cfb_dec; bulk_ops->ctr_enc = _gcry_twofish_ctr_enc; bulk_ops->ocb_crypt = _gcry_twofish_ocb_crypt; bulk_ops->ocb_auth = _gcry_twofish_ocb_auth; (void)hwfeatures; _gcry_burn_stack (23+6*sizeof(void*)); return rc; } #ifdef USE_AVX2 /* Assembler implementations of Twofish using AVX2. Process 16 block in parallel. */ extern void _gcry_twofish_avx2_ctr_enc(const TWOFISH_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *ctr) ASM_FUNC_ABI; extern void _gcry_twofish_avx2_cbc_dec(const TWOFISH_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_twofish_avx2_cfb_dec(const TWOFISH_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *iv) ASM_FUNC_ABI; extern void _gcry_twofish_avx2_ocb_enc(const TWOFISH_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; extern void _gcry_twofish_avx2_ocb_dec(const TWOFISH_context *ctx, unsigned char *out, const unsigned char *in, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; extern void _gcry_twofish_avx2_ocb_auth(const TWOFISH_context *ctx, const unsigned char *abuf, unsigned char *offset, unsigned char *checksum, const u64 Ls[16]) ASM_FUNC_ABI; #endif #ifdef USE_AMD64_ASM /* Assembly implementations of Twofish. */ extern void _gcry_twofish_amd64_encrypt_block(const TWOFISH_context *c, byte *out, const byte *in); extern void _gcry_twofish_amd64_decrypt_block(const TWOFISH_context *c, byte *out, const byte *in); /* These assembly implementations process three blocks in parallel. */ extern void _gcry_twofish_amd64_ctr_enc(const TWOFISH_context *c, byte *out, const byte *in, byte *ctr); extern void _gcry_twofish_amd64_cbc_dec(const TWOFISH_context *c, byte *out, const byte *in, byte *iv); extern void _gcry_twofish_amd64_cfb_dec(const TWOFISH_context *c, byte *out, const byte *in, byte *iv); extern void _gcry_twofish_amd64_ocb_enc(const TWOFISH_context *ctx, byte *out, const byte *in, byte *offset, byte *checksum, const u64 Ls[3]); extern void _gcry_twofish_amd64_ocb_dec(const TWOFISH_context *ctx, byte *out, const byte *in, byte *offset, byte *checksum, const u64 Ls[3]); extern void _gcry_twofish_amd64_ocb_auth(const TWOFISH_context *ctx, const byte *abuf, byte *offset, byte *checksum, const u64 Ls[3]); static inline void twofish_amd64_encrypt_block(const TWOFISH_context *c, byte *out, const byte *in) { _gcry_twofish_amd64_encrypt_block(c, out, in); } static inline void twofish_amd64_decrypt_block(const TWOFISH_context *c, byte *out, const byte *in) { _gcry_twofish_amd64_decrypt_block(c, out, in); } static inline void twofish_amd64_ctr_enc(const TWOFISH_context *c, byte *out, const byte *in, byte *ctr) { _gcry_twofish_amd64_ctr_enc(c, out, in, ctr); } static inline void twofish_amd64_cbc_dec(const TWOFISH_context *c, byte *out, const byte *in, byte *iv) { _gcry_twofish_amd64_cbc_dec(c, out, in, iv); } static inline void twofish_amd64_cfb_dec(const TWOFISH_context *c, byte *out, const byte *in, byte *iv) { _gcry_twofish_amd64_cfb_dec(c, out, in, iv); } static inline void twofish_amd64_ocb_enc(const TWOFISH_context *ctx, byte *out, const byte *in, byte *offset, byte *checksum, const u64 Ls[3]) { _gcry_twofish_amd64_ocb_enc(ctx, out, in, offset, checksum, Ls); } static inline void twofish_amd64_ocb_dec(const TWOFISH_context *ctx, byte *out, const byte *in, byte *offset, byte *checksum, const u64 Ls[3]) { _gcry_twofish_amd64_ocb_dec(ctx, out, in, offset, checksum, Ls); } static inline void twofish_amd64_ocb_auth(const TWOFISH_context *ctx, const byte *abuf, byte *offset, byte *checksum, const u64 Ls[3]) { _gcry_twofish_amd64_ocb_auth(ctx, abuf, offset, checksum, Ls); } #elif defined(USE_ARM_ASM) /* Assembly implementations of Twofish. */ extern void _gcry_twofish_arm_encrypt_block(const TWOFISH_context *c, byte *out, const byte *in); extern void _gcry_twofish_arm_decrypt_block(const TWOFISH_context *c, byte *out, const byte *in); #else /*!USE_AMD64_ASM && !USE_ARM_ASM*/ /* Macros to compute the g() function in the encryption and decryption * rounds. G1 is the straight g() function; G2 includes the 8-bit * rotation for the high 32-bit word. */ #define G1(a) \ (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \ ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24]) #define G2(b) \ (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \ ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24]) /* Encryption and decryption Feistel rounds. Each one calls the two g() * macros, does the PHT, and performs the XOR and the appropriate bit * rotations. The parameters are the round number (used to select subkeys), * and the four 32-bit chunks of the text. */ #define ENCROUND(n, a, b, c, d) \ x = G1 (a); y = G2 (b); \ x += y; y += x + ctx->k[2 * (n) + 1]; \ (c) ^= x + ctx->k[2 * (n)]; \ (c) = ((c) >> 1) + ((c) << 31); \ (d) = (((d) << 1)+((d) >> 31)) ^ y #define DECROUND(n, a, b, c, d) \ x = G1 (a); y = G2 (b); \ x += y; y += x; \ (d) ^= y + ctx->k[2 * (n) + 1]; \ (d) = ((d) >> 1) + ((d) << 31); \ (c) = (((c) << 1)+((c) >> 31)); \ (c) ^= (x + ctx->k[2 * (n)]) /* Encryption and decryption cycles; each one is simply two Feistel rounds * with the 32-bit chunks re-ordered to simulate the "swap" */ #define ENCCYCLE(n) \ ENCROUND (2 * (n), a, b, c, d); \ ENCROUND (2 * (n) + 1, c, d, a, b) #define DECCYCLE(n) \ DECROUND (2 * (n) + 1, c, d, a, b); \ DECROUND (2 * (n), a, b, c, d) /* Macros to convert the input and output bytes into 32-bit words, * and simultaneously perform the whitening step. INPACK packs word * number n into the variable named by x, using whitening subkey number m. * OUTUNPACK unpacks word number n from the variable named by x, using * whitening subkey number m. */ #define INPACK(n, x, m) \ x = buf_get_le32(in + (n) * 4); \ x ^= ctx->w[m] #define OUTUNPACK(n, x, m) \ x ^= ctx->w[m]; \ buf_put_le32(out + (n) * 4, x) #endif /*!USE_AMD64_ASM*/ /* Encrypt one block. in and out may be the same. */ #ifdef USE_AMD64_ASM static unsigned int twofish_encrypt (void *context, byte *out, const byte *in) { TWOFISH_context *ctx = context; twofish_amd64_encrypt_block(ctx, out, in); return /*burn_stack*/ (4*sizeof (void*)); } #elif defined(USE_ARM_ASM) static unsigned int twofish_encrypt (void *context, byte *out, const byte *in) { TWOFISH_context *ctx = context; _gcry_twofish_arm_encrypt_block(ctx, out, in); return /*burn_stack*/ (4*sizeof (void*)); } #else /*!USE_AMD64_ASM && !USE_ARM_ASM*/ static void do_twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in) { /* The four 32-bit chunks of the text. */ u32 a, b, c, d; /* Temporaries used by the round function. */ u32 x, y; /* Input whitening and packing. */ INPACK (0, a, 0); INPACK (1, b, 1); INPACK (2, c, 2); INPACK (3, d, 3); /* Encryption Feistel cycles. */ ENCCYCLE (0); ENCCYCLE (1); ENCCYCLE (2); ENCCYCLE (3); ENCCYCLE (4); ENCCYCLE (5); ENCCYCLE (6); ENCCYCLE (7); /* Output whitening and unpacking. */ OUTUNPACK (0, c, 4); OUTUNPACK (1, d, 5); OUTUNPACK (2, a, 6); OUTUNPACK (3, b, 7); } static unsigned int twofish_encrypt (void *context, byte *out, const byte *in) { TWOFISH_context *ctx = context; do_twofish_encrypt (ctx, out, in); return /*burn_stack*/ (24+3*sizeof (void*)); } #endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ /* Decrypt one block. in and out may be the same. */ #ifdef USE_AMD64_ASM static unsigned int twofish_decrypt (void *context, byte *out, const byte *in) { TWOFISH_context *ctx = context; twofish_amd64_decrypt_block(ctx, out, in); return /*burn_stack*/ (4*sizeof (void*)); } #elif defined(USE_ARM_ASM) static unsigned int twofish_decrypt (void *context, byte *out, const byte *in) { TWOFISH_context *ctx = context; _gcry_twofish_arm_decrypt_block(ctx, out, in); return /*burn_stack*/ (4*sizeof (void*)); } #else /*!USE_AMD64_ASM && !USE_ARM_ASM*/ static void do_twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in) { /* The four 32-bit chunks of the text. */ u32 a, b, c, d; /* Temporaries used by the round function. */ u32 x, y; /* Input whitening and packing. */ INPACK (0, c, 4); INPACK (1, d, 5); INPACK (2, a, 6); INPACK (3, b, 7); /* Encryption Feistel cycles. */ DECCYCLE (7); DECCYCLE (6); DECCYCLE (5); DECCYCLE (4); DECCYCLE (3); DECCYCLE (2); DECCYCLE (1); DECCYCLE (0); /* Output whitening and unpacking. */ OUTUNPACK (0, a, 0); OUTUNPACK (1, b, 1); OUTUNPACK (2, c, 2); OUTUNPACK (3, d, 3); } static unsigned int twofish_decrypt (void *context, byte *out, const byte *in) { TWOFISH_context *ctx = context; do_twofish_decrypt (ctx, out, in); return /*burn_stack*/ (24+3*sizeof (void*)); } #endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ /* Bulk encryption of complete blocks in CTR mode. This function is only intended for the bulk encryption feature of cipher.c. CTR is expected to be of size TWOFISH_BLOCKSIZE. */ static void _gcry_twofish_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { TWOFISH_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char tmpbuf[TWOFISH_BLOCKSIZE]; unsigned int burn, burn_stack_depth = 0; #ifdef USE_AVX2 if (ctx->use_avx2) { int did_use_avx2 = 0; /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_twofish_avx2_ctr_enc(ctx, outbuf, inbuf, ctr); nblocks -= 16; outbuf += 16 * TWOFISH_BLOCKSIZE; inbuf += 16 * TWOFISH_BLOCKSIZE; did_use_avx2 = 1; } if (did_use_avx2) { /* twofish-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } } #endif #ifdef USE_AMD64_ASM { /* Process data in 3 block chunks. */ while (nblocks >= 3) { twofish_amd64_ctr_enc(ctx, outbuf, inbuf, ctr); nblocks -= 3; outbuf += 3 * TWOFISH_BLOCKSIZE; inbuf += 3 * TWOFISH_BLOCKSIZE; burn = 8 * sizeof(void*); if (burn > burn_stack_depth) burn_stack_depth = burn; } /* Use generic code to handle smaller chunks... */ /* TODO: use caching instead? */ } #endif for ( ;nblocks; nblocks-- ) { /* Encrypt the counter. */ burn = twofish_encrypt(ctx, tmpbuf, ctr); if (burn > burn_stack_depth) burn_stack_depth = burn; /* XOR the input with the encrypted counter and store in output. */ cipher_block_xor(outbuf, tmpbuf, inbuf, TWOFISH_BLOCKSIZE); outbuf += TWOFISH_BLOCKSIZE; inbuf += TWOFISH_BLOCKSIZE; /* Increment the counter. */ cipher_block_add(ctr, 1, TWOFISH_BLOCKSIZE); } wipememory(tmpbuf, sizeof(tmpbuf)); _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CBC mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_twofish_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { TWOFISH_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char savebuf[TWOFISH_BLOCKSIZE]; unsigned int burn, burn_stack_depth = 0; #ifdef USE_AVX2 if (ctx->use_avx2) { int did_use_avx2 = 0; /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_twofish_avx2_cbc_dec(ctx, outbuf, inbuf, iv); nblocks -= 16; outbuf += 16 * TWOFISH_BLOCKSIZE; inbuf += 16 * TWOFISH_BLOCKSIZE; did_use_avx2 = 1; } if (did_use_avx2) { /* twofish-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } } #endif #ifdef USE_AMD64_ASM { /* Process data in 3 block chunks. */ while (nblocks >= 3) { twofish_amd64_cbc_dec(ctx, outbuf, inbuf, iv); nblocks -= 3; outbuf += 3 * TWOFISH_BLOCKSIZE; inbuf += 3 * TWOFISH_BLOCKSIZE; burn = 9 * sizeof(void*); if (burn > burn_stack_depth) burn_stack_depth = burn; } /* Use generic code to handle smaller chunks... */ } #endif for ( ;nblocks; nblocks-- ) { /* INBUF is needed later and it may be identical to OUTBUF, so store the intermediate result to SAVEBUF. */ burn = twofish_decrypt (ctx, savebuf, inbuf); if (burn > burn_stack_depth) burn_stack_depth = burn; cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, TWOFISH_BLOCKSIZE); inbuf += TWOFISH_BLOCKSIZE; outbuf += TWOFISH_BLOCKSIZE; } wipememory(savebuf, sizeof(savebuf)); _gcry_burn_stack(burn_stack_depth); } /* Bulk decryption of complete blocks in CFB mode. This function is only intended for the bulk encryption feature of cipher.c. */ static void _gcry_twofish_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { TWOFISH_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned int burn, burn_stack_depth = 0; #ifdef USE_AVX2 if (ctx->use_avx2) { int did_use_avx2 = 0; /* Process data in 16 block chunks. */ while (nblocks >= 16) { _gcry_twofish_avx2_cfb_dec(ctx, outbuf, inbuf, iv); nblocks -= 16; outbuf += 16 * TWOFISH_BLOCKSIZE; inbuf += 16 * TWOFISH_BLOCKSIZE; did_use_avx2 = 1; } if (did_use_avx2) { /* twofish-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } } #endif #ifdef USE_AMD64_ASM { /* Process data in 3 block chunks. */ while (nblocks >= 3) { twofish_amd64_cfb_dec(ctx, outbuf, inbuf, iv); nblocks -= 3; outbuf += 3 * TWOFISH_BLOCKSIZE; inbuf += 3 * TWOFISH_BLOCKSIZE; burn = 8 * sizeof(void*); if (burn > burn_stack_depth) burn_stack_depth = burn; } /* Use generic code to handle smaller chunks... */ } #endif for ( ;nblocks; nblocks-- ) { burn = twofish_encrypt(ctx, iv, iv); if (burn > burn_stack_depth) burn_stack_depth = burn; cipher_block_xor_n_copy(outbuf, iv, inbuf, TWOFISH_BLOCKSIZE); outbuf += TWOFISH_BLOCKSIZE; inbuf += TWOFISH_BLOCKSIZE; } _gcry_burn_stack(burn_stack_depth); } /* Bulk encryption/decryption of complete blocks in OCB mode. */ static size_t _gcry_twofish_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt) { #ifdef USE_AMD64_ASM TWOFISH_context *ctx = (void *)&c->context.c; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned int burn, burn_stack_depth = 0; u64 blkn = c->u_mode.ocb.data_nblocks; #ifdef USE_AVX2 if (ctx->use_avx2) { int did_use_avx2 = 0; u64 Ls[16]; u64 *l; if (nblocks >= 16) { l = bulk_ocb_prepare_L_pointers_array_blk16 (c, Ls, blkn); /* Process data in 16 block chunks. */ while (nblocks >= 16) { blkn += 16; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16); if (encrypt) _gcry_twofish_avx2_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); else _gcry_twofish_avx2_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); nblocks -= 16; outbuf += 16 * TWOFISH_BLOCKSIZE; inbuf += 16 * TWOFISH_BLOCKSIZE; did_use_avx2 = 1; } } if (did_use_avx2) { /* twofish-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } } #endif { /* Use u64 to store pointers for x32 support (assembly function * assumes 64-bit pointers). */ u64 Ls[3]; /* Process data in 3 block chunks. */ while (nblocks >= 3) { Ls[0] = (uintptr_t)(const void *)ocb_get_l(c, blkn + 1); Ls[1] = (uintptr_t)(const void *)ocb_get_l(c, blkn + 2); Ls[2] = (uintptr_t)(const void *)ocb_get_l(c, blkn + 3); blkn += 3; if (encrypt) twofish_amd64_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); else twofish_amd64_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, Ls); nblocks -= 3; outbuf += 3 * TWOFISH_BLOCKSIZE; inbuf += 3 * TWOFISH_BLOCKSIZE; burn = 8 * sizeof(void*); if (burn > burn_stack_depth) burn_stack_depth = burn; } /* Use generic code to handle smaller chunks... */ } c->u_mode.ocb.data_nblocks = blkn; if (burn_stack_depth) _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *)); #else (void)c; (void)outbuf_arg; (void)inbuf_arg; (void)encrypt; #endif return nblocks; } /* Bulk authentication of complete blocks in OCB mode. */ static size_t _gcry_twofish_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks) { #ifdef USE_AMD64_ASM TWOFISH_context *ctx = (void *)&c->context.c; const unsigned char *abuf = abuf_arg; unsigned int burn, burn_stack_depth = 0; u64 blkn = c->u_mode.ocb.aad_nblocks; #ifdef USE_AVX2 if (ctx->use_avx2) { int did_use_avx2 = 0; u64 Ls[16]; u64 *l; if (nblocks >= 16) { l = bulk_ocb_prepare_L_pointers_array_blk16 (c, Ls, blkn); /* Process data in 16 block chunks. */ while (nblocks >= 16) { blkn += 16; *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16); _gcry_twofish_avx2_ocb_auth(ctx, abuf, c->u_mode.ocb.aad_offset, c->u_mode.ocb.aad_sum, Ls); nblocks -= 16; abuf += 16 * TWOFISH_BLOCKSIZE; did_use_avx2 = 1; } } if (did_use_avx2) { /* twofish-avx2 assembly code does not use stack */ if (nblocks == 0) burn_stack_depth = 0; } /* Use generic code to handle smaller chunks... */ } #endif { /* Use u64 to store pointers for x32 support (assembly function * assumes 64-bit pointers). */ u64 Ls[3]; /* Process data in 3 block chunks. */ while (nblocks >= 3) { Ls[0] = (uintptr_t)(const void *)ocb_get_l(c, blkn + 1); Ls[1] = (uintptr_t)(const void *)ocb_get_l(c, blkn + 2); Ls[2] = (uintptr_t)(const void *)ocb_get_l(c, blkn + 3); blkn += 3; twofish_amd64_ocb_auth(ctx, abuf, c->u_mode.ocb.aad_offset, c->u_mode.ocb.aad_sum, Ls); nblocks -= 3; abuf += 3 * TWOFISH_BLOCKSIZE; burn = 8 * sizeof(void*); if (burn > burn_stack_depth) burn_stack_depth = burn; } /* Use generic code to handle smaller chunks... */ } c->u_mode.ocb.aad_nblocks = blkn; if (burn_stack_depth) _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *)); #else (void)c; (void)abuf_arg; #endif return nblocks; } - - -/* Run the self-tests for TWOFISH-CTR, tests IV increment of bulk CTR - encryption. Returns NULL on success. */ -static const char * -selftest_ctr (void) -{ - const int nblocks = 16+1; - const int blocksize = TWOFISH_BLOCKSIZE; - const int context_size = sizeof(TWOFISH_context); - - return _gcry_selftest_helper_ctr("TWOFISH", &twofish_setkey, - &twofish_encrypt, nblocks, blocksize, context_size); -} - -/* Run the self-tests for TWOFISH-CBC, tests bulk CBC decryption. - Returns NULL on success. */ -static const char * -selftest_cbc (void) -{ - const int nblocks = 16+2; - const int blocksize = TWOFISH_BLOCKSIZE; - const int context_size = sizeof(TWOFISH_context); - - return _gcry_selftest_helper_cbc("TWOFISH", &twofish_setkey, - &twofish_encrypt, nblocks, blocksize, context_size); -} - -/* Run the self-tests for TWOFISH-CFB, tests bulk CBC decryption. - Returns NULL on success. */ -static const char * -selftest_cfb (void) -{ - const int nblocks = 16+2; - const int blocksize = TWOFISH_BLOCKSIZE; - const int context_size = sizeof(TWOFISH_context); - - return _gcry_selftest_helper_cfb("TWOFISH", &twofish_setkey, - &twofish_encrypt, nblocks, blocksize, context_size); -} /* Test a single encryption and decryption with each key size. */ static const char* selftest (void) { TWOFISH_context ctx; /* Expanded key. */ byte scratch[16]; /* Encryption/decryption result buffer. */ cipher_bulk_ops_t bulk_ops; - const char *r; /* Test vectors for single encryption/decryption. Note that I am using * the vectors from the Twofish paper's "known answer test", I=3 for * 128-bit and I=4 for 256-bit, instead of the all-0 vectors from the * "intermediate value test", because an all-0 key would trigger all the * special cases in the RS matrix multiply, leaving the math untested. */ static byte plaintext[16] = { 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 }; static byte key[16] = { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A }; static const byte ciphertext[16] = { 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 }; static byte plaintext_256[16] = { 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 }; static byte key_256[32] = { 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F }; static const byte ciphertext_256[16] = { 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA }; twofish_setkey (&ctx, key, sizeof(key), &bulk_ops); twofish_encrypt (&ctx, scratch, plaintext); if (memcmp (scratch, ciphertext, sizeof (ciphertext))) return "Twofish-128 test encryption failed."; twofish_decrypt (&ctx, scratch, scratch); if (memcmp (scratch, plaintext, sizeof (plaintext))) return "Twofish-128 test decryption failed."; twofish_setkey (&ctx, key_256, sizeof(key_256), &bulk_ops); twofish_encrypt (&ctx, scratch, plaintext_256); if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256))) return "Twofish-256 test encryption failed."; twofish_decrypt (&ctx, scratch, scratch); if (memcmp (scratch, plaintext_256, sizeof (plaintext_256))) return "Twofish-256 test decryption failed."; - if ((r = selftest_ctr()) != NULL) - return r; - if ((r = selftest_cbc()) != NULL) - return r; - if ((r = selftest_cfb()) != NULL) - return r; - return NULL; } /* More complete test program. This does 1000 encryptions and decryptions * with each of 250 128-bit keys and 2000 encryptions and decryptions with * each of 125 256-bit keys, using a feedback scheme similar to a Feistel * cipher, so as to be sure of testing all the table entries pretty * thoroughly. We keep changing the keys so as to get a more meaningful * performance number, since the key setup is non-trivial for Twofish. */ #ifdef TEST #include #include #include int main() { TWOFISH_context ctx; /* Expanded key. */ int i, j; /* Loop counters. */ cipher_bulk_ops_t bulk_ops; const char *encrypt_msg; /* Message to print regarding encryption test; * the printf is done outside the loop to avoid * stuffing up the timing. */ clock_t timer; /* For computing elapsed time. */ /* Test buffer. */ byte buffer[4][16] = { {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, {0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78, 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0}, {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54 ,0x32, 0x10}, {0x01, 0x23, 0x45, 0x67, 0x76, 0x54 ,0x32, 0x10, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98} }; /* Expected outputs for the million-operation test */ static const byte test_encrypt[4][16] = { {0xC8, 0x23, 0xB8, 0xB7, 0x6B, 0xFE, 0x91, 0x13, 0x2F, 0xA7, 0x5E, 0xE6, 0x94, 0x77, 0x6F, 0x6B}, {0x90, 0x36, 0xD8, 0x29, 0xD5, 0x96, 0xC2, 0x8E, 0xE4, 0xFF, 0x76, 0xBC, 0xE5, 0x77, 0x88, 0x27}, {0xB8, 0x78, 0x69, 0xAF, 0x42, 0x8B, 0x48, 0x64, 0xF7, 0xE9, 0xF3, 0x9C, 0x42, 0x18, 0x7B, 0x73}, {0x7A, 0x88, 0xFB, 0xEB, 0x90, 0xA4, 0xB4, 0xA8, 0x43, 0xA3, 0x1D, 0xF1, 0x26, 0xC4, 0x53, 0x57} }; static const byte test_decrypt[4][16] = { {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, {0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78, 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0}, {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54 ,0x32, 0x10}, {0x01, 0x23, 0x45, 0x67, 0x76, 0x54 ,0x32, 0x10, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98} }; /* Start the timer ticking. */ timer = clock (); /* Encryption test. */ for (i = 0; i < 125; i++) { twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]), &bulk_ops); for (j = 0; j < 1000; j++) twofish_encrypt (&ctx, buffer[2], buffer[2]); twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]), &bulk_ops); for (j = 0; j < 1000; j++) twofish_encrypt (&ctx, buffer[3], buffer[3]); twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2, &bulk_ops); for (j = 0; j < 1000; j++) { twofish_encrypt (&ctx, buffer[0], buffer[0]); twofish_encrypt (&ctx, buffer[1], buffer[1]); } } encrypt_msg = memcmp (buffer, test_encrypt, sizeof (test_encrypt)) ? "encryption failure!\n" : "encryption OK!\n"; /* Decryption test. */ for (i = 0; i < 125; i++) { twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2, &bulk_ops); for (j = 0; j < 1000; j++) { twofish_decrypt (&ctx, buffer[0], buffer[0]); twofish_decrypt (&ctx, buffer[1], buffer[1]); } twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]), &bulk_ops); for (j = 0; j < 1000; j++) twofish_decrypt (&ctx, buffer[3], buffer[3]); twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]), &bulk_ops); for (j = 0; j < 1000; j++) twofish_decrypt (&ctx, buffer[2], buffer[2]); } /* Stop the timer, and print results. */ timer = clock () - timer; printf (encrypt_msg); printf (memcmp (buffer, test_decrypt, sizeof (test_decrypt)) ? "decryption failure!\n" : "decryption OK!\n"); printf ("elapsed time: %.1f s.\n", (float) timer / CLOCKS_PER_SEC); return 0; } #endif /* TEST */ gcry_cipher_spec_t _gcry_cipher_spec_twofish = { GCRY_CIPHER_TWOFISH, {0, 0}, "TWOFISH", NULL, NULL, 16, 256, sizeof (TWOFISH_context), twofish_setkey, twofish_encrypt, twofish_decrypt }; gcry_cipher_spec_t _gcry_cipher_spec_twofish128 = { GCRY_CIPHER_TWOFISH128, {0, 0}, "TWOFISH128", NULL, NULL, 16, 128, sizeof (TWOFISH_context), twofish_setkey, twofish_encrypt, twofish_decrypt }; diff --git a/tests/basic.c b/tests/basic.c index 40a0a474..f5513740 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1,16527 +1,17299 @@ /* 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 +#ifdef HAVE_STDINT_H +# include /* uintptr_t */ +#elif defined(HAVE_INTTYPES_H) +# include +#else +/* In this case, uintptr_t is provided by config.h. */ +#endif #include "../src/gcrypt-int.h" #define PGM "basic" #include "t-common.h" #if __GNUC__ >= 4 # define ALWAYS_INLINE __attribute__((always_inline)) #else # define ALWAYS_INLINE #endif 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) #define FLAG_NOFIPS (1 << 3) #define FLAG_CFB8 (1 << 4) #define FLAG_SPECIAL (1 << 5) static int in_fips_mode; #define MAX_DATA_LEN 1040 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); } static 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); } #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 CLUTTER_VECTOR_REGISTER_AMD64 1 # define CLUTTER_VECTOR_REGISTER_COUNT 16 #elif defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ >= 4 && \ defined(HAVE_GCC_INLINE_ASM_SSSE3) # define CLUTTER_VECTOR_REGISTER_I386 1 # define CLUTTER_VECTOR_REGISTER_COUNT 8 #elif defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \ defined(HAVE_GCC_INLINE_ASM_AARCH64_NEON) && \ defined(__ARM_NEON) # define CLUTTER_VECTOR_REGISTER_AARCH64 1 # define CLUTTER_VECTOR_REGISTER_COUNT 32 #elif defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \ defined(HAVE_GCC_INLINE_ASM_NEON) && \ defined(__ARM_NEON) # define CLUTTER_VECTOR_REGISTER_NEON 1 # define CLUTTER_VECTOR_REGISTER_COUNT 16 #endif #ifdef CLUTTER_VECTOR_REGISTER_COUNT static void prepare_vector_data(unsigned char data[CLUTTER_VECTOR_REGISTER_COUNT][16]) { static unsigned char basedata[16] = { 0xd7, 0xfe, 0x5c, 0x4b, 0x58, 0xfe, 0xf4, 0xb6, 0xed, 0x2f, 0x31, 0xc9, 0x1d, 0xd3, 0x62, 0x8d }; int j, i; for (i = 0; i < CLUTTER_VECTOR_REGISTER_COUNT; i++) { for (j = 0; j < 16; j++) { data[i][j] = basedata[(i + j) % 16]; } for (j = 0; j < 16; j++) { basedata[j] -= j; } } } #endif static inline ALWAYS_INLINE void clutter_vector_registers(void) { #ifdef CLUTTER_VECTOR_REGISTER_COUNT unsigned char data[CLUTTER_VECTOR_REGISTER_COUNT][16]; #if defined(CLUTTER_VECTOR_REGISTER_AARCH64) || \ defined(CLUTTER_VECTOR_REGISTER_NEON) static int init; static int have_neon; if (!init) { char *string; string = gcry_get_config (0, "hwflist"); if (string) { have_neon = (strstr(string, "arm-neon:") != NULL); xfree(string); } init = 1; } if (!have_neon) return; #elif defined(CLUTTER_VECTOR_REGISTER_I386) static int init; static int have_ssse3; if (!init) { char *string; string = gcry_get_config (0, "hwflist"); if (string) { have_ssse3 = (strstr(string, "intel-ssse3:") != NULL); xfree(string); } init = 1; } if (!have_ssse3) return; #endif prepare_vector_data(data); #if defined(CLUTTER_VECTOR_REGISTER_AMD64) asm volatile("movdqu %[data0], %%xmm0\n" "movdqu %[data1], %%xmm1\n" "movdqu %[data2], %%xmm2\n" "movdqu %[data3], %%xmm3\n" "movdqu %[data4], %%xmm4\n" "movdqu %[data5], %%xmm5\n" "movdqu %[data6], %%xmm6\n" "movdqu %[data7], %%xmm7\n" "movdqu %[data8], %%xmm8\n" "movdqu %[data9], %%xmm9\n" "movdqu %[data10], %%xmm10\n" "movdqu %[data11], %%xmm11\n" "movdqu %[data12], %%xmm12\n" "movdqu %[data13], %%xmm13\n" "movdqu %[data14], %%xmm14\n" "movdqu %[data15], %%xmm15\n" : : [data0] "m" (*data[0]), [data1] "m" (*data[1]), [data2] "m" (*data[2]), [data3] "m" (*data[3]), [data4] "m" (*data[4]), [data5] "m" (*data[5]), [data6] "m" (*data[6]), [data7] "m" (*data[7]), [data8] "m" (*data[8]), [data9] "m" (*data[9]), [data10] "m" (*data[10]), [data11] "m" (*data[11]), [data12] "m" (*data[12]), [data13] "m" (*data[13]), [data14] "m" (*data[14]), [data15] "m" (*data[15]) : "memory" #ifdef __SSE2__ ,"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" #endif ); #elif defined(CLUTTER_VECTOR_REGISTER_I386) asm volatile("movdqu %[data0], %%xmm0\n" "movdqu %[data1], %%xmm1\n" "movdqu %[data2], %%xmm2\n" "movdqu %[data3], %%xmm3\n" "movdqu %[data4], %%xmm4\n" "movdqu %[data5], %%xmm5\n" "movdqu %[data6], %%xmm6\n" "movdqu %[data7], %%xmm7\n" : : [data0] "m" (*data[0]), [data1] "m" (*data[1]), [data2] "m" (*data[2]), [data3] "m" (*data[3]), [data4] "m" (*data[4]), [data5] "m" (*data[5]), [data6] "m" (*data[6]), [data7] "m" (*data[7]) : "memory" #ifdef __SSE2__ ,"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" #endif ); #elif defined(CLUTTER_VECTOR_REGISTER_AARCH64) asm volatile("mov x0, %[ptr]\n" "ld1 {v0.16b}, [x0], #16\n" "ld1 {v1.16b}, [x0], #16\n" "ld1 {v2.16b}, [x0], #16\n" "ld1 {v3.16b}, [x0], #16\n" "ld1 {v4.16b}, [x0], #16\n" "ld1 {v5.16b}, [x0], #16\n" "ld1 {v6.16b}, [x0], #16\n" "ld1 {v7.16b}, [x0], #16\n" "ld1 {v8.16b}, [x0], #16\n" "ld1 {v9.16b}, [x0], #16\n" "ld1 {v10.16b}, [x0], #16\n" "ld1 {v11.16b}, [x0], #16\n" "ld1 {v12.16b}, [x0], #16\n" "ld1 {v13.16b}, [x0], #16\n" "ld1 {v14.16b}, [x0], #16\n" "ld1 {v15.16b}, [x0], #16\n" "ld1 {v16.16b}, [x0], #16\n" "ld1 {v17.16b}, [x0], #16\n" "ld1 {v18.16b}, [x0], #16\n" "ld1 {v19.16b}, [x0], #16\n" "ld1 {v20.16b}, [x0], #16\n" "ld1 {v21.16b}, [x0], #16\n" "ld1 {v22.16b}, [x0], #16\n" "ld1 {v23.16b}, [x0], #16\n" "ld1 {v24.16b}, [x0], #16\n" "ld1 {v25.16b}, [x0], #16\n" "ld1 {v26.16b}, [x0], #16\n" "ld1 {v27.16b}, [x0], #16\n" "ld1 {v28.16b}, [x0], #16\n" "ld1 {v29.16b}, [x0], #16\n" "ld1 {v30.16b}, [x0], #16\n" "ld1 {v31.16b}, [x0], #16\n" : : [ptr] "r" (data) : "x0", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", "memory"); #elif defined(CLUTTER_VECTOR_REGISTER_NEON) asm volatile("mov r0, %[ptr]\n" "vld1.64 {q0}, [r0]!\n" "vld1.64 {q1}, [r0]!\n" "vld1.64 {q2}, [r0]!\n" "vld1.64 {q3}, [r0]!\n" "vld1.64 {q4}, [r0]!\n" "vld1.64 {q5}, [r0]!\n" "vld1.64 {q6}, [r0]!\n" "vld1.64 {q7}, [r0]!\n" "vld1.64 {q8}, [r0]!\n" "vld1.64 {q9}, [r0]!\n" "vld1.64 {q10}, [r0]!\n" "vld1.64 {q11}, [r0]!\n" "vld1.64 {q12}, [r0]!\n" "vld1.64 {q13}, [r0]!\n" "vld1.64 {q14}, [r0]!\n" "vld1.64 {q15}, [r0]!\n" : : [ptr] "r" (data) : "r0", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory"); #endif #endif /* CLUTTER_VECTOR_REGISTER_COUNT */ } 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" }, #if USE_DES { 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" } #endif /* USE_DES */ }; 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 ((err = gcry_cipher_test_algo (tv[i].algo))) { if (in_fips_mode && tv[i].algo != GCRY_CIPHER_AES) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); } else fail ("cbc-mac algo %d, gcry_cipher_test_algo failed: %s\n", tv[i].algo, gpg_strerror (err)); continue; } else if (in_fips_mode && tv[i].algo != GCRY_CIPHER_AES) { fail ("cbc-mac algo %d, gcry_cipher_test_algo did not fail as expected 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_ecb_cipher (void) { /* ECB cipher check. Mainly for testing underlying block cipher. */ static const struct tv { int algo; const char *key; int is_weak_key; int flags; struct { const char *plaintext; int keylen; int inlen; const char *out; } data[MAX_DATA_LEN]; } tv[] = { #if USE_BLOWFISH /* Test vectors from OpenSSL for key lengths of 8 to 200 bits */ { GCRY_CIPHER_BLOWFISH, "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f" "\x00\x11\x22\x33\x44\x55\x66\x77\x88", 0, FLAG_NOFIPS, { { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 1, 8, "\xf9\xad\x59\x7c\x49\xdb\x00\x5e" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 2, 8, "\xe9\x1d\x21\xc1\xd9\x61\xa6\xd6" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 3, 8, "\xe9\xc2\xb7\x0a\x1b\xc6\x5c\xf3" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 4, 8, "\xbe\x1e\x63\x94\x08\x64\x0f\x05" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 5, 8, "\xb3\x9e\x44\x48\x1b\xdb\x1e\x6e" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 6, 8, "\x94\x57\xaa\x83\xb1\x92\x8c\x0d" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 7, 8, "\x8b\xb7\x70\x32\xf9\x60\x62\x9d" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 8, 8, "\xe8\x7a\x24\x4e\x2c\xc8\x5e\x82" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 9, 8, "\x15\x75\x0e\x7a\x4f\x4e\xc5\x77" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 10, 8, "\x12\x2b\xa7\x0b\x3a\xb6\x4a\xe0" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 11, 8, "\x3a\x83\x3c\x9a\xff\xc5\x37\xf6" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 12, 8, "\x94\x09\xda\x87\xa9\x0f\x6b\xf2" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 13, 8, "\x88\x4f\x80\x62\x50\x60\xb8\xb4" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 14, 8, "\x1f\x85\x03\x1c\x19\xe1\x19\x68" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 15, 8, "\x79\xd9\x37\x3a\x71\x4c\xa3\x4f" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 16, 8, "\x93\x14\x28\x87\xee\x3b\xe1\x5c" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 17, 8, "\x03\x42\x9e\x83\x8c\xe2\xd1\x4b" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 18, 8, "\xa4\x29\x9e\x27\x46\x9f\xf6\x7b" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 19, 8, "\xaf\xd5\xae\xd1\xc1\xbc\x96\xa8" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 20, 8, "\x10\x85\x1c\x0e\x38\x58\xda\x9f" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 21, 8, "\xe6\xf5\x1e\xd7\x9b\x9d\xb2\x1f" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 22, 8, "\x64\xa6\xe1\x4a\xfd\x36\xb4\x6f" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 23, 8, "\x80\xc7\xd7\xd4\x5a\x54\x79\xad" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 24, 8, "\x05\x04\x4b\x62\xfa\x52\xd0\x80" }, { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 0, /* test default key length of 128-bits */ 8, "\x93\x14\x28\x87\xee\x3b\xe1\x5c" }, { } } }, /* Test vector from Linux kernel for key length of 448 bits */ { GCRY_CIPHER_BLOWFISH, "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f" "\x00\x11\x22\x33\x44\x55\x66\x77\x04\x68\x91\x04\xc2\xfd\x3b\x2f" "\x58\x40\x23\x64\x1a\xba\x61\x76\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e" "\xff\xff\xff\xff\xff\xff\xff\xff", 0, FLAG_NOFIPS, { { "\xfe\xdc\xba\x98\x76\x54\x32\x10", 56, 8, "\xc0\x45\x04\x01\x2e\x4e\x1f\x53" }, { } } }, #endif /* USE_BLOWFISH */ #if USE_DES /* Weak-key testing */ { GCRY_CIPHER_DES, "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe", 1, FLAG_NOFIPS, { { "\x00\x00\x00\x00\x00\x00\x00\x00", 8, 8, "\xca\xaa\xaf\x4d\xea\xf1\xdb\xae" }, { } } }, /* Weak-key testing */ { GCRY_CIPHER_DES, "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe", 2, FLAG_NOFIPS, { { "\x00\x00\x00\x00\x00\x00\x00\x00", 8, 8, "\xca\xaa\xaf\x4d\xea\xf1\xdb\xae" }, { } } }, #endif /* USE_DES */ #if USE_SM4 { GCRY_CIPHER_SM4, "\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10", 0, FLAG_NOFIPS, { { "\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd" "\xee\xee\xee\xee\xff\xff\xff\xff\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb", 16, 32, "\x5e\xc8\x14\x3d\xe5\x09\xcf\xf7\xb5\x17\x9f\x8f\x47\x4b\x86\x19" "\x2f\x1d\x30\x5a\x7f\xb1\x7d\xf9\x85\xf8\x1c\x84\x82\x19\x23\x04" }, { } } }, { GCRY_CIPHER_SM4, "\xfe\xdc\xba\x98\x76\x54\x32\x10\x01\x23\x45\x67\x89\xab\xcd\xef", 0, FLAG_NOFIPS, { { "\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd" "\xee\xee\xee\xee\xff\xff\xff\xff\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb", 16, 32, "\xc5\x87\x68\x97\xe4\xa5\x9b\xbb\xa7\x2a\x10\xc8\x38\x72\x24\x5b" "\x12\xdd\x90\xbc\x2d\x20\x06\x92\xb5\x29\xa4\x15\x5a\xc9\xe6\x00" }, { } } }, #endif /* USE_SM4 */ }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; int i, j, keylen, algo; gcry_error_t err = 0; gcry_error_t err2 = 0; if (verbose) fprintf (stderr, " Starting ECB checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { algo = tv[i].algo; if ((err = gcry_cipher_test_algo (algo))) { if (in_fips_mode && (tv[0].flags & FLAG_NOFIPS)) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algo); } else fail ("algorithm %d, gcry_cipher_test_algo unexpectedly failed: %s\n", algo, gpg_strerror (err)); continue; } else if (in_fips_mode && (tv[i].flags & FLAG_NOFIPS)) { fail ("algorithm %d, gcry_cipher_test_algo did not fail as expected\n", algo); continue; } if (verbose) fprintf (stderr, " checking ECB mode for %s [%i]\n", gcry_cipher_algo_name (algo), algo); err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_ECB, 0); if (!err) err2 = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_ECB, 0); if (err || err2) { fail ("ecb-algo:%d-tv:%d, gcry_cipher_open failed: %s\n", algo, i, gpg_strerror (err ? err : err2)); if (err2) gcry_cipher_close (hde); return; } if (tv[i].is_weak_key == 2) { err = gcry_cipher_ctl(hde, GCRYCTL_SET_ALLOW_WEAK_KEY, NULL, 1); if (!err) err = gcry_cipher_ctl(hdd, GCRYCTL_SET_ALLOW_WEAK_KEY, NULL, 1); if (err) { fail ("ecb-algo:%d-tv:%d, gcry_cipher_ctl failed: %s\n", algo, i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } for (j = 0; tv[i].data[j].inlen; j++) { keylen = tv[i].data[j].keylen; if (!keylen) { keylen = gcry_cipher_get_algo_keylen(algo); if (!keylen) { fail ("ecb-algo:%d-tv:%d-data:%d, gcry_cipher_get_algo_keylen failed\n", algo, i, j); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err || (gcry_err_code(err) == GPG_ERR_WEAK_KEY && tv[i].is_weak_key == 2)) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (tv[i].is_weak_key == 1) { if (gcry_err_code(err) != GPG_ERR_WEAK_KEY) { fail ("ecb-algo:%d-tv:%d-data:%d, expected gcry_cipher_setkey to fail, but got: %s\n", algo, i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } else { continue; } } else if (tv[i].is_weak_key == 2) { if (gcry_err_code(err) != GPG_ERR_WEAK_KEY) { fail ("ecb-algo:%d-tv:%d-data:%d, expected gcry_cipher_setkey to fail, but got: %s\n", algo, i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } else if (err) { fail ("ecb-algo:%d-tv:%d-data:%d, gcry_cipher_setkey failed: %s\n", algo, i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].data[j].plaintext, tv[i].data[j].inlen); if (err) { fail ("ecb-algo:%d-tv:%d-data:%d, gcry_cipher_encrypt failed: %s\n", algo, 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 ("ecb-algo:%d-tv:%d-data:%d, encrypt mismatch entry\n", algo, i, j); } err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0); if (err) { fail ("ecb-algo:%d-tv:%d-data:%d, gcry_cipher_decrypt failed: %s\n", algo, 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 ("ecb-algo:%d-tv:%d-data:%d, decrypt mismatch entry\n", algo, i, j); } } gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed ECB checks.\n"); } static void check_ctr_cipher (void) { static const struct tv { int algo; int flags; char key[MAX_DATA_LEN]; char ctr[MAX_DATA_LEN]; struct data { const char *plaintext; int inlen; const char *out; } data[8]; } 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", "\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, 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", "\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, 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", "\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, 0, "\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, 0, "\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, 0, "\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, 0, "\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, 0, "\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, 0, "\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, "" } } }, /* Tests for counter overflow across 32-bit, 64-bit, 96-bit and 128-bit * boundaries. Large buffer sizes are used to allow these vectors to be * passed down to bulk CTR functions. */ { GCRY_CIPHER_AES, 0, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xfa", { { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32 * 16, "\x74\x54\x1d\x36\x3b\x1f\x40\xb7\x96\xec\x54\xdf\x37\xe1\xd1\x38" "\xfe\xdf\x13\x08\xdc\xf4\xc6\xeb\x10\xff\x0c\xc9\x2a\x1d\xd0\xb2" "\x38\xdd\xa8\x86\xbb\x58\x72\x2a\xd1\x3a\x4b\x74\x99\x98\x1c\xf9" "\xf5\xe7\x71\x0d\xcc\x44\x40\x76\x26\xe2\xe9\xa5\x3b\xe7\xee\x63" "\x0b\x30\x76\x75\x21\x14\xf7\xd0\xec\x5b\x82\x83\x03\x66\x68\xd1" "\x57\x94\x1f\xf3\x41\x58\x81\xa0\xb2\xa7\x91\x7a\xc5\xfa\x33\xb8" "\x42\x6c\x76\x8f\xaa\x41\x0b\x72\xab\x10\x39\x51\x25\x9b\xa1\x4a" "\xd4\x82\x67\x74\xd1\x18\xc5\x35\x1a\xa4\x81\x13\x69\x0c\x39\x73" "\xba\xd5\xaf\x63\xcd\xe9\xca\x2e\x4e\x44\x44\xfc\x23\xa5\x0e\x24" "\xdc\xb7\x69\x3b\xf7\x57\x07\xd7\xbe\xd0\x19\xca\x2a\xd2\xa5\x32" "\x49\xa3\xb6\xd7\x3f\x02\xbc\xbb\x41\x63\x4a\xc5\x8f\x5c\x51\x0a" "\x59\x16\x2f\x9a\xd7\x58\x88\x1b\x51\x46\xe6\xe3\x37\xd6\x36\xbb" "\x1e\xc9\x89\x8f\xd0\x8d\xa8\x77\xa2\xee\xfc\x4c\x65\xc2\x8a\x3c" "\xf4\xad\x0d\x6b\x80\x04\x32\xc9\x39\x9e\x24\xd9\x99\xf7\x26\x93" "\xe3\x8f\x97\x38\xb6\x2e\xa6\xf1\xe3\x8a\x7c\xfe\x4f\xed\xfe\xcb" "\xff\x4e\x4a\x7a\x34\xc3\x1a\x92\x7c\x35\xdd\xd4\xc0\xf3\x1c\x51" "\x4c\x52\x08\xe3\x78\xa3\x6a\x6b\x98\x40\xae\x3c\xf9\xcb\xa3\x85" "\x0d\xbf\xdb\xf0\x6e\x53\xb2\xcc\xf7\x77\x37\xa9\x33\x1a\x1c\xed" "\x26\x3f\x79\x30\x3f\x82\x9c\x3f\xd8\x72\x98\x17\x4b\x57\xa9\xd1" "\xbd\x74\xa7\xab\x18\x85\xc6\x4c\x5a\x29\x9a\x41\xad\xae\x52\x87" "\x8d\x72\x77\xfe\x91\xd9\x1f\xca\x02\x1e\x30\xa5\x4c\x8f\x74\xd6" "\x71\xeb\x4d\xd9\x63\xaa\x90\xbf\x08\xa0\x38\x3c\x98\x46\x7a\x82" "\xfd\x0d\xb3\x78\xbf\xf5\xcd\x25\xfb\x05\x4d\x39\x9c\x53\x35\xb4" "\x34\x1b\x4b\x44\xf8\xfb\xb0\xf4\x56\xaa\xbd\x16\xba\xd1\x2b\x8d" "\x62\x4b\x56\x70\x91\x1a\x77\x0f\x2b\x6a\x0e\xf4\x4b\x83\x8f\x89" "\xa3\xe1\x5d\x3d\x0b\x1e\xb2\x43\xc6\x36\x98\x7a\xd7\xd4\x00\x09" "\xa1\x09\x0b\x49\xa2\x72\xeb\x24\x16\x70\x15\x21\x82\x17\x48\x11" "\x81\x93\xc9\x5a\x86\x2f\xd2\x96\x42\xb4\xb4\x08\x81\x85\xe5\x76" "\xa6\xc5\x10\x15\xfe\x4e\x84\x00\x64\xb5\xeb\x92\x22\x40\x97\xbb" "\xcf\xab\xc2\xf1\xbf\x44\xee\xb7\x7a\xaa\xe2\x5d\x1b\xa4\xeb\x3d" "\x65\x5b\x84\xd8\xf4\xb6\x04\xf8\x62\xe3\x6b\xd9\xc6\xf3\x99\x89" "\x11\xa0\xd4\x3f\x64\x4d\xfd\xac\x17\x80\x8e\x0d\x96\x2f\x4d\x69" }, { "", 0, "" } } }, { GCRY_CIPHER_AES, 0, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", "\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xfa", { { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32 * 16, "\xe3\x4c\xbe\xd8\xfd\x49\x8d\x84\xfc\x35\xe1\x1c\x56\x88\x6a\xf3" "\x78\x22\x42\x79\xa5\xd5\x74\xb9\x19\xc3\x1b\x9a\x2e\x18\x57\xcc" "\x27\x91\x03\xa2\x5d\xb8\xf7\xb7\x3a\xe2\x32\x4a\x77\x4c\x9c\xf7" "\xfc\x54\xa5\x75\xec\xff\x99\x59\x73\x66\xf8\xd7\xe7\x46\xf9\xba" "\x36\xcb\xe8\xa7\x19\xcf\xc8\x0c\x71\xb2\x8f\x97\xa7\xbd\xbd\x05" "\x39\xa7\xef\x0a\x0a\x58\x52\xa8\xbf\xd2\x03\x23\x44\xbf\x94\x12" "\x13\x18\x9a\x6a\xe4\xab\x07\xae\x70\xa3\xaa\xbd\x30\xbe\x99\xde" "\x8f\x94\x29\x44\x4c\x8f\x4b\x35\x99\x42\x12\x35\xb5\x10\xdf\x3d" "\x94\x54\x46\x34\x1c\x6f\x59\x71\xfe\x0e\xb6\x62\xb1\xfb\x99\x50" "\xdd\xa6\x6f\x25\x1c\xfd\xb9\xdc\x9f\xce\xf7\xc9\x33\xba\x82\x8a" "\xb8\x82\xd4\xbc\x28\x56\xf6\x42\x71\x85\x7a\x6a\xb1\xcc\xa0\xa1" "\xa5\xe6\x36\xee\x73\xd7\x1c\x6c\xa0\x6c\xe2\x15\xa5\x82\x69\x46" "\x2d\x94\x7b\xb1\xc1\x5f\xbb\x96\x03\xb1\x33\x27\x8f\xe1\xc3\x7a" "\x62\x78\xad\x78\x11\x49\x93\x73\xce\xa1\xd8\xc5\x59\xe3\x54\x79" "\xca\xaf\xc9\xe2\xde\x11\x83\x6d\x66\x39\xe1\x06\xa7\x41\x74\xe9" "\x24\x54\xa5\x5b\x1c\x07\xdd\x2d\xf5\xc0\x27\xdc\x7e\x1d\xfa\x44" "\x21\xd3\xe9\x4c\x3a\x2a\xb7\xbe\x4f\x37\x9f\xbe\x3d\x1a\x41\x6f" "\xba\x4d\x0a\x72\xb2\x18\x83\x75\x17\x87\xf9\x22\x8a\x7c\x9d\x2a" "\x8b\xc8\xda\xde\xda\xa0\xda\x56\x60\x02\x11\x4b\xca\xe0\x4f\xa4" "\xbd\x71\x9a\x85\x7c\xd3\xf7\xbb\xc3\x4e\x10\x7d\x14\xbb\xa5\x10" "\x10\xea\x35\x59\xe3\x17\x0a\x8d\x6e\x22\xe4\xc2\x83\x3f\x60\x6a" "\x53\x19\xf2\xfa\xd8\x86\x5d\x44\xc3\xef\xd9\x2a\x0a\x71\xe0\x46" "\xee\xa5\xad\xd2\xba\x80\x7d\xb1\x35\x3f\xe7\x4f\x24\xe1\x6a\x6b" "\xe1\xc9\xe0\xc9\x2a\x27\x27\xa9\x63\x15\x1c\x01\xb1\x06\xaa\xca" "\x20\x15\xe5\xa9\xba\xab\xbf\xa9\x06\x02\xac\x09\x2a\x55\x8d\xc6" "\x22\x93\xfd\x50\x2f\xac\x02\x97\x0d\xea\xfc\xa0\x5a\x1a\x30\x9c" "\xf7\x77\x91\x46\xea\x5a\x94\x79\x5e\xad\xff\x91\x58\x6a\xed\x3f" "\xba\x48\xa9\x3b\xd7\xff\x63\x39\x1e\x67\x8e\x23\xe8\xe3\x62\x45" "\x08\xe0\xea\x64\xa2\x6a\x3d\x6c\xdf\x30\x0d\x00\xa1\x88\x13\x2b" "\x57\x30\x3e\xea\x6b\xb2\x57\xfb\x16\x65\xf1\x26\x81\x7c\xbf\xb6" "\x53\x90\xff\x75\xcb\x3e\xb5\x97\x1d\x52\xbe\x67\x58\xbe\x50\x45" "\x69\x3a\x29\x52\x1e\xb6\xb4\x70\x82\xb8\x1a\x0d\x6f\x3b\xbe\x14" }, { "", 0, "" } } }, { GCRY_CIPHER_AES, 0, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", "\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa", { { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32 * 16, "\xf1\x51\x2c\xa5\xd9\x8a\xeb\xa2\xa9\xfc\xe2\x24\x73\x69\xaa\x7d" "\x1d\xae\xbf\xca\xae\xed\xf9\x2c\x97\x03\xa3\xef\x3f\x7c\xec\xeb" "\x45\x69\x4a\x66\x9b\xde\xbf\x46\x01\x28\xf1\xde\xed\xb2\xa4\x7e" "\xa3\x52\xe1\x85\x9c\x6b\xcf\x6b\x42\xba\xce\x02\x1c\xee\x35\x6a" "\xfa\x18\x46\xf0\x90\xc9\x80\x1a\xc6\xbe\x02\x65\xf1\x77\xe8\xcf" "\x5a\x4b\x94\xa8\x55\xcc\x21\x39\xe3\xae\xb7\x2a\xcc\x8d\xc7\x9f" "\x95\x03\xe3\xa2\x24\x5a\x2b\xe4\x3c\x98\x74\xed\xfe\x1b\xed\x9e" "\xfe\x1a\x92\xed\x86\xf1\x06\x6a\xf9\x79\x48\x5c\xd2\x5a\x98\x47" "\x63\x81\xfd\xfc\x9a\xef\xaf\xea\x3a\xff\x5c\xd8\xd7\xab\xef\x8c" "\x88\x91\x34\x5a\x2c\x05\x6a\xf2\x2e\xf6\xd0\x01\x59\x35\x28\x95" "\x61\x3a\x1a\x31\xb3\x64\xc4\x8c\xa3\x5d\xe0\xf9\x09\xed\x58\x47" "\xa0\x85\xe1\x06\x0b\xc0\xc0\x1e\x7f\x3f\x5e\x56\x71\x17\x8b\xa0" "\x95\x8f\x3d\x29\x16\x89\xd1\xfb\xe9\x49\xa5\x7d\xea\xe8\x50\xc1" "\x95\x2d\xbd\x6d\x80\x0c\x74\x8d\x6c\xcd\xc2\x75\x94\x40\xb7\x24" "\xf3\xf8\xe4\xf2\x1c\xeb\x1b\x58\x0c\x1a\x06\x0a\xad\x48\x4f\x13" "\x12\x94\x7a\xa0\x03\xa2\x4b\x0f\xbc\xd7\xd4\xa0\x8d\x45\xab\xf1" "\xd9\x1b\x1d\x1a\xa7\x9e\x5f\xe3\x07\xfd\xd4\xad\xa9\xf3\x95\xaa" "\x47\xf8\x25\x2e\xca\x60\x7c\x14\x35\x8e\xb6\x23\x15\xe4\x96\x3c" "\xdf\xb6\x86\xd8\x87\xe0\xf1\x7e\x04\x2a\xc2\xb7\x39\x74\x10\x52" "\x18\xe7\x2d\x63\xe2\x40\xe4\xfd\xe8\x1a\xee\xb9\xdf\xe2\xf5\xcb" "\x2d\x2d\x8f\x71\x38\x9e\x8a\x8b\xc9\xb3\xf8\xb0\x25\xaa\xb9\xf2" "\x08\x7c\xa2\x6b\x16\x75\x65\x98\x7c\x72\x7c\x86\x7f\xba\xe3\x2b" "\x68\x6e\x37\xf9\x4c\x17\xf3\xfe\xc8\xc5\xf7\x38\xfb\xe2\x33\xfd" "\x62\xb8\x59\x46\x65\xf6\xc3\x06\x56\x02\xb3\x93\x17\x37\xd6\x3e" "\x2d\x47\x96\x3e\xd8\x01\x97\x3a\x29\x5a\x39\x17\x58\xcb\x6b\x2e" "\xf4\x6a\xeb\x4c\xb1\xff\xde\xc6\x86\x9e\x7a\x2f\xe9\x63\x4e\x99" "\x58\x0d\xb3\x33\x38\x4c\xd0\xe6\x0f\x1b\x88\xe0\x87\x29\xf1\x4c" "\x25\x6a\x18\x62\x93\x58\xf1\x7e\xf9\xbf\x38\x1a\x7b\x41\xf3\xa7" "\xee\x39\x07\x4a\x1e\xf9\x57\x16\x41\x38\xe1\xc5\xce\x4c\x8c\xae" "\xf9\x74\xc2\x40\x76\x84\xa0\x86\xec\xd3\xe3\xd6\xcc\x64\xc8\x8a" "\x67\x06\x75\x54\x89\x32\xf2\x6e\xee\x96\x84\x38\xbd\xf3\xd7\xd7" "\x8a\x83\x7e\xee\x9d\xb5\xcf\xb6\x91\x0b\x98\xb5\xbf\xc0\x1d\x60" }, { "", 0, "" } } }, { GCRY_CIPHER_AES, 0, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xfa", { { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32 * 16, "\x72\x93\xe9\x78\x6b\xd1\x11\x41\xd8\x52\x32\x0c\x8b\x5f\xc3\x93" "\x0a\xae\x0e\xdc\x96\x0a\xa5\x0a\x5b\x95\x7c\xc6\xad\x30\xd0\x98" "\xea\xd3\x71\xe6\x4b\x1b\x3e\xb6\xd0\xfb\x94\x23\x6b\x54\x40\xff" "\xf1\xc2\x60\xb3\x2d\x20\xf9\xae\xfb\x32\x86\xf8\xc2\x05\xa7\x12" "\x96\xe0\x3e\x48\x73\x56\x58\xc2\xa3\x99\x9e\xa2\xb4\x6f\xa9\x7a" "\x32\x6e\xe7\xf6\xb8\x1c\x58\x2f\x55\xc6\xcd\xb5\xe5\xd2\x2f\xc8" "\xff\x05\x59\x37\x75\x6c\xad\xce\x69\x74\xed\x4b\x8c\x98\x7d\xae" "\xc2\x81\x9b\x7a\x46\x14\x73\x72\x34\x85\x15\x64\x96\xed\xb8\xb9" "\xf1\xce\x2d\xd4\x8b\x7e\xd1\x81\xd5\x91\x9c\x10\x37\xe9\x98\x4d" "\xeb\x5d\x8a\x78\xf3\x85\x6f\xc0\xb0\x85\x0b\x75\xf6\x07\xa0\x11" "\xd2\x8e\x7b\x63\x23\xba\xdc\xc0\xec\x4d\xac\xeb\xde\x41\x29\x66" "\x6c\x5a\x9e\x88\x69\xba\x33\xb3\x3d\x5f\x78\xb3\x36\x8b\x2d\xf3" "\x37\x7e\x13\xe6\x93\x3e\xce\x00\xcf\x12\x47\x64\x55\xfe\xbd\xb6" "\xa6\xd9\x41\x50\x0a\x42\x1f\xfd\xc7\xea\x6c\xc3\xac\x0f\x3d\x91" "\xe5\xa1\x95\x5b\x4e\x24\xe5\x34\x1e\x03\x10\x3f\x9d\xa0\x89\x74" "\xea\x26\x5c\x23\x1b\x5b\x8b\x08\x49\xce\xd8\xa8\x10\xf3\x88\x37" "\x38\xc2\x9d\xba\x75\x2b\x5e\xec\xf1\xf1\x3c\x90\xab\xae\x88\xe2" "\x49\xf9\xb8\xad\x7b\x8e\x30\x96\xaf\x48\xec\x37\x11\x52\xef\x49" "\xea\xcb\x97\x16\x13\x7b\xf4\x03\x50\x61\x6a\xd4\x09\xfd\x66\x1d" "\x56\x13\x48\x9b\xe3\x5d\xfe\x60\x47\x0a\x62\xfd\xae\xbc\x15\xc2" "\x0f\xbd\xc0\xb8\x70\x4d\x89\x2d\x4e\xa5\x7b\x36\xfc\xda\xdc\xc3" "\x47\x45\x8e\x86\xa8\xa6\xd3\x51\x0e\xaa\x90\x30\xef\x02\x53\x04" "\x89\x92\xcc\x36\x33\x00\x9f\xdc\xa3\x7d\xbf\x0d\x10\x4f\x50\xe7" "\x84\x72\xfa\x76\x57\xa6\xbd\x65\x8f\xc7\x04\xef\x03\xaf\xff\xf0" "\x8c\x6f\x98\x58\xac\x95\xe7\x7e\xeb\x4d\x24\xfb\x37\xbc\x9b\x19" "\x1a\x48\x2b\x86\xe4\x21\x24\xf5\x1a\xb1\x8a\xcb\x0d\x14\x6e\x4e" "\x3d\x39\xed\x95\x73\xeb\xaa\x31\x56\xbe\x4d\x32\x02\x15\xf1\x24" "\x9f\x23\xa6\xd8\xf4\x52\x4b\xfd\x9c\xc0\x45\x5c\xc4\xb0\xae\x4b" "\x39\xca\x17\x7a\xfb\xc0\xdb\x8c\x92\x52\xd4\x37\x93\x29\x7c\x2e" "\x77\xcd\x8d\x2a\xbd\x6e\x4d\x23\xe2\xff\x84\xa5\x1a\x2a\xd2\x4a" "\x19\xd7\xef\x1d\xea\xcf\x79\x8f\x81\x48\x2d\x5d\x72\x58\x99\x11" "\xec\x95\xda\x65\x73\x35\x34\xb1\x28\x10\x07\x94\xe8\xc1\x1e\x17" }, { "", 0, "" } } }, { GCRY_CIPHER_AES256, 0, "\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", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xfa", { { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32 * 16, "\x0c\x39\xef\x9d\x9b\x85\x05\x78\x93\x92\x13\xc4\xe9\xc7\x0b\x12" "\x36\x73\x18\xfa\x58\x33\x09\x7f\xf4\xd2\xf8\x93\x46\x5a\xd0\xdd" "\x8d\x48\x2e\x6b\xb1\xf9\x9b\xc2\x0c\x66\x88\x48\x93\xaf\x0d\xac" "\x47\x3f\xbb\x84\xc5\xf8\x8d\xc1\x7c\xfe\xb8\xb9\x9f\xcc\x86\x3c" "\xfd\x9f\xa3\xf9\x2c\x22\xeb\xa1\x9a\x68\x6b\xb9\x24\xf6\xe6\x74" "\xb9\xc2\x73\x98\x10\xcb\xa1\x57\xa9\xfe\x6a\x10\x8c\x6e\x56\x9e" "\x64\x1d\x1a\x3a\x80\xbe\xcf\xf6\xf0\xf3\x8f\x97\x64\xfd\xcf\x96" "\x36\x7e\xf8\x28\x88\x31\x55\x74\x08\xe1\x02\x95\x0a\x16\xe2\x6a" "\x15\xd6\xbf\xfc\x44\xf4\x30\x1e\x0e\x2e\x51\x39\xec\xa6\x3a\xf7" "\x15\x9f\x1c\x54\x64\xb2\x54\x84\x73\x00\x03\xd9\x26\x30\x73\x5e" "\x3a\x96\x67\xf1\x28\x2c\x84\x3c\x59\xdf\xc3\x01\x6c\xe4\x07\x33" "\x2e\x16\x53\x92\xfd\xee\x1d\x47\xbe\x15\x1d\x65\x58\xb5\x9b\x08" "\x04\x71\x65\xfa\x11\x49\x9d\xc6\xca\xab\x34\xb1\x40\x39\x98\xe9" "\xd4\xa5\xda\x17\x74\x5e\x80\x18\xc3\xf9\xcd\x60\x34\x5c\x68\x09" "\x4c\xf7\xa1\x3a\x5c\xdb\xf6\xc5\x06\xe2\x70\x98\x3b\xea\x0f\x77" "\x43\x1a\x0b\x4f\x74\x54\xe8\x7c\xd6\xb2\x02\xcc\xc9\x11\x49\x65" "\x4c\xb2\x2b\x5a\x39\x13\xdb\xcf\x07\x77\x27\x69\x90\xa9\xe6\x7a" "\xd2\xa0\x3e\xd9\xa8\x4c\x6b\x8d\x2f\x39\x10\x67\xea\x4c\x10\xc7" "\xac\x70\xf9\x50\x1d\xe7\xfd\x88\x66\xf1\xed\x36\x5c\xa1\x5f\x92" "\xf6\xcb\xd2\xe1\xb0\x9d\x55\x45\xe4\x62\x3d\xec\x11\x33\x6e\x3e" "\x7f\x87\x06\x1b\x4c\x71\xf0\xe5\x0f\xed\xde\xa0\x47\x85\x59\xa5" "\xf4\x03\xde\x25\x8c\x23\x42\x47\x94\x1b\xa5\xbb\x2e\x09\x54\xe2" "\xf8\x75\x29\xb6\xa6\x3b\x86\x1d\xa0\x4d\xbc\x5c\x49\xf1\x38\x3f" "\x23\x12\x63\x98\x26\xa7\x7a\xe6\x48\x0a\x14\x1a\xcc\xd6\xf0\xc7" "\xd8\x69\x1e\x39\x0a\xf5\x79\xed\x82\x79\x43\x54\x65\x15\x90\x44" "\xb8\xcf\x52\x51\x7a\x9a\x32\x16\x2a\x36\xcb\x9c\xde\x48\x10\xdc" "\x97\x70\x72\xc8\x83\x0f\x66\xaf\x95\x59\xfb\xca\x06\x46\x6f\x8e" "\x49\xbd\x72\xcd\x8b\xa3\x69\xaa\xde\xc3\xaa\xf0\x4e\x65\x7c\x8b" "\x93\xa7\xa9\x85\xdb\xf9\x7d\xdf\x6a\x52\xda\xcf\x42\xb8\x9c\x17" "\x6c\xc4\xa1\x5e\x5c\x69\x76\x5d\x26\x95\x1e\x13\xdc\xa3\x57\x7a" "\xb7\x8a\x4c\xb8\x88\xaa\x74\x78\xbb\xd3\xee\xfd\xc3\xa4\xa9\xf1" "\x6b\x34\x1a\x79\x67\x9c\xb1\xfd\xd4\xd9\x8b\xf4\x28\xfe\xff\xc1" }, { "", 0, "" } } }, { GCRY_CIPHER_AES256, 0, "\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", "\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xfa", { { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32 * 16, "\x16\x2e\x03\x23\x3e\xa6\x2e\xd7\x51\xf9\x56\xfc\x19\xea\x01\xfe" "\x81\x26\x0e\xb3\x01\x39\xa7\xb7\x06\xda\x7c\x85\xbd\xed\x14\x3f" "\x1c\x01\xf4\x55\x76\x7d\xa7\x22\x15\xb4\xd8\x4d\x1d\x2c\x59\x6b" "\x52\x00\x85\x00\x35\xc4\x5a\x90\x9e\xb6\xc0\x6d\x61\xca\x6d\x1f" "\xed\xbd\x96\x2b\xd9\x87\xbc\xfd\xf6\x1d\xd6\x3c\xa8\x2d\x92\xb9" "\xa6\xfb\xdb\x5c\xfd\xe0\x7d\x1b\x58\xfd\x36\x21\x77\xbc\xff\xdf" "\x51\x1d\xd5\xef\x9a\x68\x2b\x7d\xa4\x9f\x91\xc8\x6c\x4f\x7a\xc3" "\x40\xc5\x3c\xef\x92\xef\x2d\x64\x3f\x63\x8b\x82\x22\xdb\x1e\x85" "\x31\x0b\x64\x7d\x31\x9d\xdc\x92\xe4\x53\x9e\x9b\xbe\x37\x07\x8d" "\xeb\xe3\xae\xfb\xff\xe3\xba\xcc\xa3\x4f\x42\x54\x3e\xbb\x9f\xb6" "\xa8\xf3\x6e\x76\x9a\x45\xa0\xf1\xbc\x19\x34\x26\xab\xad\x8c\x60" "\x3b\x9b\x31\x7f\xb5\xf1\xbb\x8c\xbc\x71\x43\xcb\xb8\xc6\xfb\xe6" "\x9c\x9b\xf0\x3f\x66\x65\xc2\xd9\x1a\x13\xd8\xea\x53\xa7\x24\xb9" "\xf8\x98\xce\x2c\xc8\xee\xe7\x18\x29\x91\xdf\x6e\x27\x1d\xc2\x46" "\xc2\x66\x3f\x2b\xcc\xbb\x57\xd8\xb9\x5c\xbe\xf3\x88\x4e\xa9\x99" "\x95\x50\x22\xa5\xbe\x51\xe4\x37\x1a\xfa\x20\x61\x25\x2c\x7c\xac" "\x42\x0e\xdb\xbd\x0f\x3c\x1a\x4f\xda\x57\x52\x61\x3a\x5a\x1e\x35" "\x1f\x6d\xb7\x26\x61\x5e\xa9\x23\xc3\x56\x47\xe9\xb1\xb8\x70\x1d" "\x0f\x67\xfd\x7e\x88\x15\xe2\x16\xd7\xdd\x32\x9f\x81\xfe\xe5\x97" "\x05\x19\x93\xc5\xd0\x88\x32\x62\x60\x82\xc7\xb8\x65\xa5\x75\x4c" "\xaf\x1e\x44\x0f\x03\x24\x09\xe2\x91\x87\xbd\xf8\xd1\x1f\x37\x77" "\x7e\xe3\xa8\xdb\x23\x8b\x49\xa1\x4b\xa7\xe6\x30\x36\x01\xcc\x69" "\xb4\x4a\x20\x20\x23\xdb\xcc\xcd\x57\x44\xd3\xfd\x88\xf8\xbe\x90" "\x08\xb3\xed\x2d\x6c\x7b\x3d\x3d\xaf\xc6\xf4\xe6\x2d\x31\x7f\xfc" "\x84\xc2\x4e\xa6\x04\xda\x96\x3a\x95\xf7\x7b\x31\x0c\x25\x1f\x0e" "\x9e\xbe\xf4\x78\xc1\xcb\x3a\x6d\xab\x60\x5d\xe5\x56\x1d\x4c\x1c" "\xed\xff\x40\x38\xed\xea\x89\x40\x46\x49\x47\x0a\x52\x93\x7a\x71" "\x0a\xba\x8d\x12\xbe\x8f\x0b\xc6\x31\x9f\x2d\x8a\x42\x66\x06\x66" "\x34\x93\xf0\x58\x1c\x9c\xc6\x41\xfc\x5e\x46\x2c\x7d\x85\x22\x82" "\x28\x03\x80\x89\xfc\x05\x8e\x18\x01\x85\x38\xe5\x6a\x90\xd9\x28" "\x0a\x25\xd2\xf7\xb5\x6d\x07\x21\x94\x11\x6f\xc1\xef\x9a\x89\xd9" "\x02\xce\xc6\x97\x43\x29\x9a\x1f\xfd\x29\x61\x04\xe2\x64\xf2\xca" }, { "", 0, "" } } }, { GCRY_CIPHER_AES256, 0, "\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", "\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa", { { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32 * 16, "\xc8\x1a\x9c\x1e\xa9\x44\x9f\x3f\x3a\xf2\x34\x91\x8e\x41\x14\xea" "\xec\x88\x5e\xd0\x8c\x19\xe9\xa8\xef\x33\x0f\x43\xd8\x17\xe7\x02" "\x15\xed\xfe\x3b\xbc\x97\xcc\x1d\x61\xb0\x64\xa1\x87\x6f\x72\x0c" "\xed\x60\x0d\x75\x77\x12\x38\xb6\x2b\x31\xaf\x5a\x5e\x06\x2e\x85" "\x01\x75\x99\x06\xf8\x94\xf0\xb5\xb6\xe9\x78\xe4\x51\x6c\x42\x8b" "\x1f\xe1\x38\x68\xb5\x87\x1c\xa5\x5d\x2a\x84\xaa\xa4\xbf\x06\x8c" "\x9d\xba\x41\xa7\x77\xf3\xb4\x6a\x37\xb7\xaa\xae\x49\xd6\xdf\x8d" "\x19\x7b\x1d\x24\xed\x7a\xcc\x26\x78\x85\x9d\xf9\x22\xc3\xb5\xcb" "\x44\x36\xcd\xaa\x0c\x5a\xf4\xa8\x5f\x3c\x65\x90\xa9\xbd\x35\x80" "\x67\x3f\xc9\xc0\xde\xf4\x3c\x0e\xb1\x9c\x80\x96\x0e\x6d\x3e\xd0" "\xfc\xd6\x8a\x65\xc1\xe5\x2d\x96\x23\x5b\x08\x37\xd9\xde\x82\x87" "\xaa\x83\xb8\x8a\x1c\xae\xbd\x99\x24\x28\x7f\xc5\x99\x54\xff\xc0" "\x85\x28\xa5\xdf\xf3\xec\x77\x69\x22\xb8\x0f\xd7\x0e\xcf\xbd\x95" "\xff\xda\x89\x03\xaf\x14\x06\x47\x6e\x7a\xae\x2f\xb4\x97\x23\xae" "\x42\xc6\x31\x14\xa6\x8f\xc2\x4c\xcc\x4d\x1f\xc7\x2b\xb2\x93\x71" "\x80\x70\xa1\x6f\x92\xf9\xde\x5b\x1f\xb0\xc7\xa8\x8b\xe1\xeb\x3b" "\x51\x74\x02\xb2\x39\xfc\xf3\xe3\x68\x80\x7b\x73\x1d\x8e\x62\x99" "\x1c\xe8\x58\x18\xfa\x41\x9e\x21\x66\x9e\x24\xea\x53\xc1\x9d\x06" "\x20\x86\xd6\x78\x34\xef\x9c\xb1\x49\x11\xdf\x93\xe6\xc8\x8e\xde" "\xc8\x29\x99\x1a\x31\x6a\xb6\xd5\x7d\xfd\x4f\x1c\xab\xf4\x4d\xc9" "\xaa\x2a\x44\xf0\x0b\x5e\x35\x0c\xab\x51\xbb\xc3\xe4\xbd\x33\xe9" "\x25\xec\x7b\xf1\x04\x38\x3c\x3e\x4a\xd1\x59\x1e\x65\x20\x60\xdd" "\x66\x31\x7a\xbf\x7f\x8e\x5f\xfe\x5c\x45\xdc\xb4\xd6\x92\x59\x0c" "\xbf\xd6\x97\xf2\x7a\xfe\x77\x33\x40\x47\x1f\xe2\xb6\xac\x31\x8d" "\x68\xaa\x76\x7e\xdc\xc6\x02\x35\xf0\x94\xcd\xc7\xcf\xc3\x86\x17" "\x14\xcb\x70\x6d\x9c\x7a\x4c\xaf\xc5\xa5\xcd\x65\xb9\x7c\x1b\xd9" "\x89\x77\x69\x8a\xed\xec\x38\x29\xe2\xc9\x63\x42\x84\xad\x86\x7c" "\x55\x47\x84\x7a\x06\x99\x25\xaf\xef\x5a\xfd\x19\x69\x6c\x66\xd0" "\x19\x89\x2a\xd1\xff\xba\x51\xd9\x84\x1c\x52\xca\x50\x11\xe6\xd4" "\x73\x67\xc6\xc6\xe1\xc4\x34\x9f\x1d\x2c\x9f\x71\xa0\x42\xe9\x72" "\x9e\x28\x2a\x7c\xb7\x00\xb3\x71\xc8\x77\xd2\x94\x0a\x72\x39\x62" "\x7b\x2b\xaf\x8f\xd2\x17\xbc\x6a\x83\xb2\x8b\x22\xea\xf1\x2d\x98" }, { "", 0, "" } } }, { GCRY_CIPHER_AES256, 0, "\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", "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xfa", { { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32 * 16, "\xa0\x45\x6a\x19\xf3\x06\x20\x7f\x14\xce\x28\x0f\xe3\xdf\x44\x09" "\x15\x8d\xe1\xff\x64\x74\xfb\xdd\xb9\x96\x61\xd3\x57\xae\xaa\x46" "\x73\xa3\x98\x8d\x07\x66\xd7\xb2\xe8\xd9\xb5\xd8\xb5\xb5\x52\x72" "\x52\x33\x83\x4a\x9c\xc0\x06\x51\x38\x8c\x73\x67\xb9\xbe\x0c\x0b" "\x8f\xd1\xf4\xa7\xdb\xd0\x35\x96\xcb\xeb\x63\x80\x5c\x33\x7e\xa8" "\x5b\x4d\x10\x22\x33\x4b\x8c\x62\xb1\x9b\x3c\xc9\xf2\xf5\x45\x94" "\x80\xf8\x18\x12\xba\xb8\xc1\x19\xdb\x4c\x70\xda\x9d\x98\xc8\x89" "\xd8\x79\xe1\x25\x20\x52\xa1\x8e\xa1\x4f\x5e\x3d\xe6\xad\xe7\x35" "\x3a\x81\xef\xc9\x60\xbb\xde\xc6\x8b\x5e\xae\xd1\x2c\x2e\xa3\x4c" "\xb0\xd3\xe3\x12\xf7\x44\x3f\xe1\x34\x5c\xbf\xcd\xec\xa4\x1f\x45" "\x47\x13\x44\xec\xee\x4f\x7b\x7c\x53\x2f\xc4\x34\x3b\x6d\x70\x34" "\xd5\x9f\x61\xd5\xb4\x25\x07\xcc\x06\xfd\xc4\x34\x2a\x97\x16\xad" "\x24\xa3\xa0\xd0\x3a\xc4\xd3\xb4\x22\xa8\x73\xf5\xcd\x3f\x72\x9f" "\xae\x51\x6c\x7f\x3a\x5a\xfa\xdd\xdb\xbe\xcc\x09\xc8\xf8\x0a\x25" "\x87\x66\x8c\x90\xe1\xdf\xff\x37\xc5\x66\xc5\x26\xe1\x42\x5f\x8d" "\x18\x6a\x08\x54\xf2\x88\x2b\xc4\x12\x5f\x9d\x06\x9e\x3e\xbd\x44" "\x1e\xfb\x9a\x55\x53\xcc\x21\xef\x6c\x74\x60\x04\x64\x61\xc4\x86" "\x9d\x36\xdc\x2b\x68\x80\x0e\x8a\x99\x17\x07\xd3\x03\x7e\x44\x79" "\xd0\x30\xec\x72\x68\xef\x34\x72\x80\xee\xb8\x86\xc1\x4e\x51\x6f" "\xd3\xbd\xce\x04\x48\xbf\x0c\x40\xad\xa8\x7d\xd0\xfa\x12\xba\x64" "\x0c\xc3\x83\x37\xc1\xc1\xf7\x31\x7e\x59\x1f\x8e\xa3\x81\x64\xdd" "\x94\xef\xd6\xb1\xf6\xc3\x66\x58\x43\x4c\x25\xdc\x72\x6b\xf7\x37" "\x0b\x68\x85\x4d\x3b\x48\x1f\x04\x1e\x44\xff\x7a\xf0\x60\x89\xf7" "\xe8\x6e\x38\x9b\xa1\x63\x43\x47\xe1\x7e\x5c\xc0\xbe\x29\xb0\x75" "\xe7\xf3\x19\x22\x94\xf1\xa8\x4b\x05\xf4\xb2\x5b\xa4\x24\xdd\xbf" "\x19\xce\x7d\x1f\x13\x25\xde\xfa\xb9\x0b\x29\x49\x00\xa3\xfc\x13" "\xd2\x76\xf9\x98\x3b\x64\x30\xb6\xa3\xb3\xc0\xa2\x25\x70\xe0\x65" "\x25\x8e\xfd\xb1\x85\xd7\xd5\xc8\x4f\x52\xb5\x9e\x93\x84\xbf\xc9" "\x6f\x5c\xe5\xbd\x04\xe2\xfa\xa8\xea\xfe\xa6\x63\xb0\xa7\x75\x9c" "\x7c\xec\x3d\xbf\xb1\x28\xae\x1f\xd1\xdd\x57\x7b\x69\x36\xa9\xaf" "\xe6\x09\xf3\x46\x5e\x7d\xc6\x4e\x7b\xec\x3c\xc9\x26\x11\xae\x20" "\xe8\x6f\x27\xa8\x09\x60\xbe\xf0\xb0\xf7\x80\x71\x61\x57\x0b\xe2" }, { "", 0, "" } } }, #if USE_CAMELLIA { GCRY_CIPHER_CAMELLIA256, FLAG_NOFIPS, "\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", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xfa", { { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32 * 16, "\x6e\x85\xe1\x26\xf0\x1a\x70\x5b\x62\x4e\x94\xa3\x07\x70\xb8\xc7" "\x07\x20\x67\xc8\xd1\x30\xec\x82\x0c\x28\x0d\x01\x09\xd0\xef\x85" "\xf5\xea\x24\xee\x3d\xa6\x99\x00\x78\x19\xf5\x30\x57\x6f\x43\x52" "\xd2\xfc\xb5\x07\x0a\xe7\x6e\xd4\xd2\x76\x47\x6e\x5b\xb7\x28\x03" "\x62\x01\xe9\xaf\xe1\x29\xf9\x3c\x86\xc7\x50\xb1\xfb\xac\x76\xf8" "\x7b\x4a\x7b\x67\x63\xd8\xf1\xbc\xba\x9c\xfe\xaf\x7c\x00\xff\x51" "\x82\xd8\x3d\x99\xd6\xf9\x64\xfc\xcd\x97\x6c\x4e\x30\xa3\xd8\x66" "\x2d\x29\x38\x5f\x07\x67\x7e\x16\x6d\xd1\xe6\xd4\xcd\xaa\xe8\x0a" "\x1d\x5e\x47\x66\x9d\x28\xf6\xb0\xf4\x1e\xe6\xff\x1c\x2e\x03\x20" "\x31\x45\x24\x92\xcb\xd4\x59\xb9\xe8\x8a\xed\x3d\x01\xe2\xaa\x09" "\xa4\xb8\x78\x0d\x72\xa0\x5c\x4c\x48\x82\x20\xe1\xa4\xe9\xc1\xf9" "\x5c\xd5\x0d\xda\x2c\x01\x41\x94\xa3\x34\x2a\x22\xac\xf6\x1e\xc3" "\xfb\x92\x70\x7f\x12\xb1\x0a\x7e\xac\x61\xbe\xce\xc1\xa6\xb4\x17" "\xfd\x7e\xa7\x95\x97\xc1\x38\xc7\x20\x88\xe7\x64\x3a\xca\x90\x87" "\x5e\xa5\x71\x0d\xfc\x7d\x50\x91\x71\xa0\xb9\xc2\x9a\x34\xa9\x80" "\x05\x77\x30\xf5\x61\x15\x4b\x12\xa7\x6f\x19\x9a\xd3\x3a\x8c\xe9" "\x8c\xf7\x65\x5f\xde\x84\x18\x20\xe6\x35\x51\x32\xab\x4a\x85\x67" "\x29\xec\xb2\x82\xf4\x70\x9d\x77\x21\x0e\x4a\x80\x80\x67\x3c\x76" "\x70\x34\xa7\x00\x65\xaa\xcc\x54\x97\x46\x12\xd9\xfb\x1d\xef\x04" "\x58\xe3\x75\x0e\xf9\x24\x9d\xf2\x4e\xe1\x61\x7a\x7e\xc3\x32\xb2" "\xfb\x80\x5f\x77\x18\x4c\x8b\xc4\xd3\xe2\xe3\x13\xc4\xe3\x98\x9b" "\x86\xfe\xb2\x76\xc5\xbc\x18\xe2\xaa\x6d\x70\xe4\xfe\xf7\x10\x39" "\xdd\xc7\x9f\x34\x99\x3b\x46\xa5\xf1\xf7\x80\xab\x7a\x03\x33\xfb" "\x44\x74\x62\x84\xe5\x83\x05\x34\x13\x60\x1c\xfe\xc2\x34\xf5\x58" "\x0e\xdd\x33\x32\x3d\xab\x1a\xfe\x83\x33\x7c\x33\x84\x85\xaa\x8c" "\x69\x0c\xb0\x72\xdd\x4b\xd4\x6f\x03\x62\xf8\x59\x65\x4c\xe9\x07" "\x8b\xcc\x24\x04\x6c\x05\xc9\x1d\xb7\xd5\xea\xb8\x34\x83\x23\x29" "\x5e\x1f\xc9\xc8\xbf\xd9\x1e\xbf\x4d\x84\x41\x27\xf1\x51\xb3\x11" "\x2a\x40\x5b\xbe\xa1\x70\xd9\x47\x65\x35\xd3\xc8\xcf\xea\x96\xbf" "\xb2\x84\xda\x85\x72\xeb\x3d\xb9\x7d\xb0\x75\xfe\xdb\x6f\xa4\xe3" "\xce\xa9\xdb\xa3\x95\x7a\xa8\x2c\xbf\x94\x97\x89\x29\xd8\x1b\x4d" "\x44\xba\x92\x30\x80\x1c\x88\x06\xe8\xb7\x0c\xf4\x11\xfe\x66\xf2" }, { "", 0, "" } } }, { GCRY_CIPHER_CAMELLIA256, FLAG_NOFIPS, "\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", "\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xfa", { { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32 * 16, "\xdf\xe6\x82\xe0\xec\x70\x2f\x6f\xd5\x61\xd8\x31\xe7\xf3\xfb\x18" "\x4f\xd3\x58\xb0\x5a\xa6\xf2\x2b\x3d\x6e\xdd\xb8\xfb\x9f\x02\x3c" "\xf5\xb7\xc5\xa1\x17\xd3\x07\x8b\x3f\x07\x56\x90\xbd\x9c\x24\xa4" "\x2c\x1f\x45\x93\x1e\x37\xf2\x04\xbc\x34\xae\x7d\x13\x57\xe9\xc0" "\x30\x48\xad\xc1\x81\x8e\xee\x9a\xed\x8e\x0f\x9b\x16\x20\x57\x72" "\xc6\x74\x40\x2e\x60\xde\x49\x40\xc2\x22\xa0\xd7\xb8\xfb\x3d\xd0" "\xfc\x25\x37\x4d\xd2\x8e\x7e\x96\xd9\xdc\x19\x32\xc1\xe7\x9c\xe5" "\x13\x8a\xa6\x15\xd9\x3c\xba\xa6\x8f\x80\x69\x75\x74\xaf\x91\xf3" "\xac\xd2\xdf\xcd\x78\xce\x49\xb0\x59\x29\x77\x68\x7c\x35\x35\x14" "\x7a\xf7\x5a\x46\x25\x9a\x1d\x6b\x97\x7c\xee\x9a\x45\x85\x05\xff" "\xfc\xc9\x0c\x12\x8a\xa7\xee\xec\xaa\x8a\x5e\x43\x04\x0d\x2d\xdb" "\x14\x54\xbe\x3d\x63\xe6\x90\x1e\x0c\x46\xb8\x1a\xe5\xd3\x0c\xae" "\xac\xb9\xdd\xec\xab\xb9\x2f\x8a\xf5\x27\xf0\xd0\xf6\x43\x80\x72" "\x04\x23\x5b\xc3\xdc\x97\xdd\x7d\x3e\xf1\x5b\xc7\xbc\xd1\x96\xfc" "\xcc\xf3\xa6\x20\x76\x34\x26\xb7\x18\x59\xa4\x3e\xb2\xd1\xe3\x82" "\x24\xe9\xf4\x9c\xaa\x0f\x63\xd2\xfc\x7b\x73\x35\x92\x4c\x14\x6f" "\x3f\x2a\x71\xf8\x50\xf2\xaa\x09\xb6\xb1\x0c\xf8\x7b\xe1\x9f\xce" "\x63\x2e\x58\x47\xdf\x9d\x58\xb0\x59\xd2\xe0\x12\x33\x00\xd9\x57" "\x75\xf8\x06\xba\x58\x87\xd0\x9d\x3d\x7a\x9e\x1b\x9c\x9c\xa1\x79" "\xdc\x96\x41\xff\x3a\xb6\x44\xda\x70\xad\xa3\x66\x2d\x9e\xad\xc5" "\xb1\xb1\x48\xdb\x02\xf1\x26\x74\x8f\x10\x36\x19\xcc\x3b\x56\x91" "\x7f\x00\x1d\x32\x79\xb3\xdd\x31\x84\x75\xf1\xf0\xb9\x6e\xcb\x09" "\x0e\x3c\xb1\xe8\x1d\x72\xf9\xdf\x91\xda\x79\x09\x18\xcb\x67\xde" "\xb4\x60\xea\x48\x0b\x45\xbf\x79\xeb\xc3\x86\x72\xc4\x44\x81\x51" "\xcd\x93\xb4\xce\xc3\x64\xef\xaa\x1f\x66\x39\x24\x2c\xc7\x5a\xcc" "\xee\x09\x9a\x60\xfb\xcc\xb2\x2e\x7a\x8b\x4f\x90\x67\x40\xba\x4c" "\x67\xa4\x2b\x40\xd0\x30\xb7\xb3\x66\x56\x63\xf4\x77\x1d\x5e\x59" "\xd5\x42\xec\x7a\x35\x01\xde\xf9\x50\x64\x84\x60\x06\x8c\x65\xf1" "\x64\xef\x4f\x2f\xc7\xc4\x0e\xb1\x3f\xcf\x7e\x4a\x4e\x12\x21\x9c" "\xc5\xe3\xc2\x9e\xa8\x4c\xee\x55\x2d\x87\xa3\x46\x20\x83\x79\x88" "\x37\x82\x13\x94\x4a\x22\xaf\x1e\x10\xc1\xba\x5c\xd3\xc8\x27\x48" "\x4e\x57\xb0\x3a\x22\xfc\xab\xc2\x4d\x7b\x30\xa5\xdb\x93\xb4\xe6" }, { "", 0, "" } } }, { GCRY_CIPHER_CAMELLIA256, FLAG_NOFIPS, "\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", "\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfa", { { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32 * 16, "\xc0\x06\xd1\xed\x3e\xe9\x12\x44\xed\x8d\x15\xb2\x7a\x92\x95\x21" "\xa7\x86\x5c\x2f\xca\x3b\xa4\x1b\x0e\x7b\x96\xcd\xef\x2f\xf9\x1d" "\x9f\xd9\xeb\x5b\xa0\xec\x77\x2b\x20\x81\x99\xe6\x4a\xc6\x10\x0e" "\xd9\xff\x0e\xe1\x54\x5e\x28\xdc\xcf\xb2\xd1\xbb\x66\x37\x74\x3b" "\xa6\x3e\x85\x6b\xe1\x4f\xb3\xb2\x9a\xff\xba\x45\x02\xd0\xa6\x0b" "\x51\x9a\x15\x09\xf2\xb9\xfa\xe2\xc2\x11\x93\x09\xcf\xcb\x1e\x83" "\x9e\xd1\xfb\x92\xa5\xaa\x54\xcf\x26\xeb\x53\x60\xb0\xc2\x81\xe6" "\x09\x11\x18\x92\x62\xa6\x81\xce\xad\x4f\xe2\x10\x07\x40\xb0\xb2" "\x0b\x54\xd7\x6b\x71\xd1\xa9\x8c\x7e\x72\x1b\xe1\x65\x18\x47\x32" "\xdb\xc7\x95\xc7\x18\x22\xca\xb8\xc9\xd2\x91\xe7\x6f\xf4\x89\xe2" "\x20\xf5\xd9\x90\xe6\x32\x30\xd0\x4b\x69\x03\x35\x51\x82\x54\x9a" "\xde\x41\xbe\x3e\x68\x02\x9f\xa0\x82\x0b\xa6\x13\xa7\x3b\xfd\x87" "\xeb\x0b\xb9\x8e\x2b\x2b\x10\x84\x05\xeb\x6b\xde\x64\xcc\xda\xe9" "\x7b\x3c\x98\x4f\x0b\x22\x2e\xa2\x58\xce\xc2\xd3\x83\x23\x90\xb2" "\xf8\x2b\xfe\xb0\xa9\x83\xe7\x92\xb2\x7d\x40\x41\xc2\x03\xac\x3a" "\xc2\xa3\x62\x41\x10\x5c\x75\x39\xe1\x19\x7a\x41\xc9\x26\x5b\x37" "\x0c\x80\x39\x86\x56\xa1\x5c\xe8\x88\x20\x74\xed\x7e\xe3\xf2\x96" "\x73\x6e\xaf\x83\x7f\xea\x48\xb9\x2b\x8e\xb3\x0e\x38\xbb\xb6\x4c" "\xb8\xc4\x41\x57\xef\x19\x0e\x3d\x6b\xc1\xbf\x4e\xac\xd6\x8e\x54" "\xc2\xfa\x23\x4f\x74\x58\x58\xdd\xde\x66\x40\xea\xaf\xca\x8e\x2c" "\x08\xf8\x86\xb5\x7a\x98\x93\xa9\x16\x9d\xb2\x90\x1e\xcb\x74\x0e" "\x87\xae\xc3\xc3\x7b\xdf\xd4\x85\x52\xc5\x0c\xa5\x4e\xfc\xa4\x9d" "\xb2\x4e\xc3\xb1\xb1\xf9\xb4\x61\x13\x8c\x2c\xbf\x54\xc6\x30\x07" "\x2b\x68\xc1\x94\xc0\xe3\x2f\xdb\xe5\x8d\x11\x81\x32\xa6\x00\x29" "\x91\x05\x0e\x9b\x2d\xaf\x5f\x7c\x36\xac\x02\x35\xa0\x10\xea\xf2" "\x9a\x10\x73\xf0\xc6\xd2\x22\x0f\xc6\x41\xa0\xac\xbc\xc7\x98\x37" "\x7f\xb4\xfc\x4a\x34\xb2\x77\x12\x61\x58\x30\xc2\x9c\x96\x6e\xd9" "\xc2\x8d\xb0\x81\x7a\x68\x1e\xb0\x93\xf6\x4e\xeb\x2b\xa0\xcb\x44" "\x07\x85\x58\xe7\x57\x68\xfd\x0d\xd2\xf7\x01\x79\xbd\x86\x75\x09" "\x13\x96\xf3\x8c\xa9\x1b\x30\x06\x9d\x8a\x53\x84\x7d\x24\x02\xe2" "\x14\x7f\x76\x5f\x91\xad\x88\xe2\x53\xdc\xbe\x6a\x13\x78\xb7\xd5" "\xa9\x79\x56\xa8\x5b\x08\xce\xb6\x86\xd9\x1e\x0e\x26\x7f\x67\xf5" }, { "", 0, "" } } }, { GCRY_CIPHER_CAMELLIA256, FLAG_NOFIPS, "\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", "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xfa", { { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32 * 16, "\xac\xc5\xeb\x09\x8b\x1c\x42\xa6\x46\x50\xeb\x19\xe9\x93\xbc\x39" "\x50\x93\xdb\x3d\x2c\x34\x92\xad\xba\x29\xf2\x03\x19\xb4\xda\xf4" "\xe0\x3f\x10\xb4\x07\x9e\xa4\x0a\xab\xd5\xd2\x46\x13\x79\x8b\xf9" "\xd0\x76\x6c\x3e\xb3\x39\x09\x68\x2c\x60\x87\x34\x3c\x66\x72\x06" "\x0d\xab\xb4\xf1\xe3\x8c\x05\xfb\x58\x73\xbe\x2b\x5e\x0f\x0d\xba" "\xa2\xeb\x21\x33\x22\x98\x24\x88\xd7\xf4\x4e\x9b\xa3\x81\xe5\xcb" "\xaa\x84\xd3\xa6\x29\x3f\x0e\x07\x2f\x2d\xea\x0a\xf1\x13\xaf\x5d" "\x5d\x62\x3d\x35\x8d\x50\xd4\x49\xf9\x39\x37\xea\x57\xc5\x2e\x35" "\x5b\xf9\xa7\xd9\x2e\xc0\x2d\x39\x27\xcb\x83\x03\x3f\x2b\x17\x18" "\xcd\xb4\x67\x63\xd3\xf5\x28\xfd\x00\xb9\x96\xb8\xa7\xaf\x94\x9f" "\x5e\xd7\xca\x26\x9b\xd3\x8e\x83\x65\x8f\xa0\xcb\x83\x86\xae\x70" "\xaa\x04\x76\x54\x79\xef\x89\x5e\x81\x78\x7f\x49\x05\xab\x45\x70" "\x01\x6f\x87\x9d\xdc\x2a\xb2\xd6\xd7\x00\xc7\x61\xea\xb7\xb5\xf5" "\x98\x56\x20\x70\xa5\x8d\x8d\x7f\x91\xd2\xee\xe5\xf0\x7c\xf7\xd0" "\x12\x27\x03\x8d\x24\x06\x54\x81\x5a\x6b\xe8\x2f\xf9\x4c\xd6\xa4" "\x03\x4f\xd8\xee\x18\x8b\xef\x27\x89\xb2\x2a\x51\xde\xa1\xa8\x55" "\xa6\x1e\xd7\x4c\xcd\x22\x65\x20\xac\xf1\x17\xaf\xf5\x0a\x50\x05" "\xaf\x93\x26\xb5\xa3\x37\xf6\x87\x83\x5f\xde\x4e\x18\xe2\x2f\xae" "\xc6\x57\x56\x4f\x33\x16\xbc\xdc\xad\x89\xf2\x9d\xe8\x7c\x6c\x33" "\x70\x51\xe2\x9c\x29\x16\x2e\x57\x47\x14\x8c\xc4\x98\x2a\x12\x92" "\xb8\xc0\x85\x70\xa2\xd8\x33\x80\x38\xb0\x95\xae\x47\x26\x40\x88" "\x48\x0a\xa8\xfe\x35\x29\x9a\xdb\x41\x1d\x5a\xdc\xf0\xa1\x9e\xaf" "\x44\xae\x53\xb7\xd9\xe8\x2c\xe9\x0a\xe7\x88\xb7\x95\x9e\x40\xd1" "\xf4\x48\x20\x2d\x93\xcf\x03\xc8\xa6\x22\x95\x35\x7a\xef\x80\xa5" "\x8c\x37\x23\x83\x97\x31\xea\xdf\x73\x63\xa8\xc6\xa2\x92\xd8\x92" "\x3f\x89\xaa\x90\x61\xef\x8c\x4b\x3d\xfe\x07\xb0\x9e\xf2\x0c\xee" "\x94\x1d\x53\x70\x54\xf9\xdf\x92\x78\x88\xe5\x27\x3f\x8c\x4f\x8c" "\xe3\xc6\x50\xe4\x94\x5b\x40\x9b\xc6\x92\x7f\x61\xa8\x17\xdf\x38" "\xc0\x7d\x6d\x65\x71\x53\xb9\xa6\xad\x43\x9d\xc0\x3b\x7b\xa2\xc6" "\x14\x82\xe3\x11\xce\x15\x5d\xc4\xa4\x0c\x1a\x29\xcd\x2b\x43\x8e" "\xb5\x80\x16\xe5\x0d\xed\x06\xc9\x4d\x03\x79\x93\x45\x13\xee\x37" "\xcf\x8d\x18\x7c\x19\xc0\x8c\x15\xa6\x2f\x64\xed\xa5\x6f\x5f\x61" }, { "", 0, "" } } }, #endif /*USE_CAMELLIA*/ #if USE_CAST5 /* A selfmade test vector using an 64 bit block cipher. */ { GCRY_CIPHER_CAST5, FLAG_NOFIPS, "\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*/ #if USE_SM4 { GCRY_CIPHER_SM4, FLAG_NOFIPS, "\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb" "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xee\xee\xee\xee\xee\xee\xee\xee\xff\xff\xff\xff\xff\xff\xff\xff" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb", 64, "\xac\x32\x36\xcb\x97\x0c\xc2\x07\x91\x36\x4c\x39\x5a\x13\x42\xd1" "\xa3\xcb\xc1\x87\x8c\x6f\x30\xcd\x07\x4c\xce\x38\x5c\xdd\x70\xc7" "\xf2\x34\xbc\x0e\x24\xc1\x19\x80\xfd\x12\x86\x31\x0c\xe3\x7b\x92" "\x6e\x02\xfc\xd0\xfa\xa0\xba\xf3\x8b\x29\x33\x85\x1d\x82\x45\x14" }, { "", 0, "" } } }, { GCRY_CIPHER_SM4, FLAG_NOFIPS, "\xfe\xdc\xba\x98\x76\x54\x32\x10\x01\x23\x45\x67\x89\xab\xcd\xef", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb" "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xee\xee\xee\xee\xee\xee\xee\xee\xff\xff\xff\xff\xff\xff\xff\xff" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb", 64, "\x5d\xcc\xcd\x25\xb9\x5a\xb0\x74\x17\xa0\x85\x12\xee\x16\x0e\x2f" "\x8f\x66\x15\x21\xcb\xba\xb4\x4c\xc8\x71\x38\x44\x5b\xc2\x9e\x5c" "\x0a\xe0\x29\x72\x05\xd6\x27\x04\x17\x3b\x21\x23\x9b\x88\x7f\x6c" "\x8c\xb5\xb8\x00\x91\x7a\x24\x88\x28\x4b\xde\x9e\x16\xea\x29\x06" }, { "", 0, "" } } }, #endif /* USE_SM4 */ { 0, 0, "", "", { {"", 0, "" } } } }; gcry_cipher_hd_t hde, hdd; unsigned char out[32 * 16]; 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 ((err = gcry_cipher_test_algo (tv[i].algo))) { if (in_fips_mode && (tv[i].flags & FLAG_NOFIPS)) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); } else fail ("algo %d CTR, gcry_cipher_test_algo unexpectedly failed: %s\n", tv[i].algo, gpg_strerror (err)); continue; } else if (in_fips_mode && (tv[i].flags & FLAG_NOFIPS)) { fail ("algo %d CTR, gcry_cipher_test_algo did not fail as expected\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, sizeof(out), 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, sizeof(out), "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, sizeof(out), "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 flags; 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]; const char *oid; /* For gost 28147 param sets */ } 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, FLAG_CFB8, "\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, FLAG_CFB8, "\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, FLAG_CFB8, "\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, FLAG_CFB8, "\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, FLAG_CFB8, "\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, FLAG_CFB8, "\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"}, } }, #if USE_DES { GCRY_CIPHER_3DES, FLAG_CFB8 | FLAG_NOFIPS, "\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, FLAG_CFB8 | FLAG_NOFIPS, "\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"}, } }, #endif /* USE_DES */ #if USE_GOST28147 { GCRY_CIPHER_GOST28147_MESH, FLAG_NOFIPS, "\x48\x0c\x74\x1b\x02\x6b\x55\xd5\xb6\x6d\xd7\x1d\x40\x48\x05\x6b" "\x6d\xeb\x3c\x29\x0f\x84\x80\x23\xee\x0d\x47\x77\xe3\xfe\x61\xc9", "\x1f\x3f\x82\x1e\x0d\xd8\x1e\x22", { { "\x8c\x9c\x44\x35\xfb\xe9\xa5\xa3\xa0\xae\x28\x56\x91\x10\x8e\x1e" "\xd2\xbb\x18\x53\x81\x27\x0d\xa6\x68\x59\x36\xc5\x81\x62\x9a\x8e" "\x7d\x50\xf1\x6f\x97\x62\x29\xec\x80\x51\xe3\x7d\x6c\xc4\x07\x95" "\x28\x63\xdc\xb4\xb9\x2d\xb8\x13\xb1\x05\xb5\xf9\xeb\x75\x37\x4e" "\xf7\xbf\x51\xf1\x98\x86\x43\xc4\xe4\x3d\x3e\xa7\x62\xec\x41\x59" "\xe0\xbd\xfb\xb6\xfd\xec\xe0\x77\x13\xd2\x59\x90\xa1\xb8\x97\x6b" "\x3d\x8b\x7d\xfc\x9d\xca\x82\x73\x32\x70\x0a\x74\x03\xc6\x0c\x26" "\x7f\x56\xf0\x9d\xb2\xeb\x71\x40\xd7\xc3\xb1\xa7\xc5\x1e\x20\x17" "\xb3\x50\x1d\x8a\x6e\x19\xcb\xbe\x20\x86\x2b\xd6\x1c\xfd\xb4\xb7" "\x5d\x9a\xb3\xe3\x7d\x15\x7a\x35\x01\x9f\x5d\x65\x89\x4b\x34\xc6" "\xf4\x81\x3f\x78\x30\xcf\xe9\x15\x90\x9a\xf9\xde\xba\x63\xd0\x19" "\x14\x66\x3c\xb9\xa4\xb2\x84\x94\x02\xcf\xce\x20\xcf\x76\xe7\xc5" "\x48\xf7\x69\x3a\x5d\xec\xaf\x41\xa7\x12\x64\x83\xf5\x99\x1e\x9e" "\xb2\xab\x86\x16\x00\x23\x8e\xe6\xd9\x80\x0b\x6d\xc5\x93\xe2\x5c" "\x8c\xd8\x5e\x5a\xae\x4a\x85\xfd\x76\x01\xea\x30\xf3\x78\x34\x10" "\x72\x51\xbc\x9f\x76\xce\x1f\xd4\x8f\x33\x50\x34\xc7\x4d\x7b\xcf" "\x91\x63\x7d\x82\x9e\xa1\x23\x45\xf5\x45\xac\x98\x7a\x48\xff\x64" "\xd5\x59\x47\xde\x2b\x3f\xfa\xec\x50\xe0\x81\x60\x8b\xc3\xfc\x80" "\x98\x17\xc7\xa3\xc2\x57\x3d\xab\x91\x67\xf5\xc4\xab\x92\xc8\xd6" "\x3b\x6b\x3f\xff\x15\x6b\xcf\x53\x65\x02\xf1\x74\xca\xa9\xbe\x24" "\xd2\xf0\xb7\x26\xa8\xd7\x6d\xed\x90\x36\x7b\x3e\x41\xa9\x7f\xa3" "\x1b\xf4\x43\xc5\x51\xbe\x28\x59\xe9\x45\x26\x49\x38\x32\xf8\xf3" "\x92\x6e\x30\xcc\xb0\xa0\xf9\x01\x14\xc8\xba\xd9\xf0\x2a\x29\xe2" "\x52\x9a\x76\x95\x3a\x16\x32\xec\xf4\x10\xec\xee\x47\x00\x70\x19" "\xe4\x72\x35\x66\x44\x53\x2d\xa2\xf3\xaa\x7e\x8a\x33\x13\xcd\xc8" "\xbf\x0e\x40\x90\x00\xe4\x42\xc3\x09\x84\xe1\x66\x17\xa2\xaf\x03" "\xab\x6b\xa1\xec\xfb\x17\x72\x81\xfe\x9a\x9f\xf4\xb2\x33\x1f\xae" "\x0c\xd1\x6a\xae\x19\xb8\xaf\xec\xe3\xea\x00\xf8\xac\x87\x07\x5f" "\x6d\xb0\xac\x6b\x22\x48\x36\xbf\x22\x18\xb0\x03\x9f\x6c\x70\x45" "\x36\xf0\x6b\xc6\xc2\xa5\x72\x2c\xd8\xe0\x27\x3d\xec\x56\x07\x05" "\x7d\x83\xa1\x65\x7d\x41\x5b\xcd\x77\x24\xe5\xaa\x76\x47\xd0\x50" "\xf6\xe7\xb5\x59\x75\x31\x27\xef\xd8\xa6\x4e\x7f\xb8\x40\xb1\xdf" "\x53\x14\xed\xf1\x68\x5f\xfc\x3f\x02\xdb\x05\xeb\x31\xe4\x2c\x7f" "\x32\xb5\x70\x8e\x75\x85\xa4\x5c\x16\x23\x37\xf2\x10\x79\xcb\xdc" "\xf8\x1c\x25\xc2\xa1\x3d\x9c\x33\x6c\xed\xc3\xe7\xf3\x02\x87\x82" "\x4e\xfb\xac\xb3\x2d\xfc\xf8\x0d\x1d\x4a\x39\xd4\xb3\x09\xbb\xe9" "\x25\xc7\xec\x6a\x87\x72\x84\xed\x12\x60\x19\x64\xeb\x16\x2a\x5b" "\x10\x76\x27\xff\x7b\xe4\xae\xe5\xa4\x04\x02\x7f\xbb\x0a\xb5\xf4" "\x05\xa5\x56\x1c\x53\x31\x7a\x93\xba\x16\x15\xab\x62\x60\xfc\xde" "\x72\x36\x6e\x28\xaf\x98\x0d\xe6\xf4\xde\x60\xa7\x7e\x06\x07\x86" "\xf3\x94\xb6\x6d\x0d\x93\xa6\xbc\x60\x70\x33\xac\x3f\xa1\xa8\x4a" "\x20\x61\xb6\xb5\x43\xa3\x15\x5a\x00\xbe\x76\x98\x57\x72\xab\x7a" "\x0e\x18\x93\x82\x3a\x18\x78\x6e\x71\x7b\x78\x4f\x7e\x8c\xde\x7a" "\x62\xb5\x0a\x7c\x45\x1d\x16\xd5\xc3\x8c\x9b\x25\xb4\x50\x90\xcd" "\x96\x93\xad\x0f\xd4\x43\xcb\x49\x0f\xfc\x5a\x31\xf4\x19\xb7\xd4" "\xeb\x4d\x40\x58\xd0\x3b\xc8\xe0\x4a\x54\x2f\xdb\x22\xc3\x29\x7b" "\x40\x90\x61\x43\xd3\x7e\xe2\x30\x2b\x48\x3c\xce\x90\x93\xb1\x8b" "\x31\x96\x65\x6d\x57\x8b\x9d\x4d\x53\xf0\x83\x1c\xe5\xa1\x9d\x55" "\xe3\xbf\x7e\xca\x1a\x74\x66\x14\xcc\x47\x43\xd9\xbb\xef\x97\x7d" "\xb7\x6e\xff\xf1\x22\xf8\x10\x2d\x3f\xcd\x49\x96\xd9\x09\x11\xb8" "\x33\xd0\x23\x9a\xfa\x16\xcb\x50\x26\x57\x24\x5c\x0e\xba\xf0\x3f" "\x37\x2f\xa3\xf7\x18\x57\x48\x48\x95\xcf\xef\x87\x67\x2a\xe9\xb6" "\x8a\x21\x36\x7f\xff\x48\x6c\x46\x35\x57\xf2\xbc\x48\x67\x8f\x63" "\x23\x78\x11\x2b\xc2\x08\xde\x51\xe8\x8b\x92\x29\xf9\x9a\x9e\xad" "\xed\x0f\xeb\xa2\xd2\x40\x92\xd4\xde\x62\x95\x76\xfd\x6e\x3c\xbf" "\xc0\xd7\x0d\xe5\x1b\xa4\xc7\x18\xe1\x58\xa4\x56\xef\x2e\x17\x1b" "\x75\xcb\xbc\xf9\x2a\x95\x71\xa7\x1d\x7f\xe7\x73\x63\x05\x6b\x19" "\x4c\xf4\x22\x14\xc4\x59\x88\x66\x92\x86\x61\x5c\x6a\xae\xec\x58" "\xff\xc9\xf2\x44\xd4\xa2\xf5\x98\xeb\x5f\x09\xbc\x8a\xbf\x3c\xb4" "\x3e\xb1\x20\x05\x44\x96\x79\x0a\x40\x92\x7f\x9d\xd1\xaf\xbc\x90" "\x95\x0a\x81\xd4\xa7\xc6\xb8\xe0\xe4\x39\x30\x1d\x79\xc0\xe5\xfa" "\xb4\xe9\x63\xb4\x09\x72\x3b\x3e\xd9\xf6\xd9\x10\x21\x18\x7e\xe5" "\xad\x81\xd7\xd5\x82\xd0\x8c\x3b\x38\x95\xf8\x92\x01\xa9\x92\x00" "\x70\xd1\xa7\x88\x77\x1f\x3a\xeb\xb5\xe4\xf5\x9d\xc7\x37\x86\xb2" "\x12\x46\x34\x19\x72\x8c\xf5\x8c\xf6\x78\x98\xe0\x7c\xd3\xf4", 1039, "\x23\xc6\x7f\x20\xa1\x23\x58\xbc\x7b\x05\xdb\x21\x15\xcf\x96\x41" "\xc7\x88\xef\x76\x5c\x49\xdb\x42\xbf\xf3\xc0\xf5\xbd\x5d\xd9\x8e" "\xaf\x3d\xf4\xe4\xda\x88\xbd\xbc\x47\x5d\x76\x07\xc9\x5f\x54\x1d" "\x1d\x6a\xa1\x2e\x18\xd6\x60\x84\x02\x18\x37\x92\x92\x15\xab\x21" "\xee\x21\xcc\x71\x6e\x51\xd9\x2b\xcc\x81\x97\x3f\xeb\x45\x99\xb8" "\x1b\xda\xff\x90\xd3\x41\x06\x9c\x3f\xfb\xe4\xb2\xdc\xc9\x03\x0d" "\xa7\xae\xd7\x7d\x02\xb8\x32\xab\xf3\x65\xa3\x65\x6c\x4e\xe4\xa2" "\x5e\x9e\xee\xcd\xde\x79\x36\x6b\x1b\xe1\x3c\xdf\x10\xad\x4f\x02" "\xe1\x14\xaa\x09\xb4\x0b\x76\xeb\x69\x38\x20\x02\xcb\x8e\xc0\xdf" "\xca\x48\x74\xc3\x31\xad\x42\x2c\x51\x9b\xd0\x6a\xc1\x36\xd7\x21" "\xdf\xb0\x45\xba\xca\x7f\x35\x20\x28\xbb\xc1\x76\xfd\x43\x5d\x23" "\x7d\x31\x84\x1a\x97\x4d\x83\xaa\x7e\xf1\xc4\xe6\x83\xac\x0d\xef" "\xef\x3c\xa4\x7c\x48\xe4\xc8\xca\x0d\x7d\xea\x7c\x45\xd7\x73\x50" "\x25\x1d\x01\xc4\x02\x1a\xcd\xe0\x38\x5b\xa8\x5a\x16\x9a\x10\x59" "\x74\xd7\x19\xc6\xf3\xb5\x17\xf6\x59\x8d\x62\xaf\x44\xe8\xdc\xe9" "\xc1\x76\xf1\xd0\xbd\x29\xd7\xec\x1d\xac\x57\xdb\x1a\x3f\xd8\xf6" "\x6e\xb6\xe6\xdf\x36\xe7\x89\xce\x56\x35\x43\x1c\x7d\x57\x79\x0e" "\xd8\xf4\xd7\xa7\x0d\xc6\x8f\x91\x66\x67\x82\x0f\x49\xc9\xc5\x65" "\x81\xa1\x39\x5a\x53\x9f\x02\xa5\xd5\x36\x22\xa8\xa8\x1c\x37\x0e" "\x76\x46\xdf\xbd\x6a\xdb\xfc\x1b\xbd\x10\xb8\xb1\xbc\x72\x4c\x58" "\x4a\xda\x6d\x66\x00\xda\x7a\x66\xa0\xe7\x3b\x39\xa3\xf7\x05\x07" "\xfa\x21\x4b\xc7\x94\xc0\xd3\x7b\x19\x02\x5d\x4a\x10\xf1\xc2\x0f" "\x19\x68\x27\xc7\x7d\xbf\x55\x03\x57\x7d\xaf\x77\xae\x80\x2f\x7a" "\xe6\x1f\x4b\xdc\x15\x18\xc0\x62\xa1\xe8\xd9\x1c\x9e\x8c\x96\x39" "\xc1\xc4\x88\xf7\x0c\xe1\x04\x84\x68\x51\xce\xf1\x90\xda\x7f\x76" "\xc8\xc0\x88\xef\x8e\x15\x25\x3e\x7b\xe4\x79\xb5\x66\x2d\x9c\xd1" "\x13\xda\xd0\xd5\x46\xd5\x8d\x46\x18\x07\xee\xd8\xc9\x64\xe3\xbe" "\x0e\x68\x27\x09\x96\x26\xf6\xe2\x19\x61\x3f\xf4\x58\x27\x0a\xeb" "\xce\x7c\xb6\x68\x92\xe7\x12\x3b\x31\xd4\x48\xdf\x35\x8d\xf4\x86" "\x42\x2a\x15\x4b\xe8\x19\x1f\x26\x65\x9b\xa8\xda\x4b\x79\x1f\x8e" "\xe6\x13\x7e\x49\x8f\xc1\xce\xdc\x5e\x64\x74\xce\x02\x78\xe0\xcf" "\xa0\xed\x5e\x31\x74\xd1\xd0\xb4\xee\x70\x19\x14\x3c\x8f\x16\xa6" "\xcf\x12\x93\x15\x88\xeb\x91\x65\x76\x98\xfd\xa1\x94\x30\xba\x43" "\x62\x65\x40\x04\x77\x9e\xd6\xab\x8b\x0d\x93\x80\x50\x5f\xa2\x76" "\x20\xa7\xd6\x9c\x27\x15\x27\xbc\xa5\x5a\xbf\xe9\x92\x82\x05\xa8" "\x41\xe9\xb5\x60\xd5\xc0\xd7\x4b\xad\x38\xb2\xe9\xd1\xe5\x51\x5f" "\x24\x78\x24\x9a\x23\xd2\xc2\x48\xbd\x0e\xf1\x37\x72\x91\x87\xb0" "\x4e\xbd\x99\x6b\x2c\x01\xb6\x79\x69\xec\x0c\xed\xe5\x3f\x50\x64" "\x7c\xb9\xdd\xe1\x92\x81\xb5\xd0\xcb\x17\x83\x86\x8b\xea\x4f\x93" "\x08\xbc\x22\x0c\xef\xe8\x0d\xf5\x9e\x23\xe1\xf9\xb7\x6b\x45\x0b" "\xcb\xa9\xb6\x4d\x28\x25\xba\x3e\x86\xf2\x75\x47\x5d\x9d\x6b\xf6" "\x8a\x05\x58\x73\x3d\x00\xde\xfd\x69\xb1\x61\x16\xf5\x2e\xb0\x9f" "\x31\x6a\x00\xb9\xef\x71\x63\x47\xa3\xca\xe0\x40\xa8\x7e\x02\x04" "\xfe\xe5\xce\x48\x73\xe3\x94\xcf\xe2\xff\x29\x7e\xf6\x32\xbb\xb7" "\x55\x12\x21\x7a\x9c\x75\x04\x0c\xb4\x7c\xb0\x3d\x40\xb3\x11\x9a" "\x7a\x9a\x13\xfb\x77\xa7\x51\x68\xf7\x05\x47\x3b\x0f\x52\x5c\xe6" "\xc2\x99\x3a\x37\x54\x5c\x4f\x2b\xa7\x01\x08\x74\xbc\x91\xe3\xe2" "\xfe\x65\x94\xfd\x3d\x18\xe0\xf0\x62\xed\xc2\x10\x82\x9c\x58\x7f" "\xb2\xa3\x87\x8a\x74\xd9\xc1\xfb\x84\x28\x17\xc7\x2b\xcb\x53\x1f" "\x4e\x8a\x82\xfc\xb4\x3f\xc1\x47\x25\xf3\x21\xdc\x4c\x2d\x08\xfa" "\xe7\x0f\x03\xa9\x68\xde\x6b\x41\xa0\xf9\x41\x6c\x57\x4d\x3a\x0e" "\xea\x51\xca\x9f\x97\x11\x7d\xf6\x8e\x88\x63\x67\xc9\x65\x13\xca" "\x38\xed\x35\xbe\xf4\x27\xa9\xfc\xa9\xe6\xc3\x40\x86\x08\x39\x72" "\x37\xee\xb2\x87\x09\x96\xb7\x40\x87\x36\x92\xc1\x5d\x6a\x2c\x43" "\xca\x25\xc8\x35\x37\x2d\xb5\xa9\x27\x44\x50\xf2\x6d\x22\x75\x41" "\x77\x2a\xdb\xb1\x8c\x6d\x05\xe8\xc9\x99\xc7\x08\xf9\x14\x8f\x78" "\xa9\x8f\xc2\x5a\x7a\x65\xc5\xd8\x86\xbb\x72\x69\x6b\x6b\x45\x83" "\x5b\xb1\xf7\xcd\x16\x73\xee\xe9\x80\x85\xfe\x8e\xe1\xae\x53\x8f" "\xde\xbe\x48\x8b\x59\xef\xf6\x7e\xd8\xb5\xa8\x47\xc0\x4e\x15\x58" "\xca\xd3\x2f\xf8\x6c\xa6\x3d\x78\x4d\x7a\x54\xd6\x10\xe5\xcc\x05" "\xe2\x29\xb5\x86\x07\x39\x7d\x78\x8e\x5a\x8f\x83\x4c\xe7\x3d\x68" "\x3e\xe5\x02\xe6\x64\x4f\x5e\xb4\x49\x77\xf0\xc0\xfa\x6f\xc8\xfb" "\x9f\x84\x6f\x55\xfb\x30\x5e\x89\x93\xa9\xf3\xa6\xa3\xd7\x26\xbb" "\xd8\xa8\xd9\x95\x1d\xfe\xfc\xd7\xa8\x93\x66\x2f\x04\x53\x06\x64" "\x7f\x31\x29\xae\xb7\x9f\xba\xc4\x6d\x68\xd1\x24\x32\xf4\x11", }, }, "1.2.643.2.2.31.2" }, #endif #if USE_SM4 { GCRY_CIPHER_SM4, FLAG_NOFIPS, "\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd" "\xee\xee\xee\xee\xff\xff\xff\xff\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb", 32, "\xac\x32\x36\xcb\x86\x1d\xd3\x16\xe6\x41\x3b\x4e\x3c\x75\x24\xb7" "\x69\xd4\xc5\x4e\xd4\x33\xb9\xa0\x34\x60\x09\xbe\xb3\x7b\x2b\x3f" }, } }, { GCRY_CIPHER_SM4, FLAG_NOFIPS, "\xfe\xdc\xba\x98\x76\x54\x32\x10\x01\x23\x45\x67\x89\xab\xcd\xef", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd" "\xee\xee\xee\xee\xff\xff\xff\xff\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb", 32, "\x5d\xcc\xcd\x25\xa8\x4b\xa1\x65\x60\xd7\xf2\x65\x88\x70\x68\x49" "\x0d\x9b\x86\xff\x20\xc3\xbf\xe1\x15\xff\xa0\x2c\xa6\x19\x2c\xc5" }, } }, #endif /* USE_SM4 */ }; 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 ((err = gcry_cipher_test_algo (tv[i].algo))) { if (in_fips_mode && (tv[i].flags & FLAG_NOFIPS)) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); } else fail ("algo %d CFB, gcry_cipher_test_algo unexpectedly failed: %s\n", tv[i].algo, gpg_strerror (err)); continue; } else if (in_fips_mode && (tv[i].flags & FLAG_NOFIPS)) { fail ("algo %d CFB, gcry_cipher_test_algo did not fail as expected\n", tv[i].algo); continue; } mode = (tv[i].flags & FLAG_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; } if (tv[i].oid) { err = gcry_cipher_set_sbox (hde, tv[i].oid); if (!err) err = gcry_cipher_set_sbox (hdd, tv[i].oid); if (err) { fail ("cfb, gcry_cipher_set_sbox failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); 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; int flags; 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, 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, "\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, 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, "\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, 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, "\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" } } }, #if USE_SM4 { GCRY_CIPHER_SM4, FLAG_NOFIPS, "\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd" "\xee\xee\xee\xee\xff\xff\xff\xff\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb", 32, "\xac\x32\x36\xcb\x86\x1d\xd3\x16\xe6\x41\x3b\x4e\x3c\x75\x24\xb7" "\x1d\x01\xac\xa2\x48\x7c\xa5\x82\xcb\xf5\x46\x3e\x66\x98\x53\x9b" }, } }, { GCRY_CIPHER_SM4, FLAG_NOFIPS, "\xfe\xdc\xba\x98\x76\x54\x32\x10\x01\x23\x45\x67\x89\xab\xcd\xef", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb\xcc\xcc\xcc\xcc\xdd\xdd\xdd\xdd" "\xee\xee\xee\xee\xff\xff\xff\xff\xaa\xaa\xaa\xaa\xbb\xbb\xbb\xbb", 32, "\x5d\xcc\xcd\x25\xa8\x4b\xa1\x65\x60\xd7\xf2\x65\x88\x70\x68\x49" "\x33\xfa\x16\xbd\x5c\xd9\xc8\x56\xca\xca\xa1\xe1\x01\x89\x7a\x97" }, } } #endif /* USE_SM4 */ }; 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 ((err = gcry_cipher_test_algo (tv[i].algo))) { if (in_fips_mode && (tv[i].flags & FLAG_NOFIPS)) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); } else fail ("algo %d OFB, gcry_cipher_test_algo unexpectedly failed: %s\n", tv[i].algo, gpg_strerror (err)); continue; } else if (in_fips_mode && (tv[i].flags & FLAG_NOFIPS)) { fail ("algo %d OFB, gcry_cipher_test_algo did not fail as expected\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" }, { 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", "\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, "\x52\x2d\xc1\xf0\x99\x56\x7d\x07\xf4\x7f\x37\xa3\x2a\x84\x42\x7d" "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9\x75\x98\xa2\xbd\x25\x55\xd1\xaa" "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d\xa7\xb0\x8b\x10\x56\x82\x88\x38" "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a\xbc\xc9\xf6\x62", "\x76\xfc\x6e\xce\x0f\x4e\x17\x68\xcd\xdf\x88\x53\xbb\x2d\x55\x1b" }, /* 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++) { /* The AES algorithm is allowed in FIPS mode */ if ((err = gcry_cipher_test_algo (tv[i].algo))) { fail ("aes-gcm, gcry_cipher_test_algo failed: %s\n", gpg_strerror (err)); 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++) { /* The AES algorithm is allowed in FIPS mode */ if ((err = gcry_cipher_test_algo (tv[i].algo))) { fail ("aes-eax, gcry_cipher_test_algo failed: %s\n", gpg_strerror (err)); 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_siv_cipher (void) { static const struct tv { int algo; char key[MAX_DATA_LEN]; char ad1[MAX_DATA_LEN]; int ad1len; char ad2[MAX_DATA_LEN]; int ad2len; char nonce[MAX_DATA_LEN]; int noncelen; unsigned char plaintext[MAX_DATA_LEN]; int inlen; char tag[MAX_DATA_LEN]; char out[MAX_DATA_LEN]; } tv[] = { /* Test vectors from RFC5297 */ { GCRY_CIPHER_AES128, "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\x20\x21\x22\x23\x24\x25\x26\x27", 24, "", -1, "", -1, "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee", 14, "\x85\x63\x2d\x07\xc6\xe8\xf3\x7f\x95\x0a\xcd\x32\x0a\x2e\xcc\x93", "\x40\xc0\x2b\x96\x90\xc4\xdc\x04\xda\xef\x7f\x6a\xfe\x5c" }, { GCRY_CIPHER_AES128, "\x7f\x7e\x7d\x7c\x7b\x7a\x79\x78\x77\x76\x75\x74\x73\x72\x71\x70" "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff" "\xde\xad\xda\xda\xde\xad\xda\xda\xff\xee\xdd\xcc\xbb\xaa\x99\x88" "\x77\x66\x55\x44\x33\x22\x11\x00", 40, "\x10\x20\x30\x40\x50\x60\x70\x80\x90\xa0", 10, "\x09\xf9\x11\x02\x9d\x74\xe3\x5b\xd8\x41\x56\xc5\x63\x56\x88\xc0", 16, "\x74\x68\x69\x73\x20\x69\x73\x20\x73\x6f\x6d\x65\x20\x70\x6c\x61" "\x69\x6e\x74\x65\x78\x74\x20\x74\x6f\x20\x65\x6e\x63\x72\x79\x70" "\x74\x20\x75\x73\x69\x6e\x67\x20\x53\x49\x56\x2d\x41\x45\x53", 47, "\x7b\xdb\x6e\x3b\x43\x26\x67\xeb\x06\xf4\xd1\x4b\xff\x2f\xbd\x0f", "\xcb\x90\x0f\x2f\xdd\xbe\x40\x43\x26\x60\x19\x65\xc8\x89\xbf\x17" "\xdb\xa7\x7c\xeb\x09\x4f\xa6\x63\xb7\xa3\xf7\x48\xba\x8a\xf8\x29" "\xea\x64\xad\x54\x4a\x27\x2e\x9c\x48\x5b\x62\xa3\xfd\x5c\x0d" }, /* From libaes_siv */ { GCRY_CIPHER_AES256, "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0", "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\x20\x21\x22\x23\x24\x25\x26\x27", 24, "", -1, "", -1, "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee", 14, "\x72\x4d\xfb\x2e\xaf\x94\xdb\xb1\x9b\x0b\xa3\xa2\x99\xa0\x80\x1e", "\xf3\xb0\x5a\x55\x49\x8e\xc2\x55\x26\x90\xb8\x98\x10\xe4" }, /* From https://github.com/cryptomator/siv-mode */ { GCRY_CIPHER_AES128, "\x90\xe5\x90\xae\xca\x19\x70\xed\xd1\x9f\xe5\x0f\xa6\x91\xae\x12" "\x34\x2c\x49\x7a\x22\xc2\x4f\xaa\x9e\x87\x19\x2e\x34\x00\xfb\xce", "\x2d\xdf\x87\xac\x97\x5d\x0c", 7, "", -1, "", -1, "\x44", 1, "\x7b\x0d\xdd\x88\x74\x39\x43\xc6\x44\xc1\xd1\xa2\x18\xa3\x1e\xdf", "\x2e" }, { GCRY_CIPHER_AES128, "\xf6\xde\x98\x19\x31\x1b\xd3\xde\x0b\xd1\x98\x70\x9d\xea\x9f\xdf" "\xb8\x2e\x80\x44\xe4\x00\x13\x2a\x90\xff\xe9\xa9\xde\x81\x44\x75", "\x7b\xd3\x6f\x24\x09\xfc\xd0\x0f\x5c\xcd\x9a\xf2\xe3\xf5\x76\x45" "\xf7\xc5\x3f\x39\xf7\xad\xcb\xf0\x7a\x0e\x43\x30\x7e\x55\xa2\x53" "\x47\x49\x48\x20\x20\x27\x6c\x8a\x20\x44\x22\xcd\x26\xbf\x7e\x89" "\x88\x38\x0d\x94\xff\x12\xc5\x18\xfd\x20\x2c\x2a\x1b\x00\xb3", 63, "", -1, "", -1, "", 0, "\x4c\x0e\xc2\xcc\x61\x59\xb1\x17\xdb\x98\x6d\x9a\xa5\xb4\xa0\x11", "" }, /* From https://github.com/RustCrypto/AEADs */ { GCRY_CIPHER_AES128, "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", "", -1, "", -1, "", -1, "", 0, "\xf2\x00\x7a\x5b\xeb\x2b\x89\x00\xc5\x88\xa7\xad\xf5\x99\xf1\x72", "" }, { GCRY_CIPHER_AES128, "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", "", -1, "", -1, "", -1, "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff", 16, "\xf3\x04\xf9\x12\x86\x3e\x30\x3d\x5b\x54\x0e\x50\x57\xc7\x01\x0c", "\x94\x2f\xfa\xf4\x5b\x0e\x5c\xa5\xfb\x9a\x56\xa5\x26\x3b\xb0\x65" }, /* From nettle */ { GCRY_CIPHER_AES128, "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", "", 0, "", -1, "\x01", 1, "", 0, "\xc6\x96\xf8\x4f\xdf\x92\xab\xa3\xc3\x1c\x23\xd5\xf2\x08\x75\x13", "" }, /* From botan */ { GCRY_CIPHER_AES128, "\x2a\x83\xf6\x10\xa1\xd1\x77\xec\x2e\x00\x89\x80\xdc\x02\xa6\x6e" "\xeb\x75\xaf\x6c\xba\x44\xa4\xe0\x9f\x3d\x93\xea\x1f\xa2\x88\x67", "", 0, "", -1, "", -1, "", 0, "\x6b\xc5\xca\x86\x32\x29\x66\x75\x18\xa9\xab\xbd\x5a\xe6\xc1\xd5", "" }, { GCRY_CIPHER_AES128, "\x97\xef\x57\xd4\xe2\xe9\x2f\x14\xdf\x73\x31\xfb\xa3\xd9\xf3\x58" "\x87\xdd\xe7\xad\x86\x91\xfb\x80\x17\x68\x58\xd6\x59\x20\x14\x27", "", 0, "", -1, "", -1, "\x75\x73\x97\x4d\x6f\xa7\x65\xbc\xd0\xe6\x23\x2c\x24\x0e\x82\x7e", 16, "\x68\x60\xa9\xc7\xbf\x4a\x6b\x21\x92\x44\xd7\xa8\xea\xa1\xf5\x0c", "\x6f\x97\x93\x82\xcd\xe6\x8d\xe6\x0a\xb2\xad\x09\x53\x60\x64\x85" } }; 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 taglen2; if (verbose) fprintf (stderr, " Starting SIV checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { /* The AES algorithm is allowed in FIPS mode */ if ((err = gcry_cipher_test_algo (tv[i].algo))) { fail ("aes-siv, gcry_cipher_test_algo failed: %s\n", gpg_strerror (err)); continue; } if (verbose) fprintf (stderr, " checking SIV 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_SIV, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_SIV, 0); if (err) { fail ("aes-siv, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen (tv[i].algo) * 2; if (!keylen) { fail ("aes-siv, 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-siv, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (tv[i].ad1len >= 0) { err = gcry_cipher_authenticate (hde, tv[i].ad1, tv[i].ad1len); if (!err) err = gcry_cipher_authenticate (hdd, tv[i].ad1, tv[i].ad1len); if (err) { fail ("aes-siv, gcry_cipher_authenticate failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (tv[i].ad2len >= 0) { err = gcry_cipher_authenticate (hde, tv[i].ad2, tv[i].ad2len); if (!err) err = gcry_cipher_authenticate (hdd, tv[i].ad2, tv[i].ad2len); if (err) { fail ("aes-siv, gcry_cipher_authenticate failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (tv[i].noncelen >= 0) { 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-siv, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* Further AD not allowed after setting nonce. */ err = gcry_cipher_authenticate (hde, tv[i].nonce, tv[i].noncelen); if (!err) { fail ("aes-siv, gcry_cipher_authenticate after setiv did not fail\n"); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2); if (err) { fail ("cipher-siv, 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-siv, 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; } if (tv[i].inlen) { err = gcry_cipher_encrypt (hde, out, tv[i].inlen, tv[i].plaintext, tv[i].inlen); if (err) { fail ("aes-siv, 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)) { mismatch (tv[i].out, tv[i].inlen, out, tv[i].inlen); fail ("aes-siv, encrypt mismatch entry %d\n", i); } err = gcry_cipher_gettag (hde, tag, taglen2); if (err) { fail ("aes-siv, 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, tag, taglen2)) { mismatch (tv[i].tag, taglen2, tag, taglen2); fail ("aes-siv, tag mismatch entry %d\n", i); } err = gcry_cipher_set_decryption_tag (hdd, tag, taglen2); if (err) { fail ("aes-siv, gcry_cipher_set_decryption_tag (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_decrypt (hdd, out, tv[i].inlen, NULL, 0); if (err) { fail ("aes-siv, 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 ("aes-siv, decrypt mismatch entry %d\n", i); err = gcry_cipher_checktag (hdd, tag, taglen2); if (err) { fail ("aes-siv, gcry_cipher_checktag (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } else { err = gcry_cipher_gettag (hde, tag, taglen2); if (err) { fail ("aes-siv, 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, tag, taglen2)) { mismatch (tv[i].tag, taglen2, tag, taglen2); fail ("aes-siv, tag mismatch entry %d\n", i); } err = gcry_cipher_checktag (hdd, tv[i].tag, taglen2); if (err) { fail ("aes-siv, gcry_cipher_checktag (%d) 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 SIV checks.\n"); } static void check_gcm_siv_cipher (void) { static const struct tv { int algo; char key[MAX_DATA_LEN]; char nonce[12]; char ad[MAX_DATA_LEN]; int adlen; unsigned char plaintext[MAX_DATA_LEN]; int inlen; char out[MAX_DATA_LEN]; char tag[MAX_DATA_LEN]; } tv[] = { /* Test vectors from RFC8452 */ { GCRY_CIPHER_AES128, "\xee\x8e\x1e\xd9\xff\x25\x40\xae\x8f\x2b\xa9\xf5\x0b\xc2\xf2\x7c", "\x75\x2a\xba\xd3\xe0\xaf\xb5\xf4\x34\xdc\x43\x10", "example", 7, "Hello world", 11, "\x5d\x34\x9e\xad\x17\x5e\xf6\xb1\xde\xf6\xfd", "\x4f\xbc\xde\xb7\xe4\x79\x3f\x4a\x1d\x7e\x4f\xaa\x70\x10\x0a\xf1" }, { GCRY_CIPHER_AES128, "\x01\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", "", -1, "", 0, "", "\xdc\x20\xe2\xd8\x3f\x25\x70\x5b\xb4\x9e\x43\x9e\xca\x56\xde\x25" }, { GCRY_CIPHER_AES128, "\x01\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", "", 0, "", 0, "", "\xdc\x20\xe2\xd8\x3f\x25\x70\x5b\xb4\x9e\x43\x9e\xca\x56\xde\x25", }, { GCRY_CIPHER_AES128, "\x01\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", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00", 8, "\xb5\xd8\x39\x33\x0a\xc7\xb7\x86", "\x57\x87\x82\xff\xf6\x01\x3b\x81\x5b\x28\x7c\x22\x49\x3a\x36\x4c", }, { GCRY_CIPHER_AES128, "\x01\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", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "\x73\x23\xea\x61\xd0\x59\x32\x26\x00\x47\xd9\x42", "\xa4\x97\x8d\xb3\x57\x39\x1a\x0b\xc4\xfd\xec\x8b\x0d\x10\x66\x39", }, { GCRY_CIPHER_AES128, "\x01\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", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, "\x74\x3f\x7c\x80\x77\xab\x25\xf8\x62\x4e\x2e\x94\x85\x79\xcf\x77", "\x30\x3a\xaf\x90\xf6\xfe\x21\x19\x9c\x60\x68\x57\x74\x37\xa0\xc4", }, { GCRY_CIPHER_AES128, "\x01\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", "", 0, "\x01\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", 32, "\x84\xe0\x7e\x62\xba\x83\xa6\x58\x54\x17\x24\x5d\x7e\xc4\x13\xa9" "\xfe\x42\x7d\x63\x15\xc0\x9b\x57\xce\x45\xf2\xe3\x93\x6a\x94\x45", "\x1a\x8e\x45\xdc\xd4\x57\x8c\x66\x7c\xd8\x68\x47\xbf\x61\x55\xff", }, { GCRY_CIPHER_AES128, "\x01\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", "", 0, "\x01\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" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 48, "\x3f\xd2\x4c\xe1\xf5\xa6\x7b\x75\xbf\x23\x51\xf1\x81\xa4\x75\xc7" "\xb8\x00\xa5\xb4\xd3\xdc\xf7\x01\x06\xb1\xee\xa8\x2f\xa1\xd6\x4d" "\xf4\x2b\xf7\x22\x61\x22\xfa\x92\xe1\x7a\x40\xee\xaa\xc1\x20\x1b", "\x5e\x6e\x31\x1d\xbf\x39\x5d\x35\xb0\xfe\x39\xc2\x71\x43\x88\xf8", }, { GCRY_CIPHER_AES128, "\x01\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", "", 0, "\x01\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" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 64, "\x24\x33\x66\x8f\x10\x58\x19\x0f\x6d\x43\xe3\x60\xf4\xf3\x5c\xd8" "\xe4\x75\x12\x7c\xfc\xa7\x02\x8e\xa8\xab\x5c\x20\xf7\xab\x2a\xf0" "\x25\x16\xa2\xbd\xcb\xc0\x8d\x52\x1b\xe3\x7f\xf2\x8c\x15\x2b\xba" "\x36\x69\x7f\x25\xb4\xcd\x16\x9c\x65\x90\xd1\xdd\x39\x56\x6d\x3f", "\x8a\x26\x3d\xd3\x17\xaa\x88\xd5\x6b\xdf\x39\x36\xdb\xa7\x5b\xb8", }, { GCRY_CIPHER_AES128, "\x01\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", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00", 8, "\x1e\x6d\xab\xa3\x56\x69\xf4\x27", "\x3b\x0a\x1a\x25\x60\x96\x9c\xdf\x79\x0d\x99\x75\x9a\xbd\x15\x08", }, { GCRY_CIPHER_AES128, "\x01\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", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "\x29\x6c\x78\x89\xfd\x99\xf4\x19\x17\xf4\x46\x20", "\x08\x29\x9c\x51\x02\x74\x5a\xaa\x3a\x0c\x46\x9f\xad\x9e\x07\x5a", }, { GCRY_CIPHER_AES128, "\x01\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", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, "\xe2\xb0\xc5\xda\x79\xa9\x01\xc1\x74\x5f\x70\x05\x25\xcb\x33\x5b", "\x8f\x89\x36\xec\x03\x9e\x4e\x4b\xb9\x7e\xbd\x8c\x44\x57\x44\x1f", }, { GCRY_CIPHER_AES128, "\x01\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", "\x01", 1, "\x02\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", 32, "\x62\x00\x48\xef\x3c\x1e\x73\xe5\x7e\x02\xbb\x85\x62\xc4\x16\xa3" "\x19\xe7\x3e\x4c\xaa\xc8\xe9\x6a\x1e\xcb\x29\x33\x14\x5a\x1d\x71", "\xe6\xaf\x6a\x7f\x87\x28\x7d\xa0\x59\xa7\x16\x84\xed\x34\x98\xe1", }, { GCRY_CIPHER_AES128, "\x01\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", "\x01", 1, "\x02\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" "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 48, "\x50\xc8\x30\x3e\xa9\x39\x25\xd6\x40\x90\xd0\x7b\xd1\x09\xdf\xd9" "\x51\x5a\x5a\x33\x43\x10\x19\xc1\x7d\x93\x46\x59\x99\xa8\xb0\x05" "\x32\x01\xd7\x23\x12\x0a\x85\x62\xb8\x38\xcd\xff\x25\xbf\x9d\x1e", "\x6a\x8c\xc3\x86\x5f\x76\x89\x7c\x2e\x4b\x24\x5c\xf3\x1c\x51\xf2", }, { GCRY_CIPHER_AES128, "\x01\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", "\x01", 1, "\x02\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" "\x04\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", 64, "\x2f\x5c\x64\x05\x9d\xb5\x5e\xe0\xfb\x84\x7e\xd5\x13\x00\x37\x46" "\xac\xa4\xe6\x1c\x71\x1b\x5d\xe2\xe7\xa7\x7f\xfd\x02\xda\x42\xfe" "\xec\x60\x19\x10\xd3\x46\x7b\xb8\xb3\x6e\xbb\xae\xbc\xe5\xfb\xa3" "\x0d\x36\xc9\x5f\x48\xa3\xe7\x98\x0f\x0e\x7a\xc2\x99\x33\x2a\x80", "\xcd\xc4\x6a\xe4\x75\x56\x3d\xe0\x37\x00\x1e\xf8\x4a\xe2\x17\x44", }, { GCRY_CIPHER_AES128, "\x01\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", "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "\x02\x00\x00\x00", 4, "\xa8\xfe\x3e\x87", "\x07\xeb\x1f\x84\xfb\x28\xf8\xcb\x73\xde\x8e\x99\xe2\xf4\x8a\x14", }, { GCRY_CIPHER_AES128, "\x01\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", "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00", 18, "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00\x00\x00", 20, "\x6b\xb0\xfe\xcf\x5d\xed\x9b\x77\xf9\x02\xc7\xd5\xda\x23\x6a\x43" "\x91\xdd\x02\x97", "\x24\xaf\xc9\x80\x5e\x97\x6f\x45\x1e\x6d\x87\xf6\xfe\x10\x65\x14", }, { GCRY_CIPHER_AES128, "\x01\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", "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00", 20, "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00", 18, "\x44\xd0\xaa\xf6\xfb\x2f\x1f\x34\xad\xd5\xe8\x06\x4e\x83\xe1\x2a" "\x2a\xda", "\xbf\xf9\xb2\xef\x00\xfb\x47\x92\x0c\xc7\x2a\x0c\x0f\x13\xb9\xfd", }, { GCRY_CIPHER_AES128, "\xe6\x60\x21\xd5\xeb\x8e\x4f\x40\x66\xd4\xad\xb9\xc3\x35\x60\xe4", "\xf4\x6e\x44\xbb\x3d\xa0\x01\x5c\x94\xf7\x08\x87", "", 0, "", 0, "", "\xa4\x19\x4b\x79\x07\x1b\x01\xa8\x7d\x65\xf7\x06\xe3\x94\x95\x78", }, { GCRY_CIPHER_AES128, "\x36\x86\x42\x00\xe0\xea\xf5\x28\x4d\x88\x4a\x0e\x77\xd3\x16\x46", "\xba\xe8\xe3\x7f\xc8\x34\x41\xb1\x60\x34\x56\x6b", "\x46\xbb\x91\xc3\xc5", 5, "\x7a\x80\x6c", 3, "\xaf\x60\xeb", "\x71\x1b\xd8\x5b\xc1\xe4\xd3\xe0\xa4\x62\xe0\x74\xee\xa4\x28\xa8", }, { GCRY_CIPHER_AES128, "\xae\xdb\x64\xa6\xc5\x90\xbc\x84\xd1\xa5\xe2\x69\xe4\xb4\x78\x01", "\xaf\xc0\x57\x7e\x34\x69\x9b\x9e\x67\x1f\xdd\x4f", "\xfc\x88\x0c\x94\xa9\x51\x98\x87\x42\x96", 10, "\xbd\xc6\x6f\x14\x65\x45", 6, "\xbb\x93\xa3\xe3\x4d\x3c", "\xd6\xa9\xc4\x55\x45\xcf\xc1\x1f\x03\xad\x74\x3d\xba\x20\xf9\x66", }, { GCRY_CIPHER_AES128, "\xd5\xcc\x1f\xd1\x61\x32\x0b\x69\x20\xce\x07\x78\x7f\x86\x74\x3b", "\x27\x5d\x1a\xb3\x2f\x6d\x1f\x04\x34\xd8\x84\x8c", "\x04\x67\x87\xf3\xea\x22\xc1\x27\xaa\xf1\x95\xd1\x89\x47\x28", 15, "\x11\x77\x44\x1f\x19\x54\x95\x86\x0f", 9, "\x4f\x37\x28\x1f\x7a\xd1\x29\x49\xd0", "\x1d\x02\xfd\x0c\xd1\x74\xc8\x4f\xc5\xda\xe2\xf6\x0f\x52\xfd\x2b", }, { GCRY_CIPHER_AES128, "\xb3\xfe\xd1\x47\x3c\x52\x8b\x84\x26\xa5\x82\x99\x59\x29\xa1\x49", "\x9e\x9a\xd8\x78\x0c\x8d\x63\xd0\xab\x41\x49\xc0", "\xc9\x88\x2e\x53\x86\xfd\x9f\x92\xec\x48\x9c\x8f\xde\x2b\xe2\xcf" "\x97\xe7\x4e\x93", 20, "\x9f\x57\x2c\x61\x4b\x47\x45\x91\x44\x74\xe7\xc7", 12, "\xf5\x46\x73\xc5\xdd\xf7\x10\xc7\x45\x64\x1c\x8b", "\xc1\xdc\x2f\x87\x1f\xb7\x56\x1d\xa1\x28\x6e\x65\x5e\x24\xb7\xb0", }, { GCRY_CIPHER_AES128, "\x2d\x4e\xd8\x7d\xa4\x41\x02\x95\x2e\xf9\x4b\x02\xb8\x05\x24\x9b", "\xac\x80\xe6\xf6\x14\x55\xbf\xac\x83\x08\xa2\xd4", "\x29\x50\xa7\x0d\x5a\x1d\xb2\x31\x6f\xd5\x68\x37\x8d\xa1\x07\xb5" "\x2b\x0d\xa5\x52\x10\xcc\x1c\x1b\x0a", 25, "\x0d\x8c\x84\x51\x17\x80\x82\x35\x5c\x9e\x94\x0f\xea\x2f\x58", 15, "\xc9\xff\x54\x5e\x07\xb8\x8a\x01\x5f\x05\xb2\x74\x54\x0a\xa1", "\x83\xb3\x44\x9b\x9f\x39\x55\x2d\xe9\x9d\xc2\x14\xa1\x19\x0b\x0b", }, { GCRY_CIPHER_AES128, "\xbd\xe3\xb2\xf2\x04\xd1\xe9\xf8\xb0\x6b\xc4\x7f\x97\x45\xb3\xd1", "\xae\x06\x55\x6f\xb6\xaa\x78\x90\xbe\xbc\x18\xfe", "\x18\x60\xf7\x62\xeb\xfb\xd0\x82\x84\xe4\x21\x70\x2d\xe0\xde\x18" "\xba\xa9\xc9\x59\x62\x91\xb0\x84\x66\xf3\x7d\xe2\x1c\x7f", 30, "\x6b\x3d\xb4\xda\x3d\x57\xaa\x94\x84\x2b\x98\x03\xa9\x6e\x07\xfb" "\x6d\xe7", 18, "\x62\x98\xb2\x96\xe2\x4e\x8c\xc3\x5d\xce\x0b\xed\x48\x4b\x7f\x30" "\xd5\x80", "\x3e\x37\x70\x94\xf0\x47\x09\xf6\x4d\x7b\x98\x53\x10\xa4\xdb\x84", }, { GCRY_CIPHER_AES128, "\xf9\x01\xcf\xe8\xa6\x96\x15\xa9\x3f\xdf\x7a\x98\xca\xd4\x81\x79", "\x62\x45\x70\x9f\xb1\x88\x53\xf6\x8d\x83\x36\x40", "\x75\x76\xf7\x02\x8e\xc6\xeb\x5e\xa7\xe2\x98\x34\x2a\x94\xd4\xb2" "\x02\xb3\x70\xef\x97\x68\xec\x65\x61\xc4\xfe\x6b\x7e\x72\x96\xfa" "\x85\x9c\x21", 35, "\xe4\x2a\x3c\x02\xc2\x5b\x64\x86\x9e\x14\x6d\x7b\x23\x39\x87\xbd" "\xdf\xc2\x40\x87\x1d", 21, "\x39\x1c\xc3\x28\xd4\x84\xa4\xf4\x64\x06\x18\x1b\xcd\x62\xef\xd9" "\xb3\xee\x19\x7d\x05", "\x2d\x15\x50\x6c\x84\xa9\xed\xd6\x5e\x13\xe9\xd2\x4a\x2a\x6e\x70", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "", 0, "", "\x07\xf5\xf4\x16\x9b\xbf\x55\xa8\x40\x0c\xd4\x7e\xa6\xfd\x40\x0f", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00", 8, "\xc2\xef\x32\x8e\x5c\x71\xc8\x3b", "\x84\x31\x22\x13\x0f\x73\x64\xb7\x61\xe0\xb9\x74\x27\xe3\xdf\x28", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "\x9a\xab\x2a\xeb\x3f\xaa\x0a\x34\xae\xa8\xe2\xb1", "\x8c\xa5\x0d\xa9\xae\x65\x59\xe4\x8f\xd1\x0f\x6e\x5c\x9c\xa1\x7e", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, "\x85\xa0\x1b\x63\x02\x5b\xa1\x9b\x7f\xd3\xdd\xfc\x03\x3b\x3e\x76", "\xc9\xea\xc6\xfa\x70\x09\x42\x70\x2e\x90\x86\x23\x83\xc6\xc3\x66", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\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", 32, "\x4a\x6a\x9d\xb4\xc8\xc6\x54\x92\x01\xb9\xed\xb5\x30\x06\xcb\xa8" "\x21\xec\x9c\xf8\x50\x94\x8a\x7c\x86\xc6\x8a\xc7\x53\x9d\x02\x7f", "\xe8\x19\xe6\x3a\xbc\xd0\x20\xb0\x06\xa9\x76\x39\x76\x32\xeb\x5d", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\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" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 48, "\xc0\x0d\x12\x18\x93\xa9\xfa\x60\x3f\x48\xcc\xc1\xca\x3c\x57\xce" "\x74\x99\x24\x5e\xa0\x04\x6d\xb1\x6c\x53\xc7\xc6\x6f\xe7\x17\xe3" "\x9c\xf6\xc7\x48\x83\x7b\x61\xf6\xee\x3a\xdc\xee\x17\x53\x4e\xd5", "\x79\x0b\xc9\x68\x80\xa9\x9b\xa8\x04\xbd\x12\xc0\xe6\xa2\x2c\xc4", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\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" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 64, "\xc2\xd5\x16\x0a\x1f\x86\x83\x83\x49\x10\xac\xda\xfc\x41\xfb\xb1" "\x63\x2d\x4a\x35\x3e\x8b\x90\x5e\xc9\xa5\x49\x9a\xc3\x4f\x96\xc7" "\xe1\x04\x9e\xb0\x80\x88\x38\x91\xa4\xdb\x8c\xaa\xa1\xf9\x9d\xd0" "\x04\xd8\x04\x87\x54\x07\x35\x23\x4e\x37\x44\x51\x2c\x6f\x90\xce", "\x11\x28\x64\xc2\x69\xfc\x0d\x9d\x88\xc6\x1f\xa4\x7e\x39\xaa\x08", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00", 8, "\x1d\xe2\x29\x67\x23\x7a\x81\x32", "\x91\x21\x3f\x26\x7e\x3b\x45\x2f\x02\xd0\x1a\xe3\x3e\x4e\xc8\x54", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "\x16\x3d\x6f\x9c\xc1\xb3\x46\xcd\x45\x3a\x2e\x4c", "\xc1\xa4\xa1\x9a\xe8\x00\x94\x1c\xcd\xc5\x7c\xc8\x41\x3c\x27\x7f", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, "\xc9\x15\x45\x82\x3c\xc2\x4f\x17\xdb\xb0\xe9\xe8\x07\xd5\xec\x17", "\xb2\x92\xd2\x8f\xf6\x11\x89\xe8\xe4\x9f\x38\x75\xef\x91\xaf\xf7", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\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", 32, "\x07\xda\xd3\x64\xbf\xc2\xb9\xda\x89\x11\x6d\x7b\xef\x6d\xaa\xaf" "\x6f\x25\x55\x10\xaa\x65\x4f\x92\x0a\xc8\x1b\x94\xe8\xba\xd3\x65", "\xae\xa1\xba\xd1\x27\x02\xe1\x96\x56\x04\x37\x4a\xab\x96\xdb\xbc", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\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" "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 48, "\xc6\x7a\x1f\x0f\x56\x7a\x51\x98\xaa\x1f\xcc\x8e\x3f\x21\x31\x43" "\x36\xf7\xf5\x1c\xa8\xb1\xaf\x61\xfe\xac\x35\xa8\x64\x16\xfa\x47" "\xfb\xca\x3b\x5f\x74\x9c\xdf\x56\x45\x27\xf2\x31\x4f\x42\xfe\x25", "\x03\x33\x27\x42\xb2\x28\xc6\x47\x17\x36\x16\xcf\xd4\x4c\x54\xeb", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\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" "\x04\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", 64, "\x67\xfd\x45\xe1\x26\xbf\xb9\xa7\x99\x30\xc4\x3a\xad\x2d\x36\x96" "\x7d\x3f\x0e\x4d\x21\x7c\x1e\x55\x1f\x59\x72\x78\x70\xbe\xef\xc9" "\x8c\xb9\x33\xa8\xfc\xe9\xde\x88\x7b\x1e\x40\x79\x99\x88\xdb\x1f" "\xc3\xf9\x18\x80\xed\x40\x5b\x2d\xd2\x98\x31\x88\x58\x46\x7c\x89", "\x5b\xde\x02\x85\x03\x7c\x5d\xe8\x1e\x5b\x57\x0a\x04\x9b\x62\xa0", }, { GCRY_CIPHER_AES256, "\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "\x02\x00\x00\x00", 4, "\x22\xb3\xf4\xcd", "\x18\x35\xe5\x17\x74\x1d\xfd\xdc\xcf\xa0\x7f\xa4\x66\x1b\x74\xcf", }, { GCRY_CIPHER_AES256, "\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", "\x03\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" "\x02\x00", 18, "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00\x00\x00", 20, "\x43\xdd\x01\x63\xcd\xb4\x8f\x9f\xe3\x21\x2b\xf6\x1b\x20\x19\x76" "\x06\x7f\x34\x2b", "\xb8\x79\xad\x97\x6d\x82\x42\xac\xc1\x88\xab\x59\xca\xbf\xe3\x07", }, { GCRY_CIPHER_AES256, "\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", "\x03\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" "\x02\x00\x00\x00", 20, "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00", 18, "\x46\x24\x01\x72\x4b\x5c\xe6\x58\x8d\x5a\x54\xaa\xe5\x37\x55\x13" "\xa0\x75", "\xcf\xcd\xf5\x04\x21\x12\xaa\x29\x68\x5c\x91\x2f\xc2\x05\x65\x43", }, { GCRY_CIPHER_AES256, "\xe6\x60\x21\xd5\xeb\x8e\x4f\x40\x66\xd4\xad\xb9\xc3\x35\x60\xe4" "\xf4\x6e\x44\xbb\x3d\xa0\x01\x5c\x94\xf7\x08\x87\x36\x86\x42\x00", "\xe0\xea\xf5\x28\x4d\x88\x4a\x0e\x77\xd3\x16\x46", "", 0, "", 0, "", "\x16\x9f\xbb\x2f\xbf\x38\x9a\x99\x5f\x63\x90\xaf\x22\x22\x8a\x62", }, { GCRY_CIPHER_AES256, "\xba\xe8\xe3\x7f\xc8\x34\x41\xb1\x60\x34\x56\x6b\x7a\x80\x6c\x46" "\xbb\x91\xc3\xc5\xae\xdb\x64\xa6\xc5\x90\xbc\x84\xd1\xa5\xe2\x69", "\xe4\xb4\x78\x01\xaf\xc0\x57\x7e\x34\x69\x9b\x9e", "\x4f\xbd\xc6\x6f\x14", 5, "\x67\x1f\xdd", 3, "\x0e\xac\xcb", "\x93\xda\x9b\xb8\x13\x33\xae\xe0\xc7\x85\xb2\x40\xd3\x19\x71\x9d", }, { GCRY_CIPHER_AES256, "\x65\x45\xfc\x88\x0c\x94\xa9\x51\x98\x87\x42\x96\xd5\xcc\x1f\xd1" "\x61\x32\x0b\x69\x20\xce\x07\x78\x7f\x86\x74\x3b\x27\x5d\x1a\xb3", "\x2f\x6d\x1f\x04\x34\xd8\x84\x8c\x11\x77\x44\x1f", "\x67\x87\xf3\xea\x22\xc1\x27\xaa\xf1\x95", 10, "\x19\x54\x95\x86\x0f\x04", 6, "\xa2\x54\xda\xd4\xf3\xf9", "\x6b\x62\xb8\x4d\xc4\x0c\x84\x63\x6a\x5e\xc1\x20\x20\xec\x8c\x2c", }, { GCRY_CIPHER_AES256, "\xd1\x89\x47\x28\xb3\xfe\xd1\x47\x3c\x52\x8b\x84\x26\xa5\x82\x99" "\x59\x29\xa1\x49\x9e\x9a\xd8\x78\x0c\x8d\x63\xd0\xab\x41\x49\xc0", "\x9f\x57\x2c\x61\x4b\x47\x45\x91\x44\x74\xe7\xc7", "\x48\x9c\x8f\xde\x2b\xe2\xcf\x97\xe7\x4e\x93\x2d\x4e\xd8\x7d", 15, "\xc9\x88\x2e\x53\x86\xfd\x9f\x92\xec", 9, "\x0d\xf9\xe3\x08\x67\x82\x44\xc4\x4b", "\xc0\xfd\x3d\xc6\x62\x8d\xfe\x55\xeb\xb0\xb9\xfb\x22\x95\xc8\xc2", }, { GCRY_CIPHER_AES256, "\xa4\x41\x02\x95\x2e\xf9\x4b\x02\xb8\x05\x24\x9b\xac\x80\xe6\xf6" "\x14\x55\xbf\xac\x83\x08\xa2\xd4\x0d\x8c\x84\x51\x17\x80\x82\x35", "\x5c\x9e\x94\x0f\xea\x2f\x58\x29\x50\xa7\x0d\x5a", "\x0d\xa5\x52\x10\xcc\x1c\x1b\x0a\xbd\xe3\xb2\xf2\x04\xd1\xe9\xf8" "\xb0\x6b\xc4\x7f", 20, "\x1d\xb2\x31\x6f\xd5\x68\x37\x8d\xa1\x07\xb5\x2b", 12, "\x8d\xbe\xb9\xf7\x25\x5b\xf5\x76\x9d\xd5\x66\x92", "\x40\x40\x99\xc2\x58\x7f\x64\x97\x9f\x21\x82\x67\x06\xd4\x97\xd5", }, { GCRY_CIPHER_AES256, "\x97\x45\xb3\xd1\xae\x06\x55\x6f\xb6\xaa\x78\x90\xbe\xbc\x18\xfe" "\x6b\x3d\xb4\xda\x3d\x57\xaa\x94\x84\x2b\x98\x03\xa9\x6e\x07\xfb", "\x6d\xe7\x18\x60\xf7\x62\xeb\xfb\xd0\x82\x84\xe4", "\xf3\x7d\xe2\x1c\x7f\xf9\x01\xcf\xe8\xa6\x96\x15\xa9\x3f\xdf\x7a" "\x98\xca\xd4\x81\x79\x62\x45\x70\x9f", 25, "\x21\x70\x2d\xe0\xde\x18\xba\xa9\xc9\x59\x62\x91\xb0\x84\x66", 15, "\x79\x35\x76\xdf\xa5\xc0\xf8\x87\x29\xa7\xed\x3c\x2f\x1b\xff", "\xb3\x08\x0d\x28\xf6\xeb\xb5\xd3\x64\x8c\xe9\x7b\xd5\xba\x67\xfd", }, { GCRY_CIPHER_AES256, "\xb1\x88\x53\xf6\x8d\x83\x36\x40\xe4\x2a\x3c\x02\xc2\x5b\x64\x86" "\x9e\x14\x6d\x7b\x23\x39\x87\xbd\xdf\xc2\x40\x87\x1d\x75\x76\xf7", "\x02\x8e\xc6\xeb\x5e\xa7\xe2\x98\x34\x2a\x94\xd4", "\x9c\x21\x59\x05\x8b\x1f\x0f\xe9\x14\x33\xa5\xbd\xc2\x0e\x21\x4e" "\xab\x7f\xec\xef\x44\x54\xa1\x0e\xf0\x65\x7d\xf2\x1a\xc7", 30, "\xb2\x02\xb3\x70\xef\x97\x68\xec\x65\x61\xc4\xfe\x6b\x7e\x72\x96" "\xfa\x85", 18, "\x85\x7e\x16\xa6\x49\x15\xa7\x87\x63\x76\x87\xdb\x4a\x95\x19\x63" "\x5c\xdd", "\x45\x4f\xc2\xa1\x54\xfe\xa9\x1f\x83\x63\xa3\x9f\xec\x7d\x0a\x49", }, { GCRY_CIPHER_AES256, "\x3c\x53\x5d\xe1\x92\xea\xed\x38\x22\xa2\xfb\xbe\x2c\xa9\xdf\xc8" "\x82\x55\xe1\x4a\x66\x1b\x8a\xa8\x2c\xc5\x42\x36\x09\x3b\xbc\x23", "\x68\x80\x89\xe5\x55\x40\xdb\x18\x72\x50\x4e\x1c", "\x73\x43\x20\xcc\xc9\xd9\xbb\xbb\x19\xcb\x81\xb2\xaf\x4e\xcb\xc3" "\xe7\x28\x34\x32\x1f\x7a\xa0\xf7\x0b\x72\x82\xb4\xf3\x3d\xf2\x3f" "\x16\x75\x41", 35, "\xce\xd5\x32\xce\x41\x59\xb0\x35\x27\x7d\x4d\xfb\xb7\xdb\x62\x96" "\x8b\x13\xcd\x4e\xec", 21, "\x62\x66\x60\xc2\x6e\xa6\x61\x2f\xb1\x7a\xd9\x1e\x8e\x76\x76\x39" "\xed\xd6\xc9\xfa\xee", "\x9d\x6c\x70\x29\x67\x5b\x89\xea\xf4\xba\x1d\xed\x1a\x28\x65\x94", }, { 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", "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x4d\xb9\x23\xdc\x79\x3e\xe6\x49\x7c\x76\xdc\xc0\x3a\x98\xe1\x08", 32, "\xf3\xf8\x0f\x2c\xf0\xcb\x2d\xd9\xc5\x98\x4f\xcd\xa9\x08\x45\x6c" "\xc5\x37\x70\x3b\x5b\xa7\x03\x24\xa6\x79\x3a\x7b\xf2\x18\xd3\xea", "\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", }, { 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", "", 0, "\xeb\x36\x40\x27\x7c\x7f\xfd\x13\x03\xc7\xa5\x42\xd0\x2d\x3e\x4c" "\x00\x00\x00\x00\x00\x00\x00\x00", 24, "\x18\xce\x4f\x0b\x8c\xb4\xd0\xca\xc6\x5f\xea\x8f\x79\x25\x7b\x20" "\x88\x8e\x53\xe7\x22\x99\xe5\x6d", "\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", }, /* Large block testing */ { GCRY_CIPHER_AES128, "\x01\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", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x72\x94\x7b\x5d\x3c\x14\xc0\xa6\x27\x8d\x8d\xee\xbd\xe8\x8c\x6a" "\x21\x34\xce\x64\x8f\x01\x01\xc6\xe4\x5d\xed\x2e\xb9\xec\xac\x53" "\xf2\x07\xed\x60\xc8\xa2\x2f\x2e\x83\x0e\xf2\xbc\x42\x51\x24\x3b" "\x41\x4f\x26\x84\xf0\x25\x69\x3f\x38\x29\xfb\xe9\xbb\x1a\x94\xd1" "\x94\x0c\xce\xad\x8e\x66\xeb\xda\xc9\x1c\x72\x5a\x7f\x95\x4f\x9c" "\x02\x27\x79\x8f\xe7\x51\x51\x3d\x1e\x2c\x4e\xcd\x07\xe5\xd1\xf0" "\x6c\x95\x82\x37\x00\x50\x5e\xff\x82\xfb\x69\x0b\x4e\x7f\x10\x12" "\x7d\x18\x7f\xa8\x88\x59\xfb\x55\x9b\x70\x36\xfc\xde\x75\xed\x77" "\xf9\x09\x87\x29\x30\x7c\x81\x41\x12\xc2\xbd\xcd\x9f\x86\x98\x38" "\x96\x44\x4c\xda\x2e\xbe\x7a\xfb\xdd\x4a\x4e\xa0\x84\x94\xd5\x76" "\xa6\xae\x02\xcb\x1b\xd4\xd8\xcb\xa5\x24\x28\xe1\x3c\x1e\xdc\x3d" "\x25\x50\xe7\xfb\x92\xad\xd9\x80\x33\xe0\xb2\x50\x07\xd4\x43\x40" "\x41\x63\x98\x63\xa6\x1a\xfc\x56\x84\x3f\xf7\x4f\x31\xe7\xfe\xc5" "\x73\x52\xfd\x6d\x9b\xbb\x9b\xf8\x19\xf8\xdc\x9f\x3a\x88\xa6\x7c" "\xf3\x6b\xbe\xde\xda\x05\x2e\x79\x54\xb9\x3e\x59\x43\x0a\x1b\x16" "\xcf\x94\x97\x71\x03\x74\x12\x37\xaf\xd4\x0a\x4b\x30\x16\x9b\x8b" "\x9f\xae\x78\x46\x83\xde\x34\xc5\x31\x71\x67\x5e\xdb\x8d\x93\x71" "\x90\x03\x72\x00\x9f\x4e\x1e\x7d\xf3\x3f\xf8\x31\xe7\xf6\xb4\x6d" "\x8d\xdc\xa0\x85\x32\x7b\x32\x40\x8c\xa9\x90\x69\xac\x03\xdb\xd4" "\xa5\x62\x9c\xfd\x78\xde\xc8\x4a\x18\x67\xa0\xee\x5e\x1e\xad\x1a" "\x1c\xee\x78\xbd\xea\xdc\xc8\x34\xd1\x92\x20\xa7\x0d\x12\x90\x88" "\x91\xe4\x6c\x3c\x06\x78\x13\x00\xdc\xc7\x3e\xd7\x91\xf7\xc1\xd6" "\x5a\x99\x95\x23\xb5\xd8\x3d\x0f\x12\xaf\x25\xd8\xcf\xe8\x27\x7f" "\xbc\x7c\xe2\xad\x34\x66\x7f\xfb\xf5\xa8\x11\xc1\xe6\x04\x37\x41" "\xaf\x96\xb3\xb7\xee\x05\xf5\xd7\x7c\xc6\xfe\x2e\xa9\x07\x47\x08" "\xa4\x50\x65\xc0\x2e\xd7\x27\xd8\x70\x8c\xf1\x12\x30\x4a\x82\xf6" "\xb7\x68\xdb\x9d\x73\xc2\x82\x3d\x44\xda\xfb\xdd\x03\xc1\xdc\xfc" "\x3f\x7f\x2e\xe2\xd3\x73\x24\xaf\xd1\x35\xa9\x4f\x3a\xad\x9d\x5c" "\xd7\xc6\xa3\xb1\x11\xf1\xbb\xa0\x23\xe1\x22\x88\x5b\x10\xb3\xd6" "\x01\x78\x5f\x9e\x4d\x96\x7b\xeb\x81\x6b\xce\x2d\xf5\x6a\xd1\xa8" "\xb7\x56\xdd\xd0\x4b\xb0\xc9\x64\x7a\x2f\x63\xcb\xd6\x61\x84\x4b" "\x9e\x4d\x0b\x2c\x99\xbc\xa2\x94\xf5\x07\x20\xe6\xe9\xc2\xd2\xa6" "\x1c\x37\xd5\x88\x01\x71\xe2\x16\xcd\x10\x7a\x07\x8b\xf3\xb5\x49" "\x75\xbe\x0b\xe1\xb2\x28\x15\x88\x2b\xb4\xee\x34\xfd\x67\x30\xd8" "\xdc\x38\x90\x66\xb6\x51\x90\xb3\xdb\xee\x4e\x66\xc3\x05\xdf\xee" "\x32\xac\x8b\xa2\x00\xcc\xff\xa2\x52\x19\x79\x7e\x6c\xc9\x68\xb2" "\xab\xe4\x69\x11\xea\x00\xc9\x2b\x58\x77\x8b\x6c\x28\x0e\x40\x42" "\xcc\xa7\xb2\x58\xed\x5e\x0b\x19\x49\xe5\x5e\xb1\xb5\x24\x61\x63" "\x7d\x5b\x6a\x7d\x3d\xc1\x6e\x09\x64\x43\x66\x31\x3c\xb0\x26\x2e" "\xc8\x27\xf6\x5a\x5f\x22\x94\x42\x62\x2a\xf6\x5a\x7d\xc2\x4a\x0d" "\xd2\xad\xaa\x0e\xb2\xa4\x29\x1c\xb8\x3b\xaa\xc9\x1d\x1a\x30\xf8" "\x0b\x35\xb2\x84\x75\xc3\x08\x0c\xe5\x36\xa9\xff\xfe\xb9\xc2\xb7" "\x51\xab\x2d\x9d\x3e\x1c\x08\x8c\x6c\x64\xe1\xd9\x97\xf4\xfc\x4d" "\x77\x6d\x0e\xce\x73\x0b\x7f\x57\x41\xed\xdf\x96\x11\xb3\xcc\x61" "\xe8\x12\x31\x16\x72\x4c\x10\xd4\x52\x14\x4c\x83\xaa\x3c\x29\x6c" "\x51\x40\x9a\x4d\x9b\xd0\xe6\x7f\xad\x31\x54\x88\x90\xe1\xa8\x0e" "\xd8\xf4\x84\x11\xdb\x02\x41\xff\xb0\x8a\x92\x95\x97\xd6\x98\x8a" "\xa0\x43\xda\x70\xbb\x17\xd0\x5a\x81\x3e\xf7\xcf\xc9\x33\xd9\x76" "\x2f\x53\xa2\xac\xa0\x8a\x73\xe4\x0c\x81\xbe\x26\x01\x3f\x6d\x79" "\x8a\x37\x59\x5b\x0a\x9a\x10\x6b\x04\x30\xed\xda\x11\x73\x73\xd9" "\xa2\x9a\xf8\x8e\x67\x82\x5a\x8d\xc0\x52\xe8\x42\x89\xcd\x9c\xb1" "\x5c\x3d\xd4\x75\x03\x71\x03\x3f\xdc\x6b\x79\xb4\x02\xb6\xac\xc4" "\x11\x0f\x61\xc8\xf7\x5d\xc6\xbf\x48\x02\xa3\xdc\xa8\x37\x10\x85" "\xb2\x8d\xbd\xb0\x79\x09\xb0\x5f\x30\x6c\x40\xba\x03\xbb\x22\xcc" "\x80\xa1\xc3\x91\x88\x25\x92\xbe\xa6\xfa\x14\x77\x56\xb3\xc0\xb5" "\x69\x8c\x6f\xed\x21\xaf\x0c\x79\x07\x64\xa2\xea\xeb\x47\x2c\x1e" "\x7d\x6c\x12\xae\x75\xc4\xee\x12\x46\x72\x87\x65\x73\x51\xee\xf8" "\x08\x63\x20\xa1\x61\xca\x73\x8f\xdf\xcb\x97\xf8\xfc\xb0\x56\xea" "\x34\x9d\xce\xb8\x91\xb8\xfc\xec\x76\xd0\x71\xb7\x92\xc9\xb2\x28" "\xee\x0b\x5d\x7c\x4a\xf6\x73\x4d\xc2\x5b\x5b\xae\x7b\xa6\x9c\xba" "\x29\x7d\x7d\x3c\x29\x01\x04\x2d\xd1\x6c\x8d\x8d\xe5\xb4\x6b\xf9" "\x2a\x83\xb8\x14\x00\x1c\x91\x72\x5e\x8f\x13\x56\x6d\x9b\x6d\x27" "\xe8\x22\x55\x4b\x2f\x8a\x31\x16\x98\x03\x51\x73\xa7\x2e\x18\x81" "\x51\x0a\x8f\x6d\x17\xd0\xea\x04\x1c\x11\xb9\x6b\x8e\xaa\x76", 1023, "\x24\x28\x57\xa0\x3c\x12\xe2\x6a\x65\x97\x96\x75\xb3\x75\x67\x4c" "\xd0\xc8\xa7\x07\x7d\x55\x10\xbc\x11\xfe\x45\xbe\x74\x27\x74\xa3" "\x8b\xb8\x51\x0d\x2e\xf0\x0c\x83\xed\xe4\x8b\x15\xf2\xae\xd8\xd5" "\xed\xd8\x76\x0d\x0b\x5b\x7b\x5a\x17\x83\xf3\x37\xe5\x81\x90\xe8" "\x15\xb4\xec\xf8\x5a\x00\x72\xf2\xbb\x68\x0a\xc9\x6c\x4a\x80\x45" "\x04\xa5\x7e\xfa\xf3\x45\x08\x65\xd0\xd6\xcd\x08\xd1\x1f\x45\x6b" "\x23\xa9\x0f\xe1\x10\x90\x26\x48\x23\x23\xd2\x60\xc4\x16\x31\x03" "\x30\xbe\xf0\xd0\xa0\xa7\xcf\xaa\xe6\x27\x0e\xd6\x7b\x79\xf1\x2b" "\x29\x27\x57\x5a\xb7\xf5\xf8\xb4\x35\x3c\xb5\x10\xb8\xbf\xbe\xad" "\xdb\x9b\x3d\x35\x63\xac\x9b\xfe\x86\x69\x2c\x54\xf5\x7c\x7f\xd6" "\xcd\x33\x9f\x57\x7f\xce\x72\x18\x60\x2e\x20\x33\xc9\x13\x9f\x60" "\x5f\x67\x24\xc2\xbb\x9e\x63\x80\xcf\x96\xb9\xf0\xf1\x9e\xcc\x5a" "\x61\x02\x6d\xab\x4c\xf7\x13\xe4\x48\x0f\x9f\xc9\x24\x8e\x40\x06" "\x53\x30\xac\xd9\xe8\xf5\xcd\xd4\xcf\x99\x1f\x3c\x08\x74\x38\x7e" "\x0b\x76\x0d\xc3\xbd\x2a\x75\x3a\x55\x0c\xc6\xd3\x50\x59\x53\xf2" "\x14\x1d\x09\xb0\xfa\x8d\xc2\x5e\x6b\x79\xed\x5e\x10\xcc\x1c\xbe" "\x03\x75\x6d\x23\x44\xe8\xd6\x4d\x8f\xe4\xd6\x1a\x16\x83\x79\x72" "\xdc\x51\x25\x61\x75\xe7\x00\x09\xdf\xfe\x0c\x6c\x99\xa8\xb0\xfc" "\xbf\xb6\x7f\xae\x0a\x75\x2e\xd4\x69\xfe\xf1\xb7\x68\xbe\x07\xf0" "\x9c\xa3\x82\x1f\x4d\x06\xa7\x73\x53\xbd\x98\x99\x93\x1b\xc9\xb6" "\x04\x5e\xc0\xc1\xd8\x53\x7e\x6f\xd9\x4e\xa0\x37\xab\x71\x92\xc7" "\x97\x4b\x80\x40\x14\xd0\xd0\xee\x93\xfb\xd5\x76\xce\xd7\x9e\x74" "\xee\x5d\xe6\x79\xb2\x92\xbb\xff\x63\x19\x61\x64\xcc\x60\x80\x8b" "\x9c\x1f\x38\x01\x43\xf7\xa6\xcd\x20\x5d\x1d\x2a\x2a\x25\xf4\xd5" "\x17\x3d\x9c\xd2\x56\x8c\x76\x4e\xa0\xba\x24\x55\x55\xd4\x87\x78" "\xde\x30\xe8\x6f\x39\xa5\x22\x91\x2b\x7b\x20\x6f\xf6\x44\xff\xec" "\x29\x4e\xc8\x30\xf7\x23\x18\xef\xb8\x33\xfb\x5f\xf2\xe2\xd8\xc1" "\xe3\x0f\x24\x19\xff\x99\x7e\xa2\xdb\x78\xde\xc3\x92\x47\x9b\x32" "\xd6\xfa\xb7\x34\x14\xa4\xde\xd0\xa4\x6f\x7b\x03\x90\x80\x7a\x1e" "\xb7\xc7\xc3\x75\x98\xa6\x76\xfc\xa6\x38\xa3\xf6\x17\xe8\x90\x25" "\x28\x66\x41\x78\xe9\x70\x44\xbc\x62\x64\xf5\xaa\xd8\x62\x09\xf3" "\xff\x05\xd5\x4e\xea\x8d\xf0\x0e\x4e\x3c\x37\xbe\x30\xe6\x69\x15" "\xc5\x7b\xa6\x67\x1a\x74\xca\x4f\x0f\x5c\xf3\xac\x20\xaa\xc3\xad" "\xf5\xb3\x58\x8e\x22\x53\x3d\xe8\x0a\x1b\x33\x88\xf1\x8d\x9c\xc8" "\x5a\xb6\xd3\xde\x1a\x7a\x21\x12\x1e\x70\x0e\x52\x90\x24\xe0\x1c" "\xaa\x04\x79\xbc\x58\x42\xcb\xe1\x42\x82\xbe\xeb\x17\xd6\xd9\x8c" "\xc5\xe8\x77\xde\x77\xb5\x31\xf5\x7f\x09\x8b\x7d\x59\x6e\xbd\xe0" "\x7b\x0f\xe6\x29\x37\x7b\x19\x90\x69\x33\x0a\xbe\x50\xa5\x11\xba" "\xc5\x90\x78\x31\xfc\x1e\x6c\x8e\x50\x99\x2b\xd9\x50\x39\xaa\x80" "\x19\x59\xae\x1e\x7a\x7d\xea\xbe\x92\x0e\xc1\xd4\x99\x71\x50\xb2" "\x46\x0e\x39\x73\x45\x92\x8e\xd7\xb3\xcd\xf7\x37\x8e\x78\x2b\x2b" "\xba\x33\xc1\x3e\xdd\xac\x9d\x09\xcd\xb0\x7e\x78\x05\x70\x44\x98" "\x8d\xcd\xf3\xf4\x55\x07\x6a\x75\x66\x6a\xd2\xf2\x4a\x95\x6b\x07" "\xfc\x8d\x6d\xe9\x40\xc5\x94\x19\xb5\x29\x5c\xaa\xb0\x7b\x2b\x8d" "\x64\x41\xfd\x10\x58\xba\x6c\x1f\x7e\x88\x5f\x77\x8c\xe0\x3a\xda" "\x7d\xed\xc4\xf1\x30\xce\x8d\x47\xd8\xe2\x8c\xca\xea\xf8\xb7\x73" "\x9d\xb4\xfc\x06\x09\x17\x20\x00\x96\xe4\xd2\x07\x01\x10\x44\xef" "\x7e\x18\x74\xac\xba\xe3\x26\x0d\x11\x27\xbf\xf3\xbb\x06\x1c\x49" "\xd7\xae\x79\xe1\xaf\xd8\x66\x48\x03\xb6\x08\x66\x79\x11\xc5\x68" "\x47\xbc\x4b\xfe\xc4\xa6\x7b\x3a\x66\xcd\x9f\x93\x70\xc2\x42\xd9" "\xac\x54\x36\x73\x1b\x3a\x89\x1f\x13\xc7\x63\x9e\x43\xbf\xdd\xd7" "\x54\xc7\xda\x6f\x74\x83\x81\x27\x19\xb3\xde\x1a\x14\xec\x0b\x96" "\xee\x12\x02\xd1\x9f\x30\xe1\xef\xb8\xb4\xe9\xa4\x72\xc1\x48\xbc" "\x23\x21\x64\x32\x0d\xac\x49\x6e\x53\x80\x37\x10\x2d\xcf\x6f\x11" "\xf3\xd0\xf3\x02\xb6\x9d\x6e\x3c\x44\x39\x4d\xee\x8b\x8f\xea\xfa" "\x20\xf4\x98\x67\x9c\xe3\x12\x82\xa8\xbe\x1c\x3a\x1c\x51\x81\x9d" "\xc0\xfe\x46\x79\xd0\x19\x6b\xf1\x5d\xbb\x4d\xde\x42\xc9\x72\x93" "\x62\x65\xb5\x88\xb1\x5f\x92\xfe\x56\x56\x58\xfb\x7a\x81\x7c\x02" "\xb0\xc0\x53\x84\x6f\x13\x20\x53\xec\x49\x93\xae\x7e\x3c\x3f\xdf" "\xe7\xba\xa0\x40\x24\x10\xd4\xe6\xf5\xed\x65\xd3\x21\x36\xb1\xe6" "\x11\x0a\x47\xbc\xd3\x21\x33\x30\x03\x37\x8c\x45\xe5\xdd\xb0\xd5" "\xcb\x80\x42\xdd\x84\xd6\x70\xf0\xbb\x5b\x44\xe0\x84\x8b\x83\x7c" "\xcb\xec\x6a\x28\xa3\xf3\x4a\x6c\x0d\xb0\x79\x34\x13\x10\x64\xfc" "\xee\x12\x55\x82\x25\x25\x30\xb9\xa6\xf8\x3c\x81\x36\xcd\xef", "\xce\xc3\x13\x6c\x40\x2a\xcc\x51\xa1\xce\xb3\xed\xe8\xa6\x5b\x04", } }; 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 taglen2; if (verbose) fprintf (stderr, " Starting GCM-SIV checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { /* The AES algorithm is allowed in FIPS mode */ if ((err = gcry_cipher_test_algo (tv[i].algo))) { fail ("aes-gcm-siv, gcry_cipher_test_algo failed: %s\n", gpg_strerror (err)); continue; } if (verbose) fprintf (stderr, " checking GCM-SIV 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_SIV, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_GCM_SIV, 0); if (err) { fail ("aes-gcm-siv, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen (tv[i].algo); if (!keylen) { fail ("aes-gcm-siv, 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-siv, 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, 12); if (!err) err = gcry_cipher_setiv (hdd, tv[i].nonce, 12); if (err) { fail ("aes-gcm-siv, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (tv[i].adlen >= 0) { err = gcry_cipher_authenticate (hde, tv[i].ad, tv[i].adlen); if (!err) err = gcry_cipher_authenticate (hdd, tv[i].ad, tv[i].adlen); if (err) { fail ("aes-gcm-siv, gcry_cipher_authenticate 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-siv, 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-siv, 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; } if (tv[i].inlen) { err = gcry_cipher_encrypt (hde, out, tv[i].inlen, tv[i].plaintext, tv[i].inlen); if (err) { fail ("aes-gcm-siv, 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)) { mismatch (tv[i].out, tv[i].inlen, out, tv[i].inlen); fail ("aes-gcm-siv, encrypt mismatch entry %d\n", i); } err = gcry_cipher_gettag (hde, tag, taglen2); if (err) { fail ("aes-gcm-siv, 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, tag, taglen2)) { mismatch (tv[i].tag, taglen2, tag, taglen2); fail ("aes-gcm-siv, tag mismatch entry %d\n", i); } err = gcry_cipher_set_decryption_tag (hdd, tag, taglen2); if (err) { fail ("aes-gcm-siv, gcry_cipher_set_decryption_tag (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_decrypt (hdd, out, tv[i].inlen, NULL, 0); if (err) { fail ("aes-gcm-siv, 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 ("aes-gcm-siv, decrypt mismatch entry %d\n", i); err = gcry_cipher_checktag (hdd, tag, taglen2); if (err) { fail ("aes-gcm-siv, gcry_cipher_checktag (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } else { err = gcry_cipher_gettag (hde, tag, taglen2); if (err) { fail ("aes-gcm-siv, 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, tag, taglen2)) { mismatch (tv[i].tag, taglen2, tag, taglen2); fail ("aes-gcm-siv, tag mismatch entry %d\n", i); } err = gcry_cipher_checktag (hdd, tv[i].tag, taglen2); if (err) { fail ("aes-gcm-siv, gcry_cipher_checktag (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } tag[13] ^= 0x4; err = gcry_cipher_checktag (hdd, tag, taglen2); if (gpg_err_code (err) != GPG_ERR_CHECKSUM) { fail ("aes-gcm-siv, gcry_cipher_checktag (%d) expected checksum fail: %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 GCM-SIV checks.\n"); } 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" }, /* generated with c implementation */ { 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, "\xb0\x58\x83\x17\x3a\x8e\x69\xf2\x18\x9d\x71\xe4\x8a\x0b\x7a\xcd" "\xe2\xd8\xb9\x8b\xdf\x99\xc2\x6d\x05\x4b\x44\x1e\x65\x5d\xda\xd5" "\x79\xf0\x19\xab\x94\x50\xd0\xc5\x54\xfe\x76\xc8\xd9\xf3\x39\x33" "\x9c\x0f\x27\x89\x85\x99\xe3\xed\x5c\x31\x04\xa6\x20\xab\xb3\x78" "\xac\x31\xba\x21\x8c\xac\x70\xd1\xe2\x92\xd6\x50\x58\x69\xab\xd4" "\x38\xdc\x9c\x71\x81\xf7\xf1\x68\x10\x50\x07\x09\x0e\x51\x49\xd2" "\x10\x9a\x2e\x78\xfb\xc7\xd3\xc2\x84\xda\xf2\x52\x17\x2c\xa6\xe8" "\x56\x60\x80\x46\xed\xfb\x9f\xab\xc2\x01\xf0\x06\x6b\x6e\xcc\xf6" "\x55\x3e\x81\xc7\x71\x9f\x10\xf0\x8e\x5a\x4b\xf6\xae\x90\x75\x03" "\x4f\xb3\xb4\xff\x66\xfa\xe3\xb6\x1c\xca\x0c\x75\x8a\x08\x3d\xce" "\x58\x69\x9d\xa9\x19\x29\xda\x2f\xa1\xb2\xae\xa7\x83\xd5\x92\xc2" "\x15\xdc\xef\x76\xd2\xd1\x9f\xb4\x7f\x3e\xb3\x7a\xa8\x3e\xba\xa3" "\x9e\x2e\x73\xe3\x4d\xdc\x50\xba\x5b\xb0\x8b\x1a\x87\x21\x03\x93" "\x74\x20\x01\xda\x38\x85\x1c\x3c\x57\x51\x09\x0e\xd8\xfc\x2b\xef" "\x38\x8e\x11\xa4\x9e\x11\xcc\xc5\x9f\x4c\xc2\x0d\x3e\x5f\x73\x40" "\x5a\xf4\x5b\x57\x84\x6e\xc7\xd0\x8e\xad\x1c\x1b\xae\x59\xba\xf5" "\x77\xed\x44\x08\x9c\x9b\xfd\x88\xd9\x27\xe8\x43\xe8\xdd\x86\xfd" "\x05\x3a\xc2\x11\x88\x98\x87\xcb\xa1\x72\xc2\x52\x5c\xd1\x1a\x40" "\x80\xe2\x1e\xe8\x9b\x4e\x63\x9b\xfb\x58\x11\x44\x36\x35\x83\x9b" "\x20\x9b\x4b\x58\xef\x1f\xfa\xe1\xb0\xe0\xb8\x60\x87\x0b\xdb\x83" "\x6f\xeb\xc0\x80\x63\xa8\xc4\x22\x0f\x1d\xec\x9b\x44\xfa\xd3\x13" "\x75\xb0\xfe\x74\x3c\xde\x9e\xb4\x91\x72\xc5\xf6\x36\x14\x18\x2d" "\x15\x2e\x6b\x34\xcf\xed\x86\x4f\x1b\x56\xcf\x09\x8f\x3d\xd1\x8d" "\x01\x7c\xba\x6a\xf4\x82\xdc\xf6\x9e\xc9\x79\xd4\x9e\x50\xc2\x9a" "\x4f\x90\x10\x44\xd5\xcf\x6b\x1d\xb3\xce\x7c\xeb\x3f\x8f\xbc\xe6" "\x76\xad\x78\x97\xee\xaf\x66\x73\xe4\x11\xb9\x6c\xf4\xc1\x1a\x76" "\xd6\x54\x4c\x6c\x44\x58\xec\xd9\x8f\xf9\xc6\x7f\x71\x95\x04\xfe" "\x6b\x42\xd6\x4f\xc6\xa8\xc1\xfa\x1e\x2c\xf2\x49\x6a\x5a\xe5\x28" "\x34\x30\x05\xc1\x21\x3a\x5f\xfd\xaf\x61\x1f\xa0\x91\xd4\x17\xcf" "\x65\x9d\xf5\xdb\x4b\xc2\x3d\x12\xed\xe1\x4e\xf1\x34\x50\x13\xa7" "\x3f\xe6\x26\xcb\xc9\xb3\x64\x69\xa9\x82\x21\xec\x64\xa9\x2e\x83" "\xa9\x9d\xa0\xbe\x20\xef\x5f\x71\x45\xe7\x9f\x75\xa3\x72\x16\xef" "\x1b\xf7\x9a\x15\xe2\x75\x92\x39\xbb\xb1\x4f\x34\xf4\x88\x0d\xcf" "\xbf\xd6\xfe\x5d\x61\x14\x45\x83\xf9\x6a\x3e\x81\x0f\x14\x78\xda" "\x94\xe2\xce\x7d\x1c\x15\xd7\xe0\x95\x1d\xd8\x96\xc2\x11\xb1\x55" "\xae\xc6\x95\x43\x38\x0a\x01\xc2\x30\xb8\x1b\x12\x39\x98\x58\x20" "\xbd\x65\x50\x1d\x17\x13\x02\xb9\xe4\x88\x39\x72\xc8\x58\xa0\xa8" "\x8f\xb9\xc2\x78\x82\x3a\x56\xe8\x0d\xf9\x1b\xbb\xfb\xf0\x5b\xc4" "\x9a\x2d\xf0\xd5\x57\x6f\xce\x4b\xb6\x3e\x1b\xbf\x54\xb4\x3e\x4e" "\x52\x5c\x2e\x6b\x5e\x01\xd1\xb3\xb5\x16\x67\xe4\x16\xad\x3c\x4d" "\x1c\xb2\xc0\x54\xcc\xf9\xba\x11\x85\xdf\x43\x1a\xfb\x55\x9b\x88" "\x27\x9e\x17\x29\x41\x7d\x2a\xb4\xf6\x61\x93\xa5\x1f\x5b\xb3\x06" "\xbe\x86\x40\x11\xc6\xfc\x36\x44\xdb\xbf\x4c\x6b\x21\x15\xa9\x10" "\x01\xdc\x53\x9c\x57\x27\xbe\x55\x19\x86\x17\x96\xfa\xdc\x4d\xf4" "\xd9\x79\xbe\x6c\x29\x1b\xed\xbd\x09\x72\xb4\xbf\x88\xc7\x52\x39" "\x5f\x62\x35\xad\x41\x87\xa6\xaa\x99\x20\xbc\x7d\x97\x67\x83\xa5" "\xc3\x43\xc6\x7f\x31\xb9\x0c\xe1\x82\xa5\x66\x9a\x58\xe3\xaf\x6b" "\x59\x09\x5b\xad\xed\xc2\x57\x66\x4e\x72\xb0\xaa\x0d\xeb\x9c\x48" "\x3f\x0b\xaf\xc6\x46\x06\x54\x3a\x2a\x19\xb3\x9d\xde\xd9\xa0\xcf" "\x71\x69\x33\xe8\x2c\xa8\x56\x8c\x0b\xae\x41\xc7\xb5\xfd\xca\xea" "\x0f\xd1\xd7\xe0\x3e\xf6\xf5\xd1\xb2\x57\x21\x00\x32\xca\x02\x4d" "\x18\xbe\x2c\x25\xe9\xbe\x0a\x34\x44\x92\xaa\x43\x09\xf7\xb4\x35" "\xac\x65\xc3\xc1\x4c\x66\x74\x91\x9f\xae\xe2\x27\x37\x8a\xfe\x13" "\x57\xf0\x39\x30\xf0\x06\xef\xa0\x5f\x90\xb7\xfa\xd9\x42\x3e\xcb" "\xdc\x9c\x44\x36\x13\x8e\x66\xbc\x85\xe8\xfa\x2c\x73\xa5\x87\xbd" "\x63\x98\x42\x56\x1a\xe9\xc4\x80\xa1\x0e\xd5\x9a\x27\xd2\x82\x20" "\x08\xe5\x98\x60\x00\x6d\xd9\x53\x9b\xae\x67\xfb\x03\xff\x82\xf1" "\xc6\x9b\x0b\xf1\x2c\x97\x89\x1c\x8e\x84\xd0\xb3\x2a\x44\xa3\xb2" "\x77\x1d\xf2\x2e\x6a\xf7\x05\x67\x32\x21\xca\x39\x2e\x7f\x1a\x69" "\x21\xdd\xaa\xfc\x19\xad\xc5\xf8\xfe\x6f\x17\x9e\x32\x64\xf8\xeb" "\x98\x8a\x5e\x2e\x89\xea\xfb\xed\xd7\x09\x1a\x7f\xa5\xf6\xe3\xd4" "\x33\x60\xbb\xc2\x2b\x1a\xd6\x4c\x03\xe1\xc3\xc6\x90\x0e\x7a\x89" "\xe8\x50\x4b\x47\xc2\x91\x5d\x2a\x49\xf5\xb0\x5f\x69\xbb\x88\x51" "\x0c\xa2\xc0\x88\x99\x91\xcd\x77\x11\x31\x3a\x8f\x99\x03\xd7\x5e", 1024, "\x9d\x96\x71\x67\x3d\x66\x16\x72\x55\x29\x61\x42\x77\x99\x4a\x50" "\xdd\x2a\x80\x56\x8f\xb7\x50\x82\x80\x63\x47\x7b\xc1\x44\x3b\x02" "\x5b\xe8\x96\x93\x97\x6c\xff\x42\x90\x40\xf9\xe9\x93\xfe\x7e\xa3" "\x4c\xd9\xe8\xdc\xda\xf7\x8f\xcd\xe7\xa7\x1f\xaa\x7c\x8b\x07\xda" "\xf0\x70\x4d\x47\x8e\x87\x86\x71\x1e\x7a\x13\x7b\x9c\x42\x5d\x30" "\x0c\x04\xfb\x7b\xe0\x0e\xa7\xb1\x5c\x89\xf7\xdd\x81\x0a\xe0\xe4" "\xe2\x69\xa2\x36\x60\x45\x1c\xcc\x27\x2f\xaf\x70\x59\x6d\xc5\xb4" "\x40\x04\x69\x1d\xe8\xf3\xf5\x7e\x49\xd7\x81\x12\x5b\xd3\xc6\x77" "\x82\x5c\x9e\x91\x6b\x6b\x7d\xd7\x45\xb8\x39\x94\x0a\x1a\xb4\xc4" "\xff\xba\x05\x7b\x0b\xba\xe1\x81\x90\x29\xdd\xb5\x58\x0b\x1f\x82" "\x9e\x4d\xdd\x1b\xc1\x62\x14\x1a\x8f\xc1\x8c\xf6\x46\x07\xb2\xcd" "\x6a\xb5\xa1\x06\x4c\xc3\xa3\x3f\x02\x08\xe2\x29\x3c\x05\xbd\xcb" "\xf0\xfa\x27\xf1\x7b\x48\x45\x46\x62\x88\x01\xb8\xd3\x0a\x29\xbc" "\xd6\xbb\x20\xee\x75\x5f\x29\x0c\x47\x9e\x0f\x1d\xdf\x81\x39\x9a" "\x1c\x48\x69\x09\xeb\x42\xae\x71\x11\x4c\x53\x9c\x69\xa6\x71\x50" "\x45\x4d\x31\x71\xdd\xdb\xb1\x64\x37\xbf\x03\x76\xb2\x44\xf9\xbb" "\xa3\x25\x6b\xcf\xb0\x9f\x1d\x78\xdf\x93\xde\x2d\x57\x23\x6f\xff" "\x02\xf8\xc6\xf5\x5f\x4b\xd5\x8a\x15\xc2\x5f\x9d\x47\x3b\x2f\x8f" "\x36\x93\x4a\x96\xae\x57\xaa\xd7\x6e\xea\x45\x94\xfb\xa2\xab\x56" "\xae\x7e\xb3\xc5\x87\xa5\xd4\x2d\xf0\x99\x1e\x0a\x05\xb8\x33\xe4" "\x89\x6c\x9e\x6d\x8c\xf1\xb4\xaa\x1f\xaa\xfb\x4b\x40\x90\xc0\x50" "\xf3\x7d\x2a\x67\x68\x25\x0a\x9a\x89\x1f\x90\xfd\xb0\x9d\x7d\xaf" "\x72\x22\xeb\x22\xb9\x63\x5f\x2c\x54\x49\xa3\x99\xc4\x74\xab\xc0" "\x2c\x85\x31\x26\x84\x57\xfd\xce\x34\x10\x63\x57\x9f\x0c\x0a\xa3" "\x02\xb0\x87\x36\xf5\xf8\x1e\x66\x81\x74\x2c\x3e\x90\xc0\x10\xf1" "\x53\xd4\xc3\x45\x9b\xe2\x58\xcf\x86\x2e\xf4\xb3\x11\xff\xe6\xc8" "\x5c\x74\x6e\xb4\xd9\x52\x2c\x52\x71\x5e\xb4\xf1\xca\xa7\x1c\x09" "\x6a\x2d\xc0\x20\x38\xf5\x61\xdc\xd9\x8d\x42\x71\x65\xf8\xce\xa7" "\xcb\x2c\x44\x09\x87\x5a\x02\xdd\x8c\xe1\xec\xd0\xe1\xeb\x4d\x25" "\x70\x57\xbd\xc7\x1b\xee\xb5\xc0\x81\xc5\x75\x45\xb8\xb7\xad\xfd" "\x33\xdc\xbe\x09\x71\xd0\xd4\xee\xf7\x37\x4e\x6f\x80\x5f\xec\x3f" "\x35\x75\x39\xaa\x41\xe6\x62\x17\xc5\x8f\xa4\xa7\x31\xd6\xd5\xe9" "\x56\xc2\xc7\x1d\xf1\x58\xf6\xad\x3b\xbc\xbe\x65\x12\xd4\xfb\xe2" "\x0a\x5a\x64\x9e\xad\x70\x1d\x95\xbd\x24\x1a\xa9\x99\xc0\x70\x74" "\xb1\x79\x01\x4f\xfd\x5d\x76\xa7\xd9\x53\x3d\x87\x2b\x51\xb4\xf3" "\x17\xa5\x41\xe9\x8b\xba\xd3\x69\xcd\xe6\x44\x0f\x18\x8f\x59\x0d" "\xb0\xb8\x2a\x7f\xbb\x16\x51\xf5\xe8\xad\xda\x66\xaa\x3a\xb6\x7d" "\x10\x13\x8d\xd9\x7d\x15\x09\x80\x7b\x00\x67\x96\x90\x21\x3e\xd4" "\x1a\xe8\x3b\x1c\x78\x31\x9b\x63\x64\xb9\x1b\x50\x11\x93\x48\x13" "\x89\xcb\xba\x57\x23\xcd\x95\x95\xd5\xee\x8b\x0d\xb4\xdf\x0c\x8a" "\xae\xae\x55\x3f\x93\xad\xc1\x3e\xe5\x31\x20\x73\x58\xb0\x0b\xba" "\xf5\x03\x7b\x50\x39\xa3\x66\xa9\x82\x47\x65\x29\xa8\x49\xd7\x5c" "\x51\x89\x97\x03\x31\x11\x75\x83\x6e\x4e\x80\x2d\x57\x93\x88\xec" "\x0e\x22\xa8\xde\x50\x99\x2c\xaa\xaf\x60\x3a\x74\xa0\x31\x16\x37" "\xcd\x8a\x4d\xda\x40\x1d\x0c\xf1\xc4\x7a\xd0\xaa\xf4\xa7\x55\xe3" "\xa4\xe3\x9d\x27\x4f\x81\xc6\x07\x74\x13\x8e\x4b\xd9\x6c\x33\xba" "\x28\x8d\xb7\x79\x36\x29\xfc\x98\x91\x29\x87\xe7\xf6\x92\xb8\x7c" "\xe4\xca\xb7\x21\x49\x8c\x01\x59\xad\x65\x37\x62\x9b\xba\x40\xc1" "\x79\x87\xe5\x48\x58\xe3\x0e\x3a\xda\x31\x03\x55\x36\x64\x00\xda" "\x61\x8a\x0a\x93\xdc\x82\xcc\x63\x40\xb5\x46\xde\xf0\x8c\x3f\x6d" "\x3e\x32\xf2\xe6\x1d\x37\xf0\xd1\x7e\x33\x52\xb6\x97\xc3\x80\x64" "\xa4\x0d\x5f\x97\xa5\xd8\xa3\x47\x1a\x83\x1f\xd0\x52\x81\xb9\xd9" "\x7a\x32\xe6\xf1\x3e\x7d\xdc\x01\x5d\xb8\x44\x12\xc0\x1f\x72\x72" "\x8b\x0e\xfa\x05\x37\x73\xbd\xc4\x06\x67\x18\xd7\xd4\x80\x2c\x2c" "\x13\x06\xfe\x82\x5b\x65\x88\xe3\x0b\x06\x3c\xe6\xe4\xd0\x8f\x24" "\x6a\x6a\x4d\x21\x4c\x2d\x05\x76\x12\xf9\xee\xbf\xb5\x5e\xcd\x03" "\xf0\x5b\x35\x82\xb7\x1d\x7b\xca\xa6\x14\x40\x68\xd2\xa5\x49\x34" "\x69\xb7\x05\x48\xf9\xdb\x93\xd4\x0b\x45\x8d\xb3\x1e\xa3\xf9\x5d" "\x8c\x18\xc5\x40\x14\x67\xc5\x40\xbe\x61\x53\x74\x52\x94\x6c\x5e" "\xc6\xdf\xd0\xe7\xe5\xbd\x4b\xca\x89\xca\xf6\xf4\xc5\x6f\xf6\x87" "\x9e\x3a\x11\x5a\xa8\xcd\x83\x70\x19\x63\x8a\xaf\x08\xb1\x33\xa9" "\x2a\xcc\xde\x7f\xd2\x63\xfb\x85\x40\x77\x40\x8f\x9d\xa0\x7c\xed" "\x8d\xe5\xe5\x31\x05\x75\xf2\x7e\xab\x22\x54\xbf\xfe\xd3\x1f\x45" "\x95\x0d\x6d\x07\x6a\x90\x06\xd6\x45\x97\xc0\x82\x88\xfc\xd8\xd0", "\xf1\xef\xf4\x8d\x9c\xfa\x92\x10\xd9\x4f\x22\x3f\x2f\x75\xe1\x8b" }, }; gcry_cipher_hd_t hde, hdd; unsigned char out[2048]; 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 (gcry_cipher_test_algo (tv[i].algo)) { if (in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); } continue; } else if (in_fips_mode) { fail ("poly1305, gcry_cipher_test_algo worked in fips mode\n"); continue; } 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 flags; 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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, 0, /* 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"}, #if USE_CAMELLIA /* RFC 5528 */ { GCRY_CIPHER_CAMELLIA128, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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, FLAG_NOFIPS, /* 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"} #endif /* USE_CAMELLIA */ }; 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 ((err = gcry_cipher_test_algo (tv[i].algo))) { if (in_fips_mode && (tv[i].flags & FLAG_NOFIPS)) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); } else fail ("cipher-ccm, gcry_cipher_test_algo failed: %s\n", gpg_strerror (err)); continue; } else if (in_fips_mode && (tv[i].flags & FLAG_NOFIPS)) { fail ("cipher-ccm, gcry_cipher_test_algo unexpectedly worked\n"); 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[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); /* Verify the FIPS indicator marks this as non-approved */ if (in_fips_mode) { err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER, tv[tidx].algo, GCRY_CIPHER_MODE_OCB); if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) fail ("cipher-ocb, gcry_control did not fail as expected (tv %d): %s\n", tidx, gpg_strerror (err)); } 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, 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[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 += 16) { unsigned char hash[20]; unsigned char ctr[4]; ctr[0] = (i >> 0) & 0xff; ctr[1] = (i >> 8) & 0xff; ctr[2] = (i >> 16) & 0xff; ctr[3] = (i >> 24) & 0xff; gcry_md_hash_buffer (GCRY_MD_SHA1, hash, ctr, sizeof(ctr)); memcpy(inbuf + i, hash, 16); } if ((err = gcry_cipher_test_algo (algo))) { if (in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algo); } else fail ("cipher-ocb, gcry_cipher_test_algo failed (large, algo %d): %s\n", algo, gpg_strerror (err)); goto out_free; } /* Verify the FIPS indicator marks this as non-approved */ if (in_fips_mode) { err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER, algo, GCRY_CIPHER_MODE_OCB); if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) fail ("cipher-ocb, gcry_control did not fail as expected (large, algo %d): %s\n", algo, gpg_strerror (err)); } 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, hdd; unsigned char tag[16]; unsigned char tag2[16]; unsigned char tag3[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; } if ((err = gcry_cipher_test_algo (algo))) { if (in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algo); } else fail ("cipher-ocb, gcry_cipher_test_algo failed (checksum, algo %d): %s\n", algo, gpg_strerror (err)); goto out_free; } /* Verify the FIPS indicator marks this as non-approved */ if (in_fips_mode) { err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER, algo, GCRY_CIPHER_MODE_OCB); if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) fail ("cipher-ocb, gcry_control did not fail as expected (checksum, algo %d): %s\n", algo, gpg_strerror (err)); } 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) err = gcry_cipher_open (&hdd, 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) err = gcry_cipher_setkey (hdd, 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); gcry_cipher_close (hdd); goto out_free; } err = gcry_cipher_setiv (hde, nonce, 12); if (!err) err = gcry_cipher_setiv (hde2, nonce, 12); if (!err) err = gcry_cipher_setiv (hdd, 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); gcry_cipher_close (hdd); 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) { err = gcry_cipher_final (hdd); } if (!err) { err = gcry_cipher_decrypt (hdd, outbuf, buflen, outbuf, buflen); } 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); 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 (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)); } err = gcry_cipher_gettag (hdd, tag3, 16); if (err) { fail ("cipher_ocb, gcry_cipher_gettag failed (checksum3, 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); } if (memcmp (tag, tag3, 16)) { mismatch (tag, 16, tag3, 16); fail ("cipher-ocb, decrypt tag mismatch (checksum, algo %d)\n", algo); } gcry_cipher_close (hde); gcry_cipher_close (hde2); gcry_cipher_close (hdd); 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; /* Verify the FIPS indicator marks this as non-approved */ if (in_fips_mode) { err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OCB); if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) fail ("cipher-ocb-splitaad, gcry_control did not fail as expected: %s\n", gpg_strerror (err)); } 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, "\x4a\x00\x7f\x8d\xbe\x38\x32\x48\xb2\x2f\x7f\x27\xd8\x15\x7f\xb0"); check_ocb_cipher_largebuf(GCRY_CIPHER_AES256, 32, "\xec\xc5\xe9\x2b\x24\x91\xba\x64\xbc\xe3\x62\xb6\x83\x20\xad\xbd"); #if USE_CAMELLIA check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA128, 16, "\xd5\xbd\x76\xec\x75\x4a\xab\x6c\x13\xec\x87\x95\x11\xd4\xf0\x3d"); check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA192, 24, "\xde\xdd\x6b\xbf\xce\x15\x01\x39\x7c\xc5\x69\x19\x72\xa2\x67\x23"); check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA256, 32, "\x0c\xf3\xd5\x82\x20\x73\xee\x0f\xbd\x6b\x32\x38\xf9\x10\xef\xe5"); #endif /* USE_CAMELLIA */ #if USE_TWOFISH check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 16, "\x54\x87\x68\xb6\x17\xe6\xd7\xa6\x76\x0d\x7e\x9f\x57\x8b\xec\x88"); check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 32, "\x0b\xc3\x93\x52\xfa\x97\x22\xe6\x88\x6e\x29\x4d\x77\x35\x48\x84"); #endif /* USE_TWOFISH */ #if USE_SERPENT check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT128, 16, "\x7e\x49\x3b\xd6\xde\x6e\x9e\x53\x67\xcd\x00\xad\xc9\xd9\xa5\xbc"); check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT192, 24, "\x1e\x33\x0e\x06\xc8\x27\x6a\x0b\x41\x5e\x93\xae\x39\xf4\x50\x12"); check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT256, 32, "\x6b\x4c\x3f\x8f\x77\x75\xf2\x4d\xaf\xde\x2c\x5f\x1a\x80\xb8\x4d"); #endif /* USE_SERPENT */ #if USE_SM4 check_ocb_cipher_largebuf(GCRY_CIPHER_SM4, 16, "\x3c\x32\x54\x5d\xc5\x17\xa1\x16\x3f\x8e\xc7\x1d\x8d\x8b\x2d\xb0"); #endif /* USE_SM4 */ /* 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_basic (enum gcry_cipher_algos algo) { #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"); if ((err = gcry_cipher_test_algo (algo))) { if (in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algo); } else fail ("gost28147, gcry_cipher_test_algo failed: %s\n", gpg_strerror (err)); return; } else if (in_fips_mode) { fail ("gost28147, gcry_cipher_test_algo did not fail as expcected\n"); return; } keylen = gcry_cipher_get_algo_keylen(algo); 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, algo, GCRY_CIPHER_MODE_ECB, 0); if (!err) err = gcry_cipher_open (&hdd, algo, 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_gost28147_cipher (void) { check_gost28147_cipher_basic (GCRY_CIPHER_GOST28147); check_gost28147_cipher_basic (GCRY_CIPHER_GOST28147_MESH); } 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[] = { #if 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*/ #if 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 ((err = gcry_cipher_test_algo (tv[i].algo))) { if (in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); } else fail ("stream, gcry_cipher_test_algo: failed: %s\n", gpg_strerror (err)); continue; } else if (in_fips_mode) { fail ("stream, gcry_cipher_test_algo: did not fail as expected\n"); 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[] = { #if 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 ((err = gcry_cipher_test_algo (tv[i].algo))) { if (in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); } else fail ("stream, gcry_cipher_test_algo: failed: %s\n", gpg_strerror (err)); continue; } else if (in_fips_mode) { fail ("stream, gcry_cipher_test_algo: did not fail as expected\n"); 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_AES, GCRY_CIPHER_MODE_OFB, "abcdefghijklmnop", 16, "1234567890123456", 16, /*[17]*/ { 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, /*[18]*/ { 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, /*[19]*/ { 0x38, 0x8c, 0xe1, 0xe2, 0xbe, 0x67, 0x60, 0xe8, 0xeb, 0xce, 0xd0, 0xc6, 0xaa, 0xd6, 0xf6, 0x26, 0x15, 0x56, 0xd0, 0x2b } }, }; 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); /* Verify the FIPS indicator marks approved cipher/modes combinations */ if (in_fips_mode) { err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER, tv[i].algo, tv[i].mode); if (gpg_err_code (err) != GPG_ERR_NO_ERROR) fail ("gcry_control unexpectedly failed for algo = %s, mode = %d : %s\n", gcry_cipher_algo_name (tv[i].algo), tv[i].mode, gpg_strerror (err)); } 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; } clutter_vector_registers(); err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen); clutter_vector_registers(); 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; } clutter_vector_registers(); err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen); clutter_vector_registers(); 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)); clutter_vector_registers(); 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); clutter_vector_registers(); 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_CFB: case GCRY_CIPHER_MODE_CFB8: 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 unsigned int get_algo_mode_taglen (int algo, int mode) { switch (mode) { case GCRY_CIPHER_MODE_CCM: case GCRY_CIPHER_MODE_GCM: case GCRY_CIPHER_MODE_POLY1305: return 16; case GCRY_CIPHER_MODE_EAX: return gcry_cipher_get_algo_blklen(algo); } return 0; } 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) { clutter_vector_registers(); 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 split_mode, int pass) { gcry_cipher_hd_t hd; unsigned char *in_buffer, *out_buffer; unsigned char *enc_result; unsigned char tag_result[16]; unsigned char tag[16]; unsigned char *in, *out; int keylen; gcry_error_t err = 0; unsigned int blklen; unsigned int piecelen; unsigned int pos; unsigned int taglen; in_buffer = malloc (nplain + 1); out_buffer = malloc (nplain + 1); enc_result = malloc (nplain); if (!in_buffer || !out_buffer || !enc_result) { fail ("pass %d, algo %d, mode %d, malloc failed\n", pass, algo, mode); goto err_out_free; } blklen = get_algo_mode_blklen(algo, mode); taglen = get_algo_mode_taglen(algo, mode); assert (nkey == 64); assert (nplain > 0); assert ((nplain % 16) == 0); 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); goto err_out_free; } if (keylen < 40 / 8 || keylen > 32) { fail ("pass %d, algo %d, mode %d, keylength problem (%d)\n", pass, algo, mode, keylen); goto err_out_free; } 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)); goto err_out_free; } clutter_vector_registers(); 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); goto err_out_free; } if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) goto err_out_free; clutter_vector_registers(); err = gcry_cipher_encrypt (hd, out, nplain, plain, nplain); if (in_fips_mode && mode == GCRY_CIPHER_MODE_GCM) { if (!err) fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt is expected to " "fail in FIPS mode: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } 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); goto err_out_free; } if (taglen > 0) { clutter_vector_registers(); err = gcry_cipher_gettag (hd, tag, taglen); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_gettag failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } memcpy(tag_result, tag, taglen); } memcpy (enc_result, out, nplain); if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) goto err_out_free; clutter_vector_registers(); 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); goto err_out_free; } if (taglen > 0) { clutter_vector_registers(); err = gcry_cipher_checktag (hd, tag_result, taglen); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_checktag failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } } 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) goto err_out_free; memcpy (out, plain, nplain); clutter_vector_registers(); 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); goto err_out_free; } if (taglen > 0) { err = gcry_cipher_gettag (hd, tag, taglen); if (err) { fail ("pass %d, algo %d, mode %d, in-place, " "gcry_cipher_gettag failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } if (memcmp (tag_result, tag, taglen)) fail ("pass %d, algo %d, mode %d, in-place, tag mismatch\n", pass, algo, mode); } 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) goto err_out_free; clutter_vector_registers(); 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); goto err_out_free; } if (taglen > 0) { clutter_vector_registers(); err = gcry_cipher_checktag (hd, tag_result, taglen); if (err) { fail ("pass %d, algo %d, mode %d, in-place, " "gcry_cipher_checktag failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } } 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) goto err_out_free; piecelen = blklen; pos = 0; while (pos < nplain) { if (piecelen > nplain - pos) piecelen = nplain - pos; clutter_vector_registers(); 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); goto err_out_free; } pos += piecelen; piecelen = split_mode == 1 ? (piecelen + blklen) : (piecelen * 2 - ((piecelen != blklen) ? blklen : 0)); } if (taglen > 0) { clutter_vector_registers(); err = gcry_cipher_gettag (hd, tag, taglen); if (err) { fail ("pass %d, algo %d, mode %d, split-buffer (pos: %d, " "piecelen: %d), gcry_cipher_gettag failed: %s\n", pass, algo, mode, pos, piecelen, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } if (memcmp (tag_result, tag, taglen)) fail ("pass %d, algo %d, mode %d, in-place, tag mismatch\n", pass, algo, mode); } 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) goto err_out_free; piecelen = blklen; pos = 0; while (pos < nplain) { if (piecelen > nplain - pos) piecelen = nplain - pos; clutter_vector_registers(); 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); goto err_out_free; } pos += piecelen; piecelen = split_mode == 1 ? (piecelen + blklen) : (piecelen * 2 - ((piecelen != blklen) ? blklen : 0)); } if (taglen > 0) { clutter_vector_registers(); err = gcry_cipher_checktag (hd, tag_result, taglen); if (err) { fail ("pass %d, algo %d, mode %d, split-buffer (pos: %d, " "piecelen: %d), gcry_cipher_checktag failed: %s\n", pass, algo, mode, pos, piecelen, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } } 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) goto err_out_free; piecelen = blklen; pos = 0; while (pos < nplain) { if (piecelen > nplain - pos) piecelen = nplain - pos; memcpy (out + pos, plain + pos, piecelen); clutter_vector_registers(); 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); goto err_out_free; } pos += piecelen; piecelen = split_mode == 1 ? (piecelen + blklen) : (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) goto err_out_free; piecelen = blklen; pos = 0; while (pos < nplain) { if (piecelen > nplain - pos) piecelen = nplain - pos; clutter_vector_registers(); 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); goto err_out_free; } pos += piecelen; piecelen = split_mode == 1 ? (piecelen + blklen) : (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); free (enc_result); free (out_buffer); free (in_buffer); return 0; err_out_free: free (enc_result); free (out_buffer); free (in_buffer); return -1; } static int check_one_cipher_ctr_reset (gcry_cipher_hd_t hd, int algo, int mode, u32 ctr_high_bits, int be_ctr, int pass) { unsigned char iv[16] = { 0 }; unsigned char swap; unsigned int ivlen; u32 ctr_low_bits; int err; int i; /* This should be largest parallel block processing count in any * implementation negated. Currently for CTR this is 32 and, for * ChaCha20, count is 8. */ ctr_low_bits = (mode == GCRY_CIPHER_MODE_CTR) ? -32 : -8; gcry_cipher_reset (hd); if (mode == GCRY_CIPHER_MODE_CTR) ivlen = get_algo_mode_blklen(algo, GCRY_CIPHER_MODE_ECB); else ivlen = 16; /* Little-endian fill. */ for (i = 0; i < 4; i++) iv[i + 0] = (ctr_low_bits >> (i * 8)) & 0xff; for (i = 0; i < 4; i++) iv[i + 4] = (ctr_high_bits >> (i * 8)) & 0xff; if (be_ctr) { /* Swap to big-endian. */ for (i = 0; i < ivlen / 2; i++) { swap = iv[i]; iv[i] = iv[ivlen - (i + 1)]; iv[ivlen - (i + 1)] = swap; } } clutter_vector_registers(); if (mode == GCRY_CIPHER_MODE_CTR) err = gcry_cipher_setctr (hd, iv, ivlen); else err = gcry_cipher_setiv (hd, iv, ivlen); 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; } return 0; } static int check_one_cipher_ctr_overflow (int algo, int mode, int flags, const char *key, size_t nkey, const unsigned char *plain, size_t nplain, unsigned long ctr_high_bits, int be_ctr, int pass) { gcry_cipher_hd_t hd; unsigned char *out; unsigned char *enc_result; int keylen; gcry_error_t err = 0; unsigned int firstlen; unsigned int leftlen; unsigned int blklen; unsigned int pos; unsigned int i; out = malloc (nplain); enc_result = malloc (nplain); if (!out || !enc_result) { fail ("pass %d, algo %d, mode %d, malloc failed\n", pass, algo, mode); goto err_out_free; } assert (nkey == 64); assert (nplain > 0); assert ((nplain % 16) == 0); 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); goto err_out_free; } if (keylen < 40 / 8 || keylen > 32) { fail ("pass %d, algo %d, mode %d, keylength problem (%d)\n", pass, algo, mode, keylen); goto err_out_free; } 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)); goto err_out_free; } clutter_vector_registers(); 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); goto err_out_free; } if (check_one_cipher_ctr_reset (hd, algo, mode, ctr_high_bits, be_ctr, pass) < 0) goto err_out_free; /* Non-bulk processing. */ for (i = 0; i < nplain; i += 16) { clutter_vector_registers(); err = gcry_cipher_encrypt (hd, out + i, 16, plain + i, 16); 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); goto err_out_free; } } memcpy (enc_result, out, nplain); /* Test with different bulk processing sizes. */ for (blklen = 2 * 16; blklen <= 32 * 16; blklen *= 2) { /* Move bulk processing start offset, test at different spots to * test bulk counter calculation throughly. */ for (firstlen = 16; firstlen < 8 * 64; firstlen += 16) { if (check_one_cipher_ctr_reset (hd, algo, mode, ctr_high_bits, be_ctr, pass) < 0) goto err_out_free; clutter_vector_registers(); err = gcry_cipher_encrypt (hd, out, firstlen, plain, firstlen); 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); goto err_out_free; } leftlen = nplain - firstlen; pos = firstlen; while (leftlen) { unsigned int currlen = leftlen > blklen ? blklen : leftlen; clutter_vector_registers(); err = gcry_cipher_encrypt (hd, out + pos, currlen, plain + pos, currlen); if (err) { fail ("pass %d, algo %d, mode %d, block len %d, first len %d," "gcry_cipher_encrypt failed: %s\n", pass, algo, mode, blklen, firstlen, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } pos += currlen; leftlen -= currlen; } if (memcmp (enc_result, out, nplain)) fail ("pass %d, algo %d, mode %d, block len %d, first len %d, " "encrypt mismatch\n", pass, algo, mode, blklen, firstlen); } } gcry_cipher_close (hd); free (enc_result); free (out); return 0; err_out_free: free (enc_result); free (out); return -1; } static void check_one_cipher (int algo, int mode, int flags) { size_t medium_buffer_size = 2048 - 16; size_t large_buffer_size = 64 * 1024 + 1024 - 16; char key[64+1]; unsigned char *plain; int bufshift, i; plain = malloc (large_buffer_size + 1); if (!plain) { fail ("pass %d, algo %d, mode %d, malloc failed\n", -1, algo, mode); return; } 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 < medium_buffer_size; 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, medium_buffer_size, bufshift, 0, 0+10*bufshift)) goto out; /* Pass 1: Key not aligned. */ memmove (key+1, key, 64); if (check_one_cipher_core (algo, mode, flags, key+1, 64, plain, medium_buffer_size, bufshift, 0, 1+10*bufshift)) goto out; /* Pass 2: Key not aligned and data not aligned. */ memmove (plain+1, plain, medium_buffer_size); if (check_one_cipher_core (algo, mode, flags, key+1, 64, plain+1, medium_buffer_size, bufshift, 0, 2+10*bufshift)) goto out; /* 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, medium_buffer_size, bufshift, 0, 3+10*bufshift)) goto out; } /* Pass 5: Large buffer test. */ memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF_" "0123456789abcdef.,;/[]{}-=ABCDEF", 64); memcpy (plain, "foobar42FOOBAR17", 16); for (i = 16; i < large_buffer_size; 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, large_buffer_size, bufshift, 0, 50)) goto out; if (check_one_cipher_core (algo, mode, flags, key, 64, plain, large_buffer_size, bufshift, 1, 51)) goto out; /* Pass 6: Counter overflow tests for ChaCha20 and CTR mode. */ if (mode == GCRY_CIPHER_MODE_STREAM && algo == GCRY_CIPHER_CHACHA20) { /* 32bit overflow test (little-endian counter) */ if (check_one_cipher_ctr_overflow (algo, mode, flags, key, 64, plain, medium_buffer_size, 0UL, 0, 60)) goto out; /* 64bit overflow test (little-endian counter) */ if (check_one_cipher_ctr_overflow (algo, mode, flags, key, 64, plain, medium_buffer_size, 0xffffffffUL, 0, 61)) goto out; } else if (mode == GCRY_CIPHER_MODE_CTR) { /* 32bit overflow test (big-endian counter) */ if (check_one_cipher_ctr_overflow (algo, mode, flags, key, 64, plain, medium_buffer_size, 0UL, 1, 62)) goto out; /* 64bit overflow test (big-endian counter) */ if (check_one_cipher_ctr_overflow (algo, mode, flags, key, 64, plain, medium_buffer_size, 0xffffffffUL, 1, 63)) goto out; } out: free (plain); } +static void buf_xor(void *vdst, const void *vsrc1, const void *vsrc2, size_t len) +{ + char *dst = vdst; + const char *src1 = vsrc1; + const char *src2 = vsrc2; + + while (len) + { + *(char *)dst = *(char *)src1 ^ *(char *)src2; + dst++; + src1++; + src2++; + len--; + } +} + +/* Run the tests for -CBC-, tests bulk CBC + decryption. Returns NULL on success. */ +static int +cipher_cbc_bulk_test (int cipher_algo) +{ + const int nblocks = 128 - 1; + int i, offs; + int blocksize; + const char *cipher; + gcry_cipher_hd_t hd_one; + gcry_cipher_hd_t hd_cbc; + gcry_error_t err = 0; + unsigned char *plaintext, *plaintext2, *ciphertext, *iv, *iv2, *mem; + unsigned int memsize; + unsigned int keylen; + + static const unsigned char key[32] = { + 0x66,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, + 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x22, + 0x66,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, + 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x22 + }; + + if (gcry_cipher_test_algo (cipher_algo)) + return -1; + blocksize = gcry_cipher_get_algo_blklen(cipher_algo); + if (blocksize < 8) + return -1; + cipher = gcry_cipher_algo_name (cipher_algo); + keylen = gcry_cipher_get_algo_keylen (cipher_algo); + if (keylen > sizeof(key)) + { + fail ("%s-CBC-%d test failed (key too short)", cipher, blocksize * 8); + return -1; + } + + memsize = (blocksize * 2) + (blocksize * nblocks * 3) + 16; + + mem = xcalloc (1, memsize); + if (!mem) + return -1; + + offs = (16 - ((uintptr_t)mem & 15)) & 15; + iv = (void*)(mem + offs); + iv2 = iv + blocksize; + plaintext = iv2 + blocksize; + plaintext2 = plaintext + nblocks * blocksize; + ciphertext = plaintext2 + nblocks * blocksize; + + err = gcry_cipher_open (&hd_one, cipher_algo, GCRY_CIPHER_MODE_ECB, 0); + if (err) + { + xfree(mem); + fail ("%s-CBC-%d test failed (cipher open fail)", cipher, blocksize * 8); + return -1; + } + err = gcry_cipher_open (&hd_cbc, cipher_algo, GCRY_CIPHER_MODE_CBC, 0); + if (err) + { + gcry_cipher_close (hd_one); + xfree(mem); + fail ("%s-CBC-%d test failed (cipher open fail)", cipher, blocksize * 8); + return -1; + } + + /* Initialize ctx */ + if (gcry_cipher_setkey (hd_one, key, keylen) || + gcry_cipher_setkey (hd_cbc, key, keylen)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cbc); + xfree(mem); + fail ("%s-CBC-%d test failed (setkey fail)", cipher, blocksize * 8); + return -1; + } + + /* Test single block code path */ + memset (iv, 0x4e, blocksize); + memset (iv2, 0x4e, blocksize); + for (i = 0; i < blocksize; i++) + plaintext[i] = i; + + /* CBC manually. */ + buf_xor (ciphertext, iv, plaintext, blocksize); + err = gcry_cipher_encrypt (hd_one, ciphertext, blocksize, + ciphertext, blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cbc); + xfree(mem); + fail ("%s-CBC-%d test failed (ECB encrypt fail)", cipher, blocksize * 8); + return -1; + } + memcpy (iv, ciphertext, blocksize); + + /* CBC decrypt. */ + err = gcry_cipher_setiv (hd_cbc, iv2, blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cbc); + xfree(mem); + fail ("%s-CBC-%d test failed (setiv fail)", cipher, blocksize * 8); + return -1; + } + err = gcry_cipher_decrypt (hd_cbc, plaintext2, blocksize * 1, + ciphertext, blocksize * 1); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cbc); + xfree(mem); + fail ("%s-CBC-%d test failed (CBC decrypt fail)", cipher, blocksize * 8); + return -1; + } + + if (memcmp (plaintext2, plaintext, blocksize)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cbc); + xfree (mem); + fail ("%s-CBC-%d test failed (plaintext mismatch)", cipher, blocksize * 8); + return -1; + } + +#if 0 /* missing interface for reading IV */ + if (memcmp (iv2, iv, blocksize)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cbc); + xfree (mem); + fail ("%s-CBC-%d test failed (IV mismatch)", cipher, blocksize * 8); + return -1; + } +#endif + + /* Test parallelized code paths */ + memset (iv, 0x5f, blocksize); + memset (iv2, 0x5f, blocksize); + + for (i = 0; i < nblocks * blocksize; i++) + plaintext[i] = i; + + /* Create CBC ciphertext manually. */ + for (i = 0; i < nblocks * blocksize; i+=blocksize) + { + buf_xor (&ciphertext[i], iv, &plaintext[i], blocksize); + err = gcry_cipher_encrypt (hd_one, &ciphertext[i], blocksize, + &ciphertext[i], blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cbc); + xfree(mem); + fail ("%s-CBC-%d test failed (ECB encrypt fail)", cipher, blocksize * 8); + return -1; + } + memcpy (iv, &ciphertext[i], blocksize); + } + + /* Decrypt using bulk CBC and compare result. */ + err = gcry_cipher_setiv (hd_cbc, iv2, blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cbc); + xfree(mem); + fail ("%s-CBC-%d test failed (setiv fail)", cipher, blocksize * 8); + return -1; + } + err = gcry_cipher_decrypt (hd_cbc, plaintext2, blocksize * nblocks, + ciphertext, blocksize * nblocks); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cbc); + xfree(mem); + fail ("%s-CBC-%d test failed (CBC decrypt fail)", cipher, blocksize * 8); + return -1; + } + + if (memcmp (plaintext2, plaintext, nblocks * blocksize)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cbc); + xfree (mem); + fail ("%s-CBC-%d test failed (plaintext mismatch, parallel path)", + cipher, blocksize * 8); + return -1; + } +#if 0 /* missing interface for reading IV */ + if (memcmp (iv2, iv, blocksize)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cbc); + xfree (mem); + fail ("%s-CBC-%d test failed (IV mismatch, parallel path)", + cipher, blocksize * 8); + return -1; + } +#endif + + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cbc); + xfree (mem); + return -1; +} + + +static void +buf_xor_2dst(void *vdst1, void *vdst2, const void *vsrc, size_t len) +{ + byte *dst1 = vdst1; + byte *dst2 = vdst2; + const byte *src = vsrc; + + for (; len; len--) + *dst1++ = (*dst2++ ^= *src++); +} + +/* Run the tests for -CFB-, tests bulk CFB + decryption. Returns NULL on success. */ +static int +cipher_cfb_bulk_test (int cipher_algo) +{ + const int nblocks = 128 - 1; + int blocksize; + const char *cipher; + gcry_cipher_hd_t hd_one; + gcry_cipher_hd_t hd_cfb; + gcry_error_t err = 0; + int i, offs; + unsigned char *plaintext, *plaintext2, *ciphertext, *iv, *iv2, *mem; + unsigned int memsize; + unsigned int keylen; + + static const unsigned char key[32] = { + 0x11,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, + 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x33, + 0x11,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, + 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x33 + }; + + if (gcry_cipher_test_algo (cipher_algo)) + return -1; + blocksize = gcry_cipher_get_algo_blklen(cipher_algo); + if (blocksize < 8) + return -1; + cipher = gcry_cipher_algo_name (cipher_algo); + keylen = gcry_cipher_get_algo_keylen (cipher_algo); + if (keylen > sizeof(key)) + { + fail ("%s-CFB-%d test failed (key too short)", cipher, blocksize * 8); + return -1; + } + + memsize = (blocksize * 2) + (blocksize * nblocks * 3) + 16; + + mem = xcalloc (1, memsize); + if (!mem) + return -1; + + offs = (16 - ((uintptr_t)mem & 15)) & 15; + iv = (void*)(mem + offs); + iv2 = iv + blocksize; + plaintext = iv2 + blocksize; + plaintext2 = plaintext + nblocks * blocksize; + ciphertext = plaintext2 + nblocks * blocksize; + + err = gcry_cipher_open (&hd_one, cipher_algo, GCRY_CIPHER_MODE_ECB, 0); + if (err) + { + xfree(mem); + fail ("%s-CFB-%d test failed (cipher open fail)", cipher, blocksize * 8); + return -1; + } + err = gcry_cipher_open (&hd_cfb, cipher_algo, GCRY_CIPHER_MODE_CFB, 0); + if (err) + { + gcry_cipher_close (hd_one); + xfree(mem); + fail ("%s-CFB-%d test failed (cipher open fail)", cipher, blocksize * 8); + return -1; + } + + /* Initialize ctx */ + if (gcry_cipher_setkey (hd_one, key, keylen) || + gcry_cipher_setkey (hd_cfb, key, keylen)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cfb); + xfree(mem); + fail ("%s-CFB-%d test failed (setkey fail)", cipher, blocksize * 8); + return -1; + } + + /* Test single block code path */ + memset(iv, 0xd3, blocksize); + memset(iv2, 0xd3, blocksize); + for (i = 0; i < blocksize; i++) + plaintext[i] = i; + + /* CFB manually. */ + err = gcry_cipher_encrypt (hd_one, ciphertext, blocksize, iv, blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cfb); + xfree(mem); + fail ("%s-CFB-%d test failed (ECB encrypt fail)", cipher, blocksize * 8); + return -1; + } + buf_xor_2dst (iv, ciphertext, plaintext, blocksize); + + /* CFB decrypt. */ + err = gcry_cipher_setiv (hd_cfb, iv2, blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cfb); + xfree(mem); + fail ("%s-CFB-%d test failed (setiv fail)", cipher, blocksize * 8); + return -1; + } + err = gcry_cipher_decrypt (hd_cfb, plaintext2, blocksize * 1, + ciphertext, blocksize * 1); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cfb); + xfree(mem); + fail ("%s-CFB-%d test failed (CFB decrypt fail)", cipher, blocksize * 8); + return -1; + } + if (memcmp(plaintext2, plaintext, blocksize)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cfb); + xfree(mem); + fail ("%s-CFB-%d test failed (plaintext mismatch)", + cipher, blocksize * 8); + return -1; + } + +#if 0 + if (memcmp(iv2, iv, blocksize)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cfb); + xfree(mem); + fail ("%s-CFB-%d test failed (IV mismatch)", + cipher, blocksize * 8); + return -1; + } +#endif + + /* Test parallelized code paths */ + memset(iv, 0xe6, blocksize); + memset(iv2, 0xe6, blocksize); + + for (i = 0; i < nblocks * blocksize; i++) + plaintext[i] = i; + + /* Create CFB ciphertext manually. */ + for (i = 0; i < nblocks * blocksize; i+=blocksize) + { + err = gcry_cipher_encrypt (hd_one, &ciphertext[i], blocksize, + iv, blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cfb); + xfree(mem); + fail ("%s-CFB-%d test failed (ECB encrypt fail)", cipher, blocksize * 8); + return -1; + } + buf_xor_2dst (iv, &ciphertext[i], &plaintext[i], blocksize); + } + + /* Decrypt using bulk CBC and compare result. */ + err = gcry_cipher_setiv (hd_cfb, iv2, blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cfb); + xfree(mem); + fail ("%s-CFB-%d test failed (setiv fail)", cipher, blocksize * 8); + return -1; + } + err = gcry_cipher_decrypt (hd_cfb, plaintext2, blocksize * nblocks, + ciphertext, blocksize * nblocks); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cfb); + xfree(mem); + fail ("%s-CFB-%d test failed (CFB decrypt fail)", cipher, blocksize * 8); + return -1; + } + + if (memcmp(plaintext2, plaintext, nblocks * blocksize)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cfb); + xfree(mem); + fail ("%s-CFB-%d test failed (plaintext mismatch, parallel path)", + cipher, blocksize * 8); + return -1; + } +#if 0 + if (memcmp(iv2, iv, blocksize)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cfb); + xfree(mem); + fail ("%s-CFB-%d test failed (IV mismatch, parallel path)", + cipher, blocksize * 8); + return -1; + } +#endif + + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_cfb); + xfree(mem); + return -1; +} + + +/* Run the tests for -CTR-, tests IV increment + of bulk CTR encryption. Returns NULL on success. */ +static int +cipher_ctr_bulk_test (int cipher_algo) +{ + const int nblocks = 128 - 1; + int blocksize; + const char *cipher; + gcry_cipher_hd_t hd_one; + gcry_cipher_hd_t hd_ctr; + gcry_error_t err = 0; + int i, j, offs, diff; + unsigned char *plaintext, *plaintext2, *ciphertext, *ciphertext2, + *iv, *iv2, *mem; + unsigned int memsize; + unsigned int keylen; + + static const unsigned char key[32] = { + 0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, + 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21, + 0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, + 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21 + }; + + if (gcry_cipher_test_algo (cipher_algo)) + return -1; + blocksize = gcry_cipher_get_algo_blklen(cipher_algo); + if (blocksize < 8) + return -1; + cipher = gcry_cipher_algo_name (cipher_algo); + keylen = gcry_cipher_get_algo_keylen (cipher_algo); + if (keylen > sizeof(key)) + { + fail ("%s-CTR-%d test failed (key too short)", cipher, blocksize * 8); + return -1; + } + + memsize = (blocksize * 2) + (blocksize * nblocks * 4) + 16; + + mem = xcalloc (1, memsize); + if (!mem) + return -1; + + offs = (16 - ((uintptr_t)mem & 15)) & 15; + iv = (void*)(mem + offs); + iv2 = iv + blocksize; + plaintext = iv2 + blocksize; + plaintext2 = plaintext + nblocks * blocksize; + ciphertext = plaintext2 + nblocks * blocksize; + ciphertext2 = ciphertext + nblocks * blocksize; + + err = gcry_cipher_open (&hd_one, cipher_algo, GCRY_CIPHER_MODE_ECB, 0); + if (err) + { + xfree(mem); + fail ("%s-CTR-%d test failed (cipher open fail)", cipher, blocksize * 8); + return -1; + } + err = gcry_cipher_open (&hd_ctr, cipher_algo, GCRY_CIPHER_MODE_CTR, 0); + if (err) + { + gcry_cipher_close (hd_one); + xfree(mem); + fail ("%s-CTR-%d test failed (cipher open fail)", cipher, blocksize * 8); + return -1; + } + + /* Initialize ctx */ + if (gcry_cipher_setkey (hd_one, key, keylen) || + gcry_cipher_setkey (hd_ctr, key, keylen)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (setkey fail)", cipher, blocksize * 8); + return -1; + } + + /* Test single block code path */ + memset (iv, 0xff, blocksize); + for (i = 0; i < blocksize; i++) + plaintext[i] = i; + + /* CTR manually. */ + err = gcry_cipher_encrypt (hd_one, ciphertext, blocksize, iv, blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (ECB encrypt fail)", cipher, blocksize * 8); + return -1; + } + for (i = 0; i < blocksize; i++) + ciphertext[i] ^= plaintext[i]; + for (i = blocksize; i > 0; i--) + { + iv[i-1]++; + if (iv[i-1]) + break; + } + + memset (iv2, 0xff, blocksize); + err = gcry_cipher_setctr (hd_ctr, iv2, blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (setiv fail)", cipher, blocksize * 8); + return -1; + } + err = gcry_cipher_encrypt (hd_ctr, plaintext2, blocksize * 1, + ciphertext, blocksize * 1); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (CTR encrypt fail)", cipher, blocksize * 8); + return -1; + } + + if (memcmp (plaintext2, plaintext, blocksize)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (plaintext mismatch)", + cipher, blocksize * 8); + return -1; + } + +#if 0 + if (memcmp (iv2, iv, blocksize)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (IV mismatch)", cipher, blocksize * 8); + return -1; + } +#endif + + /* Test bulk encryption with typical IV. */ + memset(iv, 0x57, blocksize-4); + iv[blocksize-1] = 1; + iv[blocksize-2] = 0; + iv[blocksize-3] = 0; + iv[blocksize-4] = 0; + memset(iv2, 0x57, blocksize-4); + iv2[blocksize-1] = 1; + iv2[blocksize-2] = 0; + iv2[blocksize-3] = 0; + iv2[blocksize-4] = 0; + + for (i = 0; i < blocksize * nblocks; i++) + plaintext2[i] = plaintext[i] = i; + + /* Create CTR ciphertext manually. */ + for (i = 0; i < blocksize * nblocks; i+=blocksize) + { + err = gcry_cipher_encrypt (hd_one, &ciphertext[i], blocksize, + iv, blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (ECB encrypt fail)", + cipher, blocksize * 8); + return -1; + } + for (j = 0; j < blocksize; j++) + ciphertext[i+j] ^= plaintext[i+j]; + for (j = blocksize; j > 0; j--) + { + iv[j-1]++; + if (iv[j-1]) + break; + } + } + + err = gcry_cipher_setctr (hd_ctr, iv2, blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (setiv fail)", cipher, blocksize * 8); + return -1; + } + err = gcry_cipher_encrypt (hd_ctr, ciphertext2, blocksize * nblocks, + plaintext2, blocksize * nblocks); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (CTR encrypt fail)", cipher, blocksize * 8); + return -1; + } + + if (memcmp (ciphertext2, ciphertext, blocksize * nblocks)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (ciphertext mismatch, bulk)", + cipher, blocksize * 8); + return -1; + } +#if 0 + if (memcmp (iv2, iv, blocksize)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (IV mismatch, bulk)", cipher, blocksize * 8); + return -1; + } +#endif + + /* Test parallelized code paths (check counter overflow handling) */ + for (diff = 0; diff < nblocks; diff++) { + memset(iv, 0xff, blocksize); + iv[blocksize-1] -= diff; + iv[0] = iv[1] = 0; + iv[2] = 0x07; + + for (i = 0; i < blocksize * nblocks; i++) + plaintext[i] = i; + + /* Create CTR ciphertext manually. */ + for (i = 0; i < blocksize * nblocks; i+=blocksize) + { + err = gcry_cipher_encrypt (hd_one, &ciphertext[i], blocksize, + iv, blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (ECB encrypt fail)", + cipher, blocksize * 8); + return -1; + } + for (j = 0; j < blocksize; j++) + ciphertext[i+j] ^= plaintext[i+j]; + for (j = blocksize; j > 0; j--) + { + iv[j-1]++; + if (iv[j-1]) + break; + } + } + + /* Decrypt using bulk CTR and compare result. */ + memset(iv2, 0xff, blocksize); + iv2[blocksize-1] -= diff; + iv2[0] = iv2[1] = 0; + iv2[2] = 0x07; + + err = gcry_cipher_setctr (hd_ctr, iv2, blocksize); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (setiv fail)", cipher, blocksize * 8); + return -1; + } + err = gcry_cipher_decrypt (hd_ctr, plaintext2, blocksize * nblocks, + ciphertext, blocksize * nblocks); + if (err) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (CTR decrypt fail)", cipher, blocksize * 8); + return -1; + } + + if (memcmp (plaintext2, plaintext, blocksize * nblocks)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (plaintext mismatch, diff: %d)", + cipher, blocksize * 8, diff); + return -1; + } +#if 0 + if (memcmp(iv2, iv, blocksize)) + { + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + fail ("%s-CTR-%d test failed (IV mismatch, diff: %d)", + cipher, blocksize * 8, diff); + return -1; + } +#endif + } + + gcry_cipher_close (hd_one); + gcry_cipher_close (hd_ctr); + xfree(mem); + return -1; +} + + + 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, GCRY_CIPHER_GOST28147_MESH, #endif #if USE_SM4 GCRY_CIPHER_SM4, #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 }; gcry_error_t err = 0; int i; if (verbose) fprintf (stderr, "Starting Cipher checks.\n"); for (i = 0; algos[i]; i++) { if ((err = gcry_cipher_test_algo (algos[i]))) { if (in_fips_mode && (algos[i] == GCRY_CIPHER_AES || algos[i] == GCRY_CIPHER_AES192 || algos[i] == GCRY_CIPHER_AES256)) fail ("algorithm %d failed: %s\n", algos[i], gpg_strerror (err)); else { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i]); } continue; } else if (in_fips_mode && algos[i] != GCRY_CIPHER_AES && algos[i] != GCRY_CIPHER_AES192 && algos[i] != GCRY_CIPHER_AES256) { fail ("algorithm %d did not fail as expected 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); + + if (gcry_cipher_get_algo_blklen (algos[i]) >= 8) + { + cipher_cbc_bulk_test (algos[i]); + cipher_cfb_bulk_test (algos[i]); + cipher_ctr_bulk_test (algos[i]); + } } for (i = 0; algos2[i]; i++) { if ((err = gcry_cipher_test_algo (algos2[i]))) { if (in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos2[i]); } else fail ("algorithm %d failed: %s\n", algos2[i], gpg_strerror (err)); continue; } else if (in_fips_mode) { fail ("algorithm %d did not fail as expected 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_ecb_cipher (); check_aes128_cbc_cts_cipher (); check_cbc_mac_cipher (); check_ctr_cipher (); check_cfb_cipher (); check_ofb_cipher (); check_ccm_cipher (); if (!in_fips_mode) { /* This will have to go through modifications as the GCM fails in fips * as late as in gcry_cipher_gettag, but we want to allow it in the end */ check_gcm_cipher (); } check_poly1305_cipher (); check_ocb_cipher (); check_xts_cipher (); check_eax_cipher (); check_siv_cipher (); check_gcm_siv_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, j; 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) { clutter_vector_registers(); 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] && !xof) { unsigned char *p1, *p2; char buf[129]; /* Test hashing small input sizes first as full block, then byte-by-byte * and check that resulting digests are the same. */ err = gcry_md_open (&hd2, algo, 0); if (err) { gcry_md_close (hd); fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err)); return; } if (key && klen) { clutter_vector_registers(); err = gcry_md_setkey (hd2, key, klen); if (err) { gcry_md_close (hd); gcry_md_close (hd2); fail ("algo %d, gcry_md_setkey failed: %s\n", algo, gpg_strerror (err)); return; } } for (i = 0; i < sizeof(buf); i++) buf[i] = i; for (i = 1; i < sizeof(buf); i++) { gcry_md_reset (hd); gcry_md_reset (hd2); clutter_vector_registers(); gcry_md_write (hd, buf, i); for (j = 0; j < i; j++) gcry_md_write (hd2, &buf[j], 1); clutter_vector_registers(); p1 = gcry_md_read (hd, algo); p2 = gcry_md_read (hd2, algo); if (memcmp (p1, p2, mdlen)) { printf ("full block (input length %d): ", i); for (i = 0; i < mdlen; i++) printf ("%02x ", p1[i] & 0xFF); printf ("\nbyte-by-byte: "); for (i = 0; i < mdlen; i++) printf ("%02x ", p2[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } } gcry_md_close (hd2); gcry_md_reset (hd); } 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); clutter_vector_registers(); 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); clutter_vector_registers(); gcry_md_write (hd, aaa, piecelen); left -= piecelen; if (piecelen == sizeof(aaa)) piecelen = ++startlen; else piecelen = piecelen * 2 - ((piecelen != startlen) ? startlen : 0); } } else { clutter_vector_registers(); gcry_md_write (hd, data, len); } clutter_vector_registers(); 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) { static const char buf[128]; clutter_vector_registers(); 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); } /* Write after final/read is allowed for timing attack mitigation * purposes. Try writing and see if we catch fire. */ clutter_vector_registers(); gcry_md_write (hd2, buf, sizeof(buf)); } else { char buf[1000]; int outmax = sizeof(buf) > elen ? elen : sizeof(buf); clutter_vector_registers(); err = gcry_md_copy (&hd, hd2); if (err) { fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err)); } clutter_vector_registers(); 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. */ clutter_vector_registers(); 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_SHA256; 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++) { clutter_vector_registers(); 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; clutter_vector_registers(); 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); } clutter_vector_registers(); p1 = gcry_md_read (crc1, crcalgo); clutter_vector_registers(); 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)); clutter_vector_registers(); 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_one_md_final(int algo, const char *expect, unsigned int expectlen) { const unsigned int max_inbuf_len = 288 + 1; char *inbuf; char xorbuf[64]; char digest[64]; unsigned int mdlen; int i, j; mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 64) { return; } if (expectlen == 0) expectlen = mdlen; if (expectlen != mdlen) { fail ("check_one_md_final: algo %d, digest length mismatch\n", algo); return; } clutter_vector_registers(); gcry_md_hash_buffer (algo, xorbuf, NULL, 0); for (i = 1; i < max_inbuf_len; i++) { inbuf = xmalloc(i); if (!inbuf) { fail ("out-of-memory\n"); return; } for (j = 0; j < i; j++) inbuf[j] = j; gcry_md_hash_buffer (algo, digest, inbuf, i); for (j = 0; j < expectlen; j++) xorbuf[j] ^= digest[j]; xfree (inbuf); } if (memcmp(expect, xorbuf, expectlen) != 0) { printf ("computed: "); for (i = 0; i < expectlen; i++) printf ("%02x ", xorbuf[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < expectlen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("check_one_md_final: 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_SHA512_256, "abc", "\x53\x04\x8E\x26\x81\x94\x1E\xF9\x9B\x2E\x29\xB7\x6B\x4C\x7D\xAB" "\xE4\xC2\xD0\xC6\x34\xFC\x6D\x46\xE0\xE2\xF1\x31\x07\xE7\xAF\x23" }, { GCRY_MD_SHA512_256, "!", "\x9a\x59\xa0\x52\x93\x01\x87\xa9\x70\x38\xca\xe6\x92\xf3\x07\x08" "\xaa\x64\x91\x92\x3e\xf5\x19\x43\x94\xdc\x68\xd5\x6c\x74\xfb\x21" }, { GCRY_MD_SHA512_224, "abc", "\x46\x34\x27\x0F\x70\x7B\x6A\x54\xDA\xAE\x75\x30\x46\x08\x42\xE2" "\x0E\x37\xED\x26\x5C\xEE\xE9\xA4\x3E\x89\x24\xAA" }, { GCRY_MD_SHA512_224, "!", "\x37\xab\x33\x1d\x76\xf0\xd3\x6d\xe4\x22\xbd\x0e\xde\xb2\x2a\x28" "\xac\xcd\x48\x7b\x7a\x84\x53\xae\x96\x5d\xd2\x87" }, { 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" }, /* Special tests for carry flag in addition */ { GCRY_MD_STRIBOG512, "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE" "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE" "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE" "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE" "\x16\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x16", "\x8b\x06\xf4\x1e\x59\x90\x7d\x96\x36\xe8\x92\xca\xf5\x94\x2f\xcd" "\xfb\x71\xfa\x31\x16\x9a\x5e\x70\xf0\xed\xb8\x73\x66\x4d\xf4\x1c" "\x2c\xce\x6e\x06\xdc\x67\x55\xd1\x5a\x61\xcd\xeb\x92\xbd\x60\x7c" "\xc4\xaa\xca\x67\x32\xbf\x35\x68\xa2\x3a\x21\x0d\xd5\x20\xfd\x41" }, { GCRY_MD_STRIBOG512, "\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\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" "\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\xff\xff\xff\xff\xff\xff\xff\xff", "\x90\xa1\x61\xd1\x2a\xd3\x09\x49\x8d\x3f\xe5\xd4\x82\x02\xd8\xa4" "\xe9\xc4\x06\xd6\xa2\x64\xae\xab\x25\x8a\xc5\xec\xc3\x7a\x79\x62" "\xaa\xf9\x58\x7a\x5a\xbb\x09\xb6\xbb\x81\xec\x4b\x37\x52\xa3\xff" "\x5a\x83\x8e\xf1\x75\xbe\x57\x72\x05\x6b\xc5\xfe\x54\xfc\xfc\x7e" }, #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" }, #if USE_SM3 { 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" }, #endif /* USE_SM3 */ { GCRY_MD_GOSTR3411_CP, "*", "\x72\xd7\xe3\xbf\xa0\x08\xc9\x62\xae\xa9\xc5\xd8\x93\x5f\x17\xd7" "\x3f\xf2\x52\xb4\xc1\x16\xcf\x63\xa4\xcc\x4a\x8c\x7f\xe5\x60\x2c" }, { GCRY_MD_MD4, "*", "\xe8\xb9\xe4\x59\x61\x08\xc0\xfe\x54\xef\xc5\x8e\x20\x7c\x9b\x37" }, { GCRY_MD_MD5, "*", "\x0b\x1e\xab\xa2\x5e\x48\x76\x92\xae\x16\x12\xde\x5f\xb3\x29\x41" }, { GCRY_MD_RMD160, "*", "\x28\xfd\xd6\xa8\x95\x29\x43\x6b\x5e\xd9\xa0\x06\x82\xbb\xe6\x10" "\xd3\xcc\x79\x33" }, { GCRY_MD_SHA1, "*", "\xd8\x37\x46\x1a\x46\xfe\x42\x11\x7d\x50\xca\xf7\x3d\x7e\x0c\x36" "\x42\x0c\x15\xb6" }, { GCRY_MD_SHA224, "*", "\x2e\xba\x51\x6c\x71\x5a\x1d\xb8\x6b\x57\xfb\xf1\x46\xa0\xa7\x1d" "\x72\x66\xaf\x90\xb8\x01\x18\xc8\x58\x57\xa5\x63" }, { GCRY_MD_SHA256, "*", "\x30\xed\xe4\x69\xf3\x1c\x70\x8a\x6d\x92\x00\xac\xd8\x08\x89\xea" "\x7e\x92\xff\x02\x0b\x72\x4a\xdf\xa9\x2b\x9f\x80\xba\xd0\x25\xd0" }, { GCRY_MD_SHA384, "*", "\x21\xd7\x40\xdf\x34\x13\xcf\x56\xf7\x61\x0a\x1b\x11\xb7\x1e\x01" "\x87\xad\xbb\x3e\x9a\xe8\xaa\xaa\xbc\x3a\x89\x39\x0a\xa9\xcb\x4f" "\x09\x75\x4c\x44\x59\x42\xf5\x13\x5f\xe5\xa6\x2b\x16\xbe\xfc\xdf" }, { GCRY_MD_SHA512, "*", "\x5c\xbe\x01\x03\xbd\x8d\xa1\x38\x5e\x87\x00\x94\x8d\x14\xd0\xb3" "\x2c\x88\xeb\xb8\xf6\xcc\x06\x44\x54\xb1\x58\x88\xa9\x67\xa0\xe3" "\x0d\x28\x8b\xf4\x2c\xc6\x7a\xdc\x1a\x35\xbf\x0c\xc8\x35\xf0\x24" "\x69\xb5\xfe\x15\x6f\x71\xbd\x87\x07\x52\x27\xcc\xdc\x21\x84\x21" }, { GCRY_MD_SHA3_224, "*", "\x1a\xa6\x6f\x1a\x3c\x62\x14\x75\xea\x9d\x49\x4d\x39\x01\x2b\xbd" "\x4d\xe1\x58\xbc\x32\xac\x48\xcf\x6a\x1a\x54\x34" }, { GCRY_MD_SHA3_256, "*", "\x87\xf8\x0e\x78\xc1\x7b\x0c\x36\x4c\xbb\x8d\xca\x5e\x77\xc3\xfd" "\x95\xbd\xaf\x94\x85\xc6\x0c\xe6\x22\x52\xeb\x22\x50\x32\x48\x57" }, { GCRY_MD_SHA3_384, "*", "\x89\x5a\xd6\xc8\x60\x20\x66\xe7\x9e\xb3\x6d\x5c\x07\xd7\x5e\xd0" "\x48\x84\x9d\x51\x75\x14\x77\xdb\xcd\xbf\x70\x18\xdc\x64\x53\x85" "\x94\x95\xa5\xd3\x26\x9c\xf1\x63\x14\x8d\x11\xa0\xfc\xd8\x05\x9e" }, { GCRY_MD_SHA3_512, "*", "\x53\x0b\x1c\xb7\xff\x2c\xaa\x7e\x62\x15\xa7\x57\x9a\xd0\xcf\x4f" "\xa5\xae\xe0\x05\x1c\x77\x0f\x29\x5b\x3f\xba\xab\x88\x0c\x0b\x8e" "\x10\xcf\x3d\xa9\x0d\x1e\x97\x98\x96\xeb\x24\x2e\x70\x30\xd0\x78" "\x2b\x9e\x30\xad\x5d\xcf\x56\xcf\xd0\xc1\x58\x95\x53\x09\x78\xd6" }, #if USE_SM3 { GCRY_MD_SM3, "*", "\xb6\xfc\x1e\xc4\xad\x9b\x88\xbd\x08\xaa\xf3\xb3\xfa\x4f\x1b\x9c" "\xd6\x9a\x32\x09\x28\x9e\xda\x3a\x99\xb6\x09\x8f\x35\x99\xa6\x11" }, #endif /* USE_SM3 */ { GCRY_MD_STRIBOG256, "*", "\x35\x0b\xec\x46\x1f\x98\x19\xe7\x33\x12\xda\x9f\xaf\x3d\x32\xa6" "\xe4\xa5\x80\x38\x1b\x56\x68\x13\x2d\x0d\xa6\xfd\xfa\xe5\x3d\xf2" }, { GCRY_MD_STRIBOG512, "*", "\x01\x4c\xbd\xd4\x3a\x1a\x51\x9e\xa8\x7c\x1f\xd2\xc3\x2e\x71\x78" "\x03\x46\xd0\x1b\x30\xdd\x07\xf6\x82\x2b\xa4\x43\x8f\x95\x44\x9d" "\x92\x3a\x17\x70\x1b\xdd\xfc\x8f\x71\x20\xc6\xa0\xd8\x6f\xb2\x06" "\xb6\x61\x27\x48\x45\x94\x96\xe7\xdc\xf5\x7a\x2f\x83\x82\x03\x08" }, { GCRY_MD_TIGER1, "*", "\x95\xe1\x25\x8f\xc5\x4b\x82\x12\x69\x83\xfa\xfd\x79\x7d\x87\x38" "\x01\x4f\xf9\x24\xa2\xf0\x8f\x85" }, { GCRY_MD_WHIRLPOOL, "*", "\x8e\x02\x8e\x8d\xeb\x03\xcc\x37\xf2\x67\x61\x4e\x16\x27\x06\x13" "\x26\x8c\x35\x17\x0c\xab\x3c\x8b\x25\xc3\x3a\x2b\x7d\x54\xbf\xcf" "\x7e\xa2\xe4\x4f\x8d\x67\xb7\x85\xfa\x54\x76\x7c\xb0\x24\x87\xd5" "\x0e\x7d\x3b\x02\x8f\x30\x9e\x91\x78\xea\xc6\xdc\x0e\xee\x71\xca" }, { GCRY_MD_CRC24_RFC2440, "*", "\x44\x53\xd8" }, { GCRY_MD_CRC32, "*", "\x96\x11\x46\x4d" }, { GCRY_MD_TIGER, "*", "\x12\x82\x4b\xc5\x8f\x25\xe1\x95\x38\x87\x7d\x79\xfd\xfa\x83\x69" "\x85\x8f\xf0\xa2\x24\xf9\x4f\x01" }, { GCRY_MD_TIGER2, "*", "\xc6\x8f\x98\x71\xee\xb3\x1a\xf6\x77\x50\x8e\x74\x98\x08\x6c\x42" "\xc0\x37\x43\xc2\x17\x89\x5f\x98" }, { GCRY_MD_CRC32_RFC1510, "*", "\xf4\x45\xfd\x43" }, { GCRY_MD_BLAKE2B_512, "*", "\xe0\xf7\x38\x87\x07\xf9\xfd\xeb\x58\x8d\xb9\xb8\xa4\x85\x21\x8e" "\x56\xa9\xe6\x8d\x64\x4d\xfb\xe8\x8a\x84\xa4\x45\xc7\x80\x4b\x1f" "\x63\x0b\x27\x84\x96\xd4\xeb\x99\x19\xcb\xc6\x37\x01\x42\xb9\x03" "\x50\x63\xdf\xb9\x5e\xc5\xb1\xda\x2d\x19\xeb\x65\x73\xd2\xfa\xfa" }, { GCRY_MD_BLAKE2B_384, "*", "\x44\xde\xb8\x2b\x46\x22\xe5\xc6\xa5\x66\x8a\x88\x2b\xc3\x2c\x27" "\xc1\x4e\x4f\x6b\x70\x96\xcb\x1a\x99\x04\x67\x54\x8a\x0a\x55\xb4" "\xdb\x8b\xf6\x36\xfc\x2e\xf6\x2a\x6b\xe2\x1d\x09\x0e\x2f\x65\x33" }, { GCRY_MD_BLAKE2B_256, "*", "\x75\xd1\x62\xad\x02\xf1\x3f\xa3\x95\x2f\x5f\x89\x13\x2c\xf4\x2f" "\xc3\x84\xd2\x46\xbc\x35\x2b\x13\x01\xe0\x9e\x46\x55\x92\x40\x5a" }, { GCRY_MD_BLAKE2B_160, "*", "\x8c\x67\x38\x0e\xf8\xc7\xb6\x3e\x7f\x8e\x32\x73\x8a\xba\xa4\x71" "\x87\x9a\xb0\x4c" }, { GCRY_MD_BLAKE2S_256, "*", "\x71\x4a\x6d\xe4\xbb\x6c\x9f\x22\xff\x50\x02\xba\x5f\x54\xa6\x39" "\x9d\x07\x95\x82\x38\x98\xac\x62\xab\xc6\x13\x12\x65\x64\x9e\x69" }, { GCRY_MD_BLAKE2S_224, "*", "\x4c\x01\xe6\x67\xa2\x02\xd1\x62\x9b\xc3\x3b\xb5\x93\xc4\x3c\xa9" "\x90\x7b\x96\x70\xfd\xdf\xd1\xc3\xad\x09\xa9\xe7" }, { GCRY_MD_BLAKE2S_160, "*", "\x21\xca\x18\x74\x76\x3c\x6b\xe4\x92\x01\xd6\xd5\x91\xd1\x53\xfb" "\x37\x73\x99\xb9" }, { GCRY_MD_BLAKE2S_128, "*", "\x1d\x87\xfa\x69\xe0\x93\xd9\xcd\xb0\x3c\x52\x00\x35\xe1\xa3\xee" }, { GCRY_MD_GOSTR3411_94, "*", "\x6e\xa9\x9e\x23\xde\x5f\x7a\xb7\x7f\xa7\xdc\xe1\xc8\x05\x46\xae" "\x1e\x7c\x76\xbb\x52\x0f\x52\x07\x78\x59\xd3\xc1\x64\xdb\x51\xac" }, { 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)) { if (in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i].md); } else show_md_not_available (algos[i].md); continue; } if (!strcmp (algos[i].data, "*")) { if (verbose) fprintf (stderr, " checking %s [%i] for final handling\n", gcry_md_algo_name (algos[i].md), algos[i].md); check_one_md_final (algos[i].md, algos[i].expect, algos[i].expectlen); 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; } err = gcry_md_setkey( hd, key, keylen ); if (err) { if (in_fips_mode) { if (verbose) fprintf (stderr, " shorter key (%d) rejected correctly in fips mode\n", keylen); } gcry_md_close (hd); return; } gcry_md_write (hd, data, datalen); err = gcry_md_copy (&hd2, hd); gcry_md_close (hd); if (err) { fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err)); return; } p = gcry_md_read (hd2, algo); if (!p) fail("algo %d, hmac gcry_md_read failed\n", algo); else 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)) { if (in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i].md); } else show_old_hmac_not_available (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; } clutter_vector_registers(); err = gcry_mac_setkey (hd, key, keylen); if (err) { if (in_fips_mode) { if (verbose) fprintf (stderr, " shorter key (%d) rejected correctly in fips mode\n", keylen); } else fail("algo %d, mac gcry_mac_setkey failed: %s\n", algo, gpg_strerror (err)); goto out; } if (ivlen && iv) { clutter_vector_registers(); 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++) { clutter_vector_registers(); 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); clutter_vector_registers(); 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); clutter_vector_registers(); gcry_mac_write (hd, aaa, piecelen); left -= piecelen; if (piecelen == sizeof(aaa)) piecelen = ++startlen; else piecelen = piecelen * 2 - ((piecelen != startlen) ? startlen : 0); } } else { clutter_vector_registers(); 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; } clutter_vector_registers(); 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; clutter_vector_registers(); 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" }, #if USE_DES { 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" }, #endif /* USE_DES */ #if USE_CAMELLIA /* 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" }, #endif /* USE_CAMELLIA */ /* 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 }, #if USE_GOST28147 { GCRY_MAC_GOST28147_IMIT, "\xb5\xa1\xf0\xe3\xce\x2f\x02\x1d\x67\x61\x94\x34\x5c\x41\xe3\x6e", "\x9d\x05\xb7\x9e\x90\xca\xd0\x0a\x2c\xda\xd2\x2e\xf4\xe8\x6f\x5c" "\xf5\xdc\x37\x68\x19\x85\xb3\xbf\xaa\x18\xc1\xc3\x05\x0a\x91\xa2", "\xf8\x1f\x08\xa3", NULL, 16, 32 }, #endif /* USE_GOST28147 */ { 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)) { if (in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i].algo); } else show_mac_not_available (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 key SKEY. PKEY is used for verification. */ static void check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo, int flags) { 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 }, { "(data\n (flags pss)\n" " (hash-algo sha1)\n" " (value #11223344556677889900AA#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags pss)\n" " (hash-algo sha1)\n" " (value #11223344556677889900AA#)\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)); sig = NULL; 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 (in_fips_mode && (flags & FLAG_NOFIPS)) { if (!rc) fail ("gcry_pk_sign did not fail as expected in FIPS mode\n"); goto next; } 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); next: 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 key 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, int flags) { 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 }, { 256, "(data (flags sm2)\n" " (hash sm3 #112233445566778899AABBCCDDEEFF00" /* */ "123456789ABCDEF0123456789ABCDEF0#))", 0, "(data (flags sm2)\n" " (hash sm3 #B524F552CD82B8B028476E005C377FB1" /* */ "9A87E6FC682D48BB5D42E3D9B9EFFE76#))", 0 }, { 0, NULL } }; nbits = gcry_pk_get_nbits (skey); sig = NULL; 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 (in_fips_mode && (flags & FLAG_NOFIPS)) { if (!rc) fail ("gcry_pk_sign did not fail as expected in FIPS mode\n"); goto next; } 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); next: 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, int flags) { 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 flags; } datas[] = { { GCRY_PK_RSA, "(data\n (flags pkcs1)\n" " (value #11223344556677889900AA#))\n", NULL, 0, 0, 0, FLAG_NOFIPS }, { GCRY_PK_RSA, "(data\n (flags pkcs1)\n" " (value #11223344556677889900AA#))\n", "(flags pkcs1)", 1, 0, 0, FLAG_NOFIPS }, { 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, FLAG_SPECIAL }, { GCRY_PK_RSA, "(data\n (flags oaep)\n" " (value #11223344556677889900AA#))\n", "(flags pkcs1)", 1, 0, GPG_ERR_ENCODING_PROBLEM, FLAG_SPECIAL }, { 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 (in_fips_mode && ((flags & FLAG_NOFIPS) || (datas[dataidx].flags & FLAG_NOFIPS))) { if (!rc) fail ("gcry_pk_encrypt did not fail as expected in FIPS mode\n"); goto next; } 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. */ 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 || in_fips_mode) && (datas[dataidx].flags & FLAG_SPECIAL)) { /* 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); } } next: 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, flags); else check_pubkey_sign (n, skey, pkey, algo, flags); } if ((flags & FLAG_CRYPT)) check_pubkey_crypt (n, skey, pkey, algo, flags); 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 = 0; 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 | FLAG_GRIP | FLAG_NOFIPS, /* 1k RSA */ { "(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_RSA, FLAG_CRYPT | FLAG_SIGN | FLAG_GRIP, /* 2k RSA */ { "(private-key" " (rsa" " (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC" " 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8" " 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C" " 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917" " DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613" " 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C" " 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918" " 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6" " CB#)\n" " (e #010001#)\n" " (d #07EF82500C403899934FE993AC5A36F14FF2DF38CF1EF315F205EE4C83EDAA19" " 8890FC23DE9AA933CAFB37B6A8A8DBA675411958337287310D3FF2F1DDC0CB93" " 7E70F57F75F833C021852B631D2B9A520E4431A03C5C3FCB5742DCD841D9FB12" " 771AA1620DCEC3F1583426066ED9DC3F7028C5B59202C88FDF20396E2FA0EC4F" " 5A22D9008F3043673931BC14A5046D6327398327900867E39CC61B2D1AFE2F48" " EC8E1E3861C68D257D7425F4E6F99ABD77D61F10CA100EFC14389071831B33DD" " 69CC8EABEF860D1DC2AAA84ABEAE5DFC91BC124DAF0F4C8EF5BBEA436751DE84" " 3A8063E827A024466F44C28614F93B0732A100D4A0D86D532FE1E22C7725E401" " #)\n" " (p #00C29D438F115825779631CD665A5739367F3E128ADC29766483A46CA80897E0" " 79B32881860B8F9A6A04C2614A904F6F2578DAE13EA67CD60AE3D0AA00A1FF9B" " 441485E44B2DC3D0B60260FBFE073B5AC72FAF67964DE15C8212C389D20DB9CF" " 54AF6AEF5C4196EAA56495DD30CF709F499D5AB30CA35E086C2A1589D6283F17" " 83#)\n" " (q #00D1984135231CB243FE959C0CBEF551EDD986AD7BEDF71EDF447BE3DA27AF46" " 79C974A6FA69E4D52FE796650623DE70622862713932AA2FD9F2EC856EAEAA77" " 88B4EA6084DC81C902F014829B18EA8B2666EC41586818E0589E18876065F97E" " 8D22CE2DA53A05951EC132DCEF41E70A9C35F4ACC268FFAC2ADF54FA1DA110B9" " 19#)\n" " (u #67CF0FD7635205DD80FA814EE9E9C267C17376BF3209FB5D1BC42890D2822A04" " 479DAF4D5B6ED69D0F8D1AF94164D07F8CD52ECEFE880641FA0F41DDAB1785E4" " A37A32F997A516480B4CD4F6482B9466A1765093ED95023CA32D5EDC1E34CEE9" " AF595BC51FE43C4BF810FA225AF697FB473B83815966188A4312C048B885E3F7" " #)))\n", "(public-key\n" " (rsa\n" " (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC" " 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8" " 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C" " 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917" " DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613" " 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C" " 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918" " 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6" " CB#)\n" " (e #010001#)))\n", "\xe0\x08\x98\x9b\xb6\x44\xa2\x9a\x83\x37" "\x47\xdd\x69\x55\xdb\x3a\xac\x89\x6e\x40"} }, { GCRY_PK_DSA, FLAG_SIGN | FLAG_GRIP | FLAG_NOFIPS, /* 1k DSA */ { "(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 | FLAG_GRIP | FLAG_NOFIPS, { "(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 #028532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE#)))\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 #03D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2B" " EB6644D3609FC781B7#)))\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 | FLAG_NOFIPS, { "(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 | FLAG_NOFIPS, { "(private-key\n" " (ecc\n" " (curve GOST2012-512-test)\n" " (q #04115DC5BC96760C7B48598D8AB9E740D4C4A85A65BE33C1" " 815B5C320C854621DD5A515856D13314AF69BC5B924C8B" " 4DDFF75C45415C1D9DD9DD33612CD530EFE137C7C90CD4" " 0B0F5621DC3AC1B751CFA0E2634FA0503B3D52639F5D7F" " B72AFD61EA199441D943FFE7F0C70A2759A3CDB84C114E" " 1F9339FDF27F35ECA93677BEEC#)\n" " (d #0BA6048AADAE241BA40936D47756D7C93091A0E851466970" " 0EE7508E508B102072E8123B2200A0563322DAD2827E2714" " A2636B7BFD18AADFC62967821FA18DD4#)))\n", "(public-key\n" " (ecc\n" " (curve GOST2012-512-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" } }, { /* sm2 test */ GCRY_PK_ECDSA, FLAG_SIGN | FLAG_NOFIPS, { "(private-key\n" " (ecc\n" " (curve sm2p256v1)\n" " (q #04" " 8759389A34AAAD07ECF4E0C8C2650A4459C8D926EE2378324E0261C52538CB47" " 7528106B1E0B7C8DD5FF29A9C86A89065656EB33154BC0556091EF8AC9D17D78#)" " (d #41EBDBA9C98CBECCE7249CF18BFD427FF8EA0B2FAB7B9D305D9D9BF4DB6ADFC2#)" "))", "(public-key\n" " (ecc\n" " (curve sm2p256v1)\n" " (q #04" " 8759389A34AAAD07ECF4E0C8C2650A4459C8D926EE2378324E0261C52538CB47" " 7528106B1E0B7C8DD5FF29A9C86A89065656EB33154BC0556091EF8AC9D17D78#)" "))", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } } }; gcry_error_t err = 0; 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 ((err = gcry_pk_test_algo (pubkeys[i].id))) { if (in_fips_mode && (pubkeys[i].flags & FLAG_NOFIPS)) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", pubkeys[i].id); } else { fail ("gcry_pk_test_algo failed: %s\n", gpg_strerror (err)); continue; } } check_one_pubkey (i, pubkeys[i]); } if (verbose) fprintf (stderr, "Completed public key checks.\n"); if (verbose) fprintf (stderr, "Starting additional public key check.\n"); check_one_pubkey_new (i); if (verbose) fprintf (stderr, "Completed additional public key check.\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 hash_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, "--hash")) { hash_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 (hash_only) { check_digests (); check_hmac (); check_mac (); } 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. */ gcry_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. */ gcry_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; }